From 2cde0dc30f0cd7770ecf7252a0bed83fd0cb1bdb Mon Sep 17 00:00:00 2001 From: Luke Hill <20105237+luke-hill@users.noreply.github.com> Date: Wed, 8 Apr 2026 20:16:51 +0100 Subject: [PATCH 1/2] Add readers for fake query objects that are being isolated (#1852) --- lib/cucumber/formatter/query/hook_by_test_step.rb | 2 ++ lib/cucumber/formatter/query/pickle_by_test.rb | 2 ++ lib/cucumber/formatter/query/step_definitions_by_test_step.rb | 2 ++ lib/cucumber/formatter/query/test_case_started_by_test_case.rb | 2 ++ 4 files changed, 8 insertions(+) diff --git a/lib/cucumber/formatter/query/hook_by_test_step.rb b/lib/cucumber/formatter/query/hook_by_test_step.rb index dd1be34c2..0aebc7640 100644 --- a/lib/cucumber/formatter/query/hook_by_test_step.rb +++ b/lib/cucumber/formatter/query/hook_by_test_step.rb @@ -6,6 +6,8 @@ module Cucumber module Formatter module Query class HookByTestStep + attr_reader :hook_id_by_test_step_id + def initialize(config) @hook_id_by_test_step_id = {} diff --git a/lib/cucumber/formatter/query/pickle_by_test.rb b/lib/cucumber/formatter/query/pickle_by_test.rb index 304fb4939..3cee6e5f6 100644 --- a/lib/cucumber/formatter/query/pickle_by_test.rb +++ b/lib/cucumber/formatter/query/pickle_by_test.rb @@ -6,6 +6,8 @@ module Cucumber module Formatter module Query class PickleByTest + attr_reader :pickle_id_by_test_case_id + def initialize(config) @pickle_id_by_test_case_id = {} config.on_event :test_case_created, &method(:on_test_case_created) diff --git a/lib/cucumber/formatter/query/step_definitions_by_test_step.rb b/lib/cucumber/formatter/query/step_definitions_by_test_step.rb index 833b78620..4da3cbd5c 100644 --- a/lib/cucumber/formatter/query/step_definitions_by_test_step.rb +++ b/lib/cucumber/formatter/query/step_definitions_by_test_step.rb @@ -6,6 +6,8 @@ module Cucumber module Formatter module Query class StepDefinitionsByTestStep + attr_reader :step_definition_ids_by_test_step_id, :step_match_arguments_by_test_step_id + def initialize(config) @step_definition_ids_by_test_step_id = {} @step_match_arguments_by_test_step_id = {} diff --git a/lib/cucumber/formatter/query/test_case_started_by_test_case.rb b/lib/cucumber/formatter/query/test_case_started_by_test_case.rb index f3fcdbde4..b657121ba 100644 --- a/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +++ b/lib/cucumber/formatter/query/test_case_started_by_test_case.rb @@ -6,6 +6,8 @@ module Cucumber module Formatter module Query class TestCaseStartedByTestCase + attr_reader :attempts_by_test_case_id, :test_case_started_id_by_test_case_id + def initialize(config) @config = config config.on_event :test_case_created, &method(:on_test_case_created) From 28e168063cd25d565919c67b90c712fdedaf00db Mon Sep 17 00:00:00 2001 From: Luke Hill <20105237+luke-hill@users.noreply.github.com> Date: Thu, 9 Apr 2026 09:29:03 +0100 Subject: [PATCH 2/2] Removed a couple more of the fake queries (#1856) --- lib/cucumber/formatter/message_builder.rb | 35 +++++-- .../formatter/query/hook_by_test_step.rb | 36 ------- .../formatter/query/pickle_by_test.rb | 30 ------ .../formatter/query/hook_by_test_step_spec.rb | 93 ------------------- .../formatter/query/pickle_by_test_spec.rb | 63 ------------- 5 files changed, 26 insertions(+), 231 deletions(-) delete mode 100644 lib/cucumber/formatter/query/hook_by_test_step.rb delete mode 100644 lib/cucumber/formatter/query/pickle_by_test.rb delete mode 100644 spec/cucumber/formatter/query/hook_by_test_step_spec.rb delete mode 100644 spec/cucumber/formatter/query/pickle_by_test_spec.rb diff --git a/lib/cucumber/formatter/message_builder.rb b/lib/cucumber/formatter/message_builder.rb index 3eaa5b7a6..635f45f0a 100644 --- a/lib/cucumber/formatter/message_builder.rb +++ b/lib/cucumber/formatter/message_builder.rb @@ -2,8 +2,6 @@ require 'base64' require 'cucumber/formatter/backtrace_filter' -require 'cucumber/formatter/query/hook_by_test_step' -require 'cucumber/formatter/query/pickle_by_test' require 'cucumber/formatter/query/step_definitions_by_test_step' require 'cucumber/formatter/query/test_case_started_by_test_case' @@ -18,8 +16,6 @@ class MessageBuilder def initialize(config) @config = config - @hook_by_test_step = Query::HookByTestStep.new(config) - @pickle_by_test = Query::PickleByTest.new(config) @step_definitions_by_test_step = Query::StepDefinitionsByTestStep.new(config) @test_case_started_by_test_case = Query::TestCaseStartedByTestCase.new(config) @@ -27,8 +23,12 @@ def initialize(config) @query = Cucumber::Query.new(@repository) @test_run_started_id = config.id_generator.new_id + + # Fake Query objects @test_case_by_step_id = {} + @pickle_id_by_test_case_id = {} @pickle_id_step_by_test_step_id = {} + @hook_id_by_test_step_id = {} # Ensure all handlers for events occur after all ivars are instantiated @@ -42,7 +42,7 @@ def initialize(config) config.on_event :step_activated, &method(:on_step_activated) config.on_event :step_definition_registered, &method(:on_step_definition_registered) - # TODO: Handle TestCaseCreated + config.on_event :test_case_created, &method(:on_test_case_created) config.on_event :test_case_ready, &method(:on_test_case_ready) config.on_event :test_case_started, &method(:on_test_case_started) config.on_event :test_case_finished, &method(:on_test_case_finished) @@ -104,15 +104,19 @@ def on_gherkin_source_read(event) output_envelope(message) end - def on_hook_test_step_created(_event) - # TODO: Handle HookTestStepCreated + def on_hook_test_step_created(event) + @hook_id_by_test_step_id[event.test_step.id] = event.hook.id + end + + def on_test_case_created(event) + @pickle_id_by_test_case_id[event.test_case.id] = event.pickle.id end def on_test_case_ready(event) message = Cucumber::Messages::Envelope.new( test_case: Cucumber::Messages::TestCase.new( id: event.test_case.id, - pickle_id: @pickle_by_test.pickle_id(event.test_case), + pickle_id: fake_query_pickle_id(event.test_case), test_steps: event.test_case.test_steps.map { |step| test_step_to_message(step) }, test_run_started_id: @test_run_started_id ) @@ -146,7 +150,7 @@ def test_step_to_message(step) def hook_step_to_message(step) Cucumber::Messages::TestStep.new( id: step.id, - hook_id: @hook_by_test_step.hook_id(step) + hook_id: fake_query_hook_id(step) ) end @@ -209,6 +213,7 @@ def on_test_case_started(event) def on_test_step_created(event) @pickle_id_step_by_test_step_id[event.test_step.id] = event.pickle_step.id test_step_to_message(event.test_step) + @hook_id_by_test_step_id[event.test_step.id] = nil # TODO: We need to determine what message to output here (Unsure - Placeholder added) # message = Cucumber::Messages::Envelope.new( # pickle: { @@ -378,6 +383,18 @@ def on_undefined_parameter_type(event) def test_case_started_id(test_case) @test_case_started_by_test_case.test_case_started_id_by_test_case(test_case) end + + def fake_query_hook_id(test_step) + return @hook_id_by_test_step_id[test_step.id] if @hook_id_by_test_step_id.key?(test_step.id) + + raise TestStepUnknownError, "No hook found for #{test_step.id} }. Known: #{@hook_id_by_test_step_id.keys}" + end + + def fake_query_pickle_id(test_case) + return @pickle_id_by_test_case_id[test_case.id] if @pickle_id_by_test_case_id.key?(test_case.id) + + raise TestCaseUnknownError, "No pickle found for #{test_case.id} }. Known: #{@pickle_id_by_test_case_id.keys}" + end end end end diff --git a/lib/cucumber/formatter/query/hook_by_test_step.rb b/lib/cucumber/formatter/query/hook_by_test_step.rb deleted file mode 100644 index 0aebc7640..000000000 --- a/lib/cucumber/formatter/query/hook_by_test_step.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -require 'cucumber/formatter/errors' - -module Cucumber - module Formatter - module Query - class HookByTestStep - attr_reader :hook_id_by_test_step_id - - def initialize(config) - @hook_id_by_test_step_id = {} - - config.on_event :test_step_created, &method(:on_test_step_created) - config.on_event :hook_test_step_created, &method(:on_hook_test_step_created) - end - - def hook_id(test_step) - return @hook_id_by_test_step_id[test_step.id] if @hook_id_by_test_step_id.key?(test_step.id) - - raise TestStepUnknownError, "No hook found for #{test_step.id} }. Known: #{@hook_id_by_test_step_id.keys}" - end - - private - - def on_test_step_created(event) - @hook_id_by_test_step_id[event.test_step.id] = nil - end - - def on_hook_test_step_created(event) - @hook_id_by_test_step_id[event.test_step.id] = event.hook.id - end - end - end - end -end diff --git a/lib/cucumber/formatter/query/pickle_by_test.rb b/lib/cucumber/formatter/query/pickle_by_test.rb deleted file mode 100644 index 3cee6e5f6..000000000 --- a/lib/cucumber/formatter/query/pickle_by_test.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -require 'cucumber/formatter/errors' - -module Cucumber - module Formatter - module Query - class PickleByTest - attr_reader :pickle_id_by_test_case_id - - def initialize(config) - @pickle_id_by_test_case_id = {} - config.on_event :test_case_created, &method(:on_test_case_created) - end - - def pickle_id(test_case) - return @pickle_id_by_test_case_id[test_case.id] if @pickle_id_by_test_case_id.key?(test_case.id) - - raise TestCaseUnknownError, "No pickle found for #{test_case.id} }. Known: #{@pickle_id_by_test_case_id.keys}" - end - - private - - def on_test_case_created(event) - @pickle_id_by_test_case_id[event.test_case.id] = event.pickle.id - end - end - end - end -end diff --git a/spec/cucumber/formatter/query/hook_by_test_step_spec.rb b/spec/cucumber/formatter/query/hook_by_test_step_spec.rb deleted file mode 100644 index 840c134aa..000000000 --- a/spec/cucumber/formatter/query/hook_by_test_step_spec.rb +++ /dev/null @@ -1,93 +0,0 @@ -# frozen_string_literal: true - -require 'cucumber/formatter/spec_helper' -require 'cucumber/formatter/query/hook_by_test_step' - -RSpec.describe Cucumber::Formatter::Query::HookByTestStep do - extend Cucumber::Formatter::SpecHelperDsl - include Cucumber::Formatter::SpecHelper - - before(:each) do - Cucumber::Term::ANSIColor.coloring = false - @test_cases = [] - - @out = StringIO.new - @config = actual_runtime.configuration.with_options(out_stream: @out) - @formatter = described_class.new(@config) - - @config.on_event :test_case_started do |event| - @test_cases << event.test_case - end - - @hook_ids = [] - @config.on_event :envelope do |event| - next unless event.envelope.hook - - @hook_ids << event.envelope.hook.id - end - end - - context 'given a single feature' do - before(:each) do - run_defined_feature - end - - context 'with a scenario' do - describe '#pickle_step_id' do - define_feature <<-FEATURE - Feature: Banana party - - Scenario: Monkey eats banana - Given there are bananas - FEATURE - - define_steps do - Before() {} - After() {} - end - - it 'provides the ID of the Before Hook used to generate the Test::Step' do - test_case = @test_cases.first - expect(@formatter.hook_id(test_case.test_steps.first)).to eq(@hook_ids.first) - end - - it 'provides the ID of the After Hook used to generate the Test::Step' do - test_case = @test_cases.first - expect(@formatter.hook_id(test_case.test_steps.last)).to eq(@hook_ids.last) - end - - it 'returns nil if the step was not generated from a hook' do - test_case = @test_cases.first - expect(@formatter.hook_id(test_case.test_steps[1])).to be_nil - end - - it 'raises an exception when the test_step is unknown' do - test_step = double - allow(test_step).to receive(:id).and_return('whatever-id') - - expect { @formatter.hook_id(test_step) }.to raise_error(Cucumber::Formatter::TestStepUnknownError) - end - end - end - - context 'with AfterStep hooks' do - describe '#pickle_step_id' do - define_feature <<-FEATURE - Feature: Banana party - - Scenario: Monkey eats banana - Given there are bananas - FEATURE - - define_steps do - AfterStep() {} - end - - it 'provides the ID of the AfterStepHook used to generate the Test::Step' do - test_case = @test_cases.first - expect(@formatter.hook_id(test_case.test_steps.last)).to eq(@hook_ids.first) - end - end - end - end -end diff --git a/spec/cucumber/formatter/query/pickle_by_test_spec.rb b/spec/cucumber/formatter/query/pickle_by_test_spec.rb deleted file mode 100644 index 2cdf95b9e..000000000 --- a/spec/cucumber/formatter/query/pickle_by_test_spec.rb +++ /dev/null @@ -1,63 +0,0 @@ -# frozen_string_literal: true - -require 'cucumber/formatter/spec_helper' -require 'cucumber/formatter/query/pickle_by_test' - -module Cucumber - module Formatter - module Query - RSpec.describe PickleByTest do - extend SpecHelperDsl - include SpecHelper - - before(:each) do - Cucumber::Term::ANSIColor.coloring = false - @test_cases = [] - - @out = StringIO.new - @config = actual_runtime.configuration.with_options(out_stream: @out) - @formatter = described_class.new(@config) - - @config.on_event :test_case_created do |event| - @test_cases << event.test_case - end - - @pickle_ids = [] - @config.on_event :envelope do |event| - next unless event.envelope.pickle - - @pickle_ids << event.envelope.pickle.id - end - end - - describe 'given a single feature' do - before(:each) do - run_defined_feature - end - - describe 'with a scenario' do - describe '#pickle_id' do - define_feature <<-FEATURE - Feature: Banana party - - Scenario: Monkey eats banana - Given there are bananas - FEATURE - - it 'provides the ID of the pickle used to generate the Test::Case' do - expect(@formatter.pickle_id(@test_cases.first)).to eq(@pickle_ids.first) - end - - it 'raises an error when the Test::Case is unknown' do - test_case = double - allow(test_case).to receive(:id).and_return('whatever-id') - - expect { @formatter.pickle_id(test_case) }.to raise_error(Cucumber::Formatter::TestCaseUnknownError) - end - end - end - end - end - end - end -end