示例#1
0
 def test_compare_mixed_types(self):
     a = CompareDict({'aaa': 2, 'bbb': 3, 'ccc': 'z'}, 'foo')
     b = CompareDict({'aaa': 'y', 'bbb': 4.0, 'ccc': 5}, 'foo')
     expected = set([
         xInvalid(2, 'y', foo='aaa'),
         xDeviation(-1, 4, foo='bbb'),
         xInvalid('z', 5, foo='ccc'),
     ])
     self.assertEqual(expected, set(a.compare(b)))
示例#2
0
    def test_ne(self):
        data1 = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
        a = CompareDict(data1, 'foo')
        b = CompareDict(data1, 'foo')
        self.assertFalse(a != b)

        data2 = {'a': 1, 'b': 2.5, 'c': 3, 'd': 4}
        a = CompareDict(data1, 'foo')
        b = CompareDict(data2, 'foo')
        self.assertTrue(a != b)
示例#3
0
    def test_repr(self):
        expected = "CompareDict({'a': 1}, key_names='foo')"
        result = CompareDict({'a': 1}, 'foo')
        self.assertEqual(expected, repr(result))

        result = CompareDict({('a', ): 1},
                             ['foo'])  # <- Single-item containers.
        self.assertEqual(expected, repr(result))  # Same "expected" as above.

        expected = "CompareDict({('a', 'b'): 1}, key_names=['foo', 'bar'])"
        result = CompareDict({('a', 'b'): 1}, ['foo', 'bar'])
        self.assertEqual(expected, repr(result))
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, Container):
            first = CompareSet([first])
        elif isinstance(first, Set):
            first = CompareSet(first)
        elif isinstance(first, 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)
示例#5
0
    def test_eq(self):
        data1 = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
        a = CompareDict(data1, 'foo')
        b = CompareDict(data1, 'foo')
        self.assertTrue(a == b)

        data2 = {'a': 1, 'b': 2.5, 'c': 3, 'd': 4}
        a = CompareDict(data1, 'foo')
        b = CompareDict(data2, 'foo')
        self.assertFalse(a == b)

        # Test coersion of mapping.
        data1 = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
        a = CompareDict(data1, 'foo')
        self.assertTrue(a == {'a': 1, 'b': 2, 'c': 3, 'd': 4})

        # Test coersion of list of tuples.
        data1 = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
        data2 = [
            ('a', 1),  # <- Should be coerced
            ('b', 2),  #    into CompareDict
            ('c', 3),  #    internally.
            ('d', 4)
        ]
        a = CompareDict(data1, 'foo')
        b = data2
        self.assertTrue(a == b)
示例#6
0
    def test_init(self):
        data = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

        x = CompareDict(data, 'foo')  # dict.
        self.assertEqual(data, x)

        x = CompareDict(list(data.items()), 'foo')  # list of tuples.
        self.assertEqual(data, x)

        # Non-mapping data (data error).
        data_list = ['a', 'b', 'c', 'd']
        with self.assertRaises(ValueError):
            x = CompareDict(data_list, 'foo')

        # Single-item wrapped in collection.
        data = {('a', ): 1, ('b', ): 2, ('c', ): 3, ('d', ): 4}
        x = CompareDict(data, ['foo'])
        unwrapped = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
        self.assertEqual(unwrapped, x)

        # Omitted *key_names*.
        data = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
        x = CompareDict(data)
        self.assertEqual(data, x)
        self.assertEqual(x.key_names, ('_0', ))

        data = {('a', 'a'): 1, ('b', 'b'): 2, ('c', 'c'): 3}
        x = CompareDict(data)
        self.assertEqual(data, x)
        self.assertEqual(x.key_names, ('_0', '_1'))
示例#7
0
    def test_compare_function(self):
        a = CompareDict({'aaa': 'x', 'bbb': 'y', 'ccc': 'z'}, 'foo')

        # All True.
        result = a.compare(lambda x: len(x) == 1)
        self.assertEqual([], result)

        # Some False.
        result = a.compare(lambda a: a in ('x', 'y'))
        expected = [xInvalid('z', foo='ccc')]
        self.assertEqual(expected, result)

        # All True, multiple args.
        a = CompareDict({'aaa': (1, 2), 'bbb': (1, 3), 'ccc': (4, 8)}, 'foo')
        result = a.compare(lambda x, y: x < y)
        self.assertEqual([], result)

        # Some False, multiple args.
        a = CompareDict({'aaa': (1, 0), 'bbb': (1, 3), 'ccc': (3, 2)}, 'foo')
        result = a.compare(lambda x, y: x < y)
        expected = [xInvalid((1, 0), foo='aaa'), xInvalid((3, 2), foo='ccc')]
        self.assertEqual(expected, result)
示例#8
0
    def test_all_fn(self):
        # All True, single arg key function..
        compare_obj = CompareDict({
            'aaa': (1, 2),
            'bbb': (1, 3),
            'ccc': (4, 8)
        }, 'foo')
        result = compare_obj.all(lambda x: x[0] < x[1])
        self.assertTrue(result)

        # Some False, single arg key function..
        compare_obj = CompareDict({
            'aaa': (1, 2),
            'bbb': (5, 3),
            'ccc': (4, 8)
        }, 'foo')
        result = compare_obj.all(lambda x: x[0] < x[1])
        self.assertFalse(result)

        # All True, multi-arg key function.
        compare_obj = CompareDict({
            'aaa': (1, 2),
            'bbb': (1, 3),
            'ccc': (4, 8)
        }, 'foo')
        result = compare_obj.all(lambda x, y: x < y)
        self.assertTrue(result)

        # Some False,multi-arg key function.
        compare_obj = CompareDict({
            'aaa': (1, 2),
            'bbb': (5, 3),
            'ccc': (4, 8)
        }, 'foo')
        result = compare_obj.all(lambda x, y: x < y)
        self.assertFalse(result)
示例#9
0
 def test_compare_strings(self):
     a = CompareDict({'aaa': 'x', 'bbb': 'y', 'ccc': 'z'}, 'foo')
     b = CompareDict({'aaa': 'x', 'bbb': 'z', 'ccc': 'z'}, 'foo')
     expected = [xInvalid('y', 'z', foo='bbb')]
     self.assertEqual(expected, a.compare(b))
示例#10
0
    def test_compare_numbers(self):
        a = CompareDict({'aaa': 1, 'bbb': 2, 'ccc': 3, 'ddd': 4}, 'foo')
        b = CompareDict({'aaa': 1, 'bbb': 2, 'ccc': 3, 'ddd': 4}, 'foo')
        self.assertEqual([], a.compare(b), ('When there is no difference, '
                                            'compare should return an empty '
                                            'list.'))

        a = CompareDict({'aaa': 1, 'bbb': 2, 'ccc': 3, 'ddd': 4}, 'foo')
        b = CompareDict({'aaa': 1, 'bbb': 2.5, 'ccc': 3, 'ddd': 4}, 'foo')
        expected = [xDeviation(-0.5, 2.5, foo='bbb')]
        self.assertEqual(expected, a.compare(b))

        # 'b' is zero in self/subject.
        a = CompareDict({'aaa': 1, 'bbb': 0, 'ccc': 3, 'ddd': 4}, 'foo')
        b = CompareDict({'aaa': 1, 'bbb': 2.5, 'ccc': 3, 'ddd': 4}, 'foo')
        expected = [xDeviation(-2.5, 2.5, foo='bbb')]
        self.assertEqual(expected, a.compare(b))

        # 'bbb' is zero in other/reference.
        a = CompareDict({'aaa': 1, 'bbb': 2, 'ccc': 3, 'ddd': 4}, 'foo')
        b = CompareDict({'aaa': 1, 'bbb': 0, 'ccc': 3, 'ddd': 4}, 'foo')
        expected = [xDeviation(+2, 0, foo='bbb')]
        self.assertEqual(expected, a.compare(b))

        # 'bbb' is missing from self/subject.
        a = CompareDict({'aaa': 1, 'ccc': 3, 'ddd': 4}, 'foo')
        b = CompareDict({'aaa': 1, 'bbb': 2.5, 'ccc': 3, 'ddd': 4}, 'foo')
        expected = [xDeviation(-2.5, 2.5, foo='bbb')]  # <- QUESTION: This
        self.assertEqual(expected, a.compare(b))  #    deviation looks the
        #    same as 0 vs 2.5.
        #    Is this OK?

        # 'bbb' is missing from a/subject.
        a = CompareDict({'aaa': 1, 'ccc': 3, 'ddd': 4}, 'foo')
        b = CompareDict({'aaa': 1, 'bbb': 0, 'ccc': 3, 'ddd': 4}, 'foo')
        expected = [xDeviation(None, 0, foo='bbb')]
        self.assertEqual(expected, a.compare(b))

        # 'bbb' is empty string in a/subject.
        a = CompareDict({'aaa': 1, 'bbb': '', 'ccc': 3, 'ddd': 4}, 'foo')
        b = CompareDict({'aaa': 1, 'bbb': 0, 'ccc': 3, 'ddd': 4}, 'foo')
        expected = [xDeviation('', 0, foo='bbb')]
        self.assertEqual(expected, a.compare(b))

        # 'bbb' is missing from b/reference.
        a = CompareDict({'aaa': 1, 'bbb': 0, 'ccc': 3, 'ddd': 4}, 'foo')
        b = CompareDict({'aaa': 1, 'ccc': 3, 'ddd': 4}, 'foo')
        expected = [xDeviation(0, None, foo='bbb')]
        self.assertEqual(expected, a.compare(b))

        # Test coersion of *other*.
        a = CompareDict({'aaa': 1, 'bbb': 2, 'ccc': 3, 'ddd': 4}, 'foo')
        b = {'aaa': 1, 'bbb': 2.5, 'ccc': 3, 'ddd': 4}
        expected = [xDeviation(-0.5, 2.5, foo='bbb')]
        self.assertEqual(expected, a.compare(b))
示例#11
0
    def test_make_rows(self):
        make_set = lambda data: set(frozenset(row.items()) for row in data)

        # Single-item keys, single-item values.
        data = {'aaa': 1, 'bbb': 2, 'ccc': 3}
        result = CompareDict(data, 'foo')
        iterable = result.make_rows('bar')
        expected = [
            {
                'foo': 'aaa',
                'bar': 1
            },
            {
                'foo': 'bbb',
                'bar': 2
            },
            {
                'foo': 'ccc',
                'bar': 3
            },
        ]
        self.assertEqual(make_set(expected), make_set(iterable))

        # Composite keys.
        data = {('aaa', 'xxx'): 1, ('bbb', 'yyy'): 2, ('ccc', 'zzz'): 3}
        result = CompareDict(data, ['foo', 'bar'])
        iterable = result.make_rows('baz')
        expected = [
            {
                'foo': 'aaa',
                'bar': 'xxx',
                'baz': 1
            },
            {
                'foo': 'bbb',
                'bar': 'yyy',
                'baz': 2
            },
            {
                'foo': 'ccc',
                'bar': 'zzz',
                'baz': 3
            },
        ]
        self.assertEqual(make_set(expected), make_set(iterable))

        # Composite values.
        data = {'aaa': ('xxx', 1), 'bbb': ('yyy', 2), 'ccc': ('zzz', 3)}
        result = CompareDict(data, 'foo')
        iterable = result.make_rows(['bar', 'baz'])
        expected = [
            {
                'foo': 'aaa',
                'bar': 'xxx',
                'baz': 1
            },
            {
                'foo': 'bbb',
                'bar': 'yyy',
                'baz': 2
            },
            {
                'foo': 'ccc',
                'bar': 'zzz',
                'baz': 3
            },
        ]
        self.assertEqual(make_set(expected), make_set(iterable))

        data = {'aaa': 1, 'bbb': 2, 'ccc': 3}
        result = CompareDict(data, 'foo')
        with self.assertRaises(AssertionError):
            iterable = result.make_rows(['bar', 'baz'])  # Too many *names*.

        data = {'aaa': (1, 2, 3), 'bbb': (2, 4, 6), 'ccc': (3, 6, 9)}
        result = CompareDict(data, 'foo')
        with self.assertRaises(AssertionError):
            iterable = result.make_rows('bar')  # Too few *names*.

        data = {'aaa': 1, 'bbb': 2, 'ccc': 3}
        result = CompareDict(data, 'foo')
        with self.assertRaises(ValueError):
            iterable = result.make_rows(
                'foo')  # 'foo' conflicts with group_by.
    def test_rebuild_comparedict(self):
        interface = [('col1', 'a'), ('col2', 'b'), ('col3', 'c'), (None, 'd')]
        adapted = AdapterSource(self.source, interface)
        rebuild_comparedict = adapted._rebuild_comparedict

        # Rebuild single key result as two key result.
        orig = CompareDict({'x': 1, 'y': 2, 'z': 3}, key_names='a')
        result = rebuild_comparedict(orig,
                                     'c',
                                     'c',
                                     'a', ['a', 'b'],
                                     missing_col='')
        expected = CompareDict({
            ('x', ''): 1,
            ('y', ''): 2,
            ('z', ''): 3
        },
                               key_names=['a', 'b'])
        self.assertEqual(expected, result)

        # Rebuild two key result as three key result.
        orig = CompareDict({
            ('x', 'x'): 1,
            ('y', 'y'): 2,
            ('z', 'z'): 3
        },
                           key_names=['a', 'c'])
        result = rebuild_comparedict(orig,
                                     'c',
                                     'c', ['a', 'b'], ['a', 'd', 'b'],
                                     missing_col='')
        expected = CompareDict(
            {
                ('x', '', 'x'): 1,
                ('y', '', 'y'): 2,
                ('z', '', 'z'): 3
            },
            key_names=['a', 'd', 'b'])
        self.assertEqual(expected, result)

        # Rebuild single value tuple result as two value result.
        orig = CompareDict({'x': (1, ), 'y': (2, ), 'z': (3, )}, key_names='a')
        result = rebuild_comparedict(orig,
                                     'c', ['c', 'd'],
                                     'a',
                                     'a',
                                     missing_col='')
        expected = CompareDict({
            'x': (1, ''),
            'y': (2, ''),
            'z': (3, '')
        },
                               key_names='a')
        self.assertEqual(expected, result)

        # Rebuild single value result as two value result.
        if True:
            orig = CompareDict({'x': 1, 'y': 2, 'z': 3}, key_names='a')
            result = rebuild_comparedict(orig,
                                         'c', ['c', 'd'],
                                         'a',
                                         'a',
                                         missing_col='')
            expected = CompareDict({
                'x': (1, ''),
                'y': (2, ''),
                'z': (3, '')
            },
                                   key_names=['c', 'd'])
            self.assertEqual(expected, result)

        # Rebuild two column result as three column result.
        orig = CompareDict({
            'x': (1, 2),
            'y': (2, 4),
            'z': (3, 6)
        },
                           key_names='a')
        result = rebuild_comparedict(orig, ['b', 'c'], ['b', 'd', 'c'],
                                     'a',
                                     'a',
                                     missing_col='empty')
        expected = CompareDict(
            {
                'x': (1, 'empty', 2),
                'y': (2, 'empty', 4),
                'z': (3, 'empty', 6)
            },
            key_names='a')
        self.assertEqual(expected, result)

        # Rebuild two key and two column result as three key and three column result.
        orig = CompareDict(
            {
                ('x', 'x'): (1, 2),
                ('y', 'y'): (2, 4),
                ('z', 'z'): (3, 6)
            },
            key_names=['a', 'c'])
        result = rebuild_comparedict(orig, ['b', 'c'], ['b', 'd', 'c'],
                                     ['a', 'b'], ['a', 'd', 'b'],
                                     missing_col='empty')
        expected = CompareDict(
            {
                ('x', '', 'x'): (1, 'empty', 2),
                ('y', '', 'y'): (2, 'empty', 4),
                ('z', '', 'z'): (3, 'empty', 6)
            },
            key_names=['a', 'd', 'b'])
        self.assertEqual(expected, result)