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