Passed
Push — master ( f24e00...29eba8 )
by Vladimir
10:15
created

QueryPlanTest::testQueryPlan()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 279
Code Lines 174

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 174
dl 0
loc 279
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
3
declare(strict_types=1);
4
5
namespace GraphQL\Tests\Type;
6
7
use GraphQL\GraphQL;
8
use GraphQL\Type\Definition\ObjectType;
9
use GraphQL\Type\Definition\QueryPlan;
10
use GraphQL\Type\Definition\ResolveInfo;
11
use GraphQL\Type\Definition\Type;
12
use GraphQL\Type\Schema;
13
use PHPUnit\Framework\TestCase;
14
15
final class QueryPlanTest extends TestCase
16
{
17
    public function testQueryPlan() : void
18
    {
19
        $image = new ObjectType([
20
            'name'   => 'Image',
21
            'fields' => [
22
                'url'    => ['type' => Type::string()],
23
                'width'  => ['type' => Type::int()],
24
                'height' => ['type' => Type::int()],
25
            ],
26
        ]);
27
28
        $article = null;
29
30
        $author = new ObjectType([
31
            'name'   => 'Author',
32
            'fields' => static function () use ($image, &$article) {
33
                return [
34
                    'id'            => ['type' => Type::string()],
35
                    'name'          => ['type' => Type::string()],
36
                    'pic'           => [
37
                        'type' => $image,
38
                        'args' => [
39
                            'width'  => ['type' => Type::int()],
40
                            'height' => ['type' => Type::int()],
41
                        ],
42
                    ],
43
                    'recentArticle' => ['type' => $article],
44
                ];
45
            },
46
        ]);
47
48
        $reply = new ObjectType([
49
            'name'   => 'Reply',
50
            'fields' => [
51
                'author' => ['type' => $author],
52
                'body'   => ['type' => Type::string()],
53
            ],
54
        ]);
55
56
        $article = new ObjectType([
57
            'name'   => 'Article',
58
            'fields' => [
59
                'id'          => ['type' => Type::string()],
60
                'isPublished' => ['type' => Type::boolean()],
61
                'author'      => ['type' => $author],
62
                'title'       => ['type' => Type::string()],
63
                'body'        => ['type' => Type::string()],
64
                'image'       => ['type' => $image],
65
                'replies'     => ['type' => Type::listOf($reply)],
66
            ],
67
        ]);
68
69
        $doc               = '
70
      query Test {
71
        article {
72
            author {
73
                name
74
                pic(width: 100, height: 200) {
75
                    url
76
                    width
77
                }
78
            }
79
            image {
80
                width
81
                height
82
                ...MyImage
83
            }
84
            replies {
85
                body
86
                author {
87
                    id
88
                    name
89
                    pic {
90
                        url
91
                        width
92
                        ... on Image {
93
                            height
94
                        }
95
                    }
96
                    recentArticle {
97
                        id
98
                        title
99
                        body
100
                    }
101
                }
102
            }
103
        }
104
      }
105
      fragment MyImage on Image {
106
        url
107
      }
108
';
109
        $expectedQueryPlan = [
110
            'author'  => [
111
                'type' => $author,
112
                'args' => [],
113
                'fields' => [
114
                    'name' => [
115
                        'type' => Type::string(),
116
                        'args' => [],
117
                        'fields' => [],
118
                    ],
119
                    'pic'  => [
120
                        'type' => $image,
121
                        'args' => [
122
                            'width' => 100,
123
                            'height' => 200,
124
                        ],
125
                        'fields' => [
126
                            'url'   => [
127
                                'type' => Type::string(),
128
                                'args' => [],
129
                                'fields' => [],
130
                            ],
131
                            'width' => [
132
                                'type' => Type::int(),
133
                                'args' => [],
134
                                'fields' => [],
135
                            ],
136
                        ],
137
                    ],
138
                ],
139
            ],
140
            'image'   => [
141
                'type' => $image,
142
                'args' => [],
143
                'fields' => [
144
                    'url'   => [
145
                        'type' => Type::string(),
146
                        'args' => [],
147
                        'fields' => [],
148
                    ],
149
                    'width' => [
150
                        'type' => Type::int(),
151
                        'args' => [],
152
                        'fields' => [],
153
                    ],
154
                    'height' => [
155
                        'type' => Type::int(),
156
                        'args' => [],
157
                        'fields' => [],
158
                    ],
159
                ],
160
            ],
161
            'replies' => [
162
                'type' => Type::listOf($reply),
163
                'args' => [],
164
                'fields' => [
165
                    'body'   => [
166
                        'type' => Type::string(),
167
                        'args' => [],
168
                        'fields' => [],
169
                    ],
170
                    'author' => [
171
                        'type' => $author,
172
                        'args' => [],
173
                        'fields' => [
174
                            'id' => [
175
                                'type' => Type::string(),
176
                                'args' => [],
177
                                'fields' => [],
178
                            ],
179
                            'name' => [
180
                                'type' => Type::string(),
181
                                'args' => [],
182
                                'fields' => [],
183
                            ],
184
                            'pic'  => [
185
                                'type' => $image,
186
                                'args' => [],
187
                                'fields' => [
188
                                    'url'   => [
189
                                        'type' => Type::string(),
190
                                        'args' => [],
191
                                        'fields' => [],
192
                                    ],
193
                                    'width' => [
194
                                        'type' => Type::int(),
195
                                        'args' => [],
196
                                        'fields' => [],
197
                                    ],
198
                                    'height' => [
199
                                        'type' => Type::int(),
200
                                        'args' => [],
201
                                        'fields' => [],
202
                                    ],
203
                                ],
204
                            ],
205
                            'recentArticle' => [
206
                                'type' => $article,
207
                                'args' => [],
208
                                'fields' => [
209
                                    'id' => [
210
                                        'type' => Type::string(),
211
                                        'args' => [],
212
                                        'fields' => [],
213
                                    ],
214
                                    'title' => [
215
                                        'type' => Type::string(),
216
                                        'args' => [],
217
                                        'fields' => [],
218
                                    ],
219
                                    'body' => [
220
                                        'type' => Type::string(),
221
                                        'args' => [],
222
                                        'fields' => [],
223
                                    ],
224
                                ],
225
                            ],
226
                        ],
227
                    ],
228
                ],
229
            ],
230
        ];
231
232
        $expectedReferencedTypes = [
233
            'Image',
234
            'Author',
235
            'Article',
236
            'Reply',
237
        ];
238
239
        $expectedReferencedFields = [
240
            'url',
241
            'width',
242
            'height',
243
            'name',
244
            'pic',
245
            'id',
246
            'recentArticle',
247
            'title',
248
            'body',
249
            'author',
250
            'image',
251
            'replies',
252
        ];
253
254
        $hasCalled = false;
255
        /** @var QueryPlan $queryPlan */
256
        $queryPlan = null;
257
258
        $blogQuery = new ObjectType([
259
            'name'   => 'Query',
260
            'fields' => [
261
                'article' => [
262
                    'type'    => $article,
263
                    'resolve' => static function (
264
                        $value,
265
                        $args,
266
                        $context,
267
                        ResolveInfo $info
268
                    ) use (
269
                        &$hasCalled,
270
                        &$queryPlan
271
                    ) {
272
                        $hasCalled = true;
273
                        $queryPlan = $info->lookAhead();
274
275
                        return null;
276
                    },
277
                ],
278
            ],
279
        ]);
280
281
        $schema = new Schema(['query' => $blogQuery]);
282
        $result = GraphQL::executeQuery($schema, $doc)->toArray();
283
284
        self::assertTrue($hasCalled);
285
        self::assertEquals(['data' => ['article' => null]], $result);
286
        self::assertEquals($expectedQueryPlan, $queryPlan->queryPlan());
287
        self::assertEquals($expectedReferencedTypes, $queryPlan->getReferencedTypes());
288
        self::assertEquals($expectedReferencedFields, $queryPlan->getReferencedFields());
289
        self::assertEquals(['url', 'width', 'height'], $queryPlan->subFields('Image'));
290
291
        self::assertTrue($queryPlan->hasField('url'));
292
        self::assertFalse($queryPlan->hasField('test'));
293
294
        self::assertTrue($queryPlan->hasType('Image'));
295
        self::assertFalse($queryPlan->hasType('Test'));
296
    }
297
298
    public function testMergedFragmentsQueryPlan() : void
299
    {
300
        $image = new ObjectType([
301
            'name'   => 'Image',
302
            'fields' => [
303
                'url'    => ['type' => Type::string()],
304
                'width'  => ['type' => Type::int()],
305
                'height' => ['type' => Type::int()],
306
            ],
307
        ]);
308
309
        $article = null;
310
311
        $author = new ObjectType([
312
            'name'   => 'Author',
313
            'fields' => static function () use ($image, &$article) {
314
                return [
315
                    'id'            => ['type' => Type::string()],
316
                    'name'          => ['type' => Type::string()],
317
                    'pic'           => [
318
                        'type' => $image,
319
                        'args' => [
320
                            'width'  => ['type' => Type::int()],
321
                            'height' => ['type' => Type::int()],
322
                        ],
323
                    ],
324
                    'recentArticle' => ['type' => $article],
325
                ];
326
            },
327
        ]);
328
329
        $reply = new ObjectType([
330
            'name'   => 'Reply',
331
            'fields' => [
332
                'author' => ['type' => $author],
333
                'body'   => ['type' => Type::string()],
334
            ],
335
        ]);
336
337
        $article = new ObjectType([
338
            'name'   => 'Article',
339
            'fields' => [
340
                'id'          => ['type' => Type::string()],
341
                'isPublished' => ['type' => Type::boolean()],
342
                'author'      => ['type' => $author],
343
                'title'       => ['type' => Type::string()],
344
                'body'        => ['type' => Type::string()],
345
                'image'       => ['type' => $image],
346
                'replies'     => ['type' => Type::listOf($reply)],
347
            ],
348
        ]);
349
350
        $doc = '
351
      query Test {
352
        article {
353
            author {
354
                name
355
                pic(width: 100, height: 200) {
356
                    url
357
                    width
358
                }
359
            }
360
            image {
361
                width
362
                height
363
                ...MyImage
364
            }
365
            ...Replies01
366
            ...Replies02
367
        }
368
      }
369
      fragment MyImage on Image {
370
        url
371
      }
372
373
      fragment Replies01 on Article {
374
        _replies012: replies {
375
            body
376
        }
377
      }
378
      fragment Replies02 on Article {
379
        _replies012: replies {
380
            author {
381
                id
382
                name
383
                pic {
384
                    url
385
                    width
386
                    ... on Image {
387
                        height
388
                    }
389
                }
390
                recentArticle {
391
                    id
392
                    title
393
                    body
394
                }
395
            }
396
        }
397
       }
398
';
399
400
        $expectedQueryPlan = [
401
            'author'  => [
402
                'type' => $author,
403
                'args' => [],
404
                'fields' => [
405
                    'name' => [
406
                        'type' => Type::string(),
407
                        'args' => [],
408
                        'fields' => [],
409
                    ],
410
                    'pic'  => [
411
                        'type' => $image,
412
                        'args' => [
413
                            'width' => 100,
414
                            'height' => 200,
415
                        ],
416
                        'fields' => [
417
                            'url'   => [
418
                                'type' => Type::string(),
419
                                'args' => [],
420
                                'fields' => [],
421
                            ],
422
                            'width' => [
423
                                'type' => Type::int(),
424
                                'args' => [],
425
                                'fields' => [],
426
                            ],
427
                        ],
428
                    ],
429
                ],
430
            ],
431
            'image'   => [
432
                'type' => $image,
433
                'args' => [],
434
                'fields' => [
435
                    'url'   => [
436
                        'type' => Type::string(),
437
                        'args' => [],
438
                        'fields' => [],
439
                    ],
440
                    'width' => [
441
                        'type' => Type::int(),
442
                        'args' => [],
443
                        'fields' => [],
444
                    ],
445
                    'height' => [
446
                        'type' => Type::int(),
447
                        'args' => [],
448
                        'fields' => [],
449
                    ],
450
                ],
451
            ],
452
            'replies' => [
453
                'type' => Type::listOf($reply),
454
                'args' => [],
455
                'fields' => [
456
                    'body'   => [
457
                        'type' => Type::string(),
458
                        'args' => [],
459
                        'fields' => [],
460
                    ],
461
                    'author' => [
462
                        'type' => $author,
463
                        'args' => [],
464
                        'fields' => [
465
                            'id' => [
466
                                'type' => Type::string(),
467
                                'args' => [],
468
                                'fields' => [],
469
                            ],
470
                            'name' => [
471
                                'type' => Type::string(),
472
                                'args' => [],
473
                                'fields' => [],
474
                            ],
475
                            'pic'  => [
476
                                'type' => $image,
477
                                'args' => [],
478
                                'fields' => [
479
                                    'url'   => [
480
                                        'type' => Type::string(),
481
                                        'args' => [],
482
                                        'fields' => [],
483
                                    ],
484
                                    'width' => [
485
                                        'type' => Type::int(),
486
                                        'args' => [],
487
                                        'fields' => [],
488
                                    ],
489
                                    'height' => [
490
                                        'type' => Type::int(),
491
                                        'args' => [],
492
                                        'fields' => [],
493
                                    ],
494
                                ],
495
                            ],
496
                            'recentArticle' => [
497
                                'type' => $article,
498
                                'args' => [],
499
                                'fields' => [
500
                                    'id' => [
501
                                        'type' => Type::string(),
502
                                        'args' => [],
503
                                        'fields' => [],
504
                                    ],
505
                                    'title' => [
506
                                        'type' => Type::string(),
507
                                        'args' => [],
508
                                        'fields' => [],
509
                                    ],
510
                                    'body' => [
511
                                        'type' => Type::string(),
512
                                        'args' => [],
513
                                        'fields' => [],
514
                                    ],
515
                                ],
516
                            ],
517
                        ],
518
                    ],
519
                ],
520
            ],
521
        ];
522
523
        $expectedReferencedTypes = [
524
            'Image',
525
            'Author',
526
            'Reply',
527
            'Article',
528
        ];
529
530
        $expectedReferencedFields = [
531
            'url',
532
            'width',
533
            'height',
534
            'name',
535
            'pic',
536
            'id',
537
            'recentArticle',
538
            'body',
539
            'author',
540
            'replies',
541
            'title',
542
            'image',
543
        ];
544
545
        $hasCalled = false;
546
        /** @var QueryPlan $queryPlan */
547
        $queryPlan = null;
548
549
        $blogQuery = new ObjectType([
550
            'name'   => 'Query',
551
            'fields' => [
552
                'article' => [
553
                    'type'    => $article,
554
                    'resolve' => static function (
555
                        $value,
556
                        $args,
557
                        $context,
558
                        ResolveInfo $info
559
                    ) use (
560
                        &$hasCalled,
561
                        &$queryPlan
562
                    ) {
563
                        $hasCalled = true;
564
                        $queryPlan = $info->lookAhead();
565
566
                        return null;
567
                    },
568
                ],
569
            ],
570
        ]);
571
572
        $schema = new Schema(['query' => $blogQuery]);
573
        $result = GraphQL::executeQuery($schema, $doc)->toArray();
574
575
        self::assertTrue($hasCalled);
576
        self::assertEquals(['data' => ['article' => null]], $result);
577
        self::assertEquals($expectedQueryPlan, $queryPlan->queryPlan());
578
        self::assertEquals($expectedReferencedTypes, $queryPlan->getReferencedTypes());
579
        self::assertEquals($expectedReferencedFields, $queryPlan->getReferencedFields());
580
        self::assertEquals(['url', 'width', 'height'], $queryPlan->subFields('Image'));
581
582
        self::assertTrue($queryPlan->hasField('url'));
583
        self::assertFalse($queryPlan->hasField('test'));
584
585
        self::assertTrue($queryPlan->hasType('Image'));
586
        self::assertFalse($queryPlan->hasType('Test'));
587
    }
588
}
589