diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2017-08-28 20:26:38 +0200 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2017-08-28 20:26:38 +0200 |
commit | 8f6fa7db038a29941b70862386ae4120499637d2 (patch) | |
tree | 077cf3bb788174dbd52e630e04887a859fe80e0f | |
parent | fbc92f8400d4565a86b81329053a1302ce21c2f8 (diff) |
Ensure 100% branch coverage
This ensures that the tests fail if 100% branch coverage is not
achieved. It also adds some pragma statements for code that cannot be
covered or is Python version dependent.
Furthermore, the get_module_list() function was removed from stdnum.util
and more tests were made from stdnum.util and stdnum.numdb. The
functionality to call format() in a country-specific IBAN implementation
was also dropped because it was not used.
-rw-r--r-- | setup.cfg | 1 | ||||
-rw-r--r-- | stdnum/iban.py | 3 | ||||
-rw-r--r-- | stdnum/ismn.py | 4 | ||||
-rw-r--r-- | stdnum/meid.py | 7 | ||||
-rw-r--r-- | stdnum/numdb.py | 7 | ||||
-rw-r--r-- | stdnum/util.py | 15 | ||||
-rw-r--r-- | tests/numdb-test.dat | 1 | ||||
-rw-r--r-- | tests/test_util.doctest | 50 |
8 files changed, 64 insertions, 24 deletions
@@ -13,6 +13,7 @@ cover-inclusive=true cover-erase=true cover-html=true cover-html-dir=coverage +cover-min-percentage=100 [build_sphinx] all_files = 1 diff --git a/stdnum/iban.py b/stdnum/iban.py index a9c56b3..5908a71 100644 --- a/stdnum/iban.py +++ b/stdnum/iban.py @@ -129,7 +129,4 @@ def is_valid(number, check_country=True): def format(number, separator=' '): """Reformat the passed number to the space-separated format.""" number = compact(number) - module = _get_cc_module(number[:2]) - if module and hasattr(module, 'format') and module.format != format: - return module.format(number, separator=separator) return separator.join(number[i:i + 4] for i in range(0, len(number), 4)) diff --git a/stdnum/ismn.py b/stdnum/ismn.py index b04c763..d7337f0 100644 --- a/stdnum/ismn.py +++ b/stdnum/ismn.py @@ -121,8 +121,8 @@ def split(number): 6 digits) and a check digit.""" # clean up number number = to_ismn13(compact(number)) - # rind the correct range and split the number - for length, low, high in _ranges: + # find the correct range and split the number + for length, low, high in _ranges: # pragma: no branch (all ranges covered) if low <= number[4:4 + length] <= high: return (number[:3], number[3], number[4:4 + length], number[4 + length:-1], number[-1]) diff --git a/stdnum/meid.py b/stdnum/meid.py index 3077753..db43866 100644 --- a/stdnum/meid.py +++ b/stdnum/meid.py @@ -107,10 +107,11 @@ def compact(number, strip_check_digit=True): def _bit_length(n): """Number of bits necessary to represent the number in binary.""" - if hasattr(n, 'bit_length'): + try: return n.bit_length() - import math - return int(math.log(n, 2)) + 1 + except AttributeError: # pragma: no cover (Python 2.6 only) + import math + return int(math.log(n, 2)) + 1 def validate(number, strip_check_digit=True): diff --git a/stdnum/numdb.py b/stdnum/numdb.py index ea3c3b9..e3e48e2 100644 --- a/stdnum/numdb.py +++ b/stdnum/numdb.py @@ -1,6 +1,6 @@ # numdb.py - module for handling hierarchically organised numbers # -# Copyright (C) 2010, 2011, 2012, 2013 Arthur de Jong +# Copyright (C) 2010-2017 Arthur de Jong # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -76,7 +76,7 @@ True True >>> dbfile.info('633322') == [ ... ('6', {'prop1': 'boo'}), -... ('333', {'prop2': 'bar', 'prop3': 'baz'}), +... ('333', {'prop2': 'bar', 'prop3': 'baz', 'prop4': 'bla'}), ... ('22', {}), ... ] True @@ -187,8 +187,7 @@ def read(fp): for indent, length, low, high, props in _parse(fp): if indent > last_indent: # populate the children field of the last indent - if stack[last_indent][-1][4] is None: - stack[last_indent][-1][4] = [] + stack[last_indent][-1][4] = [] stack[indent] = stack[last_indent][-1][4] stack[indent].append([length, low, high, props, None]) last_indent = indent diff --git a/stdnum/util.py b/stdnum/util.py index 111f5af..3d4b04f 100644 --- a/stdnum/util.py +++ b/stdnum/util.py @@ -120,7 +120,7 @@ def clean(number, deletechars=''): number = ''.join(x for x in number) except Exception: raise InvalidFormat() - if sys.version < '3' and isinstance(number, str): # pragma: no cover (Python 2/3 specific code) + if sys.version < '3' and isinstance(number, str): # pragma: no cover (Python 2 specific code) try: number = _clean_chars(number.decode()).encode() except UnicodeError: @@ -128,7 +128,7 @@ def clean(number, deletechars=''): number = _clean_chars(number.decode('utf-8')).encode('utf-8') except UnicodeError: pass - else: # pragma: no cover (Python 2/3 specific code) + else: # pragma: no cover (Python 3 specific code) number = _clean_chars(number) return ''.join(x for x in number if x not in deletechars) @@ -138,8 +138,7 @@ def get_number_modules(base='stdnum'): __import__(base) module = sys.modules[base] for loader, name, is_pkg in pkgutil.walk_packages( - module.__path__, module.__name__ + '.', - onerror=lambda x: None): + module.__path__, module.__name__ + '.'): __import__(name) module = sys.modules[name] if hasattr(module, 'validate'): @@ -158,14 +157,6 @@ def get_module_description(module): return _strip_doctest_re.sub('', doc).strip() -def get_module_list(): - for module in get_number_modules(): - yield ' * %s: %s' % ( - module.__name__.replace('stdnum.', ''), - get_module_name(module), - ) - - def get_cc_module(cc, name): """Find the country-specific named module.""" cc = cc.lower() diff --git a/tests/numdb-test.dat b/tests/numdb-test.dat index 2dfad4e..6b25454 100644 --- a/tests/numdb-test.dat +++ b/tests/numdb-test.dat @@ -3,6 +3,7 @@ 100-999 prop2="bar" 200,300-399 prop3="baz" 6 prop1="boo" + 333 prop4="bla" 90-99 prop1="booz" 00-89 prop2="foo" 900-999 prop2="fooz" diff --git a/tests/test_util.doctest b/tests/test_util.doctest new file mode 100644 index 0000000..28674b7 --- /dev/null +++ b/tests/test_util.doctest @@ -0,0 +1,50 @@ +test_util.doctest - more detailed doctests for the stdnum.util package + +Copyright (C) 2017 Arthur de Jong + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA + + +This file contains more detailed doctests for the stdnum.util package. It +tries to test more corner cases and detailed functionality. This module is +meant for internal use by stdnum modules and is not guaranteed to remain +stable and as such not part of the public API of stdnum. + +>>> from stdnum.util import ( +... get_number_modules, get_module_name, get_module_description) + + +The get_module_name() function is used in the example WSGI application and +release scripts to get the number's name. It should not end in a dot (even +though the docstring subject should). + +>>> from stdnum import isbn +>>> get_module_name(isbn) +'ISBN (International Standard Book Number)' +>>> any(get_module_name(mod).endswith('.') for mod in get_number_modules()) +False + + +The get_module_description() function is used in the example WSGI application +to extract the extended description of the number for presentation purposes. +The doctests should not be present in the descriptions. + +>>> from stdnum import isbn +>>> get_module_description(isbn).startswith( +... 'The ISBN is the International Standard Book Number') +True +>>> any('>>>' in get_module_description(mod) for mod in get_number_modules()) +False |