record_test.gno
9.32 Kb ยท 355 lines
1package commondao
2
3import (
4 "std"
5 "testing"
6
7 "gno.land/p/nt/uassert"
8 "gno.land/p/nt/urequire"
9)
10
11func TestVotingRecordDefaults(t *testing.T) {
12 var (
13 record VotingRecord
14 user = std.Address("g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5")
15 )
16
17 uassert.Equal(t, record.Size(), 0)
18 uassert.Equal(t, record.VoteCount(ChoiceYes), 0)
19 uassert.Equal(t, record.VoteCount(ChoiceNo), 0)
20 uassert.Equal(t, record.VoteCount(ChoiceAbstain), 0)
21 uassert.False(t, record.HasVoted(user))
22}
23
24func TestVotingRecordAddVote(t *testing.T) {
25 cases := []struct {
26 name string
27 setup func(*VotingRecord)
28 votes []Vote
29 yesCount, noCount, abstainCount int
30 updated bool
31 }{
32 {
33 name: "single vote",
34 votes: []Vote{
35 {
36 Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
37 Choice: ChoiceYes,
38 },
39 },
40 yesCount: 1,
41 },
42 {
43 name: "multiple votes",
44 votes: []Vote{
45 {
46 Address: "g125t352u4pmdrr57emc4pe04y40sknr5ztng5mt",
47 Choice: ChoiceNo,
48 },
49 {
50 Address: "g12chzmwxw8sezcxe9h2csp0tck76r4ptwdlyyqk",
51 Choice: ChoiceYes,
52 },
53 {
54 Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
55 Choice: ChoiceNo,
56 },
57 {
58 Address: "g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj",
59 Choice: ChoiceAbstain,
60 },
61 },
62 yesCount: 1,
63 noCount: 2,
64 abstainCount: 1,
65 },
66 {
67 name: "vote exists",
68 votes: []Vote{
69 {
70 Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5",
71 Choice: ChoiceYes,
72 },
73 },
74 setup: func(r *VotingRecord) {
75 r.AddVote(Vote{Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", Choice: ChoiceAbstain})
76 },
77 yesCount: 1,
78 abstainCount: 0,
79 updated: true,
80 },
81 }
82
83 for _, tc := range cases {
84 t.Run(tc.name, func(t *testing.T) {
85 var (
86 record VotingRecord
87 updated bool
88 )
89
90 if tc.setup != nil {
91 tc.setup(&record)
92 }
93
94 for _, v := range tc.votes {
95 updated = updated || record.AddVote(v)
96 }
97
98 urequire.Equal(t, updated, tc.updated, "expect vote to be updated")
99 urequire.Equal(t, record.Size(), len(tc.votes), "expect record size to match")
100
101 var i int
102 record.Iterate(0, record.Size(), false, func(v Vote) bool {
103 uassert.Equal(t, v.Address, tc.votes[i].Address)
104 uassert.Equal(t, string(v.Choice), string(tc.votes[i].Choice))
105 uassert.True(t, record.HasVoted(v.Address))
106
107 i++
108 return false
109 })
110
111 uassert.Equal(t, record.VoteCount(ChoiceYes), tc.yesCount, "expect YES vote count to match")
112 uassert.Equal(t, record.VoteCount(ChoiceNo), tc.noCount, "expect NO vote count to match")
113 uassert.Equal(t, record.VoteCount(ChoiceAbstain), tc.abstainCount, "expect ABSTAIN vote count to match")
114 })
115 }
116}
117
118func TestFindMostVotedChoice(t *testing.T) {
119 cases := []struct {
120 name string
121 setup func(*VotingRecord)
122 choice VoteChoice
123 }{
124 {
125 name: "no votes",
126 choice: ChoiceNone,
127 },
128 {
129 name: "one vote",
130 setup: func(r *VotingRecord) {
131 r.AddVote(Vote{Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", Choice: ChoiceYes})
132 },
133 choice: ChoiceYes,
134 },
135 {
136 name: "multiple votes",
137 setup: func(r *VotingRecord) {
138 r.AddVote(Vote{Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", Choice: ChoiceNo})
139 r.AddVote(Vote{Address: "g12chzmwxw8sezcxe9h2csp0tck76r4ptwdlyyqk", Choice: ChoiceYes})
140 r.AddVote(Vote{Address: "g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj", Choice: ChoiceNo})
141 },
142 choice: ChoiceNo,
143 },
144 {
145 name: "tie",
146 setup: func(r *VotingRecord) {
147 r.AddVote(Vote{Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", Choice: ChoiceYes})
148 r.AddVote(Vote{Address: "g12chzmwxw8sezcxe9h2csp0tck76r4ptwdlyyqk", Choice: ChoiceNo})
149 },
150 choice: ChoiceNone,
151 },
152 }
153
154 for _, tc := range cases {
155 t.Run(tc.name, func(t *testing.T) {
156 var record VotingRecord
157
158 if tc.setup != nil {
159 tc.setup(&record)
160 }
161
162 choice := FindMostVotedChoice(record.Readonly())
163
164 uassert.Equal(t, string(choice), string(tc.choice))
165 })
166 }
167}
168
169func TestSelectChoiceByAbsoluteMajority(t *testing.T) {
170 cases := []struct {
171 name string
172 setup func(*VotingRecord)
173 choice VoteChoice
174 membersCount int
175 success bool
176 }{
177 {
178 name: "no votes",
179 choice: ChoiceNone,
180 membersCount: 3,
181 success: false,
182 },
183 {
184 name: "majority",
185 setup: func(r *VotingRecord) {
186 r.AddVote(Vote{Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", Choice: ChoiceYes})
187 r.AddVote(Vote{Address: "g12chzmwxw8sezcxe9h2csp0tck76r4ptwdlyyqk", Choice: ChoiceYes})
188 r.AddVote(Vote{Address: "g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj", Choice: ChoiceNo})
189 },
190 choice: ChoiceYes,
191 membersCount: 3,
192 success: true,
193 },
194 {
195 name: "no majority",
196 setup: func(r *VotingRecord) {
197 r.AddVote(Vote{Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", Choice: ChoiceYes})
198 r.AddVote(Vote{Address: "g12chzmwxw8sezcxe9h2csp0tck76r4ptwdlyyqk", Choice: ChoiceNo})
199 },
200 choice: "",
201 membersCount: 3,
202 success: false,
203 },
204 {
205 name: "majority with abstain vote",
206 setup: func(r *VotingRecord) {
207 r.AddVote(Vote{Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", Choice: ChoiceYes})
208 r.AddVote(Vote{Address: "g12chzmwxw8sezcxe9h2csp0tck76r4ptwdlyyqk", Choice: ChoiceYes})
209 r.AddVote(Vote{Address: "g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj", Choice: ChoiceAbstain})
210 },
211 choice: ChoiceYes,
212 membersCount: 3,
213 success: true,
214 },
215 }
216
217 for _, tc := range cases {
218 t.Run(tc.name, func(t *testing.T) {
219 var record VotingRecord
220
221 if tc.setup != nil {
222 tc.setup(&record)
223 }
224
225 choice, success := SelectChoiceByAbsoluteMajority(record.Readonly(), tc.membersCount)
226
227 uassert.Equal(t, string(tc.choice), string(choice), "choice")
228 uassert.Equal(t, tc.success, success, "success")
229 })
230 }
231}
232
233func TestSelectChoiceBySuperMajority(t *testing.T) {
234 cases := []struct {
235 name string
236 setup func(*VotingRecord)
237 choice VoteChoice
238 membersCount int
239 success bool
240 }{
241 {
242 name: "no votes",
243 choice: ChoiceNone,
244 membersCount: 3,
245 success: false,
246 },
247 {
248 name: "majority",
249 setup: func(r *VotingRecord) {
250 r.AddVote(Vote{Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", Choice: ChoiceYes})
251 r.AddVote(Vote{Address: "g12chzmwxw8sezcxe9h2csp0tck76r4ptwdlyyqk", Choice: ChoiceYes})
252 r.AddVote(Vote{Address: "g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj", Choice: ChoiceNo})
253 },
254 choice: ChoiceYes,
255 membersCount: 3,
256 success: true,
257 },
258 {
259 name: "no majority",
260 setup: func(r *VotingRecord) {
261 r.AddVote(Vote{Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", Choice: ChoiceYes})
262 r.AddVote(Vote{Address: "g12chzmwxw8sezcxe9h2csp0tck76r4ptwdlyyqk", Choice: ChoiceNo})
263 },
264 choice: "",
265 membersCount: 3,
266 success: false,
267 },
268 {
269 name: "majority with abstain vote",
270 setup: func(r *VotingRecord) {
271 r.AddVote(Vote{Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", Choice: ChoiceYes})
272 r.AddVote(Vote{Address: "g12chzmwxw8sezcxe9h2csp0tck76r4ptwdlyyqk", Choice: ChoiceYes})
273 r.AddVote(Vote{Address: "g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj", Choice: ChoiceAbstain})
274 },
275 choice: ChoiceYes,
276 membersCount: 3,
277 success: true,
278 },
279 }
280
281 for _, tc := range cases {
282 t.Run(tc.name, func(t *testing.T) {
283 var record VotingRecord
284
285 if tc.setup != nil {
286 tc.setup(&record)
287 }
288
289 choice, success := SelectChoiceBySuperMajority(record.Readonly(), tc.membersCount)
290
291 uassert.Equal(t, string(tc.choice), string(choice), "choice")
292 uassert.Equal(t, tc.success, success, "success")
293 })
294 }
295}
296
297func TestSelectChoiceByPlurality(t *testing.T) {
298 cases := []struct {
299 name string
300 setup func(*VotingRecord)
301 choice VoteChoice
302 success bool
303 }{
304 {
305 name: "no votes",
306 choice: ChoiceNone,
307 success: false,
308 },
309 {
310 name: "plurality",
311 setup: func(r *VotingRecord) {
312 r.AddVote(Vote{Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", Choice: ChoiceYes})
313 r.AddVote(Vote{Address: "g12chzmwxw8sezcxe9h2csp0tck76r4ptwdlyyqk", Choice: ChoiceYes})
314 r.AddVote(Vote{Address: "g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj", Choice: ChoiceNo})
315 },
316 choice: ChoiceYes,
317 success: true,
318 },
319 {
320 name: "no plurality",
321 setup: func(r *VotingRecord) {
322 r.AddVote(Vote{Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", Choice: ChoiceYes})
323 r.AddVote(Vote{Address: "g12chzmwxw8sezcxe9h2csp0tck76r4ptwdlyyqk", Choice: ChoiceNo})
324 },
325 choice: "",
326 success: false,
327 },
328 {
329 name: "plurality with abstain vote",
330 setup: func(r *VotingRecord) {
331 r.AddVote(Vote{Address: "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5", Choice: ChoiceYes})
332 r.AddVote(Vote{Address: "g12chzmwxw8sezcxe9h2csp0tck76r4ptwdlyyqk", Choice: ChoiceYes})
333 r.AddVote(Vote{Address: "g1vh7krmmzfua5xjmkatvmx09z37w34lsvd2mxa5", Choice: ChoiceNo})
334 r.AddVote(Vote{Address: "g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj", Choice: ChoiceAbstain})
335 },
336 choice: ChoiceYes,
337 success: true,
338 },
339 }
340
341 for _, tc := range cases {
342 t.Run(tc.name, func(t *testing.T) {
343 var record VotingRecord
344
345 if tc.setup != nil {
346 tc.setup(&record)
347 }
348
349 choice, success := SelectChoiceByPlurality(record.Readonly())
350
351 uassert.Equal(t, string(tc.choice), string(choice), "choice")
352 uassert.Equal(t, tc.success, success, "success")
353 })
354 }
355}