render_test.gno
2.71 Kb · 92 lines
1package life
2
3import (
4 "strconv"
5 "strings"
6 "testing"
7
8 "gno.land/p/nt/uassert/v0"
9)
10
11// ExampleRender pins the whole page on a deliberately small board so the
12// expected output stays readable. initBoard resets the grid, so this example
13// is independent of the tests that run before it.
14func ExampleRender() {
15 initBoard(5, 3)
16 SetCell(1, 1, true)
17 SetCell(2, 1, true)
18 SetCell(3, 1, true)
19 print(Render(""))
20 // Output:
21 // # Conway's Game of Life
22 //
23 // > A classic cellular automaton, ported to Gno — board state lives on-chain.
24 //
25 // **Generation:** 0 | **Population:** 3 | **Board:** 5×3
26 //
27 // ```
28 // +-----+
29 // |.....|
30 // |.OOO.|
31 // |.....|
32 // +-----+
33 // ```
34 //
35 // ## Transactions
36 //
37 // | Call | Effect |
38 // |---|---|
39 // | `Step()` | Advance one generation |
40 // | `MultiStep(n)` | Advance *n* generations (max 100) |
41 // | `SetCell(x, y, alive)` | Flip a single cell |
42 // | `Reset(w, h)` | Clear and resize (max 50×40) |
43 // | `LoadPreset(name)` | `glider` · `blinker` · `toad` · `beacon` · `block` · `pulsar` |
44 //
45 // ## Rules
46 //
47 // 1. A live cell with 2 or 3 live neighbours survives.
48 // 2. A dead cell with exactly 3 live neighbours becomes alive.
49 // 3. All other cells die or remain dead.
50}
51
52// TestRenderTracksGeneration checks the header counters follow the simulation.
53func TestRenderTracksGeneration(t *testing.T) {
54 initBoard(5, 3)
55 SetCell(1, 1, true)
56 SetCell(2, 1, true)
57 SetCell(3, 1, true)
58
59 uassert.True(t, strings.Contains(Render(""), "**Generation:** 0 | **Population:** 3"),
60 "fresh board should report generation 0")
61
62 Step() // blinker rotates to vertical; on a 3-row board only the centre survives
63 out := Render("")
64 uassert.True(t, strings.Contains(out, "**Generation:** 1"), "generation should advance")
65 uassert.True(t, strings.Contains(out, "**Population:** "+strconv.Itoa(population)),
66 "rendered population should match the counter")
67}
68
69// TestRenderDrawsLiveCells checks the ASCII grid maps cells to O/. correctly.
70func TestRenderDrawsLiveCells(t *testing.T) {
71 initBoard(3, 3)
72 SetCell(0, 0, true)
73 SetCell(2, 2, true)
74
75 out := Render("")
76 uassert.True(t, strings.Contains(out, "+---+\n|O..|\n|...|\n|..O|\n+---+"),
77 "corners should render as live cells")
78}
79
80// TestRenderBoardDimensions checks the border and header follow a resize.
81func TestRenderBoardDimensions(t *testing.T) {
82 initBoard(8, 2)
83 out := Render("")
84 uassert.True(t, strings.Contains(out, "**Board:** 8×2"), "header should report the new size")
85 uassert.True(t, strings.Contains(out, "+"+strings.Repeat("-", 8)+"+"), "border should match width")
86}
87
88// TestRenderIgnoresPath documents that Render has no sub-routes.
89func TestRenderIgnoresPath(t *testing.T) {
90 initBoard(4, 4)
91 uassert.Equal(t, Render(""), Render("/whatever"))
92}