def test_collect_filter_good(self): context = ExecutionContext() source = {'outer': [_LETTER_DICT, _NUMBER_DICT]} filter_pred = TestEqualsPredicate(2) pred = PathPredicate(PATH_SEP.join(['outer', 'b']), pred=filter_pred) # This is a precise test against the exact result returned. builder = PathPredicateResultBuilder(source, pred) path_0 = PATH_SEP.join(['outer[0]', 'b']) path_1 = PATH_SEP.join(['outer[1]', 'b']) bad_result = PathValueResult(source=source, target_path=pred.path, path_value=PathValue(path_0, 'B'), valid=False, pred=filter_pred) good_result = PathValueResult(source=source, target_path=pred.path, path_value=PathValue(path_1, 2), valid=True, pred=filter_pred) builder.add_result_candidate(PathValue(path_0, 'B'), bad_result) builder.add_result_candidate(PathValue(path_1, 2), good_result) expect = builder.build(True) pred_result = pred(context, source) self.assertEqual([PathValue(PATH_SEP.join(['outer[1]', 'b']), 2)], pred_result.path_values) self.assertEqual(expect, pred_result) self.assertEqual( [jp.PathPredicateResultCandidate(PathValue(path_0, 'B'), bad_result)], pred_result.invalid_candidates) self.assertEqual( [jp.PathPredicateResultCandidate(PathValue(path_1, 2), good_result)], pred_result.valid_candidates) self.assertEqual([], pred_result.path_failures)
def test_collect_filter_good(self): source = {'outer': [_LETTER_DICT, _NUMBER_DICT]} filter_pred = TestEqualsPredicate(2) pred = PathPredicate(PATH_SEP.join(['outer', 'b']), pred=filter_pred) # This is a precise test against the exact result returned. builder = PathPredicateResultBuilder(source, pred) path_0 = PATH_SEP.join(['outer[0]', 'b']) path_1 = PATH_SEP.join(['outer[1]', 'b']) bad_result = PathValueResult(source=source, target_path=pred.path, path_value=PathValue(path_0, 'B'), valid=False, pred=filter_pred) good_result = PathValueResult(source=source, target_path=pred.path, path_value=PathValue(path_1, 2), valid=True, pred=filter_pred) builder.add_result_candidate(PathValue(path_0, 'B'), bad_result) builder.add_result_candidate(PathValue(path_1, 2), good_result) expect = builder.build(True) pred_result = pred(source) self.assertEqual([PathValue(PATH_SEP.join(['outer[1]', 'b']), 2)], pred_result.path_values) self.assertEqual(expect, pred_result) self.assertEqual( [jp.PathPredicateResultCandidate(PathValue(path_0, 'B'), bad_result)], pred_result.invalid_candidates) self.assertEqual( [jp.PathPredicateResultCandidate(PathValue(path_1, 2), good_result)], pred_result.valid_candidates) self.assertEqual([], pred_result.path_failures)
def test_path_found_multiple(self): source = {'outer': [_LETTER_DICT, _NUMBER_DICT]} pred = jp.PathPredicate(PATH_SEP.join(['outer', 'a'])) result = pred(source) self.assertEqual( _make_result(pred, None, source, [ PathValue(PATH_SEP.join(['outer[0]', 'a']), 'A'), PathValue(PATH_SEP.join(['outer[1]', 'a']), 1) ], []), result)
def test_path_value_found_nested(self): source = _COMPOSITE_DICT pred = jp.PathEqPredicate(PATH_SEP.join(['letters', 'a']), 'A') result = pred(source) self.assertEqual( _make_result(pred, jp.STR_EQ('A'), source, [PathValue(PATH_SEP.join(['letters', 'a']), 'A')], []), result) self.assertTrue(result)
def test_path_value_found_nested(self): source = _COMPOSITE_DICT pred = jp.PathEqPredicate(PATH_SEP.join(['letters', 'a']), 'A') result = pred(source) self.assertEqual( _make_result( pred, jp.STR_EQ('A'), source, [PathValue(PATH_SEP.join(['letters', 'a']), 'A')], []), result) self.assertTrue(result)
def test_path_found_multiple(self): source = {'outer': [_LETTER_DICT, _NUMBER_DICT]} pred = jp.PathPredicate(PATH_SEP.join(['outer', 'a'])) result = pred(source) self.assertEqual( _make_result( pred, None, source, [PathValue(PATH_SEP.join(['outer[0]', 'a']), 'A'), PathValue(PATH_SEP.join(['outer[1]', 'a']), 1)], []), result)
def test_path_value_not_found(self): source = _COMPOSITE_DICT pred = jp.PathEqPredicate(PATH_SEP.join(['letters', 'a']), 'B') result = pred(source) self.assertEqual( _make_result(pred, jp.STR_EQ('B'), source, [], [ jp.PathValueResult(pred=jp.STR_EQ('B'), path_value=PathValue( PATH_SEP.join(['letters', 'a']), 'A'), source=_COMPOSITE_DICT, target_path=PATH_SEP.join(['letters', 'a'])) ]), result)
def test_path_found_in_array(self): pred = jp.PathPredicate(PATH_SEP.join(['outer', 'inner', 'a'])) simple = {'a': 'A', 'b': 'B'} source = {'outer': [{'middle': simple}, {'inner': simple}]} found = [PathValue(PATH_SEP.join(['outer[1]', 'inner', 'a']), 'A')] pruned = [ jp.MissingPathError( source['outer'][0], 'inner', path_value=PathValue('outer[0]', source['outer'][0]))] expect = _make_result(pred, None, source, found, [], pruned) self.assertEqual(expect, pred(source))
def test_collect_from_list_found(self): # """Ambiguous path passes through a list element.""" source = [_LETTER_DICT] pred = PathPredicate('a') values = pred(source) self.assertEqual([PathValue(PATH_SEP.join(['[0]', 'a']), 'A')], values.path_values) pred = PathPredicate('b') values = pred(source) self.assertEqual([PathValue(PATH_SEP.join(['[0]', 'b']), 'B')], values.path_values) self.assertEqual([], values.path_failures)
def test_collect_from_nested_dict_found(self): # """Nested dictionary attribute lookup.""" source = {'outer': {'inner': _LETTER_DICT}} pred = PathPredicate(PATH_SEP.join(['outer', 'inner', 'a'])) values = pred(source) self.assertEqual([PathValue(pred.path, 'A')], values.path_values) self.assertEqual([], values.path_failures) pred = PathPredicate(PATH_SEP.join(['outer', 'inner', 'b'])) values = pred(source) self.assertEqual([PathValue(pred.path, 'B')], values.path_values) self.assertEqual([], values.path_failures)
def test_collect_plain_terminal_list(self): # """Path to a value that is a list.""" source = {'a': [_LETTER_DICT]} pred = PathPredicate('a' + DONT_ENUMERATE_TERMINAL) values = pred(source) self.assertEqual([PathValue('a', [_LETTER_DICT])], values.path_values) self.assertEqual([], values.path_failures) pred = PathPredicate(PATH_SEP.join(['a', 'a'])) values = pred(source) self.assertEqual([PathValue(PATH_SEP.join(['a[0]', 'a']), 'A')], values.path_values) self.assertEqual([], values.path_failures)
def test_path_value_not_found(self): source = _COMPOSITE_DICT pred = jp.PathEqPredicate(PATH_SEP.join(['letters', 'a']), 'B') result = pred(source) self.assertEqual( _make_result( pred, jp.STR_EQ('B'), source, [], [jp.PathValueResult( pred=jp.STR_EQ('B'), path_value=PathValue(PATH_SEP.join(['letters', 'a']), 'A'), source=_COMPOSITE_DICT, target_path=PATH_SEP.join(['letters', 'a']))]), result)
def test_path_found_in_array(self): pred = jp.PathPredicate(PATH_SEP.join(['outer', 'inner', 'a'])) simple = {'a': 'A', 'b': 'B'} source = {'outer': [{'middle': simple}, {'inner': simple}]} found = [PathValue(PATH_SEP.join(['outer[1]', 'inner', 'a']), 'A')] pruned = [ jp.MissingPathError(source['outer'][0], 'inner', path_value=PathValue('outer[0]', source['outer'][0])) ] expect = _make_result(pred, None, source, found, [], pruned) self.assertEqual(expect, pred(source))
def test_collect_from_nested_list_found(self): # """Ambiguous path through nested lists.""" context = ExecutionContext() source = {'outer': [_LETTER_DICT, _NUMBER_DICT]} pred = PathPredicate(PATH_SEP.join(['outer', 'a'])) values = pred(context, source) self.assertEqual([ PathValue(PATH_SEP.join(['outer[0]', 'a']), 'A'), PathValue(PATH_SEP.join(['outer[1]', 'a']), 1) ], values.path_values) pred = PathPredicate(PATH_SEP.join(['outer', 'z'])) values = pred(context, source) self.assertEqual([PathValue(PATH_SEP.join(['outer[0]', 'z']), 'Z')], values.path_values) self.assertEqual([ MissingPathError(_NUMBER_DICT, 'z', path_value=PathValue('outer[1]', _NUMBER_DICT)) ], values.path_failures) pred = PathPredicate(PATH_SEP.join(['outer', 'three'])) values = pred(context, source) self.assertEqual([PathValue(PATH_SEP.join(['outer[1]', 'three']), 3)], values.path_values) self.assertEqual([ MissingPathError(_LETTER_DICT, 'three', path_value=PathValue('outer[0]', _LETTER_DICT)) ], values.path_failures)
def test_collect_from_nested_list_found(self): # """Ambiguous path through nested lists.""" context = ExecutionContext() source = {'outer': [_LETTER_DICT, _NUMBER_DICT]} pred = PathPredicate(PATH_SEP.join(['outer', 'a'])) values = pred(context, source) self.assertEqual([PathValue(PATH_SEP.join(['outer[0]', 'a']), 'A'), PathValue(PATH_SEP.join(['outer[1]', 'a']), 1)], values.path_values) pred = PathPredicate(PATH_SEP.join(['outer', 'z'])) values = pred(context, source) self.assertEqual([PathValue(PATH_SEP.join(['outer[0]', 'z']), 'Z')], values.path_values) self.assertEqual( [MissingPathError( _NUMBER_DICT, 'z', path_value=PathValue('outer[1]', _NUMBER_DICT))], values.path_failures) pred = PathPredicate(PATH_SEP.join(['outer', 'three'])) values = pred(context, source) self.assertEqual([PathValue(PATH_SEP.join(['outer[1]', 'three']), 3)], values.path_values) self.assertEqual( [MissingPathError( _LETTER_DICT, 'three', path_value=PathValue('outer[0]', _LETTER_DICT))], values.path_failures)
def test_collect_from_nested_dict_not_found(self): # """Nested dictionary attribute lookup with missing element.""" source = _LETTER_DICT pred = PathPredicate(PATH_SEP.join(['a', 'b'])) values = pred(source) self.assertEqual([], values.path_values) self.assertEqual( [MissingPathError('A', 'b', path_value=PathValue('a', 'A'))], values.path_failures)
def test_collect_from_nested_list_not_found(self): # """Path through nested lists that cannot be resolved.""" source = {'outer': [_LETTER_DICT, _NUMBER_DICT]} pred = PathPredicate(PATH_SEP.join(['outer', 'X'])) values = pred(source) self.assertEqual([], values.path_values) self.assertEqual( [MissingPathError( _LETTER_DICT, 'X', path_value=PathValue('outer[0]', _LETTER_DICT)), MissingPathError( _NUMBER_DICT, 'X', path_value=PathValue('outer[1]', _NUMBER_DICT))], values.path_failures)
def test_collect_from_list_with_index(self): # """Path with explicit list indexes to traverse.""" source = [_LETTER_DICT, _NUMBER_DICT] pred = PathPredicate('[0]') values = pred(source) self.assertEqual([PathValue('[0]', _LETTER_DICT)], values.path_values) self.assertEqual([], values.path_failures) pred = PathPredicate('[1]') values = pred(source) self.assertEqual([PathValue('[1]', _NUMBER_DICT)], values.path_values) self.assertEqual([], values.path_failures) pred = PathPredicate(PATH_SEP.join(['[1]', 'a'])) values = pred(source) self.assertEqual([PathValue('[1]/a', 1)], values.path_values) self.assertEqual([], values.path_failures)