graphql 0.19.2 → 0.19.3

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: 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