From 522db48e0302fc916558b59a81512235c00d907a Mon Sep 17 00:00:00 2001 From: Jelani Woods Date: Wed, 30 Jul 2025 08:23:56 -0500 Subject: [PATCH 1/6] --wip-- [skip ci] --- spec/stdout_spec.rb | 26 ++++++++++++++++++++++++++ spec/support/code.rb | 1 + 2 files changed, 27 insertions(+) create mode 100644 spec/stdout_spec.rb create mode 100644 spec/support/code.rb diff --git a/spec/stdout_spec.rb b/spec/stdout_spec.rb new file mode 100644 index 0000000..512260d --- /dev/null +++ b/spec/stdout_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe "Special serialization cases" do + describe "stdout actual detection" do + it "marks string comparisons as diffable" do + test_content = <<~RUBY + RSpec.describe "stdout" do + it "compares strings" do + expect { require_relative("#{Dir.pwd}/spec/support/code.rb") }.to output(/Hello, world!/).to_stdout + end + end + RUBY + + p output = run_formatter_with_content(test_content) + + puts "====" * 3 + p output["examples"].first["details"]["actual"] + p output["examples"].first["details"]["expected"] + puts "====" * 3 + puts "\n\n\n" * 3 + expect(output["examples"].first["details"]["actual"]).to match("Hello, World!") + end + end +end \ No newline at end of file diff --git a/spec/support/code.rb b/spec/support/code.rb new file mode 100644 index 0000000..9d3f432 --- /dev/null +++ b/spec/support/code.rb @@ -0,0 +1 @@ +pp "Hello, world!" \ No newline at end of file From a9d6b6b8a67a1a6cf067f004c858a86d62775466 Mon Sep 17 00:00:00 2001 From: Jelani Woods Date: Wed, 30 Jul 2025 15:16:24 -0500 Subject: [PATCH 2/6] --wip-- [skip ci] --- .../formatters/enriched_json_formatter.rb | 15 +++++++++++++++ spec/spec_helper.rb | 4 +--- spec/stdout_spec.rb | 17 ++++++++++------- spec/support/code.rb | 2 +- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/lib/rspec/enriched_json/formatters/enriched_json_formatter.rb b/lib/rspec/enriched_json/formatters/enriched_json_formatter.rb index c548d79..84f8096 100644 --- a/lib/rspec/enriched_json/formatters/enriched_json_formatter.rb +++ b/lib/rspec/enriched_json/formatters/enriched_json_formatter.rb @@ -36,6 +36,21 @@ def stop(group_notification) end end + def dump_summary(summary) + puts "dumping summary" + super + + if @output_hash[:errors_outside_of_examples]&.any? + @output_hash[:errors_outside_of_examples].map! do |error| + { + class: error[:exception].class.name, + message: error[:exception].message, + backtrace: error[:exception].backtrace, + } + end + end + end + private def add_metadata(hash, example) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 417ce54..345ff77 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -39,9 +39,7 @@ def run_formatter_with_content(test_content) "bundle", "exec", "rspec", test_file.path, "--format", "RSpec::EnrichedJson::Formatters::EnrichedJsonFormatter", "--out", output_file.path, - "-r", "./lib/rspec/enriched_json", - err: File::NULL, - out: File::NULL + "-r", "./lib/rspec/enriched_json" ) JSON.parse(File.read(output_file.path)) diff --git a/spec/stdout_spec.rb b/spec/stdout_spec.rb index 512260d..0495b98 100644 --- a/spec/stdout_spec.rb +++ b/spec/stdout_spec.rb @@ -8,17 +8,20 @@ test_content = <<~RUBY RSpec.describe "stdout" do it "compares strings" do - expect { require_relative("#{Dir.pwd}/spec/support/code.rb") }.to output(/Hello, world!/).to_stdout + path = "#{Dir.pwd}/spec/support/code.rb" + expect { require_relative(path) }.to output(/Hello, world!/).to_stdout end end RUBY - p output = run_formatter_with_content(test_content) - - puts "====" * 3 - p output["examples"].first["details"]["actual"] - p output["examples"].first["details"]["expected"] - puts "====" * 3 + output = run_formatter_with_content(test_content) + # p output + p output["summary"] + # p output["summary"]["errors_outside_of_examples_count"] + # puts "====" * 3 + # p output["examples"].first["details"]["actual"] + # p output["examples"].first["details"]["expected"] + # puts "====" * 3 puts "\n\n\n" * 3 expect(output["examples"].first["details"]["actual"]).to match("Hello, World!") end diff --git a/spec/support/code.rb b/spec/support/code.rb index 9d3f432..ecce272 100644 --- a/spec/support/code.rb +++ b/spec/support/code.rb @@ -1 +1 @@ -pp "Hello, world!" \ No newline at end of file +pp "Hello, world!".bumble \ No newline at end of file From 89cbe7b100e4f8ec027261c1d0e473725851dccc Mon Sep 17 00:00:00 2001 From: Jelani Woods Date: Thu, 31 Jul 2025 04:24:45 -0500 Subject: [PATCH 3/6] working --- .../formatters/enriched_json_formatter.rb | 38 +++++++++++++------ lib/rspec/enriched_json/version.rb | 2 +- spec/stdout_spec.rb | 29 -------------- spec/support/code.rb | 1 - 4 files changed, 28 insertions(+), 42 deletions(-) delete mode 100644 spec/stdout_spec.rb delete mode 100644 spec/support/code.rb diff --git a/lib/rspec/enriched_json/formatters/enriched_json_formatter.rb b/lib/rspec/enriched_json/formatters/enriched_json_formatter.rb index 84f8096..fcb2507 100644 --- a/lib/rspec/enriched_json/formatters/enriched_json_formatter.rb +++ b/lib/rspec/enriched_json/formatters/enriched_json_formatter.rb @@ -7,8 +7,18 @@ module RSpec module EnrichedJson module Formatters class EnrichedJsonFormatter < RSpec::Core::Formatters::JsonFormatter + PATH_AND_LINE_NUMBER_REGEX = /#?(?.+?):(?\d+)(?::in `.*')?/ + EXCEPTION_CLASS_AND_MESSAGE_REGEX = /^(?[A-Z]\w*Error|Exception):$\n(?(^\s\s.*\n?)+)/ + RSpec::Core::Formatters.register self, :message, :dump_summary, :dump_profile, :stop, :seed, :close + def initialize(output) + super + @output_hash = { + errors: [] + } + end + def stop(group_notification) @output_hash[:examples] = group_notification.notifications.map do |notification| format_example(notification.example).tap do |hash| @@ -36,19 +46,25 @@ def stop(group_notification) end end - def dump_summary(summary) - puts "dumping summary" - super + def message(notification) + ansi_escape = /\e\[[0-9;]*[mGKHF]/ + clean_message = notification.message.gsub(ansi_escape, "") - if @output_hash[:errors_outside_of_examples]&.any? - @output_hash[:errors_outside_of_examples].map! do |error| - { - class: error[:exception].class.name, - message: error[:exception].message, - backtrace: error[:exception].backtrace, - } - end + error_info = { + message: clean_message + } + + if match = clean_message.match(PATH_AND_LINE_NUMBER_REGEX) + error_info[:path] = match.named_captures["path"] + error_info[:line_number] = match.named_captures["line_number"] end + + if match = clean_message.match(EXCEPTION_CLASS_AND_MESSAGE_REGEX) + error_info[:exception_class] = match.named_captures["exception_class"] + error_info[:exception_message] = match.named_captures["exception_message"] + end + + @output_hash[:errors] << error_info end private diff --git a/lib/rspec/enriched_json/version.rb b/lib/rspec/enriched_json/version.rb index 1f1549c..6e7f6d9 100644 --- a/lib/rspec/enriched_json/version.rb +++ b/lib/rspec/enriched_json/version.rb @@ -2,6 +2,6 @@ module RSpec module EnrichedJson - VERSION = "0.8.0" + VERSION = "0.8.1" end end diff --git a/spec/stdout_spec.rb b/spec/stdout_spec.rb deleted file mode 100644 index 0495b98..0000000 --- a/spec/stdout_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -RSpec.describe "Special serialization cases" do - describe "stdout actual detection" do - it "marks string comparisons as diffable" do - test_content = <<~RUBY - RSpec.describe "stdout" do - it "compares strings" do - path = "#{Dir.pwd}/spec/support/code.rb" - expect { require_relative(path) }.to output(/Hello, world!/).to_stdout - end - end - RUBY - - output = run_formatter_with_content(test_content) - # p output - p output["summary"] - # p output["summary"]["errors_outside_of_examples_count"] - # puts "====" * 3 - # p output["examples"].first["details"]["actual"] - # p output["examples"].first["details"]["expected"] - # puts "====" * 3 - puts "\n\n\n" * 3 - expect(output["examples"].first["details"]["actual"]).to match("Hello, World!") - end - end -end \ No newline at end of file diff --git a/spec/support/code.rb b/spec/support/code.rb deleted file mode 100644 index ecce272..0000000 --- a/spec/support/code.rb +++ /dev/null @@ -1 +0,0 @@ -pp "Hello, world!".bumble \ No newline at end of file From 515fc7a857204f2972b4dbb88baecd35e078839e Mon Sep 17 00:00:00 2001 From: Jelani Woods Date: Thu, 31 Jul 2025 04:26:26 -0500 Subject: [PATCH 4/6] --wip-- [skip ci] --- spec/spec_helper.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 345ff77..417ce54 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -39,7 +39,9 @@ def run_formatter_with_content(test_content) "bundle", "exec", "rspec", test_file.path, "--format", "RSpec::EnrichedJson::Formatters::EnrichedJsonFormatter", "--out", output_file.path, - "-r", "./lib/rspec/enriched_json" + "-r", "./lib/rspec/enriched_json", + err: File::NULL, + out: File::NULL ) JSON.parse(File.read(output_file.path)) From afc7d420cb5a613dcedfb64775a9494668a7f57b Mon Sep 17 00:00:00 2001 From: Jelani Woods Date: Thu, 31 Jul 2025 05:11:02 -0500 Subject: [PATCH 5/6] ensure normal messages are present --- .../formatters/enriched_json_formatter.rb | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/lib/rspec/enriched_json/formatters/enriched_json_formatter.rb b/lib/rspec/enriched_json/formatters/enriched_json_formatter.rb index fcb2507..0c1f146 100644 --- a/lib/rspec/enriched_json/formatters/enriched_json_formatter.rb +++ b/lib/rspec/enriched_json/formatters/enriched_json_formatter.rb @@ -7,6 +7,7 @@ module RSpec module EnrichedJson module Formatters class EnrichedJsonFormatter < RSpec::Core::Formatters::JsonFormatter + EXCEPTION_DETECTOR_REGEX = /(Exception|Error|undefined method|uninitialized constant)/ PATH_AND_LINE_NUMBER_REGEX = /#?(?.+?):(?\d+)(?::in `.*')?/ EXCEPTION_CLASS_AND_MESSAGE_REGEX = /^(?[A-Z]\w*Error|Exception):$\n(?(^\s\s.*\n?)+)/ @@ -47,24 +48,28 @@ def stop(group_notification) end def message(notification) - ansi_escape = /\e\[[0-9;]*[mGKHF]/ - clean_message = notification.message.gsub(ansi_escape, "") + super - error_info = { - message: clean_message - } + if notification.message.match?(EXCEPTION_DETECTOR_REGEX) + ansi_escape = /\e\[[0-9;]*[mGKHF]/ + clean_message = notification.message.gsub(ansi_escape, "") - if match = clean_message.match(PATH_AND_LINE_NUMBER_REGEX) - error_info[:path] = match.named_captures["path"] - error_info[:line_number] = match.named_captures["line_number"] - end + error_info = { + message: clean_message + } - if match = clean_message.match(EXCEPTION_CLASS_AND_MESSAGE_REGEX) - error_info[:exception_class] = match.named_captures["exception_class"] - error_info[:exception_message] = match.named_captures["exception_message"] - end + if match = clean_message.match(PATH_AND_LINE_NUMBER_REGEX) + error_info[:path] = match.named_captures["path"] + error_info[:line_number] = match.named_captures["line_number"] + end + + if match = clean_message.match(EXCEPTION_CLASS_AND_MESSAGE_REGEX) + error_info[:exception_class] = match.named_captures["exception_class"] + error_info[:exception_message] = match.named_captures["exception_message"] + end - @output_hash[:errors] << error_info + @output_hash[:errors] << error_info + end end private From c8586f3c99e3d0fd20931671c4c823422d52f63c Mon Sep 17 00:00:00 2001 From: Jelani Woods Date: Fri, 1 Aug 2025 11:09:02 -0500 Subject: [PATCH 6/6] Address feedback --- .../formatters/enriched_json_formatter.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/rspec/enriched_json/formatters/enriched_json_formatter.rb b/lib/rspec/enriched_json/formatters/enriched_json_formatter.rb index 0c1f146..c48c528 100644 --- a/lib/rspec/enriched_json/formatters/enriched_json_formatter.rb +++ b/lib/rspec/enriched_json/formatters/enriched_json_formatter.rb @@ -7,9 +7,10 @@ module RSpec module EnrichedJson module Formatters class EnrichedJsonFormatter < RSpec::Core::Formatters::JsonFormatter + ANSI_COLOR_REGEX = /\e\[[0-9;]*[mGKHF]/ EXCEPTION_DETECTOR_REGEX = /(Exception|Error|undefined method|uninitialized constant)/ - PATH_AND_LINE_NUMBER_REGEX = /#?(?.+?):(?\d+)(?::in `.*')?/ - EXCEPTION_CLASS_AND_MESSAGE_REGEX = /^(?[A-Z]\w*Error|Exception):$\n(?(^\s\s.*\n?)+)/ + PATH_AND_LINE_NUMBER_REGEX = /#?(?.+?):(?\d+)/ + EXCEPTION_CLASS_AND_MESSAGE_REGEX = /^(?[A-Z]\w*Error|Exception):$\n(?(?^\s\s.*\n?)+)/ RSpec::Core::Formatters.register self, :message, :dump_summary, :dump_profile, :stop, :seed, :close @@ -51,19 +52,18 @@ def message(notification) super if notification.message.match?(EXCEPTION_DETECTOR_REGEX) - ansi_escape = /\e\[[0-9;]*[mGKHF]/ - clean_message = notification.message.gsub(ansi_escape, "") + clean_message = notification.message.gsub(ANSI_COLOR_REGEX, "") error_info = { message: clean_message } - if match = clean_message.match(PATH_AND_LINE_NUMBER_REGEX) + if (match = clean_message.match(PATH_AND_LINE_NUMBER_REGEX)) error_info[:path] = match.named_captures["path"] error_info[:line_number] = match.named_captures["line_number"] end - if match = clean_message.match(EXCEPTION_CLASS_AND_MESSAGE_REGEX) + if (match = clean_message.match(EXCEPTION_CLASS_AND_MESSAGE_REGEX)) error_info[:exception_class] = match.named_captures["exception_class"] error_info[:exception_message] = match.named_captures["exception_message"] end