From c69b584cf74d456e22644d07ea24d9725513af8e Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Fri, 5 Sep 2025 20:39:03 +0100 Subject: [PATCH 01/14] Add blank query object and remove all junit formatter implementations --- lib/cucumber/formatter/junit.rb | 386 ++++++++++++++++---------------- lib/cucumber/query.rb | 5 + 2 files changed, 198 insertions(+), 193 deletions(-) create mode 100644 lib/cucumber/query.rb diff --git a/lib/cucumber/formatter/junit.rb b/lib/cucumber/formatter/junit.rb index e457383df..45654483a 100644 --- a/lib/cucumber/formatter/junit.rb +++ b/lib/cucumber/formatter/junit.rb @@ -11,199 +11,199 @@ module Cucumber module Formatter # The formatter used for --format junit class Junit - include Io - - class UnNamedFeatureError < StandardError - def initialize(feature_file) - super("The feature in '#{feature_file}' does not have a name. The JUnit XML format requires a name for the testsuite element.") - end - end - - def initialize(config) - @ast_lookup = AstLookup.new(config) - config.on_event :test_case_started, &method(:on_test_case_started) - config.on_event :test_case_finished, &method(:on_test_case_finished) - config.on_event :test_step_finished, &method(:on_test_step_finished) - config.on_event :test_run_finished, &method(:on_test_run_finished) - @reportdir = ensure_dir(config.out_stream, 'junit') - @config = config - @features_data = Hash.new do |h, k| - h[k] = { - feature: nil, - failures: 0, - errors: 0, - tests: 0, - skipped: 0, - time: 0, - builder: Builder::XmlMarkup.new(indent: 2) - } - end - end - - def on_test_case_started(event) - test_case = event.test_case - start_feature(test_case) unless same_feature_as_previous_test_case?(test_case) - @failing_test_step = nil - # In order to fill out and , we need to - # intercept the $stderr and $stdout - @interceptedout = Interceptor::Pipe.wrap(:stdout) - @interceptederr = Interceptor::Pipe.wrap(:stderr) - end - - def on_test_step_finished(event) - test_step, result = *event.attributes - return if @failing_test_step - - @failing_test_step = test_step unless result.ok?(strict: @config.strict) - end - - def on_test_case_finished(event) - test_case, result = *event.attributes - result = result.with_filtered_backtrace(Cucumber::Formatter::BacktraceFilter) - test_case_name = NameBuilder.new(test_case, @ast_lookup) - scenario = test_case_name.scenario_name - scenario_designation = "#{scenario}#{test_case_name.name_suffix}" - output = create_output_string(test_case, scenario, result, test_case_name.row_name) - build_testcase(result, scenario_designation, output) - - Interceptor::Pipe.unwrap! :stdout - Interceptor::Pipe.unwrap! :stderr - end - - def on_test_run_finished(_event) - @features_data.each_value { |data| end_feature(data) } - end - - private - - def same_feature_as_previous_test_case?(test_case) - @current_feature_data && @current_feature_data[:uri] == test_case.location.file - end - - def start_feature(test_case) - uri = test_case.location.file - feature = @ast_lookup.gherkin_document(uri).feature - raise UnNamedFeatureError, uri if feature.name.empty? - - @current_feature_data = @features_data[uri] - @current_feature_data[:uri] = uri unless @current_feature_data[:uri] - @current_feature_data[:feature] = feature unless @current_feature_data[:feature] - end - - def end_feature(feature_data) - @testsuite = Builder::XmlMarkup.new(indent: 2) - @testsuite.instruct! - @testsuite.testsuite( - failures: feature_data[:failures], - errors: feature_data[:errors], - skipped: feature_data[:skipped], - tests: feature_data[:tests], - time: format('%