mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-30 05:23:57 +03:00
Added Union type
This commit is contained in:
parent
7923f45595
commit
1c24e1b954
|
@ -1,6 +1,6 @@
|
||||||
from graphql import (GraphQLEnumType, GraphQLInputObjectType,
|
from graphql import (GraphQLEnumType, GraphQLInputObjectType,
|
||||||
GraphQLInterfaceType, GraphQLObjectType,
|
GraphQLInterfaceType, GraphQLObjectType,
|
||||||
GraphQLScalarType)
|
GraphQLScalarType, GraphQLUnionType)
|
||||||
|
|
||||||
|
|
||||||
class GrapheneGraphQLType(object):
|
class GrapheneGraphQLType(object):
|
||||||
|
@ -18,6 +18,10 @@ class GrapheneInterfaceType(GrapheneGraphQLType, GraphQLInterfaceType):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class GrapheneUnionType(GrapheneGraphQLType, GraphQLUnionType):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class GrapheneObjectType(GrapheneGraphQLType, GraphQLObjectType):
|
class GrapheneObjectType(GrapheneGraphQLType, GraphQLObjectType):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -28,12 +28,15 @@ class InterfaceMeta(AbstractTypeMeta):
|
||||||
|
|
||||||
return type.__new__(cls, name, bases, dict(attrs, _meta=options))
|
return type.__new__(cls, name, bases, dict(attrs, _meta=options))
|
||||||
|
|
||||||
|
def __str__(cls):
|
||||||
|
return cls._meta.name
|
||||||
|
|
||||||
|
|
||||||
class Interface(six.with_metaclass(InterfaceMeta)):
|
class Interface(six.with_metaclass(InterfaceMeta)):
|
||||||
resolve_type = None
|
resolve_type = None
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
raise Exception("An interface cannot be intitialized")
|
raise Exception("An Interface cannot be intitialized")
|
||||||
|
|
||||||
# @classmethod
|
# @classmethod
|
||||||
# def implements(cls, objecttype):
|
# def implements(cls, objecttype):
|
||||||
|
|
|
@ -28,6 +28,9 @@ class ObjectTypeMeta(AbstractTypeMeta):
|
||||||
|
|
||||||
return type.__new__(cls, name, bases, dict(attrs, _meta=options))
|
return type.__new__(cls, name, bases, dict(attrs, _meta=options))
|
||||||
|
|
||||||
|
def __str__(cls):
|
||||||
|
return cls._meta.name
|
||||||
|
|
||||||
|
|
||||||
class ObjectType(six.with_metaclass(ObjectTypeMeta)):
|
class ObjectType(six.with_metaclass(ObjectTypeMeta)):
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,9 @@ class ScalarTypeMeta(type):
|
||||||
|
|
||||||
return super_new(cls, name, bases, dict(attrs, _meta=options))
|
return super_new(cls, name, bases, dict(attrs, _meta=options))
|
||||||
|
|
||||||
|
def __str__(cls):
|
||||||
|
return cls._meta.name
|
||||||
|
|
||||||
|
|
||||||
class Scalar(six.with_metaclass(ScalarTypeMeta, UnmountedType)):
|
class Scalar(six.with_metaclass(ScalarTypeMeta, UnmountedType)):
|
||||||
serialize = None
|
serialize = None
|
||||||
|
|
|
@ -3,6 +3,8 @@ from collections import OrderedDict
|
||||||
from py.test import raises
|
from py.test import raises
|
||||||
|
|
||||||
from ..objecttype import ObjectType
|
from ..objecttype import ObjectType
|
||||||
|
from ..interface import Interface
|
||||||
|
from ..union import Union
|
||||||
from ..scalars import String, Int, Boolean
|
from ..scalars import String, Int, Boolean
|
||||||
from ..field import Field
|
from ..field import Field
|
||||||
from ..structures import List
|
from ..structures import List
|
||||||
|
@ -44,6 +46,15 @@ class Subscription(ObjectType):
|
||||||
article_subscribe = Field(Article) # id=String()
|
article_subscribe = Field(Article) # id=String()
|
||||||
|
|
||||||
|
|
||||||
|
class MyInterface(Interface):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MyUnion(Union):
|
||||||
|
class Meta:
|
||||||
|
types = (Article, )
|
||||||
|
|
||||||
|
|
||||||
def test_defines_a_query_only_schema():
|
def test_defines_a_query_only_schema():
|
||||||
blog_schema = Schema(Query)
|
blog_schema = Schema(Query)
|
||||||
|
|
||||||
|
@ -177,11 +188,11 @@ def test_defines_a_subscription_schema():
|
||||||
# assert schema.get_type_map()['SomeSubtype'] == SomeSubtype
|
# assert schema.get_type_map()['SomeSubtype'] == SomeSubtype
|
||||||
|
|
||||||
|
|
||||||
# def test_stringifies_simple_types():
|
def test_stringifies_simple_types():
|
||||||
# assert str(GraphQLInt) == 'Int'
|
assert str(Int) == 'Int'
|
||||||
# assert str(BlogArticle) == 'Article'
|
assert str(Article) == 'Article'
|
||||||
# assert str(InterfaceType) == 'Interface'
|
assert str(MyInterface) == 'MyInterface'
|
||||||
# assert str(UnionType) == 'Union'
|
assert str(MyUnion) == 'MyUnion'
|
||||||
# assert str(EnumType) == 'Enum'
|
# assert str(EnumType) == 'Enum'
|
||||||
# assert str(InputObjectType) == 'InputObject'
|
# assert str(InputObjectType) == 'InputObject'
|
||||||
# assert str(GraphQLNonNull(GraphQLInt)) == 'Int!'
|
# assert str(GraphQLNonNull(GraphQLInt)) == 'Int!'
|
||||||
|
|
42
graphene/new_types/tests/test_union.py
Normal file
42
graphene/new_types/tests/test_union.py
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from ..objecttype import ObjectType
|
||||||
|
from ..union import Union
|
||||||
|
|
||||||
|
|
||||||
|
class MyObjectType1(ObjectType):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class MyObjectType2(ObjectType):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def test_generate_union():
|
||||||
|
class MyUnion(Union):
|
||||||
|
'''Documentation'''
|
||||||
|
class Meta:
|
||||||
|
types = (MyObjectType1, MyObjectType2)
|
||||||
|
|
||||||
|
assert MyUnion._meta.name == "MyUnion"
|
||||||
|
assert MyUnion._meta.description == "Documentation"
|
||||||
|
assert MyUnion._meta.types == (MyObjectType1, MyObjectType2)
|
||||||
|
|
||||||
|
|
||||||
|
def test_generate_union_with_meta():
|
||||||
|
class MyUnion(Union):
|
||||||
|
class Meta:
|
||||||
|
name = 'MyOtherUnion'
|
||||||
|
description = 'Documentation'
|
||||||
|
types = (MyObjectType1, MyObjectType2)
|
||||||
|
|
||||||
|
assert MyUnion._meta.name == "MyOtherUnion"
|
||||||
|
assert MyUnion._meta.description == "Documentation"
|
||||||
|
|
||||||
|
|
||||||
|
def test_generate_union_with_no_types():
|
||||||
|
with pytest.raises(Exception) as exc_info:
|
||||||
|
class MyUnion(Union):
|
||||||
|
pass
|
||||||
|
|
||||||
|
assert str(exc_info.value) == 'Must provide types for Union MyUnion.'
|
37
graphene/new_types/union.py
Normal file
37
graphene/new_types/union.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import six
|
||||||
|
|
||||||
|
from ..utils.is_base_type import is_base_type
|
||||||
|
from .options import Options
|
||||||
|
|
||||||
|
|
||||||
|
class UnionMeta(type):
|
||||||
|
|
||||||
|
def __new__(cls, name, bases, attrs):
|
||||||
|
# Also ensure initialization is only performed for subclasses of
|
||||||
|
# Union
|
||||||
|
if not is_base_type(bases, UnionMeta):
|
||||||
|
return type.__new__(cls, name, bases, attrs)
|
||||||
|
|
||||||
|
options = Options(
|
||||||
|
attrs.pop('Meta', None),
|
||||||
|
name=name,
|
||||||
|
description=attrs.get('__doc__'),
|
||||||
|
types=(),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert (
|
||||||
|
isinstance(options.types, (list, tuple)) and
|
||||||
|
len(options.types) > 0
|
||||||
|
), 'Must provide types for Union {}.'.format(options.name)
|
||||||
|
|
||||||
|
return type.__new__(cls, name, bases, dict(attrs, _meta=options))
|
||||||
|
|
||||||
|
def __str__(cls):
|
||||||
|
return cls._meta.name
|
||||||
|
|
||||||
|
|
||||||
|
class Union(six.with_metaclass(UnionMeta)):
|
||||||
|
resolve_type = None
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
raise Exception("An Union cannot be intitialized")
|
Loading…
Reference in New Issue
Block a user