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
|
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)
}
}
}
|