/
abc_size_spec.rb
159 lines (138 loc) · 4.48 KB
/
abc_size_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# frozen_string_literal: true
RSpec.describe RuboCop::Cop::Metrics::AbcSize, :config do
subject(:cop) { described_class.new(config) }
context 'when Max is 0' do
let(:cop_config) { { 'Max' => 0 } }
it 'accepts an empty method' do
expect_no_offenses(<<~RUBY)
def method_name
end
RUBY
end
it 'accepts an empty `define_method`' do
expect_no_offenses(<<~RUBY)
define_method :method_name do
end
RUBY
end
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. [<0, 2, 1> 2.24/0]
call_foo if some_condition # 0 + 2*2 + 1*1
end
RUBY
end
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, 0> 1/0]
x = 1
end
RUBY
end
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, 1, 0> 1.41/0]
x[0] = 1
end
RUBY
end
it 'registers an offense for complex content including A, B, and C ' \
'scores' do
expect_offense(<<~RUBY)
def method_name
^^^^^^^^^^^^^^^ 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
p value # 0, 1, 0
end
end
RUBY
end
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, 0> 1/0]
x = 1
end
RUBY
end
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. [<0, 2, 0> 2/0]
object&.do_something
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
let(:cop_config) { { 'Max' => 2 } }
it 'accepts two assignments' do
expect_no_offenses(<<~RUBY)
def method_name
x = 1
y = 2
end
RUBY
end
end
context 'when Max is 2.3' do
let(:cop_config) { { 'Max' => 2.3 } }
it 'accepts a total score of 2.24' do
expect_no_offenses(<<~RUBY)
def method_name
y = 1 if y == 1
end
RUBY
end
end
{
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 } }
it "reports size and max as #{presentation}" do
# Build an amount of code large enough to register an offense.
code = [' x = Hash.new if 1 == 1 || 2 == 2'] * max
inspect_source(['def method_name',
*code,
'end'].join("\n"))
expect(cop.messages)
.to eq(['Assignment Branch Condition size for method_name is too ' \
"high. [#{presentation}]"])
end
end
end
end