Permalink
Browse files

Bring levels testing up to 100%

  • Loading branch information...
abadger committed Nov 27, 2017
1 parent 297f0b9 commit 73e37d4f904d2050cba6028601f5e2db50e53020
Showing with 165 additions and 97 deletions.
  1. +3 −0 .coveragerc
  2. +1 −0 test-requirements.txt
  3. +104 −87 tests/test_levels.py
  4. +6 −3 tox.ini
  5. +51 −7 twiggy/levels.py
View
@@ -10,6 +10,9 @@ exclude_lines =
# Have to re-enable the standard pragma
pragma: no cover
# Don't complain for py3 or py2 code being skipped
pragma: no py${PYTEST_PYMAJVER} cover
# Don't complain about missing debug-only code:
# Don't complain if tests don't hit defensive assertion code:
View
@@ -1,4 +1,5 @@
pytest
pytest-cov
pytest-mock
pytest-env-info
unittest2
View
@@ -1,90 +1,107 @@
import sys
import pytest
from twiggy import levels
if sys.version_info >= (2, 7):
import unittest
else:
try:
import unittest2 as unittest
except ImportError:
raise RuntimeError("unittest2 is required for Python < 2.7")
class LevelTestCase(unittest.TestCase):
def test_display(self):
assert str(levels.DEBUG) == 'DEBUG'
assert repr(levels.DEBUG) == '<LogLevel DEBUG>'
def test_name2level(self):
assert levels.name2level('debug') is levels.DEBUG
assert levels.name2level('Debug') is levels.DEBUG
def test_less_than(self):
assert levels.DEBUG < levels.INFO
assert levels.INFO < levels.NOTICE
assert levels.NOTICE < levels.WARNING
assert levels.WARNING < levels.ERROR
assert levels.ERROR < levels.CRITICAL
assert levels.CRITICAL < levels.DISABLED
def test_less_than_equals(self):
assert levels.DEBUG <= levels.INFO
assert levels.INFO <= levels.NOTICE
assert levels.NOTICE <= levels.WARNING
assert levels.WARNING <= levels.ERROR
assert levels.ERROR <= levels.CRITICAL
assert levels.CRITICAL <= levels.DISABLED
def test_greater_than(self):
assert levels.INFO > levels.DEBUG
assert levels.NOTICE > levels.INFO
assert levels.WARNING > levels.NOTICE
assert levels.ERROR > levels.WARNING
assert levels.CRITICAL > levels.ERROR
assert levels.DISABLED > levels.CRITICAL
def test_greater_than_equals(self):
assert levels.INFO >= levels.DEBUG
assert levels.NOTICE >= levels.INFO
assert levels.WARNING >= levels.NOTICE
assert levels.ERROR >= levels.WARNING
assert levels.CRITICAL >= levels.ERROR
assert levels.DISABLED >= levels.CRITICAL
def test_equality(self):
assert levels.DEBUG == levels.DEBUG
assert levels.INFO == levels.INFO
assert levels.NOTICE == levels.NOTICE
assert levels.WARNING == levels.WARNING
assert levels.ERROR == levels.ERROR
assert levels.CRITICAL == levels.CRITICAL
def test_inequality(self):
assert not levels.DEBUG != levels.DEBUG
assert not levels.INFO != levels.INFO
assert not levels.NOTICE != levels.NOTICE
assert not levels.WARNING != levels.WARNING
assert not levels.ERROR != levels.ERROR
assert not levels.CRITICAL != levels.CRITICAL
assert levels.INFO != levels.DEBUG
assert levels.NOTICE != levels.WARNING
assert levels.WARNING != levels.NOTICE
assert levels.ERROR != levels.WARNING
assert levels.CRITICAL != levels.ERROR
assert levels.DISABLED != levels.CRITICAL
def test_dict_key(self):
d = {levels.DEBUG: 42}
assert d[levels.DEBUG] == 42
def test_bogus_not_equals(self):
assert levels.DEBUG != 1
@unittest.skipIf(sys.version_info < (3, ), "Python 2.x comparisons are insane")
def test_bogus_compare(self):
# XXX is there a comparable test for 2.x?
with self.assertRaises(TypeError):
levels.DEBUG < 42
def test_display():
assert str(levels.DEBUG) == 'DEBUG'
assert repr(levels.DEBUG) == '<LogLevel DEBUG>'
def test_name2level():
assert levels.name2level('debug') is levels.DEBUG
assert levels.name2level('Debug') is levels.DEBUG
def test_less_than():
assert levels.DEBUG < levels.INFO
assert levels.INFO < levels.NOTICE
assert levels.NOTICE < levels.WARNING
assert levels.WARNING < levels.ERROR
assert levels.ERROR < levels.CRITICAL
assert levels.CRITICAL < levels.DISABLED
def test_less_than_equals():
assert levels.DEBUG <= levels.INFO
assert levels.INFO <= levels.NOTICE
assert levels.NOTICE <= levels.WARNING
assert levels.WARNING <= levels.ERROR
assert levels.ERROR <= levels.CRITICAL
assert levels.CRITICAL <= levels.DISABLED
def test_greater_than():
assert levels.INFO > levels.DEBUG
assert levels.NOTICE > levels.INFO
assert levels.WARNING > levels.NOTICE
assert levels.ERROR > levels.WARNING
assert levels.CRITICAL > levels.ERROR
assert levels.DISABLED > levels.CRITICAL
def test_greater_than_equals():
assert levels.INFO >= levels.DEBUG
assert levels.NOTICE >= levels.INFO
assert levels.WARNING >= levels.NOTICE
assert levels.ERROR >= levels.WARNING
assert levels.CRITICAL >= levels.ERROR
assert levels.DISABLED >= levels.CRITICAL
def test_equality():
assert levels.DEBUG == levels.DEBUG
assert levels.INFO == levels.INFO
assert levels.NOTICE == levels.NOTICE
assert levels.WARNING == levels.WARNING
assert levels.ERROR == levels.ERROR
assert levels.CRITICAL == levels.CRITICAL
def test_inequality():
assert not levels.DEBUG != levels.DEBUG
assert not levels.INFO != levels.INFO
assert not levels.NOTICE != levels.NOTICE
assert not levels.WARNING != levels.WARNING
assert not levels.ERROR != levels.ERROR
assert not levels.CRITICAL != levels.CRITICAL
assert levels.INFO != levels.DEBUG
assert levels.NOTICE != levels.WARNING
assert levels.WARNING != levels.NOTICE
assert levels.ERROR != levels.WARNING
assert levels.CRITICAL != levels.ERROR
assert levels.DISABLED != levels.CRITICAL
def test_dict_key():
d = {levels.DEBUG: 42}
assert d[levels.DEBUG] == 42
def test_bogus_equals():
assert not levels.DEBUG == 1
def test_bogus_not_equals():
assert levels.DEBUG != 1
def test_bogus_less_than():
with pytest.raises(TypeError):
levels.DEBUG < 42
def test_bogus_less_than_equals():
with pytest.raises(TypeError):
levels.DEBUG <= 42
def test_bogus_greater_than():
with pytest.raises(TypeError):
levels.DEBUG > 42
def test_bogus_greater_than_equals():
with pytest.raises(TypeError):
levels.DEBUG >= 42
View
@@ -4,17 +4,20 @@
# and then run "tox" from this directory.
[tox]
envlist = py26, py27, pypy, pypy3, py33, py34, py35, py36
envlist = py2{6,7}, pypy{,3}, py3{3,4,5,6}
[testenv]
deps = -r{toxinidir}/test-requirements.txt
setenv = TWIGGY_UNDER_TEST=1
commands = py.test {posargs:--tb=short --cov=twiggy --cov-report=xml --cov-report=html --cov-report=term-missing tests/}
setenv =
TWIGGY_UNDER_TEST=1
commands =
py.test {posargs:--tb=short --cov=twiggy --cov-report=xml --cov-report=html --cov-report=term-missing tests/}
[testenv:doc]
setenv = TWIGGY_UNDER_TEST=
deps = sphinx
changedir = doc
whitelist_externals = make
commands =
sphinx-build . _build/html
make linkcheck
View
@@ -3,8 +3,41 @@
``CRITICAL``, ``DISABLED``
"""
from six import PY3, with_metaclass
class LogLevel(object):
class LogLevelMeta(type):
"""
Metaclass that aids in making comparisons work the same in Python2 and Python3
Python3 raises TypeError when unorderable types are compared via lt, gt, le, ge.
Python2 picks an order but it doesn't always make much sense.
In Python3, we only need the rich comparison operators to get this behaviour.
In Python2, we use the __cmp__ function to raise TypeError for lt, gt, le, and ge.
We define __eq__ and __ne__ on their own since those should just say that a LogLevel is never
equal to a non-LogLevel.
"""
def __new__(meta, name, bases, dct):
cls = super(LogLevelMeta, meta).__new__(meta, name, bases, dct)
if PY3: # pragma: no py2 cover
cls.__lt__ = cls._lt
cls.__gt__ = cls._gt
cls.__le__ = cls._le
cls.__ge__ = cls._ge
del cls.__cmp__
else: # pragma: no py3 cover
del cls._lt
del cls._gt
del cls._le
del cls._ge
return cls
class LogLevel(with_metaclass(LogLevelMeta, object)):
"""A log level. Users should *not* create new instances.
Levels are opaque; they may be compared to each other, but nothing else.
@@ -24,42 +57,53 @@ def __str__(self):
def __repr__(self):
return "<LogLevel %s>" % self.__name
def __lt__(self, other):
def _lt(self, other): # pragma: no py2 cover
if not isinstance(other, LogLevel):
return NotImplemented
else:
return self.__value < other.__value
def __le__(self, other):
def _le(self, other): # pragma: no py2 cover
if not isinstance(other, LogLevel):
return NotImplemented
else:
return self.__value <= other.__value
def __gt__(self, other):
def _gt(self, other): # pragma: no py2 cover
if not isinstance(other, LogLevel):
return NotImplemented
else:
return self.__value > other.__value
def __ge__(self, other):
def _ge(self, other): # pragma: no py2 cover
if not isinstance(other, LogLevel):
return NotImplemented
else:
return self.__value >= other.__value
def __eq__(self, other):
if not isinstance(other, LogLevel):
return NotImplemented
return False
else:
return self.__value == other.__value
def __ne__(self, other):
if not isinstance(other, LogLevel):
return NotImplemented
return True
else:
return self.__value != other.__value
def __cmp__(self, other): # pragma: no py3 cover
# Python 2 only
if not isinstance(other, LogLevel):
raise TypeError('Unorderable types LogLevel() and %s' % type(other))
elif self.__value < other.__value:
return -1
elif self.__value > other.__value:
return 1
else:
return 0
def __hash__(self):
return hash(self.__value)

0 comments on commit 73e37d4

Please sign in to comment.