ParserTest::testEscapedStrings()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
rs 9.504
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
/**
3
 * Date: 01.12.15
4
 *
5
 * @author Portey Vasil <[email protected]>
6
 */
7
8
namespace Youshido\Tests\Parser;
9
10
use Youshido\GraphQL\Parser\Ast\Argument;
11
use Youshido\GraphQL\Parser\Ast\ArgumentValue\InputList;
12
use Youshido\GraphQL\Parser\Ast\ArgumentValue\InputObject;
13
use Youshido\GraphQL\Parser\Ast\ArgumentValue\Literal;
14
use Youshido\GraphQL\Parser\Ast\ArgumentValue\Variable;
15
use Youshido\GraphQL\Parser\Ast\ArgumentValue\VariableReference;
16
use Youshido\GraphQL\Parser\Ast\Field;
17
use Youshido\GraphQL\Parser\Ast\Fragment;
18
use Youshido\GraphQL\Parser\Ast\FragmentReference;
19
use Youshido\GraphQL\Parser\Ast\Mutation;
20
use Youshido\GraphQL\Parser\Ast\Query;
21
use Youshido\GraphQL\Parser\Ast\TypedFragmentReference;
22
use Youshido\GraphQL\Parser\Location;
23
use Youshido\GraphQL\Parser\Parser;
24
use Youshido\GraphQL\Parser\Token;
25
26
class TokenizerTestingParser extends Parser {
27
    public function initTokenizerForTesting($source) {
28
        $this->initTokenizer($source);
29
    }
30
31
    public function getTokenForTesting() {
32
        return $this->lookAhead;
33
    }
34
}
35
36
class ParserTest extends \PHPUnit_Framework_TestCase
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
37
{
38
39 View Code Duplication
    public function testEmptyParser()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
40
    {
41
        $parser = new Parser();
42
43
        $this->assertEquals([
44
            'queries'            => [],
45
            'mutations'          => [],
46
            'fragments'          => [],
47
            'fragmentReferences' => [],
48
            'variables'          => [],
49
            'variableReferences' => [],
50
        ], $parser->parse());
51
    }
52
53
    /**
54
     * @expectedException Youshido\GraphQL\Exception\Parser\SyntaxErrorException
55
     */
56
    public function testInvalidSelection()
57
    {
58
        $parser = new Parser();
59
        $data   = $parser->parse('
0 ignored issues
show
Unused Code introduced by
$data is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
60
        {
61
            test {
62
                id
63
                image {
64
                    
65
                }
66
            }
67
        }
68
        ');
69
    }
70
71
    public function testComments()
72
    {
73
        $query = <<<GRAPHQL
74
# asdasd "asdasdasd"
75
# comment line 2
76
77
query {
78
    authors (category: "#2") { #asda asd
79
        _id
80
    }
81
}
82
GRAPHQL;
83
84
        $parser     = new Parser();
85
        $parsedData = $parser->parse($query);
86
87
        $this->assertEquals($parsedData, [
88
            'queries'            => [
89
                new Query('authors', null,
90
                    [
91
                        new Argument('category', new Literal('#2', new Location(5, 25)), new Location(5, 14)),
92
                    ],
93
                    [
94
                        new Field('_id', null, [], [], new Location(6, 9)),
95
                    ], [], new Location(5, 5)),
96
            ],
97
            'mutations'          => [],
98
            'fragments'          => [],
99
            'fragmentReferences' => [],
100
            'variables'          => [],
101
            'variableReferences' => [],
102
        ]);
103
    }
104
105
    private function tokenizeStringContents($graphQLString) {
106
        $parser = new TokenizerTestingParser();
107
        $parser->initTokenizerForTesting('"' . $graphQLString . '"');
108
109
        return $parser->getTokenForTesting();
110
    }
111
112
113
    public function testEscapedStrings()
114
    {
115
        $this->assertEquals([
116
                $this->tokenizeStringContents(""),           
117
                $this->tokenizeStringContents("x"),
118
                $this->tokenizeStringContents("\\\""),
119
                $this->tokenizeStringContents("\\/"),   
120
                $this->tokenizeStringContents("\\f"),
121
                $this->tokenizeStringContents("\\n"),
122
                $this->tokenizeStringContents("\\r"),         
123
                $this->tokenizeStringContents("\\b"),
124
                $this->tokenizeStringContents("\\uABCD")
125
            ],
126
            [
127
                new Token(Token::TYPE_STRING, 1, 1, ""),
128
                new Token(Token::TYPE_STRING, 1, 2, "x"),
129
                new Token(Token::TYPE_STRING, 1, 3, '"'),
130
                new Token(Token::TYPE_STRING, 1, 3, '/'),
131
                new Token(Token::TYPE_STRING, 1, 3, "\f"),
132
                new Token(Token::TYPE_STRING, 1, 3, "\n"),
133
                new Token(Token::TYPE_STRING, 1, 3, "\r"),     
134
                new Token(Token::TYPE_STRING, 1, 3, sprintf("%c", 8)),         
135
                new Token(Token::TYPE_STRING, 1, 7, html_entity_decode("&#xABCD;", ENT_QUOTES, 'UTF-8'))            
136
            ]
137
        );
138
    }
139
140
    /**
141
     * @param $query string
142
     *
143
     * @dataProvider wrongQueriesProvider
144
     * @expectedException Youshido\GraphQL\Exception\Parser\SyntaxErrorException
145
     */
146
    public function testWrongQueries($query)
147
    {
148
        $parser = new Parser();
149
150
        $parser->parse($query);
151
    }
152
153
    public function testCommas()
154
    {
155
        $parser = new Parser();
156
        $data   = $parser->parse('{ foo,       ,,  , bar  }');
157
        $this->assertEquals([
158
            new Query('foo', '', [], [], [], new Location(1, 3)),
159
            new Query('bar', '', [], [], [], new Location(1, 20)),
160
        ], $data['queries']);
161
    }
162
163
    public function testQueryWithNoFields()
164
    {
165
        $parser = new Parser();
166
        $data   = $parser->parse('{ name }');
167
        $this->assertEquals([
168
            'queries'            => [
169
                new Query('name', '', [], [], [], new Location(1, 3)),
170
            ],
171
            'mutations'          => [],
172
            'fragments'          => [],
173
            'fragmentReferences' => [],
174
            'variables'          => [],
175
            'variableReferences' => [],
176
        ], $data);
177
    }
178
179
    public function testQueryWithFields()
180
    {
181
        $parser = new Parser();
182
        $data   = $parser->parse('{ post, user { name } }');
183
        $this->assertEquals([
184
            'queries'            => [
185
                new Query('post', null, [], [], [], new Location(1, 3)),
186
                new Query('user', null, [], [
187
                    new Field('name', null, [], [], new Location(1, 16)),
188
                ], [], new Location(1, 9)),
189
            ],
190
            'mutations'          => [],
191
            'fragments'          => [],
192
            'fragmentReferences' => [],
193
            'variables'          => [],
194
            'variableReferences' => [],
195
        ], $data);
196
    }
197
198 View Code Duplication
    public function testFragmentWithFields()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
199
    {
200
        $parser = new Parser();
201
        $data   = $parser->parse('
202
            fragment FullType on __Type {
203
                kind
204
                fields {
205
                    name
206
                }
207
            }');
208
        $this->assertEquals([
209
            'queries'            => [],
210
            'mutations'          => [],
211
            'fragments'          => [
212
                new Fragment('FullType', '__Type', [], [
213
                    new Field('kind', null, [], [], new Location(3, 17)),
214
                    new Query('fields', null, [], [
215
                        new Field('name', null, [], [], new Location(5, 21)),
216
                    ], [], new Location(4, 17)),
217
                ], new Location(2, 22)),
218
            ],
219
            'fragmentReferences' => [],
220
            'variables'          => [],
221
            'variableReferences' => [],
222
        ], $data);
223
    }
224
225
    public function testInspectionQuery()
226
    {
227
        $parser = new Parser();
228
229
        $data = $parser->parse('
230
            query IntrospectionQuery {
231
                __schema {
232
                    queryType { name }
233
                    mutationType { name }
234
                    types {
235
                        ...FullType
236
                    }
237
                    directives {
238
                        name
239
                        description
240
                        args {
241
                            ...InputValue
242
                        }
243
                        onOperation
244
                        onFragment
245
                        onField
246
                    }
247
                }
248
            }
249
250
            fragment FullType on __Type {
251
                kind
252
                name
253
                description
254
                fields {
255
                    name
256
                    description
257
                    args {
258
                        ...InputValue
259
                    }
260
                    type {
261
                        ...TypeRef
262
                    }
263
                    isDeprecated
264
                    deprecationReason
265
                }
266
                inputFields {
267
                    ...InputValue
268
                }
269
                interfaces {
270
                    ...TypeRef
271
                }
272
                enumValues {
273
                    name
274
                    description
275
                    isDeprecated
276
                    deprecationReason
277
                }
278
                possibleTypes {
279
                    ...TypeRef
280
                }
281
            }
282
283
            fragment InputValue on __InputValue {
284
                name
285
                description
286
                type { ...TypeRef }
287
                defaultValue
288
            }
289
290
            fragment TypeRef on __Type {
291
                kind
292
                name
293
                ofType {
294
                    kind
295
                    name
296
                    ofType {
297
                        kind
298
                        name
299
                        ofType {
300
                            kind
301
                            name
302
                        }
303
                    }
304
                }
305
            }
306
        ');
307
308
        $this->assertEquals([
309
            'queries'            => [
310
                new Query('__schema', null, [], [
311
                    new Query('queryType', null, [], [
312
                        new Field('name', null, [], [], new Location(4, 33)),
313
                    ], [], new Location(4, 21)),
314
                    new Query('mutationType', null, [], [
315
                        new Field('name', null, [], [], new Location(5, 36)),
316
                    ], [], new Location(5, 21)),
317
                    new Query('types', null, [], [
318
                        new FragmentReference('FullType', new Location(7, 28)),
319
                    ], [], new Location(6, 21)),
320
                    new Query('directives', null, [], [
321
                        new Field('name', null, [], [], new Location(10, 25)),
322
                        new Field('description', null, [], [], new Location(11, 25)),
323
                        new Query('args', null, [], [
324
                            new FragmentReference('InputValue', new Location(13, 32)),
325
                        ], [], new Location(12, 25)),
326
                        new Field('onOperation', null, [], [], new Location(15, 25)),
327
                        new Field('onFragment', null, [], [], new Location(16, 25)),
328
                        new Field('onField', null, [], [], new Location(17, 25)),
329
                    ], [], new Location(9, 21)),
330
                ], [], new Location(3, 17)),
331
            ],
332
            'mutations'          => [],
333
            'fragments'          => [
334
                new Fragment('FullType', '__Type', [], [
335
                    new Field('kind', null, [], [], new Location(23, 17)),
336
                    new Field('name', null, [], [], new Location(24, 17)),
337
                    new Field('description', null, [], [], new Location(25, 17)),
338
                    new Query('fields', null, [], [
339
                        new Field('name', null, [], [], new Location(27, 21)),
340
                        new Field('description', null, [], [], new Location(28, 21)),
341
                        new Query('args', null, [], [
342
                            new FragmentReference('InputValue', new Location(30, 28)),
343
                        ], [], new Location(29, 21)),
344
                        new Query('type', null, [], [
345
                            new FragmentReference('TypeRef', new Location(33, 28)),
346
                        ], [], new Location(32, 21)),
347
                        new Field('isDeprecated', null, [], [], new Location(35, 21)),
348
                        new Field('deprecationReason', null, [], [], new Location(36, 21)),
349
                    ], [], new Location(26, 17)),
350
                    new Query('inputFields', null, [], [
351
                        new FragmentReference('InputValue', new Location(39, 24)),
352
                    ], [], new Location(38, 17)),
353
                    new Query('interfaces', null, [], [
354
                        new FragmentReference('TypeRef', new Location(42, 24)),
355
                    ], [], new Location(41, 17)),
356
                    new Query('enumValues', null, [], [
357
                        new Field('name', null, [], [], new Location(45, 21)),
358
                        new Field('description', null, [], [], new Location(46, 21)),
359
360
                        new Field('isDeprecated', null, [], [], new Location(47, 21)),
361
                        new Field('deprecationReason', null, [], [], new Location(48, 21)),
362
                    ], [], new Location(44, 17)),
363
                    new Query('possibleTypes', null, [], [
364
                        new FragmentReference('TypeRef', new Location(51, 24)),
365
                    ], [], new Location(50, 17)),
366
                ], new Location(22, 22)),
367
                new Fragment('InputValue', '__InputValue', [], [
368
                    new Field('name', null, [], [], new Location(56, 17)),
369
                    new Field('description', null, [], [], new Location(57, 17)),
370
                    new Query('type', null, [], [
371
                        new FragmentReference('TypeRef', new Location(58, 27)),
372
                    ], [], new Location(58, 17)),
373
                    new Field('defaultValue', null, [], [], new Location(59, 17)),
374
                ], new Location(55, 22)),
375
                new Fragment('TypeRef', '__Type', [], [
376
                    new Field('kind', null, [], [], new Location(63, 17)),
377
                    new Field('name', null, [], [], new Location(64, 17)),
378
                    new Query('ofType', null, [], [
379
                        new Field('kind', null, [], [], new Location(66, 21)),
380
                        new Field('name', null, [], [], new Location(67, 21)),
381
                        new Query('ofType', null, [], [
382
                            new Field('kind', null, [], [], new Location(69, 25)),
383
                            new Field('name', null, [], [], new Location(70, 25)),
384
                            new Query('ofType', null, [], [
385
                                new Field('kind', null, [], [], new Location(72, 29)),
386
                                new Field('name', null, [], [], new Location(73, 29)),
387
                            ], [], new Location(71, 25)),
388
                        ], [], new Location(68, 21)),
389
                    ], [], new Location(65, 17)),
390
                ], new Location(62, 22)),
391
            ],
392
            'fragmentReferences' => [
393
                new FragmentReference('FullType', new Location(7, 28)),
394
                new FragmentReference('InputValue', new Location(13, 32)),
395
                new FragmentReference('InputValue', new Location(30, 28)),
396
                new FragmentReference('TypeRef', new Location(33, 28)),
397
                new FragmentReference('InputValue', new Location(39, 24)),
398
                new FragmentReference('TypeRef', new Location(42, 24)),
399
                new FragmentReference('TypeRef', new Location(51, 24)),
400
                new FragmentReference('TypeRef', new Location(58, 27)),
401
            ],
402
            'variables'          => [],
403
            'variableReferences' => [],
404
        ], $data);
405
    }
406
407
    public function wrongQueriesProvider()
408
    {
409
        return [
410
            ['{ test (a: "asd", b: <basd>) { id }'],
411
            ['{ test (asd: [..., asd]) { id } }'],
412
            ['{ test (asd: { "a": 4, "m": null, "asd": false  "b": 5, "c" : { a }}) { id } }'],
413
            ['asdasd'],
414
            ['mutation { test(asd: ... ){ ...,asd, asd } }'],
415
            ['mutation { test{ . test on Test { id } } }'],
416
            ['mutation { test( a: "asdd'],
417
            ['mutation { test( a: { "asd": 12 12'],
418
            ['mutation { test( a: { "asd": 12'],
419
        ];
420
    }
421
422
    /**
423
     * @dataProvider mutationProvider
424
     */
425
    public function testMutations($query, $structure)
426
    {
427
        $parser = new Parser();
428
429
        $parsedStructure = $parser->parse($query);
430
431
        $this->assertEquals($parsedStructure, $structure);
432
    }
433
434 View Code Duplication
    public function testTypedFragment()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
435
    {
436
        $parser          = new Parser();
437
        $parsedStructure = $parser->parse('
438
            {
439
                test: test {
440
                    name,
441
                    ... on UnionType {
442
                        unionName
443
                    }
444
                }
445
            }
446
        ');
447
448
        $this->assertEquals($parsedStructure, [
449
            'queries'            => [
450
                new Query('test', 'test', [],
451
                    [
452
                        new Field('name', null, [], [], new Location(4, 21)),
453
                        new TypedFragmentReference('UnionType', [new Field('unionName', null, [], [], new Location(6, 25))], [], new Location(5, 28)),
454
                    ], [], new Location(3, 23)),
455
            ],
456
            'mutations'          => [],
457
            'fragments'          => [],
458
            'fragmentReferences' => [],
459
            'variables'          => [],
460
            'variableReferences' => [],
461
        ]);
462
    }
463
464
    public function mutationProvider()
465
    {
466
        return [
467
            [
468
                'query ($variable: Int){ query ( teas: $variable ) { alias: name } }',
469
                [
470
                    'queries'            => [
471
                        new Query('query', null,
472
                            [
473
                                new Argument('teas', new VariableReference('variable', (new Variable('variable', 'Int', false, false, true, new Location(1, 8)))->setUsed(true), new Location(1, 39)), new Location(1, 33)),
474
                            ],
475
                            [
476
                                new Field('name', 'alias', [], [], new Location(1, 60)),
477
                            ], [], new Location(1, 25)),
478
                    ],
479
                    'mutations'          => [],
480
                    'fragments'          => [],
481
                    'fragmentReferences' => [],
482
                    'variables'          => [
483
                        (new Variable('variable', 'Int', false, false, true, new Location(1, 8)))->setUsed(true),
484
                    ],
485
                    'variableReferences' => [
486
                        new VariableReference('variable', (new Variable('variable', 'Int', false, false, true, new Location(1, 8)))->setUsed(true), new Location(1, 39)),
487
                    ],
488
                ],
489
            ],
490
            [
491
                '{ query { alias: name } }',
492
                [
493
                    'queries'            => [
494
                        new Query('query', null, [], [new Field('name', 'alias', [], [], new Location(1, 18))], [], new Location(1, 3)),
495
                    ],
496
                    'mutations'          => [],
497
                    'fragments'          => [],
498
                    'fragmentReferences' => [],
499
                    'variables'          => [],
500
                    'variableReferences' => [],
501
                ],
502
            ],
503
            [
504
                'mutation { createUser ( email: "[email protected]", active: true ) { id } }',
505
                [
506
                    'queries'            => [],
507
                    'mutations'          => [
508
                        new Mutation(
509
                            'createUser',
510
                            null,
511
                            [
512
                                new Argument('email', new Literal('[email protected]', new Location(1, 33)), new Location(1, 25)),
513
                                new Argument('active', new Literal(true, new Location(1, 57)), new Location(1, 49)),
514
                            ],
515
                            [
516
                                new Field('id', null, [], [], new Location(1, 66)),
517
                            ],
518
                            [],
519
                            new Location(1, 12)
520
                        ),
521
                    ],
522
                    'fragments'          => [],
523
                    'fragmentReferences' => [],
524
                    'variables'          => [],
525
                    'variableReferences' => [],
526
                ],
527
            ],
528
            [
529
                'mutation { test : createUser (id: 4) }',
530
                [
531
                    'queries'            => [],
532
                    'mutations'          => [
533
                        new Mutation(
534
                            'createUser',
535
                            'test',
536
                            [
537
                                new Argument('id', new Literal(4, new Location(1, 35)), new Location(1, 31)),
538
                            ],
539
                            [],
540
                            [],
541
                            new Location(1, 19)
542
                        ),
543
                    ],
544
                    'fragments'          => [],
545
                    'fragmentReferences' => [],
546
                    'variables'          => [],
547
                    'variableReferences' => [],
548
                ],
549
            ],
550
        ];
551
    }
552
553
    /**
554
     * @dataProvider queryProvider
555
     */
556
    public function testParser($query, $structure)
557
    {
558
        $parser          = new Parser();
559
        $parsedStructure = $parser->parse($query);
560
561
        $this->assertEquals($structure, $parsedStructure);
562
    }
563
564
565
    public function queryProvider()
566
    {
567
        return [
568
            [
569
                '{ film(id: 1 filmID: 2) { title } }',
570
                [
571
                    'queries'            => [
572
                        new Query('film', null, [
573
                            new Argument('id', new Literal(1, new Location(1, 12)), new Location(1, 8)),
574
                            new Argument('filmID', new Literal(2, new Location(1, 22)), new Location(1, 14)),
575
                        ], [
576
                            new Field('title', null, [], [], new Location(1, 27)),
577
                        ], [], new Location(1, 3)),
578
                    ],
579
                    'mutations'          => [],
580
                    'fragments'          => [],
581
                    'fragmentReferences' => [],
582
                    'variables'          => [],
583
                    'variableReferences' => [],
584
                ],
585
            ],
586
            [
587
                '{ test (id: -5) { id } } ',
588
                [
589
                    'queries'            => [
590
                        new Query('test', null, [
591
                            new Argument('id', new Literal(-5, new Location(1, 13)), new Location(1, 9)),
592
                        ], [
593
                            new Field('id', null, [], [], new Location(1, 19)),
594
                        ], [], new Location(1, 3)),
595
                    ],
596
                    'mutations'          => [],
597
                    'fragments'          => [],
598
                    'fragmentReferences' => [],
599
                    'variables'          => [],
600
                    'variableReferences' => [],
601
                ],
602
            ],
603
            [
604
                "{ test (id: -5) \r\n { id } } ",
605
                [
606
                    'queries'            => [
607
                        new Query('test', null, [
608
                            new Argument('id', new Literal(-5, new Location(1, 13)), new Location(1, 9)),
609
                        ], [
610
                            new Field('id', null, [], [], new Location(2, 4)),
611
                        ], [], new Location(1, 3)),
612
                    ],
613
                    'mutations'          => [],
614
                    'fragments'          => [],
615
                    'fragmentReferences' => [],
616
                    'variables'          => [],
617
                    'variableReferences' => [],
618
                ],
619
            ],
620
            [
621
                'query CheckTypeOfLuke {
622
                  hero(episode: EMPIRE) {
623
                    __typename,
624
                    name
625
                  }
626
                }',
627
                [
628
                    'queries'            => [
629
                        new Query('hero', null, [
630
                            new Argument('episode', new Literal('EMPIRE', new Location(2, 33)), new Location(2, 24)),
631
                        ], [
632
                            new Field('__typename', null, [], [], new Location(3, 21)),
633
                            new Field('name', null, [], [], new Location(4, 21)),
634
                        ], [], new Location(2, 19)),
635
                    ],
636
                    'mutations'          => [],
637
                    'fragments'          => [],
638
                    'fragmentReferences' => [],
639
                    'variables'          => [],
640
                    'variableReferences' => [],
641
                ],
642
            ],
643
            [
644
                '{ test { __typename, id } }',
645
                [
646
                    'queries'            => [
647
                        new Query('test', null, [], [
648
                            new Field('__typename', null, [], [], new Location(1, 10)),
649
                            new Field('id', null, [], [], new Location(1, 22)),
650
                        ], [], new Location(1, 3)),
651
                    ],
652
                    'mutations'          => [],
653
                    'fragments'          => [],
654
                    'fragmentReferences' => [],
655
                    'variables'          => [],
656
                    'variableReferences' => [],
657
                ],
658
            ],
659
            [
660
                '{}',
661
                [
662
                    'queries'            => [],
663
                    'mutations'          => [],
664
                    'fragments'          => [],
665
                    'fragmentReferences' => [],
666
                    'variables'          => [],
667
                    'variableReferences' => [],
668
                ],
669
            ],
670
            [
671
                'query test {}',
672
                [
673
                    'queries'            => [],
674
                    'mutations'          => [],
675
                    'fragments'          => [],
676
                    'fragmentReferences' => [],
677
                    'variables'          => [],
678
                    'variableReferences' => [],
679
                ],
680
            ],
681
            [
682
                'query {}',
683
                [
684
                    'queries'            => [],
685
                    'mutations'          => [],
686
                    'fragments'          => [],
687
                    'fragmentReferences' => [],
688
                    'variables'          => [],
689
                    'variableReferences' => [],
690
                ],
691
            ],
692
            [
693
                'mutation setName { setUserName }',
694
                [
695
                    'queries'            => [],
696
                    'mutations'          => [new Mutation('setUserName', null, [], [], [], new Location(1, 20))],
697
                    'fragments'          => [],
698
                    'fragmentReferences' => [],
699
                    'variables'          => [],
700
                    'variableReferences' => [],
701
                ],
702
            ],
703
            [
704
                '{ test { ...userDataFragment } } fragment userDataFragment on User { id, name, email }',
705
                [
706
                    'queries'            => [
707
                        new Query('test', null, [], [new FragmentReference('userDataFragment', new Location(1, 13))], [], new Location(1, 3)),
708
                    ],
709
                    'mutations'          => [],
710
                    'fragments'          => [
711
                        new Fragment('userDataFragment', 'User', [], [
712
                            new Field('id', null, [], [], new Location(1, 70)),
713
                            new Field('name', null, [], [], new Location(1, 74)),
714
                            new Field('email', null, [], [], new Location(1, 80)),
715
                        ], new Location(1, 43)),
716
                    ],
717
                    'fragmentReferences' => [
718
                        new FragmentReference('userDataFragment', new Location(1, 13)),
719
                    ],
720
                    'variables'          => [],
721
                    'variableReferences' => [],
722
                ],
723
            ],
724
            [
725
                '{ user (id: 10, name: "max", float: 123.123 ) { id, name } }',
726
                [
727
                    'queries'            => [
728
                        new Query(
729
                            'user',
730
                            null,
731
                            [
732
                                new Argument('id', new Literal('10', new Location(1, 13)), new Location(1, 9)),
733
                                new Argument('name', new Literal('max', new Location(1, 24)), new Location(1, 17)),
734
                                new Argument('float', new Literal('123.123', new Location(1, 37)), new Location(1, 30)),
735
                            ],
736
                            [
737
                                new Field('id', null, [], [], new Location(1, 49)),
738
                                new Field('name', null, [], [], new Location(1, 53)),
739
                            ],
740
                            [],
741
                            new Location(1, 3)
742
                        ),
743
                    ],
744
                    'mutations'          => [],
745
                    'fragments'          => [],
746
                    'fragmentReferences' => [],
747
                    'variables'          => [],
748
                    'variableReferences' => [],
749
                ],
750
            ],
751
            [
752
                '{ allUsers : users ( id: [ 1, 2, 3] ) { id } }',
753
                [
754
                    'queries'            => [
755
                        new Query(
756
                            'users',
757
                            'allUsers',
758
                            [
759
                                new Argument('id', new InputList([1, 2, 3], new Location(1, 26)), new Location(1, 22)),
760
                            ],
761
                            [
762
                                new Field('id', null, [], [], new Location(1, 41)),
763
                            ],
764
                            [],
765
                            new Location(1, 14)
766
                        ),
767
                    ],
768
                    'mutations'          => [],
769
                    'fragments'          => [],
770
                    'fragmentReferences' => [],
771
                    'variables'          => [],
772
                    'variableReferences' => [],
773
                ],
774
            ],
775
            [
776
                '{ allUsers : users ( id: [ 1, "2", true, null] ) { id } }',
777
                [
778
                    'queries'            => [
779
                        new Query(
780
                            'users',
781
                            'allUsers',
782
                            [
783
                                new Argument('id', new InputList([1, "2", true, null], new Location(1, 26)), new Location(1, 22)),
784
                            ],
785
                            [
786
                                new Field('id', null, [], [], new Location(1, 52)),
787
                            ],
788
                            [],
789
                            new Location(1, 14)
790
                        ),
791
                    ],
792
                    'mutations'          => [],
793
                    'fragments'          => [],
794
                    'fragmentReferences' => [],
795
                    'variables'          => [],
796
                    'variableReferences' => [],
797
                ],
798
            ],
799
            [
800
                '{ allUsers : users ( object: { "a": 123, "d": "asd",  "b" : [ 1, 2, 4 ], "c": { "a" : 123, "b":  "asd" } } ) { id } }',
801
                [
802
                    'queries'            => [
803
                        new Query(
804
                            'users',
805
                            'allUsers',
806
                            [
807
                                new Argument('object', new InputObject([
808
                                    'a' => 123,
809
                                    'd' => 'asd',
810
                                    'b' => [1, 2, 4],
811
                                    'c' => new InputObject([
812
                                        'a' => 123,
813
                                        'b' => 'asd',
814
                                    ], new Location(1, 79)),
815
                                ], new Location(1, 30)), new Location(1, 22)),
816
                            ],
817
                            [
818
                                new Field('id', null, [], [], new Location(1, 112)),
819
                            ],
820
                            [],
821
                            new Location(1, 14)
822
                        ),
823
                    ],
824
                    'mutations'          => [],
825
                    'fragments'          => [],
826
                    'fragmentReferences' => [],
827
                    'variables'          => [],
828
                    'variableReferences' => [],
829
                ],
830
            ],
831
        ];
832
    }
833
834
    public function testVariablesInQuery()
835
    {
836
        $parser = new Parser();
837
838
        $data = $parser->parse('
839
            query StarWarsAppHomeRoute($names_0:[String!]!, $query: String) {
840
              factions(names:$names_0, test: $query) {
841
                id,
842
                ...F2
843
              }
844
            }
845
            fragment F0 on Ship {
846
              id,
847
              name
848
            }
849
            fragment F1 on Faction {
850
              id,
851
              factionId
852
            }
853
            fragment F2 on Faction {
854
              id,
855
              factionId,
856
              name,
857
              _shipsDRnzJ:ships(first:10) {
858
                edges {
859
                  node {
860
                    id,
861
                    ...F0
862
                  },
863
                  cursor
864
                },
865
                pageInfo {
866
                  hasNextPage,
867
                  hasPreviousPage
868
                }
869
              },
870
              ...F1
871
            }
872
        ');
873
874
        $this->assertArrayNotHasKey('errors', $data);
875
    }
876
877
    public function testVariableDefaultValue()
878
    {
879
        $parser          = new Parser();
880
        $parsedStructure = $parser->parse('
881
            query ($format: String = "small"){
882
              user {
883
                avatar(format: $format)
884
              }
885
            }
886
        ');
887
        /** @var Variable $var */
888
        $var = $parsedStructure['variables'][0];
889
        $this->assertTrue($var->hasDefaultValue());
890
        $this->assertEquals('small', $var->getDefaultValue()->getValue());
891
        $this->assertEquals('small', $var->getValue()->getValue());
892
    }
893
894
}
895