rubocop 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rubocop might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/CHANGELOG.md +35 -0
- data/CONTRIBUTING.md +2 -0
- data/README.md +102 -5
- data/config/default.yml +31 -3
- data/config/enabled.yml +21 -3
- data/lib/rubocop.rb +5 -0
- data/lib/rubocop/cli.rb +27 -7
- data/lib/rubocop/config.rb +21 -2
- data/lib/rubocop/config_store.rb +4 -1
- data/lib/rubocop/cop/commissioner.rb +2 -4
- data/lib/rubocop/cop/cop.rb +8 -8
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +3 -0
- data/lib/rubocop/cop/lint/block_alignment.rb +10 -20
- data/lib/rubocop/cop/lint/useless_assignment.rb +63 -0
- data/lib/rubocop/cop/lint/useless_comparison.rb +30 -0
- data/lib/rubocop/cop/style/align_parameters.rb +23 -13
- data/lib/rubocop/cop/style/and_or.rb +13 -1
- data/lib/rubocop/cop/style/blocks.rb +35 -0
- data/lib/rubocop/cop/style/character_literal.rb +1 -1
- data/lib/rubocop/cop/style/comment_annotation.rb +20 -5
- data/lib/rubocop/cop/style/dot_position.rb +7 -1
- data/lib/rubocop/cop/style/empty_line_between_defs.rb +1 -1
- data/lib/rubocop/cop/style/favor_modifier.rb +4 -4
- data/lib/rubocop/cop/style/module_function.rb +34 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +7 -9
- data/lib/rubocop/cop/style/redundant_begin.rb +7 -7
- data/lib/rubocop/cop/style/redundant_return.rb +9 -11
- data/lib/rubocop/cop/style/redundant_self.rb +5 -1
- data/lib/rubocop/cop/style/regexp_literal.rb +2 -1
- data/lib/rubocop/cop/style/signal_exception.rb +40 -0
- data/lib/rubocop/cop/style/string_literals.rb +2 -2
- data/lib/rubocop/cop/style/symbol_name.rb +11 -0
- data/lib/rubocop/cop/style/trivial_accessors.rb +22 -10
- data/lib/rubocop/cop/variable_inspector.rb +92 -71
- data/lib/rubocop/formatter/clang_style_formatter.rb +8 -3
- data/lib/rubocop/formatter/disabled_config_formatter.rb +32 -0
- data/lib/rubocop/formatter/formatter_set.rb +7 -4
- data/lib/rubocop/target_finder.rb +3 -4
- data/lib/rubocop/version.rb +1 -1
- data/rubocop.gemspec +1 -1
- data/spec/rubocop/cli_spec.rb +90 -1
- data/spec/rubocop/cops/commissioner_spec.rb +1 -1
- data/spec/rubocop/cops/lint/assignment_in_condition_spec.rb +6 -0
- data/spec/rubocop/cops/lint/block_alignment_spec.rb +16 -4
- data/spec/rubocop/cops/lint/empty_ensure_spec.rb +1 -1
- data/spec/rubocop/cops/lint/ensure_return_spec.rb +1 -1
- data/spec/rubocop/cops/lint/shadowing_outer_local_variable_spec.rb +4 -4
- data/spec/rubocop/cops/lint/unused_local_variable_spec.rb +49 -13
- data/spec/rubocop/cops/lint/useless_assignment_spec.rb +62 -0
- data/spec/rubocop/cops/lint/useless_comparison_spec.rb +31 -0
- data/spec/rubocop/cops/style/align_parameters_spec.rb +9 -0
- data/spec/rubocop/cops/style/and_or_spec.rb +12 -0
- data/spec/rubocop/cops/style/avoid_global_vars_spec.rb +1 -1
- data/spec/rubocop/cops/style/blocks_spec.rb +57 -14
- data/spec/rubocop/cops/style/character_literal_spec.rb +2 -2
- data/spec/rubocop/cops/style/comment_annotation_spec.rb +32 -4
- data/spec/rubocop/cops/style/dot_position_spec.rb +10 -0
- data/spec/rubocop/cops/style/empty_line_between_defs_spec.rb +12 -0
- data/spec/rubocop/cops/style/end_of_line_spec.rb +1 -0
- data/spec/rubocop/cops/style/favor_modifier_spec.rb +18 -0
- data/spec/rubocop/cops/style/hash_syntax_spec.rb +7 -2
- data/spec/rubocop/cops/style/module_function_spec.rb +30 -0
- data/spec/rubocop/cops/style/redundant_begin_spec.rb +2 -2
- data/spec/rubocop/cops/style/redundant_return_spec.rb +4 -4
- data/spec/rubocop/cops/style/redundant_self_spec.rb +36 -2
- data/spec/rubocop/cops/style/regexp_literal_spec.rb +1 -0
- data/spec/rubocop/cops/style/signal_exception_spec.rb +74 -0
- data/spec/rubocop/cops/style/string_literals_spec.rb +10 -0
- data/spec/rubocop/cops/style/symbol_name_spec.rb +13 -0
- data/spec/rubocop/cops/style/trivial_accessors_spec.rb +28 -3
- data/spec/rubocop/cops/variable_inspector_spec.rb +217 -36
- data/spec/rubocop/formatter/base_formatter_spec.rb +3 -3
- data/spec/rubocop/formatter/clang_style_formatter_spec.rb +19 -0
- data/spec/rubocop/formatter/disabled_config_formatter_spec.rb +48 -0
- data/spec/rubocop/formatter/formatter_set_spec.rb +1 -1
- data/spec/rubocop/processed_source_spec.rb +1 -1
- data/spec/spec_helper.rb +18 -13
- metadata +31 -38
@@ -13,7 +13,7 @@ module Rubocop
|
|
13
13
|
' return something',
|
14
14
|
'end']
|
15
15
|
inspect_source(cop, src)
|
16
|
-
expect(cop.offences).to
|
16
|
+
expect(cop.offences.size).to eq(1)
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'reports an offence for defs with only a return' do
|
@@ -21,7 +21,7 @@ module Rubocop
|
|
21
21
|
' return something',
|
22
22
|
'end']
|
23
23
|
inspect_source(cop, src)
|
24
|
-
expect(cop.offences).to
|
24
|
+
expect(cop.offences.size).to eq(1)
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'reports an offence for def ending with return' do
|
@@ -31,7 +31,7 @@ module Rubocop
|
|
31
31
|
' return something',
|
32
32
|
'end']
|
33
33
|
inspect_source(cop, src)
|
34
|
-
expect(cop.offences).to
|
34
|
+
expect(cop.offences.size).to eq(1)
|
35
35
|
end
|
36
36
|
|
37
37
|
it 'reports an offence for defs ending with return' do
|
@@ -41,7 +41,7 @@ module Rubocop
|
|
41
41
|
' return something',
|
42
42
|
'end']
|
43
43
|
inspect_source(cop, src)
|
44
|
-
expect(cop.offences).to
|
44
|
+
expect(cop.offences.size).to eq(1)
|
45
45
|
end
|
46
46
|
|
47
47
|
it 'accepts return in a non-final position' do
|
@@ -11,7 +11,7 @@ module Rubocop
|
|
11
11
|
it 'reports an offence a self receiver on an rvalue' do
|
12
12
|
src = ['a = self.b']
|
13
13
|
inspect_source(cop, src)
|
14
|
-
expect(cop.offences).to
|
14
|
+
expect(cop.offences.size).to eq(1)
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'accepts a self receiver on an lvalue of an assignment' do
|
@@ -52,7 +52,41 @@ module Rubocop
|
|
52
52
|
|
53
53
|
it 'accepts a self receiver for methods named like ruby keywords' do
|
54
54
|
src = ['a = self.class',
|
55
|
-
'self.for(deps, [], true)'
|
55
|
+
'self.for(deps, [], true)',
|
56
|
+
'self.and(other)',
|
57
|
+
'self.or(other)',
|
58
|
+
'self.alias',
|
59
|
+
'self.begin',
|
60
|
+
'self.break',
|
61
|
+
'self.case',
|
62
|
+
'self.def',
|
63
|
+
'self.defined',
|
64
|
+
'self.do',
|
65
|
+
'self.else',
|
66
|
+
'self.elsif',
|
67
|
+
'self.end',
|
68
|
+
'self.ensure',
|
69
|
+
'self.false',
|
70
|
+
'self.if',
|
71
|
+
'self.in',
|
72
|
+
'self.module',
|
73
|
+
'self.next',
|
74
|
+
'self.nil',
|
75
|
+
'self.not',
|
76
|
+
'self.redo',
|
77
|
+
'self.rescue',
|
78
|
+
'self.retry',
|
79
|
+
'self.return',
|
80
|
+
'self.self',
|
81
|
+
'self.super',
|
82
|
+
'self.then',
|
83
|
+
'self.true',
|
84
|
+
'self.undef',
|
85
|
+
'self.unless',
|
86
|
+
'self.until',
|
87
|
+
'self.when',
|
88
|
+
'self.while',
|
89
|
+
'self.yield'
|
56
90
|
]
|
57
91
|
inspect_source(cop, src)
|
58
92
|
expect(cop.offences).to be_empty
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
module Rubocop
|
6
|
+
module Cop
|
7
|
+
module Style
|
8
|
+
describe SignalException do
|
9
|
+
let(:cop) { described_class.new }
|
10
|
+
|
11
|
+
it 'registers an offence for raise in begin section' do
|
12
|
+
inspect_source(cop,
|
13
|
+
['begin',
|
14
|
+
' raise',
|
15
|
+
'rescue Exception',
|
16
|
+
' #do nothing',
|
17
|
+
'end'])
|
18
|
+
expect(cop.offences.size).to eq(1)
|
19
|
+
expect(cop.messages).to eq([SignalException::FAIL_MSG])
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'registers an offence for raise in def body' do
|
23
|
+
inspect_source(cop,
|
24
|
+
['def test',
|
25
|
+
' raise',
|
26
|
+
'rescue Exception',
|
27
|
+
' #do nothing',
|
28
|
+
'end'])
|
29
|
+
expect(cop.offences.size).to eq(1)
|
30
|
+
expect(cop.messages).to eq([SignalException::FAIL_MSG])
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'registers an offence for fail in rescue section' do
|
34
|
+
inspect_source(cop,
|
35
|
+
['begin',
|
36
|
+
' fail',
|
37
|
+
'rescue Exception',
|
38
|
+
' fail',
|
39
|
+
'end'])
|
40
|
+
expect(cop.offences.size).to eq(1)
|
41
|
+
expect(cop.messages).to eq([SignalException::RAISE_MSG])
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'registers an offence for fail def rescue section' do
|
45
|
+
inspect_source(cop,
|
46
|
+
['def test',
|
47
|
+
' fail',
|
48
|
+
'rescue Exception',
|
49
|
+
' fail',
|
50
|
+
'end'])
|
51
|
+
expect(cop.offences.size).to eq(1)
|
52
|
+
expect(cop.messages).to eq([SignalException::RAISE_MSG])
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'is not confused by nested begin/rescue' do
|
56
|
+
inspect_source(cop,
|
57
|
+
['begin',
|
58
|
+
' raise',
|
59
|
+
' begin',
|
60
|
+
' raise',
|
61
|
+
' rescue',
|
62
|
+
' fail',
|
63
|
+
' end',
|
64
|
+
'rescue Exception',
|
65
|
+
' #do nothing',
|
66
|
+
'end'])
|
67
|
+
expect(cop.offences.size).to eq(3)
|
68
|
+
expect(cop.messages).to eq([SignalException::FAIL_MSG] * 2 +
|
69
|
+
[SignalException::RAISE_MSG])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -43,6 +43,16 @@ module Rubocop
|
|
43
43
|
expect(cop.offences).to be_empty
|
44
44
|
end
|
45
45
|
|
46
|
+
it 'accepts " in a %w' do
|
47
|
+
inspect_source(cop, ['%w(")'])
|
48
|
+
expect(cop.offences).to be_empty
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'accepts \\\\\n in a string' do # this would be: "\\\n"
|
52
|
+
inspect_source(cop, ['"foo \\\\\n bar"'])
|
53
|
+
expect(cop.offences).to be_empty
|
54
|
+
end
|
55
|
+
|
46
56
|
it 'can handle double quotes within embedded expression' do
|
47
57
|
src = ['"#{"A"}"']
|
48
58
|
inspect_source(cop, src)
|
@@ -105,6 +105,19 @@ module Rubocop
|
|
105
105
|
expect(symbol_name.offences).to be_empty
|
106
106
|
end
|
107
107
|
|
108
|
+
it 'accepts non snake case arguments to private_constant' do
|
109
|
+
inspect_source(symbol_name,
|
110
|
+
['private_constant :NORMAL_MODE, :ADMIN_MODE'])
|
111
|
+
expect(symbol_name.offences).to be_empty
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'registers an offence for non snake case symbol near ' +
|
115
|
+
'private_constant' do
|
116
|
+
inspect_source(symbol_name,
|
117
|
+
['private_constant f(:ADMIN_MODE)'])
|
118
|
+
expect(symbol_name.offences.size).to eq(1)
|
119
|
+
end
|
120
|
+
|
108
121
|
it 'can handle an alias of and operator without crashing' do
|
109
122
|
inspect_source(symbol_name,
|
110
123
|
['alias + add'])
|
@@ -6,8 +6,10 @@ module Rubocop
|
|
6
6
|
module Cop
|
7
7
|
module Style
|
8
8
|
describe TrivialAccessors do
|
9
|
-
|
10
|
-
|
9
|
+
subject(:cop) { described_class.new }
|
10
|
+
before do
|
11
|
+
described_class.config = {}
|
12
|
+
end
|
11
13
|
|
12
14
|
it 'finds trivial reader' do
|
13
15
|
inspect_source(cop,
|
@@ -346,7 +348,7 @@ module Rubocop
|
|
346
348
|
end
|
347
349
|
|
348
350
|
context 'exact name match required' do
|
349
|
-
before {
|
351
|
+
before { described_class.config['ExactNameMatch'] = true }
|
350
352
|
|
351
353
|
it 'finds only 1 trivial reader' do
|
352
354
|
inspect_source(cop,
|
@@ -390,6 +392,29 @@ module Rubocop
|
|
390
392
|
expect(cop.offences).to be_empty
|
391
393
|
end
|
392
394
|
end
|
395
|
+
|
396
|
+
context 'with whitelist defined' do
|
397
|
+
before do
|
398
|
+
described_class.config = {
|
399
|
+
'Whitelist' => ['to_foo', 'bar=']
|
400
|
+
}
|
401
|
+
end
|
402
|
+
|
403
|
+
it 'ignores accessors in the whitelist' do
|
404
|
+
inspect_source(cop,
|
405
|
+
[' def to_foo',
|
406
|
+
' @foo',
|
407
|
+
' end'])
|
408
|
+
expect(cop.offences).to be_empty
|
409
|
+
end
|
410
|
+
it 'ignores writers in the whitelist' do
|
411
|
+
inspect_source(cop,
|
412
|
+
[' def bar=(bar)',
|
413
|
+
' @bar = bar',
|
414
|
+
' end'])
|
415
|
+
expect(cop.offences).to be_empty
|
416
|
+
end
|
417
|
+
end
|
393
418
|
end
|
394
419
|
end
|
395
420
|
end
|
@@ -247,39 +247,39 @@ module Rubocop
|
|
247
247
|
end
|
248
248
|
|
249
249
|
describe NodeScanner do
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
def some_method
|
256
|
-
baz = 3.to_s
|
257
|
-
end
|
258
|
-
end
|
259
|
-
END
|
260
|
-
end
|
250
|
+
describe '.scan_nodes_in_scope' do
|
251
|
+
let(:ast) do
|
252
|
+
processed_source = Rubocop::SourceParser.parse(source)
|
253
|
+
processed_source.ast
|
254
|
+
end
|
261
255
|
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
256
|
+
let(:source) do
|
257
|
+
<<-END
|
258
|
+
class SomeClass
|
259
|
+
foo = 1.to_s
|
260
|
+
bar = 2.to_s
|
261
|
+
def some_method
|
262
|
+
baz = 3.to_s
|
263
|
+
end
|
264
|
+
end
|
265
|
+
END
|
266
|
+
end
|
266
267
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
268
|
+
# (class
|
269
|
+
# (const nil :SomeClass) nil
|
270
|
+
# (begin
|
271
|
+
# (lvasgn :foo
|
272
|
+
# (send
|
273
|
+
# (int 1) :to_s))
|
274
|
+
# (lvasgn :bar
|
275
|
+
# (send
|
276
|
+
# (int 2) :to_s))
|
277
|
+
# (def :some_method
|
278
|
+
# (args)
|
279
|
+
# (lvasgn :baz
|
280
|
+
# (send
|
281
|
+
# (int 3) :to_s)))))
|
281
282
|
|
282
|
-
describe '.scan_nodes_in_scope' do
|
283
283
|
it 'does not scan children of inner scope node' do
|
284
284
|
scanned_node_count = 0
|
285
285
|
|
@@ -316,15 +316,196 @@ module Rubocop
|
|
316
316
|
expect(index).not_to eq(0)
|
317
317
|
end
|
318
318
|
|
319
|
-
|
320
|
-
|
319
|
+
let(:trace) { [] }
|
320
|
+
|
321
|
+
before do
|
322
|
+
NodeScanner.scan_nodes_in_scope(ast) do |node|
|
323
|
+
short_info = node.type.to_s
|
324
|
+
node.children.each do |child|
|
325
|
+
break if child.is_a?(Parser::AST::Node)
|
326
|
+
short_info << " #{child.inspect}"
|
327
|
+
end
|
328
|
+
trace << short_info
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
context 'when invoking a method ' +
|
333
|
+
'which is taking block and normal arguments' do
|
334
|
+
let(:source) do
|
335
|
+
<<-END
|
336
|
+
some_method(foo = 1) do |block_arg|
|
337
|
+
content_of_block = 2
|
338
|
+
end
|
339
|
+
puts foo
|
340
|
+
END
|
341
|
+
end
|
342
|
+
|
343
|
+
# (begin
|
344
|
+
# (block
|
345
|
+
# (send nil :some_method
|
346
|
+
# (lvasgn :foo
|
347
|
+
# (int 1)))
|
348
|
+
# (args
|
349
|
+
# (arg :block_arg))
|
350
|
+
# (lvasgn :content_of_block
|
351
|
+
# (int 2)))
|
352
|
+
# (send nil :puts
|
353
|
+
# (lvar :foo)))
|
354
|
+
|
355
|
+
it 'scans the method node and its normal argument nodes' do
|
356
|
+
expect(trace).to eq([
|
357
|
+
'block',
|
358
|
+
'send nil :some_method',
|
359
|
+
'lvasgn :foo',
|
360
|
+
'int 1',
|
361
|
+
'send nil :puts',
|
362
|
+
'lvar :foo'
|
363
|
+
])
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
context 'when opening singleton class of an instance' do
|
368
|
+
let(:source) do
|
369
|
+
<<-END
|
370
|
+
instance = Object.new
|
371
|
+
class << instance
|
372
|
+
content_of_singleton_class = 1
|
373
|
+
end
|
374
|
+
p instance
|
375
|
+
END
|
376
|
+
end
|
377
|
+
|
378
|
+
# (begin
|
379
|
+
# (lvasgn :instance
|
380
|
+
# (send
|
381
|
+
# (const nil :Object) :new))
|
382
|
+
# (sclass
|
383
|
+
# (lvar :instance)
|
384
|
+
# (lvasgn :content_of_singleton_class
|
385
|
+
# (int 1)))
|
386
|
+
# (send nil :p
|
387
|
+
# (lvar :instance)))
|
388
|
+
|
389
|
+
it 'scans the subject instance node' do
|
390
|
+
expect(trace).to eq([
|
391
|
+
'lvasgn :instance',
|
392
|
+
'send',
|
393
|
+
'const nil :Object',
|
394
|
+
'sclass',
|
395
|
+
'lvar :instance',
|
396
|
+
'send nil :p',
|
397
|
+
'lvar :instance'
|
398
|
+
])
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
context 'when defining singleton method' do
|
403
|
+
let(:source) do
|
404
|
+
<<-END
|
405
|
+
instance = Object.new
|
406
|
+
def instance.some_method(method_arg)
|
407
|
+
content_of_method = 2
|
408
|
+
end
|
409
|
+
p instance
|
410
|
+
END
|
411
|
+
end
|
412
|
+
|
413
|
+
# (begin
|
414
|
+
# (lvasgn :instance
|
415
|
+
# (send
|
416
|
+
# (const nil :Object) :new))
|
417
|
+
# (defs
|
418
|
+
# (lvar :instance) :some_method
|
419
|
+
# (args
|
420
|
+
# (arg :method_arg))
|
421
|
+
# (lvasgn :content_of_method
|
422
|
+
# (int 2)))
|
423
|
+
# (send nil :p
|
424
|
+
# (lvar :instance)))
|
425
|
+
|
426
|
+
it 'scans the subject instance node' do
|
427
|
+
expect(trace).to eq([
|
428
|
+
'lvasgn :instance',
|
429
|
+
'send',
|
430
|
+
'const nil :Object',
|
431
|
+
'defs',
|
432
|
+
'lvar :instance',
|
433
|
+
'send nil :p',
|
434
|
+
'lvar :instance'
|
435
|
+
])
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
context 'when scanning around post while loop' do
|
440
|
+
let(:source) do
|
441
|
+
<<-END
|
442
|
+
begin
|
443
|
+
foo = 1
|
444
|
+
end while foo > 10
|
445
|
+
puts foo
|
446
|
+
END
|
447
|
+
end
|
321
448
|
|
322
|
-
|
323
|
-
|
324
|
-
|
449
|
+
# (begin
|
450
|
+
# (while-post
|
451
|
+
# (send
|
452
|
+
# (lvar :foo) :>
|
453
|
+
# (int 10))
|
454
|
+
# (kwbegin
|
455
|
+
# (lvasgn :foo
|
456
|
+
# (int 1))))
|
457
|
+
# (send nil :puts
|
458
|
+
# (lvar :foo)))
|
459
|
+
|
460
|
+
it 'scans loop body nodes first then condition nodes' do
|
461
|
+
expect(trace).to eq([
|
462
|
+
'while_post',
|
463
|
+
'kwbegin',
|
464
|
+
'lvasgn :foo',
|
465
|
+
'int 1',
|
466
|
+
'send',
|
467
|
+
'lvar :foo',
|
468
|
+
'int 10',
|
469
|
+
'send nil :puts',
|
470
|
+
'lvar :foo'
|
471
|
+
])
|
325
472
|
end
|
473
|
+
end
|
326
474
|
|
327
|
-
|
475
|
+
context 'when scanning around post until loop' do
|
476
|
+
let(:source) do
|
477
|
+
<<-END
|
478
|
+
begin
|
479
|
+
foo = 1
|
480
|
+
end until foo < 10
|
481
|
+
puts foo
|
482
|
+
END
|
483
|
+
end
|
484
|
+
|
485
|
+
# (begin
|
486
|
+
# (until-post
|
487
|
+
# (send
|
488
|
+
# (lvar :foo) :<
|
489
|
+
# (int 10))
|
490
|
+
# (kwbegin
|
491
|
+
# (lvasgn :foo
|
492
|
+
# (int 1))))
|
493
|
+
# (send nil :puts
|
494
|
+
# (lvar :foo)))
|
495
|
+
|
496
|
+
it 'scans loop body nodes first then condition nodes' do
|
497
|
+
expect(trace).to eq([
|
498
|
+
'until_post',
|
499
|
+
'kwbegin',
|
500
|
+
'lvasgn :foo',
|
501
|
+
'int 1',
|
502
|
+
'send',
|
503
|
+
'lvar :foo',
|
504
|
+
'int 10',
|
505
|
+
'send nil :puts',
|
506
|
+
'lvar :foo'
|
507
|
+
])
|
508
|
+
end
|
328
509
|
end
|
329
510
|
end
|
330
511
|
end
|