package game import ( "os" "path/filepath" "strings" "testing" "time" "thehouseoficarus/internal/casino" ) // lookOutput polls the queued session writer until the look output has // settled (no growth across two samples), then returns it, ANSI-stripped. func lookOutput(t *testing.T, conn *chanConn) string { t.Helper() last := 0 stable := 0 for stable < 2 { n := len(conn.Bytes()) if n == last { stable++ } else { stable = 0 last = n } time.Sleep(10 * time.Millisecond) } return stripANSI(string(conn.Bytes())) } // TestLookAtTableShowsGameStateAndHints covers feature 1 with the full // production harness: a seated player's look shows the room first, then the // game table, then the current hint commands — rules always, list when the // game has multiple wagers. func TestLookAtTableShowsGameStateAndHints(t *testing.T) { h := newHarness(t) h.seedAccount("alice") h.seedCharacter("alice", "alice") sess, conn := h.connect("alice") // Add a casino room and move there. room := "id: 4\nname: Simplified Salon\ncasino_tables:\n - id: simple\n game: craps\n craps:\n variant: simplified\n" path := filepath.Join(h.dir, "rooms", "4.yaml") if err := os.WriteFile(path, []byte(room), 0644); err != nil { t.Fatal(err) } h.g.World.AddRoomPath(4, path) sess.Player.RoomID = 4 h.hub.EnterRoom(sess, 4) cfg := casino.TableConfig{ID: "simple", Game: casino.GameCraps, Craps: casino.CrapsConfig{Variant: "simplified"}} h.g.Casino.Join(4, cfg, "alice") h.g.executeLook(sess, nil, "look") text := lookOutput(t, conn) if !strings.Contains(text, "Simplified Salon") { t.Fatalf("look lost the room: %q", text) } if !strings.Contains(strings.ToUpper(text), "SIMPLIFIED CRAPS") || !strings.Contains(text, "Limits") { t.Fatalf("look missing the table state: %q", text) } if !strings.Contains(text, "rules") { t.Fatalf("look missing the rules hint: %q", text) } } // TestLookStandingShowsFixtureOnly: an unseated player's look keeps the // plain room listing (no game state block). func TestLookStandingShowsFixtureOnly(t *testing.T) { h := newHarness(t) h.seedAccount("alice") h.seedCharacter("alice", "alice") sess, conn := h.connect("alice") room := "id: 4\nname: Simplified Salon\ncasino_tables:\n - id: simple\n game: craps\n craps:\n variant: simplified\n" path := filepath.Join(h.dir, "rooms", "4.yaml") if err := os.WriteFile(path, []byte(room), 0644); err != nil { t.Fatal(err) } h.g.World.AddRoomPath(4, path) sess.Player.RoomID = 4 h.hub.EnterRoom(sess, 4) h.g.executeLook(sess, nil, "look") text := lookOutput(t, conn) if strings.Contains(text, "bet ") { t.Fatalf("standing look leaked a betting menu: %q", text) } if !strings.Contains(text, "play craps") { t.Fatalf("standing look missing the play hint: %q", text) } }