Our engineering team prefer expect(object.good?).to be(true) over expect(object).to be_good so that it's easier to search for "good?" method name across the whole code base.
Therefore, we are using the following settings for RSpec/PredicateMatcher:
RSpec/PredicateMatcher:
Strict: true
EnforcedStyle: explicit
However, this cop also finds the rspec-rails have_http_status matcher should be changed:
Instead of:
expect(response).to have_http_status(:success)
The cop would suggest:
expect(response.has_http_status?(:success)).to be(true)
Which results in method not found of Response#has_http_status?.
Is this the expected behavior? If so, what settings should I use to allow have_http_status?
Our current workaround is to use a dirty hack to add have_http_status to built-in matchers list?:
# .rubocoprc.rb
RuboCop::Cop::RSpec::ExplicitHelper::BUILT_IN_MATCHERS =
RuboCop::Cop::RSpec::ExplicitHelper::BUILT_IN_MATCHERS.dup.push('have_http_status').freeze
# .rubocop.yml
require:
- ./rubocoprc.rb
@chitsaou I believe have_http_status clashes with predicate matchers, and technically auto-correction is correct.
I don't see a reason not to include have_http_status to BUILT_IN_MATCHERS by default.
However, it's a special case, different from the other built-in matchers. Ignoring this offence might not be the best choice, as it's still possible to correct the example:
- expect(response).to have_http_status(:success)
+ expect(response.status).to be(:success)
Which approach would you prefer?
We should double check for more common have_ matchers in rspec-rails or other common matching tools and make sure we haven't overlooked any others.
It might possibly make sense to add a user-customizable ignore list as well for custom matchers.
Also, I added a note to #721 that we should mark this cop as unsafe.
shoulda-matchers:
Also those:
have_secure_passwordcorresponds tohas_secure_password
have_and_belong_to_manytests yourhas_and_belongs_to_manyassociations.
have_db_columntests that the table that backs your model has a specific column.
have_db_indextests that the table that backs your model has an index on a specific column.
have_manytests yourhas_manyassociations.
have_onetests yourhas_oneassociations.
have_readonly_attributetests usage of theattr_readonlymacro.
rspec-rails:
have_http_statushave_renderedhave_enqueued_mail - block matcherI don't see any common pattern here, probably they should all be excluded.
Thanks for all of your replies. It's true that there might be other have_* matchers from libraries, such as these from webmock:
have_been_requested
have_not_been_made
have_requested(method, uri)
have_not_requested(method, uri)
Wouldn't it be great if we can configure ignore list for this cop?
@chitsaou #838 has just been released in 1.37.0 allowing you to configure RSpec/PredicateMatcher to ignore specific matchers:
RSpec/PredicateMatcher:
AllowedExplicitMatchers:
- have_http_status
- have_been_made
Do you think this is sufficient?
On a side note, it would be incredible to add such configuration to corresponding projects (e.g. webmock and shoulda-matchers), however, I'm afraid it will override each other.
@Darhazer do you think it's a reasonable approach to avoid pulling the list of such third-party matchers into default rubocop-rspec configuration? Is it possible with the current RuboCop's configuration system?
I don't think it's currently possible.
It would be nice to provide such an API for 3rd party extensions to adjust rubocop config, although it could become rather complicated.
For the time being, we will need to pull the list of matchers from popular gems.
@pirj This new option of RSpec/PredicateMatcher cop allows us to adjust the whitelist. Really appreciate your help and the works from @mkrawc. You're awesome 馃帀
I agree that managing a list might be hard, but at least we have a start :)
Thank you all again!
reasonable approach to avoid pulling the list of such third-party matchers into default rubocop-rspec configuration
Stumbled across inherit_mode:
However, advanced users can still merge arrays using the
inherit_modesetting.
If you guys are interested, we may add something like:
inherit_mode:
merge:
- RSpec/PredicateMatcher/AllowedExplicitMatchers
add your settings to a third-party gem and see if it's being pulled.
Would you like to hack on it @chitsaou ?
Most helpful comment
@pirj This new option of
RSpec/PredicateMatchercop allows us to adjust the whitelist. Really appreciate your help and the works from @mkrawc. You're awesome 馃帀I agree that managing a list might be hard, but at least we have a start :)
Thank you all again!