def test_cardinality_bounds_2_indirect(self): predicate = jp.CardinalityPredicate(_AorB, min=lambda x: x['min'], max=lambda x: x['max']) for min in range(0, 3): for max in range(0, 3): if min > max: continue context = ExecutionContext(min=min, max=max) expect_ok = min <= 2 and max >= 2 source = _CAB result = predicate(context, source) all_results = [ jp.SequencedPredicateResult( False, _AorB, [jp.PathValueResult(_CAB, '', PathValue('[0]', 'C'), valid=False, pred=_eq_A), jp.PathValueResult(_CAB, '', PathValue('[0]', 'C'), valid=False, pred=_eq_B)]), jp.SequencedPredicateResult( True, _AorB, [jp.PathValueResult(_CAB, '', PathValue('[1]', 'A'), valid=True, pred=_eq_A)]), jp.SequencedPredicateResult( True, _AorB, [jp.PathValueResult(_CAB, '', PathValue('[2]', 'B'), valid=False, pred=_eq_A), jp.PathValueResult(_CAB, '', PathValue('[2]', 'B'), valid=True, pred=_eq_B)])] builder = jp.PathPredicateResultBuilder( pred=jp.PathPredicate('', _AorB), source=_CAB) builder.add_result_candidate(PathValue('[0]', 'C'), all_results[0]) builder.add_result_candidate(PathValue('[1]', 'A'), all_results[1]) builder.add_result_candidate(PathValue('[2]', 'B'), all_results[2]) expect_path_result = builder.build(True) if expect_ok: self.assertEqual( jp.ConfirmedCardinalityResult(predicate, expect_path_result), result) elif max == 0: self.assertEqual( jp.UnexpectedValueCardinalityResult( predicate, expect_path_result), result) else: self.assertEqual( jp.FailedCardinalityRangeResult( predicate, expect_path_result), result)
def bad_result(path_value, pred, source=None, target_path=''): """Constructs a JsonFoundValueResult where pred returns value as invalid.""" source = path_value.value if source is None else source return jp.PathValueResult(pred=pred, source=source, target_path=target_path, path_value=path_value, valid=False)
def assertBad(self, expect_value, pred, context=None): """Assert that got_result is expect_value returned by pred as invalid.""" path_value = PathValue('', expect_value) got_result = pred(context or ExecutionContext(), expect_value) expect = jp.PathValueResult(pred=pred, source=expect_value, target_path='', path_value=path_value, valid=False) self.assertEqual(expect, got_result)
def test_list_equivalent(self): context = ExecutionContext() source = [{'a':'A', 'b':'B'}, {'one':1, 'two':2}] pred = jp.EQUIVALENT([source[1], source[0]]) result = pred(context, source) self.assertEqual( jp.PathValueResult(valid=True, source=source, target_path='', path_value=PathValue('', source), pred=jp.LIST_SIMILAR(pred.operand)), result)
def test_list_equivalent_indirect(self): context = ExecutionContext(testB='B', second={'one':1, 'two':2}) source = [{'a':'A', 'b': lambda x: x['testB']}, lambda x: x['second']] actual_source = [{'a':'A', 'b':'B'}, {'one':1, 'two':2}] pred = jp.EQUIVALENT(source) result = pred(context, actual_source) self.assertEqual( jp.PathValueResult(valid=True, source=actual_source, target_path='', path_value=PathValue('', actual_source), pred=jp.LIST_SIMILAR(actual_source)), 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_list_subset_nonstrict_bad(self): context = ExecutionContext() letters = {'a':'A', 'b':'B', 'c':'C'} numbers = {'a':1, 'b':2, 'c':'C'} source = [letters, numbers] common_subset_pred = jp.LIST_SUBSET([{'c':3}]) self.assertEqual( jp.PathValueResult( valid=False, pred=common_subset_pred, source=source, target_path='', path_value=PathValue('', source)), common_subset_pred(context, source))
def test_dict_nested_subset_exact_values(self): context = ExecutionContext() small = {'first':'Apple', 'second':'Banana'} small_nested = {'outer':small} # In dictionary we want exact matches of strings, not substrings. nested_operand = {'first':'A'} operand = {'outer':nested_operand} subset_pred = jp.DICT_SUBSET(operand) self.assertEqual( jp.PathValueResult( valid=False, pred=jp.STR_EQ('A'), path_value=PathValue(jp.PATH_SEP.join(['outer', 'first']), 'Apple'), source=small_nested, target_path=jp.PATH_SEP.join(['outer', 'first'])), subset_pred(context, small_nested))
def _make_result(use_pred, inner_pred, source, good, invalid, pruned=None): builder = jp.PathPredicateResultBuilder(source, use_pred) builder.add_all_path_failures(pruned or []) for path_value in good: builder.add_result_candidate( path_value, jp.PathValueResult(source=source, target_path=path_value.path, pred=inner_pred, valid=True, path_value=path_value)) for result in invalid: path_value = result.path_value builder.add_result_candidate(path_value, result) return builder.build(len(good) > 0)
def test_cardinality_bounds_1(self): for min in range(0, 3): for max in range(0, 3): if min > max: continue predicate = jp.CardinalityPredicate(_AorX, min=min, max=max) expect_ok = min <= 1 and max >= 1 source = _CAB result = predicate(source) all_results = [ jp.CompositePredicateResult(False, _AorX, [ jp.PathValueResult(_CAB, '', PathValue('[0]', 'C'), valid=False, pred=_eq_A), jp.PathValueResult(_CAB, '', PathValue('[0]', 'C'), valid=False, pred=_eq_X) ]), jp.CompositePredicateResult(True, _AorX, [ jp.PathValueResult(_CAB, '', PathValue('[1]', 'A'), valid=True, pred=_eq_A) ]), jp.CompositePredicateResult(False, _AorX, [ jp.PathValueResult(_CAB, '', PathValue('[2]', 'B'), valid=False, pred=_eq_A), jp.PathValueResult(_CAB, '', PathValue('[2]', 'B'), valid=False, pred=_eq_X) ]) ] builder = jp.PathPredicateResultBuilder(pred=jp.PathPredicate( '', _AorX), source=_CAB) builder.add_result_candidate(PathValue('[0]', 'C'), all_results[0]) builder.add_result_candidate(PathValue('[1]', 'A'), all_results[1]) builder.add_result_candidate(PathValue('[2]', 'B'), all_results[2]) expect_path_result = builder.build(True) if expect_ok: self.assertEqual( jp.ConfirmedCardinalityResult(predicate, expect_path_result), result) elif max == 0: self.assertEqual( jp.UnexpectedValueCardinalityResult( predicate, expect_path_result), result) else: self.assertEqual( jp.FailedCardinalityRangeResult( predicate, expect_path_result), result)