agent/pkg/lib/lib_test.go
Snider ede5d6f561 feat(lib): migrate to Core Embed system with Result returns
- All public functions return core.Result instead of (string, error)
- Mount scopes basedir — no path prefix needed in ReadString calls
- Add Bundle struct replacing (string, map, error) anti-pattern
- listDir takes *core.Embed not embed.FS
- ListTasks/ListPersonas use FS() + BaseDirectory() for WalkDir
- Remove bytes, os, text/template imports
- 22 tests: Prompt, Task, TaskBundle, Flow, Persona, Template,
  List functions, ExtractWorkspace (Good/Bad patterns)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 09:08:35 +00:00

273 lines
5.8 KiB
Go

package lib
import (
"io/fs"
"os"
"path/filepath"
"testing"
)
// --- Prompt ---
func TestPrompt_Good(t *testing.T) {
r := Prompt("coding")
if !r.OK {
t.Fatal("Prompt('coding') returned !OK")
}
if r.Value.(string) == "" {
t.Error("Prompt('coding') returned empty string")
}
}
func TestPrompt_Bad(t *testing.T) {
r := Prompt("nonexistent-slug")
if r.OK {
t.Error("Prompt('nonexistent-slug') should return !OK")
}
}
// --- Task ---
func TestTask_Good_Yaml(t *testing.T) {
r := Task("bug-fix")
if !r.OK {
t.Fatal("Task('bug-fix') returned !OK")
}
if r.Value.(string) == "" {
t.Error("Task('bug-fix') returned empty string")
}
}
func TestTask_Good_Md(t *testing.T) {
r := Task("code/review")
if !r.OK {
t.Fatal("Task('code/review') returned !OK")
}
if r.Value.(string) == "" {
t.Error("Task('code/review') returned empty string")
}
}
func TestTask_Bad(t *testing.T) {
r := Task("nonexistent-slug")
if r.OK {
t.Error("Task('nonexistent-slug') should return !OK")
}
if r.Value != fs.ErrNotExist {
t.Error("Task('nonexistent-slug') should return fs.ErrNotExist")
}
}
// --- TaskBundle ---
func TestTaskBundle_Good(t *testing.T) {
r := TaskBundle("code/review")
if !r.OK {
t.Fatal("TaskBundle('code/review') returned !OK")
}
b := r.Value.(Bundle)
if b.Main == "" {
t.Error("Bundle.Main is empty")
}
if len(b.Files) == 0 {
t.Error("Bundle.Files is empty — expected companion files")
}
}
func TestTaskBundle_Bad(t *testing.T) {
r := TaskBundle("nonexistent")
if r.OK {
t.Error("TaskBundle('nonexistent') should return !OK")
}
}
// --- Flow ---
func TestFlow_Good(t *testing.T) {
r := Flow("go")
if !r.OK {
t.Fatal("Flow('go') returned !OK")
}
if r.Value.(string) == "" {
t.Error("Flow('go') returned empty string")
}
}
// --- Persona ---
func TestPersona_Good(t *testing.T) {
// Use first persona from list to avoid hardcoding
personas := ListPersonas()
if len(personas) == 0 {
t.Skip("no personas found")
}
r := Persona(personas[0])
if !r.OK {
t.Fatalf("Persona(%q) returned !OK", personas[0])
}
if r.Value.(string) == "" {
t.Errorf("Persona(%q) returned empty string", personas[0])
}
}
// --- Template ---
func TestTemplate_Good_Prompt(t *testing.T) {
r := Template("coding")
if !r.OK {
t.Fatal("Template('coding') returned !OK")
}
if r.Value.(string) == "" {
t.Error("Template('coding') returned empty string")
}
}
func TestTemplate_Good_TaskFallback(t *testing.T) {
r := Template("bug-fix")
if !r.OK {
t.Fatal("Template('bug-fix') returned !OK — should fall through to Task")
}
}
func TestTemplate_Bad(t *testing.T) {
r := Template("nonexistent-slug")
if r.OK {
t.Error("Template('nonexistent-slug') should return !OK")
}
}
// --- List Functions ---
func TestListPrompts(t *testing.T) {
prompts := ListPrompts()
if len(prompts) == 0 {
t.Error("ListPrompts() returned empty")
}
}
func TestListTasks(t *testing.T) {
tasks := ListTasks()
if len(tasks) == 0 {
t.Fatal("ListTasks() returned empty")
}
// Verify nested paths are included (e.g., "code/review")
found := false
for _, s := range tasks {
if s == "code/review" {
found = true
break
}
}
if !found {
t.Error("ListTasks() missing nested path 'code/review'")
}
}
func TestListPersonas(t *testing.T) {
personas := ListPersonas()
if len(personas) == 0 {
t.Error("ListPersonas() returned empty")
}
// Should have nested paths like "code/go"
hasNested := false
for _, p := range personas {
if len(p) > 0 && filepath.Dir(p) != "." {
hasNested = true
break
}
}
if !hasNested {
t.Error("ListPersonas() has no nested paths")
}
}
func TestListFlows(t *testing.T) {
flows := ListFlows()
if len(flows) == 0 {
t.Error("ListFlows() returned empty")
}
}
func TestListWorkspaces(t *testing.T) {
workspaces := ListWorkspaces()
if len(workspaces) == 0 {
t.Error("ListWorkspaces() returned empty")
}
}
// --- ExtractWorkspace ---
func TestExtractWorkspace_CreatesFiles(t *testing.T) {
dir := t.TempDir()
data := &WorkspaceData{Repo: "test-repo", Task: "test task"}
err := ExtractWorkspace("default", dir, data)
if err != nil {
t.Fatalf("ExtractWorkspace failed: %v", err)
}
for _, name := range []string{"CODEX.md", "CLAUDE.md", "PROMPT.md", "TODO.md", "CONTEXT.md"} {
path := filepath.Join(dir, name)
if _, err := os.Stat(path); os.IsNotExist(err) {
t.Errorf("expected %s to exist", name)
}
}
}
func TestExtractWorkspace_CreatesSubdirectories(t *testing.T) {
dir := t.TempDir()
data := &WorkspaceData{Repo: "test-repo", Task: "test task"}
err := ExtractWorkspace("default", dir, data)
if err != nil {
t.Fatalf("ExtractWorkspace failed: %v", err)
}
refDir := filepath.Join(dir, ".core", "reference")
if _, err := os.Stat(refDir); os.IsNotExist(err) {
t.Fatalf(".core/reference/ directory not created")
}
axSpec := filepath.Join(refDir, "RFC-025-AGENT-EXPERIENCE.md")
if _, err := os.Stat(axSpec); os.IsNotExist(err) {
t.Errorf("AX spec not extracted: %s", axSpec)
}
entries, err := os.ReadDir(refDir)
if err != nil {
t.Fatalf("failed to read reference dir: %v", err)
}
goFiles := 0
for _, e := range entries {
if filepath.Ext(e.Name()) == ".go" {
goFiles++
}
}
if goFiles == 0 {
t.Error("no .go files in .core/reference/")
}
docsDir := filepath.Join(refDir, "docs")
if _, err := os.Stat(docsDir); os.IsNotExist(err) {
t.Errorf(".core/reference/docs/ not created")
}
}
func TestExtractWorkspace_TemplateSubstitution(t *testing.T) {
dir := t.TempDir()
data := &WorkspaceData{Repo: "my-repo", Task: "fix the bug"}
err := ExtractWorkspace("default", dir, data)
if err != nil {
t.Fatalf("ExtractWorkspace failed: %v", err)
}
content, err := os.ReadFile(filepath.Join(dir, "TODO.md"))
if err != nil {
t.Fatalf("failed to read TODO.md: %v", err)
}
if len(content) == 0 {
t.Error("TODO.md is empty")
}
}