Skip to content
This repository has been archived by the owner on Nov 30, 2024. It is now read-only.

Fix differ support #1199

Merged
merged 4 commits into from
Jun 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ matrix:
include:
- rvm: jruby-1.7
env: JRUBY_OPTS='--dev --1.8'
- rvm: 2.7.1
env: DIFF_LCS_VERSION="~> 1.3.0"
allow_failures:
- rvm: jruby-head
- rvm: ruby-head
Expand Down
6 changes: 6 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ else
gem 'rake', '> 12.3.2'
end

if ENV['DIFF_LCS_VERSION']
gem 'diff-lcs', ENV['DIFF_LCS_VERSION']
else
gem 'diff-lcs', '~> 1.4', '>= 1.4.3'
end

gem 'coderay' # for syntax highlighting
gem 'yard', '~> 0.9.24', :require => false

Expand Down
71 changes: 70 additions & 1 deletion features/custom_matchers/define_diffable_matcher.feature
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,33 @@ Feature: define diffable matcher

When a matcher is defined as diffable, the output will include a diff of the submitted objects when the objects are more than simple primitives.

Scenario: define a diffable matcher
@skip-when-diff-lcs-1.3
Scenario: define a diffable matcher (with diff-lcs 1.4)
Given a file named "diffable_matcher_spec.rb" with:
"""ruby
RSpec::Matchers.define :be_just_like do |expected|
match do |actual|
actual == expected
end

diffable
end

RSpec.describe "two\nlines" do
it { is_expected.to be_just_like("three\nlines") }
end
"""
When I run `rspec ./diffable_matcher_spec.rb`
Then it should fail with:
"""
Diff:
@@ -1 +1 @@
-three
+two
"""

@skip-when-diff-lcs-1.4
Scenario: define a diffable matcher (with diff-lcs 1.3)
Given a file named "diffable_matcher_spec.rb" with:
"""ruby
RSpec::Matchers.define :be_just_like do |expected|
Expand All @@ -27,10 +53,53 @@ Feature: define diffable matcher
lines
"""

@skip-when-diff-lcs-1.3
Scenario: Redefine actual

Sometimes is neccessary to overwrite actual to make diffing work, e.g. if `actual` is a name of a file you want to read from. For this to work you need to overwrite `@actual` in your matcher.

Given a file named "redefine_actual_matcher_spec.rb" with:
"""ruby
RSpec::Matchers.define :have_content do |expected|
match do |actual|
@actual = File.read(actual).chomp

values_match? expected, @actual
end

diffable
end

RSpec.describe 'Compare files' do
context 'when content is equal' do
it { expect('data.txt').to have_content 'Data' }
end

context 'when files are different' do
it { expect('data.txt').to have_content "No\nData\nhere" }
end
end
"""
And a file named "data.txt" with:
"""
Data
"""
When I run `rspec ./redefine_actual_matcher_spec.rb --format documentation`
Then the exit status should not be 0
And the output should contain:
"""
2 examples, 1 failure
"""
And the output should contain:
"""
@@ -1,4 +1,6 @@
-No
Data
-here
"""

@skip-when-diff-lcs-1.4
Scenario: Redefine actual (with diff-lcs 1.3)
Given a file named "redefine_actual_matcher_spec.rb" with:
"""ruby
RSpec::Matchers.define :have_content do |expected|
Expand Down
30 changes: 29 additions & 1 deletion features/diffing.feature
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,35 @@ Feature: diffing
string
"""

Scenario: diff for a multiline string and a regexp
@skip-when-diff-lcs-1.3
Scenario: diff for a multiline string and a regexp on diff-lcs 1.4
Given a file named "example_spec.rb" with:
"""ruby
RSpec.describe "a multiline string" do
it "is like another string" do
expected = /expected/m
actual = <<-ACTUAL
this is the
actual
string
ACTUAL
expect(actual).to match expected
end
end
"""
When I run `rspec example_spec.rb`
Then the output should contain:
"""
Diff:
@@ -1,3 +1,5 @@
-/expected/m
+this is the
+ actual
+ string
"""

@skip-when-diff-lcs-1.4
Scenario: diff for a multiline string and a regexp on diff-lcs 1.3
Given a file named "example_spec.rb" with:
"""ruby
RSpec.describe "a multiline string" do
Expand Down
15 changes: 15 additions & 0 deletions features/support/diff_lcs_versions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Around "@skip-when-diff-lcs-1.4" do |scenario, block|
if Diff::LCS::VERSION.to_f >= 1.4
warn "Skipping scenario #{scenario.title} on #{Diff::LCS::VERSION.to_f}"
else
block.call
end
end

Around "@skip-when-diff-lcs-1.3" do |scenario, block|
if Diff::LCS::VERSION.to_f < 1.4
warn "Skipping scenario #{scenario.title} on #{Diff::LCS::VERSION.to_f}"
else
block.call
end
end
8 changes: 6 additions & 2 deletions spec/rspec/expectations/fail_with_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
end

RSpec.describe RSpec::Expectations, "#fail_with with matchers" do
include RSpec::Support::Spec::DiffHelpers

before do
allow(RSpec::Matchers.configuration).to receive_messages(:color? => false)
end
Expand All @@ -42,7 +44,7 @@

expected_diff = dedent(<<-EOS)
|
|@@ -1,2 +1,2 @@
|@@ #{one_line_header} @@
|-["poo", "car"]
|+[(a string matching /foo/), (a string matching /bar/)]
|
Expand All @@ -55,14 +57,16 @@
end

RSpec.describe RSpec::Expectations, "#fail_with with --color" do
include RSpec::Support::Spec::DiffHelpers

before do
allow(RSpec::Matchers.configuration).to receive_messages(:color? => true)
end

it "tells the differ to use color" do
expected = "foo bar baz\n"
actual = "foo bang baz\n"
expected_diff = "\e[0m\n\e[0m\e[34m@@ -1,2 +1,2 @@\n\e[0m\e[31m-foo bang baz\n\e[0m\e[32m+foo bar baz\n\e[0m"
expected_diff = "\e[0m\n\e[0m\e[34m@@ #{one_line_header} @@\n\e[0m\e[31m-foo bang baz\n\e[0m\e[32m+foo bar baz\n\e[0m"

expect {
RSpec::Expectations.fail_with "message", actual, expected
Expand Down
13 changes: 4 additions & 9 deletions spec/rspec/matchers/built_in/have_attributes_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
RSpec.describe "#have_attributes matcher" do
include RSpec::Support::Spec::DiffHelpers

Person = Struct.new(:name, :age)

Expand Down Expand Up @@ -36,7 +37,6 @@ def respond_to?(method_name)
end

describe "expect(...).to have_attributes(with_one_attribute)" do

it_behaves_like "an RSpec matcher", :valid_value => Person.new("Correct name", 33), :invalid_value => Person.new("Wrong Name", 11) do
let(:matcher) { have_attributes(:name => "Correct name") }
end
Expand Down Expand Up @@ -71,7 +71,7 @@ def count
allow(RSpec::Matchers.configuration).to receive_messages(:color? => false)

expected_diff = dedent(<<-EOS)
|@@ -1,2 +1,2 @@
|@@ #{one_line_header} @@
|-:name => "Wrong Name",
|+:name => "Correct name",
EOS
Expand Down Expand Up @@ -100,7 +100,6 @@ def count
end

describe "expect(...).to have_attributes(key => matcher)" do

it "passes when the matchers match" do
expect(person).to have_attributes(:age => (a_value > 30))
end
Expand All @@ -119,7 +118,6 @@ def count
end

describe "expect(...).to_not have_attributes(with_one_attribute)" do

it "passes if target does not have any of the expected attributes" do
expect(person).to_not have_attributes(:age => wrong_age)
end
Expand Down Expand Up @@ -150,7 +148,6 @@ def count
end

describe "expect(...).to have_attributes(with_multiple_attributes)" do

it_behaves_like "an RSpec matcher", :valid_value => Person.new("Correct name", 33), :invalid_value => Person.new("Wrong Name", 11) do
let(:matcher) { have_attributes(:name => "Correct name", :age => 33) }
end
Expand All @@ -169,11 +166,11 @@ def count
allow(RSpec::Matchers.configuration).to receive_messages(:color? => false)

expected_diff = dedent(<<-EOS)
|@@ -1,3 +1,3 @@
|@@ #{one_line_header(3)} @@
|-:age => 11,
|+:age => 33,
| :name => "Correct name",
EOS
expected_diff << "\n :name => \"Correct name\",\n" if Diff::LCS::VERSION.to_f < 1.4

expect {
expect(person).to have_attributes(:name => correct_name, :age => wrong_age)
Expand All @@ -194,7 +191,6 @@ def count
end

describe "expect(...).to_not have_attributes(with_multiple_attributes)" do

it "passes if target has none of the expected attributes" do
expect(person).to_not have_attributes(:name => wrong_name, :age => wrong_age)
end
Expand Down Expand Up @@ -229,5 +225,4 @@ def count
def object_inspect(object)
surface_descriptions_in object.inspect
end

end
11 changes: 7 additions & 4 deletions spec/rspec/matchers/built_in/include_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ def to_hash
end

RSpec.describe "#include matcher" do
include RSpec::Support::Spec::DiffHelpers

it "is diffable" do
expect(include("a")).to be_diffable
end
Expand Down Expand Up @@ -87,13 +89,14 @@ def hash.send; :sent; end
|+"foo" => 1,
END
else
dedent(<<-END)
diff = dedent(<<-END)
|Diff:
|@@ -1,3 +1,3 @@
|@@ #{one_line_header(3)} @@
|-:bar => 3,
|+:bar => 2,
| :foo => 1,
END
diff << "\n :foo => 1,\n" if Diff::LCS::VERSION.to_f < 1.4
diff
end

expect {
Expand Down Expand Up @@ -297,7 +300,7 @@ class PseudoHash < SimpleDelegator
)
}.to fail_including(dedent(<<-END))
|Diff:
|@@ -1,2 +1,2 @@
|@@ #{one_line_header} @@
|-[{:number=>1}, {:number=>0}, {:number=>3}]
|+[{:number=>1}, {:number=>2}, {:number=>3}]
END
Expand Down
4 changes: 3 additions & 1 deletion spec/rspec/matchers/built_in/match_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
RSpec.describe "expect(...).to match(expected)" do
include RSpec::Support::Spec::DiffHelpers

it_behaves_like "an RSpec matcher", :valid_value => 'ab', :invalid_value => 'bc' do
let(:matcher) { match(/a/) }
end
Expand Down Expand Up @@ -68,7 +70,7 @@

failure_message_that_includes_diff = %r|
\s*Diff:
\s*@@ -1,2 \+1,2 @@
\s*@@ #{Regexp.escape one_line_header} @@
\s*-/bar/
\s*\+"foo"|

Expand Down
8 changes: 7 additions & 1 deletion spec/rspec/matchers/dsl_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,13 @@ def foo
diff = e.message.sub(/\A.*Diff:/m, "Diff:").gsub(/^\s*/, '')
end

expect(diff).to eq "Diff:\n@@ -1,3 +1,3 @@\n-line1\n+LINE1\nline2\n"
if Diff::LCS::VERSION.to_f < 1.4
expected_diff = "Diff:\n@@ -1,3 +1,3 @@\n-line1\n+LINE1\nline2\n"
else
expected_diff = "Diff:\n@@ -1 +1 @@\n-line1\n+LINE1\n"
end

expect(diff).to eq expected_diff
end

it 'does not confuse the diffability of different matchers' do
Expand Down