From 4bc1daaf259e0c19c5fe4a12ec8bc7f6e5a735c1 Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Mon, 5 Oct 2026 20:00:02 -0400 Subject: feat: terminal talk action, typed pai gow poker phase --- internal/game/harness_test.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'internal/game/harness_test.go') diff --git a/internal/game/harness_test.go b/internal/game/harness_test.go index 3bdce0f..c5377b4 100644 --- a/internal/game/harness_test.go +++ b/internal/game/harness_test.go @@ -131,6 +131,39 @@ func newHarness(t *testing.T) *harness { return h } +// newHarnessWithTicks is newHarness with the production master tick +// subscription registered, so tick-driven systems (disconnect countdown, +// action advance, casino tick) run exactly as they do in production. Most +// harness tests drive the systems directly and do not need this. +func newHarnessWithTicks(t *testing.T) *harness { + t.Helper() + h := newHarness(t) + h.g.SubscribeTicks(1, func() bool { + h.g.RunTickSystems() + return true + }) + return h +} + +// Regression: the harness must be able to run the real master tick sequence, +// which is the only way the disconnect countdown (Hub.Remove -> DisconnectTick +// -> onRemove) is exercised end-to-end. +func TestHarnessWithTicksCompletesDisconnect(t *testing.T) { + h := newHarnessWithTicks(t) + h.seedAccount("alice") + h.seedCharacter("alice", "alice") + sess, _ := h.connect("alice") + h.hub.Remove(sess) + h.barrier() + deadline := time.Now().Add(2 * time.Second) + for time.Now().Before(deadline) && len(h.hub.AllSessions()) > 0 { + time.Sleep(5 * time.Millisecond) + } + if got := len(h.hub.AllSessions()); got != 0 { + t.Fatalf("session not hard-removed after the countdown: %d", got) + } +} + // seedWorld writes the minimal on-disk content a Game needs: three rooms. func seedWorld(t *testing.T, dir string) { t.Helper() -- cgit v1.2.3