Merge remote branch 'smt/hard_links_and_deletion'
This commit is contained in:
commit
e4ea7e1406
7
Rakefile
7
Rakefile
@ -1,7 +1,10 @@
|
|||||||
task :default do
|
desc "Run tests"
|
||||||
Dir['test/*_test.rb'].each { |file| require file }
|
task :test do
|
||||||
|
Dir['test/**/*_test.rb'].each { |file| require file }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
task :default => :test
|
||||||
|
|
||||||
begin
|
begin
|
||||||
require 'jeweler'
|
require 'jeweler'
|
||||||
|
|
||||||
|
@ -33,5 +33,13 @@ module FakeFS
|
|||||||
name
|
name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def delete(node = self)
|
||||||
|
if node == self
|
||||||
|
parent.delete(self)
|
||||||
|
else
|
||||||
|
super(node.name)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,16 +1,54 @@
|
|||||||
module FakeFS
|
module FakeFS
|
||||||
class FakeFile
|
class FakeFile
|
||||||
attr_accessor :name, :parent, :content
|
attr_accessor :name, :parent
|
||||||
|
|
||||||
|
class Inode
|
||||||
|
def initialize(file_owner)
|
||||||
|
@content = ""
|
||||||
|
@links = [file_owner]
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_accessor :content
|
||||||
|
attr_accessor :links
|
||||||
|
|
||||||
|
def link(file)
|
||||||
|
links << file unless links.include?(file)
|
||||||
|
file.inode = self
|
||||||
|
end
|
||||||
|
|
||||||
|
def unlink(file)
|
||||||
|
links.delete(file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def initialize(name = nil, parent = nil)
|
def initialize(name = nil, parent = nil)
|
||||||
@name = name
|
@name = name
|
||||||
@parent = parent
|
@parent = parent
|
||||||
@content = ''
|
@inode = Inode.new(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_accessor :inode
|
||||||
|
|
||||||
|
def content
|
||||||
|
@inode.content
|
||||||
|
end
|
||||||
|
|
||||||
|
def content=(str)
|
||||||
|
@inode.content = str
|
||||||
|
end
|
||||||
|
|
||||||
|
def links
|
||||||
|
@inode.links
|
||||||
|
end
|
||||||
|
|
||||||
|
def link(other_file)
|
||||||
|
@inode.link(other_file)
|
||||||
end
|
end
|
||||||
|
|
||||||
def clone(parent = nil)
|
def clone(parent = nil)
|
||||||
clone = super()
|
clone = super()
|
||||||
clone.parent = parent if parent
|
clone.parent = parent if parent
|
||||||
|
clone.inode = inode.clone
|
||||||
clone
|
clone
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -25,5 +63,10 @@ module FakeFS
|
|||||||
def to_s
|
def to_s
|
||||||
File.join(parent.to_s, name)
|
File.join(parent.to_s, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def delete
|
||||||
|
inode.unlink(self)
|
||||||
|
parent.delete(self)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -15,12 +15,18 @@ module FakeFS
|
|||||||
FileSystem.find(target)
|
FileSystem.find(target)
|
||||||
end
|
end
|
||||||
|
|
||||||
def method_missing(*args, &block)
|
def delete
|
||||||
entry.send(*args, &block)
|
parent.delete(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
def respond_to?(method)
|
def respond_to?(method)
|
||||||
entry.respond_to?(method)
|
entry.respond_to?(method)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def method_missing(*args, &block)
|
||||||
|
entry.send(*args, &block)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -2,6 +2,31 @@ module FakeFS
|
|||||||
class File
|
class File
|
||||||
PATH_SEPARATOR = '/'
|
PATH_SEPARATOR = '/'
|
||||||
|
|
||||||
|
MODES = [
|
||||||
|
READ_ONLY = "r",
|
||||||
|
READ_WRITE = "r+",
|
||||||
|
WRITE_ONLY = "w",
|
||||||
|
READ_WRITE_TRUNCATE = "w+",
|
||||||
|
APPEND_WRITE_ONLY = "a",
|
||||||
|
APPEND_READ_WRITE = "a+"
|
||||||
|
]
|
||||||
|
|
||||||
|
FILE_CREATION_MODES = MODES - [READ_ONLY, READ_WRITE]
|
||||||
|
|
||||||
|
READ_ONLY_MODES = [
|
||||||
|
READ_ONLY
|
||||||
|
]
|
||||||
|
|
||||||
|
WRITE_ONLY_MODES = [
|
||||||
|
WRITE_ONLY,
|
||||||
|
APPEND_WRITE_ONLY
|
||||||
|
]
|
||||||
|
|
||||||
|
TRUNCATION_MODES = [
|
||||||
|
WRITE_ONLY,
|
||||||
|
READ_WRITE_TRUNCATE
|
||||||
|
]
|
||||||
|
|
||||||
def self.extname(path)
|
def self.extname(path)
|
||||||
RealFile.extname(path)
|
RealFile.extname(path)
|
||||||
end
|
end
|
||||||
@ -69,7 +94,7 @@ module FakeFS
|
|||||||
FileSystem.find(symlink.target).to_s
|
FileSystem.find(symlink.target).to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.open(path, mode='r', perm = 0644)
|
def self.open(path, mode=READ_ONLY, perm = 0644)
|
||||||
if block_given?
|
if block_given?
|
||||||
yield new(path, mode, perm)
|
yield new(path, mode, perm)
|
||||||
else
|
else
|
||||||
@ -89,13 +114,86 @@ module FakeFS
|
|||||||
def self.readlines(path)
|
def self.readlines(path)
|
||||||
read(path).split("\n")
|
read(path).split("\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.link(source, dest)
|
||||||
|
if directory?(source)
|
||||||
|
raise Errno::EPERM, "Operation not permitted - #{source} or #{dest}"
|
||||||
|
end
|
||||||
|
|
||||||
|
if !exists?(source)
|
||||||
|
raise Errno::ENOENT, "No such file or directory - #{source} or #{dest}"
|
||||||
|
end
|
||||||
|
|
||||||
|
if exists?(dest)
|
||||||
|
raise Errno::EEXIST, "File exists - #{source} or #{dest}"
|
||||||
|
end
|
||||||
|
|
||||||
|
source = FileSystem.find(source)
|
||||||
|
dest = FileSystem.add(dest, source.entry.clone)
|
||||||
|
source.link(dest)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
def self.stat(file)
|
||||||
|
File::Stat.new(file)
|
||||||
|
end
|
||||||
|
|
||||||
|
class Stat
|
||||||
|
def initialize(file)
|
||||||
|
if !File.exists?(file)
|
||||||
|
raise(Errno::ENOENT, "No such file or directory - #{file}")
|
||||||
|
end
|
||||||
|
|
||||||
|
@file = file
|
||||||
|
end
|
||||||
|
|
||||||
|
def symlink?
|
||||||
|
File.symlink?(@file)
|
||||||
|
end
|
||||||
|
|
||||||
|
def directory?
|
||||||
|
File.directory?(@file)
|
||||||
|
end
|
||||||
|
|
||||||
|
def nlink
|
||||||
|
FileSystem.find(@file).links.size
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
attr_reader :path
|
attr_reader :path
|
||||||
def initialize(path, mode = nil, perm = nil)
|
|
||||||
|
def initialize(path, mode = READ_ONLY, perm = nil)
|
||||||
@path = path
|
@path = path
|
||||||
@mode = mode
|
@mode = mode
|
||||||
@file = FileSystem.find(path)
|
@file = FileSystem.find(path)
|
||||||
@open = true
|
@open = true
|
||||||
|
|
||||||
|
check_valid_mode
|
||||||
|
file_creation_mode? ? create_missing_file : check_file_existence!
|
||||||
|
truncate_file if truncation_mode?
|
||||||
end
|
end
|
||||||
|
|
||||||
def close
|
def close
|
||||||
@ -103,7 +201,9 @@ module FakeFS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def read
|
def read
|
||||||
raise IOError.new('closed stream') unless @open
|
raise IOError, 'closed stream' unless @open
|
||||||
|
raise IOError, 'not opened for reading' if write_only?
|
||||||
|
|
||||||
@file.content
|
@file.content
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -118,11 +218,8 @@ module FakeFS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def write(content)
|
def write(content)
|
||||||
raise IOError.new('closed stream') unless @open
|
raise IOError, 'closed stream' unless @open
|
||||||
|
raise IOError, 'not open for writing' if read_only?
|
||||||
if !File.exists?(@path)
|
|
||||||
@file = FileSystem.add(path, FakeFile.new)
|
|
||||||
end
|
|
||||||
|
|
||||||
@file.content += content
|
@file.content += content
|
||||||
end
|
end
|
||||||
@ -130,5 +227,49 @@ module FakeFS
|
|||||||
alias_method :<<, :write
|
alias_method :<<, :write
|
||||||
|
|
||||||
def flush; self; end
|
def flush; self; end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def check_file_existence!
|
||||||
|
unless @file
|
||||||
|
raise Errno::ENOENT, "No such file or directory - #{@file}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_valid_mode
|
||||||
|
if !mode_in?(MODES)
|
||||||
|
raise ArgumentError, "illegal access mode #{@mode}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def read_only?
|
||||||
|
mode_in? READ_ONLY_MODES
|
||||||
|
end
|
||||||
|
|
||||||
|
def file_creation_mode?
|
||||||
|
mode_in? FILE_CREATION_MODES
|
||||||
|
end
|
||||||
|
|
||||||
|
def write_only?
|
||||||
|
mode_in? WRITE_ONLY_MODES
|
||||||
|
end
|
||||||
|
|
||||||
|
def truncation_mode?
|
||||||
|
mode_in? TRUNCATION_MODES
|
||||||
|
end
|
||||||
|
|
||||||
|
def mode_in?(list)
|
||||||
|
list.include?(@mode)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_missing_file
|
||||||
|
if !File.exists?(@path)
|
||||||
|
@file = FileSystem.add(path, FakeFile.new)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def truncate_file
|
||||||
|
@file.content = ""
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -54,7 +54,7 @@ module FakeFS
|
|||||||
files.each do |f|
|
files.each do |f|
|
||||||
if RealFile.file?(f)
|
if RealFile.file?(f)
|
||||||
FileUtils.mkdir_p(File.dirname(f))
|
FileUtils.mkdir_p(File.dirname(f))
|
||||||
File.open(f, 'w') do |g|
|
File.open(f, File::WRITE_ONLY) do |g|
|
||||||
g.print RealFile.open(f){|h| h.read }
|
g.print RealFile.open(f){|h| h.read }
|
||||||
end
|
end
|
||||||
elsif RealFile.directory?(f)
|
elsif RealFile.directory?(f)
|
||||||
@ -66,8 +66,8 @@ module FakeFS
|
|||||||
end
|
end
|
||||||
|
|
||||||
def delete(path)
|
def delete(path)
|
||||||
if dir = FileSystem.find(path)
|
if node = FileSystem.find(path)
|
||||||
dir.parent.delete(dir.name)
|
node.delete
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
88
test/fake/file_test.rb
Normal file
88
test/fake/file_test.rb
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
||||||
|
require 'fakefs/safe'
|
||||||
|
require 'test/unit'
|
||||||
|
|
||||||
|
class FakeFileTest < Test::Unit::TestCase
|
||||||
|
include FakeFS
|
||||||
|
|
||||||
|
def setup
|
||||||
|
FileSystem.clear
|
||||||
|
|
||||||
|
@file = FakeFile.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_fake_file_has_empty_content_by_default
|
||||||
|
assert_equal "", @file.content
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_fake_file_can_read_and_write_to_content
|
||||||
|
@file.content = "foobar"
|
||||||
|
assert_equal "foobar", @file.content
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_fake_file_has_1_link_by_default
|
||||||
|
assert_equal [@file], @file.links
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_fake_file_can_create_link
|
||||||
|
other_file = FakeFile.new
|
||||||
|
|
||||||
|
@file.link(other_file)
|
||||||
|
|
||||||
|
assert_equal [@file, other_file], @file.links
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_fake_file_wont_add_link_to_same_file_twice
|
||||||
|
other_file = FakeFile.new
|
||||||
|
|
||||||
|
@file.link other_file
|
||||||
|
@file.link other_file
|
||||||
|
|
||||||
|
assert_equal [@file, other_file], @file.links
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_links_are_mutual
|
||||||
|
other_file = FakeFile.new
|
||||||
|
|
||||||
|
@file.link(other_file)
|
||||||
|
|
||||||
|
assert_equal [@file, other_file], other_file.links
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_can_link_multiple_files
|
||||||
|
file_two = FakeFile.new
|
||||||
|
file_three = FakeFile.new
|
||||||
|
|
||||||
|
@file.link file_two
|
||||||
|
@file.link file_three
|
||||||
|
|
||||||
|
assert_equal [@file, file_two, file_three], @file.links
|
||||||
|
assert_equal [@file, file_two, file_three], file_two.links
|
||||||
|
assert_equal [@file, file_two, file_three], file_three.links
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_links_share_same_content
|
||||||
|
other_file = FakeFile.new
|
||||||
|
|
||||||
|
@file.link other_file
|
||||||
|
|
||||||
|
@file.content = "foobar"
|
||||||
|
|
||||||
|
assert_equal "foobar", other_file.content
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_clone_creates_new_inode
|
||||||
|
clone = @file.clone
|
||||||
|
assert !clone.inode.equal?(@file.inode)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_cloning_does_not_use_same_content_object
|
||||||
|
clone = @file.clone
|
||||||
|
|
||||||
|
clone.content = "foo"
|
||||||
|
@file.content = "bar"
|
||||||
|
|
||||||
|
assert_equal "foo", clone.content
|
||||||
|
assert_equal "bar", @file.content
|
||||||
|
end
|
||||||
|
end
|
11
test/fake/symlink_test.rb
Normal file
11
test/fake/symlink_test.rb
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
||||||
|
require 'fakefs/safe'
|
||||||
|
require 'test/unit'
|
||||||
|
|
||||||
|
class FakeSymlinkTest < Test::Unit::TestCase
|
||||||
|
include FakeFS
|
||||||
|
|
||||||
|
def test_symlink_has_method_missing_as_private
|
||||||
|
assert FakeSymlink.private_instance_methods.include?("method_missing")
|
||||||
|
end
|
||||||
|
end
|
@ -96,6 +96,92 @@ class FakeFSTest < Test::Unit::TestCase
|
|||||||
assert File.exists?(path)
|
assert File.exists?(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_file_opens_in_read_only_mode
|
||||||
|
File.open("foo", "w") { |f| f << "foo" }
|
||||||
|
|
||||||
|
f = File.open("foo")
|
||||||
|
|
||||||
|
assert_raises(IOError) do
|
||||||
|
f << "bar"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_file_opens_in_invalid_mode
|
||||||
|
FileUtils.touch("foo")
|
||||||
|
|
||||||
|
assert_raises(ArgumentError) do
|
||||||
|
File.open("foo", "an_illegal_mode")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_raises_error_when_cannot_find_file_in_read_mode
|
||||||
|
assert_raises(Errno::ENOENT) do
|
||||||
|
File.open("does_not_exist", "r")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_raises_error_when_cannot_find_file_in_read_write_mode
|
||||||
|
assert_raises(Errno::ENOENT) do
|
||||||
|
File.open("does_not_exist", "r+")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_creates_files_in_write_only_mode
|
||||||
|
File.open("foo", "w")
|
||||||
|
assert File.exists?("foo")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_creates_files_in_read_write_truncate_mode
|
||||||
|
File.open("foo", "w+")
|
||||||
|
assert File.exists?("foo")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_creates_files_in_append_write_only
|
||||||
|
File.open("foo", "a")
|
||||||
|
assert File.exists?("foo")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_creates_files_in_append_read_write
|
||||||
|
File.open("foo", "a+")
|
||||||
|
assert File.exists?("foo")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_file_in_write_only_raises_error_when_reading
|
||||||
|
FileUtils.touch("foo")
|
||||||
|
|
||||||
|
f = File.open("foo", "w")
|
||||||
|
|
||||||
|
assert_raises(IOError) do
|
||||||
|
f.read
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_file_in_write_mode_truncates_existing_file
|
||||||
|
File.open("foo", "w") { |f| f << "contents" }
|
||||||
|
|
||||||
|
f = File.open("foo", "w")
|
||||||
|
|
||||||
|
assert_equal "", File.read("foo")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_file_in_read_write_truncation_mode_truncates_file
|
||||||
|
File.open("foo", "w") { |f| f << "foo" }
|
||||||
|
|
||||||
|
f = File.open("foo", "w+")
|
||||||
|
|
||||||
|
assert_equal "", File.read("foo")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_file_in_append_write_only_raises_error_when_reading
|
||||||
|
FileUtils.touch("foo")
|
||||||
|
|
||||||
|
f = File.open("foo", "a")
|
||||||
|
|
||||||
|
assert_raises(IOError) do
|
||||||
|
f.read
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_can_read_files_once_written
|
def test_can_read_files_once_written
|
||||||
path = '/path/to/file.txt'
|
path = '/path/to/file.txt'
|
||||||
File.open(path, 'w') do |f|
|
File.open(path, 'w') do |f|
|
||||||
@ -532,6 +618,14 @@ class FakeFSTest < Test::Unit::TestCase
|
|||||||
assert_equal 'works', File.open('new/nother') { |f| f.read }
|
assert_equal 'works', File.open('new/nother') { |f| f.read }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_can_symlink_through_file
|
||||||
|
FileUtils.touch("/foo")
|
||||||
|
|
||||||
|
File.symlink("/foo", "/bar")
|
||||||
|
|
||||||
|
assert File.symlink?("/bar")
|
||||||
|
end
|
||||||
|
|
||||||
def test_files_can_be_touched
|
def test_files_can_be_touched
|
||||||
FileUtils.touch('touched_file')
|
FileUtils.touch('touched_file')
|
||||||
assert File.exists?('touched_file')
|
assert File.exists?('touched_file')
|
||||||
@ -827,6 +921,144 @@ class FakeFSTest < Test::Unit::TestCase
|
|||||||
def test_tmpdir
|
def test_tmpdir
|
||||||
assert Dir.tmpdir == "/tmp"
|
assert Dir.tmpdir == "/tmp"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_hard_link_creates_file
|
||||||
|
FileUtils.touch("/foo")
|
||||||
|
|
||||||
|
File.link("/foo", "/bar")
|
||||||
|
assert File.exists?("/bar")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_hard_link_with_missing_file_raises_error
|
||||||
|
assert_raises(Errno::ENOENT) do
|
||||||
|
File.link("/foo", "/bar")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_hard_link_with_existing_destination_file
|
||||||
|
FileUtils.touch("/foo")
|
||||||
|
FileUtils.touch("/bar")
|
||||||
|
|
||||||
|
assert_raises(Errno::EEXIST) do
|
||||||
|
File.link("/foo", "/bar")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_hard_link_returns_0_when_successful
|
||||||
|
FileUtils.touch("/foo")
|
||||||
|
|
||||||
|
assert_equal 0, File.link("/foo", "/bar")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_hard_link_returns_duplicate_file
|
||||||
|
File.open("/foo", "w") { |x| x << "some content" }
|
||||||
|
|
||||||
|
File.link("/foo", "/bar")
|
||||||
|
assert_equal "some content", File.read("/bar")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_hard_link_with_directory_raises_error
|
||||||
|
Dir.mkdir "/foo"
|
||||||
|
|
||||||
|
assert_raises(Errno::EPERM) do
|
||||||
|
File.link("/foo", "/bar")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_file_stat_returns_file_stat_object
|
||||||
|
FileUtils.touch("/foo")
|
||||||
|
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)
|
def here(fname)
|
||||||
RealFile.expand_path(RealFile.dirname(__FILE__)+'/'+fname)
|
RealFile.expand_path(RealFile.dirname(__FILE__)+'/'+fname)
|
||||||
|
70
test/file/stat_test.rb
Normal file
70
test/file/stat_test.rb
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
||||||
|
require 'fakefs/safe'
|
||||||
|
require 'test/unit'
|
||||||
|
|
||||||
|
class FileStatTest < Test::Unit::TestCase
|
||||||
|
include FakeFS
|
||||||
|
|
||||||
|
def setup
|
||||||
|
FileSystem.clear
|
||||||
|
end
|
||||||
|
|
||||||
|
def touch(*args)
|
||||||
|
FileUtils.touch(*args)
|
||||||
|
end
|
||||||
|
|
||||||
|
def ln_s(*args)
|
||||||
|
FileUtils.ln_s(*args)
|
||||||
|
end
|
||||||
|
|
||||||
|
def mkdir(*args)
|
||||||
|
Dir.mkdir(*args)
|
||||||
|
end
|
||||||
|
|
||||||
|
def ln(*args)
|
||||||
|
File.link(*args)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_file_stat_init_with_non_existant_file
|
||||||
|
assert_raises(Errno::ENOENT) do
|
||||||
|
File::Stat.new("/foo")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_symlink_should_be_true_when_symlink
|
||||||
|
touch("/foo")
|
||||||
|
ln_s("/foo", "/bar")
|
||||||
|
|
||||||
|
assert File::Stat.new("/bar").symlink?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_symlink_should_be_false_when_not_a_symlink
|
||||||
|
FileUtils.touch("/foo")
|
||||||
|
|
||||||
|
assert !File::Stat.new("/foo").symlink?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_should_return_false_for_directory_when_not_a_directory
|
||||||
|
FileUtils.touch("/foo")
|
||||||
|
|
||||||
|
assert !File::Stat.new("/foo").directory?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_should_return_true_for_directory_when_a_directory
|
||||||
|
mkdir "/foo"
|
||||||
|
|
||||||
|
assert File::Stat.new("/foo").directory?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_one_file_has_hard_link
|
||||||
|
touch "testfile"
|
||||||
|
assert_equal 1, File.stat("testfile").nlink
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_two_hard_links_show_nlinks_as_two
|
||||||
|
touch "testfile"
|
||||||
|
ln "testfile", "testfile.bak"
|
||||||
|
|
||||||
|
assert_equal 2, File.stat("testfile").nlink
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user