Skip to content

Commit ad0e857

Browse files
authored
Merge pull request #163 from jkimbo/update-enum-tests
Update enum tests
2 parents 1ab1c04 + 373aeca commit ad0e857

File tree

4 files changed

+109
-27
lines changed

4 files changed

+109
-27
lines changed

graphql/execution/executor.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -465,10 +465,15 @@ def complete_leaf_value(return_type, result):
465465
"""
466466
Complete a Scalar or Enum by serializing to a valid value, returning null if serialization is not possible.
467467
"""
468-
# serialize = getattr(return_type, 'serialize', None)
469-
# assert serialize, 'Missing serialize method on type'
468+
assert hasattr(return_type, 'serialize'), 'Missing serialize method on type'
469+
serialized_result = return_type.serialize(result)
470470

471-
return return_type.serialize(result)
471+
if serialized_result is None:
472+
raise GraphQLError(
473+
('Expected a value of type "{}" but ' +
474+
'received: {}').format(return_type, result)
475+
)
476+
return serialized_result
472477

473478

474479
def complete_abstract_value(exe_context, return_type, field_asts, info, result):

graphql/type/definition.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,12 @@ def __init__(self, name, values, description=None):
414414

415415
self.values = define_enum_values(self, values)
416416

417+
def get_values(self):
418+
return self.values
419+
420+
def get_value(self, name):
421+
return self._name_lookup.get(name)
422+
417423
def serialize(self, value):
418424
if isinstance(value, collections.Hashable):
419425
enum_value = self._value_lookup.get(value)
@@ -464,23 +470,32 @@ def define_enum_values(type, value_map):
464470
)
465471
value = copy.copy(value)
466472
value.name = value_name
467-
if value.value is None:
473+
if value.value == Undefined:
468474
value.value = value_name
469475

470476
values.append(value)
471477

472478
return values
473479

474480

481+
class Undefined(object):
482+
"""A representation of an Undefined value distinct from a None value"""
483+
pass
484+
485+
475486
class GraphQLEnumValue(object):
476487
__slots__ = 'name', 'value', 'deprecation_reason', 'description'
477488

478-
def __init__(self, value=None, deprecation_reason=None, description=None, name=None):
489+
def __init__(self, value=Undefined, deprecation_reason=None, description=None, name=None):
479490
self.name = name
480491
self.value = value
481492
self.deprecation_reason = deprecation_reason
482493
self.description = description
483494

495+
@property
496+
def is_deprecated(self):
497+
return bool(self.deprecation_reason)
498+
484499
def __eq__(self, other):
485500
return (
486501
self is other or (

graphql/type/tests/test_definition.py

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,31 @@ def test_defines_a_subscription_schema():
118118
# assert subscription.name == 'articleSubscribe'
119119

120120

121+
def test_defines_an_enum_type_with_deprecated_value():
122+
EnumTypeWithDeprecatedValue = GraphQLEnumType('EnumWithDeprecatedValue', {
123+
'foo': GraphQLEnumValue(deprecation_reason='Just because'),
124+
})
125+
value = EnumTypeWithDeprecatedValue.get_values()[0]
126+
assert value.name == 'foo'
127+
assert value.description is None
128+
assert value.is_deprecated is True
129+
assert value.deprecation_reason == 'Just because'
130+
assert value.value == 'foo'
131+
132+
133+
def test_defines_an_enum_type_with_a_value_of_none():
134+
EnumTypeWithNoneValue = GraphQLEnumType('EnumWithNullishValue', {
135+
'NULL': GraphQLEnumValue(None),
136+
})
137+
138+
value = EnumTypeWithNoneValue.get_values()[0]
139+
assert value.name == 'NULL'
140+
assert value.description is None
141+
assert value.is_deprecated is False
142+
assert value.deprecation_reason is None
143+
assert value.value is None
144+
145+
121146
def test_defines_an_object_type_with_deprecated_field():
122147
TypeWithDeprecatedField = GraphQLObjectType('foo', fields={
123148
'bar': GraphQLField(
@@ -178,6 +203,23 @@ def test_includes_nested_input_objects_in_the_map():
178203
assert schema.get_type_map()['NestedInputObject'] is NestedInputObject
179204

180205

206+
def test_includes_interface_possible_types_in_the_type_map():
207+
SomeInterface = GraphQLInterfaceType('SomeInterface', fields={'f': GraphQLField(GraphQLInt)})
208+
SomeSubtype = GraphQLObjectType(
209+
name='SomeSubtype',
210+
fields={'f': GraphQLField(GraphQLInt)},
211+
interfaces=[SomeInterface],
212+
is_type_of=lambda: None
213+
)
214+
schema = GraphQLSchema(
215+
query=GraphQLObjectType(
216+
name='Query',
217+
fields={
218+
'iface': GraphQLField(SomeInterface)}),
219+
types=[SomeSubtype])
220+
assert schema.get_type_map()['SomeSubtype'] == SomeSubtype
221+
222+
181223
def test_includes_interfaces_thunk_subtypes_in_the_type_map():
182224
SomeInterface = GraphQLInterfaceType(
183225
name='SomeInterface',
@@ -205,23 +247,6 @@ def test_includes_interfaces_thunk_subtypes_in_the_type_map():
205247
assert schema.get_type_map()['SomeSubtype'] is SomeSubtype
206248

207249

208-
def test_includes_interfaces_subtypes_in_the_type_map():
209-
SomeInterface = GraphQLInterfaceType('SomeInterface', fields={'f': GraphQLField(GraphQLInt)})
210-
SomeSubtype = GraphQLObjectType(
211-
name='SomeSubtype',
212-
fields={'f': GraphQLField(GraphQLInt)},
213-
interfaces=[SomeInterface],
214-
is_type_of=lambda: None
215-
)
216-
schema = GraphQLSchema(
217-
query=GraphQLObjectType(
218-
name='Query',
219-
fields={
220-
'iface': GraphQLField(SomeInterface)}),
221-
types=[SomeSubtype])
222-
assert schema.get_type_map()['SomeSubtype'] == SomeSubtype
223-
224-
225250
def test_stringifies_simple_types():
226251
assert str(GraphQLInt) == 'Int'
227252
assert str(BlogArticle) == 'Article'

graphql/type/tests/test_enum_type.py

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from collections import OrderedDict
22

33
from rx import Observable
4-
from pytest import raises
54

65
from graphql import graphql
76
from graphql.type import (GraphQLArgument, GraphQLEnumType, GraphQLEnumValue,
@@ -114,13 +113,28 @@ def test_does_not_accept_string_literals():
114113
'Expected type "Color", found "GREEN".'
115114

116115

116+
def test_does_not_accept_values_not_in_the_enum():
117+
result = graphql(Schema, '{ colorEnum(fromEnum: GREENISH) }')
118+
assert not result.data
119+
assert result.errors[0].message == 'Argument "fromEnum" has invalid value GREENISH.\n' \
120+
'Expected type "Color", found GREENISH.'
121+
122+
123+
def test_does_not_accept_values_with_incorrect_casing():
124+
result = graphql(Schema, '{ colorEnum(fromEnum: green) }')
125+
assert not result.data
126+
assert result.errors[0].message == 'Argument "fromEnum" has invalid value green.\n' \
127+
'Expected type "Color", found green.'
128+
129+
117130
def test_does_not_accept_incorrect_internal_value():
118131
result = graphql(Schema, '{ colorEnum(fromString: "GREEN") }')
119132
assert result.data == {'colorEnum': None}
120-
assert not result.errors
133+
assert result.errors[0].message == 'Expected a value of type "Color" ' \
134+
'but received: GREEN'
121135

122136

123-
def test_does_not_accept_internal_value_in_placeof_enum_literal():
137+
def test_does_not_accept_internal_value_in_place_of_enum_literal():
124138
result = graphql(Schema, '{ colorEnum(fromEnum: 1) }')
125139
assert not result.data
126140
assert result.errors[0].message == 'Argument "fromEnum" has invalid value 1.\n' \
@@ -135,8 +149,11 @@ def test_does_not_accept_enum_literal_in_place_of_int():
135149

136150

137151
def test_accepts_json_string_as_enum_variable():
138-
result = graphql(Schema, 'query test($color: Color!) { colorEnum(fromEnum: $color) }', variable_values={
139-
'color': 'BLUE'})
152+
result = graphql(
153+
Schema,
154+
'query test($color: Color!) { colorEnum(fromEnum: $color) }',
155+
variable_values={'color': 'BLUE'}
156+
)
140157
assert not result.errors
141158
assert result.data == {'colorEnum': 'BLUE'}
142159

@@ -195,6 +212,26 @@ def test_enum_inputs_may_be_nullable():
195212
assert result.data == {'colorEnum': None, 'colorInt': None}
196213

197214

215+
def test_presents_a_get_values_api():
216+
values = ColorType.get_values()
217+
assert len(values) == 3
218+
assert values[0].name == 'RED'
219+
assert values[0].value == 0
220+
assert values[1].name == 'GREEN'
221+
assert values[1].value == 1
222+
assert values[2].name == 'BLUE'
223+
assert values[2].value == 2
224+
225+
226+
def test_presents_a_get_value_api():
227+
oneValue = ColorType.get_value('RED')
228+
assert oneValue.name == 'RED'
229+
assert oneValue.value == 0
230+
231+
badUsage = ColorType.get_value(0)
232+
assert badUsage is None
233+
234+
198235
def test_sorts_values_if_not_using_ordered_dict():
199236
enum = GraphQLEnumType(name='Test', values={
200237
'c': GraphQLEnumValue(),

0 commit comments

Comments
 (0)