diff --git a/ChangeLog b/ChangeLog index 727f736a11..dba515d8ae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Sun Feb 03 21:13:13 2008 Yusuke Endoh + + * test/ruby/test_numeric.rb: forgot to add this (at r15360). + * test/ruby/test_file_exhaustive.rb: add tests to achive over 80% test + coverage of file.c. + Sat Feb 2 20:06:42 2008 Yukihiro Matsumoto * lib/benchmark.rb (Benchmark::realtime): make Benchmark#realtime diff --git a/test/ruby/test_file_exhaustive.rb b/test/ruby/test_file_exhaustive.rb new file mode 100644 index 0000000000..df35d4256e --- /dev/null +++ b/test/ruby/test_file_exhaustive.rb @@ -0,0 +1,688 @@ +require "test/unit" +require "fileutils" +require "tmpdir" + +class TestFileExhaustive < Test::Unit::TestCase + def setup + @dir = Dir.mktmpdir("rubytest-file") + @file = make_tmp_filename("file") + @zerofile = make_tmp_filename("zerofile") + @nofile = make_tmp_filename("nofile") + @symlinkfile = make_tmp_filename("symlinkfile") + @hardlinkfile = make_tmp_filename("hardlinkfile") + make_file("foo", @file) + make_file("", @zerofile) + @time = Time.now + begin + File.symlink(@file, @symlinkfile) + rescue NotImplementedError + @symlinkfile = nil + end + begin + File.link(@file, @hardlinkfile) + rescue NotImplementedError + @hardlinkfile = nil + end + end + + def teardown + GC.start + FileUtils.remove_entry_secure @dir + end + + def make_file(content, file = @file) + open(file, "w") {|fh| fh << content } + end + + def make_tmp_filename(prefix) + @hardlinkfile = @dir + "/" + prefix + File.basename(__FILE__) + ".#{$$}.test" + end + + def test_path + file = @file + + assert_equal(file, File.new(file).path) + assert_equal(file, File.path(file)) + o = Object.new + class << o; self; end.class_eval do + define_method(:to_path) { file } + end + assert_equal(file, File.path(o)) + end + + def assert_integer(n) + assert(n.is_a?(Fixnum), n.inspect + " is not Fixnum.") + end + + def assert_integer_or_nil(n) + assert(n.is_a?(Integer) || n.equal?(nil), n.inspect + " is neither Fixnum nor nil.") + end + + def test_stat + sleep(@time - Time.now + 1.1) + make_file("foo", @file + "2") + fs1, fs2 = File.stat(@file), File.stat(@file + "2") + assert_nothing_raised do + assert_equal(0, fs1 <=> fs1) + assert_equal(-1, fs1 <=> fs2) + assert_equal(1, fs2 <=> fs1) + assert_nil(fs1 <=> nil) + assert_integer(fs1.dev) + assert_integer_or_nil(fs1.rdev) + assert_integer_or_nil(fs1.dev_major) + assert_integer_or_nil(fs1.dev_minor) + assert_integer_or_nil(fs1.rdev_major) + assert_integer_or_nil(fs1.rdev_minor) + assert_integer(fs1.ino) + assert_integer(fs1.mode) + unless /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + assert_equal(@hardlinkfile ? 2 : 1, fs1.nlink) + end + assert_integer(fs1.uid) + assert_integer(fs1.gid) + assert_equal(3, fs1.size) + assert_integer_or_nil(fs1.blksize) + assert_integer_or_nil(fs1.blocks) + assert_kind_of(Time, fs1.atime) + assert_kind_of(Time, fs1.mtime) + assert_kind_of(Time, fs1.ctime) + assert_kind_of(String, fs1.inspect) + end + assert_raise(Errno::ENOENT) { File.stat(@nofile) } + assert_kind_of(File::Stat, File.new(@file).stat) + assert_raise(Errno::ENOENT) { File.lstat(@nofile) } + assert_kind_of(File::Stat, File.new(@file).lstat) + end + + def test_directory_p + assert(File.directory?(@dir)) + assert(!(File.directory?(@file))) + assert(!(File.directory?(@nofile))) + end + + def test_pipe_p ## xxx + assert(!(File.pipe?(@dir))) + assert(!(File.pipe?(@file))) + assert(!(File.pipe?(@nofile))) + end + + def test_symlink_p + assert(!(File.symlink?(@dir))) + assert(!(File.symlink?(@file))) + assert(File.symlink?(@symlinkfile)) if @symlinkfile + assert(!(File.symlink?(@hardlinkfile))) if @hardlinkfile + assert(!(File.symlink?(@nofile))) + end + + def test_socket_p ## xxx + assert(!(File.socket?(@dir))) + assert(!(File.socket?(@file))) + assert(!(File.socket?(@nofile))) + end + + def test_blockdev_p ## xxx + assert(!(File.blockdev?(@dir))) + assert(!(File.blockdev?(@file))) + assert(!(File.blockdev?(@nofile))) + end + + def test_chardev_p ## xxx + assert(!(File.chardev?(@dir))) + assert(!(File.chardev?(@file))) + assert(!(File.chardev?(@nofile))) + end + + def test_exist_p + assert(File.exist?(@dir)) + assert(File.exist?(@file)) + assert(!(File.exist?(@nofile))) + end + + def test_readable_p + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + File.chmod(0200, @file) + assert(!(File.readable?(@file))) + File.chmod(0600, @file) + assert(File.readable?(@file)) + assert(!(File.readable?(@nofile))) + end + + def test_readable_real_p + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + File.chmod(0200, @file) + assert(!(File.readable_real?(@file))) + File.chmod(0600, @file) + assert(File.readable_real?(@file)) + assert(!(File.readable_real?(@nofile))) + end + + def test_world_readable_p + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + File.chmod(0006, @file) + assert(File.world_readable?(@file)) + File.chmod(0060, @file) + assert(!(File.world_readable?(@file))) + File.chmod(0600, @file) + assert(!(File.world_readable?(@file))) + assert(!(File.world_readable?(@nofile))) + end + + def test_writable_p + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + File.chmod(0400, @file) + assert(!(File.writable?(@file))) + File.chmod(0600, @file) + assert(File.writable?(@file)) + assert(!(File.writable?(@nofile))) + end + + def test_writable_real_p + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + File.chmod(0400, @file) + assert(!(File.writable_real?(@file))) + File.chmod(0600, @file) + assert(File.writable_real?(@file)) + assert(!(File.writable_real?(@nofile))) + end + + def test_world_writable_p + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + File.chmod(0006, @file) + assert(File.world_writable?(@file)) + File.chmod(0060, @file) + assert(!(File.world_writable?(@file))) + File.chmod(0600, @file) + assert(!(File.world_writable?(@file))) + assert(!(File.world_writable?(@nofile))) + end + + def test_executable_p + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + File.chmod(0100, @file) + assert(File.executable?(@file)) + File.chmod(0600, @file) + assert(!(File.executable?(@file))) + assert(!(File.executable?(@nofile))) + end + + def test_executable_real_p + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + File.chmod(0100, @file) + assert(File.executable_real?(@file)) + File.chmod(0600, @file) + assert(!(File.executable_real?(@file))) + assert(!(File.executable_real?(@nofile))) + end + + def test_file_p + assert(!(File.file?(@dir))) + assert(File.file?(@file)) + assert(!(File.file?(@nofile))) + end + + def test_zero_p + assert_nothing_raised { File.zero?(@dir) } + assert(!(File.zero?(@file))) + assert(File.zero?(@zerofile)) + assert(!(File.zero?(@nofile))) + end + + def test_size_p + assert_nothing_raised { File.size?(@dir) } + assert_equal(3, File.size?(@file)) + assert(!(File.size?(@zerofile))) + assert(!(File.size?(@nofile))) + end + + def test_owned_p ## xxx + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + assert(File.owned?(@file)) + assert(File.grpowned?(@file)) + end + + def test_suid_sgid_sticky ## xxx + assert(!(File.setuid?(@file))) + assert(!(File.setgid?(@file))) + assert(!(File.sticky?(@file))) + end + + def test_identical_p + assert(File.identical?(@file, @file)) + assert(!(File.identical?(@file, @zerofile))) + assert(!(File.identical?(@file, @nofile))) + assert(!(File.identical?(@nofile, @file))) + end + + def test_size + assert_integer(File.size(@dir)) + assert_equal(3, File.size(@file)) + assert_equal(0, File.size(@zerofile)) + assert_raise(Errno::ENOENT) { File.size(@nofile) } + end + + def test_ftype + assert_equal("directory", File.ftype(@dir)) + assert_equal("file", File.ftype(@file)) + assert_equal("link", File.ftype(@symlinkfile)) if @symlinkfile + assert_equal("file", File.ftype(@hardlinkfile)) if @hardlinkfile + assert_raise(Errno::ENOENT) { File.ftype(@nofile) } + end + + def test_atime + t1 = File.atime(@file) + t2 = File.new(@file).atime + assert_kind_of(Time, t1) + assert_kind_of(Time, t2) + assert_equal(t1, t2) + assert_raise(Errno::ENOENT) { File.atime(@nofile) } + end + + def test_mtime + t1 = File.mtime(@file) + t2 = File.new(@file).mtime + assert_kind_of(Time, t1) + assert_kind_of(Time, t2) + assert_equal(t1, t2) + assert_raise(Errno::ENOENT) { File.mtime(@nofile) } + end + + def test_ctime + t1 = File.ctime(@file) + t2 = File.new(@file).ctime + assert_kind_of(Time, t1) + assert_kind_of(Time, t2) + assert_equal(t1, t2) + assert_raise(Errno::ENOENT) { File.ctime(@nofile) } + end + + def test_chmod + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + assert_equal(1, File.chmod(0444, @file)) + assert_equal(0444, File.stat(@file).mode % 01000) + assert_equal(0, File.new(@file).chmod(0222)) + assert_equal(0222, File.stat(@file).mode % 01000) + File.chmod(0600, @file) + assert_raise(Errno::ENOENT) { File.chmod(0600, @nofile) } + end + + def test_lchmod + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + assert_equal(1, File.lchmod(0444, @file)) + assert_equal(0444, File.stat(@file).mode % 01000) + assert_equal(0, File.new(@file).lchmod(0222)) + assert_equal(0222, File.stat(@file).mode % 01000) + File.lchmod(0600, @file) + assert_raise(Errno::ENOENT) { File.lchmod(0600, @nofile) } + rescue NotImplementedError + end + + def test_chown ## xxx + end + + def test_lchown ## xxx + end + + def test_symlink + return unless @symlinkfile + assert_equal("link", File.ftype(@symlinkfile)) + assert_raise(Errno::EEXIST) { File.symlink(@file, @file) } + end + + def test_utime + t = Time.local(2000) + File.utime(t + 1, t + 2, @zerofile) + assert_equal(t + 1, File.atime(@zerofile)) + assert_equal(t + 2, File.mtime(@zerofile)) + end + + def test_hardlink + return unless @hardlinkfile + assert_equal("file", File.ftype(@hardlinkfile)) + assert_raise(Errno::EEXIST) { File.link(@file, @file) } + end + + def test_symlink + return unless @symlinkfile + assert_equal(@file, File.readlink(@symlinkfile)) + assert_raise(Errno::EINVAL) { File.readlink(@file) } + assert_raise(Errno::ENOENT) { File.readlink(@nofile) } + rescue NotImplementedError + end + + def test_unlink + assert_equal(1, File.unlink(@file)) + make_file("foo", @file) + assert_raise(Errno::ENOENT) { File.unlink(@nofile) } + end + + def test_rename + assert_equal(0, File.rename(@file, @nofile)) + assert(!(File.exist?(@file))) + assert(File.exist?(@nofile)) + assert_equal(0, File.rename(@nofile, @file)) + assert_raise(Errno::ENOENT) { File.rename(@nofile, @file) } + end + + def test_umask + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + prev = File.umask(0777) + assert_equal(0777, File.umask) + open(@nofile, "w") { } + assert_equal(0, File.stat(@nofile).mode % 01000) + File.unlink(@nofile) + assert_equal(0777, File.umask(prev)) + assert_raise(ArgumentError) { File.umask(0, 1, 2) } + end + + def test_expand_path + assert_equal(@file, File.expand_path(File.basename(@file), File.dirname(@file))) + end + + def test_basename + assert_equal(File.basename(@file).sub(/\.test$/, ""), File.basename(@file, ".test")) + assert_equal("", File.basename("")) + assert_equal("foo", File.basename("foo")) + assert_equal("foo", File.basename("foo", ".ext")) + assert_equal("foo", File.basename("foo.ext", ".ext")) + end + + def test_dirname + assert(@file.start_with?(File.dirname(@file))) + assert_equal(".", File.dirname("")) + end + + def test_extname + assert(".test", File.extname(@file)) + assert_equal("", File.extname("foo")) + assert_equal("", File.extname("")) + end + + def test_split + d, b = File.split(@file) + assert_equal(File.dirname(@file), d) + assert_equal(File.basename(@file), b) + end + + def test_join + s = "foo" + File::SEPARATOR + "bar" + File::SEPARATOR + "baz" + assert_equal(s, File.join("foo", "bar", "baz")) + assert_equal(s, File.join(["foo", "bar", "baz"])) + o = Object.new + def o.to_path; "foo"; end + assert_equal(s, File.join(o, "bar", "baz")) + assert_equal(s, File.join("foo" + File::SEPARATOR, "bar", File::SEPARATOR + "baz")) + end + + def test_truncate + assert_equal(0, File.truncate(@file, 1)) + assert(File.exist?(@file)) + assert_equal(1, File.size(@file)) + assert_equal(0, File.truncate(@file, 0)) + assert(File.exist?(@file)) + assert(File.zero?(@file)) + make_file("foo", @file) + assert_raise(Errno::ENOENT) { File.truncate(@nofile, 0) } + + f = File.new(@file, "w") + assert_equal(0, f.truncate(2)) + assert(File.exist?(@file)) + assert_equal(2, File.size(@file)) + assert_equal(0, f.truncate(0)) + assert(File.exist?(@file)) + assert(File.zero?(@file)) + f.close + make_file("foo", @file) + + assert_raise(IOError) { File.new(@file).truncate(0) } + rescue NotImplementedError + end + + def test_flock ## xxx + f = File.new(@file, "w") + f.flock(File::LOCK_EX) + f.flock(File::LOCK_SH) + f.flock(File::LOCK_UN) + f.close + rescue NotImplementedError + end + + def test_test + sleep(@time - Time.now + 1.1) + make_file("foo", @file + "2") + [@dir, @file, @zerofile, @symlinkfile, @hardlinkfile].compact.each do |f| + assert_equal(File.atime(f), test(?A, f)) + assert_equal(File.ctime(f), test(?C, f)) + assert_equal(File.mtime(f), test(?M, f)) + assert_equal(File.blockdev?(f), test(?b, f)) + assert_equal(File.chardev?(f), test(?c, f)) + assert_equal(File.directory?(f), test(?d, f)) + assert_equal(File.exist?(f), test(?e, f)) + assert_equal(File.file?(f), test(?f, f)) + assert_equal(File.setgid?(f), test(?g, f)) + assert_equal(File.grpowned?(f), test(?G, f)) + assert_equal(File.sticky?(f), test(?k, f)) + assert_equal(File.symlink?(f), test(?l, f)) + assert_equal(File.owned?(f), test(?o, f)) + assert_nothing_raised { test(?O, f) } + assert_equal(File.pipe?(f), test(?p, f)) + assert_equal(File.readable?(f), test(?r, f)) + assert_equal(File.readable_real?(f), test(?R, f)) + assert_equal(File.size?(f), test(?s, f)) + assert_equal(File.socket?(f), test(?S, f)) + assert_equal(File.setuid?(f), test(?u, f)) + assert_equal(File.writable?(f), test(?w, f)) + assert_equal(File.world_writable?(f), test(?W, f)) + assert_equal(File.executable?(f), test(?x, f)) + assert_equal(File.executable_real?(f), test(?X, f)) + assert_equal(File.zero?(f), test(?z, f)) + end + assert_equal(false, test(?-, @dir, @file)) + assert_equal(true, test(?-, @file, @file)) + assert_equal(true, test(?=, @file, @file)) + assert_equal(false, test(?=, @file, @file + "2")) + assert_equal(false, test(?>, @file, @file)) + assert_equal(false, test(?>, @file, @file + "2")) + assert_equal(true, test(?>, @file + "2", @file)) + assert_equal(false, test(?<, @file, @file)) + assert_equal(true, test(?<, @file, @file + "2")) + assert_equal(false, test(?<, @file + "2", @file)) + assert_raise(ArgumentError) { test } + assert_raise(Errno::ENOENT) { test(?A, @nofile) } + assert_raise(ArgumentError) { test(?a) } + assert_raise(ArgumentError) { test("\0".ord) } + end + + def test_stat_init + sleep(@time - Time.now + 1.1) + make_file("foo", @file + "2") + fs1, fs2 = File::Stat.new(@file), File::Stat.new(@file + "2") + assert_nothing_raised do + assert_equal(0, fs1 <=> fs1) + assert_equal(-1, fs1 <=> fs2) + assert_equal(1, fs2 <=> fs1) + assert_nil(fs1 <=> nil) + assert_integer(fs1.dev) + assert_integer_or_nil(fs1.rdev) + assert_integer_or_nil(fs1.dev_major) + assert_integer_or_nil(fs1.dev_minor) + assert_integer_or_nil(fs1.rdev_major) + assert_integer_or_nil(fs1.rdev_minor) + assert_integer(fs1.ino) + assert_integer(fs1.mode) + unless /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + assert_equal(@hardlinkfile ? 2 : 1, fs1.nlink) + end + assert_integer(fs1.uid) + assert_integer(fs1.gid) + assert_equal(3, fs1.size) + assert_integer_or_nil(fs1.blksize) + assert_integer_or_nil(fs1.blocks) + assert_kind_of(Time, fs1.atime) + assert_kind_of(Time, fs1.mtime) + assert_kind_of(Time, fs1.ctime) + assert_kind_of(String, fs1.inspect) + end + assert_raise(Errno::ENOENT) { File::Stat.new(@nofile) } + assert_kind_of(File::Stat, File::Stat.new(@file).dup) + assert_raise(TypeError) do + File::Stat.new(@file).instance_eval { initialize_copy(0) } + end + end + + def test_stat_ftype + assert_equal("directory", File::Stat.new(@dir).ftype) + assert_equal("file", File::Stat.new(@file).ftype) + # File::Stat uses stat + assert_equal("file", File::Stat.new(@symlinkfile).ftype) if @symlinkfile + assert_equal("file", File::Stat.new(@hardlinkfile).ftype) if @hardlinkfile + end + + def test_stat_directory_p + assert(File::Stat.new(@dir).directory?) + assert(!(File::Stat.new(@file).directory?)) + end + + def test_stat_pipe_p ## xxx + assert(!(File::Stat.new(@dir).pipe?)) + assert(!(File::Stat.new(@file).pipe?)) + end + + def test_stat_symlink_p + assert(!(File::Stat.new(@dir).symlink?)) + assert(!(File::Stat.new(@file).symlink?)) + # File::Stat uses stat + assert(!(File::Stat.new(@symlinkfile).symlink?)) if @symlinkfile + assert(!(File::Stat.new(@hardlinkfile).symlink?)) if @hardlinkfile + end + + def test_stat_socket_p ## xxx + assert(!(File::Stat.new(@dir).socket?)) + assert(!(File::Stat.new(@file).socket?)) + end + + def test_stat_blockdev_p ## xxx + assert(!(File::Stat.new(@dir).blockdev?)) + assert(!(File::Stat.new(@file).blockdev?)) + end + + def test_stat_chardev_p ## xxx + assert(!(File::Stat.new(@dir).chardev?)) + assert(!(File::Stat.new(@file).chardev?)) + end + + def test_stat_readable_p + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + File.chmod(0200, @file) + assert(!(File::Stat.new(@file).readable?)) + File.chmod(0600, @file) + assert(File::Stat.new(@file).readable?) + end + + def test_stat_readable_real_p + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + File.chmod(0200, @file) + assert(!(File::Stat.new(@file).readable_real?)) + File.chmod(0600, @file) + assert(File::Stat.new(@file).readable_real?) + end + + def test_stat_world_readable_p + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + File.chmod(0006, @file) + assert(File::Stat.new(@file).world_readable?) + File.chmod(0060, @file) + assert(!(File::Stat.new(@file).world_readable?)) + File.chmod(0600, @file) + assert(!(File::Stat.new(@file).world_readable?)) + end + + def test_stat_writable_p + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + File.chmod(0400, @file) + assert(!(File::Stat.new(@file).writable?)) + File.chmod(0600, @file) + assert(File::Stat.new(@file).writable?) + end + + def test_stat_writable_real_p + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + File.chmod(0400, @file) + assert(!(File::Stat.new(@file).writable_real?)) + File.chmod(0600, @file) + assert(File::Stat.new(@file).writable_real?) + end + + def test_stat_world_writable_p + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + File.chmod(0006, @file) + assert(File::Stat.new(@file).world_writable?) + File.chmod(0060, @file) + assert(!(File::Stat.new(@file).world_writable?)) + File.chmod(0600, @file) + assert(!(File::Stat.new(@file).world_writable?)) + end + + def test_stat_executable_p + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + File.chmod(0100, @file) + assert(File::Stat.new(@file).executable?) + File.chmod(0600, @file) + assert(!(File::Stat.new(@file).executable?)) + end + + def test_stat_executable_real_p + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + File.chmod(0100, @file) + assert(File::Stat.new(@file).executable_real?) + File.chmod(0600, @file) + assert(!(File::Stat.new(@file).executable_real?)) + end + + def test_stat_file_p + assert(!(File::Stat.new(@dir).file?)) + assert(File::Stat.new(@file).file?) + end + + def test_stat_zero_p + assert_nothing_raised { File::Stat.new(@dir).zero? } + assert(!(File::Stat.new(@file).zero?)) + assert(File::Stat.new(@zerofile).zero?) + end + + def test_stat_size_p + assert_nothing_raised { File::Stat.new(@dir).size? } + assert_equal(3, File::Stat.new(@file).size?) + assert(!(File::Stat.new(@zerofile).size?)) + end + + def test_stat_owned_p ## xxx + return if /(mswin|bccwin|mingw|emx)/ =~ RUBY_PLATFORM + assert(File::Stat.new(@file).owned?) + assert(File::Stat.new(@file).grpowned?) + end + + def test_stat_suid_sgid_sticky ## xxx + assert(!(File::Stat.new(@file).setuid?)) + assert(!(File::Stat.new(@file).setgid?)) + assert(!(File::Stat.new(@file).sticky?)) + end + + def test_stat_size + assert_integer(File::Stat.new(@dir).size) + assert_equal(3, File::Stat.new(@file).size) + assert_equal(0, File::Stat.new(@zerofile).size) + end + + def test_path_check + assert_nothing_raised { ENV["PATH"] } + end + + def test_find_file + assert_raise(SecurityError) do + Thread.new do + $SAFE = 4 + load(@file) + end.join + end + end +end diff --git a/test/ruby/test_numeric.rb b/test/ruby/test_numeric.rb new file mode 100644 index 0000000000..b94f2cba59 --- /dev/null +++ b/test/ruby/test_numeric.rb @@ -0,0 +1,446 @@ +require 'test/unit' + +class TestNumeric < Test::Unit::TestCase + class DummyNumeric < Numeric + end + + def test_coerce + a, b = 1.coerce(2) + assert_equal(Fixnum, a.class) + assert_equal(Fixnum, b.class) + + a, b = 1.coerce(2.0) + assert_equal(Float, a.class) + assert_equal(Float, b.class) + + assert_raise(TypeError) { -Numeric.new } + end + + def test_dummynumeric + a = DummyNumeric.new + + DummyNumeric.class_eval do + def coerce(x); nil; end + end + assert_raise(TypeError) { -a } + assert_nil(1 <=> a) + assert_raise(ArgumentError) { 1 <= a } + + DummyNumeric.class_eval do + def coerce(x); 1.coerce(x); end + end + assert_equal(2, 1 + a) + assert_equal(0, 1 <=> a) + assert(1 <= a) + + DummyNumeric.class_eval do + def coerce(x); [x, 1]; end + end + assert_equal(-1, -a) + + ensure + DummyNumeric.class_eval do + remove_method :coerce + end + end + + def test_numeric + a = Numeric.new + assert_raise(TypeError) { def a.foo; end } + assert_raise(TypeError) { a.dup } + end + + def test_quo + DummyNumeric.class_eval do + def /(x); :div; end + end + + assert_equal(:div, DummyNumeric.new.quo(0)) + + ensure + DummyNumeric.class_eval do + remove_method :/ + end + end + + def test_divmod + DummyNumeric.class_eval do + def /(x); 42.0; end + def %(x); :mod; end + end + + assert_equal(42, DummyNumeric.new.div(0)) + assert_equal(:mod, DummyNumeric.new.modulo(0)) + assert_equal([42, :mod], DummyNumeric.new.divmod(0)) + + ensure + DummyNumeric.class_eval do + remove_method :/, :% + end + end + + def test_scalar_p + assert(Numeric.new.scalar?) + end + + def test_integer_p + assert(!Numeric.new.integer?) + end + + def test_abs + a = DummyNumeric.new + DummyNumeric.class_eval do + def -@; :ok; end + def <(x); true; end + end + + assert_equal(:ok, a.abs) + + DummyNumeric.class_eval do + def <(x); false; end + end + + assert_equal(a, a.abs) + + ensure + DummyNumeric.class_eval do + remove_method :-@, :< + end + end + + def test_zero_p + DummyNumeric.class_eval do + def ==(x); true; end + end + + assert(DummyNumeric.new.zero?) + + ensure + DummyNumeric.class_eval do + remove_method :== + end + end + + def test_to_int + DummyNumeric.class_eval do + def to_i; :ok; end + end + + assert_equal(:ok, DummyNumeric.new.to_int) + + ensure + DummyNumeric.class_eval do + remove_method :to_i + end + end + + def test_cmp + a = Numeric.new + assert_equal(0, a <=> a) + assert_nil(a <=> :foo) + end + + def test_floor_ceil_round_truncate + DummyNumeric.class_eval do + def to_f; 1.5; end + end + + a = DummyNumeric.new + assert_equal(1, a.floor) + assert_equal(2, a.ceil) + assert_equal(2, a.round) + assert_equal(1, a.truncate) + + DummyNumeric.class_eval do + def to_f; 1.4; end + end + + a = DummyNumeric.new + assert_equal(1, a.floor) + assert_equal(2, a.ceil) + assert_equal(1, a.round) + assert_equal(1, a.truncate) + + DummyNumeric.class_eval do + def to_f; -1.5; end + end + + a = DummyNumeric.new + assert_equal(-2, a.floor) + assert_equal(-1, a.ceil) + assert_equal(-2, a.round) + assert_equal(-1, a.truncate) + + ensure + DummyNumeric.class_eval do + remove_method :to_f + end + end + + def test_step + a = [] + 1.step(10) {|x| a << x } + assert_equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], a) + + a = [] + 1.step(10, 2) {|x| a << x } + assert_equal([1, 3, 5, 7, 9], a) + + assert_raise(ArgumentError) { 1.step(10, 1, 0) { } } + assert_raise(ArgumentError) { 1.step(10, 0) { } } + + a = [] + 10.step(1, -2) {|x| a << x } + assert_equal([10, 8, 6, 4, 2], a) + + a = [] + 1.0.step(10.0, 2.0) {|x| a << x } + assert_equal([1.0, 3.0, 5.0, 7.0, 9.0], a) + + a = [] + 1.step(10, 2**32) {|x| a << x } + assert_equal([1], a) + + a = [] + 10.step(1, -(2**32)) {|x| a << x } + assert_equal([10], a) + end + + def test_num2long + assert_raise(TypeError) { 1 & nil } + assert_equal(1, 1 & 1.0) + assert_raise(RangeError) { 1 & 2147483648.0 } + o = Object.new + def o.to_int; 1; end + assert_equal(1, 1 & o) + end + + def test_eql + assert(1 == 1.0) + assert(!(1.eql?(1.0))) + assert(!(1.eql?(2))) + end +end +require 'test/unit' + +class TestNumeric < Test::Unit::TestCase + class DummyNumeric < Numeric + end + + def test_coerce + a, b = 1.coerce(2) + assert_equal(Fixnum, a.class) + assert_equal(Fixnum, b.class) + + a, b = 1.coerce(2.0) + assert_equal(Float, a.class) + assert_equal(Float, b.class) + + assert_raise(TypeError) { -Numeric.new } + end + + def test_dummynumeric + a = DummyNumeric.new + + DummyNumeric.class_eval do + def coerce(x); nil; end + end + assert_raise(TypeError) { -a } + assert_nil(1 <=> a) + assert_raise(ArgumentError) { 1 <= a } + + DummyNumeric.class_eval do + def coerce(x); 1.coerce(x); end + end + assert_equal(2, 1 + a) + assert_equal(0, 1 <=> a) + assert(1 <= a) + + DummyNumeric.class_eval do + def coerce(x); [x, 1]; end + end + assert_equal(-1, -a) + + ensure + DummyNumeric.class_eval do + remove_method :coerce + end + end + + def test_numeric + a = Numeric.new + assert_raise(TypeError) { def a.foo; end } + assert_raise(TypeError) { a.dup } + end + + def test_quo + DummyNumeric.class_eval do + def /(x); :div; end + end + + assert_equal(:div, DummyNumeric.new.quo(0)) + + ensure + DummyNumeric.class_eval do + remove_method :/ + end + end + + def test_divmod + DummyNumeric.class_eval do + def /(x); 42.0; end + def %(x); :mod; end + end + + assert_equal(42, DummyNumeric.new.div(0)) + assert_equal(:mod, DummyNumeric.new.modulo(0)) + assert_equal([42, :mod], DummyNumeric.new.divmod(0)) + + ensure + DummyNumeric.class_eval do + remove_method :/, :% + end + end + + def test_scalar_p + assert(Numeric.new.scalar?) + end + + def test_integer_p + assert(!Numeric.new.integer?) + end + + def test_abs + a = DummyNumeric.new + DummyNumeric.class_eval do + def -@; :ok; end + def <(x); true; end + end + + assert_equal(:ok, a.abs) + + DummyNumeric.class_eval do + def <(x); false; end + end + + assert_equal(a, a.abs) + + ensure + DummyNumeric.class_eval do + remove_method :-@, :< + end + end + + def test_zero_p + DummyNumeric.class_eval do + def ==(x); true; end + end + + assert(DummyNumeric.new.zero?) + + ensure + DummyNumeric.class_eval do + remove_method :== + end + end + + def test_to_int + DummyNumeric.class_eval do + def to_i; :ok; end + end + + assert_equal(:ok, DummyNumeric.new.to_int) + + ensure + DummyNumeric.class_eval do + remove_method :to_i + end + end + + def test_cmp + a = Numeric.new + assert_equal(0, a <=> a) + assert_nil(a <=> :foo) + end + + def test_floor_ceil_round_truncate + DummyNumeric.class_eval do + def to_f; 1.5; end + end + + a = DummyNumeric.new + assert_equal(1, a.floor) + assert_equal(2, a.ceil) + assert_equal(2, a.round) + assert_equal(1, a.truncate) + + DummyNumeric.class_eval do + def to_f; 1.4; end + end + + a = DummyNumeric.new + assert_equal(1, a.floor) + assert_equal(2, a.ceil) + assert_equal(1, a.round) + assert_equal(1, a.truncate) + + DummyNumeric.class_eval do + def to_f; -1.5; end + end + + a = DummyNumeric.new + assert_equal(-2, a.floor) + assert_equal(-1, a.ceil) + assert_equal(-2, a.round) + assert_equal(-1, a.truncate) + + ensure + DummyNumeric.class_eval do + remove_method :to_f + end + end + + def test_step + a = [] + 1.step(10) {|x| a << x } + assert_equal([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], a) + + a = [] + 1.step(10, 2) {|x| a << x } + assert_equal([1, 3, 5, 7, 9], a) + + assert_raise(ArgumentError) { 1.step(10, 1, 0) { } } + assert_raise(ArgumentError) { 1.step(10, 0) { } } + + a = [] + 10.step(1, -2) {|x| a << x } + assert_equal([10, 8, 6, 4, 2], a) + + a = [] + 1.0.step(10.0, 2.0) {|x| a << x } + assert_equal([1.0, 3.0, 5.0, 7.0, 9.0], a) + + a = [] + 1.step(10, 2**32) {|x| a << x } + assert_equal([1], a) + + a = [] + 10.step(1, -(2**32)) {|x| a << x } + assert_equal([10], a) + end + + def test_num2long + assert_raise(TypeError) { 1 & nil } + assert_equal(1, 1 & 1.0) + assert_raise(RangeError) { 1 & 2147483648.0 } + o = Object.new + def o.to_int; 1; end + assert_equal(1, 1 & o) + end + + def test_eql + assert(1 == 1.0) + assert(!(1.eql?(1.0))) + assert(!(1.eql?(2))) + end +end