graphql 1.4.1 → 1.4.2

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: 5e3922b4ba691948512f6936a9ebf5438e468698
4
- data.tar.gz: 9162e5e2f437fc323e733a7682dd44dae9bb8cc8
3
+ metadata.gz: fe097cf7f88ed8a62ed53cc4fb3df2943a7a26e7
4
+ data.tar.gz: 66c7f5ef3707ffdf91a8e15b5fd94319c6799f6c
5
5
  SHA512:
6
- metadata.gz: 1c3763c608645843eaffaa81d95e29d019008209b1af2f91a06d35431403114a4b60feebfec3e7659db45b05695e7a4ce3c67012f573ca4e4283ecc12a2186c3
7
- data.tar.gz: 08e82e3316840ebaeeb63aee2e73d8909ae863634c00d6eec38e03ba8a2a2038239f1e4ef694af70f952599aafc6d6bd3f1623741ebb0b7d61e3d8f43765c21e
6
+ metadata.gz: 6f922011419b6a8dcaed84c2088c0323681b27b283881339a021aeee0ae21b3d5d68da6da75dffe317d5db3514a2e0f5b7f9143553d2b3fef4d27ebeb36f45ae
7
+ data.tar.gz: e109b93bd6d60ef1e57dd09e64260b1fc89aa728c01153ec703bc73e2232ba628df78e8188dba57b98a57b81a214aa750cd6f85c4f364a9db487dec85a8d9ead
@@ -130,7 +130,7 @@ module GraphQL
130
130
 
131
131
  ensure_defined(
132
132
  :name, :deprecation_reason, :description, :description=, :property, :hash_key, :mutation, :arguments, :complexity,
133
- :resolve, :resolve=, :lazy_resolve, :lazy_resolve=, :lazy_resolve_proc,
133
+ :resolve, :resolve=, :lazy_resolve, :lazy_resolve=, :lazy_resolve_proc, :resolve_proc,
134
134
  :type, :type=, :name=, :property=, :hash_key=,
135
135
  :relay_node_field,
136
136
  )
@@ -99,7 +99,9 @@ module GraphQL
99
99
  coerced_value = input_field_defn.default_value
100
100
  end
101
101
 
102
- input_values[input_key] = coerced_value if coerced_value || value.key?(input_key)
102
+ if coerced_value || value.key?(input_key)
103
+ input_values[input_key] = coerced_value
104
+ end
103
105
  end
104
106
 
105
107
  GraphQL::Query::Arguments.new(input_values, argument_definitions: arguments)
@@ -3,100 +3,63 @@ module GraphQL
3
3
  class Query
4
4
  # Turn query string values into something useful for query execution
5
5
  class LiteralInput
6
- def self.coerce(type, value, variables)
7
- if value.is_a?(Language::Nodes::VariableIdentifier)
8
- variables[value.name]
9
- elsif value.nil?
6
+ def self.coerce(type, ast_node, variables)
7
+ case ast_node
8
+ when nil
10
9
  nil
10
+ when Language::Nodes::VariableIdentifier
11
+ variables[ast_node.name]
11
12
  else
12
- LiteralKindCoercers::STRATEGIES.fetch(type.kind).coerce(value, type, variables)
13
- end
14
- end
15
-
16
- def self.from_arguments(ast_arguments, argument_defns, variables)
17
- values_hash = {}
18
- argument_defns.each do |arg_name, arg_defn|
19
- ast_arg = ast_arguments.find { |ast_arg| ast_arg.name == arg_name }
20
- arg_default_value = arg_defn.default_value
21
- if ast_arg.nil? && arg_default_value.nil?
22
- # If it wasn't in the document,
23
- # and there's no provided default,
24
- # then don't pass it to the resolve function
25
- next
26
- else
27
- arg_value = nil
28
-
29
- if ast_arg
30
- arg_value = coerce(arg_defn.type, ast_arg.value, variables)
31
- end
32
-
33
- if arg_value.nil?
34
- arg_value = arg_default_value
13
+ case type
14
+ when GraphQL::ScalarType
15
+ type.coerce_input(ast_node)
16
+ when GraphQL::EnumType
17
+ type.coerce_input(ast_node.name)
18
+ when GraphQL::NonNullType
19
+ LiteralInput.coerce(type.of_type, ast_node, variables)
20
+ when GraphQL::ListType
21
+ if ast_node.is_a?(Array)
22
+ ast_node.map { |element_ast| LiteralInput.coerce(type.of_type, element_ast, variables) }
23
+ else
24
+ [LiteralInput.coerce(type.of_type, ast_node, variables)]
35
25
  end
36
-
37
- values_hash[arg_name] = arg_value
26
+ when GraphQL::InputObjectType
27
+ from_arguments(ast_node.arguments, type.arguments, variables)
38
28
  end
39
29
  end
40
- GraphQL::Query::Arguments.new(values_hash, argument_definitions: argument_defns)
41
30
  end
42
31
 
43
- module LiteralKindCoercers
44
- module NonNullLiteral
45
- def self.coerce(value, type, variables)
46
- LiteralInput.coerce(type.of_type, value, variables)
47
- end
48
- end
49
-
50
- module ListLiteral
51
- def self.coerce(value, type, variables)
52
- if value.is_a?(Array)
53
- value.map{ |element_ast| LiteralInput.coerce(type.of_type, element_ast, variables) }
54
- else
55
- [LiteralInput.coerce(type.of_type, value, variables)]
56
- end
57
- end
58
- end
32
+ def self.from_arguments(ast_arguments, argument_defns, variables)
33
+ values_hash = {}
34
+ indexed_arguments = ast_arguments.each_with_object({}) { |a, memo| memo[a.name] = a }
59
35
 
60
- module InputObjectLiteral
61
- def self.coerce(value, type, variables)
62
- hash = {}
63
- value.arguments.each do |arg|
64
- field_type = type.arguments[arg.name].type
65
- hash[arg.name] = LiteralInput.coerce(field_type, arg.value, variables)
66
- end
67
- type.input_fields.each do |arg_name, arg_defn|
68
- if hash[arg_name].nil?
69
- value = LiteralInput.coerce(arg_defn.type, arg_defn.default_value, variables)
70
- if !value.nil?
71
- hash[arg_name] = value
72
- end
36
+ argument_defns.each do |arg_name, arg_defn|
37
+ ast_arg = indexed_arguments[arg_name]
38
+ # First, check the argument in the AST.
39
+ # If the value is a variable,
40
+ # only add a value if the variable is actually present.
41
+ # Otherwise, coerce the value in the AST and add it.
42
+ if ast_arg
43
+ if ast_arg.value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
44
+ if variables.key?(ast_arg.value.name)
45
+ values_hash[ast_arg.name] = coerce(arg_defn.type, ast_arg.value, variables)
73
46
  end
47
+ else
48
+ values_hash[ast_arg.name] = coerce(arg_defn.type, ast_arg.value, variables)
74
49
  end
75
- Arguments.new(hash, argument_definitions: type.arguments)
76
50
  end
77
- end
78
51
 
79
- module EnumLiteral
80
- def self.coerce(value, type, variables)
81
- type.coerce_input(value.name)
52
+ # Then, the definition for a default value.
53
+ # If the definition has a default value and
54
+ # a value wasn't provided from the AST,
55
+ # then add the default value.
56
+ if arg_defn.default_value? && !values_hash.key?(arg_name)
57
+ values_hash[arg_name] = arg_defn.default_value
82
58
  end
83
59
  end
84
60
 
85
- module ScalarLiteral
86
- def self.coerce(value, type, variables)
87
- type.coerce_input(value)
88
- end
89
- end
90
-
91
- STRATEGIES = {
92
- TypeKinds::NON_NULL => NonNullLiteral,
93
- TypeKinds::LIST => ListLiteral,
94
- TypeKinds::INPUT_OBJECT => InputObjectLiteral,
95
- TypeKinds::ENUM => EnumLiteral,
96
- TypeKinds::SCALAR => ScalarLiteral,
97
- }
61
+ GraphQL::Query::Arguments.new(values_hash, argument_definitions: argument_defns)
98
62
  end
99
- private_constant :LiteralKindCoercers
100
63
  end
101
64
  end
102
65
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "1.4.1"
3
+ VERSION = "1.4.2"
4
4
  end
@@ -190,4 +190,13 @@ describe GraphQL::Field do
190
190
  assert_equal({a: 1, b: 2, c: 3}, int_field_2.metadata)
191
191
  end
192
192
  end
193
+
194
+ describe "#resolve_proc" do
195
+ it "ensures the definition was called" do
196
+ field = GraphQL::Field.define do
197
+ resolve ->(o, a, c) { :whatever }
198
+ end
199
+ assert_instance_of Proc, field.resolve_proc
200
+ end
201
+ end
193
202
  end
@@ -73,26 +73,168 @@ describe GraphQL::Query::Variables do
73
73
 
74
74
  describe "coercing null" do
75
75
  let(:provided_variables) {
76
- {"int" => nil, "intWithDefault" => nil}
76
+ {
77
+ "intWithVariable" => nil,
78
+ "intWithDefault" => nil,
79
+ "complexValWithVariable" => {
80
+ "val" => 1,
81
+ "val_with_default" => 2,
82
+ },
83
+ "complexValWithDefaultAndVariable" => {
84
+ "val" => 8,
85
+ },
86
+ }
87
+ }
88
+ let(:args) { {} }
89
+ let(:schema) {
90
+ args_cache = args
91
+
92
+ complex_val = GraphQL::InputObjectType.define do
93
+ name "ComplexVal"
94
+ argument :val, types.Int
95
+ argument :val_with_default, types.Int, default_value: 13
96
+ end
97
+
98
+ query_type = GraphQL::ObjectType.define do
99
+ name "Query"
100
+ field :variables_test, types.Int do
101
+ argument :val, types.Int
102
+ argument :val_with_default, types.Int, default_value: 13
103
+ argument :complex_val, complex_val
104
+ resolve ->(o, a, c) {
105
+ args_cache[c.ast_node.alias] = a
106
+ 1
107
+ }
108
+ end
109
+ end
110
+
111
+ GraphQL::Schema.define do
112
+ query(query_type)
113
+ end
114
+ }
115
+
116
+ let(:query_string) {<<-GRAPHQL
117
+ query testVariables(
118
+ $intWithVariable: Int,
119
+ $intWithDefault: Int = 10,
120
+ $intDefaultNull: Int = null,
121
+ $intWithoutVariable: Int,
122
+ $complexValWithVariable: ComplexVal,
123
+ $complexValWithoutVariable: ComplexVal,
124
+ $complexValWithOneDefault: ComplexVal = { val: 10 },
125
+ $complexValWithTwoDefaults: ComplexVal = { val: 11, val_with_default: 11 },
126
+ $complexValWithNullDefaults: ComplexVal = { val: null, val_with_default: null },
127
+ $complexValWithDefaultAndVariable: ComplexVal = { val: 99 },
128
+ ) {
129
+ aa: variables_test(val: $intWithVariable)
130
+ ab: variables_test(val: $intWithoutVariable)
131
+ ac: variables_test(val: $intWithDefault)
132
+ ad: variables_test(val: $intDefaultNull)
133
+
134
+ ba: variables_test(val_with_default: $intWithVariable)
135
+ bb: variables_test(val_with_default: $intWithoutVariable)
136
+ bc: variables_test(val_with_default: $intWithDefault)
137
+ bd: variables_test(val_with_default: $intDefaultNull)
138
+
139
+ ca: variables_test(complex_val: { val: $intWithVariable })
140
+ cb: variables_test(complex_val: { val: $intWithoutVariable })
141
+ cc: variables_test(complex_val: { val: $intWithDefault })
142
+ cd: variables_test(complex_val: { val: $intDefaultNull })
143
+
144
+ da: variables_test(complex_val: { val_with_default: $intWithVariable })
145
+ db: variables_test(complex_val: { val_with_default: $intWithoutVariable })
146
+ dc: variables_test(complex_val: { val_with_default: $intWithDefault })
147
+ dd: variables_test(complex_val: { val_with_default: $intDefaultNull })
148
+
149
+ ea: variables_test(complex_val: $complexValWithVariable)
150
+ eb: variables_test(complex_val: $complexValWithoutVariable)
151
+ ec: variables_test(complex_val: $complexValWithOneDefault)
152
+ ed: variables_test(complex_val: $complexValWithTwoDefaults)
153
+ ee: variables_test(complex_val: $complexValWithNullDefaults)
154
+ ef: variables_test(complex_val: $complexValWithDefaultAndVariable)
155
+ }
156
+ GRAPHQL
77
157
  }
78
158
 
159
+ let(:run_query) { schema.execute(query_string, variables: provided_variables) }
160
+
161
+ let(:variables) { GraphQL::Query::Variables.new(
162
+ schema,
163
+ GraphQL::Schema::Warden.new(schema.default_mask, schema: schema, context: nil),
164
+ ast_variables,
165
+ provided_variables)
166
+ }
167
+
168
+ def assert_has_key_with_value(hash, key, has_key, value)
169
+ assert_equal(has_key, hash.key?(key))
170
+ assert_equal(value, hash[key])
171
+ end
172
+
79
173
  it "preserves explicit null" do
80
- assert_equal nil, variables["int"]
81
- assert_equal true, variables.key?("int")
174
+ assert_has_key_with_value(variables, "intWithVariable", true, nil)
175
+ run_query
176
+ # Provided `nil` should be passed along to args
177
+ # and override any defaults (variable defaults and arg defaults)
178
+ assert_has_key_with_value(args["aa"], "val", true, nil)
179
+ assert_has_key_with_value(args["ba"], "val_with_default", true, nil)
180
+ assert_has_key_with_value(args["ca"]["complex_val"], "val", true, nil)
181
+ assert_has_key_with_value(args["da"]["complex_val"], "val_with_default", true, nil)
82
182
  end
83
183
 
84
184
  it "doesn't contain variables that weren't present" do
85
- assert_equal nil, variables["animals"]
86
- assert_equal false, variables.key?("animals")
185
+ assert_has_key_with_value(variables, "intWithoutVariable", false, nil)
186
+ run_query
187
+ assert_has_key_with_value(args["ab"], "val", false, nil)
188
+ # This one _is_ present, it gets the argument.default_value
189
+ assert_has_key_with_value(args["bb"], "val_with_default", true, 13)
190
+ assert_has_key_with_value(args["cb"]["complex_val"], "val", false, nil)
191
+ # This one _is_ present, it gets the argument.default_value
192
+ assert_has_key_with_value(args["db"]["complex_val"], "val_with_default", true, 13)
87
193
  end
88
194
 
89
195
  it "preserves explicit null when variable has a default value" do
90
- assert_equal nil, variables["intWithDefault"]
196
+ assert_has_key_with_value(variables, "intWithDefault", true, nil)
197
+ run_query
198
+ assert_has_key_with_value(args["ac"], "val", true, nil)
199
+ assert_has_key_with_value(args["bc"], "val_with_default", true, nil)
200
+ assert_has_key_with_value(args["cc"]["complex_val"], "val", true, nil)
201
+ assert_has_key_with_value(args["dc"]["complex_val"], "val_with_default", true, nil)
91
202
  end
92
203
 
93
204
  it "uses null default value" do
94
- assert_equal nil, variables["intDefaultNull"]
95
- assert_equal true, variables.key?("intDefaultNull")
205
+ assert_has_key_with_value(variables, "intDefaultNull", true, nil)
206
+ run_query
207
+ assert_has_key_with_value(args["ad"], "val", true, nil)
208
+ assert_has_key_with_value(args["bd"], "val_with_default", true, nil)
209
+ assert_has_key_with_value(args["cd"]["complex_val"], "val", true, nil)
210
+ assert_has_key_with_value(args["dd"]["complex_val"], "val_with_default", true, nil)
211
+ end
212
+
213
+ it "applies argument default values" do
214
+ run_query
215
+ # It wasn't present in the query string, but it gets argument.default_value:
216
+ assert_has_key_with_value(args["aa"], "val_with_default", true, 13)
217
+ end
218
+
219
+ it "applies coercion to input objects passed as variables" do
220
+ run_query
221
+ assert_has_key_with_value(args["ea"]["complex_val"], "val", true, 1)
222
+ assert_has_key_with_value(args["ea"]["complex_val"], "val_with_default", true, 2)
223
+
224
+ # Since the variable wasn't provided, it's not present at all:
225
+ assert_has_key_with_value(args["eb"], "complex_val", false, nil)
226
+
227
+ assert_has_key_with_value(args["ec"]["complex_val"], "val", true, 10)
228
+ assert_has_key_with_value(args["ec"]["complex_val"], "val_with_default", true, 13)
229
+
230
+ assert_has_key_with_value(args["ed"]["complex_val"], "val", true, 11)
231
+ assert_has_key_with_value(args["ed"]["complex_val"], "val_with_default", true, 11)
232
+
233
+ assert_has_key_with_value(args["ee"]["complex_val"], "val", true, nil)
234
+ assert_has_key_with_value(args["ee"]["complex_val"], "val_with_default", true, nil)
235
+
236
+ assert_has_key_with_value(args["ef"]["complex_val"], "val", true, 8)
237
+ assert_has_key_with_value(args["ef"]["complex_val"], "val_with_default", true, 13)
96
238
  end
97
239
  end
98
240
  end
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.4.1
4
+ version: 1.4.2
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-01-16 00:00:00.000000000 Z
11
+ date: 2017-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: codeclimate-test-reporter