aboutsummaryrefslogtreecommitdiffstats
path: root/skills_test.go
blob: eedf8ae18da666d1a203c6769a9ba55bc8f65911 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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)
	}
}