mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-26 03:23:55 +03:00
Improved tests and schema definition.
This commit is contained in:
parent
750bbfbc2c
commit
eafc9a102e
|
@ -6,6 +6,21 @@ from graphql.core.type import (
|
||||||
GraphQLID as ID
|
GraphQLID as ID
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from graphene import signals
|
||||||
|
|
||||||
|
from graphene.core.schema import (
|
||||||
|
Schema
|
||||||
|
)
|
||||||
|
|
||||||
|
from graphene.env import (
|
||||||
|
get_global_schema
|
||||||
|
)
|
||||||
|
|
||||||
|
from graphene.core.types import (
|
||||||
|
ObjectType,
|
||||||
|
Interface
|
||||||
|
)
|
||||||
|
|
||||||
from graphene.core.fields import (
|
from graphene.core.fields import (
|
||||||
Field,
|
Field,
|
||||||
StringField,
|
StringField,
|
||||||
|
@ -16,12 +31,6 @@ from graphene.core.fields import (
|
||||||
NonNullField,
|
NonNullField,
|
||||||
)
|
)
|
||||||
|
|
||||||
from graphene.core.types import (
|
|
||||||
ObjectType,
|
|
||||||
Interface,
|
|
||||||
Schema
|
|
||||||
)
|
|
||||||
|
|
||||||
from graphene.decorators import (
|
from graphene.decorators import (
|
||||||
resolve_only_args
|
resolve_only_args
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import inspect
|
||||||
from graphql.core.type import (
|
from graphql.core.type import (
|
||||||
GraphQLField,
|
GraphQLField,
|
||||||
GraphQLList,
|
GraphQLList,
|
||||||
|
@ -9,7 +10,7 @@ from graphql.core.type import (
|
||||||
GraphQLArgument,
|
GraphQLArgument,
|
||||||
)
|
)
|
||||||
from graphene.utils import cached_property
|
from graphene.utils import cached_property
|
||||||
from graphene.core.utils import get_object_type
|
from graphene.core.types import ObjectType
|
||||||
|
|
||||||
class Field(object):
|
class Field(object):
|
||||||
def __init__(self, field_type, resolve=None, null=True, args=None, description='', **extra_args):
|
def __init__(self, field_type, resolve=None, null=True, args=None, description='', **extra_args):
|
||||||
|
@ -25,6 +26,7 @@ class Field(object):
|
||||||
def contribute_to_class(self, cls, name):
|
def contribute_to_class(self, cls, name):
|
||||||
self.field_name = name
|
self.field_name = name
|
||||||
self.object_type = cls
|
self.object_type = cls
|
||||||
|
self.schema = cls._meta.schema
|
||||||
if isinstance(self.field_type, Field) and not self.field_type.object_type:
|
if isinstance(self.field_type, Field) and not self.field_type.object_type:
|
||||||
self.field_type.contribute_to_class(cls, name)
|
self.field_type.contribute_to_class(cls, name)
|
||||||
cls._meta.add_field(self)
|
cls._meta.add_field(self)
|
||||||
|
@ -42,12 +44,27 @@ class Field(object):
|
||||||
resolve_fn = lambda root, args, info: root.resolve(self.field_name, args, info)
|
resolve_fn = lambda root, args, info: root.resolve(self.field_name, args, info)
|
||||||
return resolve_fn(instance, args, info)
|
return resolve_fn(instance, args, info)
|
||||||
|
|
||||||
|
def get_object_type(self):
|
||||||
|
field_type = self.field_type
|
||||||
|
_is_class = inspect.isclass(field_type)
|
||||||
|
if _is_class and issubclass(field_type, ObjectType):
|
||||||
|
return field_type
|
||||||
|
elif isinstance(field_type, basestring):
|
||||||
|
if field_type == 'self':
|
||||||
|
return self.object_type
|
||||||
|
elif self.schema:
|
||||||
|
return self.schema.get_type(field_type)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def type(self):
|
def type(self):
|
||||||
if isinstance(self.field_type, Field):
|
field_type = self.field_type
|
||||||
|
if isinstance(field_type, Field):
|
||||||
field_type = self.field_type.type
|
field_type = self.field_type.type
|
||||||
else:
|
else:
|
||||||
field_type = get_object_type(self.field_type, self.object_type)
|
object_type = self.get_object_type()
|
||||||
|
if object_type:
|
||||||
|
field_type = object_type._meta.type
|
||||||
|
|
||||||
field_type = self.type_wrapper(field_type)
|
field_type = self.type_wrapper(field_type)
|
||||||
return field_type
|
return field_type
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
|
from graphene.env import get_global_schema
|
||||||
from graphene.utils import cached_property
|
from graphene.utils import cached_property
|
||||||
|
|
||||||
DEFAULT_NAMES = ('app_label', 'description', 'name', 'interface',
|
DEFAULT_NAMES = ('description', 'name', 'interface', 'schema',
|
||||||
'type_name', 'interfaces', 'proxy')
|
'type_name', 'interfaces', 'proxy')
|
||||||
|
|
||||||
|
|
||||||
class Options(object):
|
class Options(object):
|
||||||
def __init__(self, meta=None, app_label=None):
|
def __init__(self, meta=None, schema=None):
|
||||||
self.meta = meta
|
self.meta = meta
|
||||||
self.local_fields = []
|
self.local_fields = []
|
||||||
self.interface = False
|
self.interface = False
|
||||||
self.proxy = False
|
self.proxy = False
|
||||||
|
self.schema = schema or get_global_schema()
|
||||||
self.interfaces = []
|
self.interfaces = []
|
||||||
self.parents = []
|
self.parents = []
|
||||||
self.app_label = app_label
|
|
||||||
|
|
||||||
def contribute_to_class(self, cls, name):
|
def contribute_to_class(self, cls, name):
|
||||||
cls._meta = self
|
cls._meta = self
|
||||||
|
|
73
graphene/core/schema.py
Normal file
73
graphene/core/schema.py
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
from graphql.core import graphql
|
||||||
|
from graphql.core.type import (
|
||||||
|
GraphQLSchema
|
||||||
|
)
|
||||||
|
from graphene import signals
|
||||||
|
from graphene.utils import cached_property
|
||||||
|
# from graphene.relay.nodes import create_node_definitions
|
||||||
|
|
||||||
|
class Schema(object):
|
||||||
|
_query = None
|
||||||
|
|
||||||
|
def __init__(self, query=None, mutation=None, name='Schema'):
|
||||||
|
self.mutation = mutation
|
||||||
|
self.query = query
|
||||||
|
self.name = name
|
||||||
|
self._types = {}
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '<Schema: %s>' % str(self.name)
|
||||||
|
|
||||||
|
# @cachedproperty
|
||||||
|
# def node_definitions(self):
|
||||||
|
# return [object, object]
|
||||||
|
# # from graphene.relay import create_node_definitions
|
||||||
|
# # return create_node_definitions(schema=self)
|
||||||
|
|
||||||
|
# @property
|
||||||
|
# def Node(self):
|
||||||
|
# return self.node_definitions[0]
|
||||||
|
|
||||||
|
# @property
|
||||||
|
# def NodeField(self):
|
||||||
|
# return self.node_definitions[1]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def query(self):
|
||||||
|
return self._query
|
||||||
|
@query.setter
|
||||||
|
def query(self, query):
|
||||||
|
if not query:
|
||||||
|
return
|
||||||
|
self._query = query
|
||||||
|
self._query_type = query._meta.type
|
||||||
|
self._schema = GraphQLSchema(query=self._query_type, mutation=self.mutation)
|
||||||
|
|
||||||
|
def register_type(self, type):
|
||||||
|
type_name = type._meta.type_name
|
||||||
|
if type_name in self._types:
|
||||||
|
raise Exception('Type name %s already registered in %r' % (type_name, self))
|
||||||
|
self._types[type_name] = type
|
||||||
|
|
||||||
|
def get_type(self, type_name):
|
||||||
|
if type_name not in self._types:
|
||||||
|
raise Exception('Type %s not found in %r' % (type_name, self))
|
||||||
|
return self._types[type_name]
|
||||||
|
|
||||||
|
def execute(self, request='', root=None, vars=None, operation_name=None):
|
||||||
|
return graphql(
|
||||||
|
self._schema,
|
||||||
|
request=request,
|
||||||
|
root=root or self.query(),
|
||||||
|
vars=vars,
|
||||||
|
operation_name=operation_name
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@signals.class_prepared.connect
|
||||||
|
def object_type_created(object_type):
|
||||||
|
schema = object_type._meta.schema
|
||||||
|
if schema:
|
||||||
|
schema.register_type(object_type)
|
||||||
|
|
||||||
|
from graphene.env import get_global_schema
|
|
@ -3,10 +3,8 @@ import six
|
||||||
|
|
||||||
from graphql.core.type import (
|
from graphql.core.type import (
|
||||||
GraphQLObjectType,
|
GraphQLObjectType,
|
||||||
GraphQLInterfaceType,
|
GraphQLInterfaceType
|
||||||
GraphQLSchema
|
|
||||||
)
|
)
|
||||||
from graphql.core import graphql
|
|
||||||
|
|
||||||
from graphene import signals
|
from graphene import signals
|
||||||
from graphene.core.options import Options
|
from graphene.core.options import Options
|
||||||
|
@ -33,12 +31,9 @@ class ObjectTypeMeta(type):
|
||||||
meta = attr_meta
|
meta = attr_meta
|
||||||
base_meta = getattr(new_class, '_meta', None)
|
base_meta = getattr(new_class, '_meta', None)
|
||||||
|
|
||||||
if '.' in module:
|
schema = (base_meta and base_meta.schema)
|
||||||
app_label, _ = module.rsplit('.', 1)
|
|
||||||
else:
|
|
||||||
app_label = module
|
|
||||||
|
|
||||||
new_class.add_to_class('_meta', Options(meta, app_label))
|
new_class.add_to_class('_meta', Options(meta, schema))
|
||||||
if base_meta and base_meta.proxy:
|
if base_meta and base_meta.proxy:
|
||||||
new_class._meta.interface = base_meta.interface
|
new_class._meta.interface = base_meta.interface
|
||||||
# Add all attributes to the class.
|
# Add all attributes to the class.
|
||||||
|
@ -54,6 +49,8 @@ class ObjectTypeMeta(type):
|
||||||
# Things without _meta aren't functional models, so they're
|
# Things without _meta aren't functional models, so they're
|
||||||
# uninteresting parents.
|
# uninteresting parents.
|
||||||
continue
|
continue
|
||||||
|
if base._meta.schema != new_class._meta.schema:
|
||||||
|
raise Exception('The parent schema is not the same')
|
||||||
|
|
||||||
parent_fields = base._meta.local_fields
|
parent_fields = base._meta.local_fields
|
||||||
# Check for clashes between locally declared fields and those
|
# Check for clashes between locally declared fields and those
|
||||||
|
@ -138,19 +135,3 @@ class Interface(ObjectType):
|
||||||
class Meta:
|
class Meta:
|
||||||
interface = True
|
interface = True
|
||||||
proxy = True
|
proxy = True
|
||||||
|
|
||||||
|
|
||||||
class Schema(object):
|
|
||||||
def __init__(self, query, mutation=None):
|
|
||||||
self.query = query
|
|
||||||
self.query_type = query._meta.type
|
|
||||||
self._schema = GraphQLSchema(query=self.query_type, mutation=mutation)
|
|
||||||
|
|
||||||
def execute(self, request='', root=None, vars=None, operation_name=None):
|
|
||||||
return graphql(
|
|
||||||
self._schema,
|
|
||||||
request=request,
|
|
||||||
root=root or self.query(),
|
|
||||||
vars=vars,
|
|
||||||
operation_name=operation_name
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
import inspect
|
|
||||||
|
|
||||||
from graphene.core.types import ObjectType
|
|
||||||
from graphene import signals
|
|
||||||
|
|
||||||
registered_object_types = []
|
|
||||||
|
|
||||||
|
|
||||||
def get_object_type(field_type, object_type=None):
|
|
||||||
native_type = get_type(field_type, object_type)
|
|
||||||
if native_type:
|
|
||||||
field_type = native_type._meta.type
|
|
||||||
return field_type
|
|
||||||
|
|
||||||
|
|
||||||
def get_type(field_type, object_type=None):
|
|
||||||
_is_class = inspect.isclass(field_type)
|
|
||||||
if _is_class and issubclass(field_type, ObjectType):
|
|
||||||
return field_type
|
|
||||||
elif isinstance(field_type, basestring):
|
|
||||||
if field_type == 'self':
|
|
||||||
return object_type
|
|
||||||
else:
|
|
||||||
object_type = get_registered_object_type(field_type, object_type)
|
|
||||||
return object_type
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_registered_object_type(name, object_type=None):
|
|
||||||
app_label = None
|
|
||||||
object_type_name = name
|
|
||||||
|
|
||||||
if '.' in name:
|
|
||||||
app_label, object_type_name = name.rsplit('.', 1)
|
|
||||||
elif object_type:
|
|
||||||
app_label = object_type._meta.app_label
|
|
||||||
|
|
||||||
# Filter all registered object types which have the same name
|
|
||||||
ots = [ot for ot in registered_object_types if ot._meta.type_name == object_type_name]
|
|
||||||
# If the list have more than one object type with the name, filter by
|
|
||||||
# the app_label
|
|
||||||
if len(ots)>1 and app_label:
|
|
||||||
ots = [ot for ot in ots if ot._meta.app_label == app_label]
|
|
||||||
|
|
||||||
if len(ots)>1:
|
|
||||||
raise Exception('Multiple ObjectTypes returned with the name %s' % name)
|
|
||||||
if not ots:
|
|
||||||
raise Exception('No ObjectType found with name %s' % name)
|
|
||||||
|
|
||||||
return ots[0]
|
|
||||||
|
|
||||||
|
|
||||||
@signals.class_prepared.connect
|
|
||||||
def object_type_created(sender):
|
|
||||||
registered_object_types.append(sender)
|
|
9
graphene/env.py
Normal file
9
graphene/env.py
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
from graphene.core.schema import Schema
|
||||||
|
|
||||||
|
_global_schema = None
|
||||||
|
|
||||||
|
def get_global_schema():
|
||||||
|
global _global_schema
|
||||||
|
if not _global_schema:
|
||||||
|
_global_schema = Schema(name='Global Schema')
|
||||||
|
return _global_schema
|
|
@ -1,85 +1,5 @@
|
||||||
import collections
|
from graphene.relay.nodes import (
|
||||||
|
create_node_definitions
|
||||||
from graphene import signals
|
|
||||||
from graphene.core.fields import Field, NativeField
|
|
||||||
from graphene.core.types import Interface
|
|
||||||
from graphene.core.utils import get_type
|
|
||||||
from graphene.utils import cached_property
|
|
||||||
|
|
||||||
from graphql_relay.node.node import (
|
|
||||||
nodeDefinitions,
|
|
||||||
globalIdField,
|
|
||||||
fromGlobalId
|
|
||||||
)
|
|
||||||
from graphql_relay.connection.arrayconnection import (
|
|
||||||
connectionFromArray
|
|
||||||
)
|
|
||||||
from graphql_relay.connection.connection import (
|
|
||||||
connectionArgs,
|
|
||||||
connectionDefinitions
|
|
||||||
)
|
)
|
||||||
|
|
||||||
registered_nodes = {}
|
from graphene.relay.relay import *
|
||||||
|
|
||||||
|
|
||||||
def getNode(globalId, *args):
|
|
||||||
resolvedGlobalId = fromGlobalId(globalId)
|
|
||||||
_type, _id = resolvedGlobalId.type, resolvedGlobalId.id
|
|
||||||
if _type in registered_nodes:
|
|
||||||
object_type = registered_nodes[_type]
|
|
||||||
return object_type.get_node(_id)
|
|
||||||
|
|
||||||
|
|
||||||
def getNodeType(obj):
|
|
||||||
return obj._meta.type
|
|
||||||
|
|
||||||
|
|
||||||
_nodeDefinitions = nodeDefinitions(getNode, getNodeType)
|
|
||||||
|
|
||||||
|
|
||||||
class Node(Interface):
|
|
||||||
@classmethod
|
|
||||||
def get_graphql_type(cls):
|
|
||||||
if cls is Node:
|
|
||||||
# Return only nodeInterface when is the Node Inerface
|
|
||||||
return _nodeDefinitions.nodeInterface
|
|
||||||
return super(Node, cls).get_graphql_type()
|
|
||||||
|
|
||||||
|
|
||||||
class NodeField(NativeField):
|
|
||||||
field = _nodeDefinitions.nodeField
|
|
||||||
|
|
||||||
|
|
||||||
class ConnectionField(Field):
|
|
||||||
def __init__(self, field_type, resolve=None, description=''):
|
|
||||||
super(ConnectionField, self).__init__(field_type, resolve=resolve,
|
|
||||||
args=connectionArgs, description=description)
|
|
||||||
|
|
||||||
def resolve(self, instance, args, info):
|
|
||||||
resolved = super(ConnectionField, self).resolve(instance, args, info)
|
|
||||||
if resolved:
|
|
||||||
assert isinstance(resolved, collections.Iterable), 'Resolved value from the connection field have to be iterable'
|
|
||||||
return connectionFromArray(resolved, args)
|
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def type(self):
|
|
||||||
object_type = get_type(self.field_type, self.object_type)
|
|
||||||
assert issubclass(object_type, Node), 'Only nodes have connections.'
|
|
||||||
return object_type.connection
|
|
||||||
|
|
||||||
|
|
||||||
@signals.class_prepared.connect
|
|
||||||
def object_type_created(object_type):
|
|
||||||
if issubclass(object_type, Node):
|
|
||||||
type_name = object_type._meta.type_name
|
|
||||||
assert type_name not in registered_nodes, 'Two nodes with the same type_name: %s' % type_name
|
|
||||||
registered_nodes[type_name] = object_type
|
|
||||||
# def getId(*args, **kwargs):
|
|
||||||
# print '**GET ID', args, kwargs
|
|
||||||
# return 2
|
|
||||||
field = NativeField(globalIdField(type_name))
|
|
||||||
object_type.add_to_class('id', field)
|
|
||||||
assert hasattr(object_type, 'get_node'), 'get_node classmethod not found in %s Node' % type_name
|
|
||||||
|
|
||||||
connection = connectionDefinitions(type_name, object_type._meta.type).connectionType
|
|
||||||
object_type.add_to_class('connection', connection)
|
|
||||||
|
|
37
graphene/relay/nodes.py
Normal file
37
graphene/relay/nodes.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
from graphql_relay.node.node import (
|
||||||
|
nodeDefinitions,
|
||||||
|
fromGlobalId
|
||||||
|
)
|
||||||
|
|
||||||
|
def create_node_definitions(getNode=None, getNodeType=None, schema=None):
|
||||||
|
from graphene.core.types import Interface
|
||||||
|
from graphene.core.fields import Field, NativeField
|
||||||
|
if not getNode:
|
||||||
|
def getNode(globalId, *args):
|
||||||
|
from graphene.env import get_global_schema
|
||||||
|
_schema = schema or get_global_schema()
|
||||||
|
resolvedGlobalId = fromGlobalId(globalId)
|
||||||
|
_type, _id = resolvedGlobalId.type, resolvedGlobalId.id
|
||||||
|
object_type = _schema.get_type(_type)
|
||||||
|
return object_type.get_node(_id)
|
||||||
|
|
||||||
|
if not getNodeType:
|
||||||
|
def getNodeType(obj):
|
||||||
|
return obj._meta.type
|
||||||
|
|
||||||
|
_nodeDefinitions = nodeDefinitions(getNode, getNodeType)
|
||||||
|
|
||||||
|
|
||||||
|
class Node(Interface):
|
||||||
|
@classmethod
|
||||||
|
def get_graphql_type(cls):
|
||||||
|
if cls is Node:
|
||||||
|
# Return only nodeInterface when is the Node Inerface
|
||||||
|
return _nodeDefinitions.nodeInterface
|
||||||
|
return super(Node, cls).get_graphql_type()
|
||||||
|
|
||||||
|
|
||||||
|
class NodeField(NativeField):
|
||||||
|
field = _nodeDefinitions.nodeField
|
||||||
|
|
||||||
|
return Node, NodeField
|
51
graphene/relay/relay.py
Normal file
51
graphene/relay/relay.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
import collections
|
||||||
|
|
||||||
|
from graphene import signals
|
||||||
|
from graphene.utils import cached_property
|
||||||
|
|
||||||
|
from graphql_relay.node.node import (
|
||||||
|
globalIdField
|
||||||
|
)
|
||||||
|
from graphql_relay.connection.arrayconnection import (
|
||||||
|
connectionFromArray
|
||||||
|
)
|
||||||
|
from graphql_relay.connection.connection import (
|
||||||
|
connectionArgs,
|
||||||
|
connectionDefinitions
|
||||||
|
)
|
||||||
|
from graphene.relay.nodes import create_node_definitions
|
||||||
|
from graphene.core.fields import Field, NativeField
|
||||||
|
|
||||||
|
Node, NodeField = create_node_definitions()
|
||||||
|
|
||||||
|
class ConnectionField(Field):
|
||||||
|
def __init__(self, field_type, resolve=None, description=''):
|
||||||
|
super(ConnectionField, self).__init__(field_type, resolve=resolve,
|
||||||
|
args=connectionArgs, description=description)
|
||||||
|
|
||||||
|
def resolve(self, instance, args, info):
|
||||||
|
resolved = super(ConnectionField, self).resolve(instance, args, info)
|
||||||
|
if resolved:
|
||||||
|
assert isinstance(resolved, collections.Iterable), 'Resolved value from the connection field have to be iterable'
|
||||||
|
return connectionFromArray(resolved, args)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def type(self):
|
||||||
|
object_type = self.get_object_type()
|
||||||
|
assert issubclass(object_type, Node), 'Only nodes have connections.'
|
||||||
|
return object_type.connection
|
||||||
|
|
||||||
|
|
||||||
|
@signals.class_prepared.connect
|
||||||
|
def object_type_created(object_type):
|
||||||
|
if issubclass(object_type, Node):
|
||||||
|
type_name = object_type._meta.type_name
|
||||||
|
# def getId(*args, **kwargs):
|
||||||
|
# print '**GET ID', args, kwargs
|
||||||
|
# return 2
|
||||||
|
field = NativeField(globalIdField(type_name))
|
||||||
|
object_type.add_to_class('id', field)
|
||||||
|
assert hasattr(object_type, 'get_node'), 'get_node classmethod not found in %s Node' % type_name
|
||||||
|
|
||||||
|
connection = connectionDefinitions(type_name, object_type._meta.type).connectionType
|
||||||
|
object_type.add_to_class('connection', connection)
|
|
@ -18,15 +18,18 @@ from graphene.core.types import (
|
||||||
class Character(Interface):
|
class Character(Interface):
|
||||||
'''Character description'''
|
'''Character description'''
|
||||||
name = StringField()
|
name = StringField()
|
||||||
|
class Meta:
|
||||||
|
type_name = 'core.Character'
|
||||||
class Human(Character):
|
class Human(Character):
|
||||||
'''Human description'''
|
'''Human description'''
|
||||||
friends = StringField()
|
friends = StringField()
|
||||||
|
class Meta:
|
||||||
|
type_name = 'core.Human'
|
||||||
|
|
||||||
def test_interface():
|
def test_interface():
|
||||||
object_type = Character._meta.type
|
object_type = Character._meta.type
|
||||||
assert Character._meta.interface == True
|
assert Character._meta.interface == True
|
||||||
assert Character._meta.type_name == 'Character'
|
assert Character._meta.type_name == 'core.Character'
|
||||||
assert isinstance(object_type, GraphQLInterfaceType)
|
assert isinstance(object_type, GraphQLInterfaceType)
|
||||||
assert object_type.description == 'Character description'
|
assert object_type.description == 'Character description'
|
||||||
assert object_type.get_fields() == {'name': Character._meta.fields_map['name'].field}
|
assert object_type.get_fields() == {'name': Character._meta.fields_map['name'].field}
|
||||||
|
@ -34,7 +37,7 @@ def test_interface():
|
||||||
def test_object_type():
|
def test_object_type():
|
||||||
object_type = Human._meta.type
|
object_type = Human._meta.type
|
||||||
assert Human._meta.interface == False
|
assert Human._meta.interface == False
|
||||||
assert Human._meta.type_name == 'Human'
|
assert Human._meta.type_name == 'core.Human'
|
||||||
assert isinstance(object_type, GraphQLObjectType)
|
assert isinstance(object_type, GraphQLObjectType)
|
||||||
assert object_type.description == 'Human description'
|
assert object_type.description == 'Human description'
|
||||||
assert object_type.get_fields() == {'name': Character._meta.fields_map['name'].field, 'friends': Human._meta.fields_map['friends'].field}
|
assert object_type.get_fields() == {'name': Character._meta.fields_map['name'].field, 'friends': Human._meta.fields_map['friends'].field}
|
||||||
|
|
|
@ -3,6 +3,7 @@ from pytest import raises
|
||||||
import graphene
|
import graphene
|
||||||
from graphene import relay
|
from graphene import relay
|
||||||
|
|
||||||
|
schema = graphene.Schema()
|
||||||
|
|
||||||
class OtherNode(relay.Node):
|
class OtherNode(relay.Node):
|
||||||
name = graphene.StringField()
|
name = graphene.StringField()
|
||||||
|
@ -28,14 +29,19 @@ def test_node_should_have_id_field():
|
||||||
assert 'id' in OtherNode._meta.fields_map
|
assert 'id' in OtherNode._meta.fields_map
|
||||||
|
|
||||||
|
|
||||||
def test_field_no_contributed_raises_error():
|
# def test_field_no_contributed_raises_error():
|
||||||
with raises(Exception) as excinfo:
|
# with raises(Exception) as excinfo:
|
||||||
class Ship(graphene.ObjectType):
|
# class Ship(graphene.ObjectType):
|
||||||
name = graphene.StringField()
|
# name = graphene.StringField()
|
||||||
|
# class Meta:
|
||||||
|
# schema = schema
|
||||||
|
|
||||||
|
# class Faction(relay.Node):
|
||||||
class Faction(relay.Node):
|
# name = graphene.StringField()
|
||||||
name = graphene.StringField()
|
# ships = relay.ConnectionField(Ship)
|
||||||
ships = relay.ConnectionField(Ship)
|
# @classmethod
|
||||||
|
# def get_node(cls):
|
||||||
assert 'same type_name' in str(excinfo.value)
|
# pass
|
||||||
|
# class Meta:
|
||||||
|
# schema = schema
|
||||||
|
# assert 'same type_name' in str(excinfo.value)
|
||||||
|
|
|
@ -46,6 +46,9 @@ class Query(graphene.ObjectType):
|
||||||
id = graphene.Argument(graphene.String)
|
id = graphene.Argument(graphene.String)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
type_name = 'core.Query'
|
||||||
|
|
||||||
@resolve_only_args
|
@resolve_only_args
|
||||||
def resolve_hero(self, episode):
|
def resolve_hero(self, episode):
|
||||||
return wrap_character(getHero(episode))
|
return wrap_character(getHero(episode))
|
||||||
|
|
|
@ -8,6 +8,7 @@ from .data import (
|
||||||
getEmpire,
|
getEmpire,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
schema = graphene.Schema()
|
||||||
|
|
||||||
class Ship(relay.Node):
|
class Ship(relay.Node):
|
||||||
'''A ship in the Star Wars saga'''
|
'''A ship in the Star Wars saga'''
|
||||||
|
@ -19,6 +20,8 @@ class Ship(relay.Node):
|
||||||
if ship:
|
if ship:
|
||||||
return Ship(ship)
|
return Ship(ship)
|
||||||
|
|
||||||
|
# class Meta:
|
||||||
|
# schema = schema
|
||||||
|
|
||||||
class Faction(relay.Node):
|
class Faction(relay.Node):
|
||||||
'''A faction in the Star Wars saga'''
|
'''A faction in the Star Wars saga'''
|
||||||
|
@ -35,6 +38,9 @@ class Faction(relay.Node):
|
||||||
if faction:
|
if faction:
|
||||||
return Faction(faction)
|
return Faction(faction)
|
||||||
|
|
||||||
|
# class Meta:
|
||||||
|
# schema = schema
|
||||||
|
|
||||||
|
|
||||||
class Query(graphene.ObjectType):
|
class Query(graphene.ObjectType):
|
||||||
rebels = graphene.Field(Faction)
|
rebels = graphene.Field(Faction)
|
||||||
|
@ -50,4 +56,10 @@ class Query(graphene.ObjectType):
|
||||||
return Faction(getEmpire())
|
return Faction(getEmpire())
|
||||||
|
|
||||||
|
|
||||||
Schema = graphene.Schema(query=Query)
|
# class Meta:
|
||||||
|
# schema = schema
|
||||||
|
|
||||||
|
print '*CACA', schema._types
|
||||||
|
|
||||||
|
schema.query = Query
|
||||||
|
Schema = schema
|
||||||
|
|
Loading…
Reference in New Issue
Block a user