package game import ( "strings" "testing" "thehouseoficarus/internal/casino" "thehouseoficarus/internal/color" "thehouseoficarus/internal/net" "thehouseoficarus/internal/player" ) func TestCrapsCommandsAndRendering(t *testing.T) { g := &Game{Casino: casino.NewManager(1)} cfg := casino.TableConfig{ID: "craps", Game: casino.GameCraps} g.Casino.Join(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{{"12", "on", "place", "6"}, {"10", "on", "hop", "2", "3"}, {"10", "buy", "4"}, {"10", "on", "fire"}} { conn.data = nil g.executeBet(sess, args, "bet "+strings.Join(args, " ")) if !strings.Contains(string(conn.data), "You don't have enough chips and credits") { t.Fatalf("%v: %s", args, conn.data) } } conn.data = nil g.executeTableStatus(sess, []string{"rules"}, "table rules") if !strings.Contains(string(conn.data), "Bank Craps") || !strings.Contains(string(conn.data), "PASS LINE") { t.Fatal(string(conn.data)) } for _, cmd := range []string{"roll", "autoroll", "unbet"} { if _, ok := commandRegistry[cmd]; !ok { t.Fatal("missing", cmd) } } snap := &casino.CrapsSnapshot{Phase: "betting", Point: 6, Dice: [2]int{3, 4}, Queue: []string{"alice", "bob"}, Made: []int{4, 6}, Seen: []int{2, 4, 6}} if !g.seesCasinoDetails(sess, casino.Event{RoomID: 1, TableID: "craps", Snapshot: snap}) { t.Fatal("invisible board") } for _, mode := range []string{"none", "ansi", "xterm256"} { for _, unicode := range []bool{false, true} { art := renderCrapsSnapshot(snap, mode, unicode) plain := plainRoulette(art) for _, word := range []string{"PASS LINE", "DON'T COME", "FIELD", "FIRE", "ALL SMALL", "Shooter alice", "Total: 7", "POINT 6"} { if !strings.Contains(plain, word) { t.Fatal("missing", word) } } for _, r := range plain { if !unicode && r > 127 { t.Fatalf("nonASCII %q", r) } } for _, line := range strings.Split(plain, "\n") { if color.VisibleLen(line) > 78 { t.Fatalf("too wide: %s", line) } } if mode == "none" && art != plain { t.Fatal("unexpected ANSI") } if mode != "none" && !strings.Contains(art, "\x1b[") { t.Fatal("missing felt color") } } } // Snapshots and nil/empty states render safely before the first roll. if renderCrapsSnapshot(nil, "none", false) != "" { t.Fatal("nil") } for a := 1; a <= 6; a++ { for b := 1; b <= 6; b++ { snap.Dice = [2]int{a, b} if !strings.Contains(renderCrapsSnapshot(snap, "none", false), "Total:") { t.Fatal(a, b) } } } }