# frozen_string_literal: true require "spec_helper" describe GraphQL::Schema::Resolver do module ResolverTest class BaseResolver < GraphQL::Schema::Resolver end class Resolver1 < BaseResolver argument :value, Integer, required: false type [Integer, null: true], null: false def initialize(object:, context:) super if defined?(@value) raise "The instance should start fresh" end @value = [100] end def resolve(value: nil) @value << value @value end end class Resolver2 < Resolver1 argument :extra_value, Integer, required: true def resolve(extra_value:, **_rest) value = super(_rest) value << extra_value value end end class Resolver3 < Resolver1 end class Resolver4 < BaseResolver type Integer, null: false extras [:ast_node] def resolve(ast_node:) object.value + ast_node.name.size end end class Resolver5 < Resolver4 end class Query < GraphQL::Schema::Object class CustomField < GraphQL::Schema::Field def resolve_field(*args) value = super if @name == "resolver3" value << -1 end value end end field_class(CustomField) field :resolver_1, resolver: Resolver1 field :resolver_2, resolver: Resolver2 field :resolver_3, resolver: Resolver3 field :resolver_3_again, resolver: Resolver3, description: "field desc" field :resolver_4, "Positional description", resolver: Resolver4 field :resolver_5, resolver: Resolver5 end class Schema < GraphQL::Schema query(Query) end end it "gets initialized for each resolution" do # State isn't shared between calls: res = ResolverTest::Schema.execute " { r1: resolver1(value: 1) r2: resolver1 }" assert_equal [100, 1], res["data"]["r1"] assert_equal [100, nil], res["data"]["r2"] end it "inherits type and arguments" do res = ResolverTest::Schema.execute " { r1: resolver2(value: 1, extraValue: 2) r2: resolver2(extraValue: 3) }" assert_equal [100, 1, 2], res["data"]["r1"] assert_equal [100, nil, 3], res["data"]["r2"] end it "uses the object's field_class" do res = ResolverTest::Schema.execute " { r1: resolver3(value: 1) r2: resolver3 }" assert_equal [100, 1, -1], res["data"]["r1"] assert_equal [100, nil, -1], res["data"]["r2"] end describe "resolve method" do it "has access to the application object" do res = ResolverTest::Schema.execute " { resolver4 } ", root_value: OpenStruct.new(value: 4) assert_equal 13, res["data"]["resolver4"] end it "gets extras" do res = ResolverTest::Schema.execute " { resolver4 } ", root_value: OpenStruct.new(value: 0) assert_equal 9, res["data"]["resolver4"] end end describe "extras" do it "is inherited" do res = ResolverTest::Schema.execute " { resolver4 resolver5 } ", root_value: OpenStruct.new(value: 0) assert_equal 9, res["data"]["resolver4"] assert_equal 9, res["data"]["resolver5"] end end describe "when applied to a field" do it "gets the field's description" do assert_nil ResolverTest::Schema.find("Query.resolver3").description assert_equal "field desc", ResolverTest::Schema.find("Query.resolver3Again").description assert_equal "Positional description", ResolverTest::Schema.find("Query.resolver4").description end it "gets the field's name" do # Matching name: assert ResolverTest::Schema.find("Query.resolver3") # Mismatched name: assert ResolverTest::Schema.find("Query.resolver3Again") end end end