memfs 0.4.3 → 0.5.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/.travis.yml +1 -0
- data/CHANGELOG.md +5 -0
- data/README.md +3 -2
- data/lib/memfs/dir.rb +2 -2
- data/lib/memfs/file_system.rb +4 -2
- data/lib/memfs/version.rb +1 -1
- data/spec/fileutils_spec.rb +229 -191
- data/spec/memfs/dir_spec.rb +109 -95
- data/spec/memfs/fake/directory_spec.rb +8 -8
- data/spec/memfs/fake/entry_spec.rb +3 -3
- data/spec/memfs/fake/file/content_spec.rb +3 -5
- data/spec/memfs/fake/symlink_spec.rb +11 -11
- data/spec/memfs/file/stat_spec.rb +14 -14
- data/spec/memfs/file_spec.rb +269 -269
- data/spec/memfs/file_system_spec.rb +12 -0
- data/spec/memfs_spec.rb +18 -20
- metadata +3 -3
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
module MemFs
|
4
4
|
module Fake
|
5
5
|
describe Directory do
|
6
|
-
|
6
|
+
subject(:directory) { described_class.new('test') }
|
7
7
|
|
8
8
|
describe '.new' do
|
9
9
|
it 'sets . in the entries list' do
|
@@ -16,7 +16,7 @@ module MemFs
|
|
16
16
|
end
|
17
17
|
|
18
18
|
describe '#add_entry' do
|
19
|
-
let(:entry) {
|
19
|
+
let(:entry) { described_class.new('new_entry') }
|
20
20
|
|
21
21
|
it 'adds the entry to the entries list' do
|
22
22
|
directory.add_entry entry
|
@@ -35,7 +35,7 @@ module MemFs
|
|
35
35
|
end
|
36
36
|
|
37
37
|
it 'returns false if the directory is not empty' do
|
38
|
-
directory.add_entry
|
38
|
+
directory.add_entry described_class.new('test')
|
39
39
|
expect(directory).not_to be_empty
|
40
40
|
end
|
41
41
|
end
|
@@ -43,7 +43,7 @@ module MemFs
|
|
43
43
|
describe '#entry_names' do
|
44
44
|
it 'returns the list of the names of the entries in the directory' do
|
45
45
|
3.times do |n|
|
46
|
-
directory.add_entry
|
46
|
+
directory.add_entry described_class.new("dir#{n}")
|
47
47
|
end
|
48
48
|
|
49
49
|
expect(directory.entry_names).to eq(%w[. .. dir0 dir1 dir2])
|
@@ -51,7 +51,7 @@ module MemFs
|
|
51
51
|
end
|
52
52
|
|
53
53
|
describe '#find' do
|
54
|
-
let(:sub_directory) {
|
54
|
+
let(:sub_directory) { described_class.new('sub_dir') }
|
55
55
|
let(:file) { File.new('file') }
|
56
56
|
|
57
57
|
before :each do
|
@@ -73,7 +73,7 @@ module MemFs
|
|
73
73
|
end
|
74
74
|
|
75
75
|
describe '#parent=' do
|
76
|
-
let(:parent) {
|
76
|
+
let(:parent) { described_class.new('parent') }
|
77
77
|
|
78
78
|
it 'sets the .. entry in entries list' do
|
79
79
|
directory.parent = parent
|
@@ -87,7 +87,7 @@ module MemFs
|
|
87
87
|
end
|
88
88
|
|
89
89
|
describe '#path' do
|
90
|
-
let(:root) {
|
90
|
+
let(:root) { described_class.new('/') }
|
91
91
|
|
92
92
|
it 'returns the directory path' do
|
93
93
|
directory.parent = root
|
@@ -103,7 +103,7 @@ module MemFs
|
|
103
103
|
|
104
104
|
describe '#paths' do
|
105
105
|
before do
|
106
|
-
subdir =
|
106
|
+
subdir = described_class.new('subdir')
|
107
107
|
directory.add_entry(subdir)
|
108
108
|
subdir.add_entry File.new('file1')
|
109
109
|
subdir.add_entry File.new('file2')
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
module MemFs
|
4
4
|
module Fake
|
5
5
|
describe Entry do
|
6
|
-
let(:entry) {
|
6
|
+
let(:entry) { described_class.new('test') }
|
7
7
|
let(:parent) { Directory.new('parent') }
|
8
8
|
let(:time) { Time.now - 5000 }
|
9
9
|
|
@@ -76,11 +76,11 @@ module MemFs
|
|
76
76
|
end
|
77
77
|
|
78
78
|
it 'sets an empty string as name if none is given' do
|
79
|
-
expect(
|
79
|
+
expect(described_class.new.name).to be_empty
|
80
80
|
end
|
81
81
|
|
82
82
|
it 'sets the access time' do
|
83
|
-
expect(
|
83
|
+
expect(described_class.new.atime).to be_a(Time)
|
84
84
|
end
|
85
85
|
|
86
86
|
it 'sets the modification time' do
|
@@ -4,8 +4,6 @@ require 'spec_helper'
|
|
4
4
|
module MemFs
|
5
5
|
module Fake
|
6
6
|
describe File::Content do
|
7
|
-
subject { File::Content.new }
|
8
|
-
|
9
7
|
describe '#<<' do
|
10
8
|
it 'writes the given string to the contained string' do
|
11
9
|
subject << 'test'
|
@@ -21,7 +19,7 @@ module MemFs
|
|
21
19
|
end
|
22
20
|
|
23
21
|
context 'when an argument is given' do
|
24
|
-
subject {
|
22
|
+
subject { described_class.new(base_value) }
|
25
23
|
|
26
24
|
context 'when the argument is a string' do
|
27
25
|
let(:base_value) { 'test' }
|
@@ -80,7 +78,7 @@ module MemFs
|
|
80
78
|
end
|
81
79
|
|
82
80
|
describe '#truncate' do
|
83
|
-
subject {
|
81
|
+
subject { described_class.new('x' * 50) }
|
84
82
|
|
85
83
|
it 'truncates the content to length characters' do
|
86
84
|
subject.truncate(5)
|
@@ -113,7 +111,7 @@ module MemFs
|
|
113
111
|
end
|
114
112
|
|
115
113
|
context 'when initialized with a string argument' do
|
116
|
-
subject {
|
114
|
+
subject { described_class.new('test') }
|
117
115
|
|
118
116
|
describe '#read' do
|
119
117
|
it 'reads +length+ bytes from the contained string' do
|
@@ -6,7 +6,7 @@ module MemFs
|
|
6
6
|
describe '#content' do
|
7
7
|
it "returns the target's content" do
|
8
8
|
MemFs::File.open('/test-file', 'w') { |f| f.puts 'test' }
|
9
|
-
s =
|
9
|
+
s = described_class.new('/test-link', '/test-file')
|
10
10
|
expect(s.content).to be(s.dereferenced.content)
|
11
11
|
end
|
12
12
|
end
|
@@ -16,7 +16,7 @@ module MemFs
|
|
16
16
|
_fs.touch '/test-file'
|
17
17
|
target = _fs.find!('/test-file')
|
18
18
|
|
19
|
-
s =
|
19
|
+
s = described_class.new('/test-link', '/test-file')
|
20
20
|
|
21
21
|
expect(s.dereferenced).to eq(target)
|
22
22
|
end
|
@@ -26,7 +26,7 @@ module MemFs
|
|
26
26
|
target = _fs.find!('/test-file')
|
27
27
|
|
28
28
|
_fs.symlink '/test-file', '/test-link'
|
29
|
-
s =
|
29
|
+
s = described_class.new('/test-link2', '/test-link')
|
30
30
|
|
31
31
|
expect(s.dereferenced).to eq(target)
|
32
32
|
end
|
@@ -36,14 +36,14 @@ module MemFs
|
|
36
36
|
context "when the symlink's target exists" do
|
37
37
|
it 'returns its target name' do
|
38
38
|
_fs.touch('/test-file')
|
39
|
-
symlink =
|
39
|
+
symlink = described_class.new('/test-link', '/test-file')
|
40
40
|
expect(symlink.dereferenced_name).to eq('test-file')
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
44
|
context "when the symlink's target does not exist" do
|
45
45
|
it 'returns its target name' do
|
46
|
-
symlink =
|
46
|
+
symlink = described_class.new('/test-link', '/no-file')
|
47
47
|
expect(symlink.dereferenced_name).to eq('no-file')
|
48
48
|
end
|
49
49
|
end
|
@@ -53,14 +53,14 @@ module MemFs
|
|
53
53
|
context "when the symlink's target exists" do
|
54
54
|
it 'returns its target path' do
|
55
55
|
_fs.touch('/test-file')
|
56
|
-
symlink =
|
56
|
+
symlink = described_class.new('/test-link', '/test-file')
|
57
57
|
expect(symlink.dereferenced_path).to eq('/test-file')
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
61
|
context "when the symlink's target does not exist" do
|
62
62
|
it 'raises an exception' do
|
63
|
-
symlink =
|
63
|
+
symlink = described_class.new('/test-link', '/no-file')
|
64
64
|
expect {
|
65
65
|
symlink.dereferenced_path
|
66
66
|
}.to raise_exception
|
@@ -77,7 +77,7 @@ module MemFs
|
|
77
77
|
end
|
78
78
|
|
79
79
|
context "when the symlink's target exists" do
|
80
|
-
subject {
|
80
|
+
subject { described_class.new('/test-dir-link', '/test-dir') }
|
81
81
|
|
82
82
|
it 'forwards the search to it' do
|
83
83
|
entry = subject.find('test-file')
|
@@ -86,7 +86,7 @@ module MemFs
|
|
86
86
|
end
|
87
87
|
|
88
88
|
context "when the symlink's target does not exist" do
|
89
|
-
subject {
|
89
|
+
subject { described_class.new('/test-no-link', '/no-dir') }
|
90
90
|
|
91
91
|
it 'returns nil' do
|
92
92
|
entry = subject.find('test-file')
|
@@ -97,14 +97,14 @@ module MemFs
|
|
97
97
|
|
98
98
|
describe '#target' do
|
99
99
|
it 'returns the target of the symlink' do
|
100
|
-
s =
|
100
|
+
s = described_class.new('/test-link', '/test-file')
|
101
101
|
expect(s.target).to eq('/test-file')
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
105
|
describe '#type' do
|
106
106
|
it "returns 'link'" do
|
107
|
-
s =
|
107
|
+
s = described_class.new('/test-link', '/test-file')
|
108
108
|
expect(s.type).to eq('link')
|
109
109
|
end
|
110
110
|
end
|
@@ -2,17 +2,17 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module MemFs
|
4
4
|
describe File::Stat do
|
5
|
-
let(:file_stat) {
|
6
|
-
let(:dereferenced_file_stat) {
|
5
|
+
let(:file_stat) { described_class.new('/test-file') }
|
6
|
+
let(:dereferenced_file_stat) { described_class.new('/test-file', true) }
|
7
7
|
|
8
|
-
let(:dir_link_stat) {
|
9
|
-
let(:dereferenced_dir_link_stat) {
|
8
|
+
let(:dir_link_stat) { described_class.new('/test-dir-link') }
|
9
|
+
let(:dereferenced_dir_link_stat) { described_class.new('/test-dir-link', true) }
|
10
10
|
|
11
|
-
let(:link_stat) {
|
12
|
-
let(:dereferenced_link_stat) {
|
11
|
+
let(:link_stat) { described_class.new('/test-link') }
|
12
|
+
let(:dereferenced_link_stat) { described_class.new('/test-link', true) }
|
13
13
|
|
14
|
-
let(:dir_stat) {
|
15
|
-
let(:dereferenced_dir_stat) {
|
14
|
+
let(:dir_stat) { described_class.new('/test-dir') }
|
15
|
+
let(:dereferenced_dir_stat) { described_class.new('/test-dir', 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
|
-
|
32
|
+
described_class.new('/test-no-file-link', true)
|
33
33
|
}.to raise_error(Errno::ENOENT)
|
34
34
|
end
|
35
35
|
end
|
@@ -74,7 +74,7 @@ module MemFs
|
|
74
74
|
_fs.touch('/block-file')
|
75
75
|
file = _fs.find('/block-file')
|
76
76
|
file.block_device = true
|
77
|
-
block_stat =
|
77
|
+
block_stat = described_class.new('/block-file')
|
78
78
|
expect(block_stat.blockdev?).to be true
|
79
79
|
end
|
80
80
|
end
|
@@ -92,7 +92,7 @@ module MemFs
|
|
92
92
|
_fs.touch('/character-file')
|
93
93
|
file = _fs.find('/character-file')
|
94
94
|
file.character_device = true
|
95
|
-
character_stat =
|
95
|
+
character_stat = described_class.new('/character-file')
|
96
96
|
expect(character_stat.chardev?).to be true
|
97
97
|
end
|
98
98
|
end
|
@@ -391,7 +391,7 @@ module MemFs
|
|
391
391
|
_fs.touch('/block-file')
|
392
392
|
file = _fs.find('/block-file')
|
393
393
|
file.block_device = true
|
394
|
-
block_stat =
|
394
|
+
block_stat = described_class.new('/block-file')
|
395
395
|
expect(block_stat.ftype).to eq('blockSpecial')
|
396
396
|
end
|
397
397
|
end
|
@@ -401,7 +401,7 @@ module MemFs
|
|
401
401
|
_fs.touch('/character-file')
|
402
402
|
file = _fs.find('/character-file')
|
403
403
|
file.character_device = true
|
404
|
-
character_stat =
|
404
|
+
character_stat = described_class.new('/character-file')
|
405
405
|
expect(character_stat.ftype).to eq('characterSpecial')
|
406
406
|
end
|
407
407
|
end
|
@@ -418,7 +418,7 @@ module MemFs
|
|
418
418
|
it "returns 'unknown'" do
|
419
419
|
root = _fs.find('/')
|
420
420
|
root.add_entry Fake::Entry.new('test-entry')
|
421
|
-
entry_stat =
|
421
|
+
entry_stat = described_class.new('/test-entry')
|
422
422
|
expect(entry_stat.ftype).to eq('unknown')
|
423
423
|
end
|
424
424
|
end
|
data/spec/memfs/file_spec.rb
CHANGED
@@ -1,23 +1,23 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'pathname'
|
2
3
|
|
3
4
|
module MemFs
|
4
5
|
describe File do
|
5
|
-
subject {
|
6
|
-
let(:
|
7
|
-
let(:write_subject) { subject_class.new('/test-file', 'w') }
|
6
|
+
subject { described_class.new('/test-file') }
|
7
|
+
let(:write_subject) { described_class.new('/test-file', 'w') }
|
8
8
|
|
9
9
|
let(:random_string) { ('a'..'z').to_a.sample(10).join }
|
10
10
|
|
11
11
|
before do
|
12
12
|
_fs.mkdir '/test-dir'
|
13
13
|
_fs.touch '/test-file', '/test-file2'
|
14
|
-
|
15
|
-
|
14
|
+
described_class.symlink '/test-file', '/test-link'
|
15
|
+
described_class.symlink '/no-file', '/no-link'
|
16
16
|
end
|
17
17
|
|
18
18
|
|
19
19
|
it 'implements Enumerable' do
|
20
|
-
expect(
|
20
|
+
expect(described_class.ancestors).to include Enumerable
|
21
21
|
end
|
22
22
|
|
23
23
|
describe 'constants' do
|
@@ -34,20 +34,20 @@ module MemFs
|
|
34
34
|
before { MemFs::Dir.chdir('/test-dir') }
|
35
35
|
|
36
36
|
it 'converts a pathname to an absolute pathname' do
|
37
|
-
path =
|
37
|
+
path = described_class.absolute_path('./test-file')
|
38
38
|
expect(path).to eq '/test-dir/test-file'
|
39
39
|
end
|
40
40
|
|
41
41
|
context 'when +dir_string+ is given' do
|
42
42
|
it 'uses it as the starting point' do
|
43
|
-
path =
|
43
|
+
path = described_class.absolute_path('./test-file', '/no-dir')
|
44
44
|
expect(path).to eq '/no-dir/test-file'
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
48
|
context "when the given pathname starts with a '~'" do
|
49
49
|
it 'does not expanded' do
|
50
|
-
path =
|
50
|
+
path = described_class.absolute_path('~/test-file')
|
51
51
|
expect(path).to eq '/test-dir/~/test-file'
|
52
52
|
end
|
53
53
|
end
|
@@ -55,11 +55,11 @@ module MemFs
|
|
55
55
|
|
56
56
|
describe '.atime' do
|
57
57
|
it 'returns the last access time for the named file as a Time object' do
|
58
|
-
expect(
|
58
|
+
expect(described_class.atime('/test-file')).to be_a Time
|
59
59
|
end
|
60
60
|
|
61
61
|
it 'raises an error if the entry does not exist' do
|
62
|
-
expect {
|
62
|
+
expect { described_class.atime('/no-file') }.to raise_error Errno::ENOENT
|
63
63
|
end
|
64
64
|
|
65
65
|
context 'when the entry is a symlink' do
|
@@ -67,9 +67,9 @@ module MemFs
|
|
67
67
|
|
68
68
|
it 'returns the last access time of the last target of the link chain' do
|
69
69
|
_fs.find!('/test-file').atime = time
|
70
|
-
|
70
|
+
described_class.symlink '/test-link', '/test-link2'
|
71
71
|
|
72
|
-
expect(
|
72
|
+
expect(described_class.atime('/test-link2')).to eq time
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
@@ -82,14 +82,14 @@ module MemFs
|
|
82
82
|
file = _fs.find('/block-file')
|
83
83
|
file.block_device = true
|
84
84
|
|
85
|
-
blockdev =
|
85
|
+
blockdev = described_class.blockdev?('/block-file')
|
86
86
|
expect(blockdev).to be true
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
90
|
context 'and it is not a block device' do
|
91
91
|
it 'returns false' do
|
92
|
-
blockdev =
|
92
|
+
blockdev = described_class.blockdev?('/test-file')
|
93
93
|
expect(blockdev).to be false
|
94
94
|
end
|
95
95
|
end
|
@@ -97,7 +97,7 @@ module MemFs
|
|
97
97
|
|
98
98
|
context 'when the name file does not exist' do
|
99
99
|
it 'returns false' do
|
100
|
-
blockdev =
|
100
|
+
blockdev = described_class.blockdev?('/no-file')
|
101
101
|
expect(blockdev).to be false
|
102
102
|
end
|
103
103
|
end
|
@@ -105,14 +105,14 @@ module MemFs
|
|
105
105
|
|
106
106
|
describe '.basename' do
|
107
107
|
it 'returns the last component of the filename given in +file_name+' do
|
108
|
-
basename =
|
108
|
+
basename = described_class.basename('/path/to/file.txt')
|
109
109
|
expect(basename).to eq 'file.txt'
|
110
110
|
end
|
111
111
|
|
112
112
|
context 'when +suffix+ is given' do
|
113
113
|
context 'when it is present at the end of +file_name+' do
|
114
114
|
it 'removes the +suffix+ from the filename basename' do
|
115
|
-
basename =
|
115
|
+
basename = described_class.basename('/path/to/file.txt', '.txt')
|
116
116
|
expect(basename).to eq 'file'
|
117
117
|
end
|
118
118
|
end
|
@@ -127,14 +127,14 @@ module MemFs
|
|
127
127
|
file = _fs.find('/character-file')
|
128
128
|
file.character_device = true
|
129
129
|
|
130
|
-
chardev =
|
130
|
+
chardev = described_class.chardev?('/character-file')
|
131
131
|
expect(chardev).to be true
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
135
|
context 'and it is not a character device' do
|
136
136
|
it 'returns false' do
|
137
|
-
chardev =
|
137
|
+
chardev = described_class.chardev?('/test-file')
|
138
138
|
expect(chardev).to be false
|
139
139
|
end
|
140
140
|
end
|
@@ -142,7 +142,7 @@ module MemFs
|
|
142
142
|
|
143
143
|
context 'when the name file does not exist' do
|
144
144
|
it 'returns false' do
|
145
|
-
chardev =
|
145
|
+
chardev = described_class.chardev?('/no-file')
|
146
146
|
expect(chardev).to be false
|
147
147
|
end
|
148
148
|
end
|
@@ -150,97 +150,97 @@ module MemFs
|
|
150
150
|
|
151
151
|
describe '.chmod' do
|
152
152
|
it 'changes permission bits on the named file' do
|
153
|
-
|
153
|
+
described_class.chmod 0777, '/test-file'
|
154
154
|
|
155
|
-
mode =
|
155
|
+
mode = described_class.stat('/test-file').mode
|
156
156
|
expect(mode).to be 0100777
|
157
157
|
end
|
158
158
|
|
159
159
|
it 'changes permission bits on the named files (in list)' do
|
160
|
-
|
160
|
+
described_class.chmod 0777, '/test-file', '/test-file2'
|
161
161
|
|
162
|
-
mode =
|
162
|
+
mode = described_class.stat('/test-file2').mode
|
163
163
|
expect(mode).to be 0100777
|
164
164
|
end
|
165
165
|
end
|
166
166
|
|
167
167
|
describe '.chown' do
|
168
168
|
it 'changes the owner of the named file to the given numeric owner id' do
|
169
|
-
|
169
|
+
described_class.chown 42, nil, '/test-file'
|
170
170
|
|
171
|
-
uid =
|
171
|
+
uid = described_class.stat('/test-file').uid
|
172
172
|
expect(uid).to be 42
|
173
173
|
end
|
174
174
|
|
175
175
|
it 'changes owner on the named files (in list)' do
|
176
|
-
|
176
|
+
described_class.chown 42, nil, '/test-file', '/test-file2'
|
177
177
|
|
178
|
-
uid =
|
178
|
+
uid = described_class.stat('/test-file2').uid
|
179
179
|
expect(uid).to be 42
|
180
180
|
end
|
181
181
|
|
182
182
|
it 'changes the group of the named file to the given numeric group id' do
|
183
|
-
|
183
|
+
described_class.chown nil, 42, '/test-file'
|
184
184
|
|
185
|
-
gid =
|
185
|
+
gid = described_class.stat('/test-file').gid
|
186
186
|
expect(gid).to be 42
|
187
187
|
end
|
188
188
|
|
189
189
|
it 'returns the number of files' do
|
190
|
-
returned_value =
|
190
|
+
returned_value = described_class.chown(42, 42, '/test-file', '/test-file2')
|
191
191
|
expect(returned_value).to be 2
|
192
192
|
end
|
193
193
|
|
194
194
|
it 'ignores nil user id' do
|
195
195
|
expect {
|
196
|
-
|
197
|
-
}.to_not change {
|
196
|
+
described_class.chown nil, 42, '/test-file'
|
197
|
+
}.to_not change { described_class.stat('/test-file').uid }
|
198
198
|
end
|
199
199
|
|
200
200
|
it 'ignores nil group id' do
|
201
201
|
expect {
|
202
|
-
|
203
|
-
}.to_not change {
|
202
|
+
described_class.chown 42, nil, '/test-file'
|
203
|
+
}.to_not change { described_class.stat('/test-file').gid }
|
204
204
|
end
|
205
205
|
|
206
206
|
it 'ignores -1 user id' do
|
207
207
|
expect {
|
208
|
-
|
209
|
-
}.to_not change {
|
208
|
+
described_class.chown -1, 42, '/test-file'
|
209
|
+
}.to_not change { described_class.stat('/test-file').uid }
|
210
210
|
end
|
211
211
|
|
212
212
|
it 'ignores -1 group id' do
|
213
213
|
expect {
|
214
|
-
|
215
|
-
}.to_not change {
|
214
|
+
described_class.chown 42, -1, '/test-file'
|
215
|
+
}.to_not change { described_class.stat('/test-file').gid }
|
216
216
|
end
|
217
217
|
|
218
218
|
context 'when the named entry is a symlink' do
|
219
219
|
it 'changes the owner on the last target of the link chain' do
|
220
|
-
|
220
|
+
described_class.chown 42, nil, '/test-link'
|
221
221
|
|
222
|
-
uid =
|
222
|
+
uid = described_class.stat('/test-file').uid
|
223
223
|
expect(uid).to be 42
|
224
224
|
end
|
225
225
|
|
226
226
|
it 'changes the group on the last target of the link chain' do
|
227
|
-
|
227
|
+
described_class.chown nil, 42, '/test-link'
|
228
228
|
|
229
|
-
gid =
|
229
|
+
gid = described_class.stat('/test-file').gid
|
230
230
|
expect(gid).to be 42
|
231
231
|
end
|
232
232
|
|
233
233
|
it 'does not change the owner of the symlink' do
|
234
|
-
|
234
|
+
described_class.chown(42, nil, '/test-link')
|
235
235
|
|
236
|
-
uid =
|
236
|
+
uid = described_class.lstat('/test-link').uid
|
237
237
|
expect(uid).not_to be 42
|
238
238
|
end
|
239
239
|
|
240
240
|
it 'does not change the group of the symlink' do
|
241
|
-
|
241
|
+
described_class.chown nil, 42, '/test-link'
|
242
242
|
|
243
|
-
gid =
|
243
|
+
gid = described_class.lstat('/test-link').gid
|
244
244
|
expect(gid).not_to be 42
|
245
245
|
end
|
246
246
|
end
|
@@ -248,12 +248,12 @@ module MemFs
|
|
248
248
|
|
249
249
|
describe '.ctime' do
|
250
250
|
it 'returns the change time for the named file as a Time object' do
|
251
|
-
ctime =
|
251
|
+
ctime = described_class.ctime('/test-file')
|
252
252
|
expect(ctime).to be_a Time
|
253
253
|
end
|
254
254
|
|
255
255
|
it 'raises an error if the entry does not exist' do
|
256
|
-
expect {
|
256
|
+
expect { described_class.ctime '/no-file' }.to raise_error Errno::ENOENT
|
257
257
|
end
|
258
258
|
|
259
259
|
context 'when the entry is a symlink' do
|
@@ -261,16 +261,16 @@ module MemFs
|
|
261
261
|
|
262
262
|
it 'returns the last access time of the last target of the link chain' do
|
263
263
|
_fs.find!('/test-file').ctime = time
|
264
|
-
|
264
|
+
described_class.symlink '/test-link', '/test-link2'
|
265
265
|
|
266
|
-
ctime =
|
266
|
+
ctime = described_class.ctime('/test-link2')
|
267
267
|
expect(ctime).to eq time
|
268
268
|
end
|
269
269
|
end
|
270
270
|
end
|
271
271
|
|
272
272
|
describe '.delete' do
|
273
|
-
subject {
|
273
|
+
subject { described_class }
|
274
274
|
|
275
275
|
it_behaves_like 'aliased method', :delete, :unlink
|
276
276
|
end
|
@@ -278,14 +278,14 @@ module MemFs
|
|
278
278
|
describe '.directory?' do
|
279
279
|
context 'when the named entry is a directory' do
|
280
280
|
it 'returns true' do
|
281
|
-
is_directory =
|
281
|
+
is_directory = described_class.directory?('/test-dir')
|
282
282
|
expect(is_directory).to be true
|
283
283
|
end
|
284
284
|
end
|
285
285
|
|
286
286
|
context 'when the named entry is not a directory' do
|
287
287
|
it 'returns false' do
|
288
|
-
is_directory =
|
288
|
+
is_directory = described_class.directory?('/test-file')
|
289
289
|
expect(is_directory).to be false
|
290
290
|
end
|
291
291
|
end
|
@@ -293,12 +293,12 @@ module MemFs
|
|
293
293
|
|
294
294
|
describe '.dirname' do
|
295
295
|
it 'returns all components of the filename given in +file_name+ except the last one' do
|
296
|
-
dirname =
|
296
|
+
dirname = described_class.dirname('/path/to/some/file.txt')
|
297
297
|
expect(dirname).to eq '/path/to/some'
|
298
298
|
end
|
299
299
|
|
300
300
|
it 'returns / if file_name is /' do
|
301
|
-
dirname =
|
301
|
+
dirname = described_class.dirname('/')
|
302
302
|
expect(dirname).to eq '/'
|
303
303
|
end
|
304
304
|
end
|
@@ -309,13 +309,13 @@ module MemFs
|
|
309
309
|
let(:uid) { 0 }
|
310
310
|
|
311
311
|
before do
|
312
|
-
|
313
|
-
|
312
|
+
described_class.chmod access, '/test-file'
|
313
|
+
described_class.chown uid, gid, '/test-file'
|
314
314
|
end
|
315
315
|
|
316
316
|
context 'when the file is not executable by anyone' do
|
317
317
|
it 'return false' do
|
318
|
-
executable =
|
318
|
+
executable = described_class.executable?('/test-file')
|
319
319
|
expect(executable).to be false
|
320
320
|
end
|
321
321
|
end
|
@@ -324,12 +324,12 @@ module MemFs
|
|
324
324
|
let(:access) { MemFs::Fake::Entry::UEXEC }
|
325
325
|
|
326
326
|
context 'and the current user owns the file' do
|
327
|
-
before {
|
327
|
+
before { described_class.chown uid, 0, '/test-file' }
|
328
328
|
|
329
329
|
let(:uid) { Process.euid }
|
330
330
|
|
331
331
|
it 'returns true' do
|
332
|
-
executable =
|
332
|
+
executable = described_class.executable?('/test-file')
|
333
333
|
expect(executable).to be true
|
334
334
|
end
|
335
335
|
end
|
@@ -342,7 +342,7 @@ module MemFs
|
|
342
342
|
let(:gid) { Process.egid }
|
343
343
|
|
344
344
|
it 'returns true' do
|
345
|
-
executable =
|
345
|
+
executable = described_class.executable?('/test-file')
|
346
346
|
expect(executable).to be true
|
347
347
|
end
|
348
348
|
end
|
@@ -353,7 +353,7 @@ module MemFs
|
|
353
353
|
|
354
354
|
context 'and the user has no specific right on it' do
|
355
355
|
it 'returns true' do
|
356
|
-
executable =
|
356
|
+
executable = described_class.executable?('/test-file')
|
357
357
|
expect(executable).to be true
|
358
358
|
end
|
359
359
|
end
|
@@ -361,7 +361,7 @@ module MemFs
|
|
361
361
|
|
362
362
|
context 'when the file does not exist' do
|
363
363
|
it 'returns false' do
|
364
|
-
executable =
|
364
|
+
executable = described_class.executable?('/no-file')
|
365
365
|
expect(executable).to be false
|
366
366
|
end
|
367
367
|
end
|
@@ -373,13 +373,13 @@ module MemFs
|
|
373
373
|
let(:uid) { 0 }
|
374
374
|
|
375
375
|
before do
|
376
|
-
|
377
|
-
|
376
|
+
described_class.chmod access, '/test-file'
|
377
|
+
described_class.chown uid, gid, '/test-file'
|
378
378
|
end
|
379
379
|
|
380
380
|
context 'when the file is not executable by anyone' do
|
381
381
|
it 'return false' do
|
382
|
-
executable_real =
|
382
|
+
executable_real = described_class.executable_real?('/test-file')
|
383
383
|
expect(executable_real).to be false
|
384
384
|
end
|
385
385
|
end
|
@@ -390,10 +390,10 @@ module MemFs
|
|
390
390
|
context 'and the current user owns the file' do
|
391
391
|
let(:uid) { Process.uid }
|
392
392
|
|
393
|
-
before {
|
393
|
+
before { described_class.chown uid, 0, '/test-file' }
|
394
394
|
|
395
395
|
it 'returns true' do
|
396
|
-
executable_real =
|
396
|
+
executable_real = described_class.executable_real?('/test-file')
|
397
397
|
expect(executable_real).to be true
|
398
398
|
end
|
399
399
|
end
|
@@ -406,7 +406,7 @@ module MemFs
|
|
406
406
|
let(:gid) { Process.gid }
|
407
407
|
|
408
408
|
it 'returns true' do
|
409
|
-
executable_real =
|
409
|
+
executable_real = described_class.executable_real?('/test-file')
|
410
410
|
expect(executable_real).to be true
|
411
411
|
end
|
412
412
|
end
|
@@ -417,7 +417,7 @@ module MemFs
|
|
417
417
|
|
418
418
|
context 'and the user has no specific right on it' do
|
419
419
|
it 'returns true' do
|
420
|
-
executable_real =
|
420
|
+
executable_real = described_class.executable_real?('/test-file')
|
421
421
|
expect(executable_real).to be true
|
422
422
|
end
|
423
423
|
end
|
@@ -425,7 +425,7 @@ module MemFs
|
|
425
425
|
|
426
426
|
context 'when the file does not exist' do
|
427
427
|
it 'returns false' do
|
428
|
-
executable_real =
|
428
|
+
executable_real = described_class.executable_real?('/no-file')
|
429
429
|
expect(executable_real).to be false
|
430
430
|
end
|
431
431
|
end
|
@@ -434,21 +434,21 @@ module MemFs
|
|
434
434
|
describe '.exists?' do
|
435
435
|
context 'when the file exists' do
|
436
436
|
it 'returns true' do
|
437
|
-
exists =
|
437
|
+
exists = described_class.exists?('/test-file')
|
438
438
|
expect(exists).to be true
|
439
439
|
end
|
440
440
|
end
|
441
441
|
|
442
442
|
context 'when the file does not exist' do
|
443
443
|
it 'returns false' do
|
444
|
-
exists =
|
444
|
+
exists = described_class.exists?('/no-file')
|
445
445
|
expect(exists).to be false
|
446
446
|
end
|
447
447
|
end
|
448
448
|
end
|
449
449
|
|
450
450
|
describe '.exist?' do
|
451
|
-
subject {
|
451
|
+
subject { described_class }
|
452
452
|
|
453
453
|
it_behaves_like 'aliased method', :exist?, :exists?
|
454
454
|
end
|
@@ -457,20 +457,20 @@ module MemFs
|
|
457
457
|
it 'converts a pathname to an absolute pathname' do
|
458
458
|
_fs.chdir '/'
|
459
459
|
|
460
|
-
expanded_path =
|
460
|
+
expanded_path = described_class.expand_path('test-file')
|
461
461
|
expect(expanded_path).to eq '/test-file'
|
462
462
|
end
|
463
463
|
|
464
464
|
it 'references path from the current working directory' do
|
465
465
|
_fs.chdir '/test-dir'
|
466
466
|
|
467
|
-
expanded_path =
|
467
|
+
expanded_path = described_class.expand_path('test-file')
|
468
468
|
expect(expanded_path).to eq '/test-dir/test-file'
|
469
469
|
end
|
470
470
|
|
471
471
|
context 'when +dir_string+ is provided' do
|
472
472
|
it 'uses +dir_string+ as the stating point' do
|
473
|
-
expanded_path =
|
473
|
+
expanded_path = described_class.expand_path('test-file', '/test')
|
474
474
|
expect(expanded_path).to eq '/test/test-file'
|
475
475
|
end
|
476
476
|
end
|
@@ -478,21 +478,21 @@ module MemFs
|
|
478
478
|
|
479
479
|
describe '.extname' do
|
480
480
|
it 'returns the extension of the given path' do
|
481
|
-
extname =
|
481
|
+
extname = described_class.extname('test-file.txt')
|
482
482
|
expect(extname).to eq '.txt'
|
483
483
|
end
|
484
484
|
|
485
485
|
context 'when the given path starts with a period' do
|
486
486
|
context 'and the path has no extension' do
|
487
487
|
it 'returns an empty string' do
|
488
|
-
extname =
|
488
|
+
extname = described_class.extname('.test-file')
|
489
489
|
expect(extname).to eq ''
|
490
490
|
end
|
491
491
|
end
|
492
492
|
|
493
493
|
context 'and the path has an extension' do
|
494
494
|
it 'returns the extension' do
|
495
|
-
extname =
|
495
|
+
extname = described_class.extname('.test-file.txt')
|
496
496
|
expect(extname).to eq '.txt'
|
497
497
|
end
|
498
498
|
end
|
@@ -500,7 +500,7 @@ module MemFs
|
|
500
500
|
|
501
501
|
context 'when the period is the last character in path' do
|
502
502
|
it 'returns an empty string' do
|
503
|
-
extname =
|
503
|
+
extname = described_class.extname('test-subject.')
|
504
504
|
expect(extname).to eq ''
|
505
505
|
end
|
506
506
|
end
|
@@ -510,14 +510,14 @@ module MemFs
|
|
510
510
|
context 'when the named file exists' do
|
511
511
|
context 'and it is a regular file' do
|
512
512
|
it 'returns true' do
|
513
|
-
is_file =
|
513
|
+
is_file = described_class.file?('/test-file')
|
514
514
|
expect(is_file).to be true
|
515
515
|
end
|
516
516
|
end
|
517
517
|
|
518
518
|
context 'and it is not a regular file' do
|
519
519
|
it 'returns false' do
|
520
|
-
is_file =
|
520
|
+
is_file = described_class.file?('/test-dir')
|
521
521
|
expect(is_file).to be false
|
522
522
|
end
|
523
523
|
end
|
@@ -525,7 +525,7 @@ module MemFs
|
|
525
525
|
|
526
526
|
context 'when the named file does not exist' do
|
527
527
|
it 'returns false' do
|
528
|
-
is_file =
|
528
|
+
is_file = described_class.file?('/no-file')
|
529
529
|
expect(is_file).to be false
|
530
530
|
end
|
531
531
|
end
|
@@ -534,7 +534,7 @@ module MemFs
|
|
534
534
|
describe '.fnmatch' do
|
535
535
|
context 'when the given path matches against the given pattern' do
|
536
536
|
it 'returns true' do
|
537
|
-
matching =
|
537
|
+
matching = described_class.fnmatch('c?t', 'cat')
|
538
538
|
expect(matching).to be true
|
539
539
|
end
|
540
540
|
end
|
@@ -548,7 +548,7 @@ module MemFs
|
|
548
548
|
end
|
549
549
|
|
550
550
|
describe '.fnmatch?' do
|
551
|
-
subject {
|
551
|
+
subject { described_class }
|
552
552
|
|
553
553
|
it_behaves_like 'aliased method', :fnmatch?, :fnmatch
|
554
554
|
end
|
@@ -556,14 +556,14 @@ module MemFs
|
|
556
556
|
describe '.ftype' do
|
557
557
|
context 'when the named entry is a regular file' do
|
558
558
|
it "returns 'file'" do
|
559
|
-
ftype =
|
559
|
+
ftype = described_class.ftype('/test-file')
|
560
560
|
expect(ftype).to eq 'file'
|
561
561
|
end
|
562
562
|
end
|
563
563
|
|
564
564
|
context 'when the named entry is a directory' do
|
565
565
|
it "returns 'directory'" do
|
566
|
-
ftype =
|
566
|
+
ftype = described_class.ftype('/test-dir')
|
567
567
|
expect(ftype).to eq 'directory'
|
568
568
|
end
|
569
569
|
end
|
@@ -574,7 +574,7 @@ module MemFs
|
|
574
574
|
file = _fs.find('/block-file')
|
575
575
|
file.block_device = true
|
576
576
|
|
577
|
-
ftype =
|
577
|
+
ftype = described_class.ftype('/block-file')
|
578
578
|
expect(ftype).to eq 'blockSpecial'
|
579
579
|
end
|
580
580
|
end
|
@@ -585,14 +585,14 @@ module MemFs
|
|
585
585
|
file = _fs.find('/character-file')
|
586
586
|
file.character_device = true
|
587
587
|
|
588
|
-
ftype =
|
588
|
+
ftype = described_class.ftype('/character-file')
|
589
589
|
expect(ftype).to eq 'characterSpecial'
|
590
590
|
end
|
591
591
|
end
|
592
592
|
|
593
593
|
context 'when the named entry is a symlink' do
|
594
594
|
it "returns 'link'" do
|
595
|
-
ftype =
|
595
|
+
ftype = described_class.ftype('/test-link')
|
596
596
|
expect(ftype).to eq 'link'
|
597
597
|
end
|
598
598
|
end
|
@@ -604,7 +604,7 @@ module MemFs
|
|
604
604
|
root = _fs.find '/'
|
605
605
|
root.add_entry Fake::Entry.new('test-entry')
|
606
606
|
|
607
|
-
ftype =
|
607
|
+
ftype = described_class.ftype('/test-entry')
|
608
608
|
expect(ftype).to eq 'unknown'
|
609
609
|
end
|
610
610
|
end
|
@@ -614,7 +614,7 @@ module MemFs
|
|
614
614
|
context 'when the named file exists' do
|
615
615
|
context 'and the effective user group owns of the file' do
|
616
616
|
it 'returns true' do
|
617
|
-
|
617
|
+
described_class.chown 0, Process.egid, '/test-file'
|
618
618
|
|
619
619
|
grpowned = File.grpowned?('/test-file')
|
620
620
|
expect(grpowned).to be true
|
@@ -623,7 +623,7 @@ module MemFs
|
|
623
623
|
|
624
624
|
context 'and the effective user group does not own of the file' do
|
625
625
|
it 'returns false' do
|
626
|
-
|
626
|
+
described_class.chown 0, 0, '/test-file'
|
627
627
|
|
628
628
|
grpowned = File.grpowned?('/test-file')
|
629
629
|
expect(grpowned).to be false
|
@@ -641,30 +641,30 @@ module MemFs
|
|
641
641
|
|
642
642
|
describe '.identical?' do
|
643
643
|
before do
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
644
|
+
described_class.open('/test-file', 'w') { |f| f.puts 'test' }
|
645
|
+
described_class.open('/test-file2', 'w') { |f| f.puts 'test' }
|
646
|
+
described_class.symlink '/test-file', '/test-file-link'
|
647
|
+
described_class.symlink '/test-file', '/test-file-link2'
|
648
|
+
described_class.symlink '/test-file2', '/test-file2-link'
|
649
649
|
end
|
650
650
|
|
651
651
|
context 'when two paths represent the same path' do
|
652
652
|
it 'returns true' do
|
653
|
-
identical =
|
653
|
+
identical = described_class.identical?('/test-file', '/test-file')
|
654
654
|
expect(identical).to be true
|
655
655
|
end
|
656
656
|
end
|
657
657
|
|
658
658
|
context 'when two paths do not represent the same file' do
|
659
659
|
it 'returns false' do
|
660
|
-
identical =
|
660
|
+
identical = described_class.identical?('/test-file', '/test-file2')
|
661
661
|
expect(identical).to be false
|
662
662
|
end
|
663
663
|
end
|
664
664
|
|
665
665
|
context 'when one of the paths does not exist' do
|
666
666
|
it 'returns false' do
|
667
|
-
identical =
|
667
|
+
identical = described_class.identical?('/test-file', '/no-file')
|
668
668
|
expect(identical).to be false
|
669
669
|
end
|
670
670
|
end
|
@@ -672,14 +672,14 @@ module MemFs
|
|
672
672
|
context 'when a path is a symlink' do
|
673
673
|
context 'and the linked file is the same as the other path' do
|
674
674
|
it 'returns true' do
|
675
|
-
identical =
|
675
|
+
identical = described_class.identical?('/test-file', '/test-file-link')
|
676
676
|
expect(identical).to be true
|
677
677
|
end
|
678
678
|
end
|
679
679
|
|
680
680
|
context 'and the linked file is different from the other path' do
|
681
681
|
it 'returns false' do
|
682
|
-
identical =
|
682
|
+
identical = described_class.identical?('/test-file2', '/test-file-link')
|
683
683
|
expect(identical).to be false
|
684
684
|
end
|
685
685
|
end
|
@@ -688,14 +688,14 @@ module MemFs
|
|
688
688
|
context 'when the two paths are symlinks' do
|
689
689
|
context 'and both links point to the same file' do
|
690
690
|
it 'returns true' do
|
691
|
-
identical =
|
691
|
+
identical = described_class.identical?('/test-file-link', '/test-file-link2')
|
692
692
|
expect(identical).to be true
|
693
693
|
end
|
694
694
|
end
|
695
695
|
|
696
696
|
context 'and both links do not point to the same file' do
|
697
697
|
it 'returns false' do
|
698
|
-
identical =
|
698
|
+
identical = described_class.identical?('/test-file-link', '/test-file2-link')
|
699
699
|
expect(identical).to be false
|
700
700
|
end
|
701
701
|
end
|
@@ -704,7 +704,7 @@ module MemFs
|
|
704
704
|
|
705
705
|
describe '.join' do
|
706
706
|
it 'returns a new string formed by joining the strings using File::SEPARATOR' do
|
707
|
-
returned_value =
|
707
|
+
returned_value = described_class.join('a', 'b', 'c')
|
708
708
|
expect(returned_value).to eq 'a/b/c'
|
709
709
|
end
|
710
710
|
end
|
@@ -712,26 +712,26 @@ module MemFs
|
|
712
712
|
describe '.lchmod' do
|
713
713
|
context 'when the named file is a regular file' do
|
714
714
|
it 'acts like chmod' do
|
715
|
-
|
715
|
+
described_class.lchmod 0777, '/test-file'
|
716
716
|
|
717
|
-
mode =
|
717
|
+
mode = described_class.stat('/test-file').mode
|
718
718
|
expect(mode).to be 0100777
|
719
719
|
end
|
720
720
|
end
|
721
721
|
|
722
722
|
context 'when the named file is a symlink' do
|
723
723
|
it 'changes permission bits on the symlink' do
|
724
|
-
|
724
|
+
described_class.lchmod 0777, '/test-link'
|
725
725
|
|
726
|
-
mode =
|
726
|
+
mode = described_class.lstat('/test-link').mode
|
727
727
|
expect(mode).to be 0100777
|
728
728
|
end
|
729
729
|
|
730
730
|
it "does not change permission bits on the link's target" do
|
731
|
-
old_mode =
|
732
|
-
|
731
|
+
old_mode = described_class.stat('/test-file').mode
|
732
|
+
described_class.lchmod 0777, '/test-link'
|
733
733
|
|
734
|
-
mode =
|
734
|
+
mode = described_class.stat('/test-file').mode
|
735
735
|
expect(mode).to eq old_mode
|
736
736
|
end
|
737
737
|
end
|
@@ -739,36 +739,36 @@ module MemFs
|
|
739
739
|
|
740
740
|
describe '.link' do
|
741
741
|
before do
|
742
|
-
|
742
|
+
described_class.open('/test-file', 'w') { |f| f.puts 'test' }
|
743
743
|
end
|
744
744
|
|
745
745
|
it 'creates a new name for an existing file using a hard link' do
|
746
|
-
|
746
|
+
described_class.link '/test-file', '/new-file'
|
747
747
|
|
748
|
-
original_content =
|
749
|
-
copy_content =
|
748
|
+
original_content = described_class.read('/test-file')
|
749
|
+
copy_content = described_class.read('/new-file')
|
750
750
|
expect(copy_content).to eq original_content
|
751
751
|
end
|
752
752
|
|
753
753
|
it 'returns zero' do
|
754
|
-
returned_value =
|
754
|
+
returned_value = described_class.link('/test-file', '/new-file')
|
755
755
|
expect(returned_value).to be_zero
|
756
756
|
end
|
757
757
|
|
758
758
|
context 'when +old_name+ does not exist' do
|
759
759
|
it 'raises an exception' do
|
760
760
|
expect {
|
761
|
-
|
761
|
+
described_class.link '/no-file', '/nowhere'
|
762
762
|
}.to raise_error Errno::ENOENT
|
763
763
|
end
|
764
764
|
end
|
765
765
|
|
766
766
|
context 'when +new_name+ already exists' do
|
767
767
|
it 'raises an exception' do
|
768
|
-
|
768
|
+
described_class.open('/test-file2', 'w') { |f| f.puts 'test2' }
|
769
769
|
|
770
770
|
expect {
|
771
|
-
|
771
|
+
described_class.link '/test-file', '/test-file2'
|
772
772
|
}.to raise_error SystemCallError
|
773
773
|
end
|
774
774
|
end
|
@@ -776,26 +776,26 @@ module MemFs
|
|
776
776
|
|
777
777
|
describe '.lstat' do
|
778
778
|
it 'returns a File::Stat object for the named file' do
|
779
|
-
stat =
|
779
|
+
stat = described_class.lstat('/test-file')
|
780
780
|
expect(stat).to be_a File::Stat
|
781
781
|
end
|
782
782
|
|
783
783
|
context 'when the named file does not exist' do
|
784
784
|
it 'raises an exception' do
|
785
|
-
expect {
|
785
|
+
expect { described_class.lstat '/no-file' }.to raise_error Errno::ENOENT
|
786
786
|
end
|
787
787
|
end
|
788
788
|
|
789
789
|
context 'when the named file is a symlink' do
|
790
790
|
it 'does not follow the last symbolic link' do
|
791
|
-
is_symlink =
|
791
|
+
is_symlink = described_class.lstat('/test-link').symlink?
|
792
792
|
expect(is_symlink).to be true
|
793
793
|
end
|
794
794
|
|
795
795
|
context 'and its target does not exist' do
|
796
796
|
it 'ignores errors' do
|
797
797
|
expect {
|
798
|
-
|
798
|
+
described_class.lstat('/no-link')
|
799
799
|
}.not_to raise_error
|
800
800
|
end
|
801
801
|
end
|
@@ -805,7 +805,7 @@ module MemFs
|
|
805
805
|
describe '.new' do
|
806
806
|
context 'when the mode is provided' do
|
807
807
|
context 'and it is an integer' do
|
808
|
-
subject {
|
808
|
+
subject { described_class.new('/test-file', File::RDWR) }
|
809
809
|
|
810
810
|
it 'sets the mode to the integer value' do
|
811
811
|
expect(subject.send(:opening_mode)).to eq File::RDWR
|
@@ -814,47 +814,47 @@ module MemFs
|
|
814
814
|
|
815
815
|
context 'and it is a string' do
|
816
816
|
it 'sets the read mode for "r"' do
|
817
|
-
subject =
|
817
|
+
subject = described_class.new('/test-file', 'r')
|
818
818
|
expect(subject.send(:opening_mode)).to eq File::RDONLY
|
819
819
|
end
|
820
820
|
|
821
821
|
it 'sets the write+create+truncate mode for "w"' do
|
822
|
-
subject =
|
822
|
+
subject = described_class.new('/test-file', 'w')
|
823
823
|
expect(subject.send(:opening_mode)).to eq File::CREAT|File::TRUNC|File::WRONLY
|
824
824
|
end
|
825
825
|
|
826
826
|
it 'sets the read+write mode for "r+"' do
|
827
|
-
subject =
|
827
|
+
subject = described_class.new('/test-file', 'r+')
|
828
828
|
expect(subject.send(:opening_mode)).to eq File::RDWR
|
829
829
|
end
|
830
830
|
|
831
831
|
it 'sets the read+write+create+truncate mode for "w+"' do
|
832
|
-
subject =
|
832
|
+
subject = described_class.new('/test-file', 'w+')
|
833
833
|
expect(subject.send(:opening_mode)).to eq File::CREAT|File::TRUNC|File::RDWR
|
834
834
|
end
|
835
835
|
|
836
836
|
it 'sets the write+create+append mode for "a"' do
|
837
|
-
subject =
|
837
|
+
subject = described_class.new('/test-file', 'a')
|
838
838
|
expect(subject.send(:opening_mode)).to eq File::CREAT|File::APPEND|File::WRONLY
|
839
839
|
end
|
840
840
|
|
841
841
|
it 'sets the read+write+create+append mode for "a+"' do
|
842
|
-
subject =
|
842
|
+
subject = described_class.new('/test-file', 'a+')
|
843
843
|
expect(subject.send(:opening_mode)).to eq File::CREAT|File::APPEND|File::RDWR
|
844
844
|
end
|
845
845
|
|
846
846
|
it 'handles the :bom option' do
|
847
|
-
subject =
|
847
|
+
subject = described_class.new('/test-file', 'r:bom')
|
848
848
|
expect(subject.send(:opening_mode)).to eq File::RDONLY
|
849
849
|
end
|
850
850
|
|
851
851
|
it 'handles the |utf-8 option' do
|
852
|
-
subject =
|
852
|
+
subject = described_class.new('/test-file', 'r|utf-8')
|
853
853
|
expect(subject.send(:opening_mode)).to eq File::RDONLY
|
854
854
|
end
|
855
855
|
|
856
856
|
it 'handles the :bom|utf-8 option' do
|
857
|
-
subject =
|
857
|
+
subject = described_class.new('/test-file', 'r:bom|utf-8')
|
858
858
|
expect(subject.send(:opening_mode)).to eq File::RDONLY
|
859
859
|
end
|
860
860
|
end
|
@@ -862,8 +862,8 @@ module MemFs
|
|
862
862
|
context 'and it specifies that the file must be created' do
|
863
863
|
context 'and the file already exists' do
|
864
864
|
it 'changes the mtime of the file' do
|
865
|
-
|
866
|
-
|
865
|
+
described_class.new '/test-file', 'w'
|
866
|
+
described_class.exist?('/test-file')
|
867
867
|
end
|
868
868
|
end
|
869
869
|
end
|
@@ -871,11 +871,11 @@ module MemFs
|
|
871
871
|
context 'and it specifies that the file must be truncated' do
|
872
872
|
context 'and the file already exists' do
|
873
873
|
it 'truncates its content' do
|
874
|
-
|
875
|
-
file =
|
874
|
+
described_class.open('/test-file', 'w') { |f| f.puts 'hello' }
|
875
|
+
file = described_class.new('/test-file', 'w')
|
876
876
|
file.close
|
877
877
|
|
878
|
-
expect(
|
878
|
+
expect(described_class.read('/test-file')).to eq ''
|
879
879
|
end
|
880
880
|
end
|
881
881
|
end
|
@@ -883,13 +883,13 @@ module MemFs
|
|
883
883
|
|
884
884
|
context 'when no argument is given' do
|
885
885
|
it 'raises an exception' do
|
886
|
-
expect {
|
886
|
+
expect { described_class.new }.to raise_error ArgumentError
|
887
887
|
end
|
888
888
|
end
|
889
889
|
|
890
890
|
context 'when too many arguments are given' do
|
891
891
|
it 'raises an exception' do
|
892
|
-
expect {
|
892
|
+
expect { described_class.new(1, 2, 3, 4) }.to raise_error(ArgumentError)
|
893
893
|
end
|
894
894
|
end
|
895
895
|
end
|
@@ -898,7 +898,7 @@ module MemFs
|
|
898
898
|
context 'when the named file exists' do
|
899
899
|
context 'and the effective user owns of the file' do
|
900
900
|
it 'returns true' do
|
901
|
-
|
901
|
+
described_class.chown Process.euid, 0, '/test-file'
|
902
902
|
|
903
903
|
owned = File.owned?('/test-file')
|
904
904
|
expect(owned).to be true
|
@@ -907,7 +907,7 @@ module MemFs
|
|
907
907
|
|
908
908
|
context 'and the effective user does not own of the file' do
|
909
909
|
it 'returns false' do
|
910
|
-
|
910
|
+
described_class.chown 0, 0, '/test-file'
|
911
911
|
|
912
912
|
owned = File.owned?('/test-file')
|
913
913
|
expect(owned).to be false
|
@@ -926,14 +926,14 @@ module MemFs
|
|
926
926
|
describe '.path' do
|
927
927
|
context 'when the path is a string' do
|
928
928
|
it 'returns the string representation of the path' do
|
929
|
-
path =
|
929
|
+
path = described_class.path('/some/path')
|
930
930
|
expect(path).to eq '/some/path'
|
931
931
|
end
|
932
932
|
end
|
933
933
|
|
934
934
|
context 'when the path is a Pathname' do
|
935
935
|
it 'returns the string representation of the path' do
|
936
|
-
path =
|
936
|
+
path = described_class.path(Pathname.new('/some/path'))
|
937
937
|
expect(path).to eq '/some/path'
|
938
938
|
end
|
939
939
|
end
|
@@ -952,23 +952,23 @@ module MemFs
|
|
952
952
|
|
953
953
|
describe '.read' do
|
954
954
|
before do
|
955
|
-
|
955
|
+
described_class.open('/test-file', 'w') { |f| f.puts 'test' }
|
956
956
|
end
|
957
957
|
|
958
958
|
it 'reads the content of the given file' do
|
959
|
-
read_content =
|
959
|
+
read_content = described_class.read('/test-file')
|
960
960
|
expect(read_content).to eq "test\n"
|
961
961
|
end
|
962
962
|
|
963
963
|
context 'when +lenght+ is provided' do
|
964
964
|
it 'reads only +length+ characters' do
|
965
|
-
read_content =
|
965
|
+
read_content = described_class.read('/test-file', 2)
|
966
966
|
expect(read_content).to eq 'te'
|
967
967
|
end
|
968
968
|
|
969
969
|
context 'when +length+ is bigger than the file size' do
|
970
970
|
it 'reads until the end of the file' do
|
971
|
-
read_content =
|
971
|
+
read_content = described_class.read('/test-file', 1000)
|
972
972
|
expect(read_content).to eq "test\n"
|
973
973
|
end
|
974
974
|
end
|
@@ -976,33 +976,33 @@ module MemFs
|
|
976
976
|
|
977
977
|
context 'when +offset+ is provided' do
|
978
978
|
it 'starts reading from the offset' do
|
979
|
-
read_content =
|
979
|
+
read_content = described_class.read('/test-file', 2, 1)
|
980
980
|
expect(read_content).to eq 'es'
|
981
981
|
end
|
982
982
|
|
983
983
|
it 'raises an error if offset is negative' do
|
984
984
|
expect {
|
985
|
-
|
985
|
+
described_class.read '/test-file', 2, -1
|
986
986
|
}.to raise_error Errno::EINVAL
|
987
987
|
end
|
988
988
|
end
|
989
989
|
|
990
990
|
context 'when the last argument is a hash' do
|
991
991
|
it 'passes the contained options to +open+' do
|
992
|
-
expect(
|
992
|
+
expect(described_class).to receive(:open)
|
993
993
|
.with('/test-file', File::RDONLY, encoding: 'UTF-8')
|
994
994
|
.and_return(subject)
|
995
995
|
|
996
|
-
|
996
|
+
described_class.read '/test-file', encoding: 'UTF-8'
|
997
997
|
end
|
998
998
|
|
999
999
|
context 'when it contains the +open_args+ key' do
|
1000
1000
|
it 'takes precedence over the other options' do
|
1001
|
-
expect(
|
1001
|
+
expect(described_class).to receive(:open)
|
1002
1002
|
.with('/test-file', 'r')
|
1003
1003
|
.and_return(subject)
|
1004
1004
|
|
1005
|
-
|
1005
|
+
described_class.read '/test-file', mode: 'w', open_args: ['r']
|
1006
1006
|
end
|
1007
1007
|
end
|
1008
1008
|
end
|
@@ -1014,13 +1014,13 @@ module MemFs
|
|
1014
1014
|
let(:uid) { 0 }
|
1015
1015
|
|
1016
1016
|
before do
|
1017
|
-
|
1018
|
-
|
1017
|
+
described_class.chmod access, '/test-file'
|
1018
|
+
described_class.chown uid, gid, '/test-file'
|
1019
1019
|
end
|
1020
1020
|
|
1021
1021
|
context 'when the file is not readable by anyone' do
|
1022
1022
|
it 'return false' do
|
1023
|
-
readable =
|
1023
|
+
readable = described_class.readable?('/test-file')
|
1024
1024
|
expect(readable).to be false
|
1025
1025
|
end
|
1026
1026
|
end
|
@@ -1031,10 +1031,10 @@ module MemFs
|
|
1031
1031
|
context 'and the current user owns the file' do
|
1032
1032
|
let(:uid) { Process.euid }
|
1033
1033
|
|
1034
|
-
before {
|
1034
|
+
before { described_class.chown uid, 0, '/test-file' }
|
1035
1035
|
|
1036
1036
|
it 'returns true' do
|
1037
|
-
readable =
|
1037
|
+
readable = described_class.readable?('/test-file')
|
1038
1038
|
expect(readable).to be true
|
1039
1039
|
end
|
1040
1040
|
end
|
@@ -1047,7 +1047,7 @@ module MemFs
|
|
1047
1047
|
let(:gid) { Process.egid }
|
1048
1048
|
|
1049
1049
|
it 'returns true' do
|
1050
|
-
readable =
|
1050
|
+
readable = described_class.readable?('/test-file')
|
1051
1051
|
expect(readable).to be true
|
1052
1052
|
end
|
1053
1053
|
end
|
@@ -1058,7 +1058,7 @@ module MemFs
|
|
1058
1058
|
|
1059
1059
|
context 'and the user has no specific right on it' do
|
1060
1060
|
it 'returns true' do
|
1061
|
-
readable =
|
1061
|
+
readable = described_class.readable?('/test-file')
|
1062
1062
|
expect(readable).to be true
|
1063
1063
|
end
|
1064
1064
|
end
|
@@ -1066,7 +1066,7 @@ module MemFs
|
|
1066
1066
|
|
1067
1067
|
context 'when the file does not exist' do
|
1068
1068
|
it 'returns false' do
|
1069
|
-
readable =
|
1069
|
+
readable = described_class.readable?('/no-file')
|
1070
1070
|
expect(readable).to be false
|
1071
1071
|
end
|
1072
1072
|
end
|
@@ -1078,13 +1078,13 @@ module MemFs
|
|
1078
1078
|
let(:uid) { 0 }
|
1079
1079
|
|
1080
1080
|
before do
|
1081
|
-
|
1082
|
-
|
1081
|
+
described_class.chmod access, '/test-file'
|
1082
|
+
described_class.chown uid, gid, '/test-file'
|
1083
1083
|
end
|
1084
1084
|
|
1085
1085
|
context 'when the file is not readable by anyone' do
|
1086
1086
|
it 'return false' do
|
1087
|
-
readable_real =
|
1087
|
+
readable_real = described_class.readable_real?('/test-file')
|
1088
1088
|
expect(readable_real).to be false
|
1089
1089
|
end
|
1090
1090
|
end
|
@@ -1095,10 +1095,10 @@ module MemFs
|
|
1095
1095
|
context 'and the current user owns the file' do
|
1096
1096
|
let(:uid) { Process.uid }
|
1097
1097
|
|
1098
|
-
before {
|
1098
|
+
before { described_class.chown uid, 0, '/test-file' }
|
1099
1099
|
|
1100
1100
|
it 'returns true' do
|
1101
|
-
readable_real =
|
1101
|
+
readable_real = described_class.readable_real?('/test-file')
|
1102
1102
|
expect(readable_real).to be true
|
1103
1103
|
end
|
1104
1104
|
end
|
@@ -1111,7 +1111,7 @@ module MemFs
|
|
1111
1111
|
let(:gid) { Process.gid }
|
1112
1112
|
|
1113
1113
|
it 'returns true' do
|
1114
|
-
readable_real =
|
1114
|
+
readable_real = described_class.readable_real?('/test-file')
|
1115
1115
|
expect(readable_real).to be true
|
1116
1116
|
end
|
1117
1117
|
end
|
@@ -1122,7 +1122,7 @@ module MemFs
|
|
1122
1122
|
|
1123
1123
|
context 'and the user has no specific right on it' do
|
1124
1124
|
it 'returns true' do
|
1125
|
-
readable_real =
|
1125
|
+
readable_real = described_class.readable_real?('/test-file')
|
1126
1126
|
expect(readable_real).to be true
|
1127
1127
|
end
|
1128
1128
|
end
|
@@ -1130,7 +1130,7 @@ module MemFs
|
|
1130
1130
|
|
1131
1131
|
context 'when the file does not exist' do
|
1132
1132
|
it 'returns false' do
|
1133
|
-
readable_real =
|
1133
|
+
readable_real = described_class.readable_real?('/no-file')
|
1134
1134
|
expect(readable_real).to be false
|
1135
1135
|
end
|
1136
1136
|
end
|
@@ -1138,7 +1138,7 @@ module MemFs
|
|
1138
1138
|
|
1139
1139
|
describe '.readlink' do
|
1140
1140
|
it 'returns the name of the file referenced by the given link' do
|
1141
|
-
expect(
|
1141
|
+
expect(described_class.readlink('/test-link')).to eq '/test-file'
|
1142
1142
|
end
|
1143
1143
|
end
|
1144
1144
|
|
@@ -1151,7 +1151,7 @@ module MemFs
|
|
1151
1151
|
|
1152
1152
|
context 'when the path does not contain any symlink or useless dots' do
|
1153
1153
|
it 'returns the path itself' do
|
1154
|
-
path =
|
1154
|
+
path = described_class.realdirpath('/test-file')
|
1155
1155
|
expect(path).to eq '/test-file'
|
1156
1156
|
end
|
1157
1157
|
end
|
@@ -1159,14 +1159,14 @@ module MemFs
|
|
1159
1159
|
context 'when the path contains a symlink' do
|
1160
1160
|
context 'and the symlink is a middle part' do
|
1161
1161
|
it 'returns the path with the symlink dereferrenced' do
|
1162
|
-
path =
|
1162
|
+
path = described_class.realdirpath('/test-dir/sub-dir-link/test-file')
|
1163
1163
|
expect(path).to eq '/test-dir/sub-dir/test-file'
|
1164
1164
|
end
|
1165
1165
|
end
|
1166
1166
|
|
1167
1167
|
context 'and the symlink is the last part' do
|
1168
1168
|
it 'returns the path with the symlink dereferrenced' do
|
1169
|
-
path =
|
1169
|
+
path = described_class.realdirpath('/test-dir/sub-dir-link')
|
1170
1170
|
expect(path).to eq '/test-dir/sub-dir'
|
1171
1171
|
end
|
1172
1172
|
end
|
@@ -1174,7 +1174,7 @@ module MemFs
|
|
1174
1174
|
|
1175
1175
|
context 'when the path contains useless dots' do
|
1176
1176
|
it 'returns the path with the useless dots interpolated' do
|
1177
|
-
path =
|
1177
|
+
path = described_class.realdirpath('/test-dir/../test-dir/./sub-dir/test-file')
|
1178
1178
|
expect(path).to eq '/test-dir/sub-dir/test-file'
|
1179
1179
|
end
|
1180
1180
|
end
|
@@ -1183,14 +1183,14 @@ module MemFs
|
|
1183
1183
|
context 'and +dir_string+ is not provided' do
|
1184
1184
|
it 'uses the current working directory has base directory' do
|
1185
1185
|
_fs.chdir '/test-dir'
|
1186
|
-
path =
|
1186
|
+
path = described_class.realdirpath('../test-dir/./sub-dir/test-file')
|
1187
1187
|
expect(path).to eq '/test-dir/sub-dir/test-file'
|
1188
1188
|
end
|
1189
1189
|
end
|
1190
1190
|
|
1191
1191
|
context 'and +dir_string+ is provided' do
|
1192
1192
|
it 'uses the given directory has base directory' do
|
1193
|
-
path =
|
1193
|
+
path = described_class.realdirpath('../test-dir/./sub-dir/test-file', '/test-dir')
|
1194
1194
|
expect(path).to eq '/test-dir/sub-dir/test-file'
|
1195
1195
|
end
|
1196
1196
|
end
|
@@ -1203,7 +1203,7 @@ module MemFs
|
|
1203
1203
|
end
|
1204
1204
|
|
1205
1205
|
it 'uses the name of the target in the resulting path' do
|
1206
|
-
path =
|
1206
|
+
path = described_class.realdirpath('/test-dir/sub-dir/test-link')
|
1207
1207
|
expect(path).to eq '/test-dir/sub-dir/test'
|
1208
1208
|
end
|
1209
1209
|
end
|
@@ -1211,7 +1211,7 @@ module MemFs
|
|
1211
1211
|
|
1212
1212
|
context 'when the last part of the given path does not exist' do
|
1213
1213
|
it 'uses its name in the resulting path' do
|
1214
|
-
path =
|
1214
|
+
path = described_class.realdirpath('/test-dir/sub-dir/test')
|
1215
1215
|
expect(path).to eq '/test-dir/sub-dir/test'
|
1216
1216
|
end
|
1217
1217
|
end
|
@@ -1219,7 +1219,7 @@ module MemFs
|
|
1219
1219
|
context 'when a middle part of the given path does not exist' do
|
1220
1220
|
it 'raises an exception' do
|
1221
1221
|
expect {
|
1222
|
-
|
1222
|
+
described_class.realdirpath '/no-dir/test-file'
|
1223
1223
|
}.to raise_error
|
1224
1224
|
end
|
1225
1225
|
end
|
@@ -1234,7 +1234,7 @@ module MemFs
|
|
1234
1234
|
|
1235
1235
|
context 'when the path does not contain any symlink or useless dots' do
|
1236
1236
|
it 'returns the path itself' do
|
1237
|
-
path =
|
1237
|
+
path = described_class.realpath('/test-file')
|
1238
1238
|
expect(path).to eq '/test-file'
|
1239
1239
|
end
|
1240
1240
|
end
|
@@ -1242,14 +1242,14 @@ module MemFs
|
|
1242
1242
|
context 'when the path contains a symlink' do
|
1243
1243
|
context 'and the symlink is a middle part' do
|
1244
1244
|
it 'returns the path with the symlink dereferrenced' do
|
1245
|
-
path =
|
1245
|
+
path = described_class.realpath('/test-dir/sub-dir-link/test-file')
|
1246
1246
|
expect(path).to eq '/test-dir/sub-dir/test-file'
|
1247
1247
|
end
|
1248
1248
|
end
|
1249
1249
|
|
1250
1250
|
context 'and the symlink is the last part' do
|
1251
1251
|
it 'returns the path with the symlink dereferrenced' do
|
1252
|
-
path =
|
1252
|
+
path = described_class.realpath('/test-dir/sub-dir-link')
|
1253
1253
|
expect(path).to eq '/test-dir/sub-dir'
|
1254
1254
|
end
|
1255
1255
|
end
|
@@ -1257,7 +1257,7 @@ module MemFs
|
|
1257
1257
|
|
1258
1258
|
context 'when the path contains useless dots' do
|
1259
1259
|
it 'returns the path with the useless dots interpolated' do
|
1260
|
-
path =
|
1260
|
+
path = described_class.realpath('/test-dir/../test-dir/./sub-dir/test-file')
|
1261
1261
|
expect(path).to eq '/test-dir/sub-dir/test-file'
|
1262
1262
|
end
|
1263
1263
|
end
|
@@ -1267,14 +1267,14 @@ module MemFs
|
|
1267
1267
|
it 'uses the current working directory has base directory' do
|
1268
1268
|
_fs.chdir '/test-dir'
|
1269
1269
|
|
1270
|
-
path =
|
1270
|
+
path = described_class.realpath('../test-dir/./sub-dir/test-file')
|
1271
1271
|
expect(path).to eq '/test-dir/sub-dir/test-file'
|
1272
1272
|
end
|
1273
1273
|
end
|
1274
1274
|
|
1275
1275
|
context 'and +dir_string+ is provided' do
|
1276
1276
|
it 'uses the given directory has base directory' do
|
1277
|
-
path =
|
1277
|
+
path = described_class.realpath('../test-dir/./sub-dir/test-file', '/test-dir')
|
1278
1278
|
expect(path).to eq '/test-dir/sub-dir/test-file'
|
1279
1279
|
end
|
1280
1280
|
end
|
@@ -1283,7 +1283,7 @@ module MemFs
|
|
1283
1283
|
context 'when a part of the given path does not exist' do
|
1284
1284
|
it 'raises an exception' do
|
1285
1285
|
expect {
|
1286
|
-
|
1286
|
+
described_class.realpath '/no-dir/test-file'
|
1287
1287
|
}.to raise_error
|
1288
1288
|
end
|
1289
1289
|
end
|
@@ -1291,14 +1291,14 @@ module MemFs
|
|
1291
1291
|
|
1292
1292
|
describe '.rename' do
|
1293
1293
|
it 'renames the given file to the new name' do
|
1294
|
-
|
1294
|
+
described_class.rename '/test-file', '/test-file2'
|
1295
1295
|
|
1296
|
-
exists =
|
1296
|
+
exists = described_class.exists?('/test-file2')
|
1297
1297
|
expect(exists).to be true
|
1298
1298
|
end
|
1299
1299
|
|
1300
1300
|
it 'returns zero' do
|
1301
|
-
returned_value =
|
1301
|
+
returned_value = described_class.rename('/test-file', '/test-file2')
|
1302
1302
|
expect(returned_value).to be_zero
|
1303
1303
|
end
|
1304
1304
|
end
|
@@ -1359,9 +1359,9 @@ module MemFs
|
|
1359
1359
|
|
1360
1360
|
describe '.size' do
|
1361
1361
|
it 'returns the size of the file' do
|
1362
|
-
|
1362
|
+
described_class.open('/test-file', 'w') { |f| f.puts random_string }
|
1363
1363
|
|
1364
|
-
size =
|
1364
|
+
size = described_class.size('/test-file')
|
1365
1365
|
expect(size).to eq random_string.size + 1
|
1366
1366
|
end
|
1367
1367
|
end
|
@@ -1406,26 +1406,26 @@ module MemFs
|
|
1406
1406
|
|
1407
1407
|
describe '.split' do
|
1408
1408
|
it 'splits the given string into a directory and a file component' do
|
1409
|
-
returned_value =
|
1409
|
+
returned_value = described_class.split('/path/to/some-file')
|
1410
1410
|
expect(returned_value).to eq ['/path/to', 'some-file']
|
1411
1411
|
end
|
1412
1412
|
end
|
1413
1413
|
|
1414
1414
|
describe '.stat' do
|
1415
1415
|
it 'returns a File::Stat object for the named file' do
|
1416
|
-
stat =
|
1416
|
+
stat = described_class.stat('/test-file')
|
1417
1417
|
expect(stat).to be_a File::Stat
|
1418
1418
|
end
|
1419
1419
|
|
1420
1420
|
it 'follows the last symbolic link' do
|
1421
|
-
stat =
|
1421
|
+
stat = described_class.stat('/test-link').symlink?
|
1422
1422
|
expect(stat).to be false
|
1423
1423
|
end
|
1424
1424
|
|
1425
1425
|
context 'when the named file does not exist' do
|
1426
1426
|
it 'raises an exception' do
|
1427
1427
|
expect {
|
1428
|
-
|
1428
|
+
described_class.stat('/no-file')
|
1429
1429
|
}.to raise_error Errno::ENOENT
|
1430
1430
|
end
|
1431
1431
|
end
|
@@ -1434,15 +1434,15 @@ module MemFs
|
|
1434
1434
|
context 'and its target does not exist' do
|
1435
1435
|
it 'raises an exception' do
|
1436
1436
|
expect {
|
1437
|
-
|
1437
|
+
described_class.stat('/no-link')
|
1438
1438
|
}.to raise_error Errno::ENOENT
|
1439
1439
|
end
|
1440
1440
|
end
|
1441
1441
|
end
|
1442
1442
|
|
1443
1443
|
it 'always returns a new object' do
|
1444
|
-
stat_1 =
|
1445
|
-
stat_2 =
|
1444
|
+
stat_1 = described_class.stat('/test-file')
|
1445
|
+
stat_2 = described_class.stat('/test-file')
|
1446
1446
|
|
1447
1447
|
expect(stat_2).not_to be stat_1
|
1448
1448
|
end
|
@@ -1476,7 +1476,7 @@ module MemFs
|
|
1476
1476
|
|
1477
1477
|
describe '.symlink' do
|
1478
1478
|
it 'creates a symbolic link named new_name' do
|
1479
|
-
is_symlink =
|
1479
|
+
is_symlink = described_class.symlink?('/test-link')
|
1480
1480
|
expect(is_symlink).to be true
|
1481
1481
|
end
|
1482
1482
|
|
@@ -1487,13 +1487,13 @@ module MemFs
|
|
1487
1487
|
|
1488
1488
|
context 'when the target does not exist' do
|
1489
1489
|
it 'creates a symbolic link' do
|
1490
|
-
is_symlink =
|
1490
|
+
is_symlink = described_class.symlink?('/no-link')
|
1491
1491
|
expect(is_symlink).to be true
|
1492
1492
|
end
|
1493
1493
|
end
|
1494
1494
|
|
1495
1495
|
it 'returns 0' do
|
1496
|
-
returned_value =
|
1496
|
+
returned_value = described_class.symlink('/test-file', '/new-link')
|
1497
1497
|
expect(returned_value).to be_zero
|
1498
1498
|
end
|
1499
1499
|
end
|
@@ -1501,21 +1501,21 @@ module MemFs
|
|
1501
1501
|
describe '.symlink?' do
|
1502
1502
|
context 'when the named entry is a symlink' do
|
1503
1503
|
it 'returns true' do
|
1504
|
-
is_symlink =
|
1504
|
+
is_symlink = described_class.symlink?('/test-link')
|
1505
1505
|
expect(is_symlink).to be true
|
1506
1506
|
end
|
1507
1507
|
end
|
1508
1508
|
|
1509
1509
|
context 'when the named entry is not a symlink' do
|
1510
1510
|
it 'returns false' do
|
1511
|
-
is_symlink =
|
1511
|
+
is_symlink = described_class.symlink?('/test-file')
|
1512
1512
|
expect(is_symlink).to be false
|
1513
1513
|
end
|
1514
1514
|
end
|
1515
1515
|
|
1516
1516
|
context 'when the named entry does not exist' do
|
1517
1517
|
it 'returns false' do
|
1518
|
-
is_symlink =
|
1518
|
+
is_symlink = described_class.symlink?('/no-file')
|
1519
1519
|
expect(is_symlink).to be false
|
1520
1520
|
end
|
1521
1521
|
end
|
@@ -1523,49 +1523,49 @@ module MemFs
|
|
1523
1523
|
|
1524
1524
|
describe '.truncate' do
|
1525
1525
|
before do
|
1526
|
-
|
1526
|
+
described_class.open('/test-file', 'w') { |f| f.write 'x' * 50 }
|
1527
1527
|
end
|
1528
1528
|
|
1529
1529
|
it 'truncates the named file to the given size' do
|
1530
|
-
|
1530
|
+
described_class.truncate('/test-file', 5)
|
1531
1531
|
|
1532
|
-
size =
|
1532
|
+
size = described_class.size('/test-file')
|
1533
1533
|
expect(size).to be 5
|
1534
1534
|
end
|
1535
1535
|
|
1536
1536
|
it 'returns zero' do
|
1537
|
-
returned_value =
|
1537
|
+
returned_value = described_class.truncate('/test-file', 5)
|
1538
1538
|
expect(returned_value).to be_zero
|
1539
1539
|
end
|
1540
1540
|
|
1541
1541
|
context 'when the named file does not exist' do
|
1542
1542
|
it 'raises an exception' do
|
1543
|
-
expect {
|
1543
|
+
expect { described_class.truncate '/no-file', 5 }.to raise_error
|
1544
1544
|
end
|
1545
1545
|
end
|
1546
1546
|
|
1547
1547
|
context 'when the given size is negative' do
|
1548
1548
|
it 'it raises an exception' do
|
1549
|
-
expect {
|
1549
|
+
expect { described_class.truncate '/test-file', -1 }.to raise_error
|
1550
1550
|
end
|
1551
1551
|
end
|
1552
1552
|
end
|
1553
1553
|
|
1554
1554
|
describe '.umask' do
|
1555
|
-
before {
|
1555
|
+
before { described_class.umask 0022 }
|
1556
1556
|
|
1557
1557
|
it 'returns the current umask value for this process' do
|
1558
|
-
expect(
|
1558
|
+
expect(described_class.umask).to be 0022
|
1559
1559
|
end
|
1560
1560
|
|
1561
1561
|
context 'when the optional argument is given' do
|
1562
1562
|
it 'sets the umask to that value' do
|
1563
|
-
|
1564
|
-
expect(
|
1563
|
+
described_class.umask 0777
|
1564
|
+
expect(described_class.umask).to be 0777
|
1565
1565
|
end
|
1566
1566
|
|
1567
1567
|
it 'return the previous value' do
|
1568
|
-
previous_umask =
|
1568
|
+
previous_umask = described_class.umask(0777)
|
1569
1569
|
expect(previous_umask).to be 0022
|
1570
1570
|
end
|
1571
1571
|
end
|
@@ -1573,22 +1573,22 @@ module MemFs
|
|
1573
1573
|
|
1574
1574
|
describe '.unlink' do
|
1575
1575
|
it 'deletes the named file' do
|
1576
|
-
|
1576
|
+
described_class.unlink('/test-file')
|
1577
1577
|
|
1578
|
-
exists =
|
1578
|
+
exists = described_class.exists?('/test-file')
|
1579
1579
|
expect(exists).to be false
|
1580
1580
|
end
|
1581
1581
|
|
1582
1582
|
it 'returns the number of names passed as arguments' do
|
1583
|
-
returned_value =
|
1583
|
+
returned_value = described_class.unlink('/test-file', '/test-file2')
|
1584
1584
|
expect(returned_value).to be 2
|
1585
1585
|
end
|
1586
1586
|
|
1587
1587
|
context 'when multiple file names are given' do
|
1588
1588
|
it 'deletes the named files' do
|
1589
|
-
|
1589
|
+
described_class.unlink '/test-file', '/test-file2'
|
1590
1590
|
|
1591
|
-
exists =
|
1591
|
+
exists = described_class.exists?('/test-file2')
|
1592
1592
|
expect(exists).to be false
|
1593
1593
|
end
|
1594
1594
|
end
|
@@ -1596,7 +1596,7 @@ module MemFs
|
|
1596
1596
|
context 'when the entry is a directory' do
|
1597
1597
|
it 'raises an exception' do
|
1598
1598
|
expect {
|
1599
|
-
|
1599
|
+
described_class.unlink '/test-dir'
|
1600
1600
|
}.to raise_error Errno::EPERM
|
1601
1601
|
end
|
1602
1602
|
end
|
@@ -1606,39 +1606,39 @@ module MemFs
|
|
1606
1606
|
let(:time) { Time.now - 500_000 }
|
1607
1607
|
|
1608
1608
|
it 'sets the access time of each named file to the first argument' do
|
1609
|
-
|
1609
|
+
described_class.utime time, time, '/test-file'
|
1610
1610
|
|
1611
|
-
atime =
|
1611
|
+
atime = described_class.atime('/test-file')
|
1612
1612
|
expect(atime).to eq time
|
1613
1613
|
end
|
1614
1614
|
|
1615
1615
|
it 'sets the modification time of each named file to the second argument' do
|
1616
|
-
|
1616
|
+
described_class.utime time, time, '/test-file'
|
1617
1617
|
|
1618
|
-
mtime =
|
1618
|
+
mtime = described_class.mtime('/test-file')
|
1619
1619
|
expect(mtime).to eq time
|
1620
1620
|
end
|
1621
1621
|
|
1622
1622
|
it 'returns the number of file names in the argument list' do
|
1623
|
-
utime =
|
1623
|
+
utime = described_class.utime(time, time, '/test-file', '/test-file2')
|
1624
1624
|
expect(utime).to be 2
|
1625
1625
|
end
|
1626
1626
|
|
1627
1627
|
it 'raises en error if the entry does not exist' do
|
1628
1628
|
expect {
|
1629
|
-
|
1629
|
+
described_class.utime time, time, '/no-file'
|
1630
1630
|
}.to raise_error Errno::ENOENT
|
1631
1631
|
end
|
1632
1632
|
end
|
1633
1633
|
|
1634
1634
|
describe '.world_readable?' do
|
1635
|
-
before {
|
1635
|
+
before { described_class.chmod access, '/test-file' }
|
1636
1636
|
|
1637
1637
|
context 'when file_name is readable by others' do
|
1638
1638
|
let(:access) { MemFs::Fake::Entry::OREAD }
|
1639
1639
|
|
1640
1640
|
it 'returns an integer representing the file permission bits' do
|
1641
|
-
world_readable =
|
1641
|
+
world_readable = described_class.world_readable?('/test-file')
|
1642
1642
|
expect(world_readable).to eq MemFs::Fake::Entry::OREAD
|
1643
1643
|
end
|
1644
1644
|
end
|
@@ -1647,20 +1647,20 @@ module MemFs
|
|
1647
1647
|
let(:access) { MemFs::Fake::Entry::UREAD }
|
1648
1648
|
|
1649
1649
|
it 'returns nil' do
|
1650
|
-
world_readable =
|
1650
|
+
world_readable = described_class.world_readable?('/test-file')
|
1651
1651
|
expect(world_readable).to be_nil
|
1652
1652
|
end
|
1653
1653
|
end
|
1654
1654
|
end
|
1655
1655
|
|
1656
1656
|
describe '.world_writable?' do
|
1657
|
-
before {
|
1657
|
+
before { described_class.chmod access, '/test-file' }
|
1658
1658
|
|
1659
1659
|
context 'when file_name is writable by others' do
|
1660
1660
|
let(:access) { MemFs::Fake::Entry::OWRITE }
|
1661
1661
|
|
1662
1662
|
it 'returns an integer representing the file permission bits' do
|
1663
|
-
world_writable =
|
1663
|
+
world_writable = described_class.world_writable?('/test-file')
|
1664
1664
|
expect(world_writable).to eq MemFs::Fake::Entry::OWRITE
|
1665
1665
|
end
|
1666
1666
|
end
|
@@ -1669,7 +1669,7 @@ module MemFs
|
|
1669
1669
|
let(:access) { MemFs::Fake::Entry::UWRITE }
|
1670
1670
|
|
1671
1671
|
it 'returns nil' do
|
1672
|
-
world_writable =
|
1672
|
+
world_writable = described_class.world_writable?('/test-file')
|
1673
1673
|
expect(world_writable).to be_nil
|
1674
1674
|
end
|
1675
1675
|
end
|
@@ -1681,13 +1681,13 @@ module MemFs
|
|
1681
1681
|
let(:uid) { 0 }
|
1682
1682
|
|
1683
1683
|
before do
|
1684
|
-
|
1685
|
-
|
1684
|
+
described_class.chmod access, '/test-file'
|
1685
|
+
described_class.chown uid, gid, '/test-file'
|
1686
1686
|
end
|
1687
1687
|
|
1688
1688
|
context 'when the file is not writable by anyone' do
|
1689
1689
|
it 'return false' do
|
1690
|
-
writable =
|
1690
|
+
writable = described_class.writable?('/test-file')
|
1691
1691
|
expect(writable).to be false
|
1692
1692
|
end
|
1693
1693
|
end
|
@@ -1696,12 +1696,12 @@ module MemFs
|
|
1696
1696
|
let(:access) { MemFs::Fake::Entry::UWRITE }
|
1697
1697
|
|
1698
1698
|
context 'and the current user owns the file' do
|
1699
|
-
before {
|
1699
|
+
before { described_class.chown uid, 0, '/test-file' }
|
1700
1700
|
|
1701
1701
|
let(:uid) { Process.euid }
|
1702
1702
|
|
1703
1703
|
it 'returns true' do
|
1704
|
-
writable =
|
1704
|
+
writable = described_class.writable?('/test-file')
|
1705
1705
|
expect(writable).to be true
|
1706
1706
|
end
|
1707
1707
|
end
|
@@ -1714,7 +1714,7 @@ module MemFs
|
|
1714
1714
|
let(:gid) { Process.egid }
|
1715
1715
|
|
1716
1716
|
it 'returns true' do
|
1717
|
-
writable =
|
1717
|
+
writable = described_class.writable?('/test-file')
|
1718
1718
|
expect(writable).to be true
|
1719
1719
|
end
|
1720
1720
|
end
|
@@ -1725,7 +1725,7 @@ module MemFs
|
|
1725
1725
|
|
1726
1726
|
context 'and the user has no specific right on it' do
|
1727
1727
|
it 'returns true' do
|
1728
|
-
writable =
|
1728
|
+
writable = described_class.writable?('/test-file')
|
1729
1729
|
expect(writable).to be true
|
1730
1730
|
end
|
1731
1731
|
end
|
@@ -1733,7 +1733,7 @@ module MemFs
|
|
1733
1733
|
|
1734
1734
|
context 'when the file does not exist' do
|
1735
1735
|
it 'returns false' do
|
1736
|
-
writable =
|
1736
|
+
writable = described_class.writable?('/no-file')
|
1737
1737
|
expect(writable).to be false
|
1738
1738
|
end
|
1739
1739
|
end
|
@@ -1745,13 +1745,13 @@ module MemFs
|
|
1745
1745
|
let(:uid) { 0 }
|
1746
1746
|
|
1747
1747
|
before do
|
1748
|
-
|
1749
|
-
|
1748
|
+
described_class.chmod access, '/test-file'
|
1749
|
+
described_class.chown uid, gid, '/test-file'
|
1750
1750
|
end
|
1751
1751
|
|
1752
1752
|
context 'when the file is not writable by anyone' do
|
1753
1753
|
it 'return false' do
|
1754
|
-
writable_real =
|
1754
|
+
writable_real = described_class.writable_real?('/test-file')
|
1755
1755
|
expect(writable_real).to be false
|
1756
1756
|
end
|
1757
1757
|
end
|
@@ -1762,10 +1762,10 @@ module MemFs
|
|
1762
1762
|
context 'and the current user owns the file' do
|
1763
1763
|
let(:uid) { Process.uid }
|
1764
1764
|
|
1765
|
-
before {
|
1765
|
+
before { described_class.chown uid, 0, '/test-file' }
|
1766
1766
|
|
1767
1767
|
it 'returns true' do
|
1768
|
-
writable_real =
|
1768
|
+
writable_real = described_class.writable_real?('/test-file')
|
1769
1769
|
expect(writable_real).to be true
|
1770
1770
|
end
|
1771
1771
|
end
|
@@ -1778,7 +1778,7 @@ module MemFs
|
|
1778
1778
|
let(:gid) { Process.gid }
|
1779
1779
|
|
1780
1780
|
it 'returns true' do
|
1781
|
-
writable_real =
|
1781
|
+
writable_real = described_class.writable_real?('/test-file')
|
1782
1782
|
expect(writable_real).to be true
|
1783
1783
|
end
|
1784
1784
|
end
|
@@ -1789,7 +1789,7 @@ module MemFs
|
|
1789
1789
|
|
1790
1790
|
context 'and the user has no specific right on it' do
|
1791
1791
|
it 'returns true' do
|
1792
|
-
writable_real =
|
1792
|
+
writable_real = described_class.writable_real?('/test-file')
|
1793
1793
|
expect(writable_real).to be true
|
1794
1794
|
end
|
1795
1795
|
end
|
@@ -1797,7 +1797,7 @@ module MemFs
|
|
1797
1797
|
|
1798
1798
|
context 'when the file does not exist' do
|
1799
1799
|
it 'returns false' do
|
1800
|
-
writable_real =
|
1800
|
+
writable_real = described_class.writable_real?('/no-file')
|
1801
1801
|
expect(writable_real).to be false
|
1802
1802
|
end
|
1803
1803
|
end
|
@@ -1807,7 +1807,7 @@ module MemFs
|
|
1807
1807
|
context 'when the named file exists' do
|
1808
1808
|
context 'and has a zero size' do
|
1809
1809
|
it 'returns true' do
|
1810
|
-
zero =
|
1810
|
+
zero = described_class.zero?('/test-file')
|
1811
1811
|
expect(zero).to be true
|
1812
1812
|
end
|
1813
1813
|
end
|
@@ -1818,7 +1818,7 @@ module MemFs
|
|
1818
1818
|
end
|
1819
1819
|
|
1820
1820
|
it 'returns false' do
|
1821
|
-
zero =
|
1821
|
+
zero = described_class.zero?('/test-file')
|
1822
1822
|
expect(zero).to be false
|
1823
1823
|
end
|
1824
1824
|
end
|
@@ -1826,7 +1826,7 @@ module MemFs
|
|
1826
1826
|
|
1827
1827
|
context 'when the named file does not exist' do
|
1828
1828
|
it 'returns false' do
|
1829
|
-
zero =
|
1829
|
+
zero = described_class.zero?('/no-file')
|
1830
1830
|
expect(zero).to be false
|
1831
1831
|
end
|
1832
1832
|
end
|
@@ -2034,7 +2034,7 @@ module MemFs
|
|
2034
2034
|
end
|
2035
2035
|
|
2036
2036
|
context 'when the named entry is a symlink' do
|
2037
|
-
let(:symlink) {
|
2037
|
+
let(:symlink) { described_class.new('/test-link') }
|
2038
2038
|
|
2039
2039
|
it 'changes the owner on the last target of the link chain' do
|
2040
2040
|
symlink.chown 42, nil
|
@@ -2169,7 +2169,7 @@ module MemFs
|
|
2169
2169
|
|
2170
2170
|
describe '#each_byte' do
|
2171
2171
|
before do
|
2172
|
-
|
2172
|
+
described_class.open('/test-file', 'w') { |f| f << 'test' }
|
2173
2173
|
end
|
2174
2174
|
|
2175
2175
|
it 'calls the given block once for each byte of the file' do
|
@@ -2206,7 +2206,7 @@ module MemFs
|
|
2206
2206
|
|
2207
2207
|
describe '#each_char' do
|
2208
2208
|
before do
|
2209
|
-
|
2209
|
+
described_class.open('/test-file', 'w') { |f| f << 'test' }
|
2210
2210
|
end
|
2211
2211
|
|
2212
2212
|
it 'calls the given block once for each byte of the file' do
|
@@ -2326,7 +2326,7 @@ module MemFs
|
|
2326
2326
|
end
|
2327
2327
|
|
2328
2328
|
it 'does not follow the last symbolic link' do
|
2329
|
-
file =
|
2329
|
+
file = described_class.new('/test-link')
|
2330
2330
|
|
2331
2331
|
is_symlink = file.lstat.symlink?
|
2332
2332
|
expect(is_symlink).to be true
|
@@ -2335,7 +2335,7 @@ module MemFs
|
|
2335
2335
|
context 'when the named file is a symlink' do
|
2336
2336
|
context 'and its target does not exist' do
|
2337
2337
|
it 'ignores errors' do
|
2338
|
-
file =
|
2338
|
+
file = described_class.new('/no-link')
|
2339
2339
|
expect { file.lstat }.not_to raise_error
|
2340
2340
|
end
|
2341
2341
|
end
|
@@ -2525,7 +2525,7 @@ module MemFs
|
|
2525
2525
|
|
2526
2526
|
describe '#path' do
|
2527
2527
|
it 'returns the path of the file' do
|
2528
|
-
file =
|
2528
|
+
file = described_class.new('/test-file')
|
2529
2529
|
expect(file.path).to eq '/test-file'
|
2530
2530
|
end
|
2531
2531
|
end
|
@@ -2628,9 +2628,9 @@ module MemFs
|
|
2628
2628
|
|
2629
2629
|
describe '#size' do
|
2630
2630
|
it 'returns the size of the file' do
|
2631
|
-
|
2631
|
+
described_class.open('/test-file', 'w') { |f| f.puts random_string }
|
2632
2632
|
|
2633
|
-
size =
|
2633
|
+
size = described_class.new('/test-file').size
|
2634
2634
|
expect(size).to eq random_string.size + 1
|
2635
2635
|
end
|
2636
2636
|
end
|
@@ -2643,18 +2643,18 @@ module MemFs
|
|
2643
2643
|
|
2644
2644
|
describe '#truncate' do
|
2645
2645
|
it 'truncates the given file to be at most integer bytes long' do
|
2646
|
-
|
2646
|
+
described_class.open('/test-file', 'w') do |f|
|
2647
2647
|
f.puts 'this is a 24-char string'
|
2648
2648
|
f.truncate 10
|
2649
2649
|
f.close
|
2650
2650
|
end
|
2651
2651
|
|
2652
|
-
size =
|
2652
|
+
size = described_class.size('/test-file')
|
2653
2653
|
expect(size).to eq 10
|
2654
2654
|
end
|
2655
2655
|
|
2656
2656
|
it 'returns zero' do
|
2657
|
-
|
2657
|
+
described_class.open('/test-file', 'w') do |f|
|
2658
2658
|
returned_value = f.truncate(42)
|
2659
2659
|
expect(returned_value).to be_zero
|
2660
2660
|
end
|