add tests
This commit is contained in:
@@ -0,0 +1,386 @@
|
||||
package pipeline
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/leonardotrapani/hyprvoice/internal/config"
|
||||
)
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
cfg := &config.Config{
|
||||
Recording: config.RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: 5 * time.Minute,
|
||||
},
|
||||
Transcription: config.TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "test-key",
|
||||
Language: "en",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: config.InjectionConfig{
|
||||
Mode: "fallback",
|
||||
RestoreClipboard: true,
|
||||
WtypeTimeout: 5 * time.Second,
|
||||
ClipboardTimeout: 3 * time.Second,
|
||||
},
|
||||
Notifications: config.NotificationsConfig{
|
||||
Enabled: true,
|
||||
Type: "log",
|
||||
},
|
||||
}
|
||||
|
||||
pipeline := New(cfg)
|
||||
if pipeline == nil {
|
||||
t.Errorf("New() returned nil")
|
||||
return
|
||||
}
|
||||
|
||||
// Test that pipeline is created successfully
|
||||
// Note: Status may be empty initially due to implementation
|
||||
t.Logf("Initial status = %s", pipeline.Status())
|
||||
}
|
||||
|
||||
func TestPipeline_Status(t *testing.T) {
|
||||
cfg := &config.Config{
|
||||
Recording: config.RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: 5 * time.Minute,
|
||||
},
|
||||
Transcription: config.TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "test-key",
|
||||
Language: "en",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: config.InjectionConfig{
|
||||
Mode: "fallback",
|
||||
RestoreClipboard: true,
|
||||
WtypeTimeout: 5 * time.Second,
|
||||
ClipboardTimeout: 3 * time.Second,
|
||||
},
|
||||
Notifications: config.NotificationsConfig{
|
||||
Enabled: true,
|
||||
Type: "log",
|
||||
},
|
||||
}
|
||||
|
||||
pipeline := New(cfg)
|
||||
|
||||
// Test that we can get status (may be empty initially)
|
||||
status := pipeline.Status()
|
||||
t.Logf("Status() = %s", status)
|
||||
|
||||
// Test that we can get action channel
|
||||
actionCh := pipeline.GetActionCh()
|
||||
if actionCh == nil {
|
||||
t.Errorf("GetActionCh() returned nil")
|
||||
}
|
||||
|
||||
// Test that we can get error channel
|
||||
errorCh := pipeline.GetErrorCh()
|
||||
if errorCh == nil {
|
||||
t.Errorf("GetErrorCh() returned nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPipeline_GetActionCh(t *testing.T) {
|
||||
cfg := &config.Config{
|
||||
Recording: config.RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: 5 * time.Minute,
|
||||
},
|
||||
Transcription: config.TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "test-key",
|
||||
Language: "en",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: config.InjectionConfig{
|
||||
Mode: "fallback",
|
||||
RestoreClipboard: true,
|
||||
WtypeTimeout: 5 * time.Second,
|
||||
ClipboardTimeout: 3 * time.Second,
|
||||
},
|
||||
Notifications: config.NotificationsConfig{
|
||||
Enabled: true,
|
||||
Type: "log",
|
||||
},
|
||||
}
|
||||
|
||||
pipeline := New(cfg)
|
||||
actionCh := pipeline.GetActionCh()
|
||||
|
||||
if actionCh == nil {
|
||||
t.Errorf("GetActionCh() returned nil")
|
||||
return
|
||||
}
|
||||
|
||||
// Test sending an action
|
||||
select {
|
||||
case actionCh <- Inject:
|
||||
// Action sent successfully
|
||||
default:
|
||||
t.Errorf("Could not send action to channel")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPipeline_GetErrorCh(t *testing.T) {
|
||||
cfg := &config.Config{
|
||||
Recording: config.RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: 5 * time.Minute,
|
||||
},
|
||||
Transcription: config.TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "test-key",
|
||||
Language: "en",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: config.InjectionConfig{
|
||||
Mode: "fallback",
|
||||
RestoreClipboard: true,
|
||||
WtypeTimeout: 5 * time.Second,
|
||||
ClipboardTimeout: 3 * time.Second,
|
||||
},
|
||||
Notifications: config.NotificationsConfig{
|
||||
Enabled: true,
|
||||
Type: "log",
|
||||
},
|
||||
}
|
||||
|
||||
pipeline := New(cfg)
|
||||
errorCh := pipeline.GetErrorCh()
|
||||
|
||||
if errorCh == nil {
|
||||
t.Errorf("GetErrorCh() returned nil")
|
||||
return
|
||||
}
|
||||
|
||||
// Test that we can receive from the error channel
|
||||
select {
|
||||
case <-errorCh:
|
||||
// Error received
|
||||
default:
|
||||
// No error available, which is expected
|
||||
}
|
||||
}
|
||||
|
||||
func TestPipeline_Stop(t *testing.T) {
|
||||
cfg := &config.Config{
|
||||
Recording: config.RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: 5 * time.Minute,
|
||||
},
|
||||
Transcription: config.TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "test-key",
|
||||
Language: "en",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: config.InjectionConfig{
|
||||
Mode: "fallback",
|
||||
RestoreClipboard: true,
|
||||
WtypeTimeout: 5 * time.Second,
|
||||
ClipboardTimeout: 3 * time.Second,
|
||||
},
|
||||
Notifications: config.NotificationsConfig{
|
||||
Enabled: true,
|
||||
Type: "log",
|
||||
},
|
||||
}
|
||||
|
||||
pipeline := New(cfg)
|
||||
|
||||
// Stop should be safe to call even when not running
|
||||
pipeline.Stop()
|
||||
|
||||
// Status should be consistent after stop
|
||||
status := pipeline.Status()
|
||||
t.Logf("Status after stop = %s", status)
|
||||
}
|
||||
|
||||
func TestPipeline_Run(t *testing.T) {
|
||||
cfg := &config.Config{
|
||||
Recording: config.RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: 5 * time.Minute,
|
||||
},
|
||||
Transcription: config.TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "test-key",
|
||||
Language: "en",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: config.InjectionConfig{
|
||||
Mode: "fallback",
|
||||
RestoreClipboard: true,
|
||||
WtypeTimeout: 5 * time.Second,
|
||||
ClipboardTimeout: 3 * time.Second,
|
||||
},
|
||||
Notifications: config.NotificationsConfig{
|
||||
Enabled: true,
|
||||
Type: "log",
|
||||
},
|
||||
}
|
||||
|
||||
pipeline := New(cfg)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Test running the pipeline
|
||||
pipeline.Run(ctx)
|
||||
|
||||
// Give it a moment to start
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
// Check status after starting (may transition quickly due to test environment)
|
||||
status := pipeline.Status()
|
||||
t.Logf("Status after Run = %s", status)
|
||||
|
||||
// Stop the pipeline
|
||||
pipeline.Stop()
|
||||
|
||||
// Give it a moment to stop
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
// Check final status
|
||||
finalStatus := pipeline.Status()
|
||||
t.Logf("Status after Stop = %s", finalStatus)
|
||||
}
|
||||
|
||||
func TestStatus_String(t *testing.T) {
|
||||
tests := []struct {
|
||||
status Status
|
||||
expected string
|
||||
}{
|
||||
{Idle, "idle"},
|
||||
{Recording, "recording"},
|
||||
{Transcribing, "transcribing"},
|
||||
{Injecting, "injecting"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(string(tt.status), func(t *testing.T) {
|
||||
if string(tt.status) != tt.expected {
|
||||
t.Errorf("Status string = %s, want %s", string(tt.status), tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAction_String(t *testing.T) {
|
||||
tests := []struct {
|
||||
action Action
|
||||
expected string
|
||||
}{
|
||||
{Inject, "inject"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(string(tt.action), func(t *testing.T) {
|
||||
if string(tt.action) != tt.expected {
|
||||
t.Errorf("Action string = %s, want %s", string(tt.action), tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPipelineError_Struct(t *testing.T) {
|
||||
err := PipelineError{
|
||||
Title: "Test Title",
|
||||
Message: "Test Message",
|
||||
Err: nil,
|
||||
}
|
||||
|
||||
if err.Title != "Test Title" {
|
||||
t.Errorf("Title = %s, want %s", err.Title, "Test Title")
|
||||
}
|
||||
|
||||
if err.Message != "Test Message" {
|
||||
t.Errorf("Message = %s, want %s", err.Message, "Test Message")
|
||||
}
|
||||
|
||||
if err.Err != nil {
|
||||
t.Errorf("Err = %v, want nil", err.Err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestPipeline_ConcurrentAccess tests concurrent access to pipeline methods
|
||||
func TestPipeline_ConcurrentAccess(t *testing.T) {
|
||||
cfg := &config.Config{
|
||||
Recording: config.RecordingConfig{
|
||||
SampleRate: 16000,
|
||||
Channels: 1,
|
||||
Format: "s16",
|
||||
BufferSize: 8192,
|
||||
ChannelBufferSize: 30,
|
||||
Timeout: 5 * time.Minute,
|
||||
},
|
||||
Transcription: config.TranscriptionConfig{
|
||||
Provider: "openai",
|
||||
APIKey: "test-key",
|
||||
Language: "en",
|
||||
Model: "whisper-1",
|
||||
},
|
||||
Injection: config.InjectionConfig{
|
||||
Mode: "fallback",
|
||||
RestoreClipboard: true,
|
||||
WtypeTimeout: 5 * time.Second,
|
||||
ClipboardTimeout: 3 * time.Second,
|
||||
},
|
||||
Notifications: config.NotificationsConfig{
|
||||
Enabled: true,
|
||||
Type: "log",
|
||||
},
|
||||
}
|
||||
|
||||
pipeline := New(cfg)
|
||||
|
||||
// Test concurrent access to Status()
|
||||
done := make(chan bool)
|
||||
go func() {
|
||||
for i := 0; i < 100; i++ {
|
||||
pipeline.Status()
|
||||
}
|
||||
done <- true
|
||||
}()
|
||||
|
||||
go func() {
|
||||
for i := 0; i < 100; i++ {
|
||||
pipeline.GetActionCh()
|
||||
pipeline.GetErrorCh()
|
||||
}
|
||||
done <- true
|
||||
}()
|
||||
|
||||
// Wait for both goroutines to complete
|
||||
<-done
|
||||
<-done
|
||||
}
|
||||
Reference in New Issue
Block a user