Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix #7396]: Display ABC components with the value #7399

Merged
merged 1 commit into from Oct 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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