1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
package game
import (
"strings"
"testing"
"thehouseoficarus/internal/casino"
"thehouseoficarus/internal/color"
"thehouseoficarus/internal/net"
"thehouseoficarus/internal/player"
)
type casinoTestConn struct {
data []byte
}
func (c *casinoTestConn) ReadMessage() (string, error) { return "", nil }
func (c *casinoTestConn) Write(b []byte) (int, error) {
c.data = append(c.data, b...)
return len(b), nil
}
func (c *casinoTestConn) Close() error { return nil }
func (c *casinoTestConn) SetEcho(bool) error { return nil }
func TestExecuteBetRejectsInvalidMachineArgs(t *testing.T) {
g := &Game{Casino: casino.NewManager(1)}
cfg := casino.MachineConfig{ID: "slots", Game: casino.GameSlots}
g.Casino.JoinMachine(1, cfg, "alice")
conn := &casinoTestConn{}
sess := &net.Session{Player: player.New("alice"), Conn: conn}
g.loggedInChars = map[string]*net.Session{"alice": sess}
for _, args := range [][]string{{"banana"}, {"-5"}, {"10", "extra"}} {
conn.data = nil
g.executeBet(sess, args, "bet "+strings.Join(args, " "))
if !strings.Contains(string(conn.data), "Use bet, bet <amount>, or bet max.") {
t.Fatalf("bet %v: expected usage error, got %q", args, string(conn.data))
}
}
// A bare bet at a machine reaches the spin path instead of erroring.
g.Casino.SetMachineBet(1, "slots", "alice", 10)
conn.data = nil
g.executeBet(sess, nil, "bet")
if !strings.Contains(string(conn.data), "You don't have enough chips and credits") {
t.Fatalf("bare bet should attempt a spin, got %q", string(conn.data))
}
}
func TestRenderSlotSnapshotColorsWordSymbols(t *testing.T) {
snapshot := &casino.SlotSnapshot{StoppedReels: 1}
snapshot.Grid[0][0] = "scatter"
if !strings.Contains(renderSlotSnapshot(snapshot, "none", false), "scatter") {
t.Fatal("expected word-based slot symbols")
}
output := renderSlotSnapshot(snapshot, "xterm256", true)
if !strings.Contains(output, "\033[38;5;") {
t.Fatalf("expected colored slot symbols, got %q", output)
}
for _, line := range strings.Split(output, "\n") {
if color.VisibleLen(line) != 51 {
t.Fatalf("line visible width = %d, want 51: %q", color.VisibleLen(line), line)
}
}
if !strings.Contains(output, "┌") || !strings.Contains(output, "└") {
t.Fatalf("slot output lacks the Unicode frame: %q", output)
}
}
func TestRenderBlackjackSnapshotUsesCompactASCIIArt(t *testing.T) {
snapshot := &casino.BlackjackSnapshot{
Dealer: []casino.BlackjackCardView{{Rank: "?", Hidden: true}, {Rank: "K", Suit: "hearts"}},
Players: []casino.BlackjackPlayerView{{Name: "alice", Score: "20", Cards: []casino.BlackjackCardView{{Rank: "5", Suit: "clubs"}, {Rank: "Q", Suit: "spades"}}}},
}
plain := renderBlackjackSnapshot(snapshot, "none", false, 5, "dark", nil)
if !strings.Contains(plain, "+---+") || !strings.Contains(plain, "Dealer:") || !strings.Contains(plain, "alice (20):") {
t.Fatalf("unexpected blackjack art: %q", plain)
}
output := renderBlackjackSnapshot(snapshot, "xterm256", false, 5, "dark", nil)
if !strings.Contains(output, "\033[38;5;") {
t.Fatalf("expected colored blackjack art: %q", output)
}
if strings.ContainsAny(output, "│─┌┐└┘") {
t.Fatalf("blackjack art contains Unicode borders: %q", output)
}
for _, line := range strings.Split(output, "\n") {
if color.VisibleLen(line) > 80 {
t.Fatalf("blackjack line exceeds console width: %d", color.VisibleLen(line))
}
}
unicodeOutput := renderBlackjackSnapshot(snapshot, "none", true, 7, "dark", nil)
if !strings.Contains(unicodeOutput, "│5 │") || !strings.Contains(unicodeOutput, "│ 5│") || !strings.Contains(unicodeOutput, "│ ♣ │") {
t.Fatalf("unexpected Unicode card alignment: %q", unicodeOutput)
}
coloredUnicode := renderBlackjackSnapshot(snapshot, "xterm256", true, 7, "dark", nil)
if !strings.Contains(coloredUnicode, "\033[38;5;15m") || !strings.Contains(coloredUnicode, "\033[38;5;27m") {
t.Fatalf("expected white borders and blue card art: %q", coloredUnicode)
}
light := renderBlackjackSnapshot(snapshot, "xterm256", true, 7, "light", nil)
if !strings.Contains(light, "\033[48;5;15m") {
t.Fatalf("expected white card background in light style: %q", light)
}
lightLines := strings.Split(light, "\n")
if strings.Contains(lightLines[1], "\033[48;5;15m") || strings.Contains(lightLines[7], "\033[48;5;15m") {
t.Fatalf("card edges should not have a background: %q", light)
}
lightPlain := renderBlackjackSnapshot(snapshot, "none", true, 7, "light", nil)
if !strings.Contains(lightPlain, "▀▀▀▀▀▀▀") || !strings.Contains(lightPlain, "▄▄▄▄▄▄▄") {
t.Fatalf("expected half-height light card edges: %q", lightPlain)
}
}
|