1begin
2  require_relative 'dummyparser'
3  require_relative '../ruby/envutil'
4  require 'test/unit'
5  ripper_test = true
6  module TestRipper; end
7rescue LoadError
8end
9
10class TestRipper::ParserEvents < Test::Unit::TestCase
11
12  # should be enabled
13  def test_event_coverage
14    dispatched = Ripper::PARSER_EVENTS.map {|event,*| event }
15    dispatched.each do |e|
16      assert_equal true, respond_to?("test_#{e}", true),
17                   "event not tested: #{e.inspect}"
18    end
19  end
20
21  def parse(str, nm = nil, &bl)
22    dp = DummyParser.new(str)
23    dp.hook(*nm, &bl) if nm
24    dp.parse.to_s
25  end
26
27  def compile_error(str)
28    parse(str, :compile_error) {|e, msg| return msg}
29  end
30
31  def test_program
32    thru_program = false
33    assert_equal '[void()]', parse('', :on_program) {thru_program = true}
34    assert_equal true, thru_program
35  end
36
37  def test_stmts_new
38    assert_equal '[void()]', parse('')
39  end
40
41  def test_stmts_add
42    assert_equal '[ref(nil)]', parse('nil')
43    assert_equal '[ref(nil),ref(nil)]', parse('nil;nil')
44    assert_equal '[ref(nil),ref(nil),ref(nil)]', parse('nil;nil;nil')
45  end
46
47  def test_void_stmt
48    assert_equal '[void()]', parse('')
49    assert_equal '[void()]', parse('; ;')
50  end
51
52  def test_var_ref
53    assert_equal '[assign(var_field(a),ref(a))]', parse('a=a')
54    assert_equal '[ref(nil)]', parse('nil')
55    assert_equal '[ref(true)]', parse('true')
56  end
57
58  def test_vcall
59    assert_equal '[vcall(a)]', parse('a')
60  end
61
62  def test_BEGIN
63    assert_equal '[BEGIN([void()])]', parse('BEGIN{}')
64    assert_equal '[BEGIN([ref(nil)])]', parse('BEGIN{nil}')
65  end
66
67  def test_END
68    assert_equal '[END([void()])]', parse('END{}')
69    assert_equal '[END([ref(nil)])]', parse('END{nil}')
70  end
71
72  def test_alias
73    assert_equal '[alias(symbol_literal(a),symbol_literal(b))]', parse('alias a b')
74  end
75
76  def test_var_alias
77    assert_equal '[valias($a,$g)]', parse('alias $a $g')
78  end
79
80  def test_alias_error
81    assert_equal '[aliaserr(valias($a,$1))]', parse('alias $a $1')
82  end
83
84  def test_arglist
85    assert_equal '[fcall(m,[])]', parse('m()')
86    assert_equal '[fcall(m,[1])]', parse('m(1)')
87    assert_equal '[fcall(m,[1,2])]', parse('m(1,2)')
88    assert_equal '[fcall(m,[*vcall(r)])]', parse('m(*r)')
89    assert_equal '[fcall(m,[1,*vcall(r)])]', parse('m(1,*r)')
90    assert_equal '[fcall(m,[1,2,*vcall(r)])]', parse('m(1,2,*r)')
91    assert_equal '[fcall(m,[&vcall(r)])]', parse('m(&r)')
92    assert_equal '[fcall(m,[1,&vcall(r)])]', parse('m(1,&r)')
93    assert_equal '[fcall(m,[1,2,&vcall(r)])]', parse('m(1,2,&r)')
94    assert_equal '[fcall(m,[*vcall(a),&vcall(b)])]', parse('m(*a,&b)')
95    assert_equal '[fcall(m,[1,*vcall(a),&vcall(b)])]', parse('m(1,*a,&b)')
96    assert_equal '[fcall(m,[1,2,*vcall(a),&vcall(b)])]', parse('m(1,2,*a,&b)')
97  end
98
99  def test_args_add
100    thru_args_add = false
101    parse('m(a)', :on_args_add) {thru_args_add = true}
102    assert_equal true, thru_args_add
103  end
104
105  def test_args_add_block
106    thru_args_add_block = false
107    parse('m(&b)', :on_args_add_block) {thru_args_add_block = true}
108    assert_equal true, thru_args_add_block
109  end
110
111  def test_args_add_star
112    thru_args_add_star = false
113    parse('m(*a)', :on_args_add_star) {thru_args_add_star = true}
114    assert_equal true, thru_args_add_star
115    thru_args_add_star = false
116    parse('m(*a, &b)', :on_args_add_star) {thru_args_add_star = true}
117    assert_equal true, thru_args_add_star
118  end
119
120  def test_args_new
121    thru_args_new = false
122    parse('m()', :on_args_new) {thru_args_new = true}
123    assert_equal true, thru_args_new
124  end
125
126  def test_arg_paren
127    # FIXME
128  end
129
130  def test_aref
131    assert_equal '[aref(vcall(v),[1])]', parse('v[1]')
132    assert_equal '[aref(vcall(v),[1,2])]', parse('v[1,2]')
133  end
134
135  def test_assoclist_from_args
136    thru_assoclist_from_args = false
137    parse('{a=>b}', :on_assoclist_from_args) {thru_assoclist_from_args = true}
138    assert_equal true, thru_assoclist_from_args
139  end
140
141  def test_assocs
142    assert_equal '[fcall(m,[assocs(assoc(1,2))])]', parse('m(1=>2)')
143    assert_equal '[fcall(m,[assocs(assoc(1,2),assoc(3,4))])]', parse('m(1=>2,3=>4)')
144    assert_equal '[fcall(m,[3,assocs(assoc(1,2))])]', parse('m(3,1=>2)')
145  end
146
147  def test_assoc_new
148    thru_assoc_new = false
149    parse('{a=>b}', :on_assoc_new) {thru_assoc_new = true}
150    assert_equal true, thru_assoc_new
151  end
152
153  def test_assoc_splat
154    thru_assoc_splat = false
155    parse('m(**h)', :on_assoc_splat) {thru_assoc_splat = true}
156    assert_equal true, thru_assoc_splat
157  end
158
159  def test_aref_field
160    assert_equal '[assign(aref_field(vcall(a),[1]),2)]', parse('a[1]=2')
161  end
162
163  def test_arg_ambiguous
164    thru_arg_ambiguous = false
165    parse('m //', :on_arg_ambiguous) {thru_arg_ambiguous = true}
166    assert_equal true, thru_arg_ambiguous
167  end
168
169  def test_operator_ambiguous
170    thru_operator_ambiguous = false
171    parse('a=1; a %[]', :on_operator_ambiguous) {thru_operator_ambiguous = true}
172    assert_equal true, thru_operator_ambiguous
173  end
174
175  def test_array   # array literal
176    assert_equal '[array([1,2,3])]', parse('[1,2,3]')
177    assert_equal '[array([abc,def])]', parse('%w[abc def]')
178    assert_equal '[array([abc,def])]', parse('%W[abc def]')
179  end
180
181  def test_assign   # generic assignment
182    assert_equal '[assign(var_field(v),1)]', parse('v=1')
183  end
184
185  def test_assign_error
186    thru_assign_error = false
187    parse('$` = 1', :on_assign_error) {thru_assign_error = true}
188    assert_equal true, thru_assign_error
189    thru_assign_error = false
190    parse('$`, _ = 1', :on_assign_error) {thru_assign_error = true}
191    assert_equal true, thru_assign_error
192
193    thru_assign_error = false
194    parse('self::X = 1', :on_assign_error) {thru_assign_error = true}
195    assert_equal false, thru_assign_error
196    parse('def m\n self::X = 1\nend', :on_assign_error) {thru_assign_error = true}
197    assert_equal true, thru_assign_error
198
199    thru_assign_error = false
200    parse('X = 1', :on_assign_error) {thru_assign_error = true}
201    assert_equal false, thru_assign_error
202    parse('def m\n X = 1\nend', :on_assign_error) {thru_assign_error = true}
203    assert_equal true, thru_assign_error
204
205    thru_assign_error = false
206    parse('::X = 1', :on_assign_error) {thru_assign_error = true}
207    assert_equal false, thru_assign_error
208    parse('def m\n ::X = 1\nend', :on_assign_error) {thru_assign_error = true}
209    assert_equal true, thru_assign_error
210  end
211
212  def test_bare_assoc_hash
213    thru_bare_assoc_hash = false
214    parse('x[a=>b]', :on_bare_assoc_hash) {thru_bare_assoc_hash = true}
215    assert_equal true, thru_bare_assoc_hash
216    thru_bare_assoc_hash = false
217    parse('x[1, a=>b]', :on_bare_assoc_hash) {thru_bare_assoc_hash = true}
218    assert_equal true, thru_bare_assoc_hash
219    thru_bare_assoc_hash = false
220    parse('x(a=>b)', :on_bare_assoc_hash) {thru_bare_assoc_hash = true}
221    assert_equal true, thru_bare_assoc_hash
222    thru_bare_assoc_hash = false
223    parse('x(1, a=>b)', :on_bare_assoc_hash) {thru_bare_assoc_hash = true}
224    assert_equal true, thru_bare_assoc_hash
225  end
226
227  def test_begin
228    thru_begin = false
229    parse('begin end', :on_begin) {thru_begin = true}
230    assert_equal true, thru_begin
231  end
232
233  def test_binary
234    thru_binary = nil
235    %w"and or + - * / % ** | ^ & <=> > >= < <= == === != =~ !~ << >> && ||".each do |op|
236      thru_binary = false
237      parse("a #{op} b", :on_binary) {thru_binary = true}
238      assert_equal true, thru_binary
239    end
240  end
241
242  def test_blockarg
243    thru_blockarg = false
244    parse("def a(&b) end", :on_blockarg) {thru_blockarg = true}
245    assert_equal true, thru_blockarg
246    thru_blockarg = false
247    parse("def a(x, &b) end", :on_blockarg) {thru_blockarg = true}
248    assert_equal true, thru_blockarg
249
250    thru_blockarg = false
251    parse("proc{|&b|}", :on_blockarg) {thru_blockarg = true}
252    assert_equal true, thru_blockarg
253    thru_blockarg = false
254    parse("proc{|x, &b|}", :on_blockarg) {thru_blockarg = true}
255    assert_equal true, thru_blockarg
256    thru_blockarg = false
257    parse("proc{|&b;y|}", :on_blockarg) {thru_blockarg = true}
258    assert_equal true, thru_blockarg
259    thru_blockarg = false
260    parse("proc{|&b,x;y|}", :on_blockarg) {thru_blockarg = true}
261    assert_equal true, thru_blockarg
262
263    thru_blockarg = false
264    parse("proc do |&b| end", :on_blockarg) {thru_blockarg = true}
265    assert_equal true, thru_blockarg
266    thru_blockarg = false
267    parse("proc do |&b, x| end", :on_blockarg) {thru_blockarg = true}
268    assert_equal true, thru_blockarg
269    thru_blockarg = false
270    parse("proc do |&b;y| end", :on_blockarg) {thru_blockarg = true}
271    assert_equal true, thru_blockarg
272    thru_blockarg = false
273    parse("proc do |&b, x;y| end", :on_blockarg) {thru_blockarg = true}
274    assert_equal true, thru_blockarg
275  end
276
277  def test_block_var
278    thru_block_var = false
279    parse("proc{||}", :on_block_var) {thru_block_var = true}
280    assert_equal true, thru_block_var
281    thru_block_var = false
282    parse("proc{| |}", :on_block_var) {thru_block_var = true}
283    assert_equal true, thru_block_var
284    thru_block_var = false
285    parse("proc{|x|}", :on_block_var) {thru_block_var = true}
286    assert_equal true, thru_block_var
287    thru_block_var = false
288    parse("proc{|;y|}", :on_block_var) {thru_block_var = true}
289    assert_equal true, thru_block_var
290    thru_block_var = false
291    parse("proc{|x;y|}", :on_block_var) {thru_block_var = true}
292    assert_equal true, thru_block_var
293
294    thru_block_var = false
295    parse("proc do || end", :on_block_var) {thru_block_var = true}
296    assert_equal true, thru_block_var
297    thru_block_var = false
298    parse("proc do | | end", :on_block_var) {thru_block_var = true}
299    assert_equal true, thru_block_var
300    thru_block_var = false
301    parse("proc do |x| end", :on_block_var) {thru_block_var = true}
302    assert_equal true, thru_block_var
303    thru_block_var = false
304    parse("proc do |;y| end", :on_block_var) {thru_block_var = true}
305    assert_equal true, thru_block_var
306    thru_block_var = false
307    parse("proc do |x;y| end", :on_block_var) {thru_block_var = true}
308    assert_equal true, thru_block_var
309  end
310
311  def test_block_var_add_block
312    # not used
313  end
314
315  def test_block_var_add_star
316    # not used
317  end
318
319  def test_bodystmt
320    thru_bodystmt = false
321    parse("class X\nend", :on_bodystmt) {thru_bodystmt = true}
322    assert_equal true, thru_bodystmt
323  end
324
325  def test_call
326    bug2233 = '[ruby-core:26165]'
327    tree = nil
328
329    thru_call = false
330    assert_nothing_raised {
331      tree = parse("self.foo", :on_call) {thru_call = true}
332    }
333    assert_equal true, thru_call
334    assert_equal "[call(ref(self),.,foo)]", tree
335    thru_call = false
336    assert_nothing_raised(bug2233) {
337      tree = parse("foo.()", :on_call) {thru_call = true}
338    }
339    assert_equal true, thru_call
340    assert_equal "[call(vcall(foo),.,call,[])]", tree
341  end
342
343  def test_excessed_comma
344    thru_excessed_comma = false
345    parse("proc{|x,|}", :on_excessed_comma) {thru_excessed_comma = true}
346    assert_equal true, thru_excessed_comma
347    thru_excessed_comma = false
348    parse("proc{|x,y,|}", :on_excessed_comma) {thru_excessed_comma = true}
349    assert_equal true, thru_excessed_comma
350
351    thru_excessed_comma = false
352    parse("proc do |x,| end", :on_excessed_comma) {thru_excessed_comma = true}
353    assert_equal true, thru_excessed_comma
354    thru_excessed_comma = false
355    parse("proc do |x,y,| end", :on_excessed_comma) {thru_excessed_comma = true}
356    assert_equal true, thru_excessed_comma
357  end
358
359  def test_heredoc
360    bug1921 = '[ruby-core:24855]'
361    thru_heredoc_beg = false
362    tree = parse("<""<EOS\nheredoc\nEOS\n", :on_heredoc_beg) {thru_heredoc_beg = true}
363    assert_equal true, thru_heredoc_beg
364    assert_match(/string_content\(\),heredoc\n/, tree, bug1921)
365    heredoc = nil
366    parse("<""<EOS\nheredoc1\nheredoc2\nEOS\n", :on_string_add) {|e, n, s| heredoc = s}
367    assert_equal("heredoc1\nheredoc2\n", heredoc, bug1921)
368    heredoc = nil
369    parse("<""<-EOS\nheredoc1\nheredoc2\n\tEOS\n", :on_string_add) {|e, n, s| heredoc = s}
370    assert_equal("heredoc1\nheredoc2\n", heredoc, bug1921)
371  end
372
373  def test_massign
374    thru_massign = false
375    parse("a, b = 1, 2", :on_massign) {thru_massign = true}
376    assert_equal true, thru_massign
377  end
378
379  def test_mlhs_add
380    thru_mlhs_add = false
381    parse("a, b = 1, 2", :on_mlhs_add) {thru_mlhs_add = true}
382    assert_equal true, thru_mlhs_add
383  end
384
385  def test_mlhs_add_star
386    bug2232 = '[ruby-core:26163]'
387    bug4364 = '[ruby-core:35078]'
388
389    thru_mlhs_add_star = false
390    tree = parse("a, *b = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true}
391    assert_equal true, thru_mlhs_add_star
392    assert_match(/mlhs_add_star\(mlhs_add\(mlhs_new\(\),a\),b\)/, tree)
393    thru_mlhs_add_star = false
394    tree = parse("a, *b, c = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true}
395    assert_equal true, thru_mlhs_add_star
396    assert_match(/mlhs_add\(mlhs_add_star\(mlhs_add\(mlhs_new\(\),a\),b\),mlhs_add\(mlhs_new\(\),c\)\)/, tree, bug2232)
397    thru_mlhs_add_star = false
398    tree = parse("a, *, c = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true}
399    assert_equal true, thru_mlhs_add_star
400    assert_match(/mlhs_add\(mlhs_add_star\(mlhs_add\(mlhs_new\(\),a\)\),mlhs_add\(mlhs_new\(\),c\)\)/, tree, bug4364)
401    thru_mlhs_add_star = false
402    tree = parse("*b, c = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true}
403    assert_equal true, thru_mlhs_add_star
404    assert_match(/mlhs_add\(mlhs_add_star\(mlhs_new\(\),b\),mlhs_add\(mlhs_new\(\),c\)\)/, tree, bug4364)
405    thru_mlhs_add_star = false
406    tree = parse("*, c = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true}
407    assert_equal true, thru_mlhs_add_star
408    assert_match(/mlhs_add\(mlhs_add_star\(mlhs_new\(\)\),mlhs_add\(mlhs_new\(\),c\)\)/, tree, bug4364)
409  end
410
411  def test_mlhs_new
412    thru_mlhs_new = false
413    parse("a, b = 1, 2", :on_mlhs_new) {thru_mlhs_new = true}
414    assert_equal true, thru_mlhs_new
415  end
416
417  def test_mlhs_paren
418    thru_mlhs_paren = false
419    parse("a, b = 1, 2", :on_mlhs_paren) {thru_mlhs_paren = true}
420    assert_equal false, thru_mlhs_paren
421    thru_mlhs_paren = false
422    parse("(a, b) = 1, 2", :on_mlhs_paren) {thru_mlhs_paren = true}
423    assert_equal true, thru_mlhs_paren
424  end
425
426  def test_brace_block
427    thru_brace_block = false
428    parse('proc {}', :on_brace_block) {thru_brace_block = true}
429    assert_equal true, thru_brace_block
430  end
431
432  def test_break
433    thru_break = false
434    parse('proc {break}', :on_break) {thru_break = true}
435    assert_equal true, thru_break
436  end
437
438  def test_case
439    thru_case = false
440    parse('case foo when true; end', :on_case) {thru_case = true}
441    assert_equal true, thru_case
442  end
443
444  def test_class
445    thru_class = false
446    parse('class Foo; end', :on_class) {thru_class = true}
447    assert_equal true, thru_class
448  end
449
450  def test_class_name_error
451    thru_class_name_error = false
452    parse('class foo; end', :on_class_name_error) {thru_class_name_error = true}
453    assert_equal true, thru_class_name_error
454  end
455
456  def test_command
457    thru_command = false
458    parse('foo a b', :on_command) {thru_command = true}
459    assert_equal true, thru_command
460  end
461
462  def test_command_call
463    thru_command_call = false
464    parse('foo.bar a, b', :on_command_call) {thru_command_call = true}
465    assert_equal true, thru_command_call
466  end
467
468  def test_const_ref
469    thru_const_ref = false
470    parse('class A;end', :on_const_ref) {thru_const_ref = true}
471    assert_equal true, thru_const_ref
472    thru_const_ref = false
473    parse('module A;end', :on_const_ref) {thru_const_ref = true}
474    assert_equal true, thru_const_ref
475  end
476
477  def test_const_path_field
478    thru_const_path_field = false
479    parse('foo::X = 1', :on_const_path_field) {thru_const_path_field = true}
480    assert_equal true, thru_const_path_field
481  end
482
483  def test_const_path_ref
484    thru_const_path_ref = false
485    parse('foo::X', :on_const_path_ref) {thru_const_path_ref = true}
486    assert_equal true, thru_const_path_ref
487  end
488
489  def test_def
490    thru_def = false
491    parse('def foo; end', :on_def) {
492      thru_def = true
493    }
494    assert_equal true, thru_def
495    assert_equal '[def(foo,[],bodystmt([void()]))]', parse('def foo ;end')
496  end
497
498  def test_defined
499    thru_defined = false
500    parse('defined?(x)', :on_defined) {thru_defined = true}
501    assert_equal true, thru_defined
502  end
503
504  def test_defs
505    thru_defs = false
506    parse('def foo.bar; end', :on_defs) {thru_defs = true}
507    assert_equal true, thru_defs
508  end
509
510  def test_do_block
511    thru_do_block = false
512    parse('proc do end', :on_do_block) {thru_do_block = true}
513    assert_equal true, thru_do_block
514  end
515
516  def test_dot2
517    thru_dot2 = false
518    parse('a..b', :on_dot2) {thru_dot2 = true}
519    assert_equal true, thru_dot2
520  end
521
522  def test_dot3
523    thru_dot3 = false
524    parse('a...b', :on_dot3) {thru_dot3 = true}
525    assert_equal true, thru_dot3
526  end
527
528  def test_dyna_symbol
529    thru_dyna_symbol = false
530    parse(':"#{foo}"', :on_dyna_symbol) {thru_dyna_symbol = true}
531    assert_equal true, thru_dyna_symbol
532  end
533
534  def test_else
535    thru_else = false
536    parse('if foo; bar else zot end', :on_else) {thru_else = true}
537    assert_equal true, thru_else
538  end
539
540  def test_elsif
541    thru_elsif = false
542    parse('if foo; bar elsif qux; zot end', :on_elsif) {thru_elsif = true}
543    assert_equal true, thru_elsif
544  end
545
546  def test_ensure
547    thru_ensure = false
548    parse('begin foo ensure bar end', :on_ensure) {thru_ensure = true}
549    assert_equal true, thru_ensure
550  end
551
552  def test_fcall
553    thru_fcall = false
554    parse('foo()', :on_fcall) {thru_fcall = true}
555    assert_equal true, thru_fcall
556  end
557
558  def test_field
559    thru_field = false
560    parse('foo.x = 1', :on_field) {thru_field = true}
561    assert_equal true, thru_field
562  end
563
564  def test_for
565    thru_for = false
566    parse('for i in foo; end', :on_for) {thru_for = true}
567    assert_equal true, thru_for
568  end
569
570  def test_hash
571    thru_hash = false
572    parse('{1=>2}', :on_hash) {thru_hash = true}
573    assert_equal true, thru_hash
574    thru_hash = false
575    parse('{a: 2}', :on_hash) {thru_hash = true}
576    assert_equal true, thru_hash
577  end
578
579  def test_if
580    thru_if = false
581    parse('if false; end', :on_if) {thru_if = true}
582    assert_equal true, thru_if
583  end
584
585  def test_if_mod
586    thru_if_mod = false
587    parse('nil if nil', :on_if_mod) {thru_if_mod = true}
588    assert_equal true, thru_if_mod
589  end
590
591  def test_ifop
592    thru_ifop = false
593    parse('a ? b : c', :on_ifop) {thru_ifop = true}
594    assert_equal true, thru_ifop
595  end
596
597  def test_lambda
598    thru_lambda = false
599    parse('->{}', :on_lambda) {thru_lambda = true}
600    assert_equal true, thru_lambda
601  end
602
603  def test_magic_comment
604    thru_magic_comment = false
605    parse('# -*- bug-5753: ruby-dev:44984 -*-', :on_magic_comment) {|*x|thru_magic_comment = x}
606    assert_equal [:on_magic_comment, "bug_5753", "ruby-dev:44984"], thru_magic_comment
607  end
608
609  def test_method_add_block
610    thru_method_add_block = false
611    parse('a {}', :on_method_add_block) {thru_method_add_block = true}
612    assert_equal true, thru_method_add_block
613    thru_method_add_block = false
614    parse('a do end', :on_method_add_block) {thru_method_add_block = true}
615    assert_equal true, thru_method_add_block
616  end
617
618  def test_method_add_arg
619    thru_method_add_arg = false
620    parse('a()', :on_method_add_arg) {thru_method_add_arg = true}
621    assert_equal true, thru_method_add_arg
622    thru_method_add_arg = false
623    parse('a {}', :on_method_add_arg) {thru_method_add_arg = true}
624    assert_equal true, thru_method_add_arg
625    thru_method_add_arg = false
626    parse('a.b(1)', :on_method_add_arg) {thru_method_add_arg = true}
627    assert_equal true, thru_method_add_arg
628    thru_method_add_arg = false
629    parse('a::b(1)', :on_method_add_arg) {thru_method_add_arg = true}
630    assert_equal true, thru_method_add_arg
631  end
632
633  def test_module
634    thru_module = false
635    parse('module A; end', :on_module) {thru_module = true}
636    assert_equal true, thru_module
637  end
638
639  def test_mrhs_add
640    thru_mrhs_add = false
641    parse('a = a, b', :on_mrhs_add) {thru_mrhs_add = true}
642    assert_equal true, thru_mrhs_add
643  end
644
645  def test_mrhs_add_star
646    thru_mrhs_add_star = false
647    parse('a = a, *b', :on_mrhs_add_star) {thru_mrhs_add_star = true}
648    assert_equal true, thru_mrhs_add_star
649  end
650
651  def test_mrhs_new
652    thru_mrhs_new = false
653    parse('a = *a', :on_mrhs_new) {thru_mrhs_new = true}
654    assert_equal true, thru_mrhs_new
655  end
656
657  def test_mrhs_new_from_args
658    thru_mrhs_new_from_args = false
659    parse('a = a, b', :on_mrhs_new_from_args) {thru_mrhs_new_from_args = true}
660    assert_equal true, thru_mrhs_new_from_args
661  end
662
663  def test_next
664    thru_next = false
665    parse('a {next}', :on_next) {thru_next = true}
666    assert_equal true, thru_next
667  end
668
669  def test_opassign
670    thru_opassign = false
671    parse('a += b', :on_opassign) {thru_opassign = true}
672    assert_equal true, thru_opassign
673    thru_opassign = false
674    parse('a -= b', :on_opassign) {thru_opassign = true}
675    assert_equal true, thru_opassign
676    thru_opassign = false
677    parse('a *= b', :on_opassign) {thru_opassign = true}
678    assert_equal true, thru_opassign
679    thru_opassign = false
680    parse('a /= b', :on_opassign) {thru_opassign = true}
681    assert_equal true, thru_opassign
682    thru_opassign = false
683    parse('a %= b', :on_opassign) {thru_opassign = true}
684    assert_equal true, thru_opassign
685    thru_opassign = false
686    parse('a **= b', :on_opassign) {thru_opassign = true}
687    assert_equal true, thru_opassign
688    thru_opassign = false
689    parse('a &= b', :on_opassign) {thru_opassign = true}
690    assert_equal true, thru_opassign
691    thru_opassign = false
692    parse('a |= b', :on_opassign) {thru_opassign = true}
693    assert_equal true, thru_opassign
694    thru_opassign = false
695    parse('a <<= b', :on_opassign) {thru_opassign = true}
696    assert_equal true, thru_opassign
697    thru_opassign = false
698    parse('a >>= b', :on_opassign) {thru_opassign = true}
699    assert_equal true, thru_opassign
700    thru_opassign = false
701    parse('a &&= b', :on_opassign) {thru_opassign = true}
702    assert_equal true, thru_opassign
703    thru_opassign = false
704    parse('a ||= b', :on_opassign) {thru_opassign = true}
705    assert_equal true, thru_opassign
706    thru_opassign = false
707    parse('a::X ||= c 1', :on_opassign) {thru_opassign = true}
708    assert_equal true, thru_opassign
709  end
710
711  def test_opassign_error
712    thru_opassign = []
713    events = [:on_opassign]
714    parse('$~ ||= 1', events) {|a,*b|
715      thru_opassign << a
716    }
717    assert_equal events, thru_opassign
718  end
719
720  def test_param_error
721    thru_param_error = false
722    parse('def foo(A) end', :on_param_error) {thru_param_error = true}
723    assert_equal true, thru_param_error
724    thru_param_error = false
725    parse('def foo($a) end', :on_param_error) {thru_param_error = true}
726    assert_equal true, thru_param_error
727    thru_param_error = false
728    parse('def foo(@a) end', :on_param_error) {thru_param_error = true}
729    assert_equal true, thru_param_error
730    thru_param_error = false
731    parse('def foo(@@a) end', :on_param_error) {thru_param_error = true}
732    assert_equal true, thru_param_error
733  end
734
735  def test_params
736    thru_params = false
737    parse('a {||}', :on_params) {thru_params = true}
738    assert_equal true, thru_params
739    thru_params = false
740    parse('a {|x|}', :on_params) {thru_params = true}
741    assert_equal true, thru_params
742    thru_params = false
743    parse('a {|*x|}', :on_params) {thru_params = true}
744    assert_equal true, thru_params
745  end
746
747  def test_paren
748    thru_paren = false
749    parse('()', :on_paren) {thru_paren = true}
750    assert_equal true, thru_paren
751  end
752
753  def test_parse_error
754    thru_parse_error = false
755    parse('<>', :on_parse_error) {thru_parse_error = true}
756    assert_equal true, thru_parse_error
757  end
758
759  def test_qwords_add
760    thru_qwords_add = false
761    parse('%w[a]', :on_qwords_add) {thru_qwords_add = true}
762    assert_equal true, thru_qwords_add
763  end
764
765  def test_qsymbols_add
766    thru_qsymbols_add = false
767    parse('%i[a]', :on_qsymbols_add) {thru_qsymbols_add = true}
768    assert_equal true, thru_qsymbols_add
769  end
770
771  def test_symbols_add
772    thru_symbols_add = false
773    parse('%I[a]', :on_symbols_add) {thru_symbols_add = true}
774    assert_equal true, thru_symbols_add
775  end
776
777  def test_qwords_new
778    thru_qwords_new = false
779    parse('%w[]', :on_qwords_new) {thru_qwords_new = true}
780    assert_equal true, thru_qwords_new
781  end
782
783  def test_qsymbols_new
784    thru_qsymbols_new = false
785    parse('%i[]', :on_qsymbols_new) {thru_qsymbols_new = true}
786    assert_equal true, thru_qsymbols_new
787  end
788
789  def test_symbols_new
790    thru_symbols_new = false
791    parse('%I[]', :on_symbols_new) {thru_symbols_new = true}
792    assert_equal true, thru_symbols_new
793  end
794
795  def test_redo
796    thru_redo = false
797    parse('redo', :on_redo) {thru_redo = true}
798    assert_equal true, thru_redo
799  end
800
801  def test_regexp_add
802    thru_regexp_add = false
803    parse('/foo/', :on_regexp_add) {thru_regexp_add = true}
804    assert_equal true, thru_regexp_add
805  end
806
807  def test_regexp_literal
808    thru_regexp_literal = false
809    parse('//', :on_regexp_literal) {thru_regexp_literal = true}
810    assert_equal true, thru_regexp_literal
811  end
812
813  def test_regexp_new
814    thru_regexp_new = false
815    parse('//', :on_regexp_new) {thru_regexp_new = true}
816    assert_equal true, thru_regexp_new
817  end
818
819  def test_rescue
820    thru_rescue = false
821    parsed = parse('begin; 1; rescue => e; 2; end', :on_rescue) {thru_rescue = true}
822    assert_equal true, thru_rescue
823    assert_match(/1.*rescue/, parsed)
824    assert_match(/rescue\(,var_field\(e\),\[2\]\)/, parsed)
825  end
826
827  def test_rescue_mod
828    thru_rescue_mod = false
829    parsed = parse('1 rescue 2', :on_rescue_mod) {thru_rescue_mod = true}
830    assert_equal true, thru_rescue_mod
831    bug4716 = '[ruby-core:36248]'
832    assert_equal "[rescue_mod(1,2)]", parsed, bug4716
833  end
834
835  def test_rest_param
836    thru_rest_param = false
837    parse('def a(*) end', :on_rest_param) {thru_rest_param = true}
838    assert_equal true, thru_rest_param
839    thru_rest_param = false
840    parse('def a(*x) end', :on_rest_param) {thru_rest_param = true}
841    assert_equal true, thru_rest_param
842  end
843
844  def test_retry
845    thru_retry = false
846    parse('retry', :on_retry) {thru_retry = true}
847    assert_equal true, thru_retry
848  end
849
850  def test_return
851    thru_return = false
852    parse('return a', :on_return) {thru_return = true}
853    assert_equal true, thru_return
854  end
855
856  def test_return0
857    thru_return0 = false
858    parse('return', :on_return0) {thru_return0 = true}
859    assert_equal true, thru_return0
860  end
861
862  def test_sclass
863    thru_sclass = false
864    parse('class << a; end', :on_sclass) {thru_sclass = true}
865    assert_equal true, thru_sclass
866  end
867
868  def test_string_add
869    thru_string_add = false
870    parse('"aa"', :on_string_add) {thru_string_add = true}
871    assert_equal true, thru_string_add
872  end
873
874  def test_string_concat
875    thru_string_concat = false
876    parse('"a" "b"', :on_string_concat) {thru_string_concat = true}
877    assert_equal true, thru_string_concat
878  end
879
880  def test_string_content
881    thru_string_content = false
882    parse('""', :on_string_content) {thru_string_content = true}
883    assert_equal true, thru_string_content
884    thru_string_content = false
885    parse('"a"', :on_string_content) {thru_string_content = true}
886    assert_equal true, thru_string_content
887    thru_string_content = false
888    parse('%[a]', :on_string_content) {thru_string_content = true}
889    assert_equal true, thru_string_content
890    thru_string_content = false
891    parse('\'a\'', :on_string_content) {thru_string_content = true}
892    assert_equal true, thru_string_content
893    thru_string_content = false
894    parse('%<a>', :on_string_content) {thru_string_content = true}
895    assert_equal true, thru_string_content
896    thru_string_content = false
897    parse('%!a!', :on_string_content) {thru_string_content = true}
898    assert_equal true, thru_string_content
899    thru_string_content = false
900    parse('%q!a!', :on_string_content) {thru_string_content = true}
901    assert_equal true, thru_string_content
902    thru_string_content = false
903    parse('%Q!a!', :on_string_content) {thru_string_content = true}
904    assert_equal true, thru_string_content
905  end
906
907  def test_string_dvar
908    thru_string_dvar = false
909    parse('"#$a"', :on_string_dvar) {thru_string_dvar = true}
910    assert_equal true, thru_string_dvar
911    thru_string_dvar = false
912    parse('\'#$a\'', :on_string_dvar) {thru_string_dvar = true}
913    assert_equal false, thru_string_dvar
914    thru_string_dvar = false
915    parse('"#@a"', :on_string_dvar) {thru_string_dvar = true}
916    assert_equal true, thru_string_dvar
917    thru_string_dvar = false
918    parse('\'#@a\'', :on_string_dvar) {thru_string_dvar = true}
919    assert_equal false, thru_string_dvar
920    thru_string_dvar = false
921    parse('"#@@a"', :on_string_dvar) {thru_string_dvar = true}
922    assert_equal true, thru_string_dvar
923    thru_string_dvar = false
924    parse('\'#@@a\'', :on_string_dvar) {thru_string_dvar = true}
925    assert_equal false, thru_string_dvar
926    thru_string_dvar = false
927    parse('"#$1"', :on_string_dvar) {thru_string_dvar = true}
928    assert_equal true, thru_string_dvar
929    thru_string_dvar = false
930    parse('\'#$1\'', :on_string_dvar) {thru_string_dvar = true}
931    assert_equal false, thru_string_dvar
932  end
933
934  def test_string_embexpr
935    thru_string_embexpr = false
936    parse('"#{}"', :on_string_embexpr) {thru_string_embexpr = true}
937    assert_equal true, thru_string_embexpr
938    thru_string_embexpr = false
939    parse('\'#{}\'', :on_string_embexpr) {thru_string_embexpr = true}
940    assert_equal false, thru_string_embexpr
941  end
942
943  def test_string_literal
944    thru_string_literal = false
945    parse('""', :on_string_literal) {thru_string_literal = true}
946    assert_equal true, thru_string_literal
947  end
948
949  def test_super
950    thru_super = false
951    parse('super()', :on_super) {thru_super = true}
952    assert_equal true, thru_super
953  end
954
955  def test_symbol
956    thru_symbol = false
957    parse(':a', :on_symbol) {thru_symbol = true}
958    assert_equal true, thru_symbol
959    thru_symbol = false
960    parse(':$a', :on_symbol) {thru_symbol = true}
961    assert_equal true, thru_symbol
962    thru_symbol = false
963    parse(':@a', :on_symbol) {thru_symbol = true}
964    assert_equal true, thru_symbol
965    thru_symbol = false
966    parse(':@@a', :on_symbol) {thru_symbol = true}
967    assert_equal true, thru_symbol
968    thru_symbol = false
969    parse(':==', :on_symbol) {thru_symbol = true}
970    assert_equal true, thru_symbol
971  end
972
973  def test_symbol_literal
974    thru_symbol_literal = false
975    parse(':a', :on_symbol_literal) {thru_symbol_literal = true}
976    assert_equal true, thru_symbol_literal
977  end
978
979  def test_top_const_field
980    thru_top_const_field = false
981    parse('::A=1', :on_top_const_field) {thru_top_const_field = true}
982    assert_equal true, thru_top_const_field
983  end
984
985  def test_top_const_ref
986    thru_top_const_ref = false
987    parse('::A', :on_top_const_ref) {thru_top_const_ref = true}
988    assert_equal true, thru_top_const_ref
989  end
990
991  def test_unary
992    thru_unary = false
993    parse('not a 1, 2', :on_unary) {thru_unary = true}
994    assert_equal true, thru_unary
995    thru_unary = false
996    parse('not (a)', :on_unary) {thru_unary = true}
997    assert_equal true, thru_unary
998    thru_unary = false
999    parse('!a', :on_unary) {thru_unary = true}
1000    assert_equal true, thru_unary
1001    thru_unary = false
1002    parse('-10', :on_unary) {thru_unary = true}
1003    assert_equal true, thru_unary
1004    thru_unary = false
1005    parse('-10*2', :on_unary) {thru_unary = true}
1006    assert_equal true, thru_unary
1007    thru_unary = false
1008    parse('-10.1', :on_unary) {thru_unary = true}
1009    assert_equal true, thru_unary
1010    thru_unary = false
1011    parse('-10.1*2', :on_unary) {thru_unary = true}
1012    assert_equal true, thru_unary
1013    thru_unary = false
1014    parse('-a', :on_unary) {thru_unary = true}
1015    assert_equal true, thru_unary
1016    thru_unary = false
1017    parse('+a', :on_unary) {thru_unary = true}
1018    assert_equal true, thru_unary
1019    thru_unary = false
1020    parse('~a', :on_unary) {thru_unary = true}
1021    assert_equal true, thru_unary
1022    thru_unary = false
1023    parse('not()', :on_unary) {thru_unary = true}
1024    assert_equal true, thru_unary
1025  end
1026
1027  def test_undef
1028    thru_undef = false
1029    parse('undef a', :on_undef) {thru_undef = true}
1030    assert_equal true, thru_undef
1031    thru_undef = false
1032    parse('undef <=>', :on_undef) {thru_undef = true}
1033    assert_equal true, thru_undef
1034    thru_undef = false
1035    parse('undef a, b', :on_undef) {thru_undef = true}
1036    assert_equal true, thru_undef
1037  end
1038
1039  def test_unless
1040    thru_unless = false
1041    parse('unless a; end', :on_unless) {thru_unless = true}
1042    assert_equal true, thru_unless
1043  end
1044
1045  def test_unless_mod
1046    thru_unless_mod = false
1047    parse('nil unless a', :on_unless_mod) {thru_unless_mod = true}
1048    assert_equal true, thru_unless_mod
1049  end
1050
1051  def test_until
1052    thru_until = false
1053    parse('until a; end', :on_until) {thru_until = true}
1054    assert_equal true, thru_until
1055  end
1056
1057  def test_until_mod
1058    thru_until_mod = false
1059    parse('nil until a', :on_until_mod) {thru_until_mod = true}
1060    assert_equal true, thru_until_mod
1061  end
1062
1063  def test_var_field
1064    thru_var_field = false
1065    parse('a = 1', :on_var_field) {thru_var_field = true}
1066    assert_equal true, thru_var_field
1067    thru_var_field = false
1068    parse('a += 1', :on_var_field) {thru_var_field = true}
1069    assert_equal true, thru_var_field
1070  end
1071
1072  def test_when
1073    thru_when = false
1074    parse('case a when b; end', :on_when) {thru_when = true}
1075    assert_equal true, thru_when
1076    thru_when = false
1077    parse('case when a; end', :on_when) {thru_when = true}
1078    assert_equal true, thru_when
1079  end
1080
1081  def test_while
1082    thru_while = false
1083    parse('while a; end', :on_while) {thru_while = true}
1084    assert_equal true, thru_while
1085  end
1086
1087  def test_while_mod
1088    thru_while_mod = false
1089    parse('nil while a', :on_while_mod) {thru_while_mod = true}
1090    assert_equal true, thru_while_mod
1091  end
1092
1093  def test_word_add
1094    thru_word_add = false
1095    parse('%W[a]', :on_word_add) {thru_word_add = true}
1096    assert_equal true, thru_word_add
1097  end
1098
1099  def test_word_new
1100    thru_word_new = false
1101    parse('%W[a]', :on_word_new) {thru_word_new = true}
1102    assert_equal true, thru_word_new
1103  end
1104
1105  def test_words_add
1106    thru_words_add = false
1107    parse('%W[a]', :on_words_add) {thru_words_add = true}
1108    assert_equal true, thru_words_add
1109  end
1110
1111  def test_words_new
1112    thru_words_new = false
1113    parse('%W[]', :on_words_new) {thru_words_new = true}
1114    assert_equal true, thru_words_new
1115  end
1116
1117  def test_xstring_add
1118    thru_xstring_add = false
1119    parse('`x`', :on_xstring_add) {thru_xstring_add = true}
1120    assert_equal true, thru_xstring_add
1121  end
1122
1123  def test_xstring_literal
1124    thru_xstring_literal = false
1125    parse('``', :on_xstring_literal) {thru_xstring_literal = true}
1126    assert_equal true, thru_xstring_literal
1127  end
1128
1129  def test_xstring_new
1130    thru_xstring_new = false
1131    parse('``', :on_xstring_new) {thru_xstring_new = true}
1132    assert_equal true, thru_xstring_new
1133  end
1134
1135  def test_yield
1136    thru_yield = false
1137    parse('yield a', :on_yield) {thru_yield = true}
1138    assert_equal true, thru_yield
1139  end
1140
1141  def test_yield0
1142    thru_yield0 = false
1143    parse('yield', :on_yield0) {thru_yield0 = true}
1144    assert_equal true, thru_yield0
1145  end
1146
1147  def test_zsuper
1148    thru_zsuper = false
1149    parse('super', :on_zsuper) {thru_zsuper = true}
1150    assert_equal true, thru_zsuper
1151  end
1152
1153  def test_local_variables
1154    cmd = 'command(w,[regexp_literal(regexp_add(regexp_new(),25 # ),/)])'
1155    div = 'binary(ref(w),/,25)'
1156    bug1939 = '[ruby-core:24923]'
1157
1158    assert_equal("[#{cmd}]", parse('w /25 # /'), bug1939)
1159    assert_equal("[assign(var_field(w),1),#{div}]", parse("w = 1; w /25 # /"), bug1939)
1160    assert_equal("[fcall(p,[],&block([w],[#{div}]))]", parse("p{|w|w /25 # /\n}"), bug1939)
1161    assert_equal("[def(p,[w],bodystmt([#{div}]))]", parse("def p(w)\nw /25 # /\nend"), bug1939)
1162  end
1163
1164  def test_block_variables
1165    assert_equal("[fcall(proc,[],&block([],[void()]))]", parse("proc{|;y|}"))
1166    if defined?(Process::RLIMIT_AS)
1167      assert_in_out_err(["-I#{File.dirname(__FILE__)}", "-rdummyparser"],
1168                        'Process.setrlimit(Process::RLIMIT_AS,100*1024*1024); puts DummyParser.new("proc{|;y|!y}").parse',
1169                        ["[fcall(proc,[],&block([],[unary(!,ref(y))]))]"], [], '[ruby-dev:39423]')
1170    end
1171  end
1172
1173  def test_unterminated_regexp
1174    assert_equal("unterminated regexp meets end of file", compile_error('/'))
1175  end
1176
1177  def test_invalid_instance_variable_name
1178    assert_equal("`@1' is not allowed as an instance variable name", compile_error('@1'))
1179    assert_equal("`@%' is not allowed as an instance variable name", compile_error('@%'))
1180  end
1181
1182  def test_invalid_class_variable_name
1183    assert_equal("`@@1' is not allowed as a class variable name", compile_error('@@1'))
1184    assert_equal("`@@%' is not allowed as a class variable name", compile_error('@@%'))
1185  end
1186
1187  def test_invalid_global_variable_name
1188    assert_equal("`$%' is not allowed as a global variable name", compile_error('$%'))
1189  end
1190end if ripper_test
1191