pixelcanvas_test.gno
3.98 Kb · 153 lines
1package pixelcanvas
2
3import (
4 "strings"
5 "testing"
6
7 "gno.land/p/nt/avl/v0"
8 "gno.land/p/nt/testutils/v0"
9 "gno.land/p/nt/uassert/v0"
10)
11
12// reset clears realm state between tests.
13func reset() {
14 for i := range cells {
15 cells[i] = 0
16 painters[i] = ""
17 }
18 tally = avl.NewTree()
19 strokes = 0
20 lastAt = 0
21}
22
23// paint runs a Paint as addr.
24func paint(cur realm, addr address, x, y int, colour string) int {
25 testing.SetRealm(testing.NewUserRealm(addr))
26 return Paint(cross(cur), x, y, colour)
27}
28
29func TestPaintSetsCellAndPainter(cur realm, t *testing.T) {
30 reset()
31 alice := testutils.TestAddress("alice")
32
33 uassert.Equal(t, 1, paint(cur, alice, 3, 7, "red"))
34 uassert.Equal(t, "red", At(3, 7))
35 uassert.Equal(t, alice.String(), PainterAt(3, 7))
36 uassert.Equal(t, 1, Strokes())
37}
38
39// (x, y) is column, row — a paint at (3,7) must not land at (7,3).
40func TestCoordinatesAreXThenY(cur realm, t *testing.T) {
41 reset()
42 alice := testutils.TestAddress("alice")
43 paint(cur, alice, 3, 7, "blue")
44
45 uassert.Equal(t, "blue", At(3, 7))
46 uassert.Equal(t, "white", At(7, 3))
47}
48
49func TestLastWriteWins(cur realm, t *testing.T) {
50 reset()
51 alice := testutils.TestAddress("alice")
52 bob := testutils.TestAddress("bob")
53
54 paint(cur, alice, 0, 0, "red")
55 paint(cur, bob, 0, 0, "green")
56
57 uassert.Equal(t, "green", At(0, 0))
58 uassert.Equal(t, bob.String(), PainterAt(0, 0))
59 uassert.Equal(t, 2, Strokes()) // both strokes still counted
60}
61
62func TestOutOfBoundsPanics(cur realm, t *testing.T) {
63 reset()
64 alice := testutils.TestAddress("alice")
65 cases := [][2]int{{-1, 0}, {0, -1}, {Size, 0}, {0, Size}}
66 for _, c := range cases {
67 testing.SetRealm(testing.NewUserRealm(alice))
68 rec := revive(func() { Paint(cross(cur), c[0], c[1], "red") })
69 uassert.True(t, rec != nil)
70 }
71 uassert.Equal(t, 0, Strokes())
72}
73
74func TestUnknownColourPanics(cur realm, t *testing.T) {
75 reset()
76 alice := testutils.TestAddress("alice")
77 testing.SetRealm(testing.NewUserRealm(alice))
78 rec := revive(func() { Paint(cross(cur), 1, 1, "chartreuse") })
79 uassert.True(t, rec != nil)
80 uassert.Equal(t, 0, Strokes())
81}
82
83// Colour names are case- and space-insensitive.
84func TestColourNameIsNormalised(cur realm, t *testing.T) {
85 reset()
86 alice := testutils.TestAddress("alice")
87 paint(cur, alice, 2, 2, " GREEN ")
88 uassert.Equal(t, "green", At(2, 2))
89}
90
91func TestAtOutOfBoundsIsEmpty(t *testing.T) {
92 reset()
93 uassert.Equal(t, "", At(-1, 0))
94 uassert.Equal(t, "", At(Size, 0))
95 uassert.Equal(t, "", PainterAt(0, Size))
96}
97
98func TestUnpaintedCellIsWhiteWithNoPainter(t *testing.T) {
99 reset()
100 uassert.Equal(t, "white", At(5, 5))
101 uassert.Equal(t, "", PainterAt(5, 5))
102}
103
104func TestTallyRanksPainters(cur realm, t *testing.T) {
105 reset()
106 alice := testutils.TestAddress("alice")
107 bob := testutils.TestAddress("bob")
108 // alice paints 3, bob 1
109 paint(cur, alice, 0, 0, "red")
110 paint(cur, alice, 1, 0, "red")
111 paint(cur, alice, 2, 0, "red")
112 paint(cur, bob, 3, 0, "blue")
113
114 out := Render("")
115 ai := strings.Index(out, alice.String())
116 bi := strings.Index(out, bob.String())
117 uassert.True(t, ai >= 0)
118 uassert.True(t, bi >= 0)
119 uassert.True(t, ai < bi) // alice ranks first
120}
121
122func TestRenderEmptyCanvas(t *testing.T) {
123 reset()
124 out := Render("")
125 uassert.True(t, strings.Contains(out, "**0** strokes"))
126 // a blank canvas is Size rows of Size white blocks
127 uassert.Equal(t, Size*Size, strings.Count(out, "⬜"))
128 uassert.False(t, strings.Contains(out, "Top painters"))
129}
130
131func TestRenderCellLookup(cur realm, t *testing.T) {
132 reset()
133 alice := testutils.TestAddress("alice")
134 paint(cur, alice, 4, 9, "purple")
135
136 out := Render("/4,9")
137 uassert.True(t, strings.Contains(out, "Cell (4, 9)"))
138 uassert.True(t, strings.Contains(out, "**purple**"))
139 uassert.True(t, strings.Contains(out, alice.String()))
140}
141
142func TestRenderCellNeverPainted(t *testing.T) {
143 reset()
144 out := Render("/1,1")
145 uassert.True(t, strings.Contains(out, "Never painted"))
146}
147
148func TestRenderRejectsBadCoord(t *testing.T) {
149 reset()
150 for _, q := range []string{"/nope", "/1", "/99,99", "/a,b"} {
151 uassert.True(t, strings.Contains(Render(q), "Expected `x,y`"))
152 }
153}