def test_stringifies_simple_types(): assert str(GraphQLInt) == 'Int' assert str(BlogArticle) == 'Article' assert str(InterfaceType) == 'Interface' assert str(UnionType) == 'Union' assert str(EnumType) == 'Enum' assert str(InputObjectType) == 'InputObject' assert str(GraphQLNonNull(GraphQLInt)) == 'Int!' assert str(GraphQLList(GraphQLInt)) == '[Int]' assert str(GraphQLNonNull(GraphQLList(GraphQLInt))) == '[Int]!' assert str(GraphQLList(GraphQLNonNull(GraphQLInt))) == '[Int!]' assert str(GraphQLList(GraphQLList(GraphQLInt))) == '[[Int]]'
def test_builds_a_schema_with_complex_field_values(): schema = GraphQLSchema(query=GraphQLObjectType( name='ComplexFields', fields=OrderedDict( [('string', GraphQLField(GraphQLString) ), ('listOfString', GraphQLField(GraphQLList(GraphQLString))), ('nonNullString', GraphQLField(GraphQLNonNull(GraphQLString))), ('nonNullListOfString', GraphQLField(GraphQLNonNull(GraphQLList(GraphQLString)))), ('nonNullListOfNonNullString', GraphQLField( GraphQLNonNull(GraphQLList(GraphQLNonNull(GraphQLString)))) )]))) _test_schema(schema)
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_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_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)
class TestNotNullListOfNotNullT_Array_T: # [T!]! Array<T> type = GraphQLNonNull(GraphQLList(GraphQLNonNull(GraphQLInt))) test_contains_values = check([1, 2], {'data': {'nest': {'test': [1, 2]}}}) test_contains_null = check( [1, None, 2], { 'data': { 'nest': None }, 'errors': [{ 'locations': [{ 'column': 10, 'line': 1 }], 'message': 'Cannot return null for non-nullable field DataType.test.' }] }) test_returns_null = check( None, { 'data': { 'nest': None }, 'errors': [{ 'locations': [{ 'column': 10, 'line': 1 }], 'message': 'Cannot return null for non-nullable field DataType.test.' }] })
class Test_ListOfT_Array_Promise_T: # [T] Array<Promise<T>> type = GraphQLList(GraphQLInt) test_contains_values = check([succeed(1), succeed(2)], {'data': { 'nest': { 'test': [1, 2] } }}) test_contains_null = check( [succeed(1), succeed(None), succeed(2)], {'data': { 'nest': { 'test': [1, None, 2] } }}) test_contains_reject = check( lambda: [succeed(1), fail(Exception('bad')), succeed(2)], { 'data': { 'nest': { 'test': [1, None, 2] } }, 'errors': [{ 'locations': [{ 'column': 10, 'line': 1 }], 'message': 'bad' }] })
def test_nullable_list_of_nullables(): type = GraphQLList(GraphQLInt) # [T] # Contains values check(type, [1, 2], {'nest': {'test': [1, 2]}}) # Contains null check(type, [1, None, 2], {'nest': {'test': [1, None, 2]}}) # Returns null check(type, None, {'nest': {'test': None}})
def test_fails_on_a_deep_non_null(): schema = GraphQLSchema(query=GraphQLObjectType( name='Query', fields={ 'foo': GraphQLField( GraphQLList( GraphQLList(GraphQLList(GraphQLNonNull(GraphQLString))))) })) introspection = graphql(schema, introspection_query) with raises(Exception) as excinfo: build_client_schema(introspection.data) assert str( excinfo.value) == 'Decorated type deeper than introspection query.'
def test_identifies_output_types(): expected = ((GraphQLInt, True), (ObjectType, True), (InterfaceType, True), (UnionType, True), (EnumType, True), (InputObjectType, False)) for type, answer in expected: assert is_output_type(type) == answer assert is_output_type(GraphQLList(type)) == answer assert is_output_type(GraphQLNonNull(type)) == answer
class Test_ListOfT_Array_T: # [T] Array<T> type = GraphQLList(GraphQLInt) test_contains_values = check([1, 2], {'data': {'nest': {'test': [1, 2]}}}) test_contains_null = check([1, None, 2], {'data': { 'nest': { 'test': [1, None, 2] } }}) test_returns_null = check(None, {'data': {'nest': {'test': None}}})
def test_prohibits_putting_non_object_types_in_unions(): bad_union_types = [ GraphQLInt, GraphQLNonNull(GraphQLInt), GraphQLList(GraphQLInt), InterfaceType, UnionType, EnumType, InputObjectType ] for x in bad_union_types: with raises(Exception) as excinfo: GraphQLUnionType('BadUnion', [x]) assert 'Union BadUnion may only contain object types, it cannot contain: ' + str(x) + '.' \ == str(excinfo.value)
def test_nullable_list_of_non_nullables(): type = GraphQLList(GraphQLNonNull(GraphQLInt)) # [T!] # Contains values check(type, [1, 2], {'nest': {'test': [1, 2]}}) # Contains null result = run(type, [1, None, 2]) assert len(result.errors) == 1 assert result.errors[0]['message'] == 'Cannot return null for non-nullable type.' # TODO: check error location assert result.data == {'nest': {'test': None}} # Returns null check(type, None, {'nest': {'test': None}})
class TestNotNullListOfNotNullT_Promise_Array_T: # [T!]! Promise<Array<T>> type = GraphQLNonNull(GraphQLList(GraphQLNonNull(GraphQLInt))) test_contains_value = check(succeed([1, 2]), {'data': { 'nest': { 'test': [1, 2] } }}) test_contains_null = check( succeed([1, None, 2]), { 'data': { 'nest': None }, 'errors': [{ 'locations': [{ 'column': 10, 'line': 1 }], 'message': 'Cannot return null for non-nullable field DataType.test.' }] }) test_returns_null = check( succeed(None), { 'data': { 'nest': None }, 'errors': [{ 'locations': [{ 'column': 10, 'line': 1 }], 'message': 'Cannot return null for non-nullable field DataType.test.' }] }) test_rejected = check( lambda: fail(Exception('bad')), { 'data': { 'nest': None }, 'errors': [{ 'locations': [{ 'column': 10, 'line': 1 }], 'message': 'bad' }] })
def test_builds_a_schema_with_field_arguments_with_default_values(): GeoType = GraphQLInputObjectType( name='Geo', fields=OrderedDict([ ('lat', GraphQLInputObjectField(GraphQLFloat)), ('lon', GraphQLInputObjectField(GraphQLFloat)), ]) ) schema = GraphQLSchema( query=GraphQLObjectType( name='ArgFields', fields=OrderedDict([ ('defaultInt', GraphQLField( GraphQLString, args={ 'intArg': GraphQLArgument( GraphQLInt, default_value=10 ) } )), ('defaultList', GraphQLField( GraphQLString, args={ 'listArg': GraphQLArgument( GraphQLList(GraphQLInt), default_value=[1, 2, 3] ) } )), ('defaultObject', GraphQLField( GraphQLString, args={ 'objArg': GraphQLArgument( GeoType, default_value={'lat': 37.485, 'lon': -122.148} ) } )) ]) ) ) _test_schema(schema)
class TestListOfNotNullT_Array_Promise_T: # [T!] Array<Promise<T>> type = GraphQLList(GraphQLNonNull(GraphQLInt)) test_contains_values = check([succeed(1), succeed(2)], {'data': { 'nest': { 'test': [1, 2] } }}) test_contains_null = check( [succeed(1), succeed(None), succeed(2)], { 'data': { 'nest': { 'test': None } }, 'errors': [{ 'locations': [{ 'column': 10, 'line': 1 }], 'message': 'Cannot return null for non-nullable field DataType.test.' }] }) test_contains_reject = check( lambda: [succeed(1), fail(Exception('bad')), succeed(2)], { 'data': { 'nest': { 'test': None } }, 'errors': [{ 'locations': [{ 'column': 10, 'line': 1 }], 'message': 'bad' }] })
class Test_ListOfT_Promise_Array_T: # [T] Promise<Array<T>> type = GraphQLList(GraphQLInt) test_contains_values = check(succeed([1, 2]), {'data': { 'nest': { 'test': [1, 2] } }}) test_contains_null = check(succeed([1, None, 2]), {'data': { 'nest': { 'test': [1, None, 2] } }}) test_returns_null = check(succeed(None), {'data': { 'nest': { 'test': None } }}) test_rejected = check( lambda: fail(Exception('bad')), { 'data': { 'nest': { 'test': None } }, 'errors': [{ 'locations': [{ 'column': 10, 'line': 1 }], 'message': 'bad' }] })
def test_prints_non_null_list_non_null_string_field(): output = print_single_field_schema( GraphQLField(GraphQLNonNull(GraphQLList( GraphQLNonNull(GraphQLString))))) assert output == '''
def test_synchronous_error_nulls_out_error_subtrees(): doc = ''' { sync syncError syncReturnError syncReturnErrorList async asyncReject asyncEmptyReject asyncReturnError } ''' class Data: def sync(self): return 'sync' def syncError(self): raise Exception('Error getting syncError') def syncReturnError(self): return Exception("Error getting syncReturnError") def syncReturnErrorList(self): return [ 'sync0', Exception('Error getting syncReturnErrorList1'), 'sync2', Exception('Error getting syncReturnErrorList3') ] def async (self): return succeed('async') def asyncReject(self): return fail(Exception('Error getting asyncReject')) def asyncEmptyReject(self): return fail() def asyncReturnError(self): return succeed(Exception('Error getting asyncReturnError')) schema = GraphQLSchema(query=GraphQLObjectType( name='Type', fields={ 'sync': GraphQLField(GraphQLString), 'syncError': GraphQLField(GraphQLString), 'syncReturnError': GraphQLField(GraphQLString), 'syncReturnErrorList': GraphQLField(GraphQLList(GraphQLString)), 'async': GraphQLField(GraphQLString), 'asyncReject': GraphQLField(GraphQLString), 'asyncEmptyReject': GraphQLField(GraphQLString), 'asyncReturnError': GraphQLField(GraphQLString), })) executor = Executor(map_type=OrderedDict) def handle_results(result): assert result.data == { 'async': 'async', 'asyncEmptyReject': None, 'asyncReject': None, 'asyncReturnError': None, 'sync': 'sync', 'syncError': None, 'syncReturnError': None, 'syncReturnErrorList': ['sync0', None, 'sync2', None] } assert list(map(format_error, result.errors)) == [{ 'locations': [{ 'line': 4, 'column': 9 }], 'message': 'Error getting syncError' }, { 'locations': [{ 'line': 5, 'column': 9 }], 'message': 'Error getting syncReturnError' }, { 'locations': [{ 'line': 6, 'column': 9 }], 'message': 'Error getting syncReturnErrorList1' }, { 'locations': [{ 'line': 6, 'column': 9 }], 'message': 'Error getting syncReturnErrorList3' }, { 'locations': [{ 'line': 8, 'column': 9 }], 'message': 'Error getting asyncReject' }, { 'locations': [{ 'line': 9, 'column': 9 }], 'message': 'An unknown error occurred.' }, { 'locations': [{ 'line': 10, 'column': 9 }], 'message': 'Error getting asyncReturnError' }] raise_callback_results(executor.execute(schema, doc, Data()), handle_results)
def test_executes_arbitary_code(): class Data(object): a = 'Apple' b = 'Banana' c = 'Cookie' d = 'Donut' e = 'Egg' @property def f(self): return succeed('Fish') def pic(self, size=50): return succeed('Pic of size: {}'.format(size)) def deep(self): return DeepData() def promise(self): return succeed(Data()) class DeepData(object): a = 'Already Been Done' b = 'Boring' c = ['Contrived', None, succeed('Confusing')] def deeper(self): return [Data(), None, succeed(Data())] doc = ''' query Example($size: Int) { a, b, x: c ...c f ...on DataType { pic(size: $size) promise { a } } deep { a b c deeper { a b } } } fragment c on DataType { d e } ''' expected = { 'a': 'Apple', 'b': 'Banana', 'x': 'Cookie', 'd': 'Donut', 'e': 'Egg', 'f': 'Fish', 'pic': 'Pic of size: 100', 'promise': { 'a': 'Apple' }, 'deep': { 'a': 'Already Been Done', 'b': 'Boring', 'c': ['Contrived', None, 'Confusing'], 'deeper': [{ 'a': 'Apple', 'b': 'Banana' }, None, { 'a': 'Apple', 'b': 'Banana' }] } } DataType = GraphQLObjectType( 'DataType', lambda: { 'a': GraphQLField(GraphQLString), 'b': GraphQLField(GraphQLString), 'c': GraphQLField(GraphQLString), 'd': GraphQLField(GraphQLString), 'e': GraphQLField(GraphQLString), 'f': GraphQLField(GraphQLString), 'pic': GraphQLField( args={'size': GraphQLArgument(GraphQLInt)}, type=GraphQLString, resolver=lambda obj, args, *_: obj.pic(args['size']), ), 'deep': GraphQLField(DeepDataType), 'promise': GraphQLField(DataType), }) DeepDataType = GraphQLObjectType( 'DeepDataType', { 'a': GraphQLField(GraphQLString), 'b': GraphQLField(GraphQLString), 'c': GraphQLField(GraphQLList(GraphQLString)), 'deeper': GraphQLField(GraphQLList(DataType)), }) schema = GraphQLSchema(query=DataType) executor = Executor() def handle_result(result): assert not result.errors assert result.data == expected raise_callback_results( executor.execute(schema, doc, Data(), {'size': 100}, 'Example'), handle_result) raise_callback_results( executor.execute(schema, doc, Data(), {'size': 100}, 'Example', execute_serially=True), handle_result)
GraphQLString, GraphQLNonNull, GraphQLScalarType, ) from graphql.core.error import GraphQLError, format_error TestComplexScalar = GraphQLScalarType( name='ComplexScalar', serialize=lambda v: 'SerializedValue' if v == 'DeserializedValue' else None, parse_value=lambda v: 'DeserializedValue' if v == 'SerializedValue' else None, parse_literal=lambda v: 'DeserializedValue' if v.value == 'SerializedValue' else None ) TestInputObject = GraphQLInputObjectType('TestInputObject', { 'a': GraphQLInputObjectField(GraphQLString), 'b': GraphQLInputObjectField(GraphQLList(GraphQLString)), 'c': GraphQLInputObjectField(GraphQLNonNull(GraphQLString)), 'd': GraphQLInputObjectField(TestComplexScalar) }) stringify = lambda obj: json.dumps(obj, sort_keys=True) def input_to_json(obj, args, info): input = args.get('input') if input: return stringify(input) TestNestedInputObject = GraphQLInputObjectType( name='TestNestedInputObject',
'id': GraphQLField(GraphQLString), 'isPublished': GraphQLField(GraphQLBoolean), 'author': GraphQLField(BlogAuthor), 'title': GraphQLField(GraphQLString), 'body': GraphQLField(GraphQLString), }) BlogQuery = GraphQLObjectType( 'Query', { 'article': GraphQLField(BlogArticle, args={ 'id': GraphQLArgument(GraphQLString), }), 'feed': GraphQLField(GraphQLList(BlogArticle)) }) BlogMutation = GraphQLObjectType('Mutation', {'writeArticle': GraphQLField(BlogArticle)}) ObjectType = GraphQLObjectType('Object', {}) InterfaceType = GraphQLInterfaceType('Interface') UnionType = GraphQLUnionType('Union', [ObjectType]) EnumType = GraphQLEnumType('Enum', {}) InputObjectType = GraphQLInputObjectType('InputObject', {}) def test_defines_a_query_only_schema(): BlogSchema = GraphQLSchema(BlogQuery)
# Test schema. SomeInterfaceType = GraphQLInterfaceType( name='SomeInterface', resolve_type=lambda: FooType, fields=lambda: OrderedDict([ ('name', GraphQLField(GraphQLString)), ('some', GraphQLField(SomeInterfaceType)), ])) FooType = GraphQLObjectType( name='Foo', interfaces=[SomeInterfaceType], fields=lambda: OrderedDict([ ('name', GraphQLField(GraphQLString)), ('some', GraphQLField(SomeInterfaceType)), ('tree', GraphQLField(GraphQLNonNull(GraphQLList(FooType)))), ])) BarType = GraphQLObjectType(name='Bar', interfaces=[SomeInterfaceType], fields=lambda: OrderedDict([ ('name', GraphQLField(GraphQLString)), ('some', GraphQLField(SomeInterfaceType)), ('foo', GraphQLField(FooType)), ])) BizType = GraphQLObjectType(name='Biz', fields=lambda: OrderedDict([ ('fizz', GraphQLField(GraphQLString)), ]))
def test_introspects_on_input_object(): TestInputObject = GraphQLInputObjectType( 'TestInputObject', { 'a': GraphQLInputObjectField(GraphQLString, default_value='foo'), 'b': GraphQLInputObjectField(GraphQLList(GraphQLString)), }) TestType = GraphQLObjectType( 'TestType', { 'field': GraphQLField(type=GraphQLString, args={'complex': GraphQLArgument(TestInputObject)}, resolver=lambda obj, args, info: json.dumps( args.get('complex'))) }) schema = GraphQLSchema(TestType) request = ''' { __schema { types { kind name inputFields { name type { ...TypeRef } defaultValue } } } } fragment TypeRef on __Type { kind name ofType { kind name ofType { kind name ofType { kind name } } } } ''' result = graphql(schema, request) assert not result.errors assert sort_lists({'kind': 'INPUT_OBJECT', 'name': 'TestInputObject', 'inputFields': [{'name': 'a', 'type': {'kind': 'SCALAR', 'name': 'String', 'ofType': None}, 'defaultValue': '"foo"'}, {'name': 'b', 'type': {'kind': 'LIST', 'name': None, 'ofType': {'kind': 'SCALAR', 'name': 'String', 'ofType': None}}, 'defaultValue': None}]}) in \ sort_lists(result.data['__schema']['types'])
def test_executes_arbitary_code(): class Data(object): a = 'Apple' b = 'Banana' c = 'Cookie' d = 'Donut' e = 'Egg' f = 'Fish' def pic(self, size=50): return 'Pic of size: {}'.format(size) def deep(self): return DeepData() def promise(self): # FIXME: promise is unsupported return Data() class DeepData(object): a = 'Already Been Done' b = 'Boring' c = ['Contrived', None, 'Confusing'] def deeper(self): return [Data(), None, Data()] doc = ''' query Example($size: Int) { a, b, x: c ...c f ...on DataType { pic(size: $size) promise { a } } deep { a b c deeper { a b } } } fragment c on DataType { d e } ''' ast = parse(doc) expected = { 'a': 'Apple', 'b': 'Banana', 'x': 'Cookie', 'd': 'Donut', 'e': 'Egg', 'f': 'Fish', 'pic': 'Pic of size: 100', 'promise': {'a': 'Apple'}, 'deep': { 'a': 'Already Been Done', 'b': 'Boring', 'c': ['Contrived', None, 'Confusing'], 'deeper': [ {'a': 'Apple', 'b': 'Banana'}, None, {'a': 'Apple', 'b': 'Banana'}]} } DataType = GraphQLObjectType('DataType', lambda: { 'a': GraphQLField(GraphQLString), 'b': GraphQLField(GraphQLString), 'c': GraphQLField(GraphQLString), 'd': GraphQLField(GraphQLString), 'e': GraphQLField(GraphQLString), 'f': GraphQLField(GraphQLString), 'pic': GraphQLField( args={'size': GraphQLArgument(GraphQLInt)}, type=GraphQLString, resolver=lambda obj, args, *_: obj.pic(args['size']), ), 'deep': GraphQLField(DeepDataType), 'promise': GraphQLField(DataType), }) DeepDataType = GraphQLObjectType('DeepDataType', { 'a': GraphQLField(GraphQLString), 'b': GraphQLField(GraphQLString), 'c': GraphQLField(GraphQLList(GraphQLString)), 'deeper': GraphQLField(GraphQLList(DataType)), }) schema = GraphQLSchema(query=DataType) result = execute(schema, Data(), ast, 'Example', {'size': 100}) assert not result.errors assert result.data == expected
def test_executes_using_a_schema(): BlogImage = GraphQLObjectType( 'BlogImage', { 'url': GraphQLField(GraphQLString), 'width': GraphQLField(GraphQLInt), 'height': GraphQLField(GraphQLInt), }) BlogAuthor = GraphQLObjectType( 'Author', lambda: { 'id': GraphQLField(GraphQLString), 'name': GraphQLField(GraphQLString), 'pic': GraphQLField(BlogImage, args={ 'width': GraphQLArgument(GraphQLInt), 'height': GraphQLArgument(GraphQLInt), }, resolver=lambda obj, args, *_: obj.pic( args['width'], args['height'])), 'recentArticle': GraphQLField(BlogArticle), }) BlogArticle = GraphQLObjectType( 'Article', { 'id': GraphQLField(GraphQLNonNull(GraphQLString)), 'isPublished': GraphQLField(GraphQLBoolean), 'author': GraphQLField(BlogAuthor), 'title': GraphQLField(GraphQLString), 'body': GraphQLField(GraphQLString), 'keywords': GraphQLField(GraphQLList(GraphQLString)), }) BlogQuery = GraphQLObjectType( 'Query', { 'article': GraphQLField(BlogArticle, args={'id': GraphQLArgument(GraphQLID)}, resolver=lambda obj, args, *_: Article(args['id'])), 'feed': GraphQLField(GraphQLList(BlogArticle), resolver=lambda *_: map(Article, range(1, 10 + 1))), }) BlogSchema = GraphQLSchema(BlogQuery) class Article(object): def __init__(self, id): self.id = id self.isPublished = True self.author = Author() self.title = 'My Article {}'.format(id) self.body = 'This is a post' self.hidden = 'This data is not exposed in the schema' self.keywords = ['foo', 'bar', 1, True, None] class Author(object): id = 123 name = 'John Smith' def pic(self, width, height): return Pic(123, width, height) @property def recentArticle(self): return Article(1) class Pic(object): def __init__(self, uid, width, height): self.url = 'cdn://{}'.format(uid) self.width = str(width) self.height = str(height) request = ''' { feed { id, title }, article(id: "1") { ...articleFields, author { id, name, pic(width: 640, height: 480) { url, width, height }, recentArticle { ...articleFields, keywords } } } } fragment articleFields on Article { id, isPublished, title, body, hidden, notdefined } ''' # Note: this is intentionally not validating to ensure appropriate # behavior occurs when executing an invalid query. result = execute(BlogSchema, None, parse(request)) assert not result.errors assert result.data == \ { "feed": [ { "id": "1", "title": "My Article 1" }, { "id": "2", "title": "My Article 2" }, { "id": "3", "title": "My Article 3" }, { "id": "4", "title": "My Article 4" }, { "id": "5", "title": "My Article 5" }, { "id": "6", "title": "My Article 6" }, { "id": "7", "title": "My Article 7" }, { "id": "8", "title": "My Article 8" }, { "id": "9", "title": "My Article 9" }, { "id": "10", "title": "My Article 10" } ], "article": { "id": "1", "isPublished": True, "title": "My Article 1", "body": "This is a post", "author": { "id": "123", "name": "John Smith", "pic": { "url": "cdn://123", "width": 640, "height": 480 }, "recentArticle": { "id": "1", "isPublished": True, "title": "My Article 1", "body": "This is a post", "keywords": [ "foo", "bar", "1", "true", None ] } } } }
description='Released in 1983.', ) }) characterInterface = GraphQLInterfaceType( 'Character', description='A character in the Star Wars Trilogy', fields=lambda: { 'id': GraphQLField(GraphQLNonNull(GraphQLString), description='The id of the character.'), 'name': GraphQLField(GraphQLString, description='The name of the character.'), 'friends': GraphQLField( GraphQLList(characterInterface), description= 'The friends of the character, or an empty list if they have none.' ), 'appearsIn': GraphQLField(GraphQLList(episodeEnum), description='Which movies they appear in.'), }, resolve_type=lambda character, *_: humanType if starwars_fixtures.getHuman(character.id) else droidType, ) humanType = GraphQLObjectType( 'Human', description='A humanoid creature in the Star Wars universe.', fields=lambda: {
CatOrDog = GraphQLUnionType('CatOrDog', [Dog, Cat]) Intelligent = GraphQLInterfaceType('Intelligent', { 'iq': GraphQLField(GraphQLInt), }) Human = GraphQLObjectType( name='Human', interfaces=[Being, Intelligent], is_type_of=lambda: None, fields={ 'name': GraphQLField(GraphQLString, { 'surname': GraphQLArgument(GraphQLBoolean), }), 'pets': GraphQLField(GraphQLList(Pet)), 'iq': GraphQLField(GraphQLInt), }, ) Alien = GraphQLObjectType( name='Alien', is_type_of=lambda *args: True, interfaces=[Being, Intelligent], fields={ 'iq': GraphQLField(GraphQLInt), 'name': GraphQLField(GraphQLString, { 'surname': GraphQLArgument(GraphQLBoolean), }), 'numEyes': GraphQLField(GraphQLInt), },
def resolve_pet_type(value): if isinstance(value, Dog): return DogType if isinstance(value, Cat): return CatType PetType = GraphQLUnionType('Pet', [DogType, CatType], resolve_type=resolve_pet_type) PersonType = GraphQLObjectType( name='Person', interfaces=[NamedType], fields={ 'name': GraphQLField(GraphQLString), 'pets': GraphQLField(GraphQLList(PetType)), 'friends': GraphQLField(GraphQLList(NamedType)), }, is_type_of=lambda value: isinstance(value, Person)) schema = GraphQLSchema(PersonType) garfield = Cat('Garfield', False) odie = Dog('Odie', True) liz = Person('Liz', [], []) john = Person('John', [garfield, odie], [liz, odie]) # Execute: Union and intersection types def test_can_introspect_on_union_and_intersetion_types():
interfaces=[Pet]) Cat = GraphQLObjectType('Cat', lambda: {'furColor': GraphQLField(FurColor)}, interfaces=[Pet]) CatOrDog = GraphQLUnionType('CatOrDog', [Dog, Cat]) Human = GraphQLObjectType( 'Human', { 'name': GraphQLField(GraphQLString, { 'surname': GraphQLArgument(GraphQLBoolean), }), 'pets': GraphQLField(GraphQLList(Pet)), }) FurColor = GraphQLEnumType( 'FurColor', { 'BROWN': GraphQLEnumValue(0), 'BLACK': GraphQLEnumValue(1), 'TAN': GraphQLEnumValue(2), 'SPOTTED': GraphQLEnumValue(3), }) ComplexInput = GraphQLInputObjectType( 'ComplexInput', {'stringField': GraphQLField(GraphQLString)}) ComplicatedArgs = GraphQLObjectType( 'ComplicatedArgs', {