Beispiel #1
0
    def test_expected_handling(self):
        item = Invalid('foo', 'FOO')
        self.assertEqual("Invalid('foo', 'FOO')", repr(item))

        # QUESTION: How should kwds be handled if keys match item or expected?
        with self.assertRaises(TypeError):
            item = Invalid('foo', 'FOO', required='bar')
Beispiel #2
0
    def test_mapping_vs_mapping_failing(self):
        with self.assertRaises(ValidationError) as cm:
            data = {
                'a': ('abc', 1.0),
                'b': ('xyz', 2.0)
            }  # Mapping of base-elements.
            requirement = {
                'a': ('abc', int),
                'b': ('abc', float)
            }  # Mapping of requirements.
            validate(data, requirement)
        actual = cm.exception.differences
        expected = {
            'a': Invalid(('abc', 1.0), ('abc', int)),
            'b': Invalid(('xyz', 2.0), ('abc', float)),
        }
        self.assertEqual(actual, expected)

        with self.assertRaises(ValidationError) as cm:
            data = {
                'a': [('abc', 1.0), ('abc', 2)],
                'b': [('abc', 1.0), ('xyz', 2.0)]
            }  # Mapping of containers.
            requirement = {
                'a': ('abc', int),
                'b': ('abc', float)
            }  # Mapping of requirements.
            validate(data, requirement)
        actual = cm.exception.differences
        expected = {
            'a': [Invalid(('abc', 1.0))],
            'b': [Invalid(('xyz', 2.0))],
        }
        self.assertEqual(actual, expected)
    def test_get_deviation_expected_extra_or_single_arg_invalid(self):
        """Extra and single-argument Invalid differences should be
        treated the same.
        """
        func = AcceptedTolerance._get_deviation_expected

        self.assertEqual(func(Extra(2)), (2, 0))
        self.assertEqual(func(Invalid(2)), (2, 0))

        self.assertEqual(func(Extra(-2)), (-2, 0))
        self.assertEqual(func(Invalid(-2)), (-2, 0))

        self.assertEqual(func(Extra(0)), (0, 0))
        self.assertEqual(func(Invalid(0)), (0, 0))

        with self.assertRaises(TypeError):
            func(Extra((1, 2)))

        with self.assertRaises(TypeError):
            func(Invalid((1, 2)))

        with self.assertRaises(TypeError):
            func(Extra('abc'))

        with self.assertRaises(TypeError):
            func(Invalid('abc'))
Beispiel #4
0
 def test_hashable(self):
     """Differences with hashable *args should be hashable."""
     # Following should all pass without error.
     hash(Missing('foo'))
     hash(Extra('bar'))
     hash(Invalid('baz'))
     hash(Invalid('baz', 'qux'))
     hash(Deviation(-1, 10))
    def test_accepted_invalid(self):
        differences =  [Invalid('X'), Invalid('Y'), Extra('Z')]

        with self.assertRaises(ValidationError) as cm:
            with AcceptedDifferences(Invalid):  # <- Apply acceptance!
                raise ValidationError(differences)
        remaining_diffs = cm.exception.differences
        self.assertEqual(list(remaining_diffs), [Extra('Z')])
Beispiel #6
0
    def test_invalid(self):
        diff = Invalid('foo')

        with self.assertRaises(AttributeError):
            diff.expected = 'bar'

        with self.assertRaises(AttributeError):
            diff.new_attribute = 'baz'
Beispiel #7
0
    def test_repr(self):
        item = Invalid('foo')
        self.assertEqual("Invalid('foo')", repr(item))

        item = Invalid(None)
        self.assertEqual("Invalid(None)", repr(item))

        item = Invalid(2)
        self.assertEqual("Invalid(2)", repr(item))
Beispiel #8
0
    def test_repr(self):
        diff = Invalid('foo')
        self.assertEqual(repr(diff), "Invalid('foo')")

        diff = Invalid('foo', 'bar')
        self.assertEqual(repr(diff), "Invalid('foo', expected='bar')")

        diff = Invalid('foo', None)
        self.assertEqual(repr(diff), "Invalid('foo', expected=None)")
Beispiel #9
0
    def test_same(self):
        """The _getdiff() function returns differences for objects that
        are KNOWN TO BE DIFFERENT--it does not test for differences
        itself.
        """
        diff = _getdiff('a', 'a')
        self.assertEqual(diff, Invalid('a', 'a'))

        diff = _getdiff(None, None)
        self.assertEqual(diff, Invalid(None, None))
 def test_invalid_deviation_single_arg_percent(self):
     # Check error percent.
     with self.assertRaises(ValidationError) as cm:
         with AcceptedPercent(2.0):  # <- Accepts +/- 200%.
             raise ValidationError([
                 Invalid(-1),  # <- Rejected: Can not be accepted by percent.
                 Invalid(0),   # <- ACCEPTED!
                 Invalid(2),   # <- Rejected: Can not be accepted by percent.
             ])
     remaining = cm.exception.differences
     self.assertEqual(remaining, [Invalid(-1), Invalid(2)])
    def test_scope(self):
        with self.assertRaises(ValidationError) as cm:
            with AcceptedCount(2, scope='group'):  # <- Accepts 2 per group.
                raise ValidationError({
                    'foo': [Extra('xxx'), Extra('yyy')],
                    'bar': [Missing('xxx'), Missing('yyy')],
                    'baz': [Invalid('xxx'), Invalid('yyy'), Invalid('zzz')],
                })

        remaining = cm.exception.differences
        self.assertEqual(remaining, {'baz': Invalid('zzz')})
 def test_nonnumeric_but_compatible(self):
     with self.assertRaises(ValidationError) as cm:
         with AcceptedTolerance(datetime.timedelta(hours=2)):  # <- Accepts +/- 2 hours.
             raise ValidationError([
                 Invalid(datetime.datetime(1989, 2, 24, hour=10, minute=30),
                         datetime.datetime(1989, 2, 24, hour=11, minute=30)),
                 Invalid(datetime.datetime(1989, 2, 24, hour=15, minute=10),
                         datetime.datetime(1989, 2, 24, hour=11, minute=30))
             ])
     remaining = cm.exception.differences
     self.assertEqual(remaining, [Invalid(datetime.datetime(1989, 2, 24, 15, 10),
                                          expected=datetime.datetime(1989, 2, 24, 11, 30))])
 def setUp(self):
     ntup = namedtuple('ntup', ('cls', 'args', 'scope'))
     self.acceptances = [
         ntup(cls=AcceptedDifferences, args=(Invalid('A'),),        scope=set(['element'])),
         ntup(cls=AcceptedDifferences, args=([Invalid('A')],),      scope=set(['group'])),
         ntup(cls=AcceptedDifferences, args=({'X': [Invalid('A')]},), scope=set(['group'])),
         ntup(cls=AcceptedDifferences, args=([Invalid('A')], None, 'whole'), scope=set(['whole'])),
         ntup(cls=AcceptedKeys,      args=(lambda args: True,),     scope=set(['element'])),
         ntup(cls=AcceptedArgs,      args=(lambda *args: True,),    scope=set(['element'])),
         ntup(cls=AcceptedTolerance, args=(10,),                    scope=set(['element'])),
         ntup(cls=AcceptedPercent,   args=(0.05,),                  scope=set(['element'])),
         ntup(cls=AcceptedFuzzy,     args=tuple(),                  scope=set(['element'])),
         ntup(cls=AcceptedCount,     args=(4,),                     scope=set(['whole'])),
     ]
Beispiel #14
0
    def test_show_expected(self):
        """If requirement is common it should be omitted from Invalid
        difference (but not from Deviation differences).
        """
        diff = _make_difference('a', 6, show_expected=True)
        self.assertEqual(diff, Invalid('a', expected=6))

        diff = _make_difference('a', 6, show_expected=False)
        self.assertEqual(diff, Invalid('a'))

        # Show expected has no value with Missing or Extra differences.
        diff = _make_difference(NOVALUE, 6, show_expected=False)
        self.assertEqual(diff, Missing(6))

        diff = _make_difference(6, NOVALUE, show_expected=False)
        self.assertEqual(diff, Extra(6))
Beispiel #15
0
    def test_unhashable_contents(self):
        """The hash behavior of differences should act like tuples do.
        When a difference's contents are unhashable, the difference
        itself becomes unhashable too.
        """
        with self.assertRaises(TypeError):
            hash(Missing(['foo']))

        with self.assertRaises(TypeError):
            hash(Extra(['bar']))

        with self.assertRaises(TypeError):
            hash(Invalid(['baz']))

        with self.assertRaises(TypeError):
            hash(Invalid('baz', ['qux']))
    def test_non_deviation_diffs(self):
        diffs = [Missing('foo'), Extra('bar'), Invalid('baz')]
        with self.assertRaises(ValidationError) as cm:
            with AcceptedPercent(0.05):
                raise ValidationError(diffs)

        uncaught_diffs = cm.exception.differences
        self.assertEqual(diffs, uncaught_diffs)
Beispiel #17
0
    def test_required_mapping(self):
        with self.assertRaises(ValidationError) as cm:
            data = {'AAA': 'a', 'BBB': 'x'}
            required = {'AAA': 'a', 'BBB': 'b', 'CCC': 'c'}
            self.assertValid(data, required)

        differences = cm.exception.differences
        self.assertEqual(differences, {'BBB': Invalid('x', 'b'), 'CCC': Missing('c')})
Beispiel #18
0
    def test_repr_with_callables(self):
        def myfunc(x):
            return True

        class MyClass(object):
            pass

        diff = Invalid('foo', myfunc)
        self.assertEqual(repr(diff), "Invalid('foo', expected=myfunc)")

        diff = Invalid('foo', MyClass)
        self.assertEqual(repr(diff), "Invalid('foo', expected=MyClass)")

        diff = Invalid(myfunc, 'bar')
        self.assertEqual(repr(diff), "Invalid(myfunc, expected='bar')")

        diff = Invalid(MyClass, 'bar')
        self.assertEqual(repr(diff), "Invalid(MyClass, expected='bar')")
Beispiel #19
0
    def test_is_common(self):
        """If requirement is common it should be omitted from Invalid
        difference (but not from Deviation differences).
        """
        diff = _getdiff('a', 6, is_common=True)
        self.assertEqual(diff, Invalid('a'))

        diff = _getdiff(_NOTFOUND, 6, is_common=True)
        self.assertEqual(diff, Deviation(-6, 6))
Beispiel #20
0
    def test_predicate_regex(self):
        data = {'A': 'Alpha', 'B': ['Beta', 'Gamma']}
        requirement = Query.from_object({'A': r'^[A-Z]', 'B': r'^[A-Z]'})
        validate.regex(data, requirement)

        with self.assertRaises(ValidationError) as cm:
            data = {'A': 'Alpha', 'B': ['Beta', 'gamma'], 'C': ('b', 2)}
            requirement = Query.from_object({
                'A': r'^[A-Z]',
                'B': r'^[A-Z]',
                'C': r'\d'
            })
            validate.regex(data, requirement)
        actual = cm.exception.differences
        expected = {
            'B': [Invalid('gamma')],
            'C': Invalid(('b', 2), expected=r'\d'),
        }
        self.assertEqual(actual, expected)
Beispiel #21
0
    def test_keywords(self):
        """Keywords should be passed to diff objet."""
        diff = _getdiff(5, 6, col1='AAA')
        self.assertEqual(diff, Deviation(-1, 6, col1='AAA'))

        diff = _getdiff('a', 6, col1='AAA')
        self.assertEqual(diff, Invalid('a', 6, col1='AAA'))

        diff = _getdiff(_NOTFOUND, 6, col1='AAA')
        self.assertEqual(diff, Deviation(-6, 6, col1='AAA'))
Beispiel #22
0
    def test_required_other(self):
        """When *required* is a string or other object, _compare_other()
        should be called.
        """
        with self.assertRaises(ValidationError) as cm:
            required = lambda x: x.isupper()
            data = ['AAA', 'BBB', 'ccc', 'DDD']
            self.assertValid(data, required)

        differences = cm.exception.differences
        self.assertEqual(differences, [Invalid('ccc')])
Beispiel #23
0
    def test_required_vs_data_failing(self):
        """Apply single requirement to BaseElement or non-mapping
        container of data.
        """
        with self.assertRaises(ValidationError) as cm:
            data = ('abc', 1.0)  # A single base element.
            requirement = ('abc', int)
            validate(data, requirement)
        differences = cm.exception.differences
        self.assertEqual(differences, [Invalid(('abc', 1.0))])

        with self.assertRaises(ValidationError) as cm:
            data = [('abc', 1.0),
                    ('xyz', 2)]  # Non-mapping container of base elements.
            requirement = ('abc', int)
            validate(data, requirement)
        differences = cm.exception.differences
        self.assertEqual(
            differences, [Invalid(
                ('abc', 1.0)), Invalid(('xyz', 2))])
Beispiel #24
0
    def test_fuzzy_method(self):
        data = {'A': 'aaa', 'B': 'bbx'}
        requirement = Query.from_object({'A': 'aaa', 'B': 'bbb'})
        validate.fuzzy(data, requirement)

        with self.assertRaises(ValidationError) as cm:
            data = {'A': 'axx', 'B': 'bbx'}
            requirement = Query.from_object({'A': 'aaa', 'B': 'bbb'})
            validate.fuzzy(data, requirement)
        actual = cm.exception.differences
        expected = {'A': Invalid('axx', expected='aaa')}
        self.assertEqual(actual, expected)
    def test_failing(self):
        with self.assertRaises(ValidationError) as cm:
            with AcceptedFuzzy(cutoff=0.7):
                raise ValidationError(self.differences)
        remaining = cm.exception.differences
        self.assertEqual(remaining, [Invalid('bbyy', 'bbbb')])

        with self.assertRaises(ValidationError) as cm:
            with AcceptedFuzzy(cutoff=0.8):
                raise ValidationError(self.differences)
        remaining = cm.exception.differences
        self.assertEqual(remaining, self.differences, msg='none accepted')
    def test_percent_empty_value_handling(self):
        # Test empty deviation cases--should pass without error.
        with AcceptedPercent(0):  # <- Accepts empty deviations only.
            raise ValidationError([
                Invalid(None, 0),
                Invalid('', 0),
            ])

        # Test diffs that can not be accepted as percentages.
        with self.assertRaises(ValidationError) as cm:
            with AcceptedPercent(2.00):  # <- Accepts +/- 200%.
                raise ValidationError([
                    Invalid(None, 0),             # 0%
                    Invalid(0, None),             # 0%
                    Deviation(+2, 0),             # Can not be accepted by percent.
                    Invalid(+2, None),            # Can not be accepted by percent.
                    Deviation(float('nan'), 16),  # Not a number.
                ])
        actual = cm.exception.differences
        expected = [
            Deviation(+2, 0),             # Can not be accepted by percent.
            Invalid(2, None),             # Can not be accepted by percent.
            Deviation(float('nan'), 16),  # Not a number.
        ]
        self.assertEqual(actual, expected)
Beispiel #27
0
    def test_required_vs_mapping_failing(self):
        with self.assertRaises(ValidationError) as cm:
            data = {
                'a': ('abc', 1.0),
                'b': ('xyz', 2)
            }  # Mapping of base-elements.
            requirement = ('abc', int)
            validate(data, requirement)
        differences = cm.exception.differences
        self.assertEqual(differences, {
            'a': Invalid(('abc', 1.0)),
            'b': Invalid(('xyz', 2))
        })

        with self.assertRaises(ValidationError) as cm:
            data = {'a': [1, 2.0], 'b': [3.0, 4]}  # Mapping of containers.
            validate(data, int)
        differences = cm.exception.differences
        self.assertEqual(differences, {
            'a': [Invalid(2.0)],
            'b': [Invalid(3.0)]
        })
Beispiel #28
0
    def test_predicate_method(self):
        data = {'A': 'aaa', 'B': [1, 2, 3], 'C': ('a', 1)}
        requirement = Query.from_object({
            'A': set(['aaa', 'bbb']),
            'B': int,
            'C': ('a', 1)
        })
        validate.predicate(data, requirement)

        with self.assertRaises(ValidationError) as cm:
            data = {'A': 'aaa', 'B': [1, 2, 3.5], 'C': ('b', 2)}
            requirement = Query.from_object({
                'A': set(['aaa', 'bbb']),
                'B': int,
                'C': ('a', 1)
            })
            validate.predicate(data, requirement)
        actual = cm.exception.differences
        expected = {
            'B': [Invalid(3.5)],
            'C': Invalid(('b', 2), expected=('a', 1)),
        }
        self.assertEqual(actual, expected)
Beispiel #29
0
    def test_object_vs_object(self):
        """Non-numeric comparisons return Invalid type."""
        diff = _make_difference('a', 'b')
        self.assertEqual(diff, Invalid('a', 'b'))

        diff = _make_difference(5, 'b')
        self.assertEqual(diff, Invalid(5, 'b'))

        diff = _make_difference('a', 6)
        self.assertEqual(diff, Invalid('a', 6))

        diff = _make_difference(float('nan'), 6)
        self.assertEqual(diff, Deviation(float('nan'), 6))

        diff = _make_difference(5, float('nan'))
        self.assertEqual(diff, Deviation(float('nan'), float('nan')))

        fn = lambda x: True
        diff = _make_difference('a', fn)
        self.assertEqual(diff, Invalid('a', fn))

        regex = re.compile('^test$')
        diff = _make_difference('a', regex)
        self.assertEqual(diff, Invalid('a', re.compile('^test$')))
Beispiel #30
0
    def test_required_sequence(self):
        """When *required* is a sequence, should compare predicates by
        position.
        """
        with self.assertRaises(ValidationError) as cm:
            data = ['a', 2, 'x', 3]
            required = ['a', 2, 'c', 4]
            self.assertValid(data, required)

        error = cm.exception
        expected = [
            Invalid('x', expected='c'),
            Deviation(-1, 4),
        ]
        self.assertEqual(error.differences, expected)
        self.assertEqual(error.args[1], 'does not match required sequence')