From a74c402f1344709364e489798277ff2d8dbe4982 Mon Sep 17 00:00:00 2001 From: hung-phan Date: Thu, 8 Dec 2016 16:51:37 +0000 Subject: [PATCH] Implement JSON type Remove duplicated test Remove unicode for python 3 Add more tests Add None case Update json type Remove unnecessary dependencies Add more test Add test --- graphene/types/jsontype.py | 39 +++++++++++ graphene/types/tests/test_jsontype.py | 94 +++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 graphene/types/jsontype.py create mode 100644 graphene/types/tests/test_jsontype.py diff --git a/graphene/types/jsontype.py b/graphene/types/jsontype.py new file mode 100644 index 00000000..fa46bd68 --- /dev/null +++ b/graphene/types/jsontype.py @@ -0,0 +1,39 @@ +from __future__ import unicode_literals + +from graphql.language.ast import (BooleanValue, FloatValue, IntValue, + StringValue, ListValue, ObjectValue) + +from graphene.types.scalars import MIN_INT, MAX_INT +from .scalars import Scalar + + +class JSON(Scalar): + """ + The `JSON` scalar type represents JSON values as specified by + [ECMA-404](http://www.ecma-international.org/ + publications/files/ECMA-ST/ECMA-404.pdf). + """ + + @staticmethod + def identity(value): + return value + + serialize = identity + parse_value = identity + + @staticmethod + def parse_literal(ast): + if isinstance(ast, (StringValue, BooleanValue)): + return ast.value + elif isinstance(ast, IntValue): + num = int(ast.value) + if MIN_INT <= num <= MAX_INT: + return num + elif isinstance(ast, FloatValue): + return float(ast.value) + elif isinstance(ast, ListValue): + return [JSON.parse_literal(value) for value in ast.values] + elif isinstance(ast, ObjectValue): + return {field.name.value: JSON.parse_literal(field.value) for field in ast.fields} + else: + return None diff --git a/graphene/types/tests/test_jsontype.py b/graphene/types/tests/test_jsontype.py new file mode 100644 index 00000000..382e79f6 --- /dev/null +++ b/graphene/types/tests/test_jsontype.py @@ -0,0 +1,94 @@ +from ..jsontype import JSON +from ..objecttype import ObjectType +from ..schema import Schema + + +class Query(ObjectType): + json = JSON(input=JSON()) + + def resolve_json(self, args, context, info): + input = args.get('input') + return input + + +schema = Schema(query=Query) + + +def test_json_query_variable(): + for json_value in [ + 1, + 1.1, + True, + 'str', + [1, 2, 3], + [1.1, 2.2, 3.3], + [True, False], + ['str1', 'str2'], + { + 'key_a': 'a', + 'key_b': 'b' + }, + { + 'int': 1, + 'float': 1.1, + 'boolean': True, + 'string': 'str', + 'int_list': [1, 2, 3], + 'float_list': [1.1, 2.2, 3.3], + 'boolean_list': [True, False], + 'string_list': ['str1', 'str2'], + 'nested_dict': { + 'key_a': 'a', + 'key_b': 'b' + } + }, + None + ]: + result = schema.execute( + '''query Test($json: JSON){ json(input: $json) }''', + variable_values={'json': json_value} + ) + assert not result.errors + assert result.data == { + 'json': json_value + } + + +def test_json_parse_literal_query(): + result = schema.execute( + ''' + query { + json(input: { + int: 1, + float: 1.1 + boolean: true, + string: "str", + int_list: [1, 2, 3], + float_list: [1.1, 2.2, 3.3], + boolean_list: [true, false] + string_list: ["str1", "str2"], + nested_dict: { + key_a: "a", + key_b: "b" + } + }) + } + ''' + ) + assert not result.errors + assert result.data == { + 'json': { + 'int': 1, + 'float': 1.1, + 'boolean': True, + 'string': 'str', + 'int_list': [1, 2, 3], + 'float_list': [1.1, 2.2, 3.3], + 'boolean_list': [True, False], + 'string_list': ['str1', 'str2'], + 'nested_dict': { + 'key_a': 'a', + 'key_b': 'b' + } + } + }