memfs 0.4.1 → 0.4.2
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 +7 -0
- data/.rubocop.yml +29 -0
- data/CHANGELOG.md +7 -0
- data/Guardfile +5 -6
- data/README.md +6 -6
- data/Rakefile +9 -1
- data/lib/memfs.rb +6 -4
- data/lib/memfs/dir.rb +17 -21
- data/lib/memfs/fake/entry.rb +2 -2
- data/lib/memfs/fake/file/content.rb +3 -2
- data/lib/memfs/file.rb +54 -116
- data/lib/memfs/file/stat.rb +2 -2
- data/lib/memfs/file_system.rb +11 -13
- data/lib/memfs/io.rb +201 -0
- data/lib/memfs/version.rb +1 -1
- data/memfs.gemspec +17 -17
- data/memfs.png +0 -0
- data/spec/fileutils_spec.rb +233 -228
- data/spec/memfs/dir_spec.rb +76 -76
- data/spec/memfs/fake/directory_spec.rb +20 -20
- data/spec/memfs/fake/entry_spec.rb +24 -24
- data/spec/memfs/fake/file/content_spec.rb +43 -45
- data/spec/memfs/fake/file_spec.rb +14 -14
- data/spec/memfs/fake/symlink_spec.rb +22 -22
- data/spec/memfs/file/stat_spec.rb +314 -314
- data/spec/memfs/file_spec.rb +1636 -970
- data/spec/memfs/file_system_spec.rb +83 -83
- data/spec/memfs_spec.rb +15 -15
- data/spec/spec_helper.rb +17 -1
- metadata +36 -57
data/spec/memfs/dir_spec.rb
CHANGED
@@ -27,37 +27,37 @@ module MemFs
|
|
27
27
|
end
|
28
28
|
|
29
29
|
describe '.chdir' do
|
30
|
-
it
|
30
|
+
it 'changes the current working directory' do
|
31
31
|
subject.chdir '/test'
|
32
32
|
expect(subject.getwd).to eq('/test')
|
33
33
|
end
|
34
34
|
|
35
|
-
it
|
35
|
+
it 'returns zero' do
|
36
36
|
expect(subject.chdir('/test')).to be_zero
|
37
37
|
end
|
38
38
|
|
39
|
-
it
|
39
|
+
it 'raises an error when the folder does not exist' do
|
40
40
|
expect { subject.chdir('/nowhere') }.to raise_error(Errno::ENOENT)
|
41
41
|
end
|
42
42
|
|
43
|
-
context
|
44
|
-
it
|
43
|
+
context 'when a block is given' do
|
44
|
+
it 'changes current working directory for the block' do
|
45
45
|
subject.chdir '/test' do
|
46
46
|
expect(subject.pwd).to eq('/test')
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
it
|
50
|
+
it 'gets back to previous directory once the block is finished' do
|
51
51
|
subject.chdir '/'
|
52
52
|
expect {
|
53
53
|
subject.chdir('/test') {}
|
54
|
-
}.to_not change{subject.pwd}
|
54
|
+
}.to_not change { subject.pwd }
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
59
|
describe '.chroot' do
|
60
|
-
before { Process.
|
60
|
+
before { allow(Process).to receive_messages(uid: 0) }
|
61
61
|
|
62
62
|
it "changes the process's idea of the file system root" do
|
63
63
|
|
@@ -71,109 +71,109 @@ module MemFs
|
|
71
71
|
expect(subject.chroot('/test')).to eq 0
|
72
72
|
end
|
73
73
|
|
74
|
-
context
|
75
|
-
before {
|
74
|
+
context 'when the given path is a file' do
|
75
|
+
before { _fs.touch('/test/test-file') }
|
76
76
|
|
77
77
|
it 'raises an exception' do
|
78
|
-
expect{ subject.chroot('/test/test-file') }.to raise_error(Errno::ENOTDIR)
|
78
|
+
expect { subject.chroot('/test/test-file') }.to raise_error(Errno::ENOTDIR)
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
82
|
context "when the given path doesn't exist" do
|
83
83
|
it 'raises an exception' do
|
84
|
-
expect{ subject.chroot('/no-dir') }.to raise_error(Errno::ENOENT)
|
84
|
+
expect { subject.chroot('/no-dir') }.to raise_error(Errno::ENOENT)
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
88
|
context 'when the user is not root' do
|
89
|
-
before { Process.
|
89
|
+
before { allow(Process).to receive_messages(uid: 42) }
|
90
90
|
|
91
91
|
it 'raises an exception' do
|
92
|
-
expect{ subject.chroot('/no-dir') }.to raise_error(Errno::EPERM)
|
92
|
+
expect { subject.chroot('/no-dir') }.to raise_error(Errno::EPERM)
|
93
93
|
end
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
|
-
describe
|
97
|
+
describe '.delete' do
|
98
98
|
it_behaves_like 'aliased method', :delete, :rmdir
|
99
99
|
end
|
100
100
|
|
101
101
|
describe '.entries' do
|
102
|
-
it
|
102
|
+
it 'returns an array containing all of the filenames in the given directory' do
|
103
103
|
%w[/test/dir1 /test/dir2].each { |dir| subject.mkdir dir }
|
104
|
-
|
104
|
+
_fs.touch '/test/file1', '/test/file2'
|
105
105
|
expect(subject.entries('/test')).to eq(%w[. .. dir1 dir2 file1 file2])
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
109
|
-
describe
|
109
|
+
describe '.exist?' do
|
110
110
|
it_behaves_like 'aliased method', :exist?, :exists?
|
111
111
|
end
|
112
112
|
|
113
|
-
describe
|
114
|
-
it
|
113
|
+
describe '.exists?' do
|
114
|
+
it 'returns true if the given +path+ exists and is a directory' do
|
115
115
|
subject.mkdir('/test-dir')
|
116
|
-
expect(subject.exists?('/test-dir')).to
|
116
|
+
expect(subject.exists?('/test-dir')).to be true
|
117
117
|
end
|
118
118
|
|
119
|
-
it
|
120
|
-
expect(subject.exists?('/test-dir')).to
|
119
|
+
it 'returns false if the given +path+ does not exist' do
|
120
|
+
expect(subject.exists?('/test-dir')).to be false
|
121
121
|
end
|
122
122
|
|
123
|
-
it
|
124
|
-
|
125
|
-
expect(subject.exists?('/test-file')).to
|
123
|
+
it 'returns false if the given +path+ is not a directory' do
|
124
|
+
_fs.touch('/test-file')
|
125
|
+
expect(subject.exists?('/test-file')).to be false
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
129
|
-
describe
|
129
|
+
describe '.foreach' do
|
130
130
|
before :each do
|
131
|
-
|
131
|
+
_fs.touch('/test/test-file', '/test/test-file2')
|
132
132
|
end
|
133
133
|
|
134
|
-
context
|
135
|
-
it
|
136
|
-
expect{ |blk|
|
134
|
+
context 'when a block is given' do
|
135
|
+
it 'calls the block once for each entry in the named directory' do
|
136
|
+
expect { |blk|
|
137
137
|
subject.foreach('/test', &blk)
|
138
138
|
}.to yield_control.exactly(4).times
|
139
139
|
end
|
140
140
|
|
141
|
-
it
|
142
|
-
expect{ |blk|
|
141
|
+
it 'passes each entry as a parameter to the block' do
|
142
|
+
expect { |blk|
|
143
143
|
subject.foreach('/test', &blk)
|
144
144
|
}.to yield_successive_args('.', '..', 'test-file', 'test-file2')
|
145
145
|
end
|
146
146
|
|
147
147
|
context "and the directory doesn't exist" do
|
148
|
-
it
|
149
|
-
expect{ subject.foreach('/no-dir') {} }.to raise_error
|
148
|
+
it 'raises an exception' do
|
149
|
+
expect { subject.foreach('/no-dir') {} }.to raise_error
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
153
|
-
context
|
154
|
-
it
|
155
|
-
expect{
|
153
|
+
context 'and the given path is not a directory' do
|
154
|
+
it 'raises an exception' do
|
155
|
+
expect {
|
156
156
|
subject.foreach('/test/test-file') {}
|
157
157
|
}.to raise_error
|
158
158
|
end
|
159
159
|
end
|
160
160
|
end
|
161
161
|
|
162
|
-
context
|
163
|
-
it
|
162
|
+
context 'when no block is given' do
|
163
|
+
it 'returns an enumerator' do
|
164
164
|
list = subject.foreach('/test-dir')
|
165
165
|
expect(list).to be_an(Enumerator)
|
166
166
|
end
|
167
167
|
|
168
168
|
context "and the directory doesn't exist" do
|
169
|
-
it
|
169
|
+
it 'returns an enumerator' do
|
170
170
|
list = subject.foreach('/no-dir')
|
171
171
|
expect(list).to be_an(Enumerator)
|
172
172
|
end
|
173
173
|
end
|
174
174
|
|
175
|
-
context
|
176
|
-
it
|
175
|
+
context 'and the given path is not a directory' do
|
176
|
+
it 'returns an enumerator' do
|
177
177
|
list = subject.foreach('/test-dir/test-file')
|
178
178
|
expect(list).to be_an(Enumerator)
|
179
179
|
end
|
@@ -182,19 +182,19 @@ module MemFs
|
|
182
182
|
end
|
183
183
|
|
184
184
|
describe '.getwd' do
|
185
|
-
it
|
185
|
+
it 'returns the path to the current working directory' do
|
186
186
|
expect(subject.getwd).to eq(FileSystem.instance.getwd)
|
187
187
|
end
|
188
188
|
end
|
189
189
|
|
190
190
|
describe '.glob' do
|
191
191
|
before do
|
192
|
-
|
192
|
+
_fs.clear!
|
193
193
|
3.times do |dirnum|
|
194
|
-
|
195
|
-
|
194
|
+
_fs.mkdir "/test#{dirnum}"
|
195
|
+
_fs.mkdir "/test#{dirnum}/subdir"
|
196
196
|
3.times do |filenum|
|
197
|
-
|
197
|
+
_fs.touch "/test#{dirnum}/subdir/file#{filenum}"
|
198
198
|
end
|
199
199
|
end
|
200
200
|
end
|
@@ -229,7 +229,7 @@ module MemFs
|
|
229
229
|
|
230
230
|
context 'when a block is given' do
|
231
231
|
it 'calls the block with every matching filenames' do
|
232
|
-
expect{ |blk| subject.glob('/test*', &blk) }.to \
|
232
|
+
expect { |blk| subject.glob('/test*', &blk) }.to \
|
233
233
|
yield_successive_args('/test0', '/test1', '/test2')
|
234
234
|
end
|
235
235
|
|
@@ -259,13 +259,13 @@ module MemFs
|
|
259
259
|
end
|
260
260
|
|
261
261
|
describe '.mkdir' do
|
262
|
-
it
|
262
|
+
it 'creates a directory' do
|
263
263
|
subject.mkdir '/new-folder'
|
264
|
-
expect(File.directory?('/new-folder')).to
|
264
|
+
expect(File.directory?('/new-folder')).to be true
|
265
265
|
end
|
266
266
|
|
267
|
-
context
|
268
|
-
it
|
267
|
+
context 'when the directory already exist' do
|
268
|
+
it 'raises an exception' do
|
269
269
|
expect { subject.mkdir('/') }.to raise_error(Errno::EEXIST)
|
270
270
|
end
|
271
271
|
end
|
@@ -280,7 +280,7 @@ module MemFs
|
|
280
280
|
|
281
281
|
context 'when a block is given' do
|
282
282
|
it 'calls the block with the opened directory as argument' do
|
283
|
-
expect{ |blk| subject.open('/test', &blk) }.to yield_with_args(Dir)
|
283
|
+
expect { |blk| subject.open('/test', &blk) }.to yield_with_args(Dir)
|
284
284
|
end
|
285
285
|
|
286
286
|
it 'returns nil' do
|
@@ -290,21 +290,21 @@ module MemFs
|
|
290
290
|
it 'ensures the directory is closed' do
|
291
291
|
dir = nil
|
292
292
|
subject.open('/test') { |d| dir = d }
|
293
|
-
expect{ dir.close }.to raise_error(IOError)
|
293
|
+
expect { dir.close }.to raise_error(IOError)
|
294
294
|
end
|
295
295
|
end
|
296
296
|
|
297
297
|
context "when the given directory doesn't exist" do
|
298
298
|
it 'raises an exception' do
|
299
|
-
expect{ subject.open('/no-dir') }.to raise_error
|
299
|
+
expect { subject.open('/no-dir') }.to raise_error
|
300
300
|
end
|
301
301
|
end
|
302
302
|
|
303
303
|
context 'when the given path is not a directory' do
|
304
|
-
before {
|
304
|
+
before { _fs.touch('/test/test-file') }
|
305
305
|
|
306
306
|
it 'raises an exception' do
|
307
|
-
expect{ subject.open('/test/test-file') }.to raise_error
|
307
|
+
expect { subject.open('/test/test-file') }.to raise_error
|
308
308
|
end
|
309
309
|
end
|
310
310
|
end
|
@@ -312,32 +312,32 @@ module MemFs
|
|
312
312
|
describe '.new' do
|
313
313
|
context "when the given directory doesn't exist" do
|
314
314
|
it 'raises an exception' do
|
315
|
-
expect{ subject.new('/no-dir') }.to raise_error
|
315
|
+
expect { subject.new('/no-dir') }.to raise_error
|
316
316
|
end
|
317
317
|
end
|
318
318
|
|
319
319
|
context 'when the given path is not a directory' do
|
320
|
-
before {
|
320
|
+
before { _fs.touch('/test/test-file') }
|
321
321
|
|
322
322
|
it 'raises an exception' do
|
323
|
-
expect{ subject.new('/test/test-file') }.to raise_error
|
323
|
+
expect { subject.new('/test/test-file') }.to raise_error
|
324
324
|
end
|
325
325
|
end
|
326
326
|
end
|
327
327
|
|
328
|
-
describe
|
328
|
+
describe '.pwd' do
|
329
329
|
it_behaves_like 'aliased method', :pwd, :getwd
|
330
330
|
end
|
331
331
|
|
332
|
-
describe
|
333
|
-
it
|
332
|
+
describe '.rmdir' do
|
333
|
+
it 'deletes the named directory' do
|
334
334
|
subject.mkdir('/test-dir')
|
335
335
|
subject.rmdir('/test-dir')
|
336
|
-
expect(subject.exists?('/test-dir')).to
|
336
|
+
expect(subject.exists?('/test-dir')).to be false
|
337
337
|
end
|
338
338
|
|
339
|
-
context
|
340
|
-
it
|
339
|
+
context 'when the directory is not empty' do
|
340
|
+
it 'raises an exception' do
|
341
341
|
subject.mkdir('/test-dir')
|
342
342
|
subject.mkdir('/test-dir/test-sub-dir')
|
343
343
|
expect { subject.rmdir('/test-dir') }.to raise_error(Errno::ENOTEMPTY)
|
@@ -351,7 +351,7 @@ module MemFs
|
|
351
351
|
end
|
352
352
|
end
|
353
353
|
|
354
|
-
describe
|
354
|
+
describe '.unlink' do
|
355
355
|
it_behaves_like 'aliased method', :unlink, :rmdir
|
356
356
|
end
|
357
357
|
|
@@ -359,19 +359,19 @@ module MemFs
|
|
359
359
|
it 'closes the directory' do
|
360
360
|
dir = subject.open('/test')
|
361
361
|
dir.close
|
362
|
-
expect{ dir.close }.to raise_error(IOError)
|
362
|
+
expect { dir.close }.to raise_error(IOError)
|
363
363
|
end
|
364
364
|
end
|
365
365
|
|
366
366
|
describe '#each' do
|
367
|
-
before {
|
367
|
+
before { _fs.touch('/test/test-file', '/test/test-file2') }
|
368
368
|
|
369
369
|
it 'calls the block once for each entry in this directory' do
|
370
|
-
expect{ |blk| instance.each(&blk) }.to yield_control.exactly(4).times
|
370
|
+
expect { |blk| instance.each(&blk) }.to yield_control.exactly(4).times
|
371
371
|
end
|
372
372
|
|
373
373
|
it 'passes the filename of each entry as a parameter to the block' do
|
374
|
-
expect{ |blk|
|
374
|
+
expect { |blk|
|
375
375
|
instance.each(&blk)
|
376
376
|
}.to yield_successive_args('.', '..', 'test-file', 'test-file2')
|
377
377
|
end
|
@@ -390,7 +390,7 @@ module MemFs
|
|
390
390
|
end
|
391
391
|
|
392
392
|
describe '#pos' do
|
393
|
-
it
|
393
|
+
it 'returns the current position in dir' do
|
394
394
|
3.times { instance.read }
|
395
395
|
expect(instance.pos).to eq 3
|
396
396
|
end
|
@@ -425,15 +425,15 @@ module MemFs
|
|
425
425
|
|
426
426
|
describe '#read' do
|
427
427
|
before do
|
428
|
-
|
429
|
-
|
428
|
+
_fs.touch('/test/a')
|
429
|
+
_fs.touch('/test/b')
|
430
430
|
end
|
431
431
|
|
432
432
|
it 'reads the next entry from dir and returns it' do
|
433
433
|
expect(instance.read).to eq '.'
|
434
434
|
end
|
435
435
|
|
436
|
-
context
|
436
|
+
context 'when calling several times' do
|
437
437
|
it 'returns the next entry each time' do
|
438
438
|
2.times { instance.read }
|
439
439
|
expect(instance.read).to eq 'a'
|
@@ -6,11 +6,11 @@ module MemFs
|
|
6
6
|
let(:directory) { Directory.new('test') }
|
7
7
|
|
8
8
|
describe '.new' do
|
9
|
-
it
|
9
|
+
it 'sets . in the entries list' do
|
10
10
|
expect(directory.entries).to include('.' => directory)
|
11
11
|
end
|
12
12
|
|
13
|
-
it
|
13
|
+
it 'sets .. in the entries list' do
|
14
14
|
expect(directory.entries).to have_key('..')
|
15
15
|
end
|
16
16
|
end
|
@@ -18,30 +18,30 @@ module MemFs
|
|
18
18
|
describe '#add_entry' do
|
19
19
|
let(:entry) { Directory.new('new_entry') }
|
20
20
|
|
21
|
-
it
|
21
|
+
it 'adds the entry to the entries list' do
|
22
22
|
directory.add_entry entry
|
23
23
|
expect(directory.entries).to include('new_entry' => entry)
|
24
24
|
end
|
25
25
|
|
26
|
-
it
|
26
|
+
it 'sets the parent of the added entry' do
|
27
27
|
directory.add_entry entry
|
28
28
|
expect(entry.parent).to be(directory)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
describe
|
33
|
-
it
|
32
|
+
describe 'empty?' do
|
33
|
+
it 'returns true if the directory is empty' do
|
34
34
|
expect(directory).to be_empty
|
35
35
|
end
|
36
36
|
|
37
|
-
it
|
37
|
+
it 'returns false if the directory is not empty' do
|
38
38
|
directory.add_entry Directory.new('test')
|
39
39
|
expect(directory).not_to be_empty
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
describe '#entry_names' do
|
44
|
-
it
|
44
|
+
it 'returns the list of the names of the entries in the directory' do
|
45
45
|
3.times do |n|
|
46
46
|
directory.add_entry Directory.new("dir#{n}")
|
47
47
|
end
|
@@ -59,15 +59,15 @@ module MemFs
|
|
59
59
|
directory.add_entry sub_directory
|
60
60
|
end
|
61
61
|
|
62
|
-
it
|
62
|
+
it 'returns the named entry if it is one of the entries' do
|
63
63
|
expect(directory.find('sub_dir')).to be(sub_directory)
|
64
64
|
end
|
65
65
|
|
66
|
-
it
|
66
|
+
it 'calls find on the next directory in the search chain' do
|
67
67
|
expect(directory.find('sub_dir/file')).to be(file)
|
68
68
|
end
|
69
69
|
|
70
|
-
it
|
70
|
+
it 'should remove any leading / in the path' do
|
71
71
|
expect(directory.find('/sub_dir/file')).to be(file)
|
72
72
|
end
|
73
73
|
end
|
@@ -75,27 +75,27 @@ module MemFs
|
|
75
75
|
describe '#parent=' do
|
76
76
|
let(:parent) { Directory.new('parent') }
|
77
77
|
|
78
|
-
it
|
78
|
+
it 'sets the .. entry in entries list' do
|
79
79
|
directory.parent = parent
|
80
80
|
expect(directory.entries).to include('..' => parent)
|
81
81
|
end
|
82
82
|
|
83
|
-
it
|
83
|
+
it 'sets the parent directory' do
|
84
84
|
directory.parent = parent
|
85
85
|
expect(directory.parent).to be(parent)
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
-
describe
|
89
|
+
describe '#path' do
|
90
90
|
let(:root) { Directory.new('/') }
|
91
91
|
|
92
|
-
it
|
92
|
+
it 'returns the directory path' do
|
93
93
|
directory.parent = root
|
94
94
|
expect(directory.path).to eq('/test')
|
95
95
|
end
|
96
96
|
|
97
|
-
context
|
98
|
-
it
|
97
|
+
context 'when the directory is /' do
|
98
|
+
it 'returns /' do
|
99
99
|
expect(root.path).to eq('/')
|
100
100
|
end
|
101
101
|
end
|
@@ -115,17 +115,17 @@ module MemFs
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
-
describe
|
118
|
+
describe '#remove_entry' do
|
119
119
|
let(:file) { File.new('file') }
|
120
120
|
|
121
|
-
it
|
121
|
+
it 'removes an entry from the entries list' do
|
122
122
|
directory.add_entry file
|
123
123
|
directory.remove_entry file
|
124
124
|
expect(directory.entries).not_to have_value(file)
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
128
|
-
describe
|
128
|
+
describe '#type' do
|
129
129
|
it "returns 'directory'" do
|
130
130
|
expect(directory.type).to eq('directory')
|
131
131
|
end
|