def check_json_path(tolerance: Tolerance):
    """
    Check the JSON path of a tolerance and raise :exc:`InvalidActivity`
    when the path is missing or invalid.

    See: https://github.com/h2non/jsonpath-ng
    """
    if not HAS_JSONPATH:
        raise InvalidActivity(
            "Install the `jsonpath2` package to use a JSON path tolerance: "
            "`pip install chaostoolkit-lib[jsonpath]`.")

    if "path" not in tolerance:
        raise InvalidActivity(
            "hypothesis jsonpath probe tolerance must have a `path` key")

    try:
        path = tolerance.get("path", "").strip()
        if not path:
            raise InvalidActivity(
                "hypothesis probe tolerance JSON path cannot be empty")
        JSONPath.parse_str(path)
    except ValueError:
        raise InvalidActivity(
            "hypothesis probe tolerance JSON path {} is invalid".format(path))
    except TypeError:
        raise InvalidActivity(
            "hypothesis probe tolerance JSON path {} has an invalid "
            "type".format(path))
    def _assert_node_test_case(self, **kwargs):
        self.assertEqual(kwargs['__jsonpath__'], kwargs['node'].tojsonpath())

        if isinstance(kwargs['node'], RootNode):
            self.assertEqual(kwargs['node'],
                             Path.parse_str(kwargs['__jsonpath__']).root_node)

            with NamedTemporaryFile() as temp_file:
                temp_file.write(bytes(kwargs['__jsonpath__'], 'utf-8'))
                temp_file.seek(0)

                self.assertEqual(kwargs['node'],
                                 Path.parse_file(temp_file.name).root_node)

        else:
            with self.assertRaises(ValueError):
                Path(kwargs['node'])

            with self.assertRaises(ValueError):
                Path.parse_str('__jsonpath__')

        match_data_list = list(kwargs['node'].match(kwargs['root_value'],
                                                    kwargs['current_value']))

        for index, value in enumerate(match_data_list):
            self.assertEqual(kwargs['match_data_list'][index], value)

        for match_data in match_data_list:
            new_match_data_list = list(
                match_data.node.match(kwargs['root_value'],
                                      kwargs['current_value']))

            self.assertEqual([match_data], new_match_data_list)
    def test_bookstore_examples_7(self):
        """
        Test the bookstore example 7.

        .. code-block:: python

           >>> expr = Path.parse_str('$..book[0,1]')
           >>> expr.match(self.root_value)
           >>> expr = Path.parse_str('$..book[:2]')
           >>> expr.match(self.root_value)
           >>> expr = Path.parse_str('$..book[:2:1]')
           >>> expr.match(self.root_value)
        """
        for path in ['$..book[0,1]', '$..book[:2]', '$..book[:2:1]']:
            expr = Path.parse_str(path)
            self.assertEqual(Path.parse_str(str(expr)), expr)
            matches = [x.current_value for x in expr.match(self.root_value)]
            self.assertEqual(matches[0]['category'], 'reference')
            self.assertEqual(matches[0]['author'], 'Nigel Rees')
            self.assertEqual(matches[0]['title'], 'Sayings of the Century')
            self.assertEqual(matches[0]['price'], 8.95)
            self.assertEqual(matches[1]['category'], 'fiction')
            self.assertEqual(matches[1]['author'], 'Evelyn Waugh')
            self.assertEqual(matches[1]['title'], 'Sword of Honour')
            self.assertEqual(matches[1]['price'], 12.99)
Beispiel #4
0
    def test_bookstore_examples_9(self):
        """
        Test the bookstore example 9.

        .. code-block:: python

           >>> expr = Path.parse_str('$..book[*][?(@.price<=10)]')
           >>> expr.match(self.root_value)
           >>> expr = Path.parse_str('$..book[*][?(@.price<10)]')
           >>> expr.match(self.root_value)
        """
        for path in [
                '$..book[*][?(@.price<10)]', '$..book[*][?(@.price<=10)]'
        ]:
            expr = Path.parse_str(path)
            self.assertEqual(Path.parse_str(str(expr)), expr)
            matches = [x.current_value for x in expr.match(self.root_value)]
            self.assertEqual(matches[0]['category'], 'reference')
            self.assertEqual(matches[0]['author'], 'Nigel Rees')
            self.assertEqual(matches[0]['title'], 'Sayings of the Century')
            self.assertEqual(matches[0]['price'], 8.95)
            self.assertEqual(matches[1]['category'], 'fiction')
            self.assertEqual(matches[1]['author'], 'Herman Melville')
            self.assertEqual(matches[1]['title'], 'Moby Dick')
            self.assertEqual(matches[1]['isbn'], '0-553-21311-3')
            self.assertEqual(matches[1]['price'], 8.99)
Beispiel #5
0
    def test_bookstore_examples_12(self):
        """
        Test the bookstore example 12.

        .. code-block:: python

           >>> expr = Path.parse_str('$..book[*][?(@.price>=10)]')
           >>> expr.match(self.root_value)
           >>> expr = Path.parse_str('$..book[*][?(@.price>10)]')
           >>> expr.match(self.root_value)
        """
        for path in [
                '$..book[*][?(@.price>10)]', '$..book[*][?(@.price>=10)]'
        ]:
            expr = Path.parse_str(path)
            self.assertEqual(Path.parse_str(str(expr)), expr)
            matches = [x.current_value for x in expr.match(self.root_value)]
            self.assertEqual(matches[0]['category'], 'fiction')
            self.assertEqual(matches[0]['author'], 'Evelyn Waugh')
            self.assertEqual(matches[0]['title'], 'Sword of Honour')
            self.assertEqual(matches[0]['price'], 12.99)
            self.assertEqual(matches[1]['category'], 'fiction')
            self.assertEqual(matches[1]['author'], 'J. R. R. Tolkien')
            self.assertEqual(matches[1]['title'], 'The Lord of the Rings')
            self.assertEqual(matches[1]['isbn'], '0-395-19395-8')
            self.assertEqual(matches[1]['price'], 22.99)
    def test_bookstore_examples_7(self):
        """
        Test the bookstore example 7.

        .. code-block:: python

           >>> expr = Path.parse_str('$..book[0,1]')
           >>> expr.match(self.root_value)
           >>> expr = Path.parse_str('$..book[:2]')
           >>> expr.match(self.root_value)
           >>> expr = Path.parse_str('$..book[:2:1]')
           >>> expr.match(self.root_value)
        """
        for path in ["$..book[0,1]", "$..book[:2]", "$..book[:2:1]"]:
            expr = Path.parse_str(path)
            self.assertEqual(Path.parse_str(str(expr)), expr)
            matches = [x.current_value for x in expr.match(self.root_value)]
            self.assertEqual(matches[0]["category"], "reference")
            self.assertEqual(matches[0]["author"], "Nigel Rees")
            self.assertEqual(matches[0]["title"], "Sayings of the Century")
            self.assertEqual(matches[0]["price"], 8.95)
            self.assertEqual(matches[1]["category"], "fiction")
            self.assertEqual(matches[1]["author"], "Evelyn Waugh")
            self.assertEqual(matches[1]["title"], "Sword of Honour")
            self.assertEqual(matches[1]["price"], 12.99)
Beispiel #7
0
 def test_bookstore_examples_4(self):
     """Test the bookstore examples."""
     expr = Path.parse_str('$.store..price')
     self.assertEqual(Path.parse_str(str(expr)), expr)
     matches = [x.current_value for x in expr.match(self.root_value)]
     for price in [8.95, 12.99, 8.99, 22.99, 19.95]:
         self.assertTrue(price in matches)
Beispiel #8
0
 def test_bookstore_examples_3(self):
     """Test the bookstore examples."""
     expr = Path.parse_str('$.store.*')
     self.assertEqual(Path.parse_str(str(expr)), expr)
     matches = [x.current_value for x in expr.match(self.root_value)]
     self.assertTrue(isinstance(matches[0], list))
     self.assertTrue(isinstance(matches[1], dict))
     self.assertEqual(matches[0][0]['author'], 'Nigel Rees')
     self.assertEqual(matches[1]['color'], 'red')
Beispiel #9
0
 def test_bookstore_examples_11(self):
     """Test the bookstore examples."""
     expr = Path.parse_str('$..book[*][?(@.category != "fiction")]')
     self.assertEqual(Path.parse_str(str(expr)), expr)
     matches = [x.current_value for x in expr.match(self.root_value)]
     self.assertEqual(matches[0]['category'], 'reference')
     self.assertEqual(matches[0]['author'], 'Nigel Rees')
     self.assertEqual(matches[0]['title'], 'Sayings of the Century')
     self.assertEqual(matches[0]['price'], 8.95)
Beispiel #10
0
 def test_bookstore_examples_5(self):
     """Test the bookstore examples."""
     expr = Path.parse_str('$..book[2]')
     self.assertEqual(Path.parse_str(str(expr)), expr)
     matches = [x.current_value for x in expr.match(self.root_value)]
     self.assertEqual(matches[0]['category'], 'fiction')
     self.assertEqual(matches[0]['author'], 'Herman Melville')
     self.assertEqual(matches[0]['title'], 'Moby Dick')
     self.assertEqual(matches[0]['isbn'], '0-553-21311-3')
     self.assertEqual(matches[0]['price'], 8.99)
Beispiel #11
0
 def test_bookstore_examples_2(self):
     """Test the bookstore examples."""
     expr = Path.parse_str('$..author')
     self.assertEqual(Path.parse_str(str(expr)), expr)
     matches = [x.current_value for x in expr.match(self.root_value)]
     for auth in [
             'Nigel Rees', 'Evelyn Waugh', 'Herman Melville',
             'J. R. R. Tolkien'
     ]:
         self.assertTrue(auth in matches)
Beispiel #12
0
 def test_bookstore_examples_6(self):
     """Test the bookstore examples."""
     for path in ['$..book[-1:]', '$..book[-1]', '$..book[3:4:1]']:
         expr = Path.parse_str(path)
         self.assertEqual(Path.parse_str(str(expr)), expr)
         matches = [x.current_value for x in expr.match(self.root_value)]
         self.assertEqual(matches[0]['category'], 'fiction')
         self.assertEqual(matches[0]['author'], 'J. R. R. Tolkien')
         self.assertEqual(matches[0]['title'], 'The Lord of the Rings')
         self.assertEqual(matches[0]['isbn'], '0-395-19395-8')
         self.assertEqual(matches[0]['price'], 22.99)
    def _assert_node_test_case(self, **kwargs):
        self.assertEqual(kwargs["__jsonpath__"], kwargs["node"].tojsonpath())

        if isinstance(kwargs["node"], RootNode):
            self.assertEqual(kwargs["node"],
                             Path.parse_str(kwargs["__jsonpath__"]).root_node)

            with NamedTemporaryFile() as temp_file:
                temp_file.write(bytes(kwargs["__jsonpath__"], "utf-8"))
                temp_file.seek(0)

                self.assertEqual(kwargs["node"],
                                 Path.parse_file(temp_file.name).root_node)

        else:
            with self.assertRaises(ValueError):
                Path(kwargs["node"])

            with self.assertRaises(ValueError):
                Path.parse_str("__jsonpath__")

        match_data_list = list(kwargs["node"].match(kwargs["root_value"],
                                                    kwargs["current_value"]))

        self.assertListEqual(kwargs["match_data_list"], match_data_list)
        self.assertListEqual(
            list(
                map(
                    lambda match_data: match_data.node.tojsonpath(),
                    kwargs["match_data_list"],
                )),
            list(
                map(lambda match_data: match_data.node.tojsonpath(),
                    match_data_list)),
        )

        for match_data in match_data_list:
            new_match_data_list = list(
                match_data.node.match(kwargs["root_value"],
                                      kwargs["current_value"]))

            self.assertListEqual([match_data], new_match_data_list)
            self.assertListEqual(
                list(
                    map(lambda match_data: match_data.node.tojsonpath(),
                        [match_data])),
                list(
                    map(
                        lambda match_data: match_data.node.tojsonpath(),
                        new_match_data_list,
                    )),
            )
Beispiel #14
0
 def test_bookstore_examples_8(self):
     """Test the bookstore examples."""
     expr = Path.parse_str('$..book[*][?(@.isbn)]')
     self.assertEqual(Path.parse_str(str(expr)), expr)
     matches = [x.current_value for x in expr.match(self.root_value)]
     self.assertEqual(matches[0]['category'], 'fiction')
     self.assertEqual(matches[0]['author'], 'Herman Melville')
     self.assertEqual(matches[0]['title'], 'Moby Dick')
     self.assertEqual(matches[0]['isbn'], '0-553-21311-3')
     self.assertEqual(matches[0]['price'], 8.99)
     self.assertEqual(matches[1]['category'], 'fiction')
     self.assertEqual(matches[1]['author'], 'J. R. R. Tolkien')
     self.assertEqual(matches[1]['title'], 'The Lord of the Rings')
     self.assertEqual(matches[1]['isbn'], '0-395-19395-8')
     self.assertEqual(matches[1]['price'], 22.99)
    def test_bookstore_examples_10(self):
        """
        Test the bookstore example 10.

        .. code-block:: python

           >>> expr = Path.parse_str('$..book[*][?(@.author = "Nigel Rees")]')
           >>> expr.match(self.root_value)
        """
        expr = Path.parse_str('$..book[*][?(@.author = "Nigel Rees")]')
        self.assertEqual(Path.parse_str(str(expr)), expr)
        matches = [x.current_value for x in expr.match(self.root_value)]
        self.assertEqual(matches[0]['category'], 'reference')
        self.assertEqual(matches[0]['author'], 'Nigel Rees')
        self.assertEqual(matches[0]['title'], 'Sayings of the Century')
        self.assertEqual(matches[0]['price'], 8.95)
Beispiel #16
0
    def from_cloudevents_model(cls, event: Event) -> 'Transaction':
        if CLOUDEVENTS_DEFAULT_EVENT_TYPE_ != event.event_type:
            raise InvalidEventTypeValueError(event)

        if CLOUDEVENTS_DEFAULT_SOURCE_ != event.source:
            raise InvalidSourceValueError(event)

        attrs = {}

        for name in [
                '_id', 'analytical_tool', 'description', 'instrument',
                'proposal', 'submitter', 'suspense_date'
        ]:
            for match_data in Path.parse_str(
                    '$[*][?(@["destinationTable"] = {0})]["value"]'.format(
                        json.dumps('Transactions.{0}'.format(name)))).match(
                            event.data):
                if name in attrs:
                    raise TransactionDuplicateAttributeError(event, name)

                attrs[name] = match_data.current_value

            if name not in attrs:
                attrs[name] = None

        return cls(**attrs)
    def test_bookstore_examples_11(self):
        """
        Test the bookstore example 11.

        .. code-block:: python

           >>> expr = Path.parse_str('$..book[*][?(@.category != "fiction")]')
           >>> expr.match(self.root_value)
        """
        expr = Path.parse_str('$..book[*][?(@.category != "fiction")]')
        self.assertEqual(Path.parse_str(str(expr)), expr)
        matches = [x.current_value for x in expr.match(self.root_value)]
        self.assertEqual(matches[0]["category"], "reference")
        self.assertEqual(matches[0]["author"], "Nigel Rees")
        self.assertEqual(matches[0]["title"], "Sayings of the Century")
        self.assertEqual(matches[0]["price"], 8.95)
Beispiel #18
0
    def load_data(cls, faction_name):
        """
        Create a Faction object by passing in the faction name. This can be either the XWS spec name or,
        the actual name of the faction
        e.g. faction_name = 'rebelalliance'
             faction_name = 'Rebel Alliance'

        :param faction_name: String value of the faction
        :return:
        """
        obj = cls()
        for file in manifest["factions"]:
            filepath = PurePath(Path(__file__).parents[1], file).as_posix()
            with open(filepath, "r") as f:
                factions = json.load(f)

            jpath = JPath.parse_str(
                f"$..[?(@.xws=\"{faction_name}\"[email protected]=\"{faction_name}\")]")
            faction = [m.current_value for m in jpath.match(factions)]

            if not len(faction):
                raise FactionMissingException(
                    "Found no valid faction, be sure you have a valid faction "
                    "or the xws spec is at least version 2.0.0")

            for k, v in faction[0].items():
                obj.__setattr__(k, v)

        return obj
    def test_bookstore_examples_3(self):
        """
        Test the bookstore example 3.

        .. code-block:: python

           >>> expr = Path.parse_str('$.store.*')
           >>> expr.match(self.root_value)
        """
        expr = Path.parse_str("$.store.*")
        self.assertEqual(Path.parse_str(str(expr)), expr)
        matches = [x.current_value for x in expr.match(self.root_value)]
        self.assertTrue(isinstance(matches[0], list))
        self.assertTrue(isinstance(matches[1], dict))
        self.assertEqual(matches[0][0]["author"], "Nigel Rees")
        self.assertEqual(matches[1]["color"], "red")
Beispiel #20
0
 def test_node_subscript(self):
     """Test the node subscript."""
     cases = [
         ([
             'foo',
             'bar',
             'fum',
             'baz',
         ], {
             '$["collection"][$["index"]]': [
                 {
                     'index': [],
                     'expected_values': [],
                 },
                 {
                     'index': 1,
                     'expected_values': ['bar'],
                 },
             ],
             '$["collection"][$["index"][*]]': [
                 {
                     'index': [1, 3],
                     'expected_values': ['bar', 'baz'],
                 },
             ],
         }),
         ({
             'foo': 'bar',
             'fum': 'baz',
         }, {
             '$["collection"][$["index"]]': [
                 {
                     'index': [],
                     'expected_values': [],
                 },
                 {
                     'index': 'foo',
                     'expected_values': ['bar'],
                 },
             ],
             '$["collection"][$["index"][*]]': [
                 {
                     'index': ['foo', 'fum'],
                     'expected_values': ['bar', 'baz'],
                 },
             ],
         }),
     ]
     for collection, cases_for_collection in cases:
         for string, cases_for_string in cases_for_collection.items():
             for case_for_string in cases_for_string:
                 path = Path.parse_str(string)
                 self.assertEqual(string, str(path))
                 matches = list(path.match({
                     'collection': collection,
                     'index': case_for_string['index'],
                 }))
                 self.assertListEqual(case_for_string['expected_values'], list(
                     map(lambda match_data: match_data.current_value, matches)))
    def test_bookstore_examples_5(self):
        """
        Test the bookstore example 5.

        .. code-block:: python

           >>> expr = Path.parse_str('$..book[2]')
           >>> expr.match(self.root_value)
        """
        expr = Path.parse_str("$..book[2]")
        self.assertEqual(Path.parse_str(str(expr)), expr)
        matches = [x.current_value for x in expr.match(self.root_value)]
        self.assertEqual(matches[0]["category"], "fiction")
        self.assertEqual(matches[0]["author"], "Herman Melville")
        self.assertEqual(matches[0]["title"], "Moby Dick")
        self.assertEqual(matches[0]["isbn"], "0-553-21311-3")
        self.assertEqual(matches[0]["price"], 8.99)
Beispiel #22
0
    def test_bookstore_extexamples_3(self):
        """
        Test the bookstore example slice with start and multiple colons.

        .. code-block:: python

           >>> expr = Path.parse_str('$..book[2::]')
           >>> expr.match(self.root_value)
        """
        expr = Path.parse_str('$..book[2::]')
        self.assertEqual(Path.parse_str(str(expr)), expr)
        matches = [x.current_value for x in expr.match(self.root_value)]
        self.assertEqual(len(matches), 2)
        self.assertEqual(matches[0]['category'], 'fiction')
        self.assertEqual(matches[0]['author'], 'Herman Melville')
        self.assertEqual(matches[0]['title'], 'Moby Dick')
        self.assertEqual(matches[0]['isbn'], '0-553-21311-3')
        self.assertEqual(matches[0]['price'], 8.99)
    def test_bookstore_examples_2(self):
        """
        Test the bookstore example 2.

        .. code-block:: python

           >>> expr = Path.parse_str('$..author')
           >>> expr.match(self.root_value)
        """
        expr = Path.parse_str("$..author")
        self.assertEqual(Path.parse_str(str(expr)), expr)
        matches = [x.current_value for x in expr.match(self.root_value)]
        for auth in [
            "Nigel Rees",
            "Evelyn Waugh",
            "Herman Melville",
            "J. R. R. Tolkien",
        ]:
            self.assertTrue(auth in matches)
Beispiel #24
0
 def test_node_subscript_noop(self):
     """Test the node subscript with no indices."""
     string = '$["collection"][$["index"]]'
     path = Path.parse_str(string)
     self.assertEqual(string, str(path))
     data = {
         'collection': ['foo', 'bar', 'fum', 'baz'],
         'index': [],
     }
     matches = list(path.match(data))
     self.assertEqual(0, len(matches))
 def test_example(self):
     """Test the example from the README.md."""
     test_string = '{"hello":"Hello, world!"}'
     test_json = loads(test_string)
     path_expr = Path.parse_str('$["hello"]')
     result = list(
         map(lambda match_data: match_data.current_value, path_expr.match(test_json)))
     self.assertEqual(result[0], 'Hello, world!')
     result = list(
         map(lambda match_data: match_data.node.tojsonpath(), path_expr.match(test_json)))
     self.assertEqual(result[0], '$["hello"]')
    def test_bookstore_extexamples_2(self):
        """
        Test the bookstore example slice with end and multiple colons.

        .. code-block:: python

           >>> expr = Path.parse_str('$..book[:2:]')
           >>> expr.match(self.root_value)
        """
        expr = Path.parse_str("$..book[:2:]")
        self.assertEqual(Path.parse_str(str(expr)), expr)
        matches = [x.current_value for x in expr.match(self.root_value)]
        self.assertEqual(matches[0]["category"], "reference")
        self.assertEqual(matches[0]["author"], "Nigel Rees")
        self.assertEqual(matches[0]["title"], "Sayings of the Century")
        self.assertEqual(matches[0]["price"], 8.95)
        self.assertEqual(matches[1]["category"], "fiction")
        self.assertEqual(matches[1]["author"], "Evelyn Waugh")
        self.assertEqual(matches[1]["title"], "Sword of Honour")
        self.assertEqual(matches[1]["price"], 12.99)
Beispiel #27
0
    def from_cloudevents_model(cls, event: Event) -> typing.List['File']:
        """Factory creating instances of File from a cloud event."""
        insts = []

        for match_data in Path.parse_str(
                '$[*][?(@["destinationTable"] = "Files")]').match(event.data):
            inst = cls(**match_data.current_value)

            insts.append(inst)

        return insts
Beispiel #28
0
def main():
    selector = sys.argv[1]

    j = json.loads(sys.stdin.read())
    try:
        path = Path.parse_str(selector)
        results = path.match(j)

        print(json.dumps([entry.current_value for entry in results]))
    except Exception as e:
        print(repr(e))
        sys.exit(1)
Beispiel #29
0
 def test_node_subscript_array_index(self):
     """Test the node subscript with one array index."""
     string = '$["collection"][$["index"]]'
     path = Path.parse_str(string)
     self.assertEqual(string, str(path))
     data = {
         'collection': ['foo', 'bar', 'fum', 'baz'],
         'index': 1,
     }
     matches = list(path.match(data))
     self.assertEqual(1, len(matches))
     self.assertEqual('bar', matches[0].current_value)
    def test_bookstore_extexample_1(self):
        """
        Test the bookstore example with step function.

        .. code-block:: python

           >>> expr = Path.parse_str('$..book[::2]')
           >>> expr.match(self.root_value)
        """
        expr = Path.parse_str("$..book[::2]")
        self.assertEqual(Path.parse_str(str(expr)), expr)
        matches = [x.current_value for x in expr.match(self.root_value)]
        self.assertEqual(matches[0]["category"], "reference")
        self.assertEqual(matches[0]["author"], "Nigel Rees")
        self.assertEqual(matches[0]["title"], "Sayings of the Century")
        self.assertEqual(matches[0]["price"], 8.95)
        self.assertEqual(matches[1]["category"], "fiction")
        self.assertEqual(matches[1]["author"], "Herman Melville")
        self.assertEqual(matches[1]["title"], "Moby Dick")
        self.assertEqual(matches[1]["isbn"], "0-553-21311-3")
        self.assertEqual(matches[1]["price"], 8.99)