From 7c7cb1988548da0b6f20d35cd56d18c09bf59ecd Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Fri, 29 May 2009 01:12:10 -0700 Subject: [PATCH] first post --- README.markdown | 0 lib/fakefs.rb | 163 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 README.markdown create mode 100644 lib/fakefs.rb diff --git a/README.markdown b/README.markdown new file mode 100644 index 0000000..e69de29 diff --git a/lib/fakefs.rb b/lib/fakefs.rb new file mode 100644 index 0000000..e1b2d34 --- /dev/null +++ b/lib/fakefs.rb @@ -0,0 +1,163 @@ +module FakeFS + module FileUtils + extend self + + def mkdir_p(path) + FileSystem.add(path, MockDir.new) + end + + def rm(path) + FileSystem.delete(path) + end + alias_method :rm_rf, :rm + + def ln_s(target, path) + FileSystem.add(path, MockSymlink.new(target)) + end + + def cp_r(src, dest) + if dir = FileSystem.find(src) + FileSystem.add(dest, dir.entry) + end + end + + def mv(src, dest) + if target = FileSystem.find(src) + FileSystem.add(dest, target.entry) + FileSystem.delete(src) + end + end + end + + class File + PATH_SEPARATOR = '/' + + def self.join(*parts) + parts * PATH_SEPARATOR + end + + def self.exists?(path) + FileSystem.find(path) + end + + def self.expand_path(path) + ::File.expand_path(path) + end + + def self.readlink(path) + symlink = FileSystem.find(path) + FileSystem.find(symlink.target).to_s + end + end + + class Dir + def self.glob(pattern) + FileSystem.find(pattern).map { |entry| entry.to_s} + end + + def self.[](pattern) + glob(pattern) + end + end + + module FileSystem + extend self + + def fs + @fs ||= MockDir.new('.') + end + + def clear + @fs = nil + end + + def find(path) + parts = path_parts(path) + + target = parts[0...-1].inject(fs) do |dir, part| + dir[part] || {} + end + + case parts.last + when '*' + target.values + else + target[parts.last] + end + end + + def add(path, object) + parts = path_parts(path) + + d = parts[0...-1].inject(fs) do |dir, part| + dir[part] ||= MockDir.new(part, dir) + end + + object.name = parts.last + object.parent = d + d[parts.last] = object + end + + def delete(path) + if dir = FileSystem.find(path) + dir.parent.delete(dir.name) + end + end + + def path_parts(path) + path.split(File::PATH_SEPARATOR) + end + end + + class MockDir < Hash + attr_accessor :name, :parent + + def initialize(name = nil, parent = nil) + @name = name + @parent = parent + end + + def entry + self + end + + def to_s + if parent && parent.to_s != '.' + parent.to_s + '/' + name + else + name + end + end + end + + class MockSymlink + attr_accessor :name, :target + alias_method :to_s, :name + + def initialize(target) + @target = target + end + + def inspect + "symlink(#{target.split('/').last})" + end + + def entry + FileSystem.find(target) + end + + def method_missing(*args, &block) + entry.send(*args, &block) + end + end +end + +Object.class_eval do + remove_const(:Dir) + remove_const(:File) + remove_const(:FileUtils) +end + +File = FakeFS::File +FileUtils = FakeFS::FileUtils +Dir = FakeFS::Dir