ktheory-fakefs 0.2.1.1

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