package main import ( "os/exec" "strings" "testing" ) func makeMsg(user, body string) BotMessage { var msg BotMessage msg.User.Name = user msg.Message.Body.Plain = body return msg } func qalcAvailable() bool { _, err := exec.LookPath("qalc") return err == nil } func TestExecuteCommand(t *testing.T) { tests := []struct { user string body string exact string contains []string }{ {user: "anyone", body: "ping", exact: "Pong!"}, {user: "Alice", body: "hi", exact: "Hello Alice! How are you doing today?"}, {user: "anyone", body: "help math", contains: []string{"qalc"}}, {user: "anyone", body: "help bogus", contains: []string{"No help found for 'bogus'"}}, {user: "anyone", body: "help", contains: []string{"ping", "math", "hi", "trace", "help"}}, {user: "nobody", body: "unknown command", contains: []string{"Not sure what to do"}}, } for _, tt := range tests { t.Run(tt.body, func(t *testing.T) { got := executeCommand(makeMsg(tt.user, tt.body)) if tt.exact != "" && got != tt.exact { t.Errorf("got %q, want %q", got, tt.exact) } for _, sub := range tt.contains { if !strings.Contains(got, sub) { t.Errorf("output %q does not contain %q", got, sub) } } }) } } func TestLastCommandMemoryPing(t *testing.T) { user := "testmem-ping-fallback" got := executeCommand(makeMsg(user, "ping")) if got != "Pong!" { t.Fatalf("expected Pong!, got %q", got) } got = executeCommand(makeMsg(user, "anything")) if got != "Pong!" { t.Errorf("expected fallback to ping, got %q", got) } } func TestLastCommandMemoryMath(t *testing.T) { if !qalcAvailable() { t.Skip("qalc not on PATH") } user := "testmem-math-fallback" got := executeCommand(makeMsg(user, "math 2+2")) if !strings.Contains(got, "4") { t.Fatalf("math 2+2 expected output containing '4', got %q", got) } got = executeCommand(makeMsg(user, "3+3")) if !strings.Contains(got, "6") { t.Errorf("fallback math 3+3 expected output containing '6', got %q", got) } } func TestSplitFirstWord(t *testing.T) { tests := []struct { input string wantWord string wantRest string }{ {"ping", "ping", ""}, {"math 2+2", "math", "2+2"}, {"MATH 2+2", "math", "2+2"}, {"", "", ""}, {" ping ", "ping", ""}, } for _, tt := range tests { t.Run(tt.input, func(t *testing.T) { word, rest := SplitFirstWord(tt.input) if word != tt.wantWord || rest != tt.wantRest { t.Errorf("SplitFirstWord(%q) = (%q, %q), want (%q, %q)", tt.input, word, rest, tt.wantWord, tt.wantRest) } }) } } func TestMath(t *testing.T) { if !qalcAvailable() { t.Skip("qalc not on PATH") } got := executeCommand(makeMsg("anyone", "math 2+2")) if !strings.Contains(got, "4") { t.Errorf("math 2+2 expected output containing '4', got %q", got) } }