Skip to content

Commit

Permalink
[Fix #12970] Add CountModifierForms option to Metrics/BlockNesting
Browse files Browse the repository at this point in the history
Resolves #12970.

This PR adds `CountModifierForms` option to `Metrics/BlockNesting`
and set it to `false` by default.

Similar to the existing `CountBlocks`, the default is `false`.
This means that existing modifier form code will not be detected by default,
but this seems reasonable as part of the block nesting functionality.
If user require the previous behavior, user can achieve it by setting `CountBlocks` to `true`.
  • Loading branch information
koic authored and bbatsov committed Jun 7, 2024
1 parent e356c46 commit b1d6f04
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#12970](https://github.com/rubocop/rubocop/issues/12970): Add `CountModifierForms` option to `Metrics/BlockNesting` and set it to `false` by default. ([@koic][])
3 changes: 2 additions & 1 deletion config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2617,8 +2617,9 @@ Metrics/BlockNesting:
StyleGuide: '#three-is-the-number-thou-shalt-count'
Enabled: true
VersionAdded: '0.25'
VersionChanged: '0.47'
VersionChanged: '<<next>>'
CountBlocks: false
CountModifierForms: false
Max: 3

Metrics/ClassLength:
Expand Down
26 changes: 19 additions & 7 deletions lib/rubocop/cop/metrics/block_nesting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
module RuboCop
module Cop
module Metrics
# Checks for excessive nesting of conditional and looping
# constructs.
# Checks for excessive nesting of conditional and looping constructs.
#
# You can configure if blocks are considered using the `CountBlocks`
# option. When set to `false` (the default) blocks are not counted
# towards the nesting level. Set to `true` to count blocks as well.
# You can configure if blocks are considered using the `CountBlocks` and `CountModifierForms`
# options. When both are set to `false` (the default) blocks and modifier forms are not
# counted towards the nesting level. Set them to `true` to include these in the nesting level
# calculation as well.
#
# The maximum level of nesting allowed is configurable.
class BlockNesting < Base
Expand All @@ -27,7 +27,7 @@ def on_new_investigation

def check_nesting_level(node, max, current_level)
if consider_node?(node)
current_level += 1 unless node.if_type? && node.elsif?
current_level += 1 if count_if_block?(node)
if current_level > max
self.max = current_level
unless part_of_ignored_node?(node)
Expand All @@ -41,6 +41,14 @@ def check_nesting_level(node, max, current_level)
end
end

def count_if_block?(node)
return true unless node.if_type?
return false if node.elsif?
return count_modifier_forms? if node.modifier_form?

true
end

def consider_node?(node)
return true if NESTING_BLOCKS.include?(node.type)

Expand All @@ -52,7 +60,11 @@ def message(max)
end

def count_blocks?
cop_config['CountBlocks']
cop_config.fetch('CountBlocks', false)
end

def count_modifier_forms?
cop_config.fetch('CountModifierForms', false)
end
end
end
Expand Down
44 changes: 44 additions & 0 deletions spec/rubocop/cop/metrics/block_nesting_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -314,4 +314,48 @@
end
end
end

context 'when CountModifierForms is false' do
let(:cop_config) { { 'Max' => 2, 'CountModifierForms' => false } }

it 'accepts nested modifier forms' do
expect_no_offenses(<<~RUBY)
if a
if b
puts 'hello' if c
end
end
RUBY
end

it 'registers nested if expressions' do
expect_offense(<<~RUBY)
if a
if b
if c
^^^^ Avoid more than 2 levels of block nesting.
puts 'hello'
end
end
end
RUBY
end
end

context 'when CountModifierForms is true' do
let(:cop_config) { { 'Max' => 2, 'CountModifierForms' => true } }

context 'nested modifier forms' do
it 'registers an offense' do
expect_offense(<<~RUBY)
if a
if b
puts 'hello' if c
^^^^^^^^^^^^^^^^^ Avoid more than 2 levels of block nesting.
end
end
RUBY
end
end
end
end

0 comments on commit b1d6f04

Please sign in to comment.