splitwise / super_diff

A more helpful way to view differences between complex data structures in RSpec.
https://splitwise.github.io/super_diff/
MIT License
960 stars 50 forks source link

Output for data class expectations is worse than stock RSpec #252

Closed myronmarston closed 3 days ago

myronmarston commented 3 months ago

Given superdiff_worse_output.rb:

require "bundler/inline"

gemfile do
  source "https://rubygems.org"
  gem "rspec", "3.13.0"
  gem "super_diff", "0.12.1"
end

require "rspec/autorun"
require "super_diff/rspec" if ENV["SUPERDIFF"]

Point = Data.define(:x, :y)

RSpec.describe "Comparing data class instances" do
  it "fails as expected" do
    expect(Point.new(1, 2)).to eq(Point.new(1, 3))
  end
end

Here's the output I get without supediff:

$  ruby superdiff_worse_output.rb
F

Failures:

  1) Comparing data class instances fails as expected
     Failure/Error: expect(Point.new(1, 2)).to eq(Point.new(1, 3))

       expected: #<data Point x=1, y=3>
            got: #<data Point x=1, y=2>

       (compared using ==)

       Diff:
       @@ -1 +1 @@
       -#<data Point x=1, y=3>
       +#<data Point x=1, y=2>

     # superdiff_worse_output.rb:16:in `block (2 levels) in <main>'

Finished in 0.00721 seconds (files took 0.06477 seconds to load)
1 example, 1 failure

Failed examples:

rspec superdiff_worse_output.rb:15 # Comparing data class instances fails as expected

In contrast, when superdiff is loaded:

$ SUPERDIFF=1 ruby superdiff_worse_output.rb
F

Failures:

  1) Comparing data class instances fails as expected
     Failure/Error: expect(Point.new(1, 2)).to eq(Point.new(1, 3))

       Expected #<Point:0x0000000112bf3e08> to eq #<Point:0x0000000112bf3bd8>.
       Diff:

         #<Point:0x0000000112bf3e08 {
         }>
     # /Users/myron/.rvm/gems/ruby-3.2.3/gems/super_diff-0.12.1/lib/super_diff/rspec/monkey_patches.rb:43:in `handle_failure'
     # superdiff_worse_output.rb:16:in `block (2 levels) in <main>'

Finished in 0.00988 seconds (files took 0.06686 seconds to load)
1 example, 1 failure

Failed examples:

rspec superdiff_worse_output.rb:15 # Comparing data class instances fails as expected

The RSpec output without superdiff is better, IMO--I can easily tell that the y values differed! But with superdiff loaded I can't tell anymore.

jas14 commented 4 days ago

Thanks for the repro @myronmarston. Looks like we're falling back on the DefaultObject inspection + operation tree builders, which look for object instance variables instead of the Data object's #members. This should just be a matter of implementing inspection + operation tree builders that are aware of the Data class – I've started working on a PR.