Skip to content

Commit

Permalink
[Fix rubocop#7396]: Display ABC components with the value
Browse files Browse the repository at this point in the history
Providing component values gives more insights to fix the offense.
  • Loading branch information
avmnu-sng committed Oct 26, 2019
1 parent 9b48a4a commit 7aa807e
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 21 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -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)

Expand Down Expand Up @@ -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
2 changes: 1 addition & 1 deletion lib/rubocop/cop/metrics/abc_size.rb
Expand Up @@ -11,7 +11,7 @@ class AbcSize < Cop
include MethodComplexity

MSG = 'Assignment Branch Condition size for %<method>s is too high. ' \
'[%<complexity>.4g/%<max>.4g]'
'[%<abc_vector>s %<complexity>.4g/%<max>.4g]'

private

Expand Down
5 changes: 4 additions & 1 deletion lib/rubocop/cop/metrics/utils/abc_size_calculator.rb
Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion lib/rubocop/cop/mixin/method_complexity.rb
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions spec/rubocop/cli/cli_disable_uncorrectable_spec.rb
Expand Up @@ -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.
Expand Down
21 changes: 11 additions & 10 deletions spec/rubocop/cop/metrics/abc_size_spec.rb
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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 } }
Expand Down
18 changes: 12 additions & 6 deletions spec/rubocop/cop/metrics/utils/abc_size_calculator_spec.rb
Expand Up @@ -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

Expand All @@ -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

Expand All @@ -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

Expand All @@ -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

Expand All @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 7aa807e

Please sign in to comment.