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 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)
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)
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)
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_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)
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')
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)
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)
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)
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, )), )
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_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")
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 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_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)
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)
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)
def test_proxymod_path(self): proxymod_path = Path.parse_file( os.path.join(os.path.dirname(__file__), '..', 'jsonpath2', 'proxymod.txt')) self.assertEqual(1, len(list(proxymod_path.match(self.event_data)))) return
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)
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_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 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
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)
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)
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)