memfs 1.0.0 → 2.0.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 +5 -5
- data/.github/dependabot.yml +19 -0
- data/.github/workflows/ci.yml +64 -0
- data/.rspec +1 -1
- data/.rubocop.yml +98 -0
- data/CHANGELOG.md +30 -10
- data/Gemfile +19 -0
- data/Guardfile +5 -3
- data/README.md +3 -3
- data/Rakefile +4 -2
- data/bin/_guard-core +16 -0
- data/bin/coverage_summary +51 -0
- data/bin/guard +16 -0
- data/bin/rake +16 -0
- data/bin/rspec +16 -0
- data/bin/rubocop +16 -0
- data/lib/memfs/dir.rb +82 -17
- data/lib/memfs/fake/directory.rb +31 -6
- data/lib/memfs/fake/entry.rb +41 -25
- data/lib/memfs/fake/file/content.rb +6 -3
- data/lib/memfs/fake/file.rb +2 -0
- data/lib/memfs/fake/symlink.rb +2 -0
- data/lib/memfs/file/stat.rb +20 -13
- data/lib/memfs/file.rb +74 -66
- data/lib/memfs/file_system.rb +14 -9
- data/lib/memfs/filesystem_access.rb +2 -0
- data/lib/memfs/io.rb +48 -54
- data/lib/memfs/version.rb +3 -1
- data/lib/memfs.rb +83 -3
- data/memfs.gemspec +0 -17
- data/spec/fileutils_spec.rb +64 -41
- data/spec/memfs/dir_spec.rb +155 -18
- data/spec/memfs/fake/directory_spec.rb +3 -3
- data/spec/memfs/fake/entry_spec.rb +11 -5
- data/spec/memfs/fake/symlink_spec.rb +1 -1
- data/spec/memfs/file/stat_spec.rb +27 -15
- data/spec/memfs/file_spec.rb +135 -51
- data/spec/memfs/file_system_spec.rb +15 -15
- data/spec/memfs_spec.rb +29 -1
- data/spec/spec_helper.rb +19 -4
- metadata +17 -151
- data/.hound.yml +0 -2
- data/.rubocop.yml +0 -1
- data/.ruby-style.yml +0 -335
- data/.travis.yml +0 -9
|
@@ -3,16 +3,16 @@ require 'spec_helper'
|
|
|
3
3
|
module MemFs
|
|
4
4
|
::RSpec.describe File::Stat do
|
|
5
5
|
let(:file_stat) { described_class.new('/test-file') }
|
|
6
|
-
let(:dereferenced_file_stat) { described_class.new('/test-file', true) }
|
|
6
|
+
let(:dereferenced_file_stat) { described_class.new('/test-file', dereference: true) }
|
|
7
7
|
|
|
8
8
|
let(:dir_link_stat) { described_class.new('/test-dir-link') }
|
|
9
|
-
let(:dereferenced_dir_link_stat) { described_class.new('/test-dir-link', true) }
|
|
9
|
+
let(:dereferenced_dir_link_stat) { described_class.new('/test-dir-link', dereference: true) }
|
|
10
10
|
|
|
11
11
|
let(:link_stat) { described_class.new('/test-link') }
|
|
12
|
-
let(:dereferenced_link_stat) { described_class.new('/test-link', true) }
|
|
12
|
+
let(:dereferenced_link_stat) { described_class.new('/test-link', dereference: true) }
|
|
13
13
|
|
|
14
14
|
let(:dir_stat) { described_class.new('/test-dir') }
|
|
15
|
-
let(:dereferenced_dir_stat) { described_class.new('/test-dir', true) }
|
|
15
|
+
let(:dereferenced_dir_stat) { described_class.new('/test-dir', dereference: true) }
|
|
16
16
|
|
|
17
17
|
let(:entry) { _fs.find!('/test-file') }
|
|
18
18
|
|
|
@@ -29,7 +29,7 @@ module MemFs
|
|
|
29
29
|
context 'when the last target of the link chain does not exist' do
|
|
30
30
|
it 'raises an exception' do
|
|
31
31
|
expect {
|
|
32
|
-
described_class.new('/test-no-file-link', true)
|
|
32
|
+
described_class.new('/test-no-file-link', dereference: true)
|
|
33
33
|
}.to raise_error(Errno::ENOENT)
|
|
34
34
|
end
|
|
35
35
|
end
|
|
@@ -373,6 +373,18 @@ module MemFs
|
|
|
373
373
|
end
|
|
374
374
|
end
|
|
375
375
|
|
|
376
|
+
describe '#nlink' do
|
|
377
|
+
context 'when the entry is a regular file' do
|
|
378
|
+
it "returns expected nlinks for a file" do
|
|
379
|
+
expect(file_stat.nlink).to eq(1)
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
it "returns expected nlinks for a directory" do
|
|
383
|
+
expect(dir_stat.nlink).to eq(2)
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
|
|
376
388
|
describe '#ftype' do
|
|
377
389
|
context 'when the entry is a regular file' do
|
|
378
390
|
it "returns 'file'" do
|
|
@@ -441,7 +453,7 @@ module MemFs
|
|
|
441
453
|
|
|
442
454
|
context 'when the effective user group does not own of the file' do
|
|
443
455
|
it 'returns false' do
|
|
444
|
-
_fs.chown(
|
|
456
|
+
_fs.chown(9999, 9999, '/test-file')
|
|
445
457
|
expect(file_stat.grpowned?).to be false
|
|
446
458
|
end
|
|
447
459
|
end
|
|
@@ -455,8 +467,8 @@ module MemFs
|
|
|
455
467
|
|
|
456
468
|
describe '#mode' do
|
|
457
469
|
it 'returns an integer representing the permission bits of stat' do
|
|
458
|
-
_fs.chmod(
|
|
459
|
-
expect(file_stat.mode).to be(
|
|
470
|
+
_fs.chmod(0o777, '/test-file')
|
|
471
|
+
expect(file_stat.mode).to be(0o100777)
|
|
460
472
|
end
|
|
461
473
|
end
|
|
462
474
|
|
|
@@ -470,7 +482,7 @@ module MemFs
|
|
|
470
482
|
|
|
471
483
|
context 'when the effective user does not own of the file' do
|
|
472
484
|
it 'returns false' do
|
|
473
|
-
_fs.chown(
|
|
485
|
+
_fs.chown(9999, 9999, '/test-file')
|
|
474
486
|
expect(file_stat.owned?).to be false
|
|
475
487
|
end
|
|
476
488
|
end
|
|
@@ -599,14 +611,14 @@ module MemFs
|
|
|
599
611
|
describe '#setgid?' do
|
|
600
612
|
context 'when the file has the setgid bit set' do
|
|
601
613
|
it 'returns true' do
|
|
602
|
-
_fs.chmod(
|
|
614
|
+
_fs.chmod(0o2000, '/test-file')
|
|
603
615
|
expect(file_stat.setgid?).to be true
|
|
604
616
|
end
|
|
605
617
|
end
|
|
606
618
|
|
|
607
619
|
context 'when the file does not have the setgid bit set' do
|
|
608
620
|
it 'returns false' do
|
|
609
|
-
_fs.chmod(
|
|
621
|
+
_fs.chmod(0o644, '/test-file')
|
|
610
622
|
expect(file_stat.setgid?).to be false
|
|
611
623
|
end
|
|
612
624
|
end
|
|
@@ -615,14 +627,14 @@ module MemFs
|
|
|
615
627
|
describe '#setuid?' do
|
|
616
628
|
context 'when the file has the setuid bit set' do
|
|
617
629
|
it 'returns true' do
|
|
618
|
-
_fs.chmod(
|
|
630
|
+
_fs.chmod(0o4000, '/test-file')
|
|
619
631
|
expect(file_stat.setuid?).to be true
|
|
620
632
|
end
|
|
621
633
|
end
|
|
622
634
|
|
|
623
635
|
context 'when the file does not have the setuid bit set' do
|
|
624
636
|
it 'returns false' do
|
|
625
|
-
_fs.chmod(
|
|
637
|
+
_fs.chmod(0o644, '/test-file')
|
|
626
638
|
expect(file_stat.setuid?).to be false
|
|
627
639
|
end
|
|
628
640
|
end
|
|
@@ -640,12 +652,12 @@ module MemFs
|
|
|
640
652
|
|
|
641
653
|
describe '#sticky?' do
|
|
642
654
|
it 'returns true if the named file has the sticky bit set' do
|
|
643
|
-
_fs.chmod(
|
|
655
|
+
_fs.chmod(0o1777, '/test-file')
|
|
644
656
|
expect(file_stat.sticky?).to be true
|
|
645
657
|
end
|
|
646
658
|
|
|
647
659
|
it "returns false if the named file hasn't' the sticky bit set" do
|
|
648
|
-
_fs.chmod(
|
|
660
|
+
_fs.chmod(0o666, '/test-file')
|
|
649
661
|
expect(file_stat.sticky?).to be false
|
|
650
662
|
end
|
|
651
663
|
end
|
data/spec/memfs/file_spec.rb
CHANGED
|
@@ -26,6 +26,10 @@ module MemFs
|
|
|
26
26
|
expect(MemFs::File::SEPARATOR).to eq '/'
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
it 'exposes PATH_SEPARATOR' do
|
|
30
|
+
expect(MemFs::File::PATH_SEPARATOR).to eq '/'
|
|
31
|
+
end
|
|
32
|
+
|
|
29
33
|
it 'expose ALT_SEPARATOR' do
|
|
30
34
|
expect(MemFs::File::ALT_SEPARATOR).to be_nil
|
|
31
35
|
end
|
|
@@ -36,20 +40,20 @@ module MemFs
|
|
|
36
40
|
|
|
37
41
|
it 'converts a pathname to an absolute pathname' do
|
|
38
42
|
path = described_class.absolute_path('./test-file')
|
|
39
|
-
expect(path).to eq '/test-dir/test-file'
|
|
43
|
+
expect(path).to eq expected_path('/test-dir/test-file')
|
|
40
44
|
end
|
|
41
45
|
|
|
42
46
|
context 'when +dir_string+ is given' do
|
|
43
47
|
it 'uses it as the starting point' do
|
|
44
48
|
path = described_class.absolute_path('./test-file', '/no-dir')
|
|
45
|
-
expect(path).to eq '/no-dir/test-file'
|
|
49
|
+
expect(path).to eq expected_path('/no-dir/test-file')
|
|
46
50
|
end
|
|
47
51
|
end
|
|
48
52
|
|
|
49
53
|
context "when the given pathname starts with a '~'" do
|
|
50
54
|
it 'does not expanded' do
|
|
51
55
|
path = described_class.absolute_path('~/test-file')
|
|
52
|
-
expect(path).to eq '/test-dir/~/test-file'
|
|
56
|
+
expect(path).to eq expected_path('/test-dir/~/test-file')
|
|
53
57
|
end
|
|
54
58
|
end
|
|
55
59
|
end
|
|
@@ -75,6 +79,27 @@ module MemFs
|
|
|
75
79
|
end
|
|
76
80
|
end
|
|
77
81
|
|
|
82
|
+
describe '.birthtime' do
|
|
83
|
+
it 'returns creation time for the named file as a Time object' do
|
|
84
|
+
expect(described_class.birthtime('/test-file')).to be_a Time
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'raises an error if the entry does not exist' do
|
|
88
|
+
expect { described_class.birthtime('/no-file') }.to raise_error Errno::ENOENT
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
context 'when the entry is a symlink' do
|
|
92
|
+
let(:time) { Time.now - 500_000 }
|
|
93
|
+
|
|
94
|
+
it 'returns the creation time of the last target of the link chain' do
|
|
95
|
+
_fs.find!('/test-file').birthtime = time
|
|
96
|
+
described_class.symlink '/test-link', '/test-link2'
|
|
97
|
+
|
|
98
|
+
expect(described_class.birthtime('/test-link2')).to eq time
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
78
103
|
describe '.blockdev?' do
|
|
79
104
|
context 'when the name file exists' do
|
|
80
105
|
context 'and it is a block device' do
|
|
@@ -151,17 +176,17 @@ module MemFs
|
|
|
151
176
|
|
|
152
177
|
describe '.chmod' do
|
|
153
178
|
it 'changes permission bits on the named file' do
|
|
154
|
-
described_class.chmod
|
|
179
|
+
described_class.chmod 0o777, '/test-file'
|
|
155
180
|
|
|
156
181
|
mode = described_class.stat('/test-file').mode
|
|
157
|
-
expect(mode).to be
|
|
182
|
+
expect(mode).to be 0o100777
|
|
158
183
|
end
|
|
159
184
|
|
|
160
185
|
it 'changes permission bits on the named files (in list)' do
|
|
161
|
-
described_class.chmod
|
|
186
|
+
described_class.chmod 0o777, '/test-file', '/test-file2'
|
|
162
187
|
|
|
163
188
|
mode = described_class.stat('/test-file2').mode
|
|
164
|
-
expect(mode).to be
|
|
189
|
+
expect(mode).to be 0o100777
|
|
165
190
|
end
|
|
166
191
|
end
|
|
167
192
|
|
|
@@ -304,6 +329,12 @@ module MemFs
|
|
|
304
329
|
end
|
|
305
330
|
end
|
|
306
331
|
|
|
332
|
+
describe '.empty?' do
|
|
333
|
+
subject { described_class }
|
|
334
|
+
|
|
335
|
+
it_behaves_like 'aliased method', :empty?, :zero?
|
|
336
|
+
end
|
|
337
|
+
|
|
307
338
|
describe '.executable?' do
|
|
308
339
|
let(:access) { 0 }
|
|
309
340
|
let(:gid) { 0 }
|
|
@@ -459,20 +490,20 @@ module MemFs
|
|
|
459
490
|
_fs.chdir '/'
|
|
460
491
|
|
|
461
492
|
expanded_path = described_class.expand_path('test-file')
|
|
462
|
-
expect(expanded_path).to eq '/test-file'
|
|
493
|
+
expect(expanded_path).to eq expected_path('/test-file')
|
|
463
494
|
end
|
|
464
495
|
|
|
465
496
|
it 'references path from the current working directory' do
|
|
466
497
|
_fs.chdir '/test-dir'
|
|
467
498
|
|
|
468
499
|
expanded_path = described_class.expand_path('test-file')
|
|
469
|
-
expect(expanded_path).to eq '/test-dir/test-file'
|
|
500
|
+
expect(expanded_path).to eq expected_path('/test-dir/test-file')
|
|
470
501
|
end
|
|
471
502
|
|
|
472
503
|
context 'when +dir_string+ is provided' do
|
|
473
504
|
it 'uses +dir_string+ as the stating point' do
|
|
474
505
|
expanded_path = described_class.expand_path('test-file', '/test')
|
|
475
|
-
expect(expanded_path).to eq '/test/test-file'
|
|
506
|
+
expect(expanded_path).to eq expected_path('/test/test-file')
|
|
476
507
|
end
|
|
477
508
|
end
|
|
478
509
|
end
|
|
@@ -500,9 +531,16 @@ module MemFs
|
|
|
500
531
|
end
|
|
501
532
|
|
|
502
533
|
context 'when the period is the last character in path' do
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
534
|
+
if MemFs.ruby_version_gte?('2.7') && !MemFs.windows?
|
|
535
|
+
it 'returns a period' do
|
|
536
|
+
extname = described_class.extname('test-subject.')
|
|
537
|
+
expect(extname).to eq '.'
|
|
538
|
+
end
|
|
539
|
+
else
|
|
540
|
+
it 'returns an empty string' do
|
|
541
|
+
extname = described_class.extname('test-subject.')
|
|
542
|
+
expect(extname).to eq ''
|
|
543
|
+
end
|
|
506
544
|
end
|
|
507
545
|
end
|
|
508
546
|
end
|
|
@@ -624,7 +662,7 @@ module MemFs
|
|
|
624
662
|
|
|
625
663
|
context 'and the effective user group does not own of the file' do
|
|
626
664
|
it 'returns false' do
|
|
627
|
-
described_class.chown
|
|
665
|
+
described_class.chown 9999, 9999, '/test-file'
|
|
628
666
|
|
|
629
667
|
grpowned = File.grpowned?('/test-file')
|
|
630
668
|
expect(grpowned).to be false
|
|
@@ -701,6 +739,30 @@ module MemFs
|
|
|
701
739
|
end
|
|
702
740
|
end
|
|
703
741
|
end
|
|
742
|
+
|
|
743
|
+
context 'when given a File object instead of a path' do
|
|
744
|
+
it 'returns true when the File object refers to the same file' do
|
|
745
|
+
file = described_class.new('/test-file', 'r')
|
|
746
|
+
expect(described_class.identical?(file, '/test-file')).to be true
|
|
747
|
+
file.close
|
|
748
|
+
end
|
|
749
|
+
|
|
750
|
+
it 'returns true when both arguments are File objects for the same file' do
|
|
751
|
+
file1 = described_class.new('/test-file', 'r')
|
|
752
|
+
file2 = described_class.new('/test-file', 'r')
|
|
753
|
+
expect(described_class.identical?(file1, file2)).to be true
|
|
754
|
+
file1.close
|
|
755
|
+
file2.close
|
|
756
|
+
end
|
|
757
|
+
|
|
758
|
+
it 'returns false when both File objects refer to different files' do
|
|
759
|
+
file1 = described_class.new('/test-file', 'r')
|
|
760
|
+
file2 = described_class.new('/test-file2', 'r')
|
|
761
|
+
expect(described_class.identical?(file1, file2)).to be false
|
|
762
|
+
file1.close
|
|
763
|
+
file2.close
|
|
764
|
+
end
|
|
765
|
+
end
|
|
704
766
|
end
|
|
705
767
|
|
|
706
768
|
describe '.join' do
|
|
@@ -713,24 +775,24 @@ module MemFs
|
|
|
713
775
|
describe '.lchmod' do
|
|
714
776
|
context 'when the named file is a regular file' do
|
|
715
777
|
it 'acts like chmod' do
|
|
716
|
-
described_class.lchmod
|
|
778
|
+
described_class.lchmod 0o777, '/test-file'
|
|
717
779
|
|
|
718
780
|
mode = described_class.stat('/test-file').mode
|
|
719
|
-
expect(mode).to be
|
|
781
|
+
expect(mode).to be 0o100777
|
|
720
782
|
end
|
|
721
783
|
end
|
|
722
784
|
|
|
723
785
|
context 'when the named file is a symlink' do
|
|
724
786
|
it 'changes permission bits on the symlink' do
|
|
725
|
-
described_class.lchmod
|
|
787
|
+
described_class.lchmod 0o777, '/test-link'
|
|
726
788
|
|
|
727
789
|
mode = described_class.lstat('/test-link').mode
|
|
728
|
-
expect(mode).to be
|
|
790
|
+
expect(mode).to be 0o100777
|
|
729
791
|
end
|
|
730
792
|
|
|
731
793
|
it 'does not change permission bits on the link’s target' do
|
|
732
794
|
old_mode = described_class.stat('/test-file').mode
|
|
733
|
-
described_class.lchmod
|
|
795
|
+
described_class.lchmod 0o777, '/test-link'
|
|
734
796
|
|
|
735
797
|
mode = described_class.stat('/test-file').mode
|
|
736
798
|
expect(mode).to eq old_mode
|
|
@@ -880,6 +942,16 @@ module MemFs
|
|
|
880
942
|
expect(subject.send(:opening_mode)).to eq File::RDONLY
|
|
881
943
|
end
|
|
882
944
|
|
|
945
|
+
it 'handles the :utf-8 option' do
|
|
946
|
+
subject = described_class.new('/test-file', 'r:utf-8')
|
|
947
|
+
expect(subject.send(:opening_mode)).to eq File::RDONLY
|
|
948
|
+
end
|
|
949
|
+
|
|
950
|
+
it 'handles the :UTF-8 option' do
|
|
951
|
+
subject = described_class.new('/test-file', 'r:UTF-8')
|
|
952
|
+
expect(subject.send(:opening_mode)).to eq File::RDONLY
|
|
953
|
+
end
|
|
954
|
+
|
|
883
955
|
it 'handles the |utf-8 option' do
|
|
884
956
|
subject = described_class.new('/test-file', 'r|utf-8')
|
|
885
957
|
expect(subject.send(:opening_mode)).to eq File::RDONLY
|
|
@@ -941,7 +1013,7 @@ module MemFs
|
|
|
941
1013
|
|
|
942
1014
|
context 'and the effective user does not own of the file' do
|
|
943
1015
|
it 'returns false' do
|
|
944
|
-
described_class.chown
|
|
1016
|
+
described_class.chown 9999, 9999, '/test-file'
|
|
945
1017
|
|
|
946
1018
|
owned = File.owned?('/test-file')
|
|
947
1019
|
expect(owned).to be false
|
|
@@ -1025,7 +1097,7 @@ module MemFs
|
|
|
1025
1097
|
it 'passes the contained options to +open+' do
|
|
1026
1098
|
expect(described_class).to \
|
|
1027
1099
|
receive(:open)
|
|
1028
|
-
.with('/test-file', File::RDONLY, encoding: 'UTF-8')
|
|
1100
|
+
.with('/test-file', File::RDONLY, { encoding: 'UTF-8' })
|
|
1029
1101
|
.and_return(subject)
|
|
1030
1102
|
|
|
1031
1103
|
described_class.read '/test-file', encoding: 'UTF-8'
|
|
@@ -1186,7 +1258,7 @@ module MemFs
|
|
|
1186
1258
|
context 'when the path does not contain any symlink or useless dots' do
|
|
1187
1259
|
it 'returns the path itself' do
|
|
1188
1260
|
path = described_class.realdirpath('/test-file')
|
|
1189
|
-
expect(path).to eq '/test-file'
|
|
1261
|
+
expect(path).to eq expected_path('/test-file')
|
|
1190
1262
|
end
|
|
1191
1263
|
end
|
|
1192
1264
|
|
|
@@ -1194,14 +1266,14 @@ module MemFs
|
|
|
1194
1266
|
context 'and the symlink is a middle part' do
|
|
1195
1267
|
it 'returns the path with the symlink dereferrenced' do
|
|
1196
1268
|
path = described_class.realdirpath('/test-dir/sub-dir-link/test-file')
|
|
1197
|
-
expect(path).to eq '/test-dir/sub-dir/test-file'
|
|
1269
|
+
expect(path).to eq expected_path('/test-dir/sub-dir/test-file')
|
|
1198
1270
|
end
|
|
1199
1271
|
end
|
|
1200
1272
|
|
|
1201
1273
|
context 'and the symlink is the last part' do
|
|
1202
1274
|
it 'returns the path with the symlink dereferrenced' do
|
|
1203
1275
|
path = described_class.realdirpath('/test-dir/sub-dir-link')
|
|
1204
|
-
expect(path).to eq '/test-dir/sub-dir'
|
|
1276
|
+
expect(path).to eq expected_path('/test-dir/sub-dir')
|
|
1205
1277
|
end
|
|
1206
1278
|
end
|
|
1207
1279
|
end
|
|
@@ -1209,7 +1281,7 @@ module MemFs
|
|
|
1209
1281
|
context 'when the path contains useless dots' do
|
|
1210
1282
|
it 'returns the path with the useless dots interpolated' do
|
|
1211
1283
|
path = described_class.realdirpath('/test-dir/../test-dir/./sub-dir/test-file')
|
|
1212
|
-
expect(path).to eq '/test-dir/sub-dir/test-file'
|
|
1284
|
+
expect(path).to eq expected_path('/test-dir/sub-dir/test-file')
|
|
1213
1285
|
end
|
|
1214
1286
|
end
|
|
1215
1287
|
|
|
@@ -1218,14 +1290,14 @@ module MemFs
|
|
|
1218
1290
|
it 'uses the current working directory has base directory' do
|
|
1219
1291
|
_fs.chdir '/test-dir'
|
|
1220
1292
|
path = described_class.realdirpath('../test-dir/./sub-dir/test-file')
|
|
1221
|
-
expect(path).to eq '/test-dir/sub-dir/test-file'
|
|
1293
|
+
expect(path).to eq expected_path('/test-dir/sub-dir/test-file')
|
|
1222
1294
|
end
|
|
1223
1295
|
end
|
|
1224
1296
|
|
|
1225
1297
|
context 'and +dir_string+ is provided' do
|
|
1226
1298
|
it 'uses the given directory has base directory' do
|
|
1227
1299
|
path = described_class.realdirpath('../test-dir/./sub-dir/test-file', '/test-dir')
|
|
1228
|
-
expect(path).to eq '/test-dir/sub-dir/test-file'
|
|
1300
|
+
expect(path).to eq expected_path('/test-dir/sub-dir/test-file')
|
|
1229
1301
|
end
|
|
1230
1302
|
end
|
|
1231
1303
|
end
|
|
@@ -1238,7 +1310,7 @@ module MemFs
|
|
|
1238
1310
|
|
|
1239
1311
|
it 'uses the name of the target in the resulting path' do
|
|
1240
1312
|
path = described_class.realdirpath('/test-dir/sub-dir/test-link')
|
|
1241
|
-
expect(path).to eq '/test-dir/sub-dir/test'
|
|
1313
|
+
expect(path).to eq expected_path('/test-dir/sub-dir/test')
|
|
1242
1314
|
end
|
|
1243
1315
|
end
|
|
1244
1316
|
end
|
|
@@ -1246,7 +1318,7 @@ module MemFs
|
|
|
1246
1318
|
context 'when the last part of the given path does not exist' do
|
|
1247
1319
|
it 'uses its name in the resulting path' do
|
|
1248
1320
|
path = described_class.realdirpath('/test-dir/sub-dir/test')
|
|
1249
|
-
expect(path).to eq '/test-dir/sub-dir/test'
|
|
1321
|
+
expect(path).to eq expected_path('/test-dir/sub-dir/test')
|
|
1250
1322
|
end
|
|
1251
1323
|
end
|
|
1252
1324
|
|
|
@@ -1269,7 +1341,7 @@ module MemFs
|
|
|
1269
1341
|
context 'when the path does not contain any symlink or useless dots' do
|
|
1270
1342
|
it 'returns the path itself' do
|
|
1271
1343
|
path = described_class.realpath('/test-file')
|
|
1272
|
-
expect(path).to eq '/test-file'
|
|
1344
|
+
expect(path).to eq expected_path('/test-file')
|
|
1273
1345
|
end
|
|
1274
1346
|
end
|
|
1275
1347
|
|
|
@@ -1277,14 +1349,14 @@ module MemFs
|
|
|
1277
1349
|
context 'and the symlink is a middle part' do
|
|
1278
1350
|
it 'returns the path with the symlink dereferrenced' do
|
|
1279
1351
|
path = described_class.realpath('/test-dir/sub-dir-link/test-file')
|
|
1280
|
-
expect(path).to eq '/test-dir/sub-dir/test-file'
|
|
1352
|
+
expect(path).to eq expected_path('/test-dir/sub-dir/test-file')
|
|
1281
1353
|
end
|
|
1282
1354
|
end
|
|
1283
1355
|
|
|
1284
1356
|
context 'and the symlink is the last part' do
|
|
1285
1357
|
it 'returns the path with the symlink dereferrenced' do
|
|
1286
1358
|
path = described_class.realpath('/test-dir/sub-dir-link')
|
|
1287
|
-
expect(path).to eq '/test-dir/sub-dir'
|
|
1359
|
+
expect(path).to eq expected_path('/test-dir/sub-dir')
|
|
1288
1360
|
end
|
|
1289
1361
|
end
|
|
1290
1362
|
end
|
|
@@ -1292,7 +1364,7 @@ module MemFs
|
|
|
1292
1364
|
context 'when the path contains useless dots' do
|
|
1293
1365
|
it 'returns the path with the useless dots interpolated' do
|
|
1294
1366
|
path = described_class.realpath('/test-dir/../test-dir/./sub-dir/test-file')
|
|
1295
|
-
expect(path).to eq '/test-dir/sub-dir/test-file'
|
|
1367
|
+
expect(path).to eq expected_path('/test-dir/sub-dir/test-file')
|
|
1296
1368
|
end
|
|
1297
1369
|
end
|
|
1298
1370
|
|
|
@@ -1302,14 +1374,14 @@ module MemFs
|
|
|
1302
1374
|
_fs.chdir '/test-dir'
|
|
1303
1375
|
|
|
1304
1376
|
path = described_class.realpath('../test-dir/./sub-dir/test-file')
|
|
1305
|
-
expect(path).to eq '/test-dir/sub-dir/test-file'
|
|
1377
|
+
expect(path).to eq expected_path('/test-dir/sub-dir/test-file')
|
|
1306
1378
|
end
|
|
1307
1379
|
end
|
|
1308
1380
|
|
|
1309
1381
|
context 'and +dir_string+ is provided' do
|
|
1310
1382
|
it 'uses the given directory has base directory' do
|
|
1311
1383
|
path = described_class.realpath('../test-dir/./sub-dir/test-file', '/test-dir')
|
|
1312
|
-
expect(path).to eq '/test-dir/sub-dir/test-file'
|
|
1384
|
+
expect(path).to eq expected_path('/test-dir/sub-dir/test-file')
|
|
1313
1385
|
end
|
|
1314
1386
|
end
|
|
1315
1387
|
end
|
|
@@ -1341,7 +1413,7 @@ module MemFs
|
|
|
1341
1413
|
context 'when the named file exists' do
|
|
1342
1414
|
context 'and the named file has the setgid bit set' do
|
|
1343
1415
|
it 'returns true' do
|
|
1344
|
-
_fs.chmod
|
|
1416
|
+
_fs.chmod 0o2000, '/test-file'
|
|
1345
1417
|
|
|
1346
1418
|
setgid = File.setgid?('/test-file')
|
|
1347
1419
|
expect(setgid).to be true
|
|
@@ -1350,7 +1422,7 @@ module MemFs
|
|
|
1350
1422
|
|
|
1351
1423
|
context 'and the named file does not have the setgid bit set' do
|
|
1352
1424
|
it 'returns false' do
|
|
1353
|
-
_fs.chmod
|
|
1425
|
+
_fs.chmod 0o644, '/test-file'
|
|
1354
1426
|
|
|
1355
1427
|
setgid = File.setgid?('/test-file')
|
|
1356
1428
|
expect(setgid).not_to be true
|
|
@@ -1370,7 +1442,7 @@ module MemFs
|
|
|
1370
1442
|
context 'when the named file exists' do
|
|
1371
1443
|
context 'and the named file has the setuid bit set' do
|
|
1372
1444
|
it 'returns true' do
|
|
1373
|
-
_fs.chmod
|
|
1445
|
+
_fs.chmod 0o4000, '/test-file'
|
|
1374
1446
|
|
|
1375
1447
|
setuid = File.setuid?('/test-file')
|
|
1376
1448
|
expect(setuid).to be true
|
|
@@ -1379,7 +1451,7 @@ module MemFs
|
|
|
1379
1451
|
|
|
1380
1452
|
context 'and the named file does not have the setuid bit set' do
|
|
1381
1453
|
it 'returns false' do
|
|
1382
|
-
_fs.chmod
|
|
1454
|
+
_fs.chmod 0o644, '/test-file'
|
|
1383
1455
|
|
|
1384
1456
|
setuid = File.setuid?('/test-file')
|
|
1385
1457
|
expect(setuid).not_to be true
|
|
@@ -1490,7 +1562,7 @@ module MemFs
|
|
|
1490
1562
|
context 'when the named file exists' do
|
|
1491
1563
|
it 'returns true if the named file has the sticky bit set' do
|
|
1492
1564
|
_fs.touch '/test-file'
|
|
1493
|
-
_fs.chmod
|
|
1565
|
+
_fs.chmod 0o1777, '/test-file'
|
|
1494
1566
|
|
|
1495
1567
|
sticky = File.sticky?('/test-file')
|
|
1496
1568
|
expect(sticky).to be true
|
|
@@ -1498,7 +1570,7 @@ module MemFs
|
|
|
1498
1570
|
|
|
1499
1571
|
it 'returns false if the named file hasn’t the sticky bit set' do
|
|
1500
1572
|
_fs.touch '/test-file'
|
|
1501
|
-
_fs.chmod
|
|
1573
|
+
_fs.chmod 0o666, '/test-file'
|
|
1502
1574
|
|
|
1503
1575
|
sticky = File.sticky?('/test-file')
|
|
1504
1576
|
expect(sticky).to be false
|
|
@@ -1595,21 +1667,21 @@ module MemFs
|
|
|
1595
1667
|
end
|
|
1596
1668
|
|
|
1597
1669
|
describe '.umask' do
|
|
1598
|
-
before { described_class.umask
|
|
1670
|
+
before { described_class.umask 0o022 }
|
|
1599
1671
|
|
|
1600
1672
|
it 'returns the current umask value for this process' do
|
|
1601
|
-
expect(described_class.umask).to be
|
|
1673
|
+
expect(described_class.umask).to be 0o022
|
|
1602
1674
|
end
|
|
1603
1675
|
|
|
1604
1676
|
context 'when the optional argument is given' do
|
|
1605
1677
|
it 'sets the umask to that value' do
|
|
1606
|
-
described_class.umask
|
|
1607
|
-
expect(described_class.umask).to be
|
|
1678
|
+
described_class.umask 0o777
|
|
1679
|
+
expect(described_class.umask).to be 0o777
|
|
1608
1680
|
end
|
|
1609
1681
|
|
|
1610
1682
|
it 'return the previous value' do
|
|
1611
|
-
previous_umask = described_class.umask(
|
|
1612
|
-
expect(previous_umask).to be
|
|
1683
|
+
previous_umask = described_class.umask(0o777)
|
|
1684
|
+
expect(previous_umask).to be 0o022
|
|
1613
1685
|
end
|
|
1614
1686
|
end
|
|
1615
1687
|
end
|
|
@@ -2051,6 +2123,12 @@ module MemFs
|
|
|
2051
2123
|
end
|
|
2052
2124
|
end
|
|
2053
2125
|
|
|
2126
|
+
describe '#birthtime' do
|
|
2127
|
+
it 'returns a Time object' do
|
|
2128
|
+
expect(subject.birthtime).to be_a Time
|
|
2129
|
+
end
|
|
2130
|
+
end
|
|
2131
|
+
|
|
2054
2132
|
describe '#bytes' do
|
|
2055
2133
|
it_behaves_like 'aliased method', :bytes, :each_byte
|
|
2056
2134
|
end
|
|
@@ -2061,14 +2139,14 @@ module MemFs
|
|
|
2061
2139
|
|
|
2062
2140
|
describe '#chmod' do
|
|
2063
2141
|
it 'changes permission bits on the file' do
|
|
2064
|
-
subject.chmod
|
|
2142
|
+
subject.chmod 0o777
|
|
2065
2143
|
|
|
2066
2144
|
mode = subject.stat.mode
|
|
2067
|
-
expect(mode).to be
|
|
2145
|
+
expect(mode).to be 0o100777
|
|
2068
2146
|
end
|
|
2069
2147
|
|
|
2070
2148
|
it 'returns zero' do
|
|
2071
|
-
returned_value = subject.chmod(
|
|
2149
|
+
returned_value = subject.chmod(0o777)
|
|
2072
2150
|
expect(returned_value).to be_zero
|
|
2073
2151
|
end
|
|
2074
2152
|
end
|
|
@@ -2404,6 +2482,12 @@ module MemFs
|
|
|
2404
2482
|
end
|
|
2405
2483
|
end
|
|
2406
2484
|
|
|
2485
|
+
describe '#fileno' do
|
|
2486
|
+
it 'raises an exception' do
|
|
2487
|
+
expect { subject.fileno }.to raise_exception(NotImplementedError)
|
|
2488
|
+
end
|
|
2489
|
+
end
|
|
2490
|
+
|
|
2407
2491
|
describe '#flock' do
|
|
2408
2492
|
it 'returns zero' do
|
|
2409
2493
|
returned_value = subject.flock(File::LOCK_EX)
|
|
@@ -2645,7 +2729,7 @@ module MemFs
|
|
|
2645
2729
|
|
|
2646
2730
|
context 'when a buffer is given' do
|
|
2647
2731
|
it 'fills the buffer with the read content' do
|
|
2648
|
-
buffer =
|
|
2732
|
+
buffer = +''
|
|
2649
2733
|
subject.read 2, buffer
|
|
2650
2734
|
|
|
2651
2735
|
expect(buffer).to eq random_string[0, 2]
|