package cli import ( "reflect" "testing" "codeberg.org/snonux/totalrecall/internal/audio" ) func TestNewFlags(t *testing.T) { flags := NewFlags() // Test default values tests := []struct { name string got interface{} expected interface{} }{ {"AudioFormat", flags.AudioFormat, audio.DefaultProviderConfig().OutputFormat}, {"AudioFormatSpecified", flags.AudioFormatSpecified, false}, {"AudioProvider", flags.AudioProvider, audio.DefaultProviderConfig().Provider}, {"ImageAPI", flags.ImageAPI, "nanobanana"}, {"ImageAPISpecified", flags.ImageAPISpecified, false}, {"NanoBananaModelSpecified", flags.NanoBananaModelSpecified, false}, {"NanoBananaTextModelSpecified", flags.NanoBananaTextModelSpecified, false}, {"DeckName", flags.DeckName, "Bulgarian Vocabulary"}, {"OpenAIModel", flags.OpenAIModel, "gpt-4o-mini-tts"}, {"OpenAISpeed", flags.OpenAISpeed, 0.9}, {"OpenAIImageModel", flags.OpenAIImageModel, "dall-e-2"}, {"OpenAIImageSize", flags.OpenAIImageSize, "512x512"}, {"OpenAIImageQuality", flags.OpenAIImageQuality, "standard"}, {"OpenAIImageStyle", flags.OpenAIImageStyle, "natural"}, {"GeminiTTSModel", flags.GeminiTTSModel, audio.DefaultProviderConfig().GeminiTTSModel}, {"GeminiVoice", flags.GeminiVoice, ""}, {"NanoBananaModel", flags.NanoBananaModel, "gemini-3.1-flash-image-preview"}, {"NanoBananaTextModel", flags.NanoBananaTextModel, "gemini-2.5-flash"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if !reflect.DeepEqual(tt.got, tt.expected) { t.Errorf("%s = %v, want %v", tt.name, tt.got, tt.expected) } }) } // Test boolean defaults (should be false) boolTests := []struct { name string value bool }{ {"SkipAudio", flags.SkipAudio}, {"SkipImages", flags.SkipImages}, {"RetryFailedAssets", flags.RetryFailedAssets}, {"GenerateAnki", flags.GenerateAnki}, {"AnkiCSV", flags.AnkiCSV}, {"ListModels", flags.ListModels}, {"AllVoices", flags.AllVoices}, {"NoAutoPlay", flags.NoAutoPlay}, } for _, tt := range boolTests { t.Run(tt.name, func(t *testing.T) { if tt.value != false { t.Errorf("%s = %v, want false", tt.name, tt.value) } }) } // Test string defaults (should be empty) stringTests := []struct { name string value string }{ {"CfgFile", flags.CfgFile}, {"OutputDir", flags.OutputDir}, {"BatchFile", flags.BatchFile}, {"OpenAIVoice", flags.OpenAIVoice}, {"OpenAIInstruction", flags.OpenAIInstruction}, } for _, tt := range stringTests { t.Run(tt.name, func(t *testing.T) { if tt.value != "" { t.Errorf("%s = %v, want empty string", tt.name, tt.value) } }) } } func TestFlagsStructure(t *testing.T) { // Test that Flags struct has all expected fields flags := &Flags{} flagsType := reflect.TypeOf(*flags) expectedFields := []string{ "CfgFile", "OutputDir", "AudioFormat", "AudioFormatSpecified", "AudioProvider", "ImageAPI", "ImageAPISpecified", "BatchFile", "SkipAudio", "SkipImages", "RetryFailedAssets", "GenerateAnki", "AnkiCSV", "DeckName", "ListModels", "AllVoices", "NoAutoPlay", "OpenAIModel", "OpenAIVoice", "OpenAISpeed", "OpenAIInstruction", "OpenAIImageModel", "OpenAIImageSize", "OpenAIImageQuality", "OpenAIImageStyle", "GeminiTTSModel", "GeminiVoice", "NanoBananaModel", "NanoBananaModelSpecified", "NanoBananaTextModel", "NanoBananaTextModelSpecified", } for _, fieldName := range expectedFields { t.Run("has_field_"+fieldName, func(t *testing.T) { if _, ok := flagsType.FieldByName(fieldName); !ok { t.Errorf("Flags struct missing field: %s", fieldName) } }) } }