1
- from math import inf , nan
2
1
from typing import Any , List
3
2
4
3
from graphql .error import INVALID
5
4
from graphql .type import (
6
5
GraphQLEnumType ,
7
6
GraphQLFloat ,
8
- GraphQLID ,
9
7
GraphQLInputField ,
10
8
GraphQLInputObjectType ,
11
9
GraphQLInt ,
12
10
GraphQLList ,
13
11
GraphQLNonNull ,
14
- GraphQLString ,
12
+ GraphQLScalarType ,
15
13
)
16
14
from graphql .utilities import coerce_value
17
15
from graphql .utilities .coerce_value import CoercedValue
@@ -22,146 +20,56 @@ def expect_value(result: CoercedValue) -> Any:
22
20
return result .value
23
21
24
22
25
- def expect_error (result : CoercedValue ) -> List [str ]:
23
+ def expect_errors (result : CoercedValue ) -> List [str ]:
26
24
errors = result .errors
27
25
messages = [error .message for error in errors ] if errors else []
28
26
assert result .value is INVALID
29
27
return messages
30
28
31
29
32
30
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 )
47
33
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 )
51
36
assert expect_value (result ) == 1
52
37
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. "
57
42
]
58
43
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."
75
48
]
76
49
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" )
83
57
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 )
89
59
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 )
117
62
assert expect_value (result ) == 1
118
63
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 )
135
66
assert expect_value (result ) is None
136
67
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"
165
73
]
166
74
167
75
def describe_for_graphql_enum ():
@@ -176,16 +84,18 @@ def returns_no_error_for_a_known_enum_name():
176
84
bar_result = coerce_value ("BAR" , TestEnum )
177
85
assert expect_value (bar_result ) == 123_456_789
178
86
179
- def results_error_for_misspelled_enum_value ():
87
+ def returns_an_error_for_misspelled_enum_value ():
180
88
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
+ ]
182
92
183
- def results_error_for_incorrect_value_type ():
93
+ def returns_an_error_for_incorrect_value_type ():
184
94
result1 = coerce_value (123 , TestEnum )
185
- assert expect_error (result1 ) == ["Expected type TestEnum." ]
95
+ assert expect_errors (result1 ) == ["Expected type TestEnum." ]
186
96
187
97
result2 = coerce_value ({"field" : "value" }, TestEnum )
188
- assert expect_error (result2 ) == ["Expected type TestEnum." ]
98
+ assert expect_errors (result2 ) == ["Expected type TestEnum." ]
189
99
190
100
def describe_for_graphql_input_object ():
191
101
TestInputObject = GraphQLInputObjectType (
@@ -202,20 +112,20 @@ def returns_no_error_for_a_valid_input():
202
112
203
113
def returns_an_error_for_a_non_dict_value ():
204
114
result = coerce_value (123 , TestInputObject )
205
- assert expect_error (result ) == [
115
+ assert expect_errors (result ) == [
206
116
"Expected type TestInputObject to be a dict."
207
117
]
208
118
209
119
def returns_an_error_for_an_invalid_field ():
210
120
result = coerce_value ({"foo" : "abc" }, TestInputObject )
211
- assert expect_error (result ) == [
121
+ assert expect_errors (result ) == [
212
122
"Expected type Int at value.foo."
213
123
" Int cannot represent non-integer value: 'abc'"
214
124
]
215
125
216
126
def returns_multiple_errors_for_multiple_invalid_fields ():
217
127
result = coerce_value ({"foo" : "abc" , "bar" : "def" }, TestInputObject )
218
- assert expect_error (result ) == [
128
+ assert expect_errors (result ) == [
219
129
"Expected type Int at value.foo."
220
130
" Int cannot represent non-integer value: 'abc'" ,
221
131
"Expected type Int at value.bar."
@@ -224,19 +134,19 @@ def returns_multiple_errors_for_multiple_invalid_fields():
224
134
225
135
def returns_error_for_a_missing_required_field ():
226
136
result = coerce_value ({"bar" : 123 }, TestInputObject )
227
- assert expect_error (result ) == [
137
+ assert expect_errors (result ) == [
228
138
"Field value.foo of required type Int! was not provided."
229
139
]
230
140
231
141
def returns_error_for_an_unknown_field ():
232
142
result = coerce_value ({"foo" : 123 , "unknownField" : 123 }, TestInputObject )
233
- assert expect_error (result ) == [
143
+ assert expect_errors (result ) == [
234
144
"Field 'unknownField' is not defined by type TestInputObject."
235
145
]
236
146
237
147
def returns_error_for_a_misspelled_field ():
238
148
result = coerce_value ({"foo" : 123 , "bart" : 123 }, TestInputObject )
239
- assert expect_error (result ) == [
149
+ assert expect_errors (result ) == [
240
150
"Field 'bart' is not defined by type TestInputObject."
241
151
" Did you mean bar?"
242
152
]
@@ -268,6 +178,25 @@ def transforms_values_with_out_type():
268
178
result = coerce_value ({"real" : 1 , "imag" : 2 }, ComplexInputObject )
269
179
assert expect_value (result ) == 1 + 2j
270
180
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
+
271
200
def describe_for_graphql_list ():
272
201
TestList = GraphQLList (GraphQLInt )
273
202
@@ -276,8 +205,8 @@ def returns_no_error_for_a_valid_input():
276
205
assert expect_value (result ) == [1 , 2 , 3 ]
277
206
278
207
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 ) == [
281
210
"Expected type Int at value[1]."
282
211
" Int cannot represent non-integer value: 'b'" ,
283
212
"Expected type Int at value[2]."
@@ -288,6 +217,12 @@ def returns_a_list_for_a_non_list_value():
288
217
result = coerce_value (42 , TestList )
289
218
assert expect_value (result ) == [42 ]
290
219
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
+
291
226
def returns_null_for_a_null_value ():
292
227
result = coerce_value (None , TestList )
293
228
assert expect_value (result ) is None
0 commit comments