splitwise / super_diff

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

Internal library details are included in the stacktrace #265

Open jacob-carlborg-apoex opened 3 weeks ago

jacob-carlborg-apoex commented 3 weeks ago

When running RSpec with the default output for the following code snippet:

# require "super_diff/rspec"

Product = Data.define(:name, :price)

RSpec.describe "subject" do
  it "does something" do
    p1 = Product.new(name: "foo", price: 3)

    expect(p1).to have_attributes(name: "foo", price: 4)
  end
end

I get the following output:

$ rspec few_attributes_spec.rb                                                                                                                                                                                                                                                            
F

Failures:

  1) subject does something
     Failure/Error: expect(p1).to have_attributes(name: "foo", price: 4)

       expected #<data Product name="foo", price=3> to have attributes {:name => "foo", :price => 4} but had attributes {:name => "foo", :price => 3}
       Diff:
       @@ -1,3 +1,3 @@
        :name => "foo",
       -:price => 4,
       +:price => 3,

     # ./few_attributes_spec.rb:9:in `block (2 levels) in <top (required)>'

Finished in 0.01683 seconds (files took 0.08103 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./few_attributes_spec.rb:6 # subject does something

The stacktrace contains just the spec file, which is correct:

# ./few_attributes_spec.rb:9:in `block (2 levels) in <top (required)>'

But when running the same code with SuperDiff enabled I get an extra line in the stacktrace which points to internal details in the library:

$ rspec few_attributes_spec.rb                                                                                                                                                                                                                                                             
F

Failures:

  1) subject does something
     Failure/Error: expect(p1).to have_attributes(name: "foo", price: 4)
       Expected #<data Product name: "foo", price: 3> to have attributes (name: "foo", price: 4).
     # /Users/jacobcarlborg/.rvm/gems/ruby-3.3.1/gems/super_diff-0.13.0/lib/super_diff/rspec/monkey_patches.rb:43:in `handle_failure'
     # ./few_attributes_spec.rb:9:in `block (2 levels) in <top (required)>'

Finished in 0.01356 seconds (files took 0.13665 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./few_attributes_spec.rb:6 # subject does something

It includes the additional line:

# /Users/jacobcarlborg/.rvm/gems/ruby-3.3.1/gems/super_diff-0.13.0/lib/super_diff/rspec/monkey_patches.rb:43:in `handle_failure'

It would be nice if those lines could be removed from the stacktrace.

Version information:

$ rspec --version                                                                                                                                                                                                                                                                         
RSpec 3.13
  - rspec-core 3.13.0
  - rspec-expectations 3.13.0
  - rspec-mocks 3.13.1
  - rspec-rails 6.1.2
  - rspec-support 3.13.1

$ bundle info super_diff                                                                                                                                                                                                                                                                   
  * super_diff (0.13.0)
jas14 commented 2 weeks ago

Hey @jacob-carlborg-apoex , thanks for the report!

Since 3.1.0, RSpec has included a filter_gems_from_backtrace config option. (That in turns calls RSpec::Core::BacktraceFormatter#filter_gems and so on.)

If we can figure out how to call RSpec.configuration.filter_gems_from_backtrace('super_diff') exactly once when super_diff/rspec is loaded, I think that will solve this issue.

jacob-carlborg-apoex commented 2 weeks ago

Can't we just call RSpec.configuration.filter_gems_from_backtrace('super_diff') from the super_diff/rspec file?

jas14 commented 2 weeks ago

I believe so. I left this issue open in the hopes of attracting a contributor (perhaps you? 🙂) to open a PR!