diff --git a/lib/graphql/schema.rb b/lib/graphql/schema.rb index 7488ef4764..df0c7ef209 100644 --- a/lib/graphql/schema.rb +++ b/lib/graphql/schema.rb @@ -171,9 +171,9 @@ def trace_class(new_class = nil) end # @return [Class] Return the trace class to use for this mode, looking one up on the superclass if this Schema doesn't have one defined. - def trace_class_for(mode) + def trace_class_for(mode, build: true) own_trace_modes[mode] || - (superclass.respond_to?(:trace_class_for) ? superclass.trace_class_for(mode) : (own_trace_modes[mode] = build_trace_mode(mode))) + (superclass.respond_to?(:trace_class_for) ? superclass.trace_class_for(mode, build: build) : (build ? (own_trace_modes[mode] = build_trace_mode(mode)) : nil)) end # Configure `trace_class` to be used whenever `context: { trace_mode: mode_name }` is requested. @@ -218,7 +218,7 @@ def build_trace_mode(mode) else # First, see if the superclass has a custom-defined class for this. # Then, if it doesn't, use this class's default trace - base_class = (superclass.respond_to?(:trace_class_for) && superclass.trace_class_for(mode)) || trace_class_for(:default) + base_class = (superclass.respond_to?(:trace_class_for) && superclass.trace_class_for(mode, build: false)) || trace_class_for(:default) # Prepare the default trace class if it hasn't been initialized yet base_class ||= (own_trace_modes[:default] = build_trace_mode(:default)) mods = trace_modules_for(mode) diff --git a/spec/graphql/tracing/trace_modes_spec.rb b/spec/graphql/tracing/trace_modes_spec.rb index 3c774824f5..a426d2199b 100644 --- a/spec/graphql/tracing/trace_modes_spec.rb +++ b/spec/graphql/tracing/trace_modes_spec.rb @@ -138,6 +138,31 @@ def execute_query(query:) end end + describe "inheriting from a custom default trace class" do + class CustomBaseTraceParentSchema < GraphQL::Schema + class CustomTrace < GraphQL::Tracing::Trace + end + + trace_class CustomTrace + end + + class CustomBaseTraceSubclassSchema < CustomBaseTraceParentSchema + trace_with Module.new, mode: :special_with_base_class + end + + it "uses the default trace class for default mode" do + assert_equal CustomBaseTraceParentSchema::CustomTrace, CustomBaseTraceParentSchema.trace_class_for(:default) + assert_equal CustomBaseTraceParentSchema::CustomTrace, CustomBaseTraceSubclassSchema.trace_class_for(:default).superclass + + assert_instance_of CustomBaseTraceParentSchema::CustomTrace, CustomBaseTraceParentSchema.new_trace + assert_kind_of CustomBaseTraceParentSchema::CustomTrace, CustomBaseTraceSubclassSchema.new_trace + end + + it "uses the default trace class for special modes" do + assert_includes CustomBaseTraceSubclassSchema.trace_class_for(:special_with_base_class).ancestors, CustomBaseTraceParentSchema::CustomTrace + assert_kind_of CustomBaseTraceParentSchema::CustomTrace, CustomBaseTraceSubclassSchema.new_trace(mode: :special_with_base_class) + end + end describe "custom default trace mode" do class CustomDefaultSchema < TraceModesTest::ParentSchema