rubocop 0.14.0 → 0.14.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +15 -0
- data/README.md +1 -1
- data/config/default.yml +4 -0
- data/config/enabled.yml +16 -8
- data/lib/rubocop.rb +3 -0
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/config.rb +3 -160
- data/lib/rubocop/config_loader.rb +156 -0
- data/lib/rubocop/config_store.rb +6 -6
- data/lib/rubocop/cop/style/align_hash.rb +15 -11
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +46 -0
- data/lib/rubocop/cop/style/class_length.rb +27 -4
- data/lib/rubocop/cop/style/documentation.rb +23 -25
- data/lib/rubocop/cop/style/raise_args.rb +6 -1
- data/lib/rubocop/cop/style/space_after_not.rb +37 -0
- data/lib/rubocop/cop/util.rb +18 -1
- data/lib/rubocop/formatter/clang_style_formatter.rb +11 -2
- data/lib/rubocop/options.rb +3 -3
- data/lib/rubocop/version.rb +1 -1
- data/spec/project_spec.rb +2 -2
- data/spec/rubocop/cli_spec.rb +1 -1
- data/spec/rubocop/config_loader_spec.rb +314 -0
- data/spec/rubocop/config_spec.rb +1 -308
- data/spec/rubocop/config_store_spec.rb +9 -9
- data/spec/rubocop/cop/lint/shadowing_outer_local_variable_spec.rb +1 -1
- data/spec/rubocop/cop/lint/useless_assignment_spec.rb +3 -3
- data/spec/rubocop/cop/style/align_hash_spec.rb +17 -20
- data/spec/rubocop/cop/style/braces_around_hash_parameters_spec.rb +193 -0
- data/spec/rubocop/cop/style/class_length_spec.rb +64 -0
- data/spec/rubocop/cop/style/documentation_spec.rb +10 -0
- data/spec/rubocop/cop/style/indentation_width_spec.rb +0 -7
- data/spec/rubocop/cop/style/numeric_literals_spec.rb +1 -1
- data/spec/rubocop/cop/style/raise_args_spec.rb +5 -0
- data/spec/rubocop/cop/style/space_after_not_spec.rb +22 -0
- data/spec/rubocop/cop/team_spec.rb +1 -1
- data/spec/rubocop/cop/util_spec.rb +49 -0
- data/spec/rubocop/formatter/clang_style_formatter_spec.rb +42 -16
- data/spec/rubocop/options_spec.rb +3 -2
- data/spec/spec_helper.rb +1 -1
- metadata +13 -2
data/spec/rubocop/config_spec.rb
CHANGED
@@ -2,8 +2,6 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
DEFAULT_CONFIG = Rubocop::Config.load_file('config/default.yml')
|
6
|
-
|
7
5
|
describe Rubocop::Config do
|
8
6
|
include FileHelper
|
9
7
|
|
@@ -11,268 +9,6 @@ describe Rubocop::Config do
|
|
11
9
|
let(:hash) { {} }
|
12
10
|
let(:loaded_path) { 'example/.rubocop.yml' }
|
13
11
|
|
14
|
-
describe '.configuration_file_for', :isolated_environment do
|
15
|
-
subject(:configuration_file_for) do
|
16
|
-
described_class.configuration_file_for(dir_path)
|
17
|
-
end
|
18
|
-
|
19
|
-
context 'when no config file exists in ancestor directories' do
|
20
|
-
let(:dir_path) { 'dir' }
|
21
|
-
before { create_file('dir/example.rb', '') }
|
22
|
-
|
23
|
-
context 'but a config file exists in home directory' do
|
24
|
-
before { create_file('~/.rubocop.yml', '') }
|
25
|
-
|
26
|
-
it 'returns the path to the file in home directory' do
|
27
|
-
expect(configuration_file_for).to end_with('home/.rubocop.yml')
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
context 'and no config file exists in home directory' do
|
32
|
-
it 'falls back to the provided default file' do
|
33
|
-
expect(configuration_file_for).to end_with('config/default.yml')
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
context 'when a config file exists in the parent directory' do
|
39
|
-
let(:dir_path) { 'dir' }
|
40
|
-
|
41
|
-
before do
|
42
|
-
create_file('dir/example.rb', '')
|
43
|
-
create_file('.rubocop.yml', '')
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'returns the path to that configuration file' do
|
47
|
-
expect(configuration_file_for).to end_with('work/.rubocop.yml')
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
context 'when multiple config files exist in ancestor directories' do
|
52
|
-
let(:dir_path) { 'dir' }
|
53
|
-
|
54
|
-
before do
|
55
|
-
create_file('dir/example.rb', '')
|
56
|
-
create_file('dir/.rubocop.yml', '')
|
57
|
-
create_file('.rubocop.yml', '')
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'prefers closer config file' do
|
61
|
-
expect(configuration_file_for).to end_with('dir/.rubocop.yml')
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
describe '.configuration_from_file', :isolated_environment do
|
67
|
-
subject(:configuration_from_file) do
|
68
|
-
described_class.configuration_from_file(file_path)
|
69
|
-
end
|
70
|
-
|
71
|
-
context 'with any config file' do
|
72
|
-
let(:file_path) { '.rubocop.yml' }
|
73
|
-
|
74
|
-
before do
|
75
|
-
create_file(file_path, ['Encoding:',
|
76
|
-
' Enabled: false'])
|
77
|
-
end
|
78
|
-
it 'returns a configuration inheriting from default.yml' do
|
79
|
-
config = DEFAULT_CONFIG['Encoding'].dup
|
80
|
-
config['Enabled'] = false
|
81
|
-
expect(configuration_from_file)
|
82
|
-
.to eql(DEFAULT_CONFIG.merge('Encoding' => config))
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
context 'when multiple config files exist in ancestor directories' do
|
87
|
-
let(:file_path) { 'dir/.rubocop.yml' }
|
88
|
-
|
89
|
-
before do
|
90
|
-
create_file('.rubocop.yml',
|
91
|
-
['AllCops:',
|
92
|
-
' Excludes:',
|
93
|
-
' - vendor/**',
|
94
|
-
])
|
95
|
-
|
96
|
-
create_file(file_path,
|
97
|
-
['AllCops:',
|
98
|
-
' Excludes: []',
|
99
|
-
])
|
100
|
-
end
|
101
|
-
|
102
|
-
it 'gets AllCops/Excludes from the highest directory level' do
|
103
|
-
excludes = configuration_from_file['AllCops']['Excludes']
|
104
|
-
expect(excludes).to eq([File.expand_path('vendor/**')])
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
context 'when a file inherits from a parent file' do
|
109
|
-
let(:file_path) { 'dir/.rubocop.yml' }
|
110
|
-
|
111
|
-
before do
|
112
|
-
create_file('.rubocop.yml',
|
113
|
-
['AllCops:',
|
114
|
-
' Excludes:',
|
115
|
-
' - vendor/**',
|
116
|
-
' - !ruby/regexp /[A-Z]/',
|
117
|
-
])
|
118
|
-
|
119
|
-
create_file(file_path, ['inherit_from: ../.rubocop.yml'])
|
120
|
-
end
|
121
|
-
|
122
|
-
it 'gets an absolute AllCops/Excludes' do
|
123
|
-
excludes = configuration_from_file['AllCops']['Excludes']
|
124
|
-
expect(excludes).to eq([File.expand_path('vendor/**'), /[A-Z]/])
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
context 'when a file inherits from a sibling file' do
|
129
|
-
let(:file_path) { 'dir/.rubocop.yml' }
|
130
|
-
|
131
|
-
before do
|
132
|
-
create_file('src/.rubocop.yml',
|
133
|
-
['AllCops:',
|
134
|
-
' Excludes:',
|
135
|
-
' - vendor/**',
|
136
|
-
])
|
137
|
-
|
138
|
-
create_file(file_path, ['inherit_from: ../src/.rubocop.yml'])
|
139
|
-
end
|
140
|
-
|
141
|
-
it 'gets an absolute AllCops/Exclude' do
|
142
|
-
excludes = configuration_from_file['AllCops']['Excludes']
|
143
|
-
expect(excludes).to eq([File.expand_path('src/vendor/**')])
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
context 'when a file inherits from a parent and grandparent file' do
|
148
|
-
let(:file_path) { 'dir/subdir/.rubocop.yml' }
|
149
|
-
|
150
|
-
before do
|
151
|
-
create_file('dir/subdir/example.rb', '')
|
152
|
-
|
153
|
-
create_file('.rubocop.yml',
|
154
|
-
['LineLength:',
|
155
|
-
' Enabled: false',
|
156
|
-
' Max: 77'])
|
157
|
-
|
158
|
-
create_file('dir/.rubocop.yml',
|
159
|
-
['inherit_from: ../.rubocop.yml',
|
160
|
-
'',
|
161
|
-
'MethodLength:',
|
162
|
-
' Enabled: true',
|
163
|
-
' CountComments: false',
|
164
|
-
' Max: 10'
|
165
|
-
])
|
166
|
-
|
167
|
-
create_file(file_path,
|
168
|
-
['inherit_from: ../.rubocop.yml',
|
169
|
-
'',
|
170
|
-
'LineLength:',
|
171
|
-
' Enabled: true',
|
172
|
-
'',
|
173
|
-
'MethodLength:',
|
174
|
-
' Max: 5'
|
175
|
-
])
|
176
|
-
end
|
177
|
-
|
178
|
-
it 'returns the ancestor configuration plus local overrides' do
|
179
|
-
config = DEFAULT_CONFIG
|
180
|
-
.merge('LineLength' => {
|
181
|
-
'Description' =>
|
182
|
-
DEFAULT_CONFIG['LineLength']['Description'],
|
183
|
-
'Enabled' => true,
|
184
|
-
'Max' => 77
|
185
|
-
},
|
186
|
-
'MethodLength' => {
|
187
|
-
'Description' =>
|
188
|
-
DEFAULT_CONFIG['MethodLength']['Description'],
|
189
|
-
'Enabled' => true,
|
190
|
-
'CountComments' => false,
|
191
|
-
'Max' => 5
|
192
|
-
})
|
193
|
-
expect(configuration_from_file).to eq(config)
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
context 'when a file inherits from two configurations' do
|
198
|
-
let(:file_path) { '.rubocop.yml' }
|
199
|
-
|
200
|
-
before do
|
201
|
-
create_file('example.rb', '')
|
202
|
-
|
203
|
-
create_file('normal.yml',
|
204
|
-
['MethodLength:',
|
205
|
-
' Enabled: false',
|
206
|
-
' CountComments: true',
|
207
|
-
' Max: 79'])
|
208
|
-
|
209
|
-
create_file('special.yml',
|
210
|
-
['MethodLength:',
|
211
|
-
' Enabled: false',
|
212
|
-
' Max: 200'])
|
213
|
-
|
214
|
-
create_file(file_path,
|
215
|
-
['inherit_from:',
|
216
|
-
' - normal.yml',
|
217
|
-
' - special.yml',
|
218
|
-
'',
|
219
|
-
'MethodLength:',
|
220
|
-
' Enabled: true'
|
221
|
-
])
|
222
|
-
end
|
223
|
-
|
224
|
-
it 'returns values from the last one when possible' do
|
225
|
-
expected = { 'Enabled' => true, # overridden in .rubocop.yml
|
226
|
-
'CountComments' => true, # only defined in normal.yml
|
227
|
-
'Max' => 200 } # special.yml takes precedence
|
228
|
-
expect(configuration_from_file['MethodLength'].to_set)
|
229
|
-
.to be_superset(expected.to_set)
|
230
|
-
end
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
describe '.load_file', :isolated_environment do
|
235
|
-
subject(:load_file) do
|
236
|
-
described_class.load_file(configuration_path)
|
237
|
-
end
|
238
|
-
|
239
|
-
let(:configuration_path) { '.rubocop.yml' }
|
240
|
-
|
241
|
-
it 'returns a configuration loaded from the passed path' do
|
242
|
-
create_file(configuration_path, [
|
243
|
-
'Encoding:',
|
244
|
-
' Enabled: true',
|
245
|
-
])
|
246
|
-
configuration = load_file
|
247
|
-
expect(configuration['Encoding']).to eq({
|
248
|
-
'Enabled' => true
|
249
|
-
})
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
describe '.merge' do
|
254
|
-
subject(:merge) { described_class.merge(base, derived) }
|
255
|
-
|
256
|
-
let(:base) do
|
257
|
-
{
|
258
|
-
'AllCops' => {
|
259
|
-
'Includes' => ['**/*.gemspec', '**/Rakefile'],
|
260
|
-
'Excludes' => []
|
261
|
-
}
|
262
|
-
}
|
263
|
-
end
|
264
|
-
let(:derived) do
|
265
|
-
{ 'AllCops' => { 'Excludes' => ['example.rb', 'exclude_*'] } }
|
266
|
-
end
|
267
|
-
|
268
|
-
it 'returns a recursive merge of its two arguments' do
|
269
|
-
expect(merge).to eq('AllCops' => {
|
270
|
-
'Includes' => ['**/*.gemspec', '**/Rakefile'],
|
271
|
-
'Excludes' => ['example.rb', 'exclude_*']
|
272
|
-
})
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
12
|
describe '#validate', :isolated_environment do
|
277
13
|
# TODO: Because Config.load_file now outputs the validation warning,
|
278
14
|
# it is inserting text into the rspec test output here.
|
@@ -281,7 +17,7 @@ describe Rubocop::Config do
|
|
281
17
|
after(:each) { $stdout = STDOUT }
|
282
18
|
|
283
19
|
subject(:configuration) do
|
284
|
-
|
20
|
+
Rubocop::ConfigLoader.load_file(configuration_path)
|
285
21
|
end
|
286
22
|
|
287
23
|
let(:configuration_path) { '.rubocop.yml' }
|
@@ -424,47 +160,4 @@ describe Rubocop::Config do
|
|
424
160
|
end
|
425
161
|
end
|
426
162
|
end
|
427
|
-
|
428
|
-
describe 'configuration for SymbolArray', :isolated_environment do
|
429
|
-
let(:config) do
|
430
|
-
config_path = described_class.configuration_file_for('.')
|
431
|
-
described_class.configuration_from_file(config_path)
|
432
|
-
end
|
433
|
-
|
434
|
-
context 'when no config file exists for the target file' do
|
435
|
-
it 'is disabled' do
|
436
|
-
expect(config.cop_enabled?('SymbolArray')).to be_false
|
437
|
-
end
|
438
|
-
end
|
439
|
-
|
440
|
-
context 'when a config file which does not mention SymbolArray exists' do
|
441
|
-
it 'is disabled' do
|
442
|
-
create_file('.rubocop.yml', [
|
443
|
-
'LineLength:',
|
444
|
-
' Max: 79'
|
445
|
-
])
|
446
|
-
expect(config.cop_enabled?('SymbolArray')).to be_false
|
447
|
-
end
|
448
|
-
end
|
449
|
-
|
450
|
-
context 'when a config file which explicitly enables SymbolArray exists' do
|
451
|
-
it 'is enabled' do
|
452
|
-
create_file('.rubocop.yml', [
|
453
|
-
'SymbolArray:',
|
454
|
-
' Enabled: true'
|
455
|
-
])
|
456
|
-
expect(config.cop_enabled?('SymbolArray')).to be_true
|
457
|
-
end
|
458
|
-
end
|
459
|
-
end
|
460
|
-
|
461
|
-
describe 'configuration for SymbolName' do
|
462
|
-
describe 'AllowCamelCase' do
|
463
|
-
it 'is enabled by default' do
|
464
|
-
default_config = described_class.default_configuration
|
465
|
-
symbol_name_config = default_config.for_cop('SymbolName')
|
466
|
-
expect(symbol_name_config['AllowCamelCase']).to be_true
|
467
|
-
end
|
468
|
-
end
|
469
|
-
end
|
470
163
|
end
|
@@ -6,7 +6,7 @@ describe Rubocop::ConfigStore do
|
|
6
6
|
subject(:config_store) { described_class.new }
|
7
7
|
|
8
8
|
before do
|
9
|
-
Rubocop::
|
9
|
+
Rubocop::ConfigLoader.stub(:configuration_file_for) do |arg|
|
10
10
|
# File tree:
|
11
11
|
# file1
|
12
12
|
# dir/.rubocop.yml
|
@@ -14,9 +14,9 @@ describe Rubocop::ConfigStore do
|
|
14
14
|
# dir/subdir/file3
|
15
15
|
(arg =~ /dir/ ? 'dir' : '.') + '/.rubocop.yml'
|
16
16
|
end
|
17
|
-
Rubocop::
|
18
|
-
Rubocop::
|
19
|
-
Rubocop::
|
17
|
+
Rubocop::ConfigLoader.stub(:configuration_from_file) { |arg| arg }
|
18
|
+
Rubocop::ConfigLoader.stub(:load_file) { |arg| "#{arg} loaded" }
|
19
|
+
Rubocop::ConfigLoader.stub(:merge_with_default) do |config, file|
|
20
20
|
"merged #{config}"
|
21
21
|
end
|
22
22
|
end
|
@@ -29,12 +29,12 @@ describe Rubocop::ConfigStore do
|
|
29
29
|
|
30
30
|
context 'when no config specified in command line' do
|
31
31
|
it 'gets config path and config from cache if available' do
|
32
|
-
Rubocop::
|
32
|
+
Rubocop::ConfigLoader.should_receive(:configuration_file_for).once
|
33
33
|
.with('dir')
|
34
|
-
Rubocop::
|
34
|
+
Rubocop::ConfigLoader.should_receive(:configuration_file_for).once
|
35
35
|
.with('dir/subdir')
|
36
36
|
# The stub returns the same config path for dir and dir/subdir.
|
37
|
-
Rubocop::
|
37
|
+
Rubocop::ConfigLoader.should_receive(:configuration_from_file).once
|
38
38
|
.with('dir/.rubocop.yml')
|
39
39
|
|
40
40
|
config_store.for('dir/file2')
|
@@ -43,8 +43,8 @@ describe Rubocop::ConfigStore do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
it 'searches for config path if not available in cache' do
|
46
|
-
Rubocop::
|
47
|
-
Rubocop::
|
46
|
+
Rubocop::ConfigLoader.should_receive(:configuration_file_for).once
|
47
|
+
Rubocop::ConfigLoader.should_receive(:configuration_from_file).once
|
48
48
|
config_store.for('file1')
|
49
49
|
end
|
50
50
|
end
|
@@ -1439,7 +1439,7 @@ describe Rubocop::Cop::Lint::UselessAssignment do
|
|
1439
1439
|
]
|
1440
1440
|
end
|
1441
1441
|
|
1442
|
-
include_examples 'accepts'
|
1442
|
+
include_examples 'accepts' unless RUBY_VERSION < '2.0'
|
1443
1443
|
include_examples 'mimics MRI 2.0'
|
1444
1444
|
end
|
1445
1445
|
|
@@ -1452,7 +1452,7 @@ describe Rubocop::Cop::Lint::UselessAssignment do
|
|
1452
1452
|
]
|
1453
1453
|
end
|
1454
1454
|
|
1455
|
-
include_examples 'accepts'
|
1455
|
+
include_examples 'accepts' unless RUBY_VERSION < '2.0'
|
1456
1456
|
include_examples 'mimics MRI 2.0'
|
1457
1457
|
end
|
1458
1458
|
|
@@ -1464,7 +1464,7 @@ describe Rubocop::Cop::Lint::UselessAssignment do
|
|
1464
1464
|
]
|
1465
1465
|
end
|
1466
1466
|
|
1467
|
-
include_examples 'accepts'
|
1467
|
+
include_examples 'accepts' unless RUBY_VERSION < '2.0'
|
1468
1468
|
include_examples 'mimics MRI 2.0'
|
1469
1469
|
end
|
1470
1470
|
|
@@ -3,6 +3,19 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe Rubocop::Cop::Style::AlignHash, :config do
|
6
|
+
shared_examples 'not on separate lines' do
|
7
|
+
it 'accepts single line hash' do
|
8
|
+
inspect_source(cop, 'func(a: 0, bb: 1)')
|
9
|
+
expect(cop.offences).to be_empty
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'accepts several pairs per line' do
|
13
|
+
inspect_source(cop, ['func(a: 1, bb: 2,',
|
14
|
+
' ccc: 3, dddd: 4)'])
|
15
|
+
expect(cop.offences).to be_empty
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
6
19
|
subject(:cop) { described_class.new(config) }
|
7
20
|
let(:cop_config) do
|
8
21
|
{
|
@@ -88,16 +101,7 @@ describe Rubocop::Cop::Style::AlignHash, :config do
|
|
88
101
|
end
|
89
102
|
end
|
90
103
|
|
91
|
-
|
92
|
-
inspect_source(cop, 'hash = { a: 0, b: 1 }')
|
93
|
-
expect(cop.offences).to be_empty
|
94
|
-
end
|
95
|
-
|
96
|
-
it 'accepts several pairs per line' do
|
97
|
-
inspect_source(cop, ['hash = { a: 0, b: 1,',
|
98
|
-
' c: 2, d: 3 }'])
|
99
|
-
expect(cop.offences).to be_empty
|
100
|
-
end
|
104
|
+
include_examples 'not on separate lines'
|
101
105
|
|
102
106
|
context 'with table alignment configuration' do
|
103
107
|
let(:cop_config) do
|
@@ -107,16 +111,7 @@ describe Rubocop::Cop::Style::AlignHash, :config do
|
|
107
111
|
}
|
108
112
|
end
|
109
113
|
|
110
|
-
|
111
|
-
inspect_source(cop, 'func(a: 0, bb: 1)')
|
112
|
-
expect(cop.offences).to be_empty
|
113
|
-
end
|
114
|
-
|
115
|
-
it 'accepts several pairs per line' do
|
116
|
-
inspect_source(cop, ['func(a: 1, bb: 2',
|
117
|
-
' ccc: 3, dddd: 4)'])
|
118
|
-
expect(cop.offences).to be_empty
|
119
|
-
end
|
114
|
+
include_examples 'not on separate lines'
|
120
115
|
|
121
116
|
it 'accepts aligned hash keys' do
|
122
117
|
inspect_source(cop, ['hash1 = {',
|
@@ -235,6 +230,8 @@ describe Rubocop::Cop::Style::AlignHash, :config do
|
|
235
230
|
expect(cop.offences).to have(1).item
|
236
231
|
end
|
237
232
|
|
233
|
+
include_examples 'not on separate lines'
|
234
|
+
|
238
235
|
it 'auto-corrects alignment' do
|
239
236
|
new_source = autocorrect_source(cop, ['hash1 = { a: 0,',
|
240
237
|
' bb: 1,',
|