sapor 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (332) hide show
  1. checksums.yaml +7 -0
  2. data/Area Class Diagram.dia +0 -0
  3. data/Area Class Diagram.png +0 -0
  4. data/Class Diagram.dia +0 -0
  5. data/Class Diagram.png +0 -0
  6. data/Example-Catalonia.md +361 -0
  7. data/Example-Flanders.md +486 -0
  8. data/Example-Greece.md +25 -0
  9. data/Example-Oslo.md +678 -0
  10. data/Example-UnitedKingdom-Referendum.md +132 -0
  11. data/Examples.md +15 -0
  12. data/LICENSE +674 -0
  13. data/README.md +103 -0
  14. data/Rakefile +18 -0
  15. data/Technical Documentation.md +14 -0
  16. data/bin/create_installation_package.sh +49 -0
  17. data/bin/install.sh +45 -0
  18. data/bin/sapor.rb +24 -0
  19. data/bin/sapor.sh +106 -0
  20. data/data/hu/hungary-2014.txt +1680 -0
  21. data/data/hu/hungary_2014_screen_scraper.rb +48 -0
  22. data/data/hu/hungary_2014_to_psv.rb +80 -0
  23. data/data/hu/index-2014.txt +106 -0
  24. data/data/pl/2015-gl-lis-okr.csv +42 -0
  25. data/data/pl/poland_2015_to_psv.rb +79 -0
  26. data/data/pl/poland_2015_to_psv_with_ko_and_rsw.rb +94 -0
  27. data/data/pl/poland_2015_to_psv_with_ko_konf_kp_l_and_zp.rb +100 -0
  28. data/data/pl/poland_2015_to_psv_with_ko_sld_and_wi.rb +92 -0
  29. data/data/pl/poland_2015_to_psv_with_sld.rb +84 -0
  30. data/data/pl/poland_2015_to_psv_with_sld_and_wi.rb +85 -0
  31. data/data/uk/inject_ukip_2015_as_brexit_2019_in_2017.rb +54 -0
  32. data/data/uk/united_kingdom_2015.txt +651 -0
  33. data/data/uk/united_kingdom_2015_to_psv.rb +104 -0
  34. data/data/uk/united_kingdom_2017.txt +651 -0
  35. data/data/uk/united_kingdom_2017_to_psv.rb +104 -0
  36. data/data/uk/united_kingdom_2017_to_psv_with_brexit_and_chuk.rb +113 -0
  37. data/data/uk/united_kingdom_2017_to_psv_with_tig.rb +111 -0
  38. data/lib/sapor.rb +150 -0
  39. data/lib/sapor/binomials_cache.rb +45 -0
  40. data/lib/sapor/combinations_distribution.rb +222 -0
  41. data/lib/sapor/denominators.rb +67 -0
  42. data/lib/sapor/dichotomies.rb +138 -0
  43. data/lib/sapor/dichotomy.rb +164 -0
  44. data/lib/sapor/first_past_the_post.rb +82 -0
  45. data/lib/sapor/largest_remainder.rb +118 -0
  46. data/lib/sapor/log4r_logger.rb +49 -0
  47. data/lib/sapor/log_facade.rb +40 -0
  48. data/lib/sapor/multi_district_leveled_proportional.rb +64 -0
  49. data/lib/sapor/multi_district_proportional.rb +123 -0
  50. data/lib/sapor/multi_district_variable_threshold_proportional.rb +128 -0
  51. data/lib/sapor/number_formatter.rb +45 -0
  52. data/lib/sapor/options.rb +73 -0
  53. data/lib/sapor/poll.rb +286 -0
  54. data/lib/sapor/polychotomy.rb +200 -0
  55. data/lib/sapor/pseudorandom_multirange_enumerator.rb +87 -0
  56. data/lib/sapor/referendum_polychotomy.rb +165 -0
  57. data/lib/sapor/regional_data/area.rb +82 -0
  58. data/lib/sapor/regional_data/austria.rb +84 -0
  59. data/lib/sapor/regional_data/belgium-brussels-2014.psv +46 -0
  60. data/lib/sapor/regional_data/belgium-brussels-20190526.psv +33 -0
  61. data/lib/sapor/regional_data/belgium-flanders-2014.psv +80 -0
  62. data/lib/sapor/regional_data/belgium-flanders-20190526.psv +74 -0
  63. data/lib/sapor/regional_data/belgium-wallonia-2014.psv +114 -0
  64. data/lib/sapor/regional_data/belgium-wallonia-20190526.psv +93 -0
  65. data/lib/sapor/regional_data/belgium.rb +97 -0
  66. data/lib/sapor/regional_data/belgium_brussels.rb +62 -0
  67. data/lib/sapor/regional_data/belgium_flanders.rb +64 -0
  68. data/lib/sapor/regional_data/belgium_wallonia.rb +63 -0
  69. data/lib/sapor/regional_data/catalonia-2012-2015.psv +100 -0
  70. data/lib/sapor/regional_data/catalonia-2012.psv +87 -0
  71. data/lib/sapor/regional_data/catalonia-2015-jxcat.psv +68 -0
  72. data/lib/sapor/regional_data/catalonia-2015-no-jxsi.psv +68 -0
  73. data/lib/sapor/regional_data/catalonia-2015.psv +63 -0
  74. data/lib/sapor/regional_data/catalonia-jxcat.rb +109 -0
  75. data/lib/sapor/regional_data/catalonia-no-jxsi.rb +96 -0
  76. data/lib/sapor/regional_data/catalonia.rb +96 -0
  77. data/lib/sapor/regional_data/denmark-20150618-with-e-and-p.psv +164 -0
  78. data/lib/sapor/regional_data/denmark-20150618-with-e.psv +153 -0
  79. data/lib/sapor/regional_data/denmark-20150618-with-p.psv +153 -0
  80. data/lib/sapor/regional_data/denmark-20150618.psv +142 -0
  81. data/lib/sapor/regional_data/denmark.rb +128 -0
  82. data/lib/sapor/regional_data/denmark_with_e.rb +128 -0
  83. data/lib/sapor/regional_data/denmark_with_e_and_p.rb +128 -0
  84. data/lib/sapor/regional_data/denmark_with_p.rb +128 -0
  85. data/lib/sapor/regional_data/estonia.rb +88 -0
  86. data/lib/sapor/regional_data/european-union-great-britain-20140522-brexit-chuk.psv +172 -0
  87. data/lib/sapor/regional_data/european-union-great-britain-20140522.psv +146 -0
  88. data/lib/sapor/regional_data/european-union-great-britain-20190523.psv +141 -0
  89. data/lib/sapor/regional_data/european-union-ireland-2014-ia-ri-sd.psv +64 -0
  90. data/lib/sapor/regional_data/european-union-ireland-2014-ia-sd.psv +60 -0
  91. data/lib/sapor/regional_data/european-union-ireland-2014-ia.psv +56 -0
  92. data/lib/sapor/regional_data/european-union-ireland-2014-sd.psv +56 -0
  93. data/lib/sapor/regional_data/european-union-ireland-2014.psv +50 -0
  94. data/lib/sapor/regional_data/european-union-ireland-20190524-ia.psv +58 -0
  95. data/lib/sapor/regional_data/european-union-ireland-20190524.psv +52 -0
  96. data/lib/sapor/regional_data/european_union_27_austria.rb +76 -0
  97. data/lib/sapor/regional_data/european_union_27_croatia.rb +81 -0
  98. data/lib/sapor/regional_data/european_union_27_denmark.rb +77 -0
  99. data/lib/sapor/regional_data/european_union_27_estonia.rb +74 -0
  100. data/lib/sapor/regional_data/european_union_27_finland.rb +74 -0
  101. data/lib/sapor/regional_data/european_union_27_ireland.rb +96 -0
  102. data/lib/sapor/regional_data/european_union_27_ireland_with_ia.rb +97 -0
  103. data/lib/sapor/regional_data/european_union_27_italy.rb +84 -0
  104. data/lib/sapor/regional_data/european_union_27_netherlands.rb +81 -0
  105. data/lib/sapor/regional_data/european_union_27_poland.rb +84 -0
  106. data/lib/sapor/regional_data/european_union_27_romania.rb +78 -0
  107. data/lib/sapor/regional_data/european_union_27_slovakia.rb +80 -0
  108. data/lib/sapor/regional_data/european_union_27_spain.rb +82 -0
  109. data/lib/sapor/regional_data/european_union_27_sweden.rb +76 -0
  110. data/lib/sapor/regional_data/european_union_austria.rb +76 -0
  111. data/lib/sapor/regional_data/european_union_bulgaria.rb +81 -0
  112. data/lib/sapor/regional_data/european_union_croatia.rb +81 -0
  113. data/lib/sapor/regional_data/european_union_cyprus.rb +72 -0
  114. data/lib/sapor/regional_data/european_union_czech_republic.rb +82 -0
  115. data/lib/sapor/regional_data/european_union_denmark.rb +77 -0
  116. data/lib/sapor/regional_data/european_union_estonia.rb +74 -0
  117. data/lib/sapor/regional_data/european_union_finland.rb +74 -0
  118. data/lib/sapor/regional_data/european_union_flanders.rb +74 -0
  119. data/lib/sapor/regional_data/european_union_france.rb +84 -0
  120. data/lib/sapor/regional_data/european_union_france_2019.rb +84 -0
  121. data/lib/sapor/regional_data/european_union_french_community_of_belgium.rb +73 -0
  122. data/lib/sapor/regional_data/european_union_germany.rb +86 -0
  123. data/lib/sapor/regional_data/european_union_great_britain.rb +98 -0
  124. data/lib/sapor/regional_data/european_union_greece.rb +77 -0
  125. data/lib/sapor/regional_data/european_union_hungary.rb +76 -0
  126. data/lib/sapor/regional_data/european_union_ireland.rb +96 -0
  127. data/lib/sapor/regional_data/european_union_ireland_with_ia.rb +97 -0
  128. data/lib/sapor/regional_data/european_union_italy.rb +84 -0
  129. data/lib/sapor/regional_data/european_union_latvia.rb +81 -0
  130. data/lib/sapor/regional_data/european_union_lithuania.rb +80 -0
  131. data/lib/sapor/regional_data/european_union_luxembourg.rb +75 -0
  132. data/lib/sapor/regional_data/european_union_malta.rb +71 -0
  133. data/lib/sapor/regional_data/european_union_netherlands.rb +81 -0
  134. data/lib/sapor/regional_data/european_union_northern_ireland.rb +75 -0
  135. data/lib/sapor/regional_data/european_union_poland.rb +84 -0
  136. data/lib/sapor/regional_data/european_union_portugal.rb +75 -0
  137. data/lib/sapor/regional_data/european_union_romania.rb +78 -0
  138. data/lib/sapor/regional_data/european_union_slovakia.rb +81 -0
  139. data/lib/sapor/regional_data/european_union_slovenia.rb +85 -0
  140. data/lib/sapor/regional_data/european_union_spain.rb +82 -0
  141. data/lib/sapor/regional_data/european_union_sweden.rb +76 -0
  142. data/lib/sapor/regional_data/finland-20150419-with-sin.psv +224 -0
  143. data/lib/sapor/regional_data/finland-20150419.psv +212 -0
  144. data/lib/sapor/regional_data/finland.rb +107 -0
  145. data/lib/sapor/regional_data/finland_with_sin.rb +107 -0
  146. data/lib/sapor/regional_data/flanders-2014.psv +96 -0
  147. data/lib/sapor/regional_data/flanders-20190526.psv +87 -0
  148. data/lib/sapor/regional_data/flanders.rb +115 -0
  149. data/lib/sapor/regional_data/france.rb +38 -0
  150. data/lib/sapor/regional_data/greece.rb +92 -0
  151. data/lib/sapor/regional_data/hungary-2014.psv +2104 -0
  152. data/lib/sapor/regional_data/hungary.rb +116 -0
  153. data/lib/sapor/regional_data/iceland-20161029-midflokkurinn.psv +94 -0
  154. data/lib/sapor/regional_data/iceland-20161029.psv +88 -0
  155. data/lib/sapor/regional_data/iceland-20171028.psv +85 -0
  156. data/lib/sapor/regional_data/iceland.rb +133 -0
  157. data/lib/sapor/regional_data/latvia-20141004-kpv-p-par.psv +109 -0
  158. data/lib/sapor/regional_data/latvia-20141004-kpv-par.psv +103 -0
  159. data/lib/sapor/regional_data/latvia-20141004-kpv.psv +97 -0
  160. data/lib/sapor/regional_data/latvia-20141004.psv +89 -0
  161. data/lib/sapor/regional_data/latvia.rb +112 -0
  162. data/lib/sapor/regional_data/latvia_kpv.rb +112 -0
  163. data/lib/sapor/regional_data/latvia_kpv_p_par.rb +112 -0
  164. data/lib/sapor/regional_data/latvia_kpv_par.rb +112 -0
  165. data/lib/sapor/regional_data/luxembourg-20131020.psv +76 -0
  166. data/lib/sapor/regional_data/luxembourg.rb +82 -0
  167. data/lib/sapor/regional_data/netherlands.rb +108 -0
  168. data/lib/sapor/regional_data/norway.rb +425 -0
  169. data/lib/sapor/regional_data/norwegian_municipality.rb +68 -0
  170. data/lib/sapor/regional_data/poland-20151025-with-ko-and-l-without-n-po-r-and-zl.psv +321 -0
  171. data/lib/sapor/regional_data/poland-20151025-with-ko-konf-kp-l-and-zp-without-k-k15-n-pis-po-psl-r-and-zl.psv +280 -0
  172. data/lib/sapor/regional_data/poland-20151025-with-ko-sld-and-wi-without-n-po-and-zl.psv +403 -0
  173. data/lib/sapor/regional_data/poland-20151025-with-sld-and-wi-without-zl.psv +444 -0
  174. data/lib/sapor/regional_data/poland-20151025-with-sld-without-zl.psv +403 -0
  175. data/lib/sapor/regional_data/poland-20151025.psv +403 -0
  176. data/lib/sapor/regional_data/poland.rb +125 -0
  177. data/lib/sapor/regional_data/poland_with_ko_and_l_without_n_po_r_and_zl.rb +122 -0
  178. data/lib/sapor/regional_data/poland_with_ko_konf_kp_l_and_zp_without_k_k15_n_pis_po_psl_r_and_zl.rb +123 -0
  179. data/lib/sapor/regional_data/poland_with_ko_sld_and_wi_without_n_po_and_zl.rb +125 -0
  180. data/lib/sapor/regional_data/poland_with_sld_and_wi_without_zl.rb +126 -0
  181. data/lib/sapor/regional_data/poland_with_sld_without_zl.rb +126 -0
  182. data/lib/sapor/regional_data/portugal-20151004-with-a-and-ch-without-paf.psv +438 -0
  183. data/lib/sapor/regional_data/portugal-20151004-with-a-and-il-without-paf.psv +438 -0
  184. data/lib/sapor/regional_data/portugal-20151004-with-a-ch-and-il-without-paf.psv +461 -0
  185. data/lib/sapor/regional_data/portugal-20151004-with-a-without-paf.psv +415 -0
  186. data/lib/sapor/regional_data/portugal-20151004-with-ch-and-il-without-paf.psv +438 -0
  187. data/lib/sapor/regional_data/portugal-20151004-without-paf.psv +392 -0
  188. data/lib/sapor/regional_data/portugal-20151004.psv +370 -0
  189. data/lib/sapor/regional_data/portugal.rb +101 -0
  190. data/lib/sapor/regional_data/portugal_with_a_and_ch_without_paf.rb +92 -0
  191. data/lib/sapor/regional_data/portugal_with_a_and_il_without_paf.rb +92 -0
  192. data/lib/sapor/regional_data/portugal_with_a_ch_and_il_without_paf.rb +92 -0
  193. data/lib/sapor/regional_data/portugal_with_a_without_paf.rb +92 -0
  194. data/lib/sapor/regional_data/portugal_with_ch_and_il_without_paf.rb +92 -0
  195. data/lib/sapor/regional_data/portugal_without_paf.rb +92 -0
  196. data/lib/sapor/regional_data/slovakia.rb +81 -0
  197. data/lib/sapor/regional_data/slovenia.rb +114 -0
  198. data/lib/sapor/regional_data/spain-20160626.psv +619 -0
  199. data/lib/sapor/regional_data/spain.rb +136 -0
  200. data/lib/sapor/regional_data/sweden.rb +92 -0
  201. data/lib/sapor/regional_data/sweden_20140914.rb +89 -0
  202. data/lib/sapor/regional_data/united_kingdom-2015.psv +4358 -0
  203. data/lib/sapor/regional_data/united_kingdom-20170608-brexit-chuk.psv +5154 -0
  204. data/lib/sapor/regional_data/united_kingdom-20170608-brexit.psv +4521 -0
  205. data/lib/sapor/regional_data/united_kingdom-20170608-tig.psv +4529 -0
  206. data/lib/sapor/regional_data/united_kingdom-20170608.psv +3894 -0
  207. data/lib/sapor/regional_data/united_kingdom.rb +94 -0
  208. data/lib/sapor/regional_data/united_kingdom_with_brexit.rb +110 -0
  209. data/lib/sapor/regional_data/united_kingdom_with_brexit_and_chuk.rb +111 -0
  210. data/lib/sapor/regional_data/united_kingdom_with_tig.rb +111 -0
  211. data/lib/sapor/regional_data/utopia.rb +66 -0
  212. data/lib/sapor/regional_data/wallonia-2014.psv +101 -0
  213. data/lib/sapor/regional_data/wallonia-20190526.psv +88 -0
  214. data/lib/sapor/regional_data/wallonia.rb +112 -0
  215. data/lib/sapor/representatives_polychotomy.rb +338 -0
  216. data/lib/sapor/single_district_proportional.rb +75 -0
  217. data/sapor.gemspec +35 -0
  218. data/spec/integration/area_spec.rb +28 -0
  219. data/spec/integration/poll_spec.rb +112 -0
  220. data/spec/integration/sample.poll +8 -0
  221. data/spec/spec_helper.rb +31 -0
  222. data/spec/unit/area_spec.rb +115 -0
  223. data/spec/unit/austria_spec.rb +76 -0
  224. data/spec/unit/belgium_brussels_spec.rb +58 -0
  225. data/spec/unit/belgium_flanders_spec.rb +62 -0
  226. data/spec/unit/belgium_spec.rb +26 -0
  227. data/spec/unit/belgium_wallonia_spec.rb +65 -0
  228. data/spec/unit/binomials_cache_spec.rb +34 -0
  229. data/spec/unit/catalonia_spec.rb +74 -0
  230. data/spec/unit/combinations_distribution_spec.rb +241 -0
  231. data/spec/unit/denmark_spec.rb +56 -0
  232. data/spec/unit/denmark_with_e_and_p_spec.rb +58 -0
  233. data/spec/unit/denmark_with_e_spec.rb +57 -0
  234. data/spec/unit/denmark_with_p_spec.rb +57 -0
  235. data/spec/unit/denominators_spec.rb +40 -0
  236. data/spec/unit/dichotomies_spec.rb +154 -0
  237. data/spec/unit/dichotomy_spec.rb +320 -0
  238. data/spec/unit/estonia_spec.rb +65 -0
  239. data/spec/unit/european_union_27_austria_spec.rb +61 -0
  240. data/spec/unit/european_union_27_croatia_spec.rb +60 -0
  241. data/spec/unit/european_union_27_denmark_spec.rb +62 -0
  242. data/spec/unit/european_union_27_estonia_spec.rb +94 -0
  243. data/spec/unit/european_union_27_finland_spec.rb +75 -0
  244. data/spec/unit/european_union_27_ireland_spec.rb +72 -0
  245. data/spec/unit/european_union_27_ireland_with_ia_spec.rb +74 -0
  246. data/spec/unit/european_union_27_italy_spec.rb +69 -0
  247. data/spec/unit/european_union_27_netherlands_spec.rb +81 -0
  248. data/spec/unit/european_union_27_poland_spec.rb +69 -0
  249. data/spec/unit/european_union_27_romania_spec.rb +67 -0
  250. data/spec/unit/european_union_27_slovakia_spec.rb +111 -0
  251. data/spec/unit/european_union_27_spain_spec.rb +130 -0
  252. data/spec/unit/european_union_27_sweden_spec.rb +89 -0
  253. data/spec/unit/european_union_austria_spec.rb +61 -0
  254. data/spec/unit/european_union_bulgaria_spec.rb +97 -0
  255. data/spec/unit/european_union_croatia_spec.rb +59 -0
  256. data/spec/unit/european_union_cyprus_spec.rb +65 -0
  257. data/spec/unit/european_union_czech_republic_spec.rb +125 -0
  258. data/spec/unit/european_union_denmark_spec.rb +61 -0
  259. data/spec/unit/european_union_estonia_spec.rb +93 -0
  260. data/spec/unit/european_union_finland_spec.rb +75 -0
  261. data/spec/unit/european_union_flanders_spec.rb +56 -0
  262. data/spec/unit/european_union_france_2019_spec.rb +73 -0
  263. data/spec/unit/european_union_france_spec.rb +73 -0
  264. data/spec/unit/european_union_french_community_of_belgium_spec.rb +61 -0
  265. data/spec/unit/european_union_germany_spec.rb +90 -0
  266. data/spec/unit/european_union_great_britain_spec.rb +87 -0
  267. data/spec/unit/european_union_greece_spec.rb +148 -0
  268. data/spec/unit/european_union_hungary_spec.rb +57 -0
  269. data/spec/unit/european_union_ireland_spec.rb +72 -0
  270. data/spec/unit/european_union_ireland_with_ia_spec.rb +74 -0
  271. data/spec/unit/european_union_italy_spec.rb +69 -0
  272. data/spec/unit/european_union_latvia_spec.rb +76 -0
  273. data/spec/unit/european_union_lithuania_spec.rb +68 -0
  274. data/spec/unit/european_union_luxembourg_spec.rb +63 -0
  275. data/spec/unit/european_union_malta_spec.rb +60 -0
  276. data/spec/unit/european_union_netherlands_spec.rb +81 -0
  277. data/spec/unit/european_union_northern_ireland_spec.rb +66 -0
  278. data/spec/unit/european_union_poland_spec.rb +69 -0
  279. data/spec/unit/european_union_portugal_spec.rb +77 -0
  280. data/spec/unit/european_union_romania_spec.rb +67 -0
  281. data/spec/unit/european_union_slovakia_spec.rb +111 -0
  282. data/spec/unit/european_union_slovenia_spec.rb +77 -0
  283. data/spec/unit/european_union_spain_spec.rb +129 -0
  284. data/spec/unit/european_union_sweden_spec.rb +89 -0
  285. data/spec/unit/finland_spec.rb +65 -0
  286. data/spec/unit/finland_with_sin_spec.rb +67 -0
  287. data/spec/unit/first_past_the_post_spec.rb +54 -0
  288. data/spec/unit/flanders_spec.rb +70 -0
  289. data/spec/unit/france_spec.rb +32 -0
  290. data/spec/unit/greece_spec.rb +118 -0
  291. data/spec/unit/hungary_spec.rb +132 -0
  292. data/spec/unit/iceland_spec.rb +57 -0
  293. data/spec/unit/largest_remainder_spec.rb +79 -0
  294. data/spec/unit/latvia_kpv_p_par_spec.rb +38 -0
  295. data/spec/unit/latvia_kpv_par_spec.rb +38 -0
  296. data/spec/unit/latvia_kpv_spec.rb +38 -0
  297. data/spec/unit/latvia_spec.rb +60 -0
  298. data/spec/unit/luxembourg_spec.rb +54 -0
  299. data/spec/unit/multi_district_leveled_proportional_spec.rb +49 -0
  300. data/spec/unit/multi_district_proportional_spec.rb +81 -0
  301. data/spec/unit/netherlands_spec.rb +107 -0
  302. data/spec/unit/norway_spec.rb +64 -0
  303. data/spec/unit/norwegian_municipality_spec.rb +89 -0
  304. data/spec/unit/number_formatter_spec.rb +173 -0
  305. data/spec/unit/poland_spec.rb +62 -0
  306. data/spec/unit/poland_with_ko_and_l_without_n_po_r_and_zl_spec.rb +60 -0
  307. data/spec/unit/poland_with_ko_konf_kp_l_and_zp_without_k_k15_n_pis_po_psl_r_and_zl_spec.rb +59 -0
  308. data/spec/unit/poland_with_ko_sld_and_wi_without_n_po_and_zl_spec.rb +62 -0
  309. data/spec/unit/poland_with_sld_and_wi_without_zl_spec.rb +63 -0
  310. data/spec/unit/poland_with_sld_without_zl_spec.rb +62 -0
  311. data/spec/unit/poll_spec.rb +110 -0
  312. data/spec/unit/portugal_spec.rb +66 -0
  313. data/spec/unit/portugal_with_a_and_ch_without_paf_spec.rb +68 -0
  314. data/spec/unit/portugal_with_a_and_il_without_paf_spec.rb +68 -0
  315. data/spec/unit/portugal_with_a_ch_and_il_without_paf_spec.rb +69 -0
  316. data/spec/unit/portugal_with_a_without_paf_spec.rb +67 -0
  317. data/spec/unit/portugal_with_ch_and_il_without_paf_spec.rb +68 -0
  318. data/spec/unit/portugal_without_paf_spec.rb +66 -0
  319. data/spec/unit/pseudorandom_multirange_enumerator_spec.rb +82 -0
  320. data/spec/unit/referendum_polychotomy_spec.rb +289 -0
  321. data/spec/unit/representatives_polychotomy_spec.rb +332 -0
  322. data/spec/unit/slovakia_spec.rb +99 -0
  323. data/spec/unit/slovenia_spec.rb +80 -0
  324. data/spec/unit/spain_spec.rb +101 -0
  325. data/spec/unit/sweden_20140914_spec.rb +112 -0
  326. data/spec/unit/sweden_spec.rb +113 -0
  327. data/spec/unit/united_kingdom_spec.rb +65 -0
  328. data/spec/unit/united_kingdom_with_brexit_and_chuk_spec.rb +67 -0
  329. data/spec/unit/united_kingdom_with_brexit_spec.rb +66 -0
  330. data/spec/unit/united_kingdom_with_tig_spec.rb +66 -0
  331. data/spec/unit/wallonia_spec.rb +70 -0
  332. metadata +490 -0
@@ -0,0 +1,332 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Statistical Analysis of Polling Results (SAPoR)
4
+ # Copyright (C) 2016 Filip van Laenen <f.a.vanlaenen@ieee.org>
5
+ #
6
+ # This file is part of SAPoR.
7
+ #
8
+ # SAPoR is free software: you can redistribute it and/or modify it under the
9
+ # terms of the GNU General Public License as published by the Free Software
10
+ # Foundation, either version 3 of the License, or (at your option) any later
11
+ # version.
12
+ #
13
+ # SAPoR is distributed in the hope that it will be useful, but WITHOUT ANY
14
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15
+ # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16
+ #
17
+ # You can find a copy of the GNU General Public License in /doc/gpl.txt
18
+ #
19
+
20
+ require 'spec_helper'
21
+
22
+ class TestArea
23
+ include Singleton
24
+
25
+ LAST_ELECTION_RESULT = { 'Red' => 91_811, 'Green' => 190_934,
26
+ 'Blue' => 290_647, 'Yellow' => 356_473 }
27
+
28
+ LAST_DETAILED_ELECTION_RESULT = { 'North' => { 'Red' => 50, 'Green' => 70
29
+ },
30
+ 'South' => { 'Red' => 70, 'Green' => 50,
31
+ 'Blue' => 100 },
32
+ 'East' => { 'Red' => 90, 'Green' => 70,
33
+ 'Blue' => 90 },
34
+ 'West' => { 'Red' => 110, 'Green' => 50,
35
+ 'Yellow' => 120 } }
36
+
37
+ ELECTORAL_SYSTEM = Sapor::FirstPastThePost.new(LAST_ELECTION_RESULT,
38
+ LAST_DETAILED_ELECTION_RESULT)
39
+
40
+ def area_code
41
+ 'TA'
42
+ end
43
+
44
+ def coalitions
45
+ [%w(Red Green), %w(Red Blue)]
46
+ end
47
+
48
+ def population_size
49
+ 1_000
50
+ end
51
+
52
+ def no_of_seats
53
+ LAST_DETAILED_ELECTION_RESULT.size
54
+ end
55
+
56
+ def seats(simulation)
57
+ ELECTORAL_SYSTEM.project(simulation)
58
+ end
59
+ end
60
+
61
+ TEST_AREA = TestArea.instance
62
+
63
+ def pentachotomy(max_error = 0.01)
64
+ results = { 'Red' => 1, 'Green' => 2, 'Blue' => 3, 'Yellow' => 6,
65
+ 'Other' => 1 }
66
+ dichotomies = Sapor::Dichotomies.new(results, 1000)
67
+ dichotomies.refine
68
+ dichotomies.refine
69
+ dichotomies.refine
70
+ Sapor::RepresentativesPolychotomy.new(results, TEST_AREA, dichotomies, max_error)
71
+ end
72
+
73
+ describe Sapor::RepresentativesPolychotomy, '#new' do
74
+ it 'extracts the 99.99% confidence intervals as ranges for max 1% error' do
75
+ expect(pentachotomy.range('Red').size).to eq(17)
76
+ expect(pentachotomy.range('Green').size).to eq(19)
77
+ expect(pentachotomy.range('Blue').size).to eq(20)
78
+ expect(pentachotomy.range('Yellow').size).to eq(22)
79
+ end
80
+
81
+ it 'extracts the 99.9999% confidence intervals as ranges for max 0.1%' \
82
+ ' error' do
83
+ expect(pentachotomy(0.001).range('Red').size).to eq(20)
84
+ expect(pentachotomy(0.001).range('Green').size).to eq(22)
85
+ expect(pentachotomy(0.001).range('Blue').size).to eq(23)
86
+ expect(pentachotomy(0.001).range('Yellow').size).to eq(25)
87
+ end
88
+
89
+ # TODO: A test case where the construction of the enumerator fails
90
+ end
91
+
92
+ describe Sapor::RepresentativesPolychotomy, '#error_estimate' do
93
+ it 'is 1 by default (no refinement)' do
94
+ polychotomy = pentachotomy
95
+ expect(polychotomy.error_estimate).to eq(1.0)
96
+ end
97
+
98
+ it 'is 1 after the first refinement' do
99
+ polychotomy = pentachotomy
100
+ polychotomy.refine
101
+ expect(polychotomy.error_estimate).to eq(1.0)
102
+ end
103
+
104
+ it 'is at least the difference between the most probable fractions (two' \
105
+ ' refinements)' do
106
+ polychotomy = pentachotomy
107
+ polychotomy.refine
108
+ polychotomy.refine
109
+ expect(polychotomy.error_estimate.round(3)).to eq(0.333)
110
+ end
111
+
112
+ it 'is at least the difference between the most probable fractions (three' \
113
+ ' refinements)' do
114
+ polychotomy = pentachotomy
115
+ polychotomy.refine
116
+ polychotomy.refine
117
+ polychotomy.refine
118
+ expect(polychotomy.error_estimate.round(3)).to eq(0.259)
119
+ end
120
+ end
121
+
122
+ describe Sapor::RepresentativesPolychotomy, '#most_probable_fraction' do
123
+ it 'is nil by default (no refinement)' do
124
+ polychotomy = pentachotomy
125
+ expect(polychotomy.most_probable_fraction('Red')).to be_nil
126
+ expect(polychotomy.most_probable_fraction('Green')).to be_nil
127
+ expect(polychotomy.most_probable_fraction('Blue')).to be_nil
128
+ expect(polychotomy.most_probable_fraction('Yellow')).to be_nil
129
+ end
130
+
131
+ it 'returns a value after the first refinement' do
132
+ polychotomy = pentachotomy
133
+ polychotomy.refine
134
+ expect(polychotomy.most_probable_fraction('Red').round(2)).to eq(0.02)
135
+ expect(polychotomy.most_probable_fraction('Green').round(2)).to eq(0.02)
136
+ expect(polychotomy.most_probable_fraction('Blue').round(2)).to eq(0.02)
137
+ expect(polychotomy.most_probable_fraction('Yellow').round(2)).to eq(0.09)
138
+ end
139
+
140
+ it 'returns an updated value after the second refinement' do
141
+ polychotomy = pentachotomy
142
+ polychotomy.refine
143
+ polychotomy.refine
144
+ expect(polychotomy.most_probable_fraction('Red').round(2)).to eq(0.28)
145
+ expect(polychotomy.most_probable_fraction('Green').round(2)).to eq(0.09)
146
+ expect(polychotomy.most_probable_fraction('Blue').round(2)).to eq(0.35)
147
+ expect(polychotomy.most_probable_fraction('Yellow').round(2)).to eq(0.20)
148
+ end
149
+
150
+ it 'returns an updated value after the third refinement' do
151
+ polychotomy = pentachotomy
152
+ polychotomy.refine
153
+ polychotomy.refine
154
+ polychotomy.refine
155
+ expect(polychotomy.most_probable_fraction('Red').round(2)).to eq(0.35)
156
+ expect(polychotomy.most_probable_fraction('Green').round(2)).to eq(0.09)
157
+ expect(polychotomy.most_probable_fraction('Blue').round(2)).to eq(0.09)
158
+ expect(polychotomy.most_probable_fraction('Yellow').round(2)).to eq(0.39)
159
+ end
160
+ end
161
+
162
+ describe Sapor::RepresentativesPolychotomy, '#no_of_data_points' do
163
+ it 'is 0 by default (no refinement)' do
164
+ polychotomy = pentachotomy
165
+ expect(polychotomy.no_of_data_points).to eq(0)
166
+ end
167
+
168
+ it 'is 1 after 1 refinement' do
169
+ polychotomy = pentachotomy
170
+ polychotomy.refine
171
+ expect(polychotomy.no_of_data_points).to eq(1)
172
+ end
173
+
174
+ it 'is 19 after 2 refinements' do
175
+ polychotomy = pentachotomy
176
+ polychotomy.refine
177
+ polychotomy.refine
178
+ expect(polychotomy.no_of_data_points).to eq(8)
179
+ end
180
+
181
+ it 'is 38 after 3 refinements' do
182
+ polychotomy = pentachotomy
183
+ polychotomy.refine
184
+ polychotomy.refine
185
+ polychotomy.refine
186
+ expect(polychotomy.no_of_data_points).to eq(27)
187
+ end
188
+
189
+ # TODO: A test case that runs all the simulations
190
+ end
191
+
192
+ describe Sapor::RepresentativesPolychotomy, '#no_of_simulations' do
193
+ it 'is 0 by default (no refinement)' do
194
+ polychotomy = pentachotomy
195
+ expect(polychotomy.no_of_simulations).to eq(0)
196
+ end
197
+
198
+ it 'is 1 after 1 refinement' do
199
+ polychotomy = pentachotomy
200
+ polychotomy.refine
201
+ expect(polychotomy.no_of_simulations).to eq(1)
202
+ end
203
+
204
+ it 'is 2 after 2 refinements' do
205
+ polychotomy = pentachotomy
206
+ polychotomy.refine
207
+ polychotomy.refine
208
+ expect(polychotomy.no_of_simulations).to eq(2)
209
+ end
210
+
211
+ it 'is 4 after 3 refinements' do
212
+ polychotomy = pentachotomy
213
+ polychotomy.refine
214
+ polychotomy.refine
215
+ polychotomy.refine
216
+ expect(polychotomy.no_of_simulations).to eq(4)
217
+ end
218
+
219
+ # TODO: A test case that runs until the end of the enumerator
220
+ end
221
+
222
+ describe Sapor::RepresentativesPolychotomy, '#progress_report' do
223
+ it 'reports progress with the number of simulations and data points,' \
224
+ ' together with the search space size and the fraction that already has' \
225
+ ' been searched' do
226
+ expected_report = '1 simulations out of 1 data points, 1 / 142,120 of' \
227
+ ' search space size (142,120).'
228
+ polychotomy = pentachotomy
229
+ polychotomy.refine
230
+ expect(polychotomy.progress_report).to eq(expected_report)
231
+ end
232
+
233
+ it 'reports no of simulations and data points with thousands separator' do
234
+ expected_report = '1,024 simulations out of 9,287 data points, 1 / 15' \
235
+ ' of search space size (142,120).'
236
+ polychotomy = pentachotomy
237
+ 11.times { polychotomy.refine }
238
+ expect(polychotomy.progress_report).to eq(expected_report)
239
+ end
240
+
241
+ it 'rounds the fraction of the space size searched with 1 decimal if' \
242
+ ' larger than one tenth' do
243
+ expected_report = '2,048 simulations out of 19,433 data points, 1 / 7.3' \
244
+ ' of search space size (142,120).'
245
+ polychotomy = pentachotomy
246
+ 12.times { polychotomy.refine }
247
+ expect(polychotomy.progress_report).to eq(expected_report)
248
+ end
249
+ end
250
+
251
+ describe Sapor::RepresentativesPolychotomy, '#report' do
252
+ it 'produces a report after first refinement for short choice labels' do
253
+ expected_report = 'Most probable rounded fractions, fractions and 95%' \
254
+ " confidence intervals:\n" \
255
+ "Choice Result MPRF MPF CI(95%) P(>↓) Seats\n" \
256
+ "Yellow 46.2% 5.6% 9.3% 9.3%– 11.1% 100.0% 1–1\n" + # TODO: Shouldn't MPRF be 5.6% and CI 9.3%–9.3%?
257
+ "Blue 23.1% 1.9% 1.9% 1.9%– 3.7% 0.0% 0–0\n" + # TODO: Shouldn't CI be 1.9%–1.9%?
258
+ "Green 15.4% 1.9% 1.9% 1.9%– 3.7% 0.0% 0–0\n" + # TODO: Shouldn't CI be 1.9%–1.9%?
259
+ "Red 7.7% 1.9% 1.9% 1.9%– 3.7% 3–3\n" + # TODO: Shouldn't CI be 1.9%–1.9%?
260
+ "Coalition Result MPRF MPF CI(95%) P(>50%) Seats P(>50%)\n" \
261
+ "Blue + Red 30.8% 50.0% 3.8% 3.8%– 3.8% 0.0% 3–3 100.0%\n" \
262
+ 'Green + Red 23.1% 50.0% 3.8% 3.8%– 3.8% 0.0% 3–3 100.0%'
263
+ polychotomy = pentachotomy
264
+ polychotomy.refine
265
+ expect(polychotomy.report).to eq(expected_report)
266
+ end
267
+
268
+ it 'produces a report by default for long choice labels' do
269
+ results = { 'Dark Red' => 1, 'Light Green' => 2, 'Medium Blue' => 3,
270
+ 'Other' => 1 }
271
+ dichotomies = Sapor::Dichotomies.new(results, 1000)
272
+ dichotomies.refine
273
+ dichotomies.refine
274
+ dichotomies.refine
275
+ polychotomy = Sapor::RepresentativesPolychotomy.new(results, TEST_AREA, dichotomies, 0.01)
276
+ polychotomy.refine
277
+ expected_report = 'Most probable rounded fractions, fractions and 95%' \
278
+ " confidence intervals:\n" \
279
+ "Choice Result MPRF MPF CI(95%) P(>↓) Seats\n" \
280
+ "Medium Blue 42.9% 1.9% 1.9% 1.9%– 3.7% 0.0% 0–0\n" + # TODO: Shouldn't CI be 1.9%–1.9%?
281
+ "Light Green 28.6% 1.9% 1.9% 1.9%– 3.7% 0.0% 0–0\n" + # TODO: Shouldn't CI be 1.9%–1.9%?
282
+ "Dark Red 14.3% 1.9% 1.9% 1.9%– 3.7% 0–0\n" + # TODO: Shouldn't CI be 1.9%–1.9%?
283
+ # TODO: "Red 3–3\n" \
284
+ # TODO: 'Yellow 1–1'
285
+ "Coalition Result MPRF MPF CI(95%) P(>50%) Seats P(>50%)\n" \
286
+ "Blue + Red 0.0% 50.0% 0.0% 0.0%– 0.0% 0.0% 0–0 0.0%\n" \
287
+ 'Green + Red 0.0% 50.0% 0.0% 0.0%– 0.0% 0.0% 0–0 0.0%'
288
+ expect(polychotomy.report).to eq(expected_report)
289
+ end
290
+
291
+ it 'produces a report by default for short choice labels' do
292
+ results = { 'Red' => 1, 'Green' => 2, 'Blue' => 3, 'Other' => 1 }
293
+ dichotomies = Sapor::Dichotomies.new(results, 1000)
294
+ dichotomies.refine
295
+ dichotomies.refine
296
+ dichotomies.refine
297
+ polychotomy = Sapor::RepresentativesPolychotomy.new(results, TEST_AREA, dichotomies, 0.01)
298
+ polychotomy.refine
299
+ expected_report = 'Most probable rounded fractions, fractions and 95%' \
300
+ " confidence intervals:\n" \
301
+ "Choice Result MPRF MPF CI(95%) P(>↓) Seats\n" \
302
+ "Blue 42.9% 1.9% 1.9% 1.9%– 3.7% 0.0% 0–0\n" + # TODO: Shouldn't CI be 1.9%–1.9%?
303
+ "Green 28.6% 1.9% 1.9% 1.9%– 3.7% 0.0% 0–0\n" + # TODO: Shouldn't CI be 1.9%–1.9%?
304
+ "Red 14.3% 1.9% 1.9% 1.9%– 3.7% 3–3\n" + # TODO: Shouldn't CI be 1.9%–1.9%?
305
+ # TODO: 'Yellow 1–1'
306
+ "Coalition Result MPRF MPF CI(95%) P(>50%) Seats P(>50%)\n" \
307
+ "Blue + Red 57.1% 50.0% 3.8% 3.8%– 3.8% 0.0% 3–3 100.0%\n" \
308
+ 'Green + Red 42.9% 50.0% 3.8% 3.8%– 3.8% 0.0% 3–3 100.0%'
309
+ expect(polychotomy.report).to eq(expected_report)
310
+ end
311
+
312
+ it 'sorts line with the same results alphabetically' do
313
+ results = { 'Red' => 1, 'Green' => 1, 'Blue' => 1, 'Other' => 1 }
314
+ dichotomies = Sapor::Dichotomies.new(results, 1000)
315
+ dichotomies.refine
316
+ dichotomies.refine
317
+ dichotomies.refine
318
+ polychotomy = Sapor::RepresentativesPolychotomy.new(results, TEST_AREA, dichotomies, 0.01)
319
+ polychotomy.refine
320
+ expected_report = 'Most probable rounded fractions, fractions and 95%' \
321
+ " confidence intervals:\n" \
322
+ "Choice Result MPRF MPF CI(95%) P(>↓) Seats\n" \
323
+ "Blue 25.0% 1.9% 1.9% 1.9%– 3.7% 0.0% 0–0\n" + # TODO: Shouldn't CI be 1.9%–1.9%?
324
+ "Green 25.0% 1.9% 1.9% 1.9%– 3.7% 0.0% 0–0\n" + # TODO: Shouldn't CI be 1.9%–1.9%?
325
+ "Red 25.0% 1.9% 1.9% 1.9%– 3.7% 3–3\n" + # TODO: Shouldn't CI be 1.9%–1.9%?
326
+ # TODO: 'Yellow 1–1'
327
+ "Coalition Result MPRF MPF CI(95%) P(>50%) Seats P(>50%)\n" \
328
+ "Blue + Red 50.0% 50.0% 3.8% 3.8%– 3.8% 0.0% 3–3 100.0%\n" \
329
+ 'Green + Red 50.0% 50.0% 3.8% 3.8%– 3.8% 0.0% 3–3 100.0%'
330
+ expect(polychotomy.report).to eq(expected_report)
331
+ end
332
+ end
@@ -0,0 +1,99 @@
1
+ #
2
+ # Statistical Analysis of Polling Results (SAPoR)
3
+ # Copyright (C) 2016 Filip van Laenen <f.a.vanlaenen@ieee.org>
4
+ #
5
+ # This file is part of SAPoR.
6
+ #
7
+ # SAPoR is free software: you can redistribute it and/or modify it under the
8
+ # terms of the GNU General Public License as published by the Free Software
9
+ # Foundation, either version 3 of the License, or (at your option) any later
10
+ # version.
11
+ #
12
+ # SAPoR is distributed in the hope that it will be useful, but WITHOUT ANY
13
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
+ # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15
+ #
16
+ # You can find a copy of the GNU General Public License in /doc/gpl.txt
17
+ #
18
+
19
+ require 'spec_helper'
20
+
21
+ describe Sapor::Slovakia, '#area_code' do
22
+ it 'returns SK as the area code' do
23
+ expect(Sapor::Slovakia.instance.area_code).to eq('SK')
24
+ end
25
+ end
26
+
27
+ describe Sapor::Slovakia, '#no_of_seats' do
28
+ it 'returns 150 as the number of seats' do
29
+ expect(Sapor::Slovakia.instance.no_of_seats).to eq(150)
30
+ end
31
+ end
32
+
33
+ describe Sapor::Slovakia, '#population_size' do
34
+ it 'returns a population size of 2,648,184 - 20,798' do
35
+ expect(Sapor::Slovakia.instance.population_size).to eq(2_648_184 - 20_798)
36
+ end
37
+ end
38
+
39
+ describe Sapor::Slovakia, '#threshold' do
40
+ it 'returns a threshold of 5%' do
41
+ expect(Sapor::Slovakia.instance.threshold).to eq(0.05)
42
+ end
43
+ end
44
+
45
+ describe Sapor::Slovakia, '#seats' do
46
+ it 'calculates the number of seats for the election of 2017' do
47
+ results = { 'SMER–sociálna demokracia' => 737_481,
48
+ 'Sloboda a Solidarita' => 315_558,
49
+ 'OBYČAJNÍ ĽUDIA a nezávislé osobnosti–NOVA' => 287_611,
50
+ 'Slovenská národná strana' => 225_386,
51
+ 'Kotleba–Ľudová strana Naše Slovensko' => 209_779,
52
+ 'SME RODINA–Boris Kollár' => 172_860,
53
+ 'MOST–HÍD' => 169_593,
54
+ '#SIEŤ' => 146_205,
55
+ 'Kresťanskodemokratické hnutie' => 128_908,
56
+ 'Strana maďarskej komunity–Magyar Közösség Pártja' => 105_495,
57
+ 'Slovenská občianska koalícia' => 21_785,
58
+ 'Strana TIP' => 18_845,
59
+ 'Strana zelených Slovenska' => 17_541,
60
+ 'Komunistická strana Slovenska' => 16_278,
61
+ 'Slovenská demokratická a kresťanská únia–Demokratická' \
62
+ ' strana' => 6_938,
63
+ 'ŠANCA' => 6_522,
64
+ 'Strana moderného Slovenska' => 4_559,
65
+ 'PRIAMA DEMOKRACIA' => 3_595,
66
+ 'Courage – Great National and Pro-Russian Coalition' => 3_428,
67
+ 'VZDOR–strana práce' => 3_182,
68
+ 'Maďarská kresťanskodemokratická aliancia–Magyar' \
69
+ ' Kereszténydemokrata Szövetség' => 2_426,
70
+ 'Democratic Party–Ľudo Kaník' => 1_998,
71
+ 'Coalition–Together for Slovakia' => 1_777}
72
+ seats = Sapor::Slovakia.instance.seats(results)
73
+ expect(seats['SMER–sociálna demokracia']).to eq(49)
74
+ expect(seats['Sloboda a Solidarita']).to eq(21)
75
+ expect(seats['OBYČAJNÍ ĽUDIA a nezávislé osobnosti–NOVA']).to eq(19)
76
+ expect(seats['Slovenská národná strana']).to eq(15)
77
+ expect(seats['Kotleba–Ľudová strana Naše Slovensko']).to eq(14)
78
+ expect(seats['SME RODINA–Boris Kollár']).to eq(11)
79
+ expect(seats['MOST–HÍD']).to eq(11)
80
+ expect(seats['#SIEŤ']).to eq(10)
81
+ expect(seats['Kresťanskodemokratické hnutie']).to eq(0)
82
+ expect(seats['Strana maďarskej komunity–Magyar Közösség Pártja']).to eq(0)
83
+ expect(seats['Slovenská občianska koalícia']).to eq(0)
84
+ expect(seats['Strana TIP']).to eq(0)
85
+ expect(seats['Strana zelených Slovenska']).to eq(0)
86
+ expect(seats['Komunistická strana Slovenska']).to eq(0)
87
+ expect(seats['Slovenská demokratická a kresťanská únia–Demokratická' \
88
+ ' strana']).to eq(0)
89
+ expect(seats['ŠANCA']).to eq(0)
90
+ expect(seats['Strana moderného Slovenska']).to eq(0)
91
+ expect(seats['PRIAMA DEMOKRACIA']).to eq(0)
92
+ expect(seats['Courage – Great National and Pro-Russian Coalition']).to eq(0)
93
+ expect(seats['VZDOR–strana práce']).to eq(0)
94
+ expect(seats['Maďarská kresťanskodemokratická aliancia–Magyar' \
95
+ ' Kereszténydemokrata Szövetség']).to eq(0)
96
+ expect(seats['Democratic Party–Ľudo Kaník']).to eq(0)
97
+ expect(seats['Coalition–Together for Slovakia']).to eq(0)
98
+ end
99
+ end
@@ -0,0 +1,80 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Statistical Analysis of Polling Results (SAPoR)
4
+ # Copyright (C) 2016 Filip van Laenen <f.a.vanlaenen@ieee.org>
5
+ #
6
+ # This file is part of SAPoR.
7
+ #
8
+ # SAPoR is free software: you can redistribute it and/or modify it under the
9
+ # terms of the GNU General Public License as published by the Free Software
10
+ # Foundation, either version 3 of the License, or (at your option) any later
11
+ # version.
12
+ #
13
+ # SAPoR is distributed in the hope that it will be useful, but WITHOUT ANY
14
+ # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15
+ # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16
+ #
17
+ # You can find a copy of the GNU General Public License in /doc/gpl.txt
18
+ #
19
+
20
+ require 'spec_helper'
21
+
22
+ describe Sapor::Slovenia, '#area_code' do
23
+ it 'returns SI as the area code' do
24
+ expect(Sapor::Slovenia.instance.area_code).to eq('SI')
25
+ end
26
+ end
27
+
28
+ describe Sapor::Slovenia, '#no_of_seats' do
29
+ it 'returns 90 as the number of seats' do
30
+ expect(Sapor::Slovenia.instance.no_of_seats).to eq(90)
31
+ end
32
+ end
33
+
34
+ describe Sapor::Slovenia, '#population_size' do
35
+ it 'returns a population size of 874,291' do
36
+ expect(Sapor::Slovenia.instance.population_size).to \
37
+ eq(874_291)
38
+ end
39
+ end
40
+
41
+ describe Sapor::Slovenia, '#seats' do
42
+ it 'calculates the number of seats for the election of 2014' do
43
+ results = { 'Stranka Mira Cerarja' => 301_563,
44
+ 'Slovenska demokratska stranka' => 181_052,
45
+ 'Demokratična stranka upokojencev Slovenije' => 88_968,
46
+ 'Socialni demokrati' => 52_249,
47
+ 'Združena levica' => 52_189,
48
+ 'Nova Slovenija–Krščanski demokrati' => 48_846,
49
+ 'Zavezništvo Alenke Bratušek' => 38_293,
50
+ 'Slovenska ljudska stranka' => 34_548,
51
+ 'Pozitivna Slovenija' => 25_975,
52
+ 'Slovenska nacionalna stranka' => 19_218,
53
+ 'Piratska stranka Slovenije' => 11_737,
54
+ 'Stranka Verjamem' => 6_800,
55
+ 'Državljanska lista' => 5_556,
56
+ 'Zeleni Slovenije' => 4_629,
57
+ 'Enakopravni deželani–Naprej Slovenija' => 2_125,
58
+ 'Liberalno gospodarska stranka' => 458,
59
+ 'Stranka Humana Slovenija' => 85 }
60
+ seats = Sapor::Slovenia.instance.seats(results)
61
+ expect(seats['Stranka Mira Cerarja']).to eq(36)
62
+ expect(seats['Slovenska demokratska stranka']).to eq(21)
63
+ expect(seats['Demokratična stranka upokojencev Slovenije']).to eq(10)
64
+ expect(seats['Socialni demokrati']).to eq(6)
65
+ expect(seats['Združena levica']).to eq(6)
66
+ expect(seats['Nova Slovenija–Krščanski demokrati']).to eq(5)
67
+ expect(seats['Zavezništvo Alenke Bratušek']).to eq(4)
68
+ expect(seats['Hungarian and Italian minorities']).to eq(2)
69
+ expect(seats['Slovenska ljudska stranka']).to eq(0)
70
+ expect(seats['Pozitivna Slovenija']).to eq(0)
71
+ expect(seats['Slovenska nacionalna stranka']).to eq(0)
72
+ expect(seats['Piratska stranka Slovenije']).to eq(0)
73
+ expect(seats['Stranka Verjamem']).to eq(0)
74
+ expect(seats['Državljanska lista']).to eq(0)
75
+ expect(seats['Zeleni Slovenije']).to eq(0)
76
+ expect(seats['Enakopravni deželani–Naprej Slovenija']).to eq(0)
77
+ expect(seats['Liberalno gospodarska stranka']).to eq(0)
78
+ expect(seats['Stranka Humana Slovenija']).to eq(0)
79
+ end
80
+ end