# frozen_string_literal: true require "spec_helper" describe GraphQL::Argument do it "is validated at schema build-time" do query_type = GraphQL::ObjectType.define do name "Query" field :invalid, types.Boolean do argument :invalid, types.Float, default_value: ["123"] end end err = assert_raises(GraphQL::Schema::InvalidTypeError) { schema = GraphQL::Schema.define(query: query_type) schema.types } expected_error = %|Query is invalid: field "invalid" argument "invalid" default value ["123"] is not valid for type Float| assert_includes err.message, expected_error end describe ".from_dsl" do it "accepts an existing argument" do existing = GraphQL::Argument.define do name "bar" type GraphQL::STRING_TYPE end arg = GraphQL::Argument.from_dsl(:foo, existing) assert_equal "foo", arg.name assert_equal GraphQL::STRING_TYPE, arg.type end it "accepts a definition block after defining kwargs" do arg = GraphQL::Argument.from_dsl(:foo, GraphQL::STRING_TYPE) do description "my type is #{target.type}" end assert_equal "my type is String", arg.description end it "accepts a definition block and yields the argument if the block has an arity of one" do arg = GraphQL::Argument.from_dsl(:foo, GraphQL::STRING_TYPE) do |argument| argument.description "my type is #{target.type}" end assert_equal "my type is String", arg.description end it "accepts a definition block with existing arg" do existing = GraphQL::Argument.define do name "bar" type GraphQL::STRING_TYPE end arg = GraphQL::Argument.from_dsl(:foo, existing) do description "Description for an existing field." end assert_equal "Description for an existing field.", arg.description end it "creates an argument from dsl arguments" do arg = GraphQL::Argument.from_dsl( :foo, GraphQL::STRING_TYPE, "A Description", default_value: "Bar" ) assert_equal "foo", arg.name assert_equal GraphQL::STRING_TYPE, arg.type assert_equal "A Description", arg.description assert_equal "Bar", arg.default_value end end it "accepts custom keywords" do type = GraphQL::ObjectType.define do name "Something" field :something, types.String do argument "flagged", types.Int, metadata_flag: :flag_1 end end arg = type.fields["something"].arguments["flagged"] assert_equal true, arg.metadata[:flag_1] end it "accepts proc type" do argument = GraphQL::Argument.define(name: :favoriteFood, type: -> { GraphQL::STRING_TYPE }) assert_equal GraphQL::STRING_TYPE, argument.type end it "accepts a default_value" do argument = GraphQL::Argument.define(name: :favoriteFood, type: GraphQL::STRING_TYPE, default_value: 'Default') assert_equal 'Default', argument.default_value assert argument.default_value? end it "accepts a default_value of nil" do argument = GraphQL::Argument.define(name: :favoriteFood, type: GraphQL::STRING_TYPE, default_value: nil) assert argument.default_value.nil? assert argument.default_value? end it "default_value is optional" do argument = GraphQL::Argument.define(name: :favoriteFood, type: GraphQL::STRING_TYPE) assert argument.default_value.nil? assert !argument.default_value? end describe "#as, #exposed_as" do it "accepts a `as` property to define the arg name at resolve time" do argument = GraphQL::Argument.define(name: :favoriteFood, type: GraphQL::STRING_TYPE, as: :favFood) assert_equal argument.as, :favFood end it "uses `name` or `as` for `expose_as`" do arg_1 = GraphQL::Argument.define(name: :favoriteFood, type: GraphQL::STRING_TYPE, as: :favFood) assert_equal arg_1.expose_as, "favFood" arg_2 = GraphQL::Argument.define(name: :favoriteFood, type: GraphQL::STRING_TYPE) assert_equal arg_2.expose_as, "favoriteFood" arg_3 = arg_2.redefine { as :ff } assert_equal arg_3.expose_as, "ff" end it "can be set in the passed block" do argument = GraphQL::Argument.define do name "arg" as "arg_name" end assert_equal "arg_name", argument.as end end describe "prepare" do it "accepts a prepare proc and calls it to generate the prepared value" do prepare_proc = Proc.new { |arg, ctx| arg + ctx[:val] } argument = GraphQL::Argument.define(name: :plusOne, type: GraphQL::INT_TYPE, prepare: prepare_proc) assert_equal argument.prepare(1, {val: 1}), 2 end it "returns the value itself if no prepare proc is provided" do argument = GraphQL::Argument.define(name: :someNumber, type: GraphQL::INT_TYPE) assert_equal argument.prepare(1, nil), 1 end it "can be set in the passed block" do prepare_proc = Proc.new { |arg, ctx| arg + ctx[:val] } argument = GraphQL::Argument.define do name "arg" prepare prepare_proc end assert_equal argument.prepare(1, {val: 1}), 2 end end end