def test_raises_if_unknown_operation_name_is_provided(): doc = 'query Example { a } query OtherExample { a }' class Data(object): a = 'b' ast = parse(doc) Type = GraphQLObjectType('Type', { 'a': GraphQLField(GraphQLString) }) with raises(GraphQLError) as excinfo: execute(GraphQLSchema(Type), ast, Data()) assert 'Must provide operation name if query contains multiple operations.' == str(excinfo.value)
def test_raises_if_no_operation_name_is_provided_with_multiple_operations(): doc = 'query Example { a } query OtherExample { a }' class Data(object): a = 'b' ast = parse(doc) Type = GraphQLObjectType('Type', { 'a': GraphQLField(GraphQLString) }) with raises(GraphQLError) as excinfo: execute(GraphQLSchema(Type), ast, Data(), operation_name="UnknownExample") assert 'Unknown operation named "UnknownExample".' == str(excinfo.value)
def test_raises_if_no_operation_is_provided(): doc = 'fragment Example on Type { a }' class Data(object): a = 'b' ast = parse(doc) Type = GraphQLObjectType('Type', { 'a': GraphQLField(GraphQLString) }) with raises(GraphQLError) as excinfo: execute(GraphQLSchema(Type), ast, Data()) assert 'Must provide an operation.' == str(excinfo.value)
def test_correctly_threads_arguments(): doc = ''' query Example { b(numArg: 123, stringArg: "foo") } ''' def resolver(_, args, *_args): assert args['numArg'] == 123 assert args['stringArg'] == 'foo' resolver.got_here = True resolver.got_here = False doc_ast = parse(doc) Type = GraphQLObjectType('Type', { 'b': GraphQLField( GraphQLString, args={ 'numArg': GraphQLArgument(GraphQLInt), 'stringArg': GraphQLArgument(GraphQLString), }, resolver=resolver), }) result = execute(GraphQLSchema(Type), doc_ast, None, operation_name='Example') assert not result.errors assert resolver.got_here
def assert_evaluate_mutations_serially(executor=None): doc = '''mutation M { first: immediatelyChangeTheNumber(newNumber: 1) { theNumber }, second: promiseToChangeTheNumber(newNumber: 2) { theNumber }, third: immediatelyChangeTheNumber(newNumber: 3) { theNumber } fourth: promiseToChangeTheNumber(newNumber: 4) { theNumber }, fifth: immediatelyChangeTheNumber(newNumber: 5) { theNumber } }''' ast = parse(doc) result = execute(schema, ast, Root(6), operation_name='M', executor=executor) assert not result.errors assert result.data == \ { 'first': {'theNumber': 1}, 'second': {'theNumber': 2}, 'third': {'theNumber': 3}, 'fourth': {'theNumber': 4}, 'fifth': {'theNumber': 5}, }
def test_middleware_class(): doc = '''{ ok not_ok }''' class Data(object): def ok(self): return 'ok' def not_ok(self): return 'not_ok' doc_ast = parse(doc) Type = GraphQLObjectType('Type', { 'ok': GraphQLField(GraphQLString), 'not_ok': GraphQLField(GraphQLString), }) class MyMiddleware(object): def resolve(self, next, *args, **kwargs): p = next(*args, **kwargs) return p.then(lambda x: x[::-1]) middlewares = MiddlewareManager(MyMiddleware()) result = execute(GraphQLSchema(Type), doc_ast, Data(), middleware=middlewares) assert result.data == {'ok': 'ko', 'not_ok': 'ko_ton'}
def test_asyncio_executor_custom_loop(): loop = asyncio.get_event_loop() def resolver(context, *_): asyncio.sleep(0.001, loop=loop) return 'hey' @asyncio.coroutine def resolver_2(context, *_): asyncio.sleep(0.003, loop=loop) return 'hey2' def resolver_3(contest, *_): return 'hey3' Type = GraphQLObjectType('Type', { 'a': GraphQLField(GraphQLString, resolver=resolver), 'b': GraphQLField(GraphQLString, resolver=resolver_2), 'c': GraphQLField(GraphQLString, resolver=resolver_3) }) ast = parse('{ a b c }') result = execute(GraphQLSchema(Type), ast, executor=AsyncioExecutor(loop=loop)) assert not result.errors assert result.data == {'a': 'hey', 'b': 'hey2', 'c': 'hey3'}
def test_reraise(): ast = parse('query Example { a }') def resolver(context, *_): raise Exception('Failed') Type = GraphQLObjectType('Type', { 'a': GraphQLField(GraphQLString, resolver=resolver), }) result = execute(GraphQLSchema(Type), ast) with pytest.raises(Exception) as exc_info: result.errors[0].reraise() extracted = traceback.extract_tb(exc_info.tb) formatted_tb = [row[2:] for row in extracted] if formatted_tb[2][0] == 'reraise': formatted_tb[2:] = formatted_tb[3:] assert formatted_tb == [ ('test_reraise', 'result.errors[0].reraise()'), ('reraise', 'six.reraise(type(self), self, self.stack)'), # ('reraise', 'raise value.with_traceback(tb)'), ('resolve_or_error', 'return executor.execute(resolve_fn, source, args, context, info)'), ('execute', 'return fn(*args, **kwargs)'), ('resolver', "raise Exception('Failed')") ] assert str(exc_info.value) == 'Failed'
def test_nulls_out_error_subtrees(): doc = '''{ ok, error }''' class Data(object): def ok(self): return 'ok' def error(self): raise Exception('Error getting error') doc_ast = parse(doc) Type = GraphQLObjectType('Type', { 'ok': GraphQLField(GraphQLString), 'error': GraphQLField(GraphQLString), }) result = execute(GraphQLSchema(Type), doc_ast, Data()) assert result.data == {'ok': 'ok', 'error': None} assert len(result.errors) == 1 assert result.errors[0].message == 'Error getting error'
def run_check(self): test_type = self.type data = Data(test=test_data) DataType = GraphQLObjectType( name='DataType', fields=lambda: { 'test': GraphQLField(test_type), 'nest': GraphQLField(DataType, resolver=lambda *_: data) } ) schema = GraphQLSchema(query=DataType) response = execute(schema, ast, data) if response.errors: result = { 'data': response.data, 'errors': [format_error(e) for e in response.errors] } else: result = { 'data': response.data } assert result == expected
def test_supports_the_type_root_field(): TestType = GraphQLObjectType('TestType', { 'testField': GraphQLField(GraphQLString) }) schema = GraphQLSchema(TestType) request = '{ __type(name: "TestType") { name } }' result = execute(schema, parse(request), object()) assert not result.errors assert result.data == {'__type': {'name': 'TestType'}}
def test_middleware_wrong(): doc = '''{ ok }''' class Data(object): def ok(self): return 'ok' doc_ast = parse(doc) Type = GraphQLObjectType('Type', { 'ok': GraphQLField(GraphQLString), }) middlewares = [None] with raises(AssertionError) as excinfo: execute(GraphQLSchema(Type), doc_ast, Data(), middlewares=middlewares) assert 'middlewares have to be an instance of MiddlewareManager. Received "[None]".' == str(excinfo.value)
def test_fails_to_execute_a_query_containing_a_type_definition(): query = parse(''' { foo } type Query { foo: String } ''') schema = GraphQLSchema( GraphQLObjectType( name='Query', fields={ 'foo': GraphQLField(GraphQLString) } ) ) with raises(GraphQLError) as excinfo: execute(schema, query) assert excinfo.value.message == 'GraphQL cannot execute a request containing a ObjectTypeDefinition.'
def test_raise(): ast = parse('query Example { a }') def resolver(context, *_): raise Exception('Failed') Type = GraphQLObjectType('Type', { 'a': GraphQLField(GraphQLString, resolver=resolver), }) result = execute(GraphQLSchema(Type), ast) assert str(result.errors[0]) == 'Failed'
def test_does_not_include_illegal_fields_in_output(): doc = 'mutation M { thisIsIllegalDontIncludeMe }' ast = parse(doc) Q = GraphQLObjectType('Q', { 'a': GraphQLField(GraphQLString) }) M = GraphQLObjectType('M', { 'c': GraphQLField(GraphQLString) }) result = execute(GraphQLSchema(Q, M), ast) assert not result.errors assert result.data == {}
def test_middleware_skip_promise_wrap(): doc = '''{ ok not_ok }''' class Data(object): def ok(self): return 'ok' def not_ok(self): return 'not_ok' doc_ast = parse(doc) Type = GraphQLObjectType('Type', { 'ok': GraphQLField(GraphQLString), 'not_ok': GraphQLField(GraphQLString), }) class MyPromiseMiddleware(object): def resolve(self, next, *args, **kwargs): return Promise.resolve(next(*args, **kwargs)) class MyEmptyMiddleware(object): def resolve(self, next, *args, **kwargs): return next(*args, **kwargs) middlewares_with_promise = MiddlewareManager( MyPromiseMiddleware(), wrap_in_promise=False) middlewares_without_promise = MiddlewareManager( MyEmptyMiddleware(), wrap_in_promise=False) result1 = execute(GraphQLSchema(Type), doc_ast, Data(), middleware=middlewares_with_promise) result2 = execute(GraphQLSchema(Type), doc_ast, Data(), middleware=middlewares_without_promise) assert result1.data == result2.data and result1.data == { 'ok': 'ok', 'not_ok': 'not_ok'}
def test_uses_the_only_operation_if_no_operation_name_is_provided(): doc = 'query Example { a }' class Data(object): a = 'b' ast = parse(doc) Type = GraphQLObjectType('Type', { 'a': GraphQLField(GraphQLString) }) result = execute(GraphQLSchema(Type), ast, Data()) assert not result.errors assert result.data == {'a': 'b'}
def test_uses_the_named_operation_if_operation_name_is_provided(): doc = 'query Example { first: a } query OtherExample { second: a }' class Data(object): a = 'b' ast = parse(doc) Type = GraphQLObjectType('Type', { 'a': GraphQLField(GraphQLString) }) result = execute(GraphQLSchema(Type), ast, Data(), operation_name='OtherExample') assert not result.errors assert result.data == {'second': 'b'}
def test_cannot_be_used_for_execution(): ast = parse(''' extend type Query { newField: String } ''') extended_schema = extend_schema(test_schema, ast) clientQuery = parse('{ newField }') result = execute(extended_schema, clientQuery, object()) assert result.data['newField'] is None assert str(result.errors[0] ) == 'Client Schema cannot be used for execution.'
def test_exceptions_are_reraised_if_specified(mocker): logger = mocker.patch('graphql.execution.executor.logger') query = parse(''' { foo } ''') def resolver(*_): raise Exception("UH OH!") schema = GraphQLSchema( GraphQLObjectType( name='Query', fields={ 'foo': GraphQLField(GraphQLString, resolver=resolver) } ) ) execute(schema, query) logger.exception.assert_called_with("An error occurred while resolving field Query.foo")
def check(doc, data, expected): ast = parse(doc) response = execute(schema, ast, data) if response.errors: result = { 'data': response.data, 'errors': [format_error(e) for e in response.errors] } else: result = { 'data': response.data } assert result == expected
def check(doc, expected, args=None): ast = parse(doc) response = execute(schema, ast, variable_values=args) if response.errors: result = { 'data': response.data, 'errors': [format_error(e) for e in response.errors] } else: result = { 'data': response.data } assert result == expected
def test_fails_when_an_is_type_of_check_is_not_met(): class Special(object): def __init__(self, value): self.value = value class NotSpecial(object): def __init__(self, value): self.value = value SpecialType = GraphQLObjectType( 'SpecialType', fields={ 'value': GraphQLField(GraphQLString), }, is_type_of=lambda obj, info: isinstance(obj, Special) ) schema = GraphQLSchema( GraphQLObjectType( name='Query', fields={ 'specials': GraphQLField( GraphQLList(SpecialType), resolver=lambda root, *_: root['specials'] ) } ) ) query = parse('{ specials { value } }') value = { 'specials': [Special('foo'), NotSpecial('bar')] } result = execute(schema, query, value) assert result.data == { 'specials': [ {'value': 'foo'}, None ] } assert 'Expected value of type "SpecialType" but got: NotSpecial.' in [ str(e) for e in result.errors]
def test_uses_the_subscription_schema_for_subscriptions(): doc = 'query Q { a } subscription S { a }' class Data(object): a = 'b' c = 'd' ast = parse(doc) Q = GraphQLObjectType('Q', { 'a': GraphQLField(GraphQLString) }) S = GraphQLObjectType('S', { 'a': GraphQLField(GraphQLString) }) result = execute(GraphQLSchema(Q, subscription=S), ast, Data(), operation_name='S') assert not result.errors assert result.data == {'a': 'b'}
def test_uses_the_mutation_schema_for_queries(): doc = 'query Q { a } mutation M { c }' class Data(object): a = 'b' c = 'd' ast = parse(doc) Q = GraphQLObjectType('Q', { 'a': GraphQLField(GraphQLString) }) M = GraphQLObjectType('M', { 'c': GraphQLField(GraphQLString) }) result = execute(GraphQLSchema(Q, M), ast, Data(), operation_name='M') assert not result.errors assert result.data == {'c': 'd'}
def test_gevent_executor_with_error(): ast = parse('query Example { a, b }') def resolver(context, *_): gevent.sleep(0.001) return 'hey' def resolver_2(context, *_): gevent.sleep(0.003) raise Exception('resolver_2 failed!') Type = GraphQLObjectType('Type', { 'a': GraphQLField(GraphQLString, resolver=resolver), 'b': GraphQLField(GraphQLString, resolver=resolver_2) }) result = execute(GraphQLSchema(Type), ast, executor=GeventExecutor()) formatted_errors = list(map(format_error, result.errors)) assert formatted_errors == [{'locations': [{'line': 1, 'column': 20}], 'message': 'resolver_2 failed!'}] assert result.data == {'a': 'hey', 'b': None}
def executes_union_types_with_inline_fragment(): # This is the valid version of the query in the above test. document = parse(""" { __typename name pets { __typename ... on Dog { name barks } ... on Cat { name meows } } } """) assert execute(schema=schema, document=document, root_value=john) == ( { "__typename": "Person", "name": "John", "pets": [ { "__typename": "Cat", "name": "Garfield", "meows": False }, { "__typename": "Dog", "name": "Odie", "barks": True }, ], }, None, )
def test_merges_parallel_fragments(): ast = parse(''' { a, deep {...FragOne, ...FragTwo} } fragment FragOne on Type { b deep { b, deeper: deep { b } } } fragment FragTwo on Type { c deep { c, deeper: deep { c } } } ''') Type = GraphQLObjectType('Type', lambda: { 'a': GraphQLField(GraphQLString, resolver=lambda *_: 'Apple'), 'b': GraphQLField(GraphQLString, resolver=lambda *_: 'Banana'), 'c': GraphQLField(GraphQLString, resolver=lambda *_: 'Cherry'), 'deep': GraphQLField(Type, resolver=lambda *_: {}), }) schema = GraphQLSchema(query=Type) result = execute(schema, ast) assert not result.errors assert result.data == \ { 'a': 'Apple', 'deep': { 'b': 'Banana', 'c': 'Cherry', 'deep': { 'b': 'Banana', 'c': 'Cherry', 'deeper': { 'b': 'Banana', 'c': 'Cherry'}}} }
def test_gets_execution_info_in_resolver(): # type: () -> None class encountered: schema = None root_value = None context = None def resolve_type(obj, info): # type: (Person, ResolveInfo) -> GraphQLObjectType encountered.schema = info.schema encountered.root_value = info.root_value encountered.context = context return PersonType2 NamedType2 = GraphQLInterfaceType( name="Named", fields={"name": GraphQLField(GraphQLString)}, resolve_type=resolve_type, ) PersonType2 = GraphQLObjectType( name="Person", interfaces=[NamedType2], fields={ "name": GraphQLField(GraphQLString), "friends": GraphQLField(GraphQLList(NamedType2)), }, ) schema2 = GraphQLSchema(query=PersonType2) john2 = Person("John", [], [liz]) context = {"hey"} ast = parse("""{ name, friends { name } }""") result = execute(schema2, ast, john2, context_value=context) assert not result.errors assert result.data == {"name": "John", "friends": [{"name": "Liz"}]} assert encountered.schema == schema2 assert encountered.root_value == john2 assert encountered.context == context
def merges_parallel_fragments(): ast = parse( """ { a, ...FragOne, ...FragTwo } fragment FragOne on Type { b deep { b, deeper: deep { b } } } fragment FragTwo on Type { c deep { c, deeper: deep { c } } } """ ) Type = GraphQLObjectType( "Type", lambda: { "a": GraphQLField(GraphQLString, resolve=lambda *_args: "Apple"), "b": GraphQLField(GraphQLString, resolve=lambda *_args: "Banana"), "c": GraphQLField(GraphQLString, resolve=lambda *_args: "Cherry"), "deep": GraphQLField(Type, resolve=lambda *_args: {}), }, ) schema = GraphQLSchema(Type) assert execute(schema, ast) == ( { "a": "Apple", "b": "Banana", "c": "Cherry", "deep": { "b": "Banana", "c": "Cherry", "deeper": {"b": "Banana", "c": "Cherry"}, }, }, None, )
def uses_the_query_schema_for_queries(): schema = GraphQLSchema( GraphQLObjectType("Q", {"a": GraphQLField(GraphQLString)}), GraphQLObjectType("M", {"c": GraphQLField(GraphQLString)}), GraphQLObjectType("S", {"a": GraphQLField(GraphQLString)}), ) document = parse( """ query Q { a } mutation M { c } subscription S { a } """ ) class Data: a = "b" c = "d" result = execute(schema, document, Data(), operation_name="Q") assert result == ({"a": "b"}, None)
def accepts_an_object_with_named_properties_as_arguments(): doc = "query Example { a }" data = "rootValue" schema = GraphQLSchema( GraphQLObjectType( "Type", { "a": GraphQLField(GraphQLString, resolve=lambda root_value, *args: root_value) }, )) assert execute(schema, document=parse(doc), root_value=data) == ( { "a": "rootValue" }, None, )
async def resolve_fields_in_parallel(): barrier = Barrier(2) async def resolve(*_args): return await barrier.wait() schema = GraphQLSchema( GraphQLObjectType( "Query", { "foo": GraphQLField(GraphQLBoolean, resolve=resolve), "bar": GraphQLField(GraphQLBoolean, resolve=resolve), }, )) ast = parse("{foo, bar}") # raises TimeoutError if not parallel result = await asyncio.wait_for(execute(schema, ast), 1.0) assert result == ({"foo": True, "bar": True}, None)
def test_avoids_recursion(): doc = ''' query Q { a ...Frag ...Frag } fragment Frag on Type { a, ...Frag } ''' class Data(object): a = 'b' ast = parse(doc) Type = GraphQLObjectType('Type', {'a': GraphQLField(GraphQLString)}) result = execute(GraphQLSchema(Type), ast, Data(), operation_name='Q') assert not result.errors assert result.data == {'a': 'b'}
def test_does_not_include_arguments_that_were_not_set(): schema = GraphQLSchema( GraphQLObjectType( 'Type', { 'field': GraphQLField( GraphQLString, resolver=lambda source, info, **args: args and json.dumps( args, sort_keys=True, separators=(',', ':')), args={ 'a': GraphQLArgument(GraphQLBoolean), 'b': GraphQLArgument(GraphQLBoolean), 'c': GraphQLArgument(GraphQLBoolean), 'd': GraphQLArgument(GraphQLInt), 'e': GraphQLArgument(GraphQLInt), }) })) ast = parse('{ field(a: true, c: false, e: 0) }') result = execute(schema, ast) assert result.data == {'field': '{"a":true,"c":false,"e":0}'}
def test_threads_root_value_context_correctly(): doc = 'query Example { a }' class Data(object): context_thing = 'thing' ast = parse(doc) def resolver(root_value, *_): assert root_value.context_thing == 'thing' resolver.got_here = True resolver.got_here = False Type = GraphQLObjectType('Type', { 'a': GraphQLField(GraphQLString, resolver=resolver) }) result = execute(GraphQLSchema(Type), ast, Data(), operation_name='Example') assert not result.errors assert resolver.got_here
def test_reraise(): ast = parse('query Example { a }') def resolver(context, *_): raise Exception('Failed') Type = GraphQLObjectType( 'Type', { 'a': GraphQLField(GraphQLString, resolver=resolver), }) result = execute(GraphQLSchema(Type), ast) with pytest.raises(Exception) as exc_info: result.errors[0].reraise() extracted = traceback.extract_tb(exc_info.tb) formatted_tb = [row[2:] for row in extracted] if formatted_tb[2][0] == 'reraise': formatted_tb[2:] = formatted_tb[3:] assert formatted_tb == [ ('test_reraise', 'result.errors[0].reraise()'), ('reraise', 'six.reraise(type(self), self, self.stack)'), # ('reraise', 'raise value.with_traceback(tb)'), ('resolve_or_error', 'return executor.execute(resolve_fn, source, info, **args)'), ('execute', 'return fn(*args, **kwargs)'), ('resolver', "raise Exception('Failed')") ] # assert formatted_tb == [ # ('test_reraise', 'result.errors[0].reraise()'), # ('reraise', 'six.reraise(type(self), self, self.stack)'), # ('on_complete_resolver', 'result = __resolver(*args, **kwargs)'), # # ('reraise', 'raise value.with_traceback(tb)'), # # ('resolve_or_error', 'return executor.execute(resolve_fn, source, info, **args)'), # # ('execute', 'return fn(*args, **kwargs)'), # ('resolver', "raise Exception('Failed')") # ] assert str(exc_info.value) == 'Failed'
def list_of_functions(): doc = parse("{ field }") # noinspection PyMethodMayBeStatic class Data: def field(self, _info): return "resolved" test_type = GraphQLObjectType( "TestType", {"field": GraphQLField(GraphQLString)} ) log = [] class LogMiddleware: def __init__(self, name): self.name = name # noinspection PyMethodMayBeStatic def resolve(self, next_, *args, **kwargs): log.append(f"enter {self.name}") value = next_(*args, **kwargs) log.append(f"exit {self.name}") return value middlewares = [LogMiddleware("A"), LogMiddleware("B"), LogMiddleware("C")] result = execute( GraphQLSchema(test_type), doc, Data(), middleware=middlewares ) assert result.data == {"field": "resolved"} # type: ignore assert log == [ "enter C", "enter B", "enter A", "exit A", "exit B", "exit C", ]
def merges_parallel_fragments(): ast = parse(""" { a, ...FragOne, ...FragTwo } fragment FragOne on Type { b deep { b, deeper: deep { b } } } fragment FragTwo on Type { c deep { c, deeper: deep { c } } } """) Type = GraphQLObjectType( 'Type', lambda: { 'a': GraphQLField(GraphQLString, resolve=lambda *_args: 'Apple'), 'b': GraphQLField(GraphQLString, resolve=lambda *_args: 'Banana'), 'c': GraphQLField(GraphQLString, resolve=lambda *_args: 'Cherry'), 'deep': GraphQLField(Type, resolve=lambda *_args: {}) }) schema = GraphQLSchema(Type) assert execute(schema, ast) == ({ 'a': 'Apple', 'b': 'Banana', 'c': 'Cherry', 'deep': { 'b': 'Banana', 'c': 'Cherry', 'deeper': { 'b': 'Banana', 'c': 'Cherry' } } }, None)
def test_executes_union_types_with_inline_fragment(): # type: () -> None # This is the valid version of the query in the above test. ast = parse(""" { __typename name pets { __typename ... on Dog { name barks } ... on Cat { name meows } } } """) result = execute(schema, ast, john) assert not result.errors assert result.data == { "__typename": "Person", "name": "John", "pets": [ { "__typename": "Cat", "name": "Garfield", "meows": False }, { "__typename": "Dog", "name": "Odie", "barks": True }, ], }
def fails_when_an_is_type_of_check_is_not_met(): class Special: # noinspection PyShadowingNames def __init__(self, value): self.value = value class NotSpecial: # noinspection PyShadowingNames def __init__(self, value): self.value = value def __repr__(self): return f'{self.__class__.__name__}({self.value!r})' SpecialType = GraphQLObjectType( 'SpecialType', {'value': GraphQLField(GraphQLString)}, is_type_of=lambda obj, _info: isinstance(obj, Special)) schema = GraphQLSchema( GraphQLObjectType( 'Query', { 'specials': GraphQLField(GraphQLList(SpecialType), resolve=lambda root_value, *_args: root_value[ 'specials']) })) query = parse('{ specials { value } }') value = {'specials': [Special('foo'), NotSpecial('bar')]} assert execute(schema, query, value) == ({ 'specials': [{ 'value': 'foo' }, None] }, [{ 'message': "Expected value of type 'SpecialType' but got:" " NotSpecial('bar').", 'locations': [(1, 3)], 'path': ['specials', 1] }])
def fails_when_an_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 SpecialType = GraphQLObjectType( "SpecialType", {"value": GraphQLField(GraphQLString)}, is_type_of=lambda obj, _info: isinstance(obj, Special), ) schema = GraphQLSchema( GraphQLObjectType( "Query", {"specials": GraphQLField(GraphQLList(SpecialType))})) document = parse("{ specials { value } }") root_value = {"specials": [Special("foo"), NotSpecial("bar")]} result = execute(schema, document, root_value) assert result == ( { "specials": [{ "value": "foo" }, None] }, [{ "message": "Expected value of type 'SpecialType' but got:" " <NotSpecial instance>.", "locations": [(1, 3)], "path": ["specials", 1], }], )
def test_merges_parallel_fragments(): ast = parse(''' { a, ...FragOne, ...FragTwo } fragment FragOne on Type { b deep { b, deeper: deep { b } } } fragment FragTwo on Type { c deep { c, deeper: deep { c } } } ''') Type = GraphQLObjectType('Type', lambda: { 'a': GraphQLField(GraphQLString, resolver=lambda *_: 'Apple'), 'b': GraphQLField(GraphQLString, resolver=lambda *_: 'Banana'), 'c': GraphQLField(GraphQLString, resolver=lambda *_: 'Cherry'), 'deep': GraphQLField(Type, resolver=lambda *_: {}), }) schema = GraphQLSchema(query=Type) result = execute(schema, ast) assert not result.errors assert result.data == \ { 'a': 'Apple', 'b': 'Banana', 'c': 'Cherry', 'deep': { 'b': 'Banana', 'c': 'Cherry', 'deeper': { 'b': 'Banana', 'c': 'Cherry'}} }
def test_asyncio_executor(): def resolver(context, *_): asyncio.sleep(0.001) return 'hey' async def resolver_2(context, *_): await asyncio.sleep(0.003) return 'hey2' def resolver_3(contest, *_): return 'hey3' Type = GraphQLObjectType( 'Type', { 'a': GraphQLField(GraphQLString, resolver=resolver), 'b': GraphQLField(GraphQLString, resolver=resolver_2), 'c': GraphQLField(GraphQLString, resolver=resolver_3) }) ast = parse('{ a b c }') result = execute(GraphQLSchema(Type), ast, executor=AsyncioExecutor()) assert not result.errors assert result.data == {'a': 'hey', 'b': 'hey2', 'c': 'hey3'}
def test_correctly_threads_arguments(): # type: () -> None doc = """ query Example { b(numArg: 123, stringArg: "foo") } """ def resolver(source, info, numArg, stringArg): # type: (Optional[Any], ResolveInfo, int, str) -> None assert numArg == 123 assert stringArg == "foo" resolver.got_here = True resolver.got_here = False doc_ast = parse(doc) Type = GraphQLObjectType( "Type", { "b": GraphQLField( GraphQLString, args={ "numArg": GraphQLArgument(GraphQLInt), "stringArg": GraphQLArgument(GraphQLString), }, resolver=resolver, ) }, ) result = execute(GraphQLSchema(Type), doc_ast, None, operation_name="Example") assert not result.errors assert resolver.got_here
def test_only_include_fields_from_matching_fragment_condition(): ast = parse(''' { pets { ...PetFields } } fragment PetFields on Pet { __typename ... on Dog { name } } ''') result = execute(schema, ast, john) assert not result.errors assert result.data == { 'pets': [{ '__typename': 'Cat' }, { '__typename': 'Dog', 'name': 'Odie' }], }
def executes_interface_types_with_inline_fragment(): # This is the valid version of the query in the above test. ast = parse(""" { __typename name friends { __typename name ... on Dog { barks } ... on Cat { meows } } } """) assert execute(schema, ast, john) == ( { "__typename": "Person", "name": "John", "friends": [ { "__typename": "Person", "name": "Liz" }, { "__typename": "Dog", "name": "Odie", "barks": True }, ], }, None, )
def field_error_when_non_null_arg_provided_explicit_null_variable(): result = execute( schema_with_non_null_arg, parse(""" query ($testVar: String = "default value") { withNonNullArg (cannotBeNull: $testVar) } """), variable_values={"testVar": None}, ) assert result == ( { "withNonNullArg": None }, [{ "message": "Argument 'cannotBeNull' of non-null type" " 'String!' must not be null.", "locations": [(3, 53)], "path": ["withNonNullArg"], }], )
def errors_if_no_operation_name_is_provided_with_multiple_operations(): schema = GraphQLSchema( GraphQLObjectType("Type", {"a": GraphQLField(GraphQLString)}) ) document = parse( """ query Example { a } query OtherExample { a } """ ) result = execute(schema, document) assert result == ( None, [ { "message": "Must provide operation name if query contains" " multiple operations." } ], )
def test_avoids_recursion(): # type: () -> None doc = """ query Q { a ...Frag ...Frag } fragment Frag on Type { a, ...Frag } """ class Data(object): a = "b" ast = parse(doc) Type = GraphQLObjectType("Type", {"a": GraphQLField(GraphQLString)}) result = execute(GraphQLSchema(Type), ast, Data(), operation_name="Q") assert not result.errors assert result.data == {"a": "b"}
def gets_execution_info_in_resolver(): encountered = {} def resolve_type(_source, info, _type): encountered["context"] = info.context encountered["schema"] = info.schema encountered["root_value"] = info.root_value return PersonType2 NamedType2 = GraphQLInterfaceType( "Named", {"name": GraphQLField(GraphQLString)}, resolve_type=resolve_type ) PersonType2 = GraphQLObjectType( "Person", { "name": GraphQLField(GraphQLString), "friends": GraphQLField(GraphQLList(NamedType2)), }, interfaces=[NamedType2], ) schema2 = GraphQLSchema(PersonType2) document = parse("{ name, friends { name } }") root_value = Person("John", [], [liz]) context_value = {"authToken": "123abc"} assert execute( schema=schema2, document=document, root_value=root_value, context_value=context_value, ) == ({"name": "John", "friends": [{"name": "Liz"}]}, None,) assert encountered == { "schema": schema2, "root_value": root_value, "context": context_value, }
def test_fails_when_an_is_type_of_check_is_not_met(): # type: () -> None class Special(object): def __init__(self, value): # type: (str) -> None self.value = value class NotSpecial(object): def __init__(self, value): # type: (str) -> None self.value = value SpecialType = GraphQLObjectType( "SpecialType", fields={"value": GraphQLField(GraphQLString)}, is_type_of=lambda obj, info: isinstance(obj, Special), ) schema = GraphQLSchema( GraphQLObjectType( name="Query", fields={ "specials": GraphQLField( GraphQLList(SpecialType), resolver=lambda root, *_: root["specials"] ) }, ) ) query = parse("{ specials { value } }") value = {"specials": [Special("foo"), NotSpecial("bar")]} result = execute(schema, query, value) assert result.data == {"specials": [{"value": "foo"}, None]} assert 'Expected value of type "SpecialType" but got: NotSpecial.' in [ str(e) for e in result.errors ]
def test_gevent_executor(): def resolver(context, *_): gevent.sleep(0.001) return 'hey' def resolver_2(context, *_): gevent.sleep(0.003) return 'hey2' def resolver_3(contest, *_): return 'hey3' Type = GraphQLObjectType('Type', { 'a': GraphQLField(GraphQLString, resolver=resolver), 'b': GraphQLField(GraphQLString, resolver=resolver_2), 'c': GraphQLField(GraphQLString, resolver=resolver_3) }) ast = parse('{ a b c }') result = execute(GraphQLSchema(Type), ast, executor=GeventExecutor()) assert not result.errors assert result.data == {'a': 'hey', 'b': 'hey2', 'c': 'hey3'}
def test_gets_execution_info_in_resolver(): class encountered: schema = None root_value = None context = None def resolve_type(obj, info): encountered.schema = info.schema encountered.root_value = info.root_value encountered.context = context return PersonType2 NamedType2 = GraphQLInterfaceType( name='Named', fields={'name': GraphQLField(GraphQLString)}, resolve_type=resolve_type) PersonType2 = GraphQLObjectType(name='Person', interfaces=[NamedType2], fields={ 'name': GraphQLField(GraphQLString), 'friends': GraphQLField(GraphQLList(NamedType2)) }) schema2 = GraphQLSchema(query=PersonType2) john2 = Person('John', [], [liz]) context = {'hey'} ast = parse('''{ name, friends { name } }''') result = execute(schema2, ast, john2, context_value=context) assert not result.errors assert result.data == {'name': 'John', 'friends': [{'name': 'Liz'}]} assert encountered.schema == schema2 assert encountered.root_value == john2 assert encountered.context == context
async def correct_field_ordering_despite_execution_order(): schema = GraphQLSchema( GraphQLObjectType( "Type", { "a": GraphQLField(GraphQLString), "b": GraphQLField(GraphQLString), "c": GraphQLField(GraphQLString), "d": GraphQLField(GraphQLString), "e": GraphQLField(GraphQLString), }, ) ) document = parse("{ a, b, c, d, e}") # noinspection PyMethodMayBeStatic,PyMethodMayBeStatic class Data: def a(self, _info): return "a" async def b(self, _info): return "b" def c(self, _info): return "c" async def d(self, _info): return "d" def e(self, _info): return "e" awaitable_result = execute(schema, document, Data()) assert isinstance(awaitable_result, Awaitable) result = await awaitable_result assert result == ({"a": "a", "b": "b", "c": "c", "d": "d", "e": "e"}, None)
def test_executes_interface_types_with_inline_fragment(): # type: () -> None # This is the valid version of the query in the above test. ast = parse(""" { __typename name friends { __typename name ... on Dog { barks } ... on Cat { meows } } } """) result = execute(schema, ast, john) assert not result.errors assert result.data == { "__typename": "Person", "name": "John", "friends": [ { "__typename": "Person", "name": "Liz" }, { "__typename": "Dog", "name": "Odie", "barks": True }, ], }
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(schema, document, Data(), operation_name="Q") assert result == ({"a": "b"}, None)
def test_does_not_include_arguments_that_were_not_set(): schema = GraphQLSchema(GraphQLObjectType( 'Type', { 'field': GraphQLField( GraphQLString, resolver=lambda data, args, *_: args and json.dumps(args, sort_keys=True, separators=(',', ':')), args={ 'a': GraphQLArgument(GraphQLBoolean), 'b': GraphQLArgument(GraphQLBoolean), 'c': GraphQLArgument(GraphQLBoolean), 'd': GraphQLArgument(GraphQLInt), 'e': GraphQLArgument(GraphQLInt), } ) } )) ast = parse('{ field(a: true, c: false, e: 0) }') result = execute(schema, ast) assert result.data == { 'field': '{"a":true,"c":false,"e":0}' }
def test_threads_root_value_context_correctly(): # type: () -> None doc = "query Example { a }" class Data(object): context_thing = "thing" ast = parse(doc) def resolver(root_value, *_): # type: (Data, *ResolveInfo) -> None assert root_value.context_thing == "thing" resolver.got_here = True resolver.got_here = False Type = GraphQLObjectType( "Type", {"a": GraphQLField(GraphQLString, resolver=resolver)} ) result = execute(GraphQLSchema(Type), ast, Data(), operation_name="Example") assert not result.errors assert resolver.got_here