diff --git a/ChangeLog b/ChangeLog index 9efa64beedbfd4..1ce414c86128b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Sat Feb 24 16:47:33 2007 Minero Aoki + + * bootstraptest: new test suite. + + * bootstraptest/runner.rb: new file. + + * bootstraptest/test_literal.rb: new file. + + * bootstraptest/test_method.rb: new file. + Sat Feb 24 16:29:15 2007 NAKAMURA Usaku * win32/win32.c (StartSocket): remove unnecessary code. diff --git a/bootstraptest/runner.rb b/bootstraptest/runner.rb new file mode 100644 index 00000000000000..d48d14e6e6302e --- /dev/null +++ b/bootstraptest/runner.rb @@ -0,0 +1,120 @@ +# $Id: $ + +# NOTE: +# Never use optparse in this file. +# Never use test/unit in this file. +# Never use Ruby extensions in this file. + +require 'fileutils' + +def main + @ruby = nil + dir = 'bootstraptest.tmpwd' + tests = nil + ARGV.delete_if {|arg| + case arg + when /\A--ruby=(.*)/ + @ruby = File.expand_path($1) + true + when /\A--sets=(.*)/ + tests = Dir.glob("#{File.dirname($0)}/test_{#{$1}}*.rb") + puts tests.map {|path| File.basename(path) }.inspect + true + else + false + end + } + if tests and not ARGV.empty? + $stderr.puts "--tests and arguments are exclusive" + exit 1 + end + tests ||= ARGV + tests = Dir.glob("#{File.dirname($0)}/test_*.rb") if tests.empty? + pathes = tests.map {|path| File.expand_path(path) } + in_temporary_working_directory(dir) { + exec_test pathes + } +end + +def exec_test(pathes) + @count = 0 + @error = 0 + @errbuf = [] + @location = nil + pathes.each do |path| + load File.expand_path(path) + end + $stderr.puts + if @error == 0 + $stderr.puts "PASS #{@count} tests" + exit 0 + else + @errbuf.each do |msg| + $stderr.puts msg + end + $stderr.puts "FAIL #{@error}/#{@count} tests failed" + exit 1 + end +end + +def assert_equal(expected, really) + newtest + restr = get_result_string(really) + check_coredump + if expected == restr + $stderr.print '.' + else + $stderr.print 'F' + error "expected #{expected.inspect} but is: #{restr.inspect}" + end +rescue Exception => err + $stderr.print 'E' + error err.message +end + +def get_result_string(src) + if @ruby + File.open('bootstraptest.tmp.rb', 'w') {|f| + f.puts "print(begin; #{src}; end)" + } + `#{@ruby} bootstraptest.tmp.rb` + else + eval(src).to_s + end +end + +def newtest + @location = File.basename(caller(2).first) + @count += 1 + cleanup_coredump +end + +def error(msg) + @errbuf.push "\##{@count} #{@location}: #{msg}" + @error += 1 +end + +def in_temporary_working_directory(dir) + FileUtils.rm_rf dir + Dir.mkdir dir + Dir.chdir(dir) { + yield + } +end + +def cleanup_coredump + FileUtils.rm_f 'core' + Dir.glob('core.*').each do |ent| + FileUtils.rm_f ent + end +end + +class CoreDumpError < StandardError; end + +def check_coredump + if File.file?('core') or not Dir.glob('core.*').empty? + raise CoreDumpError, "core dumped" + end +end + +main diff --git a/bootstraptest/test_literal.rb b/bootstraptest/test_literal.rb new file mode 100644 index 00000000000000..fea5bcd07df2a6 --- /dev/null +++ b/bootstraptest/test_literal.rb @@ -0,0 +1,165 @@ +# 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]' + +# 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' diff --git a/bootstraptest/test_method.rb b/bootstraptest/test_method.rb new file mode 100644 index 00000000000000..e1f6eabdf85ded --- /dev/null +++ b/bootstraptest/test_method.rb @@ -0,0 +1,278 @@ +# regular argument +assert_equal '1', 'def m() 1 end; m()' +assert_equal '1', 'def m(a) a end; m(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(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)' + +# 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 ) + +# 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.send(:m); rescue NoMethodError; 1 end ) +assert_equal '1', %q( class C; def m() 1 end; private :m end + C.new.funcall(:m) )