Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[interpreter] Fix default values for input objects #1951

Merged
merged 2 commits into from
Nov 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions lib/graphql/execution/interpreter/runtime.rb
Original file line number Diff line number Diff line change
Expand Up @@ -309,14 +309,30 @@ def after_lazy(obj, field:, path:, eager: false)
end
end

def arguments(graphql_object, arg_owner, ast_node)
def each_argument_pair(ast_args_or_hash)
case ast_args_or_hash
when GraphQL::Language::Nodes::Field, GraphQL::Language::Nodes::InputObject, GraphQL::Language::Nodes::Directive
ast_args_or_hash.arguments.each do |arg|
yield(arg.name, arg.value)
end
when Hash
ast_args_or_hash.each do |key, value|
normalized_name = GraphQL::Schema::Member::BuildType.camelize(key.to_s)
yield(normalized_name, value)
end
else
raise "Invariant, unexpected #{ast_args_or_hash.inspect}"
end
end

def arguments(graphql_object, arg_owner, ast_node_or_hash)
kwarg_arguments = {}
arg_defns = arg_owner.arguments
ast_node.arguments.each do |arg|
arg_defn = arg_defns[arg.name]
each_argument_pair(ast_node_or_hash) do |arg_name, arg_value|
arg_defn = arg_defns[arg_name]
# Need to distinguish between client-provided `nil`
# and nothing-at-all
is_present, value = arg_to_value(graphql_object, arg_defn.type, arg.value)
is_present, value = arg_to_value(graphql_object, arg_defn.type, arg_value)
if is_present
# This doesn't apply to directives, which are legacy
# Can remove this when Skip and Include use classes or something.
Expand All @@ -328,7 +344,8 @@ def arguments(graphql_object, arg_owner, ast_node)
end
arg_defns.each do |name, arg_defn|
if arg_defn.default_value? && !kwarg_arguments.key?(arg_defn.keyword)
kwarg_arguments[arg_defn.keyword] = arg_defn.default_value
_is_present, value = arg_to_value(graphql_object, arg_defn.type, arg_defn.default_value)
kwarg_arguments[arg_defn.keyword] = value
end
end
kwarg_arguments
Expand Down
2 changes: 1 addition & 1 deletion lib/graphql/query/arguments.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def self.construct_arguments_class(argument_owner)
def initialize(values, context:, defaults_used:)
@argument_values = values.inject({}) do |memo, (inner_key, inner_value)|
arg_name = inner_key.to_s
arg_defn = self.class.argument_definitions[arg_name]
arg_defn = self.class.argument_definitions[arg_name] || raise("Not foudn #{arg_name} among #{self.class.argument_definitions.keys}")
arg_default_used = defaults_used.include?(arg_name)
arg_value = wrap_value(inner_value, arg_defn.type, context)
string_key = arg_defn.expose_as
Expand Down
7 changes: 7 additions & 0 deletions spec/graphql/schema/input_object_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ class Schema < GraphQL::Schema
end
end

describe "when used with default_value" do
it "comes as an instance" do
res = Jazz::Schema.execute("{ defaultValueTest }")
assert_equal "Jazz::InspectableInput -> {:string_value=>\"S\"}", res["data"]["defaultValueTest"]
end
end

describe "#to_h" do
module InputObjectToHTest
class TestInput1 < GraphQL::Schema::InputObject
Expand Down
12 changes: 12 additions & 0 deletions spec/support/jazz.rb
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,18 @@ def hash_by_sym
def named_entities
[Models.data["Ensemble"].first, nil]
end

field :default_value_test, String, null: false do
if TESTING_INTERPRETER
argument :arg_with_default, InspectableInput, required: false, default_value: { string_value: "S" }
else
argument :arg_with_default, InspectableInput, required: false, default_value: { "stringValue" => "S" }
end
end

def default_value_test(arg_with_default:)
"#{arg_with_default.class.name} -> #{arg_with_default.to_h}"
end
end

class EnsembleInput < GraphQL::Schema::InputObject
Expand Down