From cc33072eced3d5460512c09c42ec4531c807d7af Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Sat, 19 Sep 2026 01:55:34 -0400 Subject: fix: casino stake preservation, world state reconciliation, casino game registration --- internal/game/snapshot_render_guard_test.go | 40 +++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 internal/game/snapshot_render_guard_test.go (limited to 'internal/game/snapshot_render_guard_test.go') diff --git a/internal/game/snapshot_render_guard_test.go b/internal/game/snapshot_render_guard_test.go new file mode 100644 index 0000000..83833d5 --- /dev/null +++ b/internal/game/snapshot_render_guard_test.go @@ -0,0 +1,40 @@ +package game + +// Guard for the last per-game presentation seam: the Snapshot marker interface +// guarantees an event carries a structured view, but renderCasinoSnapshot's +// type switch silently returns "" for a snapshot it does not know. This +// source-level test pairs every `func (*X) snapshot() {}` in the casino package +// with a `case *casino.X:` in the renderer, so adding a game cannot silently +// drop its view (the text message would still appear, hiding the loss). + +import ( + "os" + "path/filepath" + "regexp" + "strings" + "testing" +) + +func TestEveryCasinoSnapshotHasARenderer(t *testing.T) { + typesSrc, err := os.ReadFile(filepath.Join("..", "casino", "types.go")) + if err != nil { + t.Fatalf("read casino types: %v", err) + } + renderSrc, err := os.ReadFile("casino.go") + if err != nil { + t.Fatalf("read renderer: %v", err) + } + + re := regexp.MustCompile(`func \(\*(\w+)\) snapshot\(\)`) + matches := re.FindAllStringSubmatch(string(typesSrc), -1) + if len(matches) == 0 { + t.Fatal("no Snapshot implementations found in casino/types.go") + } + for _, m := range matches { + name := m[1] + want := "case *casino." + name + ":" + if !strings.Contains(string(renderSrc), want) { + t.Errorf("snapshot %s has no renderer: add `%s` to renderCasinoSnapshot", name, want) + } + } +} -- cgit v1.2.3