Skip to content

Commit

Permalink
Add make_strawberry_decorator function
Browse files Browse the repository at this point in the history
  • Loading branch information
jkimbo authored and patrick91 committed Mar 12, 2021
1 parent 52e9dfd commit 333f18c
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 0 deletions.
33 changes: 33 additions & 0 deletions strawberry/decorator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import functools

from .resolvers import get_resolver_arguments
from .utils.inspect import get_func_args


def make_strawberry_decorator(func):
def decorator(resolver):
if hasattr(resolver, "_field_definition"):
raise Exception("Can't apply decorator after strawberry.field") # TODO

function_args = get_func_args(resolver)

@functools.wraps(resolver)
def wrapped_resolver(source, info, **kwargs):
def wrapped(**kwargs):
# If resolver is another strawberry decorator then pass all the
# arguments to it
if getattr(resolver, "_strawberry_decorator", False):
return resolver(source, info, **kwargs)

args, extra_kwargs = get_resolver_arguments(function_args, source, info)
return resolver(*args, **extra_kwargs, **kwargs)

# Call the decorator body with the original set of kwargs so that it
# has the opportunity to modify them
return func(wrapped, source, info=info, **kwargs)

wrapped_resolver._strawberry_decorator = True

return wrapped_resolver

return decorator
117 changes: 117 additions & 0 deletions tests/test_decorator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import strawberry
from strawberry.decorator import make_strawberry_decorator


def test_basic_decorator():
@make_strawberry_decorator
def upper_case(resolver, source, info, **kwargs):
result = resolver(**kwargs)
return result.upper()

@strawberry.type
class Query:
@strawberry.field
@upper_case
def greeting() -> str:
return "hi"

schema = strawberry.Schema(query=Query)
result = schema.execute_sync("query { greeting }")

assert not result.errors
assert result.data == {"greeting": "HI"}


def test_decorator_with_arguments():
def suffix(value):
@make_strawberry_decorator
def wrapper(resolver, source, info, **kwargs):
result = resolver(**kwargs)
return f"{result}{value}"

return wrapper

@strawberry.type
class Query:
@strawberry.field
@suffix(" 👋")
def greeting() -> str:
return "hi"

schema = strawberry.Schema(query=Query)
result = schema.execute_sync("query { greeting }")

assert not result.errors
assert result.data == {"greeting": "hi 👋"}


def test_multiple_decorators():
@make_strawberry_decorator
def upper_case(resolver, source, info, **kwargs):
result = resolver(**kwargs)
return result.upper()

def suffix(value):
@make_strawberry_decorator
def wrapper(resolver, source, info, **kwargs):
result = resolver(**kwargs)
return f"{result}{value}"

return wrapper

@strawberry.type
class Query:
@strawberry.field
@suffix(" 👋")
@upper_case
def greeting() -> str:
return "hi"

schema = strawberry.Schema(query=Query)
result = schema.execute_sync("query { greeting }")

assert not result.errors
assert result.data == {"greeting": "HI 👋"}


def test_decorator_with_graphql_arguments():
@make_strawberry_decorator
def upper_case(resolver, source, info, **kwargs):
result = resolver(**kwargs)
return result.upper()

@strawberry.type
class Query:
@strawberry.field
@upper_case
def greeting(name: str) -> str:
return f"hi {name}"

schema = strawberry.Schema(query=Query)
result = schema.execute_sync('query { greeting(name: "everyone") }')

assert not result.errors
assert result.data == {"greeting": "HI EVERYONE"}


def test_decorator_modify_argument():
def title_case_argument(argument_name):
@make_strawberry_decorator
def wrapped(resolver, source, info, **kwargs):
kwargs[argument_name] = kwargs[argument_name].title()
return resolver(**kwargs)

return wrapped

@strawberry.type
class Query:
@strawberry.field
@title_case_argument("name")
def greeting(name: str) -> str:
return f"hi {name}"

schema = strawberry.Schema(query=Query)
result = schema.execute_sync('query { greeting(name: "patrick") }')

assert not result.errors
assert result.data == {"greeting": "hi Patrick"}

0 comments on commit 333f18c

Please sign in to comment.