def test_string_eq(self):
     context = ExecutionContext()
     eq_abc = jp.STR_EQ('abc')
     self.assertGoodResult(PathValue('', 'abc'), eq_abc,
                           eq_abc(context, 'abc'))
     self.assertBadResult(PathValue('', 'abcd'), eq_abc,
                          eq_abc(context, 'abcd'))
Beispiel #2
0
 def test_string_ne(self):
   context = ExecutionContext()
   ne_abc = jp.STR_NE('abc')
   self.assertGoodResult(PathValue('', 'abcd'),
                         ne_abc, ne_abc(context, 'abcd'))
   self.assertBadResult(PathValue('', 'abc'),
                        ne_abc, ne_abc(context, 'abc'))
Beispiel #3
0
  def test_collect_with_dict_subset(self):
    # See test_dict_subset_with_array_nodes for comparision.
    context = ExecutionContext()
    letters = {'a':'A', 'b':'B', 'c':'C'}
    numbers = {'a':1, 'b':2}
    both = [letters, numbers]
    source = {'items': both}
    letter_subset_pred = jp.DICT_SUBSET({'a':'A'})
    path_pred = jp.PathPredicate('items', pred=letter_subset_pred)
    result = path_pred(context, source)

    mismatch_error = jp.TypeMismatchError(
        expect_type=(int, long, float), got_type=str,
        source=source,
        target_path=jp.PATH_SEP.join(['items', 'a']),
        path_value=PathValue('items[1]', numbers))
    valid_result = letter_subset_pred(context, letters).clone_with_source(
        source=source, base_target_path='items', base_value_path='items[0]')
    self.assertEqual(
        # pylint: disable=bad-continuation
        jp.PathPredicateResultBuilder(source, path_pred)
          .add_result_candidate(PathValue('items[0]', letters), valid_result)
          .add_result_candidate(PathValue('items[1]', numbers),
                                mismatch_error)
          .build(True),
        result)
 def test_indirect_string(self):
     context = ExecutionContext(TEST='abc')
     eq_abc = jp.STR_EQ(lambda x: x['TEST'])
     self.assertGoodResult(PathValue('', 'abc'), eq_abc,
                           eq_abc(context, 'abc'))
     self.assertBadResult(PathValue('', 'abcd'), eq_abc,
                          eq_abc(context, 'abcd'))
Beispiel #5
0
 def test_string_substr(self):
     substr_q = jp.STR_SUBSTR('q')
     substr_pqr = jp.STR_SUBSTR('pqr')
     self.assertGoodResult(PathValue('', 'pqr'), substr_q, substr_q('pqr'))
     self.assertGoodResult(PathValue('', 'rqp'), substr_q, substr_q('rqp'))
     self.assertGoodResult(PathValue('', 'pqr'), substr_pqr,
                           substr_pqr('pqr'))
     self.assertBadResult(PathValue('', 'abc'), substr_q, substr_q('abc'))
     self.assertBadResult(PathValue('', 'xyz'), substr_q, substr_q('xyz'))
Beispiel #6
0
 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)
Beispiel #7
0
    def test_dict_ne(self):
        letters = {'a': 'A', 'b': 'B', 'c': 'C'}
        operand = {'a': 'A', 'b': 'B'}
        ne_pred = jp.DICT_NE(operand)

        self.assertGoodResult(PathValue('', letters), ne_pred,
                              ne_pred(letters))
        self.assertBadResult(PathValue('', operand), ne_pred, ne_pred(operand))
        self.assertGoodResult(PathValue('', {'a': 'A'}), ne_pred,
                              ne_pred({'a': 'A'}))
Beispiel #8
0
  def test_dict_ne(self):
    context = ExecutionContext()
    letters = {'a':'A', 'b':'B', 'c':'C'}
    operand = {'a': 'A', 'b': 'B'}
    ne_pred = jp.DICT_NE(operand)

    self.assertGoodResult(PathValue('', letters),
                          ne_pred, ne_pred(context, letters))
    self.assertBadResult(PathValue('', operand),
                         ne_pred, ne_pred(context, operand))
    self.assertGoodResult(PathValue('', {'a': 'A'}),
                          ne_pred, ne_pred(context, {'a': 'A'}))
 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_from_dict_found(self):
    # """Normal dictionary attribute lookup."""
    source = _LETTER_DICT
    pred = PathPredicate('a')
    values = pred(source)
    self.assertEqual([PathValue('a', 'A')], values.path_values)
    self.assertEqual([], values.path_failures)

    pred = PathPredicate('b')
    values = pred(source)
    self.assertEqual([PathValue('b', '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)
Beispiel #13
0
  def test_dict_eq_indirect(self):
    context = ExecutionContext(testA='A', testKey='b')
    letters = {'a':'A', 'b':'B', 'c':'C'}
    operand = {'a': lambda x: x['testA'], 'b': 'B'}
    actual_operand = {'a': 'A', 'b': 'B'}
    eq_pred = jp.DICT_EQ(operand)

    self.assertBadResult(PathValue('', letters),
                         eq_pred, eq_pred(context, letters))
    self.assertGoodResult(PathValue('', actual_operand),
                          eq_pred, eq_pred(context, actual_operand))
    self.assertBadResult(PathValue('', {'a': 'A'}),
                         eq_pred, eq_pred(context, {'a': 'A'}))
 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)
Beispiel #15
0
 def test_string_substr(self):
   context = ExecutionContext()
   substr_q = jp.STR_SUBSTR('q')
   substr_pqr = jp.STR_SUBSTR('pqr')
   self.assertGoodResult(PathValue('', 'pqr'),
                         substr_q, substr_q(context, 'pqr'))
   self.assertGoodResult(PathValue('', 'rqp'),
                         substr_q, substr_q(context, 'rqp'))
   self.assertGoodResult(PathValue('', 'pqr'),
                         substr_pqr, substr_pqr(context, 'pqr'))
   self.assertBadResult(PathValue('', 'abc'),
                        substr_q, substr_q(context, 'abc'))
   self.assertBadResult(PathValue('', 'xyz'),
                        substr_q, substr_q(context, 'xyz'))
Beispiel #16
0
    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))
Beispiel #17
0
    def test_dict_subset_with_array_values(self):
        small = {'a': ['A'], 'b': [1, 2]}
        big = {'a': ['A', 'B', 'C'], 'b': [1, 2, 3], 'c': ['red', 'yellow']}
        small_nested = {'first': small}
        big_nested = {'first': big, 'second': big}

        small_subset_pred = jp.DICT_SUBSET(small)
        nested_subset_pred = jp.DICT_SUBSET(small_nested)

        # These are matching the outer source objects because they contain
        # the subset we are looking for.
        self.assertGoodResult(PathValue('', big), small_subset_pred,
                              small_subset_pred(big))
        self.assertGoodResult(PathValue('', big_nested), nested_subset_pred,
                              nested_subset_pred(big_nested))
Beispiel #18
0
  def test_dict_simple_subset(self):
    context = ExecutionContext()
    letters = {'a':'A', 'b':'B', 'c':'C'}
    operand = {'a': 'A', 'b': 'B'}
    subset_pred = jp.DICT_SUBSET(operand)

    self.assertGoodResult(PathValue('', letters),
                          subset_pred, subset_pred(context, letters))
    self.assertGoodResult(PathValue('', operand),
                          subset_pred, subset_pred(context, operand))
    source = {'a':'A'}
    self.assertEqual(
        jp.MissingPathError(source=source, target_path='b',
                            path_value=PathValue('', source)),
        subset_pred(context, source))
Beispiel #19
0
    def test_dict_nested_subset(self):
        small = {'first': 'Apple', 'second': 'Banana'}
        small_subset_pred = jp.DICT_SUBSET(small)

        big = {'first': 'Apple', 'second': 'Banana', 'third': 'Cherry'}

        self.assertGoodResult(PathValue('', big), small_subset_pred,
                              small_subset_pred(big))

        small_nested = {'outer': small}
        small_nested_subset_pred = jp.DICT_SUBSET(small_nested)

        big_nested = {'outer': big, 'another': big}
        self.assertGoodResult(PathValue('', big_nested),
                              small_nested_subset_pred,
                              small_nested_subset_pred(big_nested))
Beispiel #20
0
    def test_collect_from_dict_transform(self):
        context = ExecutionContext()
        source = {'a': 7, 'b': 4}
        pred = PathPredicate('',
                             transform=lambda ctxt, val: val['a'] - val['b'])
        expect = 7 - 4
        values = pred(context, source)

        builder = PathPredicateResultBuilder(source, pred)
        builder.add_result_candidate(
            PathValue('', source),
            PathValueResult(source=source,
                            target_path='',
                            path_value=PathValue('', expect),
                            valid=True))
        self.assertEqual(builder.build(True), values)
Beispiel #21
0
 def __call__(self, context, value):
     valid = value == context.eval(self.__operand)
     return PathValueResult(pred=self,
                            source=value,
                            target_path='',
                            path_value=PathValue('', value),
                            valid=valid)
  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)
Beispiel #23
0
 def test_path_value_found_top(self):
     source = _COMPOSITE_DICT
     pred = jp.PathEqPredicate('letters', _LETTER_DICT)
     result = pred(source)
     expect = _make_result(pred, jp.DICT_EQ(_LETTER_DICT), source,
                           [PathValue('letters', _LETTER_DICT)], [])
     self.assertTrue(result)
     self.assertEqual(expect, result)
Beispiel #24
0
    def test_list_subset_strict_bad(self):
        letters = {'a': 'A', 'b': 'B', 'c': 'C'}
        numbers = {'a': 1, 'b': 2, 'c': 'C'}
        source = [letters, numbers]

        common_subset_pred = jp.LIST_SUBSET([{'c': 'C'}], strict=True)
        self.assertBadResult(PathValue('', source), common_subset_pred,
                             common_subset_pred(source))
Beispiel #25
0
    def test_collect_from_list_of_list_with_index(self):
        # """Path with explicit list indexes to traverse through nested lists."""
        context = ExecutionContext()
        upper = ['A', 'B', 'C']
        lower = ['a', 'b', 'c']
        letters = [upper, lower]
        arabic = [1, 2, 3]
        roman = ['i', 'ii', 'iii']
        numbers = [arabic, roman]
        source = [letters, numbers]

        # By default, values that are lists get expanded (one level)
        pred = PathPredicate('[1]')
        values = pred(context, source)
        self.assertEquals(
            [PathValue('[1][0]', arabic),
             PathValue('[1][1]', roman)], values.path_values)
        self.assertEqual([], values.path_failures)

        # If we dont want to expand, then decorate with DONT_ENUMERATE_TERMINAL.
        pred = PathPredicate('[0]' + DONT_ENUMERATE_TERMINAL)
        values = pred(context, source)
        self.assertEqual([PathValue('[0]', letters)], values.path_values)
        self.assertEqual([], values.path_failures)

        pred = PathPredicate('[1]' + DONT_ENUMERATE_TERMINAL)
        values = pred(context, source)
        self.assertEqual([PathValue('[1]', numbers)], values.path_values)
        self.assertEqual([], values.path_failures)

        # Go out one more level
        pred = PathPredicate('[1][0]' + DONT_ENUMERATE_TERMINAL)
        values = pred(context, source)
        self.assertEqual([PathValue('[1][0]', arabic)], values.path_values)
        self.assertEqual([], values.path_failures)

        pred = PathPredicate('[1][0]')
        values = pred(context, source)
        self.assertEqual([
            PathValue('[1][0][0]', 1),
            PathValue('[1][0][1]', 2),
            PathValue('[1][0][2]', 3)
        ], values.path_values)
        self.assertEqual([], values.path_failures)

        # Go all the way down.
        pred = PathPredicate('[1][0][2]')
        values = pred(context, source)
        self.assertEqual([PathValue('[1][0][2]', 3)], values.path_values)
        self.assertEqual([], values.path_failures)
Beispiel #26
0
    def test_collect_from_list_identity(self):
        context = ExecutionContext()
        letters = ['A', 'B', 'C']
        pred = PathPredicate('')
        values = pred(context, letters)
        self.assertEqual([
            PathValue('[0]', 'A'),
            PathValue('[1]', 'B'),
            PathValue('[2]', 'C')
        ], values.path_values)
        self.assertEqual([], values.path_failures)

        pred = PathPredicate(DONT_ENUMERATE_TERMINAL)
        values = pred(context, letters)
        self.assertEqual([PathValue('', letters)], values.path_values)
        self.assertEqual([], values.path_failures)

        pred = PathPredicate(PATH_SEP)
        values = pred(context, letters)
        self.assertEqual([
            PathValue('[0]', 'A'),
            PathValue('[1]', 'B'),
            PathValue('[2]', 'C')
        ], values.path_values)
        self.assertEqual([], values.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_list_subset_nested_bad(self):
        context = ExecutionContext()
        letters = {'a': 'A', 'b': 'B', 'c': 'C'}
        numbers = {'a': 1, 'b': 2, 'c': 'C'}
        source = [numbers, [letters]]

        pred = jp.LIST_SUBSET([[{'b': 2}]])
        self.assertBadResult(PathValue('', source), pred,
                             pred(context, source))
 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)
Beispiel #30
0
    def test_list_subset_nonstrict_good(self):
        letters = {'a': 'A', 'b': 'B', 'c': 'C'}
        numbers = {'a': 1, 'b': 2, 'c': 'C'}
        source = [letters, numbers]

        common_subset_pred = jp.LIST_SUBSET([{'c': 'C'}])
        self.assertFalse(common_subset_pred.strict)
        self.assertGoodResult(PathValue('', source), common_subset_pred,
                              common_subset_pred(source))