asciiart_test.gno
3.44 Kb · 134 lines
1package asciiart
2
3import (
4 "strings"
5 "testing"
6
7 "gno.land/p/moul/kit/store/v0"
8 "gno.land/p/nt/testutils/v0"
9)
10
11func resetState() {
12 gallery = store.Named("piece")
13}
14
15func TestRenderDiamond(t *testing.T) {
16 got := RenderDiamond(3)
17 want := " *\n ***\n*****\n ***\n *"
18 if got != want {
19 t.Fatalf("RenderDiamond(3) =\n%s\nwant\n%s", got, want)
20 }
21}
22
23func TestRenderPyramid(t *testing.T) {
24 got := RenderPyramid(3)
25 want := " *\n ***\n*****"
26 if got != want {
27 t.Fatalf("RenderPyramid(3) =\n%s\nwant\n%s", got, want)
28 }
29}
30
31func TestRenderSierpinski(t *testing.T) {
32 got := RenderSierpinski(4)
33 want := "####\n# # \n## \n# "
34 if got != want {
35 t.Fatalf("RenderSierpinski(4) =\n%s\nwant\n%s", got, want)
36 }
37}
38
39func TestRenderSierpinskiRejectsNonPowerOfTwo(t *testing.T) {
40 defer func() {
41 if r := recover(); r == nil {
42 t.Fatal("expected panic for a non-power-of-two size")
43 }
44 }()
45 RenderSierpinski(5)
46}
47
48func TestRenderChecker(t *testing.T) {
49 got := RenderChecker(3)
50 want := "#.#\n.#.\n#.#"
51 if got != want {
52 t.Fatalf("RenderChecker(3) =\n%s\nwant\n%s", got, want)
53 }
54}
55
56func TestRenderPatternUnknown(t *testing.T) {
57 defer func() {
58 if r := recover(); r == nil {
59 t.Fatal("expected panic for an unknown pattern")
60 }
61 }()
62 renderPattern("spiral", 3)
63}
64
65// v1 asserted that its own padID() padded to width 6. That is the narrowest
66// ceiling in this repo: padID(10^6) is 7 characters and sorts before
67// padID(10^6-1), so from the millionth piece on the gallery would have
68// rendered out of order. The store key is 8 bytes for every id.
69func TestPadID(t *testing.T) {
70 if a, b := store.ID(2).Key(), store.ID(10).Key(); !(a < b) {
71 t.Error("id 2 should sort before id 10")
72 }
73 if a, b := store.ID(999999).Key(), store.ID(1000000).Key(); !(a < b) {
74 t.Error("ordering should survive one past v1's width-6 ceiling")
75 }
76}
77
78// Crossing: Generate mutates realm state, so the test needs `cur realm`.
79func TestGenerateAddsToGallery(cur realm, t *testing.T) {
80 resetState()
81 alice := testutils.TestAddress("alice")
82 testing.SetRealm(testing.NewUserRealm(alice))
83
84 art := Generate(cross(cur), "checker", 3)
85 if art != RenderChecker(3) {
86 t.Fatal("Generate should return the rendered art")
87 }
88 if gallery.LastID() != 1 {
89 t.Fatalf("LastID = %s, want 1", gallery.LastID())
90 }
91
92 // The store's Get returns (value, ok), so a stored nil is distinguishable
93 // from an absent id, which avl/v0's single-value Get cannot express.
94 v, ok := gallery.Get(1)
95 if !ok {
96 t.Fatal("expected piece #1 to exist in the gallery")
97 }
98 p := v.(*piece)
99 if p.Pattern != "checker" || p.Size != 3 || p.Author != alice {
100 t.Fatalf("unexpected piece: %+v", p)
101 }
102}
103
104func TestGenerateRejectsOutOfRangeSize(cur realm, t *testing.T) {
105 resetState()
106 alice := testutils.TestAddress("alice")
107 testing.SetRealm(testing.NewUserRealm(alice))
108
109 rec := revive(func() { Generate(cross(cur), "diamond", 0) })
110 if rec == nil {
111 t.Fatal("expected panic for size < 1")
112 }
113 rec = revive(func() { Generate(cross(cur), "diamond", maxSize+1) })
114 if rec == nil {
115 t.Fatal("expected panic for size > maxSize")
116 }
117}
118
119// Non-crossing: Render is a plain read.
120func TestRenderHomeEmptyGallery(t *testing.T) {
121 resetState()
122 out := Render("")
123 if !strings.Contains(out, "nothing generated yet") {
124 t.Fatal(`Render("") on an empty gallery should say so`)
125 }
126}
127
128func TestRenderPieceNotFound(t *testing.T) {
129 resetState()
130 out := Render("99")
131 if !strings.Contains(out, "No such piece") {
132 t.Fatal(`Render("99") on a missing piece should say so`)
133 }
134}