diff options
| author | historia <[not public]> | 2026-09-30 16:16:17 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-09-30 16:16:17 -0400 |
| commit | a4c09c2d38d1f3bc1d3ad4bdb0234bdea7c37e73 (patch) | |
| tree | 00c9567e620f331a59dd44f1f1fa779ecd94a845 /internal/game/casino_commands_test.go | |
| parent | 724079f8de1ae69965c6267dca3d7fc3cc86afa2 (diff) | |
| download | thehouseoficarus-a4c09c2d38d1f3bc1d3ad4bdb0234bdea7c37e73.tar.gz | |
feat: additional craps variants added, standardizard casino command hints
Diffstat (limited to 'internal/game/casino_commands_test.go')
| -rw-r--r-- | internal/game/casino_commands_test.go | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/internal/game/casino_commands_test.go b/internal/game/casino_commands_test.go new file mode 100644 index 0000000..7820650 --- /dev/null +++ b/internal/game/casino_commands_test.go @@ -0,0 +1,118 @@ +package game + +import ( + "strings" + "testing" + + "thehouseoficarus/internal/casino" + "thehouseoficarus/internal/color" + "thehouseoficarus/internal/net" + "thehouseoficarus/internal/player" +) + +func TestCasinoCommandsWrapBeforeSessionWithoutLosingIndent(t *testing.T) { + commands := []casino.MenuCommand{ + {Command: "bet <amount> on <target>", Desc: "Place bets until the dice roll; table rules lists targets"}, + {Command: "roll / autoroll / stop", Desc: "Shoot / repeat on your turn / return to manual play"}, + {Command: "unbet <target> / unbet all", Desc: "Remove one bet / every optional bet"}, + {Command: "table", Desc: "View the felt"}, + {Command: "insurance", Desc: "Buy insurance; a deliberately long description which requires a hanging continuation line"}, + {Command: "decline", Desc: "Continue without insurance (also the timeout default)"}, + {Command: "bet <amount> on player/banker/tie/player_pair/banker_pair", Desc: "One wager per round; 'on' is optional"}, + {Command: "option casino_display compact", Desc: "Compact action hints (detailed for full command menus)"}, + {Command: "spin", Desc: "Spin using your current wager"}, + {Command: "autospin", Desc: "Start automatic betting"}, + {Command: "unicode", Desc: strings.Repeat("é", 100)}, + } + for _, wrap := range []int{0, 40, 60, 80, 120} { + p := player.New("a") + p.Options = map[string]any{"wrap_width": wrap} + conn := &casinoTestConn{} + sess := &net.Session{Player: p, Conn: conn} + g := &Game{} + text := g.casinoMenuCommands(sess, commands) + sess.WriteLine(text) + limit := 80 + if wrap > 0 { + limit = min(limit, wrap) + } + for _, line := range strings.Split(strings.ReplaceAll(plainRoulette(string(conn.data)), "\r\n", "\n"), "\n") { + if line == "" { + continue + } + if color.VisibleLen(line) > limit { + t.Fatalf("wrap %d overlong %d: %q", wrap, color.VisibleLen(line), line) + } + if !strings.HasPrefix(line, " ") { + t.Fatalf("wrap %d lost indent: %q", wrap, line) + } + } + expected := strings.ReplaceAll(plainRoulette(text), "\r\n", "\n") + actual := strings.TrimRight(strings.ReplaceAll(plainRoulette(string(conn.data)), "\r\n", "\n"), "\n") + if expected != actual { + t.Fatalf("session reflowed prewrapped menu at %d", wrap) + } + } +} +func TestCasinoCommandsHangingIndentAndShortDescription(t *testing.T) { + sess := &net.Session{Player: player.New("a")} + g := &Game{} + commands := []casino.MenuCommand{ + {Command: "bet <amount> on <target>", Desc: "Place a wager; targets: table rules"}, + {Command: "table", Desc: "View the felt"}, + } + text := plainRoulette(g.casinoMenuCommands(sess, commands)) + lines := strings.Split(text, "\n") + if len(lines) != 2 { + t.Fatal("short commands should not wrap", text) + } + col := strings.Index(lines[0], "Place") + if col != strings.Index(lines[1], "View") { + t.Fatal("descriptions not aligned", text) + } + commands[0].Desc = strings.Repeat("long description ", 10) + text = plainRoulette(g.casinoMenuCommands(sess, commands)) + lines = strings.Split(text, "\n") + for _, line := range lines[1 : len(lines)-1] { + if !strings.HasPrefix(line, strings.Repeat(" ", col)) { + t.Fatal("missing hanging indent", text) + } + } +} +func TestCasinoCompactHintsUseOnlyAvailableCommands(t *testing.T) { + p := player.New("a") + p.Options = map[string]any{"casino_display": "compact"} + p.Credits = 10 + sess := &net.Session{Player: p} + g := &Game{} + menu := &casino.MenuView{Heading: "Your turn", Commands: []casino.MenuCommand{ + {Command: "hit", Desc: "Take a card"}, {Command: "stand", Desc: "Hold"}, {Command: "double", Cost: 20}, + }} + text := plainRoulette(g.casinoPrivateMessage(sess, "casino_menu", menu, "")) + if strings.Contains(text, "double") || !strings.Contains(text, " h:hit") || !strings.Contains(text, " st:stand") { + t.Fatal(text) + } + menu.ShowBalance = true + menu.Repeat = true + menu.Commands = []casino.MenuCommand{{Command: "table", Desc: "View the felt"}} + text = plainRoulette(g.casinoPrivateMessage(sess, "casino_menu", menu, "")) + if strings.Contains(text, "bet") || strings.Contains(text, "sitout") { + t.Fatal("compact mode invented actions", text) + } +} +func TestSimplifiedFeltSpacingAndNoIdlePrompt(t *testing.T) { + text := renderCrapsSnapshot(&casino.CrapsSnapshot{Variant: "simplified"}, "none", true) + if strings.Contains(text, "Place a bet, then roll when ready.") { + t.Fatal(text) + } + rows := strings.Split(text, "\n") + for i, row := range rows { + if strings.Contains(row, "PASS ONLY") { + if i+2 >= len(rows) || strings.Trim(rows[i+1], "│ ") != "" || !strings.HasPrefix(rows[i+2], "└") { + t.Fatal("expected exactly one blank felt row", text) + } + return + } + } + t.Fatal("missing pass label") +} |
