splitwise / super_diff

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

Exception when using custom rspec matcher #140

Open jk779 opened 2 years ago

jk779 commented 2 years ago

Hi! This is a great gem! 🎊

I'm experiencing a problem tho. When using a custom rspec matcher like this:

RSpec::Matchers.define :include_or_eq do |expected|
  match do |actual|
    if actual.is_a?(Hash)
      return actual[:any].include? expected if actual.key? :any
      return actual[:all].sort == expected.sort if actual.key? :all

      raise 'Neither :all nor :any key defined :('
    else
      actual == expected
    end
  end
end

and expecting with it like this:

allow(Client).to receive(:check).with(
  anything,
  include_or_eq(subject),
  action,
  { return_user: return_user }
).and_return ret_value

i'll get the following error when the matcher doesn't match:

ArgumentError:
       wrong number of arguments (0 for 1) for SuperDiff::ObjectInspection::InspectionTreeBuilders::Main initializer
     Shared Example Group: "update endpoints" called from ./spec/shared_examples/a_custom_endpoint.rb:8
     Shared Example Group: "a custom endpoint" called from ./spec/grape/api/v1/admin/badwords_spec.rb:31
     # /Users/michael/.asdf/installs/ruby/2.7.0/lib/ruby/gems/2.7.0/gems/attr_extras-6.2.4/lib/attr_extras/attr_initialize.rb:53:in `validate_arity'

(full stacktrace here)

When using the same code with a non-custom matcher, e.g.:

allow(Client).to receive(:check).with(
  anything,
  a_string_including(subject),
  action,
  { return_user: return_user }
).and_return ret_value

everything works great and an expected super_diff is displayed.

Am I missing something here?

mcmire commented 2 years ago

This looks like a bug to me! Is it possible for you to obtain a larger backtrace by chance? I can see an indicator to what the issue might be but not where it's originating from inside the gem.

jk779 commented 2 years ago

Hi @mcmire, thanks fot your reply and sorry for the long silence from my part :( I'm currently running into this issue again in the same project.

In another project where i'm using your gem and the gem the custom matcher is coming from as well, the issue does not occur. So i suspect there is something really strange going on in my application that is causing this (maybe another gem thats interfering?)

I'd love to share more backtraces, i've already dug deep into it with ruby-debug-ide, but it's not that easy to understand whats going on when SuperDiff.inspect_object is recusively called and interacting with attr_extras leading into this exception eventually. Can you point me which kind of trace/debug info you'd need? (I've already attached a "full" backtrace in the original post, which i guess you have seen?)

Since it's not a public project this issue arises in I'm sadly not able to share the whole source code here :(

Because it's probably a project/app specific problem, I strongly think the problem is on my part, but i would greatly appreciate your help anyways if you've a minute to spare :)! Otherwise I think this issue can be closed. 🙈

Thanks!