rubocop 0.11.1 → 0.12.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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -1
  3. data/README.md +28 -3
  4. data/config/default.yml +14 -12
  5. data/config/disabled.yml +1 -1
  6. data/config/enabled.yml +190 -118
  7. data/lib/rubocop.rb +9 -1
  8. data/lib/rubocop/cli.rb +49 -13
  9. data/lib/rubocop/config.rb +5 -5
  10. data/lib/rubocop/cop/cop.rb +34 -1
  11. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +47 -0
  12. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
  13. data/lib/rubocop/cop/lint/useless_assignment.rb +39 -11
  14. data/lib/rubocop/cop/lint/useless_comparison.rb +2 -4
  15. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +20 -0
  16. data/lib/rubocop/cop/rails/read_attribute.rb +28 -0
  17. data/lib/rubocop/cop/style/access_control.rb +12 -1
  18. data/lib/rubocop/cop/style/attr.rb +7 -0
  19. data/lib/rubocop/cop/style/collection_methods.rb +13 -1
  20. data/lib/rubocop/cop/style/constant_name.rb +1 -1
  21. data/lib/rubocop/cop/style/def_parentheses.rb +18 -0
  22. data/lib/rubocop/cop/style/documentation.rb +1 -1
  23. data/lib/rubocop/cop/style/empty_literal.rb +14 -0
  24. data/lib/rubocop/cop/style/even_odd.rb +56 -0
  25. data/lib/rubocop/cop/style/favor_modifier.rb +2 -2
  26. data/lib/rubocop/cop/style/hash_methods.rb +40 -0
  27. data/lib/rubocop/cop/style/indentation_width.rb +148 -0
  28. data/lib/rubocop/cop/style/method_and_variable_snake_case.rb +40 -25
  29. data/lib/rubocop/cop/style/method_call_parentheses.rb +8 -0
  30. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -1
  31. data/lib/rubocop/cop/style/nil_comparison.rb +38 -0
  32. data/lib/rubocop/cop/style/signal_exception.rb +11 -0
  33. data/lib/rubocop/cop/style/space_after_method_name.rb +34 -0
  34. data/lib/rubocop/cop/util.rb +17 -0
  35. data/lib/rubocop/formatter/emacs_style_formatter.rb +2 -2
  36. data/lib/rubocop/formatter/file_list_formatter.rb +3 -2
  37. data/lib/rubocop/formatter/formatter_set.rb +3 -11
  38. data/lib/rubocop/formatter/offence_count_formatter.rb +50 -0
  39. data/lib/rubocop/formatter/progress_formatter.rb +0 -2
  40. data/lib/rubocop/formatter/simple_text_formatter.rb +1 -6
  41. data/lib/rubocop/version.rb +1 -1
  42. data/spec/project_spec.rb +7 -0
  43. data/spec/rubocop/cli_spec.rb +119 -57
  44. data/spec/rubocop/config_spec.rb +23 -17
  45. data/spec/rubocop/cop/commissioner_spec.rb +8 -8
  46. data/spec/rubocop/cop/cop_spec.rb +80 -0
  47. data/spec/rubocop/cop/lint/parentheses_as_grouped_expression_spec.rb +63 -0
  48. data/spec/rubocop/cop/lint/useless_assignment_spec.rb +59 -0
  49. data/spec/rubocop/cop/rails/has_and_belongs_to_many_spec.rb +19 -0
  50. data/spec/rubocop/cop/rails/read_attribute_spec.rb +19 -0
  51. data/spec/rubocop/cop/rails/validation_spec.rb +5 -5
  52. data/spec/rubocop/cop/style/access_control_spec.rb +28 -0
  53. data/spec/rubocop/cop/style/attr_spec.rb +6 -1
  54. data/spec/rubocop/cop/style/collection_methods_spec.rb +5 -0
  55. data/spec/rubocop/cop/style/constant_name_spec.rb +9 -0
  56. data/spec/rubocop/cop/style/def_with_parentheses_spec.rb +14 -9
  57. data/spec/rubocop/cop/style/def_without_parentheses_spec.rb +12 -7
  58. data/spec/rubocop/cop/style/empty_literal_spec.rb +42 -27
  59. data/spec/rubocop/cop/style/even_odd_spec.rb +47 -0
  60. data/spec/rubocop/cop/style/favor_modifier_spec.rb +15 -14
  61. data/spec/rubocop/cop/style/hash_methods_spec.rb +51 -0
  62. data/spec/rubocop/cop/style/indentation_width_spec.rb +390 -0
  63. data/spec/rubocop/cop/style/method_and_variable_snake_case_spec.rb +58 -50
  64. data/spec/rubocop/cop/style/method_call_parentheses_spec.rb +6 -1
  65. data/spec/rubocop/cop/style/nil_comparison_spec.rb +31 -0
  66. data/spec/rubocop/cop/style/signal_exception_spec.rb +28 -0
  67. data/spec/rubocop/cop/style/space_after_method_name_spec.rb +61 -0
  68. data/spec/rubocop/formatter/emacs_style_formatter_spec.rb +9 -2
  69. data/spec/rubocop/formatter/file_list_formatter_spec.rb +3 -3
  70. data/spec/rubocop/formatter/offence_count_formatter_spec.rb +52 -0
  71. data/spec/rubocop/formatter/progress_formatter_spec.rb +70 -84
  72. data/spec/rubocop/source_parser_spec.rb +1 -1
  73. metadata +29 -5
  74. data/lib/rubocop/cop/style/line_continuation.rb +0 -27
  75. data/spec/rubocop/cop/style/line_continuation_spec.rb +0 -26
@@ -6,33 +6,38 @@ module Rubocop
6
6
  module Cop
7
7
  module Style
8
8
  describe DefWithParentheses do
9
- let(:def_par) { DefWithParentheses.new }
9
+ let(:cop) { described_class.new }
10
10
 
11
11
  it 'reports an offence for def with empty parens' do
12
12
  src = ['def func()',
13
13
  'end']
14
- inspect_source(def_par, src)
15
- expect(def_par.offences.size).to eq(1)
14
+ inspect_source(cop, src)
15
+ expect(cop.offences.size).to eq(1)
16
16
  end
17
17
 
18
18
  it 'reports an offence for class def with empty parens' do
19
19
  src = ['def Test.func()',
20
20
  'end']
21
- inspect_source(def_par, src)
22
- expect(def_par.offences.size).to eq(1)
21
+ inspect_source(cop, src)
22
+ expect(cop.offences.size).to eq(1)
23
23
  end
24
24
 
25
25
  it 'accepts def with arg and parens' do
26
26
  src = ['def func(a)',
27
27
  'end']
28
- inspect_source(def_par, src)
29
- expect(def_par.offences).to be_empty
28
+ inspect_source(cop, src)
29
+ expect(cop.offences).to be_empty
30
30
  end
31
31
 
32
32
  it 'accepts empty parentheses in one liners' do
33
33
  src = ["def to_s() join '/' end"]
34
- inspect_source(def_par, src)
35
- expect(def_par.offences).to be_empty
34
+ inspect_source(cop, src)
35
+ expect(cop.offences).to be_empty
36
+ end
37
+
38
+ it 'auto-removes unneeded parens' do
39
+ new_source = autocorrect_source(cop, "def test();\nsomething\nend")
40
+ expect(new_source).to eq("def test;\nsomething\nend")
36
41
  end
37
42
  end
38
43
  end
@@ -6,27 +6,32 @@ module Rubocop
6
6
  module Cop
7
7
  module Style
8
8
  describe DefWithoutParentheses do
9
- let(:def_par) { DefWithoutParentheses.new }
9
+ let(:cop) { described_class.new }
10
10
 
11
11
  it 'reports an offence for def with parameters but no parens' do
12
12
  src = ['def func a, b',
13
13
  'end']
14
- inspect_source(def_par, src)
15
- expect(def_par.offences.size).to eq(1)
14
+ inspect_source(cop, src)
15
+ expect(cop.offences.size).to eq(1)
16
16
  end
17
17
 
18
18
  it 'reports an offence for class def with parameters but no parens' do
19
19
  src = ['def Test.func a, b',
20
20
  'end']
21
- inspect_source(def_par, src)
22
- expect(def_par.offences.size).to eq(1)
21
+ inspect_source(cop, src)
22
+ expect(cop.offences.size).to eq(1)
23
23
  end
24
24
 
25
25
  it 'accepts def with no args and no parens' do
26
26
  src = ['def func',
27
27
  'end']
28
- inspect_source(def_par, src)
29
- expect(def_par.offences).to be_empty
28
+ inspect_source(cop, src)
29
+ expect(cop.offences).to be_empty
30
+ end
31
+
32
+ it 'auto-adds required parens' do
33
+ new_source = autocorrect_source(cop, 'def test param; end')
34
+ expect(new_source).to eq('def test (param); end')
30
35
  end
31
36
  end
32
37
  end
@@ -6,83 +6,98 @@ module Rubocop
6
6
  module Cop
7
7
  module Style
8
8
  describe EmptyLiteral do
9
- let(:a) { EmptyLiteral.new }
9
+ let(:cop) { described_class.new }
10
10
 
11
11
  describe 'Empty Array' do
12
12
  it 'registers an offence for Array.new()' do
13
- inspect_source(a,
13
+ inspect_source(cop,
14
14
  ['test = Array.new()'])
15
- expect(a.offences.size).to eq(1)
16
- expect(a.offences.map(&:message))
15
+ expect(cop.offences.size).to eq(1)
16
+ expect(cop.offences.map(&:message))
17
17
  .to eq([EmptyLiteral::ARR_MSG])
18
18
  end
19
19
 
20
20
  it 'registers an offence for Array.new' do
21
- inspect_source(a,
21
+ inspect_source(cop,
22
22
  ['test = Array.new'])
23
- expect(a.offences.size).to eq(1)
24
- expect(a.offences.map(&:message))
23
+ expect(cop.offences.size).to eq(1)
24
+ expect(cop.offences.map(&:message))
25
25
  .to eq([EmptyLiteral::ARR_MSG])
26
26
  end
27
27
 
28
28
  it 'does not register an offence for Array.new(3)' do
29
- inspect_source(a,
29
+ inspect_source(cop,
30
30
  ['test = Array.new(3)'])
31
- expect(a.offences).to be_empty
31
+ expect(cop.offences).to be_empty
32
+ end
33
+
34
+ it 'auto-corrects Array.new to []' do
35
+ new_source = autocorrect_source(cop, 'test = Array.new')
36
+ expect(new_source).to eq('test = []')
32
37
  end
33
38
  end
34
39
 
35
40
  describe 'Empty Hash' do
36
41
  it 'registers an offence for Hash.new()' do
37
- inspect_source(a,
42
+ inspect_source(cop,
38
43
  ['test = Hash.new()'])
39
- expect(a.offences.size).to eq(1)
40
- expect(a.offences.map(&:message))
44
+ expect(cop.offences.size).to eq(1)
45
+ expect(cop.offences.map(&:message))
41
46
  .to eq([EmptyLiteral::HASH_MSG])
42
47
  end
43
48
 
44
49
  it 'registers an offence for Hash.new' do
45
- inspect_source(a,
50
+ inspect_source(cop,
46
51
  ['test = Hash.new'])
47
- expect(a.offences.size).to eq(1)
48
- expect(a.offences.map(&:message))
52
+ expect(cop.offences.size).to eq(1)
53
+ expect(cop.offences.map(&:message))
49
54
  .to eq([EmptyLiteral::HASH_MSG])
50
55
  end
51
56
 
52
57
  it 'does not register an offence for Hash.new(3)' do
53
- inspect_source(a,
58
+ inspect_source(cop,
54
59
  ['test = Hash.new(3)'])
55
- expect(a.offences).to be_empty
60
+ expect(cop.offences).to be_empty
56
61
  end
57
62
 
58
63
  it 'does not register an offence for Hash.new { block }' do
59
- inspect_source(a,
64
+ inspect_source(cop,
60
65
  ['test = Hash.new { block }'])
61
- expect(a.offences).to be_empty
66
+ expect(cop.offences).to be_empty
67
+ end
68
+
69
+ it 'auto-corrects Hash.new to {}' do
70
+ new_source = autocorrect_source(cop, 'test = Hash.new')
71
+ expect(new_source).to eq('test = {}')
62
72
  end
63
73
  end
64
74
 
65
75
  describe 'Empty String' do
66
76
  it 'registers an offence for String.new()' do
67
- inspect_source(a,
77
+ inspect_source(cop,
68
78
  ['test = String.new()'])
69
- expect(a.offences.size).to eq(1)
70
- expect(a.offences.map(&:message))
79
+ expect(cop.offences.size).to eq(1)
80
+ expect(cop.offences.map(&:message))
71
81
  .to eq([EmptyLiteral::STR_MSG])
72
82
  end
73
83
 
74
84
  it 'registers an offence for String.new' do
75
- inspect_source(a,
85
+ inspect_source(cop,
76
86
  ['test = String.new'])
77
- expect(a.offences.size).to eq(1)
78
- expect(a.offences.map(&:message))
87
+ expect(cop.offences.size).to eq(1)
88
+ expect(cop.offences.map(&:message))
79
89
  .to eq([EmptyLiteral::STR_MSG])
80
90
  end
81
91
 
82
92
  it 'does not register an offence for String.new("top")' do
83
- inspect_source(a,
93
+ inspect_source(cop,
84
94
  ['test = String.new("top")'])
85
- expect(a.offences).to be_empty
95
+ expect(cop.offences).to be_empty
96
+ end
97
+
98
+ it 'auto-corrects String.new to empty string literal' do
99
+ new_source = autocorrect_source(cop, 'test = String.new')
100
+ expect(new_source).to eq("test = ''")
86
101
  end
87
102
  end
88
103
  end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ module Style
8
+ describe EvenOdd do
9
+ let(:cop) { described_class.new }
10
+
11
+ it 'registers an offence for x % 2 == 0' do
12
+ inspect_source(cop,
13
+ ['x % 2 == 0'])
14
+ expect(cop.offences.size).to eq(1)
15
+ expect(cop.messages).to eq([EvenOdd::MSG_EVEN])
16
+ end
17
+
18
+ it 'registers an offence for (x % 2) == 0' do
19
+ inspect_source(cop,
20
+ ['(x % 2) == 0'])
21
+ expect(cop.offences.size).to eq(1)
22
+ expect(cop.messages).to eq([EvenOdd::MSG_EVEN])
23
+ end
24
+
25
+ it 'registers an offence for x % 2 == 1' do
26
+ inspect_source(cop,
27
+ ['x % 2 == 1'])
28
+ expect(cop.offences.size).to eq(1)
29
+ expect(cop.messages).to eq([EvenOdd::MSG_ODD])
30
+ end
31
+
32
+ it 'registers an offence for (x % 2) == 1' do
33
+ inspect_source(cop,
34
+ ['(x % 2) == 1'])
35
+ expect(cop.offences.size).to eq(1)
36
+ expect(cop.messages).to eq([EvenOdd::MSG_ODD])
37
+ end
38
+
39
+ it 'accepts x % 3 == 0' do
40
+ inspect_source(cop,
41
+ ['x % 3 == 0'])
42
+ expect(cop.offences).to be_empty
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -28,20 +28,20 @@ module Rubocop
28
28
  end
29
29
 
30
30
  it 'registers an offence for short multiline if near an else etc' do
31
- inspect_source(if_unless,
32
- ['if x',
33
- ' y',
34
- 'elsif x1',
35
- ' y1',
36
- 'else',
37
- ' z',
38
- 'end',
39
- 'n = a ? 0 : 1',
40
- 'm = 3 if m0',
41
- '',
42
- 'if a',
43
- ' b',
44
- 'end'])
31
+ inspect_source(if_unless,
32
+ ['if x',
33
+ ' y',
34
+ 'elsif x1',
35
+ ' y1',
36
+ 'else',
37
+ ' z',
38
+ 'end',
39
+ 'n = a ? 0 : 1',
40
+ 'm = 3 if m0',
41
+ '',
42
+ 'if a',
43
+ ' b',
44
+ 'end'])
45
45
  expect(if_unless.offences.size).to eq(1)
46
46
  end
47
47
 
@@ -148,6 +148,7 @@ module Rubocop
148
148
  expect(cop.offences.map(&:message)).to eq(
149
149
  ['Favor modifier while/until usage when you have a single-line ' +
150
150
  'body.'])
151
+ expect(cop.offences.map { |o| o.location.source }).to eq([keyword])
151
152
  end
152
153
 
153
154
  def check_too_long(cop, keyword)
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ module Style
8
+ describe HashMethods do
9
+ let(:cop) { described_class.new }
10
+
11
+ it 'registers an offence for has_key? with one arg' do
12
+ inspect_source(cop,
13
+ ['o.has_key?(o)'])
14
+ expect(cop.offences.size).to eq(1)
15
+ expect(cop.messages)
16
+ .to eq(['has_key? is deprecated in favor of key?.'])
17
+ end
18
+
19
+ it 'accepts has_key? with no args' do
20
+ inspect_source(cop,
21
+ ['o.has_key?'])
22
+ expect(cop.offences).to be_empty
23
+ end
24
+
25
+ it 'registers an offence for has_value? with one arg' do
26
+ inspect_source(cop,
27
+ ['o.has_value?(o)'])
28
+ expect(cop.offences.size).to eq(1)
29
+ expect(cop.messages)
30
+ .to eq(['has_value? is deprecated in favor of value?.'])
31
+ end
32
+
33
+ it 'accepts has_value? with no args' do
34
+ inspect_source(cop,
35
+ ['o.has_value?'])
36
+ expect(cop.offences).to be_empty
37
+ end
38
+
39
+ it 'auto-corrects has_key? with key?' do
40
+ new_source = autocorrect_source(cop, 'hash.has_key?(:test)')
41
+ expect(new_source).to eq('hash.key?(:test)')
42
+ end
43
+
44
+ it 'auto-corrects has_value? with value?' do
45
+ new_source = autocorrect_source(cop, 'hash.has_value?(value)')
46
+ expect(new_source).to eq('hash.value?(value)')
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,390 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module Rubocop
6
+ module Cop
7
+ module Style
8
+ describe IndentationWidth do
9
+ let(:cop) { described_class.new }
10
+
11
+ context 'with if statement' do
12
+ it 'registers an offence for bad indentation of an if body' do
13
+ inspect_source(cop,
14
+ ['if cond',
15
+ ' func',
16
+ 'end'])
17
+ expect(cop.offences.map(&:message))
18
+ .to eq(['Use 2 (not 1) spaces for indentation.'])
19
+ end
20
+
21
+ it 'registers an offence for bad indentation of an else body' do
22
+ inspect_source(cop,
23
+ ['if cond',
24
+ ' func1',
25
+ 'else',
26
+ ' func2',
27
+ 'end'])
28
+ expect(cop.offences.map(&:message))
29
+ .to eq(['Use 2 (not 1) spaces for indentation.'])
30
+ end
31
+
32
+ it 'registers an offence for bad indentation of an elsif body' do
33
+ inspect_source(cop,
34
+ ['if a1',
35
+ ' b1',
36
+ 'elsif a2',
37
+ ' b2',
38
+ 'else',
39
+ ' c',
40
+ 'end'])
41
+ expect(cop.offences.map(&:message))
42
+ .to eq(['Use 2 (not 1) spaces for indentation.'])
43
+ end
44
+
45
+ it 'registers offence for bad indentation of ternary inside else' do
46
+ inspect_source(cop,
47
+ ['if a',
48
+ ' b',
49
+ 'else',
50
+ ' x ? y : z',
51
+ 'end'])
52
+ expect(cop.offences.map(&:message))
53
+ .to eq(['Use 2 (not 5) spaces for indentation.'])
54
+ end
55
+
56
+ it 'registers offence for bad indentation of modifier if in else' do
57
+ inspect_source(cop,
58
+ ['if a',
59
+ ' b',
60
+ 'else',
61
+ ' x if y',
62
+ 'end'])
63
+ expect(cop.offences.map(&:message))
64
+ .to eq(['Use 2 (not 3) spaces for indentation.'])
65
+ end
66
+
67
+ it 'accepts a one line if statement' do
68
+ inspect_source(cop,
69
+ ['if cond then func1 else func2 end'])
70
+ expect(cop.offences).to be_empty
71
+ end
72
+
73
+ it 'accepts a correctly aligned if/elsif/else/end' do
74
+ inspect_source(cop,
75
+ ['if a1',
76
+ ' b1',
77
+ 'elsif a2',
78
+ ' b2',
79
+ 'else',
80
+ ' c',
81
+ 'end'])
82
+ expect(cop.offences).to be_empty
83
+ end
84
+
85
+ it 'accepts if/elsif/else/end laid out as a table' do
86
+ inspect_source(cop,
87
+ ['if @io == $stdout then str << "$stdout"',
88
+ 'elsif @io == $stdin then str << "$stdin"',
89
+ 'elsif @io == $stderr then str << "$stderr"',
90
+ 'else str << @io.class.to_s',
91
+ 'end'])
92
+ expect(cop.offences).to be_empty
93
+ end
94
+
95
+ it 'accepts if/then/else/end laid out as another table' do
96
+ inspect_source(cop,
97
+ ["if File.exist?('config.save')",
98
+ 'then ConfigTable.load',
99
+ 'else ConfigTable.new',
100
+ 'end'])
101
+ expect(cop.offences).to be_empty
102
+ end
103
+
104
+ it 'accepts an empty if' do
105
+ inspect_source(cop,
106
+ ['if a',
107
+ 'else',
108
+ 'end'])
109
+ expect(cop.offences).to be_empty
110
+ end
111
+
112
+ it 'accepts an if/else branches with rescue clauses' do
113
+ # Because of how the rescue clauses come out of Parser, these are
114
+ # special and need to be tested.
115
+ inspect_source(cop,
116
+ ['if a',
117
+ ' a rescue nil',
118
+ 'else',
119
+ ' a rescue nil',
120
+ 'end'])
121
+ expect(cop.offences).to be_empty
122
+ end
123
+ end
124
+
125
+ context 'with unless' do
126
+ it 'registers an offence for bad indentation of an unless body' do
127
+ inspect_source(cop,
128
+ ['unless cond',
129
+ ' func',
130
+ 'end'])
131
+ expect(cop.offences.map(&:message))
132
+ .to eq(['Use 2 (not 1) spaces for indentation.'])
133
+ end
134
+
135
+ it 'accepts an empty unless' do
136
+ inspect_source(cop,
137
+ ['unless a',
138
+ 'else',
139
+ 'end'])
140
+ expect(cop.offences).to be_empty
141
+ end
142
+ end
143
+
144
+ context 'with case' do
145
+ it 'registers an offence for bad indentation in a case/when body' do
146
+ inspect_source(cop,
147
+ ['case a',
148
+ 'when b',
149
+ ' c',
150
+ 'end'])
151
+ expect(cop.offences.map(&:message))
152
+ .to eq(['Use 2 (not 1) spaces for indentation.'])
153
+ end
154
+
155
+ it 'registers an offence for bad indentation in a case/else body' do
156
+ inspect_source(cop,
157
+ ['case a',
158
+ 'when b',
159
+ ' c',
160
+ 'when d',
161
+ ' e',
162
+ 'else',
163
+ ' f',
164
+ 'end'])
165
+ expect(cop.offences.map(&:message))
166
+ .to eq(['Use 2 (not 3) spaces for indentation.'])
167
+ end
168
+
169
+ it 'accepts correctly indented case/when/else' do
170
+ inspect_source(cop,
171
+ ['case a',
172
+ 'when b',
173
+ ' c',
174
+ 'when d',
175
+ 'else',
176
+ ' f',
177
+ 'end'])
178
+ expect(cop.offences).to be_empty
179
+ end
180
+
181
+ it 'accepts case/when/else laid out as a table' do
182
+ inspect_source(cop,
183
+ ['case sexp.loc.keyword.source',
184
+ "when 'if' then cond, body, _else = *sexp",
185
+ "when 'unless' then cond, _else, body = *sexp",
186
+ 'else cond, body = *sexp',
187
+ 'end'])
188
+ expect(cop.offences).to be_empty
189
+ end
190
+
191
+ it 'accepts case/when/else with then beginning a line' do
192
+ inspect_source(cop,
193
+ ['case sexp.loc.keyword.source',
194
+ "when 'if'",
195
+ 'then cond, body, _else = *sexp',
196
+ 'end'])
197
+ expect(cop.offences).to be_empty
198
+ end
199
+
200
+ it 'accepts indented when/else plus indented body' do
201
+ # "Indent when as deep as case" is the job of another cop.
202
+ inspect_source(cop,
203
+ ['case code_type',
204
+ " when 'ruby', 'sql', 'plain'",
205
+ ' code_type',
206
+ " when 'erb'",
207
+ " 'ruby; html-script: true'",
208
+ ' when "html"',
209
+ " 'xml'",
210
+ ' else',
211
+ " 'plain'",
212
+ 'end'])
213
+ expect(cop.offences).to be_empty
214
+ end
215
+
216
+ it 'accepts an empty case' do
217
+ inspect_source(cop,
218
+ ['case a',
219
+ 'end'])
220
+ expect(cop.offences).to be_empty
221
+ end
222
+ end
223
+
224
+ context 'with while/until' do
225
+ it 'registers an offence for bad indentation of a while body' do
226
+ inspect_source(cop,
227
+ ['while cond',
228
+ ' func',
229
+ 'end'])
230
+ expect(cop.offences.map(&:message))
231
+ .to eq(['Use 2 (not 1) spaces for indentation.'])
232
+ end
233
+
234
+ it 'registers an offence for bad indentation of begin/end/while' do
235
+ inspect_source(cop,
236
+ ['begin',
237
+ ' func1',
238
+ ' func2',
239
+ 'end while cond'])
240
+ expect(cop.offences.map(&:message))
241
+ .to eq(['Use 2 (not 1) spaces for indentation.',
242
+ 'Use 2 (not 3) spaces for indentation.'])
243
+ end
244
+
245
+ it 'registers an offence for bad indentation of an until body' do
246
+ inspect_source(cop,
247
+ ['until cond',
248
+ ' func',
249
+ 'end'])
250
+ expect(cop.offences.map(&:message))
251
+ .to eq(['Use 2 (not 1) spaces for indentation.'])
252
+ end
253
+
254
+ it 'accepts an empty while' do
255
+ inspect_source(cop,
256
+ ['while a',
257
+ 'end'])
258
+ expect(cop.offences).to be_empty
259
+ end
260
+ end
261
+
262
+ context 'with for' do
263
+ it 'registers an offence for bad indentation of a for body' do
264
+ inspect_source(cop,
265
+ ['for var in 1..10',
266
+ ' func',
267
+ 'end'])
268
+ expect(cop.offences.map(&:message))
269
+ .to eq(['Use 2 (not 1) spaces for indentation.'])
270
+ end
271
+
272
+ it 'accepts an empty for' do
273
+ inspect_source(cop,
274
+ ['for var in 1..10',
275
+ 'end'])
276
+ expect(cop.offences).to be_empty
277
+ end
278
+ end
279
+
280
+ context 'with def/defs' do
281
+ it 'registers an offence for bad indentation of a def body' do
282
+ inspect_source(cop,
283
+ ['def test',
284
+ ' func1',
285
+ ' func2', # No offence registered for this.
286
+ 'end'])
287
+ expect(cop.offences.map(&:message))
288
+ .to eq(['Use 2 (not 4) spaces for indentation.'])
289
+ end
290
+
291
+ it 'registers an offence for bad indentation of a defs body' do
292
+ inspect_source(cop,
293
+ ['def self.test',
294
+ ' func',
295
+ 'end'])
296
+ expect(cop.offences.map(&:message))
297
+ .to eq(['Use 2 (not 3) spaces for indentation.'])
298
+ end
299
+
300
+ it 'accepts an empty def body' do
301
+ inspect_source(cop,
302
+ ['def test',
303
+ 'end'])
304
+ expect(cop.offences).to be_empty
305
+ end
306
+
307
+ it 'accepts an empty defs body' do
308
+ inspect_source(cop,
309
+ ['def self.test',
310
+ 'end'])
311
+ expect(cop.offences).to be_empty
312
+ end
313
+ end
314
+
315
+ context 'with class' do
316
+ it 'registers an offence for bad indentation of a class body' do
317
+ inspect_source(cop,
318
+ ['class Test',
319
+ ' def func',
320
+ ' end',
321
+ 'end'])
322
+ expect(cop.offences.map(&:message))
323
+ .to eq(['Use 2 (not 4) spaces for indentation.'])
324
+ end
325
+
326
+ it 'accepts an empty class body' do
327
+ inspect_source(cop,
328
+ ['class Test',
329
+ 'end'])
330
+ expect(cop.offences).to be_empty
331
+ end
332
+ end
333
+
334
+ context 'with module' do
335
+ it 'registers an offence for bad indentation of a module body' do
336
+ inspect_source(cop,
337
+ ['module Test',
338
+ ' def func',
339
+ ' end',
340
+ 'end'])
341
+ expect(cop.offences.map(&:message))
342
+ .to eq(['Use 2 (not 4) spaces for indentation.'])
343
+ end
344
+
345
+ it 'accepts an empty module body' do
346
+ inspect_source(cop,
347
+ ['module Test',
348
+ 'end'])
349
+ expect(cop.offences).to be_empty
350
+ end
351
+ end
352
+
353
+ context 'with block' do
354
+ it 'registers an offence for bad indentation of a do/end body' do
355
+ inspect_source(cop,
356
+ ['a = func do',
357
+ ' b',
358
+ 'end'])
359
+ expect(cop.offences.map(&:message))
360
+ .to eq(['Use 2 (not 1) spaces for indentation.'])
361
+ end
362
+
363
+ it 'registers an offence for bad indentation of a {} body' do
364
+ inspect_source(cop,
365
+ ['func {',
366
+ ' b',
367
+ '}'])
368
+ expect(cop.offences.map(&:message))
369
+ .to eq(['Use 2 (not 3) spaces for indentation.'])
370
+ end
371
+
372
+ it 'accepts a correctly indented block body' do
373
+ inspect_source(cop,
374
+ ['a = func do',
375
+ ' b',
376
+ 'end'])
377
+ expect(cop.offences).to be_empty
378
+ end
379
+
380
+ it 'accepts an empty block body' do
381
+ inspect_source(cop,
382
+ ['a = func do',
383
+ 'end'])
384
+ expect(cop.offences).to be_empty
385
+ end
386
+ end
387
+ end
388
+ end
389
+ end
390
+ end