Some checks failed
CI / Check for .beads changes (push) Has been skipped
CI / Check embedded formulas (push) Failing after 17s
CI / Test (push) Failing after 1m20s
CI / Lint (push) Failing after 22s
CI / Integration Tests (push) Failing after 34s
CI / Coverage Report (push) Has been skipped
Windows CI / Windows Build and Unit Tests (push) Has been cancelled
- Update mol-deacon-patrol formula - Fix sling helpers, doctor branch check - Update startup session and tests - Remove obsolete research doc Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
177 lines
3.9 KiB
Go
177 lines
3.9 KiB
Go
package session
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestFormatStartupBeacon(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cfg BeaconConfig
|
|
wantSub []string // substrings that must appear
|
|
wantNot []string // substrings that must NOT appear
|
|
}{
|
|
{
|
|
name: "assigned with mol-id",
|
|
cfg: BeaconConfig{
|
|
Recipient: "gastown/crew/gus",
|
|
Sender: "deacon",
|
|
Topic: "assigned",
|
|
MolID: "gt-abc12",
|
|
},
|
|
wantSub: []string{
|
|
"[GAS TOWN]",
|
|
"gastown/crew/gus",
|
|
"<- deacon",
|
|
"assigned:gt-abc12",
|
|
"Work is on your hook", // assigned includes actionable instructions
|
|
"gt hook",
|
|
},
|
|
},
|
|
{
|
|
name: "cold-start no mol-id",
|
|
cfg: BeaconConfig{
|
|
Recipient: "deacon",
|
|
Sender: "mayor",
|
|
Topic: "cold-start",
|
|
},
|
|
wantSub: []string{
|
|
"[GAS TOWN]",
|
|
"deacon",
|
|
"<- mayor",
|
|
"cold-start",
|
|
"Check your hook and mail", // cold-start includes explicit instructions (like handoff)
|
|
"gt hook",
|
|
"gt mail inbox",
|
|
},
|
|
// No wantNot - timestamp contains ":"
|
|
},
|
|
{
|
|
name: "handoff self",
|
|
cfg: BeaconConfig{
|
|
Recipient: "gastown/witness",
|
|
Sender: "self",
|
|
Topic: "handoff",
|
|
},
|
|
wantSub: []string{
|
|
"[GAS TOWN]",
|
|
"gastown/witness",
|
|
"<- self",
|
|
"handoff",
|
|
"Check your hook and mail", // handoff includes explicit instructions
|
|
"gt hook",
|
|
"gt mail inbox",
|
|
},
|
|
},
|
|
{
|
|
name: "mol-id only",
|
|
cfg: BeaconConfig{
|
|
Recipient: "gastown/polecats/Toast",
|
|
Sender: "witness",
|
|
MolID: "gt-xyz99",
|
|
},
|
|
wantSub: []string{
|
|
"[GAS TOWN]",
|
|
"gastown/polecats/Toast",
|
|
"<- witness",
|
|
"gt-xyz99",
|
|
},
|
|
},
|
|
{
|
|
name: "empty topic defaults to ready",
|
|
cfg: BeaconConfig{
|
|
Recipient: "deacon",
|
|
Sender: "mayor",
|
|
},
|
|
wantSub: []string{
|
|
"[GAS TOWN]",
|
|
"ready",
|
|
},
|
|
},
|
|
{
|
|
name: "start includes fallback instructions",
|
|
cfg: BeaconConfig{
|
|
Recipient: "beads/crew/fang",
|
|
Sender: "human",
|
|
Topic: "start",
|
|
},
|
|
wantSub: []string{
|
|
"[GAS TOWN]",
|
|
"beads/crew/fang",
|
|
"<- human",
|
|
"start",
|
|
"gt prime", // fallback instruction for when SessionStart hook fails
|
|
},
|
|
},
|
|
{
|
|
name: "restart includes fallback instructions",
|
|
cfg: BeaconConfig{
|
|
Recipient: "gastown/crew/george",
|
|
Sender: "human",
|
|
Topic: "restart",
|
|
},
|
|
wantSub: []string{
|
|
"[GAS TOWN]",
|
|
"gastown/crew/george",
|
|
"restart",
|
|
"gt prime", // fallback instruction for when SessionStart hook fails
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := FormatStartupBeacon(tt.cfg)
|
|
|
|
for _, sub := range tt.wantSub {
|
|
if !strings.Contains(got, sub) {
|
|
t.Errorf("FormatStartupBeacon() = %q, want to contain %q", got, sub)
|
|
}
|
|
}
|
|
|
|
for _, sub := range tt.wantNot {
|
|
if strings.Contains(got, sub) {
|
|
t.Errorf("FormatStartupBeacon() = %q, should NOT contain %q", got, sub)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBuildStartupPrompt(t *testing.T) {
|
|
// BuildStartupPrompt combines beacon + instructions
|
|
cfg := BeaconConfig{
|
|
Recipient: "deacon",
|
|
Sender: "daemon",
|
|
Topic: "patrol",
|
|
}
|
|
instructions := "Start patrol immediately."
|
|
|
|
got := BuildStartupPrompt(cfg, instructions)
|
|
|
|
// Should contain beacon parts
|
|
if !strings.Contains(got, "[GAS TOWN]") {
|
|
t.Errorf("BuildStartupPrompt() missing beacon header")
|
|
}
|
|
if !strings.Contains(got, "deacon") {
|
|
t.Errorf("BuildStartupPrompt() missing recipient")
|
|
}
|
|
if !strings.Contains(got, "<- daemon") {
|
|
t.Errorf("BuildStartupPrompt() missing sender")
|
|
}
|
|
if !strings.Contains(got, "patrol") {
|
|
t.Errorf("BuildStartupPrompt() missing topic")
|
|
}
|
|
|
|
// Should contain instructions after beacon
|
|
if !strings.Contains(got, instructions) {
|
|
t.Errorf("BuildStartupPrompt() missing instructions")
|
|
}
|
|
|
|
// Should have blank line between beacon and instructions
|
|
if !strings.Contains(got, "\n\n"+instructions) {
|
|
t.Errorf("BuildStartupPrompt() missing blank line before instructions")
|
|
}
|
|
}
|