Skip to content

Commit

Permalink
Fix a false positive for RSpec/PredicateMatcher when include with…
Browse files Browse the repository at this point in the history
… multiple arguments

This PR is fix a false positive for `RSpec/PredicateMatcher` when `include` with multiple argument

following code:
```ruby
expect(foo).to include(foo, bar)
```

`RSpec/PredicateMatcher` autocorrects it as follows:
```ruby
expect(foo.include?(foo, bar)).to be(true)
```

However, this is a SyntaxError.
```
ArgumentError:
       wrong number of arguments (given 2, expected 1)
```
  • Loading branch information
ydah committed Jan 14, 2023
1 parent 41be00e commit 76b76f3
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Fix a false positive for `RSpec/NoExpectationExample` when using skipped in metadata is multiline string. ([@ydah])
- Fix a false positive for `RSpec/ContextMethod` when multi-line context with `#` at the beginning. ([@ydah])
- Extract Capybara cops to a separate repository. ([@pirj])
- Fix a false positive for `RSpec/PredicateMatcher` when `include` with multiple argument. ([@ydah])

## 2.17.0 (2023-01-13)

Expand Down
13 changes: 12 additions & 1 deletion lib/rubocop/cop/rspec/predicate_matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def true?(to_symbol, matcher)
end

# A helper for `explicit` style
module ExplicitHelper
module ExplicitHelper # rubocop:disable Metrics/ModuleLength
include RuboCop::RSpec::Language
extend NodePattern::Macros

Expand Down Expand Up @@ -149,12 +149,23 @@ def check_explicit(node) # rubocop:disable Metrics/MethodLength
return if part_of_ignored_node?(node)

predicate_matcher?(node) do |actual, matcher|
next unless replaceable_matcher?(matcher)

add_offense(node, message: message_explicit(matcher)) do |corrector|
corrector_explicit(corrector, node, actual, matcher, matcher)
end
end
end

def replaceable_matcher?(matcher)
case matcher.method_name.to_s
when 'include'
matcher.arguments.count <= 1
else
true
end
end

# @!method predicate_matcher?(node)
def_node_matcher :predicate_matcher?, <<-PATTERN
(send
Expand Down
7 changes: 7 additions & 0 deletions spec/rubocop/cop/rspec/predicate_matcher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,13 @@
RUBY
end

it 'does not register an offense for a `include` ' \
'with multiple arguments.' do
expect_no_offenses(<<~RUBY)
expect(foo).to include(foo, bar)
RUBY
end

it 'registers an offense for a predicate method with a block' do
expect_offense(<<~RUBY)
expect(foo).to be_all { |x| x.present? }
Expand Down

0 comments on commit 76b76f3

Please sign in to comment.