-
-
Notifications
You must be signed in to change notification settings - Fork 269
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 support for built-in exist matcher #717
Add support for built-in exist matcher #717
Conversation
Thank you for the PR @MKenyon. I saw your bug report #716, but I am not sure if this logic belongs in That said, the cop already contains logic for other built-in matchers (is_a?, instance_of?, include?, respond_to?)… Perhaps we should have separate cops for each built-in matcher? That would make it easier for our users to enable/disable them, but possibly lead to a lot of almost duplicated cops… |
The cop actually needs to know about other predicate matchers in order not to suggest turning them to |
@@ -174,7 +176,7 @@ def check_explicit(node) # rubocop:disable Metrics/MethodLength | |||
|
|||
def predicate_matcher_name?(name) | |||
name = name.to_s | |||
name.start_with?('be_', 'have_') && | |||
(name.start_with?('be_', 'have_') || name == 'exist') && |
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.
maybe just add exist
in the BUILD_IN_MATCHERS ?
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.
@Darhazer: Right. As I mentioned, I'm not fully happy with this line. Upon further investigation, you can see that the BUILT_IN_MATCHERS are only checked for be_ and have_ matchers.
179 name.start_with?('be_', 'have_') &&
180 !BUILT_IN_MATCHERS.include?(name) &&
181 !name.end_with?('?')
When I look at the specs, other built-in equivs such as include? and respond_to? only have specs for inflected. The only specs for when enforced style is explicit
are for be_ and have_ matchers.
I would propose dropping checks for exist? from the when enforced style is explicit
context. Alternatively (and likely in another PR), we could add explicit style support for all these built-ins.
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.
how about:
def predicate_matcher_name?(name)
name = name.to_s
return false if BUILT_IN_MATCHERS.include?(name)
name.start_with?('be_', 'have_') && !name.end_with?('?')
end
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.
Yep, that'll work.
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.
Oh, I've been mistaken. It will not work, as it have to return true
for exist. Seems that we'll need another array for the build-in matchers that should not be ignored.
I see you just removed it, so with explicit
it will not require replacing to exist
with .exist?).to be_truthy
. I'm fine with leaving this out of scope and just fix the inflect
style to use exist
and not be_exist
. We will have to rework the cop at some point in the future.
@bquorning WDYT?
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.
On second thought, to exist
can't be auto-corrected, as it could not know if the object responds to exist?
or exists?
, so it's even better now that exist
is accepted.
13d0dfd
to
87e80f9
Compare
87e80f9
to
3654359
Compare
I’m still a bit hesitant to add more complexity into this cop. I’m considering if we could split the cop in to a few cops instead – I’ll have to look into that at some point. But I think this change an acceptable patch to fix a real bug. 👍 |
I've inherited a codebase that is full of
expect(foo.exists?).to be_truthy
. The RSpec/PredicateMatcher already checks for most built-ins, but doesn't know about the built-inexist
matcher. As a result, it suggests I replace my code withexpect(foo).to be_exists
.I am not fully happy with the change I made in the explicit module. I'm happy to adjust that if y'all have a better idea.
[Fixes #716]
--
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).