mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-02 12:44:15 +03:00
Improved mutations, tests and overall integration.
This commit is contained in:
parent
6f87720fc1
commit
28d89a44f1
|
@ -9,18 +9,11 @@ from .types.definitions import List, NonNull
|
|||
class DeprecatedField(FieldType):
|
||||
def __init__(self, *args, **kwargs):
|
||||
cls = self.__class__
|
||||
warnings.warn("Using {} is not longer supported".format(cls.__name__)
|
||||
, FutureWarning)
|
||||
kwargs['resolver'] = kwargs.pop('resolve', None)
|
||||
self.required = kwargs.pop('required', False)
|
||||
warnings.warn("Using {} is not longer supported".format(cls.__name__), FutureWarning)
|
||||
if 'resolve' in kwargs:
|
||||
kwargs['resolver'] = kwargs.pop('resolve')
|
||||
return super(DeprecatedField, self).__init__(*args, **kwargs)
|
||||
|
||||
def as_field(self):
|
||||
t = self
|
||||
if self.required:
|
||||
t = NonNull(t)
|
||||
return Field(t, _creation_counter=self.creation_counter, *self.args, **self.kwargs)
|
||||
|
||||
|
||||
class StringField(DeprecatedField, String):
|
||||
pass
|
||||
|
|
|
@ -8,6 +8,7 @@ from graphql.core.execution.middlewares.sync import \
|
|||
from graphql.core.type import GraphQLSchema as _GraphQLSchema
|
||||
from graphql.core.utils.introspection_query import introspection_query
|
||||
from graphene.core.types.base import BaseType
|
||||
from graphene.core.types.objecttype import BaseObjectType
|
||||
|
||||
|
||||
class GraphQLSchema(_GraphQLSchema):
|
||||
|
@ -18,7 +19,6 @@ class GraphQLSchema(_GraphQLSchema):
|
|||
|
||||
|
||||
class Schema(object):
|
||||
_query = None
|
||||
_executor = None
|
||||
|
||||
def __init__(self, query=None, mutation=None, name='Schema', executor=None):
|
||||
|
@ -47,26 +47,10 @@ class Schema(object):
|
|||
else:
|
||||
return object_type
|
||||
|
||||
@property
|
||||
def query(self):
|
||||
return self._query
|
||||
|
||||
@query.setter
|
||||
def query(self, query):
|
||||
self._query = query
|
||||
|
||||
@property
|
||||
def mutation(self):
|
||||
return self._mutation
|
||||
|
||||
@mutation.setter
|
||||
def mutation(self, mutation):
|
||||
self._mutation = mutation
|
||||
|
||||
@property
|
||||
def executor(self):
|
||||
if not self._executor:
|
||||
self.executor = Executor(
|
||||
self._executor = Executor(
|
||||
[SynchronousExecutionMiddleware()], map_type=OrderedDict)
|
||||
return self._executor
|
||||
|
||||
|
@ -76,18 +60,29 @@ class Schema(object):
|
|||
|
||||
@property
|
||||
def schema(self):
|
||||
if not self._query:
|
||||
if not self.query:
|
||||
raise Exception('You have to define a base query type')
|
||||
return GraphQLSchema(self, query=self.T(self._query), mutation=self.T(self._mutation))
|
||||
return GraphQLSchema(self, query=self.T(self.query), mutation=self.T(self.mutation))
|
||||
|
||||
def register(self, object_type):
|
||||
self._types_names[object_type._meta.type_name] = object_type
|
||||
return object_type
|
||||
|
||||
def objecttype(self, type):
|
||||
name = getattr(type, 'name', None)
|
||||
if name:
|
||||
objecttype = self._types_names.get(name, None)
|
||||
if objecttype and inspect.isclass(objecttype) and issubclass(objecttype, BaseObjectType):
|
||||
return objecttype
|
||||
|
||||
def setup(self):
|
||||
assert self.query, 'The base query type is not set'
|
||||
self.T(self.query)
|
||||
|
||||
def get_type(self, type_name):
|
||||
# self.schema._build_type_map()
|
||||
self.setup()
|
||||
if type_name not in self._types_names:
|
||||
raise Exception('Type %s not found in %r' % (type_name, self))
|
||||
raise KeyError('Type %r not found in %r' % (type_name, self))
|
||||
return self._types_names[type_name]
|
||||
|
||||
@property
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import graphene
|
||||
from graphene.core.schema import Schema
|
||||
|
||||
|
@ -31,9 +30,7 @@ schema = Schema(query=Query, mutation=MyResultMutation)
|
|||
|
||||
|
||||
def test_mutation_input():
|
||||
assert ChangeNumber.input_type
|
||||
assert ChangeNumber.input_type._meta.type_name == 'ChangeNumberInput'
|
||||
assert list(ChangeNumber.input_type._meta.fields_map.keys()) == ['to']
|
||||
assert schema.T(ChangeNumber.arguments).keys() == ['to']
|
||||
|
||||
|
||||
def test_execute_mutations():
|
|
@ -120,7 +120,7 @@ def test_schema_register():
|
|||
assert schema.get_type('MyType') == MyType
|
||||
|
||||
|
||||
def test_schema_register():
|
||||
def test_schema_register_no_query_type():
|
||||
schema = Schema(name='My own schema')
|
||||
|
||||
@schema.register
|
||||
|
@ -149,6 +149,7 @@ def test_lazytype():
|
|||
|
||||
t = LazyType('MyType')
|
||||
|
||||
@schema.register
|
||||
class MyType(ObjectType):
|
||||
type = StringField(resolve=lambda *_: 'Dog')
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
from collections import OrderedDict
|
||||
from itertools import chain
|
||||
|
||||
from graphql.core.type import GraphQLArgument
|
||||
|
||||
from .base import OrderedType, ArgumentType
|
||||
from .base import BaseType, OrderedType, ArgumentType
|
||||
from ...utils import to_camel_case
|
||||
|
||||
|
||||
|
@ -21,6 +22,27 @@ class Argument(OrderedType):
|
|||
return self.name
|
||||
|
||||
|
||||
class ArgumentsGroup(BaseType):
|
||||
def __init__(self, *args, **kwargs):
|
||||
arguments = to_arguments(*args, **kwargs)
|
||||
self.arguments = OrderedDict([(arg.name, arg) for arg in arguments])
|
||||
|
||||
def internal_type(self, schema):
|
||||
return OrderedDict([(arg.name, schema.T(arg)) for arg in self.arguments.values()])
|
||||
|
||||
def __len__(self):
|
||||
return len(self.arguments)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.arguments)
|
||||
|
||||
def __contains__(self, *args):
|
||||
return self.arguments.__contains__(*args)
|
||||
|
||||
def __getitem__(self, *args):
|
||||
return self.arguments.__getitem__(*args)
|
||||
|
||||
|
||||
def to_arguments(*args, **kwargs):
|
||||
arguments = {}
|
||||
iter_arguments = chain(kwargs.items(), [(None, a) for a in args])
|
||||
|
|
|
@ -11,6 +11,9 @@ class LazyType(BaseType):
|
|||
def __init__(self, type_str):
|
||||
self.type_str = type_str
|
||||
|
||||
def is_self(self):
|
||||
return self.type_str == 'self'
|
||||
|
||||
def internal_type(self, schema):
|
||||
type = schema.get_type(self.type_str)
|
||||
return schema.T(type)
|
||||
|
|
|
@ -1,32 +1,35 @@
|
|||
import six
|
||||
from collections import OrderedDict
|
||||
from functools import wraps
|
||||
|
||||
from graphql.core.type import GraphQLField, GraphQLInputObjectField
|
||||
|
||||
from .base import LazyType, OrderedType
|
||||
from .argument import to_arguments
|
||||
from .argument import ArgumentsGroup
|
||||
from .definitions import NonNull
|
||||
from ...utils import to_camel_case
|
||||
from ..types import BaseObjectType, InputObjectType
|
||||
|
||||
|
||||
class Empty(object):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class Field(OrderedType):
|
||||
def __init__(self, type, description=None, args=None, name=None, resolver=None, *args_list, **kwargs):
|
||||
def __init__(self, type, description=None, args=None, name=None, resolver=None, required=False, default=None, *args_list, **kwargs):
|
||||
_creation_counter = kwargs.pop('_creation_counter', None)
|
||||
super(Field, self).__init__(_creation_counter=_creation_counter)
|
||||
self.name = name
|
||||
if isinstance(type, six.string_types) and type != 'self':
|
||||
if isinstance(type, six.string_types):
|
||||
type = LazyType(type)
|
||||
if required:
|
||||
type = NonNull(type)
|
||||
self.type = type
|
||||
self.description = description
|
||||
args = OrderedDict(args or {}, **kwargs)
|
||||
self.arguments = to_arguments(*args_list, **args)
|
||||
self.arguments = ArgumentsGroup(*args_list, **args)
|
||||
self.object_type = None
|
||||
self.resolver = resolver
|
||||
self.default = default
|
||||
|
||||
def contribute_to_class(self, cls, attname):
|
||||
assert issubclass(cls, BaseObjectType), 'Field {} cannot be mounted in {}'.format(self, cls)
|
||||
|
@ -34,7 +37,7 @@ class Field(OrderedType):
|
|||
self.name = to_camel_case(attname)
|
||||
self.attname = attname
|
||||
self.object_type = cls
|
||||
if self.type == 'self':
|
||||
if isinstance(self.type, LazyType) and self.type.is_self():
|
||||
self.type = cls
|
||||
cls._meta.add_field(self)
|
||||
|
||||
|
@ -49,41 +52,29 @@ class Field(OrderedType):
|
|||
def get_resolver_fn(self):
|
||||
resolve_fn_name = 'resolve_%s' % self.attname
|
||||
if hasattr(self.object_type, resolve_fn_name):
|
||||
resolve_fn = getattr(self.object_type, resolve_fn_name)
|
||||
return getattr(self.object_type, resolve_fn_name)
|
||||
|
||||
@wraps(resolve_fn)
|
||||
def custom_resolve_fn(instance, args, info):
|
||||
return resolve_fn(instance, args, info)
|
||||
return custom_resolve_fn
|
||||
|
||||
def default_getter(instance, args, info):
|
||||
return getattr(instance, self.attname, None)
|
||||
|
||||
return getattr(instance, self.attname, self.default)
|
||||
return default_getter
|
||||
|
||||
def internal_type(self, schema):
|
||||
resolver = self.resolver
|
||||
description = self.description
|
||||
arguments = self.arguments
|
||||
if not description and resolver:
|
||||
description = resolver.__doc__
|
||||
type = schema.T(self.type)
|
||||
type_objecttype = schema.objecttype(type)
|
||||
if type_objecttype and type_objecttype._meta.is_mutation:
|
||||
assert len(arguments) == 0
|
||||
arguments = type_objecttype.arguments
|
||||
resolver = getattr(type_objecttype, 'mutate')
|
||||
|
||||
assert type, 'Internal type for field %s is None' % str(self)
|
||||
return GraphQLField(type, args=self.get_arguments(schema), resolver=resolver,
|
||||
return GraphQLField(type, args=schema.T(arguments), resolver=resolver,
|
||||
description=description,)
|
||||
|
||||
def get_arguments(self, schema):
|
||||
if not self.arguments:
|
||||
return None
|
||||
|
||||
return OrderedDict([(arg.name, schema.T(arg)) for arg in self.arguments])
|
||||
|
||||
def __copy__(self):
|
||||
obj = Empty()
|
||||
obj.__class__ = self.__class__
|
||||
obj.__dict__ = self.__dict__.copy()
|
||||
obj.object_type = None
|
||||
return obj
|
||||
|
||||
def __repr__(self):
|
||||
"""
|
||||
Displays the module, class and name of the field.
|
||||
|
@ -103,9 +94,11 @@ class Field(OrderedType):
|
|||
|
||||
|
||||
class InputField(OrderedType):
|
||||
def __init__(self, type, description=None, default=None, name=None, _creation_counter=None):
|
||||
def __init__(self, type, description=None, default=None, name=None, _creation_counter=None, required=False):
|
||||
super(InputField, self).__init__(_creation_counter=_creation_counter)
|
||||
self.name = name
|
||||
if required:
|
||||
type = NonNull(type)
|
||||
self.type = type
|
||||
self.description = description
|
||||
self.default = default
|
||||
|
|
|
@ -8,6 +8,7 @@ import six
|
|||
from graphene import signals
|
||||
from graphene.core.options import Options
|
||||
from graphene.core.types.base import BaseType
|
||||
from graphene.core.types.argument import ArgumentsGroup
|
||||
from graphql.core.type import (GraphQLArgument, GraphQLInputObjectType,
|
||||
GraphQLInterfaceType, GraphQLObjectType)
|
||||
|
||||
|
@ -66,9 +67,10 @@ class ObjectTypeMeta(type):
|
|||
if input_class:
|
||||
items = dict(input_class.__dict__)
|
||||
items.pop('__dict__', None)
|
||||
input_type = type('{}Input'.format(
|
||||
new_class._meta.type_name), (ObjectType, ), items)
|
||||
new_class.add_to_class('input_type', input_type)
|
||||
items.pop('__doc__', None)
|
||||
items.pop('__module__', None)
|
||||
arguments = ArgumentsGroup(**items)
|
||||
new_class.add_to_class('arguments', arguments)
|
||||
|
||||
new_class.add_extra_fields()
|
||||
|
||||
|
@ -88,7 +90,7 @@ class ObjectTypeMeta(type):
|
|||
# on the base classes (we cannot handle shadowed fields at the
|
||||
# moment).
|
||||
for field in parent_fields:
|
||||
if field.name in field_names and field.__class__ != field_names[field.name].__class__:
|
||||
if field.name in field_names and field.type.__class__ != field_names[field.name].type.__class__:
|
||||
raise Exception(
|
||||
'Local field %r in class %r (%r) clashes '
|
||||
'with field with similar name from '
|
||||
|
@ -213,14 +215,10 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
|
|||
|
||||
|
||||
class Mutation(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
|
||||
|
||||
@classmethod
|
||||
def get_input_type(cls):
|
||||
return getattr(cls, 'input_type', None)
|
||||
pass
|
||||
|
||||
|
||||
class InputObjectType(ObjectType):
|
||||
|
||||
@classmethod
|
||||
def internal_type(cls, schema):
|
||||
fields = lambda: OrderedDict([(f.name, schema.T(f))
|
||||
|
|
|
@ -19,7 +19,7 @@ def test_nonnull_scalar():
|
|||
assert type.of_type == GraphQLString
|
||||
|
||||
|
||||
def test_mixed_scalar():
|
||||
def test_nested_scalars():
|
||||
type = schema.T(NonNull(List(String())))
|
||||
assert isinstance(type, GraphQLNonNull)
|
||||
assert isinstance(type.of_type, GraphQLList)
|
||||
|
|
|
@ -75,12 +75,7 @@ def test_field_string_reference():
|
|||
def test_field_custom_arguments():
|
||||
field = Field(None, name='my_customName', p=String())
|
||||
|
||||
class MyObjectType(ObjectType):
|
||||
my_field = field
|
||||
|
||||
schema = Schema(query=MyObjectType)
|
||||
|
||||
args = field.get_arguments(schema)
|
||||
args = field.arguments
|
||||
assert 'p' in args
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
from py.test import raises
|
||||
from pytest import raises
|
||||
|
||||
from graphene.core.fields import IntField, StringField
|
||||
from graphene.core.schema import Schema
|
||||
|
@ -66,9 +65,6 @@ def test_object_type():
|
|||
assert isinstance(object_type, GraphQLObjectType)
|
||||
assert object_type.description == 'Human description'
|
||||
assert list(object_type.get_fields().keys()) == ['name', 'friends']
|
||||
# assert object_type.get_fields() == {'name': Human._meta.fields_map['name'].internal_field(
|
||||
# schema), 'friends':
|
||||
# Human._meta.fields_map['friends'].internal_field(schema)}
|
||||
assert object_type.get_interfaces() == [schema.T(Character)]
|
||||
assert Human._meta.fields_map['name'].object_type == Human
|
||||
|
||||
|
@ -115,5 +111,5 @@ def test_field_mantain_resolver_tags():
|
|||
|
||||
tag_resolver(resolve_name, 'test')
|
||||
|
||||
field = Droid._meta.fields_map['name'].internal_field(schema)
|
||||
field = schema.T(Droid._meta.fields_map['name'])
|
||||
assert resolver_has_tag(field.resolver, 'test')
|
|
@ -1,162 +0,0 @@
|
|||
|
||||
from py.test import raises
|
||||
from pytest import raises
|
||||
|
||||
from graphene.core.fields import Field, NonNullField, StringField
|
||||
from graphene.core.options import Options
|
||||
from graphene.core.schema import Schema
|
||||
from graphene.core.types import ObjectType
|
||||
from graphql.core.type import (GraphQLBoolean, GraphQLField, GraphQLID,
|
||||
GraphQLInt, GraphQLNonNull, GraphQLString)
|
||||
|
||||
|
||||
class ot(ObjectType):
|
||||
def resolve_customdoc(self, *args, **kwargs):
|
||||
'''Resolver documentation'''
|
||||
return None
|
||||
|
||||
def __str__(self):
|
||||
return "ObjectType"
|
||||
|
||||
schema = Schema()
|
||||
|
||||
|
||||
def test_field_no_contributed_raises_error():
|
||||
f = Field(GraphQLString)
|
||||
with raises(Exception) as excinfo:
|
||||
schema.T(f)
|
||||
|
||||
|
||||
def test_field_type():
|
||||
f = Field(GraphQLString)
|
||||
f.contribute_to_class(ot, 'field_name')
|
||||
assert isinstance(schema.T(f), GraphQLField)
|
||||
assert schema.T(f).type == GraphQLString
|
||||
|
||||
|
||||
def test_field_name_automatic_camelcase():
|
||||
f = Field(GraphQLString)
|
||||
f.contribute_to_class(ot, 'field_name')
|
||||
assert f.name == 'fieldName'
|
||||
|
||||
|
||||
def test_field_name_use_name_if_exists():
|
||||
f = Field(GraphQLString, name='my_custom_name')
|
||||
f.contribute_to_class(ot, 'field_name')
|
||||
assert f.name == 'my_custom_name'
|
||||
|
||||
|
||||
def test_stringfield_type():
|
||||
f = StringField()
|
||||
f.contribute_to_class(ot, 'field_name')
|
||||
assert schema.T(f) == GraphQLString
|
||||
|
||||
|
||||
def test_nonnullfield_type():
|
||||
f = NonNullField(StringField())
|
||||
f.contribute_to_class(ot, 'field_name')
|
||||
assert isinstance(schema.T(f), GraphQLNonNull)
|
||||
|
||||
|
||||
def test_stringfield_type_required():
|
||||
f = Field(StringField(required=True))
|
||||
f.contribute_to_class(ot, 'field_name')
|
||||
assert isinstance(schema.T(f), GraphQLField)
|
||||
assert isinstance(schema.T(f).type, GraphQLNonNull)
|
||||
|
||||
|
||||
def test_field_resolve():
|
||||
f = StringField(required=True, resolve=lambda *args: 'RESOLVED')
|
||||
f.contribute_to_class(ot, 'field_name')
|
||||
field_type = f.internal_field(schema)
|
||||
assert 'RESOLVED' == field_type.resolver(ot, None, None)
|
||||
|
||||
|
||||
def test_field_resolve_type_custom():
|
||||
class MyCustomType(ObjectType):
|
||||
pass
|
||||
|
||||
class OtherType(ObjectType):
|
||||
pass
|
||||
|
||||
s = Schema()
|
||||
|
||||
f = Field('MyCustomType')
|
||||
f.contribute_to_class(OtherType, 'field_name')
|
||||
field_type = f.get_object_type(s)
|
||||
assert field_type == MyCustomType
|
||||
|
||||
|
||||
def test_field_resolve_type_custom():
|
||||
s = Schema()
|
||||
|
||||
f = Field('self')
|
||||
f.contribute_to_class(ot, 'field_name')
|
||||
field_type = f.get_object_type(s)
|
||||
assert field_type == ot
|
||||
|
||||
|
||||
def test_field_orders():
|
||||
f1 = Field(None)
|
||||
f2 = Field(None)
|
||||
assert f1 < f2
|
||||
|
||||
|
||||
def test_field_orders_wrong_type():
|
||||
field = Field(None)
|
||||
try:
|
||||
assert not field < 1
|
||||
except TypeError:
|
||||
# Fix exception raising in Python3+
|
||||
pass
|
||||
|
||||
|
||||
def test_field_eq():
|
||||
f1 = Field(None)
|
||||
f2 = Field(None)
|
||||
assert f1 != f2
|
||||
|
||||
|
||||
def test_field_eq_wrong_type():
|
||||
field = Field(None)
|
||||
assert field != 1
|
||||
|
||||
|
||||
def test_field_hash():
|
||||
f1 = Field(None)
|
||||
f2 = Field(None)
|
||||
assert hash(f1) != hash(f2)
|
||||
|
||||
|
||||
def test_field_none_type_raises_error():
|
||||
s = Schema()
|
||||
f = Field(None)
|
||||
f.contribute_to_class(ot, 'field_name')
|
||||
with raises(Exception) as excinfo:
|
||||
f.internal_field(s)
|
||||
assert str(
|
||||
excinfo.value) == "Internal type for field ObjectType.field_name is None"
|
||||
|
||||
|
||||
def test_field_str():
|
||||
f = StringField()
|
||||
f.contribute_to_class(ot, 'field_name')
|
||||
assert str(f) == "ObjectType.field_name"
|
||||
|
||||
|
||||
def test_field_repr():
|
||||
f = StringField()
|
||||
assert repr(f) == "<graphene.core.fields.StringField>"
|
||||
|
||||
|
||||
def test_field_repr_contributed():
|
||||
f = StringField()
|
||||
f.contribute_to_class(ot, 'field_name')
|
||||
assert repr(f) == "<graphene.core.fields.StringField: field_name>"
|
||||
|
||||
|
||||
def test_field_resolve_objecttype_cos():
|
||||
f = StringField()
|
||||
f.contribute_to_class(ot, 'customdoc')
|
||||
field = f.internal_field(schema)
|
||||
assert field.description == 'Resolver documentation'
|
|
@ -1,16 +0,0 @@
|
|||
from graphene.core.scalars import GraphQLSkipField
|
||||
|
||||
|
||||
def test_skipfield_serialize():
|
||||
f = GraphQLSkipField
|
||||
assert f.serialize('a') is None
|
||||
|
||||
|
||||
def test_skipfield_parse_value():
|
||||
f = GraphQLSkipField
|
||||
assert f.parse_value('a') is None
|
||||
|
||||
|
||||
def test_skipfield_parse_literal():
|
||||
f = GraphQLSkipField
|
||||
assert f.parse_literal('a') is None
|
|
@ -1,143 +0,0 @@
|
|||
|
||||
from py.test import raises
|
||||
from pytest import raises
|
||||
|
||||
from graphene import Interface, ObjectType, Schema
|
||||
from graphene.core.fields import Field, ListField, StringField
|
||||
from graphql.core import graphql
|
||||
from graphql.core.type import (GraphQLInterfaceType, GraphQLObjectType,
|
||||
GraphQLSchema)
|
||||
from tests.utils import assert_equal_lists
|
||||
|
||||
schema = Schema(name='My own schema')
|
||||
|
||||
|
||||
class Character(Interface):
|
||||
name = StringField()
|
||||
|
||||
|
||||
class Pet(ObjectType):
|
||||
type = StringField(resolve=lambda *_: 'Dog')
|
||||
|
||||
|
||||
class Human(Character):
|
||||
friends = ListField(Character)
|
||||
pet = Field(Pet)
|
||||
|
||||
def resolve_name(self, *args):
|
||||
return 'Peter'
|
||||
|
||||
def resolve_friend(self, *args):
|
||||
return Human(object())
|
||||
|
||||
def resolve_pet(self, *args):
|
||||
return Pet(object())
|
||||
|
||||
schema.query = Human
|
||||
|
||||
|
||||
def test_get_registered_type():
|
||||
assert schema.get_type('Character') == Character
|
||||
|
||||
|
||||
def test_get_unregistered_type():
|
||||
with raises(Exception) as excinfo:
|
||||
schema.get_type('NON_EXISTENT_MODEL')
|
||||
assert 'not found' in str(excinfo.value)
|
||||
|
||||
|
||||
def test_schema_query():
|
||||
assert schema.query == Human
|
||||
|
||||
|
||||
def test_query_schema_graphql():
|
||||
object()
|
||||
query = '''
|
||||
{
|
||||
name
|
||||
pet {
|
||||
type
|
||||
}
|
||||
}
|
||||
'''
|
||||
expected = {
|
||||
'name': 'Peter',
|
||||
'pet': {
|
||||
'type': 'Dog'
|
||||
}
|
||||
}
|
||||
result = graphql(schema.schema, query, root=Human(object()))
|
||||
assert not result.errors
|
||||
assert result.data == expected
|
||||
|
||||
|
||||
def test_query_schema_execute():
|
||||
object()
|
||||
query = '''
|
||||
{
|
||||
name
|
||||
pet {
|
||||
type
|
||||
}
|
||||
}
|
||||
'''
|
||||
expected = {
|
||||
'name': 'Peter',
|
||||
'pet': {
|
||||
'type': 'Dog'
|
||||
}
|
||||
}
|
||||
result = schema.execute(query, root=object())
|
||||
assert not result.errors
|
||||
assert result.data == expected
|
||||
|
||||
|
||||
def test_schema_get_type_map():
|
||||
assert_equal_lists(
|
||||
schema.schema.get_type_map().keys(),
|
||||
['__Field', 'String', 'Pet', 'Character', '__InputValue', '__Directive',
|
||||
'__TypeKind', '__Schema', '__Type', 'Human', '__EnumValue', 'Boolean']
|
||||
)
|
||||
|
||||
|
||||
def test_schema_no_query():
|
||||
schema = Schema(name='My own schema')
|
||||
with raises(Exception) as excinfo:
|
||||
schema.schema
|
||||
assert 'define a base query type' in str(excinfo)
|
||||
|
||||
|
||||
def test_schema_register():
|
||||
schema = Schema(name='My own schema')
|
||||
|
||||
@schema.register
|
||||
class MyType(ObjectType):
|
||||
type = StringField(resolve=lambda *_: 'Dog')
|
||||
|
||||
schema.query = MyType
|
||||
|
||||
assert schema.get_type('MyType') == MyType
|
||||
|
||||
|
||||
def test_schema_register():
|
||||
schema = Schema(name='My own schema')
|
||||
|
||||
@schema.register
|
||||
class MyType(ObjectType):
|
||||
type = StringField(resolve=lambda *_: 'Dog')
|
||||
|
||||
with raises(Exception) as excinfo:
|
||||
schema.get_type('MyType')
|
||||
assert 'base query type' in str(excinfo.value)
|
||||
|
||||
|
||||
def test_schema_introspect():
|
||||
schema = Schema(name='My own schema')
|
||||
|
||||
class MyType(ObjectType):
|
||||
type = StringField(resolve=lambda *_: 'Dog')
|
||||
|
||||
schema.query = MyType
|
||||
|
||||
introspection = schema.introspect()
|
||||
assert '__schema' in introspection
|
Loading…
Reference in New Issue
Block a user