1 | from typing import List, Dict
|
---|
2 | import unittest
|
---|
3 | from unittest.mock import Mock
|
---|
4 |
|
---|
5 | from unitpy.GeneralTests import GeneralTests
|
---|
6 |
|
---|
7 | from geniusweb.actions.PartyId import PartyId
|
---|
8 | from geniusweb.actions.Vote import Vote
|
---|
9 | from geniusweb.actions.Votes import Votes
|
---|
10 | from geniusweb.issuevalue.Bid import Bid
|
---|
11 | from geniusweb.voting.CollectedVotes import CollectedVotes
|
---|
12 |
|
---|
13 |
|
---|
14 | class CollectedVotesTest (unittest.TestCase, GeneralTests[CollectedVotes]):
|
---|
15 |
|
---|
16 | bidA = Mock(Bid)
|
---|
17 | bidB = Mock(Bid)
|
---|
18 | a = Mock(Bid)
|
---|
19 | b = Mock(Bid)
|
---|
20 | c = Mock(Bid)
|
---|
21 | d = Mock(Bid)
|
---|
22 | party1 = PartyId("party1")
|
---|
23 | party2 = PartyId("party2")
|
---|
24 | party3 = PartyId("party3")
|
---|
25 | party4 = PartyId("party4")
|
---|
26 |
|
---|
27 | partyP = PartyId("partyP")
|
---|
28 | partyQ = PartyId("partyQ")
|
---|
29 | partyR = PartyId("partyR")
|
---|
30 | partyS = PartyId("partyS")
|
---|
31 |
|
---|
32 | votePA2 = Vote(partyP, bidA, 2, 9)
|
---|
33 | voteQA2 = Vote(partyQ, bidA, 2, 9)
|
---|
34 | voteQA3 = Vote(partyQ, bidA, 3, 9)
|
---|
35 | voteQB3 = Vote(partyQ, bidB, 3, 9)
|
---|
36 | voteQB2 = Vote(partyQ, bidB, 2, 9)
|
---|
37 | voteRA2 = Vote(partyR, bidA, 2, 9)
|
---|
38 | voteRA3 = Vote(partyR, bidA, 3, 9)
|
---|
39 | voteRA4 = Vote(partyR, bidA, 4, 9)
|
---|
40 | voteRB2 = Vote(partyR, bidB, 2, 9)
|
---|
41 |
|
---|
42 | allpowers:Dict[PartyId,int] = {}
|
---|
43 |
|
---|
44 | cv1 = CollectedVotes({}, {})
|
---|
45 | cv1a = CollectedVotes({}, {})
|
---|
46 |
|
---|
47 | votes = Votes(partyP, set([votePA2]))
|
---|
48 | cv2 = CollectedVotes({partyP: votes},{partyP: 1})
|
---|
49 |
|
---|
50 |
|
---|
51 | allpowers[partyP]= 1
|
---|
52 | allpowers[partyQ]=1
|
---|
53 | allpowers[partyR]= 1
|
---|
54 | allpowers[partyS]=1
|
---|
55 |
|
---|
56 |
|
---|
57 | def getGeneralTestData(self)->List[List[CollectedVotes]]:
|
---|
58 | return [[self.cv1, self.cv1a], [self.cv2]]
|
---|
59 |
|
---|
60 | def getGeneralTestStrings(self)->List[str] :
|
---|
61 | return ["CollectedVotes.\\{\\}.*\\{\\}.*",
|
---|
62 | "CollectedVotes.\\{partyP=Votes.*Vote.partyP.*Mock.*,2.*\\}.*\\{partyP=1\\}.*"]
|
---|
63 |
|
---|
64 |
|
---|
65 | def testGetAllBids(self):
|
---|
66 | allvotes:Dict[PartyId, Vote] = {}
|
---|
67 | allvotes[self.partyP]= Votes(self.partyP, set([self.votePA2]))
|
---|
68 | allvotes[self.partyQ]= Votes(self.partyQ,
|
---|
69 | set([self.voteQA2, self.voteQB3]))
|
---|
70 |
|
---|
71 | allbids:Dict[Bid, Set[Vote]] = CollectedVotes(allvotes, self.allpowers)\
|
---|
72 | .getAllBids()
|
---|
73 | self.assertEqual(2, len(allbids))
|
---|
74 | self.assertEqual(set([self.votePA2, self.voteQA2]),
|
---|
75 | allbids.get(self.bidA))
|
---|
76 | self.assertEqual(set([self.voteQB3]), allbids.get(self.bidB))
|
---|
77 |
|
---|
78 | def testGetMaxSubset2(self):
|
---|
79 | votes = set([self.votePA2, self.voteQA2])
|
---|
80 | cv = CollectedVotes({},self.allpowers)
|
---|
81 | parties = cv._getMaxPowerGroup(votes)
|
---|
82 | self.assertEqual(set([self.partyP, self.partyQ]), parties)
|
---|
83 |
|
---|
84 | # test the optimized code similarly
|
---|
85 | parties = cv._getMaxPowerGroupBreathFirst(votes)
|
---|
86 | self.assertEqual(set([self.partyP, self.partyQ]), parties)
|
---|
87 |
|
---|
88 | def testGetMaxSubset3(self):
|
---|
89 | votes = set([self.votePA2, self.voteQA2, self.voteRA4])
|
---|
90 | cv = CollectedVotes({},self.allpowers)
|
---|
91 |
|
---|
92 | parties = cv._getMaxPowerGroup(votes)
|
---|
93 | # party R wants 4 votes so we can't satisfy
|
---|
94 | self.assertEqual(set([self.partyP, self.partyQ]), parties)
|
---|
95 |
|
---|
96 | # test the optimized code similarly
|
---|
97 | parties = cv._getMaxPowerGroupBreathFirst(votes)
|
---|
98 | self.assertEqual(set([self.partyP, self.partyQ]), parties)
|
---|
99 |
|
---|
100 | def testGetMaxSubset3b(self):
|
---|
101 | votes = set([self.votePA2, self.voteQA2, self.voteRA3])
|
---|
102 | cv = CollectedVotes({},self.allpowers)
|
---|
103 | parties = cv._getMaxPowerGroup(votes)
|
---|
104 | # party R wants 4 votes so we can't satisfy
|
---|
105 | self.assertEqual(set([self.partyP, self.partyQ, self.partyR]),
|
---|
106 | parties)
|
---|
107 |
|
---|
108 | # test the optimized code similarly
|
---|
109 | parties = cv._getMaxPowerGroupBreathFirst(votes)
|
---|
110 | self.assertEquals(set([self.partyP, self.partyQ, self.partyR]),
|
---|
111 | parties)
|
---|
112 |
|
---|
113 | def testNoConsensus(self):
|
---|
114 | votes = set([self.voteQA3, self.voteRA3])
|
---|
115 | cv =CollectedVotes({}, self.allpowers)
|
---|
116 | self.assertEqual(set(), cv._getMaxPowerGroup(votes))
|
---|
117 | self.assertEqual(set(), cv._getMaxPowerGroupBreathFirst(votes))
|
---|
118 |
|
---|
119 | def testGetMaxAgreements(self) :
|
---|
120 | allvotes:Map[PartyId, Votes] = {}
|
---|
121 | allvotes[self.partyP]= Votes(self.partyP, set([self.votePA2]))
|
---|
122 | allvotes[self.partyQ]= Votes(self.partyQ,
|
---|
123 | set([self.voteQA2, self.voteQB2]))
|
---|
124 | allvotes[self.partyR]= Votes(self.partyR,
|
---|
125 | set([self.voteRA4, self.voteRB2]))
|
---|
126 |
|
---|
127 | allagrees:Map[Bid, Set[PartyId]] = CollectedVotes(allvotes,
|
---|
128 | self.allpowers).getMaxAgreements()
|
---|
129 | self.assertEquals(set([self.partyP, self.partyQ]),
|
---|
130 | allagrees.get(self.bidA))
|
---|
131 | self.assertEqual(set([self.partyQ, self.partyR]),
|
---|
132 | allagrees.get(self.bidB))
|
---|
133 |
|
---|
134 |
|
---|
135 | def testGetNoAgreements(self) :
|
---|
136 | allvotes:Dict[PartyId, Votes] = {}
|
---|
137 | allvotes[self.partyP]= Votes(self.partyP, set([self.votePA2]))
|
---|
138 | allagrees = CollectedVotes(allvotes, self.allpowers).getMaxAgreements()
|
---|
139 | self.assertEquals({}, allagrees)
|
---|
140 |
|
---|
141 | def testgetConsensusGroupsTest(self):
|
---|
142 | cv = CollectedVotes({},self.allpowers)
|
---|
143 |
|
---|
144 | consensus = cv._getConsensusGroups(
|
---|
145 | set([self.votePA2, self.voteQA2]))
|
---|
146 | # should give 1 solution: both parties join in.
|
---|
147 | print(consensus)
|
---|
148 | self.assertEqual(1, len(consensus))
|
---|
149 | self.assertEqual(2, len(next(iter(consensus))))
|
---|
150 |
|
---|
151 | def testgetConsensusGroupsTestPQR(self):
|
---|
152 | cv = CollectedVotes({},self.allpowers)
|
---|
153 |
|
---|
154 | consensus = cv._getConsensusGroups(
|
---|
155 | set([self.votePA2, self.voteQA2, self.voteRA4]))
|
---|
156 | # should give 1 solution: P and Q join in. 4 is unreachable.
|
---|
157 | print(consensus)
|
---|
158 | self.assertEqual(1, len(consensus))
|
---|
159 | self.assertEqual(2, len(next(iter(consensus))))
|
---|
160 |
|
---|
161 | def testgetConsensusGroupsTestPQR2(self):
|
---|
162 | cv = CollectedVotes({},self.allpowers)
|
---|
163 |
|
---|
164 | consensus = cv._getConsensusGroups(
|
---|
165 | set([self.votePA2, self.voteQA2, self.voteRA2]))
|
---|
166 | # should give 4 solutions: P+Q, P+R, Q+R and P+Q+R
|
---|
167 | print(consensus)
|
---|
168 | self.assertEqual(4, len(consensus))
|
---|
169 |
|
---|
170 | def testgetConsensusGroupsTestRExtraPower(self) :
|
---|
171 | # give R extra power to reach the 4 if other 2 join
|
---|
172 | allpowers = {self.partyP: 1, self.partyQ: 1, self.partyR: 2}
|
---|
173 |
|
---|
174 | cv = CollectedVotes({}, allpowers)
|
---|
175 |
|
---|
176 | consensus = cv._getConsensusGroups(
|
---|
177 | set([self.votePA2, self.voteQA2, self.voteRA4]))
|
---|
178 | # should give solutions P+Q and P+Q+R
|
---|
179 | print(consensus)
|
---|
180 | self.assertEqual(2, len(consensus))
|
---|
181 | lengths = set([ len(con) for con in consensus ])
|
---|
182 | self.assertEqual(set([2,3]), lengths)
|
---|
183 |
|
---|
184 | def testWith(self):
|
---|
185 | allvotes:Map[PartyId, Votes] = {}
|
---|
186 | allvotes[self.partyP]= Votes(self.partyP, set([self.votePA2]))
|
---|
187 | cv = CollectedVotes(allvotes, self.allpowers)
|
---|
188 | self.assertEqual(1, len(cv.getVotes().keys()))
|
---|
189 | cv = cv.With(Votes(self.partyQ, set([self.voteQA2])), 2)
|
---|
190 | self.assertEquals(2, len(cv.getVotes().keys()))
|
---|
191 |
|
---|
192 | def testWithout(self):
|
---|
193 | allvotes:Map[PartyId, Votes] = {}
|
---|
194 | allvotes[self.partyP]= Votes(self.partyP, set([self.votePA2]))
|
---|
195 | allvotes[self.partyQ]= Votes(self.partyQ,
|
---|
196 | set([self.voteQA2, self.voteQB2]))
|
---|
197 | allvotes[self.partyR]= Votes(self.partyR,
|
---|
198 | set([self.voteRA4, self.voteRB2]))
|
---|
199 |
|
---|
200 | # give R extra power to reach the 4 if other 2 join
|
---|
201 | allpowers = {self.partyP: 1,self.partyQ: 1,self.partyR: 2}
|
---|
202 |
|
---|
203 | cv = CollectedVotes(allvotes, allpowers)
|
---|
204 |
|
---|
205 | self.assertEqual(3, len(cv.getVotes()))
|
---|
206 | cv = cv.Without(set([self.partyP, self.partyQ]))
|
---|
207 | self.assertEqual(1, len(cv.getVotes()))
|
---|
208 | self.assertEqual(1, len(cv.getPowers()))
|
---|
209 |
|
---|
210 | def testgetConsensusGroupMaxPower(self):
|
---|
211 | P = Vote(self.partyP, self.bidA, 2, 3)
|
---|
212 | Q = Vote(self.partyQ, self.bidA, 2, 3)
|
---|
213 | R = Vote(self.partyR, self.bidA, 2, 3)
|
---|
214 | S = Vote(self.partyS, self.bidA, 2, 3)
|
---|
215 | allvotes:Map[PartyId, Votes] = {}
|
---|
216 | allvotes[self.partyP]= Votes(self.partyP, set([P]))
|
---|
217 | allvotes[self.partyQ]= Votes(self.partyQ, set([Q]))
|
---|
218 | allvotes[self.partyR]= Votes(self.partyR, set([R]))
|
---|
219 | allvotes[self.partyS]= Votes(self.partyS, set([S]))
|
---|
220 |
|
---|
221 | cv = CollectedVotes(allvotes, self.allpowers)
|
---|
222 | consensus = cv._getConsensusGroups(
|
---|
223 | set([P, Q, R, S]))
|
---|
224 | print(consensus)
|
---|
225 | # check that all are size 2 or 3.
|
---|
226 | for set1 in consensus:
|
---|
227 | self.assertTrue(len(set1) == 2 or len(set1) == 3)
|
---|
228 |
|
---|
229 | def testgetConsensusGroupMaxPowerModifiedPartyPowers(self):
|
---|
230 | # party R gets power 2.
|
---|
231 | P = Vote(self.partyP, self.bidA, 2, 3)
|
---|
232 | Q = Vote(self.partyQ, self.bidA, 2, 3)
|
---|
233 | R = Vote(self.partyR, self.bidA, 2, 3)
|
---|
234 | allvotes:Map[PartyId, Votes] = {}
|
---|
235 | allvotes[self.partyP]= Votes(self.partyP, set([P]))
|
---|
236 | allvotes[self.partyQ]= Votes(self.partyQ, set([Q]))
|
---|
237 | allvotes[self.partyR]= Votes(self.partyR, set([R]))
|
---|
238 |
|
---|
239 | powers={self.partyP: 1,self.partyQ: 1, self.partyR: 2}
|
---|
240 |
|
---|
241 | cv = CollectedVotes(allvotes, powers)
|
---|
242 | consensus = cv._getConsensusGroups(set([P, Q, R]))
|
---|
243 | print(consensus)
|
---|
244 | # R has power 2 now. That means groups of size 3 are not posisble.
|
---|
245 | # check that all are size 2.
|
---|
246 | for set1 in consensus:
|
---|
247 | self.assertTrue(len(set1) == 2)
|
---|
248 |
|
---|
249 | def testRandomOrderOfSet(self):
|
---|
250 | # this test that a Set of parties does not have
|
---|
251 | # the fixed order of the list #1878
|
---|
252 | # not really testing our code but crucial for proper working.
|
---|
253 | list1 = [self.partyQ, self.partyR, self.partyS]
|
---|
254 | # #1878 does Set randomize somewhat?
|
---|
255 | parties = set(list1)
|
---|
256 | self.assertNotEquals(list1, [parties])
|
---|
257 |
|
---|
258 | list2 = [list]
|
---|
259 | list2.append(self.partyP)
|
---|
260 | parties = set(list2)
|
---|
261 | self.assertNotEquals(list2, [parties])
|
---|