graphql 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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,117 @@
1
+ require "graphql/compatibility/query_parser_specification/query_assertions"
2
+ require "graphql/compatibility/query_parser_specification/parse_error_specification"
3
+
4
+ module GraphQL
5
+ module Compatibility
6
+ # This asserts that a given parse function turns a string into
7
+ # the proper tree of {{GraphQL::Language::Nodes}}.
8
+ module QueryParserSpecification
9
+ # @yieldparam query_string [String] A query string to parse
10
+ # @yieldreturn [GraphQL::Language::Nodes::Document]
11
+ # @return [Class<Minitest::Test>] A test suite for this parse function
12
+ def self.build_suite(&block)
13
+ Class.new(Minitest::Test) do
14
+ include QueryAssertions
15
+ include ParseErrorSpecification
16
+
17
+ @@parse_fn = block
18
+
19
+ def parse(query_string)
20
+ @@parse_fn.call(query_string)
21
+ end
22
+
23
+ def test_it_parses_queries
24
+ document = parse(QUERY_STRING)
25
+ query = document.definitions.first
26
+ assert_valid_query(query)
27
+ assert_valid_fragment(document.definitions.last)
28
+ assert_valid_variable(query.variables.first)
29
+ field = query.selections.first
30
+ assert_valid_field(field)
31
+ assert_valid_variable_argument(field.arguments.first)
32
+ assert_valid_literal_argument(field.arguments.last)
33
+ assert_valid_directive(field.directives.first)
34
+ fragment_spread = query.selections[1].selections.last
35
+ assert_valid_fragment_spread(fragment_spread)
36
+ assert_valid_typed_inline_fragment(query.selections[2])
37
+ assert_valid_typeless_inline_fragment(query.selections[3])
38
+ end
39
+
40
+ def test_it_parses_unnamed_queries
41
+ document = parse("{ name, age, height }")
42
+ operation = document.definitions.first
43
+ assert_equal 1, document.definitions.length
44
+ assert_equal "query", operation.operation_type
45
+ assert_equal nil, operation.name
46
+ assert_equal 3, operation.selections.length
47
+ end
48
+
49
+ def test_it_parses_the_introspection_query
50
+ parse(GraphQL::Introspection::INTROSPECTION_QUERY)
51
+ end
52
+
53
+ def test_it_parses_inputs
54
+ query_string = %|
55
+ {
56
+ field(
57
+ int: 3,
58
+ float: 4.7e-24,
59
+ bool: false,
60
+ string: "☀︎🏆\\n \\" \u00b6 /",
61
+ enum: ENUM_NAME,
62
+ array: [7, 8, 9]
63
+ object: {a: [1,2,3], b: {c: "4"}}
64
+ unicode_bom: "\xef\xbb\xbfquery"
65
+ keywordEnum: on
66
+ )
67
+ }
68
+ |
69
+ document = parse(query_string)
70
+ inputs = document.definitions.first.selections.first.arguments
71
+ assert_equal 3, inputs[0].value, "Integers"
72
+ assert_equal 0.47e-23, inputs[1].value, "Floats"
73
+ assert_equal false, inputs[2].value, "Booleans"
74
+ assert_equal %|☀︎🏆\n " ¶ /|, inputs[3].value, "Strings"
75
+ assert_instance_of GraphQL::Language::Nodes::Enum, inputs[4].value
76
+ assert_equal "ENUM_NAME", inputs[4].value.name, "Enums"
77
+ assert_equal [7,8,9], inputs[5].value, "Lists"
78
+
79
+ obj = inputs[6].value
80
+ assert_equal "a", obj.arguments[0].name
81
+ assert_equal [1,2,3], obj.arguments[0].value
82
+ assert_equal "b", obj.arguments[1].name
83
+ assert_equal "c", obj.arguments[1].value.arguments[0].name
84
+ assert_equal "4", obj.arguments[1].value.arguments[0].value
85
+
86
+ assert_equal %|\xef\xbb\xbfquery|, inputs[7].value, "Unicode BOM"
87
+ assert_equal "on", inputs[8].value.name, "Enum value 'on'"
88
+ end
89
+ end
90
+ end
91
+
92
+ QUERY_STRING = %|
93
+ query getStuff($someVar: Int = 1, $anotherVar: [String!] ) @skip(if: false) {
94
+ myField: someField(someArg: $someVar, ok: 1.4) @skip(if: $anotherVar) @thing(or: "Whatever")
95
+
96
+ anotherField(someArg: [1,2,3]) {
97
+ nestedField
98
+ ... moreNestedFields @skip(if: true)
99
+ }
100
+
101
+ ... on OtherType @include(unless: false){
102
+ field(arg: [{key: "value", anotherKey: 0.9, anotherAnotherKey: WHATEVER}])
103
+ anotherField
104
+ }
105
+
106
+ ... {
107
+ id
108
+ }
109
+ }
110
+
111
+ fragment moreNestedFields on NestedType @or(something: "ok") {
112
+ anotherNestedField @enum(directive: true)
113
+ }
114
+ |
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,81 @@
1
+ module GraphQL
2
+ module Compatibility
3
+ module QueryParserSpecification
4
+ module ParseErrorSpecification
5
+ def assert_raises_parse_error(query_string)
6
+ assert_raises(GraphQL::ParseError) {
7
+ parse(query_string)
8
+ }
9
+ end
10
+
11
+ def test_it_includes_line_and_column
12
+ err = assert_raises_parse_error("
13
+ query getCoupons {
14
+ allCoupons: {data{id}}
15
+ }
16
+ ")
17
+
18
+ assert_includes(err.message, '{')
19
+ assert_equal(3, err.line)
20
+ assert_equal(27, err.col)
21
+ end
22
+
23
+ def test_it_rejects_unterminated_strings
24
+ assert_raises_parse_error('{ " }')
25
+ assert_raises_parse_error(%|{ "\n" }|)
26
+ end
27
+
28
+ def test_it_rejects_unexpected_ends
29
+ assert_raises_parse_error("query { stuff { thing }")
30
+ end
31
+
32
+ def assert_rejects_character(char)
33
+ err = assert_raises_parse_error("{ field#{char} }")
34
+ expected_char = char.inspect.gsub('"', '').downcase
35
+ msg_downcase = err.message.downcase
36
+ # Case-insensitive for UTF-8 printing
37
+ assert_includes(msg_downcase, expected_char, "The message includes the invalid character")
38
+ end
39
+
40
+ def test_it_rejects_invalid_characters
41
+ assert_rejects_character(";")
42
+ assert_rejects_character("\a")
43
+ assert_rejects_character("\xef")
44
+ assert_rejects_character("\v")
45
+ assert_rejects_character("\f")
46
+ assert_rejects_character("\xa0")
47
+ end
48
+
49
+ def test_it_rejects_bad_unicode
50
+ assert_raises_parse_error(%|{ field(arg:"\\x") }|)
51
+ assert_raises_parse_error(%|{ field(arg:"\\u1") }|)
52
+ assert_raises_parse_error(%|{ field(arg:"\\u0XX1") }|)
53
+ assert_raises_parse_error(%|{ field(arg:"\\uXXXX") }|)
54
+ assert_raises_parse_error(%|{ field(arg:"\\uFXXX") }|)
55
+ assert_raises_parse_error(%|{ field(arg:"\\uXXXF") }|)
56
+ end
57
+
58
+ def assert_empty_document(query_string)
59
+ doc = parse(query_string)
60
+ assert_equal 0, doc.definitions.length
61
+ end
62
+
63
+ def test_it_parses_blank_queries
64
+ assert_empty_document("")
65
+ assert_empty_document(" ")
66
+ assert_empty_document("\t \t")
67
+ end
68
+
69
+ def test_it_restricts_on
70
+ assert_raises_parse_error("{ ...on }")
71
+ assert_raises_parse_error("fragment on on Type { field }")
72
+ end
73
+
74
+ def test_it_rejects_null
75
+ err = assert_raises_parse_error("{ field(input: null) }")
76
+ assert_includes(err.message, "null")
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,78 @@
1
+ module GraphQL
2
+ module Compatibility
3
+ module QueryParserSpecification
4
+ module QueryAssertions
5
+ def assert_valid_query(query)
6
+ assert query.is_a?(GraphQL::Language::Nodes::OperationDefinition)
7
+ assert_equal "getStuff", query.name
8
+ assert_equal "query", query.operation_type
9
+ assert_equal 2, query.variables.length
10
+ assert_equal 4, query.selections.length
11
+ assert_equal 1, query.directives.length
12
+ assert_equal [2, 13], [query.line, query.col]
13
+ end
14
+
15
+ def assert_valid_fragment(fragment_def)
16
+ assert fragment_def.is_a?(GraphQL::Language::Nodes::FragmentDefinition)
17
+ assert_equal "moreNestedFields", fragment_def.name
18
+ assert_equal 1, fragment_def.selections.length
19
+ assert_equal "NestedType", fragment_def.type.name
20
+ assert_equal 1, fragment_def.directives.length
21
+ assert_equal [20, 13], fragment_def.position
22
+ end
23
+
24
+ def assert_valid_variable(variable)
25
+ assert_equal "someVar", variable.name
26
+ assert_equal "Int", variable.type.name
27
+ assert_equal 1, variable.default_value
28
+ assert_equal [2, 28], variable.position
29
+ end
30
+
31
+ def assert_valid_field(field)
32
+ assert_equal "someField", field.name
33
+ assert_equal "myField", field.alias
34
+ assert_equal 2, field.directives.length
35
+ assert_equal 2, field.arguments.length
36
+ assert_equal 0, field.selections.length
37
+ assert_equal [3, 15], field.position
38
+ end
39
+
40
+ def assert_valid_literal_argument(argument)
41
+ assert_equal "ok", argument.name
42
+ assert_equal 1.4, argument.value
43
+ end
44
+
45
+ def assert_valid_variable_argument(argument)
46
+ assert_equal "someArg", argument.name
47
+ assert_equal "someVar", argument.value.name
48
+ end
49
+
50
+ def assert_valid_fragment_spread(fragment_spread)
51
+ assert_equal "moreNestedFields", fragment_spread.name
52
+ assert_equal 1, fragment_spread.directives.length
53
+ assert_equal [7, 17], fragment_spread.position
54
+ end
55
+
56
+ def assert_valid_directive(directive)
57
+ assert_equal "skip", directive.name
58
+ assert_equal "if", directive.arguments.first.name
59
+ assert_equal 1, directive.arguments.length
60
+ assert_equal [3, 62], directive.position
61
+ end
62
+
63
+ def assert_valid_typed_inline_fragment(inline_fragment)
64
+ assert_equal "OtherType", inline_fragment.type.name
65
+ assert_equal 2, inline_fragment.selections.length
66
+ assert_equal 1, inline_fragment.directives.length
67
+ assert_equal [10, 15], inline_fragment.position
68
+ end
69
+
70
+ def assert_valid_typeless_inline_fragment(inline_fragment)
71
+ assert_equal nil, inline_fragment.type
72
+ assert_equal 1, inline_fragment.selections.length
73
+ assert_equal 0, inline_fragment.directives.length
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,239 @@
1
+ module GraphQL
2
+ module Compatibility
3
+ # This asserts that a given parse function turns a string into
4
+ # the proper tree of {{GraphQL::Language::Nodes}}.
5
+ module SchemaParserSpecification
6
+ # @yieldparam query_string [String] A query string to parse
7
+ # @yieldreturn [GraphQL::Language::Nodes::Document]
8
+ # @return [Class<Minitest::Test>] A test suite for this parse function
9
+ def self.build_suite(&block)
10
+ Class.new(Minitest::Test) do
11
+ @@parse_fn = block
12
+
13
+ def parse(query_string)
14
+ @@parse_fn.call(query_string)
15
+ end
16
+
17
+ def test_it_parses_object_types
18
+ document = parse('
19
+ # This is what
20
+ # somebody said about something
21
+ type Comment implements Node @deprecated(reason: "No longer supported") {
22
+ id: ID!
23
+ }
24
+ ')
25
+
26
+ type = document.definitions.first
27
+ assert_equal GraphQL::Language::Nodes::ObjectTypeDefinition, type.class
28
+ assert_equal 'Comment', type.name
29
+ assert_equal "This is what\nsomebody said about something", type.description
30
+ assert_equal ['Node'], type.interfaces.map(&:name)
31
+ assert_equal ['id'], type.fields.map(&:name)
32
+ assert_equal [], type.fields[0].arguments
33
+ assert_equal 'ID', type.fields[0].type.of_type.name
34
+ assert_equal 1, type.directives.length
35
+
36
+ deprecated_directive = type.directives[0]
37
+ assert_equal 'deprecated', deprecated_directive.name
38
+ assert_equal 'reason', deprecated_directive.arguments[0].name
39
+ assert_equal 'No longer supported', deprecated_directive.arguments[0].value
40
+ end
41
+
42
+ def test_it_parses_scalars
43
+ document = parse('scalar DateTime')
44
+
45
+ type = document.definitions.first
46
+ assert_equal GraphQL::Language::Nodes::ScalarTypeDefinition, type.class
47
+ assert_equal 'DateTime', type.name
48
+ end
49
+
50
+ def test_it_parses_enum_types
51
+ document = parse('
52
+ enum DogCommand {
53
+ # Good dog
54
+ SIT
55
+ DOWN @deprecated(reason: "No longer supported")
56
+ HEEL
57
+ }
58
+ ')
59
+
60
+ type = document.definitions.first
61
+ assert_equal GraphQL::Language::Nodes::EnumTypeDefinition, type.class
62
+ assert_equal 'DogCommand', type.name
63
+ assert_equal 3, type.values.length
64
+
65
+ assert_equal 'SIT', type.values[0].name
66
+ assert_equal [], type.values[0].directives
67
+ assert_equal "Good dog", type.values[0].description
68
+
69
+ assert_equal 'DOWN', type.values[1].name
70
+ assert_equal 1, type.values[1].directives.length
71
+ deprecated_directive = type.values[1].directives[0]
72
+ assert_equal 'deprecated', deprecated_directive.name
73
+ assert_equal 'reason', deprecated_directive.arguments[0].name
74
+ assert_equal 'No longer supported', deprecated_directive.arguments[0].value
75
+
76
+ assert_equal 'HEEL', type.values[2].name
77
+ assert_equal [], type.values[2].directives
78
+ end
79
+
80
+ def test_it_parses_input_types
81
+ document = parse('
82
+ input EmptyMutationInput {
83
+ clientMutationId: String
84
+ }
85
+ ')
86
+
87
+ type = document.definitions.first
88
+ assert_equal GraphQL::Language::Nodes::InputObjectTypeDefinition, type.class
89
+ assert_equal 'EmptyMutationInput', type.name
90
+ assert_equal ['clientMutationId'], type.fields.map(&:name)
91
+ assert_equal 'String', type.fields[0].type.name
92
+ assert_equal nil, type.fields[0].default_value
93
+ end
94
+
95
+ def test_it_parses_directives
96
+ document = parse('
97
+ directive @include(if: Boolean!)
98
+ on FIELD
99
+ | FRAGMENT_SPREAD
100
+ | INLINE_FRAGMENT
101
+ ')
102
+
103
+ type = document.definitions.first
104
+ assert_equal GraphQL::Language::Nodes::DirectiveDefinition, type.class
105
+ assert_equal 'include', type.name
106
+
107
+ assert_equal 1, type.arguments.length
108
+ assert_equal 'if', type.arguments[0].name
109
+ assert_equal 'Boolean', type.arguments[0].type.of_type.name
110
+
111
+ assert_equal ['FIELD', 'FRAGMENT_SPREAD', 'INLINE_FRAGMENT'], type.locations
112
+ end
113
+
114
+ def test_it_parses_field_arguments
115
+ document = parse('
116
+ type Mutation {
117
+ post(
118
+ id: ID! @deprecated(reason: "Not used"),
119
+ # This is what goes in the post
120
+ data: String
121
+ ): Post
122
+ }
123
+ ')
124
+
125
+ field = document.definitions.first.fields.first
126
+ assert_equal ['id', 'data'], field.arguments.map(&:name)
127
+ id_arg = field.arguments[0]
128
+
129
+ deprecated_directive = id_arg.directives[0]
130
+ assert_equal 'deprecated', deprecated_directive.name
131
+ assert_equal 'reason', deprecated_directive.arguments[0].name
132
+ assert_equal 'Not used', deprecated_directive.arguments[0].value
133
+
134
+ data_arg = field.arguments[1]
135
+ assert_equal "data", data_arg.name
136
+ assert_equal "This is what goes in the post", data_arg.description
137
+ end
138
+
139
+ def test_it_parses_schema_definition
140
+ document = parse('
141
+ schema {
142
+ query: QueryRoot
143
+ mutation: MutationRoot
144
+ subscription: SubscriptionRoot
145
+ }
146
+ ')
147
+
148
+ schema = document.definitions.first
149
+ assert_equal 'QueryRoot', schema.query
150
+ assert_equal 'MutationRoot', schema.mutation
151
+ assert_equal 'SubscriptionRoot', schema.subscription
152
+ end
153
+
154
+ def test_it_parses_whole_definition_with_descriptions
155
+ document = parse(SCHEMA_DEFINITION_STRING)
156
+
157
+ assert_equal 6, document.definitions.size
158
+
159
+ schema_definition = document.definitions.shift
160
+ assert_equal GraphQL::Language::Nodes::SchemaDefinition, schema_definition.class
161
+
162
+ directive_definition = document.definitions.shift
163
+ assert_equal GraphQL::Language::Nodes::DirectiveDefinition, directive_definition.class
164
+ assert_equal 'This is a directive', directive_definition.description
165
+
166
+ enum_type_definition = document.definitions.shift
167
+ assert_equal GraphQL::Language::Nodes::EnumTypeDefinition, enum_type_definition.class
168
+ assert_equal "Multiline comment\n\nWith an enum", enum_type_definition.description
169
+
170
+ assert_nil enum_type_definition.values[0].description
171
+ assert_equal 'Not a creative color', enum_type_definition.values[1].description
172
+
173
+ object_type_definition = document.definitions.shift
174
+ assert_equal GraphQL::Language::Nodes::ObjectTypeDefinition, object_type_definition.class
175
+ assert_equal 'Comment without preceding space', object_type_definition.description
176
+ assert_equal 'And a field to boot', object_type_definition.fields[0].description
177
+
178
+ input_object_type_definition = document.definitions.shift
179
+ assert_equal GraphQL::Language::Nodes::InputObjectTypeDefinition, input_object_type_definition.class
180
+ assert_equal 'Comment for input object types', input_object_type_definition.description
181
+ assert_equal 'Color of the car', input_object_type_definition.fields[0].description
182
+
183
+ interface_type_definition = document.definitions.shift
184
+ assert_equal GraphQL::Language::Nodes::InterfaceTypeDefinition, interface_type_definition.class
185
+ assert_equal 'Comment for interface definitions', interface_type_definition.description
186
+ assert_equal 'Amount of wheels', interface_type_definition.fields[0].description
187
+ end
188
+ end
189
+ end
190
+
191
+ SCHEMA_DEFINITION_STRING = %|
192
+ # Schema at beginning of file
193
+
194
+ schema {
195
+ query: Hello
196
+ }
197
+
198
+ # Comment between two definitions are omitted
199
+
200
+ # This is a directive
201
+ directive @foo(
202
+ # It has an argument
203
+ arg: Int
204
+ ) on FIELD
205
+
206
+ # Multiline comment
207
+ #
208
+ # With an enum
209
+ enum Color {
210
+ RED
211
+
212
+ # Not a creative color
213
+ GREEN
214
+ BLUE
215
+ }
216
+
217
+ #Comment without preceding space
218
+ type Hello {
219
+ # And a field to boot
220
+ str: String
221
+ }
222
+
223
+ # Comment for input object types
224
+ input Car {
225
+ # Color of the car
226
+ color: String!
227
+ }
228
+
229
+ # Comment for interface definitions
230
+ interface Vehicle {
231
+ # Amount of wheels
232
+ wheels: Int!
233
+ }
234
+
235
+ # Comment at the end of schema
236
+ |
237
+ end
238
+ end
239
+ end