1# coding: US-ASCII 2require 'test/unit' 3require 'stringio' 4 5class TestParse < Test::Unit::TestCase 6 def setup 7 @verbose = $VERBOSE 8 $VERBOSE = nil 9 end 10 11 def teardown 12 $VERBOSE = @verbose 13 end 14 15 def test_else_without_rescue 16 x = eval <<-END, nil, __FILE__, __LINE__+1 17 begin 18 else 19 42 20 end 21 END 22 assert_equal(42, x) 23 end 24 25 def test_alias_backref 26 assert_raise(SyntaxError) do 27 eval <<-END, nil, __FILE__, __LINE__+1 28 alias $foo $1 29 END 30 end 31 end 32 33 def test_command_call 34 t = Object.new 35 def t.foo(x); x; end 36 37 a = false 38 b = c = d = true 39 assert_nothing_raised do 40 eval <<-END, nil, __FILE__, __LINE__+1 41 a &&= t.foo 42 42 b &&= t.foo 42 43 c &&= t.foo nil 44 d &&= t.foo false 45 END 46 end 47 assert_equal([false, 42, nil, false], [a, b, c, d]) 48 49 a = 3 50 assert_nothing_raised { eval("a &= t.foo 5") } 51 assert_equal(1, a) 52 53 a = [nil, nil, true, true] 54 assert_nothing_raised do 55 eval <<-END, nil, __FILE__, __LINE__+1 56 a[0] ||= t.foo 42 57 a[1] &&= t.foo 42 58 a[2] ||= t.foo 42 59 a[3] &&= t.foo 42 60 END 61 end 62 assert_equal([42, nil, true, 42], a) 63 64 o = Object.new 65 class << o 66 attr_accessor :foo, :bar, :Foo, :Bar, :baz, :qux 67 end 68 o.foo = o.Foo = o::baz = nil 69 o.bar = o.Bar = o::qux = 1 70 assert_nothing_raised do 71 eval <<-END, nil, __FILE__, __LINE__+1 72 o.foo ||= t.foo 42 73 o.bar &&= t.foo 42 74 o.Foo ||= t.foo 42 75 o.Bar &&= t.foo 42 76 o::baz ||= t.foo 42 77 o::qux &&= t.foo 42 78 END 79 end 80 assert_equal([42, 42], [o.foo, o.bar]) 81 assert_equal([42, 42], [o.Foo, o.Bar]) 82 assert_equal([42, 42], [o::baz, o::qux]) 83 84 assert_raise(SyntaxError) do 85 eval <<-END, nil, __FILE__, __LINE__+1 86 $1 ||= t.foo 42 87 END 88 end 89 90 def t.bar(x); x + yield; end 91 92 a = b = nil 93 assert_nothing_raised do 94 eval <<-END, nil, __FILE__, __LINE__+1 95 a = t.bar "foo" do 96 "bar" 97 end.gsub "ob", "OB" 98 b = t.bar "foo" do 99 "bar" 100 end::gsub "ob", "OB" 101 END 102 end 103 assert_equal("foOBar", a) 104 assert_equal("foOBar", b) 105 106 a = nil 107 assert_nothing_raised do 108 t.instance_eval <<-END, __FILE__, __LINE__+1 109 a = bar "foo" do "bar" end 110 END 111 end 112 assert_equal("foobar", a) 113 114 a = nil 115 assert_nothing_raised do 116 eval <<-END, nil, __FILE__, __LINE__+1 117 a = t::bar "foo" do "bar" end 118 END 119 end 120 assert_equal("foobar", a) 121 122 def t.baz(*r) 123 @baz = r + (block_given? ? [yield] : []) 124 end 125 126 assert_nothing_raised do 127 t.instance_eval "baz (1), 2" 128 end 129 assert_equal([1, 2], t.instance_eval { @baz }) 130 end 131 132 def test_mlhs_node 133 c = Class.new 134 class << c 135 attr_accessor :foo, :bar, :Foo, :Bar 136 FOO = BAR = nil 137 end 138 139 assert_nothing_raised do 140 eval <<-END, nil, __FILE__, __LINE__+1 141 c::foo, c::bar = 1, 2 142 c.Foo, c.Bar = 1, 2 143 c::FOO, c::BAR = 1, 2 144 END 145 end 146 assert_equal([1, 2], [c::foo, c::bar]) 147 assert_equal([1, 2], [c.Foo, c.Bar]) 148 assert_equal([1, 2], [c::FOO, c::BAR]) 149 end 150 151 def test_dynamic_constant_assignment 152 assert_raise(SyntaxError) do 153 Object.new.instance_eval <<-END, __FILE__, __LINE__+1 154 def foo 155 self::FOO, self::BAR = 1, 2 156 ::FOO, ::BAR = 1, 2 157 end 158 END 159 end 160 161 assert_raise(SyntaxError) do 162 eval <<-END, nil, __FILE__, __LINE__+1 163 $1, $2 = 1, 2 164 END 165 end 166 167 assert_raise(SyntaxError) do 168 Object.new.instance_eval <<-END, __FILE__, __LINE__+1 169 def foo 170 ::FOO = 1 171 end 172 END 173 end 174 175 c = Class.new 176 assert_nothing_raised(SyntaxError) do 177 eval <<-END, nil, __FILE__, __LINE__+1 178 if false 179 c::FOO &= 1 180 ::FOO &= 1 181 end 182 END 183 end 184 185 c = Class.new 186 assert_raise(SyntaxError) do 187 eval <<-END, nil, __FILE__, __LINE__+1 188 $1 &= 1 189 END 190 end 191 end 192 193 def test_class_module 194 assert_raise(SyntaxError) do 195 eval <<-END, nil, __FILE__, __LINE__+1 196 class foo; end 197 END 198 end 199 200 assert_raise(SyntaxError) do 201 eval <<-END, nil, __FILE__, __LINE__+1 202 def foo 203 class Foo; end 204 module Bar; end 205 end 206 END 207 end 208 209 assert_raise(SyntaxError) do 210 eval <<-END, nil, __FILE__, __LINE__+1 211 class Foo Bar; end 212 END 213 end 214 end 215 216 def test_op_name 217 o = Object.new 218 def o.>(x); x; end 219 def o./(x); x; end 220 221 a = nil 222 assert_nothing_raised do 223 o.instance_eval <<-END, __FILE__, __LINE__+1 224 undef >, / 225 END 226 end 227 end 228 229 def test_arg 230 o = Object.new 231 class << o 232 attr_accessor :foo, :bar, :Foo, :Bar, :baz, :qux 233 end 234 o.foo = o.Foo = o::baz = nil 235 o.bar = o.Bar = o::qux = 1 236 assert_nothing_raised do 237 eval <<-END, nil, __FILE__, __LINE__+1 238 o.foo ||= 42 239 o.bar &&= 42 240 o.Foo ||= 42 241 o.Bar &&= 42 242 o::baz ||= 42 243 o::qux &&= 42 244 END 245 end 246 assert_equal([42, 42], [o.foo, o.bar]) 247 assert_equal([42, 42], [o.Foo, o.Bar]) 248 assert_equal([42, 42], [o::baz, o::qux]) 249 250 a = nil 251 assert_nothing_raised do 252 eval <<-END, nil, __FILE__, __LINE__+1 253 a = -2.0 ** 2 254 END 255 end 256 assert_equal(-4.0, a) 257 end 258 259 def test_block_variable 260 o = Object.new 261 def o.foo(*r); yield(*r); end 262 263 a = nil 264 assert_nothing_raised do 265 eval <<-END, nil, __FILE__, __LINE__+1 266 o.foo 1 do|; a| a = 42 end 267 END 268 end 269 assert_nil(a) 270 end 271 272 def test_bad_arg 273 assert_raise(SyntaxError) do 274 eval <<-END, nil, __FILE__, __LINE__+1 275 def foo(FOO); end 276 END 277 end 278 279 assert_raise(SyntaxError) do 280 eval <<-END, nil, __FILE__, __LINE__+1 281 def foo(@foo); end 282 END 283 end 284 285 assert_raise(SyntaxError) do 286 eval <<-END, nil, __FILE__, __LINE__+1 287 def foo($foo); end 288 END 289 end 290 291 assert_raise(SyntaxError) do 292 eval <<-END, nil, __FILE__, __LINE__+1 293 def foo(@@foo); end 294 END 295 end 296 297 o = Object.new 298 def o.foo(*r); yield(*r); end 299 300 assert_raise(SyntaxError) do 301 eval <<-END, nil, __FILE__, __LINE__+1 302 o.foo 1 {|; @a| @a = 42 } 303 END 304 end 305 end 306 307 def test_do_lambda 308 a = b = nil 309 assert_nothing_raised do 310 eval <<-END, nil, __FILE__, __LINE__+1 311 a = -> do 312 b = 42 313 end 314 END 315 end 316 a.call 317 assert_equal(42, b) 318 end 319 320 def test_block_call_colon2 321 o = Object.new 322 def o.foo(x); x + yield; end 323 324 a = b = nil 325 assert_nothing_raised do 326 o.instance_eval <<-END, __FILE__, __LINE__+1 327 a = foo 1 do 42 end.to_s 328 b = foo 1 do 42 end::to_s 329 END 330 end 331 assert_equal("43", a) 332 assert_equal("43", b) 333 end 334 335 def test_call_method 336 a = b = nil 337 assert_nothing_raised do 338 eval <<-END, nil, __FILE__, __LINE__+1 339 a = proc {|x| x + "bar" }.("foo") 340 b = proc {|x| x + "bar" }::("foo") 341 END 342 end 343 assert_equal("foobar", a) 344 assert_equal("foobar", b) 345 end 346 347 def test_xstring 348 assert_raise(Errno::ENOENT) do 349 eval("``") 350 end 351 end 352 353 def test_words 354 assert_equal([], %W( )) 355 end 356 357 def test_dstr 358 @@foo = 1 359 assert_equal("foo 1 bar", "foo #@@foo bar") 360 "1" =~ /(.)/ 361 assert_equal("foo 1 bar", "foo #$1 bar") 362 end 363 364 def test_dstr_disallowd_variable 365 bug8375 = '[ruby-core:54885] [Bug #8375]' 366 %w[@ @1 @@. @@ @@1 @@. $ $%].each do |src| 367 src = '#'+src+' ' 368 str = assert_nothing_raised(SyntaxError, "#{bug8375} #{src.dump}") do 369 break eval('"'+src+'"') 370 end 371 assert_equal(src, str, bug8375) 372 end 373 end 374 375 def test_dsym 376 assert_nothing_raised { eval(':""') } 377 end 378 379 def test_arg2 380 o = Object.new 381 382 assert_nothing_raised do 383 eval <<-END, nil, __FILE__, __LINE__+1 384 def o.foo(a=42,*r,z,&b); b.call(r.inject(a*1000+z*100, :+)); end 385 END 386 end 387 assert_equal(-1405, o.foo(1,2,3,4) {|x| -x }) 388 assert_equal(-1302, o.foo(1,2,3) {|x| -x }) 389 assert_equal(-1200, o.foo(1,2) {|x| -x }) 390 assert_equal(-42100, o.foo(1) {|x| -x }) 391 assert_raise(ArgumentError) { o.foo() } 392 393 assert_nothing_raised do 394 eval <<-END, nil, __FILE__, __LINE__+1 395 def o.foo(a=42,z,&b); b.call(a*1000+z*100); end 396 END 397 end 398 assert_equal(-1200, o.foo(1,2) {|x| -x } ) 399 assert_equal(-42100, o.foo(1) {|x| -x } ) 400 assert_raise(ArgumentError) { o.foo() } 401 402 assert_nothing_raised do 403 eval <<-END, nil, __FILE__, __LINE__+1 404 def o.foo(*r,z,&b); b.call(r.inject(z*100, :+)); end 405 END 406 end 407 assert_equal(-303, o.foo(1,2,3) {|x| -x } ) 408 assert_equal(-201, o.foo(1,2) {|x| -x } ) 409 assert_equal(-100, o.foo(1) {|x| -x } ) 410 assert_raise(ArgumentError) { o.foo() } 411 end 412 413 def test_duplicate_argument 414 assert_raise(SyntaxError) do 415 eval <<-END, nil, __FILE__, __LINE__+1 416 1.times {|&b?| } 417 END 418 end 419 420 assert_raise(SyntaxError) do 421 eval <<-END, nil, __FILE__, __LINE__+1 422 1.times {|a, a|} 423 END 424 end 425 426 assert_raise(SyntaxError) do 427 eval <<-END, nil, __FILE__, __LINE__+1 428 def foo(a, a); end 429 END 430 end 431 end 432 433 def test_define_singleton_error 434 assert_raise(SyntaxError) do 435 eval <<-END, nil, __FILE__, __LINE__+1 436 def ("foo").foo; end 437 END 438 end 439 end 440 441 def test_backquote 442 t = Object.new 443 444 assert_nothing_raised do 445 eval <<-END, nil, __FILE__, __LINE__+1 446 def t.`(x); "foo" + x + "bar"; end 447 END 448 end 449 a = b = nil 450 assert_nothing_raised do 451 eval <<-END, nil, __FILE__, __LINE__+1 452 a = t.` "zzz" 453 1.times {|;z| t.` ("zzz") } 454 END 455 t.instance_eval <<-END, __FILE__, __LINE__+1 456 b = `zzz` 457 END 458 end 459 assert_equal("foozzzbar", a) 460 assert_equal("foozzzbar", b) 461 end 462 463 def test_carrige_return 464 assert_equal(2, eval("1 +\r\n1")) 465 end 466 467 def test_string 468 assert_raise(SyntaxError) do 469 eval '"\xg1"' 470 end 471 472 assert_raise(SyntaxError) do 473 eval '"\u{1234"' 474 end 475 476 assert_raise(SyntaxError) do 477 eval '"\M1"' 478 end 479 480 assert_raise(SyntaxError) do 481 eval '"\C1"' 482 end 483 484 assert_equal("\x81", eval('"\C-\M-a"')) 485 assert_equal("\177", eval('"\c?"')) 486 end 487 488 def test_question 489 assert_raise(SyntaxError) { eval('?') } 490 assert_raise(SyntaxError) { eval('? ') } 491 assert_raise(SyntaxError) { eval("?\n") } 492 assert_raise(SyntaxError) { eval("?\t") } 493 assert_raise(SyntaxError) { eval("?\v") } 494 assert_raise(SyntaxError) { eval("?\r") } 495 assert_raise(SyntaxError) { eval("?\f") } 496 assert_equal("\u{1234}", eval("?\u{1234}")) 497 assert_equal("\u{1234}", eval('?\u{1234}')) 498 end 499 500 def test_percent 501 assert_equal(:foo, eval('%s(foo)')) 502 assert_raise(SyntaxError) { eval('%s') } 503 assert_raise(SyntaxError) { eval('%ss') } 504 assert_raise(SyntaxError) { eval('%z()') } 505 end 506 507 def test_symbol 508 bug = '[ruby-dev:41447]' 509 sym = "foo\0bar".to_sym 510 assert_nothing_raised(SyntaxError, bug) do 511 assert_equal(sym, eval(":'foo\0bar'")) 512 end 513 assert_nothing_raised(SyntaxError, bug) do 514 assert_equal(sym, eval(':"foo\u0000bar"')) 515 end 516 assert_nothing_raised(SyntaxError, bug) do 517 assert_equal(sym, eval(':"foo\u{0}bar"')) 518 end 519 assert_raise(SyntaxError) do 520 eval ':"foo\u{}bar"' 521 end 522 end 523 524 def test_parse_string 525 assert_raise(SyntaxError) do 526 eval <<-END, nil, __FILE__, __LINE__+1 527/ 528 END 529 end 530 end 531 532 def test_here_document 533 x = nil 534 535 assert_raise(SyntaxError) do 536 eval %Q( 537<\<FOO 538 ) 539 end 540 541 assert_nothing_raised(SyntaxError) do 542 x = eval %q( 543<<FOO 544#$ 545FOO 546 ) 547 end 548 assert_equal "\#$\n", x 549 550 assert_raise(SyntaxError) do 551 eval %Q( 552<\<\" 553 ) 554 end 555 556 assert_raise(SyntaxError) do 557 eval %q( 558<<`` 559 ) 560 end 561 562 assert_raise(SyntaxError) do 563 eval %q( 564<<-- 565 ) 566 end 567 568 assert_nothing_raised(SyntaxError) do 569 x = eval %q( 570<<FOO 571#$ 572foo 573FOO 574 ) 575 end 576 assert_equal "\#$\nfoo\n", x 577 578 assert_nothing_raised do 579 eval "x = <<""FOO\r\n1\r\nFOO" 580 end 581 assert_equal("1\n", x) 582 end 583 584 def test_magic_comment 585 x = nil 586 assert_nothing_raised do 587 eval <<-END, nil, __FILE__, __LINE__+1 588# coding = utf-8 589x = __ENCODING__ 590 END 591 end 592 assert_equal(Encoding.find("UTF-8"), x) 593 594 assert_raise(ArgumentError) do 595 eval <<-END, nil, __FILE__, __LINE__+1 596# coding = foobarbazquxquux_dummy_enconding 597x = __ENCODING__ 598 END 599 end 600 end 601 602 def test_utf8_bom 603 x = nil 604 assert_nothing_raised do 605 eval "\xef\xbb\xbf x = __ENCODING__" 606 end 607 assert_equal(Encoding.find("UTF-8"), x) 608 assert_raise(NameError) { eval "\xef" } 609 end 610 611 def test_dot_in_next_line 612 x = nil 613 assert_nothing_raised do 614 eval <<-END, nil, __FILE__, __LINE__+1 615 x = 1 616 .to_s 617 END 618 end 619 assert_equal("1", x) 620 end 621 622 def test_pow_asgn 623 x = 3 624 assert_nothing_raised { eval("x **= 2") } 625 assert_equal(9, x) 626 end 627 628 def test_embedded_rd 629 assert_raise(SyntaxError) do 630 eval <<-END, nil, __FILE__, __LINE__+1 631=begin 632 END 633 end 634 end 635 636 def test_float 637 assert_equal(1.0/0, eval("1e10000")) 638 assert_raise(SyntaxError) { eval('1_E') } 639 assert_raise(SyntaxError) { eval('1E1E1') } 640 end 641 642 def test_global_variable 643 assert_equal(nil, eval('$-x')) 644 assert_equal(nil, eval('alias $preserve_last_match $&')) 645 assert_equal(nil, eval('alias $& $test_parse_foobarbazqux')) 646 $test_parse_foobarbazqux = nil 647 assert_equal(nil, $&) 648 assert_equal(nil, eval('alias $& $preserve_last_match')) 649 assert_raise(SyntaxError) { eval('$#') } 650 end 651 652 def test_invalid_instance_variable 653 assert_raise(SyntaxError) { eval('@#') } 654 end 655 656 def test_invalid_class_variable 657 assert_raise(SyntaxError) { eval('@@1') } 658 end 659 660 def test_invalid_char 661 x = 1 662 assert_equal(1, eval("\x01x")) 663 assert_equal(nil, eval("\x04x")) 664 end 665 666 def test_literal_concat 667 x = "baz" 668 assert_equal("foobarbaz", eval('"foo" "bar#{x}"')) 669 end 670 671 def test_unassignable 672 assert_raise(SyntaxError) do 673 eval %q(self = 1) 674 end 675 assert_raise(SyntaxError) do 676 eval %q(nil = 1) 677 end 678 assert_raise(SyntaxError) do 679 eval %q(true = 1) 680 end 681 assert_raise(SyntaxError) do 682 eval %q(false = 1) 683 end 684 assert_raise(SyntaxError) do 685 eval %q(__FILE__ = 1) 686 end 687 assert_raise(SyntaxError) do 688 eval %q(__LINE__ = 1) 689 end 690 assert_raise(SyntaxError) do 691 eval %q(__ENCODING__ = 1) 692 end 693 assert_raise(SyntaxError) do 694 eval <<-END, nil, __FILE__, __LINE__+1 695 def foo 696 FOO = 1 697 end 698 END 699 end 700 end 701 702 def test_block_dup 703 assert_raise(SyntaxError) do 704 eval <<-END, nil, __FILE__, __LINE__+1 705 foo(&proc{}) {} 706 END 707 end 708 end 709 710 def test_set_backref 711 assert_raise(SyntaxError) do 712 eval <<-END, nil, __FILE__, __LINE__+1 713 $& = 1 714 END 715 end 716 end 717 718 def test_arg_concat 719 o = Object.new 720 class << o; self; end.instance_eval do 721 define_method(:[]=) {|*r, &b| b.call(r) } 722 end 723 r = nil 724 assert_nothing_raised do 725 eval <<-END, nil, __FILE__, __LINE__+1 726 o[&proc{|x| r = x }] = 1 727 END 728 end 729 assert_equal([1], r) 730 end 731 732 def test_void_expr_stmts_value 733 # This test checks if void contexts are warned correctly. 734 # Thus, warnings MUST NOT be suppressed. 735 $VERBOSE = true 736 stderr = $stderr 737 $stderr = StringIO.new("") 738 x = 1 739 assert_nil eval("x; nil") 740 assert_nil eval("1+1; nil") 741 assert_nil eval("TestParse; nil") 742 assert_nil eval("::TestParse; nil") 743 assert_nil eval("x..x; nil") 744 assert_nil eval("x...x; nil") 745 assert_nil eval("self; nil") 746 assert_nil eval("nil; nil") 747 assert_nil eval("true; nil") 748 assert_nil eval("false; nil") 749 assert_nil eval("defined?(1); nil") 750 751 assert_raise(SyntaxError) do 752 eval %q(1; next; 2) 753 end 754 755 o = Object.new 756 assert_nothing_raised do 757 eval <<-END, nil, __FILE__, __LINE__+1 758 x = def o.foo; end 759 END 760 end 761 assert_equal(14, $stderr.string.lines.to_a.size) 762 $stderr = stderr 763 end 764 765 def test_assign_in_conditional 766 assert_raise(SyntaxError) do 767 eval <<-END, nil, __FILE__, __LINE__+1 768 (x, y = 1, 2) ? 1 : 2 769 END 770 end 771 772 assert_nothing_raised do 773 eval <<-END, nil, __FILE__, __LINE__+1 774 if @x = true 775 1 776 else 777 2 778 end 779 END 780 end 781 end 782 783 def test_literal_in_conditional 784 assert_nothing_raised do 785 eval <<-END, nil, __FILE__, __LINE__+1 786 "foo" ? 1 : 2 787 END 788 end 789 790 assert_nothing_raised do 791 x = "bar" 792 eval <<-END, nil, __FILE__, __LINE__+1 793 /foo#{x}baz/ ? 1 : 2 794 END 795 end 796 797 assert_nothing_raised do 798 eval <<-END, nil, __FILE__, __LINE__+1 799 (true..false) ? 1 : 2 800 END 801 end 802 803 assert_nothing_raised do 804 eval <<-END, nil, __FILE__, __LINE__+1 805 ("foo".."bar") ? 1 : 2 806 END 807 end 808 809 assert_nothing_raised do 810 x = "bar" 811 eval <<-END, nil, __FILE__, __LINE__+1 812 :"foo#{"x"}baz" ? 1 : 2 813 END 814 end 815 end 816 817 def test_no_blockarg 818 assert_raise(SyntaxError) do 819 eval <<-END, nil, __FILE__, __LINE__+1 820 yield(&:+) 821 END 822 end 823 end 824 825 def test_intern 826 assert_equal(':""', ''.intern.inspect) 827 assert_equal(':$foo', '$foo'.intern.inspect) 828 assert_equal(':"!foo"', '!foo'.intern.inspect) 829 assert_equal(':"foo=="', "foo==".intern.inspect) 830 end 831 832 def test_all_symbols 833 x = Symbol.all_symbols 834 assert_kind_of(Array, x) 835 assert(x.all? {|s| s.is_a?(Symbol) }) 836 end 837 838 def test_is_class_id 839 c = Class.new 840 assert_raise(NameError) do 841 c.instance_eval { remove_class_variable(:@var) } 842 end 843 end 844 845 def test_method_block_location 846 bug5614 = '[ruby-core:40936]' 847 expected = nil 848 e = assert_raise(NoMethodError) do 849 1.times do 850 expected = __LINE__+1 851 end.print do 852 # 853 end 854 end 855 actual = e.backtrace.first[/\A#{Regexp.quote(__FILE__)}:(\d+):/o, 1].to_i 856 assert_equal(expected, actual, bug5614) 857 end 858end 859