diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-01 20:35:55 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-01 20:35:55 +0300 |
| commit | 443694d226db91695c2cdddf97d6b9e06923b7be (patch) | |
| tree | aa1e31dda33b245316917fa94a4e8fbb8c52628c | |
| parent | 5ae64f1658fb8e1daa9400efab96f3fcee5d17c0 (diff) | |
zg: add bg-bg consumer coverage
| -rw-r--r-- | internal/gui/generator.go | 2 | ||||
| -rw-r--r-- | internal/gui/generator_test.go | 75 | ||||
| -rw-r--r-- | internal/processor/processor_test.go | 87 |
3 files changed, 163 insertions, 1 deletions
diff --git a/internal/gui/generator.go b/internal/gui/generator.go index 34e713e..34e63fc 100644 --- a/internal/gui/generator.go +++ b/internal/gui/generator.go @@ -205,7 +205,7 @@ func (a *Application) generateAudioBgBg(ctx context.Context, front, back, cardDi audioConfig.OpenAISpeed = speed audioConfig.OutputDir = a.config.OutputDir - provider, err := audio.NewProvider(&audioConfig) + provider, err := newAudioProvider(&audioConfig) if err != nil { return "", "", err } diff --git a/internal/gui/generator_test.go b/internal/gui/generator_test.go index d768560..5493de9 100644 --- a/internal/gui/generator_test.go +++ b/internal/gui/generator_test.go @@ -56,12 +56,16 @@ func (f *fakePromptAwareImageClient) SetPromptCallback(callback func(prompt stri type fakeAudioProvider struct { generateCalls int + texts []string + outputFiles []string lastText string lastOutputFile string } func (f *fakeAudioProvider) GenerateAudio(_ context.Context, text, outputFile string) error { f.generateCalls++ + f.texts = append(f.texts, text) + f.outputFiles = append(f.outputFiles, outputFile) f.lastText = text f.lastOutputFile = outputFile return nil @@ -214,3 +218,74 @@ func TestGenerateAudioUsesSharedOpenAIVoices(t *testing.T) { t.Fatalf("outputPath = %q, want shared audio filename", outputPath) } } + +func TestGenerateAudioBgBgUsesSharedOpenAIVoices(t *testing.T) { + originalFactory := newAudioProvider + t.Cleanup(func() { + newAudioProvider = originalFactory + }) + + originalVoices := append([]string(nil), audio.OpenAIVoices...) + t.Cleanup(func() { + audio.OpenAIVoices = originalVoices + }) + + audio.OpenAIVoices = []string{"sentinel-bg-gui-voice"} + + fakeProvider := &fakeAudioProvider{} + var capturedConfig *audio.Config + newAudioProvider = func(config *audio.Config) (audio.Provider, error) { + copyConfig := *config + capturedConfig = ©Config + return fakeProvider, nil + } + + tempDir := t.TempDir() + cardDir := filepath.Join(tempDir, "card") + if err := os.MkdirAll(cardDir, 0755); err != nil { + t.Fatalf("failed to create card dir: %v", err) + } + + app := &Application{ + config: &Config{ + OutputDir: tempDir, + AudioFormat: "mp3", + }, + audioConfig: &audio.Config{ + Provider: "openai", + OutputDir: tempDir, + OpenAIModel: "gpt-4o-mini-tts", + OpenAIInstruction: "Speak clearly.", + }, + } + + frontPath, backPath, err := app.generateAudioBgBg(context.Background(), "ябълка", "круша", cardDir) + if err != nil { + t.Fatalf("generateAudioBgBg() unexpected error: %v", err) + } + + if capturedConfig == nil { + t.Fatal("expected audio provider config to be captured") + } + if capturedConfig.OpenAIVoice != "sentinel-bg-gui-voice" { + t.Fatalf("captured OpenAIVoice = %q, want %q", capturedConfig.OpenAIVoice, "sentinel-bg-gui-voice") + } + if fakeProvider.generateCalls != 2 { + t.Fatalf("GenerateAudio() calls = %d, want %d", fakeProvider.generateCalls, 2) + } + if len(fakeProvider.outputFiles) != 2 { + t.Fatalf("output file count = %d, want %d", len(fakeProvider.outputFiles), 2) + } + if !strings.HasSuffix(fakeProvider.outputFiles[0], "audio_front.mp3") { + t.Fatalf("front output file = %q, want audio_front.mp3", fakeProvider.outputFiles[0]) + } + if !strings.HasSuffix(fakeProvider.outputFiles[1], "audio_back.mp3") { + t.Fatalf("back output file = %q, want audio_back.mp3", fakeProvider.outputFiles[1]) + } + if !strings.HasSuffix(frontPath, "audio_front.mp3") { + t.Fatalf("frontPath = %q, want audio_front.mp3", frontPath) + } + if !strings.HasSuffix(backPath, "audio_back.mp3") { + t.Fatalf("backPath = %q, want audio_back.mp3", backPath) + } +} diff --git a/internal/processor/processor_test.go b/internal/processor/processor_test.go index 1b86910..c944d7a 100644 --- a/internal/processor/processor_test.go +++ b/internal/processor/processor_test.go @@ -2,6 +2,7 @@ package processor import ( "context" + "errors" "io" "os" "path/filepath" @@ -59,12 +60,16 @@ func (s *stubImageSearcher) GetLastPrompt() string { type fakeAudioProvider struct { generateCalls int + texts []string + outputFiles []string lastText string lastOutputFile string } func (f *fakeAudioProvider) GenerateAudio(_ context.Context, text, outputFile string) error { f.generateCalls++ + f.texts = append(f.texts, text) + f.outputFiles = append(f.outputFiles, outputFile) f.lastText = text f.lastOutputFile = outputFile return nil @@ -303,6 +308,88 @@ func TestGenerateAudioUsesSharedOpenAIVoices(t *testing.T) { } } +func TestGenerateAudioBgBgUsesSharedOpenAIVoices(t *testing.T) { + originalFactory := newAudioProvider + t.Cleanup(func() { + newAudioProvider = originalFactory + }) + + originalVoices := append([]string(nil), audio.OpenAIVoices...) + t.Cleanup(func() { + audio.OpenAIVoices = originalVoices + }) + + audio.OpenAIVoices = []string{"sentinel-bg-voice"} + + fakeProvider := &fakeAudioProvider{} + var capturedConfig *audio.Config + newAudioProvider = func(config *audio.Config) (audio.Provider, error) { + copyConfig := *config + capturedConfig = ©Config + return fakeProvider, nil + } + + tempDir := t.TempDir() + flags := cli.NewFlags() + flags.OutputDir = tempDir + flags.AudioFormat = "mp3" + + p := NewProcessor(flags) + if err := p.generateAudioBgBg("ябълка", "круша"); err != nil { + t.Fatalf("generateAudioBgBg() unexpected error: %v", err) + } + + if capturedConfig == nil { + t.Fatal("expected audio provider config to be captured") + } + if capturedConfig.OpenAIVoice != "sentinel-bg-voice" { + t.Fatalf("captured OpenAIVoice = %q, want %q", capturedConfig.OpenAIVoice, "sentinel-bg-voice") + } + if fakeProvider.generateCalls != 2 { + t.Fatalf("GenerateAudio() calls = %d, want %d", fakeProvider.generateCalls, 2) + } + if len(fakeProvider.outputFiles) != 2 { + t.Fatalf("output file count = %d, want %d", len(fakeProvider.outputFiles), 2) + } + if !strings.HasSuffix(fakeProvider.outputFiles[0], "audio_front.mp3") { + t.Fatalf("front output file = %q, want audio_front.mp3", fakeProvider.outputFiles[0]) + } + if !strings.HasSuffix(fakeProvider.outputFiles[1], "audio_back.mp3") { + t.Fatalf("back output file = %q, want audio_back.mp3", fakeProvider.outputFiles[1]) + } +} + +func TestGenerateAudioProviderFactoryError(t *testing.T) { + originalFactory := newAudioProvider + t.Cleanup(func() { + newAudioProvider = originalFactory + }) + + originalVoices := append([]string(nil), audio.OpenAIVoices...) + t.Cleanup(func() { + audio.OpenAIVoices = originalVoices + }) + + audio.OpenAIVoices = []string{"sentinel-failure-voice"} + newAudioProvider = func(*audio.Config) (audio.Provider, error) { + return nil, errors.New("provider factory failed") + } + + tempDir := t.TempDir() + flags := cli.NewFlags() + flags.OutputDir = tempDir + flags.AudioFormat = "mp3" + + p := NewProcessor(flags) + err := p.generateAudio("ябълка") + if err == nil { + t.Fatal("generateAudio() expected error from provider factory") + } + if !strings.Contains(err.Error(), "provider factory failed") { + t.Fatalf("generateAudio() error = %q, want it to contain %q", err.Error(), "provider factory failed") + } +} + func TestDownloadImagesWithTranslationUsesNanoBananaConfigAndSavesPrompt(t *testing.T) { t.Setenv("OPENAI_API_KEY", "test-openai-key") t.Setenv("GOOGLE_API_KEY", "test-google-key") |
