From 58b2d402196cfdfb84685e187015c9def53d4a32 Mon Sep 17 00:00:00 2001 From: Robert Mosolgo Date: Fri, 9 Nov 2018 12:27:01 -0500 Subject: [PATCH 1/2] Fix default values for input objs --- lib/graphql/execution/interpreter/runtime.rb | 27 ++++++++++++++++---- lib/graphql/query/arguments.rb | 2 +- spec/graphql/schema/input_object_spec.rb | 7 +++++ spec/support/jazz.rb | 12 +++++++++ 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/lib/graphql/execution/interpreter/runtime.rb b/lib/graphql/execution/interpreter/runtime.rb index e8dc38523f..4b213b9541 100644 --- a/lib/graphql/execution/interpreter/runtime.rb +++ b/lib/graphql/execution/interpreter/runtime.rb @@ -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 + 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. @@ -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 diff --git a/lib/graphql/query/arguments.rb b/lib/graphql/query/arguments.rb index 52b8be0fda..de0f23c757 100644 --- a/lib/graphql/query/arguments.rb +++ b/lib/graphql/query/arguments.rb @@ -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 diff --git a/spec/graphql/schema/input_object_spec.rb b/spec/graphql/schema/input_object_spec.rb index da3c56c0d4..95abc743b1 100644 --- a/spec/graphql/schema/input_object_spec.rb +++ b/spec/graphql/schema/input_object_spec.rb @@ -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 diff --git a/spec/support/jazz.rb b/spec/support/jazz.rb index b0f4e14276..f8a5bf787d 100644 --- a/spec/support/jazz.rb +++ b/spec/support/jazz.rb @@ -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 From a341de2abb5c71f42665ea69d664bf6c8b75d09c Mon Sep 17 00:00:00 2001 From: Robert Mosolgo Date: Fri, 9 Nov 2018 13:00:36 -0500 Subject: [PATCH 2/2] Support directives too --- lib/graphql/execution/interpreter/runtime.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/graphql/execution/interpreter/runtime.rb b/lib/graphql/execution/interpreter/runtime.rb index 4b213b9541..db03aded2a 100644 --- a/lib/graphql/execution/interpreter/runtime.rb +++ b/lib/graphql/execution/interpreter/runtime.rb @@ -311,7 +311,7 @@ def after_lazy(obj, field:, path:, eager: false) def each_argument_pair(ast_args_or_hash) case ast_args_or_hash - when GraphQL::Language::Nodes::Field, GraphQL::Language::Nodes::InputObject + 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