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 prints_unions(): foo_type = GraphQLObjectType( name="Foo", fields={"bool": GraphQLField(GraphQLBoolean)}) bar_type = GraphQLObjectType( name="Bar", fields={"str": GraphQLField(GraphQLString)}) single_union = GraphQLUnionType(name="SingleUnion", types=[foo_type]) multiple_union = GraphQLUnionType(name="MultipleUnion", types=[foo_type, bar_type]) schema = GraphQLSchema(types=[single_union, multiple_union]) output = print_for_test(schema) assert output == dedent(""" union SingleUnion = Foo type Foo { bool: Boolean } union MultipleUnion = Foo | Bar type Bar { str: String } """)
def rejects_a_union_type_without_types(): with raises(TypeError) as exc_info: # noinspection PyArgumentList schema_with_field_type(GraphQLUnionType("SomeUnion")) msg = str(exc_info.value) assert "missing 1 required positional argument: 'types'" in msg schema_with_field_type(GraphQLUnionType("SomeUnion", None))
def with_extensions(): union_extensions = {"SomeUnionExt": "union"} some_union = GraphQLUnionType("SomeUnion", [], extensions=union_extensions) assert some_union.extensions is union_extensions assert some_union.to_kwargs()["extensions"] is union_extensions
def accepts_a_union_type_without_types(): with raises(TypeError, match="missing 1 required positional argument: 'types'"): # noinspection PyArgumentList GraphQLUnionType("SomeUnion") union_type = GraphQLUnionType("SomeUnion", None) assert union_type.types == [] union_type = GraphQLUnionType("SomeUnion", []) assert union_type.types == []
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 == """ schema { query: Root } type Bar { str: String } type Foo { bool: Boolean } union MultipleUnion = Foo | Bar type Root { single: SingleUnion multiple: MultipleUnion } union SingleUnion = Foo """ )
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 rejects_a_union_type_with_incorrectly_typed_types(): with raises(TypeError) as exc_info: schema_with_field_type( GraphQLUnionType("SomeUnion", {"type": ObjectType})) msg = str(exc_info.value) assert msg == ("SomeUnion types must be a list/tuple" " or a function which returns a list/tuple.")
def prints_empty_types(): schema = GraphQLSchema( types=[ GraphQLEnumType("SomeEnum", cast(Dict[str, Any], {})), GraphQLInputObjectType("SomeInputObject", {}), GraphQLInterfaceType("SomeInterface", {}), GraphQLObjectType("SomeObject", {}), GraphQLUnionType("SomeUnion", []), ] ) output = print_for_test(schema) assert output == dedent( """ enum SomeEnum input SomeInputObject interface SomeInterface type SomeObject union SomeUnion """ )
def visit_object(self, object_: GraphQLObjectType): try: types = self.schema.type_map["_Entity"].types except KeyError: u = self.schema.type_map["_Entity"] = GraphQLUnionType("_Entity", []) types = u.types types.append(object_)
def prints_unions(): FooType = GraphQLObjectType( name="Foo", fields={"bool": GraphQLField(GraphQLBoolean)} ) BarType = GraphQLObjectType( name="Bar", fields={"str": GraphQLField(GraphQLString)} ) SingleUnion = GraphQLUnionType(name="SingleUnion", types=[FooType]) MultipleUnion = GraphQLUnionType(name="MultipleUnion", types=[FooType, BarType]) Root = GraphQLObjectType( name="Root", fields={ "single": GraphQLField(SingleUnion), "multiple": GraphQLField(MultipleUnion), }, ) Schema = GraphQLSchema(Root) output = print_for_test(Schema) assert output == dedent( """ schema { query: Root } type Bar { str: String } type Foo { bool: Boolean } union MultipleUnion = Foo | Bar type Root { single: SingleUnion multiple: MultipleUnion } union SingleUnion = Foo """ )
def rejects_an_interface_type_with_an_incorrect_type_for_resolve_type(): with raises(TypeError) as exc_info: # noinspection PyTypeChecker GraphQLUnionType("SomeUnion", [], resolve_type={}) msg = str(exc_info.value) assert msg == ( "SomeUnion must provide 'resolve_type' as a function, but got: {}." )
def test_is_type_sub_type_of_member_is_subtype_of_union(): member = GraphQLObjectType( name="Object", is_type_of=lambda *_: True, fields={"field": GraphQLField(GraphQLString)}, ) union = GraphQLUnionType(name="Union", types=[member]) schema = _test_schema(union) assert is_type_sub_type_of(schema, member, union)
def rejects_an_interface_type_with_an_incorrect_type_for_resolve_type(): with raises(TypeError) as exc_info: # noinspection PyTypeChecker schema_with_field_type( GraphQLUnionType('SomeUnion', [ObjectWithIsTypeOf], resolve_type={})) msg = str(exc_info.value) assert msg == ("SomeUnion must provide 'resolve_type' as a function," ' but got: {}.')
def internal_type(cls, schema): if cls._meta.abstract: raise Exception("Abstract ObjectTypes don't have a specific type.") return GraphQLUnionType( cls._meta.type_name, types=list(map(schema.T, cls._meta.types)), resolve_type=partial(cls._resolve_type, schema), description=cls._meta.description, )
def prints_unions(): FooType = GraphQLObjectType( name='Foo', fields={'bool': GraphQLField(GraphQLBoolean)}) BarType = GraphQLObjectType( name='Bar', fields={'str': GraphQLField(GraphQLString)}) SingleUnion = GraphQLUnionType(name='SingleUnion', types=[FooType]) MultipleUnion = GraphQLUnionType(name='MultipleUnion', types=[FooType, BarType]) Root = GraphQLObjectType(name='Root', fields={ 'single': GraphQLField(SingleUnion), 'multiple': GraphQLField(MultipleUnion) }) Schema = GraphQLSchema(Root) output = print_for_test(Schema) assert output == dedent(""" schema { query: Root } type Bar { str: String } type Foo { bool: Boolean } union MultipleUnion = Foo | Bar type Root { single: SingleUnion multiple: MultipleUnion } union SingleUnion = Foo """)
def builds_a_schema_with_a_union(): dog_type = GraphQLObjectType( "Dog", lambda: {"bestFriend": GraphQLField(friendly_type)}) human_type = GraphQLObjectType( "Human", lambda: {"bestFriend": GraphQLField(friendly_type)}) friendly_type = GraphQLUnionType("Friendly", types=[dog_type, human_type]) schema = GraphQLSchema( GraphQLObjectType("WithUnion", {"friendly": GraphQLField(friendly_type)})) check_schema(schema)
def builds_a_schema_with_a_union(): dog_type = GraphQLObjectType( 'Dog', lambda: {'bestFriend': GraphQLField(friendly_type)}) human_type = GraphQLObjectType( 'Human', lambda: {'bestFriend': GraphQLField(friendly_type)}) friendly_type = GraphQLUnionType('Friendly', types=[dog_type, human_type]) schema = GraphQLSchema( GraphQLObjectType('WithUnion', {'friendly': GraphQLField(friendly_type)})) check_schema(schema)
def prints_unions(): foo_type = GraphQLObjectType( name="Foo", fields={"bool": GraphQLField(GraphQLBoolean)}) bar_type = GraphQLObjectType( name="Bar", fields={"str": GraphQLField(GraphQLString)}) single_union = GraphQLUnionType(name="SingleUnion", types=[foo_type]) multiple_union = GraphQLUnionType(name="MultipleUnion", types=[foo_type, bar_type]) query = GraphQLObjectType( name="Query", fields={ "single": GraphQLField(single_union), "multiple": GraphQLField(multiple_union), }, ) schema = GraphQLSchema(query) output = print_for_test(schema) assert output == dedent(""" type Bar { str: String } type Foo { bool: Boolean } union MultipleUnion = Foo | Bar type Query { single: SingleUnion multiple: MultipleUnion } union SingleUnion = Foo """)
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 is_type_of_used_to_resolve_runtime_type_for_union(): DogType = GraphQLObjectType('Dog', { 'name': GraphQLField(GraphQLString), 'woofs': GraphQLField(GraphQLBoolean) }, is_type_of=get_is_type_of(Dog)) CatType = GraphQLObjectType('Cat', { 'name': GraphQLField(GraphQLString), 'meows': GraphQLField(GraphQLBoolean) }, is_type_of=get_is_type_of(Cat)) PetType = GraphQLUnionType('Pet', [CatType, DogType]) schema = GraphQLSchema( GraphQLObjectType( 'Query', { 'pets': GraphQLField(GraphQLList(PetType), resolve=lambda *_args: [Dog('Odie', True), Cat('Garfield', False)]) })) query = """ { pets { ... on Dog { name woofs } ... on Cat { name meows } } } """ result = graphql_sync(schema, query) assert result == ({ 'pets': [{ 'name': 'Odie', 'woofs': True }, { 'name': 'Garfield', 'meows': False }] }, 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: GraphQLSchema(GraphQLObjectType('Root', fields={'union': GraphQLField(GraphQLUnionType('BadUnion', [x]))})) assert 'BadUnion may only contain Object types, it cannot contain: ' + str(x) + '.' \ == str(excinfo.value)
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 rejects_a_union_type_with_non_object_member_types(): # invalid schema cannot be built with Python with raises(TypeError) as exc_info: build_schema( """ type Query { test: BadUnion } type TypeA { field: String } type TypeB { field: String } union BadUnion = | TypeA | String | TypeB """ ) msg = str(exc_info.value) assert msg == "BadUnion types must be GraphQLObjectType objects." bad_union_member_types = [ GraphQLString, GraphQLNonNull(SomeObjectType), GraphQLList(SomeObjectType), SomeInterfaceType, SomeUnionType, SomeEnumType, SomeInputObjectType, ] for member_type in bad_union_member_types: # invalid schema cannot be built with Python with raises(TypeError) as exc_info: schema_with_field_type( GraphQLUnionType("BadUnion", types=[member_type]) ) msg = str(exc_info.value) assert msg == "BadUnion types must be GraphQLObjectType objects."
def get_graphql_schema_from_schema_graph(schema_graph, class_to_field_type_overrides, hidden_classes): """Return a GraphQL schema object corresponding to the schema of the given schema graph. Args: schema_graph: SchemaGraph class_to_field_type_overrides: dict, class name -> {field name -> field type}, (string -> {string -> GraphQLType}). Used to override the type of a field in the class where it's first defined and all the class's subclasses. hidden_classes: set of strings, classes to not include in the GraphQL schema. Returns: tuple of (GraphQL schema object, GraphQL type equivalence hints dict). The tuple is of type (GraphQLSchema, GraphQLUnionType). """ _validate_overriden_fields_are_not_defined_in_superclasses( class_to_field_type_overrides, schema_graph) # The field types of subclasses must also be overridden. # Remember that the result returned by get_subclass_set(class_name) includes class_name itself. inherited_field_type_overrides = _get_inherited_field_types( class_to_field_type_overrides, schema_graph) # We remove the base vertex class from the schema if it has no properties. # If it has no properties, it's meaningless and makes the schema less syntactically sweet. if not schema_graph.get_element_by_class_name( ORIENTDB_BASE_VERTEX_CLASS_NAME).properties: hidden_classes.add(ORIENTDB_BASE_VERTEX_CLASS_NAME) graphql_types = OrderedDict() type_equivalence_hints = OrderedDict() # For each vertex class, construct its analogous GraphQL type representation. for vertex_cls_name in sorted(schema_graph.vertex_class_names): vertex_cls = schema_graph.get_element_by_class_name(vertex_cls_name) if vertex_cls_name in hidden_classes: continue inherited_field_type_overrides.setdefault(vertex_cls_name, dict()) field_type_overrides = inherited_field_type_overrides[vertex_cls_name] # We have to use delayed type binding here, because some of the type references # are circular: if an edge connects vertices of types A and B, then # GraphQL type A has a List[B] field, and type B has a List[A] field. # To avoid the circular dependency, GraphQL allows us to initialize the types # initially without their field information, and fill in their field information # later using a lambda function as the second argument to GraphQLObjectType. # This lambda function will be called on each type after all types are created # in their initial blank state. # # However, 'cls_name' is a variable that would not be correctly bound # if we naively tried to construct a lambda in-place, because Python lambdas # are not closures. Instead, call a function with 'cls_name' as an argument, # and have that function construct and return the required lambda. field_specification_lambda = _create_field_specification( schema_graph, graphql_types, field_type_overrides, hidden_classes, vertex_cls_name) # Abstract classes are interfaces, concrete classes are object types. current_graphql_type = None if vertex_cls.abstract: # "fields" is a kwarg in the interface constructor, even though # it's a positional arg in the object type constructor. current_graphql_type = GraphQLInterfaceType( vertex_cls_name, fields=field_specification_lambda) else: # For similar reasons as the field_specification_lambda, # we need to create an interface specification lambda function that # specifies the interfaces implemented by this type. interface_specification_lambda = _create_interface_specification( schema_graph, graphql_types, hidden_classes, vertex_cls_name) # N.B.: Ignore the "is_type_of" argument below, it is simply a circumvention of # a sanity check inside the GraphQL library. The library assumes that we'll use # its execution system, so it complains that we don't provide a means to # differentiate between different implementations of the same interface. # We don't care, because we compile the GraphQL query to a database query. current_graphql_type = GraphQLObjectType( vertex_cls_name, field_specification_lambda, interfaces=interface_specification_lambda, is_type_of=lambda: None) graphql_types[vertex_cls_name] = current_graphql_type # For each vertex class, construct all union types representations. for vertex_cls_name in sorted(schema_graph.vertex_class_names): vertex_cls = schema_graph.get_element_by_class_name(vertex_cls_name) if vertex_cls_name in hidden_classes: continue vertex_cls_subclasses = schema_graph.get_subclass_set(vertex_cls_name) if not vertex_cls.abstract and len(vertex_cls_subclasses) > 1: # In addition to creating this class' corresponding GraphQL type, we'll need a # union type to represent it when it appears as the endpoint of an edge. union_type_name = _get_union_type_name(vertex_cls_subclasses) # For similar reasons as the field_specification_lambda, # we need to create a union type specification lambda function that specifies # the types that this union type is composed of. type_specification_lambda = _create_union_types_specification( schema_graph, graphql_types, hidden_classes, vertex_cls_name) union_type = GraphQLUnionType(union_type_name, types=type_specification_lambda) graphql_types[union_type_name] = union_type type_equivalence_hints[graphql_types[vertex_cls_name]] = union_type # Include all abstract non-vertex classes whose only non-abstract subclasses are vertices. for non_graph_cls_name in sorted(schema_graph.non_graph_class_names): if non_graph_cls_name in hidden_classes: continue if not schema_graph.get_element_by_class_name( non_graph_cls_name).abstract: continue cls_subclasses = schema_graph.get_subclass_set(non_graph_cls_name) # No need to add the possible abstract class if it doesn't have subclasses besides itself. if len(cls_subclasses) > 1: all_non_abstract_subclasses_are_vertices = True # Check all non-abstract subclasses are vertices. for subclass_name in cls_subclasses: subclass = schema_graph.get_element_by_class_name( subclass_name) if subclass_name != non_graph_cls_name: if not subclass.abstract and not subclass.is_vertex: all_non_abstract_subclasses_are_vertices = False break if all_non_abstract_subclasses_are_vertices: # Add abstract class as an interface. inherited_field_type_overrides.setdefault( non_graph_cls_name, dict()) field_type_overrides = inherited_field_type_overrides[ non_graph_cls_name] field_specification_lambda = _create_field_specification( schema_graph, graphql_types, field_type_overrides, hidden_classes, non_graph_cls_name) graphql_type = GraphQLInterfaceType( non_graph_cls_name, fields=field_specification_lambda) graphql_types[non_graph_cls_name] = graphql_type if not graphql_types: raise EmptySchemaError( u'After evaluating all subclasses of V, we were not able to find ' u'visible schema data to import into the GraphQL schema object') # Create the root query GraphQL type. Consists of all non-union classes, i.e. # all non-abstract classes (as GraphQL types) and all abstract classes (as GraphQL interfaces). RootSchemaQuery = GraphQLObjectType( 'RootSchemaQuery', OrderedDict([(name, GraphQLField(value)) for name, value in sorted(six.iteritems(graphql_types), key=lambda x: x[0]) if not isinstance(value, GraphQLUnionType)])) schema = GraphQLSchema(RootSchemaQuery, directives=DIRECTIVES) return schema, type_equivalence_hints
is_named_type, is_required_argument, is_required_input_field, is_non_null_type, is_nullable_type, is_object_type, is_output_type, is_scalar_type, is_type, is_union_type, is_wrapping_type, ) ObjectType = GraphQLObjectType("Object", {}) InterfaceType = GraphQLInterfaceType("Interface", {}) UnionType = GraphQLUnionType("Union", types=[ObjectType]) EnumType = GraphQLEnumType("Enum", values={"foo": {}}) InputObjectType = GraphQLInputObjectType("InputObject", {}) ScalarType = GraphQLScalarType("Scalar", serialize=lambda: {}, parse_value=lambda: {}, parse_literal=lambda: {}) def describe_type_predicates(): def describe_is_type(): def returns_true_for_unwrapped_types(): assert is_type(GraphQLString) is True assert_type(GraphQLString) assert is_type(ObjectType) is True assert_type(ObjectType)
BlogMutation = GraphQLObjectType("Mutation", {"writeArticle": GraphQLField(BlogArticle)}) BlogSubscription = GraphQLObjectType( "Subscription", { "articleSubscribe": GraphQLField(args={"id": GraphQLArgument(GraphQLString)}, type=BlogArticle) }, ) ObjectType = GraphQLObjectType("Object", {}) InterfaceType = GraphQLInterfaceType("Interface") UnionType = GraphQLUnionType("Union", [ObjectType], resolve_type=lambda: None) EnumType = GraphQLEnumType("Enum", {"foo": GraphQLEnumValue()}) InputObjectType = GraphQLInputObjectType("InputObject", {}) def test_defines_a_query_only_schema(): BlogSchema = GraphQLSchema(BlogQuery) assert BlogSchema.get_query_type() == BlogQuery article_field = BlogQuery.fields["article"] assert article_field.type == BlogArticle assert article_field.type.name == "Article" # assert article_field.name == 'article' article_field_type = article_field.type
GraphQLDirective, ) from graphql.utilities import build_schema, extend_schema SomeScalarType = GraphQLScalarType(name="SomeScalar", serialize=lambda: None) SomeInterfaceType = GraphQLInterfaceType( name="SomeInterface", fields=lambda: {"f": GraphQLField(SomeObjectType)}) SomeObjectType = GraphQLObjectType( name="SomeObject", fields=lambda: {"f": GraphQLField(SomeObjectType)}, interfaces=[SomeInterfaceType], ) SomeUnionType = GraphQLUnionType(name="SomeUnion", types=[SomeObjectType]) SomeEnumType = GraphQLEnumType(name="SomeEnum", values={"ONLY": GraphQLEnumValue()}) SomeInputObjectType = GraphQLInputObjectType( name="SomeInputObject", fields={"val": GraphQLInputField(GraphQLString, default_value="hello")}, ) def with_modifiers( types: List[GraphQLNamedType] ) -> List[Union[GraphQLNamedType, GraphQLWrappingType]]: types = cast(List[Union[GraphQLNamedType, GraphQLWrappingType]], types) return (types + [GraphQLList(t)
Cat = GraphQLObjectType( "Cat", lambda: { "furColor": GraphQLField(FurColor), "name": GraphQLField(GraphQLString, {"surname": GraphQLArgument(GraphQLBoolean)}), "nickname": GraphQLField(GraphQLString), }, interfaces=[Being, Pet], is_type_of=lambda *_args: True, ) CatOrDog = GraphQLUnionType("CatOrDog", [Dog, Cat]) Intelligent = GraphQLInterfaceType("Intelligent", {"iq": GraphQLField(GraphQLInt)}) Human = GraphQLObjectType( name="Human", interfaces=[Being, Intelligent], is_type_of=lambda *_args: True, fields={ "name": GraphQLField(GraphQLString, {"surname": GraphQLArgument(GraphQLBoolean)}), "pets": GraphQLField(GraphQLList(Pet)), "iq":
Cat = GraphQLObjectType( 'Cat', lambda: { 'furColor': GraphQLField(FurColor), 'name': GraphQLField(GraphQLString, { 'surname': GraphQLArgument(GraphQLBoolean), }), 'nickname': GraphQLField(GraphQLString), }, interfaces=[Being, Pet], is_type_of=lambda: None) 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':