def test_arrayslice7(self):
     """Test the arrayslice with configuration 111 (base 2)."""
     subscript = ArraySliceSubscript(5, 7, 2)
     self.assertEqual('5:7:2', subscript.tojsonpath())
     self.assertEqual([5],
                      list(
                          map(
                              lambda match_data: match_data.current_value,
                              subscript.match(self.root_value,
                                              self.current_value))))
 def test_arrayslice2(self):
     """Test the arrayslice with configuration 010 (base 2)."""
     subscript = ArraySliceSubscript(None, 7, None)
     self.assertEqual(':7', subscript.tojsonpath())
     self.assertEqual([0, 1, 2, 3, 4, 5, 6],
                      list(
                          map(
                              lambda match_data: match_data.current_value,
                              subscript.match(self.root_value,
                                              self.current_value))))
 def test_arrayslice4(self):
     """Test the arrayslice with configuration 100 (base 2)."""
     subscript = ArraySliceSubscript(5, None, None)
     self.assertEqual('5:', subscript.tojsonpath())
     self.assertEqual([5, 6, 7, 8, 9],
                      list(
                          map(
                              lambda match_data: match_data.current_value,
                              subscript.match(self.root_value,
                                              self.current_value))))
 def test_arrayslice1(self):
     """Test the arrayslice with configuration 001 (base 2)."""
     subscript = ArraySliceSubscript(None, None, 2)
     self.assertEqual('::2', subscript.tojsonpath())
     self.assertEqual([0, 2, 4, 6, 8],
                      list(
                          map(
                              lambda match_data: match_data.current_value,
                              subscript.match(self.root_value,
                                              self.current_value))))
 def test_arrayslice6(self):
     """Test the arrayslice with configuration 110 (base 2)."""
     subscript = ArraySliceSubscript(5, 7, None)
     self.assertEqual("5:7", subscript.tojsonpath())
     self.assertEqual(
         [5, 6],
         list(
             map(
                 lambda match_data: match_data.current_value,
                 subscript.match(self.root_value, self.current_value),
             )
         ),
     )
 def test_arrayslice9(self):
     """Test the arrayslice with configuration 1001 (base 2)."""
     subscript = ArraySliceSubscript(None, -15, None)
     self.assertEqual(":-15", subscript.tojsonpath())
     self.assertEqual(
         [],
         list(
             map(
                 lambda match_data: match_data.current_value,
                 subscript.match(self.root_value, self.current_value),
             )
         ),
     )
Esempio n. 7
0
    def exitSliceable(self, ctx: JSONPathParser.SliceableContext):
        # NOTE https://github.com/pacifica/python-jsonpath2/issues/35
        #
        # This issue is caused by the way that ANTLR4 indexes terminals in a
        # context. In ANTLR4, when two or more terminals with the same name are
        # present in the same production, but only a subset of terminals are
        # parsed, the indexing does not reflect the position of the terminal
        # within the production.
        #
        # For #35, when the string "::n" is parsed, for a given "n", the context
        # contains only 1 "NUMBER" terminal, which is assigned the index 0,
        # where the index 1 would be expected (with the index 0 returning 'None'
        # or a similar sentinel value).
        #
        # The mitigation is to test for the presence of the second "COLON"
        # terminal and then to verify that it came before the second "NUMBER"
        # terminal.

        if bool(ctx.NUMBER(0)):
            if bool(ctx.COLON(1)):
                if bool(ctx.NUMBER(1)):
                    # When there are 2 "COLON" and "NUMBER" terminals, assign to
                    # 'end' and 'step' as usual.

                    end = int(ctx.NUMBER(0).getText())

                    step = int(ctx.NUMBER(1).getText())
                elif (
                    ctx.NUMBER(0).getSourceInterval()[0]
                    < ctx.COLON(1).getSourceInterval()[0]
                ):
                    # When there are 2 "COLON" terminals but only 1 "NUMBER"
                    # terminal, if the "NUMBER" terminal occurs **before** the
                    # second "COLON" terminal, then assign to 'end' only.

                    end = int(ctx.NUMBER(0).getText())

                    step = None
                else:
                    # When there are 2 "COLON" terminals but only 1 "NUMBER"
                    # terminal, if the "NUMBER" terminal occurs **after** the
                    # second "COLON" terminal, then assign to 'step' only.

                    end = None

                    step = int(ctx.NUMBER(0).getText())
            else:
                # When there is 1 "COLON" terminal and 1 "NUMBER" terminal,
                # assignn to 'end' only.

                end = int(ctx.NUMBER(0).getText())

                step = None
        else:
            end = None

            step = None

        self._stack.append(lambda start: ArraySliceSubscript(start, end, step))
Esempio n. 8
0
    def exitSliceable(self, ctx: JSONPathParser.SliceableContext):
        end = int(ctx.NUMBER(0).getText()) if bool(ctx.NUMBER(0)) else None

        step = int(ctx.NUMBER(1).getText()) if bool(ctx.NUMBER(1)) else None

        self._stack.append(lambda start: ArraySliceSubscript(start, end, step))
 def test_arrayslice_not_list(self):
     """Test the arrayslice with non-list input."""
     subscript = ArraySliceSubscript()
     root_value = None
     self.assertTrue(not isinstance(root_value, list))
     self.assertEqual([], list(subscript.match(root_value, root_value)))