def test_required_integer(self): data = set([11, 8]) integer_val = 11 result = _compare_other(data, integer_val) self.assertEqual(result, [Deviation(-3, integer_val)]) data = {'foo': 11, 'bar': 8} integer_val = 11 result = _compare_other(data, integer_val) self.assertEqual(result, {'bar': Deviation(-3, integer_val)})
def test_group_and_filter(self): """Only groupby fields should appear in diff errors (kwds-filters should be omitted). """ with self.assertRaises(DataError) as cm: self.assertSubjectSum('value', ['label1'], label2='y') differences = cm.exception.differences expected = [Deviation(+1, 20, label1='a'), Deviation(-1, 40, label1='b')] super(DataTestCase, self).assertEqual(set(differences), set(expected))
def test_failing_implicit_reference(self): self.subject = self.src2_records # <- src1 != src2 self.reference = self.src1_totals with self.assertRaises(DataError) as cm: self.assertSubjectSum('value', ['label1']) differences = cm.exception.differences expected = [Deviation(+1, 65, label1='a'), Deviation(-1, 70, label1='b')] super(DataTestCase, self).assertEqual(set(differences), set(expected))
def test_failing_explicit_dict(self): self.subject = self.src2_records # <- src1 != src2 with self.assertRaises(DataError) as cm: required = {'a': 65, 'b': 70} self.assertSubjectSum('value', ['label1'], required) differences = cm.exception.differences expected = [Deviation(+1, 65, label1='a'), Deviation(-1, 70, label1='b')] super(DataTestCase, self).assertEqual(set(differences), set(expected))
def test_nested_allowances(self): """A quick integration test to make sure allowances nest as required. """ with allow_only(Deviation(-4, 70, label1='b')): # <- specified diff only with allow_deviation(3): # <- tolerance of +/- 3 with allow_percent_deviation(0.02): # <- tolerance of +/- 2% differences = [ Deviation(+3, 65, label1='a'), Deviation(-4, 70, label1='b'), Deviation(+5, 250, label1='c'), ] raise DataError('example error', differences)
def test_tolerance_syntax(self): differences = { 'aaa': Deviation(-1, 10), 'bbb': Deviation(+3, 10), # <- Not in allowed range. } with self.assertRaises(DataError) as cm: with allow_deviation(2): # <- Allows +/- 2. raise DataError('example error', differences) #result_string = str(cm.exception) #self.assertTrue(result_string.startswith('example allowance: example error')) result_diffs = cm.exception.differences self.assertEqual({'bbb': Deviation(+3, 10)}, result_diffs)
def test_lowerupper_syntax(self): differences = { 'aaa': Deviation(-1, 10), # <- Not in allowed range. 'bbb': Deviation(+3, 10), } with self.assertRaises(DataError) as cm: with allow_percent_deviation(0.0, 0.3): # <- Allows from 0 to 30%. raise DataError('example error', differences) result_string = str(cm.exception) self.assertTrue(result_string.startswith('example error')) result_diffs = cm.exception.differences self.assertEqual({'aaa': Deviation(-1, 10)}, result_diffs)
def test_tolerance_syntax(self): differences = [ Deviation(-1, 10), Deviation(+3, 10), # <- Not in allowed range. ] with self.assertRaises(DataError) as cm: with allow_percent_deviation(0.2): # <- Allows +/- 20%. raise DataError('example error', differences) result_string = str(cm.exception) self.assertTrue(result_string.startswith('example error')) result_diffs = list(cm.exception.differences) self.assertEqual([Deviation(+3, 10)], result_diffs)
def test_lowerupper_syntax(self): differences = [ Deviation(-1, 10, label='aaa'), # <- Not in allowed range. Deviation(+3, 10, label='bbb'), ] with self.assertRaises(DataError) as cm: with allow_deviation(0, 3, 'example allowance'): # <- Allows from 0 to 3. raise DataError('example error', differences) result_string = str(cm.exception) self.assertTrue(result_string.startswith('example allowance: example error')) result_diffs = list(cm.exception.differences) self.assertEqual([Deviation(-1, 10, label='aaa')], result_diffs)
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_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 = [Deviation(-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 = [Deviation(-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 = [Deviation(+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 = [Deviation(-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 = [Deviation(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 = [Deviation('', 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 = [Deviation(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 = [Deviation(-0.5, 2.5, foo='bbb')] self.assertEqual(expected, a.compare(b))
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([ Invalid(2, 'y', foo='aaa'), Deviation(-1, 4, foo='bbb'), Invalid('z', 5, foo='ccc'), ]) self.assertEqual(expected, set(a.compare(b)))
def test_population_sums(detail, summary): data = detail({'state/territory': 'population'}).sum() requirement = summary({'state/territory': 'population'}).sum() omitted_territory = accepted({ 'Jervis Bay Territory': Deviation(-388, 388), }) with accepted.percent(0.03) | omitted_territory: validate(data, requirement)
def test_population_sums(self): data = detail({'state/territory': 'population'}).sum() requirement = summary({'state/territory': 'population'}).sum() omitted_territory = self.acceptedSpecific({ 'Jervis Bay Territory': Deviation(-388, 388), }) with self.acceptedPercent(0.03) | omitted_territory: self.assertValid(data, requirement)
def test_required_sequence(self): """When *required* is a sequence, _compare_sequence() should be called.""" with self.assertRaises(DataError) as cm: required = ['a', 2, 'c', 4] data = ['a', 2, 'x', 3] self.assertValid(data, required) differences = cm.exception.differences self.assertEqual = super(DataTestCase, self).assertEqual self.assertEqual(differences, {2: Invalid('x', 'c'), 3: Deviation(-1, 4)})
def test_empty_value_handling(self): # Test NoneType. with allow_percent_deviation(0): # <- Pass without failure. raise DataError('example error', [Deviation(None, 0)]) with allow_percent_deviation(0): # <- Pass without failure. raise DataError('example error', [Deviation(0, None)]) # Test empty string. with allow_percent_deviation(0): # <- Pass without failure. raise DataError('example error', [Deviation('', 0)]) with allow_percent_deviation(0): # <- Pass without failure. raise DataError('example error', [Deviation(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', [Deviation(float('nan'), 0)]) with self.assertRaises( DataError): # <- NaN values should not be caught! with allow_percent_deviation(0): raise DataError('example error', [Deviation(0, float('nan'))])
def test_kwds_handling(self): differences = [ Deviation(-1, 10, label='aaa'), Deviation(+2, 10, label='aaa'), Deviation(+2, 10, label='bbb'), Deviation(+3, 10, label='aaa'), ] with self.assertRaises(DataError) as cm: with allow_deviation(2, 'example allowance', label='aaa'): # <- Allows +/- 2. raise DataError('example error', differences) result_set = set(cm.exception.differences) expected_set = set([ Deviation(+2, 10, label='bbb'), # <- Keyword value not 'aaa'. Deviation(+3, 10, label='aaa'), # <- Not in allowed range. ]) self.assertEqual(expected_set, result_set)
def test_single_value_allowance(self): differences = [ Deviation(+2.9, 10, label='aaa'), # <- Not allowed. Deviation(+3.0, 10, label='bbb'), Deviation(+3.0, 5, label='ccc'), Deviation(+3.1, 10, label='ddd'), # <- Not allowed. ] with self.assertRaises(DataError) as cm: with allow_deviation(3, 3): # <- Allows +3 only. raise DataError('example error', differences) result_diffs = set(cm.exception.differences) expected_diffs = set([ Deviation(+2.9, 10, label='aaa'), Deviation(+3.1, 10, label='ddd'), ]) self.assertEqual(expected_diffs, result_diffs)
def test_keys_keyword(self): with self.assertRaises(DataError) as cm: differences = { 'aaa': Deviation(-1, 10), 'bbb': Deviation(+2, 10), 'ccc': Deviation(+2, 10), 'ddd': Deviation(+3, 10), } fn = lambda key: key in ('aaa', 'bbb', 'ddd') with allow_deviation(2, keys=fn): # <- Allows +/- 2. raise DataError('example error', differences) actual = cm.exception.differences expected = { 'ccc': Deviation(+2, 10), # <- Keyword value not allowed. 'ddd': Deviation(+3, 10), # <- Not in allowed range. } self.assertEqual(expected, actual)
def test_kwds_handling(self): differences = { 'aaa': Deviation(-1, 10), 'bbb': Deviation(+2, 10), 'ccc': Deviation(+2, 10), 'ddd': Deviation(+3, 10), } with self.assertRaises(DataError) as cm: fn = lambda x: x in ('aaa', 'bbb', 'ddd') with allow_percent_deviation(0.2, keys=fn): # <- Allows +/- 20%. raise DataError('example error', differences) result_set = cm.exception.differences expected_set = { 'ccc': Deviation(+2, 10), # <- Key value not 'aaa'. 'ddd': Deviation(+3, 10), # <- Not in allowed range. } self.assertEqual(expected_set, result_set)
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 = [Deviation(-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 = [Deviation(-2.5, 2.5, foo='bbb')] self.assertEqual(expected, a.compare(b)) # 'b' 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 = [Deviation(-2.5, 2.5, foo='bbb')] self.assertEqual(expected, a.compare(b)) # 'b' 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 = [Deviation(+2, 0, foo='bbb')] self.assertEqual(expected, a.compare(b)) # 'b' is missing from other/reference. a = CompareDict({'aaa': 1, 'bbb': 2, 'ccc': 3, 'ddd': 4}, 'foo') b = CompareDict({'aaa': 1, 'ccc': 3, 'ddd': 4}, 'foo') expected = [Deviation(+2, 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 = [Deviation(-0.5, 2.5, foo='bbb')] self.assertEqual(expected, a.compare(b))