Skip to content

Commit

Permalink
Implement RSpec 3.13.0+ compatibility (#258)
Browse files Browse the repository at this point in the history
A private RSpec API (specifically `::RSpec::Matchers::{ExpectedsForMultipleDiffs -> MultiMatcherDiff}`) changed in 3.13.0; see rspec/rspec-expectations@81d3a58.
  • Loading branch information
jas14 authored Nov 18, 2024
1 parent 63f70ca commit 8c73488
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 58 deletions.
1 change: 1 addition & 0 deletions .github/workflows/super_diff.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
15 changes: 14 additions & 1 deletion Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -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|
Expand Down
23 changes: 23 additions & 0 deletions gemfiles/no_rails_rspec_gte_3_13.gemfile
Original file line number Diff line number Diff line change
@@ -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: "../"
30 changes: 30 additions & 0 deletions gemfiles/rails_6_0_rspec_gte_3_13.gemfile
Original file line number Diff line number Diff line change
@@ -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: "../"
30 changes: 30 additions & 0 deletions gemfiles/rails_6_1_rspec_gte_3_13.gemfile
Original file line number Diff line number Diff line change
@@ -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: "../"
30 changes: 30 additions & 0 deletions gemfiles/rails_7_0_rspec_gte_3_13.gemfile
Original file line number Diff line number Diff line change
@@ -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: "../"
11 changes: 10 additions & 1 deletion lib/super_diff/rspec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,16 @@ 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.
!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
Expand Down
185 changes: 129 additions & 56 deletions lib/super_diff/rspec/monkey_patches.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 8c73488

Please sign in to comment.