memfs 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,157 @@
1
+ require 'singleton'
2
+ require 'memfs/fake/directory'
3
+ require 'memfs/fake/file'
4
+ require 'memfs/fake/symlink'
5
+
6
+ module MemFs
7
+ class FileSystem
8
+ include Singleton
9
+
10
+ attr_accessor :working_directory
11
+ attr_accessor :registred_entries
12
+ attr_accessor :root
13
+
14
+ def basename(path)
15
+ File.basename(path)
16
+ end
17
+
18
+ def chdir(path, &block)
19
+ destination = find_directory!(path)
20
+
21
+ previous_directory = working_directory
22
+ self.working_directory = destination
23
+
24
+ block.call if block
25
+ ensure
26
+ if block
27
+ self.working_directory = previous_directory
28
+ end
29
+ end
30
+
31
+ def clear!
32
+ self.root = Fake::Directory.new('/')
33
+ self.chdir('/')
34
+ end
35
+
36
+ def chmod(mode_int, file_name)
37
+ find!(file_name).mode = mode_int
38
+ end
39
+
40
+ def chown(uid, gid, path)
41
+ entry = find!(path).dereferenced
42
+ entry.uid = uid if uid && uid != -1
43
+ entry.gid = gid if gid && gid != -1
44
+ end
45
+
46
+ def directory?(path)
47
+ find(path).is_a?(Fake::Directory)
48
+ end
49
+
50
+ def dirname(path)
51
+ File.dirname(path)
52
+ end
53
+
54
+ def entries(path)
55
+ find_directory!(path).entry_names
56
+ end
57
+
58
+ def find(path)
59
+ if path == '/'
60
+ root
61
+ elsif dirname(path) == '.'
62
+ working_directory.find(path)
63
+ else
64
+ root.find(path)
65
+ end
66
+ end
67
+
68
+ def find!(path)
69
+ find(path) || raise(Errno::ENOENT, path)
70
+ end
71
+
72
+ def find_directory!(path)
73
+ entry = find!(path).dereferenced
74
+
75
+ raise Errno::ENOTDIR, path unless entry.is_a?(Fake::Directory)
76
+
77
+ entry
78
+ end
79
+
80
+ def find_parent!(path)
81
+ parent_path = dirname(path)
82
+ find_directory!(parent_path)
83
+ end
84
+
85
+ def getwd
86
+ working_directory.path
87
+ end
88
+ alias :pwd :getwd
89
+
90
+ def initialize
91
+ clear!
92
+ end
93
+
94
+ def link(old_name, new_name)
95
+ file = find!(old_name)
96
+
97
+ raise Errno::EEXIST, "(#{old_name}, #{new_name})" if find(new_name)
98
+
99
+ link = file.dup
100
+ link.name = basename(new_name)
101
+ find_parent!(new_name).add_entry link
102
+ end
103
+
104
+ def mkdir(path)
105
+ raise Errno::EEXIST, path if find(path)
106
+ find_parent!(path).add_entry Fake::Directory.new(path)
107
+ end
108
+
109
+ def rename(old_name, new_name)
110
+ file = find!(old_name)
111
+ file.delete
112
+
113
+ file.name = basename(new_name)
114
+ find_parent!(new_name).add_entry(file)
115
+ end
116
+
117
+ def rmdir(path)
118
+ directory = find!(path)
119
+
120
+ raise Errno::ENOTEMPTY, path unless directory.empty?
121
+
122
+ directory.delete
123
+ end
124
+
125
+ def symlink(old_name, new_name)
126
+ raise Errno::EEXIST, new_name if find(new_name)
127
+
128
+ find_parent!(new_name).add_entry Fake::Symlink.new(new_name, old_name)
129
+ end
130
+
131
+ def symlink?(path)
132
+ find(path).is_a?(Fake::Symlink)
133
+ end
134
+
135
+ def touch(*paths)
136
+ paths.each do |path|
137
+ entry = find(path)
138
+
139
+ unless entry
140
+ entry = Fake::File.new(path)
141
+ parent_dir = find_parent!(path)
142
+ parent_dir.add_entry entry
143
+ end
144
+
145
+ entry.touch
146
+ end
147
+ end
148
+
149
+ def unlink(path)
150
+ entry = find!(path)
151
+
152
+ raise Errno::EPERM, path if entry.is_a?(Fake::Directory)
153
+
154
+ entry.delete
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,7 @@
1
+ module MemFs
2
+ module FilesystemAccess
3
+ def fs
4
+ FileSystem.instance
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module MemFs
2
+ VERSION = '0.0.1'
3
+ end
data/lib/memfs.rb ADDED
@@ -0,0 +1,100 @@
1
+ require 'memfs/version'
2
+
3
+ # Provides a clean way to interact with a fake file system.
4
+ #
5
+ # @example Calling activate with a block.
6
+ # MemFs.activate do
7
+ # Dir.mkdir '/hello_world'
8
+ # # /hello_world exists here, in memory
9
+ # end
10
+ # # /hello_world doesn't exist and has never been on the real FS
11
+ #
12
+ # @example Calling activate! and deactivate!.
13
+ # MemFs.activate!
14
+ # # The fake file system is running here
15
+ # MemFs.deactivate!
16
+ # # Everything back to normal
17
+ module MemFs
18
+ extend self
19
+
20
+ # Keeps track of the original Ruby Dir class.
21
+ OriginalDir = ::Dir
22
+
23
+ # Keeps track of the original Ruby File class.
24
+ OriginalFile = ::File
25
+
26
+ require 'memfs/file_system'
27
+ require 'memfs/dir'
28
+ require 'memfs/file'
29
+ require 'memfs/file/stat'
30
+
31
+ # Calls the given block with MemFs activated.
32
+ #
33
+ # The advantage of using {#activate} against {#activate!} is that, in case an
34
+ # exception occurs, MemFs is deactivated.
35
+ #
36
+ # @yield with no argument.
37
+ #
38
+ # @example
39
+ # MemFs.activate do
40
+ # Dir.mkdir '/hello_world'
41
+ # # /hello_world exists here, in memory
42
+ # end
43
+ # # /hello_world doesn't exist and has never been on the real FS
44
+ #
45
+ # @example Exception in activate block.
46
+ # MemFs.activate do
47
+ # raise "Some Error"
48
+ # end
49
+ # # Still back to the original Ruby classes
50
+ #
51
+ # @return nothing.
52
+ def activate
53
+ activate!
54
+ yield
55
+ ensure
56
+ deactivate!
57
+ end
58
+
59
+ # Activates the fake file system.
60
+ #
61
+ # @note Don't forget to call {#deactivate!} to disable the fake file system,
62
+ # you may have some issues in your scripts or tests otherwise.
63
+ #
64
+ # @example
65
+ # MemFs.activate!
66
+ # Dir.mkdir '/hello_world'
67
+ # # /hello_world exists here, in memory
68
+ # MemFs.deactivate!
69
+ # # /hello_world doesn't exist and has never been on the real FS
70
+ #
71
+ # @see #deactivate!
72
+ # @return nothing.
73
+ def activate!
74
+ Object.class_eval do
75
+ remove_const :Dir
76
+ remove_const :File
77
+
78
+ const_set :Dir, MemFs::Dir
79
+ const_set :File, MemFs::File
80
+ end
81
+
82
+ MemFs::FileSystem.instance.clear!
83
+ end
84
+
85
+ # Deactivates the fake file system.
86
+ #
87
+ # @note This method should always be called when using activate!
88
+ #
89
+ # @see #activate!
90
+ # @return nothing.
91
+ def deactivate!
92
+ Object.class_eval do
93
+ remove_const :Dir
94
+ remove_const :File
95
+
96
+ const_set :Dir, MemFs::OriginalDir
97
+ const_set :File, MemFs::OriginalFile
98
+ end
99
+ end
100
+ end
data/memfs.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'memfs/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "memfs"
8
+ gem.version = MemFs::VERSION
9
+ gem.authors = ["Simon COURTOIS"]
10
+ gem.email = ["scourtois@cubyx.fr"]
11
+ gem.description = "MemFs provides a fake file system that can be used " \
12
+ "for tests. Strongly inspired by FakeFS."
13
+ gem.summary = "memfs-#{MemFs::VERSION}"
14
+ gem.homepage = "http://github.com/simonc/memfs"
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+ gem.add_development_dependency "coveralls", "~> 0.6"
22
+ gem.add_development_dependency "rake", "~> 10.0"
23
+ gem.add_development_dependency "rspec", "~> 2.12"
24
+ gem.add_development_dependency "guard", "~> 1.5"
25
+ gem.add_development_dependency "guard-rspec", "~> 2.1"
26
+ gem.add_development_dependency "rb-inotify", "~> 0.8"
27
+ gem.add_development_dependency "rb-fsevent", "~> 0.9"
28
+ gem.add_development_dependency "rb-fchange", "~> 0.0"
29
+ end