diff options
Diffstat (limited to 'jni/ruby/test/ripper/test_parser_events.rb')
| -rw-r--r-- | jni/ruby/test/ripper/test_parser_events.rb | 1232 | 
1 files changed, 1232 insertions, 0 deletions
diff --git a/jni/ruby/test/ripper/test_parser_events.rb b/jni/ruby/test/ripper/test_parser_events.rb new file mode 100644 index 0000000..08296a2 --- /dev/null +++ b/jni/ruby/test/ripper/test_parser_events.rb @@ -0,0 +1,1232 @@ +begin +  require_relative 'dummyparser' +  require 'test/unit' +  ripper_test = true +  module TestRipper; end +rescue LoadError +end + +class TestRipper::ParserEvents < Test::Unit::TestCase + +  def test_event_coverage +    dispatched = Ripper::PARSER_EVENTS +    tested = self.class.instance_methods(false).grep(/\Atest_(\w+)/) {$1.intern} +    assert_empty dispatched-tested +  end + +  def parse(str, nm = nil, &bl) +    dp = DummyParser.new(str) +    dp.hook(*nm, &bl) if nm +    dp.parse.to_s +  end + +  def compile_error(str) +    parse(str, :compile_error) {|e, msg| return msg} +  end + +  def test_program +    thru_program = false +    assert_equal '[void()]', parse('', :on_program) {thru_program = true} +    assert_equal true, thru_program +  end + +  def test_stmts_new +    assert_equal '[void()]', parse('') +  end + +  def test_stmts_add +    assert_equal '[ref(nil)]', parse('nil') +    assert_equal '[ref(nil),ref(nil)]', parse('nil;nil') +    assert_equal '[ref(nil),ref(nil),ref(nil)]', parse('nil;nil;nil') +  end + +  def test_void_stmt +    assert_equal '[void()]', parse('') +    assert_equal '[void()]', parse('; ;') +  end + +  def test_var_ref +    assert_equal '[assign(var_field(a),ref(a))]', parse('a=a') +    assert_equal '[ref(nil)]', parse('nil') +    assert_equal '[ref(true)]', parse('true') +  end + +  def test_vcall +    assert_equal '[vcall(a)]', parse('a') +  end + +  def test_BEGIN +    assert_equal '[BEGIN([void()])]', parse('BEGIN{}') +    assert_equal '[BEGIN([ref(nil)])]', parse('BEGIN{nil}') +  end + +  def test_END +    assert_equal '[END([void()])]', parse('END{}') +    assert_equal '[END([ref(nil)])]', parse('END{nil}') +  end + +  def test_alias +    assert_equal '[alias(symbol_literal(a),symbol_literal(b))]', parse('alias a b') +  end + +  def test_var_alias +    assert_equal '[valias($a,$g)]', parse('alias $a $g') +  end + +  def test_alias_error +    assert_equal '[aliaserr(valias($a,$1))]', parse('alias $a $1') +  end + +  def test_arglist +    assert_equal '[fcall(m,[])]', parse('m()') +    assert_equal '[fcall(m,[1])]', parse('m(1)') +    assert_equal '[fcall(m,[1,2])]', parse('m(1,2)') +    assert_equal '[fcall(m,[*vcall(r)])]', parse('m(*r)') +    assert_equal '[fcall(m,[1,*vcall(r)])]', parse('m(1,*r)') +    assert_equal '[fcall(m,[1,2,*vcall(r)])]', parse('m(1,2,*r)') +    assert_equal '[fcall(m,[&vcall(r)])]', parse('m(&r)') +    assert_equal '[fcall(m,[1,&vcall(r)])]', parse('m(1,&r)') +    assert_equal '[fcall(m,[1,2,&vcall(r)])]', parse('m(1,2,&r)') +    assert_equal '[fcall(m,[*vcall(a),&vcall(b)])]', parse('m(*a,&b)') +    assert_equal '[fcall(m,[1,*vcall(a),&vcall(b)])]', parse('m(1,*a,&b)') +    assert_equal '[fcall(m,[1,2,*vcall(a),&vcall(b)])]', parse('m(1,2,*a,&b)') +  end + +  def test_args_add +    thru_args_add = false +    parse('m(a)', :on_args_add) {thru_args_add = true} +    assert_equal true, thru_args_add +  end + +  def test_args_add_block +    thru_args_add_block = false +    parse('m(&b)', :on_args_add_block) {thru_args_add_block = true} +    assert_equal true, thru_args_add_block +  end + +  def test_args_add_star +    thru_args_add_star = false +    parse('m(*a)', :on_args_add_star) {thru_args_add_star = true} +    assert_equal true, thru_args_add_star +    thru_args_add_star = false +    parse('m(*a, &b)', :on_args_add_star) {thru_args_add_star = true} +    assert_equal true, thru_args_add_star +  end + +  def test_args_new +    thru_args_new = false +    parse('m()', :on_args_new) {thru_args_new = true} +    assert_equal true, thru_args_new +  end + +  def test_arg_paren +    # FIXME +  end + +  def test_aref +    assert_equal '[aref(vcall(v),[1])]', parse('v[1]') +    assert_equal '[aref(vcall(v),[1,2])]', parse('v[1,2]') +  end + +  def test_assoclist_from_args +    thru_assoclist_from_args = false +    parse('{a=>b}', :on_assoclist_from_args) {thru_assoclist_from_args = true} +    assert_equal true, thru_assoclist_from_args +  end + +  def test_assocs +    assert_equal '[fcall(m,[assocs(assoc(1,2))])]', parse('m(1=>2)') +    assert_equal '[fcall(m,[assocs(assoc(1,2),assoc(3,4))])]', parse('m(1=>2,3=>4)') +    assert_equal '[fcall(m,[3,assocs(assoc(1,2))])]', parse('m(3,1=>2)') +  end + +  def test_assoc_new +    thru_assoc_new = false +    parse('{a=>b}', :on_assoc_new) {thru_assoc_new = true} +    assert_equal true, thru_assoc_new +  end + +  def test_assoc_splat +    thru_assoc_splat = false +    parse('m(**h)', :on_assoc_splat) {thru_assoc_splat = true} +    assert_equal true, thru_assoc_splat +  end + +  def test_aref_field +    assert_equal '[assign(aref_field(vcall(a),[1]),2)]', parse('a[1]=2') +  end + +  def test_arg_ambiguous +    thru_arg_ambiguous = false +    parse('m //', :on_arg_ambiguous) {thru_arg_ambiguous = true} +    assert_equal true, thru_arg_ambiguous +  end + +  def test_operator_ambiguous +    thru_operator_ambiguous = false +    parse('a=1; a %[]', :on_operator_ambiguous) {thru_operator_ambiguous = true} +    assert_equal true, thru_operator_ambiguous +  end + +  def test_array   # array literal +    assert_equal '[array([1,2,3])]', parse('[1,2,3]') +    assert_equal '[array([abc,def])]', parse('%w[abc def]') +    assert_equal '[array([abc,def])]', parse('%W[abc def]') +  end + +  def test_assign   # generic assignment +    assert_equal '[assign(var_field(v),1)]', parse('v=1') +  end + +  def test_assign_error +    # for test_coverage +  end + +  def test_assign_error_backref +    thru_assign_error = false +    parse('$` = 1', :on_assign_error) {thru_assign_error = true} +    assert_equal true, thru_assign_error +    thru_assign_error = false +    parse('$`, _ = 1', :on_assign_error) {thru_assign_error = true} +    assert_equal true, thru_assign_error +  end + +  def test_assign_error_const_qualified +    thru_assign_error = false +    parse('self::X = 1', :on_assign_error) {thru_assign_error = true} +    assert_equal false, thru_assign_error +    parse("def m\n self::X = 1\nend", :on_assign_error) {thru_assign_error = true} +    assert_equal true, thru_assign_error +    thru_assign_error = false +    parse("def m\n self::X, a = 1, 2\nend", :on_assign_error) {thru_assign_error = true} +    assert_equal true, thru_assign_error +  end + +  def test_assign_error_const +    thru_assign_error = false +    parse('X = 1', :on_assign_error) {thru_assign_error = true} +    assert_equal false, thru_assign_error +    parse("def m\n X = 1\nend", :on_assign_error) {thru_assign_error = true} +    assert_equal true, thru_assign_error +    thru_assign_error = false +    parse("def m\n X, a = 1, 2\nend", :on_assign_error) {thru_assign_error = true} +    assert_equal true, thru_assign_error +  end + +  def test_assign_error_const_toplevel +    thru_assign_error = false +    parse('::X = 1', :on_assign_error) {thru_assign_error = true} +    assert_equal false, thru_assign_error +    parse("def m\n ::X = 1\nend", :on_assign_error) {thru_assign_error = true} +    assert_equal true, thru_assign_error +    thru_assign_error = false +    parse("def m\n ::X, a = 1, 2\nend", :on_assign_error) {thru_assign_error = true} +    assert_equal true, thru_assign_error +  end + +  def test_bare_assoc_hash +    thru_bare_assoc_hash = false +    parse('x[a=>b]', :on_bare_assoc_hash) {thru_bare_assoc_hash = true} +    assert_equal true, thru_bare_assoc_hash +    thru_bare_assoc_hash = false +    parse('x[1, a=>b]', :on_bare_assoc_hash) {thru_bare_assoc_hash = true} +    assert_equal true, thru_bare_assoc_hash +    thru_bare_assoc_hash = false +    parse('x(a=>b)', :on_bare_assoc_hash) {thru_bare_assoc_hash = true} +    assert_equal true, thru_bare_assoc_hash +    thru_bare_assoc_hash = false +    parse('x(1, a=>b)', :on_bare_assoc_hash) {thru_bare_assoc_hash = true} +    assert_equal true, thru_bare_assoc_hash +  end + +  def test_begin +    thru_begin = false +    parse('begin end', :on_begin) {thru_begin = true} +    assert_equal true, thru_begin +  end + +  %w"and or + - * / % ** | ^ & <=> > >= < <= == === != =~ !~ << >> && ||".each do |op| +    define_method("test_binary(#{op})") do +      thru_binary = false +      parse("a #{op} b", :on_binary) {thru_binary = true} +      assert_equal true, thru_binary +    end +  end + +  def test_blockarg +    thru_blockarg = false +    parse("def a(&b) end", :on_blockarg) {thru_blockarg = true} +    assert_equal true, thru_blockarg +    thru_blockarg = false +    parse("def a(x, &b) end", :on_blockarg) {thru_blockarg = true} +    assert_equal true, thru_blockarg + +    thru_blockarg = false +    parse("proc{|&b|}", :on_blockarg) {thru_blockarg = true} +    assert_equal true, thru_blockarg +    thru_blockarg = false +    parse("proc{|x, &b|}", :on_blockarg) {thru_blockarg = true} +    assert_equal true, thru_blockarg +    thru_blockarg = false +    parse("proc{|&b;y|}", :on_blockarg) {thru_blockarg = true} +    assert_equal true, thru_blockarg +    thru_blockarg = false +    parse("proc{|&b,x;y|}", :on_blockarg) {thru_blockarg = true} +    assert_equal true, thru_blockarg + +    thru_blockarg = false +    parse("proc do |&b| end", :on_blockarg) {thru_blockarg = true} +    assert_equal true, thru_blockarg +    thru_blockarg = false +    parse("proc do |&b, x| end", :on_blockarg) {thru_blockarg = true} +    assert_equal true, thru_blockarg +    thru_blockarg = false +    parse("proc do |&b;y| end", :on_blockarg) {thru_blockarg = true} +    assert_equal true, thru_blockarg +    thru_blockarg = false +    parse("proc do |&b, x;y| end", :on_blockarg) {thru_blockarg = true} +    assert_equal true, thru_blockarg +  end + +  def test_block_var +    thru_block_var = false +    parse("proc{||}", :on_block_var) {thru_block_var = true} +    assert_equal true, thru_block_var +    thru_block_var = false +    parse("proc{| |}", :on_block_var) {thru_block_var = true} +    assert_equal true, thru_block_var +    thru_block_var = false +    parse("proc{|x|}", :on_block_var) {thru_block_var = true} +    assert_equal true, thru_block_var +    thru_block_var = false +    parse("proc{|;y|}", :on_block_var) {thru_block_var = true} +    assert_equal true, thru_block_var +    thru_block_var = false +    parse("proc{|x;y|}", :on_block_var) {thru_block_var = true} +    assert_equal true, thru_block_var + +    thru_block_var = false +    parse("proc do || end", :on_block_var) {thru_block_var = true} +    assert_equal true, thru_block_var +    thru_block_var = false +    parse("proc do | | end", :on_block_var) {thru_block_var = true} +    assert_equal true, thru_block_var +    thru_block_var = false +    parse("proc do |x| end", :on_block_var) {thru_block_var = true} +    assert_equal true, thru_block_var +    thru_block_var = false +    parse("proc do |;y| end", :on_block_var) {thru_block_var = true} +    assert_equal true, thru_block_var +    thru_block_var = false +    parse("proc do |x;y| end", :on_block_var) {thru_block_var = true} +    assert_equal true, thru_block_var +  end + +  def test_block_var_add_block +    # not used +  end + +  def test_block_var_add_star +    # not used +  end + +  def test_bodystmt +    thru_bodystmt = false +    parse("class X\nend", :on_bodystmt) {thru_bodystmt = true} +    assert_equal true, thru_bodystmt +  end + +  def test_call +    bug2233 = '[ruby-core:26165]' +    tree = nil + +    thru_call = false +    assert_nothing_raised { +      tree = parse("self.foo", :on_call) {thru_call = true} +    } +    assert_equal true, thru_call +    assert_equal "[call(ref(self),.,foo)]", tree +    thru_call = false +    assert_nothing_raised(bug2233) { +      tree = parse("foo.()", :on_call) {thru_call = true} +    } +    assert_equal true, thru_call +    assert_equal "[call(vcall(foo),.,call,[])]", tree +  end + +  def test_excessed_comma +    thru_excessed_comma = false +    parse("proc{|x,|}", :on_excessed_comma) {thru_excessed_comma = true} +    assert_equal true, thru_excessed_comma +    thru_excessed_comma = false +    parse("proc{|x,y,|}", :on_excessed_comma) {thru_excessed_comma = true} +    assert_equal true, thru_excessed_comma + +    thru_excessed_comma = false +    parse("proc do |x,| end", :on_excessed_comma) {thru_excessed_comma = true} +    assert_equal true, thru_excessed_comma +    thru_excessed_comma = false +    parse("proc do |x,y,| end", :on_excessed_comma) {thru_excessed_comma = true} +    assert_equal true, thru_excessed_comma +  end + +  def test_heredoc +    bug1921 = '[ruby-core:24855]' +    thru_heredoc_beg = false +    tree = parse("<""<EOS\nheredoc\nEOS\n", :on_heredoc_beg) {thru_heredoc_beg = true} +    assert_equal true, thru_heredoc_beg +    assert_match(/string_content\(\),heredoc\n/, tree, bug1921) +    heredoc = nil +    parse("<""<EOS\nheredoc1\nheredoc2\nEOS\n", :on_string_add) {|e, n, s| heredoc = s} +    assert_equal("heredoc1\nheredoc2\n", heredoc, bug1921) +    heredoc = nil +    parse("<""<-EOS\nheredoc1\nheredoc2\n\tEOS\n", :on_string_add) {|e, n, s| heredoc = s} +    assert_equal("heredoc1\nheredoc2\n", heredoc, bug1921) +  end + +  def test_massign +    thru_massign = false +    parse("a, b = 1, 2", :on_massign) {thru_massign = true} +    assert_equal true, thru_massign +  end + +  def test_mlhs_add +    thru_mlhs_add = false +    parse("a, b = 1, 2", :on_mlhs_add) {thru_mlhs_add = true} +    assert_equal true, thru_mlhs_add +  end + +  def test_mlhs_add_star +    bug2232 = '[ruby-core:26163]' +    bug4364 = '[ruby-core:35078]' + +    thru_mlhs_add_star = false +    tree = parse("a, *b = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true} +    assert_equal true, thru_mlhs_add_star +    assert_match(/mlhs_add_star\(mlhs_add\(mlhs_new\(\),a\),b\)/, tree) +    thru_mlhs_add_star = false +    tree = parse("a, *b, c = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true} +    assert_equal true, thru_mlhs_add_star +    assert_match(/mlhs_add\(mlhs_add_star\(mlhs_add\(mlhs_new\(\),a\),b\),mlhs_add\(mlhs_new\(\),c\)\)/, tree, bug2232) +    thru_mlhs_add_star = false +    tree = parse("a, *, c = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true} +    assert_equal true, thru_mlhs_add_star +    assert_match(/mlhs_add\(mlhs_add_star\(mlhs_add\(mlhs_new\(\),a\)\),mlhs_add\(mlhs_new\(\),c\)\)/, tree, bug4364) +    thru_mlhs_add_star = false +    tree = parse("*b, c = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true} +    assert_equal true, thru_mlhs_add_star +    assert_match(/mlhs_add\(mlhs_add_star\(mlhs_new\(\),b\),mlhs_add\(mlhs_new\(\),c\)\)/, tree, bug4364) +    thru_mlhs_add_star = false +    tree = parse("*, c = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true} +    assert_equal true, thru_mlhs_add_star +    assert_match(/mlhs_add\(mlhs_add_star\(mlhs_new\(\)\),mlhs_add\(mlhs_new\(\),c\)\)/, tree, bug4364) +  end + +  def test_mlhs_new +    thru_mlhs_new = false +    parse("a, b = 1, 2", :on_mlhs_new) {thru_mlhs_new = true} +    assert_equal true, thru_mlhs_new +  end + +  def test_mlhs_paren +    thru_mlhs_paren = false +    parse("a, b = 1, 2", :on_mlhs_paren) {thru_mlhs_paren = true} +    assert_equal false, thru_mlhs_paren +    thru_mlhs_paren = false +    parse("(a, b) = 1, 2", :on_mlhs_paren) {thru_mlhs_paren = true} +    assert_equal true, thru_mlhs_paren +  end + +  def test_brace_block +    thru_brace_block = false +    parse('proc {}', :on_brace_block) {thru_brace_block = true} +    assert_equal true, thru_brace_block +  end + +  def test_break +    thru_break = false +    parse('proc {break}', :on_break) {thru_break = true} +    assert_equal true, thru_break +  end + +  def test_case +    thru_case = false +    parse('case foo when true; end', :on_case) {thru_case = true} +    assert_equal true, thru_case +  end + +  def test_class +    thru_class = false +    parse('class Foo; end', :on_class) {thru_class = true} +    assert_equal true, thru_class +  end + +  def test_class_name_error +    thru_class_name_error = false +    parse('class foo; end', :on_class_name_error) {thru_class_name_error = true} +    assert_equal true, thru_class_name_error +  end + +  def test_command +    thru_command = false +    parse('foo a b', :on_command) {thru_command = true} +    assert_equal true, thru_command +  end + +  def test_command_call +    thru_command_call = false +    parse('foo.bar a, b', :on_command_call) {thru_command_call = true} +    assert_equal true, thru_command_call +  end + +  def test_const_ref +    thru_const_ref = false +    parse('class A;end', :on_const_ref) {thru_const_ref = true} +    assert_equal true, thru_const_ref +    thru_const_ref = false +    parse('module A;end', :on_const_ref) {thru_const_ref = true} +    assert_equal true, thru_const_ref +  end + +  def test_const_path_field +    thru_const_path_field = false +    parse('foo::X = 1', :on_const_path_field) {thru_const_path_field = true} +    assert_equal true, thru_const_path_field +  end + +  def test_const_path_ref +    thru_const_path_ref = false +    parse('foo::X', :on_const_path_ref) {thru_const_path_ref = true} +    assert_equal true, thru_const_path_ref +  end + +  def test_def +    thru_def = false +    parse('def foo; end', :on_def) { +      thru_def = true +    } +    assert_equal true, thru_def +    assert_equal '[def(foo,[],bodystmt([void()]))]', parse('def foo ;end') +  end + +  def test_defined +    thru_defined = false +    parse('defined?(x)', :on_defined) {thru_defined = true} +    assert_equal true, thru_defined +  end + +  def test_defs +    thru_defs = false +    parse('def foo.bar; end', :on_defs) {thru_defs = true} +    assert_equal true, thru_defs +  end + +  def test_do_block +    thru_do_block = false +    parse('proc do end', :on_do_block) {thru_do_block = true} +    assert_equal true, thru_do_block +  end + +  def test_dot2 +    thru_dot2 = false +    parse('a..b', :on_dot2) {thru_dot2 = true} +    assert_equal true, thru_dot2 +  end + +  def test_dot3 +    thru_dot3 = false +    parse('a...b', :on_dot3) {thru_dot3 = true} +    assert_equal true, thru_dot3 +  end + +  def test_dyna_symbol +    thru_dyna_symbol = false +    parse(':"#{foo}"', :on_dyna_symbol) {thru_dyna_symbol = true} +    assert_equal true, thru_dyna_symbol + +    thru_dyna_symbol = false +    parse('{"#{foo}": 1}', :on_dyna_symbol) {thru_dyna_symbol = true} +    assert_equal true, thru_dyna_symbol +  end + +  def test_else +    thru_else = false +    parse('if foo; bar else zot end', :on_else) {thru_else = true} +    assert_equal true, thru_else +  end + +  def test_elsif +    thru_elsif = false +    parse('if foo; bar elsif qux; zot end', :on_elsif) {thru_elsif = true} +    assert_equal true, thru_elsif +  end + +  def test_ensure +    thru_ensure = false +    parse('begin foo ensure bar end', :on_ensure) {thru_ensure = true} +    assert_equal true, thru_ensure +  end + +  def test_fcall +    thru_fcall = false +    parse('foo()', :on_fcall) {thru_fcall = true} +    assert_equal true, thru_fcall +  end + +  def test_field +    thru_field = false +    parse('foo.x = 1', :on_field) {thru_field = true} +    assert_equal true, thru_field +  end + +  def test_for +    thru_for = false +    parse('for i in foo; end', :on_for) {thru_for = true} +    assert_equal true, thru_for +  end + +  def test_hash +    thru_hash = false +    parse('{1=>2}', :on_hash) {thru_hash = true} +    assert_equal true, thru_hash +    thru_hash = false +    parse('{a: 2}', :on_hash) {thru_hash = true} +    assert_equal true, thru_hash +  end + +  def test_if +    thru_if = false +    parse('if false; end', :on_if) {thru_if = true} +    assert_equal true, thru_if +  end + +  def test_if_mod +    thru_if_mod = false +    parse('nil if nil', :on_if_mod) {thru_if_mod = true} +    assert_equal true, thru_if_mod +  end + +  def test_ifop +    thru_ifop = false +    parse('a ? b : c', :on_ifop) {thru_ifop = true} +    assert_equal true, thru_ifop +  end + +  def test_lambda +    thru_lambda = false +    parse('->{}', :on_lambda) {thru_lambda = true} +    assert_equal true, thru_lambda +  end + +  def test_magic_comment +    thru_magic_comment = false +    parse('# -*- bug-5753: ruby-dev:44984 -*-', :on_magic_comment) {|*x|thru_magic_comment = x} +    assert_equal [:on_magic_comment, "bug_5753", "ruby-dev:44984"], thru_magic_comment +  end + +  def test_method_add_block +    thru_method_add_block = false +    parse('a {}', :on_method_add_block) {thru_method_add_block = true} +    assert_equal true, thru_method_add_block +    thru_method_add_block = false +    parse('a do end', :on_method_add_block) {thru_method_add_block = true} +    assert_equal true, thru_method_add_block +  end + +  def test_method_add_arg +    thru_method_add_arg = false +    parse('a()', :on_method_add_arg) {thru_method_add_arg = true} +    assert_equal true, thru_method_add_arg +    thru_method_add_arg = false +    parse('a {}', :on_method_add_arg) {thru_method_add_arg = true} +    assert_equal true, thru_method_add_arg +    thru_method_add_arg = false +    parse('a.b(1)', :on_method_add_arg) {thru_method_add_arg = true} +    assert_equal true, thru_method_add_arg +    thru_method_add_arg = false +    parse('a::b(1)', :on_method_add_arg) {thru_method_add_arg = true} +    assert_equal true, thru_method_add_arg +  end + +  def test_module +    thru_module = false +    parse('module A; end', :on_module) {thru_module = true} +    assert_equal true, thru_module +  end + +  def test_mrhs_add +    thru_mrhs_add = false +    parse('a = a, b', :on_mrhs_add) {thru_mrhs_add = true} +    assert_equal true, thru_mrhs_add +  end + +  def test_mrhs_add_star +    thru_mrhs_add_star = false +    parse('a = a, *b', :on_mrhs_add_star) {thru_mrhs_add_star = true} +    assert_equal true, thru_mrhs_add_star +  end + +  def test_mrhs_new +    thru_mrhs_new = false +    parse('a = *a', :on_mrhs_new) {thru_mrhs_new = true} +    assert_equal true, thru_mrhs_new +  end + +  def test_mrhs_new_from_args +    thru_mrhs_new_from_args = false +    parse('a = a, b', :on_mrhs_new_from_args) {thru_mrhs_new_from_args = true} +    assert_equal true, thru_mrhs_new_from_args +  end + +  def test_next +    thru_next = false +    parse('a {next}', :on_next) {thru_next = true} +    assert_equal true, thru_next +  end + +  def test_opassign +    thru_opassign = false +    parse('a += b', :on_opassign) {thru_opassign = true} +    assert_equal true, thru_opassign +    thru_opassign = false +    parse('a -= b', :on_opassign) {thru_opassign = true} +    assert_equal true, thru_opassign +    thru_opassign = false +    parse('a *= b', :on_opassign) {thru_opassign = true} +    assert_equal true, thru_opassign +    thru_opassign = false +    parse('a /= b', :on_opassign) {thru_opassign = true} +    assert_equal true, thru_opassign +    thru_opassign = false +    parse('a %= b', :on_opassign) {thru_opassign = true} +    assert_equal true, thru_opassign +    thru_opassign = false +    parse('a **= b', :on_opassign) {thru_opassign = true} +    assert_equal true, thru_opassign +    thru_opassign = false +    parse('a &= b', :on_opassign) {thru_opassign = true} +    assert_equal true, thru_opassign +    thru_opassign = false +    parse('a |= b', :on_opassign) {thru_opassign = true} +    assert_equal true, thru_opassign +    thru_opassign = false +    parse('a <<= b', :on_opassign) {thru_opassign = true} +    assert_equal true, thru_opassign +    thru_opassign = false +    parse('a >>= b', :on_opassign) {thru_opassign = true} +    assert_equal true, thru_opassign +    thru_opassign = false +    parse('a &&= b', :on_opassign) {thru_opassign = true} +    assert_equal true, thru_opassign +    thru_opassign = false +    parse('a ||= b', :on_opassign) {thru_opassign = true} +    assert_equal true, thru_opassign +    thru_opassign = false +    parse('a::X ||= c 1', :on_opassign) {thru_opassign = true} +    assert_equal true, thru_opassign +  end + +  def test_opassign_error +    thru_opassign = [] +    events = [:on_opassign] +    parse('$~ ||= 1', events) {|a,*b| +      thru_opassign << a +    } +    assert_equal events, thru_opassign +  end + +  def test_param_error +    thru_param_error = false +    parse('def foo(A) end', :on_param_error) {thru_param_error = true} +    assert_equal true, thru_param_error +    thru_param_error = false +    parse('def foo($a) end', :on_param_error) {thru_param_error = true} +    assert_equal true, thru_param_error +    thru_param_error = false +    parse('def foo(@a) end', :on_param_error) {thru_param_error = true} +    assert_equal true, thru_param_error +    thru_param_error = false +    parse('def foo(@@a) end', :on_param_error) {thru_param_error = true} +    assert_equal true, thru_param_error +  end + +  def test_params +    arg = nil +    thru_params = false +    parse('a {||}', :on_params) {|_, *v| thru_params = true; arg = v} +    assert_equal true, thru_params +    assert_equal [nil, nil, nil, nil, nil, nil, nil], arg +    thru_params = false +    parse('a {|x|}', :on_params) {|_, *v| thru_params = true; arg = v} +    assert_equal true, thru_params +    assert_equal [["x"], nil, nil, nil, nil, nil, nil], arg +    thru_params = false +    parse('a {|*x|}', :on_params) {|_, *v| thru_params = true; arg = v} +    assert_equal true, thru_params +    assert_equal [nil, nil, "*x", nil, nil, nil, nil], arg +    thru_params = false +    parse('a {|x: 1|}', :on_params) {|_, *v| thru_params = true; arg = v} +    assert_equal true, thru_params +    assert_equal [nil, nil, nil, nil, [["x:", "1"]], nil, nil], arg +    thru_params = false +    parse('a {|x:|}', :on_params) {|_, *v| thru_params = true; arg = v} +    assert_equal true, thru_params +    assert_equal [nil, nil, nil, nil, [["x:", false]], nil, nil], arg +    thru_params = false +    parse('a {|**x|}', :on_params) {|_, *v| thru_params = true; arg = v} +    assert_equal true, thru_params +    assert_equal [nil, nil, nil, nil, nil, "x", nil], arg +  end + +  def test_paren +    thru_paren = false +    parse('()', :on_paren) {thru_paren = true} +    assert_equal true, thru_paren +  end + +  def test_parse_error +    thru_parse_error = false +    parse('<>', :on_parse_error) {thru_parse_error = true} +    assert_equal true, thru_parse_error +  end + +  def test_qwords_add +    thru_qwords_add = false +    parse('%w[a]', :on_qwords_add) {thru_qwords_add = true} +    assert_equal true, thru_qwords_add +  end + +  def test_qsymbols_add +    thru_qsymbols_add = false +    parse('%i[a]', :on_qsymbols_add) {thru_qsymbols_add = true} +    assert_equal true, thru_qsymbols_add +  end + +  def test_symbols_add +    thru_symbols_add = false +    parse('%I[a]', :on_symbols_add) {thru_symbols_add = true} +    assert_equal true, thru_symbols_add +  end + +  def test_qwords_new +    thru_qwords_new = false +    parse('%w[]', :on_qwords_new) {thru_qwords_new = true} +    assert_equal true, thru_qwords_new +  end + +  def test_qsymbols_new +    thru_qsymbols_new = false +    parse('%i[]', :on_qsymbols_new) {thru_qsymbols_new = true} +    assert_equal true, thru_qsymbols_new +  end + +  def test_symbols_new +    thru_symbols_new = false +    parse('%I[]', :on_symbols_new) {thru_symbols_new = true} +    assert_equal true, thru_symbols_new +  end + +  def test_redo +    thru_redo = false +    parse('redo', :on_redo) {thru_redo = true} +    assert_equal true, thru_redo +  end + +  def test_regexp_add +    thru_regexp_add = false +    parse('/foo/', :on_regexp_add) {thru_regexp_add = true} +    assert_equal true, thru_regexp_add +  end + +  def test_regexp_literal +    thru_regexp_literal = false +    parse('//', :on_regexp_literal) {thru_regexp_literal = true} +    assert_equal true, thru_regexp_literal +  end + +  def test_regexp_new +    thru_regexp_new = false +    parse('//', :on_regexp_new) {thru_regexp_new = true} +    assert_equal true, thru_regexp_new +  end + +  def test_rescue +    thru_rescue = false +    parsed = parse('begin; 1; rescue => e; 2; end', :on_rescue) {thru_rescue = true} +    assert_equal true, thru_rescue +    assert_match(/1.*rescue/, parsed) +    assert_match(/rescue\(,var_field\(e\),\[2\]\)/, parsed) +  end + +  def test_rescue_class +    thru_rescue = false +    parsed = parse('begin; 1; rescue RuntimeError => e; 2; end', :on_rescue) {thru_rescue = true} +    assert_equal true, thru_rescue +    assert_match(/1.*rescue/, parsed) +    assert_match(/rescue\(\[ref\(RuntimeError\)\],var_field\(e\),\[2\]\)/, parsed) +  end + +  def test_rescue_mod +    thru_rescue_mod = false +    parsed = parse('1 rescue 2', :on_rescue_mod) {thru_rescue_mod = true} +    assert_equal true, thru_rescue_mod +    bug4716 = '[ruby-core:36248]' +    assert_equal "[rescue_mod(1,2)]", parsed, bug4716 +  end + +  def test_rest_param +    thru_rest_param = false +    parse('def a(*) end', :on_rest_param) {thru_rest_param = true} +    assert_equal true, thru_rest_param +    thru_rest_param = false +    parse('def a(*x) end', :on_rest_param) {thru_rest_param = true} +    assert_equal true, thru_rest_param +  end + +  def test_retry +    thru_retry = false +    parse('retry', :on_retry) {thru_retry = true} +    assert_equal true, thru_retry +  end + +  def test_return +    thru_return = false +    parse('return a', :on_return) {thru_return = true} +    assert_equal true, thru_return +  end + +  def test_return0 +    thru_return0 = false +    parse('return', :on_return0) {thru_return0 = true} +    assert_equal true, thru_return0 +  end + +  def test_sclass +    thru_sclass = false +    parse('class << a; end', :on_sclass) {thru_sclass = true} +    assert_equal true, thru_sclass +  end + +  def test_string_add +    thru_string_add = false +    parse('"aa"', :on_string_add) {thru_string_add = true} +    assert_equal true, thru_string_add +  end + +  def test_string_concat +    thru_string_concat = false +    parse('"a" "b"', :on_string_concat) {thru_string_concat = true} +    assert_equal true, thru_string_concat +  end + +  def test_string_content +    thru_string_content = false +    parse('""', :on_string_content) {thru_string_content = true} +    assert_equal true, thru_string_content +    thru_string_content = false +    parse('"a"', :on_string_content) {thru_string_content = true} +    assert_equal true, thru_string_content +    thru_string_content = false +    parse('%[a]', :on_string_content) {thru_string_content = true} +    assert_equal true, thru_string_content +    thru_string_content = false +    parse('\'a\'', :on_string_content) {thru_string_content = true} +    assert_equal true, thru_string_content +    thru_string_content = false +    parse('%<a>', :on_string_content) {thru_string_content = true} +    assert_equal true, thru_string_content +    thru_string_content = false +    parse('%!a!', :on_string_content) {thru_string_content = true} +    assert_equal true, thru_string_content +    thru_string_content = false +    parse('%q!a!', :on_string_content) {thru_string_content = true} +    assert_equal true, thru_string_content +    thru_string_content = false +    parse('%Q!a!', :on_string_content) {thru_string_content = true} +    assert_equal true, thru_string_content +  end + +  def test_string_dvar +    thru_string_dvar = false +    parse('"#$a"', :on_string_dvar) {thru_string_dvar = true} +    assert_equal true, thru_string_dvar +    thru_string_dvar = false +    parse('\'#$a\'', :on_string_dvar) {thru_string_dvar = true} +    assert_equal false, thru_string_dvar +    thru_string_dvar = false +    parse('"#@a"', :on_string_dvar) {thru_string_dvar = true} +    assert_equal true, thru_string_dvar +    thru_string_dvar = false +    parse('\'#@a\'', :on_string_dvar) {thru_string_dvar = true} +    assert_equal false, thru_string_dvar +    thru_string_dvar = false +    parse('"#@@a"', :on_string_dvar) {thru_string_dvar = true} +    assert_equal true, thru_string_dvar +    thru_string_dvar = false +    parse('\'#@@a\'', :on_string_dvar) {thru_string_dvar = true} +    assert_equal false, thru_string_dvar +    thru_string_dvar = false +    parse('"#$1"', :on_string_dvar) {thru_string_dvar = true} +    assert_equal true, thru_string_dvar +    thru_string_dvar = false +    parse('\'#$1\'', :on_string_dvar) {thru_string_dvar = true} +    assert_equal false, thru_string_dvar +  end + +  def test_string_embexpr +    thru_string_embexpr = false +    parse('"#{}"', :on_string_embexpr) {thru_string_embexpr = true} +    assert_equal true, thru_string_embexpr +    thru_string_embexpr = false +    parse('\'#{}\'', :on_string_embexpr) {thru_string_embexpr = true} +    assert_equal false, thru_string_embexpr +  end + +  def test_string_literal +    thru_string_literal = false +    parse('""', :on_string_literal) {thru_string_literal = true} +    assert_equal true, thru_string_literal +  end + +  def test_super +    thru_super = false +    parse('super()', :on_super) {thru_super = true} +    assert_equal true, thru_super +  end + +  def test_symbol +    thru_symbol = false +    parse(':a', :on_symbol) {thru_symbol = true} +    assert_equal true, thru_symbol +    thru_symbol = false +    parse(':$a', :on_symbol) {thru_symbol = true} +    assert_equal true, thru_symbol +    thru_symbol = false +    parse(':@a', :on_symbol) {thru_symbol = true} +    assert_equal true, thru_symbol +    thru_symbol = false +    parse(':@@a', :on_symbol) {thru_symbol = true} +    assert_equal true, thru_symbol +    thru_symbol = false +    parse(':==', :on_symbol) {thru_symbol = true} +    assert_equal true, thru_symbol +  end + +  def test_symbol_literal +    thru_symbol_literal = false +    parse(':a', :on_symbol_literal) {thru_symbol_literal = true} +    assert_equal true, thru_symbol_literal +  end + +  def test_top_const_field +    thru_top_const_field = false +    parse('::A=1', :on_top_const_field) {thru_top_const_field = true} +    assert_equal true, thru_top_const_field +  end + +  def test_top_const_ref +    thru_top_const_ref = false +    parse('::A', :on_top_const_ref) {thru_top_const_ref = true} +    assert_equal true, thru_top_const_ref +  end + +  def test_unary +    thru_unary = false +    parse('not a 1, 2', :on_unary) {thru_unary = true} +    assert_equal true, thru_unary +    thru_unary = false +    parse('not (a)', :on_unary) {thru_unary = true} +    assert_equal true, thru_unary +    thru_unary = false +    parse('!a', :on_unary) {thru_unary = true} +    assert_equal true, thru_unary +    thru_unary = false +    parse('-10', :on_unary) {thru_unary = true} +    assert_equal true, thru_unary +    thru_unary = false +    parse('-10*2', :on_unary) {thru_unary = true} +    assert_equal true, thru_unary +    thru_unary = false +    parse('-10.1', :on_unary) {thru_unary = true} +    assert_equal true, thru_unary +    thru_unary = false +    parse('-10.1*2', :on_unary) {thru_unary = true} +    assert_equal true, thru_unary +    thru_unary = false +    parse('-a', :on_unary) {thru_unary = true} +    assert_equal true, thru_unary +    thru_unary = false +    parse('+a', :on_unary) {thru_unary = true} +    assert_equal true, thru_unary +    thru_unary = false +    parse('~a', :on_unary) {thru_unary = true} +    assert_equal true, thru_unary +    thru_unary = false +    parse('not()', :on_unary) {thru_unary = true} +    assert_equal true, thru_unary +  end + +  def test_undef +    thru_undef = false +    parse('undef a', :on_undef) {thru_undef = true} +    assert_equal true, thru_undef +    thru_undef = false +    parse('undef <=>', :on_undef) {thru_undef = true} +    assert_equal true, thru_undef +    thru_undef = false +    parse('undef a, b', :on_undef) {thru_undef = true} +    assert_equal true, thru_undef +  end + +  def test_unless +    thru_unless = false +    parse('unless a; end', :on_unless) {thru_unless = true} +    assert_equal true, thru_unless +  end + +  def test_unless_mod +    thru_unless_mod = false +    parse('nil unless a', :on_unless_mod) {thru_unless_mod = true} +    assert_equal true, thru_unless_mod +  end + +  def test_until +    thru_until = false +    parse('until a; end', :on_until) {thru_until = true} +    assert_equal true, thru_until +  end + +  def test_until_mod +    thru_until_mod = false +    parse('nil until a', :on_until_mod) {thru_until_mod = true} +    assert_equal true, thru_until_mod +  end + +  def test_var_field +    thru_var_field = false +    parse('a = 1', :on_var_field) {thru_var_field = true} +    assert_equal true, thru_var_field +    thru_var_field = false +    parse('a += 1', :on_var_field) {thru_var_field = true} +    assert_equal true, thru_var_field +  end + +  def test_when +    thru_when = false +    parse('case a when b; end', :on_when) {thru_when = true} +    assert_equal true, thru_when +    thru_when = false +    parse('case when a; end', :on_when) {thru_when = true} +    assert_equal true, thru_when +  end + +  def test_while +    thru_while = false +    parse('while a; end', :on_while) {thru_while = true} +    assert_equal true, thru_while +  end + +  def test_while_mod +    thru_while_mod = false +    parse('nil while a', :on_while_mod) {thru_while_mod = true} +    assert_equal true, thru_while_mod +  end + +  def test_word_add +    thru_word_add = false +    parse('%W[a]', :on_word_add) {thru_word_add = true} +    assert_equal true, thru_word_add +  end + +  def test_word_new +    thru_word_new = false +    parse('%W[a]', :on_word_new) {thru_word_new = true} +    assert_equal true, thru_word_new +  end + +  def test_words_add +    thru_words_add = false +    parse('%W[a]', :on_words_add) {thru_words_add = true} +    assert_equal true, thru_words_add +  end + +  def test_words_new +    thru_words_new = false +    parse('%W[]', :on_words_new) {thru_words_new = true} +    assert_equal true, thru_words_new +  end + +  def test_xstring_add +    thru_xstring_add = false +    parse('`x`', :on_xstring_add) {thru_xstring_add = true} +    assert_equal true, thru_xstring_add +  end + +  def test_xstring_literal +    thru_xstring_literal = false +    parse('``', :on_xstring_literal) {thru_xstring_literal = true} +    assert_equal true, thru_xstring_literal +  end + +  def test_xstring_new +    thru_xstring_new = false +    parse('``', :on_xstring_new) {thru_xstring_new = true} +    assert_equal true, thru_xstring_new +  end + +  def test_yield +    thru_yield = false +    parse('yield a', :on_yield) {thru_yield = true} +    assert_equal true, thru_yield +  end + +  def test_yield0 +    thru_yield0 = false +    parse('yield', :on_yield0) {thru_yield0 = true} +    assert_equal true, thru_yield0 +  end + +  def test_zsuper +    thru_zsuper = false +    parse('super', :on_zsuper) {thru_zsuper = true} +    assert_equal true, thru_zsuper +  end + +  def test_local_variables +    cmd = 'command(w,[regexp_literal(regexp_add(regexp_new(),25 # ),/)])' +    div = 'binary(ref(w),/,25)' +    bug1939 = '[ruby-core:24923]' + +    assert_equal("[#{cmd}]", parse('w /25 # /'), bug1939) +    assert_equal("[assign(var_field(w),1),#{div}]", parse("w = 1; w /25 # /"), bug1939) +    assert_equal("[fcall(p,[],&block([w],[#{div}]))]", parse("p{|w|w /25 # /\n}"), bug1939) +    assert_equal("[def(p,[w],bodystmt([#{div}]))]", parse("def p(w)\nw /25 # /\nend"), bug1939) +  end + +  def test_block_variables +    assert_equal("[fcall(proc,[],&block([],[void()]))]", parse("proc{|;y|}")) +    if defined?(Process::RLIMIT_AS) +      assert_in_out_err(["-I#{File.dirname(__FILE__)}", "-rdummyparser"], +                        'Process.setrlimit(Process::RLIMIT_AS,100*1024*1024); puts DummyParser.new("proc{|;y|!y}").parse', +                        ["[fcall(proc,[],&block([],[unary(!,ref(y))]))]"], [], '[ruby-dev:39423]') +    end +  end + +  def test_unterminated_regexp +    assert_equal("unterminated regexp meets end of file", compile_error('/')) +  end + +  def test_invalid_instance_variable_name +    assert_equal("`@1' is not allowed as an instance variable name", compile_error('@1')) +    assert_equal("`@%' is not allowed as an instance variable name", compile_error('@%')) +  end + +  def test_invalid_class_variable_name +    assert_equal("`@@1' is not allowed as a class variable name", compile_error('@@1')) +    assert_equal("`@@%' is not allowed as a class variable name", compile_error('@@%')) +  end + +  def test_invalid_global_variable_name +    assert_equal("`$%' is not allowed as a global variable name", compile_error('$%')) +  end +end if ripper_test  | 
