-
-
Notifications
You must be signed in to change notification settings - Fork 277
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
Improve RSpec/SubjectStub cop #770
Conversation
I’m not sure I understand the case for removing the Or is the code removed unnecessarily complex? I just need a bit more clarification on why we should remove this feature. |
I'm sorry, but I disagree that if RSpec allows something, it's a valid (correct) use case. As an experiment, I've run a modified version of this cop that only detects PS Analysis of the latest
I don't have a strong opinion if this special What do you think? |
Tried simplifying that spec on RuboCop side, and it turns out another cop,
However, in
I'll try my chances with changing the enforced style for Would you accept this pull request with the removal of |
This line: expect(formatter_set).to all(have_received(:started).with(files)) previously was expect(formatter_set).to all(receive(:started).with(files)) but was triggering a RSpec/SubjectStub offence, and there was a special case treatment introduced to `rubocop-rspec` to relax detection of stubbing when `all` matcher is used together with a message expectation matcher. The cop is not at the moment able to detect `have_received` matcher, but there is an open pull request to improve the detection. That pull request (rubocop/rubocop-rspec#770) is also aiming to remove that special case treatment, because, as experiment has shown, across [`real-world-ruby-apps`](https://github.com/jeromedalbert/real-world-ruby-apps) and [`real-world-rails`](https://github.com/eliotsykes/real-world-rails), there is no other offences detected apart from this `FormatterSet` spec. In any case, the rest of the spec don't use `all`, and are explicit of which object the expectation is made against (by using `[0]`, `[1]`). Also, using spies is not justified in this case. It doesn't make much sense to use a `before` hook that is only run along with a single example.
One last known use case for I'll be more than happy to bring Is there anything else left to be addressed in this pull request? |
Previously, the following code would still be detected as an offence: allow(subject) even though there are no message expectations. Also, `is_expected` was not supported, e.g.: is_expected.to receive(:bar) was not flagged.
Addresses concerns expressed in #705
This special case treatment was added to address one use case, of an object that acts as a container for and a delegator of method calls to containing items by inheriting from an `Array`. The original code that suffered from a false detection was: expect(formatter_set).to all(receive(:started).with(files)) formatter_set.started(files) However, it has been [reworked to](https://github.com/rubocop-hq/rubocop/blob/a0aaa233c20e18784d841212e1caa724bcc919f7/spec/rubocop/formatter/formatter_set_spec.rb#18): expect(formatter_set[0]).to receive(:started).with(files) expect(formatter_set[1]).to receive(:started).with(files) formatter_set.started(files) and all known cases for this specific offence case are gone.
One specific example of the code is https://github.com/rubocop-hq/rubocop/blob/70ae6ca7978770ea699a2809f57ca2a6bdeec6be/spec/rubocop/formatter/formatter_set_spec.rb#L17 formatter_set.each do |formatter| allow(formatter).to receive(:started) end formatter_set.started(files) expect(formatter_set).to all(have_received(:started).with(files)) that could be more concisely be expressed as: formatter_set.each do |formatter| expect(formatter).to receive(:started).with(files) end formatter_set.started(files)
Is there anything else how I can improve this? |
@bquorning @Darhazer I've sent a pull request that would quickly restore the In case of emergency, it can be immediately merged. Do you have some other doubts regarding the changes made in this pull request? |
@bquorning @Darhazer Is there anything else that needs to be addressed in this pull request? |
Hi @pirj, apologies for the slow response rate around here. Your PR is in my review queue, but I just haven’t had time to get a good look at it yet. |
No worries, please take your time. |
@bquorning I was considering this, but haven't found any other cop that would benefit from it immediately. Probably there are some missed cases due to this in the other cops, but I can't tell that off the top of my head. |
Please don't merge this just now, @Darhazer has found a case this cop is missing, flagging of an unnamed subject ( |
Fixed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I expect the failing circleci job (codeclimate) to pass on master.
Thank you for the contributions, persistence, and patience 😄 |
Thanks for accepting @bquorning, @Darhazer! |
1. Use consistent wording in docstrings
2. Improve stub detection
Previously, the following code would still be detected as an offence:
even though there are no message expectations.
3. Add detection of negated runners (
not_to
,to_not
) - fixes #7054. Add support for chain and multiple stub detection (
receive_messages
,receive_message_chain
)5. Add more reasoning references
6. Improve offence message
7. Remove special case
all
matcher (see #488)This special case treatment was added to address one use case, of an object that acts as a container for and a delegator of method calls to containing items by inheriting from an
Array
.The original code that suffered from a false detection was:
However, it has been reworked to:
and can be further simplified to:
which in case of this specific object design is more indicative of what happens.
8. Added support for
have_received
detection, to detect the bad code above.9. Fixed detection of the unnamed subject stubbing when the subject is named.
Fixes #705
Before submitting the PR make sure the following are checked:
master
(if not - rebase it).bundle exec rake
) passes (be sure to run this locally, since it may produce updated documentation that you will need to commit).