Files
sherlock/internal/agent/custom_test.go
T
Alexandru Macocian 84958c7ef3
Release / release (push) Successful in 17s
Support for local agents
2026-06-15 19:03:56 +02:00

108 lines
3.1 KiB
Go

package agent
import (
"os"
"slices"
"strings"
"testing"
)
func TestRegisterCustom_CopilotBackendSpawn(t *testing.T) {
fakeBin := makeFakeBinary(t, "copilot-local")
t.Setenv("PATH", fakeBin+":"+os.Getenv("PATH"))
t.Setenv("XDG_RUNTIME_DIR", t.TempDir())
if err := RegisterCustom("copilot-local", "copilot-local", "copilot"); err != nil {
t.Fatalf("RegisterCustom: %v", err)
}
t.Cleanup(func() { delete(registry, "copilot-local") })
a, ok := Get("copilot-local")
if !ok {
t.Fatal("custom agent not registered")
}
orig := DefaultExecer
defer func() { DefaultExecer = orig }()
rec := &recordExecer{}
DefaultExecer = rec
if err := a.Spawn(Context{}, []string{"-p", "hi"}); err != nil {
t.Fatalf("Spawn: %v", err)
}
if !strings.HasSuffix(rec.argv0, "/copilot-local") {
t.Fatalf("argv0 = %s", rec.argv0)
}
// Copilot backend formatting: --additional-mcp-config @<path>.
if !slices.Contains(rec.argv, "--additional-mcp-config") {
t.Fatalf("argv missing copilot mcp flag: %v", rec.argv)
}
foundAt := false
for _, a := range rec.argv {
if strings.HasPrefix(a, "@") && strings.HasSuffix(a, "/copilot-local.mcp.json") {
foundAt = true
}
}
if !foundAt {
t.Fatalf("argv missing @-prefixed mcp path named after the custom agent: %v", rec.argv)
}
}
func TestRegisterCustom_ClaudeBackendForbidsKeyAndDefaultsCommand(t *testing.T) {
fakeBin := makeFakeBinary(t, "claude-local")
t.Setenv("PATH", fakeBin+":"+os.Getenv("PATH"))
t.Setenv("ANTHROPIC_API_KEY", "leaked")
t.Setenv("XDG_RUNTIME_DIR", t.TempDir())
// Empty command must default to the agent name.
if err := RegisterCustom("claude-local", "", "claude"); err != nil {
t.Fatalf("RegisterCustom: %v", err)
}
t.Cleanup(func() { delete(registry, "claude-local") })
orig := DefaultExecer
defer func() { DefaultExecer = orig }()
rec := &recordExecer{}
DefaultExecer = rec
a, _ := Get("claude-local")
if err := a.Spawn(Context{}, nil); err != nil {
t.Fatalf("Spawn: %v", err)
}
if !strings.HasSuffix(rec.argv0, "/claude-local") {
t.Fatalf("argv0 should default to the agent name: %s", rec.argv0)
}
if !slices.Contains(rec.argv, "--mcp-config") {
t.Fatalf("argv missing claude mcp flag: %v", rec.argv)
}
if hasEnv(rec.env, "ANTHROPIC_API_KEY") {
t.Fatal("ANTHROPIC_API_KEY leaked to claude-backed custom agent")
}
}
func TestRegisterCustom_UnknownBackend(t *testing.T) {
err := RegisterCustom("weird", "weird", "gemini")
if err == nil {
t.Fatal("expected error for unknown backend")
}
if !strings.Contains(err.Error(), "gemini") {
t.Fatalf("error should mention the bad backend: %v", err)
}
if _, ok := Get("weird"); ok {
t.Fatal("agent with bad backend should not be registered")
}
}
func TestRegisterCustom_NameCollision(t *testing.T) {
// "copilot" is a built-in; a custom agent must not clobber it.
if err := RegisterCustom("copilot", "copilot-local", "copilot"); err == nil {
t.Fatal("expected error on collision with built-in agent")
}
}
func TestRegisterCustom_EmptyName(t *testing.T) {
if err := RegisterCustom("", "cmd", "copilot"); err == nil {
t.Fatal("expected error for empty name")
}
}