Skip to content

Commit 4f6d5f9

Browse files
author
Robert Mosolgo
authored
Merge pull request #1868 from modosc/dig-inputobject-arguments
add #dig to Schema::InputObject and Query::Arguments
2 parents 67bc856 + 65184ff commit 4f6d5f9

File tree

6 files changed

+94
-0
lines changed

6 files changed

+94
-0
lines changed

lib/graphql.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ def self.scan_with_ragel(graphql_string)
6767
require "graphql/analysis"
6868
require "graphql/tracing"
6969
require "graphql/execution"
70+
require "graphql/dig"
7071
require "graphql/schema"
7172
require "graphql/types"
7273
require "graphql/relay"

lib/graphql/dig.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# frozen_string_literal: true
2+
module GraphQL
3+
module Dig
4+
# implemented using the old activesupport #dig instead of the ruby built-in
5+
# so we can use some of the magic in Schema::InputObject and Query::Arguments
6+
# to handle stringified/symbolized keys.
7+
#
8+
# @param args [Array<[String, Symbol>] Retrieves the value object corresponding to the each key objects repeatedly
9+
# @return [Object]
10+
def dig(own_key, *rest_keys)
11+
val = self[own_key]
12+
if val.nil? || rest_keys.empty?
13+
val
14+
else
15+
val.dig(*rest_keys)
16+
end
17+
end
18+
end
19+
end

lib/graphql/query/arguments.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class Query
66
# {Arguments} recursively wraps the input in {Arguments} instances.
77
class Arguments
88
extend Forwardable
9+
include GraphQL::Dig
910

1011
def self.construct_arguments_class(argument_owner)
1112
argument_definitions = argument_owner.arguments

lib/graphql/schema/input_object.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ class InputObject < GraphQL::Schema::Member
55
extend GraphQL::Schema::Member::AcceptsDefinition
66
extend Forwardable
77
extend GraphQL::Schema::Member::HasArguments
8+
include GraphQL::Dig
89

910
def initialize(values, context:, defaults_used:)
1011
@context = context

spec/graphql/query/arguments_spec.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,27 @@
121121
end
122122
end
123123

124+
describe "#dig" do
125+
it "returns the value at that key" do
126+
assert_equal 1, arguments.dig("a")
127+
assert_equal 1, arguments.dig(:a)
128+
assert arguments.dig("inputObject").is_a?(GraphQL::Query::Arguments)
129+
end
130+
131+
it "works with nested keys" do
132+
assert_equal 3, arguments.dig("inputObject", "d")
133+
assert_equal 3, arguments.dig(:inputObject, :d)
134+
assert_equal 3, arguments.dig("inputObject", :d)
135+
assert_equal 3, arguments.dig(:inputObject, "d")
136+
end
137+
138+
it "returns nil for missing keys" do
139+
assert_nil arguments.dig("z")
140+
assert_nil arguments.dig(7)
141+
end
142+
end
143+
144+
124145
describe "#key?" do
125146
let(:arg_values) { [] }
126147
let(:schema) {

spec/graphql/schema/input_object_spec.rb

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,55 @@ class TestInput2 < GraphQL::Schema::InputObject
151151
assert_equal({ a: 1, b: 2, input_object: { d: 3, e: 4 } }, input_object.to_h)
152152
end
153153
end
154+
155+
describe "#dig" do
156+
module InputObjectDigTest
157+
class TestInput1 < GraphQL::Schema::InputObject
158+
graphql_name "TestInput1"
159+
argument :d, Int, required: true
160+
argument :e, Int, required: true
161+
end
162+
163+
class TestInput2 < GraphQL::Schema::InputObject
164+
graphql_name "TestInput2"
165+
argument :a, Int, required: true
166+
argument :b, Int, required: true
167+
argument :c, TestInput1, as: :inputObject, required: true
168+
end
169+
170+
TestInput1.to_graphql
171+
TestInput2.to_graphql
172+
end
173+
arg_values = {a: 1, b: 2, c: { d: 3, e: 4 }}
174+
175+
input_object = InputObjectDigTest::TestInput2.new(
176+
arg_values,
177+
context: nil,
178+
defaults_used: Set.new
179+
)
180+
it "returns the value at that key" do
181+
assert_equal 1, input_object.dig("a")
182+
assert_equal 1, input_object.dig(:a)
183+
assert input_object.dig("inputObject").is_a?(GraphQL::Schema::InputObject)
184+
end
185+
186+
it "works with nested keys" do
187+
assert_equal 3, input_object.dig("inputObject", "d")
188+
assert_equal 3, input_object.dig(:inputObject, :d)
189+
assert_equal 3, input_object.dig("inputObject", :d)
190+
assert_equal 3, input_object.dig(:inputObject, "d")
191+
end
192+
193+
it "returns nil for missing keys" do
194+
assert_nil input_object.dig("z")
195+
assert_nil input_object.dig(7)
196+
end
197+
198+
it "handles underscored keys" do
199+
# TODO - shouldn't this work too?
200+
# assert_equal 3, input_object.dig('input_object', 'd')
201+
assert_equal 3, input_object.dig(:input_object, :d)
202+
end
203+
204+
end
154205
end

0 commit comments

Comments
 (0)