rubocop 0.9.0 → 0.9.1

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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/README.md +1 -0
  4. data/config/default.yml +12 -0
  5. data/config/enabled.yml +0 -1
  6. data/lib/rubocop.rb +3 -0
  7. data/lib/rubocop/cli.rb +7 -1
  8. data/lib/rubocop/cop/cop.rb +20 -5
  9. data/lib/rubocop/cop/lint/end_alignment.rb +51 -42
  10. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  11. data/lib/rubocop/cop/lint/literal_in_condition.rb +59 -9
  12. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -0
  13. data/lib/rubocop/cop/rails/validation.rb +0 -4
  14. data/lib/rubocop/cop/style/collection_methods.rb +28 -10
  15. data/lib/rubocop/cop/style/dot_position.rb +14 -4
  16. data/lib/rubocop/cop/style/if_then_else.rb +0 -51
  17. data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -0
  18. data/lib/rubocop/cop/style/multiline_if_then.rb +47 -0
  19. data/lib/rubocop/cop/style/one_line_conditional.rb +20 -0
  20. data/lib/rubocop/cop/style/op_method.rb +16 -14
  21. data/lib/rubocop/cop/util.rb +4 -0
  22. data/lib/rubocop/cop/variable_inspector.rb +32 -13
  23. data/lib/rubocop/version.rb +1 -1
  24. data/rubocop.gemspec +1 -1
  25. data/spec/rubocop/cli_spec.rb +21 -0
  26. data/spec/rubocop/cops/lint/end_alignment_spec.rb +206 -299
  27. data/spec/rubocop/cops/lint/ensure_return_spec.rb +11 -0
  28. data/spec/rubocop/cops/lint/literal_in_condition_spec.rb +37 -3
  29. data/spec/rubocop/cops/lint/shadowing_outer_local_variable_spec.rb +63 -0
  30. data/spec/rubocop/cops/lint/unused_local_variable_spec.rb +68 -0
  31. data/spec/rubocop/cops/offence_spec.rb +2 -2
  32. data/spec/rubocop/cops/style/collection_methods_spec.rb +32 -28
  33. data/spec/rubocop/cops/style/dot_position_spec.rb +46 -11
  34. data/spec/rubocop/cops/style/multiline_if_then_spec.rb +16 -0
  35. metadata +7 -4
@@ -31,6 +31,17 @@ module Rubocop
31
31
  'end'])
32
32
  expect(er.offences).to be_empty
33
33
  end
34
+
35
+ it 'does not check when ensure block has no body' do
36
+ expect do
37
+ inspect_source(er,
38
+ ['begin',
39
+ ' something',
40
+ 'ensure',
41
+ 'end'])
42
+ end.to_not raise_exception
43
+
44
+ end
34
45
  end
35
46
  end
36
47
  end
@@ -9,7 +9,7 @@ module Rubocop
9
9
  let(:cop) { LiteralInCondition.new }
10
10
 
11
11
  %w(1 2.0 [1] {}).each do |lit|
12
- it "registers an offence for literal #{lit} in condition" do
12
+ it "registers an offence for literal #{lit} in &&" do
13
13
  inspect_source(cop,
14
14
  ["if x && #{lit}",
15
15
  ' top',
@@ -17,9 +17,34 @@ module Rubocop
17
17
  ])
18
18
  expect(cop.offences.size).to eq(1)
19
19
  end
20
- end
21
20
 
22
- %w(1 2.0 [1] {}).each do |lit|
21
+ it "registers an offence for literal #{lit} in complex cond" do
22
+ inspect_source(cop,
23
+ ["if x && !(a && #{lit}) && y && z",
24
+ ' top',
25
+ 'end'
26
+ ])
27
+ expect(cop.offences.size).to eq(1)
28
+ end
29
+
30
+ it "registers an offence for literal #{lit} in !" do
31
+ inspect_source(cop,
32
+ ["if !#{lit}",
33
+ ' top',
34
+ 'end'
35
+ ])
36
+ expect(cop.offences.size).to eq(1)
37
+ end
38
+
39
+ it "registers an offence for literal #{lit} in complex !" do
40
+ inspect_source(cop,
41
+ ["if !(x && (y && #{lit}))",
42
+ ' top',
43
+ 'end'
44
+ ])
45
+ expect(cop.offences.size).to eq(1)
46
+ end
47
+
23
48
  it "accepts literal #{lit} if it's not an and/or operand" do
24
49
  inspect_source(cop,
25
50
  ["if test(#{lit})",
@@ -28,6 +53,15 @@ module Rubocop
28
53
  ])
29
54
  expect(cop.offences).to be_empty
30
55
  end
56
+
57
+ it "accepts literal #{lit} in non-toplevel and/or" do
58
+ inspect_source(cop,
59
+ ["if (a || #{lit}).something",
60
+ ' top',
61
+ 'end'
62
+ ])
63
+ expect(cop.offences).to be_empty
64
+ end
31
65
  end
32
66
  end
33
67
  end
@@ -158,6 +158,69 @@ module Rubocop
158
158
  include_examples 'mimics MRI 2.0'
159
159
  end
160
160
 
161
+ context 'when multiple block arguments have same name "_"' do
162
+ let(:source) do
163
+ [
164
+ 'def some_method',
165
+ ' 1.times do |_, foo, _|',
166
+ ' end',
167
+ 'end'
168
+ ]
169
+ end
170
+
171
+ include_examples 'accepts'
172
+ include_examples 'mimics MRI 2.0'
173
+ end
174
+
175
+ context 'when multiple block arguments have ' +
176
+ 'a same name starts with "_"' do
177
+ let(:source) do
178
+ [
179
+ 'def some_method',
180
+ ' 1.times do |_foo, bar, _foo|',
181
+ ' end',
182
+ 'end'
183
+ ]
184
+ end
185
+
186
+ include_examples 'accepts'
187
+ include_examples 'mimics MRI 2.0'
188
+ end
189
+
190
+ context 'when a block argument has same name "_" ' +
191
+ 'as outer scope variable "_"' do
192
+ let(:source) do
193
+ [
194
+ 'def some_method',
195
+ ' _ = 1',
196
+ ' puts _',
197
+ ' 1.times do |_|',
198
+ ' end',
199
+ 'end'
200
+ ]
201
+ end
202
+
203
+ include_examples 'accepts'
204
+ include_examples 'mimics MRI 2.0'
205
+ end
206
+
207
+ context 'when a block argument has a same name starts with "_" ' +
208
+ 'as an outer scope variable' do
209
+ let(:source) do
210
+ [
211
+ 'def some_method',
212
+ ' _foo = 1',
213
+ ' puts _foo',
214
+ ' 1.times do |_foo|',
215
+ ' end',
216
+ 'end'
217
+ ]
218
+ end
219
+
220
+ include_examples 'accepts'
221
+ include_examples 'mimics MRI 2.0'
222
+ end
223
+
161
224
  context 'when a method argument has same name ' +
162
225
  'as an outer scope variable' do
163
226
  let(:source) do
@@ -271,6 +271,61 @@ module Rubocop
271
271
  include_examples 'mimics MRI 2.0'
272
272
  end
273
273
 
274
+ context 'when a named capture is unreferenced in top level' do
275
+ let(:source) do
276
+ [
277
+ "/(?<foo>\w+)/ =~ 'FOO'",
278
+ ]
279
+ end
280
+
281
+ it 'registers an offence' do
282
+ inspect_source(cop, source)
283
+ expect(cop.offences).to have(1).item
284
+ expect(cop.offences.first.message)
285
+ .to include('unused variable - foo')
286
+ expect(cop.offences.first.line).to eq(1)
287
+ end
288
+
289
+ include_examples 'mimics MRI 2.0'
290
+ end
291
+
292
+ context 'when a named capture is unreferenced ' +
293
+ 'in other than top level' do
294
+ let(:source) do
295
+ [
296
+ 'def some_method',
297
+ " /(?<foo>\w+)/ =~ 'FOO'",
298
+ 'end'
299
+ ]
300
+ end
301
+
302
+ it 'registers an offence' do
303
+ inspect_source(cop, source)
304
+ expect(cop.offences).to have(1).item
305
+ expect(cop.offences.first.message)
306
+ .to include('unused variable - foo')
307
+ expect(cop.offences.first.line).to eq(2)
308
+ end
309
+
310
+ # MRI 2.0 accepts this case, but I have no idea why it does so
311
+ # and there's no convincing reason to conform to this behavior,
312
+ # so RuboCop does not mimic MRI in this case.
313
+ end
314
+
315
+ context 'when a named capture is referenced' do
316
+ let(:source) do
317
+ [
318
+ 'def some_method',
319
+ " /(?<foo>\w+)/ =~ 'bar'",
320
+ ' puts foo',
321
+ 'end'
322
+ ]
323
+ end
324
+
325
+ include_examples 'accepts'
326
+ include_examples 'mimics MRI 2.0'
327
+ end
328
+
274
329
  context 'when a variable is assigned in begin ' +
275
330
  'and referenced outside' do
276
331
  let(:source) do
@@ -387,6 +442,19 @@ module Rubocop
387
442
  include_examples 'mimics MRI 2.0'
388
443
  end
389
444
 
445
+ context 'when a keyword splat method argument is used' do
446
+ let(:source) do
447
+ [
448
+ 'def some_method(name: value, **rest_keywords)',
449
+ ' p rest_keywords',
450
+ 'end'
451
+ ]
452
+ end
453
+
454
+ include_examples 'accepts'
455
+ include_examples 'mimics MRI 2.0'
456
+ end
457
+
390
458
  context 'when a keyword splat method argument is not used' do
391
459
  let(:source) do
392
460
  [
@@ -102,8 +102,8 @@ module Rubocop
102
102
  source_buffer = Parser::Source::Buffer.new('test', 1)
103
103
  source_buffer.source = source.join("\n")
104
104
  begin_pos = source[0...(line - 1)].reduce(0) do |a, e|
105
- a + e.length + "\n".length
106
- end + column
105
+ a + e.length + "\n".length
106
+ end + column
107
107
  Parser::Source::Range.new(source_buffer, begin_pos, begin_pos + 1)
108
108
  end
109
109
 
@@ -6,39 +6,43 @@ module Rubocop
6
6
  module Cop
7
7
  module Style
8
8
  describe CollectionMethods do
9
- let(:cm) { CollectionMethods.new }
9
+ CollectionMethods.config = {
10
+ 'PreferredMethods' => {
11
+ 'collect' => 'map',
12
+ 'inject' => 'reduce',
13
+ 'detect' => 'find',
14
+ 'find_all' => 'select'
15
+ }
16
+ }
10
17
 
11
- it 'registers an offence for collect' do
12
- inspect_source(cm, ['[1, 2, 3].collect { |e| e + 1 }'])
13
- expect(cm.offences.size).to eq(1)
14
- expect(cm.offences.map(&:message))
15
- .to eq(['Prefer map over collect.'])
16
- end
18
+ let(:cop) { CollectionMethods.new }
17
19
 
18
- it 'registers an offence for inject' do
19
- inspect_source(cm, ['[1, 2, 3].inject { |e| e + 1 }'])
20
- expect(cm.offences.size).to eq(1)
21
- expect(cm.offences.map(&:message))
22
- .to eq(['Prefer reduce over inject.'])
23
- end
20
+ CollectionMethods.preferred_methods.keys.each do |method|
21
+ it "registers an offence for #{method} with block" do
22
+ inspect_source(cop, ["[1, 2, 3].#{method} { |e| e + 1 }"])
23
+ expect(cop.offences.size).to eq(1)
24
+ preferred_method = CollectionMethods.preferred_methods[method]
25
+ expect(cop.messages)
26
+ .to eq(["Prefer #{preferred_method} over #{method}."])
27
+ end
24
28
 
25
- it 'registers an offence for detect' do
26
- inspect_source(cm, ['[1, 2, 3].detect { |e| e + 1 }'])
27
- expect(cm.offences.size).to eq(1)
28
- expect(cm.offences.map(&:message))
29
- .to eq(['Prefer find over detect.'])
30
- end
29
+ it "registers an offence for #{method} with proc param" do
30
+ inspect_source(cop, ["[1, 2, 3].#{method}(&:test)"])
31
+ expect(cop.offences.size).to eq(1)
32
+ preferred_method = CollectionMethods.preferred_methods[method]
33
+ expect(cop.messages)
34
+ .to eq(["Prefer #{preferred_method} over #{method}."])
35
+ end
31
36
 
32
- it 'registers an offence for find_all' do
33
- inspect_source(cm, ['[1, 2, 3].find_all { |e| e + 1 }'])
34
- expect(cm.offences.size).to eq(1)
35
- expect(cm.offences.map(&:message))
36
- .to eq(['Prefer select over find_all.'])
37
- end
37
+ it "accepts #{method} with more than 1 param" do
38
+ inspect_source(cop, ["[1, 2, 3].#{method}(other, &:test)"])
39
+ expect(cop.offences).to be_empty
40
+ end
38
41
 
39
- it 'ignores find_all without an explicit receiver' do
40
- inspect_source(cm, ['find_all { |e| e + 1 }'])
41
- expect(cm.offences).to be_empty
42
+ it "accepts #{method} without a block" do
43
+ inspect_source(cop, ["[1, 2, 3].#{method}"])
44
+ expect(cop.offences).to be_empty
45
+ end
42
46
  end
43
47
  end
44
48
  end
@@ -8,21 +8,56 @@ module Rubocop
8
8
  describe DotPosition do
9
9
  let(:cop) { DotPosition.new }
10
10
 
11
- it 'registers an offence for trailing dot in multi-line method call' do
12
- inspect_source(cop, ['something.',
13
- ' method_name'])
14
- expect(cop.offences.size).to eq(1)
11
+ context 'Leading dots style' do
12
+ before { DotPosition.config = { 'Style' => 'Leading' } }
13
+
14
+ it 'registers an offence for trailing dot in multi-line call' do
15
+ inspect_source(cop, ['something.',
16
+ ' method_name'])
17
+ expect(cop.offences.size).to eq(1)
18
+ end
19
+
20
+ it 'accepts leading do in multi-line method call' do
21
+ inspect_source(cop, ['something',
22
+ ' .method_name'])
23
+ expect(cop.offences).to be_empty
24
+ end
25
+
26
+ it 'does not err on method call with no dots' do
27
+ inspect_source(cop, ['puts something'])
28
+ expect(cop.offences).to be_empty
29
+ end
15
30
  end
16
31
 
17
- it 'accepts leading do in multi-line method call' do
18
- inspect_source(cop, ['something',
19
- ' .method_name'])
20
- expect(cop.offences).to be_empty
32
+ context 'Trailing dots style' do
33
+ before { DotPosition.config = { 'Style' => 'Trailing' } }
34
+
35
+ it 'registers an offence for leading dot in multi-line call' do
36
+ inspect_source(cop, ['something',
37
+ ' .method_name'])
38
+ expect(cop.offences.size).to eq(1)
39
+ end
40
+
41
+ it 'accepts trailing dot in multi-line method call' do
42
+ inspect_source(cop, ['something.',
43
+ ' method_name'])
44
+ expect(cop.offences).to be_empty
45
+ end
46
+
47
+ it 'does not err on method call with no dots' do
48
+ inspect_source(cop, ['puts something'])
49
+ expect(cop.offences).to be_empty
50
+ end
21
51
  end
22
52
 
23
- it 'does not err on method call with no dots' do
24
- inspect_source(cop, ['puts something'])
25
- expect(cop.offences).to be_empty
53
+ context 'Unknown style' do
54
+ before { DotPosition.config = { 'Style' => 'test' } }
55
+
56
+ it 'raises an exception' do
57
+ expect do
58
+ inspect_source(cop, ['something.top'])
59
+ end.to raise_error(RuntimeError)
60
+ end
26
61
  end
27
62
  end
28
63
  end
@@ -75,6 +75,22 @@ module Rubocop
75
75
  'end'])
76
76
  expect(mit.offences).to be_empty
77
77
  end
78
+
79
+ it 'does not get confused by a postfix unless' do
80
+ inspect_source(mit,
81
+ ['two unless one',
82
+ ])
83
+ expect(mit.offences).to be_empty
84
+ end
85
+
86
+ it 'does not get confused by a nested postfix unless' do
87
+ inspect_source(mit,
88
+ ['if two',
89
+ ' puts 1',
90
+ 'end unless two'
91
+ ])
92
+ expect(mit.offences).to be_empty
93
+ end
78
94
  end
79
95
  end
80
96
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-01 00:00:00.000000000 Z
11
+ date: 2013-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rainbow
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 2.0.0.beta9
33
+ version: 2.0.0.pre1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 2.0.0.beta9
40
+ version: 2.0.0.pre1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -193,6 +193,7 @@ files:
193
193
  - lib/rubocop/cop/style/favor_unless_over_negated_if.rb
194
194
  - lib/rubocop/cop/style/hash_syntax.rb
195
195
  - lib/rubocop/cop/style/if_then_else.rb
196
+ - lib/rubocop/cop/style/if_with_semicolon.rb
196
197
  - lib/rubocop/cop/style/lambda.rb
197
198
  - lib/rubocop/cop/style/leading_comment_space.rb
198
199
  - lib/rubocop/cop/style/line_continuation.rb
@@ -200,8 +201,10 @@ files:
200
201
  - lib/rubocop/cop/style/method_and_variable_snake_case.rb
201
202
  - lib/rubocop/cop/style/method_call_parentheses.rb
202
203
  - lib/rubocop/cop/style/method_length.rb
204
+ - lib/rubocop/cop/style/multiline_if_then.rb
203
205
  - lib/rubocop/cop/style/not.rb
204
206
  - lib/rubocop/cop/style/numeric_literals.rb
207
+ - lib/rubocop/cop/style/one_line_conditional.rb
205
208
  - lib/rubocop/cop/style/op_method.rb
206
209
  - lib/rubocop/cop/style/parameter_lists.rb
207
210
  - lib/rubocop/cop/style/parentheses_around_condition.rb