From a65e87322c79a2dcc1976de30e27349598d0a852 Mon Sep 17 00:00:00 2001 From: Jason Weathered Date: Wed, 16 Oct 2019 09:12:50 +1000 Subject: [PATCH 1/4] Refactor to store the lines as intermediate state --- lib/rspec_junit_formatter/rspec3.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/rspec_junit_formatter/rspec3.rb b/lib/rspec_junit_formatter/rspec3.rb index 2a471ae..6f09785 100644 --- a/lib/rspec_junit_formatter/rspec3.rb +++ b/lib/rspec_junit_formatter/rspec3.rb @@ -77,7 +77,9 @@ def failure_message_for(example) end def failure_for(notification) - strip_diff_colors(notification.message_lines.join("\n")) << "\n" << notification.formatted_backtrace.join("\n") + lines = notification.message_lines + [''] + notification.formatted_backtrace + + strip_diff_colors(lines.join("\n")) end def exception_for(notification) From ba988567080fe12c8cb888b0f8d1dc4a0f214b50 Mon Sep 17 00:00:00 2001 From: Jason Weathered Date: Wed, 16 Oct 2019 09:15:05 +1000 Subject: [PATCH 2/4] Use fully_formatted_lines to get detail for aggregated failures --- example/spec/example_spec.rb | 5 +++++ lib/rspec_junit_formatter/rspec3.rb | 15 ++++++++++++++- spec/rspec_junit_formatter_spec.rb | 16 ++++++++++++---- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/example/spec/example_spec.rb b/example/spec/example_spec.rb index da25204..119e452 100644 --- a/example/spec/example_spec.rb +++ b/example/spec/example_spec.rb @@ -22,6 +22,11 @@ end end + it "should support multiple failures", aggregate_failures: true do + expect('foo').to eq 1 + expect('bar').to eq 2 + end + it "shows diffs cleanly" do expect({a: "b", c: "d"}).to eql({a: 2, c: 4}) end diff --git a/lib/rspec_junit_formatter/rspec3.rb b/lib/rspec_junit_formatter/rspec3.rb index 6f09785..19256dd 100644 --- a/lib/rspec_junit_formatter/rspec3.rb +++ b/lib/rspec_junit_formatter/rspec3.rb @@ -77,7 +77,20 @@ def failure_message_for(example) end def failure_for(notification) - lines = notification.message_lines + [''] + notification.formatted_backtrace + lines = notification.fully_formatted_lines(nil, RSpec::Core::Notifications::NullColorizer).map(&:to_s) + + unless lines.first.empty? + raise 'Expected first line to be empty' + end + lines.shift + + indentation = lines.reject(&:empty?).map { |line| line[/^[ \t]*/] }.min + lines = lines.map { |line| line.sub(/^#{Regexp.escape indentation}/, '') } + + unless lines.first == notification.description + raise 'Expected second line to be description' + end + lines.shift strip_diff_colors(lines.join("\n")) end diff --git a/spec/rspec_junit_formatter_spec.rb b/spec/rspec_junit_formatter_spec.rb index 87e4cb7..c981a84 100644 --- a/spec/rspec_junit_formatter_spec.rb +++ b/spec/rspec_junit_formatter_spec.rb @@ -46,6 +46,7 @@ def execute_example_spec let(:failed_testcases) { doc.xpath("/testsuite/testcase[failure]") } let(:shared_testcases) { doc.xpath("/testsuite/testcase[contains(@name, 'shared example')]") } let(:failed_shared_testcases) { doc.xpath("/testsuite/testcase[contains(@name, 'shared example')][failure]") } + let(:failed_multiple_testcases) { doc.xpath("/testsuite/testcase[contains(@name, 'multiple')][failure]") } # Combined into a single example so we don't have to re-run the example rspec # process over and over. (We need to change the parameters in later specs so @@ -57,9 +58,9 @@ def execute_example_spec expect(testsuite).not_to be(nil) expect(testsuite["name"]).to eql("rspec") - expect(testsuite["tests"]).to eql("12") + expect(testsuite["tests"]).to eql("13") expect(testsuite["skipped"]).to eql("1") - expect(testsuite["failures"]).to eql("8") + expect(testsuite["failures"]).to eql("9") expect(testsuite["errors"]).to eql("0") expect(Time.parse(testsuite["timestamp"])).to be_within(60).of(Time.now) expect(testsuite["time"].to_f).to be > 0 @@ -67,7 +68,7 @@ def execute_example_spec # it has some test cases - expect(testcases.size).to eql(12) + expect(testcases.size).to eql(13) testcases.each do |testcase| expect(testcase["classname"]).to eql("spec.example_spec") @@ -101,7 +102,7 @@ def execute_example_spec # it has failed test cases - expect(failed_testcases.size).to eql(8) + expect(failed_testcases.size).to eql(9) failed_testcases.each do |testcase| expect(testcase).not_to be(nil) @@ -128,6 +129,13 @@ def execute_example_spec expect(testcase.text).to include("shared_examples.rb") end + # it has detail for an aggregate_failures example + expect(failed_multiple_testcases.size).to eql(1) + failed_multiple_testcases.each do |testcase| + expect(testcase.text).to include("foo") + expect(testcase.text).to include("bar") + end + # it cleans up diffs diff_testcase_failure = doc.xpath("//testcase[contains(@name, 'diffs')]/failure").first From b767bc9ef4203299e68320fa3c7d1da1975ff405 Mon Sep 17 00:00:00 2001 From: Jason Weathered Date: Fri, 18 Oct 2019 15:27:15 +1000 Subject: [PATCH 3/4] Fix support for RSpec < 3.6 --- lib/rspec_junit_formatter/rspec3.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/rspec_junit_formatter/rspec3.rb b/lib/rspec_junit_formatter/rspec3.rb index 19256dd..37a83be 100644 --- a/lib/rspec_junit_formatter/rspec3.rb +++ b/lib/rspec_junit_formatter/rspec3.rb @@ -77,13 +77,23 @@ def failure_message_for(example) end def failure_for(notification) - lines = notification.fully_formatted_lines(nil, RSpec::Core::Notifications::NullColorizer).map(&:to_s) + lines = if notification.respond_to?(:fully_formatted_lines) + notification.fully_formatted_lines(nil, RSpec::Core::Notifications::NullColorizer).map(&:to_s) + else + notification.fully_formatted(nil, RSpec::Core::Notifications::NullColorizer).split("\n") + end unless lines.first.empty? raise 'Expected first line to be empty' end lines.shift + unless notification.respond_to?(:fully_formatted_lines) + if lines[0][2] == ')' + lines[0][2] = ' ' + end + end + indentation = lines.reject(&:empty?).map { |line| line[/^[ \t]*/] }.min lines = lines.map { |line| line.sub(/^#{Regexp.escape indentation}/, '') } From 6cb2758876b76618047d03ba873ea31283ed2542 Mon Sep 17 00:00:00 2001 From: Jason Weathered Date: Fri, 18 Oct 2019 15:29:48 +1000 Subject: [PATCH 4/4] Ignore missing aggregate_failures support on older versions of RSpec --- spec/rspec_junit_formatter_spec.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/rspec_junit_formatter_spec.rb b/spec/rspec_junit_formatter_spec.rb index c981a84..4faf800 100644 --- a/spec/rspec_junit_formatter_spec.rb +++ b/spec/rspec_junit_formatter_spec.rb @@ -133,7 +133,11 @@ def execute_example_spec expect(failed_multiple_testcases.size).to eql(1) failed_multiple_testcases.each do |testcase| expect(testcase.text).to include("foo") - expect(testcase.text).to include("bar") + if Gem::Version.new(RSpec::Core::Version::STRING) >= Gem::Version.new('3.3') + expect(testcase.text).to include("bar") + else + expect(testcase.text).to_not include("bar") + end end # it cleans up diffs