1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace GraphQL\Tests\Validator; |
6
|
|
|
|
7
|
|
|
use GraphQL\Error\FormattedError; |
8
|
|
|
use GraphQL\Language\SourceLocation; |
9
|
|
|
use GraphQL\Validator\Rules\VariablesInAllowedPosition; |
10
|
|
|
|
11
|
|
|
class VariablesInAllowedPositionTest extends ValidatorTestCase |
12
|
|
|
{ |
13
|
|
|
// Validate: Variables are in allowed positions |
14
|
|
|
/** |
15
|
|
|
* @see it('Boolean => Boolean') |
16
|
|
|
*/ |
17
|
|
|
public function testBooleanXBoolean() : void |
18
|
|
|
{ |
19
|
|
|
// Boolean => Boolean |
20
|
|
|
$this->expectPassesRule( |
21
|
|
|
new VariablesInAllowedPosition(), |
22
|
|
|
' |
23
|
|
|
query Query($booleanArg: Boolean) |
24
|
|
|
{ |
25
|
|
|
complicatedArgs { |
26
|
|
|
booleanArgField(booleanArg: $booleanArg) |
27
|
|
|
} |
28
|
|
|
} |
29
|
|
|
' |
30
|
|
|
); |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* @see it('Boolean => Boolean within fragment') |
35
|
|
|
*/ |
36
|
|
|
public function testBooleanXBooleanWithinFragment() : void |
37
|
|
|
{ |
38
|
|
|
// Boolean => Boolean within fragment |
39
|
|
|
$this->expectPassesRule( |
40
|
|
|
new VariablesInAllowedPosition(), |
41
|
|
|
' |
42
|
|
|
fragment booleanArgFrag on ComplicatedArgs { |
43
|
|
|
booleanArgField(booleanArg: $booleanArg) |
44
|
|
|
} |
45
|
|
|
query Query($booleanArg: Boolean) |
46
|
|
|
{ |
47
|
|
|
complicatedArgs { |
48
|
|
|
...booleanArgFrag |
49
|
|
|
} |
50
|
|
|
} |
51
|
|
|
' |
52
|
|
|
); |
53
|
|
|
|
54
|
|
|
$this->expectPassesRule( |
55
|
|
|
new VariablesInAllowedPosition(), |
56
|
|
|
' |
57
|
|
|
query Query($booleanArg: Boolean) |
58
|
|
|
{ |
59
|
|
|
complicatedArgs { |
60
|
|
|
...booleanArgFrag |
61
|
|
|
} |
62
|
|
|
} |
63
|
|
|
fragment booleanArgFrag on ComplicatedArgs { |
64
|
|
|
booleanArgField(booleanArg: $booleanArg) |
65
|
|
|
} |
66
|
|
|
' |
67
|
|
|
); |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* @see it('Boolean! => Boolean') |
72
|
|
|
*/ |
73
|
|
|
public function testBooleanNonNullXBoolean() : void |
74
|
|
|
{ |
75
|
|
|
// Boolean! => Boolean |
76
|
|
|
$this->expectPassesRule( |
77
|
|
|
new VariablesInAllowedPosition(), |
78
|
|
|
' |
79
|
|
|
query Query($nonNullBooleanArg: Boolean!) |
80
|
|
|
{ |
81
|
|
|
complicatedArgs { |
82
|
|
|
booleanArgField(booleanArg: $nonNullBooleanArg) |
83
|
|
|
} |
84
|
|
|
} |
85
|
|
|
' |
86
|
|
|
); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* @see it('Boolean! => Boolean within fragment') |
91
|
|
|
*/ |
92
|
|
|
public function testBooleanNonNullXBooleanWithinFragment() : void |
93
|
|
|
{ |
94
|
|
|
// Boolean! => Boolean within fragment |
95
|
|
|
$this->expectPassesRule( |
96
|
|
|
new VariablesInAllowedPosition(), |
97
|
|
|
' |
98
|
|
|
fragment booleanArgFrag on ComplicatedArgs { |
99
|
|
|
booleanArgField(booleanArg: $nonNullBooleanArg) |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
query Query($nonNullBooleanArg: Boolean!) |
103
|
|
|
{ |
104
|
|
|
complicatedArgs { |
105
|
|
|
...booleanArgFrag |
106
|
|
|
} |
107
|
|
|
} |
108
|
|
|
' |
109
|
|
|
); |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* @see it('[String] => [String]') |
114
|
|
|
*/ |
115
|
|
|
public function testListOfStringXListOfString() : void |
116
|
|
|
{ |
117
|
|
|
$this->expectPassesRule( |
118
|
|
|
new VariablesInAllowedPosition(), |
119
|
|
|
' |
120
|
|
|
query Query($stringListVar: [String]) |
121
|
|
|
{ |
122
|
|
|
complicatedArgs { |
123
|
|
|
stringListArgField(stringListArg: $stringListVar) |
124
|
|
|
} |
125
|
|
|
} |
126
|
|
|
' |
127
|
|
|
); |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* @see it('[String!] => [String]') |
132
|
|
|
*/ |
133
|
|
|
public function testListOfStringNonNullXListOfString() : void |
134
|
|
|
{ |
135
|
|
|
$this->expectPassesRule( |
136
|
|
|
new VariablesInAllowedPosition(), |
137
|
|
|
' |
138
|
|
|
query Query($stringListVar: [String!]) |
139
|
|
|
{ |
140
|
|
|
complicatedArgs { |
141
|
|
|
stringListArgField(stringListArg: $stringListVar) |
142
|
|
|
} |
143
|
|
|
} |
144
|
|
|
' |
145
|
|
|
); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* @see it('String => [String] in item position') |
150
|
|
|
*/ |
151
|
|
|
public function testStringXListOfStringInItemPosition() : void |
152
|
|
|
{ |
153
|
|
|
$this->expectPassesRule( |
154
|
|
|
new VariablesInAllowedPosition(), |
155
|
|
|
' |
156
|
|
|
query Query($stringVar: String) |
157
|
|
|
{ |
158
|
|
|
complicatedArgs { |
159
|
|
|
stringListArgField(stringListArg: [$stringVar]) |
160
|
|
|
} |
161
|
|
|
} |
162
|
|
|
' |
163
|
|
|
); |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* @see it('String! => [String] in item position') |
168
|
|
|
*/ |
169
|
|
|
public function testStringNonNullXListOfStringInItemPosition() : void |
170
|
|
|
{ |
171
|
|
|
$this->expectPassesRule( |
172
|
|
|
new VariablesInAllowedPosition(), |
173
|
|
|
' |
174
|
|
|
query Query($stringVar: String!) |
175
|
|
|
{ |
176
|
|
|
complicatedArgs { |
177
|
|
|
stringListArgField(stringListArg: [$stringVar]) |
178
|
|
|
} |
179
|
|
|
} |
180
|
|
|
' |
181
|
|
|
); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* @see it('ComplexInput => ComplexInput') |
186
|
|
|
*/ |
187
|
|
|
public function testComplexInputXComplexInput() : void |
188
|
|
|
{ |
189
|
|
|
$this->expectPassesRule( |
190
|
|
|
new VariablesInAllowedPosition(), |
191
|
|
|
' |
192
|
|
|
query Query($complexVar: ComplexInput) |
193
|
|
|
{ |
194
|
|
|
complicatedArgs { |
195
|
|
|
complexArgField(complexArg: $ComplexInput) |
196
|
|
|
} |
197
|
|
|
} |
198
|
|
|
' |
199
|
|
|
); |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* @see it('ComplexInput => ComplexInput in field position') |
204
|
|
|
*/ |
205
|
|
|
public function testComplexInputXComplexInputInFieldPosition() : void |
206
|
|
|
{ |
207
|
|
|
$this->expectPassesRule( |
208
|
|
|
new VariablesInAllowedPosition(), |
209
|
|
|
' |
210
|
|
|
query Query($boolVar: Boolean = false) |
211
|
|
|
{ |
212
|
|
|
complicatedArgs { |
213
|
|
|
complexArgField(complexArg: {requiredArg: $boolVar}) |
214
|
|
|
} |
215
|
|
|
} |
216
|
|
|
' |
217
|
|
|
); |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
/** |
221
|
|
|
* @see it('Boolean! => Boolean! in directive') |
222
|
|
|
*/ |
223
|
|
|
public function testBooleanNonNullXBooleanNonNullInDirective() : void |
224
|
|
|
{ |
225
|
|
|
$this->expectPassesRule( |
226
|
|
|
new VariablesInAllowedPosition(), |
227
|
|
|
' |
228
|
|
|
query Query($boolVar: Boolean!) |
229
|
|
|
{ |
230
|
|
|
dog @include(if: $boolVar) |
231
|
|
|
} |
232
|
|
|
' |
233
|
|
|
); |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* @see it('Int => Int!') |
238
|
|
|
*/ |
239
|
|
|
public function testIntXIntNonNull() : void |
240
|
|
|
{ |
241
|
|
|
$this->expectFailsRule( |
242
|
|
|
new VariablesInAllowedPosition(), |
243
|
|
|
' |
244
|
|
|
query Query($intArg: Int) { |
245
|
|
|
complicatedArgs { |
246
|
|
|
nonNullIntArgField(nonNullIntArg: $intArg) |
247
|
|
|
} |
248
|
|
|
} |
249
|
|
|
', |
250
|
|
|
[ |
251
|
|
|
FormattedError::create( |
|
|
|
|
252
|
|
|
VariablesInAllowedPosition::badVarPosMessage('intArg', 'Int', 'Int!'), |
253
|
|
|
[new SourceLocation(2, 19), new SourceLocation(4, 45)] |
254
|
|
|
), |
255
|
|
|
] |
256
|
|
|
); |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* @see it('Int => Int! within fragment') |
261
|
|
|
*/ |
262
|
|
|
public function testIntXIntNonNullWithinFragment() : void |
263
|
|
|
{ |
264
|
|
|
$this->expectFailsRule( |
265
|
|
|
new VariablesInAllowedPosition(), |
266
|
|
|
' |
267
|
|
|
fragment nonNullIntArgFieldFrag on ComplicatedArgs { |
268
|
|
|
nonNullIntArgField(nonNullIntArg: $intArg) |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
query Query($intArg: Int) { |
272
|
|
|
complicatedArgs { |
273
|
|
|
...nonNullIntArgFieldFrag |
274
|
|
|
} |
275
|
|
|
} |
276
|
|
|
', |
277
|
|
|
[ |
278
|
|
|
FormattedError::create( |
|
|
|
|
279
|
|
|
VariablesInAllowedPosition::badVarPosMessage('intArg', 'Int', 'Int!'), |
280
|
|
|
[new SourceLocation(6, 19), new SourceLocation(3, 43)] |
281
|
|
|
), |
282
|
|
|
] |
283
|
|
|
); |
284
|
|
|
} |
285
|
|
|
|
286
|
|
|
/** |
287
|
|
|
* @see it('Int => Int! within nested fragment') |
288
|
|
|
*/ |
289
|
|
|
public function testIntXIntNonNullWithinNestedFragment() : void |
290
|
|
|
{ |
291
|
|
|
// Int => Int! within nested fragment |
292
|
|
|
$this->expectFailsRule( |
293
|
|
|
new VariablesInAllowedPosition(), |
294
|
|
|
' |
295
|
|
|
fragment outerFrag on ComplicatedArgs { |
296
|
|
|
...nonNullIntArgFieldFrag |
297
|
|
|
} |
298
|
|
|
|
299
|
|
|
fragment nonNullIntArgFieldFrag on ComplicatedArgs { |
300
|
|
|
nonNullIntArgField(nonNullIntArg: $intArg) |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
query Query($intArg: Int) |
304
|
|
|
{ |
305
|
|
|
complicatedArgs { |
306
|
|
|
...outerFrag |
307
|
|
|
} |
308
|
|
|
} |
309
|
|
|
', |
310
|
|
|
[ |
311
|
|
|
FormattedError::create( |
|
|
|
|
312
|
|
|
VariablesInAllowedPosition::badVarPosMessage('intArg', 'Int', 'Int!'), |
313
|
|
|
[new SourceLocation(10, 19), new SourceLocation(7, 43)] |
314
|
|
|
), |
315
|
|
|
] |
316
|
|
|
); |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
/** |
320
|
|
|
* @see it('String over Boolean') |
321
|
|
|
*/ |
322
|
|
|
public function testStringOverBoolean() : void |
323
|
|
|
{ |
324
|
|
|
$this->expectFailsRule( |
325
|
|
|
new VariablesInAllowedPosition(), |
326
|
|
|
' |
327
|
|
|
query Query($stringVar: String) { |
328
|
|
|
complicatedArgs { |
329
|
|
|
booleanArgField(booleanArg: $stringVar) |
330
|
|
|
} |
331
|
|
|
} |
332
|
|
|
', |
333
|
|
|
[ |
334
|
|
|
FormattedError::create( |
|
|
|
|
335
|
|
|
VariablesInAllowedPosition::badVarPosMessage('stringVar', 'String', 'Boolean'), |
336
|
|
|
[new SourceLocation(2, 19), new SourceLocation(4, 39)] |
337
|
|
|
), |
338
|
|
|
] |
339
|
|
|
); |
340
|
|
|
} |
341
|
|
|
|
342
|
|
|
/** |
343
|
|
|
* @see it('String => [String]') |
344
|
|
|
*/ |
345
|
|
|
public function testStringXListOfString() : void |
346
|
|
|
{ |
347
|
|
|
$this->expectFailsRule( |
348
|
|
|
new VariablesInAllowedPosition(), |
349
|
|
|
' |
350
|
|
|
query Query($stringVar: String) { |
351
|
|
|
complicatedArgs { |
352
|
|
|
stringListArgField(stringListArg: $stringVar) |
353
|
|
|
} |
354
|
|
|
} |
355
|
|
|
', |
356
|
|
|
[ |
357
|
|
|
FormattedError::create( |
|
|
|
|
358
|
|
|
VariablesInAllowedPosition::badVarPosMessage('stringVar', 'String', '[String]'), |
359
|
|
|
[new SourceLocation(2, 19), new SourceLocation(4, 45)] |
360
|
|
|
), |
361
|
|
|
] |
362
|
|
|
); |
363
|
|
|
} |
364
|
|
|
|
365
|
|
|
/** |
366
|
|
|
* @see it('Boolean => Boolean! in directive') |
367
|
|
|
*/ |
368
|
|
|
public function testBooleanXBooleanNonNullInDirective() : void |
369
|
|
|
{ |
370
|
|
|
$this->expectFailsRule( |
371
|
|
|
new VariablesInAllowedPosition(), |
372
|
|
|
' |
373
|
|
|
query Query($boolVar: Boolean) { |
374
|
|
|
dog @include(if: $boolVar) |
375
|
|
|
} |
376
|
|
|
', |
377
|
|
|
[ |
378
|
|
|
FormattedError::create( |
|
|
|
|
379
|
|
|
VariablesInAllowedPosition::badVarPosMessage('boolVar', 'Boolean', 'Boolean!'), |
380
|
|
|
[new SourceLocation(2, 19), new SourceLocation(3, 26)] |
381
|
|
|
), |
382
|
|
|
] |
383
|
|
|
); |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
/** |
387
|
|
|
* @see it('String => Boolean! in directive') |
388
|
|
|
*/ |
389
|
|
|
public function testStringXBooleanNonNullInDirective() : void |
390
|
|
|
{ |
391
|
|
|
// String => Boolean! in directive |
392
|
|
|
$this->expectFailsRule( |
393
|
|
|
new VariablesInAllowedPosition(), |
394
|
|
|
' |
395
|
|
|
query Query($stringVar: String) { |
396
|
|
|
dog @include(if: $stringVar) |
397
|
|
|
} |
398
|
|
|
', |
399
|
|
|
[ |
400
|
|
|
FormattedError::create( |
|
|
|
|
401
|
|
|
VariablesInAllowedPosition::badVarPosMessage('stringVar', 'String', 'Boolean!'), |
402
|
|
|
[new SourceLocation(2, 19), new SourceLocation(3, 26)] |
403
|
|
|
), |
404
|
|
|
] |
405
|
|
|
); |
406
|
|
|
} |
407
|
|
|
|
408
|
|
|
/** |
409
|
|
|
* @see it('[String] => [String!]') |
410
|
|
|
*/ |
411
|
|
|
public function testStringArrayXStringNonNullArray() : void |
412
|
|
|
{ |
413
|
|
|
$this->expectFailsRule( |
414
|
|
|
new VariablesInAllowedPosition(), |
415
|
|
|
' |
416
|
|
|
query Query($stringListVar: [String]) |
417
|
|
|
{ |
418
|
|
|
complicatedArgs { |
419
|
|
|
stringListNonNullArgField(stringListNonNullArg: $stringListVar) |
420
|
|
|
} |
421
|
|
|
} |
422
|
|
|
', |
423
|
|
|
[ |
424
|
|
|
FormattedError::create( |
|
|
|
|
425
|
|
|
VariablesInAllowedPosition::badVarPosMessage('stringListVar', '[String]', '[String!]'), |
426
|
|
|
[new SourceLocation(2, 19), new SourceLocation(5, 59)] |
427
|
|
|
), |
428
|
|
|
] |
429
|
|
|
); |
430
|
|
|
} |
431
|
|
|
|
432
|
|
|
// Allows optional (nullable) variables with default values |
433
|
|
|
|
434
|
|
|
/** |
435
|
|
|
* @see it('Int => Int! fails when variable provides null default value') |
436
|
|
|
*/ |
437
|
|
|
public function testIntXIntNonNullFailsWhenVariableProvidesNullDefaultValue() |
438
|
|
|
{ |
439
|
|
|
$this->expectFailsRule( |
440
|
|
|
new VariablesInAllowedPosition(), |
441
|
|
|
' |
442
|
|
|
query Query($intVar: Int = null) { |
443
|
|
|
complicatedArgs { |
444
|
|
|
nonNullIntArgField(nonNullIntArg: $intVar) |
445
|
|
|
} |
446
|
|
|
} |
447
|
|
|
', |
448
|
|
|
[FormattedError::create( |
|
|
|
|
449
|
|
|
VariablesInAllowedPosition::badVarPosMessage('intVar', 'Int', 'Int!'), |
450
|
|
|
[new SourceLocation(2, 21), new SourceLocation(4, 47)] |
451
|
|
|
), |
452
|
|
|
] |
453
|
|
|
); |
454
|
|
|
} |
455
|
|
|
|
456
|
|
|
/** |
457
|
|
|
* @see it('Int => Int! when variable provides non-null default value') |
458
|
|
|
*/ |
459
|
|
|
public function testIntXIntNonNullWhenVariableProvidesNonNullDefaultValue() |
460
|
|
|
{ |
461
|
|
|
$this->expectPassesRule( |
462
|
|
|
new VariablesInAllowedPosition(), |
463
|
|
|
' |
464
|
|
|
query Query($intVar: Int = 1) { |
465
|
|
|
complicatedArgs { |
466
|
|
|
nonNullIntArgField(nonNullIntArg: $intVar) |
467
|
|
|
} |
468
|
|
|
}' |
469
|
|
|
); |
470
|
|
|
} |
471
|
|
|
|
472
|
|
|
/** |
473
|
|
|
* @see it('Int => Int! when optional argument provides default value') |
474
|
|
|
*/ |
475
|
|
|
public function testIntXIntNonNullWhenOptionalArgumentProvidesDefaultValue() |
476
|
|
|
{ |
477
|
|
|
$this->expectPassesRule( |
478
|
|
|
new VariablesInAllowedPosition(), |
479
|
|
|
' |
480
|
|
|
query Query($intVar: Int) { |
481
|
|
|
complicatedArgs { |
482
|
|
|
nonNullFieldWithDefault(nonNullIntArg: $intVar) |
483
|
|
|
} |
484
|
|
|
}' |
485
|
|
|
); |
486
|
|
|
} |
487
|
|
|
|
488
|
|
|
/** |
489
|
|
|
* @see it('Boolean => Boolean! in directive with default value with option') |
490
|
|
|
*/ |
491
|
|
|
public function testBooleanXBooleanNonNullInDirectiveWithDefaultValueWithOption() |
492
|
|
|
{ |
493
|
|
|
$this->expectPassesRule( |
494
|
|
|
new VariablesInAllowedPosition(), |
495
|
|
|
' |
496
|
|
|
query Query($boolVar: Boolean = false) { |
497
|
|
|
dog @include(if: $boolVar) |
498
|
|
|
}' |
499
|
|
|
); |
500
|
|
|
} |
501
|
|
|
} |
502
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.