Skip to content

Commit 6ee709b

Browse files
author
Nathaniel Woodthorpe
authored
Merge pull request #34 from zencargo/add-support-for-array-variables
add support for array variables
2 parents 581c631 + 4925b85 commit 6ee709b

File tree

2 files changed

+60
-16
lines changed

2 files changed

+60
-16
lines changed

lib/graphql/remote_loader/loader.rb

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -99,22 +99,32 @@ def self.interpolate_variables(query, variables = {})
9999
end
100100

101101
def self.interpolate_variables!(query, variables = {})
102-
variables.each do |variable, value|
103-
case value
104-
when Integer, Float, TrueClass, FalseClass
105-
# These types are safe to directly interpolate into the query, and GraphQL does not expect these types to be quoted.
106-
query.gsub!("$#{variable.to_s}", value.to_s)
107-
else
108-
# A string is either a GraphQL String or ID type.
109-
# This means we need to
110-
# a) Surround the value in quotes
111-
# b) escape special characters in the string
112-
#
113-
# This else also catches unknown objects, which could break the query if we directly interpolate.
114-
# These objects get converted to strings, then escaped.
115-
116-
query.gsub!("$#{variable.to_s}", value.to_s.inspect)
117-
end
102+
variables.each { |variable, value| query.gsub!("$#{variable.to_s}", stringify_variable(value)) }
103+
end
104+
105+
def self.stringify_variable(value)
106+
case value
107+
when Integer, Float, TrueClass, FalseClass
108+
# These types are safe to directly interpolate into the query, and GraphQL does not expect these types to be quoted.
109+
value.to_s
110+
when Array
111+
# Arrays can contain elements with various types, so we need to check them one by one
112+
stringified_elements = value.map { |element| stringify_variable(element) }
113+
"[#{stringified_elements.join(', ')}]"
114+
when Hash
115+
# Hashes can contain values with various types, so we need to check them one by one
116+
stringified_key_value_pairs = value.map { |key, value| "#{key}: #{stringify_variable(value)}" }
117+
"{#{stringified_key_value_pairs.join(', ')}}"
118+
else
119+
# A string is either a GraphQL String or ID type.
120+
# This means we need to
121+
# a) Surround the value in quotes
122+
# b) escape special characters in the string
123+
#
124+
# This else also catches unknown objects, which could break the query if we directly interpolate.
125+
# These objects get converted to strings, then escaped.
126+
127+
value.to_s.inspect
118128
end
119129
end
120130

spec/unit/lib/graphql/remote_loader/loader_spec.rb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,40 @@ def query(query_string)
116116
expect(results["data"]["foo"]).to eq("foo_result")
117117
end
118118

119+
it "interpolates array variables correctly" do
120+
TestLoader.any_instance.should_receive(:query).once
121+
.with('query { p2foo: foo(bar: ["fir\"st", true, 5, {text: "value", number: 6}]) }', anything)
122+
.and_return({
123+
"data" => {
124+
"p2foo" => "foo_result"
125+
}
126+
})
127+
128+
results = GraphQL::Batch.batch do
129+
TestLoader.load("foo(bar: $my_variable)",
130+
variables: { my_variable: ["fir\"st", true, 5, { text: 'value', number: 6 }] })
131+
end
132+
133+
expect(results["data"]["foo"]).to eq("foo_result")
134+
end
135+
136+
it "interpolates hash variables correctly" do
137+
TestLoader.any_instance.should_receive(:query).once
138+
.with('query { p2foo: foo(bar: {array: ["fir\"st", true, 5], text: "value", number: 6}) }', anything)
139+
.and_return({
140+
"data" => {
141+
"p2foo" => "foo_result"
142+
}
143+
})
144+
145+
results = GraphQL::Batch.batch do
146+
TestLoader.load("foo(bar: $my_variable)",
147+
variables: { my_variable: { array: ["fir\"st", true, 5], text: 'value', number: 6 } })
148+
end
149+
150+
expect(results["data"]["foo"]).to eq("foo_result")
151+
end
152+
119153
it "interpolates string variables correctly" do
120154
TestLoader.any_instance.should_receive(:query).once
121155
.with("query { p2foo: foo(bar: \"testing string\") }", anything)

0 commit comments

Comments
 (0)