Files
gnoma/internal/skill/registry_test.go

126 lines
3.3 KiB
Go

package skill
import (
"os"
"path/filepath"
"testing"
)
func writeSkillFile(t *testing.T, dir, filename, content string) {
t.Helper()
if err := os.WriteFile(filepath.Join(dir, filename), []byte(content), 0o644); err != nil {
t.Fatalf("writing skill file: %v", err)
}
}
func TestRegistry_LoadDir_SingleFile(t *testing.T) {
dir := t.TempDir()
writeSkillFile(t, dir, "myskill.md", "---\nname: myskill\ndescription: test skill\n---\ndo the thing\n")
reg := NewRegistry()
if err := reg.LoadDir(dir, "user"); err != nil {
t.Fatalf("LoadDir error: %v", err)
}
sk := reg.Get("myskill")
if sk == nil {
t.Fatal("skill not found after LoadDir")
}
if sk.Source != "user" {
t.Errorf("source = %q, want %q", sk.Source, "user")
}
}
func TestRegistry_LoadDir_MissingDir_NoError(t *testing.T) {
reg := NewRegistry()
err := reg.LoadDir("/nonexistent/path/that/does/not/exist", "user")
if err != nil {
t.Errorf("LoadDir on missing dir should not error, got: %v", err)
}
}
func TestRegistry_LoadDir_SkipsNonMarkdown(t *testing.T) {
dir := t.TempDir()
writeSkillFile(t, dir, "skill.md", "---\nname: good\n---\nbody\n")
writeSkillFile(t, dir, "README.txt", "not a skill")
writeSkillFile(t, dir, "config.toml", "[section]\nkey = 1")
reg := NewRegistry()
if err := reg.LoadDir(dir, "user"); err != nil {
t.Fatalf("LoadDir error: %v", err)
}
if len(reg.Names()) != 1 {
t.Errorf("expected 1 skill, got %d: %v", len(reg.Names()), reg.Names())
}
}
func TestRegistry_OverridePrecedence(t *testing.T) {
dir1 := t.TempDir()
dir2 := t.TempDir()
writeSkillFile(t, dir1, "shared.md", "---\nname: shared\ndescription: from dir1\n---\nbody1\n")
writeSkillFile(t, dir2, "shared.md", "---\nname: shared\ndescription: from dir2\n---\nbody2\n")
reg := NewRegistry()
reg.LoadDir(dir1, "user")
reg.LoadDir(dir2, "project")
sk := reg.Get("shared")
if sk == nil {
t.Fatal("skill not found")
}
if sk.Frontmatter.Description != "from dir2" {
t.Errorf("later load should override: got description %q", sk.Frontmatter.Description)
}
if sk.Source != "project" {
t.Errorf("source = %q, want project", sk.Source)
}
}
func TestRegistry_GetUnknown_ReturnsNil(t *testing.T) {
reg := NewRegistry()
if reg.Get("nonexistent") != nil {
t.Error("expected nil for unknown skill")
}
}
func TestRegistry_Names_Sorted(t *testing.T) {
dir := t.TempDir()
writeSkillFile(t, dir, "zebra.md", "---\nname: zebra\n---\nbody\n")
writeSkillFile(t, dir, "alpha.md", "---\nname: alpha\n---\nbody\n")
writeSkillFile(t, dir, "middle.md", "---\nname: middle\n---\nbody\n")
reg := NewRegistry()
reg.LoadDir(dir, "test")
names := reg.Names()
if len(names) != 3 {
t.Fatalf("expected 3 names, got %d", len(names))
}
if names[0] != "alpha" || names[1] != "middle" || names[2] != "zebra" {
t.Errorf("names not sorted: %v", names)
}
}
func TestRegistry_LoadBundled(t *testing.T) {
reg := NewRegistry()
if err := reg.LoadBundled(); err != nil {
t.Fatalf("LoadBundled error: %v", err)
}
if reg.Get("batch") == nil {
t.Error("batch skill not found after LoadBundled")
}
}
func TestRegistry_All_ReturnsCopy(t *testing.T) {
dir := t.TempDir()
writeSkillFile(t, dir, "a.md", "---\nname: aaa\n---\nbody\n")
reg := NewRegistry()
reg.LoadDir(dir, "test")
all := reg.All()
if len(all) != 1 {
t.Fatalf("expected 1, got %d", len(all))
}
}