Skip to content

Commit

Permalink
Provide a helpful message if the diff between two objects is empty. F…
Browse files Browse the repository at this point in the history
…ixes rspec#123
  • Loading branch information
justinko committed Mar 23, 2012
1 parent 584e764 commit e12a2d9
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 83 deletions.
7 changes: 7 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
### dev
[full changelog](http://github.com/rspec/rspec-expectations/compare/v2.9.0...master)

Bug fixes

* Provide a helpful message if the diff between two objects is empty.

### 2.9.0 / 2012-03-17
[full changelog](http://github.com/rspec/rspec-expectations/compare/v2.8.0...v2.9.0)

Expand Down
21 changes: 13 additions & 8 deletions lib/rspec/expectations/differ.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@
module RSpec
module Expectations
class Differ
def initialize(ignore=nil)
end

# This is snagged from diff/lcs/ldiff.rb (which is a commandline tool)
def diff_as_string(data_new, data_old)
data_old = data_old.split(/\n/).map! { |e| e.chomp }
data_new = data_new.split(/\n/).map! { |e| e.chomp }
output = ""
diffs = Diff::LCS.diff(data_old, data_new)
output = ""
return output if diffs.empty?
oldhunk = hunk = nil
file_length_difference = 0
Expand Down Expand Up @@ -41,10 +38,18 @@ def diff_as_string(data_new, data_old)
output << oldhunk.diff(format) << "\n"
end

def diff_as_object(actual,expected)
actual = object_to_string(actual)
expected = object_to_string(expected)
diff_as_string(actual, expected)
def diff_as_object(actual, expected)
actual_as_string = object_to_string(actual)
expected_as_string = object_to_string(expected)
diff = diff_as_string(actual_as_string, expected_as_string)

if diff.empty?
"#{actual}.==(#{expected}) returned false even though the diff " \
"between #{actual} and #{expected} is empty. Check the " \
"implementation of #{actual}.==."
else
diff
end
end

protected
Expand Down
159 changes: 84 additions & 75 deletions spec/rspec/expectations/differ_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,15 @@
require 'ostruct'

module RSpec
module Fixtures
class Animal
def initialize(name,species)
@name,@species = name,species
end
module Expectations
describe Differ do
let(:differ) { RSpec::Expectations::Differ.new }

def inspect
<<-EOA
<Animal
name=#{@name},
species=#{@species}
>
EOA
end
end
end
end

describe "Diff" do
before(:each) do
@options = OpenStruct.new(:diff_format => :unified, :context_lines => 3)
@differ = RSpec::Expectations::Differ.new(@options)
end

it "outputs unified diff of two strings" do
expected="foo\nbar\nzap\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nline\n"
actual="foo\nzap\nbar\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nanother\nline\n"
expected_diff= <<'EOD'
describe '#diff_as_string' do
it "outputs unified diff of two strings" do
expected="foo\nbar\nzap\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nline\n"
actual="foo\nzap\nbar\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nanother\nline\n"
expected_diff= <<'EOD'
@@ -1,6 +1,6 @@
Expand All @@ -48,15 +29,58 @@ def inspect
line
EOD

diff = @differ.diff_as_string(expected, actual)
diff.should eql(expected_diff)
end
diff = differ.diff_as_string(expected, actual)
diff.should eql(expected_diff)
end
end

describe '#diff_as_object' do
it "outputs unified diff message of two objects" do
animal_class = Class.new do
def initialize(name, species)
@name, @species = name, species
end

it "outputs unified diff message of two arrays" do
expected = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'charlie', :width, 'quite wide' ]
actual = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'tango' , :width, 'very wide' ]
def inspect
<<-EOA
<Animal
name=#{@name},
species=#{@species}
>
EOA
end
end

expected_diff = <<EOD
expected = animal_class.new "bob", "giraffe"
actual = animal_class.new "bob", "tortoise"

expected_diff = <<'EOD'
@@ -1,5 +1,5 @@
<Animal
name=bob,
- species=tortoise
+ species=giraffe
>
EOD

diff = differ.diff_as_object(expected,actual)
diff.should == expected_diff
end

it "outputs a message if the diff is empty" do
diff = differ.diff_as_object('foo', 'foo')
diff.should eq(
"foo.==(foo) returned false even though the diff between " \
"foo and foo is empty. Check the implementation of foo.==."
)
end

it "outputs unified diff message of two arrays" do
expected = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'charlie', :width, 'quite wide' ]
actual = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'tango' , :width, 'very wide' ]

expected_diff = <<'EOD'
@@ -5,7 +5,7 @@
Expand All @@ -70,33 +94,15 @@ def inspect
+ "quite wide"]
EOD

diff = @differ.diff_as_object(expected,actual)
diff.should == expected_diff
end

it "outputs unified diff message of two objects" do
expected = RSpec::Fixtures::Animal.new "bob", "giraffe"
actual = RSpec::Fixtures::Animal.new "bob", "tortoise"

expected_diff = <<'EOD'
@@ -1,5 +1,5 @@
<Animal
name=bob,
- species=tortoise
+ species=giraffe
>
EOD

diff = @differ.diff_as_object(expected,actual)
diff.should == expected_diff
end
diff = differ.diff_as_object(expected,actual)
diff.should == expected_diff
end

it "outputs unified diff message of two hashes" do
expected = { :foo => 'bar', :baz => 'quux', :metasyntactic => 'variable', :delta => 'charlie', :width =>'quite wide' }
actual = { :foo => 'bar', :metasyntactic => 'variable', :delta => 'charlotte', :width =>'quite wide' }
it "outputs unified diff message of two hashes" do
expected = { :foo => 'bar', :baz => 'quux', :metasyntactic => 'variable', :delta => 'charlie', :width =>'quite wide' }
actual = { :foo => 'bar', :metasyntactic => 'variable', :delta => 'charlotte', :width =>'quite wide' }

expected_diff = <<'EOD'
expected_diff = <<'EOD'
@@ -1,4 +1,5 @@
-:delta => "charlotte",
Expand All @@ -107,38 +113,41 @@ def inspect
:width => "quite wide"
EOD

diff = @differ.diff_as_object(expected,actual)
diff.should == expected_diff
end
diff = differ.diff_as_object(expected,actual)
diff.should == expected_diff
end

it "outputs unified diff of single line strings" do
expected = "this is one string"
actual = "this is another string"
it "outputs unified diff of single line strings" do
expected = "this is one string"
actual = "this is another string"

expected_diff = <<EOD
expected_diff = <<'EOD'
@@ -1,2 +1,2 @@
-"this is another string"
+"this is one string"
EOD

diff = @differ.diff_as_object(expected,actual)
diff.should == expected_diff
end
diff = differ.diff_as_object(expected,actual)
diff.should == expected_diff
end

it "outputs unified diff of multi line strings" do
expected = "this is:\n one string"
actual = "this is:\n another string"
it "outputs unified diff of multi line strings" do
expected = "this is:\n one string"
actual = "this is:\n another string"

expected_diff = <<EOD
expected_diff = <<'EOD'
@@ -1,3 +1,3 @@
this is:
- another string
+ one string
EOD

diff = @differ.diff_as_object(expected,actual)
diff.should == expected_diff
diff = differ.diff_as_object(expected,actual)
diff.should == expected_diff
end
end
end
end
end

0 comments on commit e12a2d9

Please sign in to comment.