feat: fanalize straeming adapters

This commit is contained in:
leonardotrapani
2026-02-01 17:53:48 +01:00
parent 8df3021a9d
commit 0025bf97b6
23 changed files with 489 additions and 644 deletions
+20 -201
View File
@@ -1984,16 +1984,13 @@ func TestConfig_ToTranscriberConfig_Threads(t *testing.T) {
}
}
func TestConfig_EffectiveLanguage(t *testing.T) {
t.Run("only general.language set", func(t *testing.T) {
func TestConfig_TranscriptionLanguage(t *testing.T) {
t.Run("language set in transcription", func(t *testing.T) {
config := &Config{
General: GeneralConfig{
Language: "es",
},
Transcription: TranscriptionConfig{
Provider: "openai",
Model: "whisper-1",
Language: "", // not set
Language: "es",
},
}
@@ -2003,29 +2000,8 @@ func TestConfig_EffectiveLanguage(t *testing.T) {
}
})
t.Run("transcription.language overrides general.language", func(t *testing.T) {
t.Run("empty language results in auto-detect", func(t *testing.T) {
config := &Config{
General: GeneralConfig{
Language: "es",
},
Transcription: TranscriptionConfig{
Provider: "openai",
Model: "whisper-1",
Language: "en", // overrides general
},
}
transcriberConfig := config.ToTranscriberConfig()
if transcriberConfig.Language != "en" {
t.Errorf("Language = %q, want %q", transcriberConfig.Language, "en")
}
})
t.Run("neither set results in auto", func(t *testing.T) {
config := &Config{
General: GeneralConfig{
Language: "",
},
Transcription: TranscriptionConfig{
Provider: "openai",
Model: "whisper-1",
@@ -2040,7 +2016,7 @@ func TestConfig_EffectiveLanguage(t *testing.T) {
})
}
func TestConfig_Validate_GeneralLanguage(t *testing.T) {
func TestConfig_Validate_TranscriptionLanguage(t *testing.T) {
baseConfig := func() *Config {
return &Config{
Recording: RecordingConfig{
@@ -2066,63 +2042,46 @@ func TestConfig_Validate_GeneralLanguage(t *testing.T) {
}
}
t.Run("valid general.language passes validation", func(t *testing.T) {
t.Run("valid transcription.language passes validation", func(t *testing.T) {
config := baseConfig()
config.General.Language = "es"
config.Transcription.Language = "es"
err := config.Validate()
if err != nil {
t.Errorf("Validate() should pass with valid general.language: %v", err)
t.Errorf("Validate() should pass with valid transcription.language: %v", err)
}
})
t.Run("general.language validated against model", func(t *testing.T) {
t.Run("transcription.language validated against model", func(t *testing.T) {
config := baseConfig()
config.General.Language = "es"
config.Transcription.Language = "es" // incompatible
config.Transcription.Provider = "whisper-cpp"
config.Transcription.Model = "base.en" // english-only model
err := config.Validate()
if err == nil {
t.Error("Validate() should fail when general.language incompatible with model")
t.Error("Validate() should fail when transcription.language incompatible with model")
}
if err != nil && !strings.Contains(err.Error(), "does not support Spanish") {
t.Errorf("error should mention Spanish, got: %v", err)
}
})
t.Run("transcription.language override validated against model", func(t *testing.T) {
t.Run("compatible language passes", func(t *testing.T) {
config := baseConfig()
config.General.Language = "en" // compatible
config.Transcription.Language = "es" // override with incompatible
config.Transcription.Provider = "whisper-cpp"
config.Transcription.Model = "base.en" // english-only model
err := config.Validate()
if err == nil {
t.Error("Validate() should fail when transcription.language override is incompatible")
}
if err != nil && !strings.Contains(err.Error(), "does not support Spanish") {
t.Errorf("error should mention Spanish, got: %v", err)
}
})
t.Run("valid override with compatible language", func(t *testing.T) {
config := baseConfig()
config.General.Language = "es" // would be incompatible
config.Transcription.Language = "en" // override with compatible
config.Transcription.Language = "en" // compatible
config.Transcription.Provider = "whisper-cpp"
config.Transcription.Model = "base.en" // english-only model
err := config.Validate()
if err != nil {
t.Errorf("Validate() should pass when transcription.language override is compatible: %v", err)
t.Errorf("Validate() should pass when transcription.language is compatible: %v", err)
}
})
t.Run("auto language always passes", func(t *testing.T) {
config := baseConfig()
config.General.Language = "" // auto
config.Transcription.Language = "" // auto
config.Transcription.Provider = "whisper-cpp"
config.Transcription.Model = "base.en" // english-only model
@@ -2133,8 +2092,8 @@ func TestConfig_Validate_GeneralLanguage(t *testing.T) {
})
}
func TestConfig_MigrateLanguageToGeneral(t *testing.T) {
t.Run("old config with transcription.language migrates to general.language", func(t *testing.T) {
func TestConfig_LoadWithTranscriptionLanguage(t *testing.T) {
t.Run("config with transcription.language loads correctly", func(t *testing.T) {
tempDir := t.TempDir()
configPath := filepath.Join(tempDir, "hyprvoice", "config.toml")
@@ -2143,77 +2102,7 @@ func TestConfig_MigrateLanguageToGeneral(t *testing.T) {
t.Fatalf("Failed to create config directory: %v", err)
}
// Old config with language in transcription section
oldConfig := `[recording]
sample_rate = 16000
channels = 1
format = "s16"
buffer_size = 8192
channel_buffer_size = 30
timeout = "5m"
[transcription]
provider = "openai"
api_key = "test-key"
model = "whisper-1"
language = "es"
[injection]
backends = ["clipboard"]
ydotool_timeout = "5s"
wtype_timeout = "5s"
clipboard_timeout = "3s"
[notifications]
type = "log"`
err = os.WriteFile(configPath, []byte(oldConfig), 0644)
if err != nil {
t.Fatalf("Failed to create config file: %v", err)
}
originalConfigDir := os.Getenv("XDG_CONFIG_HOME")
os.Setenv("XDG_CONFIG_HOME", tempDir)
defer func() {
if originalConfigDir == "" {
os.Unsetenv("XDG_CONFIG_HOME")
} else {
os.Setenv("XDG_CONFIG_HOME", originalConfigDir)
}
}()
config, err := Load()
if err != nil {
t.Errorf("Load() error = %v", err)
return
}
// Should have migrated to general.language
if config.General.Language != "es" {
t.Errorf("Expected general.language='es' after migration, got %q", config.General.Language)
}
// Effective language should be 'es'
transcriberConfig := config.ToTranscriberConfig()
if transcriberConfig.Language != "es" {
t.Errorf("Expected effective language 'es', got %q", transcriberConfig.Language)
}
})
t.Run("migration does not run when general.language already set", func(t *testing.T) {
tempDir := t.TempDir()
configPath := filepath.Join(tempDir, "hyprvoice", "config.toml")
err := os.MkdirAll(filepath.Dir(configPath), 0755)
if err != nil {
t.Fatalf("Failed to create config directory: %v", err)
}
// Config with both general.language and transcription.language set
configContent := `[general]
language = "fr"
[recording]
configContent := `[recording]
sample_rate = 16000
channels = 1
format = "s16"
@@ -2257,80 +2146,10 @@ type = "log"`
return
}
// general.language should remain 'fr', not overwritten by migration
if config.General.Language != "fr" {
t.Errorf("Expected general.language='fr' (not migrated), got %q", config.General.Language)
}
// transcription.language should still override
// Effective language should be 'es'
transcriberConfig := config.ToTranscriberConfig()
if transcriberConfig.Language != "es" {
t.Errorf("Expected effective language 'es' (transcription override), got %q", transcriberConfig.Language)
}
})
t.Run("original file not modified until explicit save", func(t *testing.T) {
tempDir := t.TempDir()
configPath := filepath.Join(tempDir, "hyprvoice", "config.toml")
err := os.MkdirAll(filepath.Dir(configPath), 0755)
if err != nil {
t.Fatalf("Failed to create config directory: %v", err)
}
oldConfig := `[recording]
sample_rate = 16000
channels = 1
format = "s16"
buffer_size = 8192
channel_buffer_size = 30
timeout = "5m"
[transcription]
provider = "openai"
api_key = "test-key"
model = "whisper-1"
language = "de"
[injection]
backends = ["clipboard"]
ydotool_timeout = "5s"
wtype_timeout = "5s"
clipboard_timeout = "3s"
[notifications]
type = "log"`
err = os.WriteFile(configPath, []byte(oldConfig), 0644)
if err != nil {
t.Fatalf("Failed to create config file: %v", err)
}
originalConfigDir := os.Getenv("XDG_CONFIG_HOME")
os.Setenv("XDG_CONFIG_HOME", tempDir)
defer func() {
if originalConfigDir == "" {
os.Unsetenv("XDG_CONFIG_HOME")
} else {
os.Setenv("XDG_CONFIG_HOME", originalConfigDir)
}
}()
_, err = Load()
if err != nil {
t.Errorf("Load() error = %v", err)
return
}
// Read the file again - should still have old format
content, err := os.ReadFile(configPath)
if err != nil {
t.Fatalf("Failed to read config file: %v", err)
}
// File should NOT have [general] section (migration is in-memory only)
if strings.Contains(string(content), "[general]") {
t.Error("Original file should not be modified by migration - [general] section found")
t.Errorf("Expected effective language 'es', got %q", transcriberConfig.Language)
}
})
}