1 # frozen_string_literal: true
5 class TestTempfile < Test::Unit::TestCase
11 def tempfile(*args, **kw, &block)
12 t = Tempfile.new(*args, **kw, &block)
13 @tempfile = (t unless block)
23 assert_instance_of(Tempfile, Tempfile.allocate)
29 t.write("hello world")
31 assert_equal "hello world", File.read(path)
34 def test_saves_in_given_directory
35 subdir = File.join(Dir.tmpdir, "tempfile-test-#{rand}")
38 tempfile = Tempfile.new("foo", subdir)
41 assert_equal subdir, File.dirname(tempfile.path)
52 assert_match(/^foo/, File.basename(t.path))
55 def test_default_basename
57 assert_file.exist?(t.path)
60 def test_basename_with_suffix
61 t = tempfile(["foo", ".txt"])
62 assert_match(/^foo/, File.basename(t.path))
63 assert_match(/\.txt$/, File.basename(t.path))
70 assert_equal true, t2.closed?
71 assert_equal false, t.closed?
78 assert_equal true, t2.closed?
79 assert_equal false, t.closed?
87 assert_file.exist?(path)
90 assert_file.not_exist?(path)
95 def test_unlink_silently_fails_on_windows
96 tempfile = tempfile("foo")
99 assert_nothing_raised do
104 File.unlink(path) if File.exist?(path)
108 def test_unlink_before_close_works_on_posix_systems
109 tempfile = tempfile("foo")
113 assert_file.not_exist?(path)
114 tempfile.write("hello ")
115 tempfile.write("world\n")
117 assert_equal "hello world\n", tempfile.read
122 end unless /mswin|mingw/ =~ RUBY_PLATFORM
124 def test_close_and_close_p
126 assert_not_predicate(t, :closed?)
128 assert_predicate(t, :closed?)
131 def test_close_with_unlink_now_true_works
135 assert_predicate(t, :closed?)
137 assert_file.not_exist?(path)
140 def test_close_with_unlink_now_true_does_not_unlink_if_already_unlinked
144 File.open(path, "w").close
147 assert_file.exist?(path)
149 File.unlink(path) rescue nil
151 end unless /mswin|mingw/ =~ RUBY_PLATFORM
153 def test_close_bang_works
157 assert_predicate(t, :closed?)
159 assert_file.not_exist?(path)
162 def test_close_bang_does_not_unlink_if_already_unlinked
166 File.open(path, "w").close
169 assert_file.exist?(path)
171 File.unlink(path) rescue nil
173 end unless /mswin|mingw/ =~ RUBY_PLATFORM
175 def test_finalizer_does_not_unlink_if_already_unlinked
176 assert_in_out_err('-rtempfile', <<-'EOS') do |(filename,*), (error,*)|
177 file = Tempfile.new('foo')
181 File.open(path, "w").close
183 assert_file.exist?(filename)
184 File.unlink(filename)
188 assert_in_out_err('-rtempfile', <<-'EOS') do |(filename,*), (error,*)|
189 file = Tempfile.new('foo')
193 File.open(path, "w").close
196 # POSIX unlink semantics supported, continue with test
197 assert_file.exist?(filename)
198 File.unlink(filename)
202 end unless /mswin|mingw/ =~ RUBY_PLATFORM
204 def test_close_does_not_make_path_nil
207 assert_not_nil t.path
210 def test_close_flushes_buffer
214 assert_equal 5, File.size(t.path)
217 def test_tempfile_is_unlinked_when_ruby_exits
218 assert_in_out_err('-rtempfile', <<-'EOS') do |(filename), (error)|
219 puts Tempfile.new('foo').path
221 assert_file.for("tempfile must not be exist after GC.").not_exist?(filename)
226 def test_tempfile_finalizer_does_not_run_if_unlinked
227 bug8768 = '[ruby-core:56521] [Bug #8768]'
228 assert_in_out_err(%w(-rtempfile), <<-'EOS') do |(filename), (error)|
229 tmp = Tempfile.new('foo')
235 assert_file.not_exist?(filename)
236 assert_nil(error, "#{bug8768} we used to get a confusing 'removing ...done' here")
240 def test_size_flushes_buffer_before_determining_file_size
243 assert_equal 0, File.size(t.path)
244 assert_equal 5, t.size
245 assert_equal 5, File.size(t.path)
248 def test_size_works_if_file_is_closed
252 assert_equal 5, t.size
255 def test_size_on_empty_file
259 assert_equal 0, t.size
265 lock = Thread::Mutex.new
266 cond = Thread::ConditionVariable.new
270 threads << Thread.new do
278 result << Tempfile.new('foo')
280 Thread.current[:result] = result
288 threads.each do |thread|
290 tempfiles |= thread[:result]
292 filenames = tempfiles.map { |f| f.path }
294 assert_equal filenames.size, filenames.uniq.size
296 tempfiles.each do |tempfile|
308 assert(M === o, "[ruby-dev:32932]")
311 def test_tempfile_encoding_nooption
312 default_external=Encoding.default_external
314 t.write("\xE6\x9D\xBE\xE6\xB1\x9F")
316 assert_equal(default_external,t.read.encoding)
319 def test_tempfile_encoding_ascii8bit
320 t = tempfile("TEST",:encoding=>"ascii-8bit")
321 t.write("\xE6\x9D\xBE\xE6\xB1\x9F")
323 assert_equal(Encoding::ASCII_8BIT,t.read.encoding)
326 def test_tempfile_encoding_ascii8bit2
327 t = tempfile("TEST",Dir::tmpdir,:encoding=>"ascii-8bit")
328 t.write("\xE6\x9D\xBE\xE6\xB1\x9F")
330 assert_equal(Encoding::ASCII_8BIT,t.read.encoding)
334 t = tempfile("TEST", mode: IO::BINARY)
335 if IO::BINARY.nonzero?
338 assert(t.binmode?, 'binmode after reopen')
340 assert_equal(0600, t.stat.mode & 0777)
344 def test_create_with_block
346 Tempfile.create("tempfile-create") {|f|
348 assert_file.exist?(path)
350 assert_file.not_exist?(path)
352 Tempfile.create("tempfile-create") {|f|
357 assert_file.not_exist?(path)
360 def test_create_without_block
362 f = Tempfile.create("tempfile-create")
364 assert_file.exist?(path)
366 assert_file.exist?(path)
369 File.unlink path if path
372 def test_create_default_basename
376 assert_file.exist?(path)
378 assert_file.not_exist?(path)
384 assert_kind_of File, file
385 assert_equal f.to_i, file.to_i
389 def test_open_traversal_dir
390 assert_mktmpdir_traversal do |traversal_path|
391 t = Tempfile.open([traversal_path, 'foo'])
398 def test_new_traversal_dir
399 assert_mktmpdir_traversal do |traversal_path|
400 t = Tempfile.new(traversal_path + 'foo')
407 def test_create_traversal_dir
408 assert_mktmpdir_traversal do |traversal_path|
409 t = Tempfile.create(traversal_path + 'foo')
419 def assert_mktmpdir_traversal
420 Dir.mktmpdir do |target|
421 target = target.chomp('/') + '/'
422 traversal_path = target.sub(/\A\w:/, '') # for DOSISH
423 traversal_path = Array.new(target.count('/')-2, '..').join('/') + traversal_path
424 actual = yield traversal_path
425 assert_not_send([File.absolute_path(actual), :start_with?, target])