[100] | 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])
|
---|