rubocop 0.24.1 → 0.25.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_todo.yml +12 -8
- data/.travis.yml +1 -1
- data/CHANGELOG.md +42 -0
- data/Gemfile +2 -0
- data/README.md +27 -6
- data/bin/rubocop +10 -15
- data/config/default.yml +72 -25
- data/config/enabled.yml +57 -25
- data/lib/rubocop.rb +15 -8
- data/lib/rubocop/config_loader.rb +11 -7
- data/lib/rubocop/cop/cop.rb +16 -16
- data/lib/rubocop/cop/ignored_node.rb +11 -4
- data/lib/rubocop/cop/lint/block_alignment.rb +29 -4
- data/lib/rubocop/cop/lint/debugger.rb +8 -1
- data/lib/rubocop/cop/lint/def_end_alignment.rb +5 -1
- data/lib/rubocop/cop/lint/end_alignment.rb +5 -5
- data/lib/rubocop/cop/lint/end_in_method.rb +2 -2
- data/lib/rubocop/cop/lint/useless_setter_call.rb +2 -2
- data/lib/rubocop/cop/{style → metrics}/block_nesting.rb +1 -1
- data/lib/rubocop/cop/{style → metrics}/class_length.rb +4 -4
- data/lib/rubocop/cop/{style → metrics}/cyclomatic_complexity.rb +5 -16
- data/lib/rubocop/cop/{style → metrics}/line_length.rb +1 -1
- data/lib/rubocop/cop/{style → metrics}/method_length.rb +8 -4
- data/lib/rubocop/cop/{style → metrics}/parameter_lists.rb +1 -1
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +61 -0
- data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +10 -2
- data/lib/rubocop/cop/mixin/code_length.rb +2 -3
- data/lib/rubocop/cop/mixin/configurable_naming.rb +6 -20
- data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/if_node.rb +1 -1
- data/lib/rubocop/cop/mixin/method_complexity.rb +32 -0
- data/lib/rubocop/cop/mixin/negative_conditional.rb +1 -1
- data/lib/rubocop/cop/mixin/{check_methods.rb → on_method.rb} +3 -3
- data/lib/rubocop/cop/mixin/on_normal_if_unless.rb +24 -0
- data/lib/rubocop/cop/mixin/percent_literal.rb +2 -1
- data/lib/rubocop/cop/mixin/space_inside.rb +33 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +14 -14
- data/lib/rubocop/cop/mixin/string_help.rb +4 -0
- data/lib/rubocop/cop/mixin/surrounding_space.rb +1 -0
- data/lib/rubocop/cop/rails/delegate.rb +2 -2
- data/lib/rubocop/cop/rails/output.rb +4 -2
- data/lib/rubocop/cop/style/accessor_method_name.rb +2 -2
- data/lib/rubocop/cop/style/align_hash.rb +9 -1
- data/lib/rubocop/cop/style/and_or.rb +37 -3
- data/lib/rubocop/cop/style/bare_percent_literals.rb +46 -0
- data/lib/rubocop/cop/style/block_end_newline.rb +56 -0
- data/lib/rubocop/cop/style/character_literal.rb +1 -1
- data/lib/rubocop/cop/style/def_with_parentheses.rb +2 -2
- data/lib/rubocop/cop/style/empty_lines_around_access_modifier.rb +31 -3
- data/lib/rubocop/cop/style/empty_lines_around_body.rb +6 -2
- data/lib/rubocop/cop/style/end_of_line.rb +3 -14
- data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -6
- data/lib/rubocop/cop/style/if_with_semicolon.rb +6 -7
- data/lib/rubocop/cop/style/indentation_width.rb +3 -8
- data/lib/rubocop/cop/style/method_def_parentheses.rb +2 -2
- data/lib/rubocop/cop/style/method_name.rb +4 -18
- data/lib/rubocop/cop/style/multiline_block_layout.rb +73 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +4 -4
- data/lib/rubocop/cop/style/negated_if.rb +1 -1
- data/lib/rubocop/cop/style/negated_while.rb +2 -2
- data/lib/rubocop/cop/style/next.rb +12 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +6 -6
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +22 -8
- data/lib/rubocop/cop/style/percent_q_literals.rb +53 -0
- 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 +2 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +7 -3
- data/lib/rubocop/cop/style/single_line_methods.rb +2 -2
- data/lib/rubocop/cop/style/space_after_method_name.rb +2 -2
- data/lib/rubocop/cop/style/space_inside_block_braces.rb +14 -10
- data/lib/rubocop/cop/style/space_inside_brackets.rb +5 -1
- data/lib/rubocop/cop/style/string_literals.rb +5 -8
- data/lib/rubocop/cop/style/trailing_comma.rb +15 -3
- data/lib/rubocop/cop/style/trivial_accessors.rb +2 -2
- data/lib/rubocop/cop/style/unneeded_capital_w.rb +2 -4
- data/lib/rubocop/cop/style/unneeded_percent_q.rb +13 -0
- data/lib/rubocop/cop/style/variable_interpolation.rb +14 -2
- data/lib/rubocop/cop/style/variable_name.rb +17 -17
- data/lib/rubocop/cop/style/while_until_modifier.rb +2 -5
- data/lib/rubocop/cop/util.rb +5 -0
- data/lib/rubocop/cop/variable_force.rb +7 -6
- data/lib/rubocop/formatter/base_formatter.rb +2 -2
- data/lib/rubocop/processed_source.rb +5 -22
- data/lib/rubocop/version.rb +1 -1
- data/relnotes/v0.25.0.md +91 -0
- data/rubocop.gemspec +2 -3
- data/spec/project_spec.rb +1 -1
- data/spec/rubocop/cli_spec.rb +70 -44
- data/spec/rubocop/comment_config_spec.rb +6 -6
- data/spec/rubocop/config_loader_spec.rb +19 -13
- data/spec/rubocop/config_spec.rb +3 -3
- data/spec/rubocop/cop/commissioner_spec.rb +1 -1
- data/spec/rubocop/cop/cop_spec.rb +3 -3
- data/spec/rubocop/cop/lint/block_alignment_spec.rb +113 -6
- data/spec/rubocop/cop/lint/debugger_spec.rb +10 -6
- data/spec/rubocop/cop/lint/useless_assignment_spec.rb +12 -0
- data/spec/rubocop/cop/{style → metrics}/block_nesting_spec.rb +1 -1
- data/spec/rubocop/cop/{style → metrics}/class_length_spec.rb +1 -1
- data/spec/rubocop/cop/{style → metrics}/cyclomatic_complexity_spec.rb +1 -1
- data/spec/rubocop/cop/{style → metrics}/if_unless_modifier_spec.rb +2 -2
- data/spec/rubocop/cop/{style → metrics}/line_length_spec.rb +7 -7
- data/spec/rubocop/cop/{style → metrics}/method_length_spec.rb +1 -1
- data/spec/rubocop/cop/{style → metrics}/parameter_lists_spec.rb +1 -1
- data/spec/rubocop/cop/metrics/perceived_complexity_spec.rb +222 -0
- data/spec/rubocop/cop/{style → metrics}/while_until_modifier_spec.rb +2 -2
- data/spec/rubocop/cop/rails/output_spec.rb +8 -2
- data/spec/rubocop/cop/style/align_hash_spec.rb +7 -0
- data/spec/rubocop/cop/style/and_or_spec.rb +245 -43
- data/spec/rubocop/cop/style/bare_percent_literals_spec.rb +132 -0
- data/spec/rubocop/cop/style/block_end_newline_spec.rb +61 -0
- data/spec/rubocop/cop/style/empty_lines_around_access_modifier_spec.rb +34 -0
- data/spec/rubocop/cop/style/end_of_line_spec.rb +8 -0
- data/spec/rubocop/cop/style/guard_clause_spec.rb +1 -1
- data/spec/rubocop/cop/style/multiline_block_layout_spec.rb +138 -0
- data/spec/rubocop/cop/style/next_spec.rb +32 -3
- data/spec/rubocop/cop/style/percent_literal_delimiters_spec.rb +34 -0
- data/spec/rubocop/cop/style/percent_q_literals_spec.rb +122 -0
- data/spec/rubocop/cop/style/space_inside_block_braces_spec.rb +20 -0
- data/spec/rubocop/cop/style/space_inside_brackets_spec.rb +26 -2
- data/spec/rubocop/cop/style/trailing_comma_spec.rb +112 -0
- data/spec/rubocop/cop/style/unneeded_percent_q_spec.rb +86 -31
- data/spec/rubocop/cop/style/variable_interpolation_spec.rb +21 -1
- data/spec/rubocop/cop/team_spec.rb +14 -9
- data/spec/spec_helper.rb +1 -0
- metadata +47 -50
- data/lib/rubocop/cop/mixin/if_then_else.rb +0 -23
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe RuboCop::Cop::Style::BlockEndNewline do
|
6
|
+
subject(:cop) { described_class.new }
|
7
|
+
|
8
|
+
it 'does not register an offense for a one-liner' do
|
9
|
+
inspect_source(cop, ['test do foo end'])
|
10
|
+
expect(cop.messages).to be_empty
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'does not register an offense for multiline blocks with newlines before '\
|
14
|
+
'the end' do
|
15
|
+
inspect_source(cop,
|
16
|
+
['test do',
|
17
|
+
' foo',
|
18
|
+
'end'])
|
19
|
+
expect(cop.messages).to be_empty
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'registers an offense when multiline block end is not on its own line' do
|
23
|
+
inspect_source(cop,
|
24
|
+
['test do',
|
25
|
+
' foo end'
|
26
|
+
])
|
27
|
+
expect(cop.messages)
|
28
|
+
.to eq(['Expression at 2, 7 should be on its own line.'])
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'registers an offense when multiline block } is not on its own line' do
|
32
|
+
inspect_source(cop,
|
33
|
+
['test {',
|
34
|
+
' foo }'
|
35
|
+
])
|
36
|
+
expect(cop.messages)
|
37
|
+
.to eq(['Expression at 2, 7 should be on its own line.'])
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'autocorrects a do/end block where the end is not on its own line' do
|
41
|
+
src = ['test do',
|
42
|
+
' foo end']
|
43
|
+
|
44
|
+
new_source = autocorrect_source(cop, src)
|
45
|
+
|
46
|
+
expect(new_source).to eq(['test do',
|
47
|
+
' foo ',
|
48
|
+
'end'].join("\n"))
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'autocorrects a {} block where the } is not on its own line' do
|
52
|
+
src = ['test {',
|
53
|
+
' foo }']
|
54
|
+
|
55
|
+
new_source = autocorrect_source(cop, src)
|
56
|
+
|
57
|
+
expect(new_source).to eq(['test {',
|
58
|
+
' foo ',
|
59
|
+
'}'].join("\n"))
|
60
|
+
end
|
61
|
+
end
|
@@ -32,6 +32,40 @@ describe RuboCop::Cop::Style::EmptyLinesAroundAccessModifier do
|
|
32
32
|
.to eq(["Keep a blank line before and after `#{access_modifier}`."])
|
33
33
|
end
|
34
34
|
|
35
|
+
it "autocorrects blank line before #{access_modifier}" do
|
36
|
+
corrected = autocorrect_source(cop,
|
37
|
+
['class Test',
|
38
|
+
' something',
|
39
|
+
" #{access_modifier}",
|
40
|
+
'',
|
41
|
+
' def test; end',
|
42
|
+
'end'])
|
43
|
+
expect(corrected).to eq(['class Test',
|
44
|
+
' something',
|
45
|
+
'',
|
46
|
+
" #{access_modifier}",
|
47
|
+
'',
|
48
|
+
' def test; end',
|
49
|
+
'end'].join("\n"))
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'autocorrects blank line after #{access_modifier}' do
|
53
|
+
corrected = autocorrect_source(cop,
|
54
|
+
['class Test',
|
55
|
+
' something',
|
56
|
+
'',
|
57
|
+
" #{access_modifier}",
|
58
|
+
' def test; end',
|
59
|
+
'end'])
|
60
|
+
expect(corrected).to eq(['class Test',
|
61
|
+
' something',
|
62
|
+
'',
|
63
|
+
" #{access_modifier}",
|
64
|
+
'',
|
65
|
+
' def test; end',
|
66
|
+
'end'].join("\n"))
|
67
|
+
end
|
68
|
+
|
35
69
|
it 'accepts missing blank line when at the beginning of class/module' do
|
36
70
|
inspect_source(cop,
|
37
71
|
['class Test',
|
@@ -54,4 +54,12 @@ describe RuboCop::Cop::Style::EndOfLine do
|
|
54
54
|
|
55
55
|
include_examples 'iso-8859-15'
|
56
56
|
end
|
57
|
+
|
58
|
+
context 'when source is a string' do
|
59
|
+
it 'registers an offence' do
|
60
|
+
inspect_source(cop, ["x=0\r"])
|
61
|
+
|
62
|
+
expect(cop.messages).to eq(['Carriage return character detected.'])
|
63
|
+
end
|
64
|
+
end
|
57
65
|
end
|
@@ -102,7 +102,7 @@ describe RuboCop::Cop::Style::GuardClause, :config do
|
|
102
102
|
|
103
103
|
context 'MinBodyLength: 1' do
|
104
104
|
let(:cop_config) do
|
105
|
-
{ '
|
105
|
+
{ 'MinBodyLength' => 1 }
|
106
106
|
end
|
107
107
|
|
108
108
|
it 'reports an offense for if whose body has 1 line' do
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe RuboCop::Cop::Style::MultilineBlockLayout do
|
6
|
+
subject(:cop) { described_class.new }
|
7
|
+
|
8
|
+
it 'registers an offense for missing newline in do/end block w/o params' do
|
9
|
+
inspect_source(cop,
|
10
|
+
['test do foo',
|
11
|
+
'end'
|
12
|
+
])
|
13
|
+
expect(cop.messages)
|
14
|
+
.to eq(['Block body expression is on the same line as the block start.'])
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'registers an offense for missing newline in {} block w/o params' do
|
18
|
+
inspect_source(cop,
|
19
|
+
['test { foo',
|
20
|
+
'}'
|
21
|
+
])
|
22
|
+
expect(cop.messages)
|
23
|
+
.to eq(['Block body expression is on the same line as the block start.'])
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'registers an offense for missing newline in do/end block with params' do
|
27
|
+
inspect_source(cop,
|
28
|
+
['test do |x| foo',
|
29
|
+
'end'
|
30
|
+
])
|
31
|
+
expect(cop.messages)
|
32
|
+
.to eq(['Block body expression is on the same line as the block start.'])
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'registers an offense for missing newline in {} block with params' do
|
36
|
+
inspect_source(cop,
|
37
|
+
['test { |x| foo',
|
38
|
+
'}'
|
39
|
+
])
|
40
|
+
expect(cop.messages)
|
41
|
+
.to eq(['Block body expression is on the same line as the block start.'])
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'does not register an offense for one-line do/end blocks' do
|
45
|
+
inspect_source(cop, 'test do foo end')
|
46
|
+
expect(cop.offenses).to be_empty
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'does not register an offense for one-line {} blocks' do
|
50
|
+
inspect_source(cop, 'test { foo }')
|
51
|
+
expect(cop.offenses).to be_empty
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'does not register offenses when there is a newline for do/end block' do
|
55
|
+
inspect_source(cop,
|
56
|
+
['test do',
|
57
|
+
' foo',
|
58
|
+
'end'
|
59
|
+
])
|
60
|
+
expect(cop.offenses).to be_empty
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'does not error out when the block is empty' do
|
64
|
+
inspect_source(cop,
|
65
|
+
['test do |x|',
|
66
|
+
'end'
|
67
|
+
])
|
68
|
+
expect(cop.offenses).to be_empty
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'does not register offenses when there is a newline for {} block' do
|
72
|
+
inspect_source(cop,
|
73
|
+
['test {',
|
74
|
+
' foo',
|
75
|
+
'}'
|
76
|
+
])
|
77
|
+
expect(cop.offenses).to be_empty
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'registers offenses for lambdas as expected' do
|
81
|
+
inspect_source(cop,
|
82
|
+
['-> (x) do foo',
|
83
|
+
' bar',
|
84
|
+
'end'
|
85
|
+
])
|
86
|
+
expect(cop.messages)
|
87
|
+
.to eq(['Block body expression is on the same line as the block start.'])
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'auto-corrects a do/end block with params that is missing newlines' do
|
91
|
+
src = ['test do |foo| bar',
|
92
|
+
'end']
|
93
|
+
|
94
|
+
new_source = autocorrect_source(cop, src)
|
95
|
+
|
96
|
+
expect(new_source).to eq(['test do |foo| ',
|
97
|
+
' bar',
|
98
|
+
'end'].join("\n"))
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'auto-corrects a do/end block with a mult-line body' do
|
102
|
+
src = ['test do |foo| bar',
|
103
|
+
' test',
|
104
|
+
'end']
|
105
|
+
|
106
|
+
new_source = autocorrect_source(cop, src)
|
107
|
+
|
108
|
+
expect(new_source).to eq(['test do |foo| ',
|
109
|
+
' bar',
|
110
|
+
' test',
|
111
|
+
'end'].join("\n"))
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'auto-corrects a {} block with params that is missing newlines' do
|
115
|
+
src = ['test { |foo| bar',
|
116
|
+
'}']
|
117
|
+
|
118
|
+
new_source = autocorrect_source(cop, src)
|
119
|
+
|
120
|
+
expect(new_source).to eq(['test { |foo| ',
|
121
|
+
' bar',
|
122
|
+
'}'].join("\n"))
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'autocorrects in more complex case with lambda and assignment, and '\
|
126
|
+
'aligns the next line two spaces out from the start of the block' do
|
127
|
+
src = ['x = -> (y) { foo',
|
128
|
+
' bar',
|
129
|
+
'}']
|
130
|
+
|
131
|
+
new_source = autocorrect_source(cop, src)
|
132
|
+
|
133
|
+
expect(new_source).to eq(['x = -> (y) { ',
|
134
|
+
' foo',
|
135
|
+
' bar',
|
136
|
+
'}'].join("\n"))
|
137
|
+
end
|
138
|
+
end
|
@@ -4,7 +4,7 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe RuboCop::Cop::Style::Next, :config do
|
6
6
|
subject(:cop) { described_class.new(config) }
|
7
|
-
let(:cop_config) { {} }
|
7
|
+
let(:cop_config) { { 'MinBodyLength' => 1 } }
|
8
8
|
|
9
9
|
it 'finds all kind of loops with condition at the end of the iteration' do
|
10
10
|
# TODO: Split this long example into multiple examples.
|
@@ -173,7 +173,7 @@ describe RuboCop::Cop::Style::Next, :config do
|
|
173
173
|
{ 'EnforcedStyle' => 'always' }
|
174
174
|
end
|
175
175
|
|
176
|
-
it '
|
176
|
+
it 'does not ignore modifier ifs' do
|
177
177
|
inspect_source(cop,
|
178
178
|
['[].each do |o|',
|
179
179
|
' puts o if o == 1',
|
@@ -251,6 +251,35 @@ describe RuboCop::Cop::Style::Next, :config do
|
|
251
251
|
' if true',
|
252
252
|
' end',
|
253
253
|
'end'])
|
254
|
-
expect(cop.offenses
|
254
|
+
expect(cop.offenses).to be_empty
|
255
|
+
end
|
256
|
+
|
257
|
+
context 'MinBodyLength: 3' do
|
258
|
+
let(:cop_config) do
|
259
|
+
{ 'MinBodyLength' => 3 }
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'accepts if whose body has 1 line' do
|
263
|
+
inspect_source(cop,
|
264
|
+
['arr.each do |e|',
|
265
|
+
' if something',
|
266
|
+
' work',
|
267
|
+
' end',
|
268
|
+
'end'])
|
269
|
+
expect(cop.offenses).to be_empty
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'reports an offense for if whose body has 3 lines' do
|
273
|
+
inspect_source(cop,
|
274
|
+
['arr.each do |e|',
|
275
|
+
' if something',
|
276
|
+
' work',
|
277
|
+
' work',
|
278
|
+
' work',
|
279
|
+
' end',
|
280
|
+
'end'])
|
281
|
+
expect(cop.offenses.size).to eq(1)
|
282
|
+
expect(cop.highlights).to eq(['each'])
|
283
|
+
end
|
255
284
|
end
|
256
285
|
end
|
@@ -258,5 +258,39 @@ describe RuboCop::Cop::Style::PercentLiteralDelimiters, :config do
|
|
258
258
|
new_source = autocorrect_source(cop, ['%w(', 'some', 'words', ')'])
|
259
259
|
expect(new_source).to eq("%w[\nsome\nwords\n]")
|
260
260
|
end
|
261
|
+
|
262
|
+
it 'preserves indentation when correcting a multiline array' do
|
263
|
+
original_source = [
|
264
|
+
' array = %w(',
|
265
|
+
' first',
|
266
|
+
' second',
|
267
|
+
' )'
|
268
|
+
]
|
269
|
+
corrected_source = [
|
270
|
+
' array = %w[',
|
271
|
+
' first',
|
272
|
+
' second',
|
273
|
+
' ]'
|
274
|
+
].join("\n")
|
275
|
+
new_source = autocorrect_source(cop, original_source)
|
276
|
+
expect(new_source).to eq(corrected_source)
|
277
|
+
end
|
278
|
+
|
279
|
+
it 'preserves irregular indentation when correcting a multiline array' do
|
280
|
+
original_source = [
|
281
|
+
' array = %w(',
|
282
|
+
' first',
|
283
|
+
' second',
|
284
|
+
')'
|
285
|
+
]
|
286
|
+
corrected_source = [
|
287
|
+
' array = %w[',
|
288
|
+
' first',
|
289
|
+
' second',
|
290
|
+
']'
|
291
|
+
].join("\n")
|
292
|
+
new_source = autocorrect_source(cop, original_source)
|
293
|
+
expect(new_source).to eq(corrected_source)
|
294
|
+
end
|
261
295
|
end
|
262
296
|
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe RuboCop::Cop::Style::PercentQLiterals, :config do
|
6
|
+
subject(:cop) { described_class.new(config) }
|
7
|
+
|
8
|
+
shared_examples 'accepts quote characters' do
|
9
|
+
it 'accepts single quotes' do
|
10
|
+
inspect_source(cop, ["'hi'"])
|
11
|
+
expect(cop.offenses).to be_empty
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'accepts double quotes' do
|
15
|
+
inspect_source(cop, ['"hi"'])
|
16
|
+
expect(cop.offenses).to be_empty
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
shared_examples 'accepts any q string with backslash t' do
|
21
|
+
context 'with special characters' do
|
22
|
+
it 'accepts %q' do
|
23
|
+
inspect_source(cop, ['%q(\t)'])
|
24
|
+
expect(cop.offenses).to be_empty
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'accepts %Q' do
|
28
|
+
inspect_source(cop, ['%Q(\t)'])
|
29
|
+
expect(cop.offenses).to be_empty
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when EnforcedStyle is lower_case_q' do
|
35
|
+
let(:cop_config) { { 'EnforcedStyle' => 'lower_case_q' } }
|
36
|
+
|
37
|
+
context 'without interpolation' do
|
38
|
+
it 'accepts %q' do
|
39
|
+
inspect_source(cop, ['%q(hi)'])
|
40
|
+
expect(cop.offenses).to be_empty
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'registers offense for %Q' do
|
44
|
+
inspect_source(cop, ['%Q(hi)'])
|
45
|
+
expect(cop.messages)
|
46
|
+
.to eq(['Do not use `%Q` unless interpolation is needed. Use `%q`.'])
|
47
|
+
expect(cop.highlights).to eq(['%Q('])
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'auto-corrects' do
|
51
|
+
new_source = autocorrect_source(cop, '%Q(hi)')
|
52
|
+
expect(new_source).to eq('%q(hi)')
|
53
|
+
end
|
54
|
+
|
55
|
+
include_examples 'accepts quote characters'
|
56
|
+
include_examples 'accepts any q string with backslash t'
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'with interpolation' do
|
60
|
+
it 'accepts %Q' do
|
61
|
+
inspect_source(cop, ['%Q(#{1 + 2})'])
|
62
|
+
expect(cop.offenses).to be_empty
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'accepts %q' do
|
66
|
+
# This is most probably a mistake, but not this cop's responisibility.
|
67
|
+
inspect_source(cop, ['%q(#{1 + 2})'])
|
68
|
+
expect(cop.offenses).to be_empty
|
69
|
+
end
|
70
|
+
|
71
|
+
include_examples 'accepts quote characters'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when EnforcedStyle is upper_case_q' do
|
76
|
+
let(:cop_config) { { 'EnforcedStyle' => 'upper_case_q' } }
|
77
|
+
|
78
|
+
context 'without interpolation' do
|
79
|
+
it 'registers offense for %q' do
|
80
|
+
inspect_source(cop, ['%q(hi)'])
|
81
|
+
expect(cop.messages).to eq(['Use `%Q` instead of `%q`.'])
|
82
|
+
expect(cop.highlights).to eq(['%q('])
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'accepts %Q' do
|
86
|
+
inspect_source(cop, ['%Q(hi)'])
|
87
|
+
expect(cop.offenses).to be_empty
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'auto-corrects' do
|
91
|
+
new_source = autocorrect_source(cop, '%q[hi]')
|
92
|
+
expect(new_source).to eq('%Q[hi]')
|
93
|
+
end
|
94
|
+
|
95
|
+
include_examples 'accepts quote characters'
|
96
|
+
include_examples 'accepts any q string with backslash t'
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'with interpolation' do
|
100
|
+
it 'accepts %Q' do
|
101
|
+
inspect_source(cop, ['%Q(#{1 + 2})'])
|
102
|
+
expect(cop.offenses).to be_empty
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'accepts %q' do
|
106
|
+
# It's strange if interpolation syntax appears inside a static string,
|
107
|
+
# but we can't be sure if it's a mistake or not. Changing it to %Q
|
108
|
+
# would alter semantics, so we leave it as it is.
|
109
|
+
inspect_source(cop, ['%q(#{1 + 2})'])
|
110
|
+
expect(cop.offenses).to be_empty
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'does not auto-correct' do
|
114
|
+
source = '%q(#{1 + 2})'
|
115
|
+
new_source = autocorrect_source(cop, source)
|
116
|
+
expect(new_source).to eq(source)
|
117
|
+
end
|
118
|
+
|
119
|
+
include_examples 'accepts quote characters'
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|