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.

Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +12 -8
  3. data/.travis.yml +1 -1
  4. data/CHANGELOG.md +42 -0
  5. data/Gemfile +2 -0
  6. data/README.md +27 -6
  7. data/bin/rubocop +10 -15
  8. data/config/default.yml +72 -25
  9. data/config/enabled.yml +57 -25
  10. data/lib/rubocop.rb +15 -8
  11. data/lib/rubocop/config_loader.rb +11 -7
  12. data/lib/rubocop/cop/cop.rb +16 -16
  13. data/lib/rubocop/cop/ignored_node.rb +11 -4
  14. data/lib/rubocop/cop/lint/block_alignment.rb +29 -4
  15. data/lib/rubocop/cop/lint/debugger.rb +8 -1
  16. data/lib/rubocop/cop/lint/def_end_alignment.rb +5 -1
  17. data/lib/rubocop/cop/lint/end_alignment.rb +5 -5
  18. data/lib/rubocop/cop/lint/end_in_method.rb +2 -2
  19. data/lib/rubocop/cop/lint/useless_setter_call.rb +2 -2
  20. data/lib/rubocop/cop/{style → metrics}/block_nesting.rb +1 -1
  21. data/lib/rubocop/cop/{style → metrics}/class_length.rb +4 -4
  22. data/lib/rubocop/cop/{style → metrics}/cyclomatic_complexity.rb +5 -16
  23. data/lib/rubocop/cop/{style → metrics}/line_length.rb +1 -1
  24. data/lib/rubocop/cop/{style → metrics}/method_length.rb +8 -4
  25. data/lib/rubocop/cop/{style → metrics}/parameter_lists.rb +1 -1
  26. data/lib/rubocop/cop/metrics/perceived_complexity.rb +61 -0
  27. data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +10 -2
  28. data/lib/rubocop/cop/mixin/code_length.rb +2 -3
  29. data/lib/rubocop/cop/mixin/configurable_naming.rb +6 -20
  30. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  31. data/lib/rubocop/cop/mixin/if_node.rb +1 -1
  32. data/lib/rubocop/cop/mixin/method_complexity.rb +32 -0
  33. data/lib/rubocop/cop/mixin/negative_conditional.rb +1 -1
  34. data/lib/rubocop/cop/mixin/{check_methods.rb → on_method.rb} +3 -3
  35. data/lib/rubocop/cop/mixin/on_normal_if_unless.rb +24 -0
  36. data/lib/rubocop/cop/mixin/percent_literal.rb +2 -1
  37. data/lib/rubocop/cop/mixin/space_inside.rb +33 -4
  38. data/lib/rubocop/cop/mixin/statement_modifier.rb +14 -14
  39. data/lib/rubocop/cop/mixin/string_help.rb +4 -0
  40. data/lib/rubocop/cop/mixin/surrounding_space.rb +1 -0
  41. data/lib/rubocop/cop/rails/delegate.rb +2 -2
  42. data/lib/rubocop/cop/rails/output.rb +4 -2
  43. data/lib/rubocop/cop/style/accessor_method_name.rb +2 -2
  44. data/lib/rubocop/cop/style/align_hash.rb +9 -1
  45. data/lib/rubocop/cop/style/and_or.rb +37 -3
  46. data/lib/rubocop/cop/style/bare_percent_literals.rb +46 -0
  47. data/lib/rubocop/cop/style/block_end_newline.rb +56 -0
  48. data/lib/rubocop/cop/style/character_literal.rb +1 -1
  49. data/lib/rubocop/cop/style/def_with_parentheses.rb +2 -2
  50. data/lib/rubocop/cop/style/empty_lines_around_access_modifier.rb +31 -3
  51. data/lib/rubocop/cop/style/empty_lines_around_body.rb +6 -2
  52. data/lib/rubocop/cop/style/end_of_line.rb +3 -14
  53. data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -6
  54. data/lib/rubocop/cop/style/if_with_semicolon.rb +6 -7
  55. data/lib/rubocop/cop/style/indentation_width.rb +3 -8
  56. data/lib/rubocop/cop/style/method_def_parentheses.rb +2 -2
  57. data/lib/rubocop/cop/style/method_name.rb +4 -18
  58. data/lib/rubocop/cop/style/multiline_block_layout.rb +73 -0
  59. data/lib/rubocop/cop/style/multiline_if_then.rb +4 -4
  60. data/lib/rubocop/cop/style/negated_if.rb +1 -1
  61. data/lib/rubocop/cop/style/negated_while.rb +2 -2
  62. data/lib/rubocop/cop/style/next.rb +12 -0
  63. data/lib/rubocop/cop/style/one_line_conditional.rb +6 -6
  64. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +22 -8
  65. data/lib/rubocop/cop/style/percent_q_literals.rb +53 -0
  66. data/lib/rubocop/cop/style/predicate_name.rb +2 -2
  67. data/lib/rubocop/cop/style/redundant_begin.rb +2 -2
  68. data/lib/rubocop/cop/style/redundant_return.rb +2 -2
  69. data/lib/rubocop/cop/style/rescue_modifier.rb +7 -3
  70. data/lib/rubocop/cop/style/single_line_methods.rb +2 -2
  71. data/lib/rubocop/cop/style/space_after_method_name.rb +2 -2
  72. data/lib/rubocop/cop/style/space_inside_block_braces.rb +14 -10
  73. data/lib/rubocop/cop/style/space_inside_brackets.rb +5 -1
  74. data/lib/rubocop/cop/style/string_literals.rb +5 -8
  75. data/lib/rubocop/cop/style/trailing_comma.rb +15 -3
  76. data/lib/rubocop/cop/style/trivial_accessors.rb +2 -2
  77. data/lib/rubocop/cop/style/unneeded_capital_w.rb +2 -4
  78. data/lib/rubocop/cop/style/unneeded_percent_q.rb +13 -0
  79. data/lib/rubocop/cop/style/variable_interpolation.rb +14 -2
  80. data/lib/rubocop/cop/style/variable_name.rb +17 -17
  81. data/lib/rubocop/cop/style/while_until_modifier.rb +2 -5
  82. data/lib/rubocop/cop/util.rb +5 -0
  83. data/lib/rubocop/cop/variable_force.rb +7 -6
  84. data/lib/rubocop/formatter/base_formatter.rb +2 -2
  85. data/lib/rubocop/processed_source.rb +5 -22
  86. data/lib/rubocop/version.rb +1 -1
  87. data/relnotes/v0.25.0.md +91 -0
  88. data/rubocop.gemspec +2 -3
  89. data/spec/project_spec.rb +1 -1
  90. data/spec/rubocop/cli_spec.rb +70 -44
  91. data/spec/rubocop/comment_config_spec.rb +6 -6
  92. data/spec/rubocop/config_loader_spec.rb +19 -13
  93. data/spec/rubocop/config_spec.rb +3 -3
  94. data/spec/rubocop/cop/commissioner_spec.rb +1 -1
  95. data/spec/rubocop/cop/cop_spec.rb +3 -3
  96. data/spec/rubocop/cop/lint/block_alignment_spec.rb +113 -6
  97. data/spec/rubocop/cop/lint/debugger_spec.rb +10 -6
  98. data/spec/rubocop/cop/lint/useless_assignment_spec.rb +12 -0
  99. data/spec/rubocop/cop/{style → metrics}/block_nesting_spec.rb +1 -1
  100. data/spec/rubocop/cop/{style → metrics}/class_length_spec.rb +1 -1
  101. data/spec/rubocop/cop/{style → metrics}/cyclomatic_complexity_spec.rb +1 -1
  102. data/spec/rubocop/cop/{style → metrics}/if_unless_modifier_spec.rb +2 -2
  103. data/spec/rubocop/cop/{style → metrics}/line_length_spec.rb +7 -7
  104. data/spec/rubocop/cop/{style → metrics}/method_length_spec.rb +1 -1
  105. data/spec/rubocop/cop/{style → metrics}/parameter_lists_spec.rb +1 -1
  106. data/spec/rubocop/cop/metrics/perceived_complexity_spec.rb +222 -0
  107. data/spec/rubocop/cop/{style → metrics}/while_until_modifier_spec.rb +2 -2
  108. data/spec/rubocop/cop/rails/output_spec.rb +8 -2
  109. data/spec/rubocop/cop/style/align_hash_spec.rb +7 -0
  110. data/spec/rubocop/cop/style/and_or_spec.rb +245 -43
  111. data/spec/rubocop/cop/style/bare_percent_literals_spec.rb +132 -0
  112. data/spec/rubocop/cop/style/block_end_newline_spec.rb +61 -0
  113. data/spec/rubocop/cop/style/empty_lines_around_access_modifier_spec.rb +34 -0
  114. data/spec/rubocop/cop/style/end_of_line_spec.rb +8 -0
  115. data/spec/rubocop/cop/style/guard_clause_spec.rb +1 -1
  116. data/spec/rubocop/cop/style/multiline_block_layout_spec.rb +138 -0
  117. data/spec/rubocop/cop/style/next_spec.rb +32 -3
  118. data/spec/rubocop/cop/style/percent_literal_delimiters_spec.rb +34 -0
  119. data/spec/rubocop/cop/style/percent_q_literals_spec.rb +122 -0
  120. data/spec/rubocop/cop/style/space_inside_block_braces_spec.rb +20 -0
  121. data/spec/rubocop/cop/style/space_inside_brackets_spec.rb +26 -2
  122. data/spec/rubocop/cop/style/trailing_comma_spec.rb +112 -0
  123. data/spec/rubocop/cop/style/unneeded_percent_q_spec.rb +86 -31
  124. data/spec/rubocop/cop/style/variable_interpolation_spec.rb +21 -1
  125. data/spec/rubocop/cop/team_spec.rb +14 -9
  126. data/spec/spec_helper.rb +1 -0
  127. metadata +47 -50
  128. data/lib/rubocop/cop/mixin/if_then_else.rb +0 -23
@@ -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
- 'Style/LineLength:',
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 Style\/LineLength:Min/)
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
- 'Style/LineLength:',
62
+ 'Metrics/LineLength:',
63
63
  ' Exclude:',
64
64
  ' - lib/file.rb',
65
65
  ' Include:',
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
- # rubocop:disable Style/LineLength
2
+ # rubocop:disable Metrics/LineLength
3
3
 
4
4
  require 'spec_helper'
5
5
 
@@ -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('Style/LineLength')
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('Style/LineLength', '--only'))
30
- .to eq('Style/LineLength')
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 Style/LineLength
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
- it 'registers an offense for mismatched block end' do
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
- ['test do |ala|',
12
- ' end'
51
+ [' scope :bar, lambda { joins(:baz)',
52
+ ' .distinct }'
13
53
  ])
14
- expect(cop.messages)
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(2)
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
- expect(cop.highlights).to eq(['binding.pry', 'binding.remote_pry'])
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
  [
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe RuboCop::Cop::Style::BlockNesting, :config do
5
+ describe RuboCop::Cop::Metrics::BlockNesting, :config do
6
6
  subject(:cop) { described_class.new(config) }
7
7
  let(:cop_config) { { 'Max' => 2 } }
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe RuboCop::Cop::Style::ClassLength, :config do
5
+ describe RuboCop::Cop::Metrics::ClassLength, :config do
6
6
  subject(:cop) { described_class.new(config) }
7
7
  let(:cop_config) { { 'Max' => 5, 'CountComments' => false } }
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe RuboCop::Cop::Style::CyclomaticComplexity, :config do
5
+ describe RuboCop::Cop::Metrics::CyclomaticComplexity, :config do
6
6
  subject(:cop) { described_class.new(config) }
7
7
 
8
8
  context 'when Max is 1' do
@@ -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 = { 'Style/LineLength' => { 'Max' => 80 } }
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
- 'Style/LineLength' => { 'Max' => 100 },
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::Style::LineLength, :config do
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 Style/LineLength
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 Style/LineLength
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 Style/LineLength
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 Style/LineLength
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 Style/LineLength
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 Style/LineLength
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
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe RuboCop::Cop::Style::MethodLength, :config do
5
+ describe RuboCop::Cop::Metrics::MethodLength, :config do
6
6
  subject(:cop) { described_class.new(config) }
7
7
  let(:cop_config) { { 'Max' => 5, 'CountComments' => false } }
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe RuboCop::Cop::Style::ParameterLists, :config do
5
+ describe RuboCop::Cop::Metrics::ParameterLists, :config do
6
6
  subject(:cop) { described_class.new(config) }
7
7
  let(:cop_config) do
8
8
  {
@@ -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