graphql 1.6.3 → 1.6.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b8eca19d9b215aed67ef5434bb5dab5cce3e8626
4
- data.tar.gz: 66740ce037cbd8e4019ed7516503e430ebb0a34a
3
+ metadata.gz: 347eef5d121c7ccb7f0c217370e2a02285d36096
4
+ data.tar.gz: e2b7083f415d77f05dcb888c121075617c93e677
5
5
  SHA512:
6
- metadata.gz: 6e34b8bce773c1304d9c4796a20a92c731de182ad1a144df2bb4a814295a2233b298d8817d24c96837540b57fd73ca3a9acb55b286308c1b7a3b3725f31c3e11
7
- data.tar.gz: b9cce7a863dfaabcb7312a0844ef659504cf5adedfe7b22246ce4856ae78d71c6204535a1351b5d0c746161b5155d06cd25f845a0d8fdc3776a9ee27ed41160d
6
+ metadata.gz: 07a84a28ba76c6b7f0586b1c4e73745ae4d279482cab00b2a1ae6d087e566156359f993d325cc102c7af3ed23b0dc3f381d29635fef85ebe73d71ed103d7e0f2
7
+ data.tar.gz: d5b0dcfeb682086a666c839ebf4d0dcfd695201682016cc55d16d28d6f487012ac8f82e6360ea58780e3a6874c4eee52b49d0e8f44d37817e0672decdb27753f
@@ -68,6 +68,11 @@ module Graphql
68
68
  default: false,
69
69
  desc: "Include GraphQL::Batch installation"
70
70
 
71
+ # These two options are taken from Rails' own generators'
72
+ class_option :api,
73
+ type: :boolean,
74
+ desc: "Preconfigure smaller stack for API only apps"
75
+
71
76
 
72
77
  GRAPHIQL_ROUTE = <<-RUBY
73
78
  if Rails.env.development?
@@ -83,19 +88,40 @@ RUBY
83
88
  template("graphql_controller.erb", "app/controllers/graphql_controller.rb")
84
89
  route('post "/graphql", to: "graphql#execute"')
85
90
 
86
- if !options[:skip_graphiql]
87
- gem("graphiql-rails", group: :development)
88
- route(GRAPHIQL_ROUTE)
89
- end
90
-
91
91
  if options[:batch]
92
92
  gem("graphql-batch")
93
93
  create_dir("app/graphql/loaders")
94
94
  end
95
+
96
+ if options.api?
97
+ say("Skipped graphiql, as this rails project is API only")
98
+ say(" You may wish to use GraphiQL.app for development: https://github.com/skevy/graphiql-app")
99
+ elsif !options[:skip_graphiql]
100
+ gem("graphiql-rails", group: :development)
101
+
102
+ # This is a little cheat just to get cleaner shell output:
103
+ log :route, 'graphiql-rails'
104
+ shell.mute do
105
+ route(GRAPHIQL_ROUTE)
106
+ end
107
+ end
108
+
109
+ if gemfile_modified?
110
+ say "Gemfile has been modified, make sure you `bundle install`"
111
+ end
95
112
  end
96
113
 
97
114
  private
98
115
 
116
+ def gemfile_modified?
117
+ @gemfile_modified
118
+ end
119
+
120
+ def gem(*args)
121
+ @gemfile_modified = true
122
+ super(*args)
123
+ end
124
+
99
125
  def create_dir(dir)
100
126
  empty_directory(dir)
101
127
  if !options[:skip_keeps]
@@ -2,11 +2,12 @@ class GraphqlController < ApplicationController
2
2
  def execute
3
3
  variables = ensure_hash(params[:variables])
4
4
  query = params[:query]
5
+ operation_name = params[:operationName]
5
6
  context = {
6
7
  # Query context goes here, for example:
7
8
  # current_user: current_user,
8
9
  }
9
- result = <%= schema_name %>.execute(query, variables: variables, context: context)
10
+ result = <%= schema_name %>.execute(query, variables: variables, context: context, operation_name: operation_name)
10
11
  render json: result
11
12
  end
12
13
 
@@ -29,6 +29,9 @@ module GraphQL
29
29
 
30
30
  attr_reader :schema, :context, :root_value, :warden, :provided_variables, :operation_name
31
31
 
32
+ # @return [Boolean] if false, static validation is skipped (execution behavior for invalid queries is undefined)
33
+ attr_accessor :validate
34
+
32
35
  attr_accessor :query_string
33
36
 
34
37
  # @return [GraphQL::Language::Nodes::Document]
@@ -59,6 +62,7 @@ module GraphQL
59
62
  @root_value = root_value
60
63
  @fragments = nil
61
64
  @operations = nil
65
+ @validate = validate
62
66
 
63
67
  @analysis_errors = []
64
68
  if variables.is_a?(String)
@@ -270,6 +274,7 @@ module GraphQL
270
274
 
271
275
  @validation_pipeline = GraphQL::Query::ValidationPipeline.new(
272
276
  query: self,
277
+ validate: @validate,
273
278
  parse_error: parse_error,
274
279
  operation_name_error: operation_name_error,
275
280
  max_depth: @max_depth,
@@ -77,6 +77,10 @@ module GraphQL
77
77
  # `context` isn't present when pre-calculating defaults
78
78
  if context
79
79
  value = arg_defn.prepare(value, context)
80
+ if value.is_a?(GraphQL::ExecutionError)
81
+ value.ast_node = ast_arg
82
+ raise value
83
+ end
80
84
  end
81
85
  values_hash[arg_name] = value
82
86
  end
@@ -24,7 +24,7 @@ module GraphQL
24
24
  def result
25
25
  result_name = irep_node.name
26
26
  raw_value = get_raw_value
27
- if raw_value == GraphQL::Execution::Execute::SKIP
27
+ if raw_value.is_a?(GraphQL::Execution::Execute::Skip)
28
28
  {}
29
29
  else
30
30
  { result_name => get_finished_value(raw_value) }
@@ -14,10 +14,11 @@ module GraphQL
14
14
  #
15
15
  # @api private
16
16
  class ValidationPipeline
17
- def initialize(query:, parse_error:, operation_name_error:, max_depth:, max_complexity:)
17
+ def initialize(query:, validate:, parse_error:, operation_name_error:, max_depth:, max_complexity:)
18
18
  @validation_errors = []
19
19
  @analysis_errors = []
20
20
  @internal_representation = nil
21
+ @validate = validate
21
22
  @parse_error = parse_error
22
23
  @operation_name_error = operation_name_error
23
24
  @query = query
@@ -76,7 +77,7 @@ module GraphQL
76
77
  elsif @operation_name_error
77
78
  @validation_errors << @operation_name_error
78
79
  else
79
- validation_result = @schema.static_validator.validate(@query)
80
+ validation_result = @schema.static_validator.validate(@query, validate: @validate)
80
81
  @validation_errors.concat(validation_result[:errors])
81
82
  @internal_representation = validation_result[:irep]
82
83
 
@@ -186,7 +186,7 @@ module GraphQL
186
186
  end
187
187
 
188
188
  out = "(\n".dup
189
- out << arguments.map.with_index{ |arg, i|
189
+ out << arguments.sort_by(&:name).map.with_index{ |arg, i|
190
190
  "#{print_description(arg, " #{indentation}", i == 0)} #{indentation}"\
191
191
  "#{print_input_value(arg)}"
192
192
  }.join("\n")
@@ -244,7 +244,7 @@ module GraphQL
244
244
  include DescriptionPrinter
245
245
  def print_fields(warden, type)
246
246
  fields = warden.fields(type)
247
- fields.map.with_index { |field, i|
247
+ fields.sort_by(&:name).map.with_index { |field, i|
248
248
  "#{print_description(field, ' ', i == 0)}"\
249
249
  " #{field.name}#{print_args(warden, field, ' ')}: #{field.type}#{print_deprecated(field)}"
250
250
  }.join("\n")
@@ -275,7 +275,7 @@ module GraphQL
275
275
  def self.print(warden, type)
276
276
  interfaces = warden.interfaces(type)
277
277
  if interfaces.any?
278
- implementations = " implements #{interfaces.map(&:to_s).join(", ")}"
278
+ implementations = " implements #{interfaces.sort_by(&:name).map(&:to_s).join(", ")}"
279
279
  else
280
280
  implementations = nil
281
281
  end
@@ -301,7 +301,7 @@ module GraphQL
301
301
  def self.print(warden, type)
302
302
  possible_types = warden.possible_types(type)
303
303
  "#{print_description(type)}"\
304
- "union #{type.name} = #{possible_types.map(&:to_s).join(" | ")}"
304
+ "union #{type.name} = #{possible_types.sort_by(&:name).map(&:to_s).join(" | ")}"
305
305
  end
306
306
  end
307
307
 
@@ -311,7 +311,7 @@ module GraphQL
311
311
  def self.print(warden, type)
312
312
  enum_values = warden.enum_values(type)
313
313
 
314
- values = enum_values.map.with_index { |v, i|
314
+ values = enum_values.sort_by(&:name).map.with_index { |v, i|
315
315
  "#{print_description(v, ' ', i == 0)}"\
316
316
  " #{v.name}#{print_deprecated(v)}"
317
317
  }.join("\n")
@@ -326,7 +326,7 @@ module GraphQL
326
326
  extend DescriptionPrinter
327
327
  def self.print(warden, type)
328
328
  arguments = warden.arguments(type)
329
- fields = arguments.map.with_index{ |field, i|
329
+ fields = arguments.sort_by(&:name).map.with_index{ |field, i|
330
330
  "#{print_description(field, " ", i == 0)}"\
331
331
  " #{print_input_value(field)}"
332
332
  }.join("\n")
@@ -7,8 +7,8 @@ module GraphQL
7
7
  #
8
8
  # @example Validate a query
9
9
  # validator = GraphQL::StaticValidation::Validator.new(schema: MySchema)
10
- # document = GraphQL.parse(query_string)
11
- # errors = validator.validate(document)
10
+ # query = GraphQL::Query.new(MySchema, query_string)
11
+ # errors = validator.validate(query)[:errors]
12
12
  #
13
13
  class Validator
14
14
  # @param schema [GraphQL::Schema]
@@ -21,14 +21,18 @@ module GraphQL
21
21
  # Validate `query` against the schema. Returns an array of message hashes.
22
22
  # @param query [GraphQL::Query]
23
23
  # @return [Array<Hash>]
24
- def validate(query)
24
+ def validate(query, validate: true)
25
25
  context = GraphQL::StaticValidation::ValidationContext.new(query)
26
26
  rewrite = GraphQL::InternalRepresentation::Rewrite.new
27
27
 
28
28
  # Put this first so its enters and exits are always called
29
29
  rewrite.validate(context)
30
- @rules.each do |rules|
31
- rules.new.validate(context)
30
+
31
+ # If the caller opted out of validation, don't attach these
32
+ if validate
33
+ @rules.each do |rules|
34
+ rules.new.validate(context)
35
+ end
32
36
  end
33
37
 
34
38
  context.visitor.visit
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "1.6.3"
3
+ VERSION = "1.6.4"
4
4
  end
data/readme.md CHANGED
@@ -31,6 +31,8 @@ $ bundle install
31
31
  $ rails generate graphql:install
32
32
  ```
33
33
 
34
+ After this, you may need to run `bundle install` again, as by default graphiql-rails is added on installation.
35
+
34
36
  Or, see ["Getting Started"](https://rmosolgo.github.io/graphql-ruby/).
35
37
 
36
38
  ## Upgrade
@@ -3,20 +3,19 @@ require "spec_helper"
3
3
  require "generators/graphql/install_generator"
4
4
 
5
5
  class GraphQLGeneratorsInstallGeneratorTest < Rails::Generators::TestCase
6
-
7
6
  tests Graphql::Generators::InstallGenerator
8
7
  destination File.expand_path("../../../tmp/dummy", File.dirname(__FILE__))
9
8
 
10
9
  setup do
11
10
  prepare_destination
12
- FileUtils.cd(File.expand_path("../../../tmp", File.dirname(__FILE__))) do
13
- `rm -rf dummy`
11
+
12
+ FileUtils.cd(File.join(destination_root, '..')) do
14
13
  `rails new dummy --skip-active-record --skip-test-unit --skip-spring --skip-bundle`
15
14
  end
16
15
  end
17
16
 
18
17
  test "it generates a folder structure" do
19
- run_generator([])
18
+ run_generator
20
19
 
21
20
  assert_file "app/graphql/types/.keep"
22
21
  assert_file "app/graphql/mutations/.keep"
@@ -93,6 +92,18 @@ RUBY
93
92
  assert_file "app/graphql/dummy_schema.rb", EXPECTED_RELAY_BATCH_SCHEMA
94
93
  end
95
94
 
95
+ test "it doesn't install graphiql when API Only" do
96
+ run_generator(['--api'])
97
+
98
+ assert_file "Gemfile" do |contents|
99
+ refute_includes contents, "graphiql-rails"
100
+ end
101
+
102
+ assert_file "config/routes.rb" do |contents|
103
+ refute_includes contents, "GraphiQL::Rails"
104
+ end
105
+ end
106
+
96
107
  test "it can skip keeps, skip graphiql and customize schema name" do
97
108
  run_generator(["--skip-keeps", "--skip-graphiql", "--schema=CustomSchema"])
98
109
  assert_no_file "app/graphql/types/.keep"
@@ -116,11 +127,12 @@ class GraphqlController < ApplicationController
116
127
  def execute
117
128
  variables = ensure_hash(params[:variables])
118
129
  query = params[:query]
130
+ operation_name = params[:operationName]
119
131
  context = {
120
132
  # Query context goes here, for example:
121
133
  # current_user: current_user,
122
134
  }
123
- result = DummySchema.execute(query, variables: variables, context: context)
135
+ result = DummySchema.execute(query, variables: variables, context: context, operation_name: operation_name)
124
136
  render json: result
125
137
  end
126
138
 
@@ -72,9 +72,9 @@ describe GraphQL::BaseType do
72
72
  expected = <<TYPE
73
73
  # A blog post
74
74
  type Post {
75
+ body: String!
75
76
  id: ID!
76
77
  title: String!
77
- body: String!
78
78
  }
79
79
  TYPE
80
80
 
@@ -20,6 +20,19 @@ describe GraphQL::Query::LiteralInput do
20
20
  end
21
21
  resolve ->(t, a, c) { a[:value] }
22
22
  end
23
+
24
+ field :fieldWithArgumentThatIsBadByDefault do
25
+ type types.Int
26
+ argument :value do
27
+ type types.Int
28
+ default_value 7
29
+ prepare ->(arg, ctx) do
30
+ GraphQL::ExecutionError.new("Always bad")
31
+ end
32
+ end
33
+
34
+ resolve ->(*args) { 42 }
35
+ end
23
36
  end
24
37
 
25
38
  GraphQL::Schema.define(query: query)
@@ -35,6 +48,11 @@ describe GraphQL::Query::LiteralInput do
35
48
  assert_equal(7, result["data"]["addToArgumentValue"])
36
49
  end
37
50
 
51
+ it "raises an execution error if the default value is bad" do
52
+ result = schema.execute("{ fieldWithArgumentThatIsBadByDefault }", context: { })
53
+ assert_equal(result["errors"], [{"message" => "Always bad"}])
54
+ end
55
+
38
56
  it "prepares values from variables" do
39
57
  result = schema.execute("query ($value: Int!) { addToArgumentValue(value: $value) }", variables: { "value" => 1}, context: { val: 2 } )
40
58
  assert_equal(result["data"]["addToArgumentValue"], 3)
@@ -518,6 +518,27 @@ describe GraphQL::Query do
518
518
  end
519
519
  end
520
520
 
521
+ describe "validate: false" do
522
+ it "doesn't validate the query" do
523
+ invalid_query_string = "{ nonExistantField }"
524
+ # Can assign attribute
525
+ query = GraphQL::Query.new(schema, invalid_query_string)
526
+ query.validate = false
527
+ assert_equal true, query.valid?
528
+ assert_equal 0, query.static_errors.length
529
+
530
+ # Can pass keyword argument
531
+ query = GraphQL::Query.new(schema, invalid_query_string, validate: false)
532
+ assert_equal true, query.valid?
533
+ assert_equal 0, query.static_errors.length
534
+
535
+ # Can pass `true`
536
+ query = GraphQL::Query.new(schema, invalid_query_string, validate: true)
537
+ assert_equal false, query.valid?
538
+ assert_equal 1, query.static_errors.length
539
+ end
540
+ end
541
+
521
542
  describe 'NullValue type arguments' do
522
543
  let(:schema_definition) {
523
544
  <<-GRAPHQL
@@ -19,11 +19,11 @@ schema {
19
19
  }
20
20
 
21
21
  type HelloScalars {
22
- str: String!
23
- int: Int
22
+ bool: Boolean
24
23
  float: Float
25
24
  id: ID
26
- bool: Boolean
25
+ int: Int
26
+ str: String!
27
27
  }
28
28
  SCHEMA
29
29
 
@@ -60,11 +60,11 @@ directive @foo(
60
60
 
61
61
  # With an enum
62
62
  enum Color {
63
- RED
63
+ BLUE
64
64
 
65
65
  # Not a creative color
66
66
  GREEN
67
- BLUE
67
+ RED
68
68
  }
69
69
 
70
70
  # What a great type
@@ -142,11 +142,11 @@ schema {
142
142
  }
143
143
 
144
144
  type HelloScalars {
145
- nonNullStr: String!
146
- listOfStrs: [String]
147
145
  listOfNonNullStrs: [String!]
148
- nonNullListOfStrs: [String]!
146
+ listOfStrs: [String]
149
147
  nonNullListOfNonNullStrs: [String!]!
148
+ nonNullListOfStrs: [String]!
149
+ nonNullStr: String!
150
150
  }
151
151
  SCHEMA
152
152
 
@@ -160,8 +160,8 @@ schema {
160
160
  }
161
161
 
162
162
  type Recurse {
163
- str: String
164
163
  recurse: Recurse
164
+ str: String
165
165
  }
166
166
  SCHEMA
167
167
 
@@ -195,10 +195,10 @@ schema {
195
195
  }
196
196
 
197
197
  type Hello {
198
- str(int: Int): String
198
+ booleanToStr(bool: Boolean): String
199
199
  floatToStr(float: Float): String
200
200
  idToStr(id: ID): String
201
- booleanToStr(bool: Boolean): String
201
+ str(int: Int): String
202
202
  strToStr(bool: String): String
203
203
  }
204
204
  SCHEMA
@@ -281,8 +281,8 @@ schema {
281
281
  }
282
282
 
283
283
  enum Hello {
284
- WO
285
284
  RLD
285
+ WO
286
286
  }
287
287
 
288
288
  type OutputEnumRoot {
@@ -382,14 +382,14 @@ schema {
382
382
  }
383
383
 
384
384
  enum Color {
385
- RED
386
385
  BLUE
386
+ RED
387
387
  }
388
388
 
389
389
  type Hello {
390
- str(int: Int = 2): String
391
390
  hello(color: Color = RED): String
392
391
  nullable(color: Color = null): String
392
+ str(int: Int = 2): String
393
393
  }
394
394
  SCHEMA
395
395
 
@@ -404,9 +404,9 @@ schema {
404
404
  }
405
405
 
406
406
  type HelloScalars {
407
- str: String
408
- int: Int
409
407
  bool: Boolean
408
+ int: Int
409
+ str: String
410
410
  }
411
411
 
412
412
  type Mutation {
@@ -420,8 +420,8 @@ type Mutation {
420
420
  it 'supports simple type with mutation and default values' do
421
421
  schema = <<-SCHEMA
422
422
  enum Color {
423
- RED
424
423
  BLUE
424
+ RED
425
425
  }
426
426
 
427
427
  type Mutation {
@@ -444,9 +444,9 @@ schema {
444
444
  }
445
445
 
446
446
  type HelloScalars {
447
- str: String
448
- int: Int
449
447
  bool: Boolean
448
+ int: Int
449
+ str: String
450
450
  }
451
451
 
452
452
  type Subscription {
@@ -494,15 +494,15 @@ union Union = Concrete
494
494
  it 'supports @deprecated' do
495
495
  schema = <<-SCHEMA
496
496
  enum MyEnum {
497
- VALUE
498
497
  OLD_VALUE @deprecated
499
498
  OTHER_VALUE @deprecated(reason: "Terrible reasons")
499
+ VALUE
500
500
  }
501
501
 
502
502
  type Query {
503
+ enum: MyEnum
503
504
  field1: String @deprecated
504
505
  field2: Int @deprecated(reason: "Because I said so")
505
- enum: MyEnum
506
506
  }
507
507
  SCHEMA
508
508
 
@@ -136,13 +136,13 @@ schema {
136
136
  query: Root
137
137
  }
138
138
 
139
- # Directs the executor to include this field or fragment only when the \`if\` argument is true.
139
+ # Directs the executor to include this field or fragment only when the `if` argument is true.
140
140
  directive @include(
141
141
  # Included when true.
142
142
  if: Boolean!
143
143
  ) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
144
144
 
145
- # Directs the executor to skip this field or fragment when the \`if\` argument is true.
145
+ # Directs the executor to skip this field or fragment when the `if` argument is true.
146
146
  directive @skip(
147
147
  # Skipped when true.
148
148
  if: Boolean!
@@ -163,30 +163,33 @@ directive @deprecated(
163
163
  # skipping a field. Directives provide this by describing additional information
164
164
  # to the executor.
165
165
  type __Directive {
166
- name: String!
166
+ args: [__InputValue!]!
167
167
  description: String
168
168
  locations: [__DirectiveLocation!]!
169
- args: [__InputValue!]!
170
- onOperation: Boolean! @deprecated(reason: "Use \`locations\`.")
171
- onFragment: Boolean! @deprecated(reason: "Use \`locations\`.")
172
- onField: Boolean! @deprecated(reason: "Use \`locations\`.")
169
+ name: String!
170
+ onField: Boolean! @deprecated(reason: "Use `locations`.")
171
+ onFragment: Boolean! @deprecated(reason: "Use `locations`.")
172
+ onOperation: Boolean! @deprecated(reason: "Use `locations`.")
173
173
  }
174
174
 
175
175
  # A Directive can be adjacent to many parts of the GraphQL language, a
176
176
  # __DirectiveLocation describes one such possible adjacencies.
177
177
  enum __DirectiveLocation {
178
- # Location adjacent to a query operation.
179
- QUERY
178
+ # Location adjacent to an argument definition.
179
+ ARGUMENT_DEFINITION
180
180
 
181
- # Location adjacent to a mutation operation.
182
- MUTATION
181
+ # Location adjacent to an enum definition.
182
+ ENUM
183
183
 
184
- # Location adjacent to a subscription operation.
185
- SUBSCRIPTION
184
+ # Location adjacent to an enum value definition.
185
+ ENUM_VALUE
186
186
 
187
187
  # Location adjacent to a field.
188
188
  FIELD
189
189
 
190
+ # Location adjacent to a field definition.
191
+ FIELD_DEFINITION
192
+
190
193
  # Location adjacent to a fragment definition.
191
194
  FRAGMENT_DEFINITION
192
195
 
@@ -196,95 +199,91 @@ enum __DirectiveLocation {
196
199
  # Location adjacent to an inline fragment.
197
200
  INLINE_FRAGMENT
198
201
 
199
- # Location adjacent to a schema definition.
200
- SCHEMA
202
+ # Location adjacent to an input object field definition.
203
+ INPUT_FIELD_DEFINITION
201
204
 
202
- # Location adjacent to a scalar definition.
203
- SCALAR
205
+ # Location adjacent to an input object type definition.
206
+ INPUT_OBJECT
207
+
208
+ # Location adjacent to an interface definition.
209
+ INTERFACE
210
+
211
+ # Location adjacent to a mutation operation.
212
+ MUTATION
204
213
 
205
214
  # Location adjacent to an object type definition.
206
215
  OBJECT
207
216
 
208
- # Location adjacent to a field definition.
209
- FIELD_DEFINITION
217
+ # Location adjacent to a query operation.
218
+ QUERY
210
219
 
211
- # Location adjacent to an argument definition.
212
- ARGUMENT_DEFINITION
220
+ # Location adjacent to a scalar definition.
221
+ SCALAR
213
222
 
214
- # Location adjacent to an interface definition.
215
- INTERFACE
223
+ # Location adjacent to a schema definition.
224
+ SCHEMA
225
+
226
+ # Location adjacent to a subscription operation.
227
+ SUBSCRIPTION
216
228
 
217
229
  # Location adjacent to a union definition.
218
230
  UNION
219
-
220
- # Location adjacent to an enum definition.
221
- ENUM
222
-
223
- # Location adjacent to an enum value definition.
224
- ENUM_VALUE
225
-
226
- # Location adjacent to an input object type definition.
227
- INPUT_OBJECT
228
-
229
- # Location adjacent to an input object field definition.
230
- INPUT_FIELD_DEFINITION
231
231
  }
232
232
 
233
233
  # One possible value for a given Enum. Enum values are unique values, not a
234
234
  # placeholder for a string or numeric value. However an Enum value is returned in
235
235
  # a JSON response as a string.
236
236
  type __EnumValue {
237
- name: String!
237
+ deprecationReason: String
238
238
  description: String
239
239
  isDeprecated: Boolean!
240
- deprecationReason: String
240
+ name: String!
241
241
  }
242
242
 
243
243
  # Object and Interface types are described by a list of Fields, each of which has
244
244
  # a name, potentially a list of arguments, and a return type.
245
245
  type __Field {
246
- name: String!
247
- description: String
248
246
  args: [__InputValue!]!
249
- type: __Type!
250
- isDeprecated: Boolean!
251
247
  deprecationReason: String
248
+ description: String
249
+ isDeprecated: Boolean!
250
+ name: String!
251
+ type: __Type!
252
252
  }
253
253
 
254
254
  # Arguments provided to Fields or Directives and the input fields of an
255
255
  # InputObject are represented as Input Values which describe their type and
256
256
  # optionally a default value.
257
257
  type __InputValue {
258
- name: String!
259
- description: String
260
- type: __Type!
261
-
262
258
  # A GraphQL-formatted string representing the default value for this input value.
263
259
  defaultValue: String
260
+ description: String
261
+ name: String!
262
+ type: __Type!
264
263
  }
265
264
 
266
265
  # A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all
267
266
  # available types and directives on the server, as well as the entry points for
268
267
  # query, mutation, and subscription operations.
269
268
  type __Schema {
270
- # A list of all types supported by this server.
271
- types: [__Type!]!
272
-
273
- # The type that query operations will be rooted at.
274
- queryType: __Type!
269
+ # A list of all directives supported by this server.
270
+ directives: [__Directive!]!
275
271
 
276
272
  # If this server supports mutation, the type that mutation operations will be rooted at.
277
273
  mutationType: __Type
278
274
 
275
+ # The type that query operations will be rooted at.
276
+ queryType: __Type!
277
+
279
278
  # If this server support subscription, the type that subscription operations will be rooted at.
280
279
  subscriptionType: __Type
281
280
 
282
- # A list of all directives supported by this server.
283
- directives: [__Directive!]!
281
+ # A list of all types supported by this server.
282
+ types: [__Type!]!
284
283
  }
285
284
 
286
285
  # The fundamental unit of any GraphQL Schema is the type. There are many kinds of
287
- # types in GraphQL as represented by the \`__TypeKind\` enum.
286
+ # types in GraphQL as represented by the `__TypeKind` enum.
288
287
  #
289
288
  # Depending on the kind of a type, certain fields describe information about that
290
289
  # type. Scalar types provide no information beyond a name and description, while
@@ -292,42 +291,42 @@ type __Schema {
292
291
  # they describe. Abstract types, Union and Interface, provide the Object types
293
292
  # possible at runtime. List and NonNull types compose other types.
294
293
  type __Type {
295
- kind: __TypeKind!
296
- name: String
297
294
  description: String
298
- fields(includeDeprecated: Boolean = false): [__Field!]
299
- interfaces: [__Type!]
300
- possibleTypes: [__Type!]
301
295
  enumValues(includeDeprecated: Boolean = false): [__EnumValue!]
296
+ fields(includeDeprecated: Boolean = false): [__Field!]
302
297
  inputFields: [__InputValue!]
298
+ interfaces: [__Type!]
299
+ kind: __TypeKind!
300
+ name: String
303
301
  ofType: __Type
302
+ possibleTypes: [__Type!]
304
303
  }
305
304
 
306
- # An enum describing what kind of type a given \`__Type\` is.
305
+ # An enum describing what kind of type a given `__Type` is.
307
306
  enum __TypeKind {
308
- # Indicates this type is a scalar.
309
- SCALAR
307
+ # Indicates this type is an enum. `enumValues` is a valid field.
308
+ ENUM
310
309
 
311
- # Indicates this type is an object. \`fields\` and \`interfaces\` are valid fields.
312
- OBJECT
310
+ # Indicates this type is an input object. `inputFields` is a valid field.
311
+ INPUT_OBJECT
313
312
 
314
- # Indicates this type is an interface. \`fields\` and \`possibleTypes\` are valid fields.
313
+ # Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.
315
314
  INTERFACE
316
315
 
317
- # Indicates this type is a union. \`possibleTypes\` is a valid field.
318
- UNION
316
+ # Indicates this type is a list. `ofType` is a valid field.
317
+ LIST
319
318
 
320
- # Indicates this type is an enum. \`enumValues\` is a valid field.
321
- ENUM
319
+ # Indicates this type is a non-null. `ofType` is a valid field.
320
+ NON_NULL
322
321
 
323
- # Indicates this type is an input object. \`inputFields\` is a valid field.
324
- INPUT_OBJECT
322
+ # Indicates this type is an object. `fields` and `interfaces` are valid fields.
323
+ OBJECT
325
324
 
326
- # Indicates this type is a list. \`ofType\` is a valid field.
327
- LIST
325
+ # Indicates this type is a scalar.
326
+ SCALAR
328
327
 
329
- # Indicates this type is a non-null. \`ofType\` is a valid field.
330
- NON_NULL
328
+ # Indicates this type is a union. `possibleTypes` is a valid field.
329
+ UNION
331
330
  }
332
331
  SCHEMA
333
332
  assert_equal expected.chomp, GraphQL::Schema::Printer.print_introspection_schema
@@ -384,15 +383,15 @@ SCHEMA
384
383
  it "returns the schema as a string for the defined types" do
385
384
  expected = <<SCHEMA
386
385
  type Audio {
386
+ duration: Int!
387
387
  id: ID!
388
388
  name: String!
389
- duration: Int!
390
389
  }
391
390
 
392
391
  enum Choice {
393
- FOO
394
392
  BAR
395
393
  BAZ @deprecated(reason: "Use \\\"BAR\\\".")
394
+ FOO
396
395
  WOZ @deprecated
397
396
  }
398
397
 
@@ -403,10 +402,11 @@ type Comment implements Node {
403
402
 
404
403
  # Autogenerated input type of CreatePost
405
404
  input CreatePostInput {
405
+ body: String!
406
+
406
407
  # A unique identifier for the client performing the mutation.
407
408
  clientMutationId: String
408
409
  title: String!
409
- body: String!
410
410
  }
411
411
 
412
412
  # Autogenerated return type of CreatePost
@@ -417,14 +417,14 @@ type CreatePostPayload {
417
417
  }
418
418
 
419
419
  type Image {
420
+ height: Int!
420
421
  id: ID!
421
422
  name: String!
422
423
  width: Int!
423
- height: Int!
424
424
  }
425
425
 
426
426
  # Media objects
427
- union Media = Image | Audio
427
+ union Media = Audio | Image
428
428
 
429
429
  type Mutation {
430
430
  # Create a blog post
@@ -437,11 +437,11 @@ interface Node {
437
437
 
438
438
  # A blog post
439
439
  type Post {
440
- id: ID!
441
- title: String!
442
440
  body: String!
443
441
  comments: [Comment!]
444
- comments_count: Int! @deprecated(reason: \"Use \\\"comments\\\".\")
442
+ comments_count: Int! @deprecated(reason: "Use \\\"comments\\\".")
443
+ id: ID!
444
+ title: String!
445
445
  }
446
446
 
447
447
  # The query root of this schema
@@ -449,7 +449,7 @@ type Query {
449
449
  post(
450
450
  # Post ID
451
451
  id: ID!
452
- varied: Varied = {id: \"123\", int: 234, float: 2.3, enum: FOO, sub: [{string: \"str\"}]}
452
+ varied: Varied = {id: "123", int: 234, float: 2.3, enum: FOO, sub: [{string: "str"}]}
453
453
  variedWithNulls: Varied = {id: null, int: null, float: null, enum: null, sub: null}
454
454
  ): Post
455
455
  }
@@ -457,10 +457,10 @@ type Query {
457
457
  # Test
458
458
  input Sub {
459
459
  # Something
460
- string: String
460
+ int: Int
461
461
 
462
462
  # Something
463
- int: Int
463
+ string: String
464
464
  }
465
465
 
466
466
  type Subscription {
@@ -468,14 +468,15 @@ type Subscription {
468
468
  }
469
469
 
470
470
  input Varied {
471
- id: ID
472
- int: Int
473
- float: Float
474
471
  bool: Boolean
475
472
  enum: Choice = FOO
473
+ float: Float
474
+ id: ID
475
+ int: Int
476
476
  sub: [Sub]
477
477
  }
478
478
  SCHEMA
479
+
479
480
  assert_equal expected.chomp, GraphQL::Schema::Printer.print_schema(schema)
480
481
  end
481
482
  end
@@ -483,8 +484,8 @@ SCHEMA
483
484
  it "applies an `only` filter" do
484
485
  expected = <<SCHEMA
485
486
  enum Choice {
486
- FOO
487
487
  BAR
488
+ FOO
488
489
  }
489
490
 
490
491
  type Subscription {
@@ -492,10 +493,10 @@ type Subscription {
492
493
  }
493
494
 
494
495
  input Varied {
495
- int: Int
496
- float: Float
497
496
  bool: Boolean
498
497
  enum: Choice = FOO
498
+ float: Float
499
+ int: Int
499
500
  }
500
501
  SCHEMA
501
502
 
@@ -520,14 +521,14 @@ SCHEMA
520
521
  it "applies an `except` filter" do
521
522
  expected = <<SCHEMA
522
523
  type Audio {
524
+ duration: Int!
523
525
  id: ID!
524
526
  name: String!
525
- duration: Int!
526
527
  }
527
528
 
528
529
  enum Choice {
529
- FOO
530
530
  BAR
531
+ FOO
531
532
  }
532
533
 
533
534
  # A blog comment
@@ -537,10 +538,11 @@ type Comment implements Node {
537
538
 
538
539
  # Autogenerated input type of CreatePost
539
540
  input CreatePostInput {
541
+ body: String!
542
+
540
543
  # A unique identifier for the client performing the mutation.
541
544
  clientMutationId: String
542
545
  title: String!
543
- body: String!
544
546
  }
545
547
 
546
548
  # Autogenerated return type of CreatePost
@@ -564,10 +566,10 @@ interface Node {
564
566
 
565
567
  # A blog post
566
568
  type Post {
567
- id: ID!
568
- title: String!
569
569
  body: String!
570
570
  comments: [Comment!]
571
+ id: ID!
572
+ title: String!
571
573
  }
572
574
 
573
575
  # The query root of this schema
@@ -596,11 +598,11 @@ SCHEMA
596
598
  expected = <<SCHEMA
597
599
  # A blog post
598
600
  type Post {
599
- id: ID!
600
- title: String!
601
601
  body: String!
602
602
  comments: [Comment!]
603
603
  comments_count: Int! @deprecated(reason: \"Use \\\"comments\\\".\")
604
+ id: ID!
605
+ title: String!
604
606
  }
605
607
  SCHEMA
606
608
  assert_equal expected.chomp, GraphQL::Schema::Printer.new(schema).print_type(schema.types['Post'])
@@ -4,7 +4,8 @@ require "spec_helper"
4
4
  describe GraphQL::StaticValidation::Validator do
5
5
  let(:validator) { GraphQL::StaticValidation::Validator.new(schema: Dummy::Schema) }
6
6
  let(:query) { GraphQL::Query.new(Dummy::Schema, query_string) }
7
- let(:errors) { validator.validate(query)[:errors].map(&:to_h) }
7
+ let(:validate) { true }
8
+ let(:errors) { validator.validate(query, validate: validate)[:errors].map(&:to_h) }
8
9
 
9
10
 
10
11
  describe "validation order" do
@@ -30,6 +31,14 @@ describe GraphQL::StaticValidation::Validator do
30
31
  # nonsenseField, nonsenseArg, bogusField, bogusArg, undefinedVar
31
32
  assert_equal(5, errors.length)
32
33
  end
34
+
35
+ describe "when validate: false" do
36
+ let(:validate) { false }
37
+
38
+ it "skips validation" do
39
+ assert_equal 0, errors.length
40
+ end
41
+ end
33
42
  end
34
43
 
35
44
  describe "infinite fragments" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.3
4
+ version: 1.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-07 00:00:00.000000000 Z
11
+ date: 2017-06-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark-ips