1# frozen_string_literal: false 2require 'test/unit' 3 4class TestSyntax < Test::Unit::TestCase 5 using Module.new { 6 refine(Object) do 7 def `(s) #` 8 s 9 end 10 end 11 } 12 13 def assert_syntax_files(test) 14 srcdir = File.expand_path("../../..", __FILE__) 15 srcdir = File.join(srcdir, test) 16 assert_separately(%W[--disable-gem - #{srcdir}], 17 __FILE__, __LINE__, <<-'eom', timeout: Float::INFINITY) 18 dir = ARGV.shift 19 for script in Dir["#{dir}/**/*.rb"].sort 20 assert_valid_syntax(IO::read(script), script) 21 end 22 eom 23 end 24 25 def test_syntax_lib; assert_syntax_files("lib"); end 26 def test_syntax_sample; assert_syntax_files("sample"); end 27 def test_syntax_ext; assert_syntax_files("ext"); end 28 def test_syntax_test; assert_syntax_files("test"); end 29 30 def test_defined_empty_argument 31 bug8220 = '[ruby-core:53999] [Bug #8220]' 32 assert_ruby_status(%w[--disable-gem], 'puts defined? ()', bug8220) 33 end 34 35 def test_must_ascii_compatible 36 require 'tempfile' 37 f = Tempfile.new("must_ac_") 38 Encoding.list.each do |enc| 39 next unless enc.ascii_compatible? 40 make_tmpsrc(f, "# -*- coding: #{enc.name} -*-") 41 assert_nothing_raised(ArgumentError, enc.name) {load(f.path)} 42 end 43 Encoding.list.each do |enc| 44 next if enc.ascii_compatible? 45 make_tmpsrc(f, "# -*- coding: #{enc.name} -*-") 46 assert_raise(ArgumentError, enc.name) {load(f.path)} 47 end 48 ensure 49 f&.close! 50 end 51 52 def test_script_lines 53 require 'tempfile' 54 f = Tempfile.new("bug4361_") 55 bug4361 = '[ruby-dev:43168]' 56 with_script_lines do |debug_lines| 57 Encoding.list.each do |enc| 58 next unless enc.ascii_compatible? 59 make_tmpsrc(f, "# -*- coding: #{enc.name} -*-\n#----------------") 60 load(f.path) 61 assert_equal([f.path], debug_lines.keys) 62 assert_equal([enc, enc], debug_lines[f.path].map(&:encoding), bug4361) 63 end 64 end 65 ensure 66 f&.close! 67 end 68 69 def test_newline_in_block_parameters 70 bug = '[ruby-dev:45292]' 71 ["", "a", "a, b"].product(["", ";x", [";", "x"]]) do |params| 72 params = ["|", *params, "|"].join("\n") 73 assert_valid_syntax("1.times{#{params}}", __FILE__, "#{bug} #{params.inspect}") 74 end 75 end 76 77 tap do |_, 78 bug6115 = '[ruby-dev:45308]', 79 blockcall = '["elem"].each_with_object [] do end', 80 methods = [['map', 'no'], ['inject([])', 'with']], 81 blocks = [['do end', 'do'], ['{}', 'brace']], 82 *| 83 [%w'. dot', %w':: colon'].product(methods, blocks) do |(c, n1), (m, n2), (b, n3)| 84 m = m.tr_s('()', ' ').strip if n2 == 'do' 85 name = "test_#{n3}_block_after_blockcall_#{n1}_#{n2}_arg" 86 code = "#{blockcall}#{c}#{m} #{b}" 87 define_method(name) {assert_valid_syntax(code, bug6115)} 88 end 89 end 90 91 def test_do_block_in_cmdarg 92 bug9726 = '[ruby-core:61950] [Bug #9726]' 93 assert_valid_syntax("tap (proc do end)", __FILE__, bug9726) 94 end 95 96 def test_normal_argument 97 assert_valid_syntax('def foo(x) end') 98 assert_syntax_error('def foo(X) end', /constant/) 99 assert_syntax_error('def foo(@x) end', /instance variable/) 100 assert_syntax_error('def foo(@@x) end', /class variable/) 101 end 102 103 def test_optional_argument 104 assert_valid_syntax('def foo(x=nil) end') 105 assert_syntax_error('def foo(X=nil) end', /constant/) 106 assert_syntax_error('def foo(@x=nil) end', /instance variable/) 107 assert_syntax_error('def foo(@@x=nil) end', /class variable/) 108 end 109 110 def test_keyword_rest 111 bug5989 = '[ruby-core:42455]' 112 assert_valid_syntax("def kwrest_test(**a) a; end", __FILE__, bug5989) 113 assert_valid_syntax("def kwrest_test2(**a, &b) end", __FILE__, bug5989) 114 o = Object.new 115 def o.kw(**a) a end 116 assert_equal({}, o.kw, bug5989) 117 assert_equal({foo: 1}, o.kw(foo: 1), bug5989) 118 assert_equal({foo: 1, bar: 2}, o.kw(foo: 1, bar: 2), bug5989) 119 EnvUtil.under_gc_stress do 120 eval("def o.m(k: 0) k end") 121 end 122 assert_equal(42, o.m(k: 42), '[ruby-core:45744]') 123 bug7922 = '[ruby-core:52744] [Bug #7922]' 124 def o.bug7922(**) end 125 assert_nothing_raised(ArgumentError, bug7922) {o.bug7922(foo: 42)} 126 end 127 128 class KW2 129 def kw(k1: 1, k2: 2) [k1, k2] end 130 end 131 132 def test_keyword_splat 133 assert_valid_syntax("foo(**h)", __FILE__) 134 o = KW2.new 135 h = {k1: 11, k2: 12} 136 assert_equal([11, 12], o.kw(**h)) 137 assert_equal([11, 12], o.kw(k2: 22, **h)) 138 assert_equal([11, 22], o.kw(**h, **{k2: 22})) 139 assert_equal([11, 12], o.kw(**{k2: 22}, **h)) 140 end 141 142 def test_keyword_duplicated_splat 143 bug10315 = '[ruby-core:65368] [Bug #10315]' 144 145 o = KW2.new 146 assert_equal([23, 2], o.kw(**{k1: 22}, **{k1: 23}), bug10315) 147 148 h = {k3: 31} 149 assert_raise(ArgumentError) {o.kw(**h)} 150 h = {"k1"=>11, k2: 12} 151 assert_raise(TypeError) {o.kw(**h)} 152 end 153 154 def test_keyword_duplicated 155 bug10315 = '[ruby-core:65625] [Bug #10315]' 156 a = [] 157 def a.add(x) push(x); x; end 158 def a.f(k:) k; end 159 a.clear 160 r = nil 161 assert_warn(/duplicated/) {r = eval("a.f(k: a.add(1), k: a.add(2))")} 162 assert_equal(2, r) 163 assert_equal([1, 2], a, bug10315) 164 a.clear 165 r = nil 166 assert_warn(/duplicated/) {r = eval("a.f({k: a.add(1), k: a.add(2)})")} 167 assert_equal(2, r) 168 assert_equal([1, 2], a, bug10315) 169 end 170 171 def test_keyword_empty_splat 172 assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}") 173 begin; 174 bug10719 = '[ruby-core:67446] [Bug #10719]' 175 assert_valid_syntax("foo(a: 1, **{})", bug10719) 176 end; 177 assert_separately([], "#{<<-"begin;"}\n#{<<-'end;'}") 178 begin; 179 bug13756 = '[ruby-core:82113] [Bug #13756]' 180 assert_valid_syntax("defined? foo(**{})", bug13756) 181 end; 182 assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}") 183 begin; 184 bug15271 = '[ruby-core:89648] [Bug #15271]' 185 assert_valid_syntax("a **{}", bug15271) 186 end; 187 end 188 189 def test_keyword_self_reference 190 bug9593 = '[ruby-core:61299] [Bug #9593]' 191 o = Object.new 192 assert_warn(/circular argument reference - var/) do 193 o.instance_eval("def foo(var: defined?(var)) var end") 194 end 195 assert_equal(42, o.foo(var: 42)) 196 assert_equal("local-variable", o.foo, bug9593) 197 198 o = Object.new 199 assert_warn(/circular argument reference - var/) do 200 o.instance_eval("def foo(var: var) var end") 201 end 202 assert_nil(o.foo, bug9593) 203 204 o = Object.new 205 assert_warn(/circular argument reference - var/) do 206 o.instance_eval("def foo(var: bar(var)) var end") 207 end 208 209 o = Object.new 210 assert_warn(/circular argument reference - var/) do 211 o.instance_eval("def foo(var: bar {var}) var end") 212 end 213 214 o = Object.new 215 assert_warn("") do 216 o.instance_eval("def foo(var: bar {|var| var}) var end") 217 end 218 219 o = Object.new 220 assert_warn("") do 221 o.instance_eval("def foo(var: def bar(var) var; end) var end") 222 end 223 224 o = Object.new 225 assert_warn("") do 226 o.instance_eval("proc {|var: 1| var}") 227 end 228 end 229 230 def test_keyword_invalid_name 231 bug11663 = '[ruby-core:71356] [Bug #11663]' 232 233 o = o = Object.new 234 assert_syntax_error('def o.foo(arg1?:) end', /arg1\?/, bug11663) 235 assert_syntax_error('def o.foo(arg1?:, arg2:) end', /arg1\?/, bug11663) 236 assert_syntax_error('proc {|arg1?:|}', /arg1\?/, bug11663) 237 assert_syntax_error('proc {|arg1?:, arg2:|}', /arg1\?/, bug11663) 238 239 bug10545 = '[ruby-dev:48742] [Bug #10545]' 240 assert_syntax_error('def o.foo(FOO: a) end', /constant/, bug10545) 241 assert_syntax_error('def o.foo(@foo: a) end', /instance variable/) 242 assert_syntax_error('def o.foo(@@foo: a) end', /class variable/) 243 end 244 245 def test_optional_self_reference 246 bug9593 = '[ruby-core:61299] [Bug #9593]' 247 o = Object.new 248 assert_warn(/circular argument reference - var/) do 249 o.instance_eval("def foo(var = defined?(var)) var end") 250 end 251 assert_equal(42, o.foo(42)) 252 assert_equal("local-variable", o.foo, bug9593) 253 254 o = Object.new 255 assert_warn(/circular argument reference - var/) do 256 o.instance_eval("def foo(var = var) var end") 257 end 258 assert_nil(o.foo, bug9593) 259 260 o = Object.new 261 assert_warn(/circular argument reference - var/) do 262 o.instance_eval("def foo(var = bar(var)) var end") 263 end 264 265 o = Object.new 266 assert_warn(/circular argument reference - var/) do 267 o.instance_eval("def foo(var = bar {var}) var end") 268 end 269 270 o = Object.new 271 assert_warn(/circular argument reference - var/) do 272 o.instance_eval("def foo(var = (def bar;end; var)) var end") 273 end 274 275 o = Object.new 276 assert_warn(/circular argument reference - var/) do 277 o.instance_eval("def foo(var = (def self.bar;end; var)) var end") 278 end 279 280 o = Object.new 281 assert_warn("") do 282 o.instance_eval("def foo(var = bar {|var| var}) var end") 283 end 284 285 o = Object.new 286 assert_warn("") do 287 o.instance_eval("def foo(var = def bar(var) var; end) var end") 288 end 289 290 o = Object.new 291 assert_warn("") do 292 o.instance_eval("proc {|var = 1| var}") 293 end 294 end 295 296 def test_warn_grouped_expression 297 bug5214 = '[ruby-core:39050]' 298 assert_warning("", bug5214) do 299 assert_valid_syntax("foo \\\n(\n true)", "test", verbose: true) 300 end 301 end 302 303 def test_warn_unreachable 304 assert_warning("test:3: warning: statement not reached\n") do 305 code = "loop do\n" "break\n" "foo\n" "end" 306 assert_valid_syntax(code, "test", verbose: true) 307 end 308 end 309 310 def test_warn_balanced 311 warning = <<WARN 312test:1: warning: `%s' after local variable or literal is interpreted as binary operator 313test:1: warning: even though it seems like %s 314WARN 315 [ 316 [:**, "argument prefix"], 317 [:*, "argument prefix"], 318 [:<<, "here document"], 319 [:&, "argument prefix"], 320 [:+, "unary operator"], 321 [:-, "unary operator"], 322 [:/, "regexp literal"], 323 [:%, "string literal"], 324 ].each do |op, syn| 325 all_assertions do |a| 326 ["puts 1 #{op}0", "puts :a #{op}0", "m = 1; puts m #{op}0"].each do |src| 327 a.for(src) do 328 assert_warning(warning % [op, syn], src) do 329 assert_valid_syntax(src, "test", verbose: true) 330 end 331 end 332 end 333 end 334 end 335 end 336 337 def test_cmd_symbol_after_keyword 338 bug6347 = '[ruby-dev:45563]' 339 assert_not_label(:foo, 'if true then not_label:foo end', bug6347) 340 assert_not_label(:foo, 'if false; else not_label:foo end', bug6347) 341 assert_not_label(:foo, 'begin not_label:foo end', bug6347) 342 assert_not_label(:foo, 'begin ensure not_label:foo end', bug6347) 343 end 344 345 def test_cmd_symbol_in_string 346 bug6347 = '[ruby-dev:45563]' 347 assert_not_label(:foo, '"#{not_label:foo}"', bug6347) 348 end 349 350 def test_cmd_symbol_singleton_class 351 bug6347 = '[ruby-dev:45563]' 352 @not_label = self 353 assert_not_label(:foo, 'class << not_label:foo; end', bug6347) 354 end 355 356 def test_cmd_symbol_superclass 357 bug6347 = '[ruby-dev:45563]' 358 @not_label = Object 359 assert_not_label(:foo, 'class Foo < not_label:foo; end', bug6347) 360 end 361 362 def test_no_label_with_percent 363 assert_syntax_error('{%"a": 1}', /unexpected ':'/) 364 assert_syntax_error("{%'a': 1}", /unexpected ':'/) 365 assert_syntax_error('{%Q"a": 1}', /unexpected ':'/) 366 assert_syntax_error("{%Q'a': 1}", /unexpected ':'/) 367 assert_syntax_error('{%q"a": 1}', /unexpected ':'/) 368 assert_syntax_error("{%q'a': 1}", /unexpected ':'/) 369 end 370 371 def test_block_after_cond 372 bug10653 = '[ruby-dev:48790] [Bug #10653]' 373 assert_valid_syntax("false ? raise {} : tap {}", bug10653) 374 assert_valid_syntax("false ? raise do end : tap do end", bug10653) 375 end 376 377 def test_paren_after_label 378 bug11456 = '[ruby-dev:49221] [Bug #11456]' 379 assert_valid_syntax("{foo: (1 rescue 0)}", bug11456) 380 assert_valid_syntax("{foo: /=/}", bug11456) 381 end 382 383 def test_percent_string_after_label 384 bug11812 = '[ruby-core:72084]' 385 assert_valid_syntax('{label:%w(*)}', bug11812) 386 assert_valid_syntax('{label: %w(*)}', bug11812) 387 end 388 389 def test_heredoc_after_label 390 bug11849 = '[ruby-core:72396] [Bug #11849]' 391 assert_valid_syntax("{label:<<DOC\n""DOC\n""}", bug11849) 392 assert_valid_syntax("{label:<<-DOC\n""DOC\n""}", bug11849) 393 assert_valid_syntax("{label:<<~DOC\n""DOC\n""}", bug11849) 394 assert_valid_syntax("{label: <<DOC\n""DOC\n""}", bug11849) 395 assert_valid_syntax("{label: <<-DOC\n""DOC\n""}", bug11849) 396 assert_valid_syntax("{label: <<~DOC\n""DOC\n""}", bug11849) 397 end 398 399 def test_cmdarg_kwarg_lvar_clashing_method 400 bug12073 = '[ruby-core:73816] [Bug#12073]' 401 a = a = 1 402 assert_valid_syntax("a b: 1") 403 assert_valid_syntax("a = 1; a b: 1", bug12073) 404 end 405 406 def test_duplicated_arg 407 assert_syntax_error("def foo(a, a) end", /duplicated argument name/) 408 assert_valid_syntax("def foo(_, _) end") 409 (obj = Object.new).instance_eval("def foo(_, x, _) x end") 410 assert_equal(2, obj.foo(1, 2, 3)) 411 end 412 413 def test_duplicated_rest 414 assert_syntax_error("def foo(a, *a) end", /duplicated argument name/) 415 assert_valid_syntax("def foo(_, *_) end") 416 (obj = Object.new).instance_eval("def foo(_, x, *_) x end") 417 assert_equal(2, obj.foo(1, 2, 3)) 418 end 419 420 def test_duplicated_opt 421 assert_syntax_error("def foo(a, a=1) end", /duplicated argument name/) 422 assert_valid_syntax("def foo(_, _=1) end") 423 (obj = Object.new).instance_eval("def foo(_, x, _=42) x end") 424 assert_equal(2, obj.foo(1, 2)) 425 end 426 427 def test_duplicated_opt_rest 428 assert_syntax_error("def foo(a=1, *a) end", /duplicated argument name/) 429 assert_valid_syntax("def foo(_=1, *_) end") 430 (obj = Object.new).instance_eval("def foo(_, x=42, *_) x end") 431 assert_equal(42, obj.foo(1)) 432 assert_equal(2, obj.foo(1, 2)) 433 end 434 435 def test_duplicated_rest_opt 436 assert_syntax_error("def foo(*a, a=1) end", /duplicated argument name/) 437 end 438 439 def test_duplicated_rest_post 440 assert_syntax_error("def foo(*a, a) end", /duplicated argument name/) 441 assert_valid_syntax("def foo(*_, _) end") 442 (obj = Object.new).instance_eval("def foo(*_, x, _) x end") 443 assert_equal(2, obj.foo(1, 2, 3)) 444 assert_equal(2, obj.foo(2, 3)) 445 (obj = Object.new).instance_eval("def foo(*_, _, x) x end") 446 assert_equal(3, obj.foo(1, 2, 3)) 447 assert_equal(3, obj.foo(2, 3)) 448 end 449 450 def test_duplicated_opt_post 451 assert_syntax_error("def foo(a=1, a) end", /duplicated argument name/) 452 assert_valid_syntax("def foo(_=1, _) end") 453 (obj = Object.new).instance_eval("def foo(_=1, x, _) x end") 454 assert_equal(2, obj.foo(1, 2, 3)) 455 assert_equal(2, obj.foo(2, 3)) 456 (obj = Object.new).instance_eval("def foo(_=1, _, x) x end") 457 assert_equal(3, obj.foo(1, 2, 3)) 458 assert_equal(3, obj.foo(2, 3)) 459 end 460 461 def test_duplicated_kw 462 assert_syntax_error("def foo(a, a: 1) end", /duplicated argument name/) 463 assert_valid_syntax("def foo(_, _: 1) end") 464 (obj = Object.new).instance_eval("def foo(_, x, _: 1) x end") 465 assert_equal(3, obj.foo(2, 3)) 466 assert_equal(3, obj.foo(2, 3, _: 42)) 467 (obj = Object.new).instance_eval("def foo(x, _, _: 1) x end") 468 assert_equal(2, obj.foo(2, 3)) 469 assert_equal(2, obj.foo(2, 3, _: 42)) 470 end 471 472 def test_duplicated_rest_kw 473 assert_syntax_error("def foo(*a, a: 1) end", /duplicated argument name/) 474 assert_nothing_raised {def foo(*_, _: 1) end} 475 (obj = Object.new).instance_eval("def foo(*_, x: 42, _: 1) x end") 476 assert_equal(42, obj.foo(42)) 477 assert_equal(42, obj.foo(2, _: 0)) 478 assert_equal(2, obj.foo(x: 2, _: 0)) 479 end 480 481 def test_duplicated_opt_kw 482 assert_syntax_error("def foo(a=1, a: 1) end", /duplicated argument name/) 483 assert_valid_syntax("def foo(_=1, _: 1) end") 484 (obj = Object.new).instance_eval("def foo(_=42, x, _: 1) x end") 485 assert_equal(0, obj.foo(0)) 486 assert_equal(0, obj.foo(0, _: 3)) 487 end 488 489 def test_duplicated_kw_kwrest 490 assert_syntax_error("def foo(a: 1, **a) end", /duplicated argument name/) 491 assert_valid_syntax("def foo(_: 1, **_) end") 492 (obj = Object.new).instance_eval("def foo(_: 1, x: 42, **_) x end") 493 assert_equal(42, obj.foo()) 494 assert_equal(42, obj.foo(a: 0)) 495 assert_equal(42, obj.foo(_: 0, a: 0)) 496 assert_equal(1, obj.foo(_: 0, x: 1, a: 0)) 497 end 498 499 def test_duplicated_rest_kwrest 500 assert_syntax_error("def foo(*a, **a) end", /duplicated argument name/) 501 assert_valid_syntax("def foo(*_, **_) end") 502 (obj = Object.new).instance_eval("def foo(*_, x, **_) x end") 503 assert_equal(1, obj.foo(1)) 504 assert_equal(1, obj.foo(1, a: 0)) 505 assert_equal(2, obj.foo(1, 2, a: 0)) 506 end 507 508 def test_duplicated_opt_kwrest 509 assert_syntax_error("def foo(a=1, **a) end", /duplicated argument name/) 510 assert_valid_syntax("def foo(_=1, **_) end") 511 (obj = Object.new).instance_eval("def foo(_=42, x, **_) x end") 512 assert_equal(1, obj.foo(1)) 513 assert_equal(1, obj.foo(1, a: 0)) 514 assert_equal(1, obj.foo(0, 1, a: 0)) 515 end 516 517 def test_duplicated_when 518 w = 'warning: duplicated when clause is ignored' 519 assert_warning(/3: #{w}.+4: #{w}.+4: #{w}.+5: #{w}.+5: #{w}/m){ 520 eval %q{ 521 case 1 522 when 1, 1 523 when 1, 1 524 when 1, 1 525 end 526 } 527 } 528 assert_warning(/#{w}/){#/3: #{w}.+4: #{w}.+5: #{w}.+5: #{w}/m){ 529 a = a = 1 530 eval %q{ 531 case 1 532 when 1, 1 533 when 1, a 534 when 1, 1 535 end 536 } 537 } 538 end 539 540 def test_invalid_break 541 assert_syntax_error("def m; break; end", /Invalid break/) 542 assert_syntax_error('/#{break}/', /Invalid break/) 543 assert_syntax_error('/#{break}/o', /Invalid break/) 544 end 545 546 def test_invalid_next 547 assert_syntax_error("def m; next; end", /Invalid next/) 548 assert_syntax_error('/#{next}/', /Invalid next/) 549 assert_syntax_error('/#{next}/o', /Invalid next/) 550 end 551 552 def test_lambda_with_space 553 feature6390 = '[ruby-dev:45605]' 554 assert_valid_syntax("-> (x, y) {}", __FILE__, feature6390) 555 end 556 557 def test_do_block_in_cmdarg_begin 558 bug6419 = '[ruby-dev:45631]' 559 assert_valid_syntax("p begin 1.times do 1 end end", __FILE__, bug6419) 560 end 561 562 def test_do_block_in_call_args 563 bug9308 = '[ruby-core:59342] [Bug #9308]' 564 assert_valid_syntax("bar def foo; self.each do end end", bug9308) 565 end 566 567 def test_do_block_in_lambda 568 bug11107 = '[ruby-core:69017] [Bug #11107]' 569 assert_valid_syntax('p ->() do a() do end end', bug11107) 570 end 571 572 def test_do_block_after_lambda 573 bug11380 = '[ruby-core:70067] [Bug #11380]' 574 assert_valid_syntax('p -> { :hello }, a: 1 do end', bug11380) 575 end 576 577 def test_reserved_method_no_args 578 bug6403 = '[ruby-dev:45626]' 579 assert_valid_syntax("def self; :foo; end", __FILE__, bug6403) 580 end 581 582 def test_unassignable 583 gvar = global_variables 584 %w[self nil true false __FILE__ __LINE__ __ENCODING__].each do |kwd| 585 assert_raise(SyntaxError) {eval("#{kwd} = nil")} 586 assert_equal(gvar, global_variables) 587 end 588 end 589 590 Bug7559 = '[ruby-dev:46737]' 591 592 def test_lineno_command_call_quote 593 expected = __LINE__ + 1 594 actual = caller_lineno "a 595b 596c 597d 598e" 599 assert_equal(expected, actual, "#{Bug7559}: ") 600 end 601 602 def assert_dedented_heredoc(expect, result, mesg = "") 603 all_assertions(mesg) do |a| 604 %w[eos "eos" 'eos' `eos`].each do |eos| 605 a.for(eos) do 606 assert_equal(eval("<<-#{eos}\n#{expect}eos\n"), 607 eval("<<~#{eos}\n#{result}eos\n")) 608 end 609 end 610 end 611 end 612 613 def test_dedented_heredoc_without_indentation 614 result = " y\n" \ 615 "z\n" 616 expect = result 617 assert_dedented_heredoc(expect, result) 618 end 619 620 def test_dedented_heredoc_with_indentation 621 result = " a\n" \ 622 " b\n" 623 expect = " a\n" \ 624 "b\n" 625 assert_dedented_heredoc(expect, result) 626 end 627 628 def test_dedented_heredoc_with_blank_less_indented_line 629 # the blank line has two leading spaces 630 result = " a\n" \ 631 " \n" \ 632 " b\n" 633 expect = "a\n" \ 634 "\n" \ 635 "b\n" 636 assert_dedented_heredoc(expect, result) 637 end 638 639 def test_dedented_heredoc_with_blank_less_indented_line_escaped 640 result = " a\n" \ 641 "\\ \\ \n" \ 642 " b\n" 643 expect = result 644 assert_dedented_heredoc(expect, result) 645 end 646 647 def test_dedented_heredoc_with_blank_more_indented_line 648 # the blank line has six leading spaces 649 result = " a\n" \ 650 " \n" \ 651 " b\n" 652 expect = "a\n" \ 653 " \n" \ 654 "b\n" 655 assert_dedented_heredoc(expect, result) 656 end 657 658 def test_dedented_heredoc_with_blank_more_indented_line_escaped 659 result = " a\n" \ 660 "\\ \\ \\ \\ \\ \\ \n" \ 661 " b\n" 662 expect = result 663 assert_dedented_heredoc(expect, result) 664 end 665 666 def test_dedented_heredoc_with_empty_line 667 result = " This would contain specially formatted text.\n" \ 668 "\n" \ 669 " That might span many lines\n" 670 expect = 'This would contain specially formatted text.'"\n" \ 671 ''"\n" \ 672 'That might span many lines'"\n" 673 assert_dedented_heredoc(expect, result) 674 end 675 676 def test_dedented_heredoc_with_interpolated_expression 677 result = ' #{1}a'"\n" \ 678 " zy\n" 679 expect = ' #{1}a'"\n" \ 680 "zy\n" 681 assert_dedented_heredoc(expect, result) 682 end 683 684 def test_dedented_heredoc_with_interpolated_string 685 w = w = "" 686 result = " \#{mesg} a\n" \ 687 " zy\n" 688 expect = '#{mesg} a'"\n" \ 689 ' zy'"\n" 690 assert_dedented_heredoc(expect, result) 691 end 692 693 def test_dedented_heredoc_with_newline 694 bug11989 = '[ruby-core:72855] [Bug #11989] after escaped newline should not be dedented' 695 result = ' x\n'" y\n" \ 696 " z\n" 697 expect = 'x\n'" y\n" \ 698 "z\n" 699 assert_dedented_heredoc(expect, result, bug11989) 700 end 701 702 def test_dedented_heredoc_with_concatenation 703 bug11990 = '[ruby-core:72857] [Bug #11990] concatenated string should not be dedented' 704 %w[eos "eos" 'eos'].each do |eos| 705 assert_equal("x\n y", 706 eval("<<~#{eos} ' y'\n x\neos\n"), 707 "#{bug11990} with #{eos}") 708 end 709 %w[eos "eos" 'eos' `eos`].each do |eos| 710 _, expect = eval("[<<~#{eos}, ' x']\n"" y\n""eos\n") 711 assert_equal(' x', expect, bug11990) 712 end 713 end 714 715 def test_dedented_heredoc_expr_at_beginning 716 result = " a\n" \ 717 '#{1}'"\n" 718 expected = " a\n" \ 719 '#{1}'"\n" 720 assert_dedented_heredoc(expected, result) 721 end 722 723 def test_dedented_heredoc_expr_string 724 result = ' one#{" two "}'"\n" 725 expected = 'one#{" two "}'"\n" 726 assert_dedented_heredoc(expected, result) 727 end 728 729 def test_dedented_heredoc_continued_line 730 result = " 1\\\n" " 2\n" 731 expected = "1\\\n" "2\n" 732 assert_dedented_heredoc(expected, result) 733 assert_syntax_error("#{<<~"begin;"}\n#{<<~'end;'}", /can't find string "TEXT"/) 734 begin; 735 <<-TEXT 736 \ 737 TEXT 738 end; 739 assert_syntax_error("#{<<~"begin;"}\n#{<<~'end;'}", /can't find string "TEXT"/) 740 begin; 741 <<~TEXT 742 \ 743 TEXT 744 end; 745 end 746 747 def test_lineno_after_heredoc 748 bug7559 = '[ruby-dev:46737]' 749 expected, _, actual = __LINE__, <<eom, __LINE__ 750 a 751 b 752 c 753 d 754eom 755 assert_equal(expected, actual, bug7559) 756 end 757 758 def test_dedented_heredoc_invalid_identifer 759 assert_syntax_error('<<~ "#{}"', /unexpected <</) 760 end 761 762 def test_dedented_heredoc_concatenation 763 assert_equal("\n0\n1", eval("<<~0 '1'\n \n0\#{}\n0")) 764 end 765 766 def test_heredoc_mixed_encoding 767 assert_syntax_error(<<-'HEREDOC', 'UTF-8 mixed within Windows-31J source') 768 #encoding: cp932 769 <<-TEXT 770 \xe9\x9d\u1234 771 TEXT 772 HEREDOC 773 assert_syntax_error(<<-'HEREDOC', 'UTF-8 mixed within Windows-31J source') 774 #encoding: cp932 775 <<-TEXT 776 \xe9\x9d 777 \u1234 778 TEXT 779 HEREDOC 780 assert_syntax_error(<<-'HEREDOC', 'UTF-8 mixed within Windows-31J source') 781 #encoding: cp932 782 <<-TEXT 783 \u1234\xe9\x9d 784 TEXT 785 HEREDOC 786 assert_syntax_error(<<-'HEREDOC', 'UTF-8 mixed within Windows-31J source') 787 #encoding: cp932 788 <<-TEXT 789 \u1234 790 \xe9\x9d 791 TEXT 792 HEREDOC 793 end 794 795 def test_lineno_operation_brace_block 796 expected = __LINE__ + 1 797 actual = caller_lineno\ 798 {} 799 assert_equal(expected, actual) 800 end 801 802 def assert_constant_reassignment_nested(preset, op, expected, err = [], bug = '[Bug #5449]') 803 [ 804 ["p ", ""], # no-pop 805 ["", "p Foo::Bar"], # pop 806 ].each do |p1, p2| 807 src = <<-EOM.gsub(/^\s*\n/, '') 808 class Foo 809 #{"Bar = " + preset if preset} 810 end 811 #{p1}Foo::Bar #{op}= 42 812 #{p2} 813 EOM 814 msg = "\# #{bug}\n#{src}" 815 assert_valid_syntax(src, caller_locations(1, 1)[0].path, msg) 816 assert_in_out_err([], src, expected, err, msg) 817 end 818 end 819 820 def test_constant_reassignment_nested 821 already = /already initialized constant Foo::Bar/ 822 uninitialized = /uninitialized constant Foo::Bar/ 823 assert_constant_reassignment_nested(nil, "||", %w[42]) 824 assert_constant_reassignment_nested("false", "||", %w[42], already) 825 assert_constant_reassignment_nested("true", "||", %w[true]) 826 assert_constant_reassignment_nested(nil, "&&", [], uninitialized) 827 assert_constant_reassignment_nested("false", "&&", %w[false]) 828 assert_constant_reassignment_nested("true", "&&", %w[42], already) 829 assert_constant_reassignment_nested(nil, "+", [], uninitialized) 830 assert_constant_reassignment_nested("false", "+", [], /undefined method/) 831 assert_constant_reassignment_nested("11", "+", %w[53], already) 832 end 833 834 def assert_constant_reassignment_toplevel(preset, op, expected, err = [], bug = '[Bug #5449]') 835 [ 836 ["p ", ""], # no-pop 837 ["", "p ::Bar"], # pop 838 ].each do |p1, p2| 839 src = <<-EOM.gsub(/^\s*\n/, '') 840 #{"Bar = " + preset if preset} 841 class Foo 842 #{p1}::Bar #{op}= 42 843 #{p2} 844 end 845 EOM 846 msg = "\# #{bug}\n#{src}" 847 assert_valid_syntax(src, caller_locations(1, 1)[0].path, msg) 848 assert_in_out_err([], src, expected, err, msg) 849 end 850 end 851 852 def test_constant_reassignment_toplevel 853 already = /already initialized constant Bar/ 854 uninitialized = /uninitialized constant Bar/ 855 assert_constant_reassignment_toplevel(nil, "||", %w[42]) 856 assert_constant_reassignment_toplevel("false", "||", %w[42], already) 857 assert_constant_reassignment_toplevel("true", "||", %w[true]) 858 assert_constant_reassignment_toplevel(nil, "&&", [], uninitialized) 859 assert_constant_reassignment_toplevel("false", "&&", %w[false]) 860 assert_constant_reassignment_toplevel("true", "&&", %w[42], already) 861 assert_constant_reassignment_toplevel(nil, "+", [], uninitialized) 862 assert_constant_reassignment_toplevel("false", "+", [], /undefined method/) 863 assert_constant_reassignment_toplevel("11", "+", %w[53], already) 864 end 865 866 def test_integer_suffix 867 ["1if true", "begin 1end"].each do |src| 868 assert_valid_syntax(src) 869 assert_equal(1, eval(src), src) 870 end 871 end 872 873 def test_value_of_def 874 assert_separately [], <<-EOS 875 assert_equal(:foo, (def foo; end)) 876 assert_equal(:foo, (def (Object.new).foo; end)) 877 EOS 878 end 879 880 def test_heredoc_cr 881 assert_syntax_error("puts <<""EOS\n""ng\n""EOS\r""NO\n", /can't find string "EOS" anywhere before EOF/) 882 end 883 884 def test_heredoc_newline 885 assert_warn(/ends with a newline/) do 886 eval("<<\"EOS\n\"\nEOS\n") 887 end 888 end 889 890 def test__END___cr 891 assert_syntax_error("__END__\r<<<<<\n", /unexpected <</) 892 end 893 894 def test_warning_for_cr 895 feature8699 = '[ruby-core:56240] [Feature #8699]' 896 assert_warning(/encountered \\r/, feature8699) do 897 eval("\r""__id__\r") 898 end 899 end 900 901 def test_unexpected_fraction 902 msg = /unexpected fraction/ 903 assert_syntax_error("0x0.0", msg) 904 assert_syntax_error("0b0.0", msg) 905 assert_syntax_error("0d0.0", msg) 906 assert_syntax_error("0o0.0", msg) 907 assert_syntax_error("0.0.0", msg) 908 end 909 910 def test_error_message_encoding 911 bug10114 = '[ruby-core:64228] [Bug #10114]' 912 code = "# -*- coding: utf-8 -*-\n" "def n \"\u{2208}\"; end" 913 assert_syntax_error(code, /def n "\u{2208}"; end/, bug10114) 914 end 915 916 def test_null_range_cmdarg 917 bug10957 = '[ruby-core:68477] [Bug #10957]' 918 assert_ruby_status(['-c', '-e', 'p ()..0'], "", bug10957) 919 assert_ruby_status(['-c', '-e', 'p ()...0'], "", bug10957) 920 assert_syntax_error('0..%w.', /unterminated string/, bug10957) 921 assert_syntax_error('0...%w.', /unterminated string/, bug10957) 922 end 923 924 def test_too_big_nth_ref 925 bug11192 = '[ruby-core:69393] [Bug #11192]' 926 assert_warn(/too big/, bug11192) do 927 eval('$99999999999999999') 928 end 929 end 930 931 def test_invalid_symbol_space 932 assert_syntax_error(": foo", /unexpected ':'/) 933 assert_syntax_error(": #\n foo", /unexpected ':'/) 934 assert_syntax_error(":#\n foo", /unexpected ':'/) 935 end 936 937 def test_fluent_dot 938 assert_valid_syntax("a\n.foo") 939 assert_valid_syntax("a\n&.foo") 940 end 941 942 def test_no_warning_logop_literal 943 assert_warning("") do 944 eval("true||raise;nil") 945 end 946 assert_warning("") do 947 eval("false&&raise;nil") 948 end 949 assert_warning("") do 950 eval("''||raise;nil") 951 end 952 end 953 954 def test_warning_literal_in_condition 955 assert_warn(/literal in condition/) do 956 eval('1 if ""') 957 end 958 assert_warn(/literal in condition/) do 959 eval('1 if //') 960 end 961 assert_warn(/literal in condition/) do 962 eval('1 if true..false') 963 end 964 assert_warning(/literal in condition/) do 965 eval('1 if 1') 966 end 967 assert_warning(/literal in condition/) do 968 eval('1 if :foo') 969 end 970 assert_warning(/literal in condition/) do 971 eval('1 if :"#{"foo".upcase}"') 972 end 973 974 assert_warn('') do 975 eval('1 if !""') 976 end 977 assert_warn('') do 978 eval('1 if !//') 979 end 980 assert_warn('') do 981 eval('1 if !(true..false)') 982 end 983 assert_warning('') do 984 eval('1 if !1') 985 end 986 assert_warning('') do 987 eval('1 if !:foo') 988 end 989 assert_warning('') do 990 eval('1 if !:"#{"foo".upcase}"') 991 end 992 end 993 994 def test_alias_symbol 995 bug8851 = '[ruby-dev:47681] [Bug #8851]' 996 formats = ['%s', ":'%s'", ':"%s"', '%%s(%s)'] 997 all_assertions(bug8851) do |all| 998 formats.product(formats) do |form1, form2| 999 all.for(code = "alias #{form1 % 'a'} #{form2 % 'p'}") do 1000 assert_valid_syntax(code) 1001 end 1002 end 1003 end 1004 end 1005 1006 def test_undef_symbol 1007 bug8851 = '[ruby-dev:47681] [Bug #8851]' 1008 formats = ['%s', ":'%s'", ':"%s"', '%%s(%s)'] 1009 all_assertions(bug8851) do |all| 1010 formats.product(formats) do |form1, form2| 1011 all.for(code = "undef #{form1 % 'a'}, #{form2 % 'p'}") do 1012 assert_valid_syntax(code) 1013 end 1014 end 1015 end 1016 end 1017 1018 def test_parenthesised_statement_argument 1019 assert_syntax_error("foo(bar rescue nil)", /unexpected rescue \(modifier\)/) 1020 assert_valid_syntax("foo (bar rescue nil)") 1021 end 1022 1023 def test_cmdarg_in_paren 1024 bug11873 = '[ruby-core:72482] [Bug #11873]' 1025 assert_valid_syntax %q{a b{c d}, :e do end}, bug11873 1026 assert_valid_syntax %q{a b(c d), :e do end}, bug11873 1027 assert_valid_syntax %q{a b{c(d)}, :e do end}, bug11873 1028 assert_valid_syntax %q{a b(c(d)), :e do end}, bug11873 1029 assert_valid_syntax %q{a b{c d}, 1 do end}, bug11873 1030 assert_valid_syntax %q{a b(c d), 1 do end}, bug11873 1031 assert_valid_syntax %q{a b{c(d)}, 1 do end}, bug11873 1032 assert_valid_syntax %q{a b(c(d)), 1 do end}, bug11873 1033 assert_valid_syntax %q{a b{c d}, "x" do end}, bug11873 1034 assert_valid_syntax %q{a b(c d), "x" do end}, bug11873 1035 assert_valid_syntax %q{a b{c(d)}, "x" do end}, bug11873 1036 assert_valid_syntax %q{a b(c(d)), "x" do end}, bug11873 1037 end 1038 1039 def test_block_after_cmdarg_in_paren 1040 bug11873 = '[ruby-core:72482] [Bug #11873]' 1041 def bug11873.p(*);end; 1042 1043 assert_raise(LocalJumpError, bug11873) do 1044 bug11873.instance_eval do 1045 p p{p p;p(p)}, tap do 1046 raise SyntaxError, "should not be passed to tap" 1047 end 1048 end 1049 end 1050 1051 assert_raise(LocalJumpError, bug11873) do 1052 bug11873.instance_eval do 1053 p p{p(p);p p}, tap do 1054 raise SyntaxError, "should not be passed to tap" 1055 end 1056 end 1057 end 1058 end 1059 1060 def test_do_block_in_hash_brace 1061 bug13073 = '[ruby-core:78837] [Bug #13073]' 1062 assert_valid_syntax 'p :foo, {a: proc do end, b: proc do end}', bug13073 1063 assert_valid_syntax 'p :foo, {:a => proc do end, b: proc do end}', bug13073 1064 assert_valid_syntax 'p :foo, {"a": proc do end, b: proc do end}', bug13073 1065 assert_valid_syntax 'p :foo, {** proc do end, b: proc do end}', bug13073 1066 assert_valid_syntax 'p :foo, {proc do end => proc do end, b: proc do end}', bug13073 1067 end 1068 1069 def test_do_after_local_variable 1070 obj = Object.new 1071 def obj.m; yield; end 1072 result = assert_nothing_raised(SyntaxError) do 1073 obj.instance_eval("m = 1; m do :ok end") 1074 end 1075 assert_equal(:ok, result) 1076 end 1077 1078 def test_brace_after_local_variable 1079 obj = Object.new 1080 def obj.m; yield; end 1081 result = assert_nothing_raised(SyntaxError) do 1082 obj.instance_eval("m = 1; m {:ok}") 1083 end 1084 assert_equal(:ok, result) 1085 end 1086 1087 def test_brace_after_literal_argument 1088 bug = '[ruby-core:81037] [Bug #13547]' 1089 error = /unexpected '{'/ 1090 assert_syntax_error('m "x" {}', error) 1091 assert_syntax_error('m 1 {}', error, bug) 1092 assert_syntax_error('m 1.0 {}', error, bug) 1093 assert_syntax_error('m :m {}', error, bug) 1094 assert_syntax_error('m :"#{m}" {}', error, bug) 1095 assert_syntax_error('m ?x {}', error, bug) 1096 assert_syntax_error('m %[] {}', error, bug) 1097 assert_syntax_error('m 0..1 {}', error, bug) 1098 assert_syntax_error('m [] {}', error, bug) 1099 end 1100 1101 def test_return_toplevel 1102 feature4840 = '[ruby-core:36785] [Feature #4840]' 1103 line = __LINE__+2 1104 code = "#{<<~"begin;"}#{<<~'end;'}" 1105 begin; 1106 return; raise 1107 begin return; rescue SystemExit; exit false; end 1108 begin return; ensure puts "ensured"; end #=> ensured 1109 begin ensure return; end 1110 begin raise; ensure; return; end 1111 begin raise; rescue; return; end 1112 return false; raise 1113 return 1; raise 1114 "#{return}" 1115 raise((return; "should not raise")) 1116 begin raise; ensure return; end; self 1117 begin raise; ensure return; end and self 1118 nil&defined?0--begin e=no_method_error(); return; 0;end 1119 return puts('ignored') #=> ignored 1120 end; 1121 .split(/\n/).map {|s|[(line+=1), *s.split(/#=> /, 2)]} 1122 failed = proc do |n, s| 1123 RubyVM::InstructionSequence.compile(s, __FILE__, nil, n).disasm 1124 end 1125 Tempfile.create(%w"test_return_ .rb") do |lib| 1126 lib.close 1127 args = %W[-W0 -r#{lib.path}] 1128 all_assertions_foreach(feature4840, *[:main, :lib].product([:class, :top], code)) do |main, klass, (n, s, *ex)| 1129 if klass == :class 1130 s = "class X; #{s}; end" 1131 if main == :main 1132 assert_in_out_err(%[-W0], s, [], /return/, proc {failed[n, s]}, success: false) 1133 else 1134 File.write(lib, s) 1135 assert_in_out_err(args, "", [], /return/, proc {failed[n, s]}, success: false) 1136 end 1137 else 1138 if main == :main 1139 assert_in_out_err(%[-W0], s, ex, [], proc {failed[n, s]}, success: true) 1140 else 1141 File.write(lib, s) 1142 assert_in_out_err(args, "", ex, [], proc {failed[n, s]}, success: true) 1143 end 1144 end 1145 end 1146 end 1147 end 1148 1149 def test_syntax_error_in_rescue 1150 bug12613 = '[ruby-core:76531] [Bug #12613]' 1151 assert_syntax_error("#{<<-"begin;"}\n#{<<-"end;"}", /Invalid retry/, bug12613) 1152 begin; 1153 while true 1154 begin 1155 p 1156 rescue 1157 retry 1158 else 1159 retry 1160 end 1161 break 1162 end 1163 end; 1164 end 1165 1166 def test_invalid_jump 1167 assert_in_out_err(%w[-e redo], "", [], /^-e:1: /) 1168 end 1169 1170 def test_keyword_not_parens 1171 assert_valid_syntax("not()") 1172 end 1173 1174 def test_rescue_do_end_raised 1175 result = [] 1176 assert_raise(RuntimeError) do 1177 eval("#{<<-"begin;"}\n#{<<-"end;"}") 1178 begin; 1179 tap do 1180 result << :begin 1181 raise "An exception occurred!" 1182 ensure 1183 result << :ensure 1184 end 1185 end; 1186 end 1187 assert_equal([:begin, :ensure], result) 1188 end 1189 1190 def test_rescue_do_end_rescued 1191 result = [] 1192 assert_nothing_raised(RuntimeError) do 1193 eval("#{<<-"begin;"}\n#{<<-"end;"}") 1194 begin; 1195 tap do 1196 result << :begin 1197 raise "An exception occurred!" 1198 rescue 1199 result << :rescue 1200 else 1201 result << :else 1202 ensure 1203 result << :ensure 1204 end 1205 end; 1206 end 1207 assert_equal([:begin, :rescue, :ensure], result) 1208 end 1209 1210 def test_rescue_do_end_no_raise 1211 result = [] 1212 assert_nothing_raised(RuntimeError) do 1213 eval("#{<<-"begin;"}\n#{<<-"end;"}") 1214 begin; 1215 tap do 1216 result << :begin 1217 rescue 1218 result << :rescue 1219 else 1220 result << :else 1221 ensure 1222 result << :ensure 1223 end 1224 end; 1225 end 1226 assert_equal([:begin, :else, :ensure], result) 1227 end 1228 1229 def test_rescue_do_end_ensure_result 1230 result = eval("#{<<-"begin;"}\n#{<<-"end;"}") 1231 begin; 1232 proc do 1233 :begin 1234 ensure 1235 :ensure 1236 end.call 1237 end; 1238 assert_equal(:begin, result) 1239 end 1240 1241 def test_rescue_do_end_ensure_in_lambda 1242 result = [] 1243 eval("#{<<-"begin;"}\n#{<<-"end;"}") 1244 begin; 1245 -> do 1246 result << :begin 1247 raise "An exception occurred!" 1248 rescue 1249 result << :rescue 1250 else 1251 result << :else 1252 ensure 1253 result << :ensure 1254 end.call 1255 end; 1256 assert_equal([:begin, :rescue, :ensure], result) 1257 end 1258 1259 def test_return_in_loop 1260 obj = Object.new 1261 def obj.test 1262 x = nil 1263 return until x unless x 1264 end 1265 assert_nil obj.test 1266 end 1267 1268 def test_assignment_return_in_loop 1269 obj = Object.new 1270 def obj.test 1271 x = nil 1272 _y = (return until x unless x) 1273 end 1274 assert_nil obj.test, "[Bug #16695]" 1275 end 1276 1277 def test_method_call_location 1278 line = __LINE__+5 1279 e = assert_raise(NoMethodError) do 1280 1.upto(0) do 1281 end 1282 . 1283 foo( 1284 1, 1285 2, 1286 ) 1287 end 1288 assert_equal(line, e.backtrace_locations[0].lineno) 1289 1290 line = __LINE__+5 1291 e = assert_raise(NoMethodError) do 1292 1.upto 0 do 1293 end 1294 . 1295 foo( 1296 1, 1297 2, 1298 ) 1299 end 1300 assert_equal(line, e.backtrace_locations[0].lineno) 1301 end 1302 1303 def test_methoddef_in_cond 1304 assert_valid_syntax('while def foo; tap do end; end; break; end') 1305 assert_valid_syntax('while def foo a = tap do end; end; break; end') 1306 end 1307 1308 def test_classdef_in_cond 1309 assert_valid_syntax('while class Foo; tap do end; end; break; end') 1310 assert_valid_syntax('while class Foo a = tap do end; end; break; end') 1311 end 1312 1313 def test_command_with_cmd_brace_block 1314 assert_valid_syntax('obj.foo (1) {}') 1315 assert_valid_syntax('obj::foo (1) {}') 1316 end 1317 1318 def test_value_expr_in_condition 1319 mesg = /void value expression/ 1320 assert_syntax_error("tap {a = (true ? next : break)}", mesg) 1321 assert_valid_syntax("tap {a = (true ? true : break)}") 1322 end 1323 1324 private 1325 1326 def not_label(x) @result = x; @not_label ||= nil end 1327 def assert_not_label(expected, src, message = nil) 1328 @result = nil 1329 assert_nothing_raised(SyntaxError, message) {eval(src)} 1330 assert_equal(expected, @result, message) 1331 end 1332 1333 def make_tmpsrc(f, src) 1334 f.open 1335 f.truncate(0) 1336 f.puts(src) 1337 f.close 1338 end 1339 1340 def with_script_lines 1341 script_lines = nil 1342 debug_lines = {} 1343 Object.class_eval do 1344 if defined?(SCRIPT_LINES__) 1345 script_lines = SCRIPT_LINES__ 1346 remove_const :SCRIPT_LINES__ 1347 end 1348 const_set(:SCRIPT_LINES__, debug_lines) 1349 end 1350 yield debug_lines 1351 ensure 1352 Object.class_eval do 1353 remove_const :SCRIPT_LINES__ 1354 const_set(:SCRIPT_LINES__, script_lines) if script_lines 1355 end 1356 end 1357 1358 def caller_lineno(*) 1359 caller_locations(1, 1)[0].lineno 1360 end 1361end 1362