summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-05-29 13:48:54 +0000
committermame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-05-29 13:48:54 +0000
commit88c1862edbcf1578537ba47114bdb2d9336d5cda (patch)
tree1a437d438579a63f77d235d47b1bf67333596eda
parent47cc870a5ace622f0f28d397a35c428214127a21 (diff)
* test/ruby/test_argf.rb: new tests for ARGF, to achieve over 85% test
coverage of file.c. * test/ruby/test_io.rb: add tests. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16683 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog7
-rw-r--r--test/ruby/test_argf.rb686
-rw-r--r--test/ruby/test_io.rb674
3 files changed, 1367 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 8a8ac966ff..bb291d4a2a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Thu May 29 22:47:53 2008 Yusuke Endoh <mame@tsg.ne.jp>
+
+ * test/ruby/test_argf.rb: new tests for ARGF, to achieve over 85% test
+ coverage of file.c.
+
+ * test/ruby/test_io.rb: add tests.
+
Thu May 29 22:41:48 2008 Yusuke Endoh <mame@tsg.ne.jp>
* io.c (argf_readchar): raise EOFError, synchronizing IO#readchar.
diff --git a/test/ruby/test_argf.rb b/test/ruby/test_argf.rb
new file mode 100644
index 0000000000..c2a1633a6d
--- /dev/null
+++ b/test/ruby/test_argf.rb
@@ -0,0 +1,686 @@
+require 'test/unit'
+require 'timeout'
+require 'tmpdir'
+require 'tempfile'
+require_relative 'envutil'
+
+class TestArgf < Test::Unit::TestCase
+ def setup
+ @t1 = Tempfile.new("foo")
+ @t1.puts "1"
+ @t1.puts "2"
+ @t1.close
+ @t2 = Tempfile.new("bar")
+ @t2.puts "3"
+ @t2.puts "4"
+ @t2.close
+ @t3 = Tempfile.new("baz")
+ @t3.puts "5"
+ @t3.puts "6"
+ @t3.close
+ end
+
+ def make_tempfile
+ t = Tempfile.new("foo")
+ t.puts "foo"
+ t.puts "bar"
+ t.puts "baz"
+ t.close
+ t
+ end
+
+ def ruby(*args)
+ args = ['-e', '$>.write($<.read)'] if args.empty?
+ ruby = EnvUtil.rubybin
+ f = IO.popen([ruby] + args, 'r+')
+ yield(f)
+ ensure
+ f.close unless !f || f.closed?
+ end
+
+ def test_argf
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ a = ARGF
+ b = a.dup
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["1", 1, "1", 1]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["2", 2, "2", 2]
+ a.rewind
+ b.rewind
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["1", 1, "1", 3]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["2", 2, "2", 4]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["3", 3, "3", 5]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["4", 4, "4", 6]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["5", 5, "5", 7]
+ a.rewind
+ b.rewind
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["5", 5, "5", 8]
+ p [a.gets.chomp, a.lineno, b.gets.chomp, b.lineno] #=> ["6", 6, "6", 9]
+ SRC
+ a = f.read.split("\n")
+ assert_equal('["1", 1, "1", 1]', a.shift)
+ assert_equal('["2", 2, "2", 2]', a.shift)
+ assert_equal('["1", 1, "1", 3]', a.shift)
+ assert_equal('["2", 2, "2", 4]', a.shift)
+ assert_equal('["3", 3, "3", 5]', a.shift)
+ assert_equal('["4", 4, "4", 6]', a.shift)
+ assert_equal('["5", 5, "5", 7]', a.shift)
+ assert_equal('["5", 5, "5", 8]', a.shift)
+ assert_equal('["6", 6, "6", 9]', a.shift)
+
+ # is this test OK? [ruby-dev:34445]
+ end
+ end
+
+ def test_lineno
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ a = ARGF
+ a.gets; p $. #=> 1
+ a.gets; p $. #=> 2
+ a.gets; p $. #=> 3
+ a.rewind; p $. #=> 3
+ a.gets; p $. #=> 3
+ a.gets; p $. #=> 4
+ a.rewind; p $. #=> 4
+ a.gets; p $. #=> 3
+ a.lineno = 1000; p $. #=> 1000
+ a.gets; p $. #=> 1001
+ a.gets; p $. #=> 1002
+ $. = 2000
+ a.gets; p $. #=> 2001
+ a.gets; p $. #=> 2001
+ SRC
+ assert_equal("1,2,3,3,3,4,4,3,1000,1001,1002,2001,2001", f.read.chomp.gsub("\n", ","))
+ end
+ end
+
+ def test_lineno
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ a = ARGF.dup
+ a.gets; p $. #=> 1
+ a.gets; p $. #=> 2
+ a.gets; p $. #=> 1
+ a.rewind; p $. #=> 1
+ a.gets; p $. #=> 1
+ a.gets; p $. #=> 2
+ a.gets; p $. #=> 1
+ a.lineno = 1000; p $. #=> 1
+ a.gets; p $. #=> 2
+ a.gets; p $. #=> 2
+ $. = 2000
+ a.gets; p $. #=> 2001
+ a.gets; p $. #=> 2000
+ SRC
+ assert_equal("1,2,1,1,1,2,1,1,2,2,2000,2000", f.read.chomp.gsub("\n", ","))
+ end
+ end
+
+ def test_inplace
+ EnvUtil.rubyexec("-", @t1.path, @t2.path, @t3.path) do |w, r, e|
+ w.puts "ARGF.inplace_mode = '.bak'"
+ w.puts "while line = ARGF.gets"
+ w.puts " puts line.chomp + '.new'"
+ w.puts "end"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("", r.read)
+ assert_equal("1.new\n2.new\n", File.read(@t1.path))
+ assert_equal("3.new\n4.new\n", File.read(@t2.path))
+ assert_equal("5.new\n6.new\n", File.read(@t3.path))
+ assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
+ assert_equal("3\n4\n", File.read(@t2.path + ".bak"))
+ assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
+ end
+ end
+
+ def test_inplace2
+ EnvUtil.rubyexec("-", @t1.path, @t2.path, @t3.path) do |w, r, e|
+ w.puts "ARGF.inplace_mode = '.bak'"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "p ARGF.inplace_mode"
+ w.puts "ARGF.inplace_mode = nil"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "p ARGF.inplace_mode"
+ w.puts "ARGF.inplace_mode = '.bak'"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "p ARGF.inplace_mode"
+ w.puts "ARGF.inplace_mode = nil"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("", r.read)
+ assert_equal("1.new\n2.new\n\".bak\"\n3.new\n4.new\nnil\n", File.read(@t1.path))
+ assert_equal("3\n4\n", File.read(@t2.path))
+ assert_equal("5.new\n\".bak\"\n6.new\n", File.read(@t3.path))
+ assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
+ assert_equal(false, File.file?(@t2.path + ".bak"))
+ assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
+ end
+ end
+
+ def test_inplace3
+ EnvUtil.rubyexec("-i.bak", "-", @t1.path, @t2.path, @t3.path) do |w, r, e|
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "p $-i"
+ w.puts "$-i = nil"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "p $-i"
+ w.puts "$-i = '.bak'"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.puts "p $-i"
+ w.puts "$-i = nil"
+ w.puts "puts ARGF.gets.chomp + '.new'"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("", r.read)
+ assert_equal("1.new\n2.new\n\".bak\"\n3.new\n4.new\nnil\n", File.read(@t1.path))
+ assert_equal("3\n4\n", File.read(@t2.path))
+ assert_equal("5.new\n\".bak\"\n6.new\n", File.read(@t3.path))
+ assert_equal("1\n2\n", File.read(@t1.path + ".bak"))
+ assert_equal(false, File.file?(@t2.path + ".bak"))
+ assert_equal("5\n6\n", File.read(@t3.path + ".bak"))
+ end
+ end
+
+ def test_inplace_rename_impossible
+ t = make_tempfile
+
+ EnvUtil.rubyexec("-", t.path) do |w, r, e|
+ w.puts "ARGF.inplace_mode = '/\\\\'"
+ w.puts "while line = ARGF.gets"
+ w.puts " puts line.chomp + '.new'"
+ w.puts "end"
+ w.close
+ assert_match(/Can't rename .* to .*: .*. skipping file/, e.read)
+ assert_equal("", r.read)
+ assert_equal("foo\nbar\nbaz\n", File.read(t.path))
+ end
+ end
+
+ def test_inplace_no_backup
+ t = make_tempfile
+
+ EnvUtil.rubyexec("-", t.path) do |w, r, e|
+ w.puts "ARGF.inplace_mode = ''"
+ w.puts "while line = ARGF.gets"
+ w.puts " puts line.chomp + '.new'"
+ w.puts "end"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("", r.read)
+ assert_equal("foo.new\nbar.new\nbaz.new\n", File.read(t.path))
+ end
+ end
+
+ def test_inplace_dup
+ t = make_tempfile
+
+ EnvUtil.rubyexec("-", t.path) do |w, r, e|
+ w.puts "ARGF.inplace_mode = '.bak'"
+ w.puts "f = ARGF.dup"
+ w.puts "while line = f.gets"
+ w.puts " puts line.chomp + '.new'"
+ w.puts "end"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("", r.read)
+ assert_equal("foo.new\nbar.new\nbaz.new\n", File.read(t.path))
+ end
+ end
+
+ def test_inplace_stdin
+ t = make_tempfile
+
+ EnvUtil.rubyexec("-", "-") do |w, r, e|
+ w.puts "ARGF.inplace_mode = '.bak'"
+ w.puts "f = ARGF.dup"
+ w.puts "while line = f.gets"
+ w.puts " puts line.chomp + '.new'"
+ w.puts "end"
+ w.close
+ assert_match("Can't do inplace edit for stdio; skipping", e.read)
+ assert_equal("", r.read)
+ end
+ end
+
+ def test_inplace_stdin2
+ t = make_tempfile
+
+ EnvUtil.rubyexec("-") do |w, r, e|
+ w.puts "ARGF.inplace_mode = '.bak'"
+ w.puts "while line = ARGF.gets"
+ w.puts " puts line.chomp + '.new'"
+ w.puts "end"
+ w.close
+ assert_match("Can't do inplace edit for stdio", e.read)
+ assert_equal("", r.read)
+ end
+ end
+
+ def test_encoding
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ p ARGF.external_encoding.is_a?(Encoding)
+ p ARGF.internal_encoding.is_a?(Encoding)
+ ARGF.gets
+ p ARGF.external_encoding.is_a?(Encoding)
+ p ARGF.internal_encoding
+ SRC
+ assert_equal("true\ntrue\ntrue\nnil\n", f.read)
+ end
+ end
+
+ def test_tell
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ loop do
+ p ARGF.tell
+ p ARGF.gets
+ end
+ rescue ArgumentError
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ [0, 2, 4, 2, 4, 2, 4].map {|i| i.to_s }.
+ zip((1..6).map {|i| '"' + i.to_s + '\n"' } + ["nil"]).flatten.
+ each do |x|
+ assert_equal(x, a.shift)
+ end
+ assert_equal('end', a.shift)
+ end
+ end
+
+ def test_seek
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ ARGF.seek(4)
+ p ARGF.gets #=> "3"
+ ARGF.seek(0, IO::SEEK_END)
+ p ARGF.gets #=> "5"
+ ARGF.seek(4)
+ p ARGF.gets #=> nil
+ begin
+ ARGF.seek(0)
+ rescue
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ assert_equal('"3\n"', a.shift)
+ assert_equal('"5\n"', a.shift)
+ assert_equal('nil', a.shift)
+ assert_equal('end', a.shift)
+ end
+ end
+
+ def test_set_pos
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ ARGF.pos = 4
+ p ARGF.gets #=> "3"
+ ARGF.pos = 4
+ p ARGF.gets #=> "5"
+ ARGF.pos = 4
+ p ARGF.gets #=> nil
+ begin
+ ARGF.pos = 4
+ rescue
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ assert_equal('"3\n"', a.shift)
+ assert_equal('"5\n"', a.shift)
+ assert_equal('nil', a.shift)
+ assert_equal('end', a.shift)
+ end
+ end
+
+ def test_rewind
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ ARGF.pos = 4
+ ARGF.rewind
+ p ARGF.gets #=> "1"
+ ARGF.pos = 4
+ p ARGF.gets #=> "3"
+ ARGF.pos = 4
+ p ARGF.gets #=> "5"
+ ARGF.pos = 4
+ p ARGF.gets #=> nil
+ begin
+ ARGF.rewind
+ rescue
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ assert_equal('"1\n"', a.shift)
+ assert_equal('"3\n"', a.shift)
+ assert_equal('"5\n"', a.shift)
+ assert_equal('nil', a.shift)
+ assert_equal('end', a.shift)
+ end
+ end
+
+ def test_fileno
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ p ARGF.fileno
+ ARGF.gets
+ ARGF.gets
+ p ARGF.fileno
+ ARGF.gets
+ ARGF.gets
+ p ARGF.fileno
+ ARGF.gets
+ ARGF.gets
+ p ARGF.fileno
+ ARGF.gets
+ begin
+ ARGF.fileno
+ rescue
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ fd1, fd2, fd3, fd4, tag = a
+ assert_match(/^\d+$/, fd1)
+ assert_match(/^\d+$/, fd2)
+ assert_match(/^\d+$/, fd3)
+ assert_match(/^\d+$/, fd4)
+ assert_equal('end', tag)
+ end
+ end
+
+ def test_to_io
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ 8.times do
+ p ARGF.to_io
+ ARGF.gets
+ end
+ SRC
+ a = f.read.split("\n")
+ f11, f12, f13, f21, f22, f31, f32, f4 = a
+ assert_equal(f11, f12)
+ assert_equal(f11, f13)
+ assert_equal(f21, f22)
+ assert_equal(f31, f32)
+ assert_match(/\(closed\)/, f4)
+ f4.sub!(/ \(closed\)/, "")
+ assert_equal(f31, f4)
+ end
+ end
+
+ def test_eof
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ 8.times do
+ p ARGF.eof?
+ ARGF.gets
+ end
+ rescue IOError
+ puts "end"
+ end
+ SRC
+ a = f.read.split("\n")
+ ((%w(true false) * 4).take(7) + %w(end)).each do |x|
+ assert_equal(x, a.shift)
+ end
+ end
+ end
+
+ def test_read
+ ruby('-e', "p ARGF.read(8)", @t1.path, @t2.path, @t3.path) do |f|
+ assert_equal("\"1\\n2\\n3\\n4\\n\"\n", f.read)
+ end
+ end
+
+ def test_read2
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ ARGF.read(8, s)
+ p s
+ SRC
+ assert_equal("\"1\\n2\\n3\\n4\\n\"\n", f.read)
+ end
+ end
+
+ def test_read3
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ nil while ARGF.gets
+ p ARGF.read
+ p ARGF.read(0, "")
+ SRC
+ assert_equal("nil\n\"\"\n", f.read)
+ end
+ end
+
+ def test_readpartial
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ begin
+ loop do
+ s << ARGF.readpartial(1)
+ t = ""; ARGF.readpartial(1, t); s << t
+ end
+ rescue EOFError
+ puts s
+ end
+ SRC
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_readpartial2
+ ruby('-e', <<-SRC) do |f|
+ s = ""
+ begin
+ loop do
+ s << ARGF.readpartial(1)
+ t = ""; ARGF.readpartial(1, t); s << t
+ end
+ rescue EOFError
+ puts s
+ end
+ SRC
+ f.puts("foo")
+ f.puts("bar")
+ f.puts("baz")
+ f.close_write
+ assert_equal("foo\nbar\nbaz\n", f.read)
+ end
+ end
+
+ def test_getc
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ while c = ARGF.getc
+ s << c
+ end
+ puts s
+ SRC
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_getbyte
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = []
+ while c = ARGF.getbyte
+ s << c
+ end
+ p s
+ SRC
+ assert_equal("[49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10]\n", f.read)
+ end
+ end
+
+ def test_readchar
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ begin
+ while c = ARGF.readchar
+ s << c
+ end
+ rescue EOFError
+ puts s
+ end
+ SRC
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_readbyte
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ s = []
+ while c = ARGF.readbyte
+ s << c
+ end
+ rescue EOFError
+ p s
+ end
+ SRC
+ assert_equal("[49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10]\n", f.read)
+ end
+ end
+
+ def test_each_line
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = []
+ ARGF.each_line {|l| s << l }
+ p s
+ SRC
+ assert_equal("[\"1\\n\", \"2\\n\", \"3\\n\", \"4\\n\", \"5\\n\", \"6\\n\"]\n", f.read)
+ end
+ end
+
+ def test_each_byte
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = []
+ ARGF.each_byte {|c| s << c }
+ p s
+ SRC
+ assert_equal("[49, 10, 50, 10, 51, 10, 52, 10, 53, 10, 54, 10]\n", f.read)
+ end
+ end
+
+ def test_each_char
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ s = ""
+ ARGF.each_char {|c| s << c }
+ puts s
+ SRC
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_filename
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ puts ARGF.filename.dump
+ end while ARGF.gets
+ puts ARGF.filename.dump
+ SRC
+ a = f.read.split("\n")
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ end
+ end
+
+ def test_filename2
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ puts $FILENAME.dump
+ end while ARGF.gets
+ puts $FILENAME.dump
+ SRC
+ a = f.read.split("\n")
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ end
+ end
+
+ def test_file
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ puts ARGF.file.path.dump
+ end while ARGF.gets
+ puts ARGF.file.path.dump
+ SRC
+ a = f.read.split("\n")
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t1.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t2.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ assert_equal(@t3.path.dump, a.shift)
+ end
+ end
+
+ def test_binmode
+ ruby('-e', "ARGF.binmode; puts ARGF.read", @t1.path, @t2.path, @t3.path) do |f|
+ assert_equal("1\n2\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_skip
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ begin
+ ARGF.skip
+ rescue
+ puts "cannot skip" # ???
+ end
+ puts ARGF.gets
+ ARGF.skip
+ puts ARGF.read
+ SRC
+ assert_equal("cannot skip\n1\n3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_close
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ ARGF.close
+ puts ARGF.read
+ SRC
+ assert_equal("3\n4\n5\n6\n", f.read)
+ end
+ end
+
+ def test_closed
+ ruby('-e', <<-SRC, @t1.path, @t2.path, @t3.path) do |f|
+ 3.times do
+ p ARGF.closed?
+ ARGF.gets
+ ARGF.gets
+ end
+ p ARGF.closed?
+ ARGF.gets
+ p ARGF.closed?
+ SRC
+ assert_equal("false\nfalse\nfalse\nfalse\ntrue\n", f.read)
+ end
+ end
+
+ def test_argv
+ ruby('-e', "p ARGF.argv; p $*", @t1.path, @t2.path, @t3.path) do |f|
+ assert_equal([@t1.path, @t2.path, @t3.path].inspect, f.gets.chomp)
+ assert_equal([@t1.path, @t2.path, @t3.path].inspect, f.gets.chomp)
+ end
+ end
+end
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index 06da5db742..c04f216011 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -3,6 +3,9 @@ require 'tmpdir'
require 'io/nonblock'
require 'socket'
require 'stringio'
+require 'timeout'
+require 'tempfile'
+require_relative 'envutil'
class TestIO < Test::Unit::TestCase
def test_gets_rs
@@ -545,4 +548,675 @@ class TestIO < Test::Unit::TestCase
}
end
+ def safe_4
+ Thread.new do
+ Timeout.timeout(10) do
+ $SAFE = 4
+ yield
+ end
+ end.join
+ end
+
+ def pipe
+ r, w = IO.pipe
+ Timeout.timeout(10) do
+ yield(r, w)
+ end
+ ensure
+ r.close unless !r || r.closed?
+ w.close unless !w || w.closed?
+ end
+
+ def pipe2(&b)
+ a = []
+ a << IO.pipe while true
+ rescue Errno::EMFILE, Errno::ENFILE, Errno::ENOMEM
+ yield(*a.last)
+ ensure
+ a.each do |r, w|
+ r.close unless !r || r.closed?
+ w.close unless !w || w.closed?
+ end
+ end
+
+ def ruby(*args)
+ args = ['-e', '$>.write($<.read)'] if args.empty?
+ ruby = EnvUtil.rubybin
+ f = IO.popen([ruby] + args, 'r+')
+ yield(f)
+ ensure
+ f.close unless !f || f.closed?
+ end
+
+ def test_try_convert
+ assert_equal(STDOUT, IO.try_convert(STDOUT))
+ assert_equal(nil, IO.try_convert("STDOUT"))
+ end
+
+ def test_ungetc
+ pipe do |r, w|
+ r.ungetc("0" * 10000)
+ w.write("1" * 10000)
+ w.close
+ assert_equal("0" * 10000 + "1" * 10000, r.read)
+ end
+ end
+
+ def test_write_non_writable
+ pipe do |r, w|
+ assert_raise(IOError) do
+ r.write "foobarbaz"
+ end
+ end
+ end
+
+ def test_dup
+ ruby do |f|
+ f2 = f.dup
+ f.puts "foo"
+ f2.puts "bar"
+ f.close_write
+ f2.close_write
+ assert_equal("foo\nbar\n", f.read)
+ assert_equal("", f2.read)
+ end
+
+ pipe2 do |r, w|
+ assert_raise(Errno::EMFILE, Errno::ENFILE, Errno::NOMEM) do
+ r2, w2 = r.dup, w.dup
+ end
+ end
+ end
+
+ def test_inspect
+ pipe do |r, w|
+ assert(r.inspect =~ /^#<IO:0x[0-9a-f]+>$/)
+ assert_raise(SecurityError) do
+ safe_4 { r.inspect }
+ end
+ end
+ end
+
+ def test_readpartial
+ pipe do |r, w|
+ w.write "foobarbaz"
+ w.close
+ assert_raise(ArgumentError) { r.readpartial(-1) }
+ assert_equal("fooba", r.readpartial(5))
+ r.readpartial(5, s = "")
+ assert_equal("rbaz", s)
+ end
+ end
+
+ def test_readpartial_error
+ pipe do |r, w|
+ s = ""
+ t = Thread.new { r.readpartial(5, s) }
+ 0 until s.size == 5
+ s.clear
+ w.write "foobarbaz"
+ w.close
+ assert_raise(RuntimeError) { t.join }
+ end
+ end
+
+ def test_read
+ pipe do |r, w|
+ w.write "foobarbaz"
+ w.close
+ assert_raise(ArgumentError) { r.read(-1) }
+ assert_equal("fooba", r.read(5))
+ r.read(nil, s = "")
+ assert_equal("rbaz", s)
+ end
+ end
+
+ def test_read_error
+ pipe do |r, w|
+ s = ""
+ t = Thread.new { r.read(5, s) }
+ 0 until s.size == 5
+ s.clear
+ w.write "foobarbaz"
+ w.close
+ assert_raise(RuntimeError) { t.join }
+ end
+ end
+
+ def test_write_nonblock
+ pipe do |r, w|
+ w.write_nonblock(1)
+ w.close
+ assert_equal("1", r.read)
+ end
+ end
+
+ def test_gets
+ pipe do |r, w|
+ w.write "foobarbaz"
+ w.close
+ assert_equal("", r.gets(0))
+ assert_equal("foobarbaz", r.gets(9))
+ end
+ end
+
+ def test_close_read
+ ruby do |f|
+ f.close_read
+ f.write "foobarbaz"
+ assert_raise(IOError) { f.read }
+ end
+ end
+
+ def test_close_read_pipe
+ pipe do |r, w|
+ r.close_read
+ assert_raise(Errno::EPIPE) { w.write "foobarbaz" }
+ end
+ end
+
+ def test_close_read_security_error
+ pipe do |r, w|
+ assert_raise(SecurityError) do
+ safe_4 { r.close_read }
+ end
+ end
+ end
+
+ def test_close_read_non_readable
+ pipe do |r, w|
+ assert_raise(IOError) do
+ w.close_read
+ end
+ end
+ end
+
+ def test_close_write
+ ruby do |f|
+ f.write "foobarbaz"
+ f.close_write
+ assert_equal("foobarbaz", f.read)
+ end
+ end
+
+ def test_close_write_security_error
+ pipe do |r, w|
+ assert_raise(SecurityError) do
+ safe_4 { r.close_write }
+ end
+ end
+ end
+
+ def test_close_write_non_readable
+ pipe do |r, w|
+ assert_raise(IOError) do
+ r.close_write
+ end
+ end
+ end
+
+ def test_pid
+ r, w = IO.pipe
+ assert_equal(nil, r.pid)
+ assert_equal(nil, w.pid)
+
+ pipe = IO.popen(EnvUtil.rubybin, "r+")
+ pid1 = pipe.pid
+ pipe.puts "p $$"
+ pipe.close_write
+ pid2 = pipe.read.chomp.to_i
+ assert_equal(pid2, pid1)
+ assert_equal(pid2, pipe.pid)
+ pipe.close
+ assert_raise(IOError) { pipe.pid }
+ end
+
+ def make_tempfile
+ t = Tempfile.new("foo")
+ t.puts "foo"
+ t.puts "bar"
+ t.puts "baz"
+ t.close
+ t
+ end
+
+ def test_set_lineno
+ t = make_tempfile
+
+ ruby("-e", <<-SRC, t.path) do |f|
+ open(ARGV[0]) do |f|
+ p $.
+ f.gets; p $.
+ f.gets; p $.
+ f.lineno = 1000; p $.
+ f.gets; p $.
+ f.gets; p $.
+ f.rewind; p $.
+ f.gets; p $.
+ f.gets; p $.
+ f.gets; p $.
+ f.gets; p $.
+ end
+ SRC
+ assert_equal("nil,1,2,2,1001,1001,1001,1,2,3,3", f.read.chomp.gsub("\n", ","))
+ end
+
+ pipe do |r, w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ r.gets; assert_equal(1, $.)
+ r.gets; assert_equal(2, $.)
+ r.lineno = 1000; assert_equal(2, $.)
+ r.gets; assert_equal(1001, $.)
+ r.gets; assert_equal(1001, $.)
+ end
+ end
+
+ def test_readline
+ pipe do |r, w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ r.readline; assert_equal(1, $.)
+ r.readline; assert_equal(2, $.)
+ r.lineno = 1000; assert_equal(2, $.)
+ r.readline; assert_equal(1001, $.)
+ assert_raise(EOFError) { r.readline }
+ end
+ end
+
+ def test_each_char
+ pipe do |r, w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ a = []
+ r.each_char {|c| a << c }
+ assert_equal(%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"], a)
+ end
+ end
+
+ def test_lines
+ pipe do |r, w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ e = r.lines
+ assert_equal("foo\n", e.next)
+ assert_equal("bar\n", e.next)
+ assert_equal("baz\n", e.next)
+ assert_raise(StopIteration) { e.next }
+ end
+ end
+
+ def test_bytes
+ pipe do |r, w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ e = r.bytes
+ (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
+ assert_equal(c.ord, e.next)
+ end
+ assert_raise(StopIteration) { e.next }
+ end
+ end
+
+ def test_chars
+ pipe do |r, w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ e = r.chars
+ (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
+ assert_equal(c, e.next)
+ end
+ assert_raise(StopIteration) { e.next }
+ end
+ end
+
+ def test_readbyte
+ pipe do |r, w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
+ assert_equal(c.ord, r.readbyte)
+ end
+ assert_raise(EOFError) { r.readbyte }
+ end
+ end
+
+ def test_readchar
+ pipe do |r, w|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ (%w(f o o) + ["\n"] + %w(b a r) + ["\n"] + %w(b a z) + ["\n"]).each do |c|
+ assert_equal(c, r.readchar)
+ end
+ assert_raise(EOFError) { r.readchar }
+ end
+ end
+
+ def test_close_on_exec
+ # xxx
+ ruby do |f|
+ assert_equal(false, f.close_on_exec?)
+ f.close_on_exec = true
+ assert_equal(true, f.close_on_exec?)
+ f.close_on_exec = false
+ assert_equal(false, f.close_on_exec?)
+ end
+
+ pipe do |r, w|
+ assert_equal(false, r.close_on_exec?)
+ r.close_on_exec = true
+ assert_equal(true, r.close_on_exec?)
+ r.close_on_exec = false
+ assert_equal(false, r.close_on_exec?)
+
+ assert_equal(false, w.close_on_exec?)
+ w.close_on_exec = true
+ assert_equal(true, w.close_on_exec?)
+ w.close_on_exec = false
+ assert_equal(false, w.close_on_exec?)
+ end
+ end
+
+ def test_close_security_error
+ pipe do |r, w|
+ assert_raise(SecurityError) do
+ safe_4 { r.close }
+ end
+ end
+ end
+
+ def test_sysseek
+ t = make_tempfile
+
+ open(t.path) do |f|
+ f.sysseek(-4, IO::SEEK_END)
+ assert_equal("baz\n", f.read)
+ end
+
+ open(t.path) do |f|
+ a = [f.getc, f.getc, f.getc]
+ a.reverse_each {|c| f.ungetc c }
+ assert_raise(IOError) { f.sysseek(1) }
+ end
+ end
+
+ def test_syswrite
+ t = make_tempfile
+
+ open(t.path, "w") do |f|
+ o = Object.new
+ def o.to_s; "FOO\n"; end
+ f.syswrite(o)
+ end
+ assert_equal("FOO\n", File.read(t.path))
+ end
+
+ def test_sysread
+ t = make_tempfile
+
+ open(t.path) do |f|
+ a = [f.getc, f.getc, f.getc]
+ a.reverse_each {|c| f.ungetc c }
+ assert_raise(IOError) { f.sysread(1) }
+ end
+ end
+
+ def test_flag
+ t = make_tempfile
+
+ assert_raise(ArgumentError) do
+ open(t.path, "z") { }
+ end
+
+ assert_raise(ArgumentError) do
+ open(t.path, "rr") { }
+ end
+ end
+
+ def test_sysopen
+ t = make_tempfile
+
+ fd = IO.sysopen(t.path)
+ assert_kind_of(Integer, fd)
+ f = IO.for_fd(fd)
+ assert_equal("foo\nbar\nbaz\n", f.read)
+ f.close
+
+ fd = IO.sysopen(t.path, "w", 0666)
+ assert_kind_of(Integer, fd)
+ f = IO.for_fd(fd)
+ f.write("FOO\n")
+ f.close
+
+ fd = IO.sysopen(t.path, "r")
+ assert_kind_of(Integer, fd)
+ f = IO.for_fd(fd)
+ assert_equal("FOO\n", f.read)
+ f.close
+ end
+
+ def test_open_redirect
+ o = Object.new
+ def o.to_open; self; end
+ assert_equal(o, open(o))
+ o2 = nil
+ open(o) do |f|
+ o2 = f
+ end
+ assert_equal(o, o2)
+ end
+
+ def test_open_pipe
+ open("|" + EnvUtil.rubybin, "r+") do |f|
+ f.puts "puts 'foo'"
+ f.close_write
+ assert_equal("foo\n", f.read)
+ end
+ end
+
+ def test_reopen
+ t = make_tempfile
+
+ pipe do |r, w|
+ assert_raise(SecurityError) do
+ safe_4 { r.reopen(t.path) }
+ end
+ end
+ end
+
+ def test_foreach
+ a = []
+ IO.foreach("|" + EnvUtil.rubybin + " -e 'puts :foo; puts :bar; puts :baz'") {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+
+ t = make_tempfile
+
+ a = []
+ IO.foreach(t.path, {:mode => "r" }) {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+
+ a = []
+ IO.foreach(t.path, {:open_args => [] }) {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+
+ a = []
+ IO.foreach(t.path, {:open_args => ["r"] }) {|x| a << x }
+ assert_equal(["foo\n", "bar\n", "baz\n"], a)
+ end
+
+ def test_printf
+ pipe do |r, w|
+ printf(w, "foo %s baz\n", "bar")
+ w.close_write
+ assert_equal("foo bar baz\n", r.read)
+ end
+ end
+
+ def test_print
+ t = make_tempfile
+
+ EnvUtil.rubyexec("-", t.path) do |w, r, e|
+ w.puts "print while $<.gets"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("foo\nbar\nbaz\n", r.read)
+ end
+ end
+
+ def test_putc
+ pipe do |r, w|
+ w.putc "A"
+ w.putc "BC"
+ w.putc 68
+ w.close_write
+ assert_equal("ABD", r.read)
+ end
+
+ EnvUtil.rubyexec do |w, r, e|
+ w.puts "putc 65"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("A", r.read)
+ end
+ end
+
+ def test_puts_recursive_array
+ a = ["foo"]
+ a << a
+ pipe do |r, w|
+ w.puts a
+ w.close
+ assert_equal("foo\n[...]\n", r.read)
+ end
+ end
+
+ def test_display
+ pipe do |r, w|
+ "foo".display(w)
+ w.close
+ assert_equal("foo", r.read)
+ end
+
+ EnvUtil.rubyexec do |w, r, e|
+ w.puts "'foo'.display"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("foo", r.read)
+ end
+ end
+
+ def test_set_stdout
+ assert_raise(TypeError) { $> = Object.new }
+
+ EnvUtil.rubyexec do |w, r, e|
+ w.puts "$> = $stderr"
+ w.puts "puts 'foo'"
+ w.close
+ assert_equal("foo\n", e.read)
+ assert_equal("", r.read)
+ end
+ end
+
+ def test_initialize
+ t = make_tempfile
+
+ fd = IO.sysopen(t.path)
+ assert_kind_of(Integer, fd)
+ f = IO.new(fd, "w")
+ f.write("FOO\n")
+ f.close
+
+ assert_equal("foo\nbar\nbaz\n", File.read(t.path))
+
+ pipe do |r, w|
+ assert_raise(RuntimeError) do
+ o = Object.new
+ class << o; self; end.instance_eval do
+ define_method(:to_io) { r }
+ end
+ w.instance_eval { initialize(o) }
+ end
+ end
+
+ pipe do |r, w|
+ r, w = IO.new(r), IO.new(w)
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ assert_equal("foo\nbar\nbaz\n", r.read)
+ end
+
+ pipe do |r, w|
+ assert_raise(ArgumentError) { IO.new(r, "r+") }
+ end
+
+ f = open(t.path)
+ assert_raise(RuntimeError) do
+ f.instance_eval { initialize }
+ end
+ end
+
+ def test_new_with_block
+ EnvUtil.rubyexec do |w, r, e|
+ w.puts "r, w = IO.pipe"
+ w.puts "IO.new(r) {}"
+ w.close
+ assert_not_equal("", e.read)
+ assert_equal("", r.read)
+ end
+ end
+
+ def test_readline2
+ EnvUtil.rubyexec("-e", <<-SRC) do |w, r, e|
+ puts readline
+ puts readline
+ puts readline
+ begin
+ puts readline
+ rescue EOFError
+ puts "end"
+ end
+ SRC
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("foo\nbar\nbaz\nend\n", r.read)
+ end
+ end
+
+ def test_readlines
+ EnvUtil.rubyexec("-e", "p readlines") do |w, r, e|
+ w.puts "foo"
+ w.puts "bar"
+ w.puts "baz"
+ w.close
+ assert_equal("", e.read)
+ assert_equal("[\"foo\\n\", \"bar\\n\", \"baz\\n\"]\n", r.read)
+ end
+ end
+
+ def test_s_read
+ t = make_tempfile
+
+ assert_equal("bar\n", File.read(t.path, 4, 4))
+ end
end