rubocop 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rubocop might be problematic. Click here for more details.

Files changed (79) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +35 -0
  3. data/CONTRIBUTING.md +2 -0
  4. data/README.md +102 -5
  5. data/config/default.yml +31 -3
  6. data/config/enabled.yml +21 -3
  7. data/lib/rubocop.rb +5 -0
  8. data/lib/rubocop/cli.rb +27 -7
  9. data/lib/rubocop/config.rb +21 -2
  10. data/lib/rubocop/config_store.rb +4 -1
  11. data/lib/rubocop/cop/commissioner.rb +2 -4
  12. data/lib/rubocop/cop/cop.rb +8 -8
  13. data/lib/rubocop/cop/lint/assignment_in_condition.rb +3 -0
  14. data/lib/rubocop/cop/lint/block_alignment.rb +10 -20
  15. data/lib/rubocop/cop/lint/useless_assignment.rb +63 -0
  16. data/lib/rubocop/cop/lint/useless_comparison.rb +30 -0
  17. data/lib/rubocop/cop/style/align_parameters.rb +23 -13
  18. data/lib/rubocop/cop/style/and_or.rb +13 -1
  19. data/lib/rubocop/cop/style/blocks.rb +35 -0
  20. data/lib/rubocop/cop/style/character_literal.rb +1 -1
  21. data/lib/rubocop/cop/style/comment_annotation.rb +20 -5
  22. data/lib/rubocop/cop/style/dot_position.rb +7 -1
  23. data/lib/rubocop/cop/style/empty_line_between_defs.rb +1 -1
  24. data/lib/rubocop/cop/style/favor_modifier.rb +4 -4
  25. data/lib/rubocop/cop/style/module_function.rb +34 -0
  26. data/lib/rubocop/cop/style/multiline_if_then.rb +7 -9
  27. data/lib/rubocop/cop/style/redundant_begin.rb +7 -7
  28. data/lib/rubocop/cop/style/redundant_return.rb +9 -11
  29. data/lib/rubocop/cop/style/redundant_self.rb +5 -1
  30. data/lib/rubocop/cop/style/regexp_literal.rb +2 -1
  31. data/lib/rubocop/cop/style/signal_exception.rb +40 -0
  32. data/lib/rubocop/cop/style/string_literals.rb +2 -2
  33. data/lib/rubocop/cop/style/symbol_name.rb +11 -0
  34. data/lib/rubocop/cop/style/trivial_accessors.rb +22 -10
  35. data/lib/rubocop/cop/variable_inspector.rb +92 -71
  36. data/lib/rubocop/formatter/clang_style_formatter.rb +8 -3
  37. data/lib/rubocop/formatter/disabled_config_formatter.rb +32 -0
  38. data/lib/rubocop/formatter/formatter_set.rb +7 -4
  39. data/lib/rubocop/target_finder.rb +3 -4
  40. data/lib/rubocop/version.rb +1 -1
  41. data/rubocop.gemspec +1 -1
  42. data/spec/rubocop/cli_spec.rb +90 -1
  43. data/spec/rubocop/cops/commissioner_spec.rb +1 -1
  44. data/spec/rubocop/cops/lint/assignment_in_condition_spec.rb +6 -0
  45. data/spec/rubocop/cops/lint/block_alignment_spec.rb +16 -4
  46. data/spec/rubocop/cops/lint/empty_ensure_spec.rb +1 -1
  47. data/spec/rubocop/cops/lint/ensure_return_spec.rb +1 -1
  48. data/spec/rubocop/cops/lint/shadowing_outer_local_variable_spec.rb +4 -4
  49. data/spec/rubocop/cops/lint/unused_local_variable_spec.rb +49 -13
  50. data/spec/rubocop/cops/lint/useless_assignment_spec.rb +62 -0
  51. data/spec/rubocop/cops/lint/useless_comparison_spec.rb +31 -0
  52. data/spec/rubocop/cops/style/align_parameters_spec.rb +9 -0
  53. data/spec/rubocop/cops/style/and_or_spec.rb +12 -0
  54. data/spec/rubocop/cops/style/avoid_global_vars_spec.rb +1 -1
  55. data/spec/rubocop/cops/style/blocks_spec.rb +57 -14
  56. data/spec/rubocop/cops/style/character_literal_spec.rb +2 -2
  57. data/spec/rubocop/cops/style/comment_annotation_spec.rb +32 -4
  58. data/spec/rubocop/cops/style/dot_position_spec.rb +10 -0
  59. data/spec/rubocop/cops/style/empty_line_between_defs_spec.rb +12 -0
  60. data/spec/rubocop/cops/style/end_of_line_spec.rb +1 -0
  61. data/spec/rubocop/cops/style/favor_modifier_spec.rb +18 -0
  62. data/spec/rubocop/cops/style/hash_syntax_spec.rb +7 -2
  63. data/spec/rubocop/cops/style/module_function_spec.rb +30 -0
  64. data/spec/rubocop/cops/style/redundant_begin_spec.rb +2 -2
  65. data/spec/rubocop/cops/style/redundant_return_spec.rb +4 -4
  66. data/spec/rubocop/cops/style/redundant_self_spec.rb +36 -2
  67. data/spec/rubocop/cops/style/regexp_literal_spec.rb +1 -0
  68. data/spec/rubocop/cops/style/signal_exception_spec.rb +74 -0
  69. data/spec/rubocop/cops/style/string_literals_spec.rb +10 -0
  70. data/spec/rubocop/cops/style/symbol_name_spec.rb +13 -0
  71. data/spec/rubocop/cops/style/trivial_accessors_spec.rb +28 -3
  72. data/spec/rubocop/cops/variable_inspector_spec.rb +217 -36
  73. data/spec/rubocop/formatter/base_formatter_spec.rb +3 -3
  74. data/spec/rubocop/formatter/clang_style_formatter_spec.rb +19 -0
  75. data/spec/rubocop/formatter/disabled_config_formatter_spec.rb +48 -0
  76. data/spec/rubocop/formatter/formatter_set_spec.rb +1 -1
  77. data/spec/rubocop/processed_source_spec.rb +1 -1
  78. data/spec/spec_helper.rb +18 -13
  79. metadata +31 -38
@@ -13,7 +13,7 @@ module Rubocop
13
13
  ' return something',
14
14
  'end']
15
15
  inspect_source(cop, src)
16
- expect(cop.offences).to have(1).item
16
+ expect(cop.offences.size).to eq(1)
17
17
  end
18
18
 
19
19
  it 'reports an offence for defs with only a return' do
@@ -21,7 +21,7 @@ module Rubocop
21
21
  ' return something',
22
22
  'end']
23
23
  inspect_source(cop, src)
24
- expect(cop.offences).to have(1).item
24
+ expect(cop.offences.size).to eq(1)
25
25
  end
26
26
 
27
27
  it 'reports an offence for def ending with return' do
@@ -31,7 +31,7 @@ module Rubocop
31
31
  ' return something',
32
32
  'end']
33
33
  inspect_source(cop, src)
34
- expect(cop.offences).to have(1).item
34
+ expect(cop.offences.size).to eq(1)
35
35
  end
36
36
 
37
37
  it 'reports an offence for defs ending with return' do
@@ -41,7 +41,7 @@ module Rubocop
41
41
  ' return something',
42
42
  'end']
43
43
  inspect_source(cop, src)
44
- expect(cop.offences).to have(1).item
44
+ expect(cop.offences.size).to eq(1)
45
45
  end
46
46
 
47
47
  it 'accepts return in a non-final position' do
@@ -11,7 +11,7 @@ module Rubocop
11
11
  it 'reports an offence a self receiver on an rvalue' do
12
12
  src = ['a = self.b']
13
13
  inspect_source(cop, src)
14
- expect(cop.offences).to have(1).item
14
+ expect(cop.offences.size).to eq(1)
15
15
  end
16
16
 
17
17
  it 'accepts a self receiver on an lvalue of an assignment' do
@@ -52,7 +52,41 @@ module Rubocop
52
52
 
53
53
  it 'accepts a self receiver for methods named like ruby keywords' do
54
54
  src = ['a = self.class',
55
- 'self.for(deps, [], true)'
55
+ 'self.for(deps, [], true)',
56
+ 'self.and(other)',
57
+ 'self.or(other)',
58
+ 'self.alias',
59
+ 'self.begin',
60
+ 'self.break',
61
+ 'self.case',
62
+ 'self.def',
63
+ 'self.defined',
64
+ 'self.do',
65
+ 'self.else',
66
+ 'self.elsif',
67
+ 'self.end',
68
+ 'self.ensure',
69
+ 'self.false',
70
+ 'self.if',
71
+ 'self.in',
72
+ 'self.module',
73
+ 'self.next',
74
+ 'self.nil',
75
+ 'self.not',
76
+ 'self.redo',
77
+ 'self.rescue',
78
+ 'self.retry',
79
+ 'self.return',
80
+ 'self.self',
81
+ 'self.super',
82
+ 'self.then',
83
+ 'self.true',
84
+ 'self.undef',
85
+ 'self.unless',
86
+ 'self.until',
87
+ 'self.when',
88
+ 'self.while',
89
+ 'self.yield'
56
90
  ]
57
91
  inspect_source(cop, src)
58
92
  expect(cop.offences).to be_empty
@@ -22,6 +22,7 @@ module Rubocop
22
22
  it 'accepts zero or one slash in regexp' do
23
23
  inspect_source(rl, ['x =~ /\/home/',
24
24
  'y =~ /\//',
25
+ 'w =~ /\//m',
25
26
  'z =~ /a/'])
26
27
  expect(rl.offences).to be_empty
27
28
  end
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ module Style
8
+ describe SignalException do
9
+ let(:cop) { described_class.new }
10
+
11
+ it 'registers an offence for raise in begin section' do
12
+ inspect_source(cop,
13
+ ['begin',
14
+ ' raise',
15
+ 'rescue Exception',
16
+ ' #do nothing',
17
+ 'end'])
18
+ expect(cop.offences.size).to eq(1)
19
+ expect(cop.messages).to eq([SignalException::FAIL_MSG])
20
+ end
21
+
22
+ it 'registers an offence for raise in def body' do
23
+ inspect_source(cop,
24
+ ['def test',
25
+ ' raise',
26
+ 'rescue Exception',
27
+ ' #do nothing',
28
+ 'end'])
29
+ expect(cop.offences.size).to eq(1)
30
+ expect(cop.messages).to eq([SignalException::FAIL_MSG])
31
+ end
32
+
33
+ it 'registers an offence for fail in rescue section' do
34
+ inspect_source(cop,
35
+ ['begin',
36
+ ' fail',
37
+ 'rescue Exception',
38
+ ' fail',
39
+ 'end'])
40
+ expect(cop.offences.size).to eq(1)
41
+ expect(cop.messages).to eq([SignalException::RAISE_MSG])
42
+ end
43
+
44
+ it 'registers an offence for fail def rescue section' do
45
+ inspect_source(cop,
46
+ ['def test',
47
+ ' fail',
48
+ 'rescue Exception',
49
+ ' fail',
50
+ 'end'])
51
+ expect(cop.offences.size).to eq(1)
52
+ expect(cop.messages).to eq([SignalException::RAISE_MSG])
53
+ end
54
+
55
+ it 'is not confused by nested begin/rescue' do
56
+ inspect_source(cop,
57
+ ['begin',
58
+ ' raise',
59
+ ' begin',
60
+ ' raise',
61
+ ' rescue',
62
+ ' fail',
63
+ ' end',
64
+ 'rescue Exception',
65
+ ' #do nothing',
66
+ 'end'])
67
+ expect(cop.offences.size).to eq(3)
68
+ expect(cop.messages).to eq([SignalException::FAIL_MSG] * 2 +
69
+ [SignalException::RAISE_MSG])
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -43,6 +43,16 @@ module Rubocop
43
43
  expect(cop.offences).to be_empty
44
44
  end
45
45
 
46
+ it 'accepts " in a %w' do
47
+ inspect_source(cop, ['%w(")'])
48
+ expect(cop.offences).to be_empty
49
+ end
50
+
51
+ it 'accepts \\\\\n in a string' do # this would be: "\\\n"
52
+ inspect_source(cop, ['"foo \\\\\n bar"'])
53
+ expect(cop.offences).to be_empty
54
+ end
55
+
46
56
  it 'can handle double quotes within embedded expression' do
47
57
  src = ['"#{"A"}"']
48
58
  inspect_source(cop, src)
@@ -105,6 +105,19 @@ module Rubocop
105
105
  expect(symbol_name.offences).to be_empty
106
106
  end
107
107
 
108
+ it 'accepts non snake case arguments to private_constant' do
109
+ inspect_source(symbol_name,
110
+ ['private_constant :NORMAL_MODE, :ADMIN_MODE'])
111
+ expect(symbol_name.offences).to be_empty
112
+ end
113
+
114
+ it 'registers an offence for non snake case symbol near ' +
115
+ 'private_constant' do
116
+ inspect_source(symbol_name,
117
+ ['private_constant f(:ADMIN_MODE)'])
118
+ expect(symbol_name.offences.size).to eq(1)
119
+ end
120
+
108
121
  it 'can handle an alias of and operator without crashing' do
109
122
  inspect_source(symbol_name,
110
123
  ['alias + add'])
@@ -6,8 +6,10 @@ module Rubocop
6
6
  module Cop
7
7
  module Style
8
8
  describe TrivialAccessors do
9
- TrivialAccessors.config = { 'ExactNameMatch' => false }
10
- let(:cop) { TrivialAccessors.new }
9
+ subject(:cop) { described_class.new }
10
+ before do
11
+ described_class.config = {}
12
+ end
11
13
 
12
14
  it 'finds trivial reader' do
13
15
  inspect_source(cop,
@@ -346,7 +348,7 @@ module Rubocop
346
348
  end
347
349
 
348
350
  context 'exact name match required' do
349
- before { TrivialAccessors.config['ExactNameMatch'] = true }
351
+ before { described_class.config['ExactNameMatch'] = true }
350
352
 
351
353
  it 'finds only 1 trivial reader' do
352
354
  inspect_source(cop,
@@ -390,6 +392,29 @@ module Rubocop
390
392
  expect(cop.offences).to be_empty
391
393
  end
392
394
  end
395
+
396
+ context 'with whitelist defined' do
397
+ before do
398
+ described_class.config = {
399
+ 'Whitelist' => ['to_foo', 'bar=']
400
+ }
401
+ end
402
+
403
+ it 'ignores accessors in the whitelist' do
404
+ inspect_source(cop,
405
+ [' def to_foo',
406
+ ' @foo',
407
+ ' end'])
408
+ expect(cop.offences).to be_empty
409
+ end
410
+ it 'ignores writers in the whitelist' do
411
+ inspect_source(cop,
412
+ [' def bar=(bar)',
413
+ ' @bar = bar',
414
+ ' end'])
415
+ expect(cop.offences).to be_empty
416
+ end
417
+ end
393
418
  end
394
419
  end
395
420
  end
@@ -247,39 +247,39 @@ module Rubocop
247
247
  end
248
248
 
249
249
  describe NodeScanner do
250
- let(:source) do
251
- <<-END
252
- class SomeClass
253
- foo = 1.to_s
254
- bar = 2.to_s
255
- def some_method
256
- baz = 3.to_s
257
- end
258
- end
259
- END
260
- end
250
+ describe '.scan_nodes_in_scope' do
251
+ let(:ast) do
252
+ processed_source = Rubocop::SourceParser.parse(source)
253
+ processed_source.ast
254
+ end
261
255
 
262
- let(:ast) do
263
- processed_source = Rubocop::SourceParser.parse(source)
264
- processed_source.ast
265
- end
256
+ let(:source) do
257
+ <<-END
258
+ class SomeClass
259
+ foo = 1.to_s
260
+ bar = 2.to_s
261
+ def some_method
262
+ baz = 3.to_s
263
+ end
264
+ end
265
+ END
266
+ end
266
267
 
267
- # (class
268
- # (const nil :SomeClass) nil
269
- # (begin
270
- # (lvasgn :foo
271
- # (send
272
- # (int 1) :to_s))
273
- # (lvasgn :bar
274
- # (send
275
- # (int 2) :to_s))
276
- # (def :some_method
277
- # (args)
278
- # (lvasgn :baz
279
- # (send
280
- # (int 3) :to_s)))))
268
+ # (class
269
+ # (const nil :SomeClass) nil
270
+ # (begin
271
+ # (lvasgn :foo
272
+ # (send
273
+ # (int 1) :to_s))
274
+ # (lvasgn :bar
275
+ # (send
276
+ # (int 2) :to_s))
277
+ # (def :some_method
278
+ # (args)
279
+ # (lvasgn :baz
280
+ # (send
281
+ # (int 3) :to_s)))))
281
282
 
282
- describe '.scan_nodes_in_scope' do
283
283
  it 'does not scan children of inner scope node' do
284
284
  scanned_node_count = 0
285
285
 
@@ -316,15 +316,196 @@ module Rubocop
316
316
  expect(index).not_to eq(0)
317
317
  end
318
318
 
319
- it 'passes node index in the scope as second block argument' do
320
- last_index = -1
319
+ let(:trace) { [] }
320
+
321
+ before do
322
+ NodeScanner.scan_nodes_in_scope(ast) do |node|
323
+ short_info = node.type.to_s
324
+ node.children.each do |child|
325
+ break if child.is_a?(Parser::AST::Node)
326
+ short_info << " #{child.inspect}"
327
+ end
328
+ trace << short_info
329
+ end
330
+ end
331
+
332
+ context 'when invoking a method ' +
333
+ 'which is taking block and normal arguments' do
334
+ let(:source) do
335
+ <<-END
336
+ some_method(foo = 1) do |block_arg|
337
+ content_of_block = 2
338
+ end
339
+ puts foo
340
+ END
341
+ end
342
+
343
+ # (begin
344
+ # (block
345
+ # (send nil :some_method
346
+ # (lvasgn :foo
347
+ # (int 1)))
348
+ # (args
349
+ # (arg :block_arg))
350
+ # (lvasgn :content_of_block
351
+ # (int 2)))
352
+ # (send nil :puts
353
+ # (lvar :foo)))
354
+
355
+ it 'scans the method node and its normal argument nodes' do
356
+ expect(trace).to eq([
357
+ 'block',
358
+ 'send nil :some_method',
359
+ 'lvasgn :foo',
360
+ 'int 1',
361
+ 'send nil :puts',
362
+ 'lvar :foo'
363
+ ])
364
+ end
365
+ end
366
+
367
+ context 'when opening singleton class of an instance' do
368
+ let(:source) do
369
+ <<-END
370
+ instance = Object.new
371
+ class << instance
372
+ content_of_singleton_class = 1
373
+ end
374
+ p instance
375
+ END
376
+ end
377
+
378
+ # (begin
379
+ # (lvasgn :instance
380
+ # (send
381
+ # (const nil :Object) :new))
382
+ # (sclass
383
+ # (lvar :instance)
384
+ # (lvasgn :content_of_singleton_class
385
+ # (int 1)))
386
+ # (send nil :p
387
+ # (lvar :instance)))
388
+
389
+ it 'scans the subject instance node' do
390
+ expect(trace).to eq([
391
+ 'lvasgn :instance',
392
+ 'send',
393
+ 'const nil :Object',
394
+ 'sclass',
395
+ 'lvar :instance',
396
+ 'send nil :p',
397
+ 'lvar :instance'
398
+ ])
399
+ end
400
+ end
401
+
402
+ context 'when defining singleton method' do
403
+ let(:source) do
404
+ <<-END
405
+ instance = Object.new
406
+ def instance.some_method(method_arg)
407
+ content_of_method = 2
408
+ end
409
+ p instance
410
+ END
411
+ end
412
+
413
+ # (begin
414
+ # (lvasgn :instance
415
+ # (send
416
+ # (const nil :Object) :new))
417
+ # (defs
418
+ # (lvar :instance) :some_method
419
+ # (args
420
+ # (arg :method_arg))
421
+ # (lvasgn :content_of_method
422
+ # (int 2)))
423
+ # (send nil :p
424
+ # (lvar :instance)))
425
+
426
+ it 'scans the subject instance node' do
427
+ expect(trace).to eq([
428
+ 'lvasgn :instance',
429
+ 'send',
430
+ 'const nil :Object',
431
+ 'defs',
432
+ 'lvar :instance',
433
+ 'send nil :p',
434
+ 'lvar :instance'
435
+ ])
436
+ end
437
+ end
438
+
439
+ context 'when scanning around post while loop' do
440
+ let(:source) do
441
+ <<-END
442
+ begin
443
+ foo = 1
444
+ end while foo > 10
445
+ puts foo
446
+ END
447
+ end
321
448
 
322
- NodeScanner.scan_nodes_in_scope(ast) do |node, index|
323
- expect(index).to eq(last_index + 1)
324
- last_index = index
449
+ # (begin
450
+ # (while-post
451
+ # (send
452
+ # (lvar :foo) :>
453
+ # (int 10))
454
+ # (kwbegin
455
+ # (lvasgn :foo
456
+ # (int 1))))
457
+ # (send nil :puts
458
+ # (lvar :foo)))
459
+
460
+ it 'scans loop body nodes first then condition nodes' do
461
+ expect(trace).to eq([
462
+ 'while_post',
463
+ 'kwbegin',
464
+ 'lvasgn :foo',
465
+ 'int 1',
466
+ 'send',
467
+ 'lvar :foo',
468
+ 'int 10',
469
+ 'send nil :puts',
470
+ 'lvar :foo'
471
+ ])
325
472
  end
473
+ end
326
474
 
327
- expect(last_index).not_to eq(-1)
475
+ context 'when scanning around post until loop' do
476
+ let(:source) do
477
+ <<-END
478
+ begin
479
+ foo = 1
480
+ end until foo < 10
481
+ puts foo
482
+ END
483
+ end
484
+
485
+ # (begin
486
+ # (until-post
487
+ # (send
488
+ # (lvar :foo) :<
489
+ # (int 10))
490
+ # (kwbegin
491
+ # (lvasgn :foo
492
+ # (int 1))))
493
+ # (send nil :puts
494
+ # (lvar :foo)))
495
+
496
+ it 'scans loop body nodes first then condition nodes' do
497
+ expect(trace).to eq([
498
+ 'until_post',
499
+ 'kwbegin',
500
+ 'lvasgn :foo',
501
+ 'int 1',
502
+ 'send',
503
+ 'lvar :foo',
504
+ 'int 10',
505
+ 'send nil :puts',
506
+ 'lvar :foo'
507
+ ])
508
+ end
328
509
  end
329
510
  end
330
511
  end