rubocop 0.6.1 → 0.7.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 (87) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -266
  3. data/CHANGELOG.md +49 -7
  4. data/README.md +75 -2
  5. data/Rakefile +2 -2
  6. data/bin/rubocop +15 -10
  7. data/lib/rubocop.rb +19 -1
  8. data/lib/rubocop/cli.rb +113 -116
  9. data/lib/rubocop/config.rb +202 -0
  10. data/lib/rubocop/config_store.rb +37 -0
  11. data/lib/rubocop/cop/alias.rb +2 -5
  12. data/lib/rubocop/cop/align_parameters.rb +1 -1
  13. data/lib/rubocop/cop/array_literal.rb +43 -4
  14. data/lib/rubocop/cop/avoid_for.rb +2 -4
  15. data/lib/rubocop/cop/avoid_global_vars.rb +49 -0
  16. data/lib/rubocop/cop/block_comments.rb +17 -0
  17. data/lib/rubocop/cop/brace_after_percent.rb +9 -5
  18. data/lib/rubocop/cop/{indentation.rb → case_indentation.rb} +1 -1
  19. data/lib/rubocop/cop/class_methods.rb +20 -0
  20. data/lib/rubocop/cop/colon_method_call.rb +44 -0
  21. data/lib/rubocop/cop/cop.rb +30 -2
  22. data/lib/rubocop/cop/def_parentheses.rb +1 -1
  23. data/lib/rubocop/cop/empty_line_between_defs.rb +26 -0
  24. data/lib/rubocop/cop/empty_lines.rb +10 -13
  25. data/lib/rubocop/cop/eval.rb +22 -0
  26. data/lib/rubocop/cop/favor_join.rb +37 -0
  27. data/lib/rubocop/cop/grammar.rb +2 -2
  28. data/lib/rubocop/cop/hash_literal.rb +43 -4
  29. data/lib/rubocop/cop/hash_syntax.rb +2 -2
  30. data/lib/rubocop/cop/if_then_else.rb +1 -1
  31. data/lib/rubocop/cop/leading_comment_space.rb +20 -0
  32. data/lib/rubocop/cop/line_continuation.rb +18 -0
  33. data/lib/rubocop/cop/line_length.rb +1 -1
  34. data/lib/rubocop/cop/method_and_variable_snake_case.rb +7 -6
  35. data/lib/rubocop/cop/method_length.rb +4 -15
  36. data/lib/rubocop/cop/not.rb +15 -0
  37. data/lib/rubocop/cop/offence.rb +9 -0
  38. data/lib/rubocop/cop/semicolon.rb +74 -3
  39. data/lib/rubocop/cop/single_line_methods.rb +60 -0
  40. data/lib/rubocop/cop/space_after_control_keyword.rb +28 -0
  41. data/lib/rubocop/cop/surrounding_space.rb +48 -9
  42. data/lib/rubocop/cop/symbol_array.rb +29 -0
  43. data/lib/rubocop/cop/trivial_accessors.rb +103 -0
  44. data/lib/rubocop/cop/unless_else.rb +1 -1
  45. data/lib/rubocop/cop/variable_interpolation.rb +3 -2
  46. data/lib/rubocop/cop/word_array.rb +38 -0
  47. data/lib/rubocop/version.rb +1 -1
  48. data/rubocop.gemspec +11 -7
  49. data/spec/project_spec.rb +27 -0
  50. data/spec/rubocop/cli_spec.rb +549 -487
  51. data/spec/rubocop/config_spec.rb +399 -0
  52. data/spec/rubocop/config_store_spec.rb +66 -0
  53. data/spec/rubocop/cops/alias_spec.rb +7 -0
  54. data/spec/rubocop/cops/array_literal_spec.rb +8 -1
  55. data/spec/rubocop/cops/avoid_for_spec.rb +15 -1
  56. data/spec/rubocop/cops/avoid_global_vars.rb +32 -0
  57. data/spec/rubocop/cops/block_comments_spec.rb +29 -0
  58. data/spec/rubocop/cops/brace_after_percent_spec.rb +19 -13
  59. data/spec/rubocop/cops/{indentation_spec.rb → case_indentation_spec.rb} +2 -2
  60. data/spec/rubocop/cops/class_methods_spec.rb +49 -0
  61. data/spec/rubocop/cops/colon_method_call_spec.rb +47 -0
  62. data/spec/rubocop/cops/empty_line_between_defs_spec.rb +83 -0
  63. data/spec/rubocop/cops/empty_lines_spec.rb +6 -63
  64. data/spec/rubocop/cops/eval_spec.rb +36 -0
  65. data/spec/rubocop/cops/favor_join_spec.rb +39 -0
  66. data/spec/rubocop/cops/hash_literal_spec.rb +8 -1
  67. data/spec/rubocop/cops/leading_comment_space_spec.rb +60 -0
  68. data/spec/rubocop/cops/line_continuation_spec.rb +24 -0
  69. data/spec/rubocop/cops/line_length_spec.rb +1 -0
  70. data/spec/rubocop/cops/method_and_variable_snake_case_spec.rb +20 -0
  71. data/spec/rubocop/cops/method_length_spec.rb +2 -5
  72. data/spec/rubocop/cops/new_lambda_literal_spec.rb +2 -3
  73. data/spec/rubocop/cops/not_spec.rb +34 -0
  74. data/spec/rubocop/cops/offence_spec.rb +7 -0
  75. data/spec/rubocop/cops/semicolon_spec.rb +79 -4
  76. data/spec/rubocop/cops/single_line_methods_spec.rb +50 -0
  77. data/spec/rubocop/cops/space_after_control_keyword_spec.rb +28 -0
  78. data/spec/rubocop/cops/space_around_equals_in_default_parameter_spec.rb +11 -1
  79. data/spec/rubocop/cops/space_inside_hash_literal_braces_spec.rb +74 -0
  80. data/spec/rubocop/cops/symbol_array_spec.rb +25 -0
  81. data/spec/rubocop/cops/trivial_accessors_spec.rb +332 -0
  82. data/spec/rubocop/cops/variable_interpolation_spec.rb +10 -1
  83. data/spec/rubocop/cops/word_array_spec.rb +39 -0
  84. data/spec/spec_helper.rb +16 -9
  85. data/spec/support/file_helper.rb +21 -0
  86. data/spec/support/isolated_environment.rb +27 -0
  87. metadata +66 -6
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ describe Eval do
8
+ let(:a) { Eval.new }
9
+
10
+ it 'registers an offence for eval as function' do
11
+ inspect_source(a,
12
+ 'file.rb',
13
+ ['eval(something)'])
14
+ expect(a.offences.size).to eq(1)
15
+ expect(a.offences.map(&:message))
16
+ .to eq([Eval::ERROR_MESSAGE])
17
+ end
18
+
19
+ it 'registers an offence for eval as command' do
20
+ inspect_source(a,
21
+ 'file.rb',
22
+ ['eval something'])
23
+ expect(a.offences.size).to eq(1)
24
+ expect(a.offences.map(&:message))
25
+ .to eq([Eval::ERROR_MESSAGE])
26
+ end
27
+
28
+ it 'does not register an offence for eval as variable' do
29
+ inspect_source(a,
30
+ 'file.rb',
31
+ ['eval = something'])
32
+ expect(a.offences).to be_empty
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ describe FavorJoin do
8
+ let(:fj) { FavorJoin.new }
9
+
10
+ it 'registers an offence for an array followed by string' do
11
+ inspect_source(fj,
12
+ 'file.rb',
13
+ ['%w(one two three) * ", "'])
14
+ expect(fj.offences.size).to eq(1)
15
+ expect(fj.offences.map(&:message))
16
+ .to eq([FavorJoin::ERROR_MESSAGE])
17
+ end
18
+
19
+ it 'does not register an offence for numbers' do
20
+ inspect_source(fj,
21
+ 'file.rb',
22
+ ['%w(one two three) * 4'])
23
+ expect(fj.offences).to be_empty
24
+ end
25
+
26
+ it 'does not register an offence for ambiguous cases' do
27
+ inspect_source(fj,
28
+ 'file.rb',
29
+ ['test * ", "'])
30
+ expect(fj.offences).to be_empty
31
+
32
+ inspect_source(fj,
33
+ 'file.rb',
34
+ ['%w(one two three) * test'])
35
+ expect(fj.offences).to be_empty
36
+ end
37
+ end
38
+ end
39
+ end
@@ -16,7 +16,14 @@ module Rubocop
16
16
  .to eq([HashLiteral::ERROR_MESSAGE])
17
17
  end
18
18
 
19
- it 'registers an offence for Hash.new'
19
+ it 'registers an offence for Hash.new' do
20
+ inspect_source(a,
21
+ 'file.rb',
22
+ ['test = Hash.new'])
23
+ expect(a.offences.size).to eq(1)
24
+ expect(a.offences.map(&:message))
25
+ .to eq([HashLiteral::ERROR_MESSAGE])
26
+ end
20
27
 
21
28
  it 'does not register an offence for Hash.new(3)' do
22
29
  inspect_source(a,
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ describe LeadingCommentSpace do
8
+ let(:lcs) { LeadingCommentSpace.new }
9
+
10
+ it 'registers an offence for comment without leading space' do
11
+ inspect_source(lcs,
12
+ 'file.rb',
13
+ ['#missing space'])
14
+ expect(lcs.offences.size).to eq(1)
15
+ end
16
+
17
+ it 'does not register an offence for # followed by no text' do
18
+ inspect_source(lcs,
19
+ 'file.rb',
20
+ ['#'])
21
+ expect(lcs.offences).to be_empty
22
+ end
23
+
24
+ it 'does not register an offence for more than one space' do
25
+ inspect_source(lcs,
26
+ 'file.rb',
27
+ ['# heavily indented'])
28
+ expect(lcs.offences).to be_empty
29
+ end
30
+
31
+ it 'does not register an offence for more than one #' do
32
+ inspect_source(lcs,
33
+ 'file.rb',
34
+ ['###### heavily indented'])
35
+ expect(lcs.offences).to be_empty
36
+ end
37
+
38
+ it 'does not register an offence for only #s' do
39
+ inspect_source(lcs,
40
+ 'file.rb',
41
+ ['######'])
42
+ expect(lcs.offences).to be_empty
43
+ end
44
+
45
+ it 'does not register an offence for #! on first line' do
46
+ inspect_source(lcs,
47
+ 'file.rb',
48
+ ['#!/usr/bin/ruby'])
49
+ expect(lcs.offences).to be_empty
50
+ end
51
+
52
+ it 'registers an offence for #! after the first line' do
53
+ inspect_source(lcs,
54
+ 'file.rb',
55
+ ['test', '#!/usr/bin/ruby'])
56
+ expect(lcs.offences.size).to eq(1)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ describe LineContinuation do
8
+ let(:lc) { LineContinuation.new }
9
+
10
+ it 'registers an offence for line continuation char' do
11
+ inspect_source(lc, 'file.rb',
12
+ ['test = 5 \\', '+ 5'])
13
+ expect(lc.offences.size).to eq(1)
14
+ end
15
+
16
+ it 'does not register an offence for cont char in a string' do
17
+ inspect_source(lc, 'file.rb',
18
+ ['result = "test string\\\n"',
19
+ 'more'])
20
+ expect(lc.offences).to be_empty
21
+ end
22
+ end
23
+ end
24
+ end
@@ -6,6 +6,7 @@ module Rubocop
6
6
  module Cop
7
7
  describe LineLength do
8
8
  let(:ll) { LineLength.new }
9
+ before { LineLength.config = { 'Max' => 79 } }
9
10
 
10
11
  it "registers an offence for a line that's 80 characters wide" do
11
12
  ll.inspect('file.rb', ['#' * 80], nil, nil)
@@ -19,6 +19,15 @@ module Rubocop
19
19
  ['Use snake_case for methods and variables.'] * 4)
20
20
  end
21
21
 
22
+ it 'registers an offence for capitalized camel case' do
23
+ inspect_source(snake_case, 'file.rb',
24
+ ['def MyMethod',
25
+ 'end',
26
+ ])
27
+ expect(snake_case.offences.map(&:message)).to eq(
28
+ ['Use snake_case for methods and variables.'])
29
+ end
30
+
22
31
  it 'accepts snake case in names' do
23
32
  inspect_source(snake_case, 'file.rb',
24
33
  ['def my_method',
@@ -42,6 +51,17 @@ module Rubocop
42
51
  inspect_source(snake_case, 'file.rb', ['$MY_GLOBAL = 0'])
43
52
  expect(snake_case.offences.map(&:message)).to be_empty
44
53
  end
54
+
55
+ it 'accepts screaming snake case constants' do
56
+ inspect_source(snake_case, 'file.rb', ['MY_CONSTANT = 0'])
57
+ expect(snake_case.offences.map(&:message)).to be_empty
58
+ end
59
+
60
+ it 'accepts assigning to camel case constant' do
61
+ inspect_source(snake_case, 'file.rb',
62
+ ['Paren = Struct.new :left, :right, :kind'])
63
+ expect(snake_case.offences.map(&:message)).to be_empty
64
+ end
45
65
  end
46
66
  end
47
67
  end
@@ -6,10 +6,7 @@ module Rubocop
6
6
  module Cop
7
7
  describe MethodLength do
8
8
  let(:method_length) { MethodLength.new }
9
- before do
10
- MethodLength.stub(:max).and_return(5)
11
- MethodLength.stub(:count_comments?).and_return(false)
12
- end
9
+ before { MethodLength.config = { 'Max' => 5, 'CountComments' => false } }
13
10
 
14
11
  it 'rejects a method with more than 5 lines' do
15
12
  inspect_source(method_length, '', ['def m()',
@@ -133,7 +130,7 @@ module Rubocop
133
130
  end
134
131
 
135
132
  it 'has the option of counting commented lines' do
136
- MethodLength.stub(:count_comments?).and_return(true)
133
+ MethodLength.config['CountComments'] = true
137
134
  inspect_source(method_length, '', ['def m()',
138
135
  ' a = 1',
139
136
  ' #a = 2',
@@ -9,14 +9,13 @@ module Rubocop
9
9
 
10
10
  it 'registers an offence for an old lambda call' do
11
11
  inspect_source(lambda_literal, 'file.rb', ['f = lambda { |x| x }'])
12
- expect(lambda_literal.offences.map(&:message)).to eq(
13
- ['The new lambda literal syntax is preferred in Ruby 1.9.'])
12
+ expect(lambda_literal.offences.size).to eq(1)
14
13
  end
15
14
 
16
15
  it 'accepts the new lambda literal' do
17
16
  inspect_source(lambda_literal, 'file.rb', ['lambda = ->(x) { x }',
18
17
  'lambda.(1)'])
19
- expect(lambda_literal.offences.map(&:message)).to be_empty
18
+ expect(lambda_literal.offences).to be_empty
20
19
  end
21
20
  end
22
21
  end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ describe Not do
8
+ let(:a) { Not.new }
9
+
10
+ it 'registers an offence for not' do
11
+ inspect_source(a,
12
+ 'file.rb',
13
+ ['not test'])
14
+ expect(a.offences.size).to eq(1)
15
+ expect(a.offences.map(&:message))
16
+ .to eq([Not::ERROR_MESSAGE])
17
+ end
18
+
19
+ it 'does not register an offence for !' do
20
+ inspect_source(a,
21
+ 'file.rb',
22
+ ['!test'])
23
+ expect(a.offences).to be_empty
24
+ end
25
+
26
+ it 'does not register an offence for :not' do
27
+ inspect_source(a,
28
+ 'file.rb',
29
+ ['[:not, :if, :else]'])
30
+ expect(a.offences).to be_empty
31
+ end
32
+ end
33
+ end
34
+ end
@@ -24,6 +24,13 @@ module Rubocop
24
24
 
25
25
  expect(offence.to_s).to eq('C: 1: message % test')
26
26
  end
27
+
28
+ it 'redefines == to compare offences based on their contents' do
29
+ o1 = Offence.new(:test, 1, 'message')
30
+ o2 = Offence.new(:test, 1, 'message')
31
+
32
+ expect(o1 == o2).to be_true
33
+ end
27
34
  end
28
35
  end
29
36
  end
@@ -6,14 +6,19 @@ module Rubocop
6
6
  module Cop
7
7
  describe Semicolon do
8
8
  let(:s) { Semicolon.new }
9
+ before do
10
+ Semicolon.config = {
11
+ 'AllowAfterParameterListInOneLineMethods' => false,
12
+ 'AllowBeforeEndInOneLineMethods' => true
13
+ }
14
+ end
9
15
 
10
16
  it 'registers an offence for a single expression' do
11
17
  inspect_source(s,
12
18
  'file.rb',
13
19
  ['puts "this is a test";'])
14
20
  expect(s.offences.size).to eq(1)
15
- expect(s.offences.map(&:message))
16
- .to eq([Semicolon::ERROR_MESSAGE])
21
+ expect(s.offences.map(&:message)).to eq([Semicolon::ERROR_MESSAGE])
17
22
  end
18
23
 
19
24
  it 'registers an offence for several expressions' do
@@ -21,8 +26,78 @@ module Rubocop
21
26
  'file.rb',
22
27
  ['puts "this is a test"; puts "So is this"'])
23
28
  expect(s.offences.size).to eq(1)
24
- expect(s.offences.map(&:message))
25
- .to eq([Semicolon::ERROR_MESSAGE])
29
+ expect(s.offences.map(&:message)).to eq([Semicolon::ERROR_MESSAGE])
30
+ end
31
+
32
+ it 'registers an offence for one line method with two statements' do
33
+ inspect_source(s,
34
+ 'file.rb',
35
+ ['def foo(a) x(1); y(2); z(3); end'])
36
+ expect(s.offences.size).to eq(2)
37
+ end
38
+
39
+ it 'registers an offence for semicolon before end if so configured' do
40
+ Semicolon.config['AllowBeforeEndInOneLineMethods'] = false
41
+ inspect_source(s,
42
+ 'file.rb',
43
+ ['def foo(a) z(3); end'])
44
+ expect(s.offences.size).to eq(1)
45
+ end
46
+
47
+ it 'accepts semicolon before end if so configured' do
48
+ inspect_source(s,
49
+ 'file.rb',
50
+ ['def foo(a) z(3); end'])
51
+ expect(s.offences).to be_empty
52
+ end
53
+
54
+ it 'registers an offence for semicolon after params if so configured' do
55
+ inspect_source(s,
56
+ 'file.rb',
57
+ ['def foo(a); y(2); z(3) end',
58
+ 'def bar(a) y(2); z(3) end'])
59
+ expect(s.offences.size).to eq(3)
60
+ end
61
+
62
+ it 'accepts semicolon after params if so configured' do
63
+ Semicolon.config['AllowAfterParameterListInOneLineMethods'] = true
64
+ inspect_source(s,
65
+ 'file.rb',
66
+ ['def foo(a); z(3) end'])
67
+ expect(s.offences).to be_empty
68
+ end
69
+
70
+ it 'accepts one line method definitions' do
71
+ Semicolon.config['AllowAfterParameterListInOneLineMethods'] = true
72
+ inspect_source(s,
73
+ 'file.rb',
74
+ ['def foo1; x(3) end',
75
+ 'def initialize(*_); end',
76
+ 'def foo2() x(3); end',
77
+ 'def foo3; x(3); end'])
78
+ expect(s.offences).to be_empty
79
+ end
80
+
81
+ it 'accepts one line empty class definitions' do
82
+ inspect_source(s,
83
+ 'file.rb',
84
+ [' class Foo < Exception; end',
85
+ ' class Bar; end'])
86
+ expect(s.offences).to be_empty
87
+ end
88
+
89
+ it 'accepts one line empty module definitions' do
90
+ inspect_source(s,
91
+ 'file.rb',
92
+ ['module Foo; end'])
93
+ expect(s.offences).to be_empty
94
+ end
95
+
96
+ it 'registers an offence for semicolon at the end no matter what' do
97
+ inspect_source(s,
98
+ 'file.rb',
99
+ ['module Foo; end;'])
100
+ expect(s.offences.size).to eq(1)
26
101
  end
27
102
  end
28
103
  end
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ describe SingleLineMethods do
8
+ let(:slm) { SingleLineMethods.new }
9
+ before { SingleLineMethods.config = { 'AllowIfMethodIsEmpty' => true } }
10
+
11
+ it 'registers an offence for a single-line method' do
12
+ inspect_source(slm, '',
13
+ ['def some_method; body end',
14
+ 'def link_to(name, url); {:name => name}; end',
15
+ 'def @table.columns; super; end'])
16
+ expect(slm.offences.map(&:message)).to eq(
17
+ [SingleLineMethods::ERROR_MESSAGE] * 3)
18
+ end
19
+
20
+ it 'registers an offence for an empty method if so configured' do
21
+ SingleLineMethods.config = { 'AllowIfMethodIsEmpty' => false }
22
+ inspect_source(slm, '', ['def no_op; end',
23
+ 'def self.resource_class=(klass); end',
24
+ 'def @table.columns; end'])
25
+ expect(slm.offences.size).to eq(3)
26
+ end
27
+
28
+ it 'accepts a single-line empty method if so configured' do
29
+ SingleLineMethods.config = { 'AllowIfMethodIsEmpty' => true }
30
+ inspect_source(slm, '', ['def no_op; end',
31
+ 'def self.resource_class=(klass); end',
32
+ 'def @table.columns; end'])
33
+ expect(slm.offences).to be_empty
34
+ end
35
+
36
+ it 'accepts a multi-line method' do
37
+ inspect_source(slm, '', ['def some_method',
38
+ ' body',
39
+ 'end'])
40
+ expect(slm.offences).to be_empty
41
+ end
42
+
43
+ it 'does not crash on an method with a capitalized name' do
44
+ inspect_source(slm, '', ['def NoSnakeCase',
45
+ 'end'])
46
+ expect(slm.offences).to be_empty
47
+ end
48
+ end
49
+ end
50
+ end