diff --git a/CHANGELOG.md b/CHANGELOG.md index 89f779a0439..8dcc3edd4c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ * [#7739](https://github.com/rubocop-hq/rubocop/pull/7739): Add `IgnoreNotImplementedMethods` configuration to `Lint/UnusedMethodArgument`. ([@tejasbubane][]) * [#7740](https://github.com/rubocop-hq/rubocop/issues/7740): Add `AllowModifiersOnSymbols` configuration to `Style/AccessModifierDeclarations`. ([@tejasbubane][]) * [#7812](https://github.com/rubocop-hq/rubocop/pull/7812): Add auto-correction for `Lint/BooleanSymbol` cop. ([@tejasbubane][]) +* [#7823](https://github.com/rubocop-hq/rubocop/pull/7823): Add `IgnoredMethods` configuration in `Metrics/AbcSize`, `Metrics/CyclomaticComplexity`, and `Metrics/PerceivedComplexity` cops. ([@drenmi][]) ### Bug fixes diff --git a/config/default.yml b/config/default.yml index 4a31afed0e3..e0a4f83a298 100644 --- a/config/default.yml +++ b/config/default.yml @@ -1833,9 +1833,10 @@ Metrics/AbcSize: - https://en.wikipedia.org/wiki/ABC_Software_Metric Enabled: true VersionAdded: '0.27' - VersionChanged: '0.66' + VersionChanged: '0.81' # The ABC size is a calculated magnitude, so this number can be an Integer or # a Float. + IgnoredMethods: [] Max: 15 Metrics/BlockLength: @@ -1875,6 +1876,8 @@ Metrics/CyclomaticComplexity: of test cases needed to validate a method. Enabled: true VersionAdded: '0.25' + VersionChanged: '0.81' + IgnoredMethods: [] Max: 6 Metrics/MethodLength: @@ -1908,6 +1911,8 @@ Metrics/PerceivedComplexity: human reader. Enabled: true VersionAdded: '0.25' + VersionChanged: '0.81' + IgnoredMethods: [] Max: 7 ################## Migration ############################# diff --git a/lib/rubocop/cop/mixin/method_complexity.rb b/lib/rubocop/cop/mixin/method_complexity.rb index 0cf4489d663..580b7d7e1a0 100644 --- a/lib/rubocop/cop/mixin/method_complexity.rb +++ b/lib/rubocop/cop/mixin/method_complexity.rb @@ -5,15 +5,20 @@ module Cop # This module handles measurement and reporting of complexity in methods. module MethodComplexity include ConfigurableMax + include IgnoredMethods extend NodePattern::Macros def on_def(node) + return if ignored_method?(node.method_name) + check_complexity(node, node.method_name) end alias on_defs on_def def on_block(node) define_method?(node) do |name| + return if ignored_method?(name) + check_complexity(node, name) end end diff --git a/manual/cops_metrics.md b/manual/cops_metrics.md index 8ceb1bb89f5..5d61f656465 100644 --- a/manual/cops_metrics.md +++ b/manual/cops_metrics.md @@ -4,7 +4,7 @@ Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged --- | --- | --- | --- | --- -Enabled | Yes | No | 0.27 | 0.66 +Enabled | Yes | No | 0.27 | 0.81 This cop checks that the ABC size of methods is not higher than the configured maximum. The ABC size is based on assignments, branches @@ -15,6 +15,7 @@ and https://en.wikipedia.org/wiki/ABC_Software_Metric. Name | Default value | Configurable values --- | --- | --- +IgnoredMethods | `[]` | Array Max | `15` | Integer ### References @@ -89,7 +90,7 @@ Max | `100` | Integer Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged --- | --- | --- | --- | --- -Enabled | Yes | No | 0.25 | - +Enabled | Yes | No | 0.25 | 0.81 This cop checks that the cyclomatic complexity of methods is not higher than the configured maximum. The cyclomatic complexity is the number of @@ -106,6 +107,7 @@ Loops can be said to have an exit condition, so they add one. Name | Default value | Configurable values --- | --- | --- +IgnoredMethods | `[]` | Array Max | `6` | Integer ## Metrics/MethodLength @@ -172,7 +174,7 @@ CountKeywordArgs | `true` | Boolean Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged --- | --- | --- | --- | --- -Enabled | Yes | No | 0.25 | - +Enabled | Yes | No | 0.25 | 0.81 This cop tries to produce a complexity score that's a measure of the complexity the reader experiences when looking at a method. For that @@ -204,4 +206,5 @@ end # 7 complexity points Name | Default value | Configurable values --- | --- | --- +IgnoredMethods | `[]` | Array Max | `7` | Integer diff --git a/spec/rubocop/cop/metrics/abc_size_spec.rb b/spec/rubocop/cop/metrics/abc_size_spec.rb index bde1435ad44..f9a1c3d9e3b 100644 --- a/spec/rubocop/cop/metrics/abc_size_spec.rb +++ b/spec/rubocop/cop/metrics/abc_size_spec.rb @@ -78,6 +78,34 @@ def method_name end RUBY end + + context 'when method is in list of ignored methods' do + let(:cop_config) { { 'Max' => 0, 'IgnoredMethods' => ['foo'] } } + + it 'does not register an offense when defining an instance method' do + expect_no_offenses(<<~RUBY) + def foo + bar.baz(:qux) + end + RUBY + end + + it 'does not register an offense when defining a class method' do + expect_no_offenses(<<~RUBY) + def self.foo + bar.baz(:qux) + end + RUBY + end + + it 'does not register an offense when using `define_method`' do + expect_no_offenses(<<~RUBY) + define_method :foo do + bar.baz(:qux) + end + RUBY + end + end end context 'when Max is 2' do diff --git a/spec/rubocop/cop/metrics/cyclomatic_complexity_spec.rb b/spec/rubocop/cop/metrics/cyclomatic_complexity_spec.rb index 004e32c8423..c176c2422ae 100644 --- a/spec/rubocop/cop/metrics/cyclomatic_complexity_spec.rb +++ b/spec/rubocop/cop/metrics/cyclomatic_complexity_spec.rb @@ -215,6 +215,34 @@ def method_name_2 end end + context 'when method is in list of ignored methods' do + let(:cop_config) { { 'Max' => 0, 'IgnoredMethods' => ['foo'] } } + + it 'does not register an offense when defining an instance method' do + expect_no_offenses(<<~RUBY) + def foo + bar.baz(:qux) + end + RUBY + end + + it 'does not register an offense when defining a class method' do + expect_no_offenses(<<~RUBY) + def self.foo + bar.baz(:qux) + end + RUBY + end + + it 'does not register an offense when using `define_method`' do + expect_no_offenses(<<~RUBY) + define_method :foo do + bar.baz(:qux) + end + RUBY + end + end + context 'when Max is 2' do let(:cop_config) { { 'Max' => 2 } } diff --git a/spec/rubocop/cop/metrics/perceived_complexity_spec.rb b/spec/rubocop/cop/metrics/perceived_complexity_spec.rb index 089bfd97e2e..a457b63895b 100644 --- a/spec/rubocop/cop/metrics/perceived_complexity_spec.rb +++ b/spec/rubocop/cop/metrics/perceived_complexity_spec.rb @@ -230,6 +230,34 @@ def method_name_2 end end + context 'when method is in list of ignored methods' do + let(:cop_config) { { 'Max' => 0, 'IgnoredMethods' => ['foo'] } } + + it 'does not register an offense when defining an instance method' do + expect_no_offenses(<<~RUBY) + def foo + bar.baz(:qux) + end + RUBY + end + + it 'does not register an offense when defining a class method' do + expect_no_offenses(<<~RUBY) + def self.foo + bar.baz(:qux) + end + RUBY + end + + it 'does not register an offense when using `define_method`' do + expect_no_offenses(<<~RUBY) + define_method :foo do + bar.baz(:qux) + end + RUBY + end + end + context 'when Max is 2' do let(:cop_config) { { 'Max' => 2 } }