Skip to content

Commit

Permalink
Remove the assertEqual() wrapper to expose the inherited method.
Browse files Browse the repository at this point in the history
Add wrapper to the backward compatibility sub-package (api_dev2)
along with related tests.  This wrapper was used by the
assertSubject...() methods which have now been removed.  The
newer assertValid() method replaces functionality provided by
this wrapper.
  • Loading branch information
shawnbrown committed Nov 27, 2016
1 parent d554c0c commit f09968f
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 142 deletions.
39 changes: 39 additions & 0 deletions datatest/__past__/api_dev2.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@
import collections
import re

from datatest.utils.builtins import *

from datatest import DataTestCase
from datatest import CompareSet
from datatest import Extra
from datatest import BaseSource

# Needed for assertEqual() wrapper.
from datatest.compare import CompareSet
from datatest.compare import CompareDict
from datatest.compare import BaseCompare

_re_type = type(re.compile(''))


Expand All @@ -28,6 +35,38 @@ def _normalize_required(self, required, method, *args, **kwds):
DataTestCase._normalize_required = _normalize_required


def assertEqual(self, first, second, msg=None):
"""Fail if *first* does not satisfy *second* as determined by
appropriate validation comparison.
If *first* and *second* are comparable, a failure will raise a
DataError containing the differences between the two.
If the *second* argument is a helper-function (or other
callable), it is used as a key which must return True for
acceptable values.
"""
if not isinstance(first, BaseCompare):
if isinstance(first, str) or not isinstance(first, collections.Container):
first = CompareSet([first])
elif isinstance(first, collections.Set):
first = CompareSet(first)
elif isinstance(first, collections.Mapping):
first = CompareDict(first)

if callable(second):
equal = first.all(second)
default_msg = 'first object contains invalid items'
else:
equal = first == second
default_msg = 'first object does not match second object'

if not equal:
differences = first.compare(second)
self.fail(msg or default_msg, differences)
DataTestCase.assertEqual = assertEqual


def assertSubjectColumns(self, required=None, msg=None):
"""Test that the column names of subject match the *required*
values. The *required* argument can be a collection, callable,
Expand Down
45 changes: 0 additions & 45 deletions datatest/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@
from .utils.builtins import *
from .utils import collections

from .compare import CompareSet # TODO!!!: Remove after assertSubjectColumns fixed!
from .compare import CompareDict # TODO!!!: Remove after assertSubjectColumns fixed!
from .compare import BaseCompare

from .compare import _compare_mapping
from .compare import _compare_sequence
from .compare import _compare_set
Expand Down Expand Up @@ -152,47 +148,6 @@ def assertValid(self, data, required=None, msg=None):
if differences:
self.fail(msg or default_msg, differences)

def assertEqual(self, first, second, msg=None):
"""Fail if *first* does not satisfy *second* as determined by
appropriate validation comparison.
If *first* and *second* are comparable, a failure will raise a
DataError containing the differences between the two::
def test_column1(self):
first = self.subject.distinct('col1')
second = self.reference.distinct('col1')
self.assertEqual(first, second)
If the *second* argument is a helper-function (or other
callable), it is used as a key which must return True for
acceptable values::
def test_column1(self):
compare_obj = self.subject.distinct('col1')
def uppercase(x): # <- Helper function.
return str(x).isupper()
self.assertEqual(compare_obj, uppercase)
"""
if not isinstance(first, BaseCompare):
if isinstance(first, str) or not isinstance(first, collections.Container):
first = CompareSet([first])
elif isinstance(first, collections.Set):
first = CompareSet(first)
elif isinstance(first, collections.Mapping):
first = CompareDict(first)

if callable(second):
equal = first.all(second)
default_msg = 'first object contains invalid items'
else:
equal = first == second
default_msg = 'first object does not match second object'

if not equal:
differences = first.compare(second)
self.fail(msg or default_msg, differences)

#def assertUnique(self, data, msg=None):
# pass

Expand Down
84 changes: 80 additions & 4 deletions tests/past_api_dev2.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ def test_names(self):
"""In the 0.7.0 API, the assertEqual() method should be wrapped
in a datatest.DataTestCase method of the same name.
"""
# TODO: Add this check once the class has been renamed.
# Check for DataTestCase name (now TestCase).
#self.assertTrue(hasattr(datatest, 'DataTestCase'))

# Check that wrapper exists.
datatest_eq = datatest.DataTestCase.assertEqual
unittest_eq = unittest.TestCase.assertEqual
Expand All @@ -68,6 +64,86 @@ def test_method(_self):
self.assertIsNone(failure)


class TestAssertEqual(datatest.DataTestCase):
"""Test behavior of wrapped assertEqual() method."""
def test_compareset_v_compareset_fail(self):
with self.assertRaises(DataError) as cm:
first = CompareSet([1,2,3,4,5,6,7])
second = CompareSet([1,2,3,4,5,6])
self.assertEqual(first, second)

differences = cm.exception.differences
super(DataTestCase, self).assertEqual(differences, [Extra(7)])

def test_compareset_v_set_fail(self):
with self.assertRaises(DataError) as cm:
first = CompareSet([1,2,3,4,5,6,7])
second = set([1,2,3,4,5,6])
self.assertEqual(first, second)

differences = cm.exception.differences
super(DataTestCase, self).assertEqual(differences, [Extra(7)])

def test_compareset_v_callable_fail(self):
with self.assertRaises(DataError) as cm:
first = CompareSet([1,2,3,4,5,6,7])
second = lambda x: x <= 6
self.assertEqual(first, second)

differences = cm.exception.differences
super(DataTestCase, self).assertEqual(differences, [Invalid(7)])

def test_compareset_v_callable_pass(self):
first = CompareSet([1,2,3,4,5,6,7])
second = lambda x: x < 10
self.assertEqual(first, second)

def test_set_v_set_fail(self):
with self.assertRaises(DataError) as cm:
first = set([1,2,3,4,5,6,7])
second = set([1,2,3,4,5,6])
self.assertEqual(first, second)

differences = cm.exception.differences
super(DataTestCase, self).assertEqual(differences, [Extra(7)])

def test_dict_v_dict_membership_fail(self):
with self.assertRaises(DataError) as cm:
first = {'foo': 'AAA', 'bar': 'BBB'}
second = {'foo': 'AAA', 'bar': 'BBB', 'baz': 'CCC'}
self.assertEqual(first, second)

differences = cm.exception.differences
super(DataTestCase, self).assertEqual(differences, [Missing('CCC', _0='baz')])

def test_dict_v_dict_numeric_fail(self):
with self.assertRaises(DataError) as cm:
first = {'foo': 1, 'bar': 2, 'baz': 2}
second = {'foo': 1, 'bar': 2, 'baz': 3}
self.assertEqual(first, second)

differences = cm.exception.differences
super(DataTestCase, self).assertEqual(differences, [Deviation(-1, 3, _0='baz')])

def test_int_v_set_fail(self):
with self.assertRaises(DataError) as cm:
first = 4
second = set([4, 7])
self.assertEqual(first, second)

differences = cm.exception.differences
super(DataTestCase, self).assertEqual(differences, [Missing(7)])

def test_str_v_set_fail(self):
with self.assertRaises(DataError) as cm:
first = 'foo'
second = set(['foo', 'bar'])
self.assertEqual(first, second)

differences = cm.exception.differences
super(DataTestCase, self).assertEqual(differences, [Missing('bar')])


class TestNormalizeReference(datatest.DataTestCase):
def setUp(self):
self.reference = MinimalSource([
Expand Down
105 changes: 12 additions & 93 deletions tests/test_case.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
import inspect
import re
from sys import version_info as _version_info
from unittest import TestCase as _TestCase # Originial TestCase, not
# compatibility layer.

Expand Down Expand Up @@ -184,101 +185,19 @@ def test_function_and_object_mismatch(self):
self.assertValid(function)


class TestAssertEqual(TestHelperCase):
@unittest.skip('Waiting until assertEqual() is migrated to __past__.')
class TestAssertEqual(unittest.TestCase):
def test_method_identity(self):
"""The datatest.TestCase class should NOT wrap the assertEqual()
method of its superclass.
"""The datatest.DataTestCase class should NOT wrap the
assertEqual() method of its superclass. In version 0.7.0,
datatest DID wrap this method--this test should remain part
of the suite to prevent regression.
"""
datatest_assertEqual = DataTestCase.assertEqual
unittest_assertEqual = unittest.TestCase.assertEqual
self.assertIs(datatest_assertEqual, unittest_assertEqual)

def testAssertEqual(self):
class _TestClass(DataTestCase):
def test_method1(_self):
first = CompareSet([1,2,3,4,5,6,7])
second = CompareSet([1,2,3,4,5,6])
_self.assertEqual(first, second)

def test_method2(_self):
first = CompareSet([1,2,3,4,5,6,7])
second = set([1,2,3,4,5,6]) # <- Built-in set type!!!
_self.assertEqual(first, second)

def test_method3(_self):
first = CompareSet([1,2,3,4,5,6,7])
second = lambda x: x <= 6 # <- callable
_self.assertEqual(first, second)

def test_method4(_self):
first = CompareSet([1,2,3,4,5,6,7])
second = lambda x: x < 10 # <- callable
_self.assertEqual(first, second)

pattern = r"first object does not match second object:\n Extra\(7\)"

failure = self._run_one_test(_TestClass, 'test_method1')
self.assertRegex(failure, pattern)

failure = self._run_one_test(_TestClass, 'test_method2')
self.assertRegex(failure, pattern)

pattern = r"first object contains invalid items:\n Invalid\(7\)"
failure = self._run_one_test(_TestClass, 'test_method3')
self.assertRegex(failure, pattern)

failure = self._run_one_test(_TestClass, 'test_method4')
self.assertIsNone(failure)

def test_set_dict(self):
class _TestClass(DataTestCase):
def test_method1(_self):
first = set([1,2,3,4,5,6,7])
second = set([1,2,3,4,5,6])
_self.assertEqual(first, second)

def test_method2(_self):
first = {'foo': 'AAA', 'bar': 'BBB'}
second = {'foo': 'AAA', 'bar': 'BBB', 'baz': 'CCC'}
_self.assertEqual(first, second)

def test_method3(_self):
first = {'foo': 1, 'bar': 2, 'baz': 2}
second = {'foo': 1, 'bar': 2, 'baz': 3}
_self.assertEqual(first, second)

pattern = r"first object does not match second object:\n Extra\(7\)"
failure = self._run_one_test(_TestClass, 'test_method1')
self.assertRegex(failure, pattern)

pattern = r"first object does not match second object:\n Missing\('CCC', _0=u?'baz'\)"
failure = self._run_one_test(_TestClass, 'test_method2')
self.assertRegex(failure, pattern)

pattern = r"first object does not match second object:\n Deviation\(-1, 3, _0=u?'baz'\)"
failure = self._run_one_test(_TestClass, 'test_method3')
self.assertRegex(failure, pattern)

def test_int_str(self):
class _TestClass(DataTestCase):
def test_method1(_self):
first = 4
second = set([4, 7])
_self.assertEqual(first, second)

def test_method3(_self):
first = 'foo'
second = set(['foo', 'bar'])
_self.assertEqual(first, second)

pattern = r"first object does not match second object:\n Missing\(7\)"
failure = self._run_one_test(_TestClass, 'test_method1')
self.assertRegex(failure, pattern)

pattern = r"first object does not match second object:\n Missing\('bar'\)"
failure = self._run_one_test(_TestClass, 'test_method3')
self.assertRegex(failure, pattern)
if _version_info[:2] > (2, 7): # For versions newer than 2.7.
self.assertIs(DataTestCase.assertEqual, unittest.TestCase.assertEqual)
else:
id_val1 = id(DataTestCase.assertEqual)
id_val2 = id(unittest.TestCase.assertEqual)
self.assertEqual(id_val1, id_val2)


class TestAllowanceWrappers(unittest.TestCase):
Expand Down

0 comments on commit f09968f

Please sign in to comment.