Add test coverage reporting

This commit is contained in:
RunasSudo 2021-01-12 03:15:47 +11:00
parent 7f30871296
commit fccb36ffbd
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
11 changed files with 46 additions and 30 deletions

12
.coveragerc Normal file
View File

@ -0,0 +1,12 @@
[run]
command_line=-m pytest
omit=
*_js.py
pyRCV2/transcrypt.py
source=pyRCV2
[report]
exclude_lines=
__pragma__
def __repr__
pragma: no cover

4
.gitignore vendored
View File

@ -1,6 +1,8 @@
/.coverage
/.python-version
/__target__
/test
/html/bundle.js
/htmlcov
/test
__pycache__
.~*

View File

@ -142,7 +142,7 @@ class BaseSTVCounter:
if result:
return result
raise STVException('Unable to complete step')
raise STVException('Unable to complete step') # pragma: no cover
def step_count_cards(self):
"""
@ -249,7 +249,7 @@ class BaseSTVCounter:
has_surplus.sort(key=lambda x: x[1].votes, reverse=True)
elif self.options['surplus_order'] == 'order':
has_surplus.sort(key=lambda x: x[1].order_elected)
else:
else: # pragma: no cover
raise STVException('Invalid surplus order option')
# Attempt to defer all remaining surpluses if possible
@ -286,7 +286,7 @@ class BaseSTVCounter:
Transfer the surplus of the given candidate
Subclasses must override this function
"""
raise NotImplementedError('Method not implemented')
raise NotImplementedError('Method not implemented') # pragma: no cover
def before_exclusion(self):
"""
@ -440,7 +440,7 @@ class BaseSTVCounter:
Exclude the given candidate and transfer the votes
Subclasses must override this function
"""
raise NotImplementedError('Method not implemented')
raise NotImplementedError('Method not implemented') # pragma: no cover
def compute_quota(self):
"""
@ -457,7 +457,7 @@ class BaseSTVCounter:
elif self.options['quota'] == 'hare' or self.options['quota'] == 'hare_exact':
self.quota = self.total / Num(self.election.seats)
else:
raise STVException('Invalid quota option')
raise STVException('Invalid quota option') # pragma: no cover
if self.options['round_quota'] is not None:
if self.options['quota'] == 'droop' or self.options['quota'] == 'hare':
@ -501,7 +501,7 @@ class BaseSTVCounter:
return count_card.votes > self.quota or (self.options['quota_mode'] == 'ers97' and count_card.votes > self.vote_required_election)
__pragma__('noopov')
else:
raise STVException('Invalid quota criterion')
raise STVException('Invalid quota criterion') # pragma: no cover
def elect_meeting_quota(self):
"""

View File

@ -31,7 +31,7 @@ def groupby(iterable, keyfunc):
import itertools
return [list(g) for k, g in itertools.groupby(iterable, keyfunc)]
__pragma__('noskip')
else:
else: # pragma: no cover
groups = []
group = []
last_result = None
@ -173,7 +173,7 @@ class WIGSTVCounter(BaseSTVCounter):
# TODO: Can we combine ballots for each candidate within each stage?
self._exclusion = (candidates_excluded, [[(c, [(b, bv)]) for c, b, bv in x] for x in ballots_by_value])
else:
raise STVException('Invalid exclusion mode')
raise STVException('Invalid exclusion mode') # pragma: no cover
this_exclusion = self._exclusion[1][0]
self._exclusion[1].remove(this_exclusion)

View File

@ -25,7 +25,7 @@ class Candidate:
def __repr__(self):
return '<Candidate ' + self.name + '>'
def toString(self):
def toString(self): # pragma: no cover
return repr(self)
class CandidateState:

View File

@ -26,7 +26,7 @@ if is_py:
from pyRCV2.numbers.native_py import Native
from pyRCV2.numbers.rational_py import Rational
__pragma__('noskip')
else:
else: # pragma: no cover
from pyRCV2.numbers.fixed_js import Fixed, set_dps, get_dps
from pyRCV2.numbers.native_js import Native
from pyRCV2.numbers.rational_js import Rational

View File

@ -36,7 +36,7 @@ def compatible_types(f):
else:
return f
__pragma__('noskip')
else:
else: # pragma: no cover
# FIXME: Do we need to perform type checking in JS?
return f
@ -61,7 +61,7 @@ class BaseNum:
Internal use: Convert the given value to an impl
Subclasses must override this method
"""
raise NotImplementedError('Method not implemented')
raise NotImplementedError('Method not implemented') # pragma: no cover
@classmethod
def _from_impl(cls, impl):
@ -79,52 +79,52 @@ class BaseNum:
Pretty print to specified number of decimal places
Subclasses must override this method
"""
raise NotImplementedError('Method not implemented')
raise NotImplementedError('Method not implemented') # pragma: no cover
# Implementation of arithmetic on impls
# Subclasses must override these functions:
@classmethod
def _add_impl(cls, i1, i2):
raise NotImplementedError('Method not implemented')
raise NotImplementedError('Method not implemented') # pragma: no cover
@classmethod
def _sub_impl(cls, i1, i2):
raise NotImplementedError('Method not implemented')
raise NotImplementedError('Method not implemented') # pragma: no cover
@classmethod
def _mul_impl(cls, i1, i2):
raise NotImplementedError('Method not implemented')
raise NotImplementedError('Method not implemented') # pragma: no cover
@classmethod
def _truediv_impl(cls, i1, i2):
raise NotImplementedError('Method not implemented')
raise NotImplementedError('Method not implemented') # pragma: no cover
@compatible_types
def __eq__(self, other):
raise NotImplementedError('Method not implemented')
raise NotImplementedError('Method not implemented') # pragma: no cover
@compatible_types
def __ne__(self, other):
return not (self.__eq__(other))
@compatible_types
def __gt__(self, other):
raise NotImplementedError('Method not implemented')
raise NotImplementedError('Method not implemented') # pragma: no cover
@compatible_types
def __ge__(self, other):
raise NotImplementedError('Method not implemented')
raise NotImplementedError('Method not implemented') # pragma: no cover
@compatible_types
def __lt__(self, other):
raise NotImplementedError('Method not implemented')
raise NotImplementedError('Method not implemented') # pragma: no cover
@compatible_types
def __le__(self, other):
raise NotImplementedError('Method not implemented')
raise NotImplementedError('Method not implemented') # pragma: no cover
def __pow__(self, power):
raise NotImplementedError('Method not implemented')
raise NotImplementedError('Method not implemented') # pragma: no cover
def round(self, dps, mode):
"""
Round to the specified number of decimal places, using the ROUND_* mode specified
Subclasses must override this method
"""
raise NotImplementedError('Method not implemented')
raise NotImplementedError('Method not implemented') # pragma: no cover
# Implement various data model functions based on _*_impl

View File

@ -24,5 +24,5 @@ if is_py:
__pragma__('skip')
from pyRCV2.random.sharandom_py import SHARandom
__pragma__('noskip')
else:
else: # pragma: no cover
from pyRCV2.random.sharandom_js import SHARandom

View File

@ -24,5 +24,5 @@ if is_py:
__pragma__('skip')
from pyRCV2.safedict.safedict_py import SafeDict
__pragma__('noskip')
else:
else: # pragma: no cover
from pyRCV2.safedict.safedict_js import SafeDict

View File

@ -22,7 +22,8 @@ __pragma__('noskip')
from pyRCV2.random import SHARandom
class RequireInput(Exception):
class RequireInput(Exception): # pragma: no cover
# For JS only
# Exceptions for control flow? In my code? It's more likely thank you think!
def __init__(self, message):
self.message = message
@ -51,7 +52,7 @@ class TiesPrompt:
print()
return l[i - 1]
else:
else: # pragma: no cover
if self.buffer is not None:
try:
choice = int(self.buffer)

View File

@ -1,8 +1,9 @@
# Dependencies
Transcrypt==3.7.16
coverage==5.3.1
py-mini-racer==0.4.0
pytest==6.2.1
pytest-steps==1.7.3
Transcrypt==3.7.16
# Dependency tree
attrs==20.3.0