diff --git a/requirements.txt b/requirements.txt index bde210e..89918da 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,18 +2,22 @@ Transcrypt==3.7.16 py-mini-racer==0.4.0 pytest==6.2.1 +pytest-steps==1.7.3 # Dependency tree attrs==20.3.0 importlib-metadata==3.3.0 iniconfig==1.1.1 +makefun==1.9.5 mypy==0.790 mypy-extensions==0.4.3 packaging==20.8 pluggy==0.13.1 py==1.10.0 pyparsing==2.4.7 +six==1.15.0 toml==0.10.2 typed-ast==1.4.1 typing-extensions==3.7.4.3 +wrapt==1.12.1 zipp==3.4.0 diff --git a/tests/test_aec.py b/tests/test_aec.py index 8338936..8daecb0 100644 --- a/tests/test_aec.py +++ b/tests/test_aec.py @@ -14,6 +14,8 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from pytest_steps import test_steps + import pyRCV2.blt import pyRCV2.numbers from pyRCV2.method.base_stv import UIGSTVCounter @@ -22,6 +24,15 @@ from pyRCV2.model import CandidateState, CountCompleted import csv import gzip +# Read model CSV + +with open('tests/aec-senate-formalpreferences-24310-TAS.csv', 'r', newline='') as f: + reader = csv.reader(f) + data = [x for x in reader] + +candidates = [data[i][0] for i in range(2, len(data) - 2)] + +@test_steps(*['Stage {}'.format(data[0][i]) for i in range(1, len(data[0]), 2)]) def test_aec_tas19(): """Compare count of aec-senate-formalpreferences-24310-TAS.blt.gz with model result at https://results.aec.gov.au/24310/Website/External/SenateStateDop-24310-TAS.pdf""" @@ -30,14 +41,6 @@ def test_aec_tas19(): with gzip.open('tests/aec-senate-formalpreferences-24310-TAS.blt.gz', 'rt') as f: election = pyRCV2.blt.readBLT(f.read()) - # Read model CSV - - with open('tests/aec-senate-formalpreferences-24310-TAS.csv', 'r', newline='') as f: - reader = csv.reader(f) - data = [x for x in reader] - - candidates = [data[i][0] for i in range(2, len(data) - 2)] - assert len(election.candidates) == len(candidates) counter = UIGSTVCounter(election, { @@ -69,3 +72,5 @@ def test_aec_tas19(): loss_fraction = pyRCV2.numbers.Num(data[len(candidates) + 3][i]) assert result.loss_fraction.votes == loss_fraction, 'Failed to verify stage {} loss to fraction, got {} expected {}'.format(stage, result.loss_fraction.votes.pp(0), loss_fraction.pp(0)) + + yield 'Stage {}'.format(stage) diff --git a/tests/test_csm.py b/tests/test_csm.py index 3d1bf04..580f1b0 100644 --- a/tests/test_csm.py +++ b/tests/test_csm.py @@ -15,6 +15,7 @@ # along with this program. If not, see . from pytest import approx +from pytest_steps import test_steps import pyRCV2.blt import pyRCV2.numbers @@ -29,6 +30,7 @@ def count_until_exclude(counter): if result.comment.startswith('Exclusion of '): return result +@test_steps(*['Round {}'.format(i) for i in range(1, 31)]) def test_csm15(): """Compare count of CSM15.blt with model result at https://www.eveonline.com/article/qbtyyo/meet-the-new-council""" @@ -89,146 +91,175 @@ def test_csm15(): result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Leehams DaWildabeast']].votes.impl == approx(63.208412) assert result.candidates[cands['Leehams DaWildabeast']].state == CandidateState.EXCLUDED + yield 'Round 1' # Round 2 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Storm Delay']].votes.impl == approx(112.229279) assert result.candidates[cands['Storm Delay']].state == CandidateState.EXCLUDED + yield 'Round 2' # Round 3 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Kalen Tsero']].votes.impl == approx(115.888433) assert result.candidates[cands['Kalen Tsero']].state == CandidateState.EXCLUDED + yield 'Round 3' # Round 4 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Rheaha Preynar']].votes.impl == approx(133.122193) assert result.candidates[cands['Rheaha Preynar']].state == CandidateState.EXCLUDED + yield 'Round 4' # Round 5 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Dhuras']].votes.impl == approx(170.123665) assert result.candidates[cands['Dhuras']].state == CandidateState.EXCLUDED + yield 'Round 5' # Round 6 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['boernl']].votes.impl == approx(181.377165) assert result.candidates[cands['boernl']].state == CandidateState.EXCLUDED + yield 'Round 6' # Round 7 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Styxx']].votes.impl == approx(184.463008) assert result.candidates[cands['Styxx']].state == CandidateState.EXCLUDED + yield 'Round 7' # Round 8 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Murray Rothbardo']].votes.impl == approx(189.651433) assert result.candidates[cands['Murray Rothbardo']].state == CandidateState.EXCLUDED + yield 'Round 8' # Round 9 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Xenuria']].votes.impl == approx(198.266912) assert result.candidates[cands['Xenuria']].state == CandidateState.EXCLUDED + yield 'Round 9' # Round 10 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Prospektor Schipplock']].votes.impl == approx(213.386936) assert result.candidates[cands['Prospektor Schipplock']].state == CandidateState.EXCLUDED + yield 'Round 10' # Round 11 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Komi Valentine']].votes.impl == approx(336.404306) assert result.candidates[cands['Komi Valentine']].state == CandidateState.EXCLUDED + yield 'Round 11' # Round 12 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['UAxDEATH']].votes.impl == approx(357.732024) assert result.candidates[cands['UAxDEATH']].state == CandidateState.EXCLUDED + yield 'Round 12' # Round 13 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Pandora Singularity']].votes.impl == approx(413.808353) assert result.candidates[cands['Pandora Singularity']].state == CandidateState.EXCLUDED + yield 'Round 13' # Round 14 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['PJHustle']].votes.impl == approx(478.737771) assert result.candidates[cands['PJHustle']].state == CandidateState.EXCLUDED + yield 'Round 14' # Round 15 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Ironwulf']].votes.impl == approx(528.845712) assert result.candidates[cands['Ironwulf']].state == CandidateState.EXCLUDED + yield 'Round 15' # Round 16 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['January Valentine']].votes.impl == approx(557.154707) assert result.candidates[cands['January Valentine']].state == CandidateState.EXCLUDED + yield 'Round 16' # Round 17 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Darius Caliente']].votes.impl == approx(620.307162) assert result.candidates[cands['Darius Caliente']].state == CandidateState.EXCLUDED + yield 'Round 17' # Round 18 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Alexis Finch']].votes.impl == approx(630.517365) assert result.candidates[cands['Alexis Finch']].state == CandidateState.EXCLUDED + yield 'Round 18' # Round 19 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['The Oz']].votes.impl == approx(673.241462) assert result.candidates[cands['The Oz']].state == CandidateState.EXCLUDED + yield 'Round 19' # Round 20 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Steadyo']].votes.impl == approx(693.622387) assert result.candidates[cands['Steadyo']].state == CandidateState.EXCLUDED + yield 'Round 20' # Round 21 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Insidious Sainthood']].votes.impl == approx(711.112702) assert result.candidates[cands['Insidious Sainthood']].state == CandidateState.EXCLUDED + yield 'Round 21' # Round 22 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Meredith en Thielles']].votes.impl == approx(773.804223) assert result.candidates[cands['Meredith en Thielles']].state == CandidateState.EXCLUDED + yield 'Round 22' # Round 23 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Stitch Kaneland']].votes.impl == approx(944.597498) assert result.candidates[cands['Stitch Kaneland']].state == CandidateState.EXCLUDED + yield 'Round 23' # Round 24 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['DutchGunner']].votes.impl == approx(1056.847624) assert result.candidates[cands['DutchGunner']].state == CandidateState.EXCLUDED + yield 'Round 24' # Round 25 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Jurius Doctor']].votes.impl == approx(1254.134642) assert result.candidates[cands['Jurius Doctor']].state == CandidateState.EXCLUDED + yield 'Round 25' # Round 26 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['BlazingBunny']].votes.impl == approx(1448.527563) assert result.candidates[cands['BlazingBunny']].state == CandidateState.EXCLUDED + yield 'Round 26' # Round 27 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['ExookiZ']].votes.impl == approx(1527.088745) assert result.candidates[cands['ExookiZ']].state == CandidateState.EXCLUDED + yield 'Round 27' # Round 28 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Juvenius Drakonius']].votes.impl == approx(1614.455637) assert result.candidates[cands['Juvenius Drakonius']].state == CandidateState.EXCLUDED + yield 'Round 28' # Round 29 result = count_until_exclude(counter) assert counter.step_results[-2].candidates[cands['Ikarus Cesaille']].votes.impl == approx(1938.970656) assert result.candidates[cands['Ikarus Cesaille']].state == CandidateState.EXCLUDED + yield 'Round 29' # Round 30 result = count_until_exclude(counter) @@ -250,3 +281,4 @@ def test_csm15(): result = counter.step() assert isinstance(result, CountCompleted) + yield 'Round 30'