graphql 1.6.3 → 1.6.4

Sign up to get free protection for your applications and to get access to all the features.
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