rspec / rspec-expectations

Provides a readable API to express expected outcomes of a code example
https://rspec.info
MIT License
1.26k stars 395 forks source link

have_attributes matcher does not show diff of mismatched attributes #995

Open segiddins opened 7 years ago

segiddins commented 7 years ago

Running the following file, I get the following output for the two different expectations

HasString = Struct.new(:string)

RSpec.describe "foo" do
  it "bar" do
    hs = HasString.new("abc\ndef\nghij\n\n493207428")

    # expect(hs.string).to eq "def"
=begin
Failures:

  1) foo bar
     Failure/Error: expect(hs.string).to eq "def"

       expected: "def"
            got: "abc\ndef\nghij\n\n493207428"

       (compared using ==)

       Diff:

       @@ -1,2 +1,6 @@
       +abc
        def
       +ghij
       +
       +493207428

     # ./spec/foo_spec.rb:6:in `block (2 levels) in <top (required)>'
=end
    expect(hs).to have_attributes(string: "def")
=begin
Failures:

  1) foo bar
     Failure/Error: expect(hs).to have_attributes(string: "def")

       expected #<struct HasString string="abc\ndef\nghij\n\n493207428"> to have attributes {:string => "def"} but had attributes {:string => "abc\ndef\nghij\n\n493207428"}
       Diff:
       @@ -1,2 +1,2 @@
       -:string => "def",
       +:string => "abc\ndef\nghij\n\n493207428",

     # ./spec/foo_spec.rb:30:in `block (2 levels) in <top (required)>'
=end
  end
end

I want a way to get the diff from the eq matcher, but still printing the to_s/inspect from the object in question, as has_attributes does.

My guess is that it's showing the hash diff, but if it showed something like:

:string =>
          +abc
           def
          +ghji
          +493207428

I think that'd be much more helpful, as diffs make failing tests much more informative

phylor commented 1 year ago

For people coming from search engines, https://github.com/mcmire/super_diff improves a lot on the output of have_attributes and other matchers.