graphql 0.19.2 → 0.19.3

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: c2492431f6efd112dd3a4aa0c2b26e17f2e45df2
4
- data.tar.gz: cd351bd76f0bf2bf4e173c900710b317210767b7
3
+ metadata.gz: 49959ced421e4d175a2ab09abb1f70046fbeecc0
4
+ data.tar.gz: e9eb998841dff1511ea8d06f6482d779e39c0d4c
5
5
  SHA512:
6
- metadata.gz: 3faf8b928d7cec65474d15cc3f29dd886f25f23d5b514d9427c578619e6c4ef8fbca048839f7633ad12ad61fae427bab5fe4eb0ff259afb8363b49524b063636
7
- data.tar.gz: a7574edfbda2742ef46ce2bb70faf5d7f437aced4180f87b2c8c7b55f5a1e267608416ca70864187debe00efac594ece5b705fdfff9edf6b3b7be34875b40b3b
6
+ metadata.gz: 8f595c5ff5a2b3062f17ec9bb038de9f2cffb550308a34a61cd8ab7c3f65a5cb878c557ebcc0aa50c31c48808be1a5a4d61ec6d609be7a14b62044809b5d4c46
7
+ data.tar.gz: 1a0452062ac5a5de8ef7102d28d2c1395e1e1cc16a379c87e844c35d6f7beaa3b036932695a8a55c506218185a05aa15425820fe34ef0a428e54ae95e828305c
@@ -85,7 +85,7 @@ module GraphQL
85
85
  end
86
86
  end
87
87
 
88
- GraphQL::Query::Arguments.new(input_values)
88
+ GraphQL::Query::Arguments.new(input_values, argument_definitions: arguments)
89
89
  end
90
90
 
91
91
  def coerce_result(value)
@@ -69,6 +69,22 @@ fragment TypeRef on __Type {
69
69
  ofType {
70
70
  kind
71
71
  name
72
+ ofType {
73
+ kind
74
+ name
75
+ ofType {
76
+ kind
77
+ name
78
+ ofType {
79
+ kind
80
+ name
81
+ ofType {
82
+ kind
83
+ name
84
+ }
85
+ }
86
+ }
87
+ }
72
88
  }
73
89
  }
74
90
  }
data/lib/graphql/query.rb CHANGED
@@ -116,7 +116,6 @@ module GraphQL
116
116
  @validation_errors
117
117
  end
118
118
 
119
-
120
119
  # TODO this should probably contain error instances, not hashes
121
120
  # @return [Array<Hash>] Errors for this particular query run (eg, exceeds max complexity)
122
121
  def analysis_errors
@@ -6,10 +6,12 @@ module GraphQL
6
6
  class Arguments
7
7
  extend Forwardable
8
8
 
9
- def initialize(values)
9
+ def initialize(values, argument_definitions:)
10
10
  @original_values = values
11
11
  @argument_values = values.inject({}) do |memo, (inner_key, inner_value)|
12
- memo[inner_key.to_s] = wrap_value(inner_value)
12
+ string_key = inner_key.to_s
13
+ arg_defn = argument_definitions[string_key]
14
+ memo[string_key] = wrap_value(inner_value, arg_defn.type)
13
15
  memo
14
16
  end
15
17
  end
@@ -36,12 +38,17 @@ module GraphQL
36
38
 
37
39
  private
38
40
 
39
- def wrap_value(value)
41
+ def wrap_value(value, arg_defn_type)
40
42
  case value
41
43
  when Array
42
- value.map { |item| wrap_value(item) }
44
+ value.map { |item| wrap_value(item, arg_defn_type.of_type) }
43
45
  when Hash
44
- self.class.new(value)
46
+ if arg_defn_type.unwrap.kind.input_object?
47
+ self.class.new(value, argument_definitions: arg_defn_type.arguments)
48
+ else
49
+ # It may be a custom scalar that coerces to a Hash
50
+ value
51
+ end
45
52
  else
46
53
  value
47
54
  end
@@ -36,7 +36,7 @@ module GraphQL
36
36
  values_hash[arg_name] = arg_value
37
37
  end
38
38
  end
39
- GraphQL::Query::Arguments.new(values_hash)
39
+ GraphQL::Query::Arguments.new(values_hash, argument_definitions: argument_defns)
40
40
  end
41
41
 
42
42
  module LiteralKindCoercers
@@ -60,7 +60,7 @@ module GraphQL
60
60
  def self.coerce(value, type, variables)
61
61
  hash = {}
62
62
  value.arguments.each do |arg|
63
- field_type = type.input_fields[arg.name].type
63
+ field_type = type.arguments[arg.name].type
64
64
  hash[arg.name] = LiteralInput.coerce(field_type, arg.value, variables)
65
65
  end
66
66
  type.input_fields.each do |arg_name, arg_defn|
@@ -71,7 +71,7 @@ module GraphQL
71
71
  end
72
72
  end
73
73
  end
74
- Arguments.new(hash)
74
+ Arguments.new(hash, argument_definitions: type.arguments)
75
75
  end
76
76
  end
77
77
 
@@ -10,11 +10,12 @@ module GraphQL
10
10
  connection_type = ObjectType.define do
11
11
  name(connection_type_name)
12
12
  field :edges, types[edge_type] do
13
+ description "A list of edges."
13
14
  resolve -> (obj, args, ctx) {
14
15
  obj.edge_nodes.map { |item| edge_class.new(item, obj) }
15
16
  }
16
17
  end
17
- field :pageInfo, !PageInfo, property: :page_info
18
+ field :pageInfo, !PageInfo, "Information to aid in pagination.", property: :page_info
18
19
  block && instance_eval(&block)
19
20
  end
20
21
 
@@ -4,8 +4,9 @@ module GraphQL
4
4
  def self.create_type(wrapped_type, name: nil, &block)
5
5
  GraphQL::ObjectType.define do
6
6
  name("#{wrapped_type.name}Edge")
7
- field :node, wrapped_type
8
- field :cursor, !types.String
7
+ description "An edge in a connection."
8
+ field :node, wrapped_type, "The item at the end of the edge."
9
+ field :cursor, !types.String, "A cursor for use in pagination."
9
10
  block && instance_eval(&block)
10
11
  end
11
12
  end
@@ -51,11 +51,12 @@ module GraphQL
51
51
  include GraphQL::Define::InstanceDefinable
52
52
  accepts_definitions(
53
53
  :name, :description, :resolve,
54
+ :return_type,
54
55
  input_field: GraphQL::Define::AssignArgument,
55
56
  return_field: GraphQL::Define::AssignObjectField,
56
57
  )
57
58
  lazy_defined_attr_accessor :name, :description
58
- lazy_defined_attr_accessor :fields, :arguments
59
+ lazy_defined_attr_accessor :fields, :arguments, :return_type
59
60
 
60
61
  # For backwards compat, but do we need this separate API?
61
62
  alias :return_fields :fields
@@ -64,21 +65,32 @@ module GraphQL
64
65
  def initialize
65
66
  @fields = {}
66
67
  @arguments = {}
68
+ @has_generated_return_type = false
67
69
  end
68
70
 
69
- def resolve=(proc)
71
+ def has_generated_return_type?
72
+ # Trigger the generation of the return type, if it is dynamically generated:
73
+ return_type
74
+ @has_generated_return_type
75
+ end
76
+
77
+ def resolve=(new_resolve_proc)
70
78
  ensure_defined
71
- @resolve_proc = proc
79
+
80
+ resolve_arity = get_arity(new_resolve_proc)
81
+ if resolve_arity == 2
82
+ warn("Mutation#resolve functions should be defined with three arguments: (root_obj, input, context). Two-argument mutation resolves are deprecated.")
83
+ new_resolve_proc = DeprecatedMutationResolve.new(new_resolve_proc)
84
+ end
85
+
86
+ @resolve_proc = MutationResolve.new(self, new_resolve_proc, wrap_result: has_generated_return_type?)
72
87
  end
73
88
 
74
89
  def field
75
90
  @field ||= begin
76
91
  ensure_defined
77
92
  relay_mutation = self
78
- field_resolve_proc = -> (obj, args, ctx){
79
- results_hash = @resolve_proc.call(args[:input], ctx)
80
- Result.new(arguments: args, result: results_hash)
81
- }
93
+ field_resolve_proc = @resolve_proc
82
94
  GraphQL::Field.define do
83
95
  type(relay_mutation.return_type)
84
96
  description(relay_mutation.description)
@@ -90,13 +102,14 @@ module GraphQL
90
102
  end
91
103
 
92
104
  def return_type
105
+ ensure_defined
93
106
  @return_type ||= begin
94
- ensure_defined
107
+ @has_generated_return_type = true
95
108
  relay_mutation = self
96
109
  GraphQL::ObjectType.define do
97
110
  name("#{relay_mutation.name}Payload")
98
111
  description("Autogenerated return type of #{relay_mutation.name}")
99
- field :clientMutationId, types.String, "A unique identifier for the client performing the mutation."
112
+ field :clientMutationId, types.String, "A unique identifier for the client performing the mutation.", property: :client_mutation_id
100
113
  relay_mutation.return_fields.each do |name, field_obj|
101
114
  field name, field: field_obj
102
115
  end
@@ -121,22 +134,71 @@ module GraphQL
121
134
  end
122
135
  end
123
136
 
137
+ def result_class
138
+ @result_class ||= begin
139
+ ensure_defined
140
+ Result.define_subclass(self)
141
+ end
142
+ end
143
+
144
+ private
145
+
146
+ def get_arity(callable)
147
+ case callable
148
+ when Proc
149
+ callable.arity
150
+ else
151
+ callable.method(:call).arity
152
+ end
153
+ end
154
+
155
+ # Use this when the mutation's return type was generated from `return_field`s.
156
+ # It delegates field lookups to the hash returned from `resolve`.
124
157
  class Result
125
- attr_reader :arguments, :result
126
- def initialize(arguments:, result:)
127
- @arguments = arguments
128
- @result = result
158
+ attr_reader :client_mutation_id
159
+ def initialize(client_mutation_id:, result:)
160
+ @client_mutation_id = client_mutation_id
161
+ result.each do |key, value|
162
+ self.public_send("#{key}=", value)
163
+ end
164
+ end
165
+
166
+ class << self
167
+ attr_accessor :mutation
168
+ end
169
+
170
+ def self.define_subclass(mutation_defn)
171
+ subclass = Class.new(self) do
172
+ attr_accessor(*mutation_defn.return_type.all_fields.map(&:name))
173
+ self.mutation = mutation_defn
174
+ end
175
+ subclass
129
176
  end
177
+ end
178
+
179
+ class DeprecatedMutationResolve
180
+ def initialize(two_argument_resolve)
181
+ @two_argument_resolve = two_argument_resolve
182
+ end
183
+
184
+ def call(obj, args, ctx)
185
+ @two_argument_resolve.call(args[:input], ctx)
186
+ end
187
+ end
130
188
 
131
- def clientMutationId
132
- arguments[:input][:clientMutationId]
189
+ class MutationResolve
190
+ def initialize(mutation, resolve, wrap_result:)
191
+ @mutation = mutation
192
+ @resolve = resolve
193
+ @wrap_result = wrap_result
133
194
  end
134
195
 
135
- def method_missing(name, *args, &block)
136
- if result.key?(name)
137
- result[name]
196
+ def call(obj, args, ctx)
197
+ mutation_result = @resolve.call(obj, args[:input], ctx)
198
+ if @wrap_result
199
+ @mutation.result_class.new(client_mutation_id: args[:input][:clientMutationId], result: mutation_result)
138
200
  else
139
- super
201
+ mutation_result
140
202
  end
141
203
  end
142
204
  end
@@ -9,8 +9,8 @@ module GraphQL
9
9
  # _may_ be modified.
10
10
  node_field = GraphQL::Field.define do
11
11
  type(GraphQL::Relay::Node.interface)
12
- description("Fetches an object given its ID")
13
- argument(:id, !types.ID, "ID of the object")
12
+ description("Fetches an object given its ID.")
13
+ argument(:id, !types.ID, "ID of the object.")
14
14
  resolve(GraphQL::Relay::Node::FindNode)
15
15
  end
16
16
 
@@ -24,7 +24,8 @@ module GraphQL
24
24
  def self.interface
25
25
  @interface ||= GraphQL::InterfaceType.define do
26
26
  name "Node"
27
- field :id, !types.ID
27
+ description "An object with an ID."
28
+ field :id, !types.ID, "ID of the object."
28
29
  end
29
30
  end
30
31
 
@@ -3,7 +3,7 @@ module GraphQL
3
3
  # Wrap a Connection and expose its page info
4
4
  PageInfo = GraphQL::ObjectType.define do
5
5
  name("PageInfo")
6
- description("Metadata about a connection")
6
+ description("Information about pagination in a connection.")
7
7
  field :hasNextPage, !types.Boolean, "Indicates if there are more pages to fetch", property: :has_next_page
8
8
  field :hasPreviousPage, !types.Boolean, "Indicates if there are any pages prior to the current page", property: :has_previous_page
9
9
  field :startCursor, types.String, "When paginating backwards, the cursor to continue", property: :start_cursor
@@ -21,7 +21,7 @@ module GraphQL
21
21
  return GraphQL::Language::Visitor::SKIP
22
22
  end
23
23
 
24
- field = parent_type.get_field(ast_field.name)
24
+ field = context.schema.get_field(parent_type, ast_field.name)
25
25
  if field.nil?
26
26
  context.errors << message("Field '#{ast_field.name}' doesn't exist on type '#{parent_type.name}'", ast_field, context: context)
27
27
  return GraphQL::Language::Visitor::SKIP
@@ -13,8 +13,10 @@ module GraphQL
13
13
 
14
14
  def validate_is_input_type(node, context)
15
15
  type_name = get_type_name(node.type)
16
- type = context.schema.types[type_name]
17
- if !type.kind.input?
16
+ type = context.schema.types.fetch(type_name, nil)
17
+ if type.nil?
18
+ context.errors << message("#{type_name} isn't a defined input type (on $#{node.name})", node, context: context)
19
+ elsif !type.kind.input?
18
20
  context.errors << message("#{type.name} isn't a valid input type (on $#{node.name})", node, context: context)
19
21
  end
20
22
  end
@@ -48,15 +48,13 @@ module GraphQL
48
48
  private
49
49
 
50
50
  # Look up strategies by name and use singleton instance to push and pop
51
- PUSH_STRATEGIES = Hash.new { |hash, key| hash[key] = get_strategy_for_node_class(key) }
52
-
53
- def self.get_strategy_for_node_class(node_class)
54
- node_class_name = node_class.name.split("::").last
51
+ PUSH_STRATEGIES = Hash.new do |hash, key|
52
+ node_class_name = key.name.split("::").last
55
53
  strategy_key = "#{node_class_name}Strategy"
56
- const_defined?(strategy_key) ? const_get(strategy_key).new : NullStrategy.new
54
+ hash[key] = const_defined?(strategy_key) ? const_get(strategy_key) : NullStrategy
57
55
  end
58
56
 
59
- class FragmentWithTypeStrategy
57
+ module FragmentWithTypeStrategy
60
58
  def push(stack, node)
61
59
  object_type = if node.type
62
60
  stack.schema.types.fetch(node.type, nil)
@@ -76,19 +74,24 @@ module GraphQL
76
74
  end
77
75
  end
78
76
 
79
- class FragmentDefinitionStrategy < FragmentWithTypeStrategy
77
+ module FragmentDefinitionStrategy
78
+ extend FragmentWithTypeStrategy
79
+ module_function
80
80
  def push_path_member(stack, node)
81
81
  stack.path.push("fragment #{node.name}")
82
82
  end
83
83
  end
84
84
 
85
- class InlineFragmentStrategy < FragmentWithTypeStrategy
85
+ module InlineFragmentStrategy
86
+ extend FragmentWithTypeStrategy
87
+ module_function
86
88
  def push_path_member(stack, node)
87
89
  stack.path.push("...#{node.type ? " on #{node.type}" : ""}")
88
90
  end
89
91
  end
90
92
 
91
- class OperationDefinitionStrategy
93
+ module OperationDefinitionStrategy
94
+ module_function
92
95
  def push(stack, node)
93
96
  # eg, QueryType, MutationType
94
97
  object_type = stack.schema.root_type_for_operation(node.operation_type)
@@ -102,7 +105,8 @@ module GraphQL
102
105
  end
103
106
  end
104
107
 
105
- class FieldStrategy
108
+ module FieldStrategy
109
+ module_function
106
110
  def push(stack, node)
107
111
  parent_type = stack.object_types.last
108
112
  parent_type = parent_type.unwrap
@@ -125,7 +129,8 @@ module GraphQL
125
129
  end
126
130
  end
127
131
 
128
- class DirectiveStrategy
132
+ module DirectiveStrategy
133
+ module_function
129
134
  def push(stack, node)
130
135
  directive_defn = stack.schema.directives[node.name]
131
136
  stack.directive_definitions.push(directive_defn)
@@ -136,7 +141,8 @@ module GraphQL
136
141
  end
137
142
  end
138
143
 
139
- class ArgumentStrategy
144
+ module ArgumentStrategy
145
+ module_function
140
146
  # Push `argument_defn` onto the stack.
141
147
  # It's possible that `argument_defn` will be nil.
142
148
  # Push it anyways so `pop` has something to pop.
@@ -165,7 +171,8 @@ module GraphQL
165
171
  end
166
172
  end
167
173
 
168
- class FragmentSpreadStrategy
174
+ module FragmentSpreadStrategy
175
+ module_function
169
176
  def push(stack, node)
170
177
  stack.path.push("... #{node.name}")
171
178
  end
@@ -176,8 +183,7 @@ module GraphQL
176
183
  end
177
184
 
178
185
  # A no-op strategy (don't handle this node)
179
- class NullStrategy
180
- def self.new; self; end
186
+ module NullStrategy
181
187
  def self.push(stack, node); end
182
188
  def self.pop(stack, node); end
183
189
  end
@@ -1,3 +1,3 @@
1
1
  module GraphQL
2
- VERSION = "0.19.2"
2
+ VERSION = "0.19.3"
3
3
  end
data/readme.md CHANGED
@@ -148,4 +148,3 @@ If you're building a backend for [Relay](http://facebook.github.io/relay/), you'
148
148
  - Revisit guides, maybe split them into smaller, more specific pages
149
149
  - Put guide titles into the `<title />`
150
150
  - Document encrypted & versioned cursors
151
- - Eager load `Schema#types` after `.define { ... }`
@@ -7,4 +7,52 @@ describe "GraphQL::Introspection::INTROSPECTION_QUERY" do
7
7
  it "runs" do
8
8
  assert(result["data"])
9
9
  end
10
+
11
+ it "handles deeply nested (<= 7) schemas" do
12
+ query_type = GraphQL::ObjectType.define do
13
+ name "DeepQuery"
14
+ field :foo do
15
+ type !GraphQL::ListType.new(
16
+ of_type: !GraphQL::ListType.new(
17
+ of_type: !GraphQL::ListType.new(
18
+ of_type: GraphQL::FLOAT_TYPE
19
+ )
20
+ )
21
+ )
22
+ end
23
+ end
24
+
25
+ deep_schema = GraphQL::Schema.define do
26
+ query query_type
27
+ end
28
+
29
+ result = deep_schema.execute(query_string)
30
+ assert(GraphQL::Schema::Loader.load(result))
31
+ end
32
+
33
+ it "doesn't handle too deeply nested (< 8) schemas" do
34
+ query_type = GraphQL::ObjectType.define do
35
+ name "DeepQuery"
36
+ field :foo do
37
+ type !GraphQL::ListType.new(
38
+ of_type: !GraphQL::ListType.new(
39
+ of_type: !GraphQL::ListType.new(
40
+ of_type: !GraphQL::ListType.new(
41
+ of_type: GraphQL::FLOAT_TYPE
42
+ )
43
+ )
44
+ )
45
+ )
46
+ end
47
+ end
48
+
49
+ deep_schema = GraphQL::Schema.define do
50
+ query query_type
51
+ end
52
+
53
+ result = deep_schema.execute(query_string)
54
+ assert_raises(KeyError) {
55
+ GraphQL::Schema::Loader.load(result)
56
+ }
57
+ end
10
58
  end
@@ -1,7 +1,29 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe GraphQL::Query::Arguments do
4
- let(:arguments) { GraphQL::Query::Arguments.new({ a: 1, b: 2, c: GraphQL::Query::Arguments.new({ d: 3, e: 4}) }) }
4
+ let(:arguments) {
5
+ test_input_1 = GraphQL::InputObjectType.define do
6
+ name "TestInput1"
7
+ argument :d, types.Int
8
+ argument :e, types.Int
9
+ end
10
+
11
+ test_input_2 = GraphQL::InputObjectType.define do
12
+ name "TestInput2"
13
+ argument :a, types.Int
14
+ argument :b, types.Int
15
+ argument :c, !test_input_1
16
+ end
17
+
18
+ GraphQL::Query::Arguments.new({
19
+ a: 1,
20
+ b: 2,
21
+ c: GraphQL::Query::Arguments.new({
22
+ d: 3,
23
+ e: 4,
24
+ }, argument_definitions: test_input_1.arguments),
25
+ }, argument_definitions: test_input_2.arguments)
26
+ }
5
27
 
6
28
  it "returns keys as strings" do
7
29
  assert_equal(["a", "b", "c"], arguments.keys)
@@ -23,6 +45,25 @@ describe GraphQL::Query::Arguments do
23
45
  assert_equal({ a: 1, b: 2, c: { d: 3, e: 4 } }, arguments.to_h)
24
46
  end
25
47
 
48
+ describe "nested hashes" do
49
+ let(:input_type) {
50
+ test_input_type = GraphQL::InputObjectType.define do
51
+ name "TestInput"
52
+ argument :a, types.Int
53
+ argument :b, test_input_type
54
+ argument :c, types.Int # will be a hash
55
+ end
56
+ }
57
+ it "wraps input objects, but not other hashes" do
58
+ args = GraphQL::Query::Arguments.new(
59
+ {a: 1, b: {a: 2}, c: {a: 3}},
60
+ argument_definitions: input_type.arguments
61
+ )
62
+ assert args["b"].is_a?(GraphQL::Query::Arguments)
63
+ assert args["c"].is_a?(Hash)
64
+ end
65
+ end
66
+
26
67
  describe "#key?" do
27
68
  let(:arg_values) { [] }
28
69
  let(:schema) {
@@ -56,5 +56,51 @@ describe GraphQL::Relay::Mutation do
56
56
  assert_equal IntroduceShipMutation, IntroduceShipMutation.field.mutation
57
57
  assert_equal IntroduceShipMutation, IntroduceShipMutation.return_type.mutation
58
58
  assert_equal IntroduceShipMutation, IntroduceShipMutation.input_type.mutation
59
+ assert_equal IntroduceShipMutation, IntroduceShipMutation.result_class.mutation
60
+ end
61
+
62
+ describe "providing a return type" do
63
+ let(:custom_return_type) {
64
+ GraphQL::ObjectType.define do
65
+ name "CustomReturnType"
66
+ field :name, types.String
67
+ end
68
+ }
69
+
70
+ let(:mutation) {
71
+ custom_type = custom_return_type
72
+ GraphQL::Relay::Mutation.define do
73
+ name "CustomReturnTypeTest"
74
+ return_type custom_type
75
+ resolve -> (input, ctx) {
76
+ OpenStruct.new(name: "Custom Return Type Test")
77
+ }
78
+ end
79
+ }
80
+
81
+ let(:schema) {
82
+ mutation_field = mutation.field
83
+
84
+ mutation_root = GraphQL::ObjectType.define do
85
+ name "Mutation"
86
+ field :custom, mutation_field
87
+ end
88
+
89
+ GraphQL::Schema.define do
90
+ mutation(mutation_root)
91
+ end
92
+ }
93
+
94
+ it "uses the provided type" do
95
+ assert_equal custom_return_type, mutation.return_type
96
+ assert_equal custom_return_type, mutation.field.type
97
+
98
+ result = schema.execute("mutation { custom(input: {}) { name } }")
99
+ assert_equal "Custom Return Type Test", result["data"]["custom"]["name"]
100
+ end
101
+
102
+ it "doesn't get a mutation in the metadata" do
103
+ assert_equal nil, custom_return_type.mutation
104
+ end
59
105
  end
60
106
  end
@@ -10,6 +10,7 @@ describe GraphQL::StaticValidation::VariablesAreInputTypes do
10
10
  $interface: AnimalProduct!,
11
11
  $object: Milk = 1,
12
12
  $objects: [Cheese]!,
13
+ $unknownType: Nonsense,
13
14
  ) {
14
15
  cheese(id: $id) { source }
15
16
  __type(name: $str) { name }
@@ -34,5 +35,11 @@ describe GraphQL::StaticValidation::VariablesAreInputTypes do
34
35
  "locations"=>[{"line"=>7, "column"=>7}],
35
36
  "fields"=>["query getCheese"],
36
37
  })
38
+
39
+ assert_includes(errors, {
40
+ "message"=>"Nonsense isn't a defined input type (on $unknownType)",
41
+ "locations"=>[{"line"=>8, "column"=>7}],
42
+ "fields"=>["query getCheese"],
43
+ })
37
44
  end
38
45
  end
@@ -155,7 +155,7 @@ IntroduceShipMutation = GraphQL::Relay::Mutation.define do
155
155
  return_field :faction, Faction
156
156
 
157
157
  # Here's the mutation operation:
158
- resolve -> (inputs, ctx) {
158
+ resolve -> (root_obj, inputs, ctx) {
159
159
  faction_id = inputs["factionId"]
160
160
  ship = STAR_WARS_DATA.create_ship(inputs["shipName"], faction_id)
161
161
  faction = STAR_WARS_DATA["Faction"][faction_id]
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: 0.19.2
4
+ version: 0.19.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-06 00:00:00.000000000 Z
11
+ date: 2016-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: codeclimate-test-reporter
@@ -550,7 +550,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
550
550
  version: '0'
551
551
  requirements: []
552
552
  rubyforge_project:
553
- rubygems_version: 2.4.5
553
+ rubygems_version: 2.5.1
554
554
  signing_key:
555
555
  specification_version: 4
556
556
  summary: A GraphQL server implementation for Ruby