def correctly_threads_arguments(): resolved_args = [] def resolve(_obj, _info, **args): resolved_args.append(args) schema = GraphQLSchema( GraphQLObjectType( "Type", { "b": GraphQLField( GraphQLString, args={ "numArg": GraphQLArgument(GraphQLInt), "stringArg": GraphQLArgument(GraphQLString), }, resolve=resolve, ) }, ) ) document = parse( """ query Example { b(numArg: 123, stringArg: "foo") } """ ) execute_sync(schema, document) assert len(resolved_args) == 1 assert resolved_args[0] == {"numArg": 123, "stringArg": "foo"}
async def throws_if_encountering_async_execution_with_check_sync(): doc = "query Example { syncField, asyncField }" with raises(RuntimeError) as exc_info: execute_sync(schema, document=parse(doc), root_value="rootValue", check_sync=True) msg = str(exc_info.value) assert msg == "GraphQL execution failed to complete synchronously."
def it_populates_path_correctly_with_complex_types(): path: Optional[ResponsePath] = None def resolve(_val, info): nonlocal path path = info.path def resolve_type(_val, _info, _type): return "SomeObject" some_object = GraphQLObjectType( "SomeObject", {"test": GraphQLField(GraphQLString, resolve=resolve)} ) some_union = GraphQLUnionType( "SomeUnion", [some_object], resolve_type=resolve_type ) test_type = GraphQLObjectType( "SomeQuery", { "test": GraphQLField( GraphQLNonNull(GraphQLList(GraphQLNonNull(some_union))) ) }, ) schema = GraphQLSchema(test_type) root_value: Any = {"test": [{}]} document = parse( """ query { l1: test { ... on SomeObject { l2: test } } } """ ) execute_sync(schema, document, root_value) assert path is not None prev, key, typename = path assert key == "l2" assert typename == "SomeObject" prev, key, typename = prev assert key == 0 assert typename is None prev, key, typename = prev assert key == "l1" assert typename == "SomeQuery" assert prev is None
def default_function_passes_args_and_context(): class Adder: _num: int def __init__(self, num): self._num = num def test(self, info, addend1: int): return self._num + addend1 + info.context.addend2 root_value = Adder(700) schema = _test_schema( GraphQLField(GraphQLInt, args={"addend1": GraphQLArgument(GraphQLInt)}) ) class ContextValue: addend2 = 9 context_value = ContextValue() document = parse("{ test(addend1: 80) }") assert execute_sync( schema=schema, document=document, root_value=root_value, context_value=context_value, ) == ( {"test": 789}, None, )
def field_error_when_missing_non_null_arg(): # Note: validation should identify this issue first # (missing args rule) however execution should still # protect against this. result = execute_sync( schema_with_non_null_arg, parse( """ query { withNonNullArg } """ ), ) assert result == ( {"withNonNullArg": None}, [ { "message": "Argument 'cannotBeNull' of required type" " 'String!' was not provided.", "locations": [(3, 23)], "path": ["withNonNullArg"], } ], )
def throws_on_invalid_variables(): schema = GraphQLSchema( GraphQLObjectType( "Type", { "fieldA": GraphQLField( GraphQLString, args={"argA": GraphQLArgument(GraphQLInt)} ) }, ) ) document = parse( """ query ($a: Int) { fieldA(argA: $a) } """ ) variable_values = "{'a': 1}" with raises(TypeError) as exc_info: assert execute_sync( schema=schema, document=document, variable_values=variable_values, # type: ignore ) assert str(exc_info.value) == ( "Variable values must be provided as a dictionary" " with variable names as keys. Perhaps look to see" " if an unparsed JSON string was provided." )
def field_error_when_non_null_arg_not_provided_variable_value(): # Note: validation should identify this issue first # (variables in allowed position rule) however execution # should still protect against this. result = execute_sync( schema_with_non_null_arg, parse(""" query ($testVar: String) { withNonNullArg(cannotBeNull: $testVar) } """), variable_values={}, ) # intentionally missing variable assert result == ( { "withNonNullArg": None }, [{ "message": "Argument 'cannotBeNull' of required type" " 'String!' was provided the variable" " '$testVar' which was not provided" " a runtime value.", "locations": [(3, 52)], "path": ["withNonNullArg"], }], )
def fails_when_serialize_of_custom_scalar_does_not_return_a_value(): custom_scalar = GraphQLScalarType( "CustomScalar", serialize=lambda _value: Undefined # returns nothing ) schema = GraphQLSchema( GraphQLObjectType( "Query", { "customScalar": GraphQLField( custom_scalar, resolve=lambda *_args: "CUSTOM_VALUE" ) }, ) ) result = execute_sync(schema, parse("{ customScalar }")) assert result == ( {"customScalar": None}, [ { "message": "Expected a value of type 'CustomScalar'" " but received: 'CUSTOM_VALUE'", "locations": [(1, 3)], "path": ["customScalar"], } ], )
def does_not_include_arguments_that_were_not_set(): schema = GraphQLSchema( GraphQLObjectType( "Type", { "field": GraphQLField( GraphQLString, args={ "a": GraphQLArgument(GraphQLBoolean), "b": GraphQLArgument(GraphQLBoolean), "c": GraphQLArgument(GraphQLBoolean), "d": GraphQLArgument(GraphQLInt), "e": GraphQLArgument(GraphQLInt), }, resolve=lambda _source, _info, **args: inspect(args), ) }, ) ) document = parse("{ field(a: true, c: false, e: 0) }") assert execute_sync(schema, document) == ( {"field": "{'a': True, 'c': False, 'e': 0}"}, None, )
def avoids_recursion(): schema = GraphQLSchema( GraphQLObjectType("Type", {"a": GraphQLField(GraphQLString)}) ) document = parse( """ query Q { a ...Frag ...Frag } fragment Frag on Type { a, ...Frag } """ ) class Data: a = "b" result = execute_sync(schema, document, Data(), operation_name="Q") assert result == ({"a": "b"}, None)
def executes_interface_types_with_inline_fragment(): # This is the valid version of the query in the above test. document = parse(""" { __typename name friends { __typename name ... on Dog { barks } ... on Cat { meows } ... on Mammal { mother { __typename ... on Dog { name barks } ... on Cat { name meows } } } } } """) assert execute_sync(schema=schema, document=document, root_value=john) == ( { "__typename": "Person", "name": "John", "friends": [ { "__typename": "Person", "name": "Liz", "mother": None }, { "__typename": "Dog", "name": "Odie", "barks": True, "mother": { "__typename": "Dog", "name": "Odie's Mom", "barks": True, }, }, ], }, None, )
def field_error_when_non_null_arg_provided_null(): # Note: validation should identify this issue first # (values of correct type rule) however execution # should still protect against this. result = execute_sync( schema_with_non_null_arg, parse( """ query { withNonNullArg(cannotBeNull: null) } """ ), ) assert result == ( {"withNonNullArg": None}, [ { "message": "Argument 'cannotBeNull' of non-null type" " 'String!' must not be null.", "locations": [(3, 52)], "path": ["withNonNullArg"], } ], )
def execute_query(query: str, root_value: Any = None) -> ExecutionResult: document = parse(query) return execute_sync( schema=schema, document=document, root_value=root_value, )
def throws_if_no_schema_is_provided(): document = parse("{ field }") with raises(TypeError) as exc_info: assert execute_sync(schema=None, document=document) # type: ignore assert str(exc_info.value) == "Expected None to be a GraphQL schema."
def pass_error_from_resolver_wrapped_as_located_graphql_error(): def resolve(_obj, _info): raise ValueError("Some error") schema = _test_schema(GraphQLField(GraphQLString, resolve=resolve)) result = execute_sync(schema, parse("{ test }")) assert result == ( {"test": None}, [{"message": "Some error", "locations": [(1, 3)], "path": ["test"]}], ) assert result.errors is not None error = result.errors[0] assert isinstance(error, GraphQLError) assert str(error) == "Some error\n\nGraphQL request:1:3\n1 | { test }\n | ^" assert error.positions == [2] locations = error.locations assert locations == [(1, 3)] location = locations[0] assert isinstance(location, SourceLocation) assert location == SourceLocation(1, 3) original_error = error.original_error assert isinstance(original_error, ValueError) assert str(original_error) == "Some error"
def uses_a_custom_type_resolver(): document = parse("{ foo { bar } }") foo_interface = GraphQLInterfaceType( "FooInterface", {"bar": GraphQLField(GraphQLString)} ) foo_object = GraphQLObjectType( "FooObject", {"bar": GraphQLField(GraphQLString)}, [foo_interface] ) schema = GraphQLSchema( GraphQLObjectType("Query", {"foo": GraphQLField(foo_interface)}), types=[foo_object], ) possible_types = None def type_resolver(_source, info, abstract_type): # Resolver should be able to figure out all possible types on its own nonlocal possible_types possible_types = info.schema.get_possible_types(abstract_type) return "FooObject" root_value = {"foo": {"bar": "bar"}} result = execute_sync(schema, document, root_value, type_resolver=type_resolver) assert result == ({"foo": {"bar": "bar"}}, None) assert possible_types == [foo_object]
def throws_if_no_document_is_provided(): schema = GraphQLSchema( GraphQLObjectType("Type", {"a": GraphQLField(GraphQLString)})) with raises(TypeError) as exc_info: assert execute_sync(schema=schema, document=None) # type: ignore assert str(exc_info.value) == "Must provide document."
async def execute_sync_and_async(query: str, root_value: Any) -> ExecutionResult: sync_result = execute_sync(schema, parse(query), root_value) async_result = await cast(Awaitable[ExecutionResult], execute(schema, parse(patch(query)), root_value)) assert repr(async_result) == patch(repr(sync_result)) return sync_result
def default_function_accesses_keys_of_dict(): root_value = {"test": "testValue"} assert execute_sync( schema=_test_schema(GraphQLField(GraphQLString)), document=parse("{ test }"), root_value=root_value, ) == ({"test": "testValue"}, None)
def does_not_include_illegal_fields_in_output(): schema = GraphQLSchema( GraphQLObjectType("Q", {"a": GraphQLField(GraphQLString)})) document = parse("{ thisIsIllegalDoNotIncludeMe }") result = execute_sync(schema, document) assert result == ({}, None)
def default_function_accesses_keys_of_chain_map(): # use a mapping that is not a subclass of dict root_value = ChainMap({"test": "testValue"}) assert execute_sync( schema=_test_schema(GraphQLField(GraphQLString)), document=parse("{ test }"), root_value=root_value, ) == ({"test": "testValue"}, None)
async def fails_when_is_type_of_check_is_not_met(): class Special: value: str def __init__(self, value): self.value = value class NotSpecial: value: str def __init__(self, value): self.value = value def is_type_of_special(obj, _info): is_special = isinstance(obj, Special) if not _info.context["async"]: return is_special async def async_is_special(): return is_special return async_is_special() SpecialType = GraphQLObjectType( "SpecialType", {"value": GraphQLField(GraphQLString)}, is_type_of=is_type_of_special, ) schema = GraphQLSchema( GraphQLObjectType( "Query", {"specials": GraphQLField(GraphQLList(SpecialType))} ) ) document = parse("{ specials { value } }") root_value = {"specials": [Special("foo"), NotSpecial("bar")]} result = execute_sync(schema, document, root_value, {"async": False}) assert not isinstance(result, Awaitable) assert result == ( {"specials": [{"value": "foo"}, None]}, [ { "message": "Expected value of type 'SpecialType' but got:" " <NotSpecial instance>.", "locations": [(1, 3)], "path": ["specials", 1], } ], ) async_result = execute(schema, document, root_value, {"async": True}) assert isinstance(async_result, Awaitable) awaited_result = await async_result assert awaited_result == result
def threads_root_value_context_correctly(): resolved_values = [] class Data: context_thing = "thing" def resolve(obj, _info): resolved_values.append(obj) schema = GraphQLSchema( GraphQLObjectType( "Type", {"a": GraphQLField(GraphQLString, resolve=resolve)})) document = parse("query Example { a }") root_value = Data() execute_sync(schema, document, root_value) assert len(resolved_values) == 1 assert resolved_values[0] is root_value
def ignores_missing_sub_selections_on_fields(): some_type = GraphQLObjectType("SomeType", {"b": GraphQLField(GraphQLString)}) schema = GraphQLSchema( GraphQLObjectType("Query", {"a": GraphQLField(some_type)}) ) document = parse("{ a }") root_value = {"a": {"b": "c"}} result = execute_sync(schema, document, root_value) assert result == ({"a": {}}, None)
def accepts_positional_arguments(): schema = GraphQLSchema( GraphQLObjectType( "Type", {"a": GraphQLField(GraphQLString, resolve=lambda obj, *args: obj)}, ) ) result = execute_sync(schema, parse("{ a }"), "rootValue") assert result == ({"a": "rootValue"}, None)
def uses_the_only_operation_if_no_operation_name_is_provided(): schema = GraphQLSchema( GraphQLObjectType("Type", {"a": GraphQLField(GraphQLString)})) document = parse("query Example { a }") class Data: a = "b" result = execute_sync(schema, document, Data()) assert result == ({"a": "b"}, None)
def provides_error_if_no_operation_is_provided(): schema = GraphQLSchema( GraphQLObjectType("Type", {"a": GraphQLField(GraphQLString)})) document = parse("fragment Example on Type { a }") class Data: a = "b" result = execute_sync(schema, document, Data()) assert result == (None, [{"message": "Must provide an operation."}])
def uses_a_custom_field_resolver(): schema = GraphQLSchema( GraphQLObjectType("Query", {"foo": GraphQLField(GraphQLString)})) document = parse("{ foo }") def field_resolver(_source, info): # For the purposes of test, just return the name of the field! return info.field_name result = execute_sync(schema, document, field_resolver=field_resolver) assert result == ({"foo": "foo"}, None)
def does_not_return_an_awaitable_for_sync_execution(): doc = "query Example { syncField }" result = execute_sync(schema, document=parse(doc), root_value="rootValue") assert result == ( { "syncField": "rootValue" }, None, )
def default_function_accesses_attributes(): class RootValue: test = "testValue" assert execute_sync( schema=_test_schema(GraphQLField(GraphQLString)), document=parse("{ test }"), root_value=RootValue(), ) == ( {"test": "testValue"}, None, )