diff options
Diffstat (limited to 'trunk/bootstraptest')
24 files changed, 5803 insertions, 0 deletions
diff --git a/trunk/bootstraptest/pending.rb b/trunk/bootstraptest/pending.rb new file mode 100644 index 0000000000..744c0adac1 --- /dev/null +++ b/trunk/bootstraptest/pending.rb @@ -0,0 +1,39 @@ +assert_equal 'A', %q{ + class A + @@a = 'A' + def a=(x) + @@a = x + end + def a + @@a + end + end + + B = A.dup + B.new.a = 'B' + A.new.a +}, '[ruby-core:17019]' + +assert_equal 'ok', %q{ + def m + lambda{ + proc{ + return :ng1 + } + }.call.call + :ng2 + end + + begin + m() + rescue LocalJumpError + :ok + end +} + +assert_normal_exit %q{ + r = Range.allocate + def r.<=>(o) true end + r.instance_eval { initialize r, r } + r.inspect +} diff --git a/trunk/bootstraptest/runner.rb b/trunk/bootstraptest/runner.rb new file mode 100644 index 0000000000..080e7b111e --- /dev/null +++ b/trunk/bootstraptest/runner.rb @@ -0,0 +1,354 @@ +# $Id$ + +# NOTE: +# Never use optparse in this file. +# Never use test/unit in this file. +# Never use Ruby extensions in this file. + +begin + require 'fileutils' + require 'tmpdir' +rescue LoadError + $:.unshift File.join(File.dirname(__FILE__), '../lib') + retry +end + +if !Dir.respond_to?(:mktmpdir) + # copied from lib/tmpdir.rb + def Dir.mktmpdir(prefix="d", tmpdir=nil) + tmpdir ||= Dir.tmpdir + t = Time.now.strftime("%Y%m%d") + n = nil + begin + path = "#{tmpdir}/#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}" + path << "-#{n}" if n + Dir.mkdir(path, 0700) + rescue Errno::EEXIST + n ||= 0 + n += 1 + retry + end + + if block_given? + begin + yield path + ensure + FileUtils.remove_entry_secure path + end + else + path + end + end +end + +def main + @ruby = File.expand_path('miniruby') + @verbose = false + dir = nil + quiet = false + tests = nil + ARGV.delete_if {|arg| + case arg + when /\A--ruby=(.*)/ + @ruby = $1 + @ruby.gsub!(/^([^ ]*)/){File.expand_path($1)} + @ruby.gsub!(/(\s+-I\s*)((?!(?:\.\/)*-(?:\s|\z))\S+)/){$1+File.expand_path($2)} + @ruby.gsub!(/(\s+-r\s*)(\.\.?\/\S+)/){$1+File.expand_path($2)} + true + when /\A--sets=(.*)/ + tests = Dir.glob("#{File.dirname($0)}/test_{#{$1}}*.rb") + puts tests.map {|path| File.basename(path) }.inspect + true + when /\A--dir=(.*)/ + dir = $1 + true + when /\A(--stress|-s)/ + $stress = true + when /\A(-q|--q(uiet))\z/ + quiet = true + true + when /\A(-v|--v(erbose))\z/ + @verbose = true + when /\A(-h|--h(elp)?)\z/ + puts(<<-End) +Usage: #{File.basename($0, '.*')} --ruby=PATH [--sets=NAME,NAME,...] + --sets=NAME,NAME,... Name of test sets. + --dir=DIRECTORY Working directory. + default: /tmp/bootstraptest.tmpwd + -s, --stress stress test. + -v, --verbose Output test name before exec. + -q, --quiet Don\'t print header message. + -h, --help Print this message and quit. +End + exit true + else + false + end + } + if tests and not ARGV.empty? + $stderr.puts "--tests and arguments are exclusive" + exit false + end + tests ||= ARGV + tests = Dir.glob("#{File.dirname($0)}/test_*.rb") if tests.empty? + pathes = tests.map {|path| File.expand_path(path) } + + unless quiet + puts Time.now + patchlevel = defined?(RUBY_PATCHLEVEL) ? " patchlevel #{RUBY_PATCHLEVEL}" : '' + puts "Driver is ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}#{patchlevel}) [#{RUBY_PLATFORM}]" + puts "Target is #{`#{@ruby} -v`.chomp}" + puts + $stdout.flush + end + + in_temporary_working_directory(dir) { + exec_test pathes + } +end + +def exec_test(pathes) + @count = 0 + @error = 0 + @errbuf = [] + @location = nil + pathes.each do |path| + $stderr.print "\n#{File.basename(path)} " + load File.expand_path(path) + end + $stderr.puts + if @error == 0 + $stderr.puts "PASS #{@count} tests" + exit true + else + @errbuf.each do |msg| + $stderr.puts msg + end + $stderr.puts "FAIL #{@error}/#{@count} tests failed" + exit false + end +end + +def assert_check(testsrc, message = '', opt = '') + $stderr.puts "\##{@count} #{@location}" if @verbose + result = get_result_string(testsrc, opt) + check_coredump + faildesc = yield(result) + if !faildesc + $stderr.print '.' + else + $stderr.print 'F' + error faildesc, message + end +rescue Exception => err + $stderr.print 'E' + error err.message, message +end + +def assert_equal(expected, testsrc, message = '') + newtest + assert_check(testsrc, message) {|result| + if expected == result + nil + else + desc = "#{result.inspect} (expected #{expected.inspect})" + pretty(testsrc, desc, result) + end + } +end + +def assert_match(expected_pattern, testsrc, message = '') + newtest + assert_check(testsrc, message) {|result| + if expected_pattern =~ result + nil + else + desc = "#{expected_pattern.inspect} expected to be =~\n#{result.inspect}" + pretty(testsrc, desc, result) + end + } +end + +def assert_not_match(unexpected_pattern, testsrc, message = '') + newtest + assert_check(testsrc, message) {|result| + if unexpected_pattern !~ result + nil + else + desc = "#{unexpected_pattern.inspect} expected to be !~\n#{result.inspect}" + pretty(testsrc, desc, result) + end + } +end + +def assert_valid_syntax(testsrc, message = '') + newtest + assert_check(testsrc, message, '-c') {|result| + result if /Syntax OK/ !~ result + } +end + +def assert_normal_exit(testsrc, message = '', ignore_signals = nil) + newtest + $stderr.puts "\##{@count} #{@location}" if @verbose + faildesc = nil + filename = make_srcfile(testsrc) + old_stderr = $stderr.dup + begin + $stderr.reopen("assert_normal_exit_stderr.log", "w") + `#{@ruby} -W0 #{filename}` + status = $? + ensure + $stderr.reopen(old_stderr) + old_stderr.close + end + if status.signaled? + signo = status.termsig + signame = Signal.list.invert[signo] + unless ignore_signals and ignore_signals.include?(signame) + sigdesc = "signal #{signo}" + if signame + sigdesc = "SIG#{signame} (#{sigdesc})" + end + faildesc = pretty(testsrc, "killed by #{sigdesc}", nil) + stderr_log = File.read("assert_normal_exit_stderr.log") + if !stderr_log.empty? + faildesc << "\n" if /\n\z/ !~ faildesc + stderr_log << "\n" if /\n\z/ !~ stderr_log + stderr_log.gsub!(/^.*\n/) { '| ' + $& } + faildesc << stderr_log + end + end + end + if !faildesc + $stderr.print '.' + true + else + $stderr.print 'F' + error faildesc, message + false + end +rescue Exception => err + $stderr.print 'E' + error err.message, message + false +end + +def assert_finish(timeout_seconds, testsrc, message = '') + newtest + $stderr.puts "\##{@count} #{@location}" if @verbose + faildesc = nil + filename = make_srcfile(testsrc) + io = IO.popen("#{@ruby} -W0 #{filename}") + pid = io.pid + waited = false + tlimit = Time.now + timeout_seconds + while Time.now < tlimit + if Process.waitpid pid, Process::WNOHANG + waited = true + break + end + sleep 0.1 + end + if !waited + Process.kill(:KILL, pid) + Process.waitpid pid + faildesc = pretty(testsrc, "not finished in #{timeout_seconds} seconds", nil) + end + io.close + if !faildesc + $stderr.print '.' + else + $stderr.print 'F' + error faildesc, message + end +rescue Exception => err + $stderr.print 'E' + error err.message, message +end + +def flunk(message = '') + newtest + $stderr.print 'F' + error message, '' +end + +def pretty(src, desc, result) + src = src.sub(/\A.*\n/, '') + (/\n/ =~ src ? "\n#{adjust_indent(src)}" : src) + " #=> #{desc}" +end + +INDENT = 27 + +def adjust_indent(src) + untabify(src).gsub(/^ {#{INDENT}}/o, '').gsub(/^/, ' ') +end + +def untabify(str) + str.gsub(/^\t+/) {' ' * (8 * $&.size) } +end + +def make_srcfile(src) + filename = 'bootstraptest.tmp.rb' + File.open(filename, 'w') {|f| + f.puts "GC.stress = true" if $stress + f.puts "print(begin; #{src}; end)" + } + filename +end + +def get_result_string(src, opt = '') + if @ruby + filename = make_srcfile(src) + begin + `#{@ruby} -W0 #{opt} #{filename}` + ensure + raise CoreDumpError, "core dumped" if $? and $?.coredump? + end + else + eval(src).to_s + end +end + +def newtest + @location = File.basename(caller(2).first) + @count += 1 + cleanup_coredump +end + +def error(msg, additional_message) + @errbuf.push "\##{@count} #{@location}: #{msg} #{additional_message}" + @error += 1 +end + +def in_temporary_working_directory(dir) + if dir + Dir.mkdir dir + Dir.chdir(dir) { + yield + } + else + Dir.mktmpdir("bootstraptest.tmpwd") {|d| + Dir.chdir(d) { + yield + } + } + end +end + +def cleanup_coredump + FileUtils.rm_f 'core' + FileUtils.rm_f Dir.glob('core.*') + FileUtils.rm_f @ruby+'.stackdump' if @ruby +end + +class CoreDumpError < StandardError; end + +def check_coredump + if File.file?('core') or not Dir.glob('core.*').empty? or + (@ruby and File.exist?(@ruby+'.stackdump')) + raise CoreDumpError, "core dumped" + end +end + +main diff --git a/trunk/bootstraptest/test_attr.rb b/trunk/bootstraptest/test_attr.rb new file mode 100644 index 0000000000..721a847145 --- /dev/null +++ b/trunk/bootstraptest/test_attr.rb @@ -0,0 +1,36 @@ +assert_equal 'ok', %q{ + module M + class A + class << self + attr_accessor :at + def workflow_rule + yield self + end + + def eval_str(str) + eval(str) + end + end + end + end + begin + M::A.eval_str(<<-END) + workflow_rule do |r| + r.at 1 + end + END + rescue ArgumentError => e + print "ok" + end +}, '[ruby-core:14641]' + +assert_equal %{ok}, %{ + class A + attr :m + end + begin + A.new.m(3) + rescue ArgumentError => e + print "ok" + end +}, '[ruby-core:15120]' diff --git a/trunk/bootstraptest/test_autoload.rb b/trunk/bootstraptest/test_autoload.rb new file mode 100644 index 0000000000..05376df220 --- /dev/null +++ b/trunk/bootstraptest/test_autoload.rb @@ -0,0 +1,52 @@ +assert_equal 'ok', %q{ + open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"} + autoload :ZZZ, "./zzz.rb" + ZZZ.ok +} + +assert_equal 'ok', %q{ + open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"} + autoload :ZZZ, "./zzz.rb" + require "./zzz.rb" + ZZZ.ok +} + +assert_equal 'ok', %q{ + open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"} + autoload :ZZZ, "./zzz.rb" + proc{$SAFE=4; ZZZ.ok}.call +} + +assert_equal 'ok', %q{ + open("zzz.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"} + autoload :ZZZ, "./zzz.rb" + require "./zzz.rb" + proc{$SAFE=4; ZZZ.ok}.call +} + +assert_equal 'ok', %q{ + open("zzz.rb", "w") {|f| f.puts "class ZZZ; def hoge;:ok;end;end"} + autoload :ZZZ, File.join(Dir.pwd, 'zzz.rb') + module M; end + Thread.new{M.instance_eval('$SAFE=4; ZZZ.new.hoge')}.value +} + +assert_equal 'ok', %q{ + open("zzz.rb", "w") {|f| f.puts "class ZZZ; def hoge;:ok;end;end"} + autoload :ZZZ, File.join(Dir.pwd, 'zzz.rb') + module M; end + Thread.new{$SAFE=4; M.instance_eval('ZZZ.new.hoge')}.value +} + +assert_equal 'ok', %q{ + open("zzz.rb", "w") {|f| f.puts "class ZZZ; def hoge;:ok;end;end"} + autoload :ZZZ, File.join(Dir.pwd, 'zzz.rb') + Thread.new{$SAFE=4; eval('ZZZ.new.hoge')}.value +} + +assert_equal 'ok', %q{ + open("zzz.rb", "w") {|f| f.puts "class ZZZ; def hoge;:ok;end;end"} + autoload :ZZZ, File.join(Dir.pwd, 'zzz.rb') + module M; end + Thread.new{eval('$SAFE=4; ZZZ.new.hoge')}.value +} diff --git a/trunk/bootstraptest/test_block.rb b/trunk/bootstraptest/test_block.rb new file mode 100644 index 0000000000..2db149063e --- /dev/null +++ b/trunk/bootstraptest/test_block.rb @@ -0,0 +1,549 @@ +assert_equal %q{1}, %q{ + 1.times{ + begin + a = 1 + ensure + foo = nil + end + } +} +assert_equal %q{2}, %q{ + [1,2,3].find{|x| x == 2} +} +assert_equal %q{2}, %q{ + class E + include Enumerable + def each(&block) + [1, 2, 3].each(&block) + end + end + E.new.find {|x| x == 2 } +} +assert_equal %q{6}, %q{ + sum = 0 + for x in [1, 2, 3] + sum += x + end + sum +} +assert_equal %q{15}, %q{ + sum = 0 + for x in (1..5) + sum += x + end + sum +} +assert_equal %q{0}, %q{ + sum = 0 + for x in [] + sum += x + end + sum +} +assert_equal %q{1}, %q{ + ans = [] + 1.times{ + for n in 1..3 + a = n + ans << a + end + } +} +assert_equal %q{1..3}, %q{ + ans = [] + for m in 1..3 + for n in 1..3 + a = [m, n] + ans << a + end + end +} +assert_equal %q{[1, 2, 3]}, %q{ + (1..3).to_a +} +assert_equal %q{[4, 8, 12]}, %q{ + (1..3).map{|e| + e * 4 + } +} +assert_equal %q{[1, 2, 3]}, %q{ + class C + include Enumerable + def each + [1,2,3].each{|e| + yield e + } + end + end + + C.new.to_a +} +assert_equal %q{[4, 5, 6]}, %q{ + class C + include Enumerable + def each + [1,2,3].each{|e| + yield e + } + end + end + + C.new.map{|e| + e + 3 + } +} +assert_equal %q{100}, %q{ + def m + yield + end + def n + yield + end + + m{ + n{ + 100 + } + } +} +assert_equal %q{20}, %q{ + def m + yield 1 + end + + m{|ib| + m{|jb| + i = 20 + } + } +} +assert_equal %q{2}, %q{ + def m + yield 1 + end + + m{|ib| + m{|jb| + ib = 20 + kb = 2 + } + } +} +assert_equal %q{3}, %q{ + def iter1 + iter2{ + yield + } + end + + def iter2 + yield + end + + iter1{ + jb = 2 + iter1{ + jb = 3 + } + jb + } +} +assert_equal %q{2}, %q{ + def iter1 + iter2{ + yield + } + end + + def iter2 + yield + end + + iter1{ + jb = 2 + iter1{ + jb + } + jb + } +} +assert_equal %q{2}, %q{ + def m + yield 1 + end + m{|ib| + ib*2 + } +} +assert_equal %q{92580}, %q{ + def m + yield 12345, 67890 + end + m{|ib,jb| + ib*2+jb + } +} +assert_equal %q{[10, nil]}, %q{ + def iter + yield 10 + end + + a = nil + [iter{|a| + a + }, a] +} +assert_equal %q{21}, %q{ + def iter + yield 10 + end + + iter{|a| + iter{|a| + a + 1 + } + a + } +} +assert_equal %q{[10, 20, 30, 40, nil, nil, nil, nil]}, %q{ + def iter + yield 10, 20, 30, 40 + end + + a = b = c = d = nil + iter{|a, b, c, d| + [a, b, c, d] + } + [a, b, c, d] +} +assert_equal %q{[10, 20, 30, 40, nil, nil]}, %q{ + def iter + yield 10, 20, 30, 40 + end + + a = b = nil + iter{|a, b, c, d| + [a, b, c, d] + } + [a, b] +} +assert_equal %q{[1]}, %q{ + $a = [] + + def iter + yield 1 + end + + def m + x = iter{|x| + $a << x + y = 0 + } + end + m + $a +} +assert_equal %q{[1, [2]]}, %q{ + def iter + yield 1, 2 + end + + iter{|a, *b| + [a, b] + } +} +assert_equal %q{[[1, 2]]}, %q{ + def iter + yield 1, 2 + end + + iter{|*a| + [a] + } +} +assert_equal %q{[1, 2, []]}, %q{ + def iter + yield 1, 2 + end + + iter{|a, b, *c| + [a, b, c] + } +} +assert_equal %q{[1, 2, nil, []]}, %q{ + def iter + yield 1, 2 + end + + iter{|a, b, c, *d| + [a, b, c, d] + } +} +assert_equal %q{1}, %q{ + def m + yield + end + m{ + 1 + } +} +assert_equal %q{15129}, %q{ + def m + yield 123 + end + m{|ib| + m{|jb| + ib*jb + } + } +} +assert_equal %q{2}, %q{ + def m a + yield a + end + m(1){|ib| + m(2){|jb| + ib*jb + } + } +} +assert_equal %q{9}, %q{ + sum = 0 + 3.times{|ib| + 2.times{|jb| + sum += ib + jb + }} + sum +} +assert_equal %q{10}, %q{ + 3.times{|bl| + break 10 + } +} +assert_equal %q{[1, 2]}, %q{ + def iter + yield 1,2,3 + end + + iter{|i, j| + [i, j] + } +} +assert_equal %q{[1, nil]}, %q{ + def iter + yield 1 + end + + iter{|i, j| + [i, j] + } +} + +assert_equal '0', %q{ +def m() +end +m {|(v0,*,(*)),|} +m {|(*v0,(*)),|} +m {|(v0,*v1,(*)),|} +m {|((v0,*v1,v2)),|} +m {|(v0,*v1,v2),|} +m {|(v0,*v1,(v2)),|} +m {|((*),*v0,v1),|} +m {|((v0),*v1,v2),|} +m {|(v0,v1,*v2,v3),|} +m {|v0,(v1,*v2,v3),|} +m {|(v0,*v1,v2),v3,|} +m {|(v0,*v1,v2)|} +m {|(v0,*v1,v2),&v3|} +m {|(v0,*v1,v2),*|} +m {|(v0,*v1,v2),*,&v3|} +m {|*,(v0,*v1,v2)|} +m {|*,(v0,*v1,v2),&v3|} +m {|v0,*,(v1,*v2,v3)|} +m {|v0,*,(v1,*v2,v3),&v4|} +m {|(v0,*v1,v2),*,v3|} +m {|(v0,*v1,v2),*,v3,&v4|} +m {|(v0, *v1, v2)|} +m {|(*,v)|} +0 +}, "block parameter (shouldn't SEGV: [ruby-dev:31143])" + +assert_equal 'nil', %q{ + def m + yield + end + m{|&b| b}.inspect +}, '[ruby-dev:31147]' + +assert_equal 'nil', %q{ + def m() + yield + end + m {|(v,(*))|}.inspect +}, '[ruby-dev:31160]' + +assert_equal 'nil', %q{ + def m() + yield + end + m {|(*,a,b)|}.inspect +}, '[ruby-dev:31153]' + +assert_equal 'nil', %q{ + def m() + yield + end + m {|((*))|}.inspect +} + +assert_equal %q{[1, 1, [1, nil], [1, nil], [1, nil], [1, nil], [1, 1], 1, [1, nil], [1, nil], [1, nil], [1, nil], [[1, 1], [1, 1]], [1, 1], [1, 1], [1, 1], [1, nil], [1, nil], [[[1, 1], [1, 1]], [[1, 1], [1, 1]]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [[1, 1], [1, 1]], [1, 1], [1, 1], [[[[1, 1], [1, 1]], [[1, 1], [1, 1]]], [[[1, 1], [1, 1]], [[1, 1], [1, 1]]]], [[[1, 1], [1, 1]], [[1, 1], [1, 1]]], [[[1, 1], [1, 1]], [[1, 1], [1, 1]]], [[[1, 1], [1, 1]], [[1, 1], [1, 1]]], [[1, 1], [1, 1]], [[1, 1], [1, 1]]]}, %q{ +def m(ary = []) + yield(ary) +end + +$ans = [] +o = 1 +5.times{ + v,(*) = o; $ans << o + m(o){|(v,(*))| $ans << v} + ((x, y)) = o; $ans << [x, y] + m(o){|((x, y))| $ans << [x, y]} + (((x, y))) = o; $ans << [x, y] + m(o){|(((x, y)))| $ans << [x, y]} + o = [o, o] +}; $ans +} + +assert_equal '0', %q{ + def m() + yield [0] + end + m {|*,v| v}.inspect +}, '[ruby-dev:31437]' +assert_equal '[0]', %q{ + def m + yield [0] + end + m{|v, &b| v}.inspect +}, '[ruby-dev:31440]' +assert_equal 'ok', %q{ + begin + lambda{|a|}.call(1, 2) + rescue ArgumentError + :ok + else + :ng + end +}, '[ruby-dev:31464]' +assert_equal 'ok', %q{ + begin + lambda{|&b|}.call(3) + rescue ArgumentError + :ok + else + :ng + end +}, '[ruby-dev:31472]' +assert_equal 'ok', %q{ + class C + def each + yield [1,2] + yield 1,2 + end + end + vs1 = [] + C.new.each {|*v| vs1 << v } + vs2 = [] + C.new.to_enum.each {|*v| vs2 << v } + vs1 == vs2 ? :ok : :ng +}, '[ruby-dev:32329]' + +assert_normal_exit %q{ + e = [1,2,3].each + 10000.times { + e = [e].each + } + Thread.new { GC.start }.join +}, '[ruby-dev:32604]' + + +assert_equal '[nil, []]', %q{ + def m() yield nil,[] end + l = lambda {|*v| v} + GC.stress=true + r = m(&l) + GC.stress=false + r.inspect +}, '[ruby-dev:32567]' + +assert_equal NilClass.to_s, %q{ + r = false; 1.times{|&b| r = b}; r.class +} + +assert_equal 'ok', %q{ + class C + define_method(:foo) do |arg, &block| + if block then block.call else arg end + end + end + C.new.foo("ng") {"ok"} +}, '[ruby-talk:266422]' + +assert_equal 'ok', %q{ + STDERR.reopen(STDOUT) + class C + define_method(:foo) do |&block| + block.call if block + end + result = "ng" + new.foo() {result = "ok"} + result + end +} + +assert_equal "ok", %q{ + class Bar + def bar; :ok; end + end + def foo + yield(Bar.new) if block_given? + end + foo(&:bar) +}, '[ruby-core:14279]' + +assert_normal_exit %q{ + class Controller + def respond_to(&block) + responder = Responder.new + block.call(responder) + responder.respond + end + def test_for_bug + respond_to{|format| + format.js{ + puts "in test" + render{|obj| + puts obj + } + } + } + end + def render(&block) + puts "in render" + end + end + + class Responder + def method_missing(symbol, &block) + puts "enter method_missing" + @response = Proc.new{ + puts 'in method missing' + block.call + } + puts "leave method_missing" + end + def respond + @response.call + end + end + t = Controller.new + t.test_for_bug +}, '[ruby-core:14395]' + diff --git a/trunk/bootstraptest/test_class.rb b/trunk/bootstraptest/test_class.rb new file mode 100644 index 0000000000..1c49b83037 --- /dev/null +++ b/trunk/bootstraptest/test_class.rb @@ -0,0 +1,132 @@ +# class +assert_equal 'true', %q( class C; end + Object.const_defined?(:C) ) +assert_equal 'Class', %q( class C; end + C.class ) +assert_equal 'C', %q( class C; end + C.name ) +assert_equal 'C', %q( class C; end + C.new.class ) +assert_equal 'C', %q( class C; end + C.new.class.name ) +assert_equal 'Class', %q( class C; end + C.new.class.class ) + +# inherited class +assert_equal 'true', %q( class A; end + class C < A; end + Object.const_defined?(:C) ) +assert_equal 'Class', %q( class A; end + class C < A; end + C.class ) +assert_equal 'C', %q( class A; end + class C < A; end + C.name ) +assert_equal 'C', %q( class A; end + class C < A; end + C.new.class ) +assert_equal 'C', %q( class A; end + class C < A; end + C.new.class.name ) +assert_equal 'Class', %q( class A; end + class C < A; end + C.new.class.class ) + +# module +assert_equal 'true', %q( module M; end + Object.const_defined?(:M) ) +assert_equal 'Module', %q( module M; end + M.class ) +assert_equal 'M', %q( module M; end + M.name ) +assert_equal 'C', %q( module M; end + class C; include M; end + C.new.class ) + +# nested class +assert_equal 'A::B', %q( class A; end + class A::B; end + A::B ) +assert_equal 'A::B', %q( class A; end + class A::B; end + A::B.name ) +assert_equal 'A::B', %q( class A; end + class A::B; end + A::B.new.class ) +assert_equal 'Class', %q( class A; end + class A::B; end + A::B.new.class.class ) +assert_equal 'A::B::C', %q( class A; end + class A::B; end + class A::B::C; end + A::B::C ) +assert_equal 'A::B::C', %q( class A; end + class A::B; end + class A::B::C; end + A::B::C.name ) +assert_equal 'Class', %q( class A; end + class A::B; end + class A::B::C; end + A::B::C.class ) +assert_equal 'A::B::C', %q( class A; end + class A::B; end + class A::B::C; end + A::B::C.new.class ) +assert_equal 'Class', %q( class A; end + class A::B; end + class A::B::C; end + A::B::C.new.class.class ) +assert_equal 'A::B2', %q( class A; end + class A::B; end + class A::B2 < A::B; end + A::B2 ) +assert_equal 'Class', %q( class A; end + class A::B; end + class A::B2 < A::B; end + A::B2.class ) + +# reopen +assert_equal 'true', %q( class C; end; c1 = ::C + class C; end; c2 = ::C + c1.equal?(c2) ) +assert_equal '1', %q( class C; end + class A; end + begin class C < A; end; rescue TypeError; 1 end ) +assert_equal '1', %q( class C; end + begin module C; end; rescue TypeError; 1 end ) +assert_equal '1', %q( C = 1 # [yarv-dev:782] + begin class C; end; rescue TypeError; 1 end ) +assert_equal '1', %q( C = 1 # [yarv-dev:800] + begin module C; end; rescue TypeError; 1 end ) + +# colon2, colon3 +assert_equal '1', %q( class A; end; A::C = 1; A::C ) +assert_equal '1', %q( A = 7; begin A::C = 7; rescue TypeError; 1 end ) +assert_equal '1', %q( begin 7::C = 7; rescue TypeError; 1 end ) +assert_equal 'C', %q( class A; class ::C; end end; C ) +assert_equal 'Class', %q( class A; class ::C; end end; C.class ) +assert_equal 'OK', %q( class A; ::C = "OK"; end; C ) +assert_equal 'String', %q( class A; ::C = "OK"; end; C.class ) + +# class/module dup +assert_equal 'Class', %q( class C; end; C.dup.class ) +assert_equal 'Module', %q( module M; end; M.dup.class ) + + +assert_equal "ok", %q{ + module Foo + end + + begin + def foo(&b) + Foo.module_eval &b + end + foo{ + def bar + end + } + bar() + rescue NameError + :ok + end +}, '[ruby-core:14378]' diff --git a/trunk/bootstraptest/test_eval.rb b/trunk/bootstraptest/test_eval.rb new file mode 100644 index 0000000000..8b99c7968c --- /dev/null +++ b/trunk/bootstraptest/test_eval.rb @@ -0,0 +1,288 @@ +assert_equal %q{ok}, %q{ + def m + a = :ok + $b = binding + end + m + eval('a', $b) +} +assert_equal %q{[:ok, :ok2]}, %q{ + def m + a = :ok + $b = binding + end + m + eval('b = :ok2', $b) + eval('[a, b]', $b) +} +assert_equal %q{[nil, 1]}, %q{ + $ans = [] + def m + $b = binding + end + m + $ans << eval(%q{ + $ans << eval(%q{ + a + }, $b) + a = 1 + }, $b) + $ans +} +assert_equal %q{C}, %q{ + Const = :top + class C + Const = :C + def m + binding + end + end + eval('Const', C.new.m) +} +assert_equal %q{top}, %q{ + Const = :top + a = 1 + class C + Const = :C + def m + eval('Const', TOPLEVEL_BINDING) + end + end + C.new.m +} +assert_equal %q{:ok +ok}, %q{ + class C + $b = binding + end + eval %q{ + def m + :ok + end + }, $b + p C.new.m +} +assert_equal %q{ok}, %q{ + b = proc{ + a = :ok + binding + }.call + a = :ng + eval("a", b) +} +assert_equal %q{C}, %q{ + class C + def foo + binding + end + end + C.new.foo.eval("self.class.to_s") +} +assert_equal %q{1}, %q{ + eval('1') +} +assert_equal %q{1}, %q{ + eval('a=1; a') +} +assert_equal %q{1}, %q{ + a = 1 + eval('a') +} +assert_equal %q{ok}, %q{ + __send__ :eval, %{ + :ok + } +} +assert_equal %q{ok}, %q{ + 1.__send__ :instance_eval, %{ + :ok + } +} +assert_equal %q{1}, %q{ + 1.instance_eval{ + self + } +} +assert_equal %q{foo}, %q{ + 'foo'.instance_eval{ + self + } +} +assert_equal %q{1}, %q{ + class Fixnum + Const = 1 + end + 1.instance_eval %{ + Const + } +} +assert_equal %q{C}, %q{ + Const = :top + class C + Const = :C + end + C.module_eval{ + Const + } +} +assert_equal %q{C}, %q{ + Const = :top + class C + Const = :C + end + C.class_eval %{ + def m + Const + end + } + C.new.m +} +assert_equal %q{C}, %q{ + Const = :top + class C + Const = :C + end + C.class_eval{ + def m + Const + end + } + C.new.m +} +assert_equal %q{[:top, :C, :top, :C]}, %q{ + Const = :top + class C + Const = :C + end + $nest = false + $ans = [] + def m + $ans << Const + C.module_eval %{ + $ans << Const + Boo = false unless defined? Boo + unless $nest + $nest = true + m + end + } + end + m + $ans +} +assert_equal %q{[10, main]}, %q{ + $nested = false + $ans = [] + $pr = proc{ + $ans << self + unless $nested + $nested = true + $pr.call + end + } + class C + def initialize &b + 10.instance_eval(&b) + end + end + C.new(&$pr) + $ans +} + +%w[break next redo].each do |keyword| + assert_match %r"Can't escape from eval with #{keyword}\z", %{ + begin + eval "0 rescue #{keyword}" + rescue SyntaxError => e + e.message + end + }, '[ruby-dev:31372]' +end + +assert_normal_exit %q{ + STDERR.reopen(STDOUT) + class Foo + def self.add_method + class_eval("def some-bad-name; puts 'hello' unless @some_variable.some_function(''); end") + end + end + Foo.add_method +}, '[ruby-core:14556] reported by Frederick Cheung' + +assert_equal 'ok', %q{ + class Module + def my_module_eval(&block) + module_eval(&block) + end + end + class String + Integer.my_module_eval do + def hoge; end + end + end + if Integer.instance_methods(false).map{|m|m.to_sym}.include?(:hoge) && + !String.instance_methods(false).map{|m|m.to_sym}.include?(:hoge) + :ok + else + :ng + end +}, "[ruby-dev:34236]" + +assert_equal 'ok', %q{ + begin + eval("class nil::Foo; end") + :ng + rescue Exception + :ok + end +} + +assert_equal 'ok', %q{ + begin + 0.instance_eval { def m() :m end } + 1.m + :ng + rescue Exception + :ok + end +}, '[ruby-dev:34579]' + +assert_equal 'ok', %q{ + begin + 12.instance_eval { @@a } + rescue NameError + :ok + end +}, '[ruby-core:16794]' + +assert_equal 'ok', %q{ + begin + 12.instance_exec { @@a } + rescue NameError + :ok + end +}, '[ruby-core:16794]' + +assert_equal 'ok', %q{ + begin + nil.instance_eval { + def a() :a end + } + rescue TypeError + :ok + end +}, '[ruby-core:16796]' + +assert_equal 'ok', %q{ + begin + nil.instance_exec { + def a() :a end + } + rescue TypeError + :ok + end +}, '[ruby-core:16796]' + +assert_normal_exit %q{ + eval("", method(:proc).call {}.binding) +} diff --git a/trunk/bootstraptest/test_exception.rb b/trunk/bootstraptest/test_exception.rb new file mode 100644 index 0000000000..bd3d02ade3 --- /dev/null +++ b/trunk/bootstraptest/test_exception.rb @@ -0,0 +1,404 @@ +assert_equal %q{2}, %q{ + begin + 1+1 + ensure + 2+2 + end +} +assert_equal %q{4}, %q{ + begin + 1+1 + begin + 2+2 + ensure + 3+3 + end + ensure + 4+4 + end +} +assert_equal %q{4}, %q{ + begin + 1+1 + begin + 2+2 + ensure + 3+3 + end + ensure + 4+4 + begin + 5+5 + ensure + 6+6 + end + end +} +assert_equal %q{NilClass}, %q{ + a = nil + 1.times{|e| + begin + rescue => err + end + a = err.class + } + a +} +assert_equal %q{RuntimeError}, %q{ + a = nil + 1.times{|e| + begin + raise + rescue => err + end + a = err.class + } + a +} +assert_equal %q{}, %q{ + $! +} +assert_equal %q{FOO}, %q{ + begin + raise "FOO" + rescue + $! + end +} +assert_equal %q{FOO}, %q{ + def m + $! + end + begin + raise "FOO" + rescue + m() + end +} +assert_equal %q{[#<RuntimeError: BAR>, #<RuntimeError: FOO>]}, %q{ + $ans = [] + def m + $! + end + begin + raise "FOO" + rescue + begin + raise "BAR" + rescue + $ans << m() + end + $ans << m() + end + $ans +} +assert_equal %q{[#<RuntimeError: FOO>, #<RuntimeError: FOO>]}, %q{ + $ans = [] + def m + $! + end + + begin + begin + raise "FOO" + ensure + $ans << m() + end + rescue + $ans << m() + end +} +assert_equal %q{[nil]}, %q{ + $ans = [] + def m + $! + end + def m2 + 1.times{ + begin + return + ensure + $ans << m + end + } + end + m2 + $ans +} +assert_equal %q{ok}, %q{ + begin + raise + rescue + :ok + end +} +assert_equal %q{ok}, %q{ + begin + raise + rescue + :ok + ensure + :ng + end +} +assert_equal %q{RuntimeError}, %q{ + begin + raise + rescue => e + e.class + end +} +assert_equal %q{ng}, %q{ + begin + raise + rescue StandardError + :ng + rescue Exception + :ok + end +} +assert_equal %q{c}, %q{ + begin + begin + raise "a" + rescue + raise "b" + ensure + raise "c" + end + rescue => e + e.message + end +} +assert_equal %q{33}, %q{ + def m a, b + a + b + end + m(1, begin + raise + rescue + 2 + end) + + m(10, begin + raise + rescue + 20 + ensure + 30 + end) +} +assert_equal %q{3}, %q{ + def m a, b + a + b + end + m(begin + raise + rescue + 1 + end, + begin + raise + rescue + 2 + end) +} +assert_equal %q{ok3}, %q{ + class E1 < Exception + end + + def m + yield + end + + begin + begin + begin + m{ + raise + } + rescue E1 + :ok2 + ensure + end + rescue + :ok3 + ensure + end + rescue E1 + :ok + ensure + end +} +assert_equal %q{7}, %q{ + $i = 0 + def m + iter{ + begin + $i += 1 + begin + $i += 2 + break + ensure + + end + ensure + $i += 4 + end + $i = 0 + } + end + + def iter + yield + end + m + $i +} +assert_equal %q{10}, %q{ + $i = 0 + def m + begin + $i += 1 + begin + $i += 2 + return + ensure + $i += 3 + end + ensure + $i += 4 + end + p :end + end + m + $i +} +assert_equal %q{1}, %q{ + begin + 1 + rescue + 2 + end +} +assert_equal %q{4}, %q{ + begin + 1 + begin + 2 + rescue + 3 + end + 4 + rescue + 5 + end +} +assert_equal %q{3}, %q{ + begin + 1 + rescue + 2 + else + 3 + end +} +assert_equal %q{2}, %q{ + begin + 1+1 + rescue + 2+2 + ensure + 3+3 + end + } +assert_equal %q{2}, %q{ + begin + 1+1 + rescue + 2+2 + ensure + 3+3 + end + } +assert_equal %q{6}, %q{ + begin + 1+1 + rescue + 2+2 + else + 3+3 + ensure + 4+4 + end + } +assert_equal %q{12}, %q{ + begin + 1+1 + begin + 2+2 + rescue + 3+3 + else + 4+4 + end + rescue + 5+5 + else + 6+6 + ensure + 7+7 + end + } +assert_equal %q{ok}, %q{ # + proc{ + begin + raise + break + rescue + :ok + end + }.call +} +assert_equal %q{}, %q{ + proc do + begin + raise StandardError + redo + rescue StandardError + end + end.call +} + +## +assert_match /undefined method `foo\'/, %q{ + STDERR.reopen(STDOUT) + class C + def inspect + bar {} + end + + def bar + raise + ensure + end + end + C.new.foo +}, "[ruby-dev:31407]" + +assert_equal 'nil', %q{ + doit = false + exc = nil + t = Thread.new { + begin + doit = true + sleep 10 + ensure + exc = $! + end + } + Thread.pass until doit + t.kill + t.join + exc.inspect +}, '[ruby-dev:32608]' + diff --git a/trunk/bootstraptest/test_finalizer.rb b/trunk/bootstraptest/test_finalizer.rb new file mode 100644 index 0000000000..22a16b1220 --- /dev/null +++ b/trunk/bootstraptest/test_finalizer.rb @@ -0,0 +1,8 @@ +assert_normal_exit %q{ +a1,a2,b1,b2=Array.new(4){""} +ObjectSpace.define_finalizer(b2,proc{}) +ObjectSpace.define_finalizer(b1,proc{b1.inspect}) + +ObjectSpace.define_finalizer(a2,proc{a1.inspect}) +ObjectSpace.define_finalizer(a1,proc{}) +}, '[ruby-dev:35778]' diff --git a/trunk/bootstraptest/test_flip.rb b/trunk/bootstraptest/test_flip.rb new file mode 100644 index 0000000000..ff194868b2 --- /dev/null +++ b/trunk/bootstraptest/test_flip.rb @@ -0,0 +1 @@ +assert_equal %q{E}, %q{$_ = "E"; eval("nil if true..~/^E/",nil,"-e"); $_} diff --git a/trunk/bootstraptest/test_flow.rb b/trunk/bootstraptest/test_flow.rb new file mode 100644 index 0000000000..9964dfb2ed --- /dev/null +++ b/trunk/bootstraptest/test_flow.rb @@ -0,0 +1,491 @@ +assert_equal %q{[1, 2, 4, 5, 6, 7, 8]}, %q{$a = []; begin; ; $a << 1 + [1,2].each{; $a << 2 + break; $a << 3 + }; $a << 4 + begin; $a << 5 + ensure; $a << 6 + end; $a << 7 +; $a << 8 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 5, 6, 7, 8]}, %q{$a = []; begin; ; $a << 1 + begin; $a << 2 + [1,2].each do; $a << 3 + break; $a << 4 + end; $a << 5 + ensure; $a << 6 + end; $a << 7 +; $a << 8 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{ok}, %q{ + ["a"].inject("ng"){|x,y| + break :ok + } +} +assert_equal %q{ok}, %q{ + unless ''.respond_to? :lines + class String + def lines + self + end + end + end + + ('a').lines.map{|e| + break :ok + } +} +assert_equal %q{[1, 2, 4, 5]}, %q{$a = []; begin; ; $a << 1 + ["a"].inject("ng"){|x,y|; $a << 2 + break :ok; $a << 3 + }; $a << 4 +; $a << 5 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 4, 5]}, %q{$a = []; begin; ; $a << 1 + ('a'..'b').map{|e|; $a << 2 + break :ok; $a << 3 + }; $a << 4 +; $a << 5 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 5, 7, 8]}, %q{$a = []; begin; ; $a << 1 + [1,2].each do; $a << 2 + begin; $a << 3 + break; $a << 4 + ensure; $a << 5 + end; $a << 6 + end; $a << 7 +; $a << 8 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 4, 5, 6, 9, 10]}, %q{$a = []; begin; ; $a << 1 + i=0; $a << 2 + while i<3; $a << 3 + i+=1; $a << 4 + begin; $a << 5 + ensure; $a << 6 + break; $a << 7 + end; $a << 8 + end; $a << 9 +; $a << 10 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 4, 5, 7, 10, 11]}, %q{$a = []; begin; ; $a << 1 + i=0; $a << 2 + while i<3; $a << 3 + i+=1; $a << 4 + begin; $a << 5 + raise; $a << 6 + ensure; $a << 7 + break; $a << 8 + end; $a << 9 + end; $a << 10 +; $a << 11 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 4, 5, 7, 10, 11]}, %q{$a = []; begin; ; $a << 1 + i=0; $a << 2 + while i<3; $a << 3 + i+=1; $a << 4 + begin; $a << 5 + raise; $a << 6 + rescue; $a << 7 + break; $a << 8 + end; $a << 9 + end; $a << 10 +; $a << 11 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1 + [1,2].each do; $a << 2 + begin; $a << 3 + raise StandardError; $a << 4 + ensure; $a << 5 + break; $a << 6 + end; $a << 7 + end; $a << 8 +; $a << 9 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1 + [1,2].each do; $a << 2 + begin; $a << 3 + raise StandardError; $a << 4 + rescue; $a << 5 + break; $a << 6 + end; $a << 7 + end; $a << 8 +; $a << 9 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 4, 6, 8, 10, 11]}, %q{$a = []; begin; ; $a << 1 + [1,2].each do; $a << 2 + begin; $a << 3 + begin; $a << 4 + break; $a << 5 + ensure; $a << 6 + end; $a << 7 + ensure; $a << 8 + end; $a << 9 + end; $a << 10 +; $a << 11 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 4, 5, 6, 7, 8, 10, 13, 3, 4, 5, 6, 7, 8, 10, 13, 3, 4, 5, 6, 7, 8, 10, 13, 14, 15]}, %q{$a = []; begin; ; $a << 1 + i = 0; $a << 2 + while i<3; $a << 3 + i+=1; $a << 4 + j = 0; $a << 5 + while j<3; $a << 6 + j+=1; $a << 7 + begin; $a << 8 + raise; $a << 9 + rescue; $a << 10 + break; $a << 11 + end; $a << 12 + end; $a << 13 + end; $a << 14 +; $a << 15 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 16, 17]}, %q{$a = []; begin; ; $a << 1 + i = 0; $a << 2 + while i<3; $a << 3 + i+=1; $a << 4 + j = 0; $a << 5 + while j<3; $a << 6 + j+=1; $a << 7 + 1.times{; $a << 8 + begin; $a << 9 + raise; $a << 10 + rescue; $a << 11 + break; $a << 12 + end; $a << 13 + }; $a << 14 + end; $a << 15 + end; $a << 16 +; $a << 17 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 4, 5, 6, 7, 8, 10, 13, 3, 4, 5, 6, 7, 8, 10, 13, 3, 4, 5, 6, 7, 8, 10, 13, 14, 15]}, %q{$a = []; begin; ; $a << 1 + i = 0; $a << 2 + while i<3; $a << 3 + i+=1; $a << 4 + j = 0; $a << 5 + while j<3; $a << 6 + j+=1; $a << 7 + begin; $a << 8 + raise; $a << 9 + ensure; $a << 10 + break; $a << 11 + end; $a << 12 + end; $a << 13 + end; $a << 14 +; $a << 15 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 3, 4, 5, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 6, 7, 8, 9, 11, 14, 15, 16, 17]}, %q{$a = []; begin; ; $a << 1 + i = 0; $a << 2 + while i<3; $a << 3 + i+=1; $a << 4 + j = 0; $a << 5 + while j<3; $a << 6 + j+=1; $a << 7 + 1.times{; $a << 8 + begin; $a << 9 + raise; $a << 10 + ensure; $a << 11 + break; $a << 12 + end; $a << 13 + }; $a << 14 + end; $a << 15 + end; $a << 16 +; $a << 17 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1 + while true; $a << 2 + begin; $a << 3 + break; $a << 4 + ensure; $a << 5 + break; $a << 6 + end; $a << 7 + end; $a << 8 +; $a << 9 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 5, 99]}, %q{$a = []; begin; ; $a << 1 + while true; $a << 2 + begin; $a << 3 + break; $a << 4 + ensure; $a << 5 + raise; $a << 6 + end; $a << 7 + end; $a << 8 +; $a << 9 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 4, 6, 8, 9, 10, 11]}, %q{$a = []; begin; ; $a << 1 + begin; $a << 2 + [1,2].each do; $a << 3 + begin; $a << 4 + break; $a << 5 + ensure; $a << 6 + end; $a << 7 + end; $a << 8 + ensure; $a << 9 + end; $a << 10 +; $a << 11 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 4, 99]}, %q{$a = []; begin; ; $a << 1 + begin; $a << 2 + raise StandardError; $a << 3 + ensure; $a << 4 + end; $a << 5 +; $a << 6 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 4]}, %q{$a = []; begin; ; $a << 1 + begin; $a << 2 + ensure; $a << 3 + end ; $a << 4 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 5, 99]}, %q{$a = []; begin; ; $a << 1 + [1,2].each do; $a << 2 + begin; $a << 3 + break; $a << 4 + ensure; $a << 5 + raise StandardError; $a << 6 + end; $a << 7 + end; $a << 8 +; $a << 9 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{3}, %q{ + def m a, b + a + b + end + m(1, + while true + break 2 + end + ) +} +assert_equal %q{4}, %q{ + def m a, b + a + b + end + m(1, + (i=0; while i<2 + i+=1 + class C + next 2 + end + end; 3) + ) +} +assert_equal %q{34}, %q{ + def m a, b + a+b + end + m(1, 1.times{break 3}) + + m(10, (1.times{next 3}; 20)) +} +assert_equal %q{[1, 2, 3, 6, 7]}, %q{$a = []; begin; ; $a << 1 + 3.times{; $a << 2 + class C; $a << 3 + break; $a << 4 + end; $a << 5 + }; $a << 6 +; $a << 7 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 4, 8, 9]}, %q{$a = []; begin; ; $a << 1 + 3.times{; $a << 2 + class A; $a << 3 + class B; $a << 4 + break; $a << 5 + end; $a << 6 + end; $a << 7 + }; $a << 8 +; $a << 9 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 2, 3, 2, 3, 6, 7]}, %q{$a = []; begin; ; $a << 1 + 3.times{; $a << 2 + class C; $a << 3 + next; $a << 4 + end; $a << 5 + }; $a << 6 +; $a << 7 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 8, 9]}, %q{$a = []; begin; ; $a << 1 + 3.times{; $a << 2 + class C; $a << 3 + class D; $a << 4 + next; $a << 5 + end; $a << 6 + end; $a << 7 + }; $a << 8 +; $a << 9 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 6, 7]}, %q{$a = []; begin; ; $a << 1 + while true; $a << 2 + class C; $a << 3 + break; $a << 4 + end; $a << 5 + end; $a << 6 +; $a << 7 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 4, 8, 9]}, %q{$a = []; begin; ; $a << 1 + while true; $a << 2 + class C; $a << 3 + class D; $a << 4 + break; $a << 5 + end; $a << 6 + end; $a << 7 + end; $a << 8 +; $a << 9 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 3, 4, 5, 3, 4, 5, 3, 4, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1 + i=0; $a << 2 + while i<3; $a << 3 + i+=1; $a << 4 + class C; $a << 5 + next 10; $a << 6 + end; $a << 7 + end; $a << 8 +; $a << 9 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{1}, %q{ + 1.times{ + while true + class C + begin + break + ensure + break + end + end + end + } +} +assert_equal %q{[1, 2, 3, 5, 2, 3, 5, 7, 8]}, %q{$a = []; begin; ; $a << 1 + [1,2].each do; $a << 2 + begin; $a << 3 + next; $a << 4 + ensure; $a << 5 + end; $a << 6 + end; $a << 7 +; $a << 8 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 2, 6, 3, 5, 7, 8]}, %q{$a = []; begin; ; $a << 1 + o = "test"; $a << 2 + def o.test(a); $a << 3 + return a; $a << 4 + ensure; $a << 5 + end; $a << 6 + o.test(123); $a << 7 +; $a << 8 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 4, 7, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1 + def m1 *args; $a << 2 + ; $a << 3 + end; $a << 4 + def m2; $a << 5 + m1(:a, :b, (return 1; :c)); $a << 6 + end; $a << 7 + m2; $a << 8 +; $a << 9 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 8, 2, 3, 4, 5, 9, 10]}, %q{$a = []; begin; ; $a << 1 + def m(); $a << 2 + begin; $a << 3 + 2; $a << 4 + ensure; $a << 5 + return 3; $a << 6 + end; $a << 7 + end; $a << 8 + m; $a << 9 +; $a << 10 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 3, 11, 4, 5, 6, 7, 12, 13]}, %q{$a = []; begin; ; $a << 1 + def m2; $a << 2 + end; $a << 3 + def m(); $a << 4 + m2(begin; $a << 5 + 2; $a << 6 + ensure; $a << 7 + return 3; $a << 8 + end); $a << 9 + 4; $a << 10 + end; $a << 11 + m(); $a << 12 +; $a << 13 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[1, 16, 2, 3, 4, 5, 6, 7, 10, 11, 17, 18]}, %q{$a = []; begin; ; $a << 1 + def m; $a << 2 + 1; $a << 3 + 1.times{; $a << 4 + 2; $a << 5 + begin; $a << 6 + 3; $a << 7 + return; $a << 8 + 4; $a << 9 + ensure; $a << 10 + 5; $a << 11 + end; $a << 12 + 6; $a << 13 + }; $a << 14 + 7; $a << 15 + end; $a << 16 + m(); $a << 17 +; $a << 18 +; rescue Exception; $a << 99; end; $a} +assert_equal %q{[:ok, :ok2, :last]}, %q{ + a = [] + i = 0 + begin + while i < 1 + i+=1 + begin + begin + next + ensure + a << :ok + end + ensure + a << :ok2 + end + end + ensure + a << :last + end + a +} +assert_equal %q{[:ok, :ok2, :last]}, %q{ + a = [] + i = 0 + begin + while i < 1 + i+=1 + begin + begin + break + ensure + a << :ok + end + ensure + a << :ok2 + end + end + ensure + a << :last + end + a +} +assert_equal %q{[:ok, :ok2, :last]}, %q{ + a = [] + i = 0 + begin + while i < 1 + if i>0 + break + end + i+=1 + begin + begin + redo + ensure + a << :ok + end + ensure + a << :ok2 + end + end + ensure + a << :last + end + a + } diff --git a/trunk/bootstraptest/test_fork.rb b/trunk/bootstraptest/test_fork.rb new file mode 100644 index 0000000000..743c22c250 --- /dev/null +++ b/trunk/bootstraptest/test_fork.rb @@ -0,0 +1,10 @@ +assert_equal '0', %q{ + begin + GC.stress = true + pid = fork {} + Process.wait pid + $?.to_i + rescue NotImplementedError + 0 + end +}, '[ruby-dev:32404]' diff --git a/trunk/bootstraptest/test_io.rb b/trunk/bootstraptest/test_io.rb new file mode 100644 index 0000000000..c0b906fb4d --- /dev/null +++ b/trunk/bootstraptest/test_io.rb @@ -0,0 +1,94 @@ +assert_finish 5, %q{ + r, w = IO.pipe + t1 = Thread.new { r.sysread(1) } + t2 = Thread.new { r.sysread(1) } + sleep 0.1 + w.write "a" + sleep 0.1 + w.write "a" +}, '[ruby-dev:31866]' + +assert_finish 10, %q{ + begin + require "io/nonblock" + r, w = IO.pipe + w.nonblock = true + w.write_nonblock("a" * 100000) + w.nonblock = false + t1 = Thread.new { w.write("b" * 4096) } + t2 = Thread.new { w.write("c" * 4096) } + sleep 0.5 + r.sysread(4096).length + sleep 0.5 + r.sysread(4096).length + t1.join + t2.join + rescue LoadError + end +}, '[ruby-dev:32566]' + +assert_finish 1, %q{ + r, w = IO.pipe + Thread.new { + w << "ab" + sleep 0.1 + w << "ab" + } + r.gets("abab") +} + +assert_equal 'ok', %q{ + require 'tmpdir' + begin + tmpname = "#{Dir.tmpdir}/ruby-btest-#{$$}-#{rand(0x100000000).to_s(36)}" + rw = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL) + rescue Errno::EEXIST + retry + end + save = STDIN.dup + STDIN.reopen(rw) + STDIN.reopen(save) + rw.close + File.unlink(tmpname) + :ok +} + +assert_equal 'ok', %q{ + require 'tmpdir' + begin + tmpname = "#{Dir.tmpdir}/ruby-btest-#{$$}-#{rand(0x100000000).to_s(36)}" + rw = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL) + rescue Errno::EEXIST + retry + end + save = STDIN.dup + STDIN.reopen(rw) + STDIN.print "a" + STDIN.reopen(save) + rw.close + File.unlink(tmpname) + :ok +} + +assert_normal_exit %q{ + ARGF.set_encoding "foo" +} + +50.times do + assert_normal_exit %q{ + at_exit { p :foo } + + megacontent = "abc" * 12345678 + File.open("megasrc", "w") {|f| f << megacontent } + + Thread.new { sleep rand*0.2; Process.kill(:INT, $$) } + + r1, w1 = IO.pipe + r2, w2 = IO.pipe + t1 = Thread.new { w1 << megacontent; w1.close } + t2 = Thread.new { r2.read } + IO.copy_stream(r1, w2) rescue nil + r2.close; w2.close + r1.close; w1.close + }, '', ["INT"] or break +end diff --git a/trunk/bootstraptest/test_jump.rb b/trunk/bootstraptest/test_jump.rb new file mode 100644 index 0000000000..77467337c2 --- /dev/null +++ b/trunk/bootstraptest/test_jump.rb @@ -0,0 +1,261 @@ +assert_equal %q{ok}, %q{ + def m + :ng1 + mm{ + yield + } + :ng2 + end + + def mm + :ng3 + yield + :ng4 + end + + m{ + break :ok + } +} +assert_equal %q{ok}, %q{ + 3.times{ + break :ok + } +} +assert_equal %q{}, %q{ + catch(:foo){ + throw :foo + } +} +assert_equal %q{false}, %q{ + catch(:foo){ + throw :foo, false + } +} +assert_equal %q{}, %q{ + catch(:foo){ + throw :foo, nil + } +} +assert_equal %q{ok}, %q{ + catch(:foo){ + throw :foo, :ok + } +} +assert_equal %q{}, %q{ + catch(:foo){ + 1.times{ + throw :foo + } + } +} +assert_equal %q{ok}, %q{ + catch(:foo){ + 1.times{ + throw :foo, :ok + } + } +} +assert_equal %q{ok}, %q{ + catch(:foo){ + catch(:bar){ + throw :foo, :ok + } + :ng + } +} +assert_equal %q{ok}, %q{ + catch(:foo){ + catch(:bar){ + 1.times{ + throw :foo, :ok + } + } + :ng + } +} +assert_equal %q{2}, %q{ + module Enumerable + def all_? + self.each{|e| + unless yield(e) + return false + end + } + true + end + end + + xxx = 0 + [1,2].each{|bi| + [3,4].each{|bj| + [true, nil, true].all_?{|be| be} + break + } + xxx += 1 + } + xxx +} +assert_equal %q{ok}, %q{ + def m + yield + end + + m{ + begin + ensure + break :ok + end + } +} +assert_equal %q{ok}, %q{ + def m + yield + :ok + end + i=0 + m{ + if i>10 + i*i + else + i+=1 + next + end + } +} +assert_equal %q{ok}, %q{ + def m + yield + end + + m{ + next :ok + } +} +assert_equal %q{131}, %q{ + def m + yield + 10 + end + i=0 + m{ + if i>10 + i*i + else + i+=1 + redo + end + } +} +assert_equal %q{ok}, %q{ +begin + eval %q{ + 1.times{ + retry + } + } +rescue SyntaxError + :ok +end +} +assert_equal %q{3}, %q{ + def m + return 3 + end + m +} +assert_equal %q{ok}, %q{ + def m + :ng1 + mm{ + return :ok + } + :ng2 + end + + def mm + :ng3 + yield + :ng4 + end + m +} +assert_equal %q{100}, %q{ + $i = 0 + def m + begin + iter{ + return + } + ensure + $i = 100 + end + end + + def iter + yield + end + m + $i +} +assert_equal %q{ok}, %q{ + def m + begin + raise + rescue + return :ok + end + :ng + end + m +} +assert_equal %q{1}, %q{ + def m + begin + raise + rescue + return 1 + end + end + + m +} +assert_equal %q{1}, %q{ + def m + begin + # + ensure + return 1 + end + end + + m +} +assert_equal 'ok', %q{ + begin + catch {|t| throw t, :ok } + rescue ArgumentError + :ng + end +}, '[ruby-dev:31609]' + +assert_equal "1", %q{ + catch do |t| + begin + throw t, 1 + 2 + ensure + 3 + end + end +}, "[ruby-dev:31698]" + +assert_normal_exit %q{ + f = 0 + 1.times do + begin + f += 1 + ensure + redo unless f > 2 + end + end +} diff --git a/trunk/bootstraptest/test_literal.rb b/trunk/bootstraptest/test_literal.rb new file mode 100644 index 0000000000..8480c65308 --- /dev/null +++ b/trunk/bootstraptest/test_literal.rb @@ -0,0 +1,194 @@ +# empty program +assert_equal '', '' +assert_equal '', ' ' +assert_equal '', "\n" + +# special const +assert_equal 'true', 'true' +assert_equal 'TrueClass', 'true.class' +assert_equal 'false', 'false' +assert_equal 'FalseClass', 'false.class' +assert_equal '', 'nil' +assert_equal 'nil', 'nil.inspect' +assert_equal 'NilClass', 'nil.class' +assert_equal 'sym', ':sym' +assert_equal ':sym', ':sym.inspect' +assert_equal 'Symbol', ':sym.class' +assert_equal '1234', '1234' +assert_equal 'Fixnum', '1234.class' +assert_equal '1234', '1_2_3_4' +assert_equal 'Fixnum', '1_2_3_4.class' +assert_equal '18', '0x12' +assert_equal 'Fixnum', '0x12.class' +assert_equal '15', '0o17' +assert_equal 'Fixnum', '0o17.class' +assert_equal '5', '0b101' +assert_equal 'Fixnum', '0b101.class' +assert_equal '123456789012345678901234567890', '123456789012345678901234567890' +assert_equal 'Bignum', '123456789012345678901234567890.class' +assert_equal '2.0', '2.0' +assert_equal 'Float', '1.3.class' + +# self +assert_equal 'main', 'self' +assert_equal 'Object', 'self.class' + +# string literal +assert_equal 'a', '?a' +assert_equal 'String', '?a.class' +assert_equal 'A', '?A' +assert_equal 'String', '?A.class' +assert_equal "\n", '?\n' +assert_equal 'String', '?\n.class' +assert_equal ' ', '?\ ' +assert_equal 'String', '?\ .class' +assert_equal 'string', "'string'" +assert_equal 'string', '"string"' +assert_equal 'string', '%(string)' +assert_equal 'string', '%q(string)' +assert_equal 'string', '%Q(string)' +assert_equal 'string string', '"string string"' +assert_equal ' ', '" "' +assert_equal "\0", '"\0"' +assert_equal "\1", '"\1"' +assert_equal "3", '"\x33"' +assert_equal "\n", '"\n"' + +# dynamic string literal +assert_equal '2', '"#{1 + 1}"' +assert_equal '16', '"#{2 ** 4}"' +assert_equal 'string', 's = "string"; "#{s}"' + +# dynamic symbol literal +assert_equal 'a3c', ':"a#{1+2}c"' +assert_equal ':a3c', ':"a#{1+2}c".inspect' +assert_equal 'Symbol', ':"a#{1+2}c".class' + +# xstring +assert_equal "foo\n", %q(`echo foo`) +assert_equal "foo\n", %q(s = "foo"; `echo #{s}`) + +# regexp +assert_equal '', '//.source' +assert_equal 'Regexp', '//.class' +assert_equal '0', '// =~ "a"' +assert_equal '0', '// =~ ""' +assert_equal 'a', '/a/.source' +assert_equal 'Regexp', '/a/.class' +assert_equal '0', '/a/ =~ "a"' +assert_equal '0', '/test/ =~ "test"' +assert_equal '', '/test/ =~ "tes"' +assert_equal '0', 're = /test/; re =~ "test"' +assert_equal '0', 'str = "test"; /test/ =~ str' +assert_equal '0', 're = /test/; str = "test"; re =~ str' + +# dynacmi regexp +assert_equal 'regexp', %q(/re#{'ge'}xp/.source) +assert_equal 'Regexp', %q(/re#{'ge'}xp/.class) + +# array +assert_equal 'Array', '[].class' +assert_equal '0', '[].size' +assert_equal '0', '[].length' +assert_equal '[]', '[].inspect' +assert_equal 'Array', '[0].class' +assert_equal '1', '[3].size' +assert_equal '[3]', '[3].inspect' +assert_equal '3', 'a = [3]; a[0]' +assert_equal 'Array', '[1,2].class' +assert_equal '2', '[1,2].size' +assert_equal '[1, 2]', '[1,2].inspect' +assert_equal 'Array', '[1,2,3,4,5].class' +assert_equal '5', '[1,2,3,4,5].size' +assert_equal '[1, 2, 3, 4, 5]', '[1,2,3,4,5].inspect' +assert_equal '1', 'a = [1,2]; a[0]' +assert_equal '2', 'a = [1,2]; a[1]' +assert_equal 'Array', 'a = [1 + 2, 3 + 4, 5 + 6]; a.class' +assert_equal '[3, 7, 11]', 'a = [1 + 2, 3 + 4, 5 + 6]; a.inspect' +assert_equal '7', 'a = [1 + 2, 3 + 4, 5 + 6]; a[1]' +assert_equal '1', '([0][0] += 1)' +assert_equal '1', '([2][0] -= 1)' +assert_equal 'Array', 'a = [obj = Object.new]; a.class' +assert_equal '1', 'a = [obj = Object.new]; a.size' +assert_equal 'true', 'a = [obj = Object.new]; a[0] == obj' +assert_equal '5', 'a = [1,2,3]; a[1] = 5; a[1]' +assert_equal 'bar', '[*:foo];:bar' +assert_equal '[1, 2]', 'def nil.to_a; [2]; end; [1, *nil]' +assert_equal '[1, 2]', 'def nil.to_a; [1, 2]; end; [*nil]' +assert_equal '[0, 1, {2=>3}]', '[0, *[1], 2=>3]', "[ruby-dev:31592]" + + +# hash +assert_equal 'Hash', '{}.class' +assert_equal '{}', '{}.inspect' +assert_equal 'Hash', '{1=>2}.class' +assert_equal '{1=>2}', '{1=>2}.inspect' +assert_equal '2', 'h = {1 => 2}; h[1]' +assert_equal '0', 'h = {1 => 2}; h.delete(1); h.size' +assert_equal '', 'h = {1 => 2}; h.delete(1); h[1]' +assert_equal '2', 'h = {"string" => "literal", "goto" => "hell"}; h.size' +assert_equal 'literal', 'h = {"string"=>"literal", "goto"=>"hell"}; h["string"]' +assert_equal 'hell', 'h = {"string"=>"literal", "goto"=>"hell"}; h["goto"]' + +# range +assert_equal 'Range', '(1..2).class' +assert_equal '1..2', '(1..2).inspect' +assert_equal '1', '(1..2).begin' +assert_equal '2', '(1..2).end' +assert_equal 'false', '(1..2).exclude_end?' +assert_equal 'Range', 'r = 1..2; r.class' +assert_equal '1..2', 'r = 1..2; r.inspect' +assert_equal '1', 'r = 1..2; r.begin' +assert_equal '2', 'r = 1..2; r.end' +assert_equal 'false', 'r = 1..2; r.exclude_end?' +assert_equal 'Range', '(1...3).class' +assert_equal '1...3', '(1...3).inspect' +assert_equal '1', '(1...3).begin' +assert_equal '3', '(1...3).end' +assert_equal 'true', '(1...3).exclude_end?' +assert_equal 'Range', 'r = (1...3); r.class' +assert_equal '1...3', 'r = (1...3); r.inspect' +assert_equal '1', 'r = (1...3); r.begin' +assert_equal '3', 'r = (1...3); r.end' +assert_equal 'true', 'r = (1...3); r.exclude_end?' +assert_equal 'Range', 'r = (1+2 .. 3+4); r.class' +assert_equal '3..7', 'r = (1+2 .. 3+4); r.inspect' +assert_equal '3', 'r = (1+2 .. 3+4); r.begin' +assert_equal '7', 'r = (1+2 .. 3+4); r.end' +assert_equal 'false', 'r = (1+2 .. 3+4); r.exclude_end?' +assert_equal 'Range', 'r = (1+2 ... 3+4); r.class' +assert_equal '3...7', 'r = (1+2 ... 3+4); r.inspect' +assert_equal '3', 'r = (1+2 ... 3+4); r.begin' +assert_equal '7', 'r = (1+2 ... 3+4); r.end' +assert_equal 'true', 'r = (1+2 ... 3+4); r.exclude_end?' +assert_equal 'Range', 'r = ("a".."c"); r.class' +assert_equal '"a".."c"', 'r = ("a".."c"); r.inspect' +assert_equal 'a', 'r = ("a".."c"); r.begin' +assert_equal 'c', 'r = ("a".."c"); r.end' + +assert_equal 'String', '__FILE__.class' +assert_equal 'Fixnum', '__LINE__.class' + +### + +assert_equal 'ok', %q{ + # this cause "called on terminated object". + ObjectSpace.each_object(Module) {|m| m.name.inspect } + :ok +} + +assert_normal_exit %q{ + begin + r = 0**-1 + r + r + rescue + end +}, '[ruby-dev:34524]' + +assert_normal_exit %q{ + begin + r = Marshal.load("\x04\bU:\rRational[\ai\x06i\x05") + r + r + rescue + end +}, '[ruby-dev:34536]' diff --git a/trunk/bootstraptest/test_load.rb b/trunk/bootstraptest/test_load.rb new file mode 100644 index 0000000000..18e8cc06a4 --- /dev/null +++ b/trunk/bootstraptest/test_load.rb @@ -0,0 +1,15 @@ +assert_equal 'ok', %q{ + open("require-lock-test.rb", "w") {|f| + f.puts "sleep 0.1" + f.puts "module M" + f.puts "end" + } + $:.unshift Dir.pwd + vs = (1..2).map {|i| + Thread.start { + require "require-lock-test" + M + } + }.map {|t| t.value } + vs[0] == M && vs[1] == M ? :ok : :ng +}, '[ruby-dev:32048]' diff --git a/trunk/bootstraptest/test_marshal.rb b/trunk/bootstraptest/test_marshal.rb new file mode 100644 index 0000000000..7e34176169 --- /dev/null +++ b/trunk/bootstraptest/test_marshal.rb @@ -0,0 +1,5 @@ + +assert_normal_exit %q{ + Marshal.load(Marshal.dump({"k"=>"v"}), lambda {|v| v}) +} + diff --git a/trunk/bootstraptest/test_massign.rb b/trunk/bootstraptest/test_massign.rb new file mode 100644 index 0000000000..0f63dd424a --- /dev/null +++ b/trunk/bootstraptest/test_massign.rb @@ -0,0 +1,183 @@ +assert_equal '[[1], 2, 3]', '*v1, (a, b) = [1,[2, 3]]; [v1, a, b]' +assert_equal '[[1], 2, 3]', '*v1,(*), (a, b) = [1,:x,[2, 3]]; [v1, a, b]' + +assert_equal '[]', '*a = *nil; a' +assert_equal '[nil]', '*a = nil; a' +assert_equal '2', 'a, a = 1, 2; a', "[ruby-dev:31522]" +assert_equal '[1, 2]', 'a, b = 1, 2' +assert_equal '[1, 2]', %q{ + ans = [] + trace_var(:$a){|v| ans << v} + trace_var(:$b){|v| ans << v} + $a, $b = 1, 2 + ans +} + +assert_equal 'ok', %q{ + r = :ok + :ng.tap {|(r)|} + r +}, '[ruby-dev:31507]' + +=begin +# generated by this script: + +3.times{|i| + 8.times{|e| + ary = (0...e).to_a + a,b,c,d,e,f = nil + vals = %w(a b c d e f) + vals[i] = '*' + vals[i] + program = "#{vals.join(", ")} = *ary" + eval(program) + ans = [a,b,c,d,e,f] + puts %Q{ + assert_equal "#{ans.inspect}", %q{ + ary = #{ary.inspect} + #{program}; [a, b, c, d, e, f] + }} + } +} +=end + + assert_equal "[[], nil, nil, nil, nil, nil]", %q{ + ary = [] + *a, b, c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[[], 0, nil, nil, nil, nil]", %q{ + ary = [0] + *a, b, c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[[], 0, 1, nil, nil, nil]", %q{ + ary = [0, 1] + *a, b, c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[[], 0, 1, 2, nil, nil]", %q{ + ary = [0, 1, 2] + *a, b, c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[[], 0, 1, 2, 3, nil]", %q{ + ary = [0, 1, 2, 3] + *a, b, c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[[], 0, 1, 2, 3, 4]", %q{ + ary = [0, 1, 2, 3, 4] + *a, b, c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[[0], 1, 2, 3, 4, 5]", %q{ + ary = [0, 1, 2, 3, 4, 5] + *a, b, c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[[0, 1], 2, 3, 4, 5, 6]", %q{ + ary = [0, 1, 2, 3, 4, 5, 6] + *a, b, c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[nil, [], nil, nil, nil, nil]", %q{ + ary = [] + a, *b, c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[0, [], nil, nil, nil, nil]", %q{ + ary = [0] + a, *b, c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[0, [], 1, nil, nil, nil]", %q{ + ary = [0, 1] + a, *b, c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[0, [], 1, 2, nil, nil]", %q{ + ary = [0, 1, 2] + a, *b, c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[0, [], 1, 2, 3, nil]", %q{ + ary = [0, 1, 2, 3] + a, *b, c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[0, [], 1, 2, 3, 4]", %q{ + ary = [0, 1, 2, 3, 4] + a, *b, c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[0, [1], 2, 3, 4, 5]", %q{ + ary = [0, 1, 2, 3, 4, 5] + a, *b, c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[0, [1, 2], 3, 4, 5, 6]", %q{ + ary = [0, 1, 2, 3, 4, 5, 6] + a, *b, c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[nil, nil, [], nil, nil, nil]", %q{ + ary = [] + a, b, *c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[0, nil, [], nil, nil, nil]", %q{ + ary = [0] + a, b, *c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[0, 1, [], nil, nil, nil]", %q{ + ary = [0, 1] + a, b, *c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[0, 1, [], 2, nil, nil]", %q{ + ary = [0, 1, 2] + a, b, *c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[0, 1, [], 2, 3, nil]", %q{ + ary = [0, 1, 2, 3] + a, b, *c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[0, 1, [], 2, 3, 4]", %q{ + ary = [0, 1, 2, 3, 4] + a, b, *c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[0, 1, [2], 3, 4, 5]", %q{ + ary = [0, 1, 2, 3, 4, 5] + a, b, *c, d, e, f = *ary; [a, b, c, d, e, f] + } + + assert_equal "[0, 1, [2, 3], 4, 5, 6]", %q{ + ary = [0, 1, 2, 3, 4, 5, 6] + a, b, *c, d, e, f = *ary; [a, b, c, d, e, f] + } + + +# +assert_equal 'ok', %q{ + a,s=[],"aaa" + 300.times { a<<s; s=s.succ } + eval <<-END__ + GC.stress=true + Fiber.new do + #{ a.join(",") },*zzz=1 + end.resume + END__ + :ok +}, '[ruby-dev:32581]' + +assert_equal 'ok', %q{ + while true + *, z = 1 + break + end + :ok +}, '[ruby-dev:32892]' diff --git a/trunk/bootstraptest/test_method.rb b/trunk/bootstraptest/test_method.rb new file mode 100644 index 0000000000..5bc0f8ccec --- /dev/null +++ b/trunk/bootstraptest/test_method.rb @@ -0,0 +1,1060 @@ +# regular argument +assert_equal '1', 'def m() 1 end; m()' +assert_equal '1', 'def m(a) a end; m(1)' +assert_equal '[1, 2]', 'def m(a,b) [a, b] end; m(1,2)' +assert_equal '[1, 2, 3]', 'def m(a,b,c) [a, b, c] end; m(1,2,3)' +assert_equal 'wrong number of arguments (1 for 0)', %q{ + def m; end + begin + m(1) + rescue => e + e.message + end +} + +assert_equal 'wrong number of arguments (0 for 1)', %q{ + def m a; end + begin + m + rescue => e + e.message + end +} + +# default argument +assert_equal '1', 'def m(x=1) x end; m()' +assert_equal '1', 'def m(x=7) x end; m(1)' +assert_equal '1', 'def m(a,x=1) x end; m(7)' +assert_equal '1', 'def m(a,x=7) x end; m(7,1)' +assert_equal '1', 'def m(a,b,x=1) x end; m(7,7)' +assert_equal '1', 'def m(a,b,x=7) x end; m(7,7,1)' +assert_equal '1', 'def m(a,x=1,y=1) x end; m(7)' +assert_equal '1', 'def m(a,x=1,y=1) y end; m(7)' +assert_equal '1', 'def m(a,x=7,y=1) x end; m(7,1)' +assert_equal '1', 'def m(a,x=7,y=1) y end; m(7,1)' +assert_equal '1', 'def m(a,x=7,y=7) x end; m(7,1,1)' +assert_equal '1', 'def m(a,x=7,y=7) y end; m(7,1,1)' + +# rest argument +assert_equal '[]', 'def m(*a) a end; m().inspect' +assert_equal '[1]', 'def m(*a) a end; m(1).inspect' +assert_equal '[1, 2]', 'def m(*a) a end; m(1,2).inspect' +assert_equal '[]', 'def m(x,*a) a end; m(7).inspect' +assert_equal '[1]', 'def m(x,*a) a end; m(7,1).inspect' +assert_equal '[1, 2]', 'def m(x,*a) a end; m(7,1,2).inspect' +assert_equal '[]', 'def m(x,y,*a) a end; m(7,7).inspect' +assert_equal '[1]', 'def m(x,y,*a) a end; m(7,7,1).inspect' +assert_equal '[1, 2]', 'def m(x,y,*a) a end; m(7,7,1,2).inspect' +assert_equal '[]', 'def m(x,y=7,*a) a end; m(7).inspect' +assert_equal '[]', 'def m(x,y,z=7,*a) a end; m(7,7).inspect' +assert_equal '[]', 'def m(x,y,z=7,*a) a end; m(7,7,7).inspect' +assert_equal '[]', 'def m(x,y,z=7,zz=7,*a) a end; m(7,7,7).inspect' +assert_equal '[]', 'def m(x,y,z=7,zz=7,*a) a end; m(7,7,7,7).inspect' +assert_equal '1', 'def m(x,y,z=7,zz=1,*a) zz end; m(7,7,7).inspect' +assert_equal '1', 'def m(x,y,z=7,zz=1,*a) zz end; m(7,7,7).inspect' +assert_equal '1', 'def m(x,y,z=7,zz=7,*a) zz end; m(7,7,7,1).inspect' + +# block argument +assert_equal 'Proc', 'def m(&block) block end; m{}.class' +assert_equal 'nil', 'def m(&block) block end; m().inspect' +assert_equal 'Proc', 'def m(a,&block) block end; m(7){}.class' +assert_equal 'nil', 'def m(a,&block) block end; m(7).inspect' +assert_equal '1', 'def m(a,&block) a end; m(1){}' +assert_equal 'Proc', 'def m(a,b=nil,&block) block end; m(7){}.class' +assert_equal 'nil', 'def m(a,b=nil,&block) block end; m(7).inspect' +assert_equal 'Proc', 'def m(a,b=nil,&block) block end; m(7,7){}.class' +assert_equal '1', 'def m(a,b=nil,&block) b end; m(7,1){}' +assert_equal 'Proc', 'def m(a,b=nil,*c,&block) block end; m(7){}.class' +assert_equal 'nil', 'def m(a,b=nil,*c,&block) block end; m(7).inspect' +assert_equal '1', 'def m(a,b=nil,*c,&block) a end; m(1).inspect' +assert_equal '1', 'def m(a,b=1,*c,&block) b end; m(7).inspect' +assert_equal '1', 'def m(a,b=7,*c,&block) b end; m(7,1).inspect' +assert_equal '[1]', 'def m(a,b=7,*c,&block) c end; m(7,7,1).inspect' + +# splat +assert_equal '1', 'def m(a) a end; m(*[1])' +assert_equal '1', 'def m(x,a) a end; m(7,*[1])' +assert_equal '1', 'def m(x,y,a) a end; m(7,7,*[1])' +assert_equal '1', 'def m(a,b) a end; m(*[1,7])' +assert_equal '1', 'def m(a,b) b end; m(*[7,1])' +assert_equal '1', 'def m(x,a,b) b end; m(7,*[7,1])' +assert_equal '1', 'def m(x,y,a,b) b end; m(7,7,*[7,1])' +assert_equal '1', 'def m(a,b,c) a end; m(*[1,7,7])' +assert_equal '1', 'def m(a,b,c) b end; m(*[7,1,7])' +assert_equal '1', 'def m(a,b,c) c end; m(*[7,7,1])' +assert_equal '1', 'def m(x,a,b,c) a end; m(7,*[1,7,7])' +assert_equal '1', 'def m(x,y,a,b,c) a end; m(7,7,*[1,7,7])' + +# hash argument +assert_equal '1', 'def m(h) h end; m(7=>1)[7]' +assert_equal '1', 'def m(h) h end; m(7=>1).size' +assert_equal '1', 'def m(h) h end; m(7=>1, 8=>7)[7]' +assert_equal '2', 'def m(h) h end; m(7=>1, 8=>7).size' +assert_equal '1', 'def m(h) h end; m(7=>1, 8=>7, 9=>7)[7]' +assert_equal '3', 'def m(h) h end; m(7=>1, 8=>7, 9=>7).size' +assert_equal '1', 'def m(x,h) h end; m(7, 7=>1)[7]' +assert_equal '1', 'def m(x,h) h end; m(7, 7=>1, 8=>7)[7]' +assert_equal '1', 'def m(x,h) h end; m(7, 7=>1, 8=>7, 9=>7)[7]' +assert_equal '1', 'def m(x,y,h) h end; m(7,7, 7=>1)[7]' +assert_equal '1', 'def m(x,y,h) h end; m(7,7, 7=>1, 8=>7)[7]' +assert_equal '1', 'def m(x,y,h) h end; m(7,7, 7=>1, 8=>7, 9=>7)[7]' + +# block argument +assert_equal '1', %q(def m(&block) mm(&block) end + def mm() yield 1 end + m {|a| a }) +assert_equal '1', %q(def m(x,&block) mm(x,&block) end + def mm(x) yield 1 end + m(7) {|a| a }) +assert_equal '1', %q(def m(x,y,&block) mm(x,y,&block) end + def mm(x,y) yield 1 end + m(7,7) {|a| a }) + +# recursive call +assert_equal '1', %q(def m(n) n == 0 ? 1 : m(n-1) end; m(5)) + +# instance method +assert_equal '1', %q(class C; def m() 1 end end; C.new.m) +assert_equal '1', %q(class C; def m(a) a end end; C.new.m(1)) +assert_equal '1', %q(class C; def m(a = 1) a end end; C.new.m) +assert_equal '[1]', %q(class C; def m(*a) a end end; C.new.m(1).inspect) +assert_equal '1', %q( class C + def m() mm() end + def mm() 1 end + end + C.new.m ) + +# singleton method (const) +assert_equal '1', %q(class C; def C.m() 1 end end; C.m) +assert_equal '1', %q(class C; def C.m(a) a end end; C.m(1)) +assert_equal '1', %q(class C; def C.m(a = 1) a end end; C.m) +assert_equal '[1]', %q(class C; def C.m(*a) a end end; C.m(1).inspect) +assert_equal '1', %q(class C; end; def C.m() 1 end; C.m) +assert_equal '1', %q(class C; end; def C.m(a) a end; C.m(1)) +assert_equal '1', %q(class C; end; def C.m(a = 1) a end; C.m) +assert_equal '[1]', %q(class C; end; def C.m(*a) a end; C.m(1).inspect) +assert_equal '1', %q(class C; def m() 7 end end; def C.m() 1 end; C.m) +assert_equal '1', %q( class C + def C.m() mm() end + def C.mm() 1 end + end + C.m ) + +# singleton method (lvar) +assert_equal '1', %q(obj = Object.new; def obj.m() 1 end; obj.m) +assert_equal '1', %q(obj = Object.new; def obj.m(a) a end; obj.m(1)) +assert_equal '1', %q(obj = Object.new; def obj.m(a=1) a end; obj.m) +assert_equal '[1]', %q(obj = Object.new; def obj.m(*a) a end; obj.m(1)) +assert_equal '1', %q(class C; def m() 7 end; end + obj = C.new + def obj.m() 1 end + obj.m) + +# inheritance +assert_equal '1', %q(class A; def m(a) a end end + class B < A; end + B.new.m(1)) +assert_equal '1', %q(class A; end + class B < A; def m(a) a end end + B.new.m(1)) +assert_equal '1', %q(class A; def m(a) a end end + class B < A; end + class C < B; end + C.new.m(1)) + +# include +assert_equal '1', %q(class A; def m(a) a end end + module M; end + class B < A; include M; end + B.new.m(1)) +assert_equal '1', %q(class A; end + module M; def m(a) a end end + class B < A; include M; end + B.new.m(1)) + +# alias +assert_equal '1', %q( def a() 1 end + alias m a + m() ) +assert_equal '1', %q( class C + def a() 1 end + alias m a + end + C.new.m ) +assert_equal '1', %q( class C + def a() 1 end + alias :m a + end + C.new.m ) +assert_equal '1', %q( class C + def a() 1 end + alias m :a + end + C.new.m ) +assert_equal '1', %q( class C + def a() 1 end + alias :m :a + end + C.new.m ) +assert_equal '1', %q( class C + def a() 1 end + alias m a + undef a + end + C.new.m ) + +# undef +assert_equal '1', %q( class C + def m() end + undef m + end + begin C.new.m; rescue NoMethodError; 1 end ) +assert_equal '1', %q( class A + def m() end + end + class C < A + def m() end + undef m + end + begin C.new.m; rescue NoMethodError; 1 end ) +assert_equal '1', %q( class A; def a() end end # [yarv-dev:999] + class B < A + def b() end + undef a, b + end + begin B.new.a; rescue NoMethodError; 1 end ) +assert_equal '1', %q( class A; def a() end end # [yarv-dev:999] + class B < A + def b() end + undef a, b + end + begin B.new.b; rescue NoMethodError; 1 end ) + +assert_equal '3', %q{ + def m1 + 1 + end + alias m2 m1 + alias :"#{'m3'}" m1 + m1 + m2 + m3 +}, '[ruby-dev:32308]' +assert_equal '1', %q{ + def foobar + end + undef :"foo#{:bar}" + 1 +}, '[ruby-dev:32308]' +assert_equal '1', %q{ + def foobar + 1 + end + alias :"bar#{:baz}" :"foo#{:bar}" + barbaz +}, '[ruby-dev:32308]' + +# private +assert_equal '1', %q( class C + def m() mm() end + def mm() 1 end + private :mm + end + C.new.m ) +assert_equal '1', %q( class C + def m() 7 end + private :m + end + begin C.m; rescue NoMethodError; 1 end ) +assert_equal '1', %q( class C + def C.m() mm() end + def C.mm() 1 end + private_class_method :mm + end + C.m ) +assert_equal '1', %q( class C + def C.m() 7 end + private_class_method :m + end + begin C.m; rescue NoMethodError; 1 end ) +assert_equal '1', %q( class C; def m() 1 end end + C.new.m # cache + class C + alias mm m; private :mm + end + C.new.m + begin C.new.mm; 7; rescue NoMethodError; 1 end ) + +# nested method +assert_equal '1', %q( class C + def m + def mm() 1 end + end + end + C.new.m + C.new.mm ) +assert_equal '1', %q( class C + def m + def mm() 1 end + end + end + instance_eval "C.new.m; C.new.mm" ) + +# method_missing +assert_equal ':m', %q( class C + def method_missing(mid, *args) mid end + end + C.new.m.inspect ) +assert_equal ':mm', %q( class C + def method_missing(mid, *args) mid end + end + C.new.mm.inspect ) +assert_equal '[1, 2]', %q( class C + def method_missing(mid, *args) args end + end + C.new.m(1,2).inspect ) +assert_equal '1', %q( class C + def method_missing(mid, *args) yield 1 end + end + C.new.m {|a| a }) +assert_equal 'nil', %q( class C + def method_missing(mid, *args, &block) block end + end + C.new.m.inspect ) + +# send +assert_equal '1', %q( class C; def m() 1 end end; + C.new.__send__(:m) ) +assert_equal '1', %q( class C; def m() 1 end end; + C.new.send(:m) ) +assert_equal '1', %q( class C; def m(a) a end end; + C.new.send(:m,1) ) +assert_equal '1', %q( class C; def m(a,b) a end end; + C.new.send(:m,1,7) ) +assert_equal '1', %q( class C; def m(x,a=1) a end end; + C.new.send(:m,7) ) +assert_equal '1', %q( class C; def m(x,a=7) a end end; + C.new.send(:m,7,1) ) +assert_equal '[1, 2]', %q( class C; def m(*a) a end end; + C.new.send(:m,1,2).inspect ) +assert_equal '1', %q( class C; def m() 7 end; private :m end + begin C.new.public_send(:m); rescue NoMethodError; 1 end ) +assert_equal '1', %q( class C; def m() 1 end; private :m end + C.new.send(:m) ) + +# with block +assert_equal '[[:ok1, :foo], [:ok2, :foo, :bar]]', +%q{ + class C + def [](a) + $ary << [yield, a] + end + def []=(a, b) + $ary << [yield, a, b] + end + end + + $ary = [] + C.new[:foo, &lambda{:ok1}] + C.new[:foo, &lambda{:ok2}] = :bar + $ary +} + +# with +assert_equal '[:ok1, [:ok2, 11]]', %q{ + class C + def [] + $ary << :ok1 + 10 + end + def []=(a) + $ary << [:ok2, a] + end + end + $ary = [] + C.new[]+=1 + $ary +} + +# splat and block arguments +assert_equal %q{[[[:x, :y, :z], NilClass], [[1, :x, :y, :z], NilClass], [[1, 2, :x, :y, :z], NilClass], [[:obj], NilClass], [[1, :obj], NilClass], [[1, 2, :obj], NilClass], [[], Proc], [[1], Proc], [[1, 2], Proc], [[], Proc], [[1], Proc], [[1, 2], Proc], [[:x, :y, :z], Proc], [[1, :x, :y, :z], Proc], [[1, 2, :x, :y, :z], Proc]]}, %q{ +def m(*args, &b) + $result << [args, b.class] +end +$result = [] +ary = [:x, :y, :z] +obj = :obj +b = Proc.new{} + +m(*ary) +m(1,*ary) +m(1,2,*ary) +m(*obj) +m(1,*obj) +m(1,2,*obj) +m(){} +m(1){} +m(1,2){} +m(&b) +m(1,&b) +m(1,2,&b) +m(*ary,&b) +m(1,*ary,&b) +m(1,2,*ary,&b) +$result +} + +# post test +assert_equal %q{[1, 2, :o1, :o2, [], 3, 4, NilClass, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, b.class, x, y] +end +; m(1, 2, 3, 4)} + +assert_equal %q{[1, 2, 3, :o2, [], 4, 5, NilClass, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, b.class, x, y] +end +; m(1, 2, 3, 4, 5)} + +assert_equal %q{[1, 2, 3, 4, [], 5, 6, NilClass, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, b.class, x, y] +end +; m(1, 2, 3, 4, 5, 6)} + +assert_equal %q{[1, 2, 3, 4, [5], 6, 7, NilClass, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, b.class, x, y] +end +; m(1, 2, 3, 4, 5, 6, 7)} + +assert_equal %q{[1, 2, 3, 4, [5, 6], 7, 8, NilClass, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, b.class, x, y] +end +; m(1, 2, 3, 4, 5, 6, 7, 8)} + +assert_equal %q{[1, 2, 3, 4, [5, 6, 7], 8, 9, NilClass, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, b.class, x, y] +end +; m(1, 2, 3, 4, 5, 6, 7, 8, 9)} + +assert_equal %q{[1, 2, 3, 4, [5, 6, 7, 8], 9, 10, NilClass, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, b.class, x, y] +end +; m(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)} + +assert_equal %q{[1, 2, 3, 4, [5, 6, 7, 8, 9], 10, 11, NilClass, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, b.class, x, y] +end +; m(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)} + +assert_equal %q{[1, 2, :o1, :o2, [], 3, 4, Proc, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, b.class, x, y] +end +; m(1, 2, 3, 4){}} + +assert_equal %q{[1, 2, 3, :o2, [], 4, 5, Proc, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, b.class, x, y] +end +; m(1, 2, 3, 4, 5){}} + +assert_equal %q{[1, 2, 3, 4, [], 5, 6, Proc, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, b.class, x, y] +end +; m(1, 2, 3, 4, 5, 6){}} + +assert_equal %q{[1, 2, 3, 4, [5], 6, 7, Proc, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, b.class, x, y] +end +; m(1, 2, 3, 4, 5, 6, 7){}} + +assert_equal %q{[1, 2, 3, 4, [5, 6], 7, 8, Proc, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, b.class, x, y] +end +; m(1, 2, 3, 4, 5, 6, 7, 8){}} + +assert_equal %q{[1, 2, 3, 4, [5, 6, 7], 8, 9, Proc, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, b.class, x, y] +end +; m(1, 2, 3, 4, 5, 6, 7, 8, 9){}} + +assert_equal %q{[1, 2, 3, 4, [5, 6, 7, 8], 9, 10, Proc, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, b.class, x, y] +end +; m(1, 2, 3, 4, 5, 6, 7, 8, 9, 10){}} + +assert_equal %q{[1, 2, 3, 4, [5, 6, 7, 8, 9], 10, 11, Proc, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, b.class, x, y] +end +; m(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11){}} + +assert_equal %q{[1, 2, :o1, :o2, [], 3, 4, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, x, y] +end +; m(1, 2, 3, 4)} + +assert_equal %q{[1, 2, 3, :o2, [], 4, 5, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, x, y] +end +; m(1, 2, 3, 4, 5)} + +assert_equal %q{[1, 2, 3, 4, [], 5, 6, nil, nil]}, %q{ +def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2) + x, y = :x, :y if $foo + [m1, m2, o1, o2, r, p1, p2, x, y] +end +; m(1, 2, 3, 4, 5, 6)} + + +# +# super +# +=begin +# below programs are generated by this program: + +BASE = <<EOS__ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; <TEST>; super; end; end +EOS__ + +tests = { +%q{ + def m +} => %q{ + C1.new.m +}, +# +%q{ + def m a +} => %q{ + C1.new.m 1 +}, +%q{ + def m a + a = :a +} => %q{ + C1.new.m 1 +}, +# +%q{ + def m a, o=:o +} => %q{ + C1.new.m 1 + C1.new.m 1, 2 +}, +%q{ + def m a, o=:o + a = :a +} => %q{ + C1.new.m 1 + C1.new.m 1, 2 +}, +%q{ + def m a, o=:o + o = :x +} => %q{ + C1.new.m 1 + C1.new.m 1, 2 +}, +# +%q{ + def m a, *r +} => %q{ + C1.new.m 1 + C1.new.m 1, 2 + C1.new.m 1, 2, 3 +}, +%q{ + def m a, *r + r = [:x, :y] +} => %q{ + C1.new.m 1 + C1.new.m 1, 2 + C1.new.m 1, 2, 3 +}, +# +%q{ + def m a, o=:o, *r +} => %q{ + C1.new.m 1 + C1.new.m 1, 2 + C1.new.m 1, 2, 3 + C1.new.m 1, 2, 3, 4 +}, +# +%q{ + def m a, o=:o, *r, &b +} => %q{ + C1.new.m 1 + C1.new.m 1, 2 + C1.new.m 1, 2, 3 + C1.new.m 1, 2, 3, 4 + C1.new.m(1){} + C1.new.m(1, 2){} + C1.new.m(1, 2, 3){} + C1.new.m(1, 2, 3, 4){} +}, +# +"def m(m1, m2, o1=:o1, o2=:o2, p1, p2)" => +%q{ +C1.new.m(1,2,3,4) +C1.new.m(1,2,3,4,5) +C1.new.m(1,2,3,4,5,6) +}, +# +"def m(m1, m2, *r, p1, p2)" => +%q{ +C1.new.m(1,2,3,4) +C1.new.m(1,2,3,4,5) +C1.new.m(1,2,3,4,5,6) +C1.new.m(1,2,3,4,5,6,7) +C1.new.m(1,2,3,4,5,6,7,8) +}, +# +"def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2)" => +%q{ +C1.new.m(1,2,3,4) +C1.new.m(1,2,3,4,5) +C1.new.m(1,2,3,4,5,6) +C1.new.m(1,2,3,4,5,6,7) +C1.new.m(1,2,3,4,5,6,7,8) +C1.new.m(1,2,3,4,5,6,7,8,9) +}, + +### +} + + +tests.each{|setup, methods| setup = setup.dup; setup.strip! + setup = BASE.gsub(/<TEST>/){setup} + methods.split(/\n/).each{|m| m = m.dup; m.strip! + next if m.empty? + expr = "#{setup}; #{m}" + result = eval(expr) + puts "assert_equal %q{#{result.inspect}}, %q{\n#{expr}}" + puts + } +} + +=end + +assert_equal %q{[:C0_m, [1, 2, :o1, :o2, 3, 4]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, p1, p2); super; end; end +; C1.new.m(1,2,3,4)} + +assert_equal %q{[:C0_m, [1, 2, 3, :o2, 4, 5]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, p1, p2); super; end; end +; C1.new.m(1,2,3,4,5)} + +assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, p1, p2); super; end; end +; C1.new.m(1,2,3,4,5,6)} + +assert_equal %q{[:C0_m, [1, :o]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o, *r; super; end; end +; C1.new.m 1} + +assert_equal %q{[:C0_m, [1, 2]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o, *r; super; end; end +; C1.new.m 1, 2} + +assert_equal %q{[:C0_m, [1, 2, 3]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o, *r; super; end; end +; C1.new.m 1, 2, 3} + +assert_equal %q{[:C0_m, [1, 2, 3, 4]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o, *r; super; end; end +; C1.new.m 1, 2, 3, 4} + +assert_equal %q{[:C0_m, [:a]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a + a = :a; super; end; end +; C1.new.m 1} + +assert_equal %q{[:C0_m, [1, 2, 3, 4]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end +; C1.new.m(1,2,3,4)} + +assert_equal %q{[:C0_m, [1, 2, 3, 4, 5]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end +; C1.new.m(1,2,3,4,5)} + +assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end +; C1.new.m(1,2,3,4,5,6)} + +assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end +; C1.new.m(1,2,3,4,5,6,7)} + +assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7, 8]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end +; C1.new.m(1,2,3,4,5,6,7,8)} + +assert_equal %q{[:C0_m, [1, :o]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o, *r, &b; super; end; end +; C1.new.m 1} + +assert_equal %q{[:C0_m, [1, 2]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o, *r, &b; super; end; end +; C1.new.m 1, 2} + +assert_equal %q{[:C0_m, [1, 2, 3]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o, *r, &b; super; end; end +; C1.new.m 1, 2, 3} + +assert_equal %q{[:C0_m, [1, 2, 3, 4]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o, *r, &b; super; end; end +; C1.new.m 1, 2, 3, 4} + +assert_equal %q{[:C0_m, [1, :o]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o, *r, &b; super; end; end +; C1.new.m(1){}} + +assert_equal %q{[:C0_m, [1, 2]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o, *r, &b; super; end; end +; C1.new.m(1, 2){}} + +assert_equal %q{[:C0_m, [1, 2, 3]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o, *r, &b; super; end; end +; C1.new.m(1, 2, 3){}} + +assert_equal %q{[:C0_m, [1, 2, 3, 4]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o, *r, &b; super; end; end +; C1.new.m(1, 2, 3, 4){}} + +assert_equal %q{[:C0_m, [1, :x]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o + o = :x; super; end; end +; C1.new.m 1} + +assert_equal %q{[:C0_m, [1, :x]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o + o = :x; super; end; end +; C1.new.m 1, 2} + +assert_equal %q{[:C0_m, [:a, :o]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o + a = :a; super; end; end +; C1.new.m 1} + +assert_equal %q{[:C0_m, [:a, 2]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o + a = :a; super; end; end +; C1.new.m 1, 2} + +assert_equal %q{[:C0_m, [1]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a; super; end; end +; C1.new.m 1} + +assert_equal %q{[:C0_m, [1, :x, :y]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, *r + r = [:x, :y]; super; end; end +; C1.new.m 1} + +assert_equal %q{[:C0_m, [1, :x, :y]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, *r + r = [:x, :y]; super; end; end +; C1.new.m 1, 2} + +assert_equal %q{[:C0_m, [1, :x, :y]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, *r + r = [:x, :y]; super; end; end +; C1.new.m 1, 2, 3} + +assert_equal %q{[:C0_m, [1, 2, :o1, :o2, 3, 4]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end +; C1.new.m(1,2,3,4)} + +assert_equal %q{[:C0_m, [1, 2, 3, :o2, 4, 5]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end +; C1.new.m(1,2,3,4,5)} + +assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end +; C1.new.m(1,2,3,4,5,6)} + +assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end +; C1.new.m(1,2,3,4,5,6,7)} + +assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7, 8]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end +; C1.new.m(1,2,3,4,5,6,7,8)} + +assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7, 8, 9]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end +; C1.new.m(1,2,3,4,5,6,7,8,9)} + +assert_equal %q{[:C0_m, [1]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, *r; super; end; end +; C1.new.m 1} + +assert_equal %q{[:C0_m, [1, 2]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, *r; super; end; end +; C1.new.m 1, 2} + +assert_equal %q{[:C0_m, [1, 2, 3]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, *r; super; end; end +; C1.new.m 1, 2, 3} + +assert_equal %q{[:C0_m, []]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m; super; end; end +; C1.new.m} + +assert_equal %q{[:C0_m, [1, :o]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o; super; end; end +; C1.new.m 1} + +assert_equal %q{[:C0_m, [1, 2]]}, %q{ +class C0; def m *args; [:C0_m, args]; end; end +class C1 < C0; def m a, o=:o; super; end; end +; C1.new.m 1, 2} + +assert_equal %q{[:ok, :ok, :ok, :ok, :ok, :ok, :ng, :ng]}, %q{ + $ans = [] + class Foo + def m + end + end + + c1 = c2 = nil + + lambda{ + $SAFE = 4 + c1 = Class.new{ + def m + end + } + c2 = Class.new(Foo){ + alias mm m + } + }.call + + def test + begin + yield + rescue SecurityError + $ans << :ok + else + $ans << :ng + end + end + + o1 = c1.new + o2 = c2.new + + test{o1.m} + test{o2.mm} + test{o1.send :m} + test{o2.send :mm} + test{o1.public_send :m} + test{o2.public_send :mm} + test{o1.method(:m).call} + test{o2.method(:mm).call} + $ans +} + +assert_equal 'ok', %q{ + class C + def x=(n) + end + def m + self.x = :ok + end + end + C.new.m +} + +assert_equal 'ok', %q{ + proc{ + $SAFE = 1 + class C + def m + :ok + end + end + }.call + C.new.m +}, '[ruby-core:11998]' + +assert_equal 'ok', %q{ + proc{ + $SAFE = 2 + class C + def m + :ok + end + end + }.call + C.new.m +}, '[ruby-core:11998]' + +assert_equal 'ok', %q{ + proc{ + $SAFE = 3 + class C + def m + :ng + end + end + }.call + begin + C.new.m + rescue SecurityError + :ok + end +}, '[ruby-core:11998]' + +assert_equal 'ok', %q{ + class B + def m() :fail end + end + class C < B + undef m + begin + remove_method :m + rescue NameError + end + end + begin + C.new.m + rescue NameError + :ok + end +}, '[ruby-dev:31816], [ruby-dev:31817]' + +assert_normal_exit %q{ + begin + Process.setrlimit(Process::RLIMIT_STACK, 4_202_496) + # FreeBSD fails this less than 4M + 8K bytes. + rescue Exception + exit + end + class C + attr "a" * (10*1024*1024) + end +}, '[ruby-dev:31818]' + +assert_equal 'ok', %q{ + class Module + def define_method2(name, &block) + define_method(name, &block) + end + end + class C + define_method2(:m) {|x, y| :fail } + end + begin + C.new.m([1,2]) + rescue ArgumentError + :ok + end +} + +assert_not_match /method_missing/, %q{ + STDERR.reopen(STDOUT) + variable_or_mehtod_not_exist +} + +assert_equal '[false, false, false, false, true, true]', %q{ + class C + define_method(:foo) { + block_given? + } + end + + C.new.foo {} + + class D + def foo + D.module_eval{ + define_method(:m1){ + block_given? + } + } + end + def bar + D.module_eval{ + define_method(:m2){ + block_given? + } + } + end + end + + D.new.foo + D.new.bar{} + [C.new.foo, C.new.foo{}, D.new.m1, D.new.m1{}, D.new.m2, D.new.m2{}] +}, '[ruby-core:14813]' diff --git a/trunk/bootstraptest/test_objectspace.rb b/trunk/bootstraptest/test_objectspace.rb new file mode 100644 index 0000000000..1a43d42017 --- /dev/null +++ b/trunk/bootstraptest/test_objectspace.rb @@ -0,0 +1,33 @@ +assert_normal_exit %q{ + eval("", TOPLEVEL_BINDING) + minobj = ObjectSpace.to_enum(:each_object).min_by {|a| a.object_id } + maxobj = ObjectSpace.to_enum(:each_object).max_by {|a| a.object_id } + minobj.object_id.upto(maxobj.object_id) {|id| + begin + o = ObjectSpace._id2ref(id) + rescue RangeError + next + end + o.inspect if defined?(o.inspect) + } +}, '[ruby-dev:31911]' + +assert_normal_exit %q{ + ary = (1..10).to_a + ary.permutation(2) {|x| + if x == [1,2] + ObjectSpace.each_object(String) {|s| + s.clear if !s.frozen? && (s.length == 40 || s.length == 80) + } + end + } +}, '[ruby-dev:31982]' + +assert_normal_exit %q{ + ary = (1..100).to_a + ary.permutation(2) {|x| + if x == [1,2] + ObjectSpace.each_object(Array) {|o| o.clear if o == ary && o.object_id != ary.object_id } + end + } +}, '[ruby-dev:31985]' diff --git a/trunk/bootstraptest/test_proc.rb b/trunk/bootstraptest/test_proc.rb new file mode 100644 index 0000000000..1ab9444c31 --- /dev/null +++ b/trunk/bootstraptest/test_proc.rb @@ -0,0 +1,396 @@ +assert_equal %q{[1, 2, 3]}, %q{ + def getproc &b + b + end + + def m + yield + end + + m{ + i = 1 + m{ + j = 2 + m{ + k = 3 + getproc{ + [i, j, k] + } + } + } + }.call +} +assert_equal %q{7}, %q{ + def make_proc(&b) + b + end + + def make_closure + a = 0 + make_proc{ + a+=1 + } + end + + cl = make_closure + cl.call + cl.call * cl.call +} +assert_equal %q{ok}, %q{ + class C + def foo + :ok + end + end + + def block + C.method(:new).to_proc + end + b = block() + b.call.foo +} +assert_equal %q{[0, 1, :last, 0, 2, :last]}, %q{ + def proc &b + b + end + + pr = [] + proc{|i_b| + p3 = proc{|j_b| + pr << proc{|k_b| + [i_b, j_b, k_b] + } + } + p3.call(1) + p3.call(2) + }.call(0) + + pr[0].call(:last).concat pr[1].call(:last) +} +assert_equal %q{12}, %q{ + def iter + yield + end + + def getproc &b + b + end + + iter{ + bvar = 3 + getproc{ + bvar2 = 4 + bvar * bvar2 + } + }.call +} +assert_equal %q{200}, %q{ + def iter + yield + end + + def getproc &b + b + end + + loc1 = 0 + pr1 = iter{ + bl1 = 1 + getproc{ + loc1 += 1 + bl1 += 1 + loc1 + bl1 + } + } + + pr2 = iter{ + bl1 = 1 + getproc{ + loc1 += 1 + bl1 += 1 + loc1 + bl1 + } + } + + pr1.call; pr2.call + pr1.call; pr2.call + pr1.call; pr2.call + (pr1.call + pr2.call) * loc1 +} +assert_equal %q{[1, 2]}, %q{ + def proc(&pr) + pr + end + + def m + a = 1 + m2{ + a + } + end + + def m2 + b = 2 + proc{ + [yield, b] + } + end + + pr = m + x = ['a', 1,2,3,4,5,6,7,8,9,0, + 1,2,3,4,5,6,7,8,9,0, + 1,2,3,4,5,6,7,8,9,0, + 1,2,3,4,5,6,7,8,9,0, + 1,2,3,4,5,6,7,8,9,0,] + pr.call +} +assert_equal %q{1}, %q{ + def proc(&pr) + pr + end + + def m + a = 1 + m2{ + a + } + end + + def m2 + b = 2 + proc{ + [yield, b] + } + 100000.times{|x| + "#{x}" + } + yield + end + m +} +assert_equal %q{[:C, :C]}, %q{ + Const = :top + class C + Const = :C + $pr = proc{ + (1..2).map{ + Const + } + } + end + $pr.call +} +assert_equal %q{top}, %q{ + Const = :top + class C + Const = :C + end + pr = proc{ + Const + } + C.class_eval %q{ + pr.call + } +} +assert_equal %q{1}, %q{ + def m(&b) + b + end + + m{|e_proctest| e_proctest}.call(1) +} +assert_equal %q{12}, %q{ + def m(&b) + b + end + + m{|e_proctest1, e_proctest2| + a = e_proctest1 * e_proctest2 * 2 + a * 3 + }.call(1, 2) +} +assert_equal %q{[[], [1], [1, 2], [1, 2, 3]]}, %q{ + [ + Proc.new{|*args| args}.call(), + Proc.new{|*args| args}.call(1), + Proc.new{|*args| args}.call(1, 2), + Proc.new{|*args| args}.call(1, 2, 3), + ] +} +assert_equal %q{[[nil, []], [1, []], [1, [2]], [1, [2, 3]]]}, %q{ + [ + Proc.new{|a, *b| [a, b]}.call(), + Proc.new{|a, *b| [a, b]}.call(1), + Proc.new{|a, *b| [a, b]}.call(1, 2), + Proc.new{|a, *b| [a, b]}.call(1, 2, 3), + ] +} +assert_equal %q{0}, %q{ + pr = proc{ + $SAFE + } + $SAFE = 1 + pr.call +} +assert_equal %q{[1, 0]}, %q{ + pr = proc{ + $SAFE += 1 + } + [pr.call, $SAFE] +} +assert_equal %q{1}, %q{ + def m(&b) + b + end + m{1}.call +} +assert_equal %q{3}, %q{ + def m(&b) + b + end + + m{ + a = 1 + a + 2 + }.call +} +assert_equal %Q{ok\n}, %q{ + class A; def get_block; proc {puts "ok"} end end + block = A.new.get_block + GC.start + block.call +}, '[ruby-core:14885]' + +assert_equal 'ok', %q{ + a = lambda {|x, y, &b| b } + b = a.curry[1] + if b.call(2){} == nil + :ng + else + :ok + end +}, '[ruby-core:15551]' + +assert_equal 'ok', %q{ + lambda { + break :ok + :ng + }.call +}, '[ruby-dev:34646]' + +assert_equal %q{[:bar, :foo]}, %q{ + def foo + klass = Class.new do + define_method(:bar) do + return :bar + end + end + [klass.new.bar, :foo] + end + foo +}, "[ ruby-Bugs-19304 ]" + +assert_equal 'ok', %q{ + $x = :ok + def def7(x, y) + x[y] + $x = :ng + end + def test_def7 + def7(lambda {|x| x.call}, Proc.new {return}) + $x = :ng + end + test_def7 + $x +}, '[ruby-core:17164]' + +assert_equal 'ok', %q{ + lambda { a = lambda { return }; $x = :ng; a[]; $x = :ok }.call + $x +}, '[ruby-core:17164]' + +assert_equal 'ok', %q{ + lambda { a = lambda { break }; $x = :ng; a[]; $x = :ok }.call + $x +}, '[ruby-core:17164]' + +assert_equal 'ok', %q{ + def def8 + $x = :ng + lambda { a = Proc.new { return }; a[]}.call + $x = :ok + end + def8 + $x +}, '[ruby-core:17164]' + + +assert_equal 'ok', %q{ + def def9 + lambda {|a| $x = :ok; a[]; $x = :ng }.call(Proc.new { return }) + $x = :ng + end + def9 + $x +}, '[ruby-core:17164]' + +assert_equal 'ok', %q{ + def def10 + $x = :ng + lambda { 1.times { return } }.call + $x = :ok + end + $x = :ok + def10 + $x +}, '[ruby-core:17164]' + +assert_equal 'ok', %q{ + def def11 + yield + end + begin + lambda { def11 { return } }.call + rescue LocalJumpError + :ng + else + :ok + end +}, '[ruby-core:17164]' + +assert_equal 'ok', %q{ + def def12 + b = Proc.new { $x = :ng; lambda { return }.call; $x = :ok }.call + end + def12 + $x +}, '[ruby-core:17164]' + +assert_equal 'ok', %q{ + def m + pr = proc{ + proc{ + return :ok + } + }.call + pr.call + :ng + end + m() +} + +assert_equal 'ok', %q{ + class Foo + def call_it + p = Proc.new + p.call + end + end + + def give_it + proc { :ok } + end + + f = Foo.new + a_proc = give_it + f.call_it(&give_it()) +}, '[ruby-core:15711]' diff --git a/trunk/bootstraptest/test_struct.rb b/trunk/bootstraptest/test_struct.rb new file mode 100644 index 0000000000..a65964d5f9 --- /dev/null +++ b/trunk/bootstraptest/test_struct.rb @@ -0,0 +1,5 @@ +assert_equal 'Struct::Foo', %q{ + Struct.instance_eval { const_set(:Foo, nil) } + Struct.new("Foo") + Struct::Foo +} diff --git a/trunk/bootstraptest/test_syntax.rb b/trunk/bootstraptest/test_syntax.rb new file mode 100644 index 0000000000..a9005a4292 --- /dev/null +++ b/trunk/bootstraptest/test_syntax.rb @@ -0,0 +1,830 @@ +assert_equal %q{4}, %q{1 && 2 && 3 && 4} +assert_equal %q{}, %q{1 && nil && 3 && 4} +assert_equal %q{}, %q{1 && 2 && 3 && nil} +assert_equal %q{false}, %q{1 && 2 && 3 && false} +assert_equal %q{4}, %q{1 and 2 and 3 and 4} +assert_equal %q{}, %q{1 and nil and 3 and 4} +assert_equal %q{}, %q{1 and 2 and 3 and nil} +assert_equal %q{false}, %q{1 and 2 and 3 and false} +assert_equal %q{}, %q{nil && true} +assert_equal %q{false}, %q{false && true} +assert_equal %q{}, %q{ + case 1 + when 2 + :ng + end} +assert_equal %q{ok}, %q{ + case 1 + when 10,20,30 + :ng1 + when 1,2,3 + :ok + when 100,200,300 + :ng2 + else + :elseng + end} +assert_equal %q{elseok}, %q{ + case 123 + when 10,20,30 + :ng1 + when 1,2,3 + :ng2 + when 100,200,300 + :ng3 + else + :elseok + end +} +assert_equal %q{ok}, %q{ + case 'test' + when /testx/ + :ng1 + when /test/ + :ok + when /tetxx/ + :ng2 + else + :ng_else + end +} +assert_equal %q{ok}, %q{ + case Object.new + when Object + :ok + end +} +assert_equal %q{ok}, %q{ + case Object + when Object.new + :ng + else + :ok + end +} +assert_equal %q{ok}, %q{ + case 'test' + when 'tes' + :ng + when 'te' + :ng + else + :ok + end +} +assert_equal %q{ok}, %q{ + case 'test' + when 'tes' + :ng + when 'te' + :ng + when 'test' + :ok + end +} +assert_equal %q{ng}, %q{ + case 'test' + when 'tes' + :ng + when /te/ + :ng + else + :ok + end +} +assert_equal %q{ok}, %q{ + case 'test' + when 'tes' + :ng + when /test/ + :ok + else + :ng + end +} +assert_equal %q{100}, %q{ + def test(arg) + case 1 + when 2 + 3 + end + return arg + end + + test(100) +} +assert_equal %q{ok}, %q{ + ary = [1, 2] + case 1 + when *ary + :ok + else + :ng + end +} +assert_equal %q{ok}, %q{ + ary = [1, 2] + case 3 + when *ary + :ng + else + :ok + end +} +assert_equal %q{ok}, %q{ + ary = [1, 2] + case 1 + when :x, *ary + :ok + when :z + :ng1 + else + :ng2 + end +} +assert_equal %q{ok}, %q{ + ary = [1, 2] + case 3 + when :x, *ary + :ng1 + when :z + :ng2 + else + :ok + end +} +assert_equal %q{[:false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :false, :false, :false, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :then, :false, :then, :then, :then, :false, :false, :false, :false, :false, :false, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :false, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :false, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :false, :then, :then, :then, :then, :then, :then, :then, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep, :then, :sep]}, %q{ + + def make_perm ary, num + if num == 1 + ary.map{|e| [e]} + else + base = make_perm(ary, num-1) + res = [] + base.each{|b| + ary.each{|e| + res << [e] + b + } + } + res + end + end + + def each_test + conds = make_perm(['fv', 'tv'], 3) + bangs = make_perm(['', '!'], 3) + exprs = make_perm(['and', 'or'], 3) + ['if', 'unless'].each{|syn| + conds.each{|cs| + bangs.each{|bs| + exprs.each{|es| + yield(syn, cs, bs, es) + } + } + } + } + end + + fv = false + tv = true + + $ans = [] + each_test{|syn, conds, bangs, exprs| + c1, c2, c3 = conds + bang1, bang2, bang3 = bangs + e1, e2 = exprs + eval %Q{ + #{syn} #{bang1}#{c1} #{e1} #{bang2}#{c2} #{e2} #{bang3}#{c3} + $ans << :then + else + $ans << :false + end + } + } + + each_test{|syn, conds, bangs, exprs| + c1, c2, c3 = conds + bang1, bang2, bang3 = bangs + e1, e2 = exprs + eval %Q{ + #{syn} #{bang1}#{c1} #{e1} #{bang2}#{c2} #{e2} #{bang3}#{c3} + $ans << :then + end + $ans << :sep + } + } + $ans +} +assert_equal %q{}, %q{ + defined?(m) +} +assert_equal %q{method}, %q{ + def m + end + defined?(m) +} +assert_equal %q{}, %q{ + defined?(a.class) +} +assert_equal %q{method}, %q{ + a = 1 + defined?(a.class) +} +assert_equal %q{["method", "method", "method", "method", nil, nil, "method", "method", "method", nil]}, %q{ + class C + def test + [defined?(m1()), defined?(self.m1), defined?(C.new.m1), + defined?(m2()), defined?(self.m2), defined?(C.new.m2), + defined?(m3()), defined?(self.m3), defined?(C.new.m3)] + end + def m1 + end + private + def m2 + end + protected + def m3 + end + end + C.new.test + [defined?(C.new.m3)] +} +assert_equal %q{[nil, nil, nil, nil, "global-variable", "global-variable", nil, nil]}, %q{ + $ans = [defined?($1), defined?($2), defined?($3), defined?($4)] + /(a)(b)/ =~ 'ab' + $ans + [defined?($1), defined?($2), defined?($3), defined?($4)] +} +assert_equal %q{nilselftruefalse}, %q{ + defined?(nil) + defined?(self) + + defined?(true) + defined?(false) +} +assert_equal %q{}, %q{ + defined?(@a) +} +assert_equal %q{instance-variable}, %q{ + @a = 1 + defined?(@a) +} +assert_equal %q{}, %q{ + defined?(@@a) +} +assert_equal %q{class variable}, %q{ + @@a = 1 + defined?(@@a) +} +assert_equal %q{}, %q{ + defined?($a) +} +assert_equal %q{global-variable}, %q{ + $a = 1 + defined?($a) +} +assert_equal %q{}, %q{ + defined?(C_definedtest) +} +assert_equal %q{constant}, %q{ + C_definedtest = 1 + defined?(C_definedtest) +} +assert_equal %q{}, %q{ + defined?(::C_definedtest) +} +assert_equal %q{constant}, %q{ + C_definedtest = 1 + defined?(::C_definedtest) +} +assert_equal %q{}, %q{ + defined?(C_definedtestA::C_definedtestB::C_definedtestC) +} +assert_equal %q{constant}, %q{ + class C_definedtestA + class C_definedtestB + C_definedtestC = 1 + end + end + defined?(C_definedtestA::C_definedtestB::C_definedtestC) +} +assert_equal %q{30}, %q{ + sum = 0 + 30.times{|ib| + if ib % 10 == 0 .. true + sum += ib + end + } + sum +} +assert_equal %q{63}, %q{ + sum = 0 + 30.times{|ib| + if ib % 10 == 0 ... true + sum += ib + end + } + sum +} +assert_equal %q{[["NUM", "Type: NUM\n"], ["NUM", "123\n"], ["NUM", "456\n"], ["NUM", "Type: ARP\n"], ["NUM", "aaa\n"], ["NUM", "bbb\n"], ["NUM", "\f\n"], ["ARP", "Type: ARP\n"], ["ARP", "aaa\n"], ["ARP", "bbb\n"]]}, %q{ + t = nil + unless ''.respond_to? :lines + class String + def lines + self + end + end + end + ary = [] +"this must not print +Type: NUM +123 +456 +Type: ARP +aaa +bbb +\f +this must not print +hoge +Type: ARP +aaa +bbb +".lines.each{|l| + if (t = l[/^Type: (.*)/, 1])..(/^\f/ =~ l) + ary << [t, l] + end + } + ary +} +assert_equal %q{1}, %q{if true then 1 ; end} +assert_equal %q{}, %q{if false then 1 ; end} +assert_equal %q{1}, %q{if true then 1 ; else; 2; end} +assert_equal %q{2}, %q{if false then 1 ; else; 2; end} +assert_equal %q{}, %q{if true then ; elsif true then ; 1 ; end} +assert_equal %q{1}, %q{if false then ; elsif true then ; 1 ; end} +assert_equal %q{}, %q{unless true then 1 ; end} +assert_equal %q{1}, %q{unless false then 1 ; end} +assert_equal %q{2}, %q{unless true then 1 ; else; 2; end} +assert_equal %q{1}, %q{unless false then 1 ; else; 2; end} +assert_equal %q{1}, %q{1 if true} +assert_equal %q{}, %q{1 if false} +assert_equal %q{}, %q{1 if nil} +assert_equal %q{}, %q{1 unless true} +assert_equal %q{1}, %q{1 unless false} +assert_equal %q{1}, %q{1 unless nil} +assert_equal %q{1}, %q{1 || 2 || 3 || 4} +assert_equal %q{1}, %q{1 || false || 3 || 4} +assert_equal %q{2}, %q{nil || 2 || 3 || 4} +assert_equal %q{2}, %q{false || 2 || 3 || 4} +assert_equal %q{false}, %q{nil || false || nil || false} +assert_equal %q{1}, %q{1 or 2 or 3 or 4} +assert_equal %q{1}, %q{1 or false or 3 or 4} +assert_equal %q{2}, %q{nil or 2 or 3 or 4} +assert_equal %q{2}, %q{false or 2 or 3 or 4} +assert_equal %q{false}, %q{nil or false or nil or false} +assert_equal %q{elseng}, %q{ + case + when 1==2, 2==3 + :ng1 + when false, 4==5 + :ok + when false + :ng2 + else + :elseng + end +} +assert_equal %q{ok}, %q{ + case + when nil, nil + :ng1 + when 1,2,3 + :ok + when false, false + :ng2 + else + :elseng + end +} +assert_equal %q{elseok}, %q{ + case + when nil + :ng1 + when false + :ng2 + else + :elseok + end} +assert_equal %q{}, %q{ + case + when 1 + end +} +assert_equal %q{ok}, %q{ + r = nil + ary = [] + case + when false + r = :ng1 + when false, false + r = :ng2 + when *ary + r = :ng3 + when false, *ary + r = :ng4 + when true, *ary + r = :ok + end + r +} +assert_equal %q{ok}, %q{ + ary = [] + case + when false, *ary + :ng + else + :ok + end +} +assert_equal %q{ok}, %q{ + ary = [false, nil] + case + when *ary + :ng + else + :ok + end +} +assert_equal %q{ok}, %q{ + ary = [false, nil] + case + when *ary + :ng + when true + :ok + else + :ng2 + end +} +assert_equal %q{ng}, %q{ + ary = [false, nil] + case + when *ary + :ok + else + :ng + end +} +assert_equal %q{ok}, %q{ + ary = [false, true] + case + when *ary + :ok + else + :ng + end +} +assert_equal %q{ok}, %q{ + ary = [false, true] + case + when false, false + when false, *ary + :ok + else + :ng + end +} +assert_equal %q{}, %q{ + i = 0 + while i < 10 + i+=1 + end} +assert_equal %q{10}, %q{ + i = 0 + while i < 10 + i+=1 + end; i} +assert_equal %q{}, %q{ + i = 0 + until i > 10 + i+=1 + end} +assert_equal %q{11}, %q{ + i = 0 + until i > 10 + i+=1 + end; i} +assert_equal %q{1}, %q{ + i = 0 + begin + i+=1 + end while false + i +} +assert_equal %q{1}, %q{ + i = 0 + begin + i+=1 + end until true + i +} +def assert_syntax_error expected, code, message = '' + assert_equal "#{expected}", + "begin eval(%q{#{code}}, nil, '', 0)"'; rescue SyntaxError => e; e.message[/\A:(?:\d+:)? (.*)/, 1] end', message +end +assert_syntax_error "unterminated string meets end of file", '().."', '[ruby-dev:29732]' +assert_equal %q{[]}, %q{$&;[]}, '[ruby-dev:31068]' +assert_syntax_error "syntax error, unexpected tSTAR, expecting '}'", %q{{*0}}, '[ruby-dev:31072]' +assert_syntax_error "`@0' is not allowed as an instance variable name", %q{@0..0}, '[ruby-dev:31095]' +assert_syntax_error "identifier $00 is not valid to get", %q{$00..0}, '[ruby-dev:31100]' +assert_syntax_error "identifier $00 is not valid to set", %q{0..$00=1} +assert_equal %q{0}, %q{[*0];0}, '[ruby-dev:31102]' +assert_syntax_error "syntax error, unexpected ')'", %q{v0,(*,v1,) = 0}, '[ruby-dev:31104]' +assert_equal %q{1}, %q{ + class << (ary=[]); def []; 0; end; def []=(x); super(0,x);end;end; ary[]+=1 +}, '[ruby-dev:31110]' +assert_syntax_error "Can't set variable $1", %q{0..$1=1}, '[ruby-dev:31118]' +assert_valid_syntax %q{1.times{1+(1&&next)}}, '[ruby-dev:31119]' +assert_valid_syntax %q{x=-1;loop{x+=1&&redo if (x+=1).zero?}}, '[ruby-dev:31119]' +assert_syntax_error %q{syntax error, unexpected $end}, %q{!}, '[ruby-dev:31243]' +assert_equal %q{[nil]}, %q{[()]}, '[ruby-dev:31252]' +assert_equal %q{true}, %q{!_=()}, '[ruby-dev:31263]' +assert_equal 'ok', %q{while true; redo; end if 1 == 2; :ok}, '[ruby-dev:31360]' +assert_equal 'ok', %q{ + 1.times { + begin + ensure + next + end + }; :ok +}, '[ruby-dev:31373]' +assert_equal 'ok', %q{ + flag = false + 1.times { + next if flag + flag = true + begin + ensure + redo + end + }; :ok +}, '[ruby-dev:31373]' + +assert_equal 'ok', %q{ + 1.times{ + p(1, (next; 2)) + }; :ok +} +assert_equal '3', %q{ + i = 0 + 1 + (while true + break 2 if (i+=1) > 1 + next + end) +} +assert_equal '3', %q{ + i = 0 + 1 + (while true + break 2 if (i+=1) > 1 + p(1, (next; 2)) + end) +} +# redo +assert_equal 'ok', %q{ + i = 0 + 1.times{ + break if i>1 + i+=1 + p(1, (redo; 2)) + }; :ok +} +assert_equal '3', %q{ + i = 0 + 1 + (while true + break 2 if (i+=1) > 1 + redo + end) +} +assert_equal '3', %q{ + i = 0 + 1 + (while true + break 2 if (i+=1) > 1 + p(1, (redo; 2)) + end) +} +assert_equal '1', %q{ + a = [0] + a[*a]+=1 +} +assert_equal '2', %q{ + ary = [0] + case 1 + when *ary, 1 + 1 + end + + case + when *ary + 1 + end +} + +assert_match /invalid multibyte char/, %q{ + STDERR.reopen(STDOUT) + eval("\"\xf0".force_encoding("utf-8")) +}, '[ruby-dev:32429]' + +# method ! and != +assert_equal 'true', %q{!false} +assert_equal 'true', %q{1 == 1} +assert_equal 'true', %q{1 != 2} +assert_equal 'true', %q{ + class C; def !=(obj); true; end; end + C.new != 1 +} +assert_equal 'true', %q{ + class C; def !@; true; end; end + !C.new +} +assert_normal_exit %q{ + eval "while true; return; end rescue p $!" +}, '[ruby-dev:31663]' +assert_equal '1', %q{ + def bar + raise + end + + def foo + 1.times{ + begin + return bar + rescue + :ok + end + } + end + + foo +} + +assert_equal 'ok', %q{ + counter = 2 + while true + counter -= 1 + next if counter != 0 + break + end + :ok +}, '[ruby-core:14385]' + +assert_equal 'ok', %q{ + counter = 2 + while true + counter -= 1 + next if counter != 0 + break :ok + end # direct +}, '[ruby-core:14385]' + +assert_equal 'ok', %q{ + counter = 2 + while true + counter -= 1 + break if counter == 0 + "#{next}" + end + :ok +}, 'reported by Yusuke ENDOH' + +assert_equal 'ok', %q{ + counter = 2 + while true + counter -= 1 + break if counter == 0 + next + redo + end + :ok +}, 'reported by Yusuke ENDOH' + +assert_equal 'ok', %q{ + counter = 2 + while true + counter -= 1 + break if counter == 0 + next + "#{ redo }" + end + :ok +}, 'reported by Yusuke ENDOH' + +assert_normal_exit %q{ + begin + raise + rescue + counter = 2 + while true + counter -= 1 + break if counter == 0 + next + retry + end + end +}, 'reported by Yusuke ENDOH' + +assert_normal_exit %q{ + counter = 2 + while true + counter -= 1 + break if counter == 0 + next + "#{ break }" + end +}, 'reported by Yusuke ENDOH' + +assert_normal_exit %q{ + counter = 2 + while true + counter -= 1 + next if counter != 0 + "#{ break }" + end +}, 'reported by Yusuke ENDOH' + +assert_equal 'ok', %q{ + 1.times do + [ + 1, 2, 3, 4, 5, 6, 7, 8, + begin + false ? next : p + break while true + end + ] + end + :ok +}, '[ruby-dev:32882]' + +assert_equal "1\n2\n", %q{ + i = 0 + while i<2 + i += 1 + next p(i) + end +} + +assert_valid_syntax('1.times {|i|print (42),1;}', '[ruby-list:44479]') + +assert_equal 'ok', %q{ + def a() end + begin + if defined?(a(1).a) + :ng + else + :ok + end + rescue + :ng + end +}, '[ruby-core:16010]' + +assert_equal 'ok', %q{ + def a() end + begin + if defined?(a::B) + :ng + else + :ok + end + rescue + :ng + end +}, '[ruby-core:16010]' + +assert_normal_exit %q{ + defined? C && 0 +} + +assert_normal_exit %q{ + class C + def m + defined?(super()) + end + end + C.new.m +} + +assert_equal 'ok', %q{ + class X < RuntimeError;end + x = [X] + begin + raise X + rescue *x + :ok + end +}, '[ruby-core:14537]' + +assert_equal 'ok', %q{ + a = [false] + (a[0] &&= true) == false ? :ok : :ng +}, '[ruby-dev:34679]' + +assert_normal_exit %q{ + a = [] + 100.times {|i| a << i << nil << nil } + p a.compact! +} + diff --git a/trunk/bootstraptest/test_thread.rb b/trunk/bootstraptest/test_thread.rb new file mode 100644 index 0000000000..ebb60056ce --- /dev/null +++ b/trunk/bootstraptest/test_thread.rb @@ -0,0 +1,363 @@ +# Thread and Fiber + +assert_equal %q{ok}, %q{ + Thread.new{ + }.join + :ok +} +assert_equal %q{ok}, %q{ + Thread.new{ + :ok + }.value +} +assert_equal %q{20100}, %q{ + v = 0 + (1..200).map{|i| + Thread.new{ + i + } + }.each{|t| + v += t.value + } + v +} +assert_equal %q{5000}, %q{ + 5000.times{|e| + (1..2).map{ + Thread.new{ + } + }.each{|e| + e.join() + } + } +} +assert_equal %q{5000}, %q{ + 5000.times{|e| + (1..2).map{ + Thread.new{ + } + }.each{|e| + e.join(1000000000) + } + } +} +assert_equal %q{5000}, %q{ + 5000.times{ + t = Thread.new{} + while t.alive? + Thread.pass + end + } +} +assert_equal %q{100}, %q{ + 100.times{ + Thread.new{loop{Thread.pass}} + } +} +assert_equal %q{ok}, %q{ + Thread.new{ + :ok + }.join.value +} +assert_equal %q{ok}, %q{ + begin + Thread.new{ + raise "ok" + }.join + rescue => e + e + end +} +assert_equal %q{ok}, %q{ + ans = nil + t = Thread.new{ + begin + sleep 0.5 + ensure + ans = :ok + end + } + Thread.pass + t.kill + t.join + ans +} +assert_equal %q{ok}, %q{ + t = Thread.new{ + sleep + } + sleep 0.1 + t.raise + begin + t.join + :ng + rescue + :ok + end +} +assert_equal %q{ok}, %q{ + t = Thread.new{ + loop{} + } + Thread.pass + t.raise + begin + t.join + :ng + rescue + :ok + end +} +assert_equal %q{ok}, %q{ + t = Thread.new{ + } + Thread.pass + t.join + t.raise # raise to exited thread + begin + t.join + :ok + rescue + :ng + end +} +assert_equal %q{run}, %q{ + t = Thread.new{ + loop{} + } + st = t.status + t.kill + st +} +assert_equal %q{sleep}, %q{ + t = Thread.new{ + sleep + } + sleep 0.1 + st = t.status + t.kill + st +} +assert_equal %q{false}, %q{ + t = Thread.new{ + } + t.kill + sleep 0.1 + t.status +} +assert_equal %q{[ThreadGroup, true]}, %q{ + ptg = Thread.current.group + Thread.new{ + ctg = Thread.current.group + [ctg.class, ctg == ptg] + }.value +} +assert_equal %q{[1, 1]}, %q{ + thg = ThreadGroup.new + + t = Thread.new{ + thg.add Thread.current + sleep + } + sleep 0.1 + [thg.list.size, ThreadGroup::Default.list.size] +} +assert_equal %q{true}, %q{ + thg = ThreadGroup.new + + t = Thread.new{sleep 5} + thg.add t + thg.list.include?(t) +} +assert_equal %q{[true, nil, true]}, %q{ + /a/ =~ 'a' + $a = $~ + Thread.new{ + $b = $~ + /a/ =~ 'a' + $c = $~ + } + $d = $~ + [$a == $d, $b, $c != $d] +} +assert_equal %q{11}, %q{ + Thread.current[:a] = 1 + Thread.new{ + Thread.current[:a] = 10 + Thread.pass + Thread.current[:a] + }.value + Thread.current[:a] +} +assert_equal %q{100}, %q{ +begin + 100.times do |i| + begin + Thread.start(Thread.current) {|u| u.raise } + raise + rescue + ensure + end + end +rescue + 100 +end +}, '[ruby-dev:31371]' + +assert_equal 'true', %{ + t = Thread.new { loop {} } + begin + pid = fork { + exit t.status != "run" + } + Process.wait pid + $?.success? + rescue NotImplementedError + true + end +} + +assert_finish 3, %{ + th = Thread.new {sleep 2} + th.join(1) + th.join +} + +assert_finish 3, %{ + require 'timeout' + th = Thread.new {sleep 2} + begin + Timeout.timeout(1) {th.join} + rescue Timeout::Error + end + th.join +} + +assert_normal_exit %q{ + STDERR.reopen(STDOUT) + exec "/" +} + +assert_normal_exit %q{ + (0..10).map { + Thread.new { + 10000.times { + Object.new.to_s + } + } + }.each {|t| + t.join + } +} + +assert_equal 'ok', %q{ + def m + t = Thread.new { while true do // =~ "" end } + sleep 0.1 + 10.times { + if /((ab)*(ab)*)*(b)/ =~ "ab"*7 + return :ng if !$4 + return :ng if $~.size != 5 + end + } + :ok + ensure + Thread.kill t + end + m +}, '[ruby-dev:34492]' + +assert_normal_exit %q{ + at_exit { Fiber.new{}.resume } +} + +assert_normal_exit %q{ + g = enum_for(:local_variables) + loop { g.next } +}, '[ruby-dev:34128]' + +assert_normal_exit %q{ + g = enum_for(:block_given?) + loop { g.next } +}, '[ruby-dev:34128]' + +assert_normal_exit %q{ + g = enum_for(:binding) + loop { g.next } +}, '[ruby-dev:34128]' + +assert_normal_exit %q{ + g = "abc".enum_for(:scan, /./) + loop { g.next } +}, '[ruby-dev:34128]' + +assert_normal_exit %q{ + g = Module.enum_for(:new) + loop { g.next } +}, '[ruby-dev:34128]' + +assert_normal_exit %q{ + Fiber.new(&Object.method(:class_eval)).resume("foo") +}, '[ruby-dev:34128]' + +assert_normal_exit %q{ + Thread.new("foo", &Object.method(:class_eval)).join +}, '[ruby-dev:34128]' + +assert_equal 'ok', %q{ + begin + Thread.new { Thread.stop } + Thread.stop + :ng + rescue Exception + :ok + end +} + +assert_equal 'ok', %q{ + begin + m1, m2 = Mutex.new, Mutex.new + Thread.new { m1.lock; sleep 1; m2.lock } + m2.lock; sleep 1; m1.lock + :ng + rescue Exception + :ok + end +} + +assert_equal 'ok', %q{ + m = Mutex.new + Thread.new { m.lock }; sleep 1; m.lock + :ok +} + +assert_equal 'ok', %q{ + m = Mutex.new + Thread.new { m.lock }; m.lock + :ok +} + +assert_equal 'ok', %q{ + m = Mutex.new + Thread.new { m.lock }.join; m.lock + :ok +} + +assert_equal 'ok', %q{ + m = Mutex.new + Thread.new { m.lock; sleep 2 } + sleep 1; m.lock + :ok +} + +assert_equal 'ok', %q{ + m = Mutex.new + Thread.new { m.lock; sleep 2; m.unlock } + sleep 1; m.lock + :ok +} + +assert_equal 'ok', %q{ + t = Thread.new {`echo`} + t.join + $? ? :ng : :ok +}, '[ruby-dev:35414]' |