From e7c49ea667706a620896b54e4be9c3fe64b872aa Mon Sep 17 00:00:00 2001 From: Jonathan Ehwald Date: Sat, 14 Dec 2024 23:35:19 +0100 Subject: [PATCH 1/8] Fix passing types to union is deprecated --- tests/types/test_lazy_types.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/types/test_lazy_types.py b/tests/types/test_lazy_types.py index 429a2b7a2c..3dfc55bcc5 100644 --- a/tests/types/test_lazy_types.py +++ b/tests/types/test_lazy_types.py @@ -2,7 +2,7 @@ import enum import sys import textwrap -from typing import Generic, TypeVar +from typing import Generic, TypeVar, Union from typing_extensions import Annotated, TypeAlias import pytest @@ -173,7 +173,7 @@ def test_lazy_type_in_union(): ActiveType = LazyType("LaziestType", "test_lazy_types") ActiveEnum = LazyType("LazyEnum", "test_lazy_types") - something = union(name="CoolUnion", types=(ActiveType, ActiveEnum)) + something = Annotated[Union[ActiveType, ActiveEnum], union(name="CoolUnion")] annotation = StrawberryAnnotation(something) resolved = annotation.resolve() @@ -190,7 +190,7 @@ def test_lazy_function_in_union(): ActiveType = Annotated["LaziestType", strawberry.lazy("test_lazy_types")] ActiveEnum = Annotated["LazyEnum", strawberry.lazy("test_lazy_types")] - something = union(name="CoolUnion", types=(ActiveType, ActiveEnum)) + something = Annotated[Union[ActiveType, ActiveEnum], union(name="CoolUnion")] annotation = StrawberryAnnotation(something) resolved = annotation.resolve() From 4f0f165d5e6aad4bb50b21152a44f52b8b8d0ace Mon Sep 17 00:00:00 2001 From: Jonathan Ehwald Date: Sat, 14 Dec 2024 23:41:03 +0100 Subject: [PATCH 2/8] Fix `is_unset` deprecation warnings in tests --- tests/fields/test_arguments.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/fields/test_arguments.py b/tests/fields/test_arguments.py index f8c911806b..f0d8a4991d 100644 --- a/tests/fields/test_arguments.py +++ b/tests/fields/test_arguments.py @@ -1,5 +1,4 @@ import sys -import warnings from typing import List, Optional, Union from typing_extensions import Annotated @@ -488,11 +487,19 @@ def test_unset_deprecation_warning(): def test_deprecated_unset(): - with pytest.deprecated_call(): + warning = "`is_unset` is deprecated use `value is UNSET` instead" + + with pytest.deprecated_call(match=warning): from strawberry.types.unset import is_unset - with warnings.catch_warnings(record=False): + with pytest.deprecated_call(match=warning): assert is_unset(UNSET) + + with pytest.deprecated_call(match=warning): assert not is_unset(None) + + with pytest.deprecated_call(match=warning): assert not is_unset(False) + + with pytest.deprecated_call(match=warning): assert not is_unset("hello world") From 456d9b629f290a4fe358f9801fe75051d7ff62f1 Mon Sep 17 00:00:00 2001 From: Jonathan Ehwald Date: Sat, 14 Dec 2024 23:49:41 +0100 Subject: [PATCH 3/8] Fix `asserts_errors` deprecation warnings in tests --- tests/test/test_client.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/test/test_client.py b/tests/test/test_client.py index 0e03d12f77..1cac370d01 100644 --- a/tests/test/test_client.py +++ b/tests/test/test_client.py @@ -9,26 +9,28 @@ async def test_query_asserts_errors_option_is_deprecated( graphql_client, asserts_errors ): - with pytest.warns( - DeprecationWarning, - match="The `asserts_errors` argument has been renamed to `assert_no_errors`", + with pytest.deprecated_call( + match="The `asserts_errors` argument has been renamed to `assert_no_errors`" ): await await_maybe( graphql_client.query("{ hello }", asserts_errors=asserts_errors) ) -@pytest.mark.parametrize("option_name", ["asserts_errors", "assert_no_errors"]) @pytest.mark.parametrize( - ("assert_no_errors", "expectation"), + ("option_name", "expectation1"), + [("asserts_errors", pytest.deprecated_call()), ("assert_no_errors", nullcontext())], +) +@pytest.mark.parametrize( + ("assert_no_errors", "expectation2"), [(True, pytest.raises(AssertionError)), (False, nullcontext())], ) async def test_query_with_assert_no_errors_option( - graphql_client, option_name, assert_no_errors, expectation + graphql_client, option_name, assert_no_errors, expectation1, expectation2 ): query = "{ ThisIsNotAValidQuery }" - with expectation: + with expectation1, expectation2: await await_maybe( graphql_client.query(query, **{option_name: assert_no_errors}) ) From 615bb55656b0747da5f9e85d45f545f7f6d11ebc Mon Sep 17 00:00:00 2001 From: Jonathan Ehwald Date: Sun, 15 Dec 2024 00:07:25 +0100 Subject: [PATCH 4/8] Fix `info.field_nodes` deprecation warnings --- tests/federation/test_entities.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/federation/test_entities.py b/tests/federation/test_entities.py index 4793c0aeb0..ad79aeade8 100644 --- a/tests/federation/test_entities.py +++ b/tests/federation/test_entities.py @@ -375,7 +375,9 @@ def resolve_reference(cls, info: Info, id: strawberry.ID) -> "Product": exception = Exception("Foo bar") exception.extensions = {"baz": "qux"} raise located_error( - exception, nodes=info.field_nodes[0], path=["_entities_override", 0] + exception, + nodes=info._raw_info.field_nodes[0], + path=["_entities_override", 0], ) @strawberry.federation.type(extend=True) From 225539cd698aafdd29043c91dcc311f3b9ba9527 Mon Sep 17 00:00:00 2001 From: Jonathan Ehwald Date: Sun, 15 Dec 2024 00:14:17 +0100 Subject: [PATCH 5/8] Fix `graphiql` deprecation warnings in tests --- tests/fastapi/test_openapi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fastapi/test_openapi.py b/tests/fastapi/test_openapi.py index d30f88abe9..1552d7310c 100644 --- a/tests/fastapi/test_openapi.py +++ b/tests/fastapi/test_openapi.py @@ -26,7 +26,7 @@ def test_disable_graphiql_view_and_allow_queries_via_get(): app = FastAPI() schema = strawberry.Schema(query=Query) graphql_app = GraphQLRouter[None, None]( - schema, graphiql=False, allow_queries_via_get=False + schema, graphql_ide=None, allow_queries_via_get=False ) app.include_router(graphql_app, prefix="/graphql") From 240583515c0c913aa6ae4f67c7e3e1bf17bd4a35 Mon Sep 17 00:00:00 2001 From: Jonathan Ehwald Date: Sun, 15 Dec 2024 00:19:35 +0100 Subject: [PATCH 6/8] Fix `listen_to_channel` deprecation warnings --- tests/channels/test_layers.py | 5 +++-- tests/views/schema.py | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/channels/test_layers.py b/tests/channels/test_layers.py index a9c325f8e8..ffc7108703 100644 --- a/tests/channels/test_layers.py +++ b/tests/channels/test_layers.py @@ -50,8 +50,9 @@ async def test_no_layers(): "Check https://channels.readthedocs.io/en/stable/topics/channel_layers.html " "for more information" ) - with pytest.raises(RuntimeError, match=msg): - await consumer.channel_listen("foobar").__anext__() + with pytest.deprecated_call(match="Use listen_to_channel instead"): + with pytest.raises(RuntimeError, match=msg): + await consumer.channel_listen("foobar").__anext__() with pytest.raises(RuntimeError, match=msg): async with consumer.listen_to_channel("foobar"): diff --git a/tests/views/schema.py b/tests/views/schema.py index cb5d9959ef..311fccbb5f 100644 --- a/tests/views/schema.py +++ b/tests/views/schema.py @@ -221,12 +221,13 @@ async def listener( ) -> AsyncGenerator[str, None]: yield info.context["request"].channel_name - async for message in info.context["request"].channel_listen( + async with info.context["request"].listen_to_channel( type="test.message", timeout=timeout, groups=[group] if group is not None else [], - ): - yield message["text"] + ) as cm: + async for message in cm: + yield message["text"] @strawberry.subscription async def listener_with_confirmation( From 7142730603dcd16b79268765263d03db5e04453f Mon Sep 17 00:00:00 2001 From: Jonathan Ehwald Date: Sun, 15 Dec 2024 02:58:32 +0100 Subject: [PATCH 7/8] Fix name-based matching of `value` deprecations --- tests/litestar/schema.py | 10 ++++++--- tests/schema/test_arguments.py | 2 +- tests/schema/test_directives.py | 32 ++++++++++++++++++----------- tests/schema/test_extensions.py | 3 ++- tests/schema/test_get_extensions.py | 4 ++-- tests/schema/test_info.py | 10 ++++++--- tests/schema/test_permission.py | 4 +--- tests/schema/test_resolvers.py | 24 ++++++++++++++-------- tests/tools/test_create_type.py | 6 +++--- 9 files changed, 58 insertions(+), 37 deletions(-) diff --git a/tests/litestar/schema.py b/tests/litestar/schema.py index 5f00b1a2ee..71b69ad464 100644 --- a/tests/litestar/schema.py +++ b/tests/litestar/schema.py @@ -99,7 +99,9 @@ async def echo( yield message @strawberry.subscription - async def request_ping(self, info) -> typing.AsyncGenerator[bool, None]: + async def request_ping( + self, info: strawberry.Info + ) -> typing.AsyncGenerator[bool, None]: ws = info.context["ws"] await ws.send_json(PingMessage().as_dict()) yield True @@ -111,7 +113,7 @@ async def infinity(self, message: str) -> typing.AsyncGenerator[str, None]: await asyncio.sleep(1) @strawberry.subscription - async def context(self, info) -> typing.AsyncGenerator[str, None]: + async def context(self, info: strawberry.Info) -> typing.AsyncGenerator[str, None]: yield info.context["custom_value"] @strawberry.subscription @@ -132,7 +134,9 @@ async def flavors(self) -> typing.AsyncGenerator[Flavor, None]: yield Flavor.CHOCOLATE @strawberry.subscription - async def debug(self, info) -> typing.AsyncGenerator[DebugInfo, None]: + async def debug( + self, info: strawberry.Info + ) -> typing.AsyncGenerator[DebugInfo, None]: active_result_handlers = [ task for task in info.context["get_tasks"]() if not task.done() ] diff --git a/tests/schema/test_arguments.py b/tests/schema/test_arguments.py index 7c1f2e32f9..6020fd5a68 100644 --- a/tests/schema/test_arguments.py +++ b/tests/schema/test_arguments.py @@ -177,7 +177,7 @@ class Query: @strawberry.field def hello( self, - info, + info: strawberry.Info, input: Annotated[str, strawberry.argument(metadata={"test": "foo"})], ) -> str: nonlocal field_definition diff --git a/tests/schema/test_directives.py b/tests/schema/test_directives.py index 3b31e97258..82108c600e 100644 --- a/tests/schema/test_directives.py +++ b/tests/schema/test_directives.py @@ -40,6 +40,7 @@ def person(self) -> Person: ) assert not result.errors + assert result.data assert result.data["person"] == {"name": "Jess"} query = """query ($skipPoints: Boolean!){ @@ -53,6 +54,7 @@ def person(self) -> Person: result = schema.execute_sync(query, variable_values={"skipPoints": False}) assert not result.errors + assert result.data assert result.data["person"] == {"name": "Jess", "points": 2000} @@ -80,6 +82,7 @@ def person(self) -> Person: result = await schema.execute(query, variable_values={"includePoints": False}) assert not result.errors + assert result.data assert result.data["person"] == {"name": "Jess"} query = """query ($skipPoints: Boolean!){ @@ -93,6 +96,7 @@ def person(self) -> Person: result = await schema.execute(query, variable_values={"skipPoints": False}) assert not result.errors + assert result.data assert result.data["person"] == {"name": "Jess", "points": 2000} @@ -104,7 +108,7 @@ class Query: @strawberry.directive( locations=[DirectiveLocation.FIELD], description="Make string uppercase" ) - def uppercase(value: str, example: str): + def uppercase(value: DirectiveValue[str], example: str): return value.upper() schema = strawberry.Schema(query=Query, directives=[uppercase]) @@ -171,11 +175,11 @@ def person(self) -> Person: @strawberry.directive( locations=[DirectiveLocation.FIELD], description="Make string uppercase" ) - def turn_uppercase(value: str): + def turn_uppercase(value: DirectiveValue[str]): return value.upper() @strawberry.directive(locations=[DirectiveLocation.FIELD]) - def replace(value: str, old: str, new: str): + def replace(value: DirectiveValue[str], old: str, new: str): return value.replace(old, new) schema = strawberry.Schema(query=Query, directives=[turn_uppercase, replace]) @@ -214,11 +218,11 @@ def person(self) -> Person: @strawberry.directive( locations=[DirectiveLocation.FIELD], description="Make string uppercase" ) - def turn_uppercase(value: str): + def turn_uppercase(value: DirectiveValue[str]): return value.upper() @strawberry.directive(locations=[DirectiveLocation.FIELD]) - def replace(value: str, old: str, new: str): + def replace(value: DirectiveValue[str], old: str, new: str): return value.replace(old, new) schema = strawberry.Schema( @@ -242,6 +246,7 @@ def replace(value: str, old: str, new: str): result = schema.execute_sync(query, variable_values={"identified": False}) assert not result.errors + assert result.data assert result.data["person"]["name"] == "JESS" assert result.data["jess"]["name"] == "Jessica" assert result.data["johnDoe"].get("name") is None @@ -262,7 +267,7 @@ def person(self) -> Person: @strawberry.directive( locations=[DirectiveLocation.FIELD], description="Make string uppercase" ) - async def uppercase(value: str): + async def uppercase(value: DirectiveValue[str]): return value.upper() schema = strawberry.Schema(query=Query, directives=[uppercase]) @@ -293,7 +298,7 @@ def person(self) -> Person: return Person() @strawberry.directive(locations=[DirectiveLocation.FIELD]) - def replace(value: str, old_list: List[str], new: str): + def replace(value: DirectiveValue[str], old_list: List[str], new: str): for old in old_list: value = value.replace(old, new) @@ -310,6 +315,7 @@ def replace(value: str, old_list: List[str], new: str): result = schema.execute_sync(query, variable_values={"identified": False}) assert not result.errors + assert result.data assert result.data["person"]["name"] == "JESS" @@ -327,7 +333,7 @@ def person(self) -> Person: @strawberry.directive( locations=[DirectiveLocation.FIELD], description="Make string uppercase" ) - def uppercase(value: str): + def uppercase(value: DirectiveValue[str]): return value.upper() class ExampleExtension(SchemaExtension): @@ -366,7 +372,7 @@ async def person(self) -> Person: @strawberry.directive( locations=[DirectiveLocation.FIELD], description="Make string uppercase" ) - def uppercase(value: str): + def uppercase(value: DirectiveValue[str]): return value.upper() class ExampleExtension(SchemaExtension): @@ -416,7 +422,7 @@ def greetingTemplate(self, locale: Locale = Locale.EN) -> str: locations=[DirectiveLocation.FIELD], description="Interpolate string on the server from context data", ) - def interpolate(value: str, info: strawberry.Info): + def interpolate(value: DirectiveValue[str], info: strawberry.Info): try: assert isinstance(info, strawberry.Info) assert info._field is field @@ -592,6 +598,7 @@ def append_names(value: DirectiveValue[str], names: List[str]): ) assert result.errors is None + assert result.data assert result.data["greeting"] == "Hi foo, bar" @@ -607,7 +614,7 @@ class Query: @strawberry.directive( locations=[DirectiveLocation.FIELD], description="Make string uppercase" ) - def uppercase(value: str, input: DirectiveInput): + def uppercase(value: DirectiveValue[str], input: DirectiveInput): return value.upper() schema = strawberry.Schema(query=Query, directives=[uppercase]) @@ -638,7 +645,7 @@ class Query: @strawberry.directive( locations=[DirectiveLocation.FIELD], description="Make string uppercase" ) - def uppercase(value: str, input: DirectiveInput): + def uppercase(value: DirectiveValue[str], input: DirectiveInput): return value.upper() schema = strawberry.Schema(query=Query, directives=[uppercase]) @@ -687,4 +694,5 @@ def append_names(value: DirectiveValue[str], names: List[str], info: CustomInfo) ) assert result.errors is None + assert result.data assert result.data["greeting"] == "Hi foo, bar" diff --git a/tests/schema/test_extensions.py b/tests/schema/test_extensions.py index 131864142c..6f54719669 100644 --- a/tests/schema/test_extensions.py +++ b/tests/schema/test_extensions.py @@ -11,6 +11,7 @@ ) import strawberry +from strawberry.directive import DirectiveValue from strawberry.scalars import JSON from strawberry.schema.schema_converter import GraphQLCoreConverter from strawberry.schema_directive import Location @@ -52,7 +53,7 @@ class Query: def test_directive(): @strawberry.directive(locations=[DirectiveLocation.FIELD]) - def uppercase(value: str, foo: str): + def uppercase(value: DirectiveValue[str], foo: str): return value.upper() @strawberry.type() diff --git a/tests/schema/test_get_extensions.py b/tests/schema/test_get_extensions.py index aeabab3ec7..5a91f79001 100644 --- a/tests/schema/test_get_extensions.py +++ b/tests/schema/test_get_extensions.py @@ -1,5 +1,5 @@ import strawberry -from strawberry.directive import DirectiveLocation +from strawberry.directive import DirectiveLocation, DirectiveValue from strawberry.extensions import SchemaExtension from strawberry.extensions.directives import ( DirectivesExtension, @@ -13,7 +13,7 @@ class Query: @strawberry.directive(locations=[DirectiveLocation.FIELD]) -def uppercase(value: str) -> str: +def uppercase(value: DirectiveValue[str]) -> str: return value.upper() diff --git a/tests/schema/test_info.py b/tests/schema/test_info.py index 3869d0d61d..70fddea56d 100644 --- a/tests/schema/test_info.py +++ b/tests/schema/test_info.py @@ -65,6 +65,7 @@ def hello_world(self, info: strawberry.Info[str, str]) -> Result: result = schema.execute_sync(query, context_value=my_context, root_value=root_value) assert not result.errors + assert result.data info = result.data["helloWorld"] assert info.pop("operation").startswith("OperationDefinitionNode at") field = json.loads(info.pop("selectedField")) @@ -315,11 +316,12 @@ def field(self, info: strawberry.Info) -> return_type: result = schema.execute_sync("{ field }") assert not result.errors + assert result.data assert result.data["field"] == return_value def test_return_type_from_field(): - def resolver(info): + def resolver(info: strawberry.Info): assert info.return_type is int return 0 @@ -332,11 +334,12 @@ class Query: result = schema.execute_sync("{ field }") assert not result.errors + assert result.data assert result.data["field"] == 0 def test_field_nodes_deprecation(): - def resolver(info): + def resolver(info: strawberry.Info): info.field_nodes return 0 @@ -350,6 +353,7 @@ class Query: result = schema.execute_sync("{ field }") assert not result.errors + assert result.data assert result.data["field"] == 0 @@ -367,7 +371,7 @@ class Query: @strawberry.field def field( self, - info, + info: strawberry.Info, arg_1: Annotated[str, strawberry.argument(description="Some description")], arg_2: Optional[TestInput] = None, ) -> str: diff --git a/tests/schema/test_permission.py b/tests/schema/test_permission.py index 23e54230d0..f041dac6b6 100644 --- a/tests/schema/test_permission.py +++ b/tests/schema/test_permission.py @@ -71,9 +71,7 @@ class Query: @strawberry.type class Subscription: @strawberry.subscription(permission_classes=[IsAdmin]) - async def user( - self, info - ) -> typing.AsyncGenerator[str, None]: # pragma: no cover + async def user(self) -> typing.AsyncGenerator[str, None]: # pragma: no cover yield "Hello" schema = strawberry.Schema(query=Query, subscription=Subscription) diff --git a/tests/schema/test_resolvers.py b/tests/schema/test_resolvers.py index 574955a954..8a81626320 100644 --- a/tests/schema/test_resolvers.py +++ b/tests/schema/test_resolvers.py @@ -1,5 +1,6 @@ # type: ignore import typing +from contextlib import nullcontext from typing import Any, Generic, List, NamedTuple, Optional, Type, TypeVar, Union import pytest @@ -512,18 +513,23 @@ def arbitrarily_named_info(icon: str, info_argument: Info) -> str: @pytest.mark.parametrize( - "resolver", + ("resolver", "deprecation"), ( - pytest.param(name_based_info), - pytest.param(type_based_info), - pytest.param(generic_type_based_info), - pytest.param(arbitrarily_named_info), + pytest.param( + name_based_info, + pytest.deprecated_call(match="Argument name-based matching of"), + ), + pytest.param(type_based_info, nullcontext()), + pytest.param(generic_type_based_info, nullcontext()), + pytest.param(arbitrarily_named_info, nullcontext()), ), ) -def test_info_argument(resolver): - @strawberry.type - class ResolverGreeting: - hello: str = strawberry.field(resolver=resolver) +def test_info_argument(resolver, deprecation): + with deprecation: + + @strawberry.type + class ResolverGreeting: + hello: str = strawberry.field(resolver=resolver) schema = strawberry.Schema(query=ResolverGreeting) result = schema.execute_sync('{ hello(icon: "🍓") }') diff --git a/tests/tools/test_create_type.py b/tests/tools/test_create_type.py index f483df8e49..4d49d1b0d3 100644 --- a/tests/tools/test_create_type.py +++ b/tests/tools/test_create_type.py @@ -137,7 +137,7 @@ class User: username: str @strawberry.mutation - def make_user(info, username: str) -> User: + def make_user(username: str) -> User: return User(username=username) Mutation = create_type("Mutation", [make_user]) @@ -156,7 +156,7 @@ class User: username: str @strawberry.mutation(name="makeNewUser", description="Make a new user") - def make_user(info, username: str) -> User: + def make_user(username: str) -> User: return User(username=username) Mutation = create_type("Mutation", [make_user]) @@ -176,7 +176,7 @@ class User: id: strawberry.ID @strawberry.field - def get_user_by_id(info, id: strawberry.ID) -> User: + def get_user_by_id(id: strawberry.ID) -> User: return User(id=id) Query = create_type("Query", [get_user_by_id]) From 4be9c5b601e1cb4dcafe4134ce3ddb9fa15c4839 Mon Sep 17 00:00:00 2001 From: Jonathan Ehwald Date: Sun, 15 Dec 2024 03:29:06 +0100 Subject: [PATCH 8/8] Test directives still work as expected --- tests/schema/test_directives.py | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/tests/schema/test_directives.py b/tests/schema/test_directives.py index 82108c600e..adfcd29f6b 100644 --- a/tests/schema/test_directives.py +++ b/tests/schema/test_directives.py @@ -103,7 +103,9 @@ def person(self) -> Person: def test_can_declare_directives(): @strawberry.type class Query: - cake: str = "made_in_switzerland" + @strawberry.field + def cake(self) -> str: + return "made_in_switzerland" @strawberry.directive( locations=[DirectiveLocation.FIELD], description="Make string uppercase" @@ -124,6 +126,10 @@ def uppercase(value: DirectiveValue[str], example: str): assert schema.as_str() == textwrap.dedent(expected_schema).strip() + result = schema.execute_sync('query { cake @uppercase(example: "foo") }') + assert result.errors is None + assert result.data == {"cake": "MADE_IN_SWITZERLAND"} + def test_directive_arguments_without_value_param(): """Regression test for Strawberry Issue #1666. @@ -199,6 +205,7 @@ def replace(value: DirectiveValue[str], old: str, new: str): result = schema.execute_sync(query, variable_values={"identified": False}) assert not result.errors + assert result.data assert result.data["person"]["name"] == "JESS" assert result.data["jess"]["name"] == "Jessica" assert result.data["johnDoe"].get("name") is None @@ -609,7 +616,9 @@ class DirectiveInput: @strawberry.type class Query: - cake: str = "made_in_switzerland" + @strawberry.field + def cake(self) -> str: + return "made_in_switzerland" @strawberry.directive( locations=[DirectiveLocation.FIELD], description="Make string uppercase" @@ -634,13 +643,19 @@ def uppercase(value: DirectiveValue[str], input: DirectiveInput): assert schema.as_str() == textwrap.dedent(expected_schema).strip() + result = schema.execute_sync('query { cake @uppercase(input: { example: "foo" }) }') + assert result.errors is None + assert result.data == {"cake": "MADE_IN_SWITZERLAND"} + def test_directives_with_scalar(): DirectiveInput = strawberry.scalar(str, name="DirectiveInput") @strawberry.type class Query: - cake: str = "made_in_switzerland" + @strawberry.field + def cake(self) -> str: + return "made_in_switzerland" @strawberry.directive( locations=[DirectiveLocation.FIELD], description="Make string uppercase" @@ -663,6 +678,10 @@ def uppercase(value: DirectiveValue[str], input: DirectiveInput): assert schema.as_str() == textwrap.dedent(expected_schema).strip() + result = schema.execute_sync('query { cake @uppercase(input: "foo") }') + assert result.errors is None + assert result.data == {"cake": "MADE_IN_SWITZERLAND"} + @pytest.mark.asyncio async def test_directive_with_custom_info_class() -> NoReturn: