Module: GraphQL::Compatibility::SchemaParserSpecification

Defined in:
lib/graphql/compatibility/schema_parser_specification.rb

Overview

This asserts that a given parse function turns a string into the proper tree of {GraphQL{GraphQL::Language{GraphQL::Language::Nodes}.

Constant Summary

SCHEMA_DEFINITION_STRING =
%|
  # Schema at beginning of file

  schema {
    query: Hello
  }

  # Comment between two definitions are omitted

  # This is a directive
  directive @foo(
    # It has an argument
    arg: Int
  ) on FIELD

  # Multiline comment
  #
  # With an enum
  enum Color {
    RED

    # Not a creative color
    GREEN
    BLUE
  }

  #Comment without preceding space
  type Hello {
    # And a field to boot
    str: String
  }

  # Comment for input object types
  input Car {
    # Color of the car
    color: String!
  }

  # Comment for interface definitions
  interface Vehicle {
    # Amount of wheels
    wheels: Int!
    brand(argument: String = null): String!
  }

  # Comment at the end of schema
|

Class Method Summary collapse

Class Method Details

.build_suite {|query_string| ... } ⇒ Class<Minitest::Test>

Returns A test suite for this parse function

Yield Parameters:

  • query_string (String)

    A query string to parse

Yield Returns:

Returns:

  • (Class<Minitest::Test>)

    A test suite for this parse function



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/graphql/compatibility/schema_parser_specification.rb', line 10

def self.build_suite(&block)
  Class.new(Minitest::Test) do
    @@parse_fn = block

    def parse(query_string)
      @@parse_fn.call(query_string)
    end

    def test_it_parses_object_types
      document = parse('
        # This is what
        # somebody said about something
        type Comment implements Node @deprecated(reason: "No longer supported") {
          id: ID!
        }
      ')

      type = document.definitions.first
      assert_equal GraphQL::Language::Nodes::ObjectTypeDefinition, type.class
      assert_equal 'Comment', type.name
      assert_equal "This is what\nsomebody said about something", type.description
      assert_equal ['Node'], type.interfaces.map(&:name)
      assert_equal ['id'], type.fields.map(&:name)
      assert_equal [], type.fields[0].arguments
      assert_equal 'ID', type.fields[0].type.of_type.name
      assert_equal 1, type.directives.length

      deprecated_directive = type.directives[0]
      assert_equal 'deprecated', deprecated_directive.name
      assert_equal 'reason', deprecated_directive.arguments[0].name
      assert_equal 'No longer supported', deprecated_directive.arguments[0].value
    end

    def test_it_parses_scalars
      document = parse('scalar DateTime')

      type = document.definitions.first
      assert_equal GraphQL::Language::Nodes::ScalarTypeDefinition, type.class
      assert_equal 'DateTime', type.name
    end

    def test_it_parses_enum_types
      document = parse('
        enum DogCommand {
          # Good dog
          SIT
          DOWN @deprecated(reason: "No longer supported")
          HEEL
        }
      ')

      type = document.definitions.first
      assert_equal GraphQL::Language::Nodes::EnumTypeDefinition, type.class
      assert_equal 'DogCommand', type.name
      assert_equal 3, type.values.length

      assert_equal 'SIT', type.values[0].name
      assert_equal [], type.values[0].directives
      assert_equal "Good dog", type.values[0].description

      assert_equal 'DOWN', type.values[1].name
      assert_equal 1, type.values[1].directives.length
      deprecated_directive = type.values[1].directives[0]
      assert_equal 'deprecated', deprecated_directive.name
      assert_equal 'reason', deprecated_directive.arguments[0].name
      assert_equal 'No longer supported', deprecated_directive.arguments[0].value

      assert_equal 'HEEL', type.values[2].name
      assert_equal [], type.values[2].directives
    end

    def test_it_parses_union_types
      document = parse(
        "union BagOfThings = \n" \
        "A |\n" \
        "B |\n" \
        "C"
      )

      union = document.definitions.first

      assert_equal GraphQL::Language::Nodes::UnionTypeDefinition, union.class
      assert_equal 'BagOfThings', union.name
      assert_equal 3, union.types.length
      assert_equal [1, 1], union.position

      assert_equal GraphQL::Language::Nodes::TypeName, union.types[0].class
      assert_equal 'A', union.types[0].name
      assert_equal [2, 1], union.types[0].position

      assert_equal GraphQL::Language::Nodes::TypeName, union.types[1].class
      assert_equal 'B', union.types[1].name
      assert_equal [3, 1], union.types[1].position

      assert_equal GraphQL::Language::Nodes::TypeName, union.types[2].class
      assert_equal 'C', union.types[2].name
      assert_equal [4, 1], union.types[2].position
    end

    def test_it_parses_input_types
      document = parse('
        input EmptyMutationInput {
          clientMutationId: String
        }
      ')

      type = document.definitions.first
      assert_equal GraphQL::Language::Nodes::InputObjectTypeDefinition, type.class
      assert_equal 'EmptyMutationInput', type.name
      assert_equal ['clientMutationId'], type.fields.map(&:name)
      assert_equal 'String', type.fields[0].type.name
      assert_equal nil, type.fields[0].default_value
    end

    def test_it_parses_directives
      document = parse('
        directive @include(if: Boolean!)
          on FIELD
          | FRAGMENT_SPREAD
          | INLINE_FRAGMENT
      ')

      type = document.definitions.first
      assert_equal GraphQL::Language::Nodes::DirectiveDefinition, type.class
      assert_equal 'include', type.name

      assert_equal 1, type.arguments.length
      assert_equal 'if', type.arguments[0].name
      assert_equal 'Boolean', type.arguments[0].type.of_type.name

      assert_equal ['FIELD', 'FRAGMENT_SPREAD', 'INLINE_FRAGMENT'], type.locations
    end

    def test_it_parses_field_arguments
      document = parse('
        type Mutation {
          post(
            id: ID! @deprecated(reason: "Not used"),
            # This is what goes in the post
            data: String
          ): Post
        }
      ')

      field = document.definitions.first.fields.first
      assert_equal ['id', 'data'], field.arguments.map(&:name)
      id_arg = field.arguments[0]

      deprecated_directive = id_arg.directives[0]
      assert_equal 'deprecated', deprecated_directive.name
      assert_equal 'reason', deprecated_directive.arguments[0].name
      assert_equal 'Not used', deprecated_directive.arguments[0].value

      data_arg = field.arguments[1]
      assert_equal "data", data_arg.name
      assert_equal "This is what goes in the post", data_arg.description
    end

    def test_it_parses_schema_definition
      document = parse('
        schema {
          query: QueryRoot
          mutation: MutationRoot
          subscription: SubscriptionRoot
        }
      ')

      schema = document.definitions.first
      assert_equal 'QueryRoot', schema.query
      assert_equal 'MutationRoot', schema.mutation
      assert_equal 'SubscriptionRoot', schema.subscription
    end

    def test_it_parses_whole_definition_with_descriptions
      document = parse(SCHEMA_DEFINITION_STRING)

      assert_equal 6, document.definitions.size

      schema_definition = document.definitions.shift
      assert_equal GraphQL::Language::Nodes::SchemaDefinition, schema_definition.class

      directive_definition = document.definitions.shift
      assert_equal GraphQL::Language::Nodes::DirectiveDefinition, directive_definition.class
      assert_equal 'This is a directive', directive_definition.description

      enum_type_definition = document.definitions.shift
      assert_equal GraphQL::Language::Nodes::EnumTypeDefinition, enum_type_definition.class
      assert_equal "Multiline comment\n\nWith an enum", enum_type_definition.description

      assert_nil enum_type_definition.values[0].description
      assert_equal 'Not a creative color', enum_type_definition.values[1].description

      object_type_definition = document.definitions.shift
      assert_equal GraphQL::Language::Nodes::ObjectTypeDefinition, object_type_definition.class
      assert_equal 'Comment without preceding space', object_type_definition.description
      assert_equal 'And a field to boot', object_type_definition.fields[0].description

      input_object_type_definition = document.definitions.shift
      assert_equal GraphQL::Language::Nodes::InputObjectTypeDefinition, input_object_type_definition.class
      assert_equal 'Comment for input object types', input_object_type_definition.description
      assert_equal 'Color of the car', input_object_type_definition.fields[0].description

      interface_type_definition = document.definitions.shift
      assert_equal GraphQL::Language::Nodes::InterfaceTypeDefinition, interface_type_definition.class
      assert_equal 'Comment for interface definitions', interface_type_definition.description
      assert_equal 'Amount of wheels', interface_type_definition.fields[0].description

      brand_field = interface_type_definition.fields[1]
      assert_equal 1, brand_field.arguments.length
      assert_equal 'argument', brand_field.arguments[0].name
      assert_instance_of GraphQL::Language::Nodes::NullValue, brand_field.arguments[0].default_value
    end
  end
end