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)
def test_all_fn(self): obj = CompareSet(['aaa', 'bbb', 'ddd']) key = lambda x: len(x) == 3 self.assertTrue(obj.all(key)) obj = CompareSet(['aaa1', 'aaa2', 'bbb1']) key = lambda x: str(x).startswith('aaa') self.assertFalse(obj.all(key))
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_eq(self): data = set([1, 2, 3, 4]) a = CompareSet(data) b = CompareSet(data) self.assertEqual(a, b) # Test coersion. a = CompareSet(data) b = [1, 2, 3, 4] # <- Should be coerced into CompareSet internally. self.assertEqual(a, b) # Test non-comparable types. a = CompareSet(data) self.assertNotEqual(a, None) self.assertNotEqual(a, False) self.assertNotEqual(a, 0)
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_rebuild_compareset(self): interface = [('col1', 'a'), ('col2', 'b'), ('col3', 'c'), (None, 'd')] adapted = AdapterSource(self.source, interface) rebuild_compareset = adapted._rebuild_compareset # Rebuild one column result as two column result. orig = CompareSet(['x', 'y', 'z']) result = rebuild_compareset(orig, 'b', ['b', 'd']) expected = CompareSet([('x', ''), ('y', ''), ('z', '')]) self.assertEqual(expected, result) # Rebuild two column result to three column with missing column in the middle. orig = CompareSet([('x1', 'x2'), ('y1', 'y2'), ('z1', 'z2')]) result = rebuild_compareset(orig, ['b', 'c'], ['b', 'd', 'c']) expected = CompareSet([('x1', '', 'x2'), ('y1', '', 'y2'), ('z1', '', 'z2')]) self.assertEqual(expected, result)
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, data source, or None. If *required* is omitted, the column names from reference are used in its place. """ subject_set = CompareSet(self.subject.columns()) required = self._normalize_required(required, 'columns') msg = msg or 'different column names' self.assertEqual(subject_set, required, msg)
def test_make_rows(self): make_set = lambda data: set(frozenset(row.items()) for row in data) result = CompareSet(['aaa', 'bbb', 'ccc']) iterable = result.make_rows('foo') expected = [{'foo': 'aaa'}, {'foo': 'bbb'}, {'foo': 'ccc'}] self.assertEqual(make_set(expected), make_set(iterable)) result = CompareSet(['aaa', 'bbb', 'ccc']) iterable = result.make_rows(['foo']) # <- Single-item list. expected = [{'foo': 'aaa'}, {'foo': 'bbb'}, {'foo': 'ccc'}] self.assertEqual(make_set(expected), make_set(iterable)) result = CompareSet([('aaa', 1), ('bbb', 2), ('ccc', 3)]) iterable = result.make_rows(['foo', 'bar']) expected = [ { 'foo': 'aaa', 'bar': 1 }, { 'foo': 'bbb', 'bar': 2 }, { 'foo': 'ccc', 'bar': 3 }, ] self.assertEqual(make_set(expected), make_set(iterable)) result = CompareSet(['aaa', 'bbb', 'ccc']) with self.assertRaises(AssertionError): iterable = result.make_rows(['foo', 'bar']) # Too many *names*. result = CompareSet([('aaa', 1), ('bbb', 2), ('ccc', 3)]) with self.assertRaises(AssertionError): iterable = result.make_rows(['foo']) # Too few *names*.
def test_distinct(self): distinct = self.datasource.distinct # Test single column. expected = ['a', 'b'] self.assertEqual(expected, distinct('label1')) self.assertEqual(expected, distinct(['label1'])) # Test single column wrapped in iterable (list). expected = [('a', ), ('b', )] self.assertEqual(expected, distinct('label1')) self.assertEqual(expected, distinct(['label1'])) # Test multiple columns. expected = [ ('a', 'x'), ('a', 'y'), ('a', 'z'), ('b', 'z'), # <- ordered (if possible) ('b', 'y'), # <- ordered (if possible) ('b', 'x'), # <- ordered (if possible) ] self.assertEqual(expected, distinct(['label1', 'label2'])) # Test multiple columns with filter. expected = [('a', 'x'), ('a', 'y'), ('b', 'y'), ('b', 'x')] self.assertEqual(expected, distinct(['label1', 'label2'], label2=['x', 'y'])) # Test multiple columns with filter on non-grouped column. expected = [('a', '17'), ('a', '13'), ('b', '25')] result = distinct(['label1', 'value'], label2='x') if isinstance(self.datasource, ExcelSource): result = CompareSet((x, str(int(y))) for x, y in result) self.assertEqual(expected, result) # Test when specified column is missing. msg = 'Error should reference missing column.' with self.assertRaisesRegex(Exception, 'label3', msg=msg): result = distinct(['label1', 'label3'], label2='x')
def test_init(self): data = set([1, 2, 3, 4]) x = CompareSet(data) # Data set. self.assertEqual(data, x) x = CompareSet(list(data)) # Data list. self.assertEqual(data, x) x = CompareSet(tuple(data)) # Data tuple. self.assertEqual(data, x) data_gen = (v for v in data) # Data generator. x = CompareSet(data_gen) self.assertEqual(data, x) # Data mapping (type error). data_dict = dict(enumerate(data)) with self.assertRaises(TypeError): x = CompareSet(data_dict) x = CompareSet(set()) self.assertEqual(set(), x)
def test_compare(self): a = CompareSet(['aaa', 'bbb', 'ddd']) b = CompareSet(['aaa', 'bbb', 'ccc']) expected = [xExtra('ddd'), xMissing('ccc')] self.assertEqual(expected, a.compare(b)) a = CompareSet(['aaa', 'bbb', 'ccc']) b = CompareSet(['aaa', 'bbb', 'ccc']) self.assertEqual([], a.compare(b), ('When there is no difference, ' 'compare should return an empty ' 'list.')) # Test callable other (all True). result = a.compare(lambda x: len(x) == 3) self.assertEqual([], result) # Test callable other (some False). result = a.compare(lambda x: x.startswith('b')) expected = set([xInvalid('aaa'), xInvalid('ccc')]) self.assertEqual(expected, set(result)) # Test callable other, multiple arguments (all True). a = CompareSet([(1, 1), (1, 2), (2, 1), (2, 2)]) result = a.compare(lambda x, y: x + y > 0) self.assertEqual([], result) # Test callable other, using single vararg (all True). a = CompareSet([(1, 1), (1, 2), (2, 1), (2, 2)]) result = a.compare(lambda *x: x[0] + x[1] > 0) self.assertEqual([], result) # Test callable other, multiple arguments (some False). a = CompareSet([(1, 1), (1, 2), (2, 1), (2, 2)]) result = a.compare(lambda x, y: x != y) expected = set([xInvalid((1, 1)), xInvalid((2, 2))]) self.assertEqual(expected, set(result)) # Test subset (less-than-or-equal). a = CompareSet(['aaa', 'bbb', 'ddd']) b = CompareSet(['aaa', 'bbb', 'ccc']) expected = [xExtra('ddd')] self.assertEqual(expected, a.compare(b, op='<=')) # Test strict subset (less-than). a = CompareSet(['aaa', 'bbb']) b = CompareSet(['aaa', 'bbb', 'ccc']) self.assertEqual([], a.compare(b, op='<')) # Test strict subset (less-than) assertion violation. a = CompareSet(['aaa', 'bbb', 'ccc']) b = CompareSet(['aaa', 'bbb', 'ccc']) self.assertEqual([xNotProperSubset()], a.compare(b, op='<')) # Test superset (greater-than-or-equal). a = CompareSet(['aaa', 'bbb', 'ccc']) b = CompareSet(['aaa', 'bbb', 'ddd']) expected = [xMissing('ddd')] self.assertEqual(expected, a.compare(b, op='>=')) # Test superset subset (greater-than). a = CompareSet(['aaa', 'bbb', 'ccc']) b = CompareSet(['aaa', 'bbb']) self.assertEqual([], a.compare(b, op='>')) # Test superset subset (greater-than) assertion violation. a = CompareSet(['aaa', 'bbb', 'ccc']) b = CompareSet(['aaa', 'bbb', 'ccc']) self.assertEqual([xNotProperSuperset()], a.compare(b, op='>'))
def test_ne(self): a = CompareSet(set([1, 2, 3])) b = CompareSet(set([1, 2, 3, 4])) self.assertTrue(a != b)
def test_repr(self): result = CompareSet(set([1])) regex = r'^CompareSet\([\[\{]1[\}\]]\)$' self.assertRegex(repr(result), regex)
def test_no_subject(self): required = CompareSet([1, 2, 3]) with self.assertRaisesRegex(NameError, "cannot find 'subject'"): self.assertSubjectSet(required)
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)