Skip to content
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

Added IgnoredMethods configuration to Style/CombinableLoops #8852

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -7,6 +7,9 @@
* [#8782](https://github.com/rubocop-hq/rubocop/issues/8782): Fix incorrect autocorrection for `Style/TernaryParentheses` with `defined?`. ([@dvandersluis][])
* [#8864](https://github.com/rubocop-hq/rubocop/issues/8864): Fix false positive for `Style/RedundantBegin` with a postfix `while` or `until`. ([@dvandersluis][])

### Changes
* [#8852](https://github.com/rubocop-hq/rubocop/pull/8852): Add `IgnoredMethods` configuration to `Style/CombinableLoops`. ([@dvandersluis][])

## 0.93.0 (2020-10-08)

### New features
Expand Down
2 changes: 2 additions & 0 deletions config/default.yml
Expand Up @@ -2797,7 +2797,9 @@ Style/CombinableLoops:
can be combined into a single loop.
Enabled: pending
Safe: false
IgnoredMethods: []
VersionAdded: '0.90'
VersionChanged: '0.94'

Style/CommandLiteral:
Description: 'Use `` or %x around command literals.'
Expand Down
28 changes: 27 additions & 1 deletion docs/modules/ROOT/pages/cops_style.adoc
Expand Up @@ -1429,7 +1429,7 @@ end
| No
| No
| 0.90
| -
| 0.94
|===

This cop checks for places where multiple consecutive loops over the same data
Expand Down Expand Up @@ -1488,6 +1488,32 @@ def method
end
----

==== IgnoredMethods: [validates_each]

[source,ruby]
----
# good
class Foo
validates_each :attr1, :attr2 do |record, attribute, value|
record.errors.add(attribute, :invalid) if invalid?(value)
end

validates_each :attr1, :attr2 do |record, attribute, value|
record.errors.add(attribute, :empty) if empty?(value)
end
end
----

=== Configurable attributes

|===
| Name | Default value | Configurable values

| IgnoredMethods
| `[]`
| Array
|===

== Style/CommandLiteral

|===
Expand Down
16 changes: 16 additions & 0 deletions lib/rubocop/cop/style/combinable_loops.rb
Expand Up @@ -55,7 +55,21 @@ module Style
# each_slice(3) { |slice| do_something(slice) }
# end
#
# @example IgnoredMethods: [validates_each]
#
# # good
# class Foo
# validates_each :attr1, :attr2 do |record, attribute, value|
# record.errors.add(attribute, :invalid) if invalid?(value)
# end
#
# validates_each :attr1, :attr2 do |record, attribute, value|
# record.errors.add(attribute, :empty) if empty?(value)
# end
# end
class CombinableLoops < Base
include IgnoredMethods

MSG = 'Combine this loop with the previous loop.'

def on_block(node)
Expand All @@ -76,6 +90,8 @@ def on_for(node)

def collection_looping_method?(node)
method_name = node.send_node.method_name
return false if ignored_method?(method_name)

method_name.match?(/^each/) || method_name.match?(/_each$/)
end

Expand Down
20 changes: 17 additions & 3 deletions spec/rubocop/cop/style/combinable_loops_spec.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Style::CombinableLoops do
subject(:cop) { described_class.new }

RSpec.describe RuboCop::Cop::Style::CombinableLoops, :config do
context 'when looping method' do
it 'registers an offense when looping over the same data as previous loop' do
expect_offense(<<~RUBY)
Expand Down Expand Up @@ -98,4 +96,20 @@
RUBY
end
end

context 'when IgnoredMethods is set' do
let(:cop_config) { { 'IgnoredMethods' => %w[validates_each] } }

it 'does not register an offense for ignored methods' do
expect_no_offenses(<<~RUBY)
validates_each :foo, :bar do |record, attribute, value|
record.errors.add(attribute, :invalid) if invalid?(value)
end

validates_each :foo, :bar do |record, attribute, value|
record.errors.add(attribute, :empty) if empty?(value)
end
RUBY
end
end
end