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}