def test_does_not_sort_values_when_using_ordered_dict(): enum = GraphQLEnumType(name='Test', values=OrderedDict([ ('c', GraphQLEnumValue()), ('b', GraphQLEnumValue()), ('a', GraphQLEnumValue()), ('d', GraphQLEnumValue()), ])) assert [v.name for v in enum.get_values()] == ['c', 'b', 'a', 'd']
def test_sorts_values_if_not_using_ordered_dict(): enum = GraphQLEnumType(name='Test', values={ 'c': GraphQLEnumValue(), 'b': GraphQLEnumValue(), 'a': GraphQLEnumValue(), 'd': GraphQLEnumValue() }) assert [v.name for v in enum.get_values()] == ['a', 'b', 'c', 'd']
BlogMutation = GraphQLObjectType("Mutation", {"writeArticle": GraphQLField(BlogArticle)}) BlogSubscription = GraphQLObjectType( "Subscription", { "articleSubscribe": GraphQLField(args={"id": GraphQLArgument(GraphQLString)}, type=BlogArticle) }, ) ObjectType = GraphQLObjectType("Object", {}) InterfaceType = GraphQLInterfaceType("Interface") UnionType = GraphQLUnionType("Union", [ObjectType], resolve_type=lambda: None) EnumType = GraphQLEnumType("Enum", {"foo": GraphQLEnumValue()}) InputObjectType = GraphQLInputObjectType("InputObject", {}) def test_defines_a_query_only_schema(): BlogSchema = GraphQLSchema(BlogQuery) assert BlogSchema.get_query_type() == BlogQuery article_field = BlogQuery.fields["article"] assert article_field.type == BlogArticle assert article_field.type.name == "Article" # assert article_field.name == 'article' article_field_type = article_field.type assert isinstance(article_field_type, GraphQLObjectType)
from graphql.utilities import build_schema, extend_schema SomeScalarType = GraphQLScalarType(name="SomeScalar", serialize=lambda: None) SomeInterfaceType = GraphQLInterfaceType( name="SomeInterface", fields=lambda: {"f": GraphQLField(SomeObjectType)}) SomeObjectType = GraphQLObjectType( name="SomeObject", fields=lambda: {"f": GraphQLField(SomeObjectType)}, interfaces=[SomeInterfaceType], ) SomeUnionType = GraphQLUnionType(name="SomeUnion", types=[SomeObjectType]) SomeEnumType = GraphQLEnumType(name="SomeEnum", values={"ONLY": GraphQLEnumValue()}) SomeInputObjectType = GraphQLInputObjectType( name="SomeInputObject", fields={"val": GraphQLInputField(GraphQLString, default_value="hello")}, ) def with_modifiers( types: List[GraphQLNamedType] ) -> List[Union[GraphQLNamedType, GraphQLWrappingType]]: types = cast(List[Union[GraphQLNamedType, GraphQLWrappingType]], types) return (types + [GraphQLList(t) for t in types] + [GraphQLNonNull(t) for t in types] + [GraphQLNonNull(GraphQLList(t)) for t in types])
) __all__ = ["star_wars_schema"] # We begin by setting up our schema. # The original trilogy consists of three movies. # # This implements the following type system shorthand: # enum Episode { NEWHOPE, EMPIRE, JEDI } episode_enum = GraphQLEnumType( "Episode", { "NEWHOPE": GraphQLEnumValue(4, description="Released in 1977."), "EMPIRE": GraphQLEnumValue(5, description="Released in 1980."), "JEDI": GraphQLEnumValue(6, description="Released in 1983."), }, description="One of the films in the Star Wars Trilogy", ) # Characters in the Star Wars trilogy are either humans or droids. # # This implements the following type system shorthand: # interface Character { # id: String! # name: String # friends: [Character] # appearsIn: [Episode] # secretBackstory: String
from graphql.type import (GraphQLArgument, GraphQLEnumType, GraphQLEnumValue, GraphQLField, GraphQLInterfaceType, GraphQLList, GraphQLNonNull, GraphQLObjectType, GraphQLSchema, GraphQLString) from .fixtures import getDroid, getFriends, getHero, getHuman episodeEnum = GraphQLEnumType( 'Episode', description='One of the films in the Star Wars Trilogy', values={ 'NEWHOPE': GraphQLEnumValue( 4, description='Released in 1977.', ), 'EMPIRE': GraphQLEnumValue( 5, description='Released in 1980.', ), 'JEDI': GraphQLEnumValue( 6, description='Released in 1983.', ) } ) characterInterface = GraphQLInterfaceType( 'Character', description='A character in the Star Wars Trilogy', fields=lambda: { 'id': GraphQLField( GraphQLNonNull(GraphQLString),
TestNestedInputObject = GraphQLInputObjectType( "TestNestedInputObject", { "na": GraphQLInputField(GraphQLNonNull(TestInputObject)), "nb": GraphQLInputField(GraphQLNonNull(GraphQLString)), }, ) TestEnum = GraphQLEnumType( "TestEnum", { "NULL": None, "UNDEFINED": INVALID, "NAN": nan, "FALSE": False, "CUSTOM": "custom value", "DEFAULT_VALUE": GraphQLEnumValue(), }, ) def field_with_input_arg(input_arg: GraphQLArgument): return GraphQLField( GraphQLString, args={"input": input_arg}, resolve=lambda _obj, _info, **args: repr(args["input"]) if "input" in args else None, )
def builds_a_schema_with_an_enum(): food_enum = GraphQLEnumType( "Food", { "VEGETABLES": GraphQLEnumValue(1, description="Foods that are vegetables."), "FRUITS": GraphQLEnumValue(2, description="Foods that are fruits."), "OILS": GraphQLEnumValue(3, description="Foods that are oils."), "DAIRY": GraphQLEnumValue(4, description="Foods that are dairy."), "MEAT": GraphQLEnumValue(5, description="Foods that are meat."), }, description="Varieties of food stuffs", ) schema = GraphQLSchema( GraphQLObjectType( "EnumFields", { "food": GraphQLField( food_enum, args={ "kind": GraphQLArgument(food_enum, description="what kind of food?") }, description="Repeats the arg you give it", ) }, )) introspection = introspection_from_schema(schema) client_schema = build_client_schema(introspection) second_introspection = introspection_from_schema(client_schema) assert second_introspection == introspection client_food_enum = client_schema.get_type("Food") # It's also an Enum type on the client. assert isinstance(client_food_enum, GraphQLEnumType) values = client_food_enum.values descriptions = { name: value.description for name, value in values.items() } assert descriptions == { "VEGETABLES": "Foods that are vegetables.", "FRUITS": "Foods that are fruits.", "OILS": "Foods that are oils.", "DAIRY": "Foods that are dairy.", "MEAT": "Foods that are meat.", } values = values.values() assert all(value.value is None for value in values) assert all(value.is_deprecated is False for value in values) assert all(value.deprecation_reason is None for value in values) assert all(value.ast_node is None for value in values)
def test_builds_a_schema_with_an_enum(): FoodEnum = GraphQLEnumType( name="Food", description="Varieties of food stuffs", values=OrderedDict([ ( "VEGETABLES", GraphQLEnumValue(1, description="Foods that are vegetables."), ), ("FRUITS", GraphQLEnumValue(2, description="Foods that are fruits.")), ("OILS", GraphQLEnumValue(3, description="Foods that are oils.")), ("DAIRY", GraphQLEnumValue(4, description="Foods that are dairy.")), ("MEAT", GraphQLEnumValue(5, description="Foods that are meat.")), ]), ) schema = GraphQLSchema(query=GraphQLObjectType( name="EnumFields", fields={ "food": GraphQLField( FoodEnum, description="Repeats the arg you give it", args={ "kind": GraphQLArgument(FoodEnum, description="what kind of food?") }, ) }, )) client_schema = _test_schema(schema) clientFoodEnum = client_schema.get_type("Food") assert isinstance(clientFoodEnum, GraphQLEnumType) assert clientFoodEnum.values == [ GraphQLEnumValue( name="VEGETABLES", value="VEGETABLES", description="Foods that are vegetables.", deprecation_reason=None, ), GraphQLEnumValue( name="FRUITS", value="FRUITS", description="Foods that are fruits.", deprecation_reason=None, ), GraphQLEnumValue( name="OILS", value="OILS", description="Foods that are oils.", deprecation_reason=None, ), GraphQLEnumValue( name="DAIRY", value="DAIRY", description="Foods that are dairy.", deprecation_reason=None, ), GraphQLEnumValue( name="MEAT", value="MEAT", description="Foods that are meat.", deprecation_reason=None, ), ]
def describe_value_from_ast(): def _test_case(type_, value_text, expected): value_node = parse_value(value_text) value = value_from_ast(value_node, type_) if isinstance(expected, float) and isnan(expected): assert isnan(value) else: assert value == expected def _test_case_with_vars(variables, type_, value_text, expected): value_node = parse_value(value_text) assert value_from_ast(value_node, type_, variables) == expected def rejects_empty_input(): # noinspection PyTypeChecker assert value_from_ast(None, GraphQLBoolean) is INVALID def converts_according_to_input_coercion_rules(): _test_case(GraphQLBoolean, "true", True) _test_case(GraphQLBoolean, "false", False) _test_case(GraphQLInt, "123", 123) _test_case(GraphQLFloat, "123", 123) _test_case(GraphQLFloat, "123.456", 123.456) _test_case(GraphQLString, '"abc123"', "abc123") _test_case(GraphQLID, "123456", "123456") _test_case(GraphQLID, '"123456"', "123456") def does_not_convert_when_input_coercion_rules_reject_a_value(): _test_case(GraphQLBoolean, "123", INVALID) _test_case(GraphQLInt, "123.456", INVALID) _test_case(GraphQLInt, "true", INVALID) _test_case(GraphQLInt, '"123"', INVALID) _test_case(GraphQLFloat, '"123"', INVALID) _test_case(GraphQLString, "123", INVALID) _test_case(GraphQLString, "true", INVALID) _test_case(GraphQLID, "123.456", INVALID) test_enum = GraphQLEnumType( "TestColor", { "RED": 1, "GREEN": 2, "BLUE": 3, "NULL": None, "NAN": nan, "NO_CUSTOM_VALUE": INVALID, }, ) def converts_enum_values_according_to_input_coercion_rules(): _test_case(test_enum, "RED", 1) _test_case(test_enum, "BLUE", 3) _test_case(test_enum, "YELLOW", INVALID) _test_case(test_enum, "3", INVALID) _test_case(test_enum, '"BLUE"', INVALID) _test_case(test_enum, "null", None) _test_case(test_enum, "NULL", None) _test_case(test_enum, "NAN", nan) _test_case(test_enum, "NO_CUSTOM_VALUE", "NO_CUSTOM_VALUE") # Boolean! non_null_bool = GraphQLNonNull(GraphQLBoolean) # [Boolean] list_of_bool = GraphQLList(GraphQLBoolean) # [Boolean!] list_of_non_null_bool = GraphQLList(non_null_bool) # [Boolean]! non_null_list_of_bool = GraphQLNonNull(list_of_bool) # [Boolean!]! non_null_list_of_non_mull_bool = GraphQLNonNull(list_of_non_null_bool) def coerces_to_null_unless_non_null(): _test_case(GraphQLBoolean, "null", None) _test_case(non_null_bool, "null", INVALID) def coerces_lists_of_values(): _test_case(list_of_bool, "true", [True]) _test_case(list_of_bool, "123", INVALID) _test_case(list_of_bool, "null", None) _test_case(list_of_bool, "[true, false]", [True, False]) _test_case(list_of_bool, "[true, 123]", INVALID) _test_case(list_of_bool, "[true, null]", [True, None]) _test_case(list_of_bool, "{ true: true }", INVALID) def coerces_non_null_lists_of_values(): _test_case(non_null_list_of_bool, "true", [True]) _test_case(non_null_list_of_bool, "123", INVALID) _test_case(non_null_list_of_bool, "null", INVALID) _test_case(non_null_list_of_bool, "[true, false]", [True, False]) _test_case(non_null_list_of_bool, "[true, 123]", INVALID) _test_case(non_null_list_of_bool, "[true, null]", [True, None]) def coerces_lists_of_non_null_values(): _test_case(list_of_non_null_bool, "true", [True]) _test_case(list_of_non_null_bool, "123", INVALID) _test_case(list_of_non_null_bool, "null", None) _test_case(list_of_non_null_bool, "[true, false]", [True, False]) _test_case(list_of_non_null_bool, "[true, 123]", INVALID) _test_case(list_of_non_null_bool, "[true, null]", INVALID) def coerces_non_null_lists_of_non_null_values(): _test_case(non_null_list_of_non_mull_bool, "true", [True]) _test_case(non_null_list_of_non_mull_bool, "123", INVALID) _test_case(non_null_list_of_non_mull_bool, "null", INVALID) _test_case(non_null_list_of_non_mull_bool, "[true, false]", [True, False]) _test_case(non_null_list_of_non_mull_bool, "[true, 123]", INVALID) _test_case(non_null_list_of_non_mull_bool, "[true, null]", INVALID) test_input_obj = GraphQLInputObjectType( "TestInput", { "int": GraphQLInputField(GraphQLInt, default_value=42), "bool": GraphQLInputField(GraphQLBoolean), "requiredBool": GraphQLInputField(non_null_bool), }, ) def coerces_input_objects_according_to_input_coercion_rules(): _test_case(test_input_obj, "null", None) _test_case(test_input_obj, "123", INVALID) _test_case(test_input_obj, "[]", INVALID) _test_case( test_input_obj, "{ int: 123, requiredBool: false }", { "int": 123, "requiredBool": False }, ) _test_case( test_input_obj, "{ bool: true, requiredBool: false }", { "int": 42, "bool": True, "requiredBool": False }, ) _test_case(test_input_obj, "{ int: true, requiredBool: true }", INVALID) _test_case(test_input_obj, "{ requiredBool: null }", INVALID) _test_case(test_input_obj, "{ bool: true }", INVALID) def accepts_variable_values_assuming_already_coerced(): _test_case_with_vars({}, GraphQLBoolean, "$var", INVALID) _test_case_with_vars({"var": True}, GraphQLBoolean, "$var", True) _test_case_with_vars({"var": None}, GraphQLBoolean, "$var", None) def asserts_variables_are_provided_as_items_in_lists(): _test_case_with_vars({}, list_of_bool, "[ $foo ]", [None]) _test_case_with_vars({}, list_of_non_null_bool, "[ $foo ]", INVALID) _test_case_with_vars({"foo": True}, list_of_non_null_bool, "[ $foo ]", [True]) # Note: variables are expected to have already been coerced, so we # do not expect the singleton wrapping behavior for variables. _test_case_with_vars({"foo": True}, list_of_non_null_bool, "$foo", True) _test_case_with_vars({"foo": [True]}, list_of_non_null_bool, "$foo", [True]) def omits_input_object_fields_for_unprovided_variables(): _test_case_with_vars( {}, test_input_obj, "{ int: $foo, bool: $foo, requiredBool: true }", { "int": 42, "requiredBool": True }, ) _test_case_with_vars({}, test_input_obj, "{ requiredBool: $foo }", INVALID) _test_case_with_vars( {"foo": True}, test_input_obj, "{ requiredBool: $foo }", { "int": 42, "requiredBool": True }, ) def transforms_names_using_out_name(): # This is an extension of GraphQL.js. complex_input_obj = GraphQLInputObjectType( "Complex", { "realPart": GraphQLInputField(GraphQLFloat, out_name="real_part"), "imagPart": GraphQLInputField( GraphQLFloat, default_value=0, out_name="imag_part"), }, ) _test_case(complex_input_obj, "{ realPart: 1 }", { "real_part": 1, "imag_part": 0 }) def transforms_values_with_out_type(): # This is an extension of GraphQL.js. complex_input_obj = GraphQLInputObjectType( "Complex", { "real": GraphQLInputField(GraphQLFloat), "imag": GraphQLInputField(GraphQLFloat), }, out_type=lambda value: complex(value["real"], value["imag"]), ) _test_case(complex_input_obj, "{ real: 1, imag: 2 }", 1 + 2j)
def describe_ast_from_value(): def converts_boolean_values_to_asts(): assert ast_from_value(True, GraphQLBoolean) == BooleanValueNode(value=True) assert ast_from_value(False, GraphQLBoolean) == BooleanValueNode(value=False) assert ast_from_value(Undefined, GraphQLBoolean) is None assert ast_from_value(None, GraphQLBoolean) == NullValueNode() assert ast_from_value(0, GraphQLBoolean) == BooleanValueNode(value=False) assert ast_from_value(1, GraphQLBoolean) == BooleanValueNode(value=True) non_null_boolean = GraphQLNonNull(GraphQLBoolean) assert ast_from_value( 0, non_null_boolean) == BooleanValueNode(value=False) def converts_int_values_to_int_asts(): assert ast_from_value(-1, GraphQLInt) == IntValueNode(value="-1") assert ast_from_value(123.0, GraphQLInt) == IntValueNode(value="123") assert ast_from_value(1e4, GraphQLInt) == IntValueNode(value="10000") # GraphQL spec does not allow coercing non-integer values to Int to # avoid accidental data loss. with raises(GraphQLError) as exc_info: assert ast_from_value(123.5, GraphQLInt) msg = str(exc_info.value) assert msg == "Int cannot represent non-integer value: 123.5" # Note: outside the bounds of 32bit signed int. with raises(GraphQLError) as exc_info: assert ast_from_value(1e40, GraphQLInt) msg = str(exc_info.value) assert msg == "Int cannot represent non 32-bit signed integer value: 1e+40" with raises(GraphQLError) as exc_info: ast_from_value(nan, GraphQLInt) msg = str(exc_info.value) assert msg == "Int cannot represent non-integer value: nan" def converts_float_values_to_float_asts(): # luckily in Python we can discern between float and int assert ast_from_value(-1, GraphQLFloat) == FloatValueNode(value="-1") assert ast_from_value(123.0, GraphQLFloat) == FloatValueNode(value="123") assert ast_from_value(123.5, GraphQLFloat) == FloatValueNode(value="123.5") assert ast_from_value(1e4, GraphQLFloat) == FloatValueNode(value="10000") assert ast_from_value(1e40, GraphQLFloat) == FloatValueNode(value="1e+40") def converts_string_values_to_string_asts(): assert ast_from_value("hello", GraphQLString) == StringValueNode(value="hello") assert ast_from_value("VALUE", GraphQLString) == StringValueNode(value="VALUE") assert ast_from_value( "VA\nLUE", GraphQLString) == StringValueNode(value="VA\nLUE") assert ast_from_value(123, GraphQLString) == StringValueNode(value="123") assert ast_from_value(False, GraphQLString) == StringValueNode(value="false") assert ast_from_value(None, GraphQLString) == NullValueNode() assert ast_from_value(Undefined, GraphQLString) is None def converts_id_values_to_int_or_string_asts(): assert ast_from_value("hello", GraphQLID) == StringValueNode(value="hello") assert ast_from_value("VALUE", GraphQLID) == StringValueNode(value="VALUE") # Note: EnumValues cannot contain non-identifier characters assert ast_from_value("VA\nLUE", GraphQLID) == StringValueNode(value="VA\nLUE") # Note: IntValues are used when possible. assert ast_from_value(-1, GraphQLID) == IntValueNode(value="-1") assert ast_from_value(123, GraphQLID) == IntValueNode(value="123") assert ast_from_value("123", GraphQLID) == IntValueNode(value="123") assert ast_from_value("01", GraphQLID) == StringValueNode(value="01") with raises(GraphQLError) as exc_info: assert ast_from_value(False, GraphQLID) assert str(exc_info.value) == "ID cannot represent value: False" assert ast_from_value(None, GraphQLID) == NullValueNode() assert ast_from_value(Undefined, GraphQLString) is None def converts_using_serialize_from_a_custom_scalar_type(): pass_through_scalar = GraphQLScalarType( "PassThroughScalar", serialize=lambda value: value, ) assert ast_from_value( "value", pass_through_scalar) == StringValueNode(value="value") with raises(TypeError) as exc_info: assert ast_from_value(nan, pass_through_scalar) assert str(exc_info.value) == "Cannot convert value to AST: nan." with raises(TypeError) as exc_info: ast_from_value(inf, pass_through_scalar) assert str(exc_info.value) == "Cannot convert value to AST: inf." return_null_scalar = GraphQLScalarType( "ReturnNullScalar", serialize=lambda value: None, ) assert ast_from_value("value", return_null_scalar) is None class SomeClass: pass return_custom_class_scalar = GraphQLScalarType( "ReturnCustomClassScalar", serialize=lambda value: SomeClass(), ) with raises(TypeError) as exc_info: ast_from_value("value", return_custom_class_scalar) msg = str(exc_info.value) assert msg == "Cannot convert value to AST: <SomeClass instance>." def does_not_convert_non_null_values_to_null_value(): non_null_boolean = GraphQLNonNull(GraphQLBoolean) assert ast_from_value(None, non_null_boolean) is None complex_value = {"someArbitrary": "complexValue"} my_enum = GraphQLEnumType("MyEnum", { "HELLO": None, "GOODBYE": None, "COMPLEX": complex_value }) def converts_string_values_to_enum_asts_if_possible(): assert ast_from_value("HELLO", my_enum) == EnumValueNode(value="HELLO") assert ast_from_value(complex_value, my_enum) == EnumValueNode(value="COMPLEX") # Note: case sensitive with raises(GraphQLError) as exc_info: ast_from_value("hello", my_enum) assert exc_info.value.message == "Enum 'MyEnum' cannot represent value: 'hello'" # Note: not a valid enum value with raises(GraphQLError) as exc_info: ast_from_value("UNKNOWN_VALUE", my_enum) assert (exc_info.value.message == "Enum 'MyEnum' cannot represent value: 'UNKNOWN_VALUE'") def converts_list_values_to_list_asts(): assert ast_from_value( ["FOO", "BAR"], GraphQLList(GraphQLString)) == ListValueNode(values=[ StringValueNode(value="FOO"), StringValueNode(value="BAR") ]) assert ast_from_value(["HELLO", "GOODBYE"], GraphQLList(my_enum)) == ListValueNode(values=[ EnumValueNode(value="HELLO"), EnumValueNode(value="GOODBYE") ]) def list_generator(): yield 1 yield 2 yield 3 assert ast_from_value( list_generator(), GraphQLList(GraphQLInt)) == (ListValueNode(values=[ IntValueNode(value="1"), IntValueNode(value="2"), IntValueNode(value="3"), ])) def converts_list_singletons(): assert ast_from_value( "FOO", GraphQLList(GraphQLString)) == StringValueNode(value="FOO") def skips_invalid_list_items(): ast = ast_from_value(["FOO", None, "BAR"], GraphQLList(GraphQLNonNull(GraphQLString))) assert ast == ListValueNode(values=[ StringValueNode(value="FOO"), StringValueNode(value="BAR") ]) input_obj = GraphQLInputObjectType( "MyInputObj", { "foo": GraphQLInputField(GraphQLFloat), "bar": GraphQLInputField(my_enum) }, ) def converts_input_objects(): assert ast_from_value({ "foo": 3, "bar": "HELLO" }, input_obj) == ObjectValueNode(fields=[ ObjectFieldNode(name=NameNode(value="foo"), value=FloatValueNode(value="3")), ObjectFieldNode(name=NameNode(value="bar"), value=EnumValueNode(value="HELLO")), ]) def converts_input_objects_with_explicit_nulls(): assert ast_from_value({ "foo": None }, input_obj) == ObjectValueNode(fields=[ ObjectFieldNode(name=NameNode(value="foo"), value=NullValueNode()) ]) def does_not_convert_non_object_values_as_input_objects(): assert ast_from_value(5, input_obj) is None
def accepts_a_well_defined_enum_type_with_empty_value_definition(): enum_type = GraphQLEnumType('SomeEnum', {'FOO': None, 'BAR': None}) assert enum_type.values['FOO'].value is None assert enum_type.values['BAR'].value is None
TestInputObject = GraphQLInputObjectType('TestInputObject', { 'a': GraphQLInputField(GraphQLString), 'b': GraphQLInputField(GraphQLList(GraphQLString)), 'c': GraphQLInputField(GraphQLNonNull(GraphQLString)), 'd': GraphQLInputField(TestComplexScalar)}) TestNestedInputObject = GraphQLInputObjectType('TestNestedInputObject', { 'na': GraphQLInputField(GraphQLNonNull(TestInputObject)), 'nb': GraphQLInputField(GraphQLNonNull(GraphQLString))}) TestEnum = GraphQLEnumType('TestEnum', { 'NULL': None, 'UNDEFINED': INVALID, 'NAN': nan, 'FALSE': False, 'CUSTOM': 'custom value', 'DEFAULT_VALUE': GraphQLEnumValue()}) def field_with_input_arg(input_arg: GraphQLArgument): return GraphQLField( GraphQLString, args={'input': input_arg}, resolve=lambda _obj, _info, **args: repr(args['input']) if 'input' in args else None) TestType = GraphQLObjectType('TestType', { 'fieldWithEnumInput': field_with_input_arg(GraphQLArgument(TestEnum)), 'fieldWithNonNullableEnumInput': field_with_input_arg(GraphQLArgument(
def does_not_allow_is_deprecated_instead_of_deprecation_reason_on_enum(): with raises( TypeError, match="got an unexpected keyword argument 'is_deprecated'" ): # noinspection PyArgumentList GraphQLEnumType("SomeEnum", {"FOO": GraphQLEnumValue(is_deprecated=True)})
def python_type_to_graphql_type(t, nonnull=True): if str(t).startswith("typing.AsyncIterator"): assert len(t.__args__) == 1 return GraphQLList( python_type_to_graphql_type(t.__args__[0], nonnull=True)) if str(t).startswith("typing.Iterable"): assert len(t.__args__) == 1 return GraphQLList( python_type_to_graphql_type(t.__args__[0], nonnull=True)) elif str(t).startswith("typing.List"): assert len(t.__args__) == 1 return GraphQLList( python_type_to_graphql_type(t.__args__[0], nonnull=True)) elif str(t).startswith("typing.Tuple"): if not len(set(t.__args__)) == 1: raise Exception("tuples must have the same type for all members") return GraphQLList( python_type_to_graphql_type(t.__args__[0], nonnull=True)) if str(t).startswith("graphql.type.definition.GraphQLList"): assert len(t.__args__) == 1 return GraphQLList( python_type_to_graphql_type(t.__args__[0], nonnull=True)) elif str(t).startswith("typing.Union") or str(t).startswith( "typing.Optional"): if len(t.__args__) == 2: if issubclass(t.__args__[1], type(None)): return python_type_to_graphql_type(t.__args__[0], nonnull=False) else: raise Exception else: raise Exception elif isinstance(t, GraphQLObjectType): if nonnull: return GraphQLNonNull(t) return t else: try: if issubclass(t, TypedInputGraphQLObject): if nonnull: return GraphQLNonNull(t.graphql_type) return t.graphql_type elif issubclass(t, TypedGraphQLObject): if nonnull: return GraphQLNonNull(t.graphql_type) return t.graphql_type elif issubclass(t, str): if nonnull: return GraphQLNonNull(String) return String elif issubclass(t, bool): if nonnull: return GraphQLNonNull(Boolean) return Boolean elif issubclass(t, int): if nonnull: return GraphQLNonNull(Int) return Int elif issubclass(t, float): if nonnull: return GraphQLNonNull(Float) return Float elif issubclass(t, enum.Enum): if not hasattr(t, "_graphql_type"): t._graphql_type = GraphQLEnumType(t.__name__, dict(t.__members__)) if nonnull: return GraphQLNonNull(t._graphql_type) return t._graphql_type else: raise Exception(t) except TypeError: print(f"Bad type: {t} of {type(t)}") raise
def describe_value_from_ast(): def _test_case(type_, value_text, expected): value_node = parse_value(value_text) assert value_from_ast(value_node, type_) == expected def _test_case_expect_nan(type_, value_text): value_node = parse_value(value_text) assert isnan(value_from_ast(value_node, type_)) def _test_case_with_vars(variables, type_, value_text, expected): value_node = parse_value(value_text) assert value_from_ast(value_node, type_, variables) == expected def rejects_empty_input(): # noinspection PyTypeChecker assert value_from_ast(None, GraphQLBoolean) is INVALID def converts_according_to_input_coercion_rules(): _test_case(GraphQLBoolean, "true", True) _test_case(GraphQLBoolean, "false", False) _test_case(GraphQLInt, "123", 123) _test_case(GraphQLFloat, "123", 123) _test_case(GraphQLFloat, "123.456", 123.456) _test_case(GraphQLString, '"abc123"', "abc123") _test_case(GraphQLID, "123456", "123456") _test_case(GraphQLID, '"123456"', "123456") def does_not_convert_when_input_coercion_rules_reject_a_value(): _test_case(GraphQLBoolean, "123", INVALID) _test_case(GraphQLInt, "123.456", INVALID) _test_case(GraphQLInt, "true", INVALID) _test_case(GraphQLInt, '"123"', INVALID) _test_case(GraphQLFloat, '"123"', INVALID) _test_case(GraphQLString, "123", INVALID) _test_case(GraphQLString, "true", INVALID) _test_case(GraphQLID, "123.456", INVALID) test_enum = GraphQLEnumType( "TestColor", { "RED": 1, "GREEN": 2, "BLUE": 3, "NULL": None, "INVALID": INVALID, "NAN": nan }, ) def converts_enum_values_according_to_input_coercion_rules(): _test_case(test_enum, "RED", 1) _test_case(test_enum, "BLUE", 3) _test_case(test_enum, "YELLOW", INVALID) _test_case(test_enum, "3", INVALID) _test_case(test_enum, '"BLUE"', INVALID) _test_case(test_enum, "null", None) _test_case(test_enum, "NULL", None) _test_case(test_enum, "INVALID", INVALID) # nan is not equal to itself, needs a special test case _test_case_expect_nan(test_enum, "NAN") # Boolean! non_null_bool = GraphQLNonNull(GraphQLBoolean) # [Boolean] list_of_bool = GraphQLList(GraphQLBoolean) # [Boolean!] list_of_non_null_bool = GraphQLList(non_null_bool) # [Boolean]! non_null_list_of_bool = GraphQLNonNull(list_of_bool) # [Boolean!]! non_null_list_of_non_mull_bool = GraphQLNonNull(list_of_non_null_bool) def coerces_to_null_unless_non_null(): _test_case(GraphQLBoolean, "null", None) _test_case(non_null_bool, "null", INVALID) def coerces_lists_of_values(): _test_case(list_of_bool, "true", [True]) _test_case(list_of_bool, "123", INVALID) _test_case(list_of_bool, "null", None) _test_case(list_of_bool, "[true, false]", [True, False]) _test_case(list_of_bool, "[true, 123]", INVALID) _test_case(list_of_bool, "[true, null]", [True, None]) _test_case(list_of_bool, "{ true: true }", INVALID) def coerces_non_null_lists_of_values(): _test_case(non_null_list_of_bool, "true", [True]) _test_case(non_null_list_of_bool, "123", INVALID) _test_case(non_null_list_of_bool, "null", INVALID) _test_case(non_null_list_of_bool, "[true, false]", [True, False]) _test_case(non_null_list_of_bool, "[true, 123]", INVALID) _test_case(non_null_list_of_bool, "[true, null]", [True, None]) def coerces_lists_of_non_null_values(): _test_case(list_of_non_null_bool, "true", [True]) _test_case(list_of_non_null_bool, "123", INVALID) _test_case(list_of_non_null_bool, "null", None) _test_case(list_of_non_null_bool, "[true, false]", [True, False]) _test_case(list_of_non_null_bool, "[true, 123]", INVALID) _test_case(list_of_non_null_bool, "[true, null]", INVALID) def coerces_non_null_lists_of_non_null_values(): _test_case(non_null_list_of_non_mull_bool, "true", [True]) _test_case(non_null_list_of_non_mull_bool, "123", INVALID) _test_case(non_null_list_of_non_mull_bool, "null", INVALID) _test_case(non_null_list_of_non_mull_bool, "[true, false]", [True, False]) _test_case(non_null_list_of_non_mull_bool, "[true, 123]", INVALID) _test_case(non_null_list_of_non_mull_bool, "[true, null]", INVALID) test_input_obj = GraphQLInputObjectType( "TestInput", { "int": GraphQLInputField(GraphQLInt, default_value=42), "bool": GraphQLInputField(GraphQLBoolean), "requiredBool": GraphQLInputField(non_null_bool), }, ) def coerces_input_objects_according_to_input_coercion_rules(): _test_case(test_input_obj, "null", None) _test_case(test_input_obj, "123", INVALID) _test_case(test_input_obj, "[]", INVALID) _test_case( test_input_obj, "{ int: 123, requiredBool: false }", { "int": 123, "requiredBool": False }, ) _test_case( test_input_obj, "{ bool: true, requiredBool: false }", { "int": 42, "bool": True, "requiredBool": False }, ) _test_case(test_input_obj, "{ int: true, requiredBool: true }", INVALID) _test_case(test_input_obj, "{ requiredBool: null }", INVALID) _test_case(test_input_obj, "{ bool: true }", INVALID) def accepts_variable_values_assuming_already_coerced(): _test_case_with_vars({}, GraphQLBoolean, "$var", INVALID) _test_case_with_vars({"var": True}, GraphQLBoolean, "$var", True) _test_case_with_vars({"var": None}, GraphQLBoolean, "$var", None) def asserts_variables_are_provided_as_items_in_lists(): _test_case_with_vars({}, list_of_bool, "[ $foo ]", [None]) _test_case_with_vars({}, list_of_non_null_bool, "[ $foo ]", INVALID) _test_case_with_vars({"foo": True}, list_of_non_null_bool, "[ $foo ]", [True]) # Note: variables are expected to have already been coerced, so we # do not expect the singleton wrapping behavior for variables. _test_case_with_vars({"foo": True}, list_of_non_null_bool, "$foo", True) _test_case_with_vars({"foo": [True]}, list_of_non_null_bool, "$foo", [True]) def omits_input_object_fields_for_unprovided_variables(): _test_case_with_vars( {}, test_input_obj, "{ int: $foo, bool: $foo, requiredBool: true }", { "int": 42, "requiredBool": True }, ) _test_case_with_vars({}, test_input_obj, "{ requiredBool: $foo }", INVALID) _test_case_with_vars( {"foo": True}, test_input_obj, "{ requiredBool: $foo }", { "int": 42, "requiredBool": True }, )
def builds_a_schema_with_an_enum(): food_enum = GraphQLEnumType( "Food", { "VEGETABLES": GraphQLEnumValue( 1, description="Foods that are vegetables." ), "FRUITS": GraphQLEnumValue(2), "OILS": GraphQLEnumValue(3, deprecation_reason="Too fatty."), }, description="Varieties of food stuffs", ) schema = GraphQLSchema( GraphQLObjectType( "EnumFields", { "food": GraphQLField( food_enum, args={ "kind": GraphQLArgument( food_enum, description="what kind of food?" ) }, description="Repeats the arg you give it", ) }, ) ) introspection = introspection_from_schema(schema) client_schema = build_client_schema(introspection) second_introspection = introspection_from_schema(client_schema) assert second_introspection == introspection # It's also an Enum type on the client. client_food_enum = assert_enum_type(client_schema.get_type("Food")) # Client types do not get server-only values, so they are set to None # rather than using the integers defined in the "server" schema. values = { name: value.to_kwargs() for name, value in client_food_enum.values.items() } assert values == { "VEGETABLES": { "value": None, "description": "Foods that are vegetables.", "deprecation_reason": None, "extensions": None, "ast_node": None, }, "FRUITS": { "value": None, "description": None, "deprecation_reason": None, "extensions": None, "ast_node": None, }, "OILS": { "value": None, "description": None, "deprecation_reason": "Too fatty.", "extensions": None, "ast_node": None, }, }
from collections import OrderedDict from rx import Observable from graphql import graphql from graphql.type import (GraphQLArgument, GraphQLEnumType, GraphQLEnumValue, GraphQLField, GraphQLInt, GraphQLObjectType, GraphQLSchema, GraphQLString) ColorType = GraphQLEnumType( name='Color', values=OrderedDict([ ('RED', GraphQLEnumValue(0)), ('GREEN', GraphQLEnumValue(1)), ('BLUE', GraphQLEnumValue(2)) ]) ) def get_first(args, *keys): for key in keys: if key in args: return args[key] return None QueryType = GraphQLObjectType( name='Query', fields={ 'colorEnum': GraphQLField(
from graphql.type import ( GraphQLArgument, GraphQLEnumType, GraphQLEnumValue, GraphQLField, GraphQLInt, GraphQLObjectType, GraphQLSchema, GraphQLString, ) import pytest ColorType = GraphQLEnumType( name="Color", values=OrderedDict([ ("RED", GraphQLEnumValue(0)), ("GREEN", GraphQLEnumValue(1)), ("BLUE", GraphQLEnumValue(2)), ]), ) def get_first(args, *keys): for key in keys: if key in args: return args[key] return None QueryType = GraphQLObjectType( name="Query",
'name': GraphQLField(GraphQLString), 'some': GraphQLField(SomeInterfaceType), 'foo': GraphQLField(FooType)}) BizType = GraphQLObjectType( name='Biz', fields=lambda: { 'fizz': GraphQLField(GraphQLString)}) SomeUnionType = GraphQLUnionType( name='SomeUnion', types=[FooType, BizType]) SomeEnumType = GraphQLEnumType( name='SomeEnum', values={ 'ONE': GraphQLEnumValue(1), 'TWO': GraphQLEnumValue(2)}) SomeInputType = GraphQLInputObjectType('SomeInput', lambda: { 'fooArg': GraphQLInputField(GraphQLString)}) FooDirective = GraphQLDirective( name='foo', args={'input': GraphQLArgument(SomeInputType)}, locations=[ DirectiveLocation.SCHEMA, DirectiveLocation.SCALAR, DirectiveLocation.OBJECT, DirectiveLocation.FIELD_DEFINITION, DirectiveLocation.ARGUMENT_DEFINITION,
interfaces=[SomeInterfaceType], fields=lambda: { "name": GraphQLField(GraphQLString), "some": GraphQLField(SomeInterfaceType), "foo": GraphQLField(FooType), }, ) BizType = GraphQLObjectType( name="Biz", fields=lambda: {"fizz": GraphQLField(GraphQLString)}) SomeUnionType = GraphQLUnionType(name="SomeUnion", types=[FooType, BizType]) SomeEnumType = GraphQLEnumType(name="SomeEnum", values={ "ONE": GraphQLEnumValue(1), "TWO": GraphQLEnumValue(2) }) SomeInputType = GraphQLInputObjectType( "SomeInput", lambda: {"fooArg": GraphQLInputField(GraphQLString)}) FooDirective = GraphQLDirective( name="foo", args={"input": GraphQLArgument(SomeInputType)}, locations=[ DirectiveLocation.SCHEMA, DirectiveLocation.SCALAR, DirectiveLocation.OBJECT, DirectiveLocation.FIELD_DEFINITION, DirectiveLocation.ARGUMENT_DEFINITION,
])) BizType = GraphQLObjectType(name='Biz', fields=lambda: OrderedDict([ ('fizz', GraphQLField(GraphQLString)), ])) SomeUnionType = GraphQLUnionType( name='SomeUnion', resolve_type=lambda: FooType, types=[FooType, BizType], ) SomeEnumType = GraphQLEnumType(name='SomeEnum', values=OrderedDict([ ('ONE', GraphQLEnumValue(1)), ('TWO', GraphQLEnumValue(2)), ])) test_schema = GraphQLSchema(query=GraphQLObjectType( name='Query', fields=lambda: OrderedDict([ ('foo', GraphQLField(FooType)), ('someUnion', GraphQLField(SomeUnionType)), ('someEnum', GraphQLField(SomeEnumType)), ('someInterface', GraphQLField( SomeInterfaceType, args={'id': GraphQLArgument(GraphQLNonNull(GraphQLID))}, )), ])),
from graphql import graphql_sync from graphql.type import ( GraphQLArgument, GraphQLBoolean, GraphQLEnumType, GraphQLEnumValue, GraphQLField, GraphQLInt, GraphQLObjectType, GraphQLSchema, GraphQLString, ) from graphql.utilities import introspection_from_schema ColorType = GraphQLEnumType("Color", values={"RED": 0, "GREEN": 1, "BLUE": 2}) class ColorTypeEnumValues(Enum): RED = 0 GREEN = 1 BLUE = 2 class Complex1: # noinspection PyMethodMayBeStatic some_random_object = datetime.now() class Complex2: some_random_value = 123
def describe_ast_from_value(): def converts_boolean_values_to_asts(): assert ast_from_value(True, GraphQLBoolean) == BooleanValueNode(value=True) assert ast_from_value(False, GraphQLBoolean) == BooleanValueNode(value=False) assert ast_from_value(INVALID, GraphQLBoolean) is None assert ast_from_value(nan, GraphQLInt) is None assert ast_from_value(None, GraphQLBoolean) == NullValueNode() assert ast_from_value(0, GraphQLBoolean) == BooleanValueNode(value=False) assert ast_from_value(1, GraphQLBoolean) == BooleanValueNode(value=True) non_null_boolean = GraphQLNonNull(GraphQLBoolean) assert ast_from_value(0, non_null_boolean) == BooleanValueNode(value=False) def converts_int_values_to_int_asts(): assert ast_from_value(-1, GraphQLInt) == IntValueNode(value="-1") assert ast_from_value(123.0, GraphQLInt) == IntValueNode(value="123") assert ast_from_value(1e4, GraphQLInt) == IntValueNode(value="10000") # GraphQL spec does not allow coercing non-integer values to Int to # avoid accidental data loss. with raises(GraphQLError) as exc_info: assert ast_from_value(123.5, GraphQLInt) msg = str(exc_info.value) assert msg == "Int cannot represent non-integer value: 123.5" # Note: outside the bounds of 32bit signed int. with raises(GraphQLError) as exc_info: assert ast_from_value(1e40, GraphQLInt) msg = str(exc_info.value) assert msg == "Int cannot represent non 32-bit signed integer value: 1e+40" def converts_float_values_to_float_asts(): # luckily in Python we can discern between float and int assert ast_from_value(-1, GraphQLFloat) == FloatValueNode(value="-1") assert ast_from_value(123.0, GraphQLFloat) == FloatValueNode(value="123") assert ast_from_value(123.5, GraphQLFloat) == FloatValueNode(value="123.5") assert ast_from_value(1e4, GraphQLFloat) == FloatValueNode(value="10000") assert ast_from_value(1e40, GraphQLFloat) == FloatValueNode(value="1e+40") def converts_string_values_to_string_asts(): assert ast_from_value("hello", GraphQLString) == StringValueNode(value="hello") assert ast_from_value("VALUE", GraphQLString) == StringValueNode(value="VALUE") assert ast_from_value("VA\nLUE", GraphQLString) == StringValueNode( value="VA\nLUE" ) assert ast_from_value(123, GraphQLString) == StringValueNode(value="123") assert ast_from_value(False, GraphQLString) == StringValueNode(value="false") assert ast_from_value(None, GraphQLString) == NullValueNode() assert ast_from_value(INVALID, GraphQLString) is None def converts_id_values_to_int_or_string_asts(): assert ast_from_value("hello", GraphQLID) == StringValueNode(value="hello") assert ast_from_value("VALUE", GraphQLID) == StringValueNode(value="VALUE") # Note: EnumValues cannot contain non-identifier characters assert ast_from_value("VA\nLUE", GraphQLID) == StringValueNode(value="VA\nLUE") # Note: IntValues are used when possible. assert ast_from_value(-1, GraphQLID) == IntValueNode(value="-1") assert ast_from_value(123, GraphQLID) == IntValueNode(value="123") assert ast_from_value("123", GraphQLID) == IntValueNode(value="123") assert ast_from_value("01", GraphQLID) == StringValueNode(value="01") with raises(GraphQLError) as exc_info: assert ast_from_value(False, GraphQLID) assert str(exc_info.value) == "ID cannot represent value: False" assert ast_from_value(None, GraphQLID) == NullValueNode() assert ast_from_value(INVALID, GraphQLString) is None def does_not_convert_non_null_values_to_null_value(): non_null_boolean = GraphQLNonNull(GraphQLBoolean) assert ast_from_value(None, non_null_boolean) is None complex_value = {"someArbitrary": "complexValue"} my_enum = GraphQLEnumType( "MyEnum", {"HELLO": None, "GOODBYE": None, "COMPLEX": complex_value} ) def converts_string_values_to_enum_asts_if_possible(): assert ast_from_value("HELLO", my_enum) == EnumValueNode(value="HELLO") assert ast_from_value(complex_value, my_enum) == EnumValueNode(value="COMPLEX") # Note: case sensitive assert ast_from_value("hello", my_enum) is None # Note: not a valid enum value assert ast_from_value("VALUE", my_enum) is None def converts_list_values_to_list_asts(): assert ast_from_value( ["FOO", "BAR"], GraphQLList(GraphQLString) ) == ListValueNode( values=[StringValueNode(value="FOO"), StringValueNode(value="BAR")] ) assert ast_from_value( ["HELLO", "GOODBYE"], GraphQLList(my_enum) ) == ListValueNode( values=[EnumValueNode(value="HELLO"), EnumValueNode(value="GOODBYE")] ) def converts_list_singletons(): assert ast_from_value("FOO", GraphQLList(GraphQLString)) == StringValueNode( value="FOO" ) def converts_input_objects(): input_obj = GraphQLInputObjectType( "MyInputObj", {"foo": GraphQLInputField(GraphQLFloat), "bar": GraphQLInputField(my_enum)}, ) assert ast_from_value({"foo": 3, "bar": "HELLO"}, input_obj) == ObjectValueNode( fields=[ ObjectFieldNode( name=NameNode(value="foo"), value=FloatValueNode(value="3") ), ObjectFieldNode( name=NameNode(value="bar"), value=EnumValueNode(value="HELLO") ), ] ) def converts_input_objects_with_explicit_nulls(): input_obj = GraphQLInputObjectType( "MyInputObj", {"foo": GraphQLInputField(GraphQLFloat), "bar": GraphQLInputField(my_enum)}, ) assert ast_from_value({"foo": None}, input_obj) == ObjectValueNode( fields=[ObjectFieldNode(name=NameNode(value="foo"), value=NullValueNode())] )
GraphQLField(GraphQLString, { 'surname': GraphQLArgument(GraphQLBoolean), }), }) Canine = GraphQLInterfaceType( 'Canine', { 'name': GraphQLField(GraphQLString, { 'surname': GraphQLArgument(GraphQLBoolean), }), }) DogCommand = GraphQLEnumType( 'DogCommand', { 'SIT': GraphQLEnumValue(0), 'HEEL': GraphQLEnumValue(1), 'DOWN': GraphQLEnumValue(2), }) Dog = GraphQLObjectType('Dog', { 'name': GraphQLField(GraphQLString, { 'surname': GraphQLArgument(GraphQLBoolean), }), 'nickname': GraphQLField(GraphQLString), 'barkVolume': GraphQLField(GraphQLInt), 'barks': GraphQLField(GraphQLBoolean), 'doesKnowCommand':
def accepts_a_well_defined_enum_type_with_empty_value_definition(): enum_type = GraphQLEnumType("SomeEnum", {"FOO": None, "BAR": None}) assert enum_type.values["FOO"].value is None assert enum_type.values["BAR"].value is None
}, ) Canine = GraphQLInterfaceType( "Canine", { "name": GraphQLField(GraphQLString, {"surname": GraphQLArgument(GraphQLBoolean)}) }, ) DogCommand = GraphQLEnumType( "DogCommand", { "SIT": GraphQLEnumValue(0), "HEEL": GraphQLEnumValue(1), "DOWN": GraphQLEnumValue(2), }, ) Dog = GraphQLObjectType( "Dog", { "name": GraphQLField(GraphQLString, {"surname": GraphQLArgument(GraphQLBoolean)}), "nickname": GraphQLField(GraphQLString), "barkVolume": GraphQLField(GraphQLInt), "barks":
def describe_ast_from_value(): def converts_boolean_values_to_asts(): assert ast_from_value(True, GraphQLBoolean) == BooleanValueNode(value=True) assert ast_from_value(False, GraphQLBoolean) == BooleanValueNode(value=False) assert ast_from_value(INVALID, GraphQLBoolean) is None assert ast_from_value(nan, GraphQLInt) is None assert ast_from_value(None, GraphQLBoolean) == NullValueNode() assert ast_from_value(0, GraphQLBoolean) == BooleanValueNode(value=False) assert ast_from_value(1, GraphQLBoolean) == BooleanValueNode(value=True) non_null_boolean = GraphQLNonNull(GraphQLBoolean) assert ast_from_value( 0, non_null_boolean) == BooleanValueNode(value=False) def converts_int_values_to_int_asts(): assert ast_from_value(-1, GraphQLInt) == IntValueNode(value='-1') assert ast_from_value(123.0, GraphQLInt) == IntValueNode(value='123') assert ast_from_value(1e4, GraphQLInt) == IntValueNode(value='10000') # GraphQL spec does not allow coercing non-integer values to Int to # avoid accidental data loss. with raises(TypeError) as exc_info: assert ast_from_value(123.5, GraphQLInt) msg = str(exc_info.value) assert msg == 'Int cannot represent non-integer value: 123.5' # Note: outside the bounds of 32bit signed int. with raises(TypeError) as exc_info: assert ast_from_value(1e40, GraphQLInt) msg = str(exc_info.value) assert msg == ( 'Int cannot represent non 32-bit signed integer value: 1e+40') def converts_float_values_to_float_asts(): # luckily in Python we can discern between float and int assert ast_from_value(-1, GraphQLFloat) == FloatValueNode(value='-1') assert ast_from_value(123.0, GraphQLFloat) == FloatValueNode(value='123') assert ast_from_value(123.5, GraphQLFloat) == FloatValueNode(value='123.5') assert ast_from_value(1e4, GraphQLFloat) == FloatValueNode(value='10000') assert ast_from_value(1e40, GraphQLFloat) == FloatValueNode(value='1e+40') def converts_string_values_to_string_asts(): assert ast_from_value('hello', GraphQLString) == StringValueNode(value='hello') assert ast_from_value('VALUE', GraphQLString) == StringValueNode(value='VALUE') assert ast_from_value( 'VA\nLUE', GraphQLString) == StringValueNode(value='VA\nLUE') assert ast_from_value(123, GraphQLString) == StringValueNode(value='123') assert ast_from_value(False, GraphQLString) == StringValueNode(value='false') assert ast_from_value(None, GraphQLString) == NullValueNode() assert ast_from_value(INVALID, GraphQLString) is None def converts_id_values_to_int_or_string_asts(): assert ast_from_value('hello', GraphQLID) == StringValueNode(value='hello') assert ast_from_value('VALUE', GraphQLID) == StringValueNode(value='VALUE') # Note: EnumValues cannot contain non-identifier characters assert ast_from_value('VA\nLUE', GraphQLID) == StringValueNode(value='VA\nLUE') # Note: IntValues are used when possible. assert ast_from_value(-1, GraphQLID) == IntValueNode(value='-1') assert ast_from_value(123, GraphQLID) == IntValueNode(value='123') assert ast_from_value('123', GraphQLID) == IntValueNode(value='123') assert ast_from_value('01', GraphQLID) == StringValueNode(value='01') with raises(TypeError) as exc_info: assert ast_from_value(False, GraphQLID) assert str(exc_info.value) == 'ID cannot represent value: False' assert ast_from_value(None, GraphQLID) == NullValueNode() assert ast_from_value(INVALID, GraphQLString) is None def does_not_convert_non_null_values_to_null_value(): non_null_boolean = GraphQLNonNull(GraphQLBoolean) assert ast_from_value(None, non_null_boolean) is None complex_value = {'someArbitrary': 'complexValue'} my_enum = GraphQLEnumType('MyEnum', { 'HELLO': None, 'GOODBYE': None, 'COMPLEX': complex_value }) def converts_string_values_to_enum_asts_if_possible(): assert ast_from_value('HELLO', my_enum) == EnumValueNode(value='HELLO') assert ast_from_value(complex_value, my_enum) == EnumValueNode(value='COMPLEX') # Note: case sensitive assert ast_from_value('hello', my_enum) is None # Note: not a valid enum value assert ast_from_value('VALUE', my_enum) is None def converts_list_values_to_list_asts(): assert ast_from_value( ['FOO', 'BAR'], GraphQLList(GraphQLString)) == ListValueNode(values=[ StringValueNode(value='FOO'), StringValueNode(value='BAR') ]) assert ast_from_value(['HELLO', 'GOODBYE'], GraphQLList(my_enum)) == ListValueNode(values=[ EnumValueNode(value='HELLO'), EnumValueNode(value='GOODBYE') ]) def converts_list_singletons(): assert ast_from_value( 'FOO', GraphQLList(GraphQLString)) == StringValueNode(value='FOO') def converts_input_objects(): input_obj = GraphQLInputObjectType( 'MyInputObj', { 'foo': GraphQLInputField(GraphQLFloat), 'bar': GraphQLInputField(my_enum) }) assert ast_from_value({ 'foo': 3, 'bar': 'HELLO' }, input_obj) == ObjectValueNode(fields=[ ObjectFieldNode(name=NameNode(value='foo'), value=FloatValueNode(value='3')), ObjectFieldNode(name=NameNode(value='bar'), value=EnumValueNode(value='HELLO')) ]) def converts_input_objects_with_explicit_nulls(): input_obj = GraphQLInputObjectType( 'MyInputObj', { 'foo': GraphQLInputField(GraphQLFloat), 'bar': GraphQLInputField(my_enum) }) assert ast_from_value({ 'foo': None }, input_obj) == ObjectValueNode(fields=[ ObjectFieldNode(name=NameNode(value='foo'), value=NullValueNode()) ])
def schema_with_enum(name): return schema_with_field_type( GraphQLEnumType("SomeEnum", {name: GraphQLEnumValue(1)}))
}) BlogMutation = GraphQLObjectType('Mutation', {'writeArticle': GraphQLField(BlogArticle)}) BlogSubscription = GraphQLObjectType( 'Subscription', { 'articleSubscribe': GraphQLField(args={'id': GraphQLArgument(GraphQLString)}, type=BlogArticle) }) ObjectType = GraphQLObjectType('Object', {}) InterfaceType = GraphQLInterfaceType('Interface') UnionType = GraphQLUnionType('Union', [ObjectType], resolve_type=lambda: None) EnumType = GraphQLEnumType('Enum', {'foo': GraphQLEnumValue()}) InputObjectType = GraphQLInputObjectType('InputObject', {}) def test_defines_a_query_only_schema(): BlogSchema = GraphQLSchema(BlogQuery) assert BlogSchema.get_query_type() == BlogQuery article_field = BlogQuery.fields['article'] assert article_field.type == BlogArticle assert article_field.type.name == 'Article' # assert article_field.name == 'article' article_field_type = article_field.type assert isinstance(article_field_type, GraphQLObjectType)
is_required_argument, is_required_input_field, is_non_null_type, is_nullable_type, is_object_type, is_output_type, is_scalar_type, is_type, is_union_type, is_wrapping_type, ) ObjectType = GraphQLObjectType("Object", {}) InterfaceType = GraphQLInterfaceType("Interface", {}) UnionType = GraphQLUnionType("Union", types=[ObjectType]) EnumType = GraphQLEnumType("Enum", values={"foo": {}}) InputObjectType = GraphQLInputObjectType("InputObject", {}) ScalarType = GraphQLScalarType("Scalar", serialize=lambda: {}, parse_value=lambda: {}, parse_literal=lambda: {}) def describe_type_predicates(): def describe_is_type(): def returns_true_for_unwrapped_types(): assert is_type(GraphQLString) is True assert_type(GraphQLString) assert is_type(ObjectType) is True assert_type(ObjectType)
def describe_value_from_ast(): @fixture def test_case(type_, value_text, expected): value_node = parse_value(value_text) assert value_from_ast(value_node, type_) == expected @fixture def test_case_expect_nan(type_, value_text): value_node = parse_value(value_text) assert isnan(value_from_ast(value_node, type_)) @fixture def test_case_with_vars(variables, type_, value_text, expected): value_node = parse_value(value_text) assert value_from_ast(value_node, type_, variables) == expected def rejects_empty_input(): # noinspection PyTypeChecker assert value_from_ast(None, GraphQLBoolean) is INVALID def converts_according_to_input_coercion_rules(): test_case(GraphQLBoolean, 'true', True) test_case(GraphQLBoolean, 'false', False) test_case(GraphQLInt, '123', 123) test_case(GraphQLFloat, '123', 123) test_case(GraphQLFloat, '123.456', 123.456) test_case(GraphQLString, '"abc123"', 'abc123') test_case(GraphQLID, '123456', '123456') test_case(GraphQLID, '"123456"', '123456') def does_not_convert_when_input_coercion_rules_reject_a_value(): test_case(GraphQLBoolean, '123', INVALID) test_case(GraphQLInt, '123.456', INVALID) test_case(GraphQLInt, 'true', INVALID) test_case(GraphQLInt, '"123"', INVALID) test_case(GraphQLFloat, '"123"', INVALID) test_case(GraphQLString, '123', INVALID) test_case(GraphQLString, 'true', INVALID) test_case(GraphQLID, '123.456', INVALID) test_enum = GraphQLEnumType( 'TestColor', { 'RED': 1, 'GREEN': 2, 'BLUE': 3, 'NULL': None, 'INVALID': INVALID, 'NAN': nan }) def converts_enum_values_according_to_input_coercion_rules(): test_case(test_enum, 'RED', 1) test_case(test_enum, 'BLUE', 3) test_case(test_enum, 'YELLOW', INVALID) test_case(test_enum, '3', INVALID) test_case(test_enum, '"BLUE"', INVALID) test_case(test_enum, 'null', None) test_case(test_enum, 'NULL', None) test_case(test_enum, 'INVALID', INVALID) # nan is not equal to itself, needs a special test case test_case_expect_nan(test_enum, 'NAN') # Boolean! non_null_bool = GraphQLNonNull(GraphQLBoolean) # [Boolean] list_of_bool = GraphQLList(GraphQLBoolean) # [Boolean!] list_of_non_null_bool = GraphQLList(non_null_bool) # [Boolean]! non_null_list_of_bool = GraphQLNonNull(list_of_bool) # [Boolean!]! non_null_list_of_non_mull_bool = GraphQLNonNull(list_of_non_null_bool) def coerces_to_null_unless_non_null(): test_case(GraphQLBoolean, 'null', None) test_case(non_null_bool, 'null', INVALID) def coerces_lists_of_values(): test_case(list_of_bool, 'true', [True]) test_case(list_of_bool, '123', INVALID) test_case(list_of_bool, 'null', None) test_case(list_of_bool, '[true, false]', [True, False]) test_case(list_of_bool, '[true, 123]', INVALID) test_case(list_of_bool, '[true, null]', [True, None]) test_case(list_of_bool, '{ true: true }', INVALID) def coerces_non_null_lists_of_values(): test_case(non_null_list_of_bool, 'true', [True]) test_case(non_null_list_of_bool, '123', INVALID) test_case(non_null_list_of_bool, 'null', INVALID) test_case(non_null_list_of_bool, '[true, false]', [True, False]) test_case(non_null_list_of_bool, '[true, 123]', INVALID) test_case(non_null_list_of_bool, '[true, null]', [True, None]) def coerces_lists_of_non_null_values(): test_case(list_of_non_null_bool, 'true', [True]) test_case(list_of_non_null_bool, '123', INVALID) test_case(list_of_non_null_bool, 'null', None) test_case(list_of_non_null_bool, '[true, false]', [True, False]) test_case(list_of_non_null_bool, '[true, 123]', INVALID) test_case(list_of_non_null_bool, '[true, null]', INVALID) def coerces_non_null_lists_of_non_null_values(): test_case(non_null_list_of_non_mull_bool, 'true', [True]) test_case(non_null_list_of_non_mull_bool, '123', INVALID) test_case(non_null_list_of_non_mull_bool, 'null', INVALID) test_case(non_null_list_of_non_mull_bool, '[true, false]', [True, False]) test_case(non_null_list_of_non_mull_bool, '[true, 123]', INVALID) test_case(non_null_list_of_non_mull_bool, '[true, null]', INVALID) test_input_obj = GraphQLInputObjectType( 'TestInput', { 'int': GraphQLInputField(GraphQLInt, default_value=42), 'bool': GraphQLInputField(GraphQLBoolean), 'requiredBool': GraphQLInputField(non_null_bool) }) def coerces_input_objects_according_to_input_coercion_rules(): test_case(test_input_obj, 'null', None) test_case(test_input_obj, '123', INVALID) test_case(test_input_obj, '[]', INVALID) test_case(test_input_obj, '{ int: 123, requiredBool: false }', { 'int': 123, 'requiredBool': False, }) test_case(test_input_obj, '{ bool: true, requiredBool: false }', { 'int': 42, 'bool': True, 'requiredBool': False, }) test_case(test_input_obj, '{ int: true, requiredBool: true }', INVALID) test_case(test_input_obj, '{ requiredBool: null }', INVALID) test_case(test_input_obj, '{ bool: true }', INVALID) def accepts_variable_values_assuming_already_coerced(): test_case_with_vars({}, GraphQLBoolean, '$var', INVALID) test_case_with_vars({'var': True}, GraphQLBoolean, '$var', True) test_case_with_vars({'var': None}, GraphQLBoolean, '$var', None) def asserts_variables_are_provided_as_items_in_lists(): test_case_with_vars({}, list_of_bool, '[ $foo ]', [None]) test_case_with_vars({}, list_of_non_null_bool, '[ $foo ]', INVALID) test_case_with_vars({'foo': True}, list_of_non_null_bool, '[ $foo ]', [True]) # Note: variables are expected to have already been coerced, so we # do not expect the singleton wrapping behavior for variables. test_case_with_vars({'foo': True}, list_of_non_null_bool, '$foo', True) test_case_with_vars({'foo': [True]}, list_of_non_null_bool, '$foo', [True]) def omits_input_object_fields_for_unprovided_variables(): test_case_with_vars({}, test_input_obj, '{ int: $foo, bool: $foo, requiredBool: true }', { 'int': 42, 'requiredBool': True }) test_case_with_vars({}, test_input_obj, '{ requiredBool: $foo }', INVALID) test_case_with_vars({'foo': True}, test_input_obj, '{ requiredBool: $foo }', { 'int': 42, 'requiredBool': True })