fakefs 0.5.4 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|