返回 DeepSeek-Reasonix
reasonix_guide_test.go
根目录 / internal / skill / reasonix_guide_test.go
1 package skill_test
2
3 import (
4 "strings"
5 "testing"
6
7 "reasonix/internal/skill"
8 )
9
10 func TestReasonixGuideBuiltinRegistered(t *testing.T) {
11 store := skill.New(skill.Options{HomeDir: t.TempDir(), DisableBuiltins: false})
12 sk, ok := store.Read("reasonix-guide")
13 if !ok {
14 t.Fatal("reasonix-guide must be registered as a builtin")
15 }
16 if sk.Scope != skill.ScopeBuiltin {
17 t.Fatalf("scope = %s", sk.Scope)
18 }
19 if sk.RunAs != skill.RunInline {
20 t.Fatalf("runAs = %s", sk.RunAs)
21 }
22 if sk.Description == "" {
23 t.Fatal("description required for index line")
24 }
25 if !strings.Contains(sk.Body, "doctor capabilities") {
26 t.Fatal("body missing doctor capabilities guidance")
27 }
28 }
29
30 func TestReasonixGuideIndexLineOnly(t *testing.T) {
31 store := skill.New(skill.Options{HomeDir: t.TempDir()})
32 list := store.List()
33 var guide skill.Skill
34 found := false
35 for _, s := range list {
36 if s.Name == "reasonix-guide" {
37 guide = s
38 found = true
39 break
40 }
41 }
42 if !found {
43 t.Fatal("reasonix-guide missing from List")
44 }
45 if guide.Body != "" {
46 t.Fatal("catalog candidate carried the skill body")
47 }
48 idx := skill.IndexBlock(list)
49 if !strings.Contains(idx, "reasonix-guide") {
50 t.Fatal("index missing reasonix-guide line")
51 }
52 // Body must not appear in the index block.
53 if strings.Contains(idx, "First action") {
54 t.Fatal("skill body leaked into system-prompt index")
55 }
56 // Exactly one index line for the skill name.
57 if c := strings.Count(idx, "- reasonix-guide"); c != 1 {
58 t.Fatalf("index lines for reasonix-guide = %d, want 1", c)
59 }
60 }
61
62 func TestReasonixGuideOverriddenByProject(t *testing.T) {
63 home := t.TempDir()
64 root := t.TempDir()
65 store := skill.New(skill.Options{HomeDir: home, ProjectRoot: root})
66 // Create project override.
67 path, err := store.CreateWithContent("reasonix-guide", skill.ScopeProject, "---\ndescription: override\nrunAs: inline\n---\nproject body\n")
68 if err != nil {
69 t.Fatal(err)
70 }
71 _ = path
72 store2 := skill.New(skill.Options{HomeDir: home, ProjectRoot: root})
73 sk, ok := store2.Read("reasonix-guide")
74 if !ok {
75 t.Fatal("expected override")
76 }
77 if sk.Scope != skill.ScopeProject {
78 t.Fatalf("scope = %s, want project", sk.Scope)
79 }
80 if !strings.Contains(sk.Body, "project body") {
81 t.Fatalf("body = %q", sk.Body)
82 }
83 }
84
85 func TestReasonixGuideDisabled(t *testing.T) {
86 store := skill.New(skill.Options{
87 HomeDir: t.TempDir(),
88 DisabledNames: []string{"reasonix-guide"},
89 })
90 if _, ok := store.Read("reasonix-guide"); ok {
91 t.Fatal("disabled builtin should not be readable")
92 }
93 for _, s := range store.List() {
94 if s.Name == "reasonix-guide" {
95 t.Fatal("disabled builtin should not be listed")
96 }
97 }
98 }
99
100 func TestReasonixGuideIndexStableAcrossCalls(t *testing.T) {
101 store := skill.New(skill.Options{HomeDir: t.TempDir()})
102 a := skill.IndexBlock(store.List())
103 b := skill.IndexBlock(store.List())
104 if a != b {
105 t.Fatal("skills index not byte-stable across List calls")
106 }
107 }
108
108 lines GO