Skip to content

Commit c250717

Browse files
committed
test: Fully cover 'coerce_calue' function with tests
Replicates graphql/graphql-js@166317a
1 parent 7649646 commit c250717

File tree

2 files changed

+72
-137
lines changed

2 files changed

+72
-137
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ The current version 3.0.0a2 of GraphQL-core is up-to-date
1616
with GraphQL.js version 14.4.2.
1717

1818
All parts of the API are covered by an extensive test suite
19-
of currently 1917 unit tests.
19+
of currently 1903 unit tests.
2020

2121

2222
## Documentation

tests/utilities/test_coerce_value.py

Lines changed: 71 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
from math import inf, nan
21
from typing import Any, List
32

43
from graphql.error import INVALID
54
from graphql.type import (
65
GraphQLEnumType,
76
GraphQLFloat,
8-
GraphQLID,
97
GraphQLInputField,
108
GraphQLInputObjectType,
119
GraphQLInt,
1210
GraphQLList,
1311
GraphQLNonNull,
14-
GraphQLString,
12+
GraphQLScalarType,
1513
)
1614
from graphql.utilities import coerce_value
1715
from graphql.utilities.coerce_value import CoercedValue
@@ -22,146 +20,56 @@ def expect_value(result: CoercedValue) -> Any:
2220
return result.value
2321

2422

25-
def expect_error(result: CoercedValue) -> List[str]:
23+
def expect_errors(result: CoercedValue) -> List[str]:
2624
errors = result.errors
2725
messages = [error.message for error in errors] if errors else []
2826
assert result.value is INVALID
2927
return messages
3028

3129

3230
def describe_coerce_value():
33-
def describe_for_graphql_string():
34-
def returns_error_for_array_input_as_string():
35-
result = coerce_value([1, 2, 3], GraphQLString)
36-
assert expect_error(result) == [
37-
f"Expected type String."
38-
" String cannot represent a non string value: [1, 2, 3]"
39-
]
40-
41-
def describe_for_graphql_id():
42-
def returns_error_for_array_input_as_string():
43-
result = coerce_value([1, 2, 3], GraphQLID)
44-
assert expect_error(result) == [
45-
f"Expected type ID. ID cannot represent value: [1, 2, 3]"
46-
]
31+
def describe_for_graphql_non_null():
32+
TestNonNull = GraphQLNonNull(GraphQLInt)
4733

48-
def describe_for_graphql_int():
49-
def returns_value_for_integer():
50-
result = coerce_value(1, GraphQLInt)
34+
def returns_non_error_for_non_null_value():
35+
result = coerce_value(1, TestNonNull)
5136
assert expect_value(result) == 1
5237

53-
def returns_no_error_for_numeric_looking_string():
54-
result = coerce_value("1", GraphQLInt)
55-
assert expect_error(result) == [
56-
f"Expected type Int. Int cannot represent non-integer value: '1'"
38+
def returns_an_error_for_undefined_value():
39+
result = coerce_value(INVALID, TestNonNull)
40+
assert expect_errors(result) == [
41+
"Expected non-nullable type Int! not to be null."
5742
]
5843

59-
def returns_value_for_negative_int_input():
60-
result = coerce_value(-1, GraphQLInt)
61-
assert expect_value(result) == -1
62-
63-
def returns_value_for_exponent_input():
64-
result = coerce_value(1e3, GraphQLInt)
65-
assert expect_value(result) == 1000
66-
67-
def returns_null_for_null_value():
68-
result = coerce_value(None, GraphQLInt)
69-
assert expect_value(result) is None
70-
71-
def returns_a_single_error_for_empty_string_as_value():
72-
result = coerce_value("", GraphQLInt)
73-
assert expect_error(result) == [
74-
"Expected type Int. Int cannot represent non-integer value: ''"
44+
def returns_an_error_for_null_value():
45+
result = coerce_value(None, TestNonNull)
46+
assert expect_errors(result) == [
47+
"Expected non-nullable type Int! not to be null."
7548
]
7649

77-
def returns_a_single_error_for_2_32_input_as_int():
78-
result = coerce_value(1 << 32, GraphQLInt)
79-
assert expect_error(result) == [
80-
"Expected type Int. Int cannot represent"
81-
" non 32-bit signed integer value: 4294967296"
82-
]
50+
def describe_for_graphql_scalar():
51+
def _parse_value(input_dict):
52+
assert isinstance(input_dict, dict)
53+
error = input_dict.get("error")
54+
if error:
55+
raise error
56+
return input_dict.get("value")
8357

84-
def returns_a_single_error_for_float_input_as_int():
85-
result = coerce_value(1.5, GraphQLInt)
86-
assert expect_error(result) == [
87-
"Expected type Int. Int cannot represent non-integer value: 1.5"
88-
]
58+
TestScalar = GraphQLScalarType("TestScalar", parse_value=_parse_value)
8959

90-
def returns_a_single_error_for_nan_input_as_int():
91-
result = coerce_value(nan, GraphQLInt)
92-
assert expect_error(result) == [
93-
"Expected type Int. Int cannot represent non-integer value: nan"
94-
]
95-
96-
def returns_a_single_error_for_infinity_input_as_int():
97-
result = coerce_value(inf, GraphQLInt)
98-
assert expect_error(result) == [
99-
"Expected type Int. Int cannot represent non-integer value: inf"
100-
]
101-
102-
def returns_a_single_error_for_char_input():
103-
result = coerce_value("a", GraphQLInt)
104-
assert expect_error(result) == [
105-
"Expected type Int. Int cannot represent non-integer value: 'a'"
106-
]
107-
108-
def returns_a_single_error_for_string_input():
109-
result = coerce_value("meow", GraphQLInt)
110-
assert expect_error(result) == [
111-
"Expected type Int. Int cannot represent non-integer value: 'meow'"
112-
]
113-
114-
def describe_for_graphql_float():
115-
def returns_value_for_integer():
116-
result = coerce_value(1, GraphQLFloat)
60+
def returns_no_error_for_valid_input():
61+
result = coerce_value({"value": 1}, TestScalar)
11762
assert expect_value(result) == 1
11863

119-
def returns_value_for_decimal():
120-
result = coerce_value(1.1, GraphQLFloat)
121-
assert expect_value(result) == 1.1
122-
123-
def returns_no_error_for_exponent_input():
124-
result = coerce_value(1e3, GraphQLFloat)
125-
assert expect_value(result) == 1000
126-
127-
def returns_error_for_numeric_looking_string():
128-
result = coerce_value("1", GraphQLFloat)
129-
assert expect_error(result) == [
130-
"Expected type Float. Float cannot represent non numeric value: '1'"
131-
]
132-
133-
def returns_null_for_null_value():
134-
result = coerce_value(None, GraphQLFloat)
64+
def returns_no_error_for_null_result():
65+
result = coerce_value({"value": None}, TestScalar)
13566
assert expect_value(result) is None
13667

137-
def returns_a_single_error_for_empty_string_input():
138-
result = coerce_value("", GraphQLFloat)
139-
assert expect_error(result) == [
140-
"Expected type Float. Float cannot represent non numeric value: ''"
141-
]
142-
143-
def returns_a_single_error_for_nan_input():
144-
result = coerce_value(nan, GraphQLFloat)
145-
assert expect_error(result) == [
146-
"Expected type Float. Float cannot represent non numeric value: nan"
147-
]
148-
149-
def returns_a_single_error_for_infinity_input():
150-
result = coerce_value(inf, GraphQLFloat)
151-
assert expect_error(result) == [
152-
"Expected type Float. Float cannot represent non numeric value: inf"
153-
]
154-
155-
def returns_a_single_error_for_char_input():
156-
result = coerce_value("a", GraphQLFloat)
157-
assert expect_error(result) == [
158-
"Expected type Float. Float cannot represent non numeric value: 'a'"
159-
]
160-
161-
def returns_a_single_error_for_string_input():
162-
result = coerce_value("meow", GraphQLFloat)
163-
assert expect_error(result) == [
164-
"Expected type Float. Float cannot represent non numeric value: 'meow'"
68+
def returns_an_error_for_undefined_result():
69+
error = ValueError("Some error message")
70+
result = coerce_value({"error": error}, TestScalar)
71+
assert expect_errors(result) == [
72+
"Expected type TestScalar. Some error message"
16573
]
16674

16775
def describe_for_graphql_enum():
@@ -176,16 +84,18 @@ def returns_no_error_for_a_known_enum_name():
17684
bar_result = coerce_value("BAR", TestEnum)
17785
assert expect_value(bar_result) == 123_456_789
17886

179-
def results_error_for_misspelled_enum_value():
87+
def returns_an_error_for_misspelled_enum_value():
18088
result = coerce_value("foo", TestEnum)
181-
assert expect_error(result) == ["Expected type TestEnum. Did you mean FOO?"]
89+
assert expect_errors(result) == [
90+
"Expected type TestEnum. Did you mean FOO?"
91+
]
18292

183-
def results_error_for_incorrect_value_type():
93+
def returns_an_error_for_incorrect_value_type():
18494
result1 = coerce_value(123, TestEnum)
185-
assert expect_error(result1) == ["Expected type TestEnum."]
95+
assert expect_errors(result1) == ["Expected type TestEnum."]
18696

18797
result2 = coerce_value({"field": "value"}, TestEnum)
188-
assert expect_error(result2) == ["Expected type TestEnum."]
98+
assert expect_errors(result2) == ["Expected type TestEnum."]
18999

190100
def describe_for_graphql_input_object():
191101
TestInputObject = GraphQLInputObjectType(
@@ -202,20 +112,20 @@ def returns_no_error_for_a_valid_input():
202112

203113
def returns_an_error_for_a_non_dict_value():
204114
result = coerce_value(123, TestInputObject)
205-
assert expect_error(result) == [
115+
assert expect_errors(result) == [
206116
"Expected type TestInputObject to be a dict."
207117
]
208118

209119
def returns_an_error_for_an_invalid_field():
210120
result = coerce_value({"foo": "abc"}, TestInputObject)
211-
assert expect_error(result) == [
121+
assert expect_errors(result) == [
212122
"Expected type Int at value.foo."
213123
" Int cannot represent non-integer value: 'abc'"
214124
]
215125

216126
def returns_multiple_errors_for_multiple_invalid_fields():
217127
result = coerce_value({"foo": "abc", "bar": "def"}, TestInputObject)
218-
assert expect_error(result) == [
128+
assert expect_errors(result) == [
219129
"Expected type Int at value.foo."
220130
" Int cannot represent non-integer value: 'abc'",
221131
"Expected type Int at value.bar."
@@ -224,19 +134,19 @@ def returns_multiple_errors_for_multiple_invalid_fields():
224134

225135
def returns_error_for_a_missing_required_field():
226136
result = coerce_value({"bar": 123}, TestInputObject)
227-
assert expect_error(result) == [
137+
assert expect_errors(result) == [
228138
"Field value.foo of required type Int! was not provided."
229139
]
230140

231141
def returns_error_for_an_unknown_field():
232142
result = coerce_value({"foo": 123, "unknownField": 123}, TestInputObject)
233-
assert expect_error(result) == [
143+
assert expect_errors(result) == [
234144
"Field 'unknownField' is not defined by type TestInputObject."
235145
]
236146

237147
def returns_error_for_a_misspelled_field():
238148
result = coerce_value({"foo": 123, "bart": 123}, TestInputObject)
239-
assert expect_error(result) == [
149+
assert expect_errors(result) == [
240150
"Field 'bart' is not defined by type TestInputObject."
241151
" Did you mean bar?"
242152
]
@@ -268,6 +178,25 @@ def transforms_values_with_out_type():
268178
result = coerce_value({"real": 1, "imag": 2}, ComplexInputObject)
269179
assert expect_value(result) == 1 + 2j
270180

181+
def describe_for_graphql_input_object_with_default_value():
182+
def _get_test_input_object(default_value):
183+
return GraphQLInputObjectType(
184+
"TestInputObject",
185+
{"foo": GraphQLInputField(GraphQLInt, default_value=default_value)},
186+
)
187+
188+
def returns_no_errors_for_valid_input_value():
189+
result = coerce_value({"foo": 5}, _get_test_input_object(7))
190+
assert expect_value(result) == {"foo": 5}
191+
192+
def returns_object_with_default_value():
193+
result = coerce_value({}, _get_test_input_object(7))
194+
assert expect_value(result) == {"foo": 7}
195+
196+
def returns_null_as_value():
197+
result = coerce_value({}, _get_test_input_object(None))
198+
assert expect_value(result) == {"foo": None}
199+
271200
def describe_for_graphql_list():
272201
TestList = GraphQLList(GraphQLInt)
273202

@@ -276,8 +205,8 @@ def returns_no_error_for_a_valid_input():
276205
assert expect_value(result) == [1, 2, 3]
277206

278207
def returns_an_error_for_an_invalid_input():
279-
result = coerce_value([1, "b", True], TestList)
280-
assert expect_error(result) == [
208+
result = coerce_value([1, "b", True, 4], TestList)
209+
assert expect_errors(result) == [
281210
"Expected type Int at value[1]."
282211
" Int cannot represent non-integer value: 'b'",
283212
"Expected type Int at value[2]."
@@ -288,6 +217,12 @@ def returns_a_list_for_a_non_list_value():
288217
result = coerce_value(42, TestList)
289218
assert expect_value(result) == [42]
290219

220+
def returns_a_list_for_a_non_list_invalid_value():
221+
result = coerce_value("INVALID", TestList)
222+
assert expect_errors(result) == [
223+
"Expected type Int. Int cannot represent non-integer value: 'INVALID'"
224+
]
225+
291226
def returns_null_for_a_null_value():
292227
result = coerce_value(None, TestList)
293228
assert expect_value(result) is None

0 commit comments

Comments
 (0)