diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-02 17:37:20 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-02 17:37:20 +0300 |
| commit | 1fc2ade33b72dd299fc987943ddd09dee7c609ad (patch) | |
| tree | 6c7df87f1c39abde92ee05707ad3ad1a03e7b3e9 /internal | |
| parent | f3b5f58a171eeb47716e2d15a40c4c480d2d5ef9 (diff) | |
task 002: restore Gemini fallback output and add failure coverage
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/audio/fallbacks.go | 1 | ||||
| -rw-r--r-- | internal/audio/voices_test.go | 20 | ||||
| -rw-r--r-- | internal/processor/processor_test.go | 42 |
3 files changed, 62 insertions, 1 deletions
diff --git a/internal/audio/fallbacks.go b/internal/audio/fallbacks.go index bd0c86e..0c3ed83 100644 --- a/internal/audio/fallbacks.go +++ b/internal/audio/fallbacks.go @@ -22,7 +22,6 @@ func RunWithVoiceFallbacks(initialVoice string, generate func(voice string) erro } lastErr = err - fmt.Printf("Warning: Gemini returned no audio for voice %s\n", voice) } return "", fmt.Errorf("Gemini returned no audio for voices %s: %w", strings.Join(attempted, ", "), lastErr) diff --git a/internal/audio/voices_test.go b/internal/audio/voices_test.go index 5e940d0..3d936d1 100644 --- a/internal/audio/voices_test.go +++ b/internal/audio/voices_test.go @@ -105,4 +105,24 @@ func TestRunWithVoiceFallbacks(t *testing.T) { t.Fatalf("attempted voices = %#v, want %#v", got, want) } }) + + t.Run("wraps exhausted Gemini voices", func(t *testing.T) { + var attempted []string + usedVoice, err := RunWithVoiceFallbacks("Charon", func(voice string) error { + attempted = append(attempted, voice) + return ErrGeminiNoAudioData + }) + if !errors.Is(err, ErrGeminiNoAudioData) { + t.Fatalf("error = %v, want wrapped ErrGeminiNoAudioData", err) + } + if usedVoice != "" { + t.Fatalf("used voice = %q, want empty", usedVoice) + } + if got, want := attempted, []string{"Charon", "Kore", "Leda"}; !reflect.DeepEqual(got, want) { + t.Fatalf("attempted voices = %#v, want %#v", got, want) + } + if got := err.Error(); got != "Gemini returned no audio for voices Charon, Kore, Leda: no audio data returned from Gemini" { + t.Fatalf("error text = %q, want wrapped attempted-voices summary", got) + } + }) } diff --git a/internal/processor/processor_test.go b/internal/processor/processor_test.go index cd6e2eb..9f59bac 100644 --- a/internal/processor/processor_test.go +++ b/internal/processor/processor_test.go @@ -737,6 +737,48 @@ func TestGenerateGeminiAudioWithFallbacksRetriesAlternateVoice(t *testing.T) { } } +func TestGenerateAudioReturnsExhaustedGeminiFallbackError(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"} + + newAudioProvider = func(*audio.Config) (audio.Provider, error) { + return &fakeAudioProvider{ + generateFunc: func(_ string, _ string) error { + return audio.ErrGeminiNoAudioData + }, + }, nil + } + + originalConfig := viper.New() + *originalConfig = *viper.GetViper() + defer func() { + *viper.GetViper() = *originalConfig + }() + viper.Reset() + viper.Set("audio.provider", "gemini") + + flags := cli.NewFlags() + flags.OutputDir = t.TempDir() + flags.AudioProvider = "gemini" + + p := NewProcessor(flags) + err := p.generateAudio("ябълка") + if !errors.Is(err, audio.ErrGeminiNoAudioData) { + t.Fatalf("generateAudio() error = %v, want wrapped ErrGeminiNoAudioData", err) + } + if got, want := err.Error(), "Gemini returned no audio for voices Charon: no audio data returned from Gemini"; got != want { + t.Fatalf("generateAudio() error text = %q, want %q", got, want) + } +} + func TestGenerateAudioBgBgUsesGeminiModelDefaultWhenVoiceNotSet(t *testing.T) { originalFactory := newAudioProvider t.Cleanup(func() { |
