diff options
| author | Simen A. W. Olsen <hello@simenandre.no> | 2026-10-25 12:41:28 +0100 |
|---|---|---|
| committer | Simen A. W. Olsen <hello@simenandre.no> | 2026-10-25 12:41:28 +0100 |
| commit | c596038adc7cdbd64988e61fee856d533b58c25d (patch) | |
| tree | a02fde25835416d143ff56b807e640f6a7e9cf82 /skills_test.go | |
| download | skills-0.1.0.tar.gz skills-0.1.0.zip | |
Diffstat (limited to 'skills_test.go')
| -rw-r--r-- | skills_test.go | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/skills_test.go b/skills_test.go new file mode 100644 index 0000000..eedf8ae --- /dev/null +++ b/skills_test.go @@ -0,0 +1,95 @@ +package main + +import ( + "os" + "path/filepath" + "testing" +) + +func TestParseSpec(t *testing.T) { + for in, want := range map[string]Spec{ + "anthropics/skills": {URL: "https://github.com/anthropics/skills"}, + "github:anthropics/skills#main": {URL: "https://github.com/anthropics/skills", Ref: "main"}, + "git@example.com:me/skills.git#v1": {URL: "ssh://git@example.com/me/skills.git", Ref: "v1"}, + "example.com:skills": {URL: "ssh://example.com/skills"}, + "https://example.com/skills.git/": {URL: "https://example.com/skills.git"}, + "git+https://example.com/skills": {URL: "https://example.com/skills"}, + "/srv/skills": {URL: "file:///srv/skills"}, + } { + got, err := parseSpec(in) + if err != nil || got != want { + t.Errorf("parseSpec(%q) = %+v, %v; want %+v", in, got, err, want) + } + } + for _, in := range []string{"", "#main", "skills", "a/b/c"} { + if _, err := parseSpec(in); err == nil { + t.Errorf("parseSpec(%q) succeeded, want an error", in) + } + } +} + +func TestFrontmatter(t *testing.T) { + fm := frontmatter([]byte("---\nname: \"deploy\"\ndescription: Ship it: now\nmetadata:\n name: nested\n---\n# body\nname: no\n")) + if fm["name"] != "deploy" || fm["description"] != "Ship it: now" { + t.Errorf("frontmatter = %v", fm) + } + if fm := frontmatter([]byte("# no front matter\n")); len(fm) != 0 { + t.Errorf("frontmatter without front matter = %v", fm) + } +} + +func TestDiscover(t *testing.T) { + root := t.TempDir() + write(t, root, "skills/pdf/SKILL.md", "---\nname: pdf\n---\n") + write(t, root, "skills/pdf/nested/SKILL.md", "---\nname: inner\n---\n") + write(t, root, "deploy/SKILL.md", "no front matter\n") + write(t, root, ".hidden/SKILL.md", "---\nname: hidden\n---\n") + + got, err := discover(root) + if err != nil { + t.Fatal(err) + } + if len(got) != 2 || got[0].Name != "deploy" || got[1].Name != "pdf" || got[1].Path != "skills/pdf" { + t.Errorf("discover = %+v", got) + } + + write(t, root, "other/SKILL.md", "---\nname: pdf\n---\n") + if _, err := discover(root); err == nil { + t.Error("discover allowed two skills named pdf") + } +} + +func TestLink(t *testing.T) { + t.Setenv("XDG_DATA_HOME", t.TempDir()) + checkout := filepath.Join(dataDir(), "checkouts", "repo", "rev") + write(t, checkout, "pdf/SKILL.md", "") + write(t, checkout, "xlsx/SKILL.md", "") + a := agent{Name: "claude", Home: t.TempDir()} + write(t, a.skillsDir(), "mine/SKILL.md", "") + ws := &workspace{} + + dirs := map[string]string{"pdf": filepath.Join(checkout, "pdf"), "xlsx": filepath.Join(checkout, "xlsx")} + if changes, conflicts, err := ws.link(dirs, []agent{a}); err != nil || len(changes) != 2 || len(conflicts) != 0 { + t.Fatalf("link = %v, %v, %v", changes, conflicts, err) + } + delete(dirs, "xlsx") + dirs["mine"] = filepath.Join(checkout, "pdf") + changes, conflicts, err := ws.link(dirs, []agent{a}) + if err != nil || len(changes) != 1 || changes[0].Action != "removed" || len(conflicts) != 1 { + t.Fatalf("relink = %v, %v, %v", changes, conflicts, err) + } + if _, err := os.Stat(filepath.Join(a.skillsDir(), "mine", "SKILL.md")); err != nil { + t.Errorf("link touched a skill it did not install: %v", err) + } +} + +func write(t *testing.T, root, rel, content string) { + t.Helper() + path := filepath.Join(root, rel) + if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(path, []byte(content), 0o644); err != nil { + t.Fatal(err) + } +} |
