diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-02 16:36:25 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-02 16:36:25 +0300 |
| commit | 6bd23a588bacee2e8c75f477150b7e2d345002ff (patch) | |
| tree | 67bfa78afe206e7560350bdd52c60e0e80ec3243 /internal/gui/generator_test.go | |
| parent | 6ce9123de04ffff961cbf1da73648679216ff637 (diff) | |
Release v0.9.0v0.9.0
Diffstat (limited to 'internal/gui/generator_test.go')
| -rw-r--r-- | internal/gui/generator_test.go | 87 |
1 files changed, 73 insertions, 14 deletions
diff --git a/internal/gui/generator_test.go b/internal/gui/generator_test.go index 0c1ac41..2828337 100644 --- a/internal/gui/generator_test.go +++ b/internal/gui/generator_test.go @@ -61,6 +61,7 @@ type fakeAudioProvider struct { outputFiles []string lastText string lastOutputFile string + generateFunc func(text, outputFile string) error } func (f *fakeAudioProvider) GenerateAudio(_ context.Context, text, outputFile string) error { @@ -69,6 +70,9 @@ func (f *fakeAudioProvider) GenerateAudio(_ context.Context, text, outputFile st f.outputFiles = append(f.outputFiles, outputFile) f.lastText = text f.lastOutputFile = outputFile + if f.generateFunc != nil { + return f.generateFunc(text, outputFile) + } return nil } @@ -254,7 +258,7 @@ func TestGenerateAudioUsesSharedOpenAIVoices(t *testing.T) { } } -func TestGenerateAudioUsesGeminiModelDefaultVoiceAndAttribution(t *testing.T) { +func TestGenerateAudioUsesRandomGeminiVoiceAndAttribution(t *testing.T) { originalFactory := newAudioProvider t.Cleanup(func() { newAudioProvider = originalFactory @@ -284,7 +288,7 @@ func TestGenerateAudioUsesGeminiModelDefaultVoiceAndAttribution(t *testing.T) { app := &Application{ config: &Config{ OutputDir: tempDir, - AudioFormat: "wav", + AudioFormat: "mp3", }, audioConfig: &audio.Config{ Provider: "gemini", @@ -306,17 +310,17 @@ func TestGenerateAudioUsesGeminiModelDefaultVoiceAndAttribution(t *testing.T) { if capturedConfig.Provider != "gemini" { t.Fatalf("captured Provider = %q, want %q", capturedConfig.Provider, "gemini") } - if capturedConfig.GeminiVoice != "" { - t.Fatalf("captured GeminiVoice = %q, want empty model-default voice", capturedConfig.GeminiVoice) + if capturedConfig.GeminiVoice != "sentinel-gemini-voice" { + t.Fatalf("captured GeminiVoice = %q, want %q", capturedConfig.GeminiVoice, "sentinel-gemini-voice") } - if capturedConfig.OutputFormat != "wav" { - t.Fatalf("captured OutputFormat = %q, want %q", capturedConfig.OutputFormat, "wav") + if capturedConfig.OutputFormat != "mp3" { + t.Fatalf("captured OutputFormat = %q, want %q", capturedConfig.OutputFormat, "mp3") } if fakeProvider.generateCalls != 1 { t.Fatalf("GenerateAudio() calls = %d, want %d", fakeProvider.generateCalls, 1) } - if !strings.HasSuffix(outputPath, "audio.wav") { - t.Fatalf("outputPath = %q, want a WAV output file", outputPath) + if !strings.HasSuffix(outputPath, "audio.mp3") { + t.Fatalf("outputPath = %q, want an MP3 output file", outputPath) } attrPath := audio.AttributionPath(outputPath) @@ -328,8 +332,8 @@ func TestGenerateAudioUsesGeminiModelDefaultVoiceAndAttribution(t *testing.T) { if !strings.Contains(attribution, "Audio generated by Google Gemini TTS") { t.Fatalf("gemini attribution missing header: %q", attribution) } - if strings.Contains(attribution, "sentinel-gemini-voice") { - t.Fatalf("gemini attribution should not use the shared voice list when voice is unset: %q", attribution) + if !strings.Contains(attribution, "sentinel-gemini-voice") { + t.Fatalf("gemini attribution should use the selected random Gemini voice: %q", attribution) } if !strings.Contains(attribution, "Processed text sent to TTS: ябълка...") { t.Fatalf("gemini attribution missing processed text: %q", attribution) @@ -340,13 +344,13 @@ func TestGenerateAudioUsesGeminiModelDefaultVoiceAndAttribution(t *testing.T) { t.Fatalf("expected metadata file: %v", err) } metadata := string(metadataData) - if !strings.Contains(metadata, "audio_file=audio.wav") { + if !strings.Contains(metadata, "audio_file=audio.mp3") { t.Fatalf("gemini metadata missing fresh audio file reference: %q", metadata) } - if !strings.Contains(metadata, "voice=model-default") { - t.Fatalf("gemini metadata missing model-default voice marker: %q", metadata) + if !strings.Contains(metadata, "voice=sentinel-gemini-voice") { + t.Fatalf("gemini metadata missing selected random voice: %q", metadata) } - if !strings.Contains(metadata, "format=wav") { + if !strings.Contains(metadata, "format=mp3") { t.Fatalf("gemini metadata missing format: %q", metadata) } if !strings.Contains(metadata, "cardtype=en-bg") { @@ -354,6 +358,61 @@ func TestGenerateAudioUsesGeminiModelDefaultVoiceAndAttribution(t *testing.T) { } } +func TestGenerateGeminiAudioWithFallbacksRetriesAlternateVoice(t *testing.T) { + originalFactory := newAudioProvider + t.Cleanup(func() { + newAudioProvider = originalFactory + }) + + originalVoices := append([]string(nil), audio.GeminiVoices...) + t.Cleanup(func() { + audio.GeminiVoices = originalVoices + }) + audio.GeminiVoices = []string{"Charon", "Kore", "Leda"} + + var attemptedVoices []string + newAudioProvider = func(config *audio.Config) (audio.Provider, error) { + attemptedVoices = append(attemptedVoices, config.GeminiVoice) + return &fakeAudioProvider{ + generateFunc: func(_ string, _ string) error { + if config.GeminiVoice == "Charon" { + return audio.ErrGeminiNoAudioData + } + return nil + }, + }, nil + } + + tempDir := t.TempDir() + outputPath := filepath.Join(tempDir, "audio.wav") + app := &Application{ + config: &Config{ + OutputDir: tempDir, + AudioFormat: "wav", + }, + audioConfig: &audio.Config{ + Provider: "gemini", + OutputDir: tempDir, + GoogleAPIKey: "google-key", + GeminiTTSModel: "gemini-2.5-flash-preview-tts", + }, + } + + voice, err := app.generateGeminiAudioWithFallbacks("Charon", func(candidate string) error { + return app.generateAudioFile(context.Background(), "ябълка", outputPath, candidate, 1.0) + }) + if err != nil { + t.Fatalf("generateGeminiAudioWithFallbacks() unexpected error: %v", err) + } + + if voice != "Kore" { + t.Fatalf("final voice = %q, want %q", voice, "Kore") + } + if got, want := strings.Join(attemptedVoices, ","), "Charon,Kore"; got != want { + t.Fatalf("attempted voices = %q, want %q", got, want) + } +} + func TestGenerateAudioBgBgUsesSharedOpenAIVoices(t *testing.T) { originalFactory := newAudioProvider t.Cleanup(func() { |
