Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make have_received complain if passed a block #364

Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/rspec/mocks/example_methods.rb
Expand Up @@ -114,6 +114,7 @@ def hide_const(constant_name)
# # You can also use most message expectations:
# expect(invitation).to have_received(:accept).with(mailer).once
def have_received(method_name)
raise "have_received matcher does not take a block argument: #{caller[0]}" if block_given?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@timcowlishaw I think this might be easier to understand if it were changed to matcher does not take a block argument. Called from #{caller(0)}. WDYT?

Matchers::HaveReceived.new(method_name)
end

Expand Down
8 changes: 8 additions & 0 deletions spec/rspec/mocks/matchers/have_received_spec.rb
Expand Up @@ -60,6 +60,14 @@ module Mocks
}.to raise_error(/0 times/)
end

it "raises an exception when a block is used to match the arguments" do
dbl = double_with_met_expectation(:expected_method)
expect {
expect(dbl).to have_received(:expected_method) { |argument|
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@timcowlishaw this can be reduced to one line:

`expect(dbl).to have_received(:expected_method) {}

}
}.to raise_error(/have_received matcher does not take a block argument/)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that you are using caller[0] here to specify the location causing the error, it'd be nice if you included that in the error regexp, to assert that it's always the right line. You can use __FILE__ and __LINE__ to avoid hardcoding the file/line.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realised this is dumb, because it'll happen in the backtrace. Sorry @timcowlishaw.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might make more sense as a warning with caller(0). What do you think @JonRowe ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just think we need to spec which line these come from, as we've had a few instances where we've messed it up, or the ruby implementation has a different idea about caller.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you think about warning versus raising though? We get the backtrace for free with a raise but it stops execution. I think a warning is a better solution.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, agreed on both counts. Assuming you wouldn't rather a PR allowing has_received to take a block to match args (as proposed below), I'll add a spec and turn this into a warning!

Thanks,

Tim

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do this, we'll merge it (maybe into 2-14-maintenance if others agree too), and if you feel like making it take a block to match args as another PR that'd be awesome :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff. Will sort this out tomorrow!

end

context "with" do
it 'passes when the given args match the args used with the message' do
dbl = double_with_met_expectation(:expected_method, :expected, :args)
Expand Down