Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
36 | { |
||
37 | public function initTokenizerForTesting($source): void |
||
38 | { |
||
39 | $this->initTokenizer($source); |
||
40 | } |
||
41 | |||
42 | public function getTokenForTesting() |
||
43 | { |
||
44 | return $this->lookAhead; |
||
45 | } |
||
46 | } |
||
47 | |||
48 | class ParserTest extends \PHPUnit_Framework_TestCase |
||
49 | { |
||
50 | public function testEmptyParser(): void |
||
51 | { |
||
52 | $parser = new Parser(); |
||
53 | |||
54 | $this->assertEquals([ |
||
55 | 'queries' => [], |
||
56 | 'mutations' => [], |
||
57 | 'fragments' => [], |
||
58 | 'fragmentReferences' => [], |
||
59 | 'variables' => [], |
||
60 | 'variableReferences' => [], |
||
61 | ], $parser->parse()); |
||
62 | } |
||
63 | |||
64 | |||
65 | public function testInvalidSelection(): void |
||
66 | { |
||
67 | $this->expectException(\Youshido\GraphQL\Exception\Parser\SyntaxErrorException::class); |
||
68 | |||
69 | $parser = new Parser(); |
||
70 | $data = $parser->parse(' |
||
71 | { |
||
72 | test { |
||
73 | id |
||
74 | image { |
||
75 | |||
76 | } |
||
77 | } |
||
78 | } |
||
79 | '); |
||
80 | } |
||
81 | |||
82 | public function testComments(): void |
||
83 | { |
||
84 | $query = <<<'GRAPHQL' |
||
85 | # asdasd "asdasdasd" |
||
86 | # comment line 2 |
||
87 | |||
88 | query { |
||
89 | authors (category: "#2") { #asda asd |
||
90 | _id |
||
91 | } |
||
92 | } |
||
93 | GRAPHQL; |
||
94 | |||
95 | $parser = new Parser(); |
||
96 | $parsedData = $parser->parse($query); |
||
97 | |||
98 | $this->assertEquals($parsedData, [ |
||
99 | 'queries' => [ |
||
100 | new Query( |
||
101 | 'authors', |
||
102 | null, |
||
103 | [ |
||
104 | new Argument('category', new Literal('#2', new Location(5, 25)), new Location(5, 14)), |
||
105 | ], |
||
106 | [ |
||
107 | new Field('_id', null, [], [], new Location(6, 9)), |
||
108 | ], |
||
109 | [], |
||
110 | new Location(5, 5) |
||
111 | ), |
||
112 | ], |
||
113 | 'mutations' => [], |
||
114 | 'fragments' => [], |
||
115 | 'fragmentReferences' => [], |
||
116 | 'variables' => [], |
||
117 | 'variableReferences' => [], |
||
118 | ]); |
||
119 | } |
||
120 | |||
121 | public function testEscapedStrings(): void |
||
122 | { |
||
123 | $this->assertEquals( |
||
124 | [ |
||
125 | $this->tokenizeStringContents(''), |
||
126 | $this->tokenizeStringContents('x'), |
||
127 | $this->tokenizeStringContents('\\"'), |
||
128 | $this->tokenizeStringContents('\\/'), |
||
129 | $this->tokenizeStringContents('\\f'), |
||
130 | $this->tokenizeStringContents('\\n'), |
||
131 | $this->tokenizeStringContents('\\r'), |
||
132 | $this->tokenizeStringContents('\\b'), |
||
133 | $this->tokenizeStringContents('\\uABCD'), |
||
134 | ], |
||
135 | [ |
||
136 | new Token(Token::TYPE_STRING, 1, 1, ''), |
||
137 | new Token(Token::TYPE_STRING, 1, 2, 'x'), |
||
138 | new Token(Token::TYPE_STRING, 1, 3, '"'), |
||
139 | new Token(Token::TYPE_STRING, 1, 3, '/'), |
||
140 | new Token(Token::TYPE_STRING, 1, 3, "\f"), |
||
141 | new Token(Token::TYPE_STRING, 1, 3, "\n"), |
||
142 | new Token(Token::TYPE_STRING, 1, 3, "\r"), |
||
143 | new Token(Token::TYPE_STRING, 1, 3, \sprintf('%c', 8)), |
||
144 | new Token(Token::TYPE_STRING, 1, 7, \html_entity_decode('ꯍ', ENT_QUOTES, 'UTF-8')), |
||
145 | ] |
||
146 | ); |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * @param $query string |
||
151 | * |
||
152 | * @dataProvider wrongQueriesProvider |
||
153 | */ |
||
154 | public function testWrongQueries($query): void |
||
155 | { |
||
156 | $this->expectException(\Youshido\GraphQL\Exception\Parser\SyntaxErrorException::class); |
||
157 | |||
158 | $parser = new Parser(); |
||
159 | |||
160 | $parser->parse($query); |
||
161 | } |
||
162 | |||
163 | public function testCommas(): void |
||
164 | { |
||
165 | $parser = new Parser(); |
||
166 | $data = $parser->parse('{ foo, ,, , bar }'); |
||
167 | $this->assertEquals([ |
||
168 | new Query('foo', '', [], [], [], new Location(1, 3)), |
||
169 | new Query('bar', '', [], [], [], new Location(1, 20)), |
||
170 | ], $data['queries']); |
||
171 | } |
||
172 | |||
173 | public function testQueryWithNoFields(): void |
||
174 | { |
||
175 | $parser = new Parser(); |
||
176 | $data = $parser->parse('{ name }'); |
||
177 | $this->assertEquals([ |
||
178 | 'queries' => [ |
||
179 | new Query('name', '', [], [], [], new Location(1, 3)), |
||
180 | ], |
||
181 | 'mutations' => [], |
||
182 | 'fragments' => [], |
||
183 | 'fragmentReferences' => [], |
||
184 | 'variables' => [], |
||
185 | 'variableReferences' => [], |
||
186 | ], $data); |
||
187 | } |
||
188 | |||
189 | public function testQueryWithFields(): void |
||
190 | { |
||
191 | $parser = new Parser(); |
||
192 | $data = $parser->parse('{ post, user { name } }'); |
||
193 | $this->assertEquals([ |
||
194 | 'queries' => [ |
||
195 | new Query('post', null, [], [], [], new Location(1, 3)), |
||
196 | new Query('user', null, [], [ |
||
197 | new Field('name', null, [], [], new Location(1, 16)), |
||
198 | ], [], new Location(1, 9)), |
||
199 | ], |
||
200 | 'mutations' => [], |
||
201 | 'fragments' => [], |
||
202 | 'fragmentReferences' => [], |
||
203 | 'variables' => [], |
||
204 | 'variableReferences' => [], |
||
205 | ], $data); |
||
206 | } |
||
207 | |||
208 | public function testFragmentWithFields(): void |
||
209 | { |
||
210 | $parser = new Parser(); |
||
211 | $data = $parser->parse(' |
||
212 | fragment FullType on __Type { |
||
213 | kind |
||
214 | fields { |
||
215 | name |
||
216 | } |
||
217 | }'); |
||
218 | $this->assertEquals([ |
||
219 | 'queries' => [], |
||
220 | 'mutations' => [], |
||
221 | 'fragments' => [ |
||
222 | new Fragment('FullType', '__Type', [], [ |
||
223 | new Field('kind', null, [], [], new Location(3, 17)), |
||
224 | new Query('fields', null, [], [ |
||
225 | new Field('name', null, [], [], new Location(5, 21)), |
||
226 | ], [], new Location(4, 17)), |
||
227 | ], new Location(2, 22)), |
||
228 | ], |
||
229 | 'fragmentReferences' => [], |
||
230 | 'variables' => [], |
||
231 | 'variableReferences' => [], |
||
232 | ], $data); |
||
233 | } |
||
234 | |||
235 | public function testInspectionQuery(): void |
||
236 | { |
||
237 | $parser = new Parser(); |
||
238 | |||
239 | $data = $parser->parse(' |
||
240 | query IntrospectionQuery { |
||
241 | __schema { |
||
242 | queryType { name } |
||
243 | mutationType { name } |
||
244 | types { |
||
245 | ...FullType |
||
246 | } |
||
247 | directives { |
||
248 | name |
||
249 | description |
||
250 | args { |
||
251 | ...InputValue |
||
252 | } |
||
253 | onOperation |
||
254 | onFragment |
||
255 | onField |
||
256 | } |
||
257 | } |
||
258 | } |
||
259 | |||
260 | fragment FullType on __Type { |
||
261 | kind |
||
262 | name |
||
263 | description |
||
264 | fields { |
||
265 | name |
||
266 | description |
||
267 | args { |
||
268 | ...InputValue |
||
269 | } |
||
270 | type { |
||
271 | ...TypeRef |
||
272 | } |
||
273 | isDeprecated |
||
274 | deprecationReason |
||
275 | } |
||
276 | inputFields { |
||
277 | ...InputValue |
||
278 | } |
||
279 | interfaces { |
||
280 | ...TypeRef |
||
281 | } |
||
282 | enumValues { |
||
283 | name |
||
284 | description |
||
285 | isDeprecated |
||
286 | deprecationReason |
||
287 | } |
||
288 | possibleTypes { |
||
289 | ...TypeRef |
||
290 | } |
||
291 | } |
||
292 | |||
293 | fragment InputValue on __InputValue { |
||
294 | name |
||
295 | description |
||
296 | type { ...TypeRef } |
||
297 | defaultValue |
||
298 | } |
||
299 | |||
300 | fragment TypeRef on __Type { |
||
301 | kind |
||
302 | name |
||
303 | ofType { |
||
304 | kind |
||
305 | name |
||
306 | ofType { |
||
307 | kind |
||
308 | name |
||
309 | ofType { |
||
310 | kind |
||
311 | name |
||
312 | } |
||
313 | } |
||
314 | } |
||
315 | } |
||
316 | '); |
||
317 | |||
318 | $this->assertEquals([ |
||
319 | 'queries' => [ |
||
320 | new Query('__schema', null, [], [ |
||
321 | new Query('queryType', null, [], [ |
||
322 | new Field('name', null, [], [], new Location(4, 33)), |
||
323 | ], [], new Location(4, 21)), |
||
324 | new Query('mutationType', null, [], [ |
||
325 | new Field('name', null, [], [], new Location(5, 36)), |
||
326 | ], [], new Location(5, 21)), |
||
327 | new Query('types', null, [], [ |
||
328 | new FragmentReference('FullType', new Location(7, 28)), |
||
329 | ], [], new Location(6, 21)), |
||
330 | new Query('directives', null, [], [ |
||
331 | new Field('name', null, [], [], new Location(10, 25)), |
||
332 | new Field('description', null, [], [], new Location(11, 25)), |
||
333 | new Query('args', null, [], [ |
||
334 | new FragmentReference('InputValue', new Location(13, 32)), |
||
335 | ], [], new Location(12, 25)), |
||
336 | new Field('onOperation', null, [], [], new Location(15, 25)), |
||
337 | new Field('onFragment', null, [], [], new Location(16, 25)), |
||
338 | new Field('onField', null, [], [], new Location(17, 25)), |
||
339 | ], [], new Location(9, 21)), |
||
340 | ], [], new Location(3, 17)), |
||
341 | ], |
||
342 | 'mutations' => [], |
||
343 | 'fragments' => [ |
||
344 | new Fragment('FullType', '__Type', [], [ |
||
345 | new Field('kind', null, [], [], new Location(23, 17)), |
||
346 | new Field('name', null, [], [], new Location(24, 17)), |
||
347 | new Field('description', null, [], [], new Location(25, 17)), |
||
348 | new Query('fields', null, [], [ |
||
349 | new Field('name', null, [], [], new Location(27, 21)), |
||
350 | new Field('description', null, [], [], new Location(28, 21)), |
||
351 | new Query('args', null, [], [ |
||
352 | new FragmentReference('InputValue', new Location(30, 28)), |
||
353 | ], [], new Location(29, 21)), |
||
354 | new Query('type', null, [], [ |
||
355 | new FragmentReference('TypeRef', new Location(33, 28)), |
||
356 | ], [], new Location(32, 21)), |
||
357 | new Field('isDeprecated', null, [], [], new Location(35, 21)), |
||
358 | new Field('deprecationReason', null, [], [], new Location(36, 21)), |
||
359 | ], [], new Location(26, 17)), |
||
360 | new Query('inputFields', null, [], [ |
||
361 | new FragmentReference('InputValue', new Location(39, 24)), |
||
362 | ], [], new Location(38, 17)), |
||
363 | new Query('interfaces', null, [], [ |
||
364 | new FragmentReference('TypeRef', new Location(42, 24)), |
||
365 | ], [], new Location(41, 17)), |
||
366 | new Query('enumValues', null, [], [ |
||
367 | new Field('name', null, [], [], new Location(45, 21)), |
||
368 | new Field('description', null, [], [], new Location(46, 21)), |
||
369 | |||
370 | new Field('isDeprecated', null, [], [], new Location(47, 21)), |
||
371 | new Field('deprecationReason', null, [], [], new Location(48, 21)), |
||
372 | ], [], new Location(44, 17)), |
||
373 | new Query('possibleTypes', null, [], [ |
||
374 | new FragmentReference('TypeRef', new Location(51, 24)), |
||
375 | ], [], new Location(50, 17)), |
||
376 | ], new Location(22, 22)), |
||
377 | new Fragment('InputValue', '__InputValue', [], [ |
||
378 | new Field('name', null, [], [], new Location(56, 17)), |
||
379 | new Field('description', null, [], [], new Location(57, 17)), |
||
380 | new Query('type', null, [], [ |
||
381 | new FragmentReference('TypeRef', new Location(58, 27)), |
||
382 | ], [], new Location(58, 17)), |
||
383 | new Field('defaultValue', null, [], [], new Location(59, 17)), |
||
384 | ], new Location(55, 22)), |
||
385 | new Fragment('TypeRef', '__Type', [], [ |
||
386 | new Field('kind', null, [], [], new Location(63, 17)), |
||
387 | new Field('name', null, [], [], new Location(64, 17)), |
||
388 | new Query('ofType', null, [], [ |
||
389 | new Field('kind', null, [], [], new Location(66, 21)), |
||
390 | new Field('name', null, [], [], new Location(67, 21)), |
||
391 | new Query('ofType', null, [], [ |
||
392 | new Field('kind', null, [], [], new Location(69, 25)), |
||
393 | new Field('name', null, [], [], new Location(70, 25)), |
||
394 | new Query('ofType', null, [], [ |
||
395 | new Field('kind', null, [], [], new Location(72, 29)), |
||
396 | new Field('name', null, [], [], new Location(73, 29)), |
||
397 | ], [], new Location(71, 25)), |
||
398 | ], [], new Location(68, 21)), |
||
399 | ], [], new Location(65, 17)), |
||
400 | ], new Location(62, 22)), |
||
401 | ], |
||
402 | 'fragmentReferences' => [ |
||
403 | new FragmentReference('FullType', new Location(7, 28)), |
||
404 | new FragmentReference('InputValue', new Location(13, 32)), |
||
405 | new FragmentReference('InputValue', new Location(30, 28)), |
||
406 | new FragmentReference('TypeRef', new Location(33, 28)), |
||
407 | new FragmentReference('InputValue', new Location(39, 24)), |
||
408 | new FragmentReference('TypeRef', new Location(42, 24)), |
||
409 | new FragmentReference('TypeRef', new Location(51, 24)), |
||
410 | new FragmentReference('TypeRef', new Location(58, 27)), |
||
411 | ], |
||
412 | 'variables' => [], |
||
413 | 'variableReferences' => [], |
||
414 | ], $data); |
||
415 | } |
||
416 | |||
417 | public function wrongQueriesProvider() |
||
418 | { |
||
419 | return [ |
||
420 | ['{ test (a: "asd", b: <basd>) { id }'], |
||
421 | ['{ test (asd: [..., asd]) { id } }'], |
||
422 | ['{ test (asd: { "a": 4, "m": null, "asd": false "b": 5, "c" : { a }}) { id } }'], |
||
423 | ['asdasd'], |
||
424 | ['mutation { test(asd: ... ){ ...,asd, asd } }'], |
||
425 | ['mutation { test{ . test on Test { id } } }'], |
||
426 | ['mutation { test( a: "asdd'], |
||
427 | ['mutation { test( a: { "asd": 12 12'], |
||
428 | ['mutation { test( a: { "asd": 12'], |
||
429 | ]; |
||
430 | } |
||
431 | |||
432 | /** |
||
433 | * @dataProvider mutationProvider |
||
434 | * |
||
435 | * @param mixed $query |
||
436 | * @param mixed $structure |
||
437 | */ |
||
438 | public function testMutations($query, $structure): void |
||
439 | { |
||
440 | $parser = new Parser(); |
||
441 | |||
442 | $parsedStructure = $parser->parse($query); |
||
443 | |||
444 | $this->assertEquals($parsedStructure, $structure); |
||
445 | } |
||
446 | |||
447 | public function testTypedFragment(): void |
||
448 | { |
||
449 | $parser = new Parser(); |
||
450 | $parsedStructure = $parser->parse(' |
||
451 | { |
||
452 | test: test { |
||
453 | name, |
||
454 | ... on UnionType { |
||
455 | unionName |
||
456 | } |
||
457 | } |
||
458 | } |
||
459 | '); |
||
460 | |||
461 | $this->assertEquals($parsedStructure, [ |
||
462 | 'queries' => [ |
||
463 | new Query( |
||
464 | 'test', |
||
465 | 'test', |
||
466 | [], |
||
467 | [ |
||
468 | new Field('name', null, [], [], new Location(4, 21)), |
||
469 | new TypedFragmentReference('UnionType', [new Field('unionName', null, [], [], new Location(6, 25))], [], new Location(5, 28)), |
||
470 | ], |
||
471 | [], |
||
472 | new Location(3, 23) |
||
473 | ), |
||
474 | ], |
||
475 | 'mutations' => [], |
||
476 | 'fragments' => [], |
||
477 | 'fragmentReferences' => [], |
||
478 | 'variables' => [], |
||
479 | 'variableReferences' => [], |
||
480 | ]); |
||
481 | } |
||
482 | |||
483 | public function mutationProvider() |
||
484 | { |
||
485 | return [ |
||
486 | [ |
||
487 | 'query ($variable: Int){ query ( teas: $variable ) { alias: name } }', |
||
488 | [ |
||
489 | 'queries' => [ |
||
490 | new Query( |
||
491 | 'query', |
||
492 | null, |
||
493 | [ |
||
494 | 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)), |
||
495 | ], |
||
496 | [ |
||
497 | new Field('name', 'alias', [], [], new Location(1, 60)), |
||
498 | ], |
||
499 | [], |
||
500 | new Location(1, 25) |
||
501 | ), |
||
502 | ], |
||
503 | 'mutations' => [], |
||
504 | 'fragments' => [], |
||
505 | 'fragmentReferences' => [], |
||
506 | 'variables' => [ |
||
507 | (new Variable('variable', 'Int', false, false, true, new Location(1, 8)))->setUsed(true), |
||
508 | ], |
||
509 | 'variableReferences' => [ |
||
510 | new VariableReference('variable', (new Variable('variable', 'Int', false, false, true, new Location(1, 8)))->setUsed(true), new Location(1, 39)), |
||
511 | ], |
||
512 | ], |
||
513 | ], |
||
514 | [ |
||
515 | '{ query { alias: name } }', |
||
516 | [ |
||
517 | 'queries' => [ |
||
518 | new Query('query', null, [], [new Field('name', 'alias', [], [], new Location(1, 18))], [], new Location(1, 3)), |
||
519 | ], |
||
520 | 'mutations' => [], |
||
521 | 'fragments' => [], |
||
522 | 'fragmentReferences' => [], |
||
523 | 'variables' => [], |
||
524 | 'variableReferences' => [], |
||
525 | ], |
||
526 | ], |
||
527 | [ |
||
528 | 'mutation { createUser ( email: "[email protected]", active: true ) { id } }', |
||
529 | [ |
||
530 | 'queries' => [], |
||
531 | 'mutations' => [ |
||
532 | new Mutation( |
||
533 | 'createUser', |
||
534 | null, |
||
535 | [ |
||
536 | new Argument('email', new Literal('[email protected]', new Location(1, 33)), new Location(1, 25)), |
||
537 | new Argument('active', new Literal(true, new Location(1, 57)), new Location(1, 49)), |
||
538 | ], |
||
539 | [ |
||
540 | new Field('id', null, [], [], new Location(1, 66)), |
||
541 | ], |
||
542 | [], |
||
543 | new Location(1, 12) |
||
544 | ), |
||
545 | ], |
||
546 | 'fragments' => [], |
||
547 | 'fragmentReferences' => [], |
||
548 | 'variables' => [], |
||
549 | 'variableReferences' => [], |
||
550 | ], |
||
551 | ], |
||
552 | [ |
||
553 | 'mutation { test : createUser (id: 4) }', |
||
554 | [ |
||
555 | 'queries' => [], |
||
556 | 'mutations' => [ |
||
557 | new Mutation( |
||
558 | 'createUser', |
||
559 | 'test', |
||
560 | [ |
||
561 | new Argument('id', new Literal(4, new Location(1, 35)), new Location(1, 31)), |
||
562 | ], |
||
563 | [], |
||
564 | [], |
||
565 | new Location(1, 19) |
||
566 | ), |
||
567 | ], |
||
568 | 'fragments' => [], |
||
569 | 'fragmentReferences' => [], |
||
570 | 'variables' => [], |
||
571 | 'variableReferences' => [], |
||
572 | ], |
||
573 | ], |
||
574 | ]; |
||
575 | } |
||
576 | |||
577 | /** |
||
578 | * @dataProvider queryProvider |
||
579 | * |
||
580 | * @param mixed $query |
||
581 | * @param mixed $structure |
||
582 | */ |
||
583 | public function testParser($query, $structure): void |
||
584 | { |
||
585 | $parser = new Parser(); |
||
586 | $parsedStructure = $parser->parse($query); |
||
587 | |||
588 | $this->assertEquals($structure, $parsedStructure); |
||
589 | } |
||
590 | |||
591 | public function queryProvider() |
||
592 | { |
||
593 | return [ |
||
594 | [ |
||
595 | '{ film(id: 1 filmID: 2) { title } }', |
||
596 | [ |
||
597 | 'queries' => [ |
||
598 | new Query('film', null, [ |
||
599 | new Argument('id', new Literal(1, new Location(1, 12)), new Location(1, 8)), |
||
600 | new Argument('filmID', new Literal(2, new Location(1, 22)), new Location(1, 14)), |
||
601 | ], [ |
||
602 | new Field('title', null, [], [], new Location(1, 27)), |
||
603 | ], [], new Location(1, 3)), |
||
604 | ], |
||
605 | 'mutations' => [], |
||
606 | 'fragments' => [], |
||
607 | 'fragmentReferences' => [], |
||
608 | 'variables' => [], |
||
609 | 'variableReferences' => [], |
||
610 | ], |
||
611 | ], |
||
612 | [ |
||
613 | '{ test (id: -5) { id } } ', |
||
614 | [ |
||
615 | 'queries' => [ |
||
616 | new Query('test', null, [ |
||
617 | new Argument('id', new Literal(-5, new Location(1, 13)), new Location(1, 9)), |
||
618 | ], [ |
||
619 | new Field('id', null, [], [], new Location(1, 19)), |
||
620 | ], [], new Location(1, 3)), |
||
621 | ], |
||
622 | 'mutations' => [], |
||
623 | 'fragments' => [], |
||
624 | 'fragmentReferences' => [], |
||
625 | 'variables' => [], |
||
626 | 'variableReferences' => [], |
||
627 | ], |
||
628 | ], |
||
629 | [ |
||
630 | "{ test (id: -5) \r\n { id } } ", |
||
631 | [ |
||
632 | 'queries' => [ |
||
633 | new Query('test', null, [ |
||
634 | new Argument('id', new Literal(-5, new Location(1, 13)), new Location(1, 9)), |
||
635 | ], [ |
||
636 | new Field('id', null, [], [], new Location(2, 4)), |
||
637 | ], [], new Location(1, 3)), |
||
638 | ], |
||
639 | 'mutations' => [], |
||
640 | 'fragments' => [], |
||
641 | 'fragmentReferences' => [], |
||
642 | 'variables' => [], |
||
643 | 'variableReferences' => [], |
||
644 | ], |
||
645 | ], |
||
646 | [ |
||
647 | 'query CheckTypeOfLuke { |
||
648 | hero(episode: EMPIRE) { |
||
649 | __typename, |
||
650 | name |
||
651 | } |
||
652 | }', |
||
653 | [ |
||
654 | 'queries' => [ |
||
655 | new Query('hero', null, [ |
||
656 | new Argument('episode', new Literal('EMPIRE', new Location(2, 33)), new Location(2, 24)), |
||
657 | ], [ |
||
658 | new Field('__typename', null, [], [], new Location(3, 21)), |
||
659 | new Field('name', null, [], [], new Location(4, 21)), |
||
660 | ], [], new Location(2, 19)), |
||
661 | ], |
||
662 | 'mutations' => [], |
||
663 | 'fragments' => [], |
||
664 | 'fragmentReferences' => [], |
||
665 | 'variables' => [], |
||
666 | 'variableReferences' => [], |
||
667 | ], |
||
668 | ], |
||
669 | [ |
||
670 | '{ test { __typename, id } }', |
||
671 | [ |
||
672 | 'queries' => [ |
||
673 | new Query('test', null, [], [ |
||
674 | new Field('__typename', null, [], [], new Location(1, 10)), |
||
675 | new Field('id', null, [], [], new Location(1, 22)), |
||
676 | ], [], new Location(1, 3)), |
||
677 | ], |
||
678 | 'mutations' => [], |
||
679 | 'fragments' => [], |
||
680 | 'fragmentReferences' => [], |
||
681 | 'variables' => [], |
||
682 | 'variableReferences' => [], |
||
683 | ], |
||
684 | ], |
||
685 | [ |
||
686 | '{}', |
||
687 | [ |
||
688 | 'queries' => [], |
||
689 | 'mutations' => [], |
||
690 | 'fragments' => [], |
||
691 | 'fragmentReferences' => [], |
||
692 | 'variables' => [], |
||
693 | 'variableReferences' => [], |
||
694 | ], |
||
695 | ], |
||
696 | [ |
||
697 | 'query test {}', |
||
698 | [ |
||
699 | 'queries' => [], |
||
700 | 'mutations' => [], |
||
701 | 'fragments' => [], |
||
702 | 'fragmentReferences' => [], |
||
703 | 'variables' => [], |
||
704 | 'variableReferences' => [], |
||
705 | ], |
||
706 | ], |
||
707 | [ |
||
708 | 'query {}', |
||
709 | [ |
||
710 | 'queries' => [], |
||
711 | 'mutations' => [], |
||
712 | 'fragments' => [], |
||
713 | 'fragmentReferences' => [], |
||
714 | 'variables' => [], |
||
715 | 'variableReferences' => [], |
||
716 | ], |
||
717 | ], |
||
718 | [ |
||
719 | 'mutation setName { setUserName }', |
||
720 | [ |
||
721 | 'queries' => [], |
||
722 | 'mutations' => [new Mutation('setUserName', null, [], [], [], new Location(1, 20))], |
||
723 | 'fragments' => [], |
||
724 | 'fragmentReferences' => [], |
||
725 | 'variables' => [], |
||
726 | 'variableReferences' => [], |
||
727 | ], |
||
728 | ], |
||
729 | [ |
||
730 | '{ test { ...userDataFragment } } fragment userDataFragment on User { id, name, email }', |
||
731 | [ |
||
732 | 'queries' => [ |
||
733 | new Query('test', null, [], [new FragmentReference('userDataFragment', new Location(1, 13))], [], new Location(1, 3)), |
||
734 | ], |
||
735 | 'mutations' => [], |
||
736 | 'fragments' => [ |
||
737 | new Fragment('userDataFragment', 'User', [], [ |
||
738 | new Field('id', null, [], [], new Location(1, 70)), |
||
739 | new Field('name', null, [], [], new Location(1, 74)), |
||
740 | new Field('email', null, [], [], new Location(1, 80)), |
||
741 | ], new Location(1, 43)), |
||
742 | ], |
||
743 | 'fragmentReferences' => [ |
||
744 | new FragmentReference('userDataFragment', new Location(1, 13)), |
||
745 | ], |
||
746 | 'variables' => [], |
||
747 | 'variableReferences' => [], |
||
748 | ], |
||
749 | ], |
||
750 | [ |
||
751 | '{ user (id: 10, name: "max", float: 123.123 ) { id, name } }', |
||
752 | [ |
||
753 | 'queries' => [ |
||
754 | new Query( |
||
755 | 'user', |
||
756 | null, |
||
757 | [ |
||
758 | new Argument('id', new Literal('10', new Location(1, 13)), new Location(1, 9)), |
||
759 | new Argument('name', new Literal('max', new Location(1, 24)), new Location(1, 17)), |
||
760 | new Argument('float', new Literal('123.123', new Location(1, 37)), new Location(1, 30)), |
||
761 | ], |
||
762 | [ |
||
763 | new Field('id', null, [], [], new Location(1, 49)), |
||
764 | new Field('name', null, [], [], new Location(1, 53)), |
||
765 | ], |
||
766 | [], |
||
767 | new Location(1, 3) |
||
768 | ), |
||
769 | ], |
||
770 | 'mutations' => [], |
||
771 | 'fragments' => [], |
||
772 | 'fragmentReferences' => [], |
||
773 | 'variables' => [], |
||
774 | 'variableReferences' => [], |
||
775 | ], |
||
776 | ], |
||
777 | [ |
||
778 | '{ allUsers : users ( id: [ 1, 2, 3] ) { id } }', |
||
779 | [ |
||
780 | 'queries' => [ |
||
781 | new Query( |
||
782 | 'users', |
||
783 | 'allUsers', |
||
784 | [ |
||
785 | new Argument('id', new InputList([1, 2, 3], new Location(1, 26)), new Location(1, 22)), |
||
786 | ], |
||
787 | [ |
||
788 | new Field('id', null, [], [], new Location(1, 41)), |
||
789 | ], |
||
790 | [], |
||
791 | new Location(1, 14) |
||
792 | ), |
||
793 | ], |
||
794 | 'mutations' => [], |
||
795 | 'fragments' => [], |
||
796 | 'fragmentReferences' => [], |
||
797 | 'variables' => [], |
||
798 | 'variableReferences' => [], |
||
799 | ], |
||
800 | ], |
||
801 | [ |
||
802 | '{ allUsers : users ( id: [ 1, "2", true, null] ) { id } }', |
||
803 | [ |
||
804 | 'queries' => [ |
||
805 | new Query( |
||
806 | 'users', |
||
807 | 'allUsers', |
||
808 | [ |
||
809 | new Argument('id', new InputList([1, '2', true, null], new Location(1, 26)), new Location(1, 22)), |
||
810 | ], |
||
811 | [ |
||
812 | new Field('id', null, [], [], new Location(1, 52)), |
||
813 | ], |
||
814 | [], |
||
815 | new Location(1, 14) |
||
816 | ), |
||
817 | ], |
||
818 | 'mutations' => [], |
||
819 | 'fragments' => [], |
||
820 | 'fragmentReferences' => [], |
||
821 | 'variables' => [], |
||
822 | 'variableReferences' => [], |
||
823 | ], |
||
824 | ], |
||
825 | [ |
||
826 | '{ allUsers : users ( object: { "a": 123, "d": "asd", "b" : [ 1, 2, 4 ], "c": { "a" : 123, "b": "asd" } } ) { id } }', |
||
827 | [ |
||
828 | 'queries' => [ |
||
829 | new Query( |
||
830 | 'users', |
||
831 | 'allUsers', |
||
832 | [ |
||
833 | new Argument('object', new InputObject([ |
||
834 | 'a' => 123, |
||
835 | 'd' => 'asd', |
||
836 | 'b' => [1, 2, 4], |
||
837 | 'c' => new InputObject([ |
||
838 | 'a' => 123, |
||
839 | 'b' => 'asd', |
||
840 | ], new Location(1, 79)), |
||
841 | ], new Location(1, 30)), new Location(1, 22)), |
||
842 | ], |
||
843 | [ |
||
844 | new Field('id', null, [], [], new Location(1, 112)), |
||
845 | ], |
||
846 | [], |
||
847 | new Location(1, 14) |
||
848 | ), |
||
849 | ], |
||
850 | 'mutations' => [], |
||
851 | 'fragments' => [], |
||
852 | 'fragmentReferences' => [], |
||
853 | 'variables' => [], |
||
854 | 'variableReferences' => [], |
||
855 | ], |
||
856 | ], |
||
857 | ]; |
||
858 | } |
||
859 | |||
860 | public function testVariablesInQuery(): void |
||
861 | { |
||
862 | $parser = new Parser(); |
||
863 | |||
864 | $data = $parser->parse(' |
||
865 | query StarWarsAppHomeRoute($names_0:[String!]!, $query: String) { |
||
866 | factions(names:$names_0, test: $query) { |
||
867 | id, |
||
868 | ...F2 |
||
869 | } |
||
870 | } |
||
871 | fragment F0 on Ship { |
||
872 | id, |
||
873 | name |
||
874 | } |
||
875 | fragment F1 on Faction { |
||
876 | id, |
||
877 | factionId |
||
878 | } |
||
879 | fragment F2 on Faction { |
||
880 | id, |
||
881 | factionId, |
||
882 | name, |
||
883 | _shipsDRnzJ:ships(first:10) { |
||
884 | edges { |
||
885 | node { |
||
886 | id, |
||
887 | ...F0 |
||
888 | }, |
||
889 | cursor |
||
890 | }, |
||
891 | pageInfo { |
||
892 | hasNextPage, |
||
893 | hasPreviousPage |
||
894 | } |
||
895 | }, |
||
928 |