fakefs 0.5.4 → 0.6.0
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +50 -0
- data/.travis.yml +0 -1
- data/Rakefile +16 -9
- data/fakefs.gemspec +1 -0
- data/lib/fakefs/base.rb +6 -5
- data/lib/fakefs/dir.rb +55 -45
- data/lib/fakefs/fake/dir.rb +5 -3
- data/lib/fakefs/fake/file.rb +9 -4
- data/lib/fakefs/fake/symlink.rb +2 -1
- data/lib/fakefs/file.rb +98 -103
- data/lib/fakefs/file_system.rb +50 -33
- data/lib/fakefs/file_test.rb +1 -0
- data/lib/fakefs/fileutils.rb +72 -71
- data/lib/fakefs/kernel.rb +8 -7
- data/lib/fakefs/pathname.rb +356 -202
- data/lib/fakefs/safe.rb +1 -1
- data/lib/fakefs/spec_helpers.rb +19 -11
- data/lib/fakefs/version.rb +2 -1
- data/spec/fakefs/fakefs_bug_ruby_2.1.0-preview2_spec.rb +2 -2
- data/spec/fakefs/spec_helpers_spec.rb +24 -23
- data/test/dir/tempfile_test.rb +1 -0
- data/test/fake/file/join_test.rb +4 -3
- data/test/fake/file/lstat_test.rb +22 -21
- data/test/fake/file/stat_test.rb +12 -11
- data/test/fake/file/sysseek_test.rb +15 -14
- data/test/fake/file/syswrite_test.rb +25 -24
- data/test/fake/file_test.rb +12 -11
- data/test/fake/symlink_test.rb +18 -10
- data/test/fakefs_test.rb +543 -542
- data/test/file/stat_test.rb +45 -41
- data/test/kernel_test.rb +5 -8
- data/test/safe_test.rb +9 -7
- data/test/test_helper.rb +2 -1
- data/test/verify.rb +6 -3
- metadata +28 -14
data/lib/fakefs/fake/file.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
module FakeFS
|
2
|
+
# Fake file class
|
2
3
|
class FakeFile
|
3
4
|
attr_accessor :name, :parent, :content, :mtime, :atime, :mode, :uid, :gid
|
4
5
|
attr_reader :ctime
|
5
6
|
|
7
|
+
# Inode class
|
6
8
|
class Inode
|
7
9
|
def initialize(file_owner)
|
8
|
-
#1.9.3 when possible set default external encoding
|
9
|
-
@content =
|
10
|
+
# 1.9.3 when possible set default external encoding
|
11
|
+
@content = ''
|
12
|
+
@content = ''.encode(
|
13
|
+
Encoding.default_external) if ''.respond_to?(:encode)
|
10
14
|
@links = [file_owner]
|
11
15
|
end
|
12
16
|
|
@@ -38,7 +42,7 @@ module FakeFS
|
|
38
42
|
@atime = @ctime
|
39
43
|
@mode = 0100000 + (0666 - File.umask)
|
40
44
|
@uid = Process.uid
|
41
|
-
@gid = Process.gid
|
45
|
+
@gid = Process.gid
|
42
46
|
end
|
43
47
|
|
44
48
|
attr_accessor :inode
|
@@ -71,7 +75,8 @@ module FakeFS
|
|
71
75
|
end
|
72
76
|
|
73
77
|
def inspect
|
74
|
-
"(FakeFile name:#{name.inspect}
|
78
|
+
"(FakeFile name:#{name.inspect} " \
|
79
|
+
"parent:#{parent.to_s.inspect} size:#{content.size})"
|
75
80
|
end
|
76
81
|
|
77
82
|
def to_s
|
data/lib/fakefs/fake/symlink.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
module FakeFS
|
2
|
+
# Fake symlink class
|
2
3
|
class FakeSymlink
|
3
4
|
attr_accessor :name, :target, :parent
|
4
5
|
|
@@ -26,7 +27,7 @@ module FakeFS
|
|
26
27
|
entry.respond_to?(method, include_private)
|
27
28
|
end
|
28
29
|
|
29
|
-
|
30
|
+
private
|
30
31
|
|
31
32
|
def method_missing(*args, &block)
|
32
33
|
entry.send(*args, &block)
|
data/lib/fakefs/file.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
require 'stringio'
|
2
2
|
|
3
3
|
module FakeFS
|
4
|
+
# FakeFS File class inherit StringIO
|
4
5
|
class File < StringIO
|
5
6
|
MODES = [
|
6
|
-
READ_ONLY =
|
7
|
-
READ_WRITE =
|
8
|
-
WRITE_ONLY =
|
9
|
-
READ_WRITE_TRUNCATE =
|
10
|
-
APPEND_WRITE_ONLY =
|
11
|
-
APPEND_READ_WRITE =
|
7
|
+
READ_ONLY = 'r',
|
8
|
+
READ_WRITE = 'r+',
|
9
|
+
WRITE_ONLY = 'w',
|
10
|
+
READ_WRITE_TRUNCATE = 'w+',
|
11
|
+
APPEND_WRITE_ONLY = 'a',
|
12
|
+
APPEND_READ_WRITE = 'a+'
|
12
13
|
]
|
13
14
|
|
14
15
|
FILE_CREATION_MODES = MODES - [READ_ONLY, READ_WRITE]
|
@@ -26,7 +27,6 @@ module FakeFS
|
|
26
27
|
|
27
28
|
FILE_CREATION_BITMASK = RealFile::CREAT
|
28
29
|
|
29
|
-
|
30
30
|
def self.extname(path)
|
31
31
|
RealFile.extname(path)
|
32
32
|
end
|
@@ -36,11 +36,11 @@ module FakeFS
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def self.exist?(path)
|
39
|
-
if
|
39
|
+
if File.symlink?(path)
|
40
40
|
referent = File.expand_path(File.readlink(path), File.dirname(path))
|
41
41
|
exist?(referent)
|
42
42
|
else
|
43
|
-
|
43
|
+
!FileSystem.find(path).nil?
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -50,13 +50,18 @@ module FakeFS
|
|
50
50
|
# Assuming that everyone can read and write files
|
51
51
|
alias_method :readable?, :exist?
|
52
52
|
alias_method :writable?, :exist?
|
53
|
+
|
54
|
+
# Assume nothing is sticky.
|
55
|
+
def sticky?(_path)
|
56
|
+
false
|
57
|
+
end
|
53
58
|
end
|
54
59
|
|
55
60
|
def self.mtime(path)
|
56
61
|
if exists?(path)
|
57
62
|
FileSystem.find(path).mtime
|
58
63
|
else
|
59
|
-
|
64
|
+
fail Errno::ENOENT
|
60
65
|
end
|
61
66
|
end
|
62
67
|
|
@@ -64,7 +69,7 @@ module FakeFS
|
|
64
69
|
if exists?(path)
|
65
70
|
FileSystem.find(path).ctime
|
66
71
|
else
|
67
|
-
|
72
|
+
fail Errno::ENOENT
|
68
73
|
end
|
69
74
|
end
|
70
75
|
|
@@ -72,7 +77,7 @@ module FakeFS
|
|
72
77
|
if exists?(path)
|
73
78
|
FileSystem.find(path).atime
|
74
79
|
else
|
75
|
-
|
80
|
+
fail Errno::ENOENT
|
76
81
|
end
|
77
82
|
end
|
78
83
|
|
@@ -82,7 +87,7 @@ module FakeFS
|
|
82
87
|
FileSystem.find(path).atime = atime
|
83
88
|
FileSystem.find(path).mtime = mtime
|
84
89
|
else
|
85
|
-
|
90
|
+
fail Errno::ENOENT
|
86
91
|
end
|
87
92
|
end
|
88
93
|
|
@@ -135,7 +140,7 @@ module FakeFS
|
|
135
140
|
end
|
136
141
|
end
|
137
142
|
|
138
|
-
def self.expand_path(file_name, dir_string=FileSystem.current_dir.to_s)
|
143
|
+
def self.expand_path(file_name, dir_string = FileSystem.current_dir.to_s)
|
139
144
|
RealFile.expand_path(file_name, RealFile.expand_path(dir_string, Dir.pwd))
|
140
145
|
end
|
141
146
|
|
@@ -158,8 +163,8 @@ module FakeFS
|
|
158
163
|
offset = args.size > 0 ? args.shift : 0
|
159
164
|
file = new(path, options)
|
160
165
|
|
161
|
-
|
162
|
-
|
166
|
+
fail Errno::ENOENT unless file.exists?
|
167
|
+
fail Errno::EISDIR, path if directory?(path)
|
163
168
|
|
164
169
|
FileSystem.find(path).atime = Time.now
|
165
170
|
file.seek(offset)
|
@@ -172,41 +177,33 @@ module FakeFS
|
|
172
177
|
FileSystem.find(path).atime = Time.now
|
173
178
|
file.readlines
|
174
179
|
else
|
175
|
-
|
180
|
+
fail Errno::ENOENT
|
176
181
|
end
|
177
182
|
end
|
178
183
|
|
179
184
|
def self.rename(source, dest)
|
180
185
|
if directory?(source) && file?(dest)
|
181
|
-
|
186
|
+
fail Errno::ENOTDIR, "#{source} or #{dest}"
|
182
187
|
elsif file?(source) && directory?(dest)
|
183
|
-
|
188
|
+
fail Errno::EISDIR, "#{source} or #{dest}"
|
184
189
|
elsif !exist?(dirname(dest))
|
185
|
-
|
190
|
+
fail Errno::ENOENT, "#{source} or #{dest}"
|
186
191
|
end
|
187
192
|
|
188
|
-
if target = FileSystem.find(source)
|
193
|
+
if (target = FileSystem.find(source))
|
189
194
|
FileSystem.add(dest, target.entry.clone)
|
190
195
|
FileSystem.delete(source)
|
191
196
|
else
|
192
|
-
|
197
|
+
fail Errno::ENOENT, "#{source} or #{dest}"
|
193
198
|
end
|
194
199
|
|
195
200
|
0
|
196
201
|
end
|
197
202
|
|
198
203
|
def self.link(source, dest)
|
199
|
-
if directory?(source)
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
if !exists?(source)
|
204
|
-
raise Errno::ENOENT, "#{source} or #{dest}"
|
205
|
-
end
|
206
|
-
|
207
|
-
if exists?(dest)
|
208
|
-
raise Errno::EEXIST, "#{source} or #{dest}"
|
209
|
-
end
|
204
|
+
fail Errno::EPERM, "#{source} or #{dest}" if directory?(source)
|
205
|
+
fail Errno::ENOENT, "#{source} or #{dest}" unless exists?(source)
|
206
|
+
fail Errno::EEXIST, "#{source} or #{dest}" if exists?(dest)
|
210
207
|
|
211
208
|
source = FileSystem.find(source)
|
212
209
|
dest = FileSystem.add(dest, source.entry.clone)
|
@@ -217,9 +214,7 @@ module FakeFS
|
|
217
214
|
|
218
215
|
def self.delete(*file_names)
|
219
216
|
file_names.each do |file_name|
|
220
|
-
|
221
|
-
raise Errno::ENOENT, file_name
|
222
|
-
end
|
217
|
+
fail Errno::ENOENT, file_name unless exists?(file_name)
|
223
218
|
|
224
219
|
FileUtils.rm(file_name)
|
225
220
|
end
|
@@ -244,7 +239,7 @@ module FakeFS
|
|
244
239
|
end
|
245
240
|
|
246
241
|
def self.split(path)
|
247
|
-
|
242
|
+
RealFile.split(path)
|
248
243
|
end
|
249
244
|
|
250
245
|
def self.chmod(mode_int, filename)
|
@@ -262,11 +257,13 @@ module FakeFS
|
|
262
257
|
def self.chown(owner_int, group_int, filename)
|
263
258
|
file = FileSystem.find(filename)
|
264
259
|
if owner_int && owner_int != -1
|
265
|
-
owner_int.is_a?(Fixnum)
|
260
|
+
owner_int.is_a?(Fixnum) || fail(TypeError,
|
261
|
+
"can't convert String into Integer")
|
266
262
|
file.uid = owner_int
|
267
263
|
end
|
268
264
|
if group_int && group_int != -1
|
269
|
-
group_int.is_a?(Fixnum)
|
265
|
+
group_int.is_a?(Fixnum) || fail(TypeError,
|
266
|
+
"can't convert String into Integer")
|
270
267
|
file.gid = group_int
|
271
268
|
end
|
272
269
|
end
|
@@ -276,20 +273,19 @@ module FakeFS
|
|
276
273
|
end
|
277
274
|
|
278
275
|
def self.binread(file, length = nil, offset = 0)
|
279
|
-
|
276
|
+
File.read(file, length, offset, mode: 'rb:ASCII-8BIT')
|
280
277
|
end
|
281
278
|
|
279
|
+
# FakeFS Stat class
|
282
280
|
class Stat
|
283
281
|
attr_reader :ctime, :mtime, :atime, :mode, :uid, :gid
|
284
282
|
|
285
|
-
def initialize(file,
|
286
|
-
|
287
|
-
raise Errno::ENOENT, file
|
288
|
-
end
|
283
|
+
def initialize(file, lstat = false)
|
284
|
+
fail(Errno::ENOENT, file) unless File.exist?(file)
|
289
285
|
|
290
286
|
@file = file
|
291
287
|
@fake_file = FileSystem.find(@file)
|
292
|
-
@__lstat =
|
288
|
+
@__lstat = lstat
|
293
289
|
@ctime = @fake_file.ctime
|
294
290
|
@mtime = @fake_file.mtime
|
295
291
|
@atime = @fake_file.atime
|
@@ -313,10 +309,10 @@ module FakeFS
|
|
313
309
|
def ftype
|
314
310
|
return 'link' if symlink?
|
315
311
|
return 'directory' if directory?
|
316
|
-
|
312
|
+
'file'
|
317
313
|
end
|
318
314
|
|
319
|
-
# assumes, like above, that all files are readable and writable
|
315
|
+
# assumes, like above, that all files are readable and writable.
|
320
316
|
def readable?
|
321
317
|
true
|
322
318
|
end
|
@@ -325,6 +321,11 @@ module FakeFS
|
|
325
321
|
true
|
326
322
|
end
|
327
323
|
|
324
|
+
# Assume nothing is sticky.
|
325
|
+
def sticky?
|
326
|
+
false
|
327
|
+
end
|
328
|
+
|
328
329
|
# World_writable and readable are platform dependent
|
329
330
|
# usually comparing with S_IROTH defined on compilation (MRI)
|
330
331
|
def world_writable?
|
@@ -360,7 +361,7 @@ module FakeFS
|
|
360
361
|
|
361
362
|
attr_reader :path
|
362
363
|
|
363
|
-
def initialize(path, mode = READ_ONLY,
|
364
|
+
def initialize(path, mode = READ_ONLY, _perm = nil)
|
364
365
|
@path = path
|
365
366
|
@mode = mode.is_a?(Hash) ? (mode[:mode] || READ_ONLY) : mode
|
366
367
|
@file = FileSystem.find(path)
|
@@ -403,12 +404,12 @@ module FakeFS
|
|
403
404
|
RealFile.allocate.is_a?(klass)
|
404
405
|
end
|
405
406
|
|
406
|
-
def ioctl(
|
407
|
-
|
407
|
+
def ioctl(*)
|
408
|
+
fail NotImplementedError
|
408
409
|
end
|
409
410
|
|
410
|
-
def read_nonblock
|
411
|
-
|
411
|
+
def read_nonblock
|
412
|
+
fail NotImplementedError
|
412
413
|
end
|
413
414
|
|
414
415
|
def stat
|
@@ -430,12 +431,12 @@ module FakeFS
|
|
430
431
|
self
|
431
432
|
end
|
432
433
|
|
433
|
-
def write_nonblock(
|
434
|
-
|
434
|
+
def write_nonblock(*)
|
435
|
+
fail NotImplementedError
|
435
436
|
end
|
436
437
|
|
437
|
-
def readpartial(
|
438
|
-
|
438
|
+
def readpartial(*)
|
439
|
+
fail NotImplementedError
|
439
440
|
end
|
440
441
|
|
441
442
|
def atime
|
@@ -446,8 +447,8 @@ module FakeFS
|
|
446
447
|
self.class.ctime(@path)
|
447
448
|
end
|
448
449
|
|
449
|
-
def flock(
|
450
|
-
|
450
|
+
def flock(*)
|
451
|
+
fail NotImplementedError
|
451
452
|
end
|
452
453
|
|
453
454
|
def mtime
|
@@ -459,31 +460,32 @@ module FakeFS
|
|
459
460
|
end
|
460
461
|
|
461
462
|
def chown(owner_int, group_int)
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
463
|
+
return unless group_int && group_int != -1
|
464
|
+
|
465
|
+
owner_int.is_a?(Fixnum) || fail(
|
466
|
+
TypeError, "can't convert String into Integer")
|
467
|
+
@file.uid = owner_int
|
468
|
+
|
469
|
+
group_int.is_a?(Fixnum) || fail(
|
470
|
+
TypeError, "can't convert String into Integer")
|
471
|
+
@file.gid = group_int
|
470
472
|
end
|
471
473
|
|
472
|
-
if RUBY_VERSION >=
|
474
|
+
if RUBY_VERSION >= '1.9'
|
473
475
|
def self.realpath(*args)
|
474
476
|
RealFile.realpath(*args)
|
475
477
|
end
|
476
478
|
|
477
479
|
def binmode?
|
478
|
-
|
480
|
+
fail NotImplementedError
|
479
481
|
end
|
480
482
|
|
481
|
-
def close_on_exec=(
|
482
|
-
|
483
|
+
def close_on_exec=(_bool)
|
484
|
+
fail NotImplementedError
|
483
485
|
end
|
484
486
|
|
485
487
|
def close_on_exec?
|
486
|
-
|
488
|
+
fail NotImplementedError
|
487
489
|
end
|
488
490
|
|
489
491
|
def to_path
|
@@ -491,27 +493,19 @@ module FakeFS
|
|
491
493
|
end
|
492
494
|
end
|
493
495
|
|
494
|
-
if RUBY_VERSION >=
|
496
|
+
if RUBY_VERSION >= '1.9.1'
|
495
497
|
def self.absolute_path(file_name, dir_name = Dir.getwd)
|
496
498
|
RealFile.absolute_path(file_name, dir_name)
|
497
499
|
end
|
498
500
|
end
|
499
501
|
|
500
|
-
if RUBY_VERSION >=
|
501
|
-
|
502
|
-
|
503
|
-
def autoclose?
|
504
|
-
@autoclose
|
505
|
-
end
|
502
|
+
if RUBY_VERSION >= '1.9.2'
|
503
|
+
attr_accessor :autoclose
|
506
504
|
|
507
505
|
def autoclose?
|
508
506
|
@autoclose ? true : false
|
509
507
|
end
|
510
508
|
|
511
|
-
def autoclose=(autoclose)
|
512
|
-
@autoclose = autoclose
|
513
|
-
end
|
514
|
-
|
515
509
|
alias_method :fdatasync, :flush
|
516
510
|
|
517
511
|
def size
|
@@ -519,8 +513,8 @@ module FakeFS
|
|
519
513
|
end
|
520
514
|
end
|
521
515
|
|
522
|
-
if RUBY_VERSION >=
|
523
|
-
def advise(
|
516
|
+
if RUBY_VERSION >= '1.9.3'
|
517
|
+
def advise(_advice, _offset = 0, _len = 0)
|
524
518
|
end
|
525
519
|
|
526
520
|
def self.write(filename, contents, offset = nil)
|
@@ -539,27 +533,29 @@ module FakeFS
|
|
539
533
|
end
|
540
534
|
end
|
541
535
|
|
542
|
-
def read(length = nil, buf =
|
536
|
+
def read(length = nil, buf = '')
|
543
537
|
read_buf = super(length, buf)
|
544
|
-
|
538
|
+
# change to binary only for ruby 1.9.3
|
539
|
+
if read_buf.respond_to?(:force_encoding) && binary_mode?
|
545
540
|
read_buf = read_buf.force_encoding('ASCII-8BIT')
|
546
541
|
end
|
547
542
|
read_buf
|
548
543
|
end
|
549
544
|
|
550
|
-
|
551
|
-
private
|
545
|
+
private
|
552
546
|
|
553
547
|
def check_modes!
|
554
|
-
StringIO.new(
|
548
|
+
StringIO.new('', @mode)
|
555
549
|
end
|
556
550
|
|
557
551
|
def binary_mode?
|
558
|
-
@mode.is_a?(String) && (@mode.include?('b') ||
|
552
|
+
@mode.is_a?(String) && (@mode.include?('b') ||
|
553
|
+
@mode.include?('binary')) &&
|
554
|
+
!@mode.include?('bom')
|
559
555
|
end
|
560
556
|
|
561
557
|
def check_file_existence!
|
562
|
-
|
558
|
+
fail Errno::ENOENT, @path unless @file
|
563
559
|
end
|
564
560
|
|
565
561
|
def file_creation_mode?
|
@@ -567,7 +563,9 @@ module FakeFS
|
|
567
563
|
end
|
568
564
|
|
569
565
|
def mode_in?(list)
|
570
|
-
list.any?
|
566
|
+
list.any? do |element|
|
567
|
+
@mode.include?(element)
|
568
|
+
end if @mode.respond_to?(:include?)
|
571
569
|
end
|
572
570
|
|
573
571
|
def mode_in_bitmask?(mask)
|
@@ -577,21 +575,18 @@ module FakeFS
|
|
577
575
|
# Create a missing file if the path is valid.
|
578
576
|
#
|
579
577
|
def create_missing_file
|
580
|
-
|
578
|
+
fail Errno::EISDIR, path if File.directory?(@path)
|
581
579
|
|
582
|
-
if
|
583
|
-
|
580
|
+
return if File.exist?(@path) # Unnecessary check, probably.
|
581
|
+
dirname = RealFile.dirname @path
|
584
582
|
|
585
|
-
|
586
|
-
|
583
|
+
unless dirname == '.'
|
584
|
+
dir = FileSystem.find dirname
|
587
585
|
|
588
|
-
|
589
|
-
raise Errno::ENOENT, path
|
590
|
-
end
|
591
|
-
end
|
592
|
-
|
593
|
-
@file = FileSystem.add(path, FakeFile.new)
|
586
|
+
fail Errno::ENOENT, path unless dir.is_a? FakeDir
|
594
587
|
end
|
588
|
+
|
589
|
+
@file = FileSystem.add(path, FakeFile.new)
|
595
590
|
end
|
596
591
|
end
|
597
592
|
end
|