mnoble-fakefs 0.3.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.
- data/.autotest +5 -0
- data/.gitignore +3 -0
- data/CONTRIBUTORS +27 -0
- data/LICENSE +20 -0
- data/README.markdown +123 -0
- data/Rakefile +66 -0
- data/fakefs.gemspec +86 -0
- data/lib/fakefs.rb +3 -0
- data/lib/fakefs/base.rb +45 -0
- data/lib/fakefs/dir.rb +116 -0
- data/lib/fakefs/fake/dir.rb +48 -0
- data/lib/fakefs/fake/file.rb +81 -0
- data/lib/fakefs/fake/symlink.rb +32 -0
- data/lib/fakefs/file.rb +403 -0
- data/lib/fakefs/file_system.rb +139 -0
- data/lib/fakefs/file_test.rb +7 -0
- data/lib/fakefs/fileutils.rb +140 -0
- data/lib/fakefs/safe.rb +11 -0
- data/lib/fakefs/spec_helpers.rb +46 -0
- data/lib/fakefs/version.rb +9 -0
- data/spec/fakefs/spec_helpers_spec.rb +57 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +3 -0
- data/test/fake/file/lstat_test.rb +59 -0
- data/test/fake/file/stat_test.rb +39 -0
- data/test/fake/file/sysseek_test.rb +44 -0
- data/test/fake/file/syswrite_test.rb +62 -0
- data/test/fake/file_test.rb +97 -0
- data/test/fake/symlink_test.rb +10 -0
- data/test/fakefs_test.rb +1611 -0
- data/test/file/stat_test.rb +73 -0
- data/test/safe_test.rb +44 -0
- data/test/test_helper.rb +8 -0
- data/test/verify.rb +31 -0
- metadata +105 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module FakeFS
|
|
2
|
+
class FakeDir < Hash
|
|
3
|
+
attr_accessor :name, :parent
|
|
4
|
+
attr_reader :ctime, :mtime
|
|
5
|
+
|
|
6
|
+
def initialize(name = nil, parent = nil)
|
|
7
|
+
@name = name
|
|
8
|
+
@parent = parent
|
|
9
|
+
@ctime = Time.now
|
|
10
|
+
@mtime = @ctime
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def entry
|
|
14
|
+
self
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def inspect
|
|
18
|
+
"(FakeDir name:#{name.inspect} parent:#{parent.to_s.inspect} size:#{size})"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def clone(parent = nil)
|
|
22
|
+
clone = Marshal.load(Marshal.dump(self))
|
|
23
|
+
clone.each do |key, value|
|
|
24
|
+
value.parent = clone
|
|
25
|
+
end
|
|
26
|
+
clone.parent = parent if parent
|
|
27
|
+
clone
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def to_s
|
|
31
|
+
if parent && parent.to_s != '.'
|
|
32
|
+
File.join(parent.to_s, name)
|
|
33
|
+
elsif parent && parent.to_s == '.'
|
|
34
|
+
"#{File::PATH_SEPARATOR}#{name}"
|
|
35
|
+
else
|
|
36
|
+
name
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def delete(node = self)
|
|
41
|
+
if node == self
|
|
42
|
+
parent.delete(self)
|
|
43
|
+
else
|
|
44
|
+
super(node.name)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
module FakeFS
|
|
2
|
+
class FakeFile
|
|
3
|
+
attr_accessor :name, :parent, :content, :mtime
|
|
4
|
+
attr_reader :ctime
|
|
5
|
+
|
|
6
|
+
class Inode
|
|
7
|
+
def initialize(file_owner)
|
|
8
|
+
@content = ""
|
|
9
|
+
@links = [file_owner]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
attr_accessor :content
|
|
13
|
+
attr_accessor :links
|
|
14
|
+
|
|
15
|
+
def link(file)
|
|
16
|
+
links << file unless links.include?(file)
|
|
17
|
+
file.inode = self
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def unlink(file)
|
|
21
|
+
links.delete(file)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def clone
|
|
25
|
+
clone = super
|
|
26
|
+
clone.content = content.dup
|
|
27
|
+
clone
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def initialize(name = nil, parent = nil)
|
|
32
|
+
@name = name
|
|
33
|
+
@parent = parent
|
|
34
|
+
@inode = Inode.new(self)
|
|
35
|
+
@ctime = Time.now
|
|
36
|
+
@mtime = @ctime
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
attr_accessor :inode
|
|
40
|
+
|
|
41
|
+
def content
|
|
42
|
+
@inode.content
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def content=(str)
|
|
46
|
+
@inode.content = str
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def links
|
|
50
|
+
@inode.links
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def link(other_file)
|
|
54
|
+
@inode.link(other_file)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def clone(parent = nil)
|
|
58
|
+
clone = super()
|
|
59
|
+
clone.parent = parent if parent
|
|
60
|
+
clone.inode = inode.clone
|
|
61
|
+
clone
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def entry
|
|
65
|
+
self
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def inspect
|
|
69
|
+
"(FakeFile name:#{name.inspect} parent:#{parent.to_s.inspect} size:#{content.size})"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def to_s
|
|
73
|
+
File.join(parent.to_s, name)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def delete
|
|
77
|
+
inode.unlink(self)
|
|
78
|
+
parent.delete(self)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module FakeFS
|
|
2
|
+
class FakeSymlink
|
|
3
|
+
attr_accessor :name, :target
|
|
4
|
+
alias_method :to_s, :name
|
|
5
|
+
|
|
6
|
+
def initialize(target)
|
|
7
|
+
@target = target
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def inspect
|
|
11
|
+
"symlink(#{target.split('/').last})"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def entry
|
|
15
|
+
FileSystem.find(target)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def delete
|
|
19
|
+
parent.delete(self)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def respond_to?(method)
|
|
23
|
+
entry.respond_to?(method)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def method_missing(*args, &block)
|
|
29
|
+
entry.send(*args, &block)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
data/lib/fakefs/file.rb
ADDED
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
require 'stringio'
|
|
2
|
+
|
|
3
|
+
module FakeFS
|
|
4
|
+
class File < StringIO
|
|
5
|
+
PATH_SEPARATOR = '/'
|
|
6
|
+
|
|
7
|
+
MODES = [
|
|
8
|
+
READ_ONLY = "r",
|
|
9
|
+
READ_WRITE = "r+",
|
|
10
|
+
WRITE_ONLY = "w",
|
|
11
|
+
READ_WRITE_TRUNCATE = "w+",
|
|
12
|
+
APPEND_WRITE_ONLY = "a",
|
|
13
|
+
APPEND_READ_WRITE = "a+"
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
FILE_CREATION_MODES = MODES - [READ_ONLY, READ_WRITE]
|
|
17
|
+
|
|
18
|
+
MODE_BITMASK = RealFile::RDONLY |
|
|
19
|
+
RealFile::WRONLY |
|
|
20
|
+
RealFile::RDWR |
|
|
21
|
+
RealFile::APPEND |
|
|
22
|
+
RealFile::CREAT |
|
|
23
|
+
RealFile::EXCL |
|
|
24
|
+
RealFile::NONBLOCK |
|
|
25
|
+
RealFile::TRUNC |
|
|
26
|
+
RealFile::NOCTTY |
|
|
27
|
+
RealFile::SYNC
|
|
28
|
+
|
|
29
|
+
FILE_CREATION_BITMASK = RealFile::CREAT
|
|
30
|
+
|
|
31
|
+
def self.extname(path)
|
|
32
|
+
RealFile.extname(path)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.join(*parts)
|
|
36
|
+
RealFile.join(parts)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.exist?(path)
|
|
40
|
+
!!FileSystem.find(path)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class << self
|
|
44
|
+
alias_method :exists?, :exist?
|
|
45
|
+
|
|
46
|
+
# Assuming that everyone can read and write files
|
|
47
|
+
alias_method :readable?, :exist?
|
|
48
|
+
alias_method :writable?, :exist?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.mtime(path)
|
|
52
|
+
if exists?(path)
|
|
53
|
+
FileSystem.find(path).mtime
|
|
54
|
+
else
|
|
55
|
+
raise Errno::ENOENT
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def self.ctime(path)
|
|
60
|
+
if exists?(path)
|
|
61
|
+
FileSystem.find(path).ctime
|
|
62
|
+
else
|
|
63
|
+
raise Errno::ENOENT
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def self.utime(atime, mtime, *paths)
|
|
68
|
+
paths.each do |path|
|
|
69
|
+
if exists?(path)
|
|
70
|
+
FileSystem.find(path).mtime = mtime
|
|
71
|
+
else
|
|
72
|
+
raise Errno::ENOENT
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
paths.size
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def self.size(path)
|
|
80
|
+
read(path).length
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def self.size?(path)
|
|
84
|
+
if exists?(path) && !size(path).zero?
|
|
85
|
+
true
|
|
86
|
+
else
|
|
87
|
+
nil
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def self.const_missing(name)
|
|
92
|
+
RealFile.const_get(name)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def self.directory?(path)
|
|
96
|
+
if path.respond_to? :entry
|
|
97
|
+
path.entry.is_a? FakeDir
|
|
98
|
+
else
|
|
99
|
+
result = FileSystem.find(path)
|
|
100
|
+
result ? result.entry.is_a?(FakeDir) : false
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def self.symlink?(path)
|
|
105
|
+
if path.respond_to? :entry
|
|
106
|
+
path.is_a? FakeSymlink
|
|
107
|
+
else
|
|
108
|
+
FileSystem.find(path).is_a? FakeSymlink
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def self.file?(path)
|
|
113
|
+
if path.respond_to? :entry
|
|
114
|
+
path.entry.is_a? FakeFile
|
|
115
|
+
else
|
|
116
|
+
result = FileSystem.find(path)
|
|
117
|
+
result ? result.entry.is_a?(FakeFile) : false
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def self.expand_path(*args)
|
|
122
|
+
RealFile.expand_path(*args)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def self.basename(*args)
|
|
126
|
+
RealFile.basename(*args)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def self.dirname(path)
|
|
130
|
+
RealFile.dirname(path)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def self.readlink(path)
|
|
134
|
+
symlink = FileSystem.find(path)
|
|
135
|
+
FileSystem.find(symlink.target).to_s
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def self.read(path)
|
|
139
|
+
file = new(path)
|
|
140
|
+
if file.exists?
|
|
141
|
+
file.read
|
|
142
|
+
else
|
|
143
|
+
raise Errno::ENOENT
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def self.readlines(path)
|
|
148
|
+
read(path).split("\n")
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def self.rename(source, dest)
|
|
152
|
+
if directory?(source) && file?(dest)
|
|
153
|
+
raise Errno::ENOTDIR, "Not a directory - #{source} or #{dest}"
|
|
154
|
+
elsif file?(source) && directory?(dest)
|
|
155
|
+
raise Errno::EISDIR, "Is a directory - #{source} or #{dest}"
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
if target = FileSystem.find(source)
|
|
159
|
+
FileSystem.add(dest, target.entry.clone)
|
|
160
|
+
FileSystem.delete(source)
|
|
161
|
+
else
|
|
162
|
+
raise Errno::ENOENT, "No such file or directory - #{source} or #{dest}"
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
0
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def self.link(source, dest)
|
|
169
|
+
if directory?(source)
|
|
170
|
+
raise Errno::EPERM, "Operation not permitted - #{source} or #{dest}"
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
if !exists?(source)
|
|
174
|
+
raise Errno::ENOENT, "No such file or directory - #{source} or #{dest}"
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
if exists?(dest)
|
|
178
|
+
raise Errno::EEXIST, "File exists - #{source} or #{dest}"
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
source = FileSystem.find(source)
|
|
182
|
+
dest = FileSystem.add(dest, source.entry.clone)
|
|
183
|
+
source.link(dest)
|
|
184
|
+
|
|
185
|
+
0
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def self.delete(file_name, *additional_file_names)
|
|
189
|
+
if !exists?(file_name)
|
|
190
|
+
raise Errno::ENOENT, "No such file or directory - #{file_name}"
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
FileUtils.rm(file_name)
|
|
194
|
+
|
|
195
|
+
additional_file_names.each do |file_name|
|
|
196
|
+
FileUtils.rm(file_name)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
additional_file_names.size + 1
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
class << self
|
|
203
|
+
alias_method :unlink, :delete
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def self.symlink(source, dest)
|
|
207
|
+
FileUtils.ln_s(source, dest)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def self.stat(file)
|
|
211
|
+
File::Stat.new(file)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def self.lstat(file)
|
|
215
|
+
File::Stat.new(file, true)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
class Stat
|
|
219
|
+
attr_reader :ctime, :mtime
|
|
220
|
+
|
|
221
|
+
def initialize(file, __lstat = false)
|
|
222
|
+
if !File.exists?(file)
|
|
223
|
+
raise(Errno::ENOENT, "No such file or directory - #{file}")
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
@file = file
|
|
227
|
+
@fake_file = FileSystem.find(@file)
|
|
228
|
+
@__lstat = __lstat
|
|
229
|
+
@ctime = @fake_file.ctime
|
|
230
|
+
@mtime = @fake_file.mtime
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def symlink?
|
|
234
|
+
File.symlink?(@file)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def directory?
|
|
238
|
+
File.directory?(@file)
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def nlink
|
|
242
|
+
@fake_file.links.size
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def size
|
|
246
|
+
if @__lstat && symlink?
|
|
247
|
+
@fake_file.target.size
|
|
248
|
+
else
|
|
249
|
+
File.size(@file)
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
attr_reader :path
|
|
255
|
+
|
|
256
|
+
def initialize(path, mode = READ_ONLY, perm = nil)
|
|
257
|
+
@path = path
|
|
258
|
+
@mode = mode
|
|
259
|
+
@file = FileSystem.find(path)
|
|
260
|
+
@autoclose = true
|
|
261
|
+
|
|
262
|
+
check_modes!
|
|
263
|
+
|
|
264
|
+
file_creation_mode? ? create_missing_file : check_file_existence!
|
|
265
|
+
|
|
266
|
+
super(@file.content, mode)
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def exists?
|
|
270
|
+
true
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
alias_method :tell=, :pos=
|
|
274
|
+
alias_method :sysread, :read
|
|
275
|
+
alias_method :syswrite, :write
|
|
276
|
+
|
|
277
|
+
undef_method :closed_read?
|
|
278
|
+
undef_method :closed_write?
|
|
279
|
+
undef_method :length
|
|
280
|
+
undef_method :size
|
|
281
|
+
undef_method :string
|
|
282
|
+
undef_method :string=
|
|
283
|
+
|
|
284
|
+
def ioctl(integer_cmd, arg)
|
|
285
|
+
raise NotImplementedError
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
def read_nonblock(maxlen, outbuf = nil)
|
|
289
|
+
raise NotImplementedError
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def stat
|
|
293
|
+
self.class.stat(@path)
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
def lstat
|
|
297
|
+
self.class.lstat(@path)
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def sysseek(position, whence = SEEK_SET)
|
|
301
|
+
seek(position, whence)
|
|
302
|
+
pos
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
alias_method :to_i, :fileno
|
|
306
|
+
|
|
307
|
+
def to_io
|
|
308
|
+
self
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def write_nonblock(string)
|
|
312
|
+
raise NotImplementedError
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
def readpartial(maxlen, outbuf = nil)
|
|
316
|
+
raise NotImplementedError
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
def atime
|
|
320
|
+
raise NotImplementedError
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
def chmod(mode_int)
|
|
324
|
+
raise NotImplementedError
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
def chown(owner_int, group_int)
|
|
328
|
+
raise NotImplementedError
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
def ctime
|
|
332
|
+
self.class.ctime(@path)
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
def flock(locking_constant)
|
|
336
|
+
raise NotImplementedError
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
def mtime
|
|
340
|
+
self.class.mtime(@path)
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
if RUBY_VERSION >= "1.9"
|
|
344
|
+
def binmode?
|
|
345
|
+
raise NotImplementedError
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
def close_on_exec=(bool)
|
|
349
|
+
raise NotImplementedError
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def close_on_exec?
|
|
353
|
+
raise NotImplementedError
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
def to_path
|
|
357
|
+
raise NotImplementedError
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
if RUBY_VERSION >= "1.9.2"
|
|
362
|
+
attr_writer :autoclose
|
|
363
|
+
|
|
364
|
+
def autoclose?
|
|
365
|
+
@autoclose
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
alias_method :fdatasync, :flush
|
|
369
|
+
|
|
370
|
+
def size
|
|
371
|
+
File.size(@path)
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
private
|
|
376
|
+
|
|
377
|
+
def check_modes!
|
|
378
|
+
StringIO.new("", @mode)
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
def check_file_existence!
|
|
382
|
+
raise Errno::ENOENT, @path unless @file
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
def file_creation_mode?
|
|
386
|
+
mode_in?(FILE_CREATION_MODES) || mode_in_bitmask?(FILE_CREATION_BITMASK)
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
def mode_in?(list)
|
|
390
|
+
list.any? { |element| @mode.include?(element) } if @mode.respond_to?(:include?)
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
def mode_in_bitmask?(mask)
|
|
394
|
+
(@mode & mask) != 0 if @mode.is_a?(Integer)
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
def create_missing_file
|
|
398
|
+
if !File.exists?(@path)
|
|
399
|
+
@file = FileSystem.add(path, FakeFile.new)
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
end
|