rspec-expectations: Unexpected target/handler behavior with respect to blocks

I would expect the following two assertions to behave similarly, at least to the point that they would both pass, but they don’t.

expect("foo").to eq("foo")
expect { "foo" }.to eq("foo")

In the same vein, I would expect these two assertions to behave differently but they are identical.

expect { "foo" }.to eq("foo")
expect(proc { "foo" }).to eq("foo")

It seems that the handoff between the target and the handler could be improved by somehow providing context/insight into whether the incoming “actual” value is something dynamic to be evaluated (a given block) or a static value (even a proc) given as an argument.

I’m hoping it’s worth a conversation. Thank you!

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Comments: 21 (14 by maintainers)

Most upvoted comments

How does one get the rspec matcher to implement supports_block_expectations??

Just define it as a method inside your matcher definition, e.g.

class MyMatcher
  def supports_block_expectations?
    true
  end

  # ...
end

If you are using the matcher definition DSL, you can just call supports_block_expectations:

RSpec::Matchers.define :my_matcher do
  supports_block_expectations

  # ..
end

We’ve actually just addressed this in #530 (based on discussion in #526). expect { "foo" }.to eq("foo") now fails with:

You must pass an argument rather than a block to use the provided matcher (eq "foo"),
or the matcher must implement `supports_block_expectations?`.

Thanks 😃