diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c6e40c0746..78232ee0679 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ * [#7446](https://github.com/rubocop-hq/rubocop/issues/7446): Add `merge` to list of non-mutating methods. ([@cstyles][]) * [#7077](https://github.com/rubocop-hq/rubocop/issues/7077): Rename `Unneeded*` cops to `Redundant*` (e.g., `Style/UnneededPercentQ` becomes `Style/RedundantPercentQ`). ([@scottmatthewman][]) +* [#7396](https://github.com/rubocop-hq/rubocop/issues/7396): Display assignments, branches, and conditions values with the offense. ([@avmnu-sng][]) ## 0.75.1 (2019-10-14) @@ -4242,3 +4243,4 @@ [@jfhinchcliffe]: https://github.com/jfhinchcliffe [@jdkaplan]: https://github.com/jdkaplan [@cstyles]: https://github.com/cstyles +[@avmnu-sng]: https://github.com/avmnu-sng diff --git a/lib/rubocop/cop/metrics/abc_size.rb b/lib/rubocop/cop/metrics/abc_size.rb index eeaf6e684c6..b286d945d95 100644 --- a/lib/rubocop/cop/metrics/abc_size.rb +++ b/lib/rubocop/cop/metrics/abc_size.rb @@ -11,7 +11,7 @@ class AbcSize < Cop include MethodComplexity MSG = 'Assignment Branch Condition size for %s is too high. ' \ - '[%.4g/%.4g]' + '[%s %.4g/%.4g]' private diff --git a/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb b/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb index 0954bba25ea..92e8c47eba2 100644 --- a/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +++ b/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb @@ -43,7 +43,10 @@ def calculate end end - Math.sqrt(@assignment**2 + @branch**2 + @condition**2).round(2) + [ + Math.sqrt(@assignment**2 + @branch**2 + @condition**2).round(2), + "<#{@assignment}, #{@branch}, #{@condition}>" + ] end def evaluate_branch_nodes(node) diff --git a/lib/rubocop/cop/mixin/method_complexity.rb b/lib/rubocop/cop/mixin/method_complexity.rb index 15656d510f5..0cf4489d663 100644 --- a/lib/rubocop/cop/mixin/method_complexity.rb +++ b/lib/rubocop/cop/mixin/method_complexity.rb @@ -32,13 +32,14 @@ def check_complexity(node, method_name) return unless node.body max = cop_config['Max'] - complexity = complexity(node.body) + complexity, abc_vector = complexity(node.body) return unless complexity > max msg = format(self.class::MSG, method: method_name, complexity: complexity, + abc_vector: abc_vector, max: max) add_offense(node, message: msg) do diff --git a/spec/rubocop/cli/cli_disable_uncorrectable_spec.rb b/spec/rubocop/cli/cli_disable_uncorrectable_spec.rb index 94fd20699c6..8ee383c199b 100644 --- a/spec/rubocop/cli/cli_disable_uncorrectable_spec.rb +++ b/spec/rubocop/cli/cli_disable_uncorrectable_spec.rb @@ -113,10 +113,10 @@ def choose_move(who_to_move) == example.rb == C: 1: 1: [Corrected] Style/FrozenStringLiteralComment: Missing magic comment # frozen_string_literal: true. C: 2: 1: [Corrected] Layout/EmptyLineAfterMagicComment: Add an empty line after magic comments. - C: 3: 3: [Todo] Metrics/AbcSize: Assignment Branch Condition size for choose_move is too high. [15.62/15] + C: 3: 3: [Todo] Metrics/AbcSize: Assignment Branch Condition size for choose_move is too high. [<8, 12, 6> 15.62/15] C: 3: 3: [Todo] Metrics/CyclomaticComplexity: Cyclomatic complexity for choose_move is too high. [7/6] C: 3: 3: [Todo] Metrics/MethodLength: Method has too many lines. [11/10] - C: 4: 3: [Todo] Metrics/AbcSize: Assignment Branch Condition size for choose_move is too high. [15.62/15] + C: 4: 3: [Todo] Metrics/AbcSize: Assignment Branch Condition size for choose_move is too high. [<8, 12, 6> 15.62/15] C: 4: 3: [Todo] Metrics/MethodLength: Method has too many lines. [11/10] C: 4: 32: [Corrected] Style/DoubleCopDisableDirective: More than one disable comment on one line. diff --git a/spec/rubocop/cop/metrics/abc_size_spec.rb b/spec/rubocop/cop/metrics/abc_size_spec.rb index 0bbfbe0644d..bde1435ad44 100644 --- a/spec/rubocop/cop/metrics/abc_size_spec.rb +++ b/spec/rubocop/cop/metrics/abc_size_spec.rb @@ -23,7 +23,7 @@ def method_name it 'registers an offense for an if modifier' do expect_offense(<<~RUBY) def method_name - ^^^^^^^^^^^^^^^ Assignment Branch Condition size for method_name is too high. [2.24/0] + ^^^^^^^^^^^^^^^ Assignment Branch Condition size for method_name is too high. [<0, 2, 1> 2.24/0] call_foo if some_condition # 0 + 2*2 + 1*1 end RUBY @@ -32,7 +32,7 @@ def method_name it 'registers an offense for an assignment of a local variable' do expect_offense(<<~RUBY) def method_name - ^^^^^^^^^^^^^^^ Assignment Branch Condition size for method_name is too high. [1/0] + ^^^^^^^^^^^^^^^ Assignment Branch Condition size for method_name is too high. [<1, 0, 0> 1/0] x = 1 end RUBY @@ -41,7 +41,7 @@ def method_name it 'registers an offense for an assignment of an element' do expect_offense(<<~RUBY) def method_name - ^^^^^^^^^^^^^^^ Assignment Branch Condition size for method_name is too high. [1.41/0] + ^^^^^^^^^^^^^^^ Assignment Branch Condition size for method_name is too high. [<1, 1, 0> 1.41/0] x[0] = 1 end RUBY @@ -51,7 +51,7 @@ def method_name 'scores' do expect_offense(<<~RUBY) def method_name - ^^^^^^^^^^^^^^^ Assignment Branch Condition size for method_name is too high. [5.74/0] + ^^^^^^^^^^^^^^^ Assignment Branch Condition size for method_name is too high. [<1, 4, 4> 5.74/0] my_options = Hash.new if 1 == 1 || 2 == 2 # 1, 1, 4 my_options.each do |key, value| # 0, 1, 0 p key # 0, 1, 0 @@ -64,7 +64,7 @@ def method_name it 'registers an offense for a `define_method`' do expect_offense(<<~RUBY) define_method :method_name do - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Assignment Branch Condition size for method_name is too high. [1/0] + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Assignment Branch Condition size for method_name is too high. [<1, 0, 0> 1/0] x = 1 end RUBY @@ -73,7 +73,7 @@ def method_name it 'treats safe navigation method calls like regular method calls' do expect_offense(<<~RUBY) # sqrt(0 + 2*2 + 0) => 2 def method_name - ^^^^^^^^^^^^^^^ Assignment Branch Condition size for method_name is too high. [2/0] + ^^^^^^^^^^^^^^^ Assignment Branch Condition size for method_name is too high. [<0, 2, 0> 2/0] object&.do_something end RUBY @@ -106,10 +106,11 @@ def method_name end { - 1.3 => '4.24/1.3', # no more than 2 decimals reported - 10.3 => '42.43/10.3', - 100.321 => '424.3/100.3', # 4 significant digits, so only 1 decimal here - 1000.3 => '4243/1000' + 1.3 => '<1, 1, 4> 4.24/1.3', # no more than 2 decimals reported + 10.3 => '<10, 10, 40> 42.43/10.3', + 100.321 => '<100, 100, 400> 424.3/100.3', # 4 significant digits, + # so only 1 decimal here + 1000.3 => '<1000, 1000, 4000> 4243/1000' }.each do |max, presentation| context "when Max is #{max}" do let(:cop_config) { { 'Max' => max } } diff --git a/spec/rubocop/cop/metrics/utils/abc_size_calculator_spec.rb b/spec/rubocop/cop/metrics/utils/abc_size_calculator_spec.rb index 4e533bbc5da..c42ca61d4fc 100644 --- a/spec/rubocop/cop/metrics/utils/abc_size_calculator_spec.rb +++ b/spec/rubocop/cop/metrics/utils/abc_size_calculator_spec.rb @@ -9,7 +9,8 @@ def method_name return x, y, z end RUBY - expect(described_class.calculate(node)).to be_within(0.001).of(3) + expect(described_class.calculate(node).first) + .to be_within(0.001).of(3) end end @@ -21,7 +22,8 @@ def method_name e = f ? g : h end RUBY - expect(described_class.calculate(node)).to be_within(0.001).of(6.63) + expect(described_class.calculate(node).first) + .to be_within(0.001).of(6.63) end end @@ -42,7 +44,8 @@ def method_name end end RUBY - expect(described_class.calculate(node)).to be_within(0.001).of(9.17) + expect(described_class.calculate(node).first) + .to be_within(0.001).of(9.17) end end @@ -63,7 +66,8 @@ def method_name end end RUBY - expect(described_class.calculate(node)).to be_within(0.001).of(10.49) + expect(described_class.calculate(node).first) + .to be_within(0.001).of(10.49) end end @@ -81,7 +85,8 @@ def method_name end RUBY - expect(described_class.calculate(node)).to be_within(0.001).of(5.83) + expect(described_class.calculate(node).first) + .to be_within(0.001).of(5.83) end it 'counts else if as 2 conditions' do @@ -99,7 +104,8 @@ def method_name end RUBY - expect(described_class.calculate(node)).to be_within(0.001).of(6.4) + expect(described_class.calculate(node).first) + .to be_within(0.001).of(6.4) end end end