File: test_generics.py

package info (click to toggle)
strawberry-graphql 0.306.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 18,176 kB
  • sloc: javascript: 178,052; python: 65,643; sh: 33; makefile: 25
file content (145 lines) | stat: -rw-r--r-- 3,828 bytes parent folder | download
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