-
-
Notifications
You must be signed in to change notification settings - Fork 276
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
Add RSpec/StringAsInstanceDoubleConstant #1957
Conversation
63c936b
to
9f1a248
Compare
Getting
However, have run |
9f1a248
to
d3d3328
Compare
lib/rubocop/cop/rspec/no_stringified_instance_double_constant.rb
Outdated
Show resolved
Hide resolved
spec/rubocop/cop/rspec/no_stringified_instance_double_constant_spec.rb
Outdated
Show resolved
Hide resolved
Did you also “add docs/ to the commit”? When I run the rake task I see a diff in the docs folder. |
There are some wip rubocop cop naming guidelines, and they insist on naming cops so that they highlight the problem. This should be “StringifiedInstanceDoubleConstant” |
d3d3328
to
53de88b
Compare
Looks like my rake problems were mostly self-inflicted, I tried to add my own documentation while I was following the contribution guidelines. For ease of new development, I'd recommend updating all of our rake task feedback to say "bundle exec rake etc" so it's easier to copy and execute |
7c794c1
to
91101d8
Compare
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 am biased since it was extracted from our app, but in favor of this 👍🏻
Interestingly, instance_double
does support a string as the name, at least according to its rdoc. I am looking at some of the implementation (instance_double
and ObjectReference.for(doubled_class)
but I couldn't tell you what happens for classes vs strings.
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.
Two questions:
- Could / should we make the same rule for
class_double
too? - Shouldn’t we also detect and replace symbols? As I understand the source, calling
instance_double
with a symbol won’t even work.
I don't think we need to extend the cop to cover symbols because RSpec will raise like this:
I have updated the PR description to be clearer about that. |
I think enforcing this for |
@pirj What’s your take on this? |
spec/rubocop/cop/rspec/string_as_instance_double_constant_spec.rb
Outdated
Show resolved
Hide resolved
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.
No errors whatsoever during a run against real-world-rspec. 499 offences look legit at a glance.
Thank you!
A few minor tweaks, and good to go.
spec/rubocop/cop/rspec/string_as_instance_double_constant_spec.rb
Outdated
Show resolved
Hide resolved
04d0955
to
82e9d17
Compare
As an aside, while following the test coverage results, I noticed what appears to be a dead code method: https://github.com/search?q=repo%3Arubocop%2Frubocop-rspec%20top_level_group%3F&type=code All specs pass without it. The only other uncovered line is I'd be happy to raise another PR after this, if its useful. I don't know if you prefer to handle all maintenance PRs internally. |
Yeah, it seems its last use was removed in 6276370 / #977.
You’re more than welcome to open a PR to remove that method 👍🏼 |
Are we ready to merge here? |
The original issue #1957 mentions all of |
Even though for the rest of double methods we may want to enforce consistency, the reason for that would be … just consistency. While for instance_double that is to enforce verification. My only question is if the class_double is the same? For the rest I’d vote for a separate cop. |
Thanks @pirj --- so the problem with adding
Then I have an additional downstream problem where that rule doesn't exist in my codebase, so instead of merging this and then pulling the upstream, I need to go work through all I guess what I'm saying is it's much more preferable for me to decouple these things. In comparison to all of the above, it's relatively trivial for anyone to duplicate this new Cop and adapt it to work for I can't think of any performance reasons to combine them either, with restrict on send in place. A combined rule would need an OR matcher like |
Makes total sense to me. Thanks for the explanation. |
Yep, that makes sense. Thank you 👍🏼 |
9802d19
to
befbe23
Compare
Hi @corsonknowles, I think you rebased the branch yesterday, but it looks like you have got a few extra/unintended changes in. Would you mind taking a look before we merge? |
Addresses rubocop#1136 Adds a cop which can autocorrect from String declarations for instance_double to Class declarations. Symbol declarations are not affected.
befbe23
to
324552c
Compare
Thanks @bquorning, amended! |
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.
Thank you for the contribution, and for your patience with our nitpicking 😅
instance_double('User', name: 'John') | ||
|
||
# good | ||
instance_double(User, name: 'John') |
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.
👋 Hello! I was looking through the offences this cop turned up in the codebase I work on, and noticed they're identical to those produced by RSpec/VerifiedDoubleReference
(which we had disabled via TODO file). The docs would suggest they're doing largely the same thing — is there any meaningful difference that could be clarified in the docs?
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.
Hi!
Nice catch, we’ve missed this completely.
The new cop is essentially the old one, but with no option to select the style. And this is certainly the direction we choose to enforce.
Your input is valuable, why did you decide to turn the cop off?
In a nutshell, we’ve discovered that an instance_double with a string argument does not verify, and behaves identically to a regular double
. It makes sense to make the usage explicit, and to use a double
for abstract doubles, and instant_double
for specific ones, and verify them.
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.
why did you decide to turn the cop off
We didn't totally turn off VerifiedDoubleReference
, just ignored a number of existing offences via .rubocop_todo.yml
— it's a large, old codebase, but Rubocop was only added semi-recently. It's definitely a useful cop for the reasons you've outlined!
That being said, if this new cop is wholly redundant, then I'll likely turn it off 😅. Would it make sense to deprecate one or the other? For what it's worth, VerifiedDoubleReference
appears to support e.g. class_double
as well, which I see was a concern raised in this PR.
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.
Thanks for sharing.
Yes, it would make sense to deprecate one of the cops, and I’d remove the EnforcedStyle: string option from the old one if it is less intrusive.
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.
Ah, thank you for immediately reporting this Luc!
I'm happy to deprecate the new cop and focus on updating the original cop.
So the action items are
- deprecate
StringAsInstanceDoubleConstant
-- is there a way to make it an alias of the other cop? - remove String style from
VerifiedDoubleReference
as it is not consistently verifying. Is there a way to deprecate this or do we simply remove it?
I'll also take a look if there's anything in the new implementation worth porting over to [VerifiedDoubleReference](https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecverifieddoublereference
I can probably get started on this on Monday. If anyone wants to pitch in or get started earlier, you are by all means welcome to.
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 guess we could have it inherit from VerifiedDoubleReference
and add the deprecation message, if that makes sense?
StringAsInstanceDoubleConstant
in favor of VerifiedDoubleReference
for constants only
#1968
Begins Addressing: #1136
Adds a cop which can autocorrect from String declarations for
instance_double
to Class declarations. Passing a variable -- which could hold a String or a Class -- is not affected by this cop.Autocorrect is not marked as safe, because the correction will cause instantiation of the Class, which depending on test setup may or may not have been loaded yet. In addition, instantiating the Class before stubbing an
instance_double
means that RSpec will treat it as a verifying double. A string reference to a Class that is not loaded is treated as a normal non-verifying double.We have been running this as safe autocorrect internally for years, and have not met with any issues as we use Zeitwerk and eager load once before running specs. In pushing this upstream, I don't want to assume that all test suites will have autoloading in place.
Before submitting the PR make sure the following are checked:
master
(if not - rebase it).CHANGELOG.md
if the new code introduces user-observable changes.bundle exec rake
) passes (be sure to run this locally, since it may produce updated documentation that you will need to commit).If you have created a new cop:
config/default.yml
.Enabled: pending
inconfig/default.yml
.Enabled: true
in.rubocop.yml
.VersionAdded: "<<next>>"
indefault/config.yml
.If you have modified an existing cop's configuration options:
VersionChanged: "<<next>>"
inconfig/default.yml
.