ai-agent/internal/agent/system_test.go
admin 8dc496b626
Some checks failed
CI / test (push) Has been cancelled
Release / release (push) Failing after 4m36s
first commit
2026-03-08 15:40:34 +07:00

187 lines
6.3 KiB
Go

package agent
import (
"os"
"path/filepath"
"strings"
"testing"
"ai-agent/internal/llm"
"ai-agent/internal/memory"
)
func TestBuildSystemPrompt(t *testing.T) {
tests := []struct {
name string
tools []llm.ToolDef
skillContent string
loadedCtx string
memStore *memory.Store
iceContext string
contains []string
notContains []string
}{
{
name: "no optional sections",
contains: []string{"No tools currently available.", "Current date:"},
notContains: []string{"Active Skills", "Loaded Context", "Remembered Facts"},
},
{
name: "with tools",
tools: []llm.ToolDef{
{Name: "test_tool", Description: "does stuff"},
},
contains: []string{"test_tool", "does stuff"},
notContains: []string{"No tools currently available."},
},
{
name: "with skills",
skillContent: "skill content here",
contains: []string{"Active Skills", "skill content here"},
},
{
name: "with loaded context",
loadedCtx: "some loaded context",
contains: []string{"Loaded Context", "some loaded context"},
},
{
name: "ICE overrides memory",
iceContext: "ice assembled context",
contains: []string{"ice assembled context"},
notContains: []string{"Remembered Facts"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := buildSystemPrompt("", tt.tools, tt.skillContent, tt.loadedCtx, tt.memStore, tt.iceContext, "", "")
for _, want := range tt.contains {
if !strings.Contains(result, want) {
t.Errorf("buildSystemPrompt() missing %q", want)
}
}
for _, notWant := range tt.notContains {
if strings.Contains(result, notWant) {
t.Errorf("buildSystemPrompt() should not contain %q", notWant)
}
}
})
}
t.Run("with memory store entries", func(t *testing.T) {
store := memory.NewStore(filepath.Join(t.TempDir(), "test-memories.json"))
_, _ = store.Save("user prefers dark mode", []string{"preference"})
result := buildSystemPrompt("", nil, "", "", store, "", "", "")
if !strings.Contains(result, "Remembered Facts") {
t.Error("expected Remembered Facts section")
}
if !strings.Contains(result, "user prefers dark mode") {
t.Error("expected memory content in prompt")
}
})
}
func TestBuildSystemPrompt_WithWorkDir(t *testing.T) {
result := buildSystemPrompt("", nil, "", "", nil, "", "/home/user/myproject", "")
if !strings.Contains(result, "Working directory: /home/user/myproject") {
t.Error("expected working directory in prompt")
}
if !strings.Contains(result, "Environment") {
t.Error("expected Environment section header")
}
}
func TestBuildSystemPrompt_EmptyWorkDir(t *testing.T) {
result := buildSystemPrompt("", nil, "", "", nil, "", "", "")
if strings.Contains(result, "Working directory") {
t.Error("should not include working directory when empty")
}
}
func TestBuildSystemPrompt_WithIgnoreContent(t *testing.T) {
ignoreContent := "- node_modules\n- *.log\n- build/"
result := buildSystemPrompt("", nil, "", "", nil, "", "", ignoreContent)
if !strings.Contains(result, "Ignored Paths") {
t.Error("expected Ignored Paths section header")
}
if !strings.Contains(result, "node_modules") {
t.Error("expected node_modules in ignore section")
}
if !strings.Contains(result, "*.log") {
t.Error("expected *.log in ignore section")
}
}
func TestBuildSystemPrompt_EmptyIgnoreContent(t *testing.T) {
result := buildSystemPrompt("", nil, "", "", nil, "", "", "")
if strings.Contains(result, "Ignored Paths") {
t.Error("should not include Ignored Paths when content is empty")
}
}
func TestDetectProjectInfo_GoProject(t *testing.T) {
dir := t.TempDir()
_ = os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module test"), 0o644)
info := detectProjectInfo(dir)
if !strings.Contains(info, "go.mod") {
t.Errorf("expected go.mod in project info, got %q", info)
}
if !strings.Contains(info, "Go module") {
t.Errorf("expected 'Go module' in project info, got %q", info)
}
}
func TestDetectProjectInfo_EmptyDir(t *testing.T) {
dir := t.TempDir()
info := detectProjectInfo(dir)
if info != "" {
t.Errorf("expected empty for dir with no markers, got %q", info)
}
}
func TestBuildMemorySection(t *testing.T) {
tests := []struct {
name string
setup func(s *memory.Store)
contains []string
wantEmpty bool
}{
{
name: "empty store",
setup: func(s *memory.Store) {},
wantEmpty: true,
},
{
name: "store with tagged entry",
setup: func(s *memory.Store) {
_, _ = s.Save("likes Go", []string{"lang", "preference"})
},
contains: []string{"Remembered Facts", "likes Go", "[tags: lang, preference]"},
},
{
name: "store with untagged entry",
setup: func(s *memory.Store) {
_, _ = s.Save("project uses modules", nil)
},
contains: []string{"Remembered Facts", "project uses modules"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
store := memory.NewStore(filepath.Join(t.TempDir(), "mem.json"))
tt.setup(store)
result := buildMemorySection(store)
if tt.wantEmpty {
if result != "" {
t.Errorf("expected empty string, got %q", result)
}
return
}
for _, want := range tt.contains {
if !strings.Contains(result, want) {
t.Errorf("buildMemorySection() missing %q in:\n%s", want, result)
}
}
})
}
}