返回 DeepSeek-Reasonix
skillslash_test.go
根目录 / internal / cli / skillslash_test.go
1 package cli
2
3 import (
4 "testing"
5
6 "reasonix/internal/skill"
7 )
8
9 // TestSlashItemsIncludesSkills proves every loaded skill is offered in the slash
10 // menu as "/<name>" (so /init, /explore, … show up), and that typing the prefix
11 // filters to it — the data path behind "type / to see the commands".
12 func TestSlashItemsIncludesSkills(t *testing.T) {
13 m := newTestChatTUI()
14 m.skills = []skill.Skill{
15 {Name: "init", Description: "bootstrap AGENTS.md", RunAs: skill.RunInline},
16 {Name: "explore", Description: "investigate", RunAs: skill.RunSubagent},
17 {Name: "writing-plans", Plugin: "superpowers", Description: "write a plan", RunAs: skill.RunInline},
18 {Name: "writing-plans", Plugin: "toolbox", Description: "write another plan", RunAs: skill.RunInline},
19 }
20
21 got := map[string]bool{}
22 for _, it := range m.slashItems() {
23 got[it.label] = true
24 }
25 for _, want := range []string{"/init", "/explore", "/superpowers:writing-plans", "/toolbox:writing-plans", "/skills", "/plugins", "/hooks", "/model"} {
26 if !got[want] {
27 t.Errorf("slash menu missing %q; have %v", want, labels(m.slashItems()))
28 }
29 }
30
31 // Typing "/init" filters the menu down to the init skill.
32 m.input.SetValue("/init")
33 m.updateCompletion()
34 if !m.completion.active {
35 t.Fatal("typing /init should open the slash menu")
36 }
37 found := false
38 for _, it := range m.completion.items {
39 if it.label == "/init" {
40 found = true
41 }
42 }
43 if !found {
44 t.Errorf("/init not in filtered menu: %v", labels(m.completion.items))
45 }
46
47 // Typing the hidden short compatibility name still discovers every plugin's
48 // visible qualified name, so an ambiguous short name becomes a chooser.
49 m.input.SetValue("/writing-plans")
50 m.updateCompletion()
51 if !m.completion.active {
52 t.Fatal("typing /writing-plans should open the slash menu")
53 }
54 filtered := map[string]int{}
55 for i, it := range m.completion.items {
56 filtered[it.label] = i
57 }
58 for _, want := range []string{"/superpowers:writing-plans", "/toolbox:writing-plans"} {
59 if _, ok := filtered[want]; !ok {
60 t.Errorf("short skill query missing %q; have %v", want, labels(m.completion.items))
61 }
62 }
63 if idx, ok := filtered["/superpowers:writing-plans"]; ok {
64 m.completion.sel = idx
65 m.acceptCompletion()
66 if got := m.input.Value(); got != "/superpowers:writing-plans " {
67 t.Errorf("accept should fill the qualified skill name, got %q", got)
68 }
69 }
70 }
71
71 lines GO