Also test ERS97 case in Javascript

This commit is contained in:
RunasSudo 2021-01-13 00:48:36 +11:00
parent d23eee79bb
commit db98a3c733
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
1 changed files with 48 additions and 1 deletions

View File

@ -20,8 +20,10 @@ import pyRCV2.blt
import pyRCV2.numbers import pyRCV2.numbers
from pyRCV2.method.gregory import EGSTVCounter from pyRCV2.method.gregory import EGSTVCounter
from pyRCV2.model import CandidateState, CountCompleted from pyRCV2.model import CandidateState, CountCompleted
import tests.util
import csv import csv
import json
# Read model CSV # Read model CSV
@ -32,7 +34,7 @@ with open('tests/data/ers97.csv', 'r', newline='') as f:
candidates = [data[i][0] for i in range(2, len(data) - 2)] 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)]) @test_steps(*['Stage {}'.format(data[0][i]) for i in range(1, len(data[0]), 2)])
def test_ers97(): def test_ers97_py():
"""Compare count of ers97.blt with model result computed by hand""" """Compare count of ers97.blt with model result computed by hand"""
pyRCV2.numbers.set_numclass(pyRCV2.numbers.Fixed) pyRCV2.numbers.set_numclass(pyRCV2.numbers.Fixed)
@ -84,3 +86,48 @@ def test_ers97():
assert result.vote_required_election.pp(2) == votes_required.pp(2), 'Failed to verify votes required for election, got {} expected {}'.format(result.vote_required_election.pp(2), votes_required.pp(2)) assert result.vote_required_election.pp(2) == votes_required.pp(2), 'Failed to verify votes required for election, got {} expected {}'.format(result.vote_required_election.pp(2), votes_required.pp(2))
yield 'Stage {}'.format(stage) yield 'Stage {}'.format(stage)
@test_steps(*['Stage {}'.format(data[0][i]) for i in range(1, len(data[0]), 2)])
def test_ers97_js():
ctx = tests.util.init_context()
ctx.eval('py.pyRCV2.numbers.set_numclass(py.pyRCV2.numbers.Fixed);')
ctx.eval('py.pyRCV2.numbers.set_dps(5);')
with open('tests/data/ers97.blt', 'r') as f:
election = f.read()
ctx.eval('let electionData = {};'.format(json.dumps(election)))
ctx.eval('let election = py.pyRCV2.blt.readBLT(electionData);')
ctx.eval('let counter = py.pyRCV2.method.gregory.EGSTVCounter(election, { quota: "droop_exact", quota_mode: "ers97", bulk_exclude: true, defer_surpluses: true, round_quota: 2, round_votes: 2, round_tvs: 2, round_weights: 2, papers: "transferable", exclusion: "by_value"});')
ctx.eval('let result = counter.reset();')
assert ctx.eval('result.quota.__eq__(py.pyRCV2.numbers.Num("107.58"))'), 'Failed to verify quota, got {} expected 107.58'.format(ctx.eval('result.quota.pp(2)'))
ctx.eval('let votes, cc, nontransferable, votes_required;')
for i in range(1, len(data[0]), 2):
stage = int(data[0][i])
while ctx.eval('counter.step_results.length') < stage:
assert ctx.eval('result = counter.step();')
comment = data[1][i]
assert ctx.eval('result.comment') == comment, 'Failed to verify comment'
for j, cand in enumerate(candidates):
ctx.eval('votes = py.pyRCV2.numbers.Num("{}");'.format(data[j + 2][i]))
ctx.eval('for (let [c1, cc1] of result.candidates.py_items()) { if (c1.py_name == "' + cand + '") { cc = cc1; } }')
assert ctx.eval('cc.votes.__eq__(votes)'), 'Failed to verify candidate "{}" votes, got {} expected {}'.format(cand, ctx.eval('cc.votes.pp(0)'), ctx.eval('votes.pp(0)'))
state = data[j + 2][i + 1] if len(data[j + 2]) > (i + 1) else ''
accept = {'': CandidateState.HOPEFUL, 'PEL': CandidateState.PROVISIONALLY_ELECTED, 'EL': CandidateState.ELECTED, 'EX': CandidateState.EXCLUDED, 'EXCLUDING': CandidateState.EXCLUDING}
assert ctx.eval('cc.state') == accept[state], 'Failed to verify candidate "{}" state'.format(cand)
ctx.eval('nontransferable = py.pyRCV2.numbers.Num({});'.format(data[len(candidates) + 2][i]))
assert ctx.eval('result.exhausted.votes.__add__(result.loss_fraction.votes).__eq__(nontransferable)'), 'Failed to verify non-transferable votes, got {} expected {}'.format(ctx.eval('result.exhausted.votes.__add__(result.loss_fraction.votes).pp(2)'), ctx.eval('nontransferable.pp(2)'))
if data[len(candidates) + 3][i]:
ctx.eval('votes_required = py.pyRCV2.numbers.Num({});'.format(data[len(candidates) + 3][i]))
assert ctx.eval('result.vote_required_election.pp(2)') == ctx.eval('votes_required.pp(2)'), 'Failed to verify votes required for election, got {} expected {}'.format(ctx.eval('result.vote_required_election.pp(2)'), ctx.eval('votes_required.pp(2)'))
yield 'Stage {}'.format(stage)