def test_uses_default_for_optional_types_when_nothing_is_passed(): @strawberry.input class Number: value: int @strawberry.input class Input: numbers: Optional[Number] = UNSET numbers_second: Optional[Number] = UNSET # case 1 args = {"input": {}} arguments = [ StrawberryArgument( graphql_name=None, python_name="input", type_annotation=StrawberryAnnotation(Input), ), ] assert convert_arguments(args, arguments) == {"input": Input(UNSET, UNSET)} # case 2 args = {"input": {"numbersSecond": None}} arguments = [ StrawberryArgument( graphql_name=None, python_name="input", type_annotation=StrawberryAnnotation(Input), ), ] assert convert_arguments(args, arguments) == {"input": Input(UNSET, None)}
def test_list(): args = { "integerList": [1, 2], "stringList": ["abc", "cde"], } arguments = [ StrawberryArgument( graphql_name="integerList", python_name="integer_list", type_annotation=StrawberryAnnotation(List[int]), ), StrawberryArgument( graphql_name="stringList", python_name="string_list", type_annotation=StrawberryAnnotation(List[str]), ), ] assert convert_arguments( args, arguments, scalar_registry=DEFAULT_SCALAR_REGISTRY ) == { "integer_list": [1, 2], "string_list": ["abc", "cde"], }
def test_simple_types(): args = {"integer": 1, "string": "abc", "float": 1.2, "bool": True} arguments = [ StrawberryArgument( graphql_name="integer", type_annotation=StrawberryAnnotation(int), python_name="integer", ), StrawberryArgument( graphql_name="string", type_annotation=StrawberryAnnotation(str), python_name="string", ), StrawberryArgument( graphql_name="float", type_annotation=StrawberryAnnotation(float), python_name="float", ), StrawberryArgument( graphql_name="bool", type_annotation=StrawberryAnnotation(bool), python_name="bool", ), ] assert convert_arguments( args, arguments, scalar_registry=DEFAULT_SCALAR_REGISTRY ) == { "integer": 1, "string": "abc", "float": 1.2, "bool": True, }
def test_none(): annotation = StrawberryAnnotation(None) with pytest.raises(ValueError, match="Annotation cannot be plain None type"): annotation.resolve() annotation = StrawberryAnnotation(Optional[int]) annotation.resolve() annotation = StrawberryAnnotation(Union[None, int]) annotation.resolve()
def test_type_var(): T = TypeVar("T") annotation = StrawberryAnnotation(T) field = StrawberryField(type_annotation=annotation) assert field.type == T
def test_input_types(): @strawberry.input class MyInput: abc: str say_hello_to: str fun: str was: int = strawberry.field(name="having") args = { "input": { "abc": "example", "sayHelloTo": "Patrick", "having": 10, "fun": "yes" } } arguments = [ StrawberryArgument( graphql_name=None, python_name="input", type_annotation=StrawberryAnnotation(MyInput), ), ] assert (convert_arguments( args, arguments, scalar_registry=DEFAULT_SCALAR_REGISTRY, config=StrawberryConfig(), ) == { "input": MyInput(abc="example", say_hello_to="Patrick", was=10, fun="yes") })
def arguments(self) -> List[StrawberryArgument]: parameters = inspect.signature(self._unbound_wrapped_func).parameters function_arguments = set(parameters) - self._SPECIAL_ARGS arguments = self.annotations.copy() arguments.pop("return", None) # Discard return annotation to get just arguments arguments_missing_annotations = function_arguments - set(arguments) if any(arguments_missing_annotations): raise MissingArgumentsAnnotationsError( field_name=self.name, arguments=arguments_missing_annotations, ) module = sys.modules[self._module] annotation_namespace = module.__dict__ strawberry_arguments = [] for arg_name, annotation in arguments.items(): parameter = parameters[arg_name] argument = StrawberryArgument( python_name=arg_name, graphql_name=None, type_annotation=StrawberryAnnotation( annotation=annotation, namespace=annotation_namespace ), default=parameter.default, ) strawberry_arguments.append(argument) return strawberry_arguments
def test_nested_list_of_complex_types(): @strawberry.input class Number: value: int @strawberry.input class Input: numbers: List[Number] args = {"input": {"numbers": [{"value": 1}, {"value": 2}]}} arguments = [ StrawberryArgument( graphql_name=None, python_name="input", type_annotation=StrawberryAnnotation(Input), ), ] assert (convert_arguments( args, arguments, scalar_registry=DEFAULT_SCALAR_REGISTRY, config=StrawberryConfig(), ) == { "input": Input(numbers=[Number(1), Number(2)]) })
def test_lazy(): LazierType = LazyType["LaziestType", __name__] args = { "lazyArg": { "something": True }, } arguments = [ StrawberryArgument( graphql_name="lazyArg", python_name="lazy_arg", type_annotation=StrawberryAnnotation(LazierType), ), ] assert (convert_arguments( args, arguments, scalar_registry=DEFAULT_SCALAR_REGISTRY, config=StrawberryConfig(), ) == { "lazy_arg": LaziestType(something=True) })
def test_when_optional(): @strawberry.input class Number: value: int @strawberry.input class Input: numbers: Optional[Number] = UNSET numbers_second: Optional[Number] = UNSET args = {} arguments = [ StrawberryArgument( graphql_name=None, python_name="input", type_annotation=StrawberryAnnotation(Optional[Input]), ) ] assert (convert_arguments( args, arguments, scalar_registry=DEFAULT_SCALAR_REGISTRY, config=StrawberryConfig(), ) == {})
def union(name: str, types: Tuple[Type, ...], *, description: str = None) -> StrawberryUnion: """Creates a new named Union type. Example usages: >>> @strawberry.type ... class A: ... >>> @strawberry.type ... class B: ... >>> strawberry.union("Name", (A, Optional[B])) """ # Validate types if len(types) == 0: raise TypeError("No types passed to `union`") for _type in types: if not isinstance(_type, TypeVar) and not hasattr( _type, "_type_definition"): raise InvalidUnionType( f"Type `{_type.__name__}` cannot be used in a GraphQL Union") union_definition = StrawberryUnion( name=name, type_annotations=tuple(StrawberryAnnotation(type_) for type_ in types), description=description, ) return union_definition
def test_union(): @strawberry.type class Un: fi: int @strawberry.type class Ion: eld: float union = StrawberryUnion( name="UnionName", type_annotations=(StrawberryAnnotation(Un), StrawberryAnnotation(Ion)), ) annotation = StrawberryAnnotation(union) field = StrawberryField(type_annotation=annotation) assert field.type is union
def test_optional_list(): annotation = StrawberryAnnotation(Optional[List[bool]]) resolved = annotation.resolve() assert isinstance(resolved, StrawberryOptional) assert resolved.of_type == List[bool] assert resolved == StrawberryOptional(of_type=List[bool]) assert resolved == Optional[List[bool]]
def test_string_of_object(): @strawberry.type class StrType: thing: int annotation = StrawberryAnnotation("StrType", namespace=locals()) resolved = annotation.resolve() assert resolved is StrType
def test_optional_union_containing_a_real_union_and_unset(): annotation = StrawberryAnnotation(Union[str, int, None, _Unset]) resolved = annotation.resolve() assert isinstance(resolved, StrawberryOptional) assert resolved.of_type == Union[str, int] assert resolved == StrawberryOptional(of_type=Union[str, int]) assert resolved == Optional[Union[str, int]]
def test_list_of_string(): annotation = StrawberryAnnotation(List["int"]) resolved = annotation.resolve() assert isinstance(resolved, StrawberryList) assert resolved.of_type is int assert resolved == StrawberryList(of_type=int) assert resolved == List[int]
def test_basic_optional(): annotation = StrawberryAnnotation(Optional[str]) resolved = annotation.resolve() assert isinstance(resolved, StrawberryOptional) assert resolved.of_type is str assert resolved == StrawberryOptional(of_type=str) assert resolved == Optional[str]
def test_list_of_lists(): annotation = StrawberryAnnotation(List[List[float]]) resolved = annotation.resolve() assert isinstance(resolved, StrawberryList) assert resolved.of_type == List[float] assert resolved == StrawberryList(of_type=List[float]) assert resolved == List[List[float]]
def test_basic_list(): annotation = StrawberryAnnotation(List[str]) resolved = annotation.resolve() assert isinstance(resolved, StrawberryList) assert resolved.of_type is str assert resolved == StrawberryList(of_type=str) assert resolved == List[str]
def test_list_of_optional(): annotation = StrawberryAnnotation(List[Optional[int]]) resolved = annotation.resolve() assert isinstance(resolved, StrawberryList) assert resolved.of_type == Optional[int] assert resolved == StrawberryList(of_type=Optional[int]) assert resolved == List[Optional[int]]
def test_optional_of_string(): annotation = StrawberryAnnotation(Optional["bool"]) resolved = annotation.resolve() assert isinstance(resolved, StrawberryOptional) assert resolved.of_type is bool assert resolved == StrawberryOptional(of_type=bool) assert resolved == Optional[bool]
def test_optional_with_unset_as_union(): annotation = StrawberryAnnotation(Union[_Unset, None, str]) resolved = annotation.resolve() assert isinstance(resolved, StrawberryOptional) assert resolved.of_type is str assert resolved == StrawberryOptional(of_type=str) assert resolved == Optional[str]
def test_object(): @strawberry.type class TypeyType: value: str annotation = StrawberryAnnotation(TypeyType) field = StrawberryField(type_annotation=annotation) assert field.type is TypeyType
def test_lazy_type_field(): # Module path is short and relative because of the way pytest runs the file LazierType = LazyType["LaziestType", "test_lazy_types"] annotation = StrawberryAnnotation(LazierType) field = StrawberryField(type_annotation=annotation) assert isinstance(field.type, LazyType) assert field.type is LazierType assert field.type.resolve_type() is LaziestType # type: ignore
def test_string_of_type_var(): T = TypeVar("T") annotation = StrawberryAnnotation("T", namespace=locals()) resolved = annotation.resolve() assert isinstance(resolved, StrawberryTypeVar) assert resolved.type_var is T assert resolved == T
def test_enum(): @strawberry.enum class Egnum(Enum): a = "A" b = "B" annotation = StrawberryAnnotation(Egnum) field = StrawberryField(type_annotation=annotation) # TODO: Remove reference to ._enum_definition with StrawberryEnum assert field.type is Egnum._enum_definition
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_generic assert resolved == List[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_generic assert resolved == Optional[T]
def test_string_of_optional(): namespace = {**locals(), **globals()} annotation = StrawberryAnnotation("Optional[int]", namespace=namespace) resolved = annotation.resolve() assert isinstance(resolved, StrawberryOptional) assert resolved.of_type is int assert resolved == StrawberryOptional(of_type=int) assert resolved == Optional[int]
def test_string_of_list(): namespace = {**locals(), **globals()} annotation = StrawberryAnnotation("List[float]", namespace=namespace) resolved = annotation.resolve() assert isinstance(resolved, StrawberryList) assert resolved.of_type is float assert resolved == StrawberryList(of_type=float) assert resolved == List[float]