From 32585731f7b809c8ca922e15b8842047326cabc4 Mon Sep 17 00:00:00 2001 From: Joe Stein Date: Wed, 8 May 2024 14:18:16 -0400 Subject: [PATCH 1/5] Add Appraisal for rspec 3.13.0 --- Appraisals | 15 +++++++++++- gemfiles/no_rails_rspec_gte_3_13.gemfile | 23 +++++++++++++++++ gemfiles/rails_6_0_rspec_gte_3_13.gemfile | 30 +++++++++++++++++++++++ gemfiles/rails_6_1_rspec_gte_3_13.gemfile | 30 +++++++++++++++++++++++ gemfiles/rails_7_0_rspec_gte_3_13.gemfile | 30 +++++++++++++++++++++++ 5 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 gemfiles/no_rails_rspec_gte_3_13.gemfile create mode 100644 gemfiles/rails_6_0_rspec_gte_3_13.gemfile create mode 100644 gemfiles/rails_6_1_rspec_gte_3_13.gemfile create mode 100644 gemfiles/rails_7_0_rspec_gte_3_13.gemfile diff --git a/Appraisals b/Appraisals index cdc1f860..e7a828f2 100644 --- a/Appraisals +++ b/Appraisals @@ -49,12 +49,25 @@ appraisals = { gem 'rspec-mocks', '3.12.0' gem 'rspec-support', '3.12.0' + gem 'rspec-rails' if with_rails + end, + rspec_gte_3_13: + proc do |with_rails| + # version = ['>= 3.13', '< 4'] + # gem "rspec", *version + + gem 'rspec', '3.13.0' + gem 'rspec-core', '3.13.0' + gem 'rspec-expectations', '3.13.0' + gem 'rspec-mocks', '3.13.0' + gem 'rspec-support', '3.13.0' + gem 'rspec-rails' if with_rails end } rails_appraisals = %i[no_rails rails_6_0 rails_6_1 rails_7_0] -rspec_appraisals = %i[rspec_lt_3_10 rspec_gte_3_10] +rspec_appraisals = %i[rspec_lt_3_10 rspec_gte_3_10 rspec_gte_3_13] rails_appraisals.each do |rails_appraisal| rspec_appraisals.each do |rspec_appraisal| diff --git a/gemfiles/no_rails_rspec_gte_3_13.gemfile b/gemfiles/no_rails_rspec_gte_3_13.gemfile new file mode 100644 index 00000000..f900f2a1 --- /dev/null +++ b/gemfiles/no_rails_rspec_gte_3_13.gemfile @@ -0,0 +1,23 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "appraisal", git: "https://github.com/thoughtbot/appraisal" +gem "bundler-audit" +gem "childprocess" +gem "climate_control" +gem "prettier_print" +gem "pry-byebug", platform: :mri +gem "pry-nav", platform: :jruby +gem "rake" +gem "rubocop" +gem "syntax_tree" +gem "syntax_tree-haml" +gem "syntax_tree-rbs" +gem "rspec", "3.13.0" +gem "rspec-core", "3.13.0" +gem "rspec-expectations", "3.13.0" +gem "rspec-mocks", "3.13.0" +gem "rspec-support", "3.13.0" + +gemspec path: "../" diff --git a/gemfiles/rails_6_0_rspec_gte_3_13.gemfile b/gemfiles/rails_6_0_rspec_gte_3_13.gemfile new file mode 100644 index 00000000..c427d0f5 --- /dev/null +++ b/gemfiles/rails_6_0_rspec_gte_3_13.gemfile @@ -0,0 +1,30 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "appraisal", git: "https://github.com/thoughtbot/appraisal" +gem "bundler-audit" +gem "childprocess" +gem "climate_control" +gem "prettier_print" +gem "pry-byebug", platform: :mri +gem "pry-nav", platform: :jruby +gem "rake" +gem "rubocop" +gem "syntax_tree" +gem "syntax_tree-haml" +gem "syntax_tree-rbs" +gem "activerecord-jdbcsqlite3-adapter", platform: :jruby +gem "jdbc-sqlite3", platform: :jruby +gem "net-ftp" +gem "combustion" +gem "rails", "~> 6.0.0" +gem "sqlite3", "~> 1.4.0", platform: [:ruby, :mswin, :mingw] +gem "rspec", "3.13.0" +gem "rspec-core", "3.13.0" +gem "rspec-expectations", "3.13.0" +gem "rspec-mocks", "3.13.0" +gem "rspec-support", "3.13.0" +gem "rspec-rails" + +gemspec path: "../" diff --git a/gemfiles/rails_6_1_rspec_gte_3_13.gemfile b/gemfiles/rails_6_1_rspec_gte_3_13.gemfile new file mode 100644 index 00000000..e1059be7 --- /dev/null +++ b/gemfiles/rails_6_1_rspec_gte_3_13.gemfile @@ -0,0 +1,30 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "appraisal", git: "https://github.com/thoughtbot/appraisal" +gem "bundler-audit" +gem "childprocess" +gem "climate_control" +gem "prettier_print" +gem "pry-byebug", platform: :mri +gem "pry-nav", platform: :jruby +gem "rake" +gem "rubocop" +gem "syntax_tree" +gem "syntax_tree-haml" +gem "syntax_tree-rbs" +gem "activerecord-jdbcsqlite3-adapter", platform: :jruby +gem "jdbc-sqlite3", platform: :jruby +gem "net-ftp" +gem "combustion" +gem "rails", "~> 6.1.0" +gem "sqlite3", "~> 1.4.0", platform: [:ruby, :mswin, :mingw] +gem "rspec", "3.13.0" +gem "rspec-core", "3.13.0" +gem "rspec-expectations", "3.13.0" +gem "rspec-mocks", "3.13.0" +gem "rspec-support", "3.13.0" +gem "rspec-rails" + +gemspec path: "../" diff --git a/gemfiles/rails_7_0_rspec_gte_3_13.gemfile b/gemfiles/rails_7_0_rspec_gte_3_13.gemfile new file mode 100644 index 00000000..51c4fd39 --- /dev/null +++ b/gemfiles/rails_7_0_rspec_gte_3_13.gemfile @@ -0,0 +1,30 @@ +# This file was generated by Appraisal + +source "https://rubygems.org" + +gem "appraisal", git: "https://github.com/thoughtbot/appraisal" +gem "bundler-audit" +gem "childprocess" +gem "climate_control" +gem "prettier_print" +gem "pry-byebug", platform: :mri +gem "pry-nav", platform: :jruby +gem "rake" +gem "rubocop" +gem "syntax_tree" +gem "syntax_tree-haml" +gem "syntax_tree-rbs" +gem "activerecord-jdbcsqlite3-adapter", platform: :jruby +gem "jdbc-sqlite3", platform: :jruby +gem "net-ftp" +gem "combustion" +gem "rails", "~> 7.0.0" +gem "sqlite3", "~> 1.4.0", platform: [:ruby, :mswin, :mingw] +gem "rspec", "3.13.0" +gem "rspec-core", "3.13.0" +gem "rspec-expectations", "3.13.0" +gem "rspec-mocks", "3.13.0" +gem "rspec-support", "3.13.0" +gem "rspec-rails" + +gemspec path: "../" From 66dd7801ac74086830e728a51b41cb6284b8f671 Mon Sep 17 00:00:00 2001 From: Joe Stein Date: Wed, 8 May 2024 16:52:40 -0400 Subject: [PATCH 2/5] Restore AliasedMatcher behavior for 3.13.0+ --- lib/super_diff/rspec.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/super_diff/rspec.rb b/lib/super_diff/rspec.rb index dfb6bad6..36ff4646 100644 --- a/lib/super_diff/rspec.rb +++ b/lib/super_diff/rspec.rb @@ -81,7 +81,11 @@ def self.a_value_within_something?(value) end def self.aliased_matcher?(value) - value.is_a?(::RSpec::Matchers::AliasedMatcher) + if SuperDiff::RSpec.rspec_version < '3.13.0' + value.is_a?(::RSpec::Matchers::AliasedMatcher) + else # See Github issue #250. + value.respond_to?(:base_matcher) + end end def self.rspec_version From 1301d6ea3bc5bfd6b006963dc5f85a271f64b072 Mon Sep 17 00:00:00 2001 From: Joe Stein Date: Wed, 8 May 2024 16:59:33 -0400 Subject: [PATCH 3/5] Update monkey patches for 3.13.0 Specifically, ExpectedsForMultipleDiffs was renamed and refactored slightly. --- lib/super_diff/rspec/monkey_patches.rb | 185 +++++++++++++++++-------- 1 file changed, 129 insertions(+), 56 deletions(-) diff --git a/lib/super_diff/rspec/monkey_patches.rb b/lib/super_diff/rspec/monkey_patches.rb index b4bd6cfe..6e063ffe 100644 --- a/lib/super_diff/rspec/monkey_patches.rb +++ b/lib/super_diff/rspec/monkey_patches.rb @@ -309,73 +309,146 @@ def format(value) end module Matchers - class ExpectedsForMultipleDiffs - SuperDiff.insert_singleton_overrides(self) do - # Add a key for different sides - def from(expected) - return expected if self === expected - - text = colorizer.wrap("Diff:", SuperDiff.configuration.header_color) - - if SuperDiff.configuration.key_enabled? - text += - "\n\n" + - colorizer.wrap( - "┌ (Key) ──────────────────────────┐", - SuperDiff.configuration.border_color - ) + "\n" + - colorizer.wrap("│ ", SuperDiff.configuration.border_color) + - colorizer.wrap( - "‹-› in expected, not in actual", - SuperDiff.configuration.expected_color - ) + - colorizer.wrap(" │", SuperDiff.configuration.border_color) + - "\n" + - colorizer.wrap("│ ", SuperDiff.configuration.border_color) + - colorizer.wrap( - "‹+› in actual, not in expected", - SuperDiff.configuration.actual_color - ) + - colorizer.wrap(" │", SuperDiff.configuration.border_color) + - "\n" + - colorizer.wrap("│ ", SuperDiff.configuration.border_color) + - "‹ › in both expected and actual" + - colorizer.wrap(" │", SuperDiff.configuration.border_color) + - "\n" + - colorizer.wrap( - "└─────────────────────────────────┘", - SuperDiff.configuration.border_color - ) + if SuperDiff::RSpec.rspec_version < "3.13.0" + class ExpectedsForMultipleDiffs + SuperDiff.insert_singleton_overrides(self) do + # Add a key for different sides + def from(expected) + return expected if self === expected + + text = colorizer.wrap("Diff:", SuperDiff.configuration.header_color) + + if SuperDiff.configuration.key_enabled? + text += + "\n\n" + + colorizer.wrap( + "┌ (Key) ──────────────────────────┐", + SuperDiff.configuration.border_color + ) + "\n" + + colorizer.wrap("│ ", SuperDiff.configuration.border_color) + + colorizer.wrap( + "‹-› in expected, not in actual", + SuperDiff.configuration.expected_color + ) + + colorizer.wrap(" │", SuperDiff.configuration.border_color) + + "\n" + + colorizer.wrap("│ ", SuperDiff.configuration.border_color) + + colorizer.wrap( + "‹+› in actual, not in expected", + SuperDiff.configuration.actual_color + ) + + colorizer.wrap(" │", SuperDiff.configuration.border_color) + + "\n" + + colorizer.wrap("│ ", SuperDiff.configuration.border_color) + + "‹ › in both expected and actual" + + colorizer.wrap(" │", SuperDiff.configuration.border_color) + + "\n" + + colorizer.wrap( + "└─────────────────────────────────┘", + SuperDiff.configuration.border_color + ) + end + + new([[expected, text]]) end - new([[expected, text]]) + def colorizer + RSpec::Core::Formatters::ConsoleCodes + end end - def colorizer - RSpec::Core::Formatters::ConsoleCodes + SuperDiff.insert_overrides(self) do + # Add an extra line break + def message_with_diff(message, differ, actual) + diff = diffs(differ, actual) + + diff.empty? ? message : "#{message.rstrip}\n\n#{diff}" + end + + private + + # Add extra line breaks in between diffs, and colorize the word "Diff" + def diffs(differ, actual) + @expected_list + .map do |(expected, diff_label)| + diff = differ.diff(actual, expected) + next if diff.strip.empty? + diff_label + diff + end + .compact + .join("\n\n") + end end end + else + class MultiMatcherDiff + SuperDiff.insert_singleton_overrides(self) do + # Add a key for different sides + def from(expected, actual) + return expected if self === expected + + text = colorizer.wrap("Diff:", SuperDiff.configuration.header_color) + + if SuperDiff.configuration.key_enabled? + text += + "\n\n" + + colorizer.wrap( + "┌ (Key) ──────────────────────────┐", + SuperDiff.configuration.border_color + ) + "\n" + + colorizer.wrap("│ ", SuperDiff.configuration.border_color) + + colorizer.wrap( + "‹-› in expected, not in actual", + SuperDiff.configuration.expected_color + ) + + colorizer.wrap(" │", SuperDiff.configuration.border_color) + + "\n" + + colorizer.wrap("│ ", SuperDiff.configuration.border_color) + + colorizer.wrap( + "‹+› in actual, not in expected", + SuperDiff.configuration.actual_color + ) + + colorizer.wrap(" │", SuperDiff.configuration.border_color) + + "\n" + + colorizer.wrap("│ ", SuperDiff.configuration.border_color) + + "‹ › in both expected and actual" + + colorizer.wrap(" │", SuperDiff.configuration.border_color) + + "\n" + + colorizer.wrap( + "└─────────────────────────────────┘", + SuperDiff.configuration.border_color + ) + end - SuperDiff.insert_overrides(self) do - # Add an extra line break - def message_with_diff(message, differ, actual) - diff = diffs(differ, actual) + new([[expected, text, actual]]) + end - diff.empty? ? message : "#{message.rstrip}\n\n#{diff}" + def colorizer + RSpec::Core::Formatters::ConsoleCodes + end end - private + SuperDiff.insert_overrides(self) do + # Add an extra line break + def message_with_diff(message, differ) + diff = diffs(differ) + + diff.empty? ? message : "#{message.rstrip}\n\n#{diff}" + end - # Add extra line breaks in between diffs, and colorize the word "Diff" - def diffs(differ, actual) - @expected_list - .map do |(expected, diff_label)| - diff = differ.diff(actual, expected) - next if diff.strip.empty? - diff_label + diff - end - .compact - .join("\n\n") + private + + # Add extra line breaks in between diffs, and colorize the word "Diff" + def diffs(differ) + @expected_list + .map do |(expected, diff_label, actual)| + diff = differ.diff(actual, expected) + next if diff.strip.empty? + diff_label + diff + end + .compact + .join("\n\n") + end end end end From 2a2805d543c3118ca0d4f079380ff2fde78ca481 Mon Sep 17 00:00:00 2001 From: Joe Stein Date: Thu, 9 May 2024 08:18:02 -0400 Subject: [PATCH 4/5] Add RSpec 3.13+ to test matrix --- .github/workflows/super_diff.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/super_diff.yml b/.github/workflows/super_diff.yml index 672683ec..032b9eba 100644 --- a/.github/workflows/super_diff.yml +++ b/.github/workflows/super_diff.yml @@ -65,6 +65,7 @@ jobs: rspec_appraisal: - rspec_lt_3_10 - rspec_gte_3_10 + - rspec_gte_3_13 env: BUNDLE_GEMFILE: gemfiles/${{ matrix.rails_appraisal }}_${{ matrix.rspec_appraisal }}.gemfile steps: From 9ee96d53c447aa89d5b66ff635e9c856a8ecd47b Mon Sep 17 00:00:00 2001 From: Joe Stein Date: Thu, 9 May 2024 12:33:11 -0400 Subject: [PATCH 5/5] Specifically exclude ActiveSupport::OrderedOptions OrderedOptions strikes again! --- lib/super_diff/rspec.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/super_diff/rspec.rb b/lib/super_diff/rspec.rb index 36ff4646..9a89a91f 100644 --- a/lib/super_diff/rspec.rb +++ b/lib/super_diff/rspec.rb @@ -84,10 +84,15 @@ def self.aliased_matcher?(value) if SuperDiff::RSpec.rspec_version < '3.13.0' value.is_a?(::RSpec::Matchers::AliasedMatcher) else # See Github issue #250. - value.respond_to?(:base_matcher) + !ordered_options?(value) && value.respond_to?(:base_matcher) end end + def self.ordered_options?(value) + defined?(::ActiveSupport::OrderedOptions) && + value.is_a?(::ActiveSupport::OrderedOptions) + end + def self.rspec_version @rspec_version ||= begin