diff options
Diffstat (limited to 'internal/aitool/dispatch_test.go')
| -rw-r--r-- | internal/aitool/dispatch_test.go | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/internal/aitool/dispatch_test.go b/internal/aitool/dispatch_test.go new file mode 100644 index 0000000..6842668 --- /dev/null +++ b/internal/aitool/dispatch_test.go @@ -0,0 +1,113 @@ +package aitool + +import ( + "fmt" + "reflect" + "testing" +) + +func TestChain(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + preferred string + want []Tool + }{ + { + name: "default chain when empty", + want: []Tool{ToolOpencode, ToolHexAI, ToolClaude, ToolAmp}, + }, + { + name: "default chain when opencode", + preferred: "opencode", + want: []Tool{ToolOpencode, ToolHexAI, ToolClaude, ToolAmp}, + }, + { + name: "hexai chain", + preferred: "hexai", + want: []Tool{ToolHexAI, ToolClaude, ToolAmp}, + }, + { + name: "claude alias chain", + preferred: "claude-code", + want: []Tool{ToolClaude, ToolAmp}, + }, + { + name: "amp only", + preferred: "amp", + want: []Tool{ToolAmp}, + }, + { + name: "unknown tool", + preferred: "unknown", + want: nil, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + got := Chain(tt.preferred) + if !reflect.DeepEqual(got, tt.want) { + t.Fatalf("Chain(%q) = %#v, want %#v", tt.preferred, got, tt.want) + } + }) + } +} + +func TestFirstAvailable(t *testing.T) { + t.Parallel() + + lookPath := fakeLookPath("claude", "amp") + got := FirstAvailable("", lookPath) + if got != ToolClaude { + t.Fatalf("FirstAvailable() = %q, want %q", got, ToolClaude) + } +} + +func TestFirstAvailable_NoToolsFound(t *testing.T) { + t.Parallel() + + got := FirstAvailable("", fakeLookPath()) + if got != "" { + t.Fatalf("FirstAvailable() = %q, want empty", got) + } +} + +func TestIsAvailable_OpencodeUsesOllamaBinary(t *testing.T) { + t.Parallel() + + if !IsAvailable(ToolOpencode, fakeLookPath("ollama")) { + t.Fatal("expected opencode to be available when ollama exists") + } + + if IsAvailable(ToolOpencode, fakeLookPath("opencode")) { + t.Fatal("expected opencode to be unavailable when only opencode binary exists") + } +} + +func TestAvailableChain_FiltersUnavailableTools(t *testing.T) { + t.Parallel() + + got := AvailableChain("", fakeLookPath("hexai", "amp")) + want := []Tool{ToolHexAI, ToolAmp} + if !reflect.DeepEqual(got, want) { + t.Fatalf("AvailableChain() = %#v, want %#v", got, want) + } +} + +func fakeLookPath(tools ...string) LookPathFunc { + available := make(map[string]struct{}, len(tools)) + for _, tool := range tools { + available[tool] = struct{}{} + } + + return func(file string) (string, error) { + if _, ok := available[file]; ok { + return "/usr/bin/" + file, nil + } + return "", fmt.Errorf("%s not found", file) + } +} |
