1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
from enum import Enum
from typing import Generic, Optional, TypeVar, Union
import pytest
import strawberry
from strawberry.annotation import StrawberryAnnotation
from strawberry.types.base import (
StrawberryList,
StrawberryObjectDefinition,
StrawberryOptional,
StrawberryTypeVar,
get_object_definition,
has_object_definition,
)
from strawberry.types.enum import StrawberryEnumDefinition
from strawberry.types.field import StrawberryField
from strawberry.types.union import StrawberryUnion
def test_basic_generic():
T = TypeVar("T")
annotation = StrawberryAnnotation(T)
resolved = annotation.resolve()
assert isinstance(resolved, StrawberryTypeVar)
assert resolved.is_graphql_generic
assert resolved.type_var is T
assert resolved == T
def test_generic_lists():
T = TypeVar("T")
annotation = StrawberryAnnotation(list[T])
resolved = annotation.resolve()
assert isinstance(resolved, StrawberryList)
assert isinstance(resolved.of_type, StrawberryTypeVar)
assert resolved.is_graphql_generic
assert resolved == list[T]
def test_generic_objects():
T = TypeVar("T")
@strawberry.type
class FooBar(Generic[T]):
thing: T
annotation = StrawberryAnnotation(FooBar)
resolved = annotation.resolve()
# TODO: Simplify with StrawberryObject
assert isinstance(resolved, type)
assert has_object_definition(resolved)
assert isinstance(resolved.__strawberry_definition__, StrawberryObjectDefinition)
assert resolved.__strawberry_definition__.is_graphql_generic
field: StrawberryField = resolved.__strawberry_definition__.fields[0]
assert isinstance(field.type, StrawberryTypeVar)
assert field.type == T
def test_generic_optionals():
T = TypeVar("T")
annotation = StrawberryAnnotation(Optional[T])
resolved = annotation.resolve()
assert isinstance(resolved, StrawberryOptional)
assert isinstance(resolved.of_type, StrawberryTypeVar)
assert resolved.is_graphql_generic
assert resolved == Optional[T]
def test_generic_unions():
S = TypeVar("S")
T = TypeVar("T")
annotation = StrawberryAnnotation(Union[S, T])
resolved = annotation.resolve()
assert isinstance(resolved, StrawberryUnion)
assert resolved.types == (S, T)
assert resolved.is_graphql_generic
assert resolved == Union[S, T]
def test_generic_with_enums():
T = TypeVar("T")
@strawberry.enum
class VehicleMake(Enum):
FORD = "ford"
TOYOTA = "toyota"
HONDA = "honda"
@strawberry.type
class GenericForEnum(Generic[T]):
generic_slot: T
annotation = StrawberryAnnotation(GenericForEnum[VehicleMake])
resolved = annotation.resolve()
# TODO: Simplify with StrawberryObject
assert isinstance(resolved, type)
assert has_object_definition(resolved)
assert isinstance(resolved.__strawberry_definition__, StrawberryObjectDefinition)
generic_slot_field: StrawberryField = resolved.__strawberry_definition__.fields[0]
assert isinstance(generic_slot_field.type, StrawberryEnumDefinition)
assert generic_slot_field.type is VehicleMake.__strawberry_definition__
def test_cant_create_concrete_of_non_strawberry_object():
T = TypeVar("T")
@strawberry.type
class Foo(Generic[T]):
generic_slot: T
with pytest.raises(ValueError):
StrawberryAnnotation(Foo).create_concrete_type(int)
def test_inline_resolver():
T = TypeVar("T")
@strawberry.type
class Edge(Generic[T]):
@strawberry.field
def node(self) -> T: # type: ignore # pragma: no cover
...
resolved = StrawberryAnnotation(Edge).resolve()
type_definition = get_object_definition(resolved, strict=True)
assert type_definition.is_graphql_generic
|