package models import "testing" func TestGetAnthropicModelAliases_StaticOnly(t *testing.T) { aliases := GetAnthropicModelAliases([]string{"sonnet-4.6", "opus-4.5"}) if len(aliases) != 2 { t.Fatalf("expected 2 aliases, got %d: %v", len(aliases), aliases) } ids := map[string]string{} for _, a := range aliases { ids[a.ID] = a.Name } if ids["claude-sonnet-4-6"] != "Claude 4.6 Sonnet" { t.Errorf("unexpected name for claude-sonnet-4-6: %s", ids["claude-sonnet-4-6"]) } if ids["claude-opus-4-5"] != "Claude 4.5 Opus" { t.Errorf("unexpected name for claude-opus-4-5: %s", ids["claude-opus-4-5"]) } } func TestGetAnthropicModelAliases_DynamicFallback(t *testing.T) { aliases := GetAnthropicModelAliases([]string{"sonnet-4.7", "opus-5.0-thinking", "gpt-4o"}) ids := map[string]string{} for _, a := range aliases { ids[a.ID] = a.Name } if ids["claude-sonnet-4-7"] != "Sonnet 4.7" { t.Errorf("unexpected name for claude-sonnet-4-7: %s", ids["claude-sonnet-4-7"]) } if ids["claude-opus-5-0-thinking"] != "Opus 5.0 (Thinking)" { t.Errorf("unexpected name for claude-opus-5-0-thinking: %s", ids["claude-opus-5-0-thinking"]) } if _, ok := ids["claude-gpt-4o"]; ok { t.Errorf("gpt-4o should not generate a claude alias") } } func TestGetAnthropicModelAliases_Mixed(t *testing.T) { aliases := GetAnthropicModelAliases([]string{"sonnet-4.6", "opus-4.7", "gpt-4o"}) ids := map[string]string{} for _, a := range aliases { ids[a.ID] = a.Name } // static entry keeps its custom name if ids["claude-sonnet-4-6"] != "Claude 4.6 Sonnet" { t.Errorf("static alias should keep original name, got: %s", ids["claude-sonnet-4-6"]) } // dynamic entry uses auto-generated name if ids["claude-opus-4-7"] != "Opus 4.7" { t.Errorf("dynamic alias name mismatch: %s", ids["claude-opus-4-7"]) } } func TestGetAnthropicModelAliases_UnknownPattern(t *testing.T) { aliases := GetAnthropicModelAliases([]string{"some-unknown-model"}) if len(aliases) != 0 { t.Fatalf("expected 0 aliases for unknown pattern, got %d: %v", len(aliases), aliases) } } func TestResolveToCursorModel_Static(t *testing.T) { tests := []struct { input string want string }{ {"claude-opus-4-6", "opus-4.6"}, {"claude-opus-4.6", "opus-4.6"}, {"claude-sonnet-4-5", "sonnet-4.5"}, {"claude-opus-4-6-thinking", "opus-4.6-thinking"}, } for _, tc := range tests { got := ResolveToCursorModel(tc.input) if got != tc.want { t.Errorf("ResolveToCursorModel(%q) = %q, want %q", tc.input, got, tc.want) } } } func TestResolveToCursorModel_DynamicFallback(t *testing.T) { tests := []struct { input string want string }{ {"claude-opus-4-7", "opus-4.7"}, {"claude-sonnet-5-0", "sonnet-5.0"}, {"claude-opus-4-7-thinking", "opus-4.7-thinking"}, {"claude-sonnet-5-0-thinking", "sonnet-5.0-thinking"}, } for _, tc := range tests { got := ResolveToCursorModel(tc.input) if got != tc.want { t.Errorf("ResolveToCursorModel(%q) = %q, want %q", tc.input, got, tc.want) } } } func TestResolveToCursorModel_Passthrough(t *testing.T) { tests := []string{"sonnet-4.6", "gpt-4o", "custom-model"} for _, input := range tests { got := ResolveToCursorModel(input) if got != input { t.Errorf("ResolveToCursorModel(%q) = %q, want passthrough %q", input, got, input) } } } func TestResolveToCursorModel_Empty(t *testing.T) { if got := ResolveToCursorModel(""); got != "" { t.Errorf("ResolveToCursorModel(\"\") = %q, want empty", got) } if got := ResolveToCursorModel(" "); got != "" { t.Errorf("ResolveToCursorModel(\" \") = %q, want empty", got) } } func TestGenerateDynamicAlias(t *testing.T) { tests := []struct { input string want AnthropicAlias ok bool }{ {"opus-4.7", AnthropicAlias{"claude-opus-4-7", "Opus 4.7"}, true}, {"sonnet-5.0-thinking", AnthropicAlias{"claude-sonnet-5-0-thinking", "Sonnet 5.0 (Thinking)"}, true}, {"gpt-4o", AnthropicAlias{}, false}, {"invalid", AnthropicAlias{}, false}, } for _, tc := range tests { got, ok := generateDynamicAlias(tc.input) if ok != tc.ok { t.Errorf("generateDynamicAlias(%q) ok = %v, want %v", tc.input, ok, tc.ok) continue } if ok && (got.ID != tc.want.ID || got.Name != tc.want.Name) { t.Errorf("generateDynamicAlias(%q) = {%q, %q}, want {%q, %q}", tc.input, got.ID, got.Name, tc.want.ID, tc.want.Name) } } } func TestReverseDynamicAlias(t *testing.T) { tests := []struct { input string want string ok bool }{ {"claude-opus-4-7", "opus-4.7", true}, {"claude-sonnet-5-0-thinking", "sonnet-5.0-thinking", true}, {"claude-opus-4-6", "opus-4.6", true}, {"claude-opus-4.6", "", false}, {"claude-haiku-4-5-20251001", "", false}, {"some-model", "", false}, } for _, tc := range tests { got, ok := reverseDynamicAlias(tc.input) if ok != tc.ok { t.Errorf("reverseDynamicAlias(%q) ok = %v, want %v", tc.input, ok, tc.ok) continue } if ok && got != tc.want { t.Errorf("reverseDynamicAlias(%q) = %q, want %q", tc.input, got, tc.want) } } }