Failed Conditions
Push — master ( 48b44f...392b56 )
by Vladimir
04:42
created

ValidatorTestCase::getTestSchema()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 370
Code Lines 256

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 256
dl 0
loc 370
rs 8
c 0
b 0
f 0
cc 1
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace GraphQL\Tests\Validator;
3
4
use GraphQL\Language\Parser;
5
use GraphQL\Type\Schema;
6
use GraphQL\Type\Definition\CustomScalarType;
7
use GraphQL\Type\Definition\Directive;
8
use GraphQL\Type\Definition\EnumType;
9
use GraphQL\Type\Definition\InputObjectType;
10
use GraphQL\Type\Definition\InterfaceType;
11
use GraphQL\Type\Definition\ObjectType;
12
use GraphQL\Type\Definition\Type;
13
use GraphQL\Type\Definition\UnionType;
14
use GraphQL\Validator\DocumentValidator;
15
use PHPUnit\Framework\TestCase;
16
17
abstract class ValidatorTestCase extends TestCase
18
{
19
    /**
20
     * @return Schema
21
     */
22
    public static function getTestSchema()
23
    {
24
        $FurColor = null;
25
26
        $Being = new InterfaceType([
27
            'name' => 'Being',
28
            'fields' => [
29
                'name' => [
30
                    'type' => Type::string(),
31
                    'args' => [ 'surname' => [ 'type' => Type::boolean() ] ]
32
                ]
33
            ],
34
        ]);
35
36
        $Pet = new InterfaceType([
37
            'name' => 'Pet',
38
            'fields' => [
39
                'name' => [
40
                    'type' => Type::string(),
41
                    'args' => [ 'surname' => [ 'type' => Type::boolean() ] ]
42
                ]
43
            ],
44
        ]);
45
46
        $Canine = new InterfaceType([
47
            'name' => 'Canine',
48
            'fields' => function() {
49
                return [
50
                    'name' => [
51
                        'type' => Type::string(),
52
                        'args' => ['surname' => ['type' => Type::boolean()]]
53
                    ]
54
                ];
55
            }
56
        ]);
57
58
        $DogCommand = new EnumType([
59
            'name' => 'DogCommand',
60
            'values' => [
61
                'SIT' => ['value' => 0],
62
                'HEEL' => ['value' => 1],
63
                'DOWN' => ['value' => 2]
64
            ]
65
        ]);
66
67
        $Dog = new ObjectType([
68
            'name' => 'Dog',
69
            'fields' => [
70
                'name' => [
71
                    'type' => Type::string(),
72
                    'args' => [ 'surname' => [ 'type' => Type::boolean() ] ]
73
                ],
74
                'nickname' => ['type' => Type::string()],
75
                'barkVolume' => ['type' => Type::int()],
76
                'barks' => ['type' => Type::boolean()],
77
                'doesKnowCommand' => [
78
                    'type' => Type::boolean(),
79
                    'args' => ['dogCommand' => ['type' => $DogCommand]]
80
                ],
81
                'isHousetrained' => [
82
                    'type' => Type::boolean(),
83
                    'args' => ['atOtherHomes' => ['type' => Type::boolean(), 'defaultValue' => true]]
84
                ],
85
                'isAtLocation' => [
86
                    'type' => Type::boolean(),
87
                    'args' => ['x' => ['type' => Type::int()], 'y' => ['type' => Type::int()]]
88
                ]
89
            ],
90
            'interfaces' => [$Being, $Pet, $Canine]
91
        ]);
92
93
        $Cat = new ObjectType([
94
            'name' => 'Cat',
95
            'fields' => function() use (&$FurColor) {
96
                return [
97
                    'name' => [
98
                        'type' => Type::string(),
99
                        'args' => [ 'surname' => [ 'type' => Type::boolean() ] ]
100
                    ],
101
                    'nickname' => ['type' => Type::string()],
102
                    'meows' => ['type' => Type::boolean()],
103
                    'meowVolume' => ['type' => Type::int()],
104
                    'furColor' => $FurColor
105
                ];
106
            },
107
            'interfaces' => [$Being, $Pet]
108
        ]);
109
110
        $CatOrDog = new UnionType([
111
            'name' => 'CatOrDog',
112
            'types' => [$Dog, $Cat],
113
        ]);
114
115
        $Intelligent = new InterfaceType([
116
            'name' => 'Intelligent',
117
            'fields' => [
118
                'iq' => ['type' => Type::int()]
119
            ]
120
        ]);
121
122
        $Human = null;
123
        $Human = new ObjectType([
124
            'name' => 'Human',
125
            'interfaces' => [$Being, $Intelligent],
126
            'fields' => function() use (&$Human, $Pet) {
127
                return [
128
                    'name' => [
129
                        'type' => Type::string(),
130
                        'args' => ['surname' => ['type' => Type::boolean()]]
131
                    ],
132
                    'pets' => ['type' => Type::listOf($Pet)],
133
                    'relatives' => ['type' => Type::listOf($Human)],
134
                    'iq' => ['type' => Type::int()]
135
                ];
136
            }
137
        ]);
138
139
        $Alien = new ObjectType([
140
            'name' => 'Alien',
141
            'interfaces' => [$Being, $Intelligent],
142
            'fields' => [
143
                'iq' => ['type' => Type::int()],
144
                'name' => [
145
                    'type' => Type::string(),
146
                    'args' => ['surname' => ['type' => Type::boolean()]]
147
                ],
148
                'numEyes' => ['type' => Type::int()]
149
            ]
150
        ]);
151
152
        $DogOrHuman = new UnionType([
153
            'name' => 'DogOrHuman',
154
            'types' => [$Dog, $Human],
155
        ]);
156
157
        $HumanOrAlien = new UnionType([
158
            'name' => 'HumanOrAlien',
159
            'types' => [$Human, $Alien],
160
        ]);
161
162
        $FurColor = new EnumType([
163
            'name' => 'FurColor',
164
            'values' => [
165
                'BROWN' => [ 'value' => 0 ],
166
                'BLACK' => [ 'value' => 1 ],
167
                'TAN' => [ 'value' => 2 ],
168
                'SPOTTED' => [ 'value' => 3 ],
169
                'NO_FUR' => [ 'value' => null ],
170
            ],
171
        ]);
172
173
        $ComplexInput = new InputObjectType([
174
            'name' => 'ComplexInput',
175
            'fields' => [
176
                'requiredField' => ['type' => Type::nonNull(Type::boolean())],
177
                'intField' => ['type' => Type::int()],
178
                'stringField' => ['type' => Type::string()],
179
                'booleanField' => ['type' => Type::boolean()],
180
                'stringListField' => ['type' => Type::listOf(Type::string())]
181
            ]
182
        ]);
183
184
        $ComplicatedArgs = new ObjectType([
185
            'name' => 'ComplicatedArgs',
186
            // TODO List
187
            // TODO Coercion
188
            // TODO NotNulls
189
            'fields' => [
190
                'intArgField' => [
191
                    'type' => Type::string(),
192
                    'args' => ['intArg' => ['type' => Type::int()]],
193
                ],
194
                'nonNullIntArgField' => [
195
                    'type' => Type::string(),
196
                    'args' => [ 'nonNullIntArg' => [ 'type' => Type::nonNull(Type::int())]],
197
                ],
198
                'stringArgField' => [
199
                    'type' => Type::string(),
200
                    'args' => [ 'stringArg' => [ 'type' => Type::string()]],
201
                ],
202
                'booleanArgField' => [
203
                    'type' => Type::string(),
204
                    'args' => ['booleanArg' => [ 'type' => Type::boolean() ]],
205
                ],
206
                'enumArgField' => [
207
                    'type' => Type::string(),
208
                    'args' => [ 'enumArg' => ['type' => $FurColor ]],
209
                ],
210
                'floatArgField' => [
211
                    'type' => Type::string(),
212
                    'args' => [ 'floatArg' => [ 'type' => Type::float()]],
213
                ],
214
                'idArgField' => [
215
                    'type' => Type::string(),
216
                    'args' => [ 'idArg' => [ 'type' => Type::id() ]],
217
                ],
218
                'stringListArgField' => [
219
                    'type' => Type::string(),
220
                    'args' => [ 'stringListArg' => [ 'type' => Type::listOf(Type::string())]],
221
                ],
222
                'complexArgField' => [
223
                    'type' => Type::string(),
224
                    'args' => [ 'complexArg' => [ 'type' => $ComplexInput ]],
225
                ],
226
                'multipleReqs' => [
227
                    'type' => Type::string(),
228
                    'args' => [
229
                        'req1' => [ 'type' => Type::nonNull(Type::int())],
230
                        'req2' => [ 'type' => Type::nonNull(Type::int())],
231
                    ],
232
                ],
233
                'multipleOpts' => [
234
                    'type' => Type::string(),
235
                    'args' => [
236
                        'opt1' => [
237
                            'type' => Type::int(),
238
                            'defaultValue' => 0,
239
                        ],
240
                        'opt2' => [
241
                            'type' => Type::int(),
242
                            'defaultValue' => 0,
243
                        ],
244
                    ],
245
                ],
246
                'multipleOptAndReq' => [
247
                    'type' => Type::string(),
248
                    'args' => [
249
                        'req1' => [ 'type' => Type::nonNull(Type::int())],
250
                        'req2' => [ 'type' => Type::nonNull(Type::int())],
251
                        'opt1' => [
252
                            'type' => Type::int(),
253
                            'defaultValue' => 0,
254
                        ],
255
                        'opt2' => [
256
                            'type' => Type::int(),
257
                            'defaultValue' => 0,
258
                        ],
259
                    ],
260
                ],
261
            ]
262
        ]);
263
264
        $invalidScalar = new CustomScalarType([
265
            'name' => 'Invalid',
266
            'serialize' => function ($value) {
267
                return $value;
268
            },
269
            'parseLiteral' => function ($node) {
270
                throw new \Exception('Invalid scalar is always invalid: ' . $node->value);
271
            },
272
            'parseValue' => function ($node) {
273
                throw new \Exception('Invalid scalar is always invalid: ' . $node);
274
            },
275
        ]);
276
277
        $anyScalar = new CustomScalarType([
278
            'name' => 'Any',
279
            'serialize' => function ($value) { return $value; },
280
            'parseLiteral' => function ($node) { return $node; }, // Allows any value
281
            'parseValue' => function ($value) { return $value; }, // Allows any value
282
        ]);
283
284
        $queryRoot = new ObjectType([
285
            'name' => 'QueryRoot',
286
            'fields' => [
287
                'human' => [
288
                    'args' => ['id' => ['type' => Type::id()]],
289
                    'type' => $Human
290
                ],
291
                'alien' => ['type' => $Alien],
292
                'dog' => ['type' => $Dog],
293
                'cat' => ['type' => $Cat],
294
                'pet' => ['type' => $Pet],
295
                'catOrDog' => ['type' => $CatOrDog],
296
                'dogOrHuman' => ['type' => $DogOrHuman],
297
                'humanOrAlien' => ['type' => $HumanOrAlien],
298
                'complicatedArgs' => ['type' => $ComplicatedArgs],
299
                'invalidArg' => [
300
                    'args' => [
301
                        'arg' => ['type' => $invalidScalar]
302
                    ],
303
                    'type' => Type::string(),
304
                ],
305
                'anyArg' => [
306
                    'args' => ['arg' => ['type' => $anyScalar]],
307
                    'type' => Type::string(),
308
                ],
309
            ]
310
        ]);
311
312
        $testSchema = new Schema([
313
            'query' => $queryRoot,
314
            'directives' => [
315
                Directive::includeDirective(),
316
                Directive::skipDirective(),
317
                new Directive([
318
                    'name' => 'onQuery',
319
                    'locations' => ['QUERY'],
320
                ]),
321
                new Directive([
322
                    'name' => 'onMutation',
323
                    'locations' => ['MUTATION'],
324
                ]),
325
                new Directive([
326
                    'name' => 'onSubscription',
327
                    'locations' => ['SUBSCRIPTION'],
328
                ]),
329
                new Directive([
330
                    'name' => 'onField',
331
                    'locations' => ['FIELD'],
332
                ]),
333
                new Directive([
334
                    'name' => 'onFragmentDefinition',
335
                    'locations' => ['FRAGMENT_DEFINITION'],
336
                ]),
337
                new Directive([
338
                    'name' => 'onFragmentSpread',
339
                    'locations' => ['FRAGMENT_SPREAD'],
340
                ]),
341
                new Directive([
342
                    'name' => 'onInlineFragment',
343
                    'locations' => ['INLINE_FRAGMENT'],
344
                ]),
345
                new Directive([
346
                    'name' => 'onSchema',
347
                    'locations' => ['SCHEMA'],
348
                ]),
349
                new Directive([
350
                    'name' => 'onScalar',
351
                    'locations' => ['SCALAR'],
352
                ]),
353
                new Directive([
354
                    'name' => 'onObject',
355
                    'locations' => ['OBJECT'],
356
                ]),
357
                new Directive([
358
                    'name' => 'onFieldDefinition',
359
                    'locations' => ['FIELD_DEFINITION'],
360
                ]),
361
                new Directive([
362
                    'name' => 'onArgumentDefinition',
363
                    'locations' => ['ARGUMENT_DEFINITION'],
364
                ]),
365
                new Directive([
366
                    'name' => 'onInterface',
367
                    'locations' => ['INTERFACE'],
368
                ]),
369
                new Directive([
370
                    'name' => 'onUnion',
371
                    'locations' => ['UNION'],
372
                ]),
373
                new Directive([
374
                    'name' => 'onEnum',
375
                    'locations' => ['ENUM'],
376
                ]),
377
                new Directive([
378
                    'name' => 'onEnumValue',
379
                    'locations' => ['ENUM_VALUE'],
380
                ]),
381
                new Directive([
382
                    'name' => 'onInputObject',
383
                    'locations' => ['INPUT_OBJECT'],
384
                ]),
385
                new Directive([
386
                    'name' => 'onInputFieldDefinition',
387
                    'locations' => ['INPUT_FIELD_DEFINITION'],
388
                ]),
389
            ],
390
        ]);
391
        return $testSchema;
392
    }
393
394
    function expectValid($schema, $rules, $queryString)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
395
    {
396
        $this->assertEquals(
397
            [],
398
            DocumentValidator::validate($schema, Parser::parse($queryString), $rules),
399
            'Should validate'
400
        );
401
    }
402
403
    function expectInvalid($schema, $rules, $queryString, $expectedErrors)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
404
    {
405
        $errors = DocumentValidator::validate($schema, Parser::parse($queryString), $rules);
406
407
        $this->assertNotEmpty($errors, 'GraphQL should not validate');
408
        $this->assertEquals($expectedErrors, array_map(['GraphQL\Error\Error', 'formatError'], $errors));
409
410
        return $errors;
411
    }
412
413
    function expectPassesRule($rule, $queryString)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
414
    {
415
        $this->expectValid($this->getTestSchema(), [$rule], $queryString);
416
    }
417
418
    function expectFailsRule($rule, $queryString, $errors)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
419
    {
420
        return $this->expectInvalid($this->getTestSchema(), [$rule], $queryString, $errors);
421
    }
422
423
    function expectPassesRuleWithSchema($schema, $rule, $queryString)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
424
    {
425
        $this->expectValid($schema, [$rule], $queryString);
426
    }
427
428
    function expectFailsRuleWithSchema($schema, $rule, $queryString, $errors)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
429
    {
430
        $this->expectInvalid($schema, [$rule], $queryString, $errors);
431
    }
432
433
    function expectPassesCompleteValidation($queryString)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
434
    {
435
        $this->expectValid($this->getTestSchema(), DocumentValidator::allRules(), $queryString);
436
    }
437
438
    function expectFailsCompleteValidation($queryString, $errors)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
439
    {
440
        $this->expectInvalid($this->getTestSchema(), DocumentValidator::allRules(), $queryString, $errors);
441
    }
442
}
443