From c00d4506623d16a928fb37ae66084d2c632970a1 Mon Sep 17 00:00:00 2001 From: Scott Taylor Date: Thu, 1 Oct 2009 02:42:29 -0400 Subject: [PATCH] Add File::delete and alias File::unlink. Get those, plus FileUtils.rm to work properly with hard links. Closes #8 --- lib/fakefs/fake/dir.rb | 8 ++++ lib/fakefs/fake/file.rb | 9 ++++ lib/fakefs/fake/symlink.rb | 6 ++- lib/fakefs/file.rb | 18 ++++++++ lib/fakefs/file_system.rb | 4 +- test/fakefs_test.rb | 90 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 132 insertions(+), 3 deletions(-) diff --git a/lib/fakefs/fake/dir.rb b/lib/fakefs/fake/dir.rb index 5ca8ca1..c75a57b 100644 --- a/lib/fakefs/fake/dir.rb +++ b/lib/fakefs/fake/dir.rb @@ -33,5 +33,13 @@ module FakeFS name end end + + def delete(node = self) + if node == self + parent.delete(self) + else + super(node.name) + end + end end end diff --git a/lib/fakefs/fake/file.rb b/lib/fakefs/fake/file.rb index 57c98f6..2c3074b 100644 --- a/lib/fakefs/fake/file.rb +++ b/lib/fakefs/fake/file.rb @@ -15,6 +15,10 @@ module FakeFS links << file unless links.include?(file) file.inode = self end + + def unlink(file) + links.delete(file) + end end def initialize(name = nil, parent = nil) @@ -59,5 +63,10 @@ module FakeFS def to_s File.join(parent.to_s, name) end + + def delete + inode.unlink(self) + parent.delete(self) + end end end diff --git a/lib/fakefs/fake/symlink.rb b/lib/fakefs/fake/symlink.rb index f4a81e9..81d6c3c 100644 --- a/lib/fakefs/fake/symlink.rb +++ b/lib/fakefs/fake/symlink.rb @@ -15,10 +15,14 @@ module FakeFS FileSystem.find(target) end + def delete + parent.delete(self) + end + def respond_to?(method) entry.respond_to?(method) end - + private def method_missing(*args, &block) diff --git a/lib/fakefs/file.rb b/lib/fakefs/file.rb index a7e3869..64c5afe 100644 --- a/lib/fakefs/file.rb +++ b/lib/fakefs/file.rb @@ -135,6 +135,24 @@ module FakeFS 0 end + def self.delete(file_name, *additional_file_names) + if !exists?(file_name) + raise Errno::ENOENT, "No such file or directory - #{file_name}" + end + + FileUtils.rm(file_name) + + additional_file_names.each do |file_name| + FileUtils.rm(file_name) + end + + additional_file_names.size + 1 + end + + class << self + alias_method :unlink, :delete + end + def self.symlink(source, dest) FileUtils.ln_s(source, dest) end diff --git a/lib/fakefs/file_system.rb b/lib/fakefs/file_system.rb index 93426f3..09af802 100644 --- a/lib/fakefs/file_system.rb +++ b/lib/fakefs/file_system.rb @@ -66,8 +66,8 @@ module FakeFS end def delete(path) - if dir = FileSystem.find(path) - dir.parent.delete(dir.name) + if node = FileSystem.find(path) + node.delete end end diff --git a/test/fakefs_test.rb b/test/fakefs_test.rb index 70cbf42..0d06956 100644 --- a/test/fakefs_test.rb +++ b/test/fakefs_test.rb @@ -970,6 +970,96 @@ class FakeFSTest < Test::Unit::TestCase assert_equal File::Stat, File.stat("/foo").class end + def test_can_delete_file_with_delete + FileUtils.touch("/foo") + + File.delete("/foo") + + assert !File.exists?("/foo") + end + + def test_can_delete_multiple_files_with_delete + FileUtils.touch("/foo") + FileUtils.touch("/bar") + + File.delete("/foo", "/bar") + + assert !File.exists?("/foo") + assert !File.exists?("/bar") + end + + def test_delete_raises_argument_error_with_no_filename_given + assert_raises ArgumentError do + File.delete + end + end + + def test_delete_returns_number_one_when_given_one_arg + FileUtils.touch("/foo") + + assert_equal 1, File.delete("/foo") + end + + def test_delete_returns_number_two_when_given_two_args + FileUtils.touch("/foo") + FileUtils.touch("/bar") + + assert_equal 2, File.delete("/foo", "/bar") + end + + def test_delete_raises_error_when_first_file_does_not_exist + assert_raises Errno::ENOENT do + File.delete("/foo") + end + end + + def test_delete_does_not_raise_error_when_second_file_does_not_exist + FileUtils.touch("/foo") + + assert_nothing_raised do + File.delete("/foo", "/bar") + end + end + + def test_unlink_is_alias_for_delete + assert_equal File.method(:unlink), File.method(:delete) + end + + def test_unlink_removes_only_one_file_content + File.open("/foo", "w") { |f| f << "some_content" } + File.link("/foo", "/bar") + + File.unlink("/bar") + File.read("/foo") == "some_content" + end + + def test_link_reports_correct_stat_info_after_unlinking + File.open("/foo", "w") { |f| f << "some_content" } + File.link("/foo", "/bar") + + File.unlink("/bar") + assert_equal 1, File.stat("/foo").nlink + end + + def test_delete_works_with_symlink + FileUtils.touch("/foo") + File.symlink("/foo", "/bar") + + File.unlink("/bar") + + assert File.exists?("/foo") + assert !File.exists?("/bar") + end + + def test_delete_works_with_symlink_source + FileUtils.touch("/foo") + File.symlink("/foo", "/bar") + + File.unlink("/foo") + + assert !File.exists?("/foo") + end + def here(fname) RealFile.expand_path(RealFile.dirname(__FILE__)+'/'+fname) end