rubocop 0.26.1 → 0.27.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +10 -6
- data/.travis.yml +2 -0
- data/CHANGELOG.md +30 -0
- data/README.md +9 -2
- data/assets/logo.png +0 -0
- data/assets/output.html.erb +68 -65
- data/config/default.yml +42 -7
- data/config/disabled.yml +5 -0
- data/config/enabled.yml +32 -7
- data/lib/rubocop.rb +10 -2
- data/lib/rubocop/comment_config.rb +11 -17
- data/lib/rubocop/config.rb +20 -16
- data/lib/rubocop/config_loader.rb +8 -12
- data/lib/rubocop/cop/cop.rb +13 -12
- data/lib/rubocop/cop/lint/block_alignment.rb +4 -6
- data/lib/rubocop/cop/lint/def_end_alignment.rb +2 -2
- data/lib/rubocop/cop/lint/require_parentheses.rb +1 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -3
- data/lib/rubocop/cop/lint/useless_setter_call.rb +2 -2
- data/lib/rubocop/cop/metrics/abc_size.rb +27 -0
- data/lib/rubocop/cop/metrics/block_nesting.rb +2 -4
- data/lib/rubocop/cop/metrics/class_length.rb +1 -1
- data/lib/rubocop/cop/metrics/line_length.rb +2 -5
- data/lib/rubocop/cop/metrics/method_length.rb +2 -2
- data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +24 -15
- data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +15 -2
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +63 -0
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/if_node.rb +3 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +3 -3
- data/lib/rubocop/cop/mixin/{on_method.rb → on_method_def.rb} +3 -3
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +2 -2
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -2
- data/lib/rubocop/cop/mixin/string_literals_help.rb +28 -0
- data/lib/rubocop/cop/rails/delegate.rb +2 -2
- data/lib/rubocop/cop/style/access_modifier_indentation.rb +2 -2
- data/lib/rubocop/cop/style/accessor_method_name.rb +2 -2
- data/lib/rubocop/cop/style/align_hash.rb +16 -12
- data/lib/rubocop/cop/style/align_parameters.rb +1 -1
- data/lib/rubocop/cop/style/and_or.rb +14 -6
- data/lib/rubocop/cop/style/array_join.rb +1 -1
- data/lib/rubocop/cop/style/block_comments.rb +16 -8
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +6 -30
- data/lib/rubocop/cop/style/case_indentation.rb +20 -12
- data/lib/rubocop/cop/style/collection_methods.rb +4 -4
- data/lib/rubocop/cop/style/colon_method_call.rb +9 -0
- data/lib/rubocop/cop/style/comment_annotation.rb +1 -1
- data/lib/rubocop/cop/style/comment_indentation.rb +22 -22
- data/lib/rubocop/cop/style/def_with_parentheses.rb +2 -2
- data/lib/rubocop/cop/style/deprecated_hash_methods.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +6 -1
- data/lib/rubocop/cop/style/else_alignment.rb +93 -0
- data/lib/rubocop/cop/style/empty_line_between_defs.rb +1 -1
- data/lib/rubocop/cop/style/empty_lines.rb +1 -1
- data/lib/rubocop/cop/style/empty_lines_around_class_body.rb +34 -0
- data/lib/rubocop/cop/style/empty_lines_around_method_body.rb +37 -0
- data/lib/rubocop/cop/style/empty_lines_around_module_body.rb +30 -0
- data/lib/rubocop/cop/style/encoding.rb +1 -1
- data/lib/rubocop/cop/style/format_string.rb +4 -4
- data/lib/rubocop/cop/style/indent_array.rb +2 -2
- data/lib/rubocop/cop/style/indent_hash.rb +17 -12
- data/lib/rubocop/cop/style/indentation_width.rb +27 -19
- data/lib/rubocop/cop/style/method_call_parentheses.rb +3 -3
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +1 -1
- data/lib/rubocop/cop/style/method_def_parentheses.rb +17 -11
- data/lib/rubocop/cop/style/method_name.rb +1 -1
- data/lib/rubocop/cop/style/multiline_operation_indentation.rb +174 -0
- data/lib/rubocop/cop/style/non_nil_check.rb +12 -15
- data/lib/rubocop/cop/style/not.rb +1 -1
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +12 -17
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/predicate_name.rb +2 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +2 -2
- data/lib/rubocop/cop/style/redundant_return.rb +3 -3
- data/lib/rubocop/cop/style/redundant_self.rb +3 -3
- data/lib/rubocop/cop/style/regexp_literal.rb +17 -13
- data/lib/rubocop/cop/style/rescue_modifier.rb +2 -2
- data/lib/rubocop/cop/style/single_line_methods.rb +7 -4
- data/lib/rubocop/cop/style/space_after_method_name.rb +2 -2
- data/lib/rubocop/cop/style/space_around_equals_in_parameter_default.rb +17 -11
- data/lib/rubocop/cop/style/space_before_block_braces.rb +1 -1
- data/lib/rubocop/cop/style/space_inside_block_braces.rb +17 -14
- data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +10 -6
- data/lib/rubocop/cop/style/string_literals.rb +13 -16
- data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +41 -0
- data/lib/rubocop/cop/style/trailing_comma.rb +1 -3
- data/lib/rubocop/cop/style/trivial_accessors.rb +3 -3
- data/lib/rubocop/cop/style/unneeded_capital_w.rb +1 -1
- data/lib/rubocop/cop/style/unneeded_percent_q.rb +2 -2
- data/lib/rubocop/cop/style/word_array.rb +23 -19
- data/lib/rubocop/cop/team.rb +13 -26
- data/lib/rubocop/cop/util.rb +5 -0
- data/lib/rubocop/cop/variable_force/locatable.rb +7 -13
- data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
- data/lib/rubocop/formatter/formatter_set.rb +9 -1
- data/lib/rubocop/formatter/html_formatter.rb +83 -55
- data/lib/rubocop/formatter/simple_text_formatter.rb +2 -2
- data/lib/rubocop/formatter/text_util.rb +25 -0
- data/lib/rubocop/options.rb +14 -7
- data/lib/rubocop/path_util.rb +11 -7
- data/lib/rubocop/runner.rb +7 -2
- data/lib/rubocop/version.rb +1 -1
- data/relnotes/v0.27.0.md +77 -0
- data/rubocop.gemspec +1 -1
- data/spec/fixtures/html_formatter/expected.html +495 -0
- data/spec/fixtures/html_formatter/project/app/controllers/application_controller.rb +5 -0
- data/spec/fixtures/html_formatter/project/app/controllers/books_controller.rb +74 -0
- data/spec/fixtures/html_formatter/project/app/models/book.rb +5 -0
- data/spec/rubocop/cli_spec.rb +56 -13
- data/spec/rubocop/cop/lint/invalid_character_literal_spec.rb +1 -1
- data/spec/rubocop/cop/metrics/abc_size_spec.rb +99 -0
- data/spec/rubocop/cop/rails/action_filter_spec.rb +1 -0
- data/spec/rubocop/cop/style/access_modifier_indentation_spec.rb +23 -1
- data/spec/rubocop/cop/style/align_hash_spec.rb +13 -0
- data/spec/rubocop/cop/style/align_parameters_spec.rb +44 -33
- data/spec/rubocop/cop/style/blocks_spec.rb +8 -0
- data/spec/rubocop/cop/style/braces_around_hash_parameters_spec.rb +9 -9
- data/spec/rubocop/cop/style/case_indentation_spec.rb +3 -2
- data/spec/rubocop/cop/style/colon_method_call_spec.rb +5 -0
- data/spec/rubocop/cop/style/comment_indentation_spec.rb +6 -1
- data/spec/rubocop/cop/style/else_alignment_spec.rb +437 -0
- data/spec/rubocop/cop/style/empty_lines_around_class_body_spec.rb +75 -0
- data/spec/rubocop/cop/style/{empty_lines_around_body_spec.rb → empty_lines_around_method_body_spec.rb} +9 -50
- data/spec/rubocop/cop/style/empty_lines_around_module_body_spec.rb +79 -0
- data/spec/rubocop/cop/style/file_name_spec.rb +1 -1
- data/spec/rubocop/cop/style/format_string_spec.rb +12 -0
- data/spec/rubocop/cop/style/indent_array_spec.rb +6 -1
- data/spec/rubocop/cop/style/indent_hash_spec.rb +2 -1
- data/spec/rubocop/cop/style/indentation_width_spec.rb +765 -722
- data/spec/rubocop/cop/style/multiline_operation_indentation_spec.rb +414 -0
- data/spec/rubocop/cop/style/non_nil_check_spec.rb +86 -55
- data/spec/rubocop/cop/style/single_line_methods_spec.rb +5 -1
- data/spec/rubocop/cop/style/space_before_block_braces_spec.rb +2 -1
- data/spec/rubocop/cop/style/space_inside_block_braces_spec.rb +2 -1
- data/spec/rubocop/cop/style/string_literals_in_interpolation_spec.rb +63 -0
- data/spec/rubocop/cop/style/string_literals_spec.rb +2 -2
- data/spec/rubocop/cop/style/word_array_spec.rb +15 -1
- data/spec/rubocop/formatter/base_formatter_spec.rb +1 -1
- data/spec/rubocop/formatter/disabled_lines_formatter_spec.rb +0 -1
- data/spec/rubocop/formatter/formatter_set_spec.rb +9 -0
- data/spec/rubocop/formatter/html_formatter_spec.rb +25 -122
- data/spec/rubocop/formatter/offense_count_formatter_spec.rb +0 -1
- data/spec/rubocop/runner_spec.rb +1 -1
- data/spec/spec_helper.rb +12 -130
- data/spec/support/cop_helper.rb +72 -0
- data/spec/support/coverage.rb +15 -0
- data/spec/support/{offenses_matcher.rb → custom_matchers.rb} +28 -0
- data/spec/support/jruby_workaround.rb +15 -0
- data/spec/support/{isolated_environment.rb → shared_contexts.rb} +19 -0
- metadata +49 -14
- data/lib/rubocop/cop/style/empty_lines_around_body.rb +0 -75
- data/spec/support/shared_context.rb +0 -20
@@ -0,0 +1,414 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe RuboCop::Cop::Style::MultilineOperationIndentation do
|
6
|
+
subject(:cop) { described_class.new(config) }
|
7
|
+
let(:config) do
|
8
|
+
merged = RuboCop::ConfigLoader
|
9
|
+
.default_configuration['Style/MultilineOperationIndentation']
|
10
|
+
.merge(cop_config)
|
11
|
+
RuboCop::Config
|
12
|
+
.new('Style/MultilineOperationIndentation' => merged,
|
13
|
+
'Style/IndentationWidth' => { 'Width' => indentation_width })
|
14
|
+
end
|
15
|
+
let(:indentation_width) { 2 }
|
16
|
+
|
17
|
+
shared_examples 'common' do
|
18
|
+
it 'accepts indented operands in ordinary statement' do
|
19
|
+
inspect_source(cop,
|
20
|
+
['a +',
|
21
|
+
' b'])
|
22
|
+
expect(cop.messages).to be_empty
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'registers an offense for no indentation of second line' do
|
26
|
+
inspect_source(cop,
|
27
|
+
['a +',
|
28
|
+
'b'])
|
29
|
+
expect(cop.messages).to eq(['Use 2 (not 0) spaces for indenting an ' \
|
30
|
+
'expression spanning multiple lines.'])
|
31
|
+
expect(cop.highlights).to eq(['b'])
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'registers an offense for one space indentation of second line' do
|
35
|
+
inspect_source(cop,
|
36
|
+
['a',
|
37
|
+
' .b'])
|
38
|
+
expect(cop.messages).to eq(['Use 2 (not 1) spaces for indenting an ' \
|
39
|
+
'expression spanning multiple lines.'])
|
40
|
+
expect(cop.highlights).to eq(['.b'])
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'registers an offense for three spaces indentation of second line' do
|
44
|
+
inspect_source(cop,
|
45
|
+
['a ||',
|
46
|
+
' b',
|
47
|
+
'c and',
|
48
|
+
' d'])
|
49
|
+
expect(cop.messages).to eq(['Use 2 (not 3) spaces for indenting an ' \
|
50
|
+
'expression spanning multiple lines.'] * 2)
|
51
|
+
expect(cop.highlights).to eq(%w(b d))
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'registers an offense for extra indentation of third line' do
|
55
|
+
inspect_source(cop,
|
56
|
+
[' a ||',
|
57
|
+
' b ||',
|
58
|
+
' c'])
|
59
|
+
expect(cop.messages).to eq(['Use 2 (not 4) spaces for indenting an ' \
|
60
|
+
'expression spanning multiple lines.'])
|
61
|
+
expect(cop.highlights).to eq(['c'])
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'registers an offense for the emacs ruby-mode 1.1 indentation of an ' \
|
65
|
+
'expression in an array' do
|
66
|
+
inspect_source(cop,
|
67
|
+
[' [',
|
68
|
+
' a +',
|
69
|
+
' b',
|
70
|
+
' ]'])
|
71
|
+
expect(cop.messages).to eq(['Use 2 (not 0) spaces for indenting an ' \
|
72
|
+
'expression spanning multiple lines.'])
|
73
|
+
expect(cop.highlights).to eq(['b'])
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'accepts two spaces indentation of second line' do
|
77
|
+
inspect_source(cop,
|
78
|
+
[' a ||',
|
79
|
+
' b'])
|
80
|
+
expect(cop.messages).to be_empty
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'accepts no extra indentation of third line' do
|
84
|
+
inspect_source(cop,
|
85
|
+
[' a &&',
|
86
|
+
' b &&',
|
87
|
+
' c'])
|
88
|
+
expect(cop.messages).to be_empty
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'accepts indented operands in for body' do
|
92
|
+
inspect_source(cop,
|
93
|
+
['for x in a',
|
94
|
+
' something &&',
|
95
|
+
' something_else',
|
96
|
+
'end'])
|
97
|
+
expect(cop.highlights).to be_empty
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'accepts alignment inside a grouped expression' do
|
101
|
+
inspect_source(cop,
|
102
|
+
['(a +',
|
103
|
+
' b)'])
|
104
|
+
expect(cop.messages).to be_empty
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'accepts an expression where the first operand spans multiple lines' do
|
108
|
+
inspect_source(cop,
|
109
|
+
['subject.each do |item|',
|
110
|
+
' result = resolve(locale) and return result',
|
111
|
+
'end and nil'])
|
112
|
+
expect(cop.messages).to be_empty
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'registers an offense for badly indented operands in chained ' \
|
116
|
+
'method call' do
|
117
|
+
inspect_source(cop,
|
118
|
+
['Foo',
|
119
|
+
'.a',
|
120
|
+
' .b'])
|
121
|
+
expect(cop.messages).to eq(['Use 2 (not 0) spaces for indenting an ' \
|
122
|
+
'expression spanning multiple lines.'])
|
123
|
+
expect(cop.highlights).to eq(['.a'])
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'registers an offense for badly indented operands in chained ' \
|
127
|
+
'method call' do
|
128
|
+
inspect_source(cop,
|
129
|
+
['Foo',
|
130
|
+
'.a',
|
131
|
+
' .b(c)'])
|
132
|
+
expect(cop.messages).to eq(['Use 2 (not 0) spaces for indenting an ' \
|
133
|
+
'expression spanning multiple lines.'])
|
134
|
+
expect(cop.highlights).to eq(['.a'])
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'accepts even indentation of consecutive lines in typical RSpec code' do
|
138
|
+
inspect_source(cop,
|
139
|
+
['expect { Foo.new }.',
|
140
|
+
' to change { Bar.count }.',
|
141
|
+
' from(1).to(2)'])
|
142
|
+
expect(cop.messages).to be_empty
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'registers an offense for extra indentation of 3rd line in typical ' \
|
146
|
+
'RSpec code' do
|
147
|
+
inspect_source(cop,
|
148
|
+
['expect { Foo.new }.',
|
149
|
+
' to change { Bar.count }.',
|
150
|
+
' from(1).to(2)'])
|
151
|
+
expect(cop.messages).to eq(['Use 2 (not 6) spaces for indenting an ' \
|
152
|
+
'expression spanning multiple lines.'])
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'when EnforcedStyle is aligned' do
|
157
|
+
let(:cop_config) { { 'EnforcedStyle' => 'aligned' } }
|
158
|
+
|
159
|
+
include_examples 'common'
|
160
|
+
|
161
|
+
it 'accepts aligned operands in if condition' do
|
162
|
+
inspect_source(cop,
|
163
|
+
['if a +',
|
164
|
+
' b',
|
165
|
+
' something',
|
166
|
+
'end'])
|
167
|
+
expect(cop.messages).to be_empty
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'registers an offense for misaligned operands in if condition' do
|
171
|
+
inspect_source(cop,
|
172
|
+
['if a +',
|
173
|
+
' b',
|
174
|
+
' something',
|
175
|
+
'end'])
|
176
|
+
expect(cop.messages).to eq(['Align the operands of a condition in an ' \
|
177
|
+
'`if` statement spanning multiple lines.'])
|
178
|
+
expect(cop.highlights).to eq(['b'])
|
179
|
+
expect(cop.config_to_allow_offenses).to eq('EnforcedStyle' => 'indented')
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'registers an offense for misaligned operands in unless condition' do
|
183
|
+
inspect_source(cop,
|
184
|
+
['unless a',
|
185
|
+
' .b',
|
186
|
+
' something',
|
187
|
+
'end'])
|
188
|
+
expect(cop.messages).to eq(['Align the operands of a condition in an ' \
|
189
|
+
'`unless` statement spanning multiple ' \
|
190
|
+
'lines.'])
|
191
|
+
expect(cop.highlights).to eq(['.b'])
|
192
|
+
expect(cop.config_to_allow_offenses).to be_nil
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'registers an offense for misaligned operands in while condition' do
|
196
|
+
inspect_source(cop,
|
197
|
+
['while a.',
|
198
|
+
' b',
|
199
|
+
' something',
|
200
|
+
'end'])
|
201
|
+
expect(cop.messages).to eq(['Align the operands of a condition in a ' \
|
202
|
+
'`while` statement spanning multiple lines.'])
|
203
|
+
expect(cop.highlights).to eq(['b'])
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'registers an offense for misaligned operands in until condition' do
|
207
|
+
inspect_source(cop,
|
208
|
+
['until a.',
|
209
|
+
' b',
|
210
|
+
' something',
|
211
|
+
'end'])
|
212
|
+
expect(cop.messages).to eq(['Align the operands of a condition in an ' \
|
213
|
+
'`until` statement spanning multiple lines.'])
|
214
|
+
expect(cop.highlights).to eq(['b'])
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'accepts aligned operands in assignment' do
|
218
|
+
inspect_source(cop,
|
219
|
+
['formatted_int = int_part',
|
220
|
+
' .to_s',
|
221
|
+
' .reverse',
|
222
|
+
" .gsub(/...(?=.)/, '\&_')"])
|
223
|
+
expect(cop.messages).to be_empty
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'registers an offense for unaligned operands in assignment' do
|
227
|
+
inspect_source(cop,
|
228
|
+
['bar = Foo',
|
229
|
+
' .a',
|
230
|
+
' .b(c)'])
|
231
|
+
expect(cop.messages).to eq(['Align the operands of an expression in an ' \
|
232
|
+
'assignment spanning multiple lines.'])
|
233
|
+
expect(cop.highlights).to eq(['.a'])
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'auto-corrects' do
|
237
|
+
new_source = autocorrect_source(cop, ['until a.',
|
238
|
+
' b',
|
239
|
+
' something',
|
240
|
+
'end'])
|
241
|
+
expect(new_source).to eq(['until a.',
|
242
|
+
' b',
|
243
|
+
' something',
|
244
|
+
'end'].join("\n"))
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
context 'when EnforcedStyle is indented' do
|
249
|
+
let(:cop_config) { { 'EnforcedStyle' => 'indented' } }
|
250
|
+
|
251
|
+
include_examples 'common'
|
252
|
+
|
253
|
+
it 'accepts indented operands in if condition' do
|
254
|
+
inspect_source(cop,
|
255
|
+
['if a +',
|
256
|
+
' b',
|
257
|
+
' something',
|
258
|
+
'end'])
|
259
|
+
expect(cop.messages).to be_empty
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'registers an offense for aligned operands in if condition' do
|
263
|
+
inspect_source(cop,
|
264
|
+
['if a +',
|
265
|
+
' b',
|
266
|
+
' something',
|
267
|
+
'end'])
|
268
|
+
expect(cop.messages).to eq(['Use 4 (not 3) spaces for indenting a ' \
|
269
|
+
'condition in an `if` statement spanning ' \
|
270
|
+
'multiple lines.'])
|
271
|
+
expect(cop.highlights).to eq(['b'])
|
272
|
+
expect(cop.config_to_allow_offenses).to eq('EnforcedStyle' => 'aligned')
|
273
|
+
end
|
274
|
+
|
275
|
+
it 'accepts the indentation of a broken string' do
|
276
|
+
inspect_source(cop,
|
277
|
+
["MSG = 'Use 2 (not %d) spaces for indenting a ' \\",
|
278
|
+
" 'broken line.'"])
|
279
|
+
expect(cop.messages).to be_empty
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'accepts normal indentation of method parameters' do
|
283
|
+
inspect_source(cop,
|
284
|
+
['Parser::Source::Range.new(expr.source_buffer,',
|
285
|
+
' begin_pos,',
|
286
|
+
' begin_pos + line.length)'])
|
287
|
+
expect(cop.messages).to be_empty
|
288
|
+
end
|
289
|
+
|
290
|
+
it 'accepts any indentation of method parameters' do
|
291
|
+
inspect_source(cop,
|
292
|
+
['a(b.',
|
293
|
+
' c',
|
294
|
+
'.d)'])
|
295
|
+
expect(cop.messages).to be_empty
|
296
|
+
end
|
297
|
+
|
298
|
+
it 'accepts normal indentation inside grouped expression' do
|
299
|
+
inspect_source(cop,
|
300
|
+
['arg_array.size == a.size && (',
|
301
|
+
' arg_array == a ||',
|
302
|
+
' arg_array.map(&:children) == a.map(&:children)',
|
303
|
+
')'])
|
304
|
+
expect(cop.messages).to be_empty
|
305
|
+
end
|
306
|
+
|
307
|
+
[
|
308
|
+
%w(an if),
|
309
|
+
%w(an unless),
|
310
|
+
%w(a while),
|
311
|
+
%w(an until)
|
312
|
+
].each do |article, keyword|
|
313
|
+
it "accepts double indentation of #{keyword} condition" do
|
314
|
+
inspect_source(cop,
|
315
|
+
["#{keyword} receiver.nil? &&",
|
316
|
+
' !args.empty? &&',
|
317
|
+
' BLACKLIST.include?(method_name)',
|
318
|
+
'end',
|
319
|
+
"#{keyword} receiver.",
|
320
|
+
' nil?',
|
321
|
+
'end'])
|
322
|
+
expect(cop.messages).to be_empty
|
323
|
+
end
|
324
|
+
|
325
|
+
it "registers an offense for a 2 space indentation of #{keyword} " \
|
326
|
+
'condition' do
|
327
|
+
inspect_source(cop,
|
328
|
+
["#{keyword} receiver.nil? &&",
|
329
|
+
' !args.empty? &&',
|
330
|
+
' BLACKLIST.include?(method_name)',
|
331
|
+
'end',
|
332
|
+
"#{keyword} receiver.",
|
333
|
+
' nil?',
|
334
|
+
'end'])
|
335
|
+
expect(cop.highlights).to eq(['!args.empty?',
|
336
|
+
'BLACKLIST.include?(method_name)',
|
337
|
+
'nil?'])
|
338
|
+
expect(cop.messages).to eq(['Use 4 (not 2) spaces for indenting a ' \
|
339
|
+
"condition in #{article} `#{keyword}` " \
|
340
|
+
'statement spanning multiple lines.'] * 3)
|
341
|
+
end
|
342
|
+
|
343
|
+
it "accepts indented operands in #{keyword} body" do
|
344
|
+
inspect_source(cop,
|
345
|
+
["#{keyword} a",
|
346
|
+
' something &&',
|
347
|
+
' something_else',
|
348
|
+
'end'])
|
349
|
+
expect(cop.highlights).to be_empty
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
%w(unless if).each do |keyword|
|
354
|
+
it "accepts special indentation of return #{keyword} condition" do
|
355
|
+
inspect_source(cop,
|
356
|
+
["return #{keyword} receiver.nil? &&",
|
357
|
+
' !args.empty? &&',
|
358
|
+
' BLACKLIST.include?(method_name)'])
|
359
|
+
expect(cop.messages).to be_empty
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
it 'registers an offense for wrong indentation of for expression' do
|
364
|
+
inspect_source(cop,
|
365
|
+
['for n in a +',
|
366
|
+
' b',
|
367
|
+
'end'])
|
368
|
+
expect(cop.messages).to eq(['Use 4 (not 2) spaces for indenting a ' \
|
369
|
+
'collection in a `for` statement spanning ' \
|
370
|
+
'multiple lines.'])
|
371
|
+
expect(cop.highlights).to eq(['b'])
|
372
|
+
end
|
373
|
+
|
374
|
+
it 'accepts special indentation of for expression' do
|
375
|
+
inspect_source(cop,
|
376
|
+
['for n in a +',
|
377
|
+
' b',
|
378
|
+
'end'])
|
379
|
+
expect(cop.messages).to be_empty
|
380
|
+
end
|
381
|
+
|
382
|
+
it 'accepts indentation of assignment' do
|
383
|
+
inspect_source(cop,
|
384
|
+
['formatted_int = int_part',
|
385
|
+
' .abs',
|
386
|
+
' .to_s',
|
387
|
+
' .reverse',
|
388
|
+
" .gsub(/...(?=.)/, '\&_')",
|
389
|
+
' .reverse'])
|
390
|
+
expect(cop.messages).to be_empty
|
391
|
+
end
|
392
|
+
|
393
|
+
it 'registers an offense for aligned operatiors in assignment' do
|
394
|
+
inspect_source(cop,
|
395
|
+
['formatted_int = int_part',
|
396
|
+
' .abs',
|
397
|
+
' .reverse'])
|
398
|
+
expect(cop.messages).to eq(['Use 2 (not 16) spaces for indenting an ' \
|
399
|
+
'expression in an assignment spanning ' \
|
400
|
+
'multiple lines.'] * 2)
|
401
|
+
end
|
402
|
+
|
403
|
+
it 'auto-corrects' do
|
404
|
+
new_source = autocorrect_source(cop, ['until a.',
|
405
|
+
' b',
|
406
|
+
' something',
|
407
|
+
'end'])
|
408
|
+
expect(new_source).to eq(['until a.',
|
409
|
+
' b',
|
410
|
+
' something',
|
411
|
+
'end'].join("\n"))
|
412
|
+
end
|
413
|
+
end
|
414
|
+
end
|
@@ -5,71 +5,80 @@ require 'spec_helper'
|
|
5
5
|
describe RuboCop::Cop::Style::NonNilCheck, :config do
|
6
6
|
subject(:cop) { described_class.new(config) }
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
context 'when not allowing semantic changes' do
|
9
|
+
let(:cop_config) do
|
10
|
+
{
|
11
|
+
'IncludeSemanticChanges' => false
|
12
|
+
}
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
it 'registers an offense for != nil' do
|
16
|
+
inspect_source(cop, 'x != nil')
|
17
|
+
expect(cop.offenses.size).to eq(1)
|
18
|
+
expect(cop.highlights).to eq(['!='])
|
19
|
+
expect(cop.messages)
|
20
|
+
.to eq(['Prefer `!expression.nil?` over `expression != nil`.'])
|
21
|
+
end
|
19
22
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
it 'does not register an offense for != 0' do
|
24
|
+
inspect_source(cop, 'x != 0')
|
25
|
+
expect(cop.offenses).to be_empty
|
26
|
+
end
|
24
27
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
it 'does not register an offense for !x.nil?' do
|
29
|
+
inspect_source(cop, '!x.nil?')
|
30
|
+
expect(cop.offenses).to be_empty
|
31
|
+
end
|
29
32
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
expect(cop.offenses).to be_empty
|
35
|
-
end
|
33
|
+
it 'does not register an offense for not x.nil?' do
|
34
|
+
inspect_source(cop, 'not x.nil?')
|
35
|
+
expect(cop.offenses).to be_empty
|
36
|
+
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
it 'does not register an offense if only expression in predicate' do
|
39
|
+
inspect_source(cop, ['def signed_in?',
|
40
|
+
' !current_user.nil?',
|
41
|
+
'end'])
|
42
|
+
expect(cop.offenses).to be_empty
|
43
|
+
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
end
|
45
|
+
it 'does not register an offense if only expression in class predicate' do
|
46
|
+
inspect_source(cop, ['def Test.signed_in?',
|
47
|
+
' current_user != nil',
|
48
|
+
'end'])
|
49
|
+
expect(cop.offenses).to be_empty
|
50
|
+
end
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
52
|
+
it 'does not register an offense if last expression in predicate' do
|
53
|
+
inspect_source(cop, ['def signed_in?',
|
54
|
+
' something',
|
55
|
+
' current_user != nil',
|
56
|
+
'end'])
|
57
|
+
expect(cop.offenses).to be_empty
|
58
|
+
end
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
60
|
+
it 'does not register an offense if last expression in class predicate' do
|
61
|
+
inspect_source(cop, ['def Test.signed_in?',
|
62
|
+
' something',
|
63
|
+
' current_user != nil',
|
64
|
+
'end'])
|
65
|
+
expect(cop.offenses).to be_empty
|
66
|
+
end
|
64
67
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
68
|
+
it 'autocorrects by changing `!= nil` to `!x.nil?`' do
|
69
|
+
corrected = autocorrect_source(cop, 'x != nil')
|
70
|
+
expect(corrected).to eq '!x.nil?'
|
71
|
+
end
|
69
72
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
+
it 'does not autocorrect by removing non-nil (!x.nil?) check' do
|
74
|
+
corrected = autocorrect_source(cop, '!x.nil?')
|
75
|
+
expect(corrected).to eq '!x.nil?'
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'does not blow up when autocorrecting implicit receiver' do
|
79
|
+
corrected = autocorrect_source(cop, '!nil?')
|
80
|
+
expect(corrected).to eq '!nil?'
|
81
|
+
end
|
73
82
|
end
|
74
83
|
|
75
84
|
context 'when allowing semantic changes' do
|
@@ -84,9 +93,21 @@ describe RuboCop::Cop::Style::NonNilCheck, :config do
|
|
84
93
|
it 'registers an offense for `!x.nil?`' do
|
85
94
|
inspect_source(cop, '!x.nil?')
|
86
95
|
expect(cop.offenses.size).to eq(1)
|
96
|
+
expect(cop.messages)
|
97
|
+
.to eq(['Explicit non-nil checks are usually redundant.'])
|
87
98
|
expect(cop.highlights).to eq(['!x.nil?'])
|
88
99
|
end
|
89
100
|
|
101
|
+
it 'does not register an offense for `x.nil?`' do
|
102
|
+
inspect_source(cop, 'x.nil?')
|
103
|
+
expect(cop.offenses).to be_empty
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'does not register an offense for `!x`' do
|
107
|
+
inspect_source(cop, '!x')
|
108
|
+
expect(cop.offenses).to be_empty
|
109
|
+
end
|
110
|
+
|
90
111
|
it 'registers an offense for `not x.nil?`' do
|
91
112
|
inspect_source(cop, 'not x.nil?')
|
92
113
|
expect(cop.offenses.size).to eq(1)
|
@@ -97,5 +118,15 @@ describe RuboCop::Cop::Style::NonNilCheck, :config do
|
|
97
118
|
corrected = autocorrect_source(cop, 'x != nil')
|
98
119
|
expect(corrected).to eq 'x'
|
99
120
|
end
|
121
|
+
|
122
|
+
it 'autocorrects by changing `!x.nil?` to `x`' do
|
123
|
+
corrected = autocorrect_source(cop, '!x.nil?')
|
124
|
+
expect(corrected).to eq 'x'
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'does not blow up when autocorrecting implicit receiver' do
|
128
|
+
corrected = autocorrect_source(cop, '!nil?')
|
129
|
+
expect(corrected).to eq 'self'
|
130
|
+
end
|
100
131
|
end
|
101
132
|
end
|