query_test.yml

  1parser provides useful errors:
  2  - name: unclosed paren
  3    input: '{'
  4    error:
  5      message: "Expected Name, found <EOF>"
  6      locations: [{line: 1, column: 2}]
  7
  8  - name: missing on in fragment
  9    input: |
 10      { ...MissingOn }
 11      fragment MissingOn Type
 12    error:
 13      message: 'Expected "on", found Name "Type"'
 14      locations: [{ line: 2, column: 20 }]
 15
 16  - name: missing name after alias
 17    input: '{ field: {} }'
 18    error:
 19      message: "Expected Name, found {"
 20      locations: [{ line: 1, column: 10 }]
 21
 22  - name: not an operation
 23    input: 'notanoperation Foo { field }'
 24    error:
 25      message: 'Unexpected Name "notanoperation"'
 26      locations: [{ line: 1, column: 1 }]
 27
 28  - name: a wild splat appears
 29    input: '...'
 30    error:
 31      message: 'Unexpected ...'
 32      locations: [{ line: 1, column: 1}]
 33
 34variables:
 35  - name: are allowed in args
 36    input: '{ field(complex: { a: { b: [ $var ] } }) }'
 37
 38  - name: are not allowed in default args
 39    input: 'query Foo($x: Complex = { a: { b: [ $var ] } }) { field }'
 40    error:
 41      message: 'Unexpected $'
 42      locations: [{ line: 1, column: 37 }]
 43
 44fragments:
 45  - name: can not be named 'on'
 46    input: 'fragment on on on { on }'
 47    error:
 48      message: 'Unexpected Name "on"'
 49      locations: [{ line: 1, column: 10 }]
 50
 51  - name: can not spread fragments called 'on'
 52    input: '{ ...on }'
 53    error:
 54      message: 'Expected Name, found }'
 55      locations: [{ line: 1, column: 9 }]
 56
 57encoding:
 58  - name: multibyte characters are supported
 59    input: |
 60      # This comment has a ਊ multi-byte character.
 61      { field(arg: "Has a ਊ multi-byte character.") }
 62    ast: |
 63      <QueryDocument>
 64        Operations: [OperationDefinition]
 65        - <OperationDefinition>
 66            Operation: Operation("query")
 67            SelectionSet: [Selection]
 68            - <Field>
 69                Alias: "field"
 70                Name: "field"
 71                Arguments: [Argument]
 72                - <Argument>
 73                    Name: "arg"
 74                    Value: "Has a ਊ multi-byte character."
 75
 76keywords are allowed anywhere a name is:
 77  - name: on
 78    input: |
 79      query on {
 80        ... a
 81        ... on on { field }
 82      }
 83      fragment a on Type {
 84        on(on: $on)
 85          @on(on: on)
 86      }
 87
 88  - name: subscription
 89    input: |
 90      query subscription {
 91        ... subscription
 92        ... on subscription { field }
 93      }
 94      fragment subscription on Type {
 95        subscription(subscription: $subscription)
 96          @subscription(subscription: subscription)
 97      }
 98
 99  - name: true
100    input: |
101      query true {
102        ... true
103        ... on true { field }
104      }
105      fragment true on Type {
106        true(true: $true)
107          @true(true: true)
108      }
109
110operations:
111  - name: anonymous mutation
112    input: 'mutation { mutationField }'
113
114  - name: named mutation
115    input: 'mutation Foo { mutationField }'
116
117  - name: anonymous subscription
118    input: 'subscription { subscriptionField }'
119
120  - name: named subscription
121    input: 'subscription Foo { subscriptionField }'
122
123
124ast:
125  - name: simple query
126    input: |
127      {
128        node(id: 4) {
129          id,
130          name
131        }
132      }
133    ast: |
134      <QueryDocument>
135        Operations: [OperationDefinition]
136        - <OperationDefinition>
137            Operation: Operation("query")
138            SelectionSet: [Selection]
139            - <Field>
140                Alias: "node"
141                Name: "node"
142                Arguments: [Argument]
143                - <Argument>
144                    Name: "id"
145                    Value: 4
146                SelectionSet: [Selection]
147                - <Field>
148                    Alias: "id"
149                    Name: "id"
150                - <Field>
151                    Alias: "name"
152                    Name: "name"
153
154  - name: nameless query with no variables
155    input: |
156      query {
157        node {
158          id
159        }
160      }
161    ast: |
162      <QueryDocument>
163        Operations: [OperationDefinition]
164        - <OperationDefinition>
165            Operation: Operation("query")
166            SelectionSet: [Selection]
167            - <Field>
168                Alias: "node"
169                Name: "node"
170                SelectionSet: [Selection]
171                - <Field>
172                    Alias: "id"
173                    Name: "id"
174
175  - name: fragment defined variables
176    input: 'fragment a($v: Boolean = false) on t { f(v: $v) }'
177    ast: |
178      <QueryDocument>
179        Fragments: [FragmentDefinition]
180        - <FragmentDefinition>
181            Name: "a"
182            VariableDefinition: [VariableDefinition]
183            - <VariableDefinition>
184                Variable: "v"
185                Type: Boolean
186                DefaultValue: false
187            TypeCondition: "t"
188            SelectionSet: [Selection]
189            - <Field>
190                Alias: "f"
191                Name: "f"
192                Arguments: [Argument]
193                - <Argument>
194                    Name: "v"
195                    Value: $v
196
197
198values:
199  - name: null
200    input: '{ f(id: null) }'
201    ast: |
202      <QueryDocument>
203        Operations: [OperationDefinition]
204        - <OperationDefinition>
205            Operation: Operation("query")
206            SelectionSet: [Selection]
207            - <Field>
208                Alias: "f"
209                Name: "f"
210                Arguments: [Argument]
211                - <Argument>
212                    Name: "id"
213                    Value: null
214
215  - name: strings
216    input: '{ f(long: """long""", short: "short") } '
217    ast: |
218      <QueryDocument>
219        Operations: [OperationDefinition]
220        - <OperationDefinition>
221            Operation: Operation("query")
222            SelectionSet: [Selection]
223            - <Field>
224                Alias: "f"
225                Name: "f"
226                Arguments: [Argument]
227                - <Argument>
228                    Name: "long"
229                    Value: "long"
230                - <Argument>
231                    Name: "short"
232                    Value: "short"
233
234  - name: list
235    input: '{ f(id: [1,2]) }'
236    ast: |
237      <QueryDocument>
238        Operations: [OperationDefinition]
239        - <OperationDefinition>
240            Operation: Operation("query")
241            SelectionSet: [Selection]
242            - <Field>
243                Alias: "f"
244                Name: "f"
245                Arguments: [Argument]
246                - <Argument>
247                    Name: "id"
248                    Value: [1,2]
249
250types:
251  - name: common types
252    input: 'query ($string: String, $int: Int, $arr: [Arr], $notnull: [Arr!]!) { f }'
253    ast: |
254      <QueryDocument>
255        Operations: [OperationDefinition]
256        - <OperationDefinition>
257            Operation: Operation("query")
258            VariableDefinitions: [VariableDefinition]
259            - <VariableDefinition>
260                Variable: "string"
261                Type: String
262            - <VariableDefinition>
263                Variable: "int"
264                Type: Int
265            - <VariableDefinition>
266                Variable: "arr"
267                Type: [Arr]
268            - <VariableDefinition>
269                Variable: "notnull"
270                Type: [Arr!]!
271            SelectionSet: [Selection]
272            - <Field>
273                Alias: "f"
274                Name: "f"
275
276large queries:
277  - name: kitchen sink
278    input: |
279      # Copyright (c) 2015-present, Facebook, Inc.
280      #
281      # This source code is licensed under the MIT license found in the
282      # LICENSE file in the root directory of this source tree.
283
284      query queryName($foo: ComplexType, $site: Site = MOBILE) {
285        whoever123is: node(id: [123, 456]) {
286          id ,
287          ... on User @defer {
288            field2 {
289              id ,
290              alias: field1(first:10, after:$foo,) @include(if: $foo) {
291                id,
292                ...frag
293              }
294            }
295          }
296          ... @skip(unless: $foo) {
297            id
298          }
299          ... {
300            id
301          }
302        }
303      }
304
305      mutation likeStory {
306        like(story: 123) @defer {
307          story {
308            id
309          }
310        }
311      }
312
313      subscription StoryLikeSubscription($input: StoryLikeSubscribeInput) {
314        storyLikeSubscribe(input: $input) {
315          story {
316            likers {
317              count
318            }
319            likeSentence {
320              text
321            }
322          }
323        }
324      }
325
326      fragment frag on Friend {
327        foo(size: $size, bar: $b, obj: {key: "value", block: """
328            block string uses \"""
329        """})
330      }
331
332      {
333        unnamed(truthy: true, falsey: false, nullish: null),
334        query
335      }
336    ast: |
337      <QueryDocument>
338        Operations: [OperationDefinition]
339        - <OperationDefinition>
340            Operation: Operation("query")
341            Name: "queryName"
342            VariableDefinitions: [VariableDefinition]
343            - <VariableDefinition>
344                Variable: "foo"
345                Type: ComplexType
346            - <VariableDefinition>
347                Variable: "site"
348                Type: Site
349                DefaultValue: MOBILE
350            SelectionSet: [Selection]
351            - <Field>
352                Alias: "whoever123is"
353                Name: "node"
354                Arguments: [Argument]
355                - <Argument>
356                    Name: "id"
357                    Value: [123,456]
358                SelectionSet: [Selection]
359                - <Field>
360                    Alias: "id"
361                    Name: "id"
362                - <InlineFragment>
363                    TypeCondition: "User"
364                    Directives: [Directive]
365                    - <Directive>
366                        Name: "defer"
367                    SelectionSet: [Selection]
368                    - <Field>
369                        Alias: "field2"
370                        Name: "field2"
371                        SelectionSet: [Selection]
372                        - <Field>
373                            Alias: "id"
374                            Name: "id"
375                        - <Field>
376                            Alias: "alias"
377                            Name: "field1"
378                            Arguments: [Argument]
379                            - <Argument>
380                                Name: "first"
381                                Value: 10
382                            - <Argument>
383                                Name: "after"
384                                Value: $foo
385                            Directives: [Directive]
386                            - <Directive>
387                                Name: "include"
388                                Arguments: [Argument]
389                                - <Argument>
390                                    Name: "if"
391                                    Value: $foo
392                            SelectionSet: [Selection]
393                            - <Field>
394                                Alias: "id"
395                                Name: "id"
396                            - <FragmentSpread>
397                                Name: "frag"
398                - <InlineFragment>
399                    Directives: [Directive]
400                    - <Directive>
401                        Name: "skip"
402                        Arguments: [Argument]
403                        - <Argument>
404                            Name: "unless"
405                            Value: $foo
406                    SelectionSet: [Selection]
407                    - <Field>
408                        Alias: "id"
409                        Name: "id"
410                - <InlineFragment>
411                    SelectionSet: [Selection]
412                    - <Field>
413                        Alias: "id"
414                        Name: "id"
415        - <OperationDefinition>
416            Operation: Operation("mutation")
417            Name: "likeStory"
418            SelectionSet: [Selection]
419            - <Field>
420                Alias: "like"
421                Name: "like"
422                Arguments: [Argument]
423                - <Argument>
424                    Name: "story"
425                    Value: 123
426                Directives: [Directive]
427                - <Directive>
428                    Name: "defer"
429                SelectionSet: [Selection]
430                - <Field>
431                    Alias: "story"
432                    Name: "story"
433                    SelectionSet: [Selection]
434                    - <Field>
435                        Alias: "id"
436                        Name: "id"
437        - <OperationDefinition>
438            Operation: Operation("subscription")
439            Name: "StoryLikeSubscription"
440            VariableDefinitions: [VariableDefinition]
441            - <VariableDefinition>
442                Variable: "input"
443                Type: StoryLikeSubscribeInput
444            SelectionSet: [Selection]
445            - <Field>
446                Alias: "storyLikeSubscribe"
447                Name: "storyLikeSubscribe"
448                Arguments: [Argument]
449                - <Argument>
450                    Name: "input"
451                    Value: $input
452                SelectionSet: [Selection]
453                - <Field>
454                    Alias: "story"
455                    Name: "story"
456                    SelectionSet: [Selection]
457                    - <Field>
458                        Alias: "likers"
459                        Name: "likers"
460                        SelectionSet: [Selection]
461                        - <Field>
462                            Alias: "count"
463                            Name: "count"
464                    - <Field>
465                        Alias: "likeSentence"
466                        Name: "likeSentence"
467                        SelectionSet: [Selection]
468                        - <Field>
469                            Alias: "text"
470                            Name: "text"
471        - <OperationDefinition>
472            Operation: Operation("query")
473            SelectionSet: [Selection]
474            - <Field>
475                Alias: "unnamed"
476                Name: "unnamed"
477                Arguments: [Argument]
478                - <Argument>
479                    Name: "truthy"
480                    Value: true
481                - <Argument>
482                    Name: "falsey"
483                    Value: false
484                - <Argument>
485                    Name: "nullish"
486                    Value: null
487            - <Field>
488                Alias: "query"
489                Name: "query"
490        Fragments: [FragmentDefinition]
491        - <FragmentDefinition>
492            Name: "frag"
493            TypeCondition: "Friend"
494            SelectionSet: [Selection]
495            - <Field>
496                Alias: "foo"
497                Name: "foo"
498                Arguments: [Argument]
499                - <Argument>
500                    Name: "size"
501                    Value: $size
502                - <Argument>
503                    Name: "bar"
504                    Value: $b
505                - <Argument>
506                    Name: "obj"
507                    Value: {key:"value",block:"block string uses \"\"\""}
508
509fuzzer:
510- name: 01
511  input: '{__typename{...}}'
512  error:
513    message: 'Expected {, found }'
514    locations: [{ line: 1, column: 16 }]
515
516- name: 02
517  input: '{...{__typename{...{}}}}'
518  error:
519    message: 'expected at least one definition, found }'
520    locations: [{ line: 1, column: 21 }]