diff --git a/graphql/execution/base.py b/graphql/execution/base.py index 3879ba30..3fe7193c 100644 --- a/graphql/execution/base.py +++ b/graphql/execution/base.py @@ -1,5 +1,8 @@ # -*- coding: utf-8 -*- -from ..error import GraphQLError +import json +import six + +from ..error import GraphQLError, format_error from ..language import ast from ..type.definition import GraphQLInterfaceType, GraphQLUnionType from ..type.directives import GraphQLIncludeDirective, GraphQLSkipDirective @@ -101,6 +104,29 @@ def __eq__(self, other): ) ) + def __repr__(self): + return str(self.response) + + def __str__(self): + return json.dumps(self.response) + + @staticmethod + def _format_error(error): + if isinstance(error, GraphQLError): + return format_error(error) + return {'message': six.text_type(error)} + + @property + def response(self): + """Returns the object as a GraphQL response. + https://facebook.github.io/graphql/#sec-Response""" + response = {} + if self.data and not self.invalid: + response['data'] = dict(self.data) + if self.errors: + response['errors'] = [self._format_error(e) for e in self.errors] + return response + def get_operation_root_type(schema, operation): op = operation.operation diff --git a/graphql/execution/tests/test_execute_schema.py b/graphql/execution/tests/test_execute_schema.py index a5c2a299..8e2bcb9a 100644 --- a/graphql/execution/tests/test_execute_schema.py +++ b/graphql/execution/tests/test_execute_schema.py @@ -1,4 +1,4 @@ -from graphql.execution import execute +from graphql.execution import execute, ExecutionResult from graphql.language.parser import parse from graphql.type import (GraphQLArgument, GraphQLBoolean, GraphQLField, GraphQLID, GraphQLInt, GraphQLList, GraphQLNonNull, @@ -185,3 +185,31 @@ def __init__(self, uid, width, height): } } } + + +def test_execution_result(): + + # Success + assert ExecutionResult(data={'foo': 'bar'}).response == \ + {'data': {'foo': 'bar'}} + + # Error + assert ExecutionResult(errors=['foo', 'bar']).response == \ + {'errors': [{'message': 'foo'}, {'message': 'bar'}]} + + # Partial success + assert ExecutionResult(data={'foo': 'bar'}, errors=['foo', 'bar']).response == \ + {'data': {'foo': 'bar'}, 'errors': [{'message': 'foo'}, {'message': 'bar'}]} + + # No arguments + assert ExecutionResult().response == {} + + # Invalid + assert ExecutionResult(invalid=True).response == {} + + # __repr__ and __str__ + result = ExecutionResult(data={'foo': 'bar'}, errors=['foo', 'bar']) + assert "'data'" in repr(result) + assert "'errors'" in repr(result) + assert '"data"' in str(result) + assert '"errors"' in str(result)