def test_match_assign_set_a_b_to_c_2(): actual = {"a": {"b": {"x": 1}}} expected = {"a": {"b": {"c": 2}}} match = get_match(path.a.b, actual) assert match.data == {"x": 1} match.data = {"c": 2} assert match.data == {"c": 2} assert actual == expected new_match = get_match(path.c, match) assert repr(new_match) == '$.a.b.c=2'
def test_match_assign_set_0_0_to_0_2(): actual = [[[2, 2]]] expected = [[[0]]] match = get_match(path[0][0], actual) assert match.data == [2, 2] match.data = [0] assert match.data == [0] assert actual == expected new_match = get_match(path[0], match) assert repr(new_match) == '$[0][0][0]=0'
def test_keys_match_all_all_has_x_eq_1(keys): exp_iter = find_matches(path.rec.x[has(path.rec.x == "1")], keys) actual = next(exp_iter) expected = get_match(path.x, keys) assert repr(actual) == repr(expected) actual = next(exp_iter) expected = get_match(path.x.x, keys) assert repr(actual) == repr(expected) assert_done_iterating(exp_iter)
def test_path_root(solar_system): """## The root""" # The **path** point to root of the tree. match = get_match(path, solar_system) assert match.data == solar_system # In a filter path point to the current element. match = get_match(path.star.name[has(path == 'Sun')], solar_system) assert match.data == 'Sun'
def test_3d_list_match_all_all_has_1_eq_1(three_dimensional_list): exp_iter = find_matches(path.rec[1][has(path.rec[1] == 14)], three_dimensional_list) actual = next(exp_iter) expected = get_match(path[1], three_dimensional_list) assert repr(actual) == repr(expected) actual = next(exp_iter) expected = get_match(path[1][1], three_dimensional_list) assert repr(actual) == repr(expected) assert_done_iterating(exp_iter)
def test_traversal_function_get(solar_system): """## get""" # The **get** function returns the first value the path leads to. # Get the star name from the solar_system sun = get(path.star.name, solar_system) assert sun == 'Sun' # When there is no match, MatchNotFoundError is thrown. try: get(path.star.human_population, solar_system) assert False, "Not expecting humans on the sun" except MatchNotFoundError: pass # Or if preferred, a default value can be given. human_population = get(path.star.human_population, solar_system, default=0) assert human_population == 0 # The default value can be automatically injected in to json document human_population = get(path.star.human_population, solar_system, default=1, store_default=True) assert human_population == solar_system["star"]["human_population"] # The data source can be a json data structure or a Match object. parent_match = get_match(path.star.planets.inner, solar_system) name = get(path[2].name, parent_match) assert name == "Earth"
def test_match_str(keys): regex_expected = r'self=\d+ self=KeyMatch parent=\d+ real_data_name=x data=dict vertex=KeyVertex ' \ r'vertex_index=1 remembered_catch_state=NoneType remembered_on_catch_match=\d+ ' \ r'remembered_on_catch_action=method path=\$.x' match = get_match(path.x, keys) assert re.fullmatch(regex_expected, str(match._traverser_match))
def test_match_del_a_b_c(): actual = {"a": {"b": {"c": 1}}} expected = {"a": {"b": {}}} match = get_match(path.a.b.c, actual) assert match.data == 1 del match.data assert actual == expected
def test_match_del_0_0_0(): actual = [[[1]]] expected = [[[]]] match = get_match(path[0][0][0], actual) assert match.data == 1 del match.data assert actual == expected
def test_match_assign_set_0_0_0_to_2(): actual = [[[1]]] expected = [[[2]]] match = get_match(path[0][0][0], actual) assert match.data == 1 match.data = 2 assert match.data == 2 assert actual == expected
def test_match_pop_0_0_0(): actual = [[[1]]] expected = [[[]]] match = get_match(path[0][0][0], actual) assert match.data == 1 actual_return = match.pop() assert actual_return == 1 assert actual == expected
def test_match_pop_a_b_c(): actual = {"a": {"b": {"c": 1}}} expected = {"a": {"b": {}}} match = get_match(path.a.b.c, actual) assert match.data == 1 actual_return = match.pop() assert actual_return == 1 assert actual == expected
def test_match_assign_set_a_b_c_to_2(): actual = {"a": {"b": {"c": 1}}} expected = {"a": {"b": {"c": 2}}} match = get_match(path.a.b.c, actual) assert match.data == 1 match.data = 2 assert match.data == 2 assert actual == expected
def my_neighbor_is_earth(match: Match): i_am_planet = get_match(path.parent.parent.parent.planets, match, must_match=False) if not i_am_planet: return False index_before_planet = match.data_name - 1 before_planet = get_match(path[index_before_planet][has(path.name == "Earth")], match.parent, must_match=False) if before_planet: return True index_after_planet = match.data_name + 1 before_planet = get_match(path[index_after_planet][has(path.name == "Earth")], match.parent, must_match=False) if before_planet: return True return False
def test_keys_get_root_has_a_or_b_or_z_trace(keys): expected_trace_messages = [ ' has .a got no match', ' has .b got no match', " has .z got {'x': {'x': '19', 'y...", " at $[has($.a) or has($.b) or has($.z)] got {'x': {'x': {'x': '1..." ] actual_trace_messages = [] def mock_print(message): actual_trace_messages.append(message) expected = keys get_match(path[has_any(path.a, path.b, path.z)], keys, must_match=False, trace=log_to(mock_print)) assert actual_trace_messages == expected_trace_messages
def test_match_vertex(keys): x_vertex = path.x y_vertex = x_vertex.y z_vertex = y_vertex.z match = get_match(z_vertex, keys) assert match.vertex == z_vertex assert match.parent.vertex == y_vertex assert match.parent.parent.vertex == x_vertex
def test_match_pop_0_0_0_lookup_error(): actual = [[[1]]] match = get_match(path[0][0][0], actual) assert match.data == 1 actual_return = match.pop() assert actual_return == 1 with pytest.raises(PopError) as exc_info: match.pop() actual = repr(exc_info.value) assert actual == "PopError(The reference data[0] does not exist. Unable to del\n path: $[0][0][0])"
def test_match_pop_a_b_c_lookup_error(): actual = {"a": {"b": {"c": 1}}} match = get_match(path.a.b.c, actual) assert match.data == 1 actual_return = match.pop() assert actual_return == 1 with pytest.raises(PopError) as exc_info: match.pop() actual = repr(exc_info.value) assert actual == "PopError(The reference data['c'] does not exist. Unable to del\n path: $.a.b.c)"
def test_set_a_to_1_invalid_type(): expected = "PopError(Invalid pop data[0] because data is of type: <class \'dict\'>, expecting " \ "type: <class \'list\'>\n" \ " path: $[0])""" data = {"a": 1} with pytest.raises(PopError) as exc_info: match = get_match(path.a, data) vertex = get_vertex_from_path_builder(path[0]) MatchTraverser.pop(match, vertex) actual = repr(exc_info.value) assert actual == expected
def test_traversal_function_get_match(solar_system): """## get_match""" # The **get_match** function returns the first Match the path leads to. # Get the star name from the solar_system match = get_match(path.star.name, solar_system) assert match.data == 'Sun' # When there is no match, MatchNotFoundError is thrown. try: get_match(path.star.human_population, solar_system) assert False, "Not expecting humans on the sun" except MatchNotFoundError: pass # Or if preferred, **None** is returned if not must_match is given. match = get_match(path.star.human_population, solar_system, must_match=False) assert match is None # The data source can be a json data structure or a Match object. parent_match = get_match(path.star.planets.inner, solar_system) earth_match = get_match(path[2].name, parent_match) assert earth_match.path == "$.star.planets.inner[2].name" assert earth_match.data == "Earth"
def test_vertex_TraversingError_root_cannot_be_traverse(): expected = f"TraversingError(Possible Bug. The root match method should never be called.{os.linesep}" \ f" path: ${os.linesep}" \ " last_match: $={})" with pytest.raises(TraversingError) as exc_info: actual = get_match(path, {}) # the root match method should never be called. # but in case of a bug, make sure it creates a error actual.vertex.match(actual._traverser_match, traverser=None, vertex_index=0) assert repr(exc_info.value) == expected
def test_traversal_function_find(solar_system): """## find""" # The **find** function returns an Iterator that iterates to each value the path leads to. Each value is # determine on its iteration. # Find all of the planet names. inner_planets = [planet for planet in find(path.star.planets.inner[wc].name, solar_system)] assert inner_planets == ['Mercury', 'Venus', 'Earth', 'Mars'] # The data source can be a json data structure or a Match object. parent_match = get_match(path.star.planets.inner, solar_system) inner_planets = [planet for planet in find(path[wc].name, parent_match)] assert inner_planets == ['Mercury', 'Venus', 'Earth', 'Mars']
def test_traversal_function_find_matches(solar_system): """## find_matches""" # The **find_matches** function returns an Iterator that iterates to each match the path leads to. Each match is # determine on its iteration. # Find the path to each of the inner planets. for match in find_matches(path.star.planets.inner[wc], solar_system): assert match.path in [ '$.star.planets.inner[0]', '$.star.planets.inner[1]', '$.star.planets.inner[2]', '$.star.planets.inner[3]', ] # The data source can be a json data structure or a Match object. parent_match = get_match(path.star.planets.inner, solar_system) for match in find_matches(path[wc], parent_match): assert match.path in [ '$.star.planets.inner[0]', '$.star.planets.inner[1]', '$.star.planets.inner[2]', '$.star.planets.inner[3]', ]
def test_traversal_function_match_class(solar_system): """## The Match Class""" # The **Match** class provides metadata about the match. match = get_match(path.star.name, solar_system) # The string representation of match = [path=value]. assert repr(match) == "$.star.name=Sun" # A list containing each match in the path. assert match.path_as_list == [match.parent.parent, match.parent, match] # The string representation of match path. assert match.path == "$.star.name" # The key that points to the match value. The data_name is a dictionary key if the parent is a dict or an index if # the parent is a list. assert match.data_name == "name" and match.parent.data[match.data_name] == match.data # The value the path matched. assert match.data == "Sun" # The parent match. assert match.parent.path == "$.star"
def test_3d_0_0_0_path(three_dimensional_list): expected = three_dimensional_list[0][0][0] actual = get_match(path[0][0][0], three_dimensional_list) assert str(actual) == f"$[0][0][0]={expected}"
def test_match_to_path_keys(keys): expected = repr(path.x.y.z) match = get_match(path.x.y.z, keys) actual = repr(match_to_path(match)) assert actual == expected
def test_match_to_path_index(three_dimensional_list): expected = repr(path[0][1][2]) match = get_match(path[0][1][2], three_dimensional_list) actual = repr(match_to_path(match)) assert actual == expected
def test_keys_x_parent_path(keys): expected = keys actual = get_match(path.x.parent, keys) assert str(actual) == f"$.x<-$={expected}"
def test_keys_x_x_parent_path(keys): expected = keys["x"] actual = get_match(path.x.y.parent, keys) assert str(actual) == f"$.x.y<-x={expected}"
def test_3d_list_x_x_parent_path(three_dimensional_list): expected = three_dimensional_list[0] actual = get_match(path[0][1].parent, three_dimensional_list) assert str(actual) == f"$[0][1]<-0={expected}"