rubocop 0.9.0 → 0.9.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/CHANGELOG.md +23 -0
- data/README.md +1 -0
- data/config/default.yml +12 -0
- data/config/enabled.yml +0 -1
- data/lib/rubocop.rb +3 -0
- data/lib/rubocop/cli.rb +7 -1
- data/lib/rubocop/cop/cop.rb +20 -5
- data/lib/rubocop/cop/lint/end_alignment.rb +51 -42
- data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_condition.rb +59 -9
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -0
- data/lib/rubocop/cop/rails/validation.rb +0 -4
- data/lib/rubocop/cop/style/collection_methods.rb +28 -10
- data/lib/rubocop/cop/style/dot_position.rb +14 -4
- data/lib/rubocop/cop/style/if_then_else.rb +0 -51
- data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +47 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +20 -0
- data/lib/rubocop/cop/style/op_method.rb +16 -14
- data/lib/rubocop/cop/util.rb +4 -0
- data/lib/rubocop/cop/variable_inspector.rb +32 -13
- data/lib/rubocop/version.rb +1 -1
- data/rubocop.gemspec +1 -1
- data/spec/rubocop/cli_spec.rb +21 -0
- data/spec/rubocop/cops/lint/end_alignment_spec.rb +206 -299
- data/spec/rubocop/cops/lint/ensure_return_spec.rb +11 -0
- data/spec/rubocop/cops/lint/literal_in_condition_spec.rb +37 -3
- data/spec/rubocop/cops/lint/shadowing_outer_local_variable_spec.rb +63 -0
- data/spec/rubocop/cops/lint/unused_local_variable_spec.rb +68 -0
- data/spec/rubocop/cops/offence_spec.rb +2 -2
- data/spec/rubocop/cops/style/collection_methods_spec.rb +32 -28
- data/spec/rubocop/cops/style/dot_position_spec.rb +46 -11
- data/spec/rubocop/cops/style/multiline_if_then_spec.rb +16 -0
- metadata +7 -4
@@ -10,15 +10,25 @@ module Rubocop
|
|
10
10
|
def on_send(node)
|
11
11
|
return unless node.loc.dot
|
12
12
|
|
13
|
-
|
14
|
-
selector_line = node.loc.selector.line
|
15
|
-
|
16
|
-
if dot_line != selector_line
|
13
|
+
unless proper_dot_position?(node)
|
17
14
|
add_offence(:convention, node.loc.dot, MSG)
|
18
15
|
end
|
19
16
|
|
20
17
|
super
|
21
18
|
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def proper_dot_position?(node)
|
23
|
+
dot_line = node.loc.dot.line
|
24
|
+
selector_line = node.loc.selector.line
|
25
|
+
|
26
|
+
case DotPosition.config['Style'].downcase
|
27
|
+
when 'leading' then dot_line == selector_line
|
28
|
+
when 'trailing' then dot_line != selector_line
|
29
|
+
else fail 'Unknown dot position style selected.'
|
30
|
+
end
|
31
|
+
end
|
22
32
|
end
|
23
33
|
end
|
24
34
|
end
|
@@ -24,57 +24,6 @@ module Rubocop
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
27
|
-
|
28
|
-
# Checks for uses of semicolon in if statements.
|
29
|
-
class IfWithSemicolon < Cop
|
30
|
-
include IfThenElse
|
31
|
-
|
32
|
-
def offending_line(node)
|
33
|
-
node.loc.begin.line if node.loc.begin && node.loc.begin.is?(';')
|
34
|
-
end
|
35
|
-
|
36
|
-
def error_message
|
37
|
-
'Never use if x; Use the ternary operator instead.'
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# Checks for uses of then multi-line if statements.
|
42
|
-
class MultilineIfThen < Cop
|
43
|
-
include IfThenElse
|
44
|
-
|
45
|
-
def offending_line(node)
|
46
|
-
condition, body = *node
|
47
|
-
next_thing = if body && body.loc.expression
|
48
|
-
body.loc.expression.begin
|
49
|
-
else
|
50
|
-
node.loc.end # No body, use "end".
|
51
|
-
end
|
52
|
-
right_after_cond =
|
53
|
-
Parser::Source::Range.new(next_thing.source_buffer,
|
54
|
-
condition.loc.expression.end.end_pos,
|
55
|
-
next_thing.begin_pos)
|
56
|
-
if right_after_cond.source =~ /\A\s*then\s*(#.*)?\s*\n/
|
57
|
-
node.loc.expression.begin.line
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def error_message
|
62
|
-
'Never use then for multi-line if/unless.'
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
# Checks for uses of if/then/else/end on a single line.
|
67
|
-
class OneLineConditional < Cop
|
68
|
-
include IfThenElse
|
69
|
-
|
70
|
-
def offending_line(node)
|
71
|
-
node.loc.expression.line unless node.loc.expression.source =~ /\n/
|
72
|
-
end
|
73
|
-
|
74
|
-
def error_message
|
75
|
-
'Favor the ternary operator (?:) over if/then/else/end constructs.'
|
76
|
-
end
|
77
|
-
end
|
78
27
|
end
|
79
28
|
end
|
80
29
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Checks for uses of semicolon in if statements.
|
7
|
+
class IfWithSemicolon < Cop
|
8
|
+
include IfThenElse
|
9
|
+
|
10
|
+
def offending_line(node)
|
11
|
+
node.loc.begin.line if node.loc.begin && node.loc.begin.is?(';')
|
12
|
+
end
|
13
|
+
|
14
|
+
def error_message
|
15
|
+
'Never use if x; Use the ternary operator instead.'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Checks for uses of the `then` keyword in multi-line if statements.
|
7
|
+
#
|
8
|
+
# This is considered bad practice:
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# if cond then
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# While if statements can contain `then` on the same line:
|
15
|
+
# @example
|
16
|
+
#
|
17
|
+
# if cond then a
|
18
|
+
# elsif cond then b
|
19
|
+
# end
|
20
|
+
class MultilineIfThen < Cop
|
21
|
+
include IfThenElse
|
22
|
+
|
23
|
+
def offending_line(node)
|
24
|
+
condition, body, else_clause = *node
|
25
|
+
next_thing = if body && body.loc.expression
|
26
|
+
body.loc.expression.begin
|
27
|
+
elsif else_clause && else_clause.loc.expression
|
28
|
+
else_clause.loc.expression.begin
|
29
|
+
else
|
30
|
+
node.loc.end # No body, use "end".
|
31
|
+
end
|
32
|
+
right_after_cond =
|
33
|
+
Parser::Source::Range.new(next_thing.source_buffer,
|
34
|
+
condition.loc.expression.end.end_pos,
|
35
|
+
next_thing.begin_pos)
|
36
|
+
if right_after_cond.source =~ /\A\s*then\s*(#.*)?\s*\n/
|
37
|
+
node.loc.expression.begin.line
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def error_message
|
42
|
+
'Never use then for multi-line if/unless.'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Checks for uses of if/then/else/end on a single line.
|
7
|
+
class OneLineConditional < Cop
|
8
|
+
include IfThenElse
|
9
|
+
|
10
|
+
def offending_line(node)
|
11
|
+
node.loc.expression.line unless node.loc.expression.source =~ /\n/
|
12
|
+
end
|
13
|
+
|
14
|
+
def error_message
|
15
|
+
'Favor the ternary operator (?:) over if/then/else/end constructs.'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -2,25 +2,27 @@
|
|
2
2
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
module Style
|
6
|
+
# This cop makes sure that certain operator methods have their sole
|
7
|
+
# parameter named *other*.
|
8
|
+
class OpMethod < Cop
|
9
|
+
MSG = 'When defining the %s operator, name its argument *other*.'
|
9
10
|
|
10
|
-
|
11
|
+
BLACKLISTED = [:+@, :-@, :[], :[]=, :<<]
|
11
12
|
|
12
|
-
|
13
|
+
TARGET_ARGS = s(:args, s(:arg, :other))
|
13
14
|
|
14
|
-
|
15
|
-
|
15
|
+
def on_def(node)
|
16
|
+
name, args, _body = *node
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
if name !~ /\A\w/ && !BLACKLISTED.include?(name) &&
|
19
|
+
args.children.size == 1 && args != TARGET_ARGS
|
20
|
+
add_offence(:convention, args.children[0].loc.expression,
|
21
|
+
sprintf(MSG, name))
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
+
super
|
25
|
+
end
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
data/lib/rubocop/cop/util.rb
CHANGED
@@ -6,10 +6,10 @@ module Rubocop
|
|
6
6
|
# This is intended to be used as mix-in, and the user class may override
|
7
7
|
# some of hook methods.
|
8
8
|
module VariableInspector
|
9
|
-
VARIABLE_ASSIGNMENT_TYPES = [:lvasgn].freeze
|
9
|
+
VARIABLE_ASSIGNMENT_TYPES = [:lvasgn, :match_with_lvasgn].freeze
|
10
10
|
ARGUMENT_DECLARATION_TYPES = [
|
11
11
|
:arg, :optarg, :restarg, :blockarg,
|
12
|
-
:kwarg, :kwoptarg, :
|
12
|
+
:kwarg, :kwoptarg, :kwrestarg,
|
13
13
|
:shadowarg
|
14
14
|
].freeze
|
15
15
|
VARIABLE_DECLARATION_TYPES =
|
@@ -25,18 +25,19 @@ module Rubocop
|
|
25
25
|
attr_accessor :used
|
26
26
|
alias_method :used?, :used
|
27
27
|
|
28
|
-
def initialize(node)
|
28
|
+
def initialize(node, name = nil)
|
29
29
|
unless VARIABLE_DECLARATION_TYPES.include?(node.type)
|
30
30
|
fail ArgumentError,
|
31
31
|
"Node type must be any of #{VARIABLE_DECLARATION_TYPES}, " +
|
32
32
|
"passed #{node.type}"
|
33
33
|
end
|
34
34
|
@node = node
|
35
|
+
@name = name.to_sym if name
|
35
36
|
@used = false
|
36
37
|
end
|
37
38
|
|
38
39
|
def name
|
39
|
-
@node.children.first
|
40
|
+
@name || @node.children.first
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
@@ -100,8 +101,8 @@ module Rubocop
|
|
100
101
|
scope_stack.count
|
101
102
|
end
|
102
103
|
|
103
|
-
def add_variable_entry(variable_declaration_node)
|
104
|
-
entry = VariableEntry.new(variable_declaration_node)
|
104
|
+
def add_variable_entry(variable_declaration_node, name = nil)
|
105
|
+
entry = VariableEntry.new(variable_declaration_node, name)
|
105
106
|
invoke_hook(:before_declaring_variable, entry)
|
106
107
|
current_scope.variable_entries[entry.name] = entry
|
107
108
|
invoke_hook(:after_declaring_variable, entry)
|
@@ -188,14 +189,11 @@ module Rubocop
|
|
188
189
|
case node.type
|
189
190
|
when *ARGUMENT_DECLARATION_TYPES
|
190
191
|
variable_table.add_variable_entry(node)
|
191
|
-
when
|
192
|
+
when :lvasgn
|
192
193
|
variable_name = node.children.first
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
else
|
197
|
-
variable_table.add_variable_entry(node)
|
198
|
-
end
|
194
|
+
process_variable_assignment(node, variable_name)
|
195
|
+
when :match_with_lvasgn
|
196
|
+
process_named_captures(node)
|
199
197
|
when *VARIABLE_USE_TYPES
|
200
198
|
variable_name = node.children.first
|
201
199
|
variable_entry = variable_table.find_variable_entry(variable_name)
|
@@ -256,6 +254,27 @@ module Rubocop
|
|
256
254
|
end
|
257
255
|
end
|
258
256
|
|
257
|
+
def process_variable_assignment(node, name)
|
258
|
+
entry = variable_table.find_variable_entry(name)
|
259
|
+
if entry
|
260
|
+
entry.used = true
|
261
|
+
else
|
262
|
+
variable_table.add_variable_entry(node, name)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
def process_named_captures(match_with_lvasgn_node)
|
267
|
+
regexp_string = match_with_lvasgn_node.children[0]
|
268
|
+
.children[0]
|
269
|
+
.children[0]
|
270
|
+
regexp = Regexp.new(regexp_string)
|
271
|
+
variable_names = regexp.named_captures.keys
|
272
|
+
|
273
|
+
variable_names.each do |name|
|
274
|
+
process_variable_assignment(match_with_lvasgn_node, name)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
259
278
|
# Hooks
|
260
279
|
|
261
280
|
def before_entering_scope(scope)
|
data/lib/rubocop/version.rb
CHANGED
data/rubocop.gemspec
CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
|
|
27
27
|
s.summary = 'Automatic Ruby code style checking tool.'
|
28
28
|
|
29
29
|
s.add_runtime_dependency('rainbow', '>= 1.1.4')
|
30
|
-
s.add_runtime_dependency('parser', '2.0.0.
|
30
|
+
s.add_runtime_dependency('parser', '2.0.0.pre1')
|
31
31
|
s.add_development_dependency('rake', '~> 10.0')
|
32
32
|
s.add_development_dependency('rspec', '~> 2.13')
|
33
33
|
s.add_development_dependency('yard', '~> 0.8')
|
data/spec/rubocop/cli_spec.rb
CHANGED
@@ -47,6 +47,7 @@ Usage: rubocop [options] [file1, file2, ...]
|
|
47
47
|
if no format is specified.
|
48
48
|
-r, --require FILE Require Ruby file.
|
49
49
|
-R, --rails Run extra Rails cops.
|
50
|
+
-l, --lint Run only lint cops.
|
50
51
|
-a, --auto-correct Auto-correct offences.
|
51
52
|
-s, --silent Silence summary.
|
52
53
|
-n, --no-color Disable color output.
|
@@ -252,8 +253,28 @@ Usage: rubocop [options] [file1, file2, ...]
|
|
252
253
|
''].join("\n"))
|
253
254
|
end
|
254
255
|
|
256
|
+
it 'runs only lint cops if --lint is passed' do
|
257
|
+
create_file('example.rb', ['if 0 ',
|
258
|
+
"\ty",
|
259
|
+
'end'])
|
260
|
+
# IfUnlessModifier depends on the configuration of LineLength.
|
261
|
+
# That configuration might have been set by other spec examples
|
262
|
+
# so we reset it to emulate a start from scratch.
|
263
|
+
Cop::Style::LineLength.config = nil
|
264
|
+
|
265
|
+
expect(cli.run(['--format', 'simple', '--lint', 'example.rb'])).to eq(1)
|
266
|
+
expect($stdout.string)
|
267
|
+
.to eq(['== example.rb ==',
|
268
|
+
'W: 1: 4: Literal 0 appeared in a condition.',
|
269
|
+
'',
|
270
|
+
'1 file inspected, 1 offence detected',
|
271
|
+
''].join("\n"))
|
272
|
+
|
273
|
+
end
|
274
|
+
|
255
275
|
it 'exits with error if an incorrect cop name is passed to --only' do
|
256
276
|
expect(cli.run(%w(--only 123))).to eq(1)
|
277
|
+
|
257
278
|
expect($stderr.string).to eq("Unrecognized cop name: 123.\n")
|
258
279
|
end
|
259
280
|
|
@@ -8,10 +8,6 @@ module Rubocop
|
|
8
8
|
module Lint
|
9
9
|
describe EndAlignment do
|
10
10
|
let(:cop) { EndAlignment.new }
|
11
|
-
before do
|
12
|
-
# TODO: Initialize the config to a default {} value. Currently it's nil.
|
13
|
-
EndAlignment.config = {}
|
14
|
-
end
|
15
11
|
|
16
12
|
it 'registers an offence for mismatched class end' do
|
17
13
|
inspect_source(cop,
|
@@ -77,348 +73,259 @@ module Rubocop
|
|
77
73
|
expect(cop.offences.size).to eq(1)
|
78
74
|
end
|
79
75
|
|
80
|
-
context '
|
81
|
-
|
82
|
-
EndAlignment.config = { 'BlockAlignSchema' => 'StartOfAssignment' }
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'accepts end aligned with a variable' do
|
86
|
-
inspect_source(cop,
|
87
|
-
['variable = test do |ala|',
|
88
|
-
'end'
|
89
|
-
])
|
90
|
-
expect(cop.offences).to be_empty
|
91
|
-
end
|
92
|
-
|
93
|
-
it 'registers an offence for mismatched block end with a variable' do
|
94
|
-
inspect_source(cop,
|
95
|
-
['variable = test do |ala|',
|
96
|
-
' end'
|
97
|
-
])
|
98
|
-
expect(cop.offences.size).to eq(1)
|
99
|
-
end
|
100
|
-
|
101
|
-
it 'accepts end aligned with an instance variable' do
|
102
|
-
inspect_source(cop,
|
103
|
-
['@variable = test do |ala|',
|
104
|
-
'end'
|
105
|
-
])
|
106
|
-
expect(cop.offences).to be_empty
|
107
|
-
end
|
108
|
-
|
109
|
-
it 'registers an offence for mismatched block end with an instance variable' do
|
110
|
-
inspect_source(cop,
|
111
|
-
['@variable = test do |ala|',
|
112
|
-
' end'
|
113
|
-
])
|
114
|
-
expect(cop.offences.size).to eq(1)
|
115
|
-
end
|
116
|
-
|
117
|
-
it 'accepts end aligned with a class variable' do
|
118
|
-
inspect_source(cop,
|
119
|
-
['@@variable = test do |ala|',
|
120
|
-
'end'
|
121
|
-
])
|
122
|
-
expect(cop.offences).to be_empty
|
123
|
-
end
|
124
|
-
|
125
|
-
it 'registers an offence for mismatched block end with a class variable' do
|
126
|
-
inspect_source(cop,
|
127
|
-
['@@variable = test do |ala|',
|
128
|
-
' end'
|
129
|
-
])
|
130
|
-
expect(cop.offences.size).to eq(1)
|
131
|
-
end
|
132
|
-
|
133
|
-
it 'accepts end aligned with a global variable' do
|
134
|
-
inspect_source(cop,
|
135
|
-
['$variable = test do |ala|',
|
136
|
-
'end'
|
137
|
-
])
|
138
|
-
expect(cop.offences).to be_empty
|
139
|
-
end
|
140
|
-
|
141
|
-
it 'registers an offence for mismatched block end with a global variable' do
|
76
|
+
context 'when the block is a logical operand' do
|
77
|
+
it 'accepts a correctly aligned block end' do
|
142
78
|
inspect_source(cop,
|
143
|
-
['
|
144
|
-
'
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
it 'accepts end aligned with a constant' do
|
150
|
-
inspect_source(cop,
|
151
|
-
['CONSTANT = test do |ala|',
|
152
|
-
'end'
|
79
|
+
['(value.is_a? Array) && value.all? do |subvalue|',
|
80
|
+
' type_check_value(subvalue, array_type)',
|
81
|
+
'end',
|
82
|
+
'a || b do',
|
83
|
+
'end',
|
153
84
|
])
|
154
85
|
expect(cop.offences).to be_empty
|
155
86
|
end
|
87
|
+
end
|
156
88
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
89
|
+
it 'accepts end aligned with a variable' do
|
90
|
+
inspect_source(cop,
|
91
|
+
['variable = test do |ala|',
|
92
|
+
'end'
|
93
|
+
])
|
94
|
+
expect(cop.offences).to be_empty
|
95
|
+
end
|
164
96
|
|
165
|
-
|
97
|
+
context 'and the block is an operand' do
|
98
|
+
it 'accepts end aligned with a variable' do
|
166
99
|
inspect_source(cop,
|
167
|
-
['
|
168
|
-
|
169
|
-
|
100
|
+
['b = 1 + preceding_line.reduce(0) do |a, e|',
|
101
|
+
' a + e.length + newline_length',
|
102
|
+
'end + 1'
|
170
103
|
])
|
171
104
|
expect(cop.offences).to be_empty
|
172
105
|
end
|
106
|
+
end
|
173
107
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
end
|
182
|
-
|
183
|
-
it 'accepts end aligned with an op-asgn (+=, -=)' do
|
184
|
-
inspect_source(cop,
|
185
|
-
['rb += files.select do |file|',
|
186
|
-
' file << something',
|
187
|
-
'end'
|
188
|
-
])
|
189
|
-
expect(cop.offences).to be_empty
|
190
|
-
end
|
108
|
+
it 'registers an offence for mismatched block end with a variable' do
|
109
|
+
inspect_source(cop,
|
110
|
+
['variable = test do |ala|',
|
111
|
+
' end'
|
112
|
+
])
|
113
|
+
expect(cop.offences.size).to eq(1)
|
114
|
+
end
|
191
115
|
|
192
|
-
|
116
|
+
context 'when the block is defined on the next line' do
|
117
|
+
it 'accepts end aligned with the block expression' do
|
193
118
|
inspect_source(cop,
|
194
|
-
['
|
195
|
-
'
|
119
|
+
['variable =',
|
120
|
+
' a_long_method_that_dont_fit_on_the_line do |v|',
|
121
|
+
' v.foo',
|
196
122
|
' end'
|
197
123
|
])
|
198
|
-
expect(cop.offences.size).to eq(1)
|
199
|
-
end
|
200
|
-
|
201
|
-
it 'accepts end aligned with an and-asgn (&&=)' do
|
202
|
-
inspect_source(cop,
|
203
|
-
['variable &&= test do |ala|',
|
204
|
-
'end'
|
205
|
-
])
|
206
124
|
expect(cop.offences).to be_empty
|
207
125
|
end
|
208
126
|
|
209
|
-
it 'registers an
|
127
|
+
it 'registers an offences for mismatched end alignment' do
|
210
128
|
inspect_source(cop,
|
211
|
-
['variable
|
212
|
-
'
|
213
|
-
|
214
|
-
expect(cop.offences.size).to eq(1)
|
215
|
-
end
|
216
|
-
|
217
|
-
it 'accepts end aligned with an or-asgn (||=)' do
|
218
|
-
inspect_source(cop,
|
219
|
-
['variable ||= test do |ala|',
|
129
|
+
['variable =',
|
130
|
+
' a_long_method_that_dont_fit_on_the_line do |v|',
|
131
|
+
' v.foo',
|
220
132
|
'end'
|
221
133
|
])
|
222
|
-
expect(cop.offences).to be_empty
|
223
|
-
end
|
224
|
-
|
225
|
-
it 'registers an offence for mismatched block end with an or-asgn (||=)' do
|
226
|
-
inspect_source(cop,
|
227
|
-
['variable ||= test do |ala|',
|
228
|
-
' end'
|
229
|
-
])
|
230
134
|
expect(cop.offences.size).to eq(1)
|
231
135
|
end
|
136
|
+
end
|
232
137
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
end
|
138
|
+
it 'accepts end aligned with an instance variable' do
|
139
|
+
inspect_source(cop,
|
140
|
+
['@variable = test do |ala|',
|
141
|
+
'end'
|
142
|
+
])
|
143
|
+
expect(cop.offences).to be_empty
|
144
|
+
end
|
241
145
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
expect(cop.offences.size).to eq(1)
|
249
|
-
end
|
146
|
+
it 'registers an offence for mismatched block end with an instance variable' do
|
147
|
+
inspect_source(cop,
|
148
|
+
['@variable = test do |ala|',
|
149
|
+
' end'
|
150
|
+
])
|
151
|
+
expect(cop.offences.size).to eq(1)
|
250
152
|
end
|
251
153
|
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
154
|
+
it 'accepts end aligned with a class variable' do
|
155
|
+
inspect_source(cop,
|
156
|
+
['@@variable = test do |ala|',
|
157
|
+
'end'
|
158
|
+
])
|
159
|
+
expect(cop.offences).to be_empty
|
160
|
+
end
|
256
161
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
162
|
+
it 'registers an offence for mismatched block end with a class variable' do
|
163
|
+
inspect_source(cop,
|
164
|
+
['@@variable = test do |ala|',
|
165
|
+
' end'
|
166
|
+
])
|
167
|
+
expect(cop.offences.size).to eq(1)
|
168
|
+
end
|
264
169
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
170
|
+
it 'accepts end aligned with a global variable' do
|
171
|
+
inspect_source(cop,
|
172
|
+
['$variable = test do |ala|',
|
173
|
+
'end'
|
174
|
+
])
|
175
|
+
expect(cop.offences).to be_empty
|
176
|
+
end
|
272
177
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
178
|
+
it 'registers an offence for mismatched block end with a global variable' do
|
179
|
+
inspect_source(cop,
|
180
|
+
['$variable = test do |ala|',
|
181
|
+
' end'
|
182
|
+
])
|
183
|
+
expect(cop.offences.size).to eq(1)
|
184
|
+
end
|
280
185
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
186
|
+
it 'accepts end aligned with a constant' do
|
187
|
+
inspect_source(cop,
|
188
|
+
['CONSTANT = test do |ala|',
|
189
|
+
'end'
|
190
|
+
])
|
191
|
+
expect(cop.offences).to be_empty
|
192
|
+
end
|
288
193
|
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
194
|
+
it 'registers an offence for mismatched block end with a constant' do
|
195
|
+
inspect_source(cop,
|
196
|
+
['Module::CONSTANT = test do |ala|',
|
197
|
+
' end'
|
198
|
+
])
|
199
|
+
expect(cop.offences.size).to eq(1)
|
200
|
+
end
|
296
201
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
202
|
+
it 'accepts end aligned with a method call' do
|
203
|
+
inspect_source(cop,
|
204
|
+
['parser.childs << lambda do |token|',
|
205
|
+
' token << 1',
|
206
|
+
'end'
|
207
|
+
])
|
208
|
+
expect(cop.offences).to be_empty
|
209
|
+
end
|
304
210
|
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
211
|
+
it 'registers an offence for mismatched block end with a method call' do
|
212
|
+
inspect_source(cop,
|
213
|
+
['parser.childs << lambda do |token|',
|
214
|
+
' token << 1',
|
215
|
+
' end'
|
216
|
+
])
|
217
|
+
expect(cop.offences.size).to eq(1)
|
218
|
+
end
|
312
219
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
220
|
+
it 'accepts end aligned with a method call with arguments' do
|
221
|
+
inspect_source(cop,
|
222
|
+
['@h[:f] = f.each_pair.map do |f, v|',
|
223
|
+
' v = 1',
|
224
|
+
'end'
|
225
|
+
])
|
226
|
+
expect(cop.offences).to be_empty
|
227
|
+
end
|
320
228
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
229
|
+
it 'registers an offence for mismatched end with a method call with arguments' do
|
230
|
+
inspect_source(cop,
|
231
|
+
['@h[:f] = f.each_pair.map do |f, v|',
|
232
|
+
' v = 1',
|
233
|
+
' end'
|
234
|
+
])
|
235
|
+
expect(cop.offences.size).to eq(1)
|
236
|
+
end
|
328
237
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
end
|
238
|
+
it 'does not raise an error for nested block in a method call' do
|
239
|
+
inspect_source(cop,
|
240
|
+
['expect(arr.all? { |o| o.valid? })'
|
241
|
+
])
|
242
|
+
expect(cop.offences).to be_empty
|
243
|
+
end
|
336
244
|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
245
|
+
it 'accepts end aligned with the outermost method in the method chain that calls the block' do
|
246
|
+
inspect_source(cop,
|
247
|
+
['expect(arr.all? do |o|',
|
248
|
+
' o.valid?',
|
249
|
+
'end)'
|
250
|
+
])
|
251
|
+
expect(cop.offences).to be_empty
|
252
|
+
end
|
345
253
|
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
254
|
+
it 'registers an offence for mismatched end aligned with the outermost method in the method chain that calls the block' do
|
255
|
+
inspect_source(cop,
|
256
|
+
['expect(arr.all? do |o|',
|
257
|
+
' o.valid?',
|
258
|
+
' end)'
|
259
|
+
])
|
260
|
+
expect(cop.offences.size).to eq(1)
|
261
|
+
end
|
354
262
|
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
263
|
+
it 'accepts end aligned with an op-asgn (+=, -=)' do
|
264
|
+
inspect_source(cop,
|
265
|
+
['rb += files.select do |file|',
|
266
|
+
' file << something',
|
267
|
+
'end'
|
268
|
+
])
|
269
|
+
expect(cop.offences).to be_empty
|
270
|
+
end
|
363
271
|
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
272
|
+
it 'registers an offence for mismatched block end with an op-asgn (+=, -=)' do
|
273
|
+
inspect_source(cop,
|
274
|
+
['rb += files.select do |file|',
|
275
|
+
' file << something',
|
276
|
+
' end'
|
277
|
+
])
|
278
|
+
expect(cop.offences.size).to eq(1)
|
279
|
+
end
|
372
280
|
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
281
|
+
it 'accepts end aligned with an and-asgn (&&=)' do
|
282
|
+
inspect_source(cop,
|
283
|
+
['variable &&= test do |ala|',
|
284
|
+
'end'
|
285
|
+
])
|
286
|
+
expect(cop.offences).to be_empty
|
287
|
+
end
|
380
288
|
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
289
|
+
it 'registers an offence for mismatched block end with an and-asgn (&&=)' do
|
290
|
+
inspect_source(cop,
|
291
|
+
['variable &&= test do |ala|',
|
292
|
+
' end'
|
293
|
+
])
|
294
|
+
expect(cop.offences.size).to eq(1)
|
295
|
+
end
|
388
296
|
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
297
|
+
it 'accepts end aligned with an or-asgn (||=)' do
|
298
|
+
inspect_source(cop,
|
299
|
+
['variable ||= test do |ala|',
|
300
|
+
'end'
|
301
|
+
])
|
302
|
+
expect(cop.offences).to be_empty
|
303
|
+
end
|
396
304
|
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
305
|
+
it 'registers an offence for mismatched block end with an or-asgn (||=)' do
|
306
|
+
inspect_source(cop,
|
307
|
+
['variable ||= test do |ala|',
|
308
|
+
' end'
|
309
|
+
])
|
310
|
+
expect(cop.offences.size).to eq(1)
|
311
|
+
end
|
404
312
|
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
313
|
+
it 'accepts end aligned with a mass assignment' do
|
314
|
+
inspect_source(cop,
|
315
|
+
['var1, var2 = lambda do |test|',
|
316
|
+
' [1, 2]',
|
317
|
+
'end'
|
318
|
+
])
|
319
|
+
expect(cop.offences).to be_empty
|
320
|
+
end
|
413
321
|
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
end
|
322
|
+
it 'registers an offence for mismatched block end with a mass assignment' do
|
323
|
+
inspect_source(cop,
|
324
|
+
['var1, var2 = lambda do |test|',
|
325
|
+
' [1, 2]',
|
326
|
+
' end'
|
327
|
+
])
|
328
|
+
expect(cop.offences.size).to eq(1)
|
422
329
|
end
|
423
330
|
end
|
424
331
|
end
|