From a8eccc226bcdb841876fc918244d41c99e67c286 Mon Sep 17 00:00:00 2001 From: jsfehler Date: Wed, 5 Jun 2024 08:48:56 -0400 Subject: [PATCH] fix: Grandchildren of Route was not inheriting callable arguments (#114) --- inori/route.py | 14 ++++++++++++-- tests/client/test_add_route.py | 18 +++++++++++++++--- tests/route/test_update_url.py | 24 ++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 tests/route/test_update_url.py diff --git a/inori/route.py b/inori/route.py index 5f590f2..3b5e009 100644 --- a/inori/route.py +++ b/inori/route.py @@ -65,6 +65,9 @@ def __init__( self.session = self.client.new_session() self.session.auth = self.client.auth + def __repr__(self): # NOQA + return f"Route: <{str(self.url)}>" + def __deepcopy__(self, memodict): """Copy in such a way as to avoid copying the client object.""" new = type(self)(self.client, str(self.url), self.trailing_slash) @@ -117,14 +120,21 @@ def __call__(self, **kwargs: str) -> T: # NOQA C90 # Children of this callable should know about the last arguments. for _, child_route in copied_route.children.items(): - child_route.url = child_route.url.format(**next_kwargs) - child_route.prev_kwargs = next_kwargs + copied_route._update_url(next_kwargs) for callable_route in child_route.callables.values(): callable_route.url = callable_route.url.format(**next_kwargs) return copied_route + def _update_url(self, new_kwargs: str) -> None: + """Update this Route and it's children's urls with new values.""" + self.url = self.url.format(**new_kwargs) + self.prev_kwargs = new_kwargs + + for _, child_route in self.children.items(): + child_route._update_url(new_kwargs) + def post(self, *args: Any, **kwargs: Any) -> requests.Response: """Send a POST request.""" return self.request('POST', self, *args, **kwargs) diff --git a/tests/client/test_add_route.py b/tests/client/test_add_route.py index eba9388..3a4ec7a 100644 --- a/tests/client/test_add_route.py +++ b/tests/client/test_add_route.py @@ -140,7 +140,7 @@ def test_multiple_args_reuse(client): assert b.url == 'https://foo.com/v1/bar/2/20' -def test_chaining(): +def test_chaining_callables(): client = Client('https://foo.com/v1/') client.add_route('bar/${potatoId}/biz/${tomatoId}') @@ -148,7 +148,7 @@ def test_chaining(): assert result.url == 'https://foo.com/v1/bar/10/biz/55' -def test_long_chaining(client): +def test_long_chaining_callables(client): client.add_route('bar/${barId}/${bazId}/${binId}') a = client.bar(barId=1) @@ -166,13 +166,25 @@ def test_long_chaining(client): assert c.url == 'https://foo.com/v1/bar/1/20/100' -def test_long_chaining_children(client): +def test_long_chaining_callables_to_children(client): client.add_route('bar/${barId}/${bazId}/bin/${binId}/bao') route = client.bar(barId=10)(bazId=20).bin(binId=30).bao assert route.url == 'https://foo.com/v1/bar/10/20/bin/30/bao' +def test_chaining_descendant_children_of_callable(client): + """ + When a callable has a child with it's own children + Then the children inherit the values of the callable. + """ + client.add_route('johnathan/${cId}/joseph/holly/jotaro/jolyne') + + a = client.johnathan(cId=1).joseph.holly.jotaro.jolyne + + assert a.url == 'https://foo.com/v1/johnathan/1/joseph/holly/jotaro/jolyne' + + def test_dash_in_route(client): """ When a Route name has a dash in it diff --git a/tests/route/test_update_url.py b/tests/route/test_update_url.py new file mode 100644 index 0000000..2a62542 --- /dev/null +++ b/tests/route/test_update_url.py @@ -0,0 +1,24 @@ +from inori import Route + + +def test_update_url(client): + """ + Given a Route has children + When Route._update_url is called + Then the Route and it's children are updated + And the children of the children are updated + """ + route = Route(client, 'johnathan/${cId}/joseph/holly') + child_route = Route(client, 'johnathan/${cId}/joseph/holly/jotaro') + grandchild_route = Route( + client, 'johnathan/${cId}/joseph/holly/jotaro/jolyne', + ) + + route.children = {'jotaro': child_route} + child_route.children = {'jolyne': grandchild_route} + + route._update_url({'cId': '5'}) + + assert route.url == 'johnathan/5/joseph/holly' + assert child_route.url == 'johnathan/5/joseph/holly/jotaro' + assert grandchild_route.url == 'johnathan/5/joseph/holly/jotaro/jolyne'