A few gaming features added, e.g. rolling dice, flipping coin, eightball.

This commit is contained in:
Storm Dragon
2026-09-03 13:25:32 -04:00
parent d0f78b1295
commit 77c687b6fe
12 changed files with 871 additions and 11 deletions
+120
View File
@@ -0,0 +1,120 @@
package rtpconn
import (
"bytes"
"strings"
"testing"
)
func TestEightBallHasClassicResponses(t *testing.T) {
want := []string{
"It is certain.",
"It is decidedly so.",
"Without a doubt.",
"Yes, definitely.",
"You may rely on it.",
"As I see it, yes.",
"Most likely.",
"Outlook good.",
"Yes.",
"Signs point to yes.",
"Reply hazy, try again.",
"Ask again later.",
"Better not tell you now.",
"Cannot predict now.",
"Concentrate and ask again.",
"Don't count on it.",
"My reply is no.",
"My sources say no.",
"Outlook not so good.",
"Very doubtful.",
}
if len(eightBallResponses) != len(want) {
t.Fatalf("eightBallResponses has %d entries, want %d", len(eightBallResponses), len(want))
}
for i := range want {
if eightBallResponses[i] != want[i] {
t.Fatalf("eightBallResponses[%d] = %q, want %q", i, eightBallResponses[i], want[i])
}
response, err := chooseEightBallResponse(bytes.NewReader([]byte{byte(i)}))
if err != nil {
t.Fatalf("chooseEightBallResponse(%d): %v", i, err)
}
if response != want[i] {
t.Fatalf("chooseEightBallResponse(%d) = %q, want %q", i, response, want[i])
}
}
}
func TestNormalizeEightBallQuestion(t *testing.T) {
question, err := normalizeEightBallQuestion(" Will\nwe win tonight? ")
if err != nil {
t.Fatalf("normalizeEightBallQuestion: %v", err)
}
if question != "Will we win tonight?" {
t.Fatalf("question = %q", question)
}
for _, value := range []any{" ", strings.Repeat("x", maxEightBallQuestionRunes+1), 42} {
if _, err := normalizeEightBallQuestion(value); err == nil {
t.Fatalf("normalizeEightBallQuestion(%#v) unexpectedly succeeded", value)
}
}
}
func TestEightBallIsServerGeneratedAndStoredInHistory(t *testing.T) {
hallName := newChalkboardTestHall(t)
asker := addTestWebClient(t, hallName, "Participant", "message")
observer := addTestWebClient(t, hallName, "Operator", "op")
if err := handleClientMessage(asker, clientMessage{
Type: "hallaction", Kind: "eightball", Value: "Will we win tonight?",
}); err != nil {
t.Fatalf("handleClientMessage(eightball): %v", err)
}
for name, messages := range map[string][]clientMessage{
"asker": drainMessages(asker),
"observer": drainMessages(observer),
} {
if len(messages) != 1 {
t.Fatalf("%s received %d messages, want 1: %#v", name, len(messages), messages)
}
message := messages[0]
if message.Type != "chat" || message.Kind != "eightball" || !message.Privileged {
t.Fatalf("%s received non-authoritative Eight Ball message: %#v", name, message)
}
if message.Source != "" || message.Username == nil || *message.Username != "Eight Ball" {
t.Fatalf("%s received Eight Ball message with unexpected identity: %#v", name, message)
}
text, ok := message.Value.(string)
if !ok || !strings.HasPrefix(text, "Participant asks: Will we win tonight?\nThe Eight Ball says: ") {
t.Fatalf("%s received malformed Eight Ball announcement %q", name, text)
}
}
history := asker.hall.GetChatHistory()
if len(history) != 1 || history[0].Kind != "eightball" {
t.Fatalf("Eight Ball history = %#v", history)
}
}
func TestEightBallRequiresMessagePermission(t *testing.T) {
hallName := newChalkboardTestHall(t)
asker := addTestWebClient(t, hallName, "Participant", "message")
asker.permissions = remove("message", asker.permissions)
if err := handleClientMessage(asker, clientMessage{
Type: "hallaction", Kind: "eightball", Value: "Will this work?",
}); err != nil {
t.Fatalf("handleClientMessage(eightball): %v", err)
}
if got := asker.hall.GetChatHistory(); len(got) != 0 {
t.Fatalf("unauthorised Eight Ball question entered history: %#v", got)
}
messages := drainMessages(asker)
if len(messages) != 1 || messages[0].Kind != "error" ||
!strings.Contains(messages[0].Value.(string), "not authorised") {
t.Fatalf("unauthorised Eight Ball response = %#v", messages)
}
}