package tts import ( "testing" ) func TestConfigValidate(t *testing.T) { tests := []struct { name string cfg Config wantErr bool }{ { name: "empty config", cfg: Config{}, wantErr: true, }, { name: "missing URL", cfg: Config{ Voice: "af_heart", }, wantErr: true, }, { name: "missing voice", cfg: Config{ URL: "http://localhost:8880", }, wantErr: true, }, { name: "invalid timeout", cfg: Config{ URL: "http://localhost:8880", Voice: "af_heart", Timeout: "not-a-duration", }, wantErr: true, }, { name: "valid minimal config", cfg: Config{ URL: "http://localhost:8880", Voice: "af_heart", }, wantErr: false, }, { name: "valid config with timeout", cfg: Config{ URL: "http://localhost:8880", Voice: "af_heart", Timeout: "120s", }, wantErr: false, }, { name: "valid config with voice map", cfg: Config{ URL: "http://localhost:8880", Voice: "af_heart", VoiceMap: map[string]string{ "english": "af_heart", "chinese": "zf_xiaobei", }, }, wantErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := tt.cfg.Validate() if (err != nil) != tt.wantErr { t.Errorf( "Validate() error = %v, wantErr %v", err, tt.wantErr, ) } }) } } func TestNewClient(t *testing.T) { tests := []struct { name string cfg Config wantErr bool }{ { name: "invalid config", cfg: Config{}, wantErr: true, }, { name: "valid config without timeout", cfg: Config{ URL: "http://localhost:8880", Voice: "af_heart", }, wantErr: false, }, { name: "valid config with timeout", cfg: Config{ URL: "http://localhost:8880", Voice: "af_heart", Timeout: "90s", }, wantErr: false, }, { name: "valid config with custom voice map", cfg: Config{ URL: "http://localhost:8880", Voice: "af_heart", VoiceMap: map[string]string{ "english": "custom_en", "french": "custom_fr", }, }, wantErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { client, err := NewClient(tt.cfg, nil) if (err != nil) != tt.wantErr { t.Errorf( "NewClient() error = %v, wantErr %v", err, tt.wantErr, ) return } if !tt.wantErr && client == nil { t.Error("NewClient() returned nil client") } }) } } func TestSelectVoice(t *testing.T) { tests := []struct { name string voiceMap map[string]string lang string want string }{ { name: "default map english", voiceMap: nil, lang: "english", want: "af_heart", }, { name: "default map chinese", voiceMap: nil, lang: "chinese", want: "zf_xiaobei", }, { name: "default map japanese", voiceMap: nil, lang: "japanese", want: "jf_alpha", }, { name: "default map unknown language", voiceMap: nil, lang: "klingon", want: "", }, { name: "custom map", voiceMap: map[string]string{ "english": "custom_english", "german": "custom_german", }, lang: "english", want: "custom_english", }, { name: "custom map missing language", voiceMap: map[string]string{ "english": "custom_english", }, lang: "french", want: "", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { cfg := Config{ URL: "http://localhost:8880", Voice: "af_heart", VoiceMap: tt.voiceMap, } client, err := NewClient(cfg, nil) if err != nil { t.Fatalf("NewClient() error = %v", err) } got := client.SelectVoice(tt.lang) if got != tt.want { t.Errorf( "SelectVoice(%q) = %q, want %q", tt.lang, got, tt.want, ) } }) } } func TestDefaultVoiceMap(t *testing.T) { // Verify that DefaultVoiceMap contains expected entries. expected := map[string]string{ "english": "af_heart", "chinese": "zf_xiaobei", "japanese": "jf_alpha", "spanish": "ef_dora", "french": "ff_siwis", "korean": "kf_sarah", } for lang, voice := range expected { if got := defaultVoices[lang]; got != voice { t.Errorf( "DefaultVoiceMap[%q] = %q, want %q", lang, got, voice, ) } } }