129 lines
4.4 KiB
Go
129 lines
4.4 KiB
Go
package agents
|
|
|
|
import (
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestManagedNPMRuntimeContracts(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
agent ManagedNPMRuntimeAgent
|
|
wantPackage string
|
|
wantACPArgs []string
|
|
}{
|
|
{"claude", NewClaudeACP(), "@agentclientprotocol/claude-agent-acp", nil},
|
|
{"codex", NewCodexACP(), "@agentclientprotocol/codex-acp", nil},
|
|
{"opencode", NewOpenCodeACP(), "opencode-ai", []string{"acp", "--print-logs", "--log-level", "ERROR"}},
|
|
{"copilot", NewCopilotACP(), "@github/copilot", []string{"--acp"}},
|
|
{"gemini", NewGemini(), "@google/gemini-cli", []string{"--acp"}},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
spec := tt.agent.ManagedNPMRuntime()
|
|
if got := spec.Package; got != tt.wantPackage {
|
|
t.Fatalf("Package = %q, want %q", got, tt.wantPackage)
|
|
}
|
|
if got := spec.ACPArgs; !slices.Equal(got, tt.wantACPArgs) {
|
|
t.Fatalf("ACPArgs = %#v, want %#v", got, tt.wantACPArgs)
|
|
}
|
|
|
|
cached := spec.CachedACPCommand()
|
|
wantCached := append([]string{"npx", "--yes", "--prefer-offline", tt.wantPackage}, tt.wantACPArgs...)
|
|
if !slices.Equal(cached.Args(), wantCached) {
|
|
t.Fatalf("CachedACPCommand = %#v, want %#v", cached.Args(), wantCached)
|
|
}
|
|
assertUnversionedPackage(t, cached.Args(), tt.wantPackage)
|
|
|
|
update := spec.CacheUpdateCommand()
|
|
wantUpdate := []string{
|
|
"npm", "exec", "--yes", "--prefer-online",
|
|
"--package=" + tt.wantPackage, "--", "node", "-e", "",
|
|
}
|
|
if !slices.Equal(update.Args(), wantUpdate) {
|
|
t.Fatalf("CacheUpdateCommand = %#v, want %#v", update.Args(), wantUpdate)
|
|
}
|
|
if strings.Contains(strings.Join(update.Args(), " "), "latest") {
|
|
t.Fatalf("CacheUpdateCommand contains explicit latest: %#v", update.Args())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestManagedNPMRuntimeExecutionCacheKeyMatchesNPM(t *testing.T) {
|
|
spec := ManagedNPMRuntimeSpec{Package: "opencode-ai"}
|
|
if got := spec.ExecutionCacheKey(); got != "e2094862b59aac7b" {
|
|
t.Fatalf("ExecutionCacheKey = %q, want npm key e2094862b59aac7b", got)
|
|
}
|
|
}
|
|
|
|
func TestManagedNPMRuntimeBuildsExactVersionCommandsAndCacheKey(t *testing.T) {
|
|
spec := ManagedNPMRuntimeSpec{
|
|
Package: "opencode-ai",
|
|
ACPArgs: []string{"acp", "--print-logs"},
|
|
}
|
|
wantACP := []string{"npx", "--yes", "--prefer-offline", "opencode-ai@1.18.5", "acp", "--print-logs"}
|
|
if got := spec.ACPCommand("1.18.5").Args(); !slices.Equal(got, wantACP) {
|
|
t.Fatalf("ACPCommand = %#v, want %#v", got, wantACP)
|
|
}
|
|
wantUpdate := []string{
|
|
"npm", "exec", "--yes", "--prefer-online",
|
|
"--package=opencode-ai@1.18.5", "--", "node", "-e", "",
|
|
}
|
|
if got := spec.CacheUpdateCommand("1.18.5").Args(); !slices.Equal(got, wantUpdate) {
|
|
t.Fatalf("CacheUpdateCommand = %#v, want %#v", got, wantUpdate)
|
|
}
|
|
if got := spec.ExecutionCacheKey("1.18.5"); got != "cd439a892fc193b3" {
|
|
t.Fatalf("versioned ExecutionCacheKey = %q, want cd439a892fc193b3", got)
|
|
}
|
|
}
|
|
|
|
func TestManagedNPMRuntimeExactVersionSupportsScopedPackages(t *testing.T) {
|
|
spec := ManagedNPMRuntimeSpec{Package: "@scope/managed-acp", ACPArgs: []string{"--acp"}}
|
|
want := []string{"npx", "--yes", "--prefer-offline", "@scope/managed-acp@3.4.5", "--acp"}
|
|
if got := spec.ACPCommand("3.4.5").Args(); !slices.Equal(got, want) {
|
|
t.Fatalf("scoped ACPCommand = %#v, want %#v", got, want)
|
|
}
|
|
if spec.ExecutionCacheKey("3.4.5") == spec.ExecutionCacheKey() {
|
|
t.Fatal("versioned scoped cache key equals legacy key")
|
|
}
|
|
}
|
|
|
|
func TestManagedAgentsHonorExactVersionCommandOption(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
agent ManagedNPMRuntimeAgent
|
|
}{
|
|
{"claude", NewClaudeACP()},
|
|
{"codex", NewCodexACP()},
|
|
{"opencode", NewOpenCodeACP()},
|
|
{"copilot", NewCopilotACP()},
|
|
{"gemini", NewGemini()},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
version := "1.2.3"
|
|
want := tt.agent.ManagedNPMRuntime().ACPCommand(version).Args()
|
|
got := tt.agent.(interface {
|
|
BuildCommand(CommandOptions) Command
|
|
}).BuildCommand(CommandOptions{ManagedRuntimeVersion: version}).Args()
|
|
if !slices.Equal(got, want) {
|
|
t.Fatalf("exact BuildCommand = %#v, want %#v", got, want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func assertUnversionedPackage(t *testing.T, argv []string, wantPackage string) {
|
|
t.Helper()
|
|
packageArg := argv[3]
|
|
if packageArg != wantPackage {
|
|
t.Fatalf("package argv = %q, want unversioned %q", packageArg, wantPackage)
|
|
}
|
|
if packageArg == wantPackage+"@latest" {
|
|
t.Fatalf("package argv contains explicit latest: %q", packageArg)
|
|
}
|
|
}
|