rubocop 0.24.1 → 0.25.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubocop might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +12 -8
- data/.travis.yml +1 -1
- data/CHANGELOG.md +42 -0
- data/Gemfile +2 -0
- data/README.md +27 -6
- data/bin/rubocop +10 -15
- data/config/default.yml +72 -25
- data/config/enabled.yml +57 -25
- data/lib/rubocop.rb +15 -8
- data/lib/rubocop/config_loader.rb +11 -7
- data/lib/rubocop/cop/cop.rb +16 -16
- data/lib/rubocop/cop/ignored_node.rb +11 -4
- data/lib/rubocop/cop/lint/block_alignment.rb +29 -4
- data/lib/rubocop/cop/lint/debugger.rb +8 -1
- data/lib/rubocop/cop/lint/def_end_alignment.rb +5 -1
- data/lib/rubocop/cop/lint/end_alignment.rb +5 -5
- data/lib/rubocop/cop/lint/end_in_method.rb +2 -2
- data/lib/rubocop/cop/lint/useless_setter_call.rb +2 -2
- data/lib/rubocop/cop/{style → metrics}/block_nesting.rb +1 -1
- data/lib/rubocop/cop/{style → metrics}/class_length.rb +4 -4
- data/lib/rubocop/cop/{style → metrics}/cyclomatic_complexity.rb +5 -16
- data/lib/rubocop/cop/{style → metrics}/line_length.rb +1 -1
- data/lib/rubocop/cop/{style → metrics}/method_length.rb +8 -4
- data/lib/rubocop/cop/{style → metrics}/parameter_lists.rb +1 -1
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +61 -0
- data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +10 -2
- data/lib/rubocop/cop/mixin/code_length.rb +2 -3
- data/lib/rubocop/cop/mixin/configurable_naming.rb +6 -20
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/if_node.rb +1 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +32 -0
- data/lib/rubocop/cop/mixin/negative_conditional.rb +1 -1
- data/lib/rubocop/cop/mixin/{check_methods.rb → on_method.rb} +3 -3
- data/lib/rubocop/cop/mixin/on_normal_if_unless.rb +24 -0
- data/lib/rubocop/cop/mixin/percent_literal.rb +2 -1
- data/lib/rubocop/cop/mixin/space_inside.rb +33 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +14 -14
- data/lib/rubocop/cop/mixin/string_help.rb +4 -0
- data/lib/rubocop/cop/mixin/surrounding_space.rb +1 -0
- data/lib/rubocop/cop/rails/delegate.rb +2 -2
- data/lib/rubocop/cop/rails/output.rb +4 -2
- data/lib/rubocop/cop/style/accessor_method_name.rb +2 -2
- data/lib/rubocop/cop/style/align_hash.rb +9 -1
- data/lib/rubocop/cop/style/and_or.rb +37 -3
- data/lib/rubocop/cop/style/bare_percent_literals.rb +46 -0
- data/lib/rubocop/cop/style/block_end_newline.rb +56 -0
- data/lib/rubocop/cop/style/character_literal.rb +1 -1
- data/lib/rubocop/cop/style/def_with_parentheses.rb +2 -2
- data/lib/rubocop/cop/style/empty_lines_around_access_modifier.rb +31 -3
- data/lib/rubocop/cop/style/empty_lines_around_body.rb +6 -2
- data/lib/rubocop/cop/style/end_of_line.rb +3 -14
- data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -6
- data/lib/rubocop/cop/style/if_with_semicolon.rb +6 -7
- data/lib/rubocop/cop/style/indentation_width.rb +3 -8
- data/lib/rubocop/cop/style/method_def_parentheses.rb +2 -2
- data/lib/rubocop/cop/style/method_name.rb +4 -18
- data/lib/rubocop/cop/style/multiline_block_layout.rb +73 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +4 -4
- data/lib/rubocop/cop/style/negated_if.rb +1 -1
- data/lib/rubocop/cop/style/negated_while.rb +2 -2
- data/lib/rubocop/cop/style/next.rb +12 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +6 -6
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +22 -8
- data/lib/rubocop/cop/style/percent_q_literals.rb +53 -0
- data/lib/rubocop/cop/style/predicate_name.rb +2 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +2 -2
- data/lib/rubocop/cop/style/redundant_return.rb +2 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +7 -3
- data/lib/rubocop/cop/style/single_line_methods.rb +2 -2
- data/lib/rubocop/cop/style/space_after_method_name.rb +2 -2
- data/lib/rubocop/cop/style/space_inside_block_braces.rb +14 -10
- data/lib/rubocop/cop/style/space_inside_brackets.rb +5 -1
- data/lib/rubocop/cop/style/string_literals.rb +5 -8
- data/lib/rubocop/cop/style/trailing_comma.rb +15 -3
- data/lib/rubocop/cop/style/trivial_accessors.rb +2 -2
- data/lib/rubocop/cop/style/unneeded_capital_w.rb +2 -4
- data/lib/rubocop/cop/style/unneeded_percent_q.rb +13 -0
- data/lib/rubocop/cop/style/variable_interpolation.rb +14 -2
- data/lib/rubocop/cop/style/variable_name.rb +17 -17
- data/lib/rubocop/cop/style/while_until_modifier.rb +2 -5
- data/lib/rubocop/cop/util.rb +5 -0
- data/lib/rubocop/cop/variable_force.rb +7 -6
- data/lib/rubocop/formatter/base_formatter.rb +2 -2
- data/lib/rubocop/processed_source.rb +5 -22
- data/lib/rubocop/version.rb +1 -1
- data/relnotes/v0.25.0.md +91 -0
- data/rubocop.gemspec +2 -3
- data/spec/project_spec.rb +1 -1
- data/spec/rubocop/cli_spec.rb +70 -44
- data/spec/rubocop/comment_config_spec.rb +6 -6
- data/spec/rubocop/config_loader_spec.rb +19 -13
- data/spec/rubocop/config_spec.rb +3 -3
- data/spec/rubocop/cop/commissioner_spec.rb +1 -1
- data/spec/rubocop/cop/cop_spec.rb +3 -3
- data/spec/rubocop/cop/lint/block_alignment_spec.rb +113 -6
- data/spec/rubocop/cop/lint/debugger_spec.rb +10 -6
- data/spec/rubocop/cop/lint/useless_assignment_spec.rb +12 -0
- data/spec/rubocop/cop/{style → metrics}/block_nesting_spec.rb +1 -1
- data/spec/rubocop/cop/{style → metrics}/class_length_spec.rb +1 -1
- data/spec/rubocop/cop/{style → metrics}/cyclomatic_complexity_spec.rb +1 -1
- data/spec/rubocop/cop/{style → metrics}/if_unless_modifier_spec.rb +2 -2
- data/spec/rubocop/cop/{style → metrics}/line_length_spec.rb +7 -7
- data/spec/rubocop/cop/{style → metrics}/method_length_spec.rb +1 -1
- data/spec/rubocop/cop/{style → metrics}/parameter_lists_spec.rb +1 -1
- data/spec/rubocop/cop/metrics/perceived_complexity_spec.rb +222 -0
- data/spec/rubocop/cop/{style → metrics}/while_until_modifier_spec.rb +2 -2
- data/spec/rubocop/cop/rails/output_spec.rb +8 -2
- data/spec/rubocop/cop/style/align_hash_spec.rb +7 -0
- data/spec/rubocop/cop/style/and_or_spec.rb +245 -43
- data/spec/rubocop/cop/style/bare_percent_literals_spec.rb +132 -0
- data/spec/rubocop/cop/style/block_end_newline_spec.rb +61 -0
- data/spec/rubocop/cop/style/empty_lines_around_access_modifier_spec.rb +34 -0
- data/spec/rubocop/cop/style/end_of_line_spec.rb +8 -0
- data/spec/rubocop/cop/style/guard_clause_spec.rb +1 -1
- data/spec/rubocop/cop/style/multiline_block_layout_spec.rb +138 -0
- data/spec/rubocop/cop/style/next_spec.rb +32 -3
- data/spec/rubocop/cop/style/percent_literal_delimiters_spec.rb +34 -0
- data/spec/rubocop/cop/style/percent_q_literals_spec.rb +122 -0
- data/spec/rubocop/cop/style/space_inside_block_braces_spec.rb +20 -0
- data/spec/rubocop/cop/style/space_inside_brackets_spec.rb +26 -2
- data/spec/rubocop/cop/style/trailing_comma_spec.rb +112 -0
- data/spec/rubocop/cop/style/unneeded_percent_q_spec.rb +86 -31
- data/spec/rubocop/cop/style/variable_interpolation_spec.rb +21 -1
- data/spec/rubocop/cop/team_spec.rb +14 -9
- data/spec/spec_helper.rb +1 -0
- metadata +47 -50
- data/lib/rubocop/cop/mixin/if_then_else.rb +0 -23
data/spec/rubocop/config_spec.rb
CHANGED
@@ -41,7 +41,7 @@ describe RuboCop::Config do
|
|
41
41
|
context 'when the configuration includes any unrecognized parameter' do
|
42
42
|
before do
|
43
43
|
create_file(configuration_path, [
|
44
|
-
'
|
44
|
+
'Metrics/LineLength:',
|
45
45
|
' Enabled: true',
|
46
46
|
' Min: 10'
|
47
47
|
])
|
@@ -50,7 +50,7 @@ describe RuboCop::Config do
|
|
50
50
|
it 'raises validation error' do
|
51
51
|
expect { configuration.validate }
|
52
52
|
.to raise_error(described_class::ValidationError,
|
53
|
-
/^unrecognized parameter
|
53
|
+
/^unrecognized parameter Metrics\/LineLength:Min/)
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
@@ -59,7 +59,7 @@ describe RuboCop::Config do
|
|
59
59
|
# configuration, but are nonetheless allowed for any cop.
|
60
60
|
before do
|
61
61
|
create_file(configuration_path, [
|
62
|
-
'
|
62
|
+
'Metrics/LineLength:',
|
63
63
|
' Exclude:',
|
64
64
|
' - lib/file.rb',
|
65
65
|
' Include:',
|
@@ -17,7 +17,7 @@ describe RuboCop::Cop::Cop do
|
|
17
17
|
describe '.qualified_cop_name' do
|
18
18
|
it 'adds namespace if the cop name is found in exactly one namespace' do
|
19
19
|
expect(described_class.qualified_cop_name('LineLength', '--only'))
|
20
|
-
.to eq('
|
20
|
+
.to eq('Metrics/LineLength')
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'returns the given cop name if it is not found in any namespace' do
|
@@ -26,8 +26,8 @@ describe RuboCop::Cop::Cop do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'returns the given cop name if it already has a namespace' do
|
29
|
-
expect(described_class.qualified_cop_name('
|
30
|
-
.to eq('
|
29
|
+
expect(described_class.qualified_cop_name('Metrics/LineLength', '--only'))
|
30
|
+
.to eq('Metrics/LineLength')
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'raises an error if the cop name is in more than one namespace' do
|
@@ -1,18 +1,57 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
# rubocop:disable
|
2
|
+
# rubocop:disable Metrics/LineLength
|
3
3
|
|
4
4
|
require 'spec_helper'
|
5
5
|
|
6
6
|
describe RuboCop::Cop::Lint::BlockAlignment do
|
7
7
|
subject(:cop) { described_class.new }
|
8
8
|
|
9
|
-
|
9
|
+
context 'when the block has no arguments' do
|
10
|
+
it 'registers an offense for mismatched block end' do
|
11
|
+
inspect_source(cop,
|
12
|
+
['test do',
|
13
|
+
' end'
|
14
|
+
])
|
15
|
+
expect(cop.messages)
|
16
|
+
.to eq(['`end` at 2, 2 is not aligned with `test do` at 1, 0'])
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'auto-corrects alignment' do
|
20
|
+
new_source = autocorrect_source(cop, ['test do',
|
21
|
+
' end'
|
22
|
+
])
|
23
|
+
|
24
|
+
expect(new_source).to eq(['test do',
|
25
|
+
'end'].join("\n"))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when the block has arguments' do
|
30
|
+
it 'registers an offense for mismatched block end' do
|
31
|
+
inspect_source(cop,
|
32
|
+
['test do |ala|',
|
33
|
+
' end'
|
34
|
+
])
|
35
|
+
expect(cop.messages)
|
36
|
+
.to eq(['`end` at 2, 2 is not aligned with `test do |ala|` at 1, 0'])
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'auto-corrects alignment' do
|
40
|
+
new_source = autocorrect_source(cop, ['test do |ala|',
|
41
|
+
' end'
|
42
|
+
])
|
43
|
+
|
44
|
+
expect(new_source).to eq(['test do |ala|',
|
45
|
+
'end'].join("\n"))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'acepts a block end that does not begin its line' do
|
10
50
|
inspect_source(cop,
|
11
|
-
['
|
12
|
-
'
|
51
|
+
[' scope :bar, lambda { joins(:baz)',
|
52
|
+
' .distinct }'
|
13
53
|
])
|
14
|
-
expect(cop.
|
15
|
-
.to eq(['`end` at 2, 2 is not aligned with `test do |ala|` at 1, 0'])
|
54
|
+
expect(cop.offenses).to be_empty
|
16
55
|
end
|
17
56
|
|
18
57
|
context 'when the block is a logical operand' do
|
@@ -53,6 +92,17 @@ describe RuboCop::Cop::Lint::BlockAlignment do
|
|
53
92
|
])
|
54
93
|
expect(cop.offenses).to be_empty
|
55
94
|
end
|
95
|
+
|
96
|
+
it 'auto-corrects alignment to the block start' do
|
97
|
+
new_source = autocorrect_source(cop,
|
98
|
+
['a = b = c = test do |ala|',
|
99
|
+
' end'
|
100
|
+
])
|
101
|
+
|
102
|
+
expect(new_source).to eq(['a = b = c = test do |ala|',
|
103
|
+
' end'
|
104
|
+
].join("\n"))
|
105
|
+
end
|
56
106
|
end
|
57
107
|
|
58
108
|
context 'and the block is an operand' do
|
@@ -97,6 +147,23 @@ describe RuboCop::Cop::Lint::BlockAlignment do
|
|
97
147
|
.to eq(['`end` at 4, 0 is not aligned with `a_long_method_that_dont_fit_on_the_line ' \
|
98
148
|
'do |v|` at 2, 2'])
|
99
149
|
end
|
150
|
+
|
151
|
+
it 'auto-corrects alignment' do
|
152
|
+
new_source = autocorrect_source(
|
153
|
+
cop,
|
154
|
+
['variable =',
|
155
|
+
' a_long_method_that_dont_fit_on_the_line do |v|',
|
156
|
+
' v.foo',
|
157
|
+
'end'
|
158
|
+
])
|
159
|
+
|
160
|
+
expect(new_source)
|
161
|
+
.to eq(['variable =',
|
162
|
+
' a_long_method_that_dont_fit_on_the_line do |v|',
|
163
|
+
' v.foo',
|
164
|
+
' end'
|
165
|
+
].join("\n"))
|
166
|
+
end
|
100
167
|
end
|
101
168
|
|
102
169
|
context 'when the method part is a call chain that spans several lines' do
|
@@ -173,6 +240,36 @@ describe RuboCop::Cop::Lint::BlockAlignment do
|
|
173
240
|
inspect_source(cop, src)
|
174
241
|
expect(cop.offenses).to be_empty
|
175
242
|
end
|
243
|
+
|
244
|
+
it 'auto-corrects misaligned ends with the start of the expression' do
|
245
|
+
src = ['def foo(bar)',
|
246
|
+
' bar.get_stuffs',
|
247
|
+
' .reject do |stuff|',
|
248
|
+
' stuff.with_a_very_long_expression_that_doesnt_fit_the_line',
|
249
|
+
' end.select do |stuff|',
|
250
|
+
' stuff.another_very_long_expression_that_doesnt_fit_the_line',
|
251
|
+
' end',
|
252
|
+
' .select do |stuff|',
|
253
|
+
' stuff.another_very_long_expression_that_doesnt_fit_the_line',
|
254
|
+
' end',
|
255
|
+
'end']
|
256
|
+
|
257
|
+
aligned_src = [
|
258
|
+
'def foo(bar)',
|
259
|
+
' bar.get_stuffs',
|
260
|
+
' .reject do |stuff|',
|
261
|
+
' stuff.with_a_very_long_expression_that_doesnt_fit_the_line',
|
262
|
+
' end.select do |stuff|',
|
263
|
+
' stuff.another_very_long_expression_that_doesnt_fit_the_line',
|
264
|
+
' end',
|
265
|
+
' .select do |stuff|',
|
266
|
+
' stuff.another_very_long_expression_that_doesnt_fit_the_line',
|
267
|
+
' end',
|
268
|
+
'end'].join("\n")
|
269
|
+
|
270
|
+
new_source = autocorrect_source(cop, src)
|
271
|
+
expect(new_source).to eq(aligned_src)
|
272
|
+
end
|
176
273
|
end
|
177
274
|
|
178
275
|
context 'when variables of a mass assignment spans several lines' do
|
@@ -194,6 +291,16 @@ describe RuboCop::Cop::Lint::BlockAlignment do
|
|
194
291
|
expect(cop.messages)
|
195
292
|
.to eq(['`end` at 4, 4 is not aligned with `e,` at 1, 0 or `f = [5, 6].map do |i|` at 2, 0'])
|
196
293
|
end
|
294
|
+
|
295
|
+
it 'can not auto-correct' do
|
296
|
+
src = ['e,',
|
297
|
+
'f = [5, 6].map do |i|',
|
298
|
+
' i - 5',
|
299
|
+
' end']
|
300
|
+
|
301
|
+
new_source = autocorrect_source(cop, src)
|
302
|
+
expect(new_source).to eq(src.join("\n"))
|
303
|
+
end
|
197
304
|
end
|
198
305
|
|
199
306
|
it 'accepts end aligned with an instance variable' do
|
@@ -23,13 +23,17 @@ describe RuboCop::Cop::Lint::Debugger do
|
|
23
23
|
|
24
24
|
it 'reports an offense for pry bindings' do
|
25
25
|
src = ['binding.pry',
|
26
|
-
'binding.remote_pry'
|
26
|
+
'binding.remote_pry',
|
27
|
+
'binding.pry_remote']
|
27
28
|
inspect_source(cop, src)
|
28
|
-
expect(cop.offenses.size).to eq(
|
29
|
+
expect(cop.offenses.size).to eq(3)
|
29
30
|
expect(cop.messages)
|
30
31
|
.to eq(['Remove debugger entry point `binding.pry`.',
|
31
|
-
'Remove debugger entry point `binding.remote_pry`.'
|
32
|
-
|
32
|
+
'Remove debugger entry point `binding.remote_pry`.',
|
33
|
+
'Remove debugger entry point `binding.pry_remote`.'])
|
34
|
+
expect(cop.highlights).to eq(['binding.pry',
|
35
|
+
'binding.remote_pry',
|
36
|
+
'binding.pry_remote'])
|
33
37
|
end
|
34
38
|
|
35
39
|
it 'does not report an offense for non-pry binding' do
|
@@ -38,7 +42,7 @@ describe RuboCop::Cop::Lint::Debugger do
|
|
38
42
|
expect(cop.offenses).to be_empty
|
39
43
|
end
|
40
44
|
|
41
|
-
%w(debugger byebug).each do |comment|
|
45
|
+
%w(debugger byebug pry remote_pry pry_remote).each do |comment|
|
42
46
|
it "does not report an offense for #{comment} in comments" do
|
43
47
|
src = ["# #{comment}"]
|
44
48
|
inspect_source(cop, src)
|
@@ -46,7 +50,7 @@ describe RuboCop::Cop::Lint::Debugger do
|
|
46
50
|
end
|
47
51
|
end
|
48
52
|
|
49
|
-
%w(debugger byebug pry).each do |method_name|
|
53
|
+
%w(debugger byebug pry remote_pry pry_remote).each do |method_name|
|
50
54
|
it "does not report an offense for a #{method_name} method" do
|
51
55
|
src = ["code.#{method_name}"]
|
52
56
|
inspect_source(cop, src)
|
@@ -1516,6 +1516,18 @@ describe RuboCop::Cop::Lint::UselessAssignment do
|
|
1516
1516
|
include_examples 'mimics MRI 2.1'
|
1517
1517
|
end
|
1518
1518
|
|
1519
|
+
context 'when an anonymous keyword splat method argument is defined' do
|
1520
|
+
let(:source) do
|
1521
|
+
[
|
1522
|
+
'def some_method(name: value, **)',
|
1523
|
+
'end'
|
1524
|
+
]
|
1525
|
+
end
|
1526
|
+
|
1527
|
+
include_examples 'accepts' unless RUBY_VERSION < '2.0'
|
1528
|
+
include_examples 'mimics MRI 2.1'
|
1529
|
+
end
|
1530
|
+
|
1519
1531
|
context 'when a block argument is not used' do
|
1520
1532
|
let(:source) do
|
1521
1533
|
[
|
@@ -7,7 +7,7 @@ describe RuboCop::Cop::Style::IfUnlessModifier do
|
|
7
7
|
|
8
8
|
subject(:cop) { described_class.new(config) }
|
9
9
|
let(:config) do
|
10
|
-
hash = { '
|
10
|
+
hash = { 'Metrics/LineLength' => { 'Max' => 80 } }
|
11
11
|
RuboCop::Config.new(hash)
|
12
12
|
end
|
13
13
|
|
@@ -128,7 +128,7 @@ describe RuboCop::Cop::Style::IfUnlessModifier do
|
|
128
128
|
context 'when the maximum line length is specified by the cop itself' do
|
129
129
|
let(:config) do
|
130
130
|
hash = {
|
131
|
-
'
|
131
|
+
'Metrics/LineLength' => { 'Max' => 100 },
|
132
132
|
'Style/IfUnlessModifier' => { 'MaxLineLength' => 80 }
|
133
133
|
}
|
134
134
|
RuboCop::Config.new(hash)
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe RuboCop::Cop::
|
5
|
+
describe RuboCop::Cop::Metrics::LineLength, :config do
|
6
6
|
subject(:cop) { described_class.new(config) }
|
7
7
|
let(:cop_config) { { 'Max' => 80 } }
|
8
8
|
|
@@ -40,11 +40,11 @@ describe RuboCop::Cop::Style::LineLength, :config do
|
|
40
40
|
end
|
41
41
|
|
42
42
|
context 'and the excessive characters include a complete URL' do
|
43
|
-
# rubocop:disable
|
43
|
+
# rubocop:disable Metrics/LineLength
|
44
44
|
let(:source) { <<-END }
|
45
45
|
# See: http://google.com/, http://gmail.com/, https://maps.google.com/, http://plus.google.com/
|
46
46
|
END
|
47
|
-
# rubocop:enable
|
47
|
+
# rubocop:enable Metrics/LineLength
|
48
48
|
|
49
49
|
it 'registers an offense for the line' do
|
50
50
|
inspect_source(cop, source)
|
@@ -59,12 +59,12 @@ describe RuboCop::Cop::Style::LineLength, :config do
|
|
59
59
|
|
60
60
|
context 'and the excessive characters include part of an URL ' \
|
61
61
|
'and another word' do
|
62
|
-
# rubocop:disable
|
62
|
+
# rubocop:disable Metrics/LineLength
|
63
63
|
let(:source) { <<-END }
|
64
64
|
# See: https://github.com/bbatsov/rubocop/commit/3b48d8bdf5b1c2e05e35061837309890f04ab08c and
|
65
65
|
# http://google.com/
|
66
66
|
END
|
67
|
-
# rubocop:enable
|
67
|
+
# rubocop:enable Metrics/LineLength
|
68
68
|
|
69
69
|
it 'registers an offense for the line' do
|
70
70
|
inspect_source(cop, source)
|
@@ -79,11 +79,11 @@ describe RuboCop::Cop::Style::LineLength, :config do
|
|
79
79
|
|
80
80
|
context 'and an error other than URI::InvalidURIError is raised ' \
|
81
81
|
'while validating an URI-ish string' do
|
82
|
-
# rubocop:disable
|
82
|
+
# rubocop:disable Metrics/LineLength
|
83
83
|
let(:source) { <<-END }
|
84
84
|
xxxxxxxxxxxxxxxxxxxxxxxxxxxxzxxxxxxxxxxx = LDAP::DEFAULT_GROUP_UNIQUE_MEMBER_LIST_KEY
|
85
85
|
END
|
86
|
-
# rubocop:enable
|
86
|
+
# rubocop:enable Metrics/LineLength
|
87
87
|
|
88
88
|
it 'does not crash' do
|
89
89
|
expect { inspect_source(cop, source) }.not_to raise_error
|
@@ -0,0 +1,222 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe RuboCop::Cop::Metrics::PerceivedComplexity, :config do
|
6
|
+
subject(:cop) { described_class.new(config) }
|
7
|
+
|
8
|
+
context 'when Max is 1' do
|
9
|
+
let(:cop_config) { { 'Max' => 1 } }
|
10
|
+
|
11
|
+
it 'accepts a method with no decision points' do
|
12
|
+
inspect_source(cop, ['def method_name',
|
13
|
+
' call_foo',
|
14
|
+
'end'])
|
15
|
+
expect(cop.offenses).to be_empty
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'accepts complex code outside of methods' do
|
19
|
+
inspect_source(cop,
|
20
|
+
['def method_name',
|
21
|
+
' call_foo',
|
22
|
+
'end',
|
23
|
+
'',
|
24
|
+
'if first_condition then',
|
25
|
+
' call_foo if second_condition && third_condition',
|
26
|
+
' call_bar if fourth_condition || fifth_condition',
|
27
|
+
'end'])
|
28
|
+
expect(cop.offenses).to be_empty
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'registers an offense for an if modifier' do
|
32
|
+
inspect_source(cop, ['def self.method_name',
|
33
|
+
' call_foo if some_condition',
|
34
|
+
'end'])
|
35
|
+
expect(cop.messages)
|
36
|
+
.to eq(['Perceived complexity for method_name is too high. [2/1]'])
|
37
|
+
expect(cop.highlights).to eq(['def'])
|
38
|
+
expect(cop.config_to_allow_offenses).to eq('Max' => 2)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'registers an offense for an unless modifier' do
|
42
|
+
inspect_source(cop, ['def method_name',
|
43
|
+
' call_foo unless some_condition',
|
44
|
+
'end'])
|
45
|
+
expect(cop.messages)
|
46
|
+
.to eq(['Perceived complexity for method_name is too high. [2/1]'])
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'registers an offense for elsif and else blocks' do
|
50
|
+
inspect_source(cop, ['def method_name',
|
51
|
+
' if first_condition then',
|
52
|
+
' call_foo',
|
53
|
+
' elsif second_condition then',
|
54
|
+
' call_bar',
|
55
|
+
' else',
|
56
|
+
' call_bam',
|
57
|
+
' end',
|
58
|
+
'end'])
|
59
|
+
expect(cop.messages)
|
60
|
+
.to eq(['Perceived complexity for method_name is too high. [4/1]'])
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'registers an offense for a ternary operator' do
|
64
|
+
inspect_source(cop, ['def method_name',
|
65
|
+
' value = some_condition ? 1 : 2',
|
66
|
+
'end'])
|
67
|
+
expect(cop.messages)
|
68
|
+
.to eq(['Perceived complexity for method_name is too high. [2/1]'])
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'registers an offense for a while block' do
|
72
|
+
inspect_source(cop, ['def method_name',
|
73
|
+
' while some_condition do',
|
74
|
+
' call_foo',
|
75
|
+
' end',
|
76
|
+
'end'])
|
77
|
+
expect(cop.messages)
|
78
|
+
.to eq(['Perceived complexity for method_name is too high. [2/1]'])
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'registers an offense for an until block' do
|
82
|
+
inspect_source(cop, ['def method_name',
|
83
|
+
' until some_condition do',
|
84
|
+
' call_foo',
|
85
|
+
' end',
|
86
|
+
'end'])
|
87
|
+
expect(cop.messages)
|
88
|
+
.to eq(['Perceived complexity for method_name is too high. [2/1]'])
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'registers an offense for a for block' do
|
92
|
+
inspect_source(cop, ['def method_name',
|
93
|
+
' for i in 1..2 do',
|
94
|
+
' call_method',
|
95
|
+
' end',
|
96
|
+
'end'])
|
97
|
+
expect(cop.messages)
|
98
|
+
.to eq(['Perceived complexity for method_name is too high. [2/1]'])
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'registers an offense for a rescue block' do
|
102
|
+
inspect_source(cop, ['def method_name',
|
103
|
+
' begin',
|
104
|
+
' call_foo',
|
105
|
+
' rescue Exception',
|
106
|
+
' call_bar',
|
107
|
+
' end',
|
108
|
+
'end'])
|
109
|
+
expect(cop.messages)
|
110
|
+
.to eq(['Perceived complexity for method_name is too high. [2/1]'])
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'registers an offense for a case/when block' do
|
114
|
+
inspect_source(cop, ['def method_name',
|
115
|
+
' case value',
|
116
|
+
' when 1 then call_foo_1',
|
117
|
+
' when 2 then call_foo_2',
|
118
|
+
' when 3 then call_foo_3',
|
119
|
+
' when 4 then call_foo_4',
|
120
|
+
' end',
|
121
|
+
'end'])
|
122
|
+
# The `case` node plus the first `when` score one complexity point
|
123
|
+
# together. The other `when` nodes get 0.2 complexity points.
|
124
|
+
expect(cop.messages)
|
125
|
+
.to eq(['Perceived complexity for method_name is too high. [3/1]'])
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'registers an offense for a case/when block without an expression ' \
|
129
|
+
'after case' do
|
130
|
+
inspect_source(cop, ['def method_name',
|
131
|
+
' case',
|
132
|
+
' when value == 1',
|
133
|
+
' call_foo',
|
134
|
+
' when value == 2',
|
135
|
+
' call_bar',
|
136
|
+
' end',
|
137
|
+
'end'])
|
138
|
+
# Here, the `case` node doesn't count, but each when scores one
|
139
|
+
# complexity point.
|
140
|
+
expect(cop.messages)
|
141
|
+
.to eq(['Perceived complexity for method_name is too high. [3/1]'])
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'registers an offense for &&' do
|
145
|
+
inspect_source(cop, ['def method_name',
|
146
|
+
' call_foo && call_bar',
|
147
|
+
'end'])
|
148
|
+
expect(cop.messages)
|
149
|
+
.to eq(['Perceived complexity for method_name is too high. [2/1]'])
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'registers an offense for and' do
|
153
|
+
inspect_source(cop, ['def method_name',
|
154
|
+
' call_foo and call_bar',
|
155
|
+
'end'])
|
156
|
+
expect(cop.messages)
|
157
|
+
.to eq(['Perceived complexity for method_name is too high. [2/1]'])
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'registers an offense for ||' do
|
161
|
+
inspect_source(cop, ['def method_name',
|
162
|
+
' call_foo || call_bar',
|
163
|
+
'end'])
|
164
|
+
expect(cop.messages)
|
165
|
+
.to eq(['Perceived complexity for method_name is too high. [2/1]'])
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'registers an offense for or' do
|
169
|
+
inspect_source(cop, ['def method_name',
|
170
|
+
' call_foo or call_bar',
|
171
|
+
'end'])
|
172
|
+
expect(cop.messages)
|
173
|
+
.to eq(['Perceived complexity for method_name is too high. [2/1]'])
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'deals with nested if blocks containing && and ||' do
|
177
|
+
inspect_source(cop,
|
178
|
+
['def method_name',
|
179
|
+
' if first_condition then',
|
180
|
+
' call_foo if second_condition && third_condition',
|
181
|
+
' call_bar if fourth_condition || fifth_condition',
|
182
|
+
' end',
|
183
|
+
'end'])
|
184
|
+
expect(cop.messages)
|
185
|
+
.to eq(['Perceived complexity for method_name is too high. [6/1]'])
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'counts only a single method' do
|
189
|
+
inspect_source(cop, ['def method_name_1',
|
190
|
+
' call_foo if some_condition',
|
191
|
+
'end',
|
192
|
+
'',
|
193
|
+
'def method_name_2',
|
194
|
+
' call_foo if some_condition',
|
195
|
+
'end'])
|
196
|
+
expect(cop.messages)
|
197
|
+
.to eq(['Perceived complexity for method_name_1 is too high. [2/1]',
|
198
|
+
'Perceived complexity for method_name_2 is too high. [2/1]'])
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context 'when Max is 2' do
|
203
|
+
let(:cop_config) { { 'Max' => 2 } }
|
204
|
+
|
205
|
+
it 'counts stupid nested if and else blocks' do
|
206
|
+
inspect_source(cop, ['def method_name', # 1
|
207
|
+
' if first_condition then', # 2
|
208
|
+
' call_foo',
|
209
|
+
' else', # 3
|
210
|
+
' if second_condition then', # 4
|
211
|
+
' call_bar',
|
212
|
+
' else', # 5
|
213
|
+
' call_bam if third_condition', # 6
|
214
|
+
' end',
|
215
|
+
' call_baz if fourth_condition', # 7
|
216
|
+
' end',
|
217
|
+
'end'])
|
218
|
+
expect(cop.messages)
|
219
|
+
.to eq(['Perceived complexity for method_name is too high. [7/2]'])
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|