def test_gets_execution_info_in_resolver(): encountered_schema = [None] encountered_root_value = [None] def resolve_type(obj, info): encountered_schema[0] = info.schema encountered_root_value[0] = info.root_value 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]) ast = parse('''{ name, friends { name } }''') result = execute(schema2, john2, ast) assert result.data == {'name': 'John', 'friends': [{'name': 'Liz'}]} assert encountered_schema[0] == schema2 assert encountered_root_value[0] == john2
def test_identifies_deprecated_fields(): TestType = GraphQLObjectType('TestType', { 'nonDeprecated': GraphQLField(GraphQLString), 'deprecated': GraphQLField(GraphQLString, deprecation_reason='Removed in 1.0') }) schema = GraphQLSchema(TestType) request = '''{__type(name: "TestType") { name fields(includeDeprecated: true) { name isDeprecated deprecationReason } } }''' result = graphql(schema, request) assert not result.errors assert sort_lists(result.data) == sort_lists({'__type': { 'name': 'TestType', 'fields': [ {'name': 'nonDeprecated', 'isDeprecated': False, 'deprecationReason': None}, {'name': 'deprecated', 'isDeprecated': True, 'deprecationReason': 'Removed in 1.0'}, ] }})
def test_includes_nested_input_objects_in_the_map(): NestedInputObject = GraphQLInputObjectType( name='NestedInputObject', fields={'value': GraphQLInputObjectField(GraphQLString)}) SomeInputObject = GraphQLInputObjectType( name='SomeInputObject', fields={'nested': GraphQLInputObjectField(NestedInputObject)}) SomeMutation = GraphQLObjectType( name='SomeMutation', fields={ 'mutateSomething': GraphQLField(type=BlogArticle, args={'input': GraphQLArgument(SomeInputObject)}) }) SomeSubscription = GraphQLObjectType( name='SomeSubscription', fields={ 'subscribeToSomething': GraphQLField(type=BlogArticle, args={'input': GraphQLArgument(SomeInputObject)}) }) schema = GraphQLSchema(query=BlogQuery, mutation=SomeMutation, subscription=SomeSubscription) assert schema.get_type_map()['NestedInputObject'] is NestedInputObject
def test_may_extend_mutations_and_subscriptions(): mutationSchema = GraphQLSchema( query=GraphQLObjectType('Query', fields=lambda: { 'queryField': GraphQLField(GraphQLString), }), mutation=GraphQLObjectType('Mutation', fields={ 'mutationField': GraphQLField(GraphQLString), }), subscription=GraphQLObjectType('Subscription', fields={ 'subscriptionField': GraphQLField(GraphQLString), }), ) ast = parse(''' extend type Query { newQueryField: Int } extend type Mutation { newMutationField: Int } extend type Subscription { newSubscriptionField: Int } ''') original_print = print_schema(mutationSchema) extended_schema = extend_schema(mutationSchema, ast) assert extend_schema != mutationSchema assert print_schema(mutationSchema) == original_print assert print_schema(extended_schema) == \ '''type Mutation {
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, value, query) assert result.data == {'specials': [{'value': 'foo'}, None]} assert 'Expected value of type "SpecialType" but got NotSpecial.' in str( result.errors)
def test_prints_unions(): FooType = GraphQLObjectType( name='Foo', fields={ 'bool': GraphQLField(GraphQLBoolean), }, ) BarType = GraphQLObjectType( name='Bar', fields={ 'str': GraphQLField(GraphQLString), }, ) SingleUnion = GraphQLUnionType(name='SingleUnion', resolve_type=lambda *_: None, types=[FooType]) MultipleUnion = GraphQLUnionType( name='MultipleUnion', resolve_type=lambda *_: None, types=[FooType, BarType], ) Root = GraphQLObjectType(name='Root', fields=OrderedDict([ ('single', GraphQLField(SingleUnion)), ('multiple', GraphQLField(MultipleUnion)), ])) Schema = GraphQLSchema(Root) output = print_for_test(Schema) assert output == '''
def test_gevent_executor_with_error(): doc = 'query Example { a, b }' @run_in_greenlet def resolver(context, *_): gevent.sleep(0.001) return 'hey' @run_in_greenlet 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) }) executor = Executor([GeventExecutionMiddleware()]) result = executor.execute(GraphQLSchema(Type), doc) 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 test_builds_a_schema_aware_of_deprecation(): schema = GraphQLSchema(query=GraphQLObjectType( name='Simple', description='This is a simple type', fields=OrderedDict( [('shinyString', GraphQLField(type=GraphQLString, description='This is a shiny string field')), ('deprecatedString', GraphQLField(type=GraphQLString, description='This is a deprecated string field', deprecation_reason='Use shinyString')), ('color', GraphQLField(type=GraphQLEnumType( name='Color', values=OrderedDict([ ('RED', GraphQLEnumValue(description='So rosy')), ('GREEN', GraphQLEnumValue(description='So grassy')), ('BLUE', GraphQLEnumValue(description='So calming')), ('MAUVE', GraphQLEnumValue( description='So sickening', deprecation_reason='No longer in fashion')), ]))))]))) _test_schema(schema)
def test_cannot_use_client_schema_for_general_execution(): customScalar = GraphQLScalarType(name='CustomScalar', serialize=lambda: None) schema = GraphQLSchema(query=GraphQLObjectType( name='Query', fields={ 'foo': GraphQLField(GraphQLString, args=OrderedDict([('custom1', GraphQLArgument(customScalar)), ('custom2', GraphQLArgument(customScalar))])) })) introspection = graphql(schema, introspection_query) client_schema = build_client_schema(introspection.data) class data: foo = 'bar' result = graphql( client_schema, 'query NoNo($v: CustomScalar) { foo(custom1: 123, custom2: $v) }', data, {'v': 'baz'}) assert result.data == {'foo': None} assert [format_error(e) for e in result.errors] == [{ 'locations': [{ 'column': 32, 'line': 1 }], 'message': 'Client Schema cannot be used for execution.' }]
def test_builds_a_schema_with_field_arguments(): schema = GraphQLSchema(query=GraphQLObjectType( name='ArgFields', fields=OrderedDict([ ('one', GraphQLField(GraphQLString, description='A field with a single arg', args={ 'intArg': GraphQLArgument(GraphQLInt, description='This is an int arg') })), ('two', GraphQLField(GraphQLString, description='A field with two args', args=OrderedDict( [('listArg', GraphQLArgument( GraphQLList(GraphQLInt), description='This is a list of int arg')), ('requiredArg', GraphQLArgument( GraphQLNonNull(GraphQLBoolean), description='This is a required arg'))]))), ]))) _test_schema(schema)
def test_builds_a_schema_with_an_input_object(): AddressType = GraphQLInputObjectType( name='Address', description='An input address', fields=OrderedDict([ ('street', GraphQLInputObjectField( GraphQLNonNull(GraphQLString), description='What street is this address?')), ('city', GraphQLInputObjectField( GraphQLNonNull(GraphQLString), description='The city the address is within?')), ('country', GraphQLInputObjectField( GraphQLString, description='The country (blank will assume USA).', default_value='USA')), ])) schema = GraphQLSchema(query=GraphQLObjectType( name='HasInputObjectFields', fields={ 'geocode': GraphQLField(description='Get a geocode from an address', type=GraphQLString, args={ 'address': GraphQLArgument( description='The address to lookup', type=AddressType) }) })) _test_schema(schema)
def test_uses_built_in_scalars_when_possible(): customScalar = GraphQLScalarType( name='CustomScalar', serialize=lambda: None ) schema = GraphQLSchema( query=GraphQLObjectType( name='Scalars', fields=OrderedDict([ ('int', GraphQLField(GraphQLInt)), ('float', GraphQLField(GraphQLFloat)), ('string', GraphQLField(GraphQLString)), ('boolean', GraphQLField(GraphQLBoolean)), ('id', GraphQLField(GraphQLID)), ('custom', GraphQLField(customScalar)), ]) ) ) client_schema = _test_schema(schema) assert client_schema.get_type('Int') == GraphQLInt assert client_schema.get_type('Float') == GraphQLFloat assert client_schema.get_type('String') == GraphQLString assert client_schema.get_type('Boolean') == GraphQLBoolean assert client_schema.get_type('ID') == GraphQLID assert client_schema.get_type('CustomScalar') != customScalar
def test_builds_a_schema_with_a_union(): DogType = GraphQLObjectType( name='Dog', fields=lambda: { 'bestFriend': GraphQLField(FriendlyType) } ) HumanType = GraphQLObjectType( name='Human', fields=lambda: { 'bestFriend': GraphQLField(FriendlyType) } ) FriendlyType = GraphQLUnionType( name='Friendly', resolve_type=lambda: None, types=[DogType, HumanType] ) schema = GraphQLSchema( query=GraphQLObjectType( name='WithUnion', fields={ 'friendly': GraphQLField(FriendlyType) } ) ) _test_schema(schema)
def test_builds_a_schema_with_an_interface(): FriendlyType = GraphQLInterfaceType( name='Friendly', resolve_type=lambda: None, fields=lambda: { 'bestFriend': GraphQLField(FriendlyType, description='The best friend of this friendly thing.') } ) GraphQLObjectType( name='Human', interfaces=[FriendlyType], fields=lambda: { 'bestFriend': GraphQLField(FriendlyType) } ) schema = GraphQLSchema( query=GraphQLObjectType( name='WithInterface', fields={ 'friendly': GraphQLField(FriendlyType) } ) ) _test_schema(schema)
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), None, doc_ast, 'Example', {}) assert not result.errors assert resolver.got_here
def test_builds_a_simple_schema_with_both_operation_types(): QueryType = GraphQLObjectType( name='QueryType', description='This is a simple query type', fields={ 'string': GraphQLField(GraphQLString, description='This is a string field.') }) MutationType = GraphQLObjectType( name='MutationType', description='This is a simple mutation type', fields={ 'setString': GraphQLField(GraphQLString, description='Set the string field', args={'value': GraphQLArgument(GraphQLString)}) }) SubscriptionType = GraphQLObjectType( name='SubscriptionType', description='This is a simple subscription type', fields={ 'string': GraphQLField(type=GraphQLString, description='This is a string field') }) schema = GraphQLSchema(QueryType, MutationType, SubscriptionType) _test_schema(schema)
def test_executor_can_enforce_strict_ordering(): 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) executor = Executor(execution_middlewares=[SynchronousExecutionMiddleware], map_type=OrderedDict) query = '{ a b c aa: c cc: c bb: b aaz: a bbz: b deep { b a c deeper: deep { c a b } } ' \ 'ccz: c zzz: c aaa: a }' def check_result(result): assert not result.errors data = result.data assert isinstance(data, OrderedDict) assert list(data.keys()) == ['a', 'b', 'c', 'aa', 'cc', 'bb', 'aaz', 'bbz', 'deep', 'ccz', 'zzz', 'aaa'] deep = data['deep'] assert isinstance(deep, OrderedDict) assert list(deep.keys()) == ['b', 'a', 'c', 'deeper'] deeper = deep['deeper'] assert isinstance(deeper, OrderedDict) assert list(deeper.keys()) == ['c', 'a', 'b'] check_result(executor.execute(schema, query)) check_result(executor.execute(schema, query, execute_serially=True))
def test_prints_interface(): FooType = GraphQLInterfaceType( name='Foo', resolve_type=lambda *_: None, fields={ 'str': GraphQLField(GraphQLString) } ) BarType = GraphQLObjectType( name='Bar', fields={ 'str': GraphQLField(GraphQLString), }, interfaces=[FooType] ) Root = GraphQLObjectType( name='Root', fields={ 'bar': GraphQLField(BarType) } ) Schema = GraphQLSchema(Root) output = print_for_test(Schema) assert output == '''
def test_gevent_executor(): @run_in_greenlet def resolver(context, *_): gevent.sleep(0.001) return 'hey' @run_in_greenlet 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) }) doc = '{ a b c }' executor = Executor([GeventExecutionMiddleware()]) result = executor.execute(GraphQLSchema(Type), doc) assert not result.errors assert result.data == {'a': 'hey', 'b': 'hey2', 'c': 'hey3'}
def test_executor_can_enforce_strict_ordering(): Type = GraphQLObjectType('Type', lambda: { 'a': GraphQLField(GraphQLString, resolver=lambda *_: succeed('Apple')), 'b': GraphQLField(GraphQLString, resolver=lambda *_: succeed('Banana')), 'c': GraphQLField(GraphQLString, resolver=lambda *_: succeed('Cherry')), 'deep': GraphQLField(Type, resolver=lambda *_: succeed({})), }) schema = GraphQLSchema(query=Type) executor = Executor(map_type=OrderedDict) query = '{ a b c aa: c cc: c bb: b aaz: a bbz: b deep { b a c deeper: deep { c a b } } ' \ 'ccz: c zzz: c aaa: a }' def handle_results(result): assert not result.errors data = result.data assert isinstance(data, OrderedDict) assert list(data.keys()) == ['a', 'b', 'c', 'aa', 'cc', 'bb', 'aaz', 'bbz', 'deep', 'ccz', 'zzz', 'aaa'] deep = data['deep'] assert isinstance(deep, OrderedDict) assert list(deep.keys()) == ['b', 'a', 'c', 'deeper'] deeper = deep['deeper'] assert isinstance(deeper, OrderedDict) assert list(deeper.keys()) == ['c', 'a', 'b'] raise_callback_results(executor.execute(schema, query), handle_results) raise_callback_results(executor.execute(schema, query, execute_serially=True), handle_results)
def test_respects_the_includedeprecated_parameter_for_fields(): TestType = GraphQLObjectType( 'TestType', { 'nonDeprecated': GraphQLField(GraphQLString), 'deprecated': GraphQLField(GraphQLString, deprecation_reason='Removed in 1.0') }) schema = GraphQLSchema(TestType) request = '''{__type(name: "TestType") { name trueFields: fields(includeDeprecated: true) { name } falseFields: fields(includeDeprecated: false) { name } omittedFields: fields { name } } }''' result = graphql(schema, request) assert not result.errors assert sort_lists(result.data) == sort_lists({ '__type': { 'name': 'TestType', 'trueFields': [{ 'name': 'nonDeprecated' }, { 'name': 'deprecated' }], 'falseFields': [{ 'name': 'nonDeprecated' }], 'omittedFields': [{ 'name': 'nonDeprecated' }], } })
def test_respects_the_includedeprecated_parameter_for_enum_values(): TestEnum = GraphQLEnumType('TestEnum', OrderedDict([ ('NONDEPRECATED', GraphQLEnumValue(0)), ('DEPRECATED', GraphQLEnumValue(1, deprecation_reason='Removed in 1.0')), ('ALSONONDEPRECATED', GraphQLEnumValue(2)) ])) TestType = GraphQLObjectType('TestType', { 'testEnum': GraphQLField(TestEnum) }) schema = GraphQLSchema(TestType) request = '''{__type(name: "TestEnum") { name trueValues: enumValues(includeDeprecated: true) { name } falseValues: enumValues(includeDeprecated: false) { name } omittedValues: enumValues { name } } }''' result = graphql(schema, request) assert not result.errors assert result.data == {'__type': { 'name': 'TestEnum', 'trueValues': [{'name': 'NONDEPRECATED'}, {'name': 'DEPRECATED'}, {'name': 'ALSONONDEPRECATED'}], 'falseValues': [{'name': 'NONDEPRECATED'}, {'name': 'ALSONONDEPRECATED'}], 'omittedValues': [{'name': 'NONDEPRECATED'}, {'name': 'ALSONONDEPRECATED'}], }}
def test_includes_interfaces_thunk_subtypes_in_the_type_map(): SomeInterface = GraphQLInterfaceType( name='SomeInterface', fields={ 'f': GraphQLField(GraphQLInt) } ) SomeSubtype = GraphQLObjectType( name='SomeSubtype', fields={ 'f': GraphQLField(GraphQLInt) }, interfaces=lambda: [SomeInterface], is_type_of=lambda: True ) schema = GraphQLSchema(query=GraphQLObjectType( name='Query', fields={ 'iface': GraphQLField(SomeInterface) } )) assert schema.get_type_map()['SomeSubtype'] is SomeSubtype
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 = executor.execute(schema, ast, data) assert response.called response = response.result 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_identifies_deprecated_enum_values(): TestEnum = GraphQLEnumType('TestEnum', OrderedDict([ ('NONDEPRECATED', GraphQLEnumValue(0)), ('DEPRECATED', GraphQLEnumValue(1, deprecation_reason='Removed in 1.0')), ('ALSONONDEPRECATED', GraphQLEnumValue(2)) ])) TestType = GraphQLObjectType('TestType', { 'testEnum': GraphQLField(TestEnum) }) schema = GraphQLSchema(TestType) request = '''{__type(name: "TestEnum") { name enumValues(includeDeprecated: true) { name isDeprecated deprecationReason } } }''' result = graphql(schema, request) assert not result.errors assert result.data == {'__type': { 'name': 'TestEnum', 'enumValues': [ {'name': 'NONDEPRECATED', 'isDeprecated': False, 'deprecationReason': None}, {'name': 'DEPRECATED', 'isDeprecated': True, 'deprecationReason': 'Removed in 1.0'}, {'name': 'ALSONONDEPRECATED', 'isDeprecated': False, 'deprecationReason': None}, ]}}
def test_executor_defer_failure(): class Data(object): def promise(self): return fail(Exception('Something bad happened! Sucks :(')) def notPromise(self): return 'i should work' DataType = GraphQLObjectType( 'DataType', { 'promise': GraphQLField(GraphQLNonNull(GraphQLString)), 'notPromise': GraphQLField(GraphQLString), }) doc = ''' query Example { promise notPromise } ''' schema = GraphQLSchema(query=DataType) executor = Executor() result = executor.execute(schema, doc, Data(), operation_name='Example') assert result.called result = result.result assert result.data is None formatted_errors = list(map(format_error, result.errors)) assert formatted_errors == [{ 'locations': [dict(line=3, column=9)], 'message': "Something bad happened! Sucks :(" }]
def test_synchronous_executor_doesnt_support_defers(): class Data(object): def promise(self): return succeed('i shouldn\'nt work') def notPromise(self): return 'i should work' DataType = GraphQLObjectType( 'DataType', { 'promise': GraphQLField(GraphQLNonNull(GraphQLString)), 'notPromise': GraphQLField(GraphQLString), }) doc = ''' query Example { promise notPromise } ''' schema = GraphQLSchema(query=DataType) executor = Executor([SynchronousExecutionMiddleware()]) result = executor.execute(schema, doc, Data(), operation_name='Example') assert not isinstance(result, Deferred) assert result.data is None formatted_errors = list(map(format_error, result.errors)) assert formatted_errors == [{ 'locations': [dict(line=3, column=9)], 'message': 'You cannot return a Deferred from a resolver ' 'when using SynchronousExecutionMiddleware' }]
def test_defines_a_query_only_schema(): BlogSchema = GraphQLSchema(BlogQuery) assert BlogSchema.get_query_type() == BlogQuery article_field = BlogQuery.get_fields()['article'] assert article_field.type == BlogArticle assert article_field.type.name == 'Article' assert article_field.name == 'article' article_field_type = article_field.type assert isinstance(article_field_type, GraphQLObjectType) title_field = article_field_type.get_fields()['title'] assert title_field.name == 'title' assert title_field.type == GraphQLString assert title_field.type.name == 'String' author_field = article_field_type.get_fields()['author'] author_field_type = author_field.type assert isinstance(author_field_type, GraphQLObjectType) recent_article_field = author_field_type.get_fields()['recentArticle'] assert recent_article_field.type == BlogArticle feed_field = BlogQuery.get_fields()['feed'] assert feed_field.type.of_type == BlogArticle assert feed_field.name == 'feed'
def test_supports_the_type_root_field(): TestType = GraphQLObjectType('TestType', {'testField': GraphQLField(GraphQLString)}) schema = GraphQLSchema(TestType) request = '{ __type(name: "TestType") { name } }' result = execute(schema, object(), parse(request)) assert not result.errors assert result.data == {'__type': {'name': 'TestType'}}
def test_includes_interfaces_subtypes_in_the_type_map(): SomeInterface = GraphQLInterfaceType('SomeInterface') SomeSubtype = GraphQLObjectType(name='SomeSubtype', fields={}, interfaces=[SomeInterface]) schema = GraphQLSchema(SomeInterface) assert schema.get_type_map()['SomeSubtype'] == SomeSubtype