rubocop 0.14.1 → 0.15.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 (109) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -3
  3. data/CHANGELOG.md +245 -198
  4. data/README.md +7 -0
  5. data/Rakefile +5 -1
  6. data/config/default.yml +27 -4
  7. data/config/enabled.yml +18 -4
  8. data/lib/rubocop.rb +13 -1
  9. data/lib/rubocop/cli.rb +83 -23
  10. data/lib/rubocop/config.rb +1 -1
  11. data/lib/rubocop/cop/cop.rb +31 -6
  12. data/lib/rubocop/cop/lint/block_alignment.rb +11 -8
  13. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +21 -14
  14. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  15. data/lib/rubocop/cop/rails/output.rb +35 -0
  16. data/lib/rubocop/cop/style/{access_control.rb → access_modifier_indentation.rb} +18 -15
  17. data/lib/rubocop/cop/style/alias.rb +14 -2
  18. data/lib/rubocop/cop/style/align_hash.rb +174 -109
  19. data/lib/rubocop/cop/style/autocorrect_alignment.rb +38 -18
  20. data/lib/rubocop/cop/style/blocks.rb +4 -6
  21. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +3 -3
  22. data/lib/rubocop/cop/style/cyclomatic_complexity.rb +46 -0
  23. data/lib/rubocop/cop/style/empty_lines_around_access_modifier.rb +48 -0
  24. data/lib/rubocop/cop/style/empty_lines_around_body.rb +62 -0
  25. data/lib/rubocop/cop/style/end_of_line.rb +6 -2
  26. data/lib/rubocop/cop/style/favor_modifier.rb +11 -1
  27. data/lib/rubocop/cop/style/final_newline.rb +10 -4
  28. data/lib/rubocop/cop/style/hash_syntax.rb +32 -21
  29. data/lib/rubocop/cop/style/leading_comment_space.rb +9 -0
  30. data/lib/rubocop/cop/style/method_call_parentheses.rb +11 -1
  31. data/lib/rubocop/cop/style/numeric_literals.rb +11 -15
  32. data/lib/rubocop/cop/style/redundant_return.rb +7 -4
  33. data/lib/rubocop/cop/style/redundant_self.rb +3 -3
  34. data/lib/rubocop/cop/style/signal_exception.rb +4 -2
  35. data/lib/rubocop/cop/style/space_after_comma_etc.rb +7 -1
  36. data/lib/rubocop/cop/style/space_after_control_keyword.rb +6 -0
  37. data/lib/rubocop/cop/style/space_after_method_name.rb +7 -1
  38. data/lib/rubocop/cop/style/space_after_not.rb +6 -2
  39. data/lib/rubocop/cop/style/space_around_block_braces.rb +149 -0
  40. data/lib/rubocop/cop/style/space_around_equals_in_parameter_default.rb +33 -0
  41. data/lib/rubocop/cop/style/space_around_operators.rb +169 -0
  42. data/lib/rubocop/cop/style/space_before_modifier_keyword.rb +6 -0
  43. data/lib/rubocop/cop/style/space_inside.rb +35 -0
  44. data/lib/rubocop/cop/style/space_inside_brackets.rb +18 -0
  45. data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +99 -0
  46. data/lib/rubocop/cop/style/space_inside_parens.rb +18 -0
  47. data/lib/rubocop/cop/style/special_global_vars.rb +52 -25
  48. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  49. data/lib/rubocop/cop/style/surrounding_space.rb +1 -344
  50. data/lib/rubocop/cop/style/trailing_blank_lines.rb +17 -5
  51. data/lib/rubocop/cop/style/trailing_whitespace.rb +9 -5
  52. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -2
  53. data/lib/rubocop/cop/style/word_array.rb +16 -1
  54. data/lib/rubocop/cop/team.rb +5 -5
  55. data/lib/rubocop/cop/util.rb +1 -0
  56. data/lib/rubocop/formatter/offence_count_formatter.rb +0 -1
  57. data/lib/rubocop/options.rb +76 -111
  58. data/lib/rubocop/rake_task.rb +4 -2
  59. data/lib/rubocop/target_finder.rb +3 -3
  60. data/lib/rubocop/version.rb +1 -1
  61. data/spec/rubocop/cli_spec.rb +123 -13
  62. data/spec/rubocop/config_spec.rb +2 -2
  63. data/spec/rubocop/cop/lint/rescue_exception_spec.rb +10 -0
  64. data/spec/rubocop/cop/lint/useless_setter_call_spec.rb +13 -0
  65. data/spec/rubocop/cop/offence_spec.rb +2 -0
  66. data/spec/rubocop/cop/rails/output_spec.rb +40 -0
  67. data/spec/rubocop/cop/style/access_modifier_indentation_spec.rb +243 -0
  68. data/spec/rubocop/cop/style/alias_spec.rb +8 -0
  69. data/spec/rubocop/cop/style/align_array_spec.rb +12 -0
  70. data/spec/rubocop/cop/style/align_hash_spec.rb +15 -0
  71. data/spec/rubocop/cop/style/braces_around_hash_parameters_spec.rb +7 -4
  72. data/spec/rubocop/cop/style/cyclomatic_complexity_spec.rb +203 -0
  73. data/spec/rubocop/cop/style/empty_lines_around_access_modifier_spec.rb +56 -0
  74. data/spec/rubocop/cop/style/empty_lines_around_body_spec.rb +87 -0
  75. data/spec/rubocop/cop/style/end_of_line_spec.rb +17 -8
  76. data/spec/rubocop/cop/style/favor_modifier_spec.rb +34 -0
  77. data/spec/rubocop/cop/style/final_newline_spec.rb +5 -0
  78. data/spec/rubocop/cop/style/hash_syntax_spec.rb +22 -2
  79. data/spec/rubocop/cop/style/leading_comment_space_spec.rb +5 -0
  80. data/spec/rubocop/cop/style/method_call_parentheses_spec.rb +39 -4
  81. data/spec/rubocop/cop/style/numeric_literals_spec.rb +5 -0
  82. data/spec/rubocop/cop/style/signal_exception_spec.rb +11 -0
  83. data/spec/rubocop/cop/style/space_after_colon_spec.rb +7 -0
  84. data/spec/rubocop/cop/style/space_after_comma_spec.rb +5 -0
  85. data/spec/rubocop/cop/style/space_after_control_keyword_spec.rb +29 -8
  86. data/spec/rubocop/cop/style/space_after_method_name_spec.rb +15 -0
  87. data/spec/rubocop/cop/style/space_after_semicolon_spec.rb +5 -0
  88. data/spec/rubocop/cop/style/space_around_block_braces_spec.rb +68 -0
  89. data/spec/rubocop/cop/style/space_around_equals_in_default_parameter_spec.rb +5 -0
  90. data/spec/rubocop/cop/style/space_around_operators_spec.rb +43 -0
  91. data/spec/rubocop/cop/style/space_before_modifier_keyword_spec.rb +23 -0
  92. data/spec/rubocop/cop/style/space_inside_brackets_spec.rb +7 -0
  93. data/spec/rubocop/cop/style/space_inside_hash_literal_braces_spec.rb +65 -23
  94. data/spec/rubocop/cop/style/space_inside_parens_spec.rb +7 -0
  95. data/spec/rubocop/cop/style/special_global_vars_spec.rb +12 -2
  96. data/spec/rubocop/cop/style/string_literals_spec.rb +6 -0
  97. data/spec/rubocop/cop/style/symbol_array_spec.rb +5 -7
  98. data/spec/rubocop/cop/style/trailing_blank_lines_spec.rb +26 -1
  99. data/spec/rubocop/cop/style/trailing_whitespace_spec.rb +7 -0
  100. data/spec/rubocop/cop/style/trivial_accessors_spec.rb +8 -0
  101. data/spec/rubocop/cop/style/word_array_spec.rb +33 -2
  102. data/spec/rubocop/cop/team_spec.rb +4 -4
  103. data/spec/rubocop/formatter/json_formatter_spec.rb +1 -1
  104. data/spec/rubocop/options_spec.rb +5 -96
  105. data/spec/rubocop/processed_source_spec.rb +3 -3
  106. data/spec/spec_helper.rb +28 -23
  107. data/spec/support/mri_syntax_checker.rb +20 -16
  108. metadata +24 -5
  109. data/spec/rubocop/cop/style/access_control_spec.rb +0 -164
@@ -13,8 +13,8 @@ describe Rubocop::Config do
13
13
  # TODO: Because Config.load_file now outputs the validation warning,
14
14
  # it is inserting text into the rspec test output here.
15
15
  # The next 2 lines should be removed eventually.
16
- before(:each) { $stdout = StringIO.new }
17
- after(:each) { $stdout = STDOUT }
16
+ before(:each) { $stderr = StringIO.new }
17
+ after(:each) { $stderr = STDERR }
18
18
 
19
19
  subject(:configuration) do
20
20
  Rubocop::ConfigLoader.load_file(configuration_path)
@@ -118,4 +118,14 @@ describe Rubocop::Cop::Lint::RescueException do
118
118
  'end'])
119
119
  expect(cop.offences).to be_empty
120
120
  end
121
+
122
+ it 'does not crash when the namespace of a rescued class is in a local ' +
123
+ 'variable' do
124
+ inspect_source(cop,
125
+ ['adapter = current_adapter',
126
+ 'begin',
127
+ 'rescue adapter::ParseError',
128
+ 'end'])
129
+ expect(cop.offences).to be_empty
130
+ end
121
131
  end
@@ -84,6 +84,19 @@ describe Rubocop::Cop::Lint::UselessSetterCall do
84
84
  end
85
85
  end
86
86
 
87
+ context 'when a lvar does not have any object passed as argument ' +
88
+ 'with multiple-assignment at the end of the method' do
89
+ it 'registers an offence' do
90
+ inspect_source(cop,
91
+ ['def test(some_arg)',
92
+ ' _first, some_lvar, _third = do_something',
93
+ ' some_lvar.attr = 5',
94
+ 'end'
95
+ ])
96
+ expect(cop.offences.size).to eq(1)
97
+ end
98
+ end
99
+
87
100
  context 'when a lvar possibly has an object passed as argument ' +
88
101
  'by logical-operator-assignment at the end of the method' do
89
102
  it 'accepts the lvar attr assignment' do
@@ -107,6 +107,8 @@ describe Rubocop::Cop::Offence do
107
107
  Parser::Source::Range.new(source_buffer, begin_pos, begin_pos + 1)
108
108
  end
109
109
 
110
+ # We want a nice table layout, so we allow space inside empty hashes.
111
+ # rubocop:disable SpaceInsideHashLiteralBraces
110
112
  [
111
113
  [{ }, { }, 0],
112
114
 
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rubocop::Cop::Rails::Output, :config do
6
+ subject(:cop) { described_class.new(config) }
7
+ let(:cop_config) { { 'Ignore' => ['^.*\.rake$'] } }
8
+
9
+ it 'should record an offence for puts statements' do
10
+ source = ['p "edmond dantes"',
11
+ 'puts "sinbad"',
12
+ 'print "abbe busoni"',
13
+ 'pp "monte cristo"']
14
+ inspect_source(cop, source)
15
+ expect(cop.offences.size).to eq(4)
16
+ end
17
+
18
+ it 'should not record an offence for methods' do
19
+ source = ['obj.print',
20
+ 'something.p',
21
+ 'nothing.pp']
22
+ inspect_source(cop, source)
23
+ expect(cop.offences).to be_empty
24
+ end
25
+
26
+ it 'should not record an offence for comments' do
27
+ source = ['# print "test"',
28
+ '# p']
29
+ inspect_source(cop, source)
30
+ expect(cop.offences).to be_empty
31
+ end
32
+
33
+ it 'should ignore certain files' do
34
+ source = ['print 1']
35
+ processed_source = parse_source(source)
36
+ processed_source.buffer.stub(:name).and_return('/var/lib/test.rake')
37
+ _investigate(cop, processed_source)
38
+ expect(cop.offences).to be_empty
39
+ end
40
+ end
@@ -0,0 +1,243 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rubocop::Cop::Style::AccessModifierIndentation, :config do
6
+ subject(:cop) { described_class.new(config) }
7
+
8
+ context 'when IndentDepth is set to method' do
9
+ let(:cop_config) { { 'EnforcedStyle' => 'indent' } }
10
+
11
+ it 'registers an offence for misaligned private' do
12
+ inspect_source(cop,
13
+ ['class Test',
14
+ '',
15
+ 'private',
16
+ '',
17
+ ' def test; end',
18
+ 'end'])
19
+ expect(cop.offences.size).to eq(1)
20
+ expect(cop.messages)
21
+ .to eq(['Indent access modifiers like private.'])
22
+ end
23
+
24
+ it 'registers an offence for misaligned private in module' do
25
+ inspect_source(cop,
26
+ ['module Test',
27
+ '',
28
+ 'private',
29
+ '',
30
+ ' def test; end',
31
+ 'end'])
32
+ expect(cop.offences.size).to eq(1)
33
+ expect(cop.messages)
34
+ .to eq(['Indent access modifiers like private.'])
35
+ end
36
+
37
+ it 'registers an offence for misaligned private in singleton class' do
38
+ inspect_source(cop,
39
+ ['class << self',
40
+ '',
41
+ 'private',
42
+ '',
43
+ ' def test; end',
44
+ 'end'])
45
+ expect(cop.offences.size).to eq(1)
46
+ expect(cop.messages)
47
+ .to eq(['Indent access modifiers like private.'])
48
+ end
49
+
50
+ it 'registers an offence for misaligned private in class ' +
51
+ 'defined with Class.new' do
52
+ inspect_source(cop,
53
+ ['Test = Class.new do',
54
+ '',
55
+ 'private',
56
+ '',
57
+ ' def test; end',
58
+ 'end'])
59
+ expect(cop.offences.size).to eq(1)
60
+ expect(cop.messages)
61
+ .to eq(['Indent access modifiers like private.'])
62
+ end
63
+
64
+ it 'registers an offence for misaligned private in module ' +
65
+ 'defined with Module.new' do
66
+ inspect_source(cop,
67
+ ['Test = Module.new do',
68
+ '',
69
+ 'private',
70
+ '',
71
+ ' def test; end',
72
+ 'end'])
73
+ expect(cop.offences.size).to eq(1)
74
+ expect(cop.messages)
75
+ .to eq(['Indent access modifiers like private.'])
76
+ end
77
+
78
+ it 'registers an offence for misaligned protected' do
79
+ inspect_source(cop,
80
+ ['class Test',
81
+ '',
82
+ 'protected',
83
+ '',
84
+ ' def test; end',
85
+ 'end'])
86
+ expect(cop.offences.size).to eq(1)
87
+ expect(cop.messages)
88
+ .to eq(['Indent access modifiers like protected.'])
89
+ end
90
+
91
+ it 'accepts properly indented private' do
92
+ inspect_source(cop,
93
+ ['class Test',
94
+ '',
95
+ ' private',
96
+ '',
97
+ ' def test; end',
98
+ 'end'])
99
+ expect(cop.offences).to be_empty
100
+ end
101
+
102
+ it 'accepts properly indented protected' do
103
+ inspect_source(cop,
104
+ ['class Test',
105
+ '',
106
+ ' protected',
107
+ '',
108
+ ' def test; end',
109
+ 'end'])
110
+ expect(cop.offences).to be_empty
111
+ end
112
+
113
+ it 'handles properly nested classes' do
114
+ inspect_source(cop,
115
+ ['class Test',
116
+ '',
117
+ ' class Nested',
118
+ '',
119
+ ' private',
120
+ '',
121
+ ' def a; end',
122
+ ' end',
123
+ '',
124
+ ' protected',
125
+ '',
126
+ ' def test; end',
127
+ 'end'])
128
+ expect(cop.offences.size).to eq(1)
129
+ expect(cop.messages)
130
+ .to eq(['Indent access modifiers like private.'])
131
+ end
132
+ end
133
+
134
+ context 'when IndentDepth is set to class' do
135
+ let(:cop_config) { { 'EnforcedStyle' => 'outdent' } }
136
+ let(:indent_msg) { 'Outdent access modifiers like private.' }
137
+ let(:blank_msg) { 'Keep a blank line before and after private.' }
138
+
139
+ it 'registers offence for private indented to method depth in a class' do
140
+ inspect_source(cop,
141
+ ['class Test',
142
+ '',
143
+ ' private',
144
+ '',
145
+ ' def test; end',
146
+ 'end'])
147
+ expect(cop.offences.size).to eq(1)
148
+ expect(cop.messages).to eq([indent_msg])
149
+ end
150
+
151
+ it 'registers offence for private indented to method depth in a module' do
152
+ inspect_source(cop,
153
+ ['module Test',
154
+ '',
155
+ ' private',
156
+ '',
157
+ ' def test; end',
158
+ 'end'])
159
+ expect(cop.offences.size).to eq(1)
160
+ expect(cop.messages).to eq([indent_msg])
161
+ end
162
+
163
+ it 'registers offence for private indented to method depth in singleton' +
164
+ 'class' do
165
+ inspect_source(cop,
166
+ ['class << self',
167
+ '',
168
+ ' private',
169
+ '',
170
+ ' def test; end',
171
+ 'end'])
172
+ expect(cop.offences.size).to eq(1)
173
+ expect(cop.messages).to eq([indent_msg])
174
+ end
175
+
176
+ it 'registers offence for private indented to method depth in class ' +
177
+ 'defined with Class.new' do
178
+ inspect_source(cop,
179
+ ['Test = Class.new do',
180
+ '',
181
+ ' private',
182
+ '',
183
+ ' def test; end',
184
+ 'end'])
185
+ expect(cop.offences.size).to eq(1)
186
+ expect(cop.messages).to eq([indent_msg])
187
+ end
188
+
189
+ it 'registers offence for private indented to method depth in module ' +
190
+ 'defined with Module.new' do
191
+ inspect_source(cop,
192
+ ['Test = Module.new do',
193
+ '',
194
+ ' private',
195
+ '',
196
+ ' def test; end',
197
+ 'end'])
198
+ expect(cop.offences.size).to eq(1)
199
+ expect(cop.messages).to eq([indent_msg])
200
+ end
201
+
202
+ it 'accepts private indented to the containing class indent level' do
203
+ inspect_source(cop,
204
+ ['class Test',
205
+ '',
206
+ 'private',
207
+ '',
208
+ ' def test; end',
209
+ 'end'])
210
+ expect(cop.offences).to be_empty
211
+ end
212
+
213
+ it 'accepts protected indented to the containing class indent level' do
214
+ inspect_source(cop,
215
+ ['class Test',
216
+ '',
217
+ 'protected',
218
+ '',
219
+ ' def test; end',
220
+ 'end'])
221
+ expect(cop.offences).to be_empty
222
+ end
223
+
224
+ it 'handles properly nested classes' do
225
+ inspect_source(cop,
226
+ ['class Test',
227
+ '',
228
+ ' class Nested',
229
+ '',
230
+ ' private',
231
+ '',
232
+ ' def a; end',
233
+ ' end',
234
+ '',
235
+ 'protected',
236
+ '',
237
+ ' def test; end',
238
+ 'end'])
239
+ expect(cop.offences.size).to eq(1)
240
+ expect(cop.messages).to eq([indent_msg])
241
+ end
242
+ end
243
+ end
@@ -38,4 +38,12 @@ describe Rubocop::Cop::Style::Alias do
38
38
  ['alias $ala $bala'])
39
39
  expect(cop.offences).to be_empty
40
40
  end
41
+
42
+ it 'accepts alias in an instance_exec block' do
43
+ inspect_source(cop,
44
+ ['cli.instance_exec do',
45
+ ' alias :old_trap_interrupt :trap_interrupt',
46
+ 'end'])
47
+ expect(cop.offences).to be_empty
48
+ end
41
49
  end
@@ -54,6 +54,18 @@ describe Rubocop::Cop::Style::AlignArray do
54
54
  ']'].join("\n"))
55
55
  end
56
56
 
57
+ it 'auto-corrects array within array' do
58
+ original_source = ['[:l1,',
59
+ ' [:l2,',
60
+ ' [:l3,',
61
+ ' [:l4]]]]']
62
+ new_source = autocorrect_source(cop, original_source)
63
+ expect(new_source).to eq(['[:l1,',
64
+ ' [:l2,',
65
+ ' [:l3,',
66
+ ' [:l4]]]]'].join("\n"))
67
+ end
68
+
57
69
  it 'auto-corrects only elements that begin a line' do
58
70
  original_source = ['array = [:bar, {',
59
71
  ' whiz: 2, bang: 3 }, option: 3]']
@@ -80,6 +80,11 @@ describe Rubocop::Cop::Style::AlignHash, :config do
80
80
  ' b: 1)'])
81
81
  expect(cop.offences).to be_empty
82
82
  end
83
+
84
+ it 'accepts an empty hash' do
85
+ inspect_source(cop, 'h = {}')
86
+ expect(cop.offences).to be_empty
87
+ end
83
88
  end
84
89
 
85
90
  it 'auto-corrects alignment' do
@@ -126,6 +131,11 @@ describe Rubocop::Cop::Style::AlignHash, :config do
126
131
  expect(cop.offences).to be_empty
127
132
  end
128
133
 
134
+ it 'accepts an empty hash' do
135
+ inspect_source(cop, 'h = {}')
136
+ expect(cop.offences).to be_empty
137
+ end
138
+
129
139
  it 'registers an offence for misaligned hash values' do
130
140
  inspect_source(cop, ['hash1 = {',
131
141
  " 'a' => 0,",
@@ -214,6 +224,11 @@ describe Rubocop::Cop::Style::AlignHash, :config do
214
224
  expect(cop.offences).to be_empty
215
225
  end
216
226
 
227
+ it 'accepts an empty hash' do
228
+ inspect_source(cop, 'h = {}')
229
+ expect(cop.offences).to be_empty
230
+ end
231
+
217
232
  it 'registers an offence for misaligned hash values' do
218
233
  inspect_source(cop, ['hash = {',
219
234
  " 'a' => 0,",
@@ -71,14 +71,17 @@ describe Rubocop::Cop::Style::BracesAroundHashParameters, :config do
71
71
  expect(cop.highlights).to be_empty
72
72
  end
73
73
 
74
+ end
75
+
76
+ describe 'registers an offence for' do
74
77
  it 'one non-hash parameter followed by a hash parameter with braces' do
75
78
  inspect_source(cop, ['where(1, { y: 2 })'])
76
- expect(cop.messages).to be_empty
77
- expect(cop.highlights).to be_empty
79
+ expect(cop.messages).to eq([
80
+ 'Redundant curly braces around a hash parameter.'
81
+ ])
82
+ expect(cop.highlights).to eq(['{ y: 2 }'])
78
83
  end
79
- end
80
84
 
81
- describe 'registers an offence for' do
82
85
  it 'one object method hash parameter with braces' do
83
86
  inspect_source(cop, ['x.func({ y: "z" })'])
84
87
  expect(cop.messages).to eq([
@@ -0,0 +1,203 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rubocop::Cop::Style::CyclomaticComplexity, :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.offences).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.offences).to be_empty
29
+ end
30
+
31
+ it 'registers an offence 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(['Cyclomatic complexity for method_name is too high. [2/1]'])
37
+ expect(cop.highlights).to eq(['def'])
38
+ end
39
+
40
+ it 'registers an offence for an unless modifier' do
41
+ inspect_source(cop, ['def method_name',
42
+ ' call_foo unless some_condition',
43
+ 'end'])
44
+ expect(cop.messages)
45
+ .to eq(['Cyclomatic complexity for method_name is too high. [2/1]'])
46
+ end
47
+
48
+ it 'registers an offence for an elsif block' do
49
+ inspect_source(cop, ['def method_name',
50
+ ' if first_condition then',
51
+ ' call_foo',
52
+ ' elsif second_condition then',
53
+ ' call_bar',
54
+ ' else',
55
+ ' call_bam',
56
+ ' end',
57
+ 'end'])
58
+ expect(cop.messages)
59
+ .to eq(['Cyclomatic complexity for method_name is too high. [3/1]'])
60
+ end
61
+
62
+ it 'registers an offence for a ternary operator' do
63
+ inspect_source(cop, ['def method_name',
64
+ ' value = some_condition ? 1 : 2',
65
+ 'end'])
66
+ expect(cop.messages)
67
+ .to eq(['Cyclomatic complexity for method_name is too high. [2/1]'])
68
+ end
69
+
70
+ it 'registers an offence for a while block' do
71
+ inspect_source(cop, ['def method_name',
72
+ ' while some_condition do',
73
+ ' call_foo',
74
+ ' end',
75
+ 'end'])
76
+ expect(cop.messages)
77
+ .to eq(['Cyclomatic complexity for method_name is too high. [2/1]'])
78
+ end
79
+
80
+ it 'registers an offence for an until block' do
81
+ inspect_source(cop, ['def method_name',
82
+ ' until some_condition do',
83
+ ' call_foo',
84
+ ' end',
85
+ 'end'])
86
+ expect(cop.messages)
87
+ .to eq(['Cyclomatic complexity for method_name is too high. [2/1]'])
88
+ end
89
+
90
+ it 'registers an offence for a for block' do
91
+ inspect_source(cop, ['def method_name',
92
+ ' for i in 1..2 do',
93
+ ' call_method',
94
+ ' end',
95
+ 'end'])
96
+ expect(cop.messages)
97
+ .to eq(['Cyclomatic complexity for method_name is too high. [2/1]'])
98
+ end
99
+
100
+ it 'registers an offence for a rescue block' do
101
+ inspect_source(cop, ['def method_name',
102
+ ' begin',
103
+ ' call_foo',
104
+ ' rescue Exception',
105
+ ' call_bar',
106
+ ' end',
107
+ 'end'])
108
+ expect(cop.messages)
109
+ .to eq(['Cyclomatic complexity for method_name is too high. [2/1]'])
110
+ end
111
+
112
+ it 'registers an offence for a case/when block' do
113
+ inspect_source(cop, ['def method_name',
114
+ ' case value',
115
+ ' when 1',
116
+ ' call_foo',
117
+ ' when 2',
118
+ ' call_bar',
119
+ ' end',
120
+ 'end'])
121
+ expect(cop.messages)
122
+ .to eq(['Cyclomatic complexity for method_name is too high. [3/1]'])
123
+ end
124
+
125
+ it 'registers an offence for &&' do
126
+ inspect_source(cop, ['def method_name',
127
+ ' call_foo && call_bar',
128
+ 'end'])
129
+ expect(cop.messages)
130
+ .to eq(['Cyclomatic complexity for method_name is too high. [2/1]'])
131
+ end
132
+
133
+ it 'registers an offence for and' do
134
+ inspect_source(cop, ['def method_name',
135
+ ' call_foo and call_bar',
136
+ 'end'])
137
+ expect(cop.messages)
138
+ .to eq(['Cyclomatic complexity for method_name is too high. [2/1]'])
139
+ end
140
+
141
+ it 'registers an offence for ||' do
142
+ inspect_source(cop, ['def method_name',
143
+ ' call_foo || call_bar',
144
+ 'end'])
145
+ expect(cop.messages)
146
+ .to eq(['Cyclomatic complexity for method_name is too high. [2/1]'])
147
+ end
148
+
149
+ it 'registers an offence for or' do
150
+ inspect_source(cop, ['def method_name',
151
+ ' call_foo or call_bar',
152
+ 'end'])
153
+ expect(cop.messages)
154
+ .to eq(['Cyclomatic complexity for method_name is too high. [2/1]'])
155
+ end
156
+
157
+ it 'deals with nested if blocks containing && and ||' do
158
+ inspect_source(cop,
159
+ ['def method_name',
160
+ ' if first_condition then',
161
+ ' call_foo if second_condition && third_condition',
162
+ ' call_bar if fourth_condition || fifth_condition',
163
+ ' end',
164
+ 'end'])
165
+ expect(cop.messages)
166
+ .to eq(['Cyclomatic complexity for method_name is too high. [6/1]'])
167
+ end
168
+
169
+ it 'counts only a single method' do
170
+ inspect_source(cop, ['def method_name_1',
171
+ ' call_foo if some_condition',
172
+ 'end',
173
+ '',
174
+ 'def method_name_2',
175
+ ' call_foo if some_condition',
176
+ 'end'])
177
+ expect(cop.messages)
178
+ .to eq(['Cyclomatic complexity for method_name_1 is too high. [2/1]',
179
+ 'Cyclomatic complexity for method_name_2 is too high. [2/1]'])
180
+ end
181
+ end
182
+
183
+ context 'when Max is 2' do
184
+ let(:cop_config) { { 'Max' => 2 } }
185
+
186
+ it 'counts stupid nested if and else blocks' do
187
+ inspect_source(cop, ['def method_name',
188
+ ' if first_condition then',
189
+ ' call_foo',
190
+ ' else',
191
+ ' if second_condition then',
192
+ ' call_bar',
193
+ ' else',
194
+ ' call_bam if third_condition',
195
+ ' end',
196
+ ' call_baz if fourth_condition',
197
+ ' end',
198
+ 'end'])
199
+ expect(cop.messages)
200
+ .to eq(['Cyclomatic complexity for method_name is too high. [5/2]'])
201
+ end
202
+ end
203
+ end