]> Git — Sourcephile - majurity.git/blob - test/HUnit.hs
Fix majorityValue: update the middlemost correctly.
[majurity.git] / test / HUnit.hs
1 {-# LANGUAGE OverloadedLists #-}
2 {-# LANGUAGE TypeFamilies #-}
3 {-# OPTIONS_GHC -fno-warn-orphans #-}
4 module HUnit where
5
6 import Test.Tasty
7 import Test.Tasty.HUnit
8
9 import Control.Arrow (second)
10 import Data.Hashable (Hashable)
11 import Data.Ratio ((%))
12 import Data.Tree (Tree(..))
13 import GHC.Exts (IsList(..))
14 import Prelude
15 import qualified Data.HashMap.Strict as HM
16
17 import Majority.Judgment
18 import Types
19
20 hunits :: TestTree
21 hunits =
22 testGroup "HUnit"
23 [ testGroup "MajorityValue" $
24 [ testCompareValue
25 (majorityValue $ Merit [(3,15), (2,7), (1,3), (0::Int,2)])
26 (majorityValue $ Merit [(3,16), (2,6), (1,2), (0,3)])
27 , testGroup "Merit"
28 [ let m = mkMerit ['A'..'F'] in
29 testMajorityValueOfMerits
30 [ (The, m [136,307,251,148,84,74])
31 ]
32 [ (The,
33 [ Middle ( 57 % 1) 'C' 'C'
34 , Middle (137 % 1) 'B' 'C'
35 , Middle (148 % 1) 'B' 'D'
36 , Middle ( 22 % 1) 'B' 'E'
37 , Middle ( 62 % 1) 'A' 'E'
38 , Middle ( 74 % 1) 'A' 'F'
39 ])
40 ]
41 , let m = mkMerit [ToReject .. TooGood] in
42 testMajorityValueOfMerits
43 [ (This, m [12,10,21,5,5,5,2])
44 , (That, m [12,16,22,3,3,3,1])
45 ]
46 [ (This, [ Middle (8 % 1) Acceptable Acceptable
47 , Middle (5 % 1) Insufficient Acceptable
48 , Middle (5 % 1) Insufficient Good
49 , Middle (5 % 1) ToReject VeryGood
50 , Middle (5 % 1) ToReject Perfect
51 , Middle (2 % 1) ToReject TooGood
52 ])
53 , (That, [ Middle ( 2 % 1) Acceptable Acceptable
54 , Middle (16 % 1) Insufficient Acceptable
55 , Middle ( 2 % 1) ToReject Acceptable
56 , Middle ( 3 % 1) ToReject Good
57 , Middle ( 3 % 1) ToReject VeryGood
58 , Middle ( 3 % 1) ToReject Perfect
59 , Middle ( 1 % 1) ToReject TooGood
60 ])
61 ]
62 ]
63 , testGroup "MajorityRanking"
64 [ testMajorityValueOfOpinions
65 [ (The, [No,No,No,No,Yes,Yes]) ]
66 [ (The, [ Middle (1 % 1) No No
67 , Middle (2 % 1) No Yes
68 ]) ]
69 , testMajorityValueOfOpinions
70 [ (The, [No,No,No,Yes,Yes,Yes]) ]
71 [ (The, [ Middle (3 % 1) No Yes ]) ]
72 , testMajorityValueOfOpinions
73 [ (The, [No,No,No,No,Yes,Yes,Yes]) ]
74 [ (The, [ Middle (1 % 2) No No
75 , Middle (3 % 1) No Yes ]) ]
76 , testMajorityValueOfOpinions
77 [ (This, [No,No,No,No,Yes,Yes])
78 , (That, [No,Yes,Yes,Yes,Yes,Yes])
79 ]
80 [ (This, [ Middle (1 % 1) No No
81 , Middle (2 % 1) No Yes
82 ])
83 , (That, [ Middle (2 % 1) Yes Yes
84 , Middle (1 % 1) No Yes
85 ])
86 ]
87 , testMajorityValueOfOpinions
88 [ (This, [No,No,No,No,No,No])
89 , (That, [No,No,No,Yes,Yes,Yes])
90 ]
91 [ (This, [Middle (3 % 1) No No])
92 , (That, [Middle (3 % 1) No Yes])
93 ]
94 , testMajorityValueOfOpinions
95 [ (This, [Yes,Yes,Yes,Yes,Yes,Yes])
96 , (That, [No,No,No,Yes,Yes,Yes])
97 ]
98 [ (This, [Middle (3 % 1) Yes Yes])
99 , (That, [Middle (3 % 1) No Yes])
100 ]
101 , testMajorityValueOfOpinions
102 [ (This, [No,No,Yes,Yes,Yes,Yes])
103 , (That, [No,No,No,Yes,Yes,Yes])
104 ]
105 [ (This, [ Middle (1 % 1) Yes Yes
106 , Middle (2 % 1) No Yes
107 ])
108 , (That, [ Middle (3 % 1) No Yes ])
109 ]
110 , testMajorityValueOfOpinions
111 [ (1::Int, [Perfect,Perfect,VeryGood,Perfect,Perfect,Perfect])
112 , (2, [Perfect,VeryGood,VeryGood,VeryGood,Good,VeryGood])
113 , (3, [Acceptable,Perfect,Good,VeryGood,VeryGood,Perfect])
114 , (4, [VeryGood,Good,Acceptable,Good,Good,Good])
115 , (5, [Good,Acceptable,VeryGood,Good,Good,Good])
116 , (6, [VeryGood,Acceptable,Insufficient,Acceptable,Acceptable,Good])
117 ]
118 [ (1, [ Middle (2 % 1) Perfect Perfect
119 , Middle (1 % 1) VeryGood Perfect
120 ])
121 , (2, [ Middle (2 % 1) VeryGood VeryGood
122 , Middle (1 % 1) Good Perfect
123 ])
124 , (3, [ Middle (1 % 1) VeryGood VeryGood
125 , Middle (1 % 1) Good Perfect
126 , Middle (1 % 1) Acceptable Perfect
127 ])
128 , (4, [ Middle (2 % 1) Good Good
129 , Middle (1 % 1) Acceptable VeryGood
130 ])
131 , (5, [ Middle (2 % 1) Good Good
132 , Middle (1 % 1) Acceptable VeryGood
133 ])
134 , (6, [ Middle (1 % 1) Acceptable Acceptable
135 , Middle (1 % 1) Acceptable Good
136 , Middle (1 % 1) Insufficient VeryGood
137 ])
138 ]
139 ]
140 , testGroup "Section"
141 [ testSection "0 judge"
142 ([]::Choices C2)
143 ([]::Judges Int G6)
144 (node0 [])
145 (Right $ node0 [])
146 , testSection "1 judge, default grade"
147 [This]
148 [(1::Int,ToReject)]
149 (node0 [])
150 (Right $ node0 [(This, [(1,[(ToReject,1%1)])])])
151 , testSection "1 judge, default grade, 2 choices"
152 [This, That]
153 [(1::Int,ToReject)]
154 (node0 [])
155 (Right $ node0 [ (This, [(1,[(ToReject,1%1)])])
156 , (That, [(1,[(ToReject,1%1)])])
157 ])
158 , testSection "1 judge, default grade"
159 [This]
160 [(1::Int,ToReject)]
161 (node0 [(This,[(1,Section Nothing Nothing)])])
162 (Right $ node0 [(This,[(1,[(ToReject,1%1)])])])
163 , testSection "2 judges, default grade"
164 [This]
165 [(1::Int,ToReject), (2::Int,ToReject)]
166 (node0
167 [ (This, [(1,Section Nothing Nothing)])
168 ])
169 (Right $ node0
170 [ (This, [ (1,[(ToReject,1%1)])
171 , (2,[(ToReject,1%1)])
172 ])
173 ])
174 , testSection "ErrorSection_unknown_choices"
175 []
176 [(1::Int,ToReject)]
177 (node0 [(This,[])])
178 (Left $ ErrorSection_unknown_choices [This])
179 , testSection "ErrorSection_unknown_choices"
180 []
181 [(1::Int,ToReject)]
182 (node0 [(This,[(2,Section Nothing Nothing)])])
183 (Left $ ErrorSection_unknown_choices [This])
184 , testSection "ErrorSection_unknown_choices"
185 [This]
186 [(1::Int,ToReject)]
187 (node0 [ (This,[(1,Section Nothing Nothing)])
188 , (That,[(2,Section Nothing Nothing)])
189 ])
190 (Left $ ErrorSection_unknown_choices [That])
191 , testSection "ErrorSection_unknown_judges"
192 [This]
193 [(1::Int,ToReject)]
194 (node0 [(This,[(2,Section Nothing Nothing)])])
195 (Left $ ErrorSection_unknown_judges [(This,[2])])
196 , testSection "1 judge, 1 grade"
197 [This]
198 [(1::Int,ToReject)]
199 (node0 [(This,[(1,Section Nothing (Just Acceptable))])])
200 (Right $ node0 [(This,[(1,[(Acceptable,1%1)])])])
201 , testSection "1 judge, 1 grade, 2 sections"
202 [This]
203 [(1::Int,ToReject)]
204 (Node
205 [ (This, [(1,Section Nothing (Just Acceptable))]) ]
206 [ node0 [(This, [(1,Section (Just $ 1%2) Nothing)])]
207 , node0 [(This, [(1,Section (Just $ 1%2) Nothing)])]
208 ])
209 (Right $ Node
210 [ (This, [(1,[(Acceptable,1%1)])]) ]
211 [ node0 [(This, [(1,[(Acceptable,1%1)])])]
212 , node0 [(This, [(1,[(Acceptable,1%1)])])]
213 ])
214 , testSection "sectionNodeShare with judge"
215 [This]
216 [(1::Int,ToReject), (2,Insufficient)]
217 (Node
218 [(This, [(1,Section Nothing (Just Acceptable))])]
219 [ node0 $ SectionNode (Just $ 1%3) [(This, [ (1,Section (Just $ 1%2) Nothing)
220 , (2,Section Nothing Nothing)
221 ])]
222 , node0 [(This, [ (1,Section (Just $ 1%2) Nothing)
223 , (2,Section Nothing (Just Good))
224 ])]
225 ])
226 (Right $ Node
227 [ (This, [ (1,[(Acceptable,1%2 + 1%2)])
228 , (2,[(Insufficient,1%3), (Good,2%3)])
229 ]) ]
230 [ node0 [(This, [ (1,[(Acceptable,1%1)])
231 , (2,[(Insufficient,1%1)])
232 ])]
233 , node0 [(This, [ (1,[(Acceptable,1%1)])
234 , (2,[(Good,1%1)])
235 ])]
236 ])
237 , testSection "sectionNodeShare without judge"
238 [This]
239 [(1::Int,ToReject), (2,Insufficient)]
240 (Node
241 [(This, [(1,Section Nothing (Just Acceptable))])]
242 [ node0 $ SectionNode (Just $ 1%3) [(This, [ (1,Section (Just $ 1%2) Nothing) ])]
243 , node0 [(This, [ (1,Section (Just $ 1%2) Nothing)
244 , (2,Section Nothing (Just Good))
245 ])]
246 ])
247 (Right $ Node
248 [ (This, [ (1,[(Acceptable,1%2 + 1%2)])
249 , (2,[(Insufficient,1%3), (Good,2%3)])
250 ]) ]
251 [ node0 [(This, [ (1,[(Acceptable,1%1)])
252 , (2,[(Insufficient,1%1)])
253 ])]
254 , node0 [(This, [ (1,[(Acceptable,1%1)])
255 , (2,[(Good,1%1)])
256 ])]
257 ])
258 , testSection "1 judge, 2 grades, 2 sections"
259 [This]
260 [(1::Int,ToReject)]
261 (Node
262 [ (This, [(1,Section Nothing (Just Acceptable))]) ]
263 [ node0 [(This, [(1,Section (Just $ 1%2) Nothing)])]
264 , node0 [(This, [(1,Section (Just $ 1%2) (Just Good))])]
265 ])
266 (Right $ Node
267 [(This, [(1,[(Acceptable,1%2), (Good,1%2)])])]
268 [ node0 [(This, [(1,[(Acceptable,1%1)])])]
269 , node0 [(This, [(1,[(Good,1%1)])])]
270 ])
271 , testSection "1 judge, 2 grades, 2 sections (1 default)"
272 [This]
273 [(1::Int,ToReject)]
274 (Node
275 [ (This, [(1,Section Nothing (Just Acceptable))]) ]
276 [ node0 [(This, [(1,Section Nothing Nothing)])]
277 , node0 [(This, [(1,Section (Just $ 1%2) (Just Good))])]
278 ])
279 (Right $ Node
280 [(This, [(1,[(Acceptable,1%2), (Good,1%2)])])]
281 [ node0 [(This, [(1,[(Acceptable,1%1)])])]
282 , node0 [(This, [(1,[(Good,1%1)])])]
283 ])
284 , testSection "1 judge, 3 grades, 3 sections (2 default)"
285 [This]
286 [(1::Int,ToReject)]
287 (Node
288 [ (This, [(1,Section Nothing (Just Acceptable))]) ]
289 [ node0 [(This, [(1,Section Nothing Nothing)])]
290 , node0 [(This, [(1,Section (Just $ 1%2) (Just Good))])]
291 , node0 [(This, [(1,Section Nothing (Just VeryGood))])]
292 ])
293 (Right $ Node
294 [(This, [(1,[(Acceptable,1%4), (Good,1%2), (VeryGood,1%4)])])]
295 [ node0 [(This, [(1,[(Acceptable,1%1)])])]
296 , node0 [(This, [(1,[(Good,1%1)])])]
297 , node0 [(This, [(1,[(VeryGood,1%1)])])]
298 ])
299 , testSection "ErrorSection_invalid_shares sum not 1"
300 [This]
301 [(1::Int,ToReject)]
302 (Node
303 [ (This, [(1,Section Nothing (Just Acceptable))]) ]
304 [ node0 [(This, [(1,Section (Just $ 1%2) Nothing)])]
305 , node0 [(This, [(1,Section (Just $ 1%3) (Just Good))])]
306 ])
307 (Left $ ErrorSection_invalid_shares [(This, [(1,[1%2,1%3])])])
308 , testSection "ErrorSection_invalid_shares negative share"
309 [This]
310 [(1::Int,ToReject)]
311 (Node
312 [ (This, [(1,Section Nothing (Just Acceptable))]) ]
313 [ node0 [(This, [(1,Section (Just $ 1%2) Nothing)])]
314 , node0 [(This, [(1,Section (Just $ -1%2) (Just Good))])]
315 ])
316 (Left $ ErrorSection_invalid_shares [(This, [(1,[1%2,-1%2])])])
317 , testSection "2 judges, 3 grade, 3 sections (1 default)"
318 [This]
319 [(1::Int,ToReject), (2::Int,ToReject)]
320 (Node
321 [ (This, [(1,Section Nothing (Just Acceptable))])
322 ]
323 [ node0
324 [ (This, [(1,Section Nothing Nothing)])
325 ]
326 , node0
327 [ (This, [(1,Section (Just $ 1%2) (Just Good))])
328 ]
329 ])
330 (Right $ Node
331 [ (This, [ (1,[(Acceptable,1%2), (Good,1%2)])
332 , (2,[(ToReject,1%1)])
333 ])
334 ]
335 [ node0
336 [ (This, [ (1,[(Acceptable,1%1)])
337 , (2,[(ToReject,1%1)])
338 ])
339 ]
340 , node0
341 [ (This, [ (1,[(Good,1%1)])
342 , (2,[(ToReject,1%1)])
343 ])
344 ]
345 ])
346 , testSection "2 judges, 4 grades, 5 sections (2 defaults)"
347 [This]
348 [(1::Int,ToReject), (2::Int,ToReject)]
349 (Node
350 [ (This, [(1,Section Nothing (Just Acceptable))])
351 ]
352 [ node0
353 [ (This, [(1,Section Nothing Nothing)])
354 ]
355 , node0
356 [ (This, [(1,Section (Just $ 1%2) (Just Good))])
357 ]
358 , Node
359 [ (This, [(1,Section Nothing (Just Good))])
360 ]
361 [ node0
362 [ (This, [ (1,Section Nothing (Just VeryGood))
363 , (2,Section Nothing (Just Insufficient))
364 ])
365 ]
366 ]
367 ])
368 (Right $ Node
369 [ (This, [ (1,[(Acceptable,1%4), (Good,1%2), (VeryGood,1%4)])
370 , (2,[(ToReject,2%3), (Insufficient,1%3)])
371 ])
372 ]
373 [ node0
374 [ (This, [ (1,[(Acceptable,1%1)])
375 , (2,[(ToReject,1%1)])
376 ])
377 ]
378 , node0
379 [ (This, [ (1,[(Good,1%1)])
380 , (2,[(ToReject,1%1)])
381 ])
382 ]
383 , Node
384 [ (This, [ (1,[(VeryGood,1%1)])
385 , (2,[(Insufficient,1%1)])
386 ])
387 ]
388 [ node0
389 [ (This, [ (1,[(VeryGood,1%1)])
390 , (2,[(Insufficient,1%1)])
391 ])
392 ]
393 ]
394 ])
395 , testSection "1 judge, default grade, 2 choices"
396 [This, That]
397 [(1::Int,ToReject)]
398 (node0 [])
399 (Right $ node0 [ (This,[(1,[(ToReject,1%1)])])
400 , (That,[(1,[(ToReject,1%1)])])
401 ])
402 , testSection "2 judges, 2 choices"
403 [This, That]
404 [(1::Int,ToReject), (2::Int,ToReject)]
405 (Node
406 [ ]
407 [ node0
408 [ (This, [(1,Section Nothing (Just Good))])
409 , (That, [(2,Section Nothing (Just Insufficient))])
410 ]
411 , node0
412 [ (This, [(1,Section Nothing (Just Acceptable))])
413 , (That, [(2,Section Nothing (Just VeryGood))])
414 ]
415 ])
416 (Right $ Node
417 [ (This, [ (1,[(Good,1%2), (Acceptable,1%2)])
418 , (2,[(ToReject,1%1)])
419 ])
420 , (That, [ (1,[(ToReject,1%1)])
421 , (2,[(Insufficient,1%2), (VeryGood,1%2)])
422 ])
423 ]
424 [ node0 [ (This, [ (1,[(Good,1%1)])
425 , (2,[(ToReject,1%1)])
426 ])
427 , (That, [ (1,[(ToReject,1%1)])
428 , (2,[(Insufficient,1%1)])
429 ])
430 ]
431 , node0 [ (This, [ (1,[(Acceptable,1%1)])
432 , (2,[(ToReject,1%1)])
433 ])
434 , (That, [ (1,[(ToReject,1%1)])
435 , (2,[(VeryGood,1%1)])
436 ])
437 ]
438 ])
439 , testSection "1 judge, 1 choice"
440 [This]
441 [(1::Int,ToReject)]
442 (Node []
443 [ node0 [ (This, [(1,Section (Just $ 1%8) (Just Acceptable))])
444 ]
445 , node0 [ (This, [(1,Section Nothing Nothing)])
446 ]
447 ])
448 (Right $ Node
449 [ (This, [(1,[(Acceptable,1%8), (ToReject,7%8)])])
450 ]
451 [ node0 [ (This, [(1,[(Acceptable, 1%1)])])
452 ]
453 , node0 [ (This, [(1,[(ToReject, 1%1)])])
454 ]
455 ])
456 , testSection "1 judge, 1 choice (missing judge)"
457 [This]
458 [(1::Int,ToReject)]
459 (Node []
460 [ node0 [ (This, [(1,Section (Just $ 1%8) (Just Acceptable))])
461 ]
462 , node0 [ (This, [])
463 ]
464 ])
465 (Right $ Node
466 [ (This, [(1,[(Acceptable,1%8), (ToReject,7%8)])])
467 ]
468 [ node0 [ (This, [(1,[(Acceptable, 1%1)])])
469 ]
470 , node0 [ (This, [(1,[(ToReject, 1%1)])])
471 ]
472 ])
473 , testSection "1 judge, 1 choice (missing judge)"
474 [This]
475 [(1::Int,ToReject)]
476 (Node []
477 [ node0 [ (This, [])
478 ]
479 , node0 [ (This, [(1,Section (Just $ 1%8) (Just Acceptable))])
480 ]
481 ])
482 (Right $ Node
483 [ (This, [(1,[(Acceptable,1%8), (ToReject,7%8)])])
484 ]
485 [ node0 [ (This, [(1,[(ToReject, 1%1)])])
486 ]
487 , node0 [ (This, [(1,[(Acceptable, 1%1)])])
488 ]
489 ])
490 , testSection "1 judge, 1 choice (missing choice)"
491 [This]
492 [(1::Int,ToReject)]
493 (Node []
494 [ node0 [ (This, [(1,Section (Just $ 1%8) (Just Acceptable))])
495 ]
496 , node0 [
497 ]
498 ])
499 (Right $ Node
500 [ (This, [(1,[(Acceptable,1%8), (ToReject,7%8)])])
501 ]
502 [ node0 [ (This, [(1,[(Acceptable, 1%1)])])
503 ]
504 , node0 [ (This, [(1,[(ToReject, 1%1)])])
505 ]
506 ])
507 , testSection "1 judge, 1 choice (missing choice)"
508 [This]
509 [(1::Int,ToReject)]
510 (Node []
511 [ node0 [
512 ]
513 , node0 [ (This, [(1,Section (Just $ 1%8) (Just Acceptable))])
514 ]
515 ])
516 (Right $ Node
517 [ (This, [(1,[(Acceptable,1%8), (ToReject,7%8)])])
518 ]
519 [ node0 [ (This, [(1,[(ToReject, 1%1)])])
520 ]
521 , node0 [ (This, [(1,[(Acceptable, 1%1)])])
522 ]
523 ])
524 , testSection "2 judges, 2 choices"
525 [This, That]
526 [(1::Int,ToReject), (2::Int,ToReject)]
527 (node0
528 [ (This, [(1,Section Nothing (Just Acceptable))])
529 , (That, [(2,Section (Just $ 1%8) (Just VeryGood))])
530 ])
531 (Right $ node0
532 [ (This, [ (1,[(Acceptable,1%1)])
533 , (2,[(ToReject,1%1)])
534 ])
535 , (That, [ (1,[(ToReject,1%1)])
536 , (2,[(VeryGood,1%1)])
537 ])
538 ])
539 , testSection "2 judges, 2 choices"
540 [This, That]
541 [(1::Int,ToReject), (2::Int,ToReject)]
542 (Node
543 [ ]
544 [ node0
545 [ (This, [(1,Section Nothing (Just Good))])
546 , (That, [(2,Section Nothing (Just Insufficient))])
547 ]
548 , node0
549 [ (This, [(1,Section Nothing (Just Acceptable))])
550 , (That, [(2,Section (Just $ 1%8) (Just VeryGood))])
551 ]
552 ])
553 (Right $ Node
554 [ (This, [ (1,[(Good,1%2), (Acceptable,1%2)])
555 , (2,[(ToReject,1%1)])
556 ])
557 , (That, [ (1,[(ToReject,1%1)])
558 , (2,[(Insufficient,7%8), (VeryGood,1%8)])
559 ])
560 ]
561 [ node0 [ (This, [ (1,[(Good,1%1)])
562 , (2,[(ToReject,1%1)])
563 ])
564 , (That, [ (1,[(ToReject,1%1)])
565 , (2,[(Insufficient,1%1)])
566 ])
567 ]
568 , node0 [ (This, [ (1,[(Acceptable,1%1)])
569 , (2,[(ToReject,1%1)])
570 ])
571 , (That, [ (1,[(ToReject,1%1)])
572 , (2,[(VeryGood,1%1)])
573 ])
574 ]
575 ])
576 , testSection "2 judges, 2 choices"
577 [This, That]
578 [(1::Int,ToReject), (2::Int,ToReject)]
579 (Node [ (This, [(1,Section Nothing (Just Acceptable))])
580 ]
581 [ node0 [ (This, [(1,Section Nothing Nothing)])
582 ]
583 , node0 [ (This, [ (1,Section (Just $ 1%2) (Just Good)) ])
584 , (That, [ (1,Section (Just $ 1%3) Nothing)
585 , (2,Section (Just $ 1%5) (Just Insufficient))
586 ])
587 ]
588 , Node [ (This, [(1,Section Nothing (Just Good))])
589 , (That, [(2,Section Nothing (Just VeryGood))])
590 ]
591 [ node0 [ (This, [ (1,Section Nothing (Just VeryGood))
592 , (2,Section Nothing (Just Insufficient))
593 ])
594 , (That, [ (1,Section Nothing (Just Acceptable)) ])
595 ]
596 , node0 [ (This, [ (1,Section Nothing (Just Acceptable))
597 ])
598 , (That, [ (1,Section Nothing (Just VeryGood))
599 , (2,Section Nothing (Just Good))
600 ])
601 ]
602 ]
603 ])
604 (Right $
605 Node [ (This, [ (1,[(Acceptable,1%4 + 1%8), (Good,1%2), (VeryGood,1%8)])
606 , (2,[(ToReject,1%3 + 1%3 + 1%6), (Insufficient,1%6)])
607 ])
608 , (That, [ (1,[(ToReject,1%3 + 1%3), (Acceptable,1%6), (VeryGood,1%6)])
609 , (2,[(ToReject,4%10), (Insufficient,1%5), (VeryGood,4%20), (Good,4%20)])
610 ])
611 ]
612 [ node0 [ (This, [ (1,[(Acceptable,1%1)]) -- 1%4
613 , (2,[(ToReject,1%1)]) -- 1%3
614 ])
615 , (That, [ (1,[(ToReject,1%1)]) -- 1%3
616 , (2,[(ToReject,1%1)]) -- 4%10
617 ])
618 ]
619 , node0 [ (This, [ (1,[(Good,1%1)]) -- 1%2
620 , (2,[(ToReject,1%1)]) -- 1%3
621 ])
622 , (That, [ (1,[(ToReject,1%1)]) -- 1%3
623 , (2,[(Insufficient,1%1)]) -- 1%5
624 ])
625 ]
626 , Node [ (This, [ (1,[(VeryGood,1%2), (Acceptable,1%2)]) -- 1%4
627 , (2,[(Insufficient,1%2), (ToReject,1%2)]) -- 1%3
628 ])
629 , (That, [ (1,[(Acceptable,1%2), (VeryGood,1%2)]) -- 1%3
630 , (2,[(VeryGood,1%2), (Good,1%2)]) -- 4%10
631 ])
632 ]
633 [ node0 [ (This, [ (1,[(VeryGood,1%1)])
634 , (2,[(Insufficient,1%1)])
635 ])
636 , (That, [ (1,[(Acceptable,1%1)])
637 , (2,[(VeryGood,1%1)])
638 ])
639 ]
640 , node0 [ (This, [ (1,[(Acceptable,1%1)])
641 , (2,[(ToReject,1%1)])
642 ])
643 , (That, [ (1,[(VeryGood,1%1)])
644 , (2,[(Good,1%1)])
645 ])
646 ]
647 ]
648 ]
649 )
650 ]
651 ]
652 ]
653
654 elide :: String -> String
655 elide s | length s > 42 = take 42 s ++ ['…']
656 | otherwise = s
657
658 mkMerit :: (Ord grade, Show grade) => [grade] -> [Share] -> Merit grade
659 mkMerit gs = fromList . (gs`zip`)
660
661 mkMeritByChoice ::
662 (Eq choice, Hashable choice, Ord grade) =>
663 [(choice,[grade])] ->
664 MeritByChoice choice grade
665 mkMeritByChoice os =
666 meritByChoice $ fromList $
667 second (fromList . zip [1::Int ..] . (singleGrade <$>)) <$> os
668
669 testCompareValue :: (Ord grade, Show grade) =>
670 MajorityValue grade -> MajorityValue grade -> TestTree
671 testCompareValue x y =
672 testGroup (elide $ show (unMajorityValue x, unMajorityValue y))
673 [ testCase "x == x" $ x`compare`x @?= EQ
674 , testCase "y == y" $ y`compare`y @?= EQ
675 , testCase "x < y" $ x`compare`y @?= LT
676 , testCase "y > x" $ y`compare`x @?= GT
677 ]
678
679 testMajorityRanking ::
680 (Eq choice, Hashable choice, Ord grade, Show grade, Show choice) =>
681 [(choice, [grade])] ->
682 MajorityRanking choice grade -> TestTree
683 testMajorityRanking os expect =
684 testCase (elide $ show os) $
685 majorityRanking (mkMeritByChoice os) @?= expect
686
687 testMajorityValueOfOpinions ::
688 (Show grade, Show choice, Ord grade, Eq choice, Hashable choice) =>
689 [(choice, [grade])] ->
690 [(choice, [Middle grade])] -> TestTree
691 testMajorityValueOfOpinions os expect =
692 testCase (elide $ show os) $
693 majorityValueByChoice (mkMeritByChoice os)
694 @?= (MajorityValue<$>HM.fromList expect)
695
696 testMajorityValueOfMerits ::
697 (Show grade, Show choice, Ord grade, Eq choice, Hashable choice) =>
698 MeritByChoice choice grade ->
699 [(choice, [Middle grade])] -> TestTree
700 testMajorityValueOfMerits ms expect =
701 testCase (elide $ show $ unMeritByChoice ms) $
702 majorityValueByChoice ms
703 @?= (MajorityValue<$>HM.fromList expect)
704
705 testSection ::
706 Eq choice =>
707 Hashable choice =>
708 Eq judge =>
709 Hashable judge =>
710 Ord grade =>
711 Show choice =>
712 Show judge =>
713 Show grade =>
714 String ->
715 Choices choice ->
716 Judges judge grade ->
717 Tree (SectionNode choice judge grade) ->
718 Either (ErrorSection choice judge grade)
719 (Tree (OpinionsByChoice choice judge grade)) ->
720 TestTree
721 testSection msg cs js ss expect =
722 testCase (elide msg) $
723 opinionsBySection cs js ss @?= expect
724
725 node0 :: a -> Tree a
726 node0 = (`Node`[])
727
728 instance (Eq choice, Hashable choice) => IsList (SectionNode choice judge grade) where
729 type Item (SectionNode choice judge grade) = (choice, SectionByJudge judge grade)
730 fromList = SectionNode Nothing . fromList
731 toList = GHC.Exts.toList . sectionByJudgeByChoice