polls_test.gno
3.76 Kb · 154 lines
1package polls
2
3import (
4 "strings"
5 "testing"
6
7 "gno.land/p/nt/testutils/v0"
8 "gno.land/p/nt/uassert/v0"
9)
10
11var (
12 alice = testutils.TestAddress("alice")
13 bob = testutils.TestAddress("bob")
14 carol = testutils.TestAddress("carol")
15)
16
17// resetState clears package-level state between tests so cases are independent.
18func resetState() {
19 polls = nil
20 nextID = 0
21}
22
23func TestParseOptions(t *testing.T) {
24 tests := []struct {
25 name string
26 input string
27 want []string
28 }{
29 {"simple", "a,b,c", []string{"a", "b", "c"}},
30 {"trims spaces", " yes , no ", []string{"yes", "no"}},
31 {"drops empties", "a,,b, ,c", []string{"a", "b", "c"}},
32 {"single", "only", []string{"only"}},
33 {"all blank", " , ,", nil},
34 }
35 for _, tt := range tests {
36 got := parseOptions(tt.input)
37 if len(got) != len(tt.want) {
38 t.Errorf("%s: len = %d, want %d (%v)", tt.name, len(got), len(tt.want), got)
39 continue
40 }
41 for i := range got {
42 if got[i] != tt.want[i] {
43 t.Errorf("%s: [%d] = %q, want %q", tt.name, i, got[i], tt.want[i])
44 }
45 }
46 }
47}
48
49func TestCreateAndVote(cur realm, t *testing.T) {
50 resetState()
51 testing.SetRealm(testing.NewUserRealm(alice))
52
53 id := CreatePoll(cross(cur), "Best chain?", "gno,eth,btc")
54 if id != 0 {
55 t.Fatalf("first poll id = %d, want 0", id)
56 }
57 if PollCount() != 1 {
58 t.Fatalf("PollCount = %d, want 1", PollCount())
59 }
60
61 // alice votes gno.
62 Vote(cross(cur), id, 0)
63
64 // bob votes eth.
65 testing.SetRealm(testing.NewUserRealm(bob))
66 Vote(cross(cur), id, 1)
67
68 // carol votes gno.
69 testing.SetRealm(testing.NewUserRealm(carol))
70 Vote(cross(cur), id, 0)
71
72 p := getPoll(id)
73 if p.Tallies[0] != 2 {
74 t.Errorf("gno tally = %d, want 2", p.Tallies[0])
75 }
76 if p.Tallies[1] != 1 {
77 t.Errorf("eth tally = %d, want 1", p.Tallies[1])
78 }
79 if total(p.Tallies) != 3 {
80 t.Errorf("total = %d, want 3", total(p.Tallies))
81 }
82}
83
84func TestDoubleVotePanics(cur realm, t *testing.T) {
85 resetState()
86 testing.SetRealm(testing.NewUserRealm(alice))
87
88 id := CreatePoll(cross(cur), "Coffee or tea?", "coffee,tea")
89 Vote(cross(cur), id, 0)
90
91 // A second vote by the same address aborts (cross-realm panic).
92 uassert.AbortsWithMessage(t, cur, "address already voted on this poll", func() {
93 Vote(cross(cur), id, 1)
94 })
95}
96
97func TestVoteBounds(cur realm, t *testing.T) {
98 resetState()
99 testing.SetRealm(testing.NewUserRealm(alice))
100
101 id := CreatePoll(cross(cur), "A or B?", "a,b")
102
103 uassert.AbortsWithMessage(t, cur, "option index out of range", func() {
104 Vote(cross(cur), id, 5)
105 })
106}
107
108func TestCreatePollNeedsTwoOptions(cur realm, t *testing.T) {
109 resetState()
110 testing.SetRealm(testing.NewUserRealm(alice))
111
112 uassert.AbortsWithMessage(t, cur, "a poll needs at least 2 options", func() {
113 CreatePoll(cross(cur), "One?", "only")
114 })
115}
116
117func TestRender(cur realm, t *testing.T) {
118 resetState()
119 testing.SetRealm(testing.NewUserRealm(alice))
120
121 // Empty index.
122 if got := Render(""); !strings.Contains(got, "No polls yet") {
123 t.Errorf("empty Render should mention no polls, got:\n%s", got)
124 }
125
126 id := CreatePoll(cross(cur), "Pick one", "x,y")
127 Vote(cross(cur), id, 0)
128
129 // Index lists the poll and bar chart glyphs.
130 idx := Render("")
131 if !strings.Contains(idx, "Pick one") {
132 t.Errorf("index missing question:\n%s", idx)
133 }
134 if !strings.Contains(idx, "▓") || !strings.Contains(idx, "░") {
135 t.Errorf("index missing bar glyphs:\n%s", idx)
136 }
137 if !strings.Contains(idx, "Total votes: 1") {
138 t.Errorf("index missing total votes:\n%s", idx)
139 }
140 if !strings.Contains(idx, "100%") {
141 t.Errorf("index missing 100%% for the sole vote:\n%s", idx)
142 }
143
144 // Single-poll path.
145 single := Render("0")
146 if !strings.Contains(single, "Poll #0") {
147 t.Errorf("single Render missing poll header:\n%s", single)
148 }
149
150 // Unknown path.
151 if got := Render("99"); !strings.Contains(got, "not found") {
152 t.Errorf("unknown poll should say not found, got:\n%s", got)
153 }
154}