graphql 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql.rb +10 -0
  3. data/lib/graphql/base_type.rb +8 -5
  4. data/lib/graphql/compatibility.rb +3 -0
  5. data/lib/graphql/compatibility/execution_specification.rb +414 -0
  6. data/lib/graphql/compatibility/query_parser_specification.rb +117 -0
  7. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +81 -0
  8. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +78 -0
  9. data/lib/graphql/compatibility/schema_parser_specification.rb +239 -0
  10. data/lib/graphql/define/instance_definable.rb +53 -21
  11. data/lib/graphql/directive.rb +1 -1
  12. data/lib/graphql/enum_type.rb +31 -8
  13. data/lib/graphql/execution/directive_checks.rb +0 -6
  14. data/lib/graphql/input_object_type.rb +6 -4
  15. data/lib/graphql/introspection/arguments_field.rb +3 -1
  16. data/lib/graphql/introspection/enum_values_field.rb +10 -5
  17. data/lib/graphql/introspection/fields_field.rb +1 -1
  18. data/lib/graphql/introspection/input_fields_field.rb +2 -2
  19. data/lib/graphql/introspection/interfaces_field.rb +7 -1
  20. data/lib/graphql/introspection/possible_types_field.rb +1 -1
  21. data/lib/graphql/introspection/schema_type.rb +1 -1
  22. data/lib/graphql/introspection/type_by_name_field.rb +4 -2
  23. data/lib/graphql/introspection/type_type.rb +7 -6
  24. data/lib/graphql/language/lexer.rl +0 -4
  25. data/lib/graphql/language/parser.rb +1 -1
  26. data/lib/graphql/language/parser.y +1 -1
  27. data/lib/graphql/list_type.rb +3 -4
  28. data/lib/graphql/non_null_type.rb +4 -8
  29. data/lib/graphql/object_type.rb +5 -3
  30. data/lib/graphql/query.rb +48 -12
  31. data/lib/graphql/query/context.rb +7 -1
  32. data/lib/graphql/query/serial_execution/execution_context.rb +8 -3
  33. data/lib/graphql/query/serial_execution/field_resolution.rb +8 -5
  34. data/lib/graphql/query/serial_execution/operation_resolution.rb +2 -2
  35. data/lib/graphql/query/serial_execution/selection_resolution.rb +4 -21
  36. data/lib/graphql/query/serial_execution/value_resolution.rb +59 -99
  37. data/lib/graphql/query/variables.rb +7 -2
  38. data/lib/graphql/scalar_type.rb +1 -1
  39. data/lib/graphql/schema.rb +49 -18
  40. data/lib/graphql/schema/build_from_definition.rb +248 -0
  41. data/lib/graphql/schema/instrumented_field_map.rb +23 -0
  42. data/lib/graphql/schema/loader.rb +4 -11
  43. data/lib/graphql/schema/possible_types.rb +4 -2
  44. data/lib/graphql/schema/printer.rb +1 -1
  45. data/lib/graphql/schema/type_expression.rb +4 -4
  46. data/lib/graphql/schema/type_map.rb +1 -1
  47. data/lib/graphql/schema/validation.rb +4 -0
  48. data/lib/graphql/schema/warden.rb +114 -0
  49. data/lib/graphql/static_validation/literal_validator.rb +10 -7
  50. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -3
  51. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -1
  52. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -1
  53. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -14
  54. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -1
  55. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  56. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +3 -4
  57. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +2 -1
  58. data/lib/graphql/static_validation/validation_context.rb +7 -1
  59. data/lib/graphql/union_type.rb +6 -3
  60. data/lib/graphql/unresolved_type_error.rb +1 -2
  61. data/lib/graphql/version.rb +1 -1
  62. data/readme.md +1 -5
  63. data/spec/graphql/compatibility/execution_specification_spec.rb +3 -0
  64. data/spec/graphql/compatibility/query_parser_specification_spec.rb +5 -0
  65. data/spec/graphql/compatibility/schema_parser_specification_spec.rb +5 -0
  66. data/spec/graphql/define/instance_definable_spec.rb +20 -0
  67. data/spec/graphql/directive_spec.rb +11 -0
  68. data/spec/graphql/enum_type_spec.rb +20 -1
  69. data/spec/graphql/input_object_type_spec.rb +9 -9
  70. data/spec/graphql/introspection/directive_type_spec.rb +4 -4
  71. data/spec/graphql/introspection/input_value_type_spec.rb +6 -6
  72. data/spec/graphql/introspection/type_type_spec.rb +28 -26
  73. data/spec/graphql/language/parser_spec.rb +27 -17
  74. data/spec/graphql/list_type_spec.rb +2 -2
  75. data/spec/graphql/query/variables_spec.rb +1 -0
  76. data/spec/graphql/scalar_type_spec.rb +3 -3
  77. data/spec/graphql/schema/build_from_definition_spec.rb +693 -0
  78. data/spec/graphql/schema/type_expression_spec.rb +3 -3
  79. data/spec/graphql/schema/validation_spec.rb +7 -3
  80. data/spec/graphql/schema/warden_spec.rb +510 -0
  81. data/spec/graphql/schema_spec.rb +129 -0
  82. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +1 -1
  83. data/spec/graphql/static_validation/type_stack_spec.rb +3 -3
  84. data/spec/spec_helper.rb +27 -1
  85. data/spec/support/dairy_app.rb +8 -5
  86. metadata +21 -3
  87. data/lib/graphql/language/parser_tests.rb +0 -809
@@ -0,0 +1,693 @@
1
+ require "spec_helper"
2
+
3
+ describe GraphQL::Schema::BuildFromDefinition do
4
+ def build_schema_and_compare_output(definition)
5
+ built_schema = GraphQL::Schema.from_definition(definition)
6
+ assert_equal definition, GraphQL::Schema::Printer.print_schema(built_schema)
7
+ end
8
+
9
+ describe '.build' do
10
+ it 'can build a schema with a simple type' do
11
+ schema = <<-SCHEMA
12
+ schema {
13
+ query: HelloScalars
14
+ }
15
+
16
+ type HelloScalars {
17
+ str: String!
18
+ int: Int
19
+ float: Float
20
+ id: ID
21
+ bool: Boolean
22
+ }
23
+ SCHEMA
24
+
25
+ build_schema_and_compare_output(schema.chop)
26
+ end
27
+
28
+ it 'can build a schema with directives' do
29
+ schema = <<-SCHEMA
30
+ schema {
31
+ query: Hello
32
+ }
33
+
34
+ directive @foo(arg: Int) on FIELD
35
+
36
+ type Hello {
37
+ str: String
38
+ }
39
+ SCHEMA
40
+
41
+ build_schema_and_compare_output(schema.chop)
42
+ end
43
+
44
+ it 'supports descriptions' do
45
+ schema = <<-SCHEMA
46
+ schema {
47
+ query: Hello
48
+ }
49
+
50
+ # This is a directive
51
+ directive @foo(
52
+ # It has an argument
53
+ arg: Int
54
+ ) on FIELD
55
+
56
+ # With an enum
57
+ enum Color {
58
+ RED
59
+
60
+ # Not a creative color
61
+ GREEN
62
+ BLUE
63
+ }
64
+
65
+ # What a great type
66
+ type Hello {
67
+ # And a field to boot
68
+ str: String
69
+ }
70
+ SCHEMA
71
+
72
+ build_schema_and_compare_output(schema.chop)
73
+ end
74
+
75
+ it 'maintains built-in directives' do
76
+ schema = <<-SCHEMA
77
+ schema {
78
+ query: Hello
79
+ }
80
+
81
+ type Hello {
82
+ str: String
83
+ }
84
+ SCHEMA
85
+
86
+ built_schema = GraphQL::Schema.from_definition(schema)
87
+ assert_equal ['deprecated', 'include', 'skip'], built_schema.directives.keys.sort
88
+ end
89
+
90
+ it 'supports overriding built-in directives' do
91
+ schema = <<-SCHEMA
92
+ schema {
93
+ query: Hello
94
+ }
95
+
96
+ directive @skip on FIELD
97
+ directive @include on FIELD
98
+ directive @deprecated on FIELD_DEFINITION
99
+
100
+ type Hello {
101
+ str: String
102
+ }
103
+ SCHEMA
104
+
105
+ built_schema = GraphQL::Schema.from_definition(schema)
106
+
107
+ refute built_schema.directives['skip'] == GraphQL::Directive::SkipDirective
108
+ refute built_schema.directives['include'] == GraphQL::Directive::IncludeDirective
109
+ refute built_schema.directives['deprecated'] == GraphQL::Directive::DeprecatedDirective
110
+ end
111
+
112
+ it 'supports adding directives while maintaining built-in directives' do
113
+ schema = <<-SCHEMA
114
+ schema {
115
+ query: Hello
116
+ }
117
+
118
+ directive @foo(arg: Int) on FIELD
119
+
120
+ type Hello {
121
+ str: String
122
+ }
123
+ SCHEMA
124
+
125
+ built_schema = GraphQL::Schema.from_definition(schema)
126
+
127
+ assert built_schema.directives.keys.include?('skip')
128
+ assert built_schema.directives.keys.include?('include')
129
+ assert built_schema.directives.keys.include?('deprecated')
130
+ assert built_schema.directives.keys.include?('foo')
131
+ end
132
+
133
+ it 'supports type modifiers' do
134
+ schema = <<-SCHEMA
135
+ schema {
136
+ query: HelloScalars
137
+ }
138
+
139
+ type HelloScalars {
140
+ nonNullStr: String!
141
+ listOfStrs: [String]
142
+ listOfNonNullStrs: [String!]
143
+ nonNullListOfStrs: [String]!
144
+ nonNullListOfNonNullStrs: [String!]!
145
+ }
146
+ SCHEMA
147
+
148
+ build_schema_and_compare_output(schema.chop)
149
+ end
150
+
151
+ it 'supports recursive type' do
152
+ schema = <<-SCHEMA
153
+ schema {
154
+ query: Recurse
155
+ }
156
+
157
+ type Recurse {
158
+ str: String
159
+ recurse: Recurse
160
+ }
161
+ SCHEMA
162
+
163
+ build_schema_and_compare_output(schema.chop)
164
+ end
165
+
166
+ it 'supports two types circular' do
167
+ schema = <<-SCHEMA
168
+ schema {
169
+ query: TypeOne
170
+ }
171
+
172
+ type TypeOne {
173
+ str: String
174
+ typeTwo: TypeTwo
175
+ }
176
+
177
+ type TypeTwo {
178
+ str: String
179
+ typeOne: TypeOne
180
+ }
181
+ SCHEMA
182
+
183
+ build_schema_and_compare_output(schema.chop)
184
+ end
185
+
186
+ it 'supports single argument fields' do
187
+ schema = <<-SCHEMA
188
+ schema {
189
+ query: Hello
190
+ }
191
+
192
+ type Hello {
193
+ str(int: Int): String
194
+ floatToStr(float: Float): String
195
+ idToStr(id: ID): String
196
+ booleanToStr(bool: Boolean): String
197
+ strToStr(bool: String): String
198
+ }
199
+ SCHEMA
200
+
201
+ build_schema_and_compare_output(schema.chop)
202
+ end
203
+
204
+ it 'supports simple type with multiple arguments' do
205
+ schema = <<-SCHEMA
206
+ schema {
207
+ query: Hello
208
+ }
209
+
210
+ type Hello {
211
+ str(int: Int, bool: Boolean): String
212
+ }
213
+ SCHEMA
214
+
215
+ build_schema_and_compare_output(schema.chop)
216
+ end
217
+
218
+ it 'supports simple type with interface' do
219
+ schema = <<-SCHEMA
220
+ schema {
221
+ query: Hello
222
+ }
223
+
224
+ type Hello implements WorldInterface {
225
+ str: String
226
+ }
227
+
228
+ interface WorldInterface {
229
+ str: String
230
+ }
231
+ SCHEMA
232
+
233
+ build_schema_and_compare_output(schema.chop)
234
+ end
235
+
236
+ it 'supports simple output enum' do
237
+ schema = <<-SCHEMA
238
+ schema {
239
+ query: OutputEnumRoot
240
+ }
241
+
242
+ enum Hello {
243
+ WORLD
244
+ }
245
+
246
+ type OutputEnumRoot {
247
+ hello: Hello
248
+ }
249
+ SCHEMA
250
+
251
+ build_schema_and_compare_output(schema.chop)
252
+ end
253
+
254
+ it 'supports simple input enum' do
255
+ schema = <<-SCHEMA
256
+ schema {
257
+ query: InputEnumRoot
258
+ }
259
+
260
+ enum Hello {
261
+ WORLD
262
+ }
263
+
264
+ type InputEnumRoot {
265
+ str(hello: Hello): String
266
+ }
267
+ SCHEMA
268
+
269
+ build_schema_and_compare_output(schema.chop)
270
+ end
271
+
272
+ it 'supports multiple value enum' do
273
+ schema = <<-SCHEMA
274
+ schema {
275
+ query: OutputEnumRoot
276
+ }
277
+
278
+ enum Hello {
279
+ WO
280
+ RLD
281
+ }
282
+
283
+ type OutputEnumRoot {
284
+ hello: Hello
285
+ }
286
+ SCHEMA
287
+
288
+ build_schema_and_compare_output(schema.chop)
289
+ end
290
+
291
+ it 'supports simple union' do
292
+ schema = <<-SCHEMA
293
+ schema {
294
+ query: Root
295
+ }
296
+
297
+ union Hello = World
298
+
299
+ type Root {
300
+ hello: Hello
301
+ }
302
+
303
+ type World {
304
+ str: String
305
+ }
306
+ SCHEMA
307
+
308
+ build_schema_and_compare_output(schema.chop)
309
+ end
310
+
311
+ it 'supports multiple union' do
312
+ schema = <<-SCHEMA
313
+ schema {
314
+ query: Root
315
+ }
316
+
317
+ union Hello = WorldOne | WorldTwo
318
+
319
+ type Root {
320
+ hello: Hello
321
+ }
322
+
323
+ type WorldOne {
324
+ str: String
325
+ }
326
+
327
+ type WorldTwo {
328
+ str: String
329
+ }
330
+ SCHEMA
331
+
332
+ build_schema_and_compare_output(schema.chop)
333
+ end
334
+
335
+ it 'supports custom scalar' do
336
+ schema = <<-SCHEMA
337
+ schema {
338
+ query: Root
339
+ }
340
+
341
+ scalar CustomScalar
342
+
343
+ type Root {
344
+ customScalar: CustomScalar
345
+ }
346
+ SCHEMA
347
+
348
+ build_schema_and_compare_output(schema.chop)
349
+ end
350
+
351
+ it 'supports input object' do
352
+ schema = <<-SCHEMA
353
+ schema {
354
+ query: Root
355
+ }
356
+
357
+ input Input {
358
+ int: Int
359
+ }
360
+
361
+ type Root {
362
+ field(in: Input): String
363
+ }
364
+ SCHEMA
365
+
366
+ build_schema_and_compare_output(schema.chop)
367
+ end
368
+
369
+ it 'supports simple argument field with default value' do
370
+ schema = <<-SCHEMA
371
+ schema {
372
+ query: Hello
373
+ }
374
+
375
+ enum Color {
376
+ RED
377
+ BLUE
378
+ }
379
+
380
+ type Hello {
381
+ str(int: Int = 2): String
382
+ hello(color: Color = RED): String
383
+ }
384
+ SCHEMA
385
+
386
+ build_schema_and_compare_output(schema.chop)
387
+ end
388
+
389
+ it 'supports simple type with mutation' do
390
+ schema = <<-SCHEMA
391
+ schema {
392
+ query: HelloScalars
393
+ mutation: Mutation
394
+ }
395
+
396
+ type HelloScalars {
397
+ str: String
398
+ int: Int
399
+ bool: Boolean
400
+ }
401
+
402
+ type Mutation {
403
+ addHelloScalars(str: String, int: Int, bool: Boolean): HelloScalars
404
+ }
405
+ SCHEMA
406
+
407
+ build_schema_and_compare_output(schema.chop)
408
+ end
409
+
410
+ it 'supports simple type with mutation and default values' do
411
+ schema = <<-SCHEMA
412
+ enum Color {
413
+ RED
414
+ BLUE
415
+ }
416
+
417
+ type Mutation {
418
+ hello(str: String, int: Int, color: Color = RED): String
419
+ }
420
+
421
+ type Query {
422
+ str: String
423
+ }
424
+ SCHEMA
425
+
426
+ build_schema_and_compare_output(schema.chop)
427
+ end
428
+
429
+ it 'supports simple type with subscription' do
430
+ schema = <<-SCHEMA
431
+ schema {
432
+ query: HelloScalars
433
+ subscription: Subscription
434
+ }
435
+
436
+ type HelloScalars {
437
+ str: String
438
+ int: Int
439
+ bool: Boolean
440
+ }
441
+
442
+ type Subscription {
443
+ subscribeHelloScalars(str: String, int: Int, bool: Boolean): HelloScalars
444
+ }
445
+ SCHEMA
446
+
447
+ build_schema_and_compare_output(schema.chop)
448
+ end
449
+
450
+ it 'supports unreferenced type implementing referenced interface' do
451
+ schema = <<-SCHEMA
452
+ type Concrete implements Iface {
453
+ key: String
454
+ }
455
+
456
+ interface Iface {
457
+ key: String
458
+ }
459
+
460
+ type Query {
461
+ iface: Iface
462
+ }
463
+ SCHEMA
464
+
465
+ build_schema_and_compare_output(schema.chop)
466
+ end
467
+
468
+ it 'supports unreferenced type implementing referenced union' do
469
+ schema = <<-SCHEMA
470
+ type Concrete {
471
+ key: String
472
+ }
473
+
474
+ type Query {
475
+ union: Union
476
+ }
477
+
478
+ union Union = Concrete
479
+ SCHEMA
480
+
481
+ build_schema_and_compare_output(schema.chop)
482
+ end
483
+
484
+ it 'supports @deprecated' do
485
+ schema = <<-SCHEMA
486
+ enum MyEnum {
487
+ VALUE
488
+ OLD_VALUE @deprecated
489
+ OTHER_VALUE @deprecated(reason: "Terrible reasons")
490
+ }
491
+
492
+ type Query {
493
+ field1: String @deprecated
494
+ field2: Int @deprecated(reason: "Because I said so")
495
+ enum: MyEnum
496
+ }
497
+ SCHEMA
498
+
499
+ build_schema_and_compare_output(schema.chop)
500
+ end
501
+ end
502
+
503
+ describe 'Failures' do
504
+ it 'Requires a schema definition or Query type' do
505
+ schema = <<-SCHEMA
506
+ type Hello {
507
+ bar: Bar
508
+ }
509
+ SCHEMA
510
+ err = assert_raises(GraphQL::Schema::InvalidDocumentError) do
511
+ GraphQL::Schema.from_definition(schema)
512
+ end
513
+ assert_equal 'Must provide schema definition with query type or a type named Query.', err.message
514
+ end
515
+
516
+ it 'Allows only a single schema definition' do
517
+ schema = <<-SCHEMA
518
+ schema {
519
+ query: Hello
520
+ }
521
+
522
+ schema {
523
+ query: Hello
524
+ }
525
+
526
+ type Hello {
527
+ bar: Bar
528
+ }
529
+ SCHEMA
530
+
531
+ err = assert_raises(GraphQL::Schema::InvalidDocumentError) do
532
+ GraphQL::Schema.from_definition(schema)
533
+ end
534
+ assert_equal 'Must provide only one schema definition.', err.message
535
+ end
536
+
537
+ it 'Requires a query type' do
538
+ schema = <<-SCHEMA
539
+ schema {
540
+ mutation: Hello
541
+ }
542
+
543
+ type Hello {
544
+ bar: Bar
545
+ }
546
+ SCHEMA
547
+
548
+ err = assert_raises(GraphQL::Schema::InvalidDocumentError) do
549
+ GraphQL::Schema.from_definition(schema)
550
+ end
551
+ assert_equal 'Must provide schema definition with query type or a type named Query.', err.message
552
+ end
553
+
554
+ it 'Unknown type referenced' do
555
+ schema = <<-SCHEMA
556
+ schema {
557
+ query: Hello
558
+ }
559
+
560
+ type Hello {
561
+ bar: Bar
562
+ }
563
+ SCHEMA
564
+
565
+ err = assert_raises(GraphQL::Schema::InvalidDocumentError) do
566
+ GraphQL::Schema.from_definition(schema)
567
+ end
568
+ assert_equal 'Type "Bar" not found in document.', err.message
569
+ end
570
+
571
+ it 'Unknown type in interface list' do
572
+ schema = <<-SCHEMA
573
+ schema {
574
+ query: Hello
575
+ }
576
+
577
+ type Hello implements Bar {
578
+ str: String
579
+ }
580
+ SCHEMA
581
+
582
+ err = assert_raises(GraphQL::Schema::InvalidDocumentError) do
583
+ GraphQL::Schema.from_definition(schema)
584
+ end
585
+ assert_equal 'Type "Bar" not found in document.', err.message
586
+ end
587
+
588
+ it 'Unknown type in union list' do
589
+ schema = <<-SCHEMA
590
+ schema {
591
+ query: Hello
592
+ }
593
+
594
+ union TestUnion = Bar
595
+
596
+ type Hello { testUnion: TestUnion }
597
+ SCHEMA
598
+
599
+ err = assert_raises(GraphQL::Schema::InvalidDocumentError) do
600
+ GraphQL::Schema.from_definition(schema)
601
+ end
602
+ assert_equal 'Type "Bar" not found in document.', err.message
603
+ end
604
+
605
+ it 'Unknown query type' do
606
+ schema = <<-SCHEMA
607
+ schema {
608
+ query: Wat
609
+ }
610
+
611
+ type Hello {
612
+ str: String
613
+ }
614
+ SCHEMA
615
+
616
+ err = assert_raises(GraphQL::Schema::InvalidDocumentError) do
617
+ GraphQL::Schema.from_definition(schema)
618
+ end
619
+ assert_equal 'Specified query type "Wat" not found in document.', err.message
620
+ end
621
+
622
+ it 'Unknown mutation type' do
623
+ schema = <<-SCHEMA
624
+ schema {
625
+ query: Hello
626
+ mutation: Wat
627
+ }
628
+
629
+ type Hello {
630
+ str: String
631
+ }
632
+ SCHEMA
633
+
634
+ err = assert_raises(GraphQL::Schema::InvalidDocumentError) do
635
+ GraphQL::Schema.from_definition(schema)
636
+ end
637
+ assert_equal 'Specified mutation type "Wat" not found in document.', err.message
638
+ end
639
+
640
+ it 'Unknown subscription type' do
641
+ schema = <<-SCHEMA
642
+ schema {
643
+ query: Hello
644
+ mutation: Wat
645
+ subscription: Awesome
646
+ }
647
+
648
+ type Hello {
649
+ str: String
650
+ }
651
+
652
+ type Wat {
653
+ str: String
654
+ }
655
+ SCHEMA
656
+
657
+ err = assert_raises(GraphQL::Schema::InvalidDocumentError) do
658
+ GraphQL::Schema.from_definition(schema)
659
+ end
660
+ assert_equal 'Specified subscription type "Awesome" not found in document.', err.message
661
+ end
662
+
663
+ it 'Does not consider operation names' do
664
+ schema = <<-SCHEMA
665
+ schema {
666
+ query: Foo
667
+ }
668
+
669
+ query Foo { field }
670
+ SCHEMA
671
+
672
+ err = assert_raises(GraphQL::Schema::InvalidDocumentError) do
673
+ GraphQL::Schema.from_definition(schema)
674
+ end
675
+ assert_equal 'Specified query type "Foo" not found in document.', err.message
676
+ end
677
+
678
+ it 'Does not consider fragment names' do
679
+ schema = <<-SCHEMA
680
+ schema {
681
+ query: Foo
682
+ }
683
+
684
+ fragment Foo on Type { field }
685
+ SCHEMA
686
+
687
+ err = assert_raises(GraphQL::Schema::InvalidDocumentError) do
688
+ GraphQL::Schema.from_definition(schema)
689
+ end
690
+ assert_equal 'Specified query type "Foo" not found in document.', err.message
691
+ end
692
+ end
693
+ end