diff --git a/changelog/fix_make_style_each_for_simple_loop_allows_block_with_no_params.md b/changelog/fix_make_style_each_for_simple_loop_allows_block_with_no_params.md new file mode 100644 index 00000000000..2de019e1b97 --- /dev/null +++ b/changelog/fix_make_style_each_for_simple_loop_allows_block_with_no_params.md @@ -0,0 +1 @@ +* [#12601](https://github.com/rubocop/rubocop/issues/12601): Make `Style/EachForSimpleLoop` accept block with no parameters. ([@koic][]) diff --git a/lib/rubocop/cop/style/each_for_simple_loop.rb b/lib/rubocop/cop/style/each_for_simple_loop.rb index 5bc42b6bf96..a4b51c8efe1 100644 --- a/lib/rubocop/cop/style/each_for_simple_loop.rb +++ b/lib/rubocop/cop/style/each_for_simple_loop.rb @@ -32,20 +32,20 @@ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler send_node = node.send_node - range = send_node.receiver.source_range.join(send_node.loc.selector) - - add_offense(range) do |corrector| + add_offense(send_node) do |corrector| range_type, min, max = each_range(node) max += 1 if range_type == :irange - corrector.replace(node.send_node, "#{max - min}.times") + corrector.replace(send_node, "#{max - min}.times") end end private def offending?(node) + return false unless node.arguments.empty? + each_range_with_zero_origin?(node) || each_range_without_block_argument?(node) end diff --git a/spec/rubocop/cop/style/each_for_simple_loop_spec.rb b/spec/rubocop/cop/style/each_for_simple_loop_spec.rb index 20ce7a47b3a..1697009e895 100644 --- a/spec/rubocop/cop/style/each_for_simple_loop_spec.rb +++ b/spec/rubocop/cop/style/each_for_simple_loop_spec.rb @@ -9,58 +9,98 @@ expect_no_offenses('(0..b).each {}') end - context 'with inline block with parameters' do + context 'with inline block with no parameters' do it 'autocorrects an offense' do expect_offense(<<~RUBY) - (0...10).each { |n| } + (0...10).each { do_something } ^^^^^^^^^^^^^ Use `Integer#times` for a simple loop which iterates a fixed number of times. RUBY expect_correction(<<~RUBY) - 10.times { |n| } + 10.times { do_something } RUBY end end - context 'with multiline block with parameters' do + context 'with inline block with parameters' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + (0...10).each { |n| do_something(n) } + RUBY + end + end + + context 'with multiline block with no parameters' do it 'autocorrects an offense' do expect_offense(<<~RUBY) - (0...10).each do |n| + (0...10).each do ^^^^^^^^^^^^^ Use `Integer#times` for a simple loop which iterates a fixed number of times. + do_something end RUBY expect_correction(<<~RUBY) - 10.times do |n| + 10.times do + do_something + end + RUBY + end + end + + context 'with multiline block with parameters' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + (0...10).each do |n| + do_something(n) end RUBY end end context 'when using safe navigation operator' do - context 'with inline block with parameters' do + context 'with inline block with no parameters' do it 'autocorrects an offense' do expect_offense(<<~RUBY) - (0...10)&.each { |n| } + (0...10)&.each { do_something } ^^^^^^^^^^^^^^ Use `Integer#times` for a simple loop which iterates a fixed number of times. RUBY expect_correction(<<~RUBY) - 10.times { |n| } + 10.times { do_something } RUBY end end - context 'with multiline block with parameters' do + context 'with inline block with parameters' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + (0...10)&.each { |n| do_something(n) } + RUBY + end + end + + context 'with multiline block with no parameters' do it 'autocorrects an offense' do expect_offense(<<~RUBY) - (0...10)&.each do |n| + (0...10)&.each do ^^^^^^^^^^^^^^ Use `Integer#times` for a simple loop which iterates a fixed number of times. + do_something end RUBY expect_correction(<<~RUBY) - 10.times do |n| + 10.times do + do_something + end + RUBY + end + end + + context 'with multiline block with parameters' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + (0...10)&.each do |n| + do_something(n) end RUBY end