예제 #1
0
    def test_instantiation(self):
        DataError('column names', xMissing('foo'))
        DataError('column names', [xMissing('foo')])
        DataError('column names', {'foo': xMissing('bar')})
        DataError('column names', {('foo', 'bar'): xMissing('baz')})

        with self.assertRaises(ValueError, msg='Empty error should raise exception.'):
            DataError(msg='', differences={})
예제 #2
0
    def test_allow_all(self):
        differences = [Missing('xxx'), Extra('yyy')]
        with allow_only(differences):
            raise DataError('example error', [Missing('xxx'), Extra('yyy')])

        # Order of differences should not matter!
        differences = [Extra('yyy'), Missing('xxx')]
        with allow_only(differences):
            raise DataError('example error', reversed(differences))
예제 #3
0
    def test_kwds_all_ok(self):
        function = lambda iterable: list()  # <- Accepts everything.
        in_diffs = [
            Missing('foo', aaa='x', bbb='y'),
            Missing('bar', aaa='x', bbb='z'),
        ]
        # Using keyword aaa='x' should accept all in_diffs.
        with allow_iter(function, 'example message', aaa='x'):
            raise DataError('example error', in_diffs)

        # Using keyword bbb=['y', 'z'] should also accept all in_diffs.
        with allow_iter(function, 'example message', bbb=['y', 'z']):
            raise DataError('example error', in_diffs)
예제 #4
0
    def test_verbose_repr(self):
        reference = 'reference-data-source'
        subject = 'subject-data-source'
        error = DataError('different columns', [xMissing('foo')], subject, reference)
        error._verbose = True  # <- Set verbose flag, here!

        pattern = ("DataError: different columns:\n"
                   " xMissing('foo')\n"
                   "\n"
                   "SUBJECT:\n"
                   "subject-data-source\n"
                   "REQUIRED:\n"
                   "reference-data-source")
        self.assertEqual(repr(error), pattern)
    def __exit__(self, exc_type, exc_value, tb):
        if exc_type is None:  # <- Values are None when no exeption was raised.
            if self.msg:
                msg = self.msg
            else:
                msg = getattr(self.function, '__name__', str(self.function))
            exc = AssertionError('No differences found: ' + str(msg))
            exc.__cause__ = None
            raise exc

        if not issubclass(exc_type, DataError):
            raise exc_value  # If not DataError, re-raise without changes.

        diffs = exc_value.differences
        rejected_kwds, accepted_kwds = self._partition_kwds(diffs, **self.kwds)
        rejected_func = self.function(accepted_kwds)  # <- Apply function!
        not_allowed = itertools.chain(rejected_kwds, rejected_func)

        not_allowed = list(not_allowed)
        if not_allowed:
            msg = [self.msg, getattr(exc_value, 'msg')]
            msg = ': '.join(x for x in msg if x)
            exc = DataError(msg, not_allowed)
            exc.__cause__ = None  # <- Suppress context using verbose
            raise exc             # alternative to support older Python
                                  # versions--see PEP 415 (same as
                                  # effect as "raise ... from None").

        return True  # <- Suppress original exception.
예제 #6
0
    def test_allow_one_but_find_duplicate(self):
        with self.assertRaises(DataError) as cm:
            with allow_only(Extra('xxx')):
                raise DataError('example error', [Extra('xxx'), Extra('xxx')])

        result_string = str(cm.exception)
        self.assertEqual("example error:\n xExtra('xxx')", result_string)
예제 #7
0
 def test_method2(_self):
     with _self.allowExtra():  # <- allow unlimited number.
         differences = [
             datatest.Extra('foo'),
             datatest.Missing('bar'),
             datatest.Missing('baz'),
         ]
         raise DataError('some differences', differences)
예제 #8
0
 def test_method1(_self):
     with _self.allowExtra(3):
         differences = [
             datatest.Extra('foo'),
             datatest.Missing('bar'),
             datatest.Missing('baz'),
         ]
         raise DataError('some differences', differences)
예제 #9
0
 def test_method(_self):
     with _self.allowAny(2):  # <- allow two
         differences = [
             datatest.Missing('foo'),
             datatest.Missing('bar'),
             datatest.Missing('baz'),
         ]
         raise DataError('some differences', differences)
 def function(iterable):
     allowed = self._walk_diff(differences)  # <- Closes over *differences*.
     allowed = Counter(allowed)
     not_allowed = []
     for x in iterable:
         if allowed[x]:
             allowed[x] -= 1
         else:
             not_allowed.append(x)
     if not_allowed:
         return not_allowed  # <- EXIT!
     not_found = list(allowed.elements())
     if not_found:
         exc = DataError('Allowed difference not found', not_found)
         exc.__cause__ = None
         raise exc
     return iter([])
예제 #11
0
 def test_method2(_self):
     with _self.allowAny(4):  # <- allow four
         differences = [
             datatest.Extra('foo'),
             datatest.Missing('bar'),
             datatest.Invalid('baz'),
         ]
         raise DataError('some differences', differences)
예제 #12
0
    def test_allow_duplicate_but_find_only_one(self):
        with self.assertRaises(DataError) as cm:
            with allow_only([Extra('xxx'), Extra('xxx')]):
                raise DataError('example error', [Extra('xxx')])

        result_string = str(cm.exception)
        self.assertEqual("Allowed difference not found:\n xExtra('xxx')",
                         result_string)
예제 #13
0
 def test_passing(_self):
     with _self.allowAny(
             3, label1='a'):  # <- allow 3 where label1 equals 'a'
         differences = [
             datatest.Deviation(-1, 3, label1='a', label2='x'),
             datatest.Deviation(+1, 4, label1='a', label2='y'),
             datatest.Deviation(-2, 5, label1='a', label2='z'),
         ]
         raise DataError('some differences', differences)
예제 #14
0
    def test_allow_some(self):
        differences = [Extra('xxx'), Missing('yyy')]

        with self.assertRaises(DataError) as cm:
            with allow_limit(1):  # <- Allows only 1 but there are 2!
                raise DataError('example error', differences)

        rejected = list(cm.exception.differences)
        self.assertEqual(differences, rejected)
예제 #15
0
    def test_allow_some(self):
        differences = [Extra('xxx'), Missing('yyy')]

        with self.assertRaises(DataError) as cm:
            with allow_missing():
                raise DataError('example error', differences)

        rejected = list(cm.exception.differences)
        self.assertEqual(rejected, [Extra('xxx')])
예제 #16
0
    def test_not_found(self):
        with self.assertRaises(DataError) as cm:
            with allow_only([Extra('xxx'), Missing('yyy')]):
                raise DataError('example error', [Extra('xxx')])

        result_str = str(cm.exception)
        self.assertTrue(result_str.startswith('Allowed difference not found'))

        result_diffs = list(cm.exception.differences)
        self.assertEqual([Missing('yyy')], result_diffs)
예제 #17
0
 def test_fail_with_nonmatched(_self):
     with _self.allowAny(
             label1='a'
     ):  # <- allow unlimited where label1 equals 'a'
         differences = [
             datatest.Deviation(-1, 3, label1='a', label2='x'),
             datatest.Deviation(+1, 4, label1='a', label2='y'),
             datatest.Deviation(-2, 5, label1='b',
                                label2='z'),  # <- label='b'
         ]
         raise DataError('some differences', differences)
예제 #18
0
    def test_kwds(self):
        diff_set = set([
            Missing('xxx', aaa='foo'),
            Missing('yyy', aaa='bar'),
            Extra('zzz', aaa='foo'),
        ])

        with self.assertRaises(DataError) as cm:
            # Allows 2 with aaa='foo' and there are two (only aaa='bar' is rejected).
            with allow_limit(2, 'example message', aaa='foo'):
                raise DataError('example error', diff_set)
        rejected = set(cm.exception.differences)
        self.assertEqual(rejected, set([Missing('yyy', aaa='bar')]))

        with self.assertRaises(DataError) as cm:
            # Allows 1 with aaa='foo' but there are 2 (all are rejected)!
            with allow_limit(1, 'example message', aaa='foo'):
                raise DataError('example error', diff_set)
        rejected = set(cm.exception.differences)
        self.assertEqual(rejected, diff_set)
예제 #19
0
    def test_kwds(self):
        in_diffs = [
            Extra('xxx', aaa='foo'),
            Extra('yyy', aaa='bar'),
            Missing('zzz', aaa='foo'),
        ]
        with self.assertRaises(DataError) as cm:
            with allow_any('example message', aaa='foo'):
                raise DataError('example error', in_diffs)

        rejected = list(cm.exception.differences)
        self.assertEqual(rejected, [Extra('yyy', aaa='bar')])
예제 #20
0
    def test_allow_some(self):
        with self.assertRaises(DataError) as cm:
            with allow_only(Extra('xxx'), 'example message'):
                raise DataError('example error',
                                [Extra('xxx'), Missing('yyy')])

        result_str = str(cm.exception)
        self.assertEqual("example message: example error:\n xMissing('yyy')",
                         result_str)

        result_diffs = list(cm.exception.differences)
        self.assertEqual([Missing('yyy')], result_diffs)
예제 #21
0
    def test_function_some_ok(self):
        function = lambda iterable: (x for x in iterable if x.value != 'bar')
        in_diffs = [
            Missing('foo'),
            Missing('bar'),
        ]
        with self.assertRaises(DataError) as cm:
            with allow_iter(function, 'example message'):
                raise DataError('example error', in_diffs)

        rejected = list(cm.exception.differences)
        self.assertEqual(rejected, [Missing('foo')])
예제 #22
0
    def test_allow_some(self):
        function = lambda x: x.value == 'bar'
        in_diffs = [
            Missing('foo'),
            Missing('bar'),
        ]
        with self.assertRaises(DataError) as cm:
            with allow_each(function, 'example message'):
                raise DataError('example error', in_diffs)

        rejected = list(cm.exception.differences)
        self.assertEqual(rejected, [Missing('foo')])
예제 #23
0
    def test_no_kwds(self):
        in_diffs = [
            Extra('xxx', aaa='foo'),
            Extra('yyy', aaa='bar'),
        ]
        with self.assertRaises(TypeError) as cm:
            with allow_any('example message'):  # <- Missing keyword argument!
                raise DataError('example error', in_diffs)

        result = cm.exception
        expected = 'requires 1 or more keyword arguments (0 given)'
        self.assertEqual(expected, str(result))
예제 #24
0
    def test_function_all_bad(self):
        function = lambda iterable: iterable  # <- Rejects everything.
        in_diffs = [
            Extra('foo'),
            Extra('bar'),
        ]
        with self.assertRaises(DataError) as cm:
            with allow_iter(function, 'example message'):
                raise DataError('example error', in_diffs)

        rejected = cm.exception.differences
        self.assertEqual(rejected, in_diffs)
예제 #25
0
    def test_empty_value_handling(self):
        # Test NoneType.
        with allow_percent_deviation(0):  # <- Pass without failure.
            raise DataError('example error', [xDeviation(None, 0)])

        with allow_percent_deviation(0):  # <- Pass without failure.
            raise DataError('example error', [xDeviation(0, None)])

        # Test empty string.
        with allow_percent_deviation(0):  # <- Pass without failure.
            raise DataError('example error', [xDeviation('', 0)])

        with allow_percent_deviation(0):  # <- Pass without failure.
            raise DataError('example error', [xDeviation(0, '')])

        # Test NaN (not a number) values.
        with self.assertRaises(
                DataError):  # <- NaN values should not be caught!
            with allow_percent_deviation(0):
                raise DataError('example error', [xDeviation(float('nan'), 0)])

        with self.assertRaises(
                DataError):  # <- NaN values should not be caught!
            with allow_percent_deviation(0):
                raise DataError('example error', [xDeviation(0, float('nan'))])
예제 #26
0
    def test_kwds_all_bad(self):
        function = lambda iterable: list()  # <- Accepts everything.
        in_diffs = [
            Missing('foo', aaa='x', bbb='y'),
            Missing('bar', aaa='x', bbb='z'),
        ]
        with self.assertRaises(DataError) as cm:
            # Using keyword bbb='j' should reject all in_diffs.
            with allow_iter(function, 'example allowance', bbb='j'):
                raise DataError('example error', in_diffs)

        rejected = list(cm.exception.differences)
        self.assertEqual(rejected, in_diffs)
예제 #27
0
    def test_repr(self):
        error = DataError('different columns', [xMissing('foo')])
        pattern = "DataError: different columns:\n xMissing('foo')"
        self.assertEqual(repr(error), pattern)

        error = DataError('different columns', xMissing('foo'))
        pattern = "DataError: different columns:\n xMissing('foo')"
        self.assertEqual(repr(error), pattern)

        # Test pprint lists.
        error = DataError('different columns', [xMissing('foo'),
                                                xMissing('bar')])
        pattern = ("DataError: different columns:\n"
                   " xMissing('foo'),\n"
                   " xMissing('bar')")
        self.assertEqual(repr(error), pattern)

        # Test dictionary.
        error = DataError('different columns', {'FOO': xMissing('bar')})
        pattern = ("DataError: different columns:\n"
                   " 'FOO': xMissing('bar')")
        self.assertEqual(repr(error), pattern)
def fail(self, msg, differences=None):
    if differences:
        try:
            subject = self.subject
        except NameError:
            subject = None
        try:
            required = self.reference
        except NameError:
            required = None
        raise DataError(msg, differences, subject, required)
    else:
        raise self.failureException(msg)
예제 #29
0
    def test_kwds_some_ok(self):
        function = lambda iterable: list()  # <- Accepts everything.
        in_diffs = [
            Missing('foo', aaa='x', bbb='y'),
            Missing('bar', aaa='x', bbb='z'),
        ]
        with self.assertRaises(DataError) as cm:
            # Keyword bbb='y' should reject second in_diffs element.
            with allow_iter(function, 'example message', bbb='y'):
                raise DataError('example error', in_diffs)

        rejected = list(cm.exception.differences)
        self.assertEqual(rejected, [Missing('bar', aaa='x', bbb='z')])
예제 #30
0
 def test_nested_acceptances(self):
     """A quick integration test to make sure acceptances nest as
     required.
     """
     with allow_only(xDeviation(-4, 70,
                                label1='b')):  # <- specified diff only
         with allow_deviation(3):  # <- tolerance of +/- 3
             with allow_percent_deviation(0.02):  # <- tolerance of +/- 2%
                 differences = [
                     xDeviation(+3, 65, label1='a'),
                     xDeviation(-4, 70, label1='b'),
                     xDeviation(+5, 250, label1='c'),
                 ]
                 raise DataError('example error', differences)