From 390c9486498666d1a594da4f190818974a2f9474 Mon Sep 17 00:00:00 2001 From: Andrew Smith Date: Fri, 12 Jan 2024 19:50:16 +0000 Subject: [PATCH 1/2] chore: add alias for range methods --- Makefile | 7 ++++++- postgrest/base_request_builder.py | 18 ++++++++++++++++++ pyproject.toml | 3 +++ tests/_sync/test_client.py | 4 ---- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index fb237339..0de05cb3 100644 --- a/Makefile +++ b/Makefile @@ -24,5 +24,10 @@ clean_infra: run_tests: tests -build_sync: +run_unasync: poetry run unasync postgrest tests + +build_sync: run_unasync remove_pytest_asyncio_from_sync + +remove_pytest_asyncio_from_sync: + sed -i 's/@pytest.mark.asyncio//g' tests/_sync/test_client.py diff --git a/postgrest/base_request_builder.py b/postgrest/base_request_builder.py index 95af0413..303fe2be 100644 --- a/postgrest/base_request_builder.py +++ b/postgrest/base_request_builder.py @@ -399,6 +399,24 @@ def nxr(self: Self, column: str, range: Tuple[int, int]) -> Self: def adj(self: Self, column: str, range: Tuple[int, int]) -> Self: return self.filter(column, Filters.ADJ, f"({range[0]},{range[1]})") + def range_gt(self: Self, column: str, range: Tuple[int, int]) -> Self: + return self.sr(column, range) + + def range_gte(self: Self, column: str, range: Tuple[int, int]) -> Self: + return self.nxl(column, range) + + def range_lt(self: Self, column: str, range: Tuple[int, int]) -> Self: + return self.sl(column, range) + + def range_lte(self: Self, column: str, range: Tuple[int, int]) -> Self: + return self.nxr(column, range) + + def range_adjacent(self: Self, column: str, range: Tuple[int, int]) -> Self: + return self.adj(column, range) + + def overlaps(self: Self, column: str, values: Iterable[Any]) -> Self: + return self.ov(column, values) + def match(self: Self, query: Dict[str, Any]) -> Self: updated_query = self diff --git a/pyproject.toml b/pyproject.toml index e47754b9..6a8981c4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,6 +53,9 @@ upload_to_vcs_release = true branch = "master" changelog_components = "semantic_release.changelog.changelog_headers,semantic_release.changelog.compare_url" +[tool.pytest.ini_options] +asyncio_mode = "auto" + [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" diff --git a/tests/_sync/test_client.py b/tests/_sync/test_client.py index eae83e6c..511260f2 100644 --- a/tests/_sync/test_client.py +++ b/tests/_sync/test_client.py @@ -28,7 +28,6 @@ def test_simple(self, postgrest_client: SyncPostgrestClient): ) assert session.headers.items() >= headers.items() - @pytest.mark.asyncio def test_custom_headers(self): with SyncPostgrestClient( "https://example.com", schema="pub", headers={"Custom-Header": "value"} @@ -72,7 +71,6 @@ def test_schema(postgrest_client: SyncPostgrestClient): assert subheaders.items() < dict(session.headers).items() -@pytest.mark.asyncio def test_params_purged_after_execute(postgrest_client: SyncPostgrestClient): assert len(postgrest_client.session.params) == 0 with pytest.raises(APIError): @@ -80,7 +78,6 @@ def test_params_purged_after_execute(postgrest_client: SyncPostgrestClient): assert len(postgrest_client.session.params) == 0 -@pytest.mark.asyncio def test_response_status_code_outside_ok(postgrest_client: SyncPostgrestClient): with pytest.raises(APIError) as exc_info: postgrest_client.from_("test").select("a", "b").eq( @@ -96,7 +93,6 @@ def test_response_status_code_outside_ok(postgrest_client: SyncPostgrestClient): assert exc_response["errors"][0].get("code") == 400 -@pytest.mark.asyncio def test_response_maybe_single(postgrest_client: SyncPostgrestClient): with patch( "postgrest._async.request_builder.AsyncSingleRequestBuilder.execute", From 62a47cc3aa52681590ec7484167416c8f4800a8e Mon Sep 17 00:00:00 2001 From: Andrew Smith Date: Fri, 12 Jan 2024 19:55:27 +0000 Subject: [PATCH 2/2] chore: add tests for range methods --- tests/_async/test_filter_request_builder.py | 100 ++++++++++++++++++++ tests/_sync/test_filter_request_builder.py | 100 ++++++++++++++++++++ 2 files changed, 200 insertions(+) diff --git a/tests/_async/test_filter_request_builder.py b/tests/_async/test_filter_request_builder.py index 35b20bf0..3e1b9abf 100644 --- a/tests/_async/test_filter_request_builder.py +++ b/tests/_async/test_filter_request_builder.py @@ -68,6 +68,24 @@ def test_equals(filter_request_builder): assert str(builder.params) == "x=eq.a" +def test_not_equal(filter_request_builder): + builder = filter_request_builder.neq("x", "a") + + assert str(builder.params) == "x=neq.a" + + +def test_greater_than(filter_request_builder): + builder = filter_request_builder.gt("x", "a") + + assert str(builder.params) == "x=gt.a" + + +def test_greater_than_or_equals_to(filter_request_builder): + builder = filter_request_builder.gte("x", "a") + + assert str(builder.params) == "x=gte.a" + + def test_contains(filter_request_builder): builder = filter_request_builder.contains("x", "a") @@ -100,3 +118,85 @@ def test_contained_by_mixed_items(filter_request_builder): # {a,["b",%20"c"]} assert str(builder.params) == "x=cd.%7Ba%2C%5B%22b%22%2C%20%22c%22%5D%7D" + + +def test_range_greater_than(filter_request_builder): + builder = filter_request_builder.range_gt( + "x", ["2000-01-02 08:30", "2000-01-02 09:30"] + ) + + # {a,["b",%20"c"]} + assert str(builder.params) == "x=sr.%282000-01-02%2008%3A30%2C2000-01-02%2009%3A30%29" + + +def test_range_greater_than_or_equal_to(filter_request_builder): + builder = filter_request_builder.range_gte( + "x", ["2000-01-02 08:30", "2000-01-02 09:30"] + ) + + # {a,["b",%20"c"]} + assert ( + str(builder.params) == "x=nxl.%282000-01-02%2008%3A30%2C2000-01-02%2009%3A30%29" + ) + + +def test_range_less_than(filter_request_builder): + builder = filter_request_builder.range_lt( + "x", ["2000-01-02 08:30", "2000-01-02 09:30"] + ) + + # {a,["b",%20"c"]} + assert str(builder.params) == "x=sl.%282000-01-02%2008%3A30%2C2000-01-02%2009%3A30%29" + + +def test_range_less_than_or_equal_to(filter_request_builder): + builder = filter_request_builder.range_lte( + "x", ["2000-01-02 08:30", "2000-01-02 09:30"] + ) + + # {a,["b",%20"c"]} + assert ( + str(builder.params) == "x=nxr.%282000-01-02%2008%3A30%2C2000-01-02%2009%3A30%29" + ) + + +def test_range_adjacent(filter_request_builder): + builder = filter_request_builder.range_adjacent( + "x", ["2000-01-02 08:30", "2000-01-02 09:30"] + ) + + # {a,["b",%20"c"]} + assert ( + str(builder.params) == "x=adj.%282000-01-02%2008%3A30%2C2000-01-02%2009%3A30%29" + ) + + +def test_overlaps(filter_request_builder): + builder = filter_request_builder.overlaps("x", ["is:closed", "severity:high"]) + + # {a,["b",%20"c"]} + assert str(builder.params) == "x=ov.%7Bis%3Aclosed%2Cseverity%3Ahigh%7D" + + +def test_like(filter_request_builder): + builder = filter_request_builder.like("x", "%a%") + + assert str(builder.params) == "x=like.%25a%25" + + +def test_ilike(filter_request_builder): + builder = filter_request_builder.ilike("x", "%a%") + + assert str(builder.params) == "x=ilike.%25a%25" + + +def test_is_(filter_request_builder): + builder = filter_request_builder.is_("x", "a") + + assert str(builder.params) == "x=is.a" + + +def test_in_(filter_request_builder): + builder = filter_request_builder.in_("x", ["a", "b"]) + + assert str(builder.params) == "x=in.%28a%2Cb%29" diff --git a/tests/_sync/test_filter_request_builder.py b/tests/_sync/test_filter_request_builder.py index 90ec14c4..a5454b97 100644 --- a/tests/_sync/test_filter_request_builder.py +++ b/tests/_sync/test_filter_request_builder.py @@ -68,6 +68,24 @@ def test_equals(filter_request_builder): assert str(builder.params) == "x=eq.a" +def test_not_equal(filter_request_builder): + builder = filter_request_builder.neq("x", "a") + + assert str(builder.params) == "x=neq.a" + + +def test_greater_than(filter_request_builder): + builder = filter_request_builder.gt("x", "a") + + assert str(builder.params) == "x=gt.a" + + +def test_greater_than_or_equals_to(filter_request_builder): + builder = filter_request_builder.gte("x", "a") + + assert str(builder.params) == "x=gte.a" + + def test_contains(filter_request_builder): builder = filter_request_builder.contains("x", "a") @@ -100,3 +118,85 @@ def test_contained_by_mixed_items(filter_request_builder): # {a,["b",%20"c"]} assert str(builder.params) == "x=cd.%7Ba%2C%5B%22b%22%2C%20%22c%22%5D%7D" + + +def test_range_greater_than(filter_request_builder): + builder = filter_request_builder.range_gt( + "x", ["2000-01-02 08:30", "2000-01-02 09:30"] + ) + + # {a,["b",%20"c"]} + assert str(builder.params) == "x=sr.%282000-01-02%2008%3A30%2C2000-01-02%2009%3A30%29" + + +def test_range_greater_than_or_equal_to(filter_request_builder): + builder = filter_request_builder.range_gte( + "x", ["2000-01-02 08:30", "2000-01-02 09:30"] + ) + + # {a,["b",%20"c"]} + assert ( + str(builder.params) == "x=nxl.%282000-01-02%2008%3A30%2C2000-01-02%2009%3A30%29" + ) + + +def test_range_less_than(filter_request_builder): + builder = filter_request_builder.range_lt( + "x", ["2000-01-02 08:30", "2000-01-02 09:30"] + ) + + # {a,["b",%20"c"]} + assert str(builder.params) == "x=sl.%282000-01-02%2008%3A30%2C2000-01-02%2009%3A30%29" + + +def test_range_less_than_or_equal_to(filter_request_builder): + builder = filter_request_builder.range_lte( + "x", ["2000-01-02 08:30", "2000-01-02 09:30"] + ) + + # {a,["b",%20"c"]} + assert ( + str(builder.params) == "x=nxr.%282000-01-02%2008%3A30%2C2000-01-02%2009%3A30%29" + ) + + +def test_range_adjacent(filter_request_builder): + builder = filter_request_builder.range_adjacent( + "x", ["2000-01-02 08:30", "2000-01-02 09:30"] + ) + + # {a,["b",%20"c"]} + assert ( + str(builder.params) == "x=adj.%282000-01-02%2008%3A30%2C2000-01-02%2009%3A30%29" + ) + + +def test_overlaps(filter_request_builder): + builder = filter_request_builder.overlaps("x", ["is:closed", "severity:high"]) + + # {a,["b",%20"c"]} + assert str(builder.params) == "x=ov.%7Bis%3Aclosed%2Cseverity%3Ahigh%7D" + + +def test_like(filter_request_builder): + builder = filter_request_builder.like("x", "%a%") + + assert str(builder.params) == "x=like.%25a%25" + + +def test_ilike(filter_request_builder): + builder = filter_request_builder.ilike("x", "%a%") + + assert str(builder.params) == "x=ilike.%25a%25" + + +def test_is_(filter_request_builder): + builder = filter_request_builder.is_("x", "a") + + assert str(builder.params) == "x=is.a" + + +def test_in_(filter_request_builder): + builder = filter_request_builder.in_("x", ["a", "b"]) + + assert str(builder.params) == "x=in.%28a%2Cb%29"