mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-25 11:03:58 +03:00
Improved syntax. Added autolinter. Added automatic flake8 checker in tests. Fixed #17
This commit is contained in:
parent
9ea57ecc5f
commit
d46e957863
|
@ -13,6 +13,6 @@ install:
|
||||||
- python setup.py develop
|
- python setup.py develop
|
||||||
script:
|
script:
|
||||||
- py.test --cov=graphene
|
- py.test --cov=graphene
|
||||||
# - flake8
|
- flake8
|
||||||
after_success:
|
after_success:
|
||||||
- coveralls
|
- coveralls
|
||||||
|
|
4
bin/autolinter
Executable file
4
bin/autolinter
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
autoflake ./ -r --remove-unused-variables --remove-all-unused-imports --in-place
|
||||||
|
isort -rc .
|
|
@ -1,8 +1,8 @@
|
||||||
from graphql.core.type import GraphQLEnumValue
|
|
||||||
import graphene
|
import graphene
|
||||||
from graphene import resolve_only_args
|
from graphene import resolve_only_args
|
||||||
|
from graphql.core.type import GraphQLEnumValue
|
||||||
|
|
||||||
from .data import getHero, getHuman, getCharacter, getDroid
|
from .data import getCharacter, getDroid, getHero, getHuman
|
||||||
|
|
||||||
Episode = graphene.Enum('Episode', dict(
|
Episode = graphene.Enum('Episode', dict(
|
||||||
NEWHOPE=GraphQLEnumValue(4),
|
NEWHOPE=GraphQLEnumValue(4),
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
from ..schema import Schema, Query
|
|
||||||
from graphql.core import graphql
|
|
||||||
from ..data import setup
|
from ..data import setup
|
||||||
|
from ..schema import Schema
|
||||||
|
|
||||||
setup()
|
setup()
|
||||||
|
|
||||||
|
|
||||||
def test_hero_name_query():
|
def test_hero_name_query():
|
||||||
query = '''
|
query = '''
|
||||||
query HeroNameQuery {
|
query HeroNameQuery {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from .models import Ship, Faction, Character
|
from .models import Character, Faction, Ship
|
||||||
|
|
||||||
|
|
||||||
def initialize():
|
def initialize():
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,18 @@
|
||||||
import graphene
|
import graphene
|
||||||
from graphene import resolve_only_args, relay
|
from graphene import relay, resolve_only_args
|
||||||
from graphene.contrib.django import (
|
from graphene.contrib.django import DjangoNode, DjangoObjectType
|
||||||
DjangoObjectType,
|
|
||||||
DjangoNode
|
from .data import (create_ship, get_empire, get_faction, get_rebels, get_ship,
|
||||||
)
|
get_ships)
|
||||||
from .models import (
|
from .models import Character as CharacterModel
|
||||||
Ship as ShipModel, Faction as FactionModel, Character as CharacterModel)
|
from .models import Faction as FactionModel
|
||||||
from .data import (
|
from .models import Ship as ShipModel
|
||||||
get_faction,
|
|
||||||
get_ship,
|
|
||||||
get_ships,
|
|
||||||
get_rebels,
|
|
||||||
get_empire,
|
|
||||||
create_ship
|
|
||||||
)
|
|
||||||
|
|
||||||
schema = graphene.Schema(name='Starwars Django Relay Schema')
|
schema = graphene.Schema(name='Starwars Django Relay Schema')
|
||||||
|
|
||||||
|
|
||||||
class Ship(DjangoNode):
|
class Ship(DjangoNode):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ShipModel
|
model = ShipModel
|
||||||
|
|
||||||
|
@ -29,11 +23,13 @@ class Ship(DjangoNode):
|
||||||
|
|
||||||
@schema.register
|
@schema.register
|
||||||
class Character(DjangoObjectType):
|
class Character(DjangoObjectType):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CharacterModel
|
model = CharacterModel
|
||||||
|
|
||||||
|
|
||||||
class Faction(DjangoNode):
|
class Faction(DjangoNode):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = FactionModel
|
model = FactionModel
|
||||||
|
|
||||||
|
@ -43,6 +39,7 @@ class Faction(DjangoNode):
|
||||||
|
|
||||||
|
|
||||||
class IntroduceShip(relay.ClientIDMutation):
|
class IntroduceShip(relay.ClientIDMutation):
|
||||||
|
|
||||||
class Input:
|
class Input:
|
||||||
ship_name = graphene.StringField(required=True)
|
ship_name = graphene.StringField(required=True)
|
||||||
faction_id = graphene.StringField(required=True)
|
faction_id = graphene.StringField(required=True)
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import pytest
|
import pytest
|
||||||
from graphql.core import graphql
|
|
||||||
|
|
||||||
from ..models import *
|
|
||||||
from ..schema import schema
|
|
||||||
from ..data import initialize
|
from ..data import initialize
|
||||||
|
from ..schema import schema
|
||||||
|
|
||||||
pytestmark = pytest.mark.django_db
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import pytest
|
import pytest
|
||||||
from ..schema import schema
|
|
||||||
from ..data import initialize
|
from ..data import initialize
|
||||||
|
from ..schema import schema
|
||||||
|
|
||||||
pytestmark = pytest.mark.django_db
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import pytest
|
import pytest
|
||||||
from pytest import raises
|
|
||||||
from graphql.core import graphql
|
|
||||||
from ..data import initialize
|
|
||||||
|
|
||||||
|
from ..data import initialize
|
||||||
from ..schema import schema
|
from ..schema import schema
|
||||||
|
|
||||||
pytestmark = pytest.mark.django_db
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
|
@ -3,7 +3,7 @@ data = {}
|
||||||
|
|
||||||
def setup():
|
def setup():
|
||||||
global data
|
global data
|
||||||
|
|
||||||
from .schema import Ship, Faction
|
from .schema import Ship, Faction
|
||||||
xwing = Ship(
|
xwing = Ship(
|
||||||
id='1',
|
id='1',
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
import graphene
|
import graphene
|
||||||
from graphene import resolve_only_args, relay
|
from graphene import relay, resolve_only_args
|
||||||
|
|
||||||
from .data import (
|
from .data import create_ship, get_empire, get_faction, get_rebels, get_ship
|
||||||
get_faction,
|
|
||||||
get_ship,
|
|
||||||
get_rebels,
|
|
||||||
get_empire,
|
|
||||||
create_ship,
|
|
||||||
)
|
|
||||||
|
|
||||||
schema = graphene.Schema(name='Starwars Relay Schema')
|
schema = graphene.Schema(name='Starwars Relay Schema')
|
||||||
|
|
||||||
|
@ -38,6 +32,7 @@ class Faction(relay.Node):
|
||||||
|
|
||||||
|
|
||||||
class IntroduceShip(relay.ClientIDMutation):
|
class IntroduceShip(relay.ClientIDMutation):
|
||||||
|
|
||||||
class Input:
|
class Input:
|
||||||
ship_name = graphene.StringField(required=True)
|
ship_name = graphene.StringField(required=True)
|
||||||
faction_id = graphene.StringField(required=True)
|
faction_id = graphene.StringField(required=True)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from ..schema import schema
|
|
||||||
from ..data import setup
|
from ..data import setup
|
||||||
|
from ..schema import schema
|
||||||
|
|
||||||
setup()
|
setup()
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from ..schema import schema
|
|
||||||
from ..data import setup
|
from ..data import setup
|
||||||
|
from ..schema import schema
|
||||||
|
|
||||||
setup()
|
setup()
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from ..schema import schema
|
|
||||||
from ..data import setup
|
from ..data import setup
|
||||||
|
from ..schema import schema
|
||||||
|
|
||||||
setup()
|
setup()
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
from singledispatch import singledispatch
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from singledispatch import singledispatch
|
||||||
|
|
||||||
from graphene.core.fields import (
|
from graphene.contrib.django.fields import (ConnectionOrListField,
|
||||||
StringField,
|
DjangoModelField)
|
||||||
IDField,
|
from graphene.core.fields import (BooleanField, FloatField, IDField, IntField,
|
||||||
IntField,
|
StringField)
|
||||||
BooleanField,
|
|
||||||
FloatField,
|
|
||||||
ListField
|
|
||||||
)
|
|
||||||
from graphene.contrib.django.fields import ConnectionOrListField, DjangoModelField
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
UUIDField = models.UUIDField
|
UUIDField = models.UUIDField
|
||||||
|
@ -32,12 +27,12 @@ def convert_django_field(field):
|
||||||
@convert_django_field.register(models.SlugField)
|
@convert_django_field.register(models.SlugField)
|
||||||
@convert_django_field.register(models.URLField)
|
@convert_django_field.register(models.URLField)
|
||||||
@convert_django_field.register(UUIDField)
|
@convert_django_field.register(UUIDField)
|
||||||
def _(field):
|
def convert_field_to_string(field):
|
||||||
return StringField(description=field.help_text)
|
return StringField(description=field.help_text)
|
||||||
|
|
||||||
|
|
||||||
@convert_django_field.register(models.AutoField)
|
@convert_django_field.register(models.AutoField)
|
||||||
def _(field):
|
def convert_field_to_id(field):
|
||||||
return IDField(description=field.help_text)
|
return IDField(description=field.help_text)
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,34 +41,34 @@ def _(field):
|
||||||
@convert_django_field.register(models.SmallIntegerField)
|
@convert_django_field.register(models.SmallIntegerField)
|
||||||
@convert_django_field.register(models.BigIntegerField)
|
@convert_django_field.register(models.BigIntegerField)
|
||||||
@convert_django_field.register(models.IntegerField)
|
@convert_django_field.register(models.IntegerField)
|
||||||
def _(field):
|
def convert_field_to_int(field):
|
||||||
return IntField(description=field.help_text)
|
return IntField(description=field.help_text)
|
||||||
|
|
||||||
|
|
||||||
@convert_django_field.register(models.BooleanField)
|
@convert_django_field.register(models.BooleanField)
|
||||||
def _(field):
|
def convert_field_to_boolean(field):
|
||||||
return BooleanField(description=field.help_text, required=True)
|
return BooleanField(description=field.help_text, required=True)
|
||||||
|
|
||||||
|
|
||||||
@convert_django_field.register(models.NullBooleanField)
|
@convert_django_field.register(models.NullBooleanField)
|
||||||
def _(field):
|
def convert_field_to_nullboolean(field):
|
||||||
return BooleanField(description=field.help_text)
|
return BooleanField(description=field.help_text)
|
||||||
|
|
||||||
|
|
||||||
@convert_django_field.register(models.DecimalField)
|
@convert_django_field.register(models.DecimalField)
|
||||||
@convert_django_field.register(models.FloatField)
|
@convert_django_field.register(models.FloatField)
|
||||||
def _(field):
|
def convert_field_to_float(field):
|
||||||
return FloatField(description=field.help_text)
|
return FloatField(description=field.help_text)
|
||||||
|
|
||||||
|
|
||||||
@convert_django_field.register(models.ManyToManyField)
|
@convert_django_field.register(models.ManyToManyField)
|
||||||
@convert_django_field.register(models.ManyToOneRel)
|
@convert_django_field.register(models.ManyToOneRel)
|
||||||
def _(field):
|
def convert_field_to_list_or_connection(field):
|
||||||
model_field = DjangoModelField(field.related_model)
|
model_field = DjangoModelField(field.related_model)
|
||||||
return ConnectionOrListField(model_field)
|
return ConnectionOrListField(model_field)
|
||||||
|
|
||||||
|
|
||||||
@convert_django_field.register(models.OneToOneField)
|
@convert_django_field.register(models.OneToOneField)
|
||||||
@convert_django_field.register(models.ForeignKey)
|
@convert_django_field.register(models.ForeignKey)
|
||||||
def _(field):
|
def convert_field_to_djangomodel(field):
|
||||||
return DjangoModelField(field.related_model, description=field.help_text)
|
return DjangoModelField(field.related_model, description=field.help_text)
|
||||||
|
|
|
@ -1,21 +1,18 @@
|
||||||
from graphene.core.fields import (
|
|
||||||
ListField
|
|
||||||
)
|
|
||||||
from graphene import relay
|
from graphene import relay
|
||||||
|
|
||||||
from graphene.core.fields import Field, LazyField
|
|
||||||
|
|
||||||
from graphene.relay.utils import is_node
|
|
||||||
from graphene.contrib.django.utils import get_type_for_model, lazy_map
|
from graphene.contrib.django.utils import get_type_for_model, lazy_map
|
||||||
|
from graphene.core.fields import Field, LazyField, ListField
|
||||||
|
from graphene.relay.utils import is_node
|
||||||
|
|
||||||
|
|
||||||
class DjangoConnectionField(relay.ConnectionField):
|
class DjangoConnectionField(relay.ConnectionField):
|
||||||
|
|
||||||
def wrap_resolved(self, value, instance, args, info):
|
def wrap_resolved(self, value, instance, args, info):
|
||||||
schema = info.schema.graphene_schema
|
schema = info.schema.graphene_schema
|
||||||
return lazy_map(value, self.get_object_type(schema))
|
return lazy_map(value, self.get_object_type(schema))
|
||||||
|
|
||||||
|
|
||||||
class LazyListField(ListField):
|
class LazyListField(ListField):
|
||||||
|
|
||||||
def resolve(self, instance, args, info):
|
def resolve(self, instance, args, info):
|
||||||
schema = info.schema.graphene_schema
|
schema = info.schema.graphene_schema
|
||||||
resolved = super(LazyListField, self).resolve(instance, args, info)
|
resolved = super(LazyListField, self).resolve(instance, args, info)
|
||||||
|
@ -23,6 +20,7 @@ class LazyListField(ListField):
|
||||||
|
|
||||||
|
|
||||||
class ConnectionOrListField(LazyField):
|
class ConnectionOrListField(LazyField):
|
||||||
|
|
||||||
def get_field(self, schema):
|
def get_field(self, schema):
|
||||||
model_field = self.field_type
|
model_field = self.field_type
|
||||||
field_object_type = model_field.get_object_type(schema)
|
field_object_type = model_field.get_object_type(schema)
|
||||||
|
@ -35,6 +33,7 @@ class ConnectionOrListField(LazyField):
|
||||||
|
|
||||||
|
|
||||||
class DjangoModelField(Field):
|
class DjangoModelField(Field):
|
||||||
|
|
||||||
def __init__(self, model, *args, **kwargs):
|
def __init__(self, model, *args, **kwargs):
|
||||||
super(DjangoModelField, self).__init__(None, *args, **kwargs)
|
super(DjangoModelField, self).__init__(None, *args, **kwargs)
|
||||||
self.model = model
|
self.model = model
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
from graphene.core.options import Options
|
from graphene.core.options import Options
|
||||||
from graphene.relay.utils import is_node
|
|
||||||
from graphene.relay.types import Node
|
from graphene.relay.types import Node
|
||||||
|
from graphene.relay.utils import is_node
|
||||||
|
|
||||||
VALID_ATTRS = ('model', 'only_fields', 'exclude_fields')
|
VALID_ATTRS = ('model', 'only_fields', 'exclude_fields')
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from graphene.core.types import ObjectTypeMeta, BaseObjectType
|
|
||||||
from graphene.contrib.django.options import DjangoOptions
|
|
||||||
from graphene.contrib.django.converter import convert_django_field
|
from graphene.contrib.django.converter import convert_django_field
|
||||||
|
from graphene.contrib.django.options import DjangoOptions
|
||||||
from graphene.contrib.django.utils import get_reverse_fields
|
from graphene.contrib.django.utils import get_reverse_fields
|
||||||
|
from graphene.core.types import BaseObjectType, ObjectTypeMeta
|
||||||
from graphene.relay.types import BaseNode
|
|
||||||
from graphene.relay.fields import GlobalIDField
|
from graphene.relay.fields import GlobalIDField
|
||||||
|
from graphene.relay.types import BaseNode
|
||||||
|
|
||||||
|
|
||||||
class DjangoObjectTypeMeta(ObjectTypeMeta):
|
class DjangoObjectTypeMeta(ObjectTypeMeta):
|
||||||
|
@ -38,6 +37,7 @@ class DjangoObjectTypeMeta(ObjectTypeMeta):
|
||||||
|
|
||||||
|
|
||||||
class InstanceObjectType(BaseObjectType):
|
class InstanceObjectType(BaseObjectType):
|
||||||
|
|
||||||
def __init__(self, instance=None):
|
def __init__(self, instance=None):
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
super(InstanceObjectType, self).__init__()
|
super(InstanceObjectType, self).__init__()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models.query import QuerySet
|
|
||||||
from django.db.models.manager import Manager
|
from django.db.models.manager import Manager
|
||||||
|
from django.db.models.query import QuerySet
|
||||||
|
|
||||||
from graphene.utils import LazyMap
|
from graphene.utils import LazyMap
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
from django.conf import settings
|
|
||||||
|
|
||||||
from graphql.core.error import GraphQLError, format_error
|
from graphql.core.error import GraphQLError, format_error
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@ class GraphQLView(View):
|
||||||
|
|
||||||
def response_errors(self, *errors):
|
def response_errors(self, *errors):
|
||||||
errors = [{
|
errors = [{
|
||||||
"message": str(e)
|
"message": str(e)
|
||||||
} for e in errors]
|
} for e in errors]
|
||||||
return HttpResponse(json.dumps({'errors': errors}), content_type='application/json')
|
return HttpResponse(json.dumps({'errors': errors}), content_type='application/json')
|
||||||
|
|
||||||
def execute_query(self, request, query, *args, **kwargs):
|
def execute_query(self, request, query, *args, **kwargs):
|
||||||
|
|
|
@ -1,26 +1,21 @@
|
||||||
import inspect
|
import inspect
|
||||||
|
from functools import total_ordering, wraps
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
from graphene.core.scalars import GraphQLSkipField
|
||||||
|
from graphene.core.types import BaseObjectType, InputObjectType
|
||||||
|
from graphene.utils import ProxySnakeDict, enum_to_graphql_enum, to_camel_case
|
||||||
|
from graphql.core.type import (GraphQLArgument, GraphQLBoolean, GraphQLField,
|
||||||
|
GraphQLFloat, GraphQLID,
|
||||||
|
GraphQLInputObjectField, GraphQLInt,
|
||||||
|
GraphQLList, GraphQLNonNull, GraphQLString)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
except ImportError:
|
except ImportError:
|
||||||
class Enum(object):
|
class Enum(object):
|
||||||
pass
|
pass
|
||||||
from functools import total_ordering, wraps
|
|
||||||
from graphql.core.type import (
|
|
||||||
GraphQLField,
|
|
||||||
GraphQLList,
|
|
||||||
GraphQLNonNull,
|
|
||||||
GraphQLInt,
|
|
||||||
GraphQLString,
|
|
||||||
GraphQLBoolean,
|
|
||||||
GraphQLID,
|
|
||||||
GraphQLArgument,
|
|
||||||
GraphQLFloat,
|
|
||||||
GraphQLInputObjectField,
|
|
||||||
)
|
|
||||||
from graphene.utils import to_camel_case, ProxySnakeDict, enum_to_graphql_enum
|
|
||||||
from graphene.core.types import BaseObjectType, InputObjectType
|
|
||||||
from graphene.core.scalars import GraphQLSkipField
|
|
||||||
|
|
||||||
|
|
||||||
class Empty(object):
|
class Empty(object):
|
||||||
|
@ -252,10 +247,12 @@ class FloatField(TypeField):
|
||||||
|
|
||||||
|
|
||||||
class ListField(Field):
|
class ListField(Field):
|
||||||
|
|
||||||
def type_wrapper(self, field_type):
|
def type_wrapper(self, field_type):
|
||||||
return GraphQLList(field_type)
|
return GraphQLList(field_type)
|
||||||
|
|
||||||
|
|
||||||
class NonNullField(Field):
|
class NonNullField(Field):
|
||||||
|
|
||||||
def type_wrapper(self, field_type):
|
def type_wrapper(self, field_type):
|
||||||
return GraphQLNonNull(field_type)
|
return GraphQLNonNull(field_type)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
from graphene.utils import cached_property
|
from graphene.utils import cached_property
|
||||||
from collections import OrderedDict, namedtuple
|
|
||||||
|
|
||||||
DEFAULT_NAMES = ('description', 'name', 'is_interface', 'is_mutation',
|
DEFAULT_NAMES = ('description', 'name', 'is_interface', 'is_mutation',
|
||||||
'type_name', 'interfaces', 'proxy')
|
'type_name', 'interfaces', 'proxy')
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
from functools import wraps
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
from functools import wraps
|
||||||
|
|
||||||
from graphql.core.type import (
|
|
||||||
GraphQLSchema as _GraphQLSchema
|
|
||||||
)
|
|
||||||
|
|
||||||
from graphql.core.execution.executor import Executor
|
|
||||||
from graphql.core.execution.middlewares.sync import SynchronousExecutionMiddleware
|
|
||||||
|
|
||||||
from graphql.core.utils.introspection_query import introspection_query
|
|
||||||
from graphene import signals
|
from graphene import signals
|
||||||
from graphene.utils import cached_property
|
from graphql.core.execution.executor import Executor
|
||||||
|
from graphql.core.execution.middlewares.sync import \
|
||||||
|
SynchronousExecutionMiddleware
|
||||||
|
from graphql.core.type import GraphQLSchema as _GraphQLSchema
|
||||||
|
from graphql.core.utils.introspection_query import introspection_query
|
||||||
|
|
||||||
|
|
||||||
class GraphQLSchema(_GraphQLSchema):
|
class GraphQLSchema(_GraphQLSchema):
|
||||||
|
|
||||||
def __init__(self, schema, *args, **kwargs):
|
def __init__(self, schema, *args, **kwargs):
|
||||||
self.graphene_schema = schema
|
self.graphene_schema = schema
|
||||||
super(GraphQLSchema, self).__init__(*args, **kwargs)
|
super(GraphQLSchema, self).__init__(*args, **kwargs)
|
||||||
|
@ -61,7 +58,8 @@ class Schema(object):
|
||||||
@property
|
@property
|
||||||
def executor(self):
|
def executor(self):
|
||||||
if not self._executor:
|
if not self._executor:
|
||||||
self.executor = Executor([SynchronousExecutionMiddleware()], map_type=OrderedDict)
|
self.executor = Executor(
|
||||||
|
[SynchronousExecutionMiddleware()], map_type=OrderedDict)
|
||||||
return self._executor
|
return self._executor
|
||||||
|
|
||||||
@executor.setter
|
@executor.setter
|
||||||
|
|
|
@ -1,19 +1,14 @@
|
||||||
import inspect
|
|
||||||
import six
|
|
||||||
import copy
|
import copy
|
||||||
|
import inspect
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from graphql.core.type import (
|
import six
|
||||||
GraphQLObjectType,
|
|
||||||
GraphQLInputObjectType,
|
|
||||||
GraphQLInterfaceType,
|
|
||||||
GraphQLArgument
|
|
||||||
)
|
|
||||||
|
|
||||||
from graphene import signals
|
from graphene import signals
|
||||||
from graphene.core.options import Options
|
from graphene.core.options import Options
|
||||||
from graphene.utils import memoize
|
|
||||||
from graphene.core.schema import register_internal_type
|
from graphene.core.schema import register_internal_type
|
||||||
|
from graphql.core.type import (GraphQLArgument, GraphQLInputObjectType,
|
||||||
|
GraphQLInterfaceType, GraphQLObjectType)
|
||||||
|
|
||||||
|
|
||||||
class ObjectTypeMeta(type):
|
class ObjectTypeMeta(type):
|
||||||
|
@ -45,14 +40,15 @@ class ObjectTypeMeta(type):
|
||||||
else:
|
else:
|
||||||
meta = attr_meta
|
meta = attr_meta
|
||||||
|
|
||||||
base_meta = getattr(new_class, '_meta', None)
|
getattr(new_class, '_meta', None)
|
||||||
|
|
||||||
new_class.add_to_class('_meta', new_class.options_cls(meta))
|
new_class.add_to_class('_meta', new_class.options_cls(meta))
|
||||||
|
|
||||||
new_class._meta.is_interface = new_class.is_interface(parents)
|
new_class._meta.is_interface = new_class.is_interface(parents)
|
||||||
new_class._meta.is_mutation = new_class.is_mutation(parents)
|
new_class._meta.is_mutation = new_class.is_mutation(parents)
|
||||||
|
|
||||||
assert not (new_class._meta.is_interface and new_class._meta.is_mutation)
|
assert not (
|
||||||
|
new_class._meta.is_interface and new_class._meta.is_mutation)
|
||||||
|
|
||||||
input_class = None
|
input_class = None
|
||||||
if new_class._meta.is_mutation:
|
if new_class._meta.is_mutation:
|
||||||
|
@ -63,12 +59,14 @@ class ObjectTypeMeta(type):
|
||||||
new_class.add_to_class(obj_name, obj)
|
new_class.add_to_class(obj_name, obj)
|
||||||
|
|
||||||
if new_class._meta.is_mutation:
|
if new_class._meta.is_mutation:
|
||||||
assert hasattr(new_class, 'mutate'), "All mutations must implement mutate method"
|
assert hasattr(
|
||||||
|
new_class, 'mutate'), "All mutations must implement mutate method"
|
||||||
|
|
||||||
if input_class:
|
if input_class:
|
||||||
items = dict(input_class.__dict__)
|
items = dict(input_class.__dict__)
|
||||||
items.pop('__dict__', None)
|
items.pop('__dict__', None)
|
||||||
input_type = type('{}Input'.format(new_class._meta.type_name), (ObjectType, ), items)
|
input_type = type('{}Input'.format(
|
||||||
|
new_class._meta.type_name), (ObjectType, ), items)
|
||||||
new_class.add_to_class('input_type', input_type)
|
new_class.add_to_class('input_type', input_type)
|
||||||
|
|
||||||
new_class.add_extra_fields()
|
new_class.add_extra_fields()
|
||||||
|
@ -166,7 +164,8 @@ class BaseObjectType(object):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
if kwargs:
|
if kwargs:
|
||||||
raise TypeError("'%s' is an invalid keyword argument for this function" % list(kwargs)[0])
|
raise TypeError(
|
||||||
|
"'%s' is an invalid keyword argument for this function" % list(kwargs)[0])
|
||||||
|
|
||||||
signals.post_init.send(self.__class__, instance=self)
|
signals.post_init.send(self.__class__, instance=self)
|
||||||
|
|
||||||
|
@ -215,12 +214,14 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
|
||||||
|
|
||||||
|
|
||||||
class Mutation(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
|
class Mutation(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_input_type(cls):
|
def get_input_type(cls):
|
||||||
return getattr(cls, 'input_type', None)
|
return getattr(cls, 'input_type', None)
|
||||||
|
|
||||||
|
|
||||||
class InputObjectType(ObjectType):
|
class InputObjectType(ObjectType):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@register_internal_type
|
@register_internal_type
|
||||||
def internal_type(cls, schema):
|
def internal_type(cls, schema):
|
||||||
|
|
|
@ -15,4 +15,4 @@ from graphene.relay.types import (
|
||||||
from graphene.relay.utils import is_node
|
from graphene.relay.utils import is_node
|
||||||
|
|
||||||
__all__ = ['ConnectionField', 'NodeField', 'GlobalIDField', 'Node',
|
__all__ = ['ConnectionField', 'NodeField', 'GlobalIDField', 'Node',
|
||||||
'PageInfo', 'Edge', 'Connection', 'is_node']
|
'PageInfo', 'Edge', 'Connection', 'ClientIDMutation', 'is_node']
|
||||||
|
|
|
@ -1,21 +1,10 @@
|
||||||
from collections import Iterable, OrderedDict
|
from collections import Iterable
|
||||||
|
|
||||||
from graphql_relay.connection.arrayconnection import (
|
|
||||||
connection_from_list
|
|
||||||
)
|
|
||||||
from graphql_relay.connection.connection import (
|
|
||||||
connection_args
|
|
||||||
)
|
|
||||||
from graphql_relay.node.node import (
|
|
||||||
from_global_id
|
|
||||||
)
|
|
||||||
from graphql.core.type import (
|
|
||||||
GraphQLNonNull,
|
|
||||||
GraphQLID,
|
|
||||||
GraphQLArgument,
|
|
||||||
)
|
|
||||||
|
|
||||||
from graphene.core.fields import Field, IDField
|
from graphene.core.fields import Field, IDField
|
||||||
|
from graphql.core.type import GraphQLArgument, GraphQLID, GraphQLNonNull
|
||||||
|
from graphql_relay.connection.arrayconnection import connection_from_list
|
||||||
|
from graphql_relay.connection.connection import connection_args
|
||||||
|
from graphql_relay.node.node import from_global_id
|
||||||
|
|
||||||
|
|
||||||
class ConnectionField(Field):
|
class ConnectionField(Field):
|
||||||
|
@ -68,6 +57,7 @@ class ConnectionField(Field):
|
||||||
|
|
||||||
|
|
||||||
class NodeField(Field):
|
class NodeField(Field):
|
||||||
|
|
||||||
def __init__(self, object_type=None, *args, **kwargs):
|
def __init__(self, object_type=None, *args, **kwargs):
|
||||||
from graphene.relay.types import Node
|
from graphene.relay.types import Node
|
||||||
super(NodeField, self).__init__(object_type or Node, *args, **kwargs)
|
super(NodeField, self).__init__(object_type or Node, *args, **kwargs)
|
||||||
|
@ -84,7 +74,7 @@ class NodeField(Field):
|
||||||
_type, _id = resolved_global_id.type, resolved_global_id.id
|
_type, _id = resolved_global_id.type, resolved_global_id.id
|
||||||
object_type = schema.get_type(_type)
|
object_type = schema.get_type(_type)
|
||||||
if not is_node(object_type) or (self.field_object_type and
|
if not is_node(object_type) or (self.field_object_type and
|
||||||
object_type != self.field_object_type):
|
object_type != self.field_object_type):
|
||||||
return
|
return
|
||||||
|
|
||||||
return object_type.get_node(_id)
|
return object_type.get_node(_id)
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
from graphql_relay.node.node import (
|
from graphene.core.fields import BooleanField, Field, ListField, StringField
|
||||||
to_global_id
|
from graphene.core.types import (InputObjectType, Interface, Mutation,
|
||||||
)
|
ObjectType)
|
||||||
|
|
||||||
from graphene.core.types import Interface, ObjectType, Mutation, InputObjectType
|
|
||||||
from graphene.core.fields import BooleanField, StringField, ListField, Field
|
|
||||||
from graphene.relay.fields import GlobalIDField
|
from graphene.relay.fields import GlobalIDField
|
||||||
from graphene.utils import memoize
|
from graphene.utils import memoize
|
||||||
|
from graphql_relay.node.node import to_global_id
|
||||||
|
|
||||||
|
|
||||||
class PageInfo(ObjectType):
|
class PageInfo(ObjectType):
|
||||||
has_next_page = BooleanField(required=True, description='When paginating forwards, are there more items?')
|
has_next_page = BooleanField(
|
||||||
has_previous_page = BooleanField(required=True, description='When paginating backwards, are there more items?')
|
required=True, description='When paginating forwards, are there more items?')
|
||||||
start_cursor = StringField(description='When paginating backwards, the cursor to continue.')
|
has_previous_page = BooleanField(
|
||||||
end_cursor = StringField(description='When paginating forwards, the cursor to continue.')
|
required=True, description='When paginating backwards, are there more items?')
|
||||||
|
start_cursor = StringField(
|
||||||
|
description='When paginating backwards, the cursor to continue.')
|
||||||
|
end_cursor = StringField(
|
||||||
|
description='When paginating forwards, the cursor to continue.')
|
||||||
|
|
||||||
|
|
||||||
class Edge(ObjectType):
|
class Edge(ObjectType):
|
||||||
|
@ -20,8 +22,10 @@ class Edge(ObjectType):
|
||||||
class Meta:
|
class Meta:
|
||||||
type_name = 'DefaultEdge'
|
type_name = 'DefaultEdge'
|
||||||
|
|
||||||
node = Field(lambda field: field.object_type.node_type, description='The item at the end of the edge')
|
node = Field(lambda field: field.object_type.node_type,
|
||||||
cursor = StringField(required=True, description='A cursor for use in pagination')
|
description='The item at the end of the edge')
|
||||||
|
cursor = StringField(
|
||||||
|
required=True, description='A cursor for use in pagination')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@memoize
|
@memoize
|
||||||
|
@ -36,8 +40,10 @@ class Connection(ObjectType):
|
||||||
class Meta:
|
class Meta:
|
||||||
type_name = 'DefaultConnection'
|
type_name = 'DefaultConnection'
|
||||||
|
|
||||||
page_info = Field(PageInfo, required=True, description='The Information to aid in pagination')
|
page_info = Field(PageInfo, required=True,
|
||||||
edges = ListField(lambda field: field.object_type.edge_type, description='Information to aid in pagination.')
|
description='The Information to aid in pagination')
|
||||||
|
edges = ListField(lambda field: field.object_type.edge_type,
|
||||||
|
description='Information to aid in pagination.')
|
||||||
|
|
||||||
_connection_data = None
|
_connection_data = None
|
||||||
|
|
||||||
|
@ -57,6 +63,7 @@ class Connection(ObjectType):
|
||||||
|
|
||||||
|
|
||||||
class BaseNode(object):
|
class BaseNode(object):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _prepare_class(cls):
|
def _prepare_class(cls):
|
||||||
from graphene.relay.utils import is_node
|
from graphene.relay.utils import is_node
|
||||||
|
@ -97,13 +104,16 @@ class ClientIDMutation(Mutation):
|
||||||
def _prepare_class(cls):
|
def _prepare_class(cls):
|
||||||
input_type = getattr(cls, 'input_type', None)
|
input_type = getattr(cls, 'input_type', None)
|
||||||
if input_type:
|
if input_type:
|
||||||
assert hasattr(cls, 'mutate_and_get_payload'), 'You have to implement mutate_and_get_payload'
|
assert hasattr(
|
||||||
new_input_inner_type = type('{}InnerInput'.format(cls._meta.type_name), (MutationInputType, input_type, ), {})
|
cls, 'mutate_and_get_payload'), 'You have to implement mutate_and_get_payload'
|
||||||
|
new_input_inner_type = type('{}InnerInput'.format(
|
||||||
|
cls._meta.type_name), (MutationInputType, input_type, ), {})
|
||||||
items = {
|
items = {
|
||||||
'input': Field(new_input_inner_type)
|
'input': Field(new_input_inner_type)
|
||||||
}
|
}
|
||||||
assert issubclass(new_input_inner_type, InputObjectType)
|
assert issubclass(new_input_inner_type, InputObjectType)
|
||||||
input_type = type('{}Input'.format(cls._meta.type_name), (ObjectType, ), items)
|
input_type = type('{}Input'.format(
|
||||||
|
cls._meta.type_name), (ObjectType, ), items)
|
||||||
setattr(cls, 'input_type', input_type)
|
setattr(cls, 'input_type', input_type)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
class LazyMap(object):
|
class LazyMap(object):
|
||||||
|
|
||||||
def __init__(self, origin, _map, state=None):
|
def __init__(self, origin, _map, state=None):
|
||||||
self._origin = origin
|
self._origin = origin
|
||||||
self._origin_iter = origin.__iter__()
|
self._origin_iter = origin.__iter__()
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from graphql.core.type import GraphQLEnumType, GraphQLEnumValue
|
from graphql.core.type import GraphQLEnumType, GraphQLEnumValue
|
||||||
|
|
||||||
|
|
||||||
def enum_to_graphql_enum(enumeration):
|
def enum_to_graphql_enum(enumeration):
|
||||||
return GraphQLEnumType(
|
return GraphQLEnumType(
|
||||||
name=enumeration.__name__,
|
name=enumeration.__name__,
|
||||||
values=OrderedDict([(it.name, GraphQLEnumValue(it.value)) for it in enumeration]),
|
values=OrderedDict([(it.name, GraphQLEnumValue(it.value))
|
||||||
|
for it in enumeration]),
|
||||||
description=enumeration.__doc__
|
description=enumeration.__doc__
|
||||||
)
|
)
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -1,6 +1,6 @@
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from setuptools import setup, find_packages
|
from setuptools import find_packages, setup
|
||||||
from setuptools.command.test import test as TestCommand
|
from setuptools.command.test import test as TestCommand
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
from .models import Reporter, Article
|
from .models import Article, Reporter
|
||||||
|
|
||||||
r = Reporter(first_name='John', last_name='Smith', email='john@example.com')
|
r = Reporter(first_name='John', last_name='Smith', email='john@example.com')
|
||||||
r.save()
|
r.save()
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
from py.test import raises
|
|
||||||
from collections import namedtuple
|
|
||||||
from pytest import raises
|
|
||||||
import graphene
|
|
||||||
from graphene import relay
|
|
||||||
from graphene.contrib.django.converter import (
|
|
||||||
convert_django_field
|
|
||||||
)
|
|
||||||
from graphene.contrib.django.fields import (
|
|
||||||
ConnectionOrListField,
|
|
||||||
DjangoModelField
|
|
||||||
)
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from py.test import raises
|
||||||
|
from pytest import raises
|
||||||
|
|
||||||
|
import graphene
|
||||||
|
from graphene.contrib.django.converter import convert_django_field
|
||||||
|
from graphene.contrib.django.fields import (ConnectionOrListField,
|
||||||
|
DjangoModelField)
|
||||||
|
|
||||||
from .models import Article, Reporter
|
from .models import Article, Reporter
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
|
|
||||||
from py.test import raises
|
from py.test import raises
|
||||||
from collections import namedtuple
|
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
|
|
||||||
import graphene
|
import graphene
|
||||||
from graphene import relay
|
from graphene import relay
|
||||||
from graphene.contrib.django import (
|
from graphene.contrib.django import DjangoNode, DjangoObjectType
|
||||||
DjangoObjectType,
|
|
||||||
DjangoNode
|
|
||||||
)
|
|
||||||
from .models import Reporter, Article
|
|
||||||
|
|
||||||
from tests.utils import assert_equal_lists
|
from tests.utils import assert_equal_lists
|
||||||
|
|
||||||
|
from .models import Article, Reporter
|
||||||
|
|
||||||
|
|
||||||
def test_should_raise_if_no_model():
|
def test_should_raise_if_no_model():
|
||||||
with raises(Exception) as excinfo:
|
with raises(Exception) as excinfo:
|
||||||
|
|
|
@ -1,29 +1,14 @@
|
||||||
from py.test import raises
|
|
||||||
from collections import namedtuple
|
|
||||||
from pytest import raises
|
|
||||||
from graphene.relay.fields import (
|
|
||||||
GlobalIDField
|
|
||||||
)
|
|
||||||
from graphene.core.fields import (
|
|
||||||
Field,
|
|
||||||
StringField,
|
|
||||||
IntField
|
|
||||||
)
|
|
||||||
from graphql.core.type import (
|
|
||||||
GraphQLObjectType,
|
|
||||||
GraphQLInterfaceType
|
|
||||||
)
|
|
||||||
|
|
||||||
from graphene import Schema
|
from graphene import Schema
|
||||||
from graphene.contrib.django.types import (
|
from graphene.contrib.django.types import DjangoInterface, DjangoNode
|
||||||
DjangoNode,
|
from graphene.core.fields import IntField
|
||||||
DjangoInterface
|
from graphene.relay.fields import GlobalIDField
|
||||||
)
|
from graphql.core.type import GraphQLInterfaceType, GraphQLObjectType
|
||||||
|
|
||||||
from .models import Reporter, Article
|
|
||||||
|
|
||||||
from tests.utils import assert_equal_lists
|
from tests.utils import assert_equal_lists
|
||||||
|
|
||||||
|
from .models import Article, Reporter
|
||||||
|
|
||||||
|
|
||||||
class Character(DjangoInterface):
|
class Character(DjangoInterface):
|
||||||
'''Character description'''
|
'''Character description'''
|
||||||
|
@ -82,7 +67,7 @@ def test_interface_resolve_type():
|
||||||
|
|
||||||
def test_object_type():
|
def test_object_type():
|
||||||
object_type = schema.T(Human)
|
object_type = schema.T(Human)
|
||||||
fields_map = Human._meta.fields_map
|
Human._meta.fields_map
|
||||||
assert Human._meta.is_interface is False
|
assert Human._meta.is_interface is False
|
||||||
assert isinstance(object_type, GraphQLObjectType)
|
assert isinstance(object_type, GraphQLObjectType)
|
||||||
assert_equal_lists(
|
assert_equal_lists(
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|
||||||
from graphene.contrib.django.views import GraphQLView
|
|
||||||
|
|
||||||
import graphene
|
import graphene
|
||||||
from graphene import Schema
|
from graphene import Schema
|
||||||
from graphene.contrib.django.types import (
|
from graphene.contrib.django.types import DjangoNode
|
||||||
DjangoNode,
|
from graphene.contrib.django.views import GraphQLView
|
||||||
DjangoInterface
|
|
||||||
)
|
|
||||||
|
|
||||||
from .models import Reporter, Article
|
from .models import Article, Reporter
|
||||||
|
|
||||||
|
|
||||||
class Character(DjangoNode):
|
class Character(DjangoNode):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Reporter
|
model = Reporter
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,4 @@
|
||||||
import json
|
import json
|
||||||
import pytest
|
|
||||||
from py.test import raises
|
|
||||||
from collections import namedtuple
|
|
||||||
from pytest import raises
|
|
||||||
from graphene.core.fields import (
|
|
||||||
Field,
|
|
||||||
StringField,
|
|
||||||
)
|
|
||||||
from graphql.core.type import (
|
|
||||||
GraphQLObjectType,
|
|
||||||
GraphQLInterfaceType
|
|
||||||
)
|
|
||||||
|
|
||||||
from graphene import Schema
|
|
||||||
from graphene.contrib.django.types import (
|
|
||||||
DjangoNode,
|
|
||||||
DjangoInterface
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def format_response(response):
|
def format_response(response):
|
||||||
|
@ -27,33 +9,39 @@ def test_client_get_no_query(settings, client):
|
||||||
settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
|
settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
|
||||||
response = client.get('/graphql')
|
response = client.get('/graphql')
|
||||||
json_response = format_response(response)
|
json_response = format_response(response)
|
||||||
assert json_response == {'errors': [{'message': 'Must provide query string.'}]}
|
assert json_response == {'errors': [
|
||||||
|
{'message': 'Must provide query string.'}]}
|
||||||
|
|
||||||
|
|
||||||
def test_client_post_no_query(settings, client):
|
def test_client_post_no_query(settings, client):
|
||||||
settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
|
settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
|
||||||
response = client.post('/graphql', {})
|
response = client.post('/graphql', {})
|
||||||
json_response = format_response(response)
|
json_response = format_response(response)
|
||||||
assert json_response == {'errors': [{'message': 'Must provide query string.'}]}
|
assert json_response == {'errors': [
|
||||||
|
{'message': 'Must provide query string.'}]}
|
||||||
|
|
||||||
|
|
||||||
def test_client_post_malformed_json(settings, client):
|
def test_client_post_malformed_json(settings, client):
|
||||||
settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
|
settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
|
||||||
response = client.post('/graphql', 'MALFORMED', 'application/json')
|
response = client.post('/graphql', 'MALFORMED', 'application/json')
|
||||||
json_response = format_response(response)
|
json_response = format_response(response)
|
||||||
assert json_response == {'errors': [{'message': 'Malformed json body in the post data'}]}
|
assert json_response == {'errors': [
|
||||||
|
{'message': 'Malformed json body in the post data'}]}
|
||||||
|
|
||||||
|
|
||||||
def test_client_post_empty_query(settings, client):
|
def test_client_post_empty_query(settings, client):
|
||||||
settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
|
settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
|
||||||
response = client.post('/graphql', json.dumps({'query': ''}), 'application/json')
|
response = client.post(
|
||||||
|
'/graphql', json.dumps({'query': ''}), 'application/json')
|
||||||
json_response = format_response(response)
|
json_response = format_response(response)
|
||||||
assert json_response == {'errors': [{'message': 'Must provide query string.'}]}
|
assert json_response == {'errors': [
|
||||||
|
{'message': 'Must provide query string.'}]}
|
||||||
|
|
||||||
|
|
||||||
def test_client_post_bad_query(settings, client):
|
def test_client_post_bad_query(settings, client):
|
||||||
settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
|
settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
|
||||||
response = client.post('/graphql', json.dumps({'query': '{ MALFORMED'}), 'application/json')
|
response = client.post(
|
||||||
|
'/graphql', json.dumps({'query': '{ MALFORMED'}), 'application/json')
|
||||||
json_response = format_response(response)
|
json_response = format_response(response)
|
||||||
assert 'errors' in json_response
|
assert 'errors' in json_response
|
||||||
assert len(json_response['errors']) == 1
|
assert len(json_response['errors']) == 1
|
||||||
|
@ -76,13 +64,15 @@ def test_client_get_good_query_with_raise(settings, client):
|
||||||
settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
|
settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
|
||||||
response = client.get('/graphql', {'query': '{ raises }'})
|
response = client.get('/graphql', {'query': '{ raises }'})
|
||||||
json_response = format_response(response)
|
json_response = format_response(response)
|
||||||
assert json_response['errors'][0]['message'] == 'This field should raise exception'
|
assert json_response['errors'][0][
|
||||||
|
'message'] == 'This field should raise exception'
|
||||||
assert json_response['data']['raises'] is None
|
assert json_response['data']['raises'] is None
|
||||||
|
|
||||||
|
|
||||||
def test_client_post_good_query(settings, client):
|
def test_client_post_good_query(settings, client):
|
||||||
settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
|
settings.ROOT_URLCONF = 'tests.contrib_django.test_urls'
|
||||||
response = client.post('/graphql', json.dumps({'query': '{ headline }'}), 'application/json')
|
response = client.post(
|
||||||
|
'/graphql', json.dumps({'query': '{ headline }'}), 'application/json')
|
||||||
json_response = format_response(response)
|
json_response = format_response(response)
|
||||||
expected_json = {
|
expected_json = {
|
||||||
'data': {
|
'data': {
|
||||||
|
@ -97,5 +87,3 @@ def test_client_post_good_query(settings, client):
|
||||||
# response = client.get('/graphql')
|
# response = client.get('/graphql')
|
||||||
# json_response = format_response(response)
|
# json_response = format_response(response)
|
||||||
# assert json_response == {'errors': [{'message': 'Must provide query string.'}]}
|
# assert json_response == {'errors': [{'message': 'Must provide query string.'}]}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,13 @@
|
||||||
|
|
||||||
from py.test import raises
|
from py.test import raises
|
||||||
from collections import namedtuple
|
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
|
|
||||||
from graphql.core.type import (
|
from graphene.core.fields import Field, NonNullField, StringField
|
||||||
GraphQLField,
|
|
||||||
GraphQLNonNull,
|
|
||||||
GraphQLInt,
|
|
||||||
GraphQLString,
|
|
||||||
GraphQLBoolean,
|
|
||||||
GraphQLID,
|
|
||||||
)
|
|
||||||
|
|
||||||
from graphene.core.fields import (
|
|
||||||
Field,
|
|
||||||
StringField,
|
|
||||||
NonNullField
|
|
||||||
)
|
|
||||||
from graphene.core.options import Options
|
from graphene.core.options import Options
|
||||||
from graphene.core.schema import Schema
|
from graphene.core.schema import Schema
|
||||||
from graphene.core.types import ObjectType
|
from graphene.core.types import ObjectType
|
||||||
|
from graphql.core.type import (GraphQLBoolean, GraphQLField, GraphQLID,
|
||||||
|
GraphQLInt, GraphQLNonNull, GraphQLString)
|
||||||
|
|
||||||
|
|
||||||
class ObjectType(object):
|
class ObjectType(object):
|
||||||
|
@ -149,7 +138,8 @@ def test_field_none_type_raises_error():
|
||||||
f.contribute_to_class(ot, 'field_name')
|
f.contribute_to_class(ot, 'field_name')
|
||||||
with raises(Exception) as excinfo:
|
with raises(Exception) as excinfo:
|
||||||
f.internal_field(s)
|
f.internal_field(s)
|
||||||
assert str(excinfo.value) == "Internal type for field ObjectType.field_name is None"
|
assert str(
|
||||||
|
excinfo.value) == "Internal type for field ObjectType.field_name is None"
|
||||||
|
|
||||||
|
|
||||||
def test_field_str():
|
def test_field_str():
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
import graphene
|
import graphene
|
||||||
from py.test import raises
|
|
||||||
from graphene.core.schema import Schema
|
from graphene.core.schema import Schema
|
||||||
|
|
||||||
my_id = 0
|
my_id = 0
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
from py.test import raises
|
|
||||||
from collections import namedtuple
|
|
||||||
from pytest import raises
|
|
||||||
from graphene.core.fields import (
|
|
||||||
Field,
|
|
||||||
StringField,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
from py.test import raises
|
||||||
|
from pytest import raises
|
||||||
|
|
||||||
|
from graphene.core.fields import StringField
|
||||||
from graphene.core.options import Options
|
from graphene.core.options import Options
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,7 +54,6 @@ def test_options_description():
|
||||||
class ObjectType(object):
|
class ObjectType(object):
|
||||||
|
|
||||||
'''False description'''
|
'''False description'''
|
||||||
pass
|
|
||||||
|
|
||||||
opt.contribute_to_class(ObjectType, '_meta')
|
opt.contribute_to_class(ObjectType, '_meta')
|
||||||
assert opt.description == 'False description'
|
assert opt.description == 'False description'
|
||||||
|
|
|
@ -1,23 +1,11 @@
|
||||||
from py.test import raises
|
|
||||||
from collections import namedtuple
|
|
||||||
from pytest import raises
|
|
||||||
from graphql.core import graphql
|
|
||||||
from graphene.core.fields import (
|
|
||||||
Field,
|
|
||||||
StringField,
|
|
||||||
ListField,
|
|
||||||
)
|
|
||||||
from graphql.core.type import (
|
|
||||||
GraphQLObjectType,
|
|
||||||
GraphQLSchema,
|
|
||||||
GraphQLInterfaceType
|
|
||||||
)
|
|
||||||
|
|
||||||
from graphene.core.types import (
|
|
||||||
Interface,
|
from graphene.core.fields import Field, ListField, StringField
|
||||||
ObjectType
|
|
||||||
)
|
|
||||||
from graphene.core.schema import Schema
|
from graphene.core.schema import Schema
|
||||||
|
from graphene.core.types import Interface, ObjectType
|
||||||
|
from graphql.core import graphql
|
||||||
|
from graphql.core.type import (GraphQLInterfaceType, GraphQLObjectType,
|
||||||
|
GraphQLSchema)
|
||||||
|
|
||||||
|
|
||||||
class Character(Interface):
|
class Character(Interface):
|
||||||
|
@ -50,7 +38,8 @@ Human_type = schema.T(Human)
|
||||||
|
|
||||||
|
|
||||||
def test_type():
|
def test_type():
|
||||||
assert Human._meta.fields_map['name'].resolve(Human(object()), None, None) == 'Peter'
|
assert Human._meta.fields_map['name'].resolve(
|
||||||
|
Human(object()), None, None) == 'Peter'
|
||||||
|
|
||||||
|
|
||||||
def test_query():
|
def test_query():
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
from graphene.core.scalars import (
|
from graphene.core.scalars import GraphQLSkipField
|
||||||
GraphQLSkipField
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_skipfield_serialize():
|
def test_skipfield_serialize():
|
||||||
|
|
|
@ -1,24 +1,12 @@
|
||||||
|
|
||||||
from py.test import raises
|
from py.test import raises
|
||||||
from collections import namedtuple
|
|
||||||
from pytest 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 import graphql
|
||||||
from graphene.core.fields import (
|
from graphql.core.type import (GraphQLInterfaceType, GraphQLObjectType,
|
||||||
Field,
|
GraphQLSchema)
|
||||||
StringField,
|
|
||||||
ListField,
|
|
||||||
)
|
|
||||||
from graphql.core.type import (
|
|
||||||
GraphQLObjectType,
|
|
||||||
GraphQLSchema,
|
|
||||||
GraphQLInterfaceType
|
|
||||||
)
|
|
||||||
|
|
||||||
from graphene import (
|
|
||||||
Interface,
|
|
||||||
ObjectType,
|
|
||||||
Schema
|
|
||||||
)
|
|
||||||
|
|
||||||
from tests.utils import assert_equal_lists
|
from tests.utils import assert_equal_lists
|
||||||
|
|
||||||
schema = Schema(name='My own schema')
|
schema = Schema(name='My own schema')
|
||||||
|
@ -63,7 +51,7 @@ def test_schema_query():
|
||||||
|
|
||||||
|
|
||||||
def test_query_schema_graphql():
|
def test_query_schema_graphql():
|
||||||
a = object()
|
object()
|
||||||
query = '''
|
query = '''
|
||||||
{
|
{
|
||||||
name
|
name
|
||||||
|
@ -84,7 +72,7 @@ def test_query_schema_graphql():
|
||||||
|
|
||||||
|
|
||||||
def test_query_schema_execute():
|
def test_query_schema_execute():
|
||||||
a = object()
|
object()
|
||||||
query = '''
|
query = '''
|
||||||
{
|
{
|
||||||
name
|
name
|
||||||
|
@ -107,7 +95,8 @@ def test_query_schema_execute():
|
||||||
def test_schema_get_type_map():
|
def test_schema_get_type_map():
|
||||||
assert_equal_lists(
|
assert_equal_lists(
|
||||||
schema.schema.get_type_map().keys(),
|
schema.schema.get_type_map().keys(),
|
||||||
['__Field', 'String', 'Pet', 'Character', '__InputValue', '__Directive', '__TypeKind', '__Schema', '__Type', 'Human', '__EnumValue', 'Boolean']
|
['__Field', 'String', 'Pet', 'Character', '__InputValue', '__Directive',
|
||||||
|
'__TypeKind', '__Schema', '__Type', 'Human', '__EnumValue', 'Boolean']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,12 @@
|
||||||
from py.test import raises
|
from py.test import raises
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
from graphene.core.fields import (
|
|
||||||
IntField,
|
|
||||||
StringField,
|
|
||||||
)
|
|
||||||
from graphql.core.execution.middlewares.utils import (
|
|
||||||
tag_resolver,
|
|
||||||
resolver_has_tag
|
|
||||||
)
|
|
||||||
from graphql.core.type import (
|
|
||||||
GraphQLObjectType,
|
|
||||||
GraphQLInterfaceType
|
|
||||||
)
|
|
||||||
|
|
||||||
from graphene.core.types import (
|
from graphene.core.fields import IntField, StringField
|
||||||
Interface
|
|
||||||
)
|
|
||||||
from graphene.core.schema import Schema
|
from graphene.core.schema import Schema
|
||||||
|
from graphene.core.types import Interface
|
||||||
|
from graphql.core.execution.middlewares.utils import (resolver_has_tag,
|
||||||
|
tag_resolver)
|
||||||
|
from graphql.core.type import GraphQLInterfaceType, GraphQLObjectType
|
||||||
|
|
||||||
|
|
||||||
class Character(Interface):
|
class Character(Interface):
|
||||||
|
@ -60,7 +50,7 @@ def test_interface():
|
||||||
|
|
||||||
def test_interface_cannot_initialize():
|
def test_interface_cannot_initialize():
|
||||||
with raises(Exception) as excinfo:
|
with raises(Exception) as excinfo:
|
||||||
c = Character()
|
Character()
|
||||||
assert 'An interface cannot be initialized' == str(excinfo.value)
|
assert 'An interface cannot be initialized' == str(excinfo.value)
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,7 +67,8 @@ def test_object_type():
|
||||||
assert object_type.description == 'Human description'
|
assert object_type.description == 'Human description'
|
||||||
assert list(object_type.get_fields().keys()) == ['name', 'friends']
|
assert list(object_type.get_fields().keys()) == ['name', 'friends']
|
||||||
# assert object_type.get_fields() == {'name': Human._meta.fields_map['name'].internal_field(
|
# assert object_type.get_fields() == {'name': Human._meta.fields_map['name'].internal_field(
|
||||||
# schema), 'friends': Human._meta.fields_map['friends'].internal_field(schema)}
|
# schema), 'friends':
|
||||||
|
# Human._meta.fields_map['friends'].internal_field(schema)}
|
||||||
assert object_type.get_interfaces() == [schema.T(Character)]
|
assert object_type.get_interfaces() == [schema.T(Character)]
|
||||||
assert Human._meta.fields_map['name'].object_type == Human
|
assert Human._meta.fields_map['name'].object_type == Human
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ def test_field_no_contributed_raises_error():
|
||||||
|
|
||||||
|
|
||||||
def test_node_should_have_same_connection_always():
|
def test_node_should_have_same_connection_always():
|
||||||
s = object()
|
object()
|
||||||
connection1 = relay.Connection.for_node(OtherNode)
|
connection1 = relay.Connection.for_node(OtherNode)
|
||||||
connection2 = relay.Connection.for_node(OtherNode)
|
connection2 = relay.Connection.for_node(OtherNode)
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
from graphql.core.type import (
|
|
||||||
GraphQLInputObjectField
|
|
||||||
)
|
|
||||||
|
|
||||||
import graphene
|
import graphene
|
||||||
from graphene import relay
|
from graphene import relay
|
||||||
from graphene.core.types import InputObjectType
|
|
||||||
from graphene.core.schema import Schema
|
from graphene.core.schema import Schema
|
||||||
|
from graphene.core.types import InputObjectType
|
||||||
|
from graphql.core.type import GraphQLInputObjectField
|
||||||
|
|
||||||
my_id = 0
|
my_id = 0
|
||||||
|
|
||||||
|
@ -41,11 +38,13 @@ def test_mutation_input():
|
||||||
assert list(ChangeNumber.input_type._meta.fields_map.keys()) == ['input']
|
assert list(ChangeNumber.input_type._meta.fields_map.keys()) == ['input']
|
||||||
_input = ChangeNumber.input_type._meta.fields_map['input']
|
_input = ChangeNumber.input_type._meta.fields_map['input']
|
||||||
inner_type = _input.get_object_type(schema)
|
inner_type = _input.get_object_type(schema)
|
||||||
client_mutation_id_field = inner_type._meta.fields_map['client_mutation_id']
|
client_mutation_id_field = inner_type._meta.fields_map[
|
||||||
|
'client_mutation_id']
|
||||||
assert issubclass(inner_type, InputObjectType)
|
assert issubclass(inner_type, InputObjectType)
|
||||||
assert isinstance(client_mutation_id_field, graphene.StringField)
|
assert isinstance(client_mutation_id_field, graphene.StringField)
|
||||||
assert client_mutation_id_field.object_type == inner_type
|
assert client_mutation_id_field.object_type == inner_type
|
||||||
assert isinstance(client_mutation_id_field.internal_field(schema), GraphQLInputObjectField)
|
assert isinstance(client_mutation_id_field.internal_field(
|
||||||
|
schema), GraphQLInputObjectField)
|
||||||
|
|
||||||
|
|
||||||
def test_execute_mutations():
|
def test_execute_mutations():
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
from graphql.core.type import (
|
|
||||||
GraphQLNonNull,
|
|
||||||
GraphQLID
|
|
||||||
)
|
|
||||||
|
|
||||||
import graphene
|
import graphene
|
||||||
from graphene import relay
|
from graphene import relay
|
||||||
|
from graphql.core.type import GraphQLID, GraphQLNonNull
|
||||||
|
|
||||||
schema = graphene.Schema()
|
schema = graphene.Schema()
|
||||||
|
|
||||||
|
|
||||||
class MyConnection(relay.Connection):
|
class MyConnection(relay.Connection):
|
||||||
my_custom_field = graphene.StringField(resolve=lambda instance, *_: 'Custom')
|
my_custom_field = graphene.StringField(
|
||||||
|
resolve=lambda instance, *_: 'Custom')
|
||||||
|
|
||||||
|
|
||||||
class MyNode(relay.Node):
|
class MyNode(relay.Node):
|
||||||
|
@ -23,7 +20,8 @@ class MyNode(relay.Node):
|
||||||
|
|
||||||
class Query(graphene.ObjectType):
|
class Query(graphene.ObjectType):
|
||||||
my_node = relay.NodeField(MyNode)
|
my_node = relay.NodeField(MyNode)
|
||||||
all_my_nodes = relay.ConnectionField(MyNode, connection_type=MyConnection, customArg=graphene.Argument(graphene.String))
|
all_my_nodes = relay.ConnectionField(
|
||||||
|
MyNode, connection_type=MyConnection, customArg=graphene.Argument(graphene.String))
|
||||||
|
|
||||||
def resolve_all_my_nodes(self, args, info):
|
def resolve_all_my_nodes(self, args, info):
|
||||||
custom_arg = args.get('customArg')
|
custom_arg = args.get('customArg')
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import collections
|
import collections
|
||||||
from graphql.core.type import GraphQLEnumType
|
|
||||||
from graphene.utils.misc import enum_to_graphql_enum
|
from graphene.utils.misc import enum_to_graphql_enum
|
||||||
|
from graphql.core.type import GraphQLEnumType
|
||||||
|
|
||||||
item = collections.namedtuple('type', 'name value')
|
item = collections.namedtuple('type', 'name value')
|
||||||
|
|
||||||
|
@ -10,4 +11,5 @@ class MyCustomEnum(list):
|
||||||
|
|
||||||
|
|
||||||
def test_enum_to_graphql_enum():
|
def test_enum_to_graphql_enum():
|
||||||
assert isinstance(enum_to_graphql_enum(MyCustomEnum([item('k', 'v')])), GraphQLEnumType)
|
assert isinstance(enum_to_graphql_enum(
|
||||||
|
MyCustomEnum([item('k', 'v')])), GraphQLEnumType)
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
from py.test import raises
|
from py.test import raises
|
||||||
|
|
||||||
from graphene.utils import ProxySnakeDict
|
from graphene.utils import ProxySnakeDict
|
||||||
|
|
||||||
|
|
||||||
def test_proxy_snake_dict():
|
def test_proxy_snake_dict():
|
||||||
my_data = {'one': 1, 'two': 2, 'none': None, 'threeOrFor': 3, 'inside': {'otherCamelCase': 3}}
|
my_data = {'one': 1, 'two': 2, 'none': None,
|
||||||
|
'threeOrFor': 3, 'inside': {'otherCamelCase': 3}}
|
||||||
p = ProxySnakeDict(my_data)
|
p = ProxySnakeDict(my_data)
|
||||||
assert 'one' in p
|
assert 'one' in p
|
||||||
assert 'two' in p
|
assert 'two' in p
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from graphene.utils import to_snake_case, to_camel_case
|
from graphene.utils import to_camel_case, to_snake_case
|
||||||
|
|
||||||
|
|
||||||
def test_snake_case():
|
def test_snake_case():
|
||||||
|
|
11
tox.ini
11
tox.ini
|
@ -1,5 +1,6 @@
|
||||||
[tox]
|
[tox]
|
||||||
envlist = py27,py33,py34,py35,pypy
|
envlist = flake8,py27,py33,py34,py35,pypy
|
||||||
|
skipsdist = true
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
deps=
|
deps=
|
||||||
|
@ -14,7 +15,13 @@ deps=
|
||||||
setenv =
|
setenv =
|
||||||
PYTHONPATH = .:{envdir}
|
PYTHONPATH = .:{envdir}
|
||||||
commands=
|
commands=
|
||||||
py.test tests/
|
py.test tests/ examples/
|
||||||
|
|
||||||
|
[testenv:flake8]
|
||||||
|
deps = flake8
|
||||||
|
commands =
|
||||||
|
pip install -e .
|
||||||
|
flake8 graphene
|
||||||
|
|
||||||
[pytest]
|
[pytest]
|
||||||
DJANGO_SETTINGS_MODULE = tests.django_settings
|
DJANGO_SETTINGS_MODULE = tests.django_settings
|
||||||
|
|
Loading…
Reference in New Issue
Block a user