|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* Date: 01.12.15 |
|
4
|
|
|
* |
|
5
|
|
|
* @author Portey Vasil <[email protected]> |
|
6
|
|
|
*/ |
|
7
|
|
|
|
|
8
|
|
|
namespace Youshido\tests\GraphQL\Parser; |
|
9
|
|
|
|
|
10
|
|
|
use Youshido\GraphQL\Parser\Ast\Argument; |
|
11
|
|
|
use Youshido\GraphQL\Parser\Ast\Field; |
|
12
|
|
|
use Youshido\GraphQL\Parser\Ast\Fragment; |
|
13
|
|
|
use Youshido\GraphQL\Parser\Ast\FragmentReference; |
|
14
|
|
|
use Youshido\GraphQL\Parser\Ast\Mutation; |
|
15
|
|
|
use Youshido\GraphQL\Parser\Ast\TypedFragmentReference; |
|
16
|
|
|
use Youshido\GraphQL\Parser\Value\InputList; |
|
17
|
|
|
use Youshido\GraphQL\Parser\Value\InputObject; |
|
18
|
|
|
use Youshido\GraphQL\Parser\Value\Literal; |
|
19
|
|
|
use Youshido\GraphQL\Parser\Ast\Query; |
|
20
|
|
|
use Youshido\GraphQL\Parser\Parser; |
|
21
|
|
|
use Youshido\GraphQL\Parser\Value\Variable; |
|
22
|
|
|
|
|
23
|
|
|
class ParserTest extends \PHPUnit_Framework_TestCase |
|
24
|
|
|
{ |
|
25
|
|
|
|
|
26
|
|
|
|
|
27
|
|
View Code Duplication |
public function testComments() |
|
|
|
|
|
|
28
|
|
|
{ |
|
29
|
|
|
$query = ' |
|
30
|
|
|
# asdasd "asdasdasd" |
|
31
|
|
|
|
|
32
|
|
|
query { |
|
33
|
|
|
authors (category: "#2") { #asda asd |
|
34
|
|
|
_id |
|
35
|
|
|
} |
|
36
|
|
|
} |
|
37
|
|
|
'; |
|
38
|
|
|
|
|
39
|
|
|
|
|
40
|
|
|
$parser = new Parser(); |
|
41
|
|
|
|
|
42
|
|
|
$parser->setSource($query); |
|
43
|
|
|
|
|
44
|
|
|
$this->assertEquals($parser->parse(), [ |
|
45
|
|
|
'queries' => [ |
|
46
|
|
|
new Query('authors', null, |
|
47
|
|
|
[ |
|
48
|
|
|
new Argument('category', new Literal('#2')) |
|
49
|
|
|
], |
|
50
|
|
|
[ |
|
51
|
|
|
new Field('_id', null), |
|
52
|
|
|
]) |
|
53
|
|
|
], |
|
54
|
|
|
'mutations' => [], |
|
55
|
|
|
'fragments' => [] |
|
56
|
|
|
]); |
|
57
|
|
|
} |
|
58
|
|
|
|
|
59
|
|
|
|
|
60
|
|
|
/** |
|
61
|
|
|
* @param $query string |
|
62
|
|
|
* |
|
63
|
|
|
* @dataProvider wrongQueriesProvider |
|
64
|
|
|
* @expectedException Youshido\GraphQL\Parser\SyntaxErrorException |
|
65
|
|
|
*/ |
|
66
|
|
|
public function testWrongQueries($query) |
|
67
|
|
|
{ |
|
68
|
|
|
$parser = new Parser(); |
|
69
|
|
|
|
|
70
|
|
|
$parser->setSource($query); |
|
71
|
|
|
$parser->parse(); |
|
72
|
|
|
} |
|
73
|
|
|
|
|
74
|
|
|
public function testGoogleExtensionQuery() |
|
75
|
|
|
{ |
|
76
|
|
|
$parser = new Parser(); |
|
77
|
|
|
|
|
78
|
|
|
$parser->setSource(' |
|
79
|
|
|
query IntrospectionQuery { |
|
80
|
|
|
__schema { |
|
81
|
|
|
queryType { name } |
|
82
|
|
|
mutationType { name } |
|
83
|
|
|
types { |
|
84
|
|
|
...FullType |
|
85
|
|
|
} |
|
86
|
|
|
directives { |
|
87
|
|
|
name |
|
88
|
|
|
description |
|
89
|
|
|
args { |
|
90
|
|
|
...InputValue |
|
91
|
|
|
} |
|
92
|
|
|
onOperation |
|
93
|
|
|
onFragment |
|
94
|
|
|
onField |
|
95
|
|
|
} |
|
96
|
|
|
} |
|
97
|
|
|
} |
|
98
|
|
|
|
|
99
|
|
|
fragment FullType on __Type { |
|
100
|
|
|
kind |
|
101
|
|
|
name |
|
102
|
|
|
description |
|
103
|
|
|
fields { |
|
104
|
|
|
name |
|
105
|
|
|
description |
|
106
|
|
|
args { |
|
107
|
|
|
...InputValue |
|
108
|
|
|
} |
|
109
|
|
|
type { |
|
110
|
|
|
...TypeRef |
|
111
|
|
|
} |
|
112
|
|
|
isDeprecated |
|
113
|
|
|
deprecationReason |
|
114
|
|
|
} |
|
115
|
|
|
inputFields { |
|
116
|
|
|
...InputValue |
|
117
|
|
|
} |
|
118
|
|
|
interfaces { |
|
119
|
|
|
...TypeRef |
|
120
|
|
|
} |
|
121
|
|
|
enumValues { |
|
122
|
|
|
name |
|
123
|
|
|
description |
|
124
|
|
|
isDeprecated |
|
125
|
|
|
deprecationReason |
|
126
|
|
|
} |
|
127
|
|
|
possibleTypes { |
|
128
|
|
|
...TypeRef |
|
129
|
|
|
} |
|
130
|
|
|
} |
|
131
|
|
|
|
|
132
|
|
|
fragment InputValue on __InputValue { |
|
133
|
|
|
name |
|
134
|
|
|
description |
|
135
|
|
|
type { ...TypeRef } |
|
136
|
|
|
defaultValue |
|
137
|
|
|
} |
|
138
|
|
|
|
|
139
|
|
|
fragment TypeRef on __Type { |
|
140
|
|
|
kind |
|
141
|
|
|
name |
|
142
|
|
|
ofType { |
|
143
|
|
|
kind |
|
144
|
|
|
name |
|
145
|
|
|
ofType { |
|
146
|
|
|
kind |
|
147
|
|
|
name |
|
148
|
|
|
ofType { |
|
149
|
|
|
kind |
|
150
|
|
|
name |
|
151
|
|
|
} |
|
152
|
|
|
} |
|
153
|
|
|
} |
|
154
|
|
|
} |
|
155
|
|
|
'); |
|
156
|
|
|
|
|
157
|
|
|
$this->assertTrue(is_array($parser->parse())); |
|
158
|
|
|
} |
|
159
|
|
|
|
|
160
|
|
|
|
|
161
|
|
|
public function wrongQueriesProvider() |
|
162
|
|
|
{ |
|
163
|
|
|
return [ |
|
164
|
|
|
['{ test { id,, asd } }'], |
|
165
|
|
|
['{ test { id,, } }'], |
|
166
|
|
|
['{ test (a: $a, b: <basd>) { id }'], |
|
167
|
|
|
['{ test (asd: [..., asd]) { id } }'], |
|
168
|
|
|
['{ test (asd: { "a": 4, b: 5}) { id } }'], |
|
169
|
|
|
['{ test (asd: { "a": 4, "m": null, "asd": false "b": 5, "c" : { a }}) { id } }'], |
|
170
|
|
|
['asdasd'], |
|
171
|
|
|
['mutation { test(asd: ... ){ ...,asd, asd } }'], |
|
172
|
|
|
['mutation { test( asd: $,as ){ ...,asd, asd } }'] |
|
173
|
|
|
]; |
|
174
|
|
|
} |
|
175
|
|
|
|
|
176
|
|
|
/** |
|
177
|
|
|
* @dataProvider mutationProvider |
|
178
|
|
|
*/ |
|
179
|
|
|
public function testMutations($query, $structure) |
|
180
|
|
|
{ |
|
181
|
|
|
$parser = new Parser(); |
|
182
|
|
|
$parser->setSource($query); |
|
183
|
|
|
|
|
184
|
|
|
$parsedStructure = $parser->parse(); |
|
185
|
|
|
|
|
186
|
|
|
$this->assertEquals($parsedStructure, $structure); |
|
187
|
|
|
} |
|
188
|
|
|
|
|
189
|
|
View Code Duplication |
public function testTypedFragment() |
|
|
|
|
|
|
190
|
|
|
{ |
|
191
|
|
|
$parser = new Parser(); |
|
192
|
|
|
$parser->setSource(' |
|
193
|
|
|
{ |
|
194
|
|
|
test: test { |
|
195
|
|
|
name, |
|
196
|
|
|
... on UnionType { |
|
197
|
|
|
unionName |
|
198
|
|
|
} |
|
199
|
|
|
} |
|
200
|
|
|
} |
|
201
|
|
|
'); |
|
202
|
|
|
|
|
203
|
|
|
$parsedStructure = $parser->parse(); |
|
204
|
|
|
|
|
205
|
|
|
$this->assertEquals($parsedStructure, [ |
|
206
|
|
|
'queries' => [ |
|
207
|
|
|
new Query('test', 'test', [], |
|
208
|
|
|
[ |
|
209
|
|
|
new Field('name', null), |
|
210
|
|
|
new TypedFragmentReference('UnionType', [ |
|
211
|
|
|
new Field('unionName') |
|
212
|
|
|
]) |
|
213
|
|
|
]) |
|
214
|
|
|
], |
|
215
|
|
|
'mutations' => [], |
|
216
|
|
|
'fragments' => [] |
|
217
|
|
|
]); |
|
218
|
|
|
} |
|
219
|
|
|
|
|
220
|
|
|
public function mutationProvider() |
|
221
|
|
|
{ |
|
222
|
|
|
return [ |
|
223
|
|
|
[ |
|
224
|
|
|
'{ query ( teas: $variable ) { alias: name } }', |
|
225
|
|
|
[ |
|
226
|
|
|
'queries' => [ |
|
227
|
|
|
new Query('query', null, |
|
228
|
|
|
[ |
|
229
|
|
|
new Argument('teas', new Variable('variable')) |
|
230
|
|
|
], |
|
231
|
|
|
[ |
|
232
|
|
|
new Field('name', 'alias') |
|
233
|
|
|
]) |
|
234
|
|
|
], |
|
235
|
|
|
'mutations' => [], |
|
236
|
|
|
'fragments' => [] |
|
237
|
|
|
] |
|
238
|
|
|
], |
|
239
|
|
|
[ |
|
240
|
|
|
'{ query { alias: name } }', |
|
241
|
|
|
[ |
|
242
|
|
|
'queries' => [ |
|
243
|
|
|
new Query('query', null, [], [new Field('name', 'alias')]) |
|
244
|
|
|
], |
|
245
|
|
|
'mutations' => [], |
|
246
|
|
|
'fragments' => [] |
|
247
|
|
|
] |
|
248
|
|
|
], |
|
249
|
|
|
[ |
|
250
|
|
|
'mutation { createUser ( email: "[email protected]", active: true ) { id } }', |
|
251
|
|
|
[ |
|
252
|
|
|
'queries' => [], |
|
253
|
|
|
'mutations' => [ |
|
254
|
|
|
new Mutation( |
|
255
|
|
|
'createUser', |
|
256
|
|
|
null, |
|
257
|
|
|
[ |
|
258
|
|
|
new Argument('email', new Literal('[email protected]')), |
|
259
|
|
|
new Argument('active', new Literal(true)), |
|
260
|
|
|
], |
|
261
|
|
|
[ |
|
262
|
|
|
new Field('id') |
|
263
|
|
|
] |
|
264
|
|
|
) |
|
265
|
|
|
], |
|
266
|
|
|
'fragments' => [] |
|
267
|
|
|
] |
|
268
|
|
|
], |
|
269
|
|
|
[ |
|
270
|
|
|
'mutation { test : createUser (id: 4) }', |
|
271
|
|
|
[ |
|
272
|
|
|
'queries' => [], |
|
273
|
|
|
'mutations' => [ |
|
274
|
|
|
new Mutation( |
|
275
|
|
|
'createUser', |
|
276
|
|
|
'test', |
|
277
|
|
|
[ |
|
278
|
|
|
new Argument('id', new Literal(4)), |
|
279
|
|
|
], |
|
280
|
|
|
[] |
|
281
|
|
|
) |
|
282
|
|
|
], |
|
283
|
|
|
'fragments' => [] |
|
284
|
|
|
] |
|
285
|
|
|
] |
|
286
|
|
|
]; |
|
287
|
|
|
} |
|
288
|
|
|
|
|
289
|
|
|
/** |
|
290
|
|
|
* @dataProvider queryProvider |
|
291
|
|
|
*/ |
|
292
|
|
|
public function testParser($query, $structure) |
|
293
|
|
|
{ |
|
294
|
|
|
$parser = new Parser(); |
|
295
|
|
|
$parser->setSource($query); |
|
296
|
|
|
|
|
297
|
|
|
$parsedStructure = $parser->parse(); |
|
298
|
|
|
|
|
299
|
|
|
$this->assertEquals($parsedStructure, $structure); |
|
300
|
|
|
} |
|
301
|
|
|
|
|
302
|
|
|
|
|
303
|
|
|
public function queryProvider() |
|
304
|
|
|
{ |
|
305
|
|
|
return [ |
|
306
|
|
|
[ |
|
307
|
|
|
'query CheckTypeOfLuke { |
|
308
|
|
|
hero(episode: EMPIRE) { |
|
309
|
|
|
__typename, |
|
310
|
|
|
name |
|
311
|
|
|
} |
|
312
|
|
|
}', |
|
313
|
|
|
[ |
|
314
|
|
|
'queries' => [ |
|
315
|
|
|
new Query('hero', null, [ |
|
316
|
|
|
new Argument('episode', new Literal('EMPIRE')) |
|
317
|
|
|
], [ |
|
318
|
|
|
new Field('__typename'), |
|
319
|
|
|
new Field('name'), |
|
320
|
|
|
]) |
|
321
|
|
|
], |
|
322
|
|
|
'mutations' => [], |
|
323
|
|
|
'fragments' => [] |
|
324
|
|
|
] |
|
325
|
|
|
], |
|
326
|
|
|
[ |
|
327
|
|
|
'{ test { __typename, id } }', |
|
328
|
|
|
[ |
|
329
|
|
|
'queries' => [ |
|
330
|
|
|
new Query('test', null, [], [ |
|
331
|
|
|
new Field('__typename'), |
|
332
|
|
|
new Field('id'), |
|
333
|
|
|
]) |
|
334
|
|
|
], |
|
335
|
|
|
'mutations' => [], |
|
336
|
|
|
'fragments' => [] |
|
337
|
|
|
] |
|
338
|
|
|
], |
|
339
|
|
|
[ |
|
340
|
|
|
'{}', |
|
341
|
|
|
[ |
|
342
|
|
|
'queries' => [], |
|
343
|
|
|
'mutations' => [], |
|
344
|
|
|
'fragments' => [] |
|
345
|
|
|
] |
|
346
|
|
|
], |
|
347
|
|
|
[ |
|
348
|
|
|
'query test {}', |
|
349
|
|
|
[ |
|
350
|
|
|
'queries' => [], |
|
351
|
|
|
'mutations' => [], |
|
352
|
|
|
'fragments' => [] |
|
353
|
|
|
] |
|
354
|
|
|
], |
|
355
|
|
|
[ |
|
356
|
|
|
'query {}', |
|
357
|
|
|
[ |
|
358
|
|
|
'queries' => [], |
|
359
|
|
|
'mutations' => [], |
|
360
|
|
|
'fragments' => [] |
|
361
|
|
|
] |
|
362
|
|
|
], |
|
363
|
|
|
[ |
|
364
|
|
|
'mutation setName { setUserName }', |
|
365
|
|
|
[ |
|
366
|
|
|
'queries' => [], |
|
367
|
|
|
'mutations' => [new Mutation('setUserName')], |
|
368
|
|
|
'fragments' => [] |
|
369
|
|
|
] |
|
370
|
|
|
], |
|
371
|
|
|
[ |
|
372
|
|
|
'{ test { ...userDataFragment } } fragment userDataFragment on User { id, name, email }', |
|
373
|
|
|
[ |
|
374
|
|
|
'queries' => [ |
|
375
|
|
|
new Query('test', null, [], [new FragmentReference('userDataFragment')]) |
|
376
|
|
|
], |
|
377
|
|
|
'mutations' => [], |
|
378
|
|
|
'fragments' => [ |
|
379
|
|
|
new Fragment('userDataFragment', 'User', [ |
|
380
|
|
|
new Field('id'), |
|
381
|
|
|
new Field('name'), |
|
382
|
|
|
new Field('email') |
|
383
|
|
|
]) |
|
384
|
|
|
] |
|
385
|
|
|
] |
|
386
|
|
|
], |
|
387
|
|
|
[ |
|
388
|
|
|
'{ user (id: 10, name: "max", float: 123.123 ) { id, name } }', |
|
389
|
|
|
[ |
|
390
|
|
|
'queries' => [ |
|
391
|
|
|
new Query( |
|
392
|
|
|
'user', |
|
393
|
|
|
null, |
|
394
|
|
|
[ |
|
395
|
|
|
new Argument('id', new Literal('10')), |
|
396
|
|
|
new Argument('name', new Literal('max')), |
|
397
|
|
|
new Argument('float', new Literal('123.123')) |
|
398
|
|
|
], |
|
399
|
|
|
[ |
|
400
|
|
|
new Field('id'), |
|
401
|
|
|
new Field('name') |
|
402
|
|
|
] |
|
403
|
|
|
) |
|
404
|
|
|
], |
|
405
|
|
|
'mutations' => [], |
|
406
|
|
|
'fragments' => [] |
|
407
|
|
|
] |
|
408
|
|
|
], |
|
409
|
|
|
[ |
|
410
|
|
|
'{ allUsers : users ( id: [ 1, 2, 3] ) { id } }', |
|
411
|
|
|
[ |
|
412
|
|
|
'queries' => [ |
|
413
|
|
|
new Query( |
|
414
|
|
|
'users', |
|
415
|
|
|
'allUsers', |
|
416
|
|
|
[ |
|
417
|
|
|
new Argument('id', new InputList([1, 2, 3])) |
|
418
|
|
|
], |
|
419
|
|
|
[ |
|
420
|
|
|
new Field('id') |
|
421
|
|
|
] |
|
422
|
|
|
) |
|
423
|
|
|
], |
|
424
|
|
|
'mutations' => [], |
|
425
|
|
|
'fragments' => [] |
|
426
|
|
|
] |
|
427
|
|
|
], |
|
428
|
|
|
[ |
|
429
|
|
|
'{ allUsers : users ( id: [ 1, "2", true, null] ) { id } }', |
|
430
|
|
|
[ |
|
431
|
|
|
'queries' => [ |
|
432
|
|
|
new Query( |
|
433
|
|
|
'users', |
|
434
|
|
|
'allUsers', |
|
435
|
|
|
[ |
|
436
|
|
|
new Argument('id', new InputList([1, "2", true, null])) |
|
437
|
|
|
], |
|
438
|
|
|
[ |
|
439
|
|
|
new Field('id') |
|
440
|
|
|
] |
|
441
|
|
|
) |
|
442
|
|
|
], |
|
443
|
|
|
'mutations' => [], |
|
444
|
|
|
'fragments' => [] |
|
445
|
|
|
] |
|
446
|
|
|
], |
|
447
|
|
|
[ |
|
448
|
|
|
'{ allUsers : users ( object: { "a": 123, "d": "asd", "b" : [ 1, 2, 4 ], "c": { "a" : 123, "b": "asd" } } ) { id } }', |
|
449
|
|
|
[ |
|
450
|
|
|
'queries' => [ |
|
451
|
|
|
new Query( |
|
452
|
|
|
'users', |
|
453
|
|
|
'allUsers', |
|
454
|
|
|
[ |
|
455
|
|
|
new Argument('object', new InputObject([ |
|
456
|
|
|
'a' => 123, |
|
457
|
|
|
'd' => 'asd', |
|
458
|
|
|
'b' => [1, 2, 4], |
|
459
|
|
|
'c' => [ |
|
460
|
|
|
'a' => 123, |
|
461
|
|
|
'b' => 'asd' |
|
462
|
|
|
] |
|
463
|
|
|
])) |
|
464
|
|
|
], |
|
465
|
|
|
[ |
|
466
|
|
|
new Field('id') |
|
467
|
|
|
] |
|
468
|
|
|
) |
|
469
|
|
|
], |
|
470
|
|
|
'mutations' => [], |
|
471
|
|
|
'fragments' => [] |
|
472
|
|
|
] |
|
473
|
|
|
] |
|
474
|
|
|
]; |
|
475
|
|
|
} |
|
476
|
|
|
|
|
477
|
|
|
} |
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.