|
016a29f…
|
lmata
|
1 |
package ircagent |
|
016a29f…
|
lmata
|
2 |
|
|
016a29f…
|
lmata
|
3 |
import "testing" |
|
016a29f…
|
lmata
|
4 |
|
|
016a29f…
|
lmata
|
5 |
func TestMentionsNick(t *testing.T) { |
|
016a29f…
|
lmata
|
6 |
t.Helper() |
|
016a29f…
|
lmata
|
7 |
|
|
016a29f…
|
lmata
|
8 |
tests := []struct { |
|
016a29f…
|
lmata
|
9 |
name string |
|
016a29f…
|
lmata
|
10 |
text string |
|
016a29f…
|
lmata
|
11 |
nick string |
|
016a29f…
|
lmata
|
12 |
want bool |
|
016a29f…
|
lmata
|
13 |
}{ |
|
016a29f…
|
lmata
|
14 |
{name: "simple mention", text: "codex: hello", nick: "codex", want: true}, |
|
016a29f…
|
lmata
|
15 |
{name: "mention in sentence", text: "hey codex can you help", nick: "codex", want: true}, |
|
016a29f…
|
lmata
|
16 |
{name: "path does not trigger", text: "look at .claude/hooks/settings.json", nick: "claude", want: false}, |
|
016a29f…
|
lmata
|
17 |
{name: "windows path does not trigger", text: `check C:\Users\me\.codex\hooks`, nick: "codex", want: false}, |
|
016a29f…
|
lmata
|
18 |
{name: "substring does not trigger", text: "codexagent is a process", nick: "codex", want: false}, |
|
016a29f…
|
lmata
|
19 |
{name: "hyphen boundary does not trigger", text: "claude-scuttlebot-a1b2c3d4 posted status", nick: "claude", want: false}, |
|
016a29f…
|
lmata
|
20 |
} |
|
016a29f…
|
lmata
|
21 |
|
|
016a29f…
|
lmata
|
22 |
for _, tt := range tests { |
|
016a29f…
|
lmata
|
23 |
t.Run(tt.name, func(t *testing.T) { |
|
016a29f…
|
lmata
|
24 |
got := MentionsNick(tt.text, tt.nick) |
|
016a29f…
|
lmata
|
25 |
if got != tt.want { |
|
016a29f…
|
lmata
|
26 |
t.Fatalf("MentionsNick(%q, %q) = %v, want %v", tt.text, tt.nick, got, tt.want) |
|
016a29f…
|
lmata
|
27 |
} |
|
016a29f…
|
lmata
|
28 |
}) |
|
016a29f…
|
lmata
|
29 |
} |
|
016a29f…
|
lmata
|
30 |
} |
|
016a29f…
|
lmata
|
31 |
|
|
016a29f…
|
lmata
|
32 |
func TestSplitCSV(t *testing.T) { |
|
016a29f…
|
lmata
|
33 |
t.Helper() |
|
016a29f…
|
lmata
|
34 |
|
|
016a29f…
|
lmata
|
35 |
got := SplitCSV(" #general, #fleet ,, #agent.codex ") |
|
016a29f…
|
lmata
|
36 |
want := []string{"#general", "#fleet", "#agent.codex"} |
|
016a29f…
|
lmata
|
37 |
if len(got) != len(want) { |
|
016a29f…
|
lmata
|
38 |
t.Fatalf("len(SplitCSV) = %d, want %d", len(got), len(want)) |
|
016a29f…
|
lmata
|
39 |
} |
|
016a29f…
|
lmata
|
40 |
for i := range want { |
|
016a29f…
|
lmata
|
41 |
if got[i] != want[i] { |
|
016a29f…
|
lmata
|
42 |
t.Fatalf("SplitCSV()[%d] = %q, want %q", i, got[i], want[i]) |
|
016a29f…
|
lmata
|
43 |
} |
|
016a29f…
|
lmata
|
44 |
} |
|
016a29f…
|
lmata
|
45 |
} |
|
016a29f…
|
lmata
|
46 |
|
|
016a29f…
|
lmata
|
47 |
func TestHasAnyPrefix(t *testing.T) { |
|
016a29f…
|
lmata
|
48 |
t.Helper() |
|
016a29f…
|
lmata
|
49 |
|
|
016a29f…
|
lmata
|
50 |
prefixes := []string{"claude-", "codex-", "gemini-"} |
|
016a29f…
|
lmata
|
51 |
if !HasAnyPrefix("claude-abc", prefixes) { |
|
016a29f…
|
lmata
|
52 |
t.Fatalf("expected claude prefix match") |
|
016a29f…
|
lmata
|
53 |
} |
|
016a29f…
|
lmata
|
54 |
if !HasAnyPrefix("codex-1234", prefixes) { |
|
016a29f…
|
lmata
|
55 |
t.Fatalf("expected codex prefix match") |
|
016a29f…
|
lmata
|
56 |
} |
|
016a29f…
|
lmata
|
57 |
if !HasAnyPrefix("gemini-1234", prefixes) { |
|
016a29f…
|
lmata
|
58 |
t.Fatalf("expected gemini prefix match") |
|
016a29f…
|
lmata
|
59 |
} |
|
016a29f…
|
lmata
|
60 |
if HasAnyPrefix("glengoolie", prefixes) { |
|
016a29f…
|
lmata
|
61 |
t.Fatalf("did not expect non-activity sender to match") |
|
016a29f…
|
lmata
|
62 |
} |
|
016a29f…
|
lmata
|
63 |
} |
|
016a29f…
|
lmata
|
64 |
|
|
016a29f…
|
lmata
|
65 |
func TestTrimAddressedText(t *testing.T) { |
|
016a29f…
|
lmata
|
66 |
t.Helper() |
|
016a29f…
|
lmata
|
67 |
|
|
016a29f…
|
lmata
|
68 |
tests := []struct { |
|
016a29f…
|
lmata
|
69 |
name string |
|
016a29f…
|
lmata
|
70 |
text string |
|
016a29f…
|
lmata
|
71 |
nick string |
|
016a29f…
|
lmata
|
72 |
want string |
|
016a29f…
|
lmata
|
73 |
}{ |
|
016a29f…
|
lmata
|
74 |
{name: "colon address", text: "codex-scuttlebot-1234: read README.md", nick: "codex-scuttlebot-1234", want: "read README.md"}, |
|
016a29f…
|
lmata
|
75 |
{name: "comma address", text: "codex, status?", nick: "codex", want: "status?"}, |
|
016a29f…
|
lmata
|
76 |
{name: "plain text stays", text: "hello there", nick: "codex", want: "hello there"}, |
|
016a29f…
|
lmata
|
77 |
} |
|
016a29f…
|
lmata
|
78 |
|
|
016a29f…
|
lmata
|
79 |
for _, tt := range tests { |
|
016a29f…
|
lmata
|
80 |
t.Run(tt.name, func(t *testing.T) { |
|
016a29f…
|
lmata
|
81 |
got := TrimAddressedText(tt.text, tt.nick) |
|
016a29f…
|
lmata
|
82 |
if got != tt.want { |
|
016a29f…
|
lmata
|
83 |
t.Fatalf("TrimAddressedText(%q, %q) = %q, want %q", tt.text, tt.nick, got, tt.want) |
|
cefe27d…
|
lmata
|
84 |
} |
|
cefe27d…
|
lmata
|
85 |
}) |
|
cefe27d…
|
lmata
|
86 |
} |
|
cefe27d…
|
lmata
|
87 |
} |
|
cefe27d…
|
lmata
|
88 |
|
|
cefe27d…
|
lmata
|
89 |
func TestMatchesGroupMention(t *testing.T) { |
|
cefe27d…
|
lmata
|
90 |
tests := []struct { |
|
cefe27d…
|
lmata
|
91 |
name, text, nick, agentType string |
|
cefe27d…
|
lmata
|
92 |
want bool |
|
cefe27d…
|
lmata
|
93 |
}{ |
|
cefe27d…
|
lmata
|
94 |
{"@all matches everyone", "@all stop working", "claude-kohakku-abc", "worker", true}, |
|
cefe27d…
|
lmata
|
95 |
{"@all mid-sentence", "hey @all check this", "gemini-foo-123", "worker", true}, |
|
cefe27d…
|
lmata
|
96 |
{"@worker matches worker type", "@worker report status", "claude-kohakku-abc", "worker", true}, |
|
cefe27d…
|
lmata
|
97 |
{"@worker doesn't match observer", "@worker report", "obs-bot", "observer", false}, |
|
cefe27d…
|
lmata
|
98 |
{"@observer matches observer", "@observer watch this", "obs-bot", "observer", true}, |
|
cefe27d…
|
lmata
|
99 |
{"@claude-* matches claude agents", "@claude-* pause", "claude-kohakku-abc", "worker", true}, |
|
cefe27d…
|
lmata
|
100 |
{"@claude-* doesn't match gemini", "@claude-* pause", "gemini-kohakku-abc", "worker", false}, |
|
cefe27d…
|
lmata
|
101 |
{"@claude-kohakku-* matches specific", "@claude-kohakku-* stop", "claude-kohakku-abc", "worker", true}, |
|
cefe27d…
|
lmata
|
102 |
{"@gemini-* matches gemini", "@gemini-* summarize", "gemini-proj-123", "worker", true}, |
|
cefe27d…
|
lmata
|
103 |
{"no mention no match", "hello world", "claude-abc", "worker", false}, |
|
cefe27d…
|
lmata
|
104 |
{"partial @all no match", "install @alloy", "claude-abc", "worker", false}, |
|
cefe27d…
|
lmata
|
105 |
} |
|
cefe27d…
|
lmata
|
106 |
for _, tt := range tests { |
|
cefe27d…
|
lmata
|
107 |
t.Run(tt.name, func(t *testing.T) { |
|
cefe27d…
|
lmata
|
108 |
got := MatchesGroupMention(tt.text, tt.nick, tt.agentType) |
|
cefe27d…
|
lmata
|
109 |
if got != tt.want { |
|
cefe27d…
|
lmata
|
110 |
t.Errorf("MatchesGroupMention(%q, %q, %q) = %v, want %v", tt.text, tt.nick, tt.agentType, got, tt.want) |
|
016a29f…
|
lmata
|
111 |
} |
|
016a29f…
|
lmata
|
112 |
}) |
|
016a29f…
|
lmata
|
113 |
} |
|
016a29f…
|
lmata
|
114 |
} |