memfs 0.3.0 → 0.4.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 +7 -0
- data/CHANGELOG.md +17 -0
- data/lib/memfs/dir.rb +93 -1
- data/lib/memfs/fake/directory.rb +4 -0
- data/lib/memfs/fake/entry.rb +4 -0
- data/lib/memfs/file.rb +15 -7
- data/lib/memfs/file_system.rb +5 -0
- data/lib/memfs/filesystem_access.rb +2 -0
- data/lib/memfs/version.rb +1 -1
- data/spec/memfs/dir_spec.rb +278 -4
- data/spec/memfs/fake/directory_spec.rb +15 -1
- data/spec/memfs/fake/entry_spec.rb +6 -0
- data/spec/memfs/file_spec.rb +4 -4
- data/spec/memfs/file_system_spec.rb +13 -1
- metadata +27 -51
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a6b1cfcdf00318e924ed6247443dffdee28f85e4
|
4
|
+
data.tar.gz: e902f9ddd053b6aa53388f5151d38e650b459874
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4478660656ed0a1fc638a01f5010fc27f3673064f36f4cda41523029266b220907ffe28cb0337763e2b266e8afb0a29ba18289293a316c56dcfac00fed763814
|
7
|
+
data.tar.gz: 6417b9df0a65364af0c7a4e6f04389b68388b456e8d6b641634b2794687f743f6e971655959d29322efac885918a297b472aa2a5fa6a5003784dd4a2652a110c
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.4.0
|
4
|
+
|
5
|
+
* ADD: `Dir.chroot`
|
6
|
+
* ADD: `Dir.glob` and `Dir[]`
|
7
|
+
* ADD: `Dir.open`
|
8
|
+
* ADD: `Dir.tmpdir`
|
9
|
+
* ADD: `Dir#close`
|
10
|
+
* ADD: `Dir#path`
|
11
|
+
* ADD: `Dir#pos=`
|
12
|
+
* ADD: `Dir#pos`
|
13
|
+
* ADD: `Dir#read`
|
14
|
+
* ADD: `Dir#rewind`
|
15
|
+
* ADD: `Dir#seek`
|
16
|
+
* ADD: `Dir#tell`
|
17
|
+
* ADD: `Dir#to_path`
|
18
|
+
* FIX: Internal implementation methods are now private
|
19
|
+
|
3
20
|
## 0.3.0
|
4
21
|
|
5
22
|
* FIX: The gem is now Ruby 1.9 compatible
|
data/lib/memfs/dir.rb
CHANGED
@@ -5,11 +5,28 @@ module MemFs
|
|
5
5
|
extend FilesystemAccess
|
6
6
|
include Enumerable
|
7
7
|
|
8
|
+
attr_reader :pos
|
9
|
+
|
10
|
+
def self.[](*patterns)
|
11
|
+
glob(patterns)
|
12
|
+
end
|
13
|
+
|
8
14
|
def self.chdir(path, &block)
|
9
15
|
fs.chdir path, &block
|
10
16
|
return 0
|
11
17
|
end
|
12
18
|
|
19
|
+
def self.chroot(path)
|
20
|
+
unless Process.uid.zero?
|
21
|
+
raise Errno::EPERM, path
|
22
|
+
end
|
23
|
+
|
24
|
+
dir = fs.find_directory!(path)
|
25
|
+
dir.name = '/'
|
26
|
+
fs.root = dir
|
27
|
+
0
|
28
|
+
end
|
29
|
+
|
13
30
|
def self.entries(dirname, opts = {})
|
14
31
|
fs.entries(dirname)
|
15
32
|
end
|
@@ -30,6 +47,19 @@ module MemFs
|
|
30
47
|
end
|
31
48
|
class << self; alias :pwd :getwd; end
|
32
49
|
|
50
|
+
def self.glob(patterns, flags = 0)
|
51
|
+
patterns = [*patterns]
|
52
|
+
list = fs.paths.select do |path|
|
53
|
+
patterns.any? do |pattern|
|
54
|
+
File.fnmatch?(pattern, path, flags | GLOB_FLAGS)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
# FIXME: ugly special case for /* and /
|
58
|
+
list.delete('/') if patterns.first == '/*'
|
59
|
+
return list unless block_given?
|
60
|
+
list.each { |path| yield path } and nil
|
61
|
+
end
|
62
|
+
|
33
63
|
def self.home(*args)
|
34
64
|
original_dir_class.home(*args)
|
35
65
|
end
|
@@ -38,10 +68,26 @@ module MemFs
|
|
38
68
|
fs.mkdir path
|
39
69
|
end
|
40
70
|
|
71
|
+
def self.open(dirname)
|
72
|
+
dir = new(dirname)
|
73
|
+
|
74
|
+
if block_given?
|
75
|
+
yield dir
|
76
|
+
else
|
77
|
+
dir
|
78
|
+
end
|
79
|
+
ensure
|
80
|
+
dir && dir.close if block_given?
|
81
|
+
end
|
82
|
+
|
41
83
|
def self.rmdir(path)
|
42
84
|
fs.rmdir path
|
43
85
|
end
|
44
86
|
|
87
|
+
def self.tmpdir
|
88
|
+
'/tmp'
|
89
|
+
end
|
90
|
+
|
45
91
|
class << self
|
46
92
|
alias :delete :rmdir
|
47
93
|
alias :unlink :rmdir
|
@@ -49,6 +95,16 @@ module MemFs
|
|
49
95
|
|
50
96
|
def initialize(path)
|
51
97
|
self.entry = fs.find_directory!(path)
|
98
|
+
self.state = :open
|
99
|
+
@pos = 0
|
100
|
+
self.max_seek = 0
|
101
|
+
end
|
102
|
+
|
103
|
+
def close
|
104
|
+
if state == :closed
|
105
|
+
fail IOError, 'closed directory'
|
106
|
+
end
|
107
|
+
self.state = :closed
|
52
108
|
end
|
53
109
|
|
54
110
|
def each(&block)
|
@@ -56,12 +112,48 @@ module MemFs
|
|
56
112
|
entry.entry_names.each(&block)
|
57
113
|
end
|
58
114
|
|
115
|
+
def path
|
116
|
+
entry.path
|
117
|
+
end
|
118
|
+
alias :to_path :path
|
119
|
+
|
120
|
+
def pos=(position)
|
121
|
+
seek(position)
|
122
|
+
position
|
123
|
+
end
|
124
|
+
|
125
|
+
def read
|
126
|
+
name = entries[pos]
|
127
|
+
@pos += 1
|
128
|
+
self.max_seek = pos
|
129
|
+
name
|
130
|
+
end
|
131
|
+
|
132
|
+
def rewind
|
133
|
+
@pos = 0
|
134
|
+
self
|
135
|
+
end
|
136
|
+
|
137
|
+
def seek(position)
|
138
|
+
if (0..max_seek).cover?(position)
|
139
|
+
@pos = position
|
140
|
+
end
|
141
|
+
self
|
142
|
+
end
|
143
|
+
|
144
|
+
def tell
|
145
|
+
@pos
|
146
|
+
end
|
147
|
+
|
59
148
|
private
|
60
149
|
|
61
|
-
|
150
|
+
GLOB_FLAGS = File::FNM_EXTGLOB | File::FNM_PATHNAME
|
151
|
+
|
152
|
+
attr_accessor :entry, :max_seek, :state
|
62
153
|
|
63
154
|
def self.original_dir_class
|
64
155
|
MemFs::OriginalDir
|
65
156
|
end
|
157
|
+
private_class_method :original_dir_class
|
66
158
|
end
|
67
159
|
end
|
data/lib/memfs/fake/directory.rb
CHANGED
data/lib/memfs/fake/entry.rb
CHANGED
data/lib/memfs/file.rb
CHANGED
@@ -226,9 +226,6 @@ module MemFs
|
|
226
226
|
file_names.size
|
227
227
|
end
|
228
228
|
|
229
|
-
attr_accessor :closed,
|
230
|
-
:entry,
|
231
|
-
:opening_mode
|
232
229
|
attr_reader :path
|
233
230
|
|
234
231
|
def initialize(filename, mode = RDONLY, perm = nil, opt = nil)
|
@@ -265,10 +262,6 @@ module MemFs
|
|
265
262
|
closed
|
266
263
|
end
|
267
264
|
|
268
|
-
def content
|
269
|
-
entry.content
|
270
|
-
end
|
271
|
-
|
272
265
|
def lstat
|
273
266
|
File.lstat(path)
|
274
267
|
end
|
@@ -318,6 +311,10 @@ module MemFs
|
|
318
311
|
|
319
312
|
private
|
320
313
|
|
314
|
+
attr_accessor :closed,
|
315
|
+
:entry,
|
316
|
+
:opening_mode
|
317
|
+
|
321
318
|
def self.dereference_name(path)
|
322
319
|
if entry = fs.find(path)
|
323
320
|
entry.dereferenced_name
|
@@ -325,30 +322,41 @@ module MemFs
|
|
325
322
|
basename(path)
|
326
323
|
end
|
327
324
|
end
|
325
|
+
private_class_method :dereference_name
|
328
326
|
|
329
327
|
def self.dereference_dir_path(path)
|
330
328
|
dereference_path(dirname(path))
|
331
329
|
end
|
330
|
+
private_class_method :dereference_dir_path
|
332
331
|
|
333
332
|
def self.dereference_path(path)
|
334
333
|
fs.find!(path).dereferenced_path
|
335
334
|
end
|
335
|
+
private_class_method :dereference_path
|
336
336
|
|
337
337
|
def self.loose_dereference_path(path)
|
338
338
|
join(dereference_dir_path(path), dereference_name(path))
|
339
339
|
end
|
340
|
+
private_class_method :loose_dereference_path
|
340
341
|
|
341
342
|
def self.original_file_class
|
342
343
|
MemFs::OriginalFile
|
343
344
|
end
|
345
|
+
private_class_method :original_file_class
|
344
346
|
|
345
347
|
def self.stat_query(path, query)
|
346
348
|
fs.find(path) && stat(path).public_send(query)
|
347
349
|
end
|
350
|
+
private_class_method :stat_query
|
348
351
|
|
349
352
|
def self.lstat_query(path, query)
|
350
353
|
fs.find(path) && lstat(path).public_send(query)
|
351
354
|
end
|
355
|
+
private_class_method :lstat_query
|
356
|
+
|
357
|
+
def content
|
358
|
+
entry.content
|
359
|
+
end
|
352
360
|
|
353
361
|
def str_to_mode_int(mode)
|
354
362
|
return mode unless mode.is_a?(String)
|
data/lib/memfs/file_system.rb
CHANGED
@@ -30,6 +30,7 @@ module MemFs
|
|
30
30
|
|
31
31
|
def clear!
|
32
32
|
self.root = Fake::Directory.new('/')
|
33
|
+
self.mkdir('/tmp')
|
33
34
|
self.chdir('/')
|
34
35
|
end
|
35
36
|
|
@@ -102,6 +103,10 @@ module MemFs
|
|
102
103
|
find_parent!(path).add_entry Fake::Directory.new(path)
|
103
104
|
end
|
104
105
|
|
106
|
+
def paths
|
107
|
+
root.paths
|
108
|
+
end
|
109
|
+
|
105
110
|
def rename(old_name, new_name)
|
106
111
|
file = find!(old_name)
|
107
112
|
file.delete
|
data/lib/memfs/version.rb
CHANGED
data/spec/memfs/dir_spec.rb
CHANGED
@@ -6,14 +6,26 @@ module MemFs
|
|
6
6
|
|
7
7
|
let(:instance) { MemFs::Dir.new('/test') }
|
8
8
|
|
9
|
-
before
|
10
|
-
subject.mkdir '/test'
|
11
|
-
end
|
9
|
+
before { subject.mkdir '/test' }
|
12
10
|
|
13
11
|
it 'is Enumerable' do
|
14
12
|
expect(instance).to be_an(Enumerable)
|
15
13
|
end
|
16
14
|
|
15
|
+
describe '[]' do
|
16
|
+
context 'when a string is given' do
|
17
|
+
it 'acts like calling glob' do
|
18
|
+
expect(subject['/*']).to eq %w[/tmp /test]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'when a list of strings is given' do
|
23
|
+
it 'acts like calling glob' do
|
24
|
+
expect(subject['/tm*', '/te*']).to eq %w[/tmp /test]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
17
29
|
describe '.chdir' do
|
18
30
|
it "changes the current working directory" do
|
19
31
|
subject.chdir '/test'
|
@@ -34,7 +46,7 @@ module MemFs
|
|
34
46
|
expect(subject.pwd).to eq('/test')
|
35
47
|
end
|
36
48
|
end
|
37
|
-
|
49
|
+
|
38
50
|
it "gets back to previous directory once the block is finished" do
|
39
51
|
subject.chdir '/'
|
40
52
|
expect {
|
@@ -44,6 +56,44 @@ module MemFs
|
|
44
56
|
end
|
45
57
|
end
|
46
58
|
|
59
|
+
describe '.chroot' do
|
60
|
+
before { Process.stub(uid: 0) }
|
61
|
+
|
62
|
+
it "changes the process's idea of the file system root" do
|
63
|
+
|
64
|
+
subject.mkdir('/test/subdir')
|
65
|
+
subject.chroot('/test')
|
66
|
+
|
67
|
+
expect(File.exist?('/subdir')).to be true
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'returns zero' do
|
71
|
+
expect(subject.chroot('/test')).to eq 0
|
72
|
+
end
|
73
|
+
|
74
|
+
context "when the given path is a file" do
|
75
|
+
before { fs.touch('/test/test-file') }
|
76
|
+
|
77
|
+
it 'raises an exception' do
|
78
|
+
expect{ subject.chroot('/test/test-file') }.to raise_error(Errno::ENOTDIR)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "when the given path doesn't exist" do
|
83
|
+
it 'raises an exception' do
|
84
|
+
expect{ subject.chroot('/no-dir') }.to raise_error(Errno::ENOENT)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'when the user is not root' do
|
89
|
+
before { Process.stub(uid: 42) }
|
90
|
+
|
91
|
+
it 'raises an exception' do
|
92
|
+
expect{ subject.chroot('/no-dir') }.to raise_error(Errno::EPERM)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
47
97
|
describe ".delete" do
|
48
98
|
it_behaves_like 'aliased method', :delete, :rmdir
|
49
99
|
end
|
@@ -137,6 +187,61 @@ module MemFs
|
|
137
187
|
end
|
138
188
|
end
|
139
189
|
|
190
|
+
describe '.glob' do
|
191
|
+
before do
|
192
|
+
fs.clear!
|
193
|
+
3.times do |dirnum|
|
194
|
+
fs.mkdir "/test#{dirnum}"
|
195
|
+
fs.mkdir "/test#{dirnum}/subdir"
|
196
|
+
3.times do |filenum|
|
197
|
+
fs.touch "/test#{dirnum}/subdir/file#{filenum}"
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
shared_examples 'returning matching filenames' do |pattern, filenames|
|
203
|
+
it "with #{pattern}" do
|
204
|
+
expect(subject.glob(pattern)).to eq filenames
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
it_behaves_like 'returning matching filenames', '/', %w[/]
|
209
|
+
it_behaves_like 'returning matching filenames', '/test0', %w[/test0]
|
210
|
+
it_behaves_like 'returning matching filenames', '/*', %w[/tmp /test0 /test1 /test2]
|
211
|
+
it_behaves_like 'returning matching filenames', '/test*', %w[/test0 /test1 /test2]
|
212
|
+
it_behaves_like 'returning matching filenames', '/*0', %w[/test0]
|
213
|
+
it_behaves_like 'returning matching filenames', '/*es*', %w[/test0 /test1 /test2]
|
214
|
+
it_behaves_like 'returning matching filenames', '/**/file0', %w[/test0/subdir/file0 /test1/subdir/file0 /test2/subdir/file0]
|
215
|
+
it_behaves_like 'returning matching filenames', '/test?', %w[/test0 /test1 /test2]
|
216
|
+
it_behaves_like 'returning matching filenames', '/test[01]', %w[/test0 /test1]
|
217
|
+
it_behaves_like 'returning matching filenames', '/test[^2]', %w[/test0 /test1]
|
218
|
+
it_behaves_like 'returning matching filenames', '/test{1,2}', %w[/test1 /test2]
|
219
|
+
|
220
|
+
context 'when a flag is given' do
|
221
|
+
it 'uses it to compare filenames' do
|
222
|
+
expect(subject.glob('/TEST*', File::FNM_CASEFOLD)).to eq \
|
223
|
+
%w[/test0 /test1 /test2]
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
context 'when a block is given' do
|
228
|
+
it 'calls the block with every matching filenames' do
|
229
|
+
expect{ |blk| subject.glob('/test*', &blk) }.to \
|
230
|
+
yield_successive_args('/test0', '/test1', '/test2')
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'returns nil' do
|
234
|
+
expect(subject.glob('/*') {}).to be nil
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
context 'when pattern is an array of patterns' do
|
239
|
+
it 'returns the list of files matching any pattern' do
|
240
|
+
expect(subject.glob(['/*0', '/*1'])).to eq %w[/test0 /test1]
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
140
245
|
describe '.home' do
|
141
246
|
it 'returns the home directory of the current user' do
|
142
247
|
expect(subject.home).to eq ENV['HOME']
|
@@ -163,6 +268,44 @@ module MemFs
|
|
163
268
|
end
|
164
269
|
end
|
165
270
|
|
271
|
+
describe '.open' do
|
272
|
+
context 'when no block is given' do
|
273
|
+
it 'returns the opened directory' do
|
274
|
+
expect(subject.open('/test')).to be_a(Dir)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
context 'when a block is given' do
|
279
|
+
it 'calls the block with the opened directory as argument' do
|
280
|
+
expect{ |blk| subject.open('/test', &blk) }.to yield_with_args(Dir)
|
281
|
+
end
|
282
|
+
|
283
|
+
it 'returns nil' do
|
284
|
+
expect(subject.open('/test') {}).to be_nil
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'ensures the directory is closed' do
|
288
|
+
dir = nil
|
289
|
+
subject.open('/test') { |d| dir = d }
|
290
|
+
expect{ dir.close }.to raise_error(IOError)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
context "when the given directory doesn't exist" do
|
295
|
+
it 'raises an exception' do
|
296
|
+
expect{ subject.open('/no-dir') }.to raise_error
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
context 'when the given path is not a directory' do
|
301
|
+
before { fs.touch('/test/test-file') }
|
302
|
+
|
303
|
+
it 'raises an exception' do
|
304
|
+
expect{ subject.open('/test/test-file') }.to raise_error
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
166
309
|
describe '.new' do
|
167
310
|
context "when the given directory doesn't exist" do
|
168
311
|
it 'raises an exception' do
|
@@ -199,10 +342,24 @@ module MemFs
|
|
199
342
|
end
|
200
343
|
end
|
201
344
|
|
345
|
+
describe '.tmpdir' do
|
346
|
+
it 'returns /tmp' do
|
347
|
+
expect(subject.tmpdir).to eq '/tmp'
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
202
351
|
describe ".unlink" do
|
203
352
|
it_behaves_like 'aliased method', :unlink, :rmdir
|
204
353
|
end
|
205
354
|
|
355
|
+
describe '#close' do
|
356
|
+
it 'closes the directory' do
|
357
|
+
dir = subject.open('/test')
|
358
|
+
dir.close
|
359
|
+
expect{ dir.close }.to raise_error(IOError)
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
206
363
|
describe '#each' do
|
207
364
|
before { fs.touch('/test/test-file', '/test/test-file2') }
|
208
365
|
|
@@ -222,5 +379,122 @@ module MemFs
|
|
222
379
|
end
|
223
380
|
end
|
224
381
|
end
|
382
|
+
|
383
|
+
describe '#path' do
|
384
|
+
it "returns the path parameter passed to dir’s constructor" do
|
385
|
+
expect(instance.path).to eq '/test'
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
describe '#pos' do
|
390
|
+
it "returns the current position in dir" do
|
391
|
+
3.times { instance.read }
|
392
|
+
expect(instance.pos).to eq 3
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
describe '#pos=' do
|
397
|
+
before { 3.times { instance.read } }
|
398
|
+
|
399
|
+
it 'seeks to a particular location in dir' do
|
400
|
+
instance.pos = 1
|
401
|
+
expect(instance.pos).to eq 1
|
402
|
+
end
|
403
|
+
|
404
|
+
it 'returns the given position' do
|
405
|
+
expect(instance.pos = 2).to eq 2
|
406
|
+
end
|
407
|
+
|
408
|
+
context 'when the location has not been seeked yet' do
|
409
|
+
it "doesn't change the location" do
|
410
|
+
instance.pos = 42
|
411
|
+
expect(instance.pos).to eq 3
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
context 'when the location is negative' do
|
416
|
+
it "doesn't change the location" do
|
417
|
+
instance.pos = -1
|
418
|
+
expect(instance.pos).to eq 3
|
419
|
+
end
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
describe '#read' do
|
424
|
+
before do
|
425
|
+
fs.touch('/test/a')
|
426
|
+
fs.touch('/test/b')
|
427
|
+
end
|
428
|
+
|
429
|
+
it 'reads the next entry from dir and returns it' do
|
430
|
+
expect(instance.read).to eq '.'
|
431
|
+
end
|
432
|
+
|
433
|
+
context "when calling several times" do
|
434
|
+
it 'returns the next entry each time' do
|
435
|
+
2.times { instance.read }
|
436
|
+
expect(instance.read).to eq 'a'
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
context 'when there are no entries left' do
|
441
|
+
it 'returns nil' do
|
442
|
+
4.times { instance.read }
|
443
|
+
expect(instance.read).to be_nil
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
describe '#rewind' do
|
449
|
+
it 'repositions dir to the first entry' do
|
450
|
+
3.times { instance.read }
|
451
|
+
instance.rewind
|
452
|
+
expect(instance.read).to eq '.'
|
453
|
+
end
|
454
|
+
|
455
|
+
it 'returns the dir itself' do
|
456
|
+
expect(instance.rewind).to be instance
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
describe '#seek' do
|
461
|
+
before { 3.times { instance.read } }
|
462
|
+
|
463
|
+
it 'seeks to a particular location in dir' do
|
464
|
+
instance.seek(1)
|
465
|
+
expect(instance.pos).to eq 1
|
466
|
+
end
|
467
|
+
|
468
|
+
it 'returns the dir itself' do
|
469
|
+
expect(instance.seek(2)).to be instance
|
470
|
+
end
|
471
|
+
|
472
|
+
context 'when the location has not been seeked yet' do
|
473
|
+
it "doesn't change the location" do
|
474
|
+
instance.seek(42)
|
475
|
+
expect(instance.pos).to eq 3
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
context 'when the location is negative' do
|
480
|
+
it "doesn't change the location" do
|
481
|
+
instance.seek(-1)
|
482
|
+
expect(instance.pos).to eq 3
|
483
|
+
end
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
describe '#tell' do
|
488
|
+
it 'returns the current position in dir' do
|
489
|
+
3.times { instance.read }
|
490
|
+
expect(instance.tell).to eq 3
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
describe '#to_path' do
|
495
|
+
it "returns the path parameter passed to dir’s constructor" do
|
496
|
+
expect(instance.to_path).to eq '/test'
|
497
|
+
end
|
498
|
+
end
|
225
499
|
end
|
226
500
|
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
module MemFs
|
4
4
|
module Fake
|
5
5
|
describe Directory do
|
6
|
-
let(:directory) { Directory.new('
|
6
|
+
let(:directory) { Directory.new('test') }
|
7
7
|
|
8
8
|
describe '.new' do
|
9
9
|
it "sets . in the entries list" do
|
@@ -101,6 +101,20 @@ module MemFs
|
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
104
|
+
describe '#paths' do
|
105
|
+
before do
|
106
|
+
subdir = Directory.new('subdir')
|
107
|
+
directory.add_entry(subdir)
|
108
|
+
subdir.add_entry File.new('file1')
|
109
|
+
subdir.add_entry File.new('file2')
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'returns the path of the directory and its entries recursively' do
|
113
|
+
expect(directory.paths).to eq \
|
114
|
+
%w[test test/subdir test/subdir/file1 test/subdir/file2]
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
104
118
|
describe "#remove_entry" do
|
105
119
|
let(:file) { File.new('file') }
|
106
120
|
|
data/spec/memfs/file_spec.rb
CHANGED
@@ -699,14 +699,14 @@ module MemFs
|
|
699
699
|
context "and it is an integer" do
|
700
700
|
it "sets the mode to the integer value" do
|
701
701
|
file = subject.new('/test-file', File::RDWR)
|
702
|
-
expect(file.opening_mode).to eq(File::RDWR)
|
702
|
+
expect(file.send(:opening_mode)).to eq(File::RDWR)
|
703
703
|
end
|
704
704
|
end
|
705
705
|
|
706
706
|
context "and it is a string" do
|
707
707
|
it "sets the mode to the integer value" do
|
708
708
|
file = subject.new('/test-file', 'r+')
|
709
|
-
expect(file.opening_mode).to eq(File::RDWR)
|
709
|
+
expect(file.send(:opening_mode)).to eq(File::RDWR)
|
710
710
|
end
|
711
711
|
end
|
712
712
|
|
@@ -1771,7 +1771,7 @@ module MemFs
|
|
1771
1771
|
file = subject.new('/test-file', 'w')
|
1772
1772
|
file.puts "test"
|
1773
1773
|
file.close
|
1774
|
-
expect(file.content.to_s).to eq("test\n")
|
1774
|
+
expect(file.send(:content).to_s).to eq("test\n")
|
1775
1775
|
end
|
1776
1776
|
|
1777
1777
|
it "does not override the file's content" do
|
@@ -1779,7 +1779,7 @@ module MemFs
|
|
1779
1779
|
file.puts "test"
|
1780
1780
|
file.puts "test"
|
1781
1781
|
file.close
|
1782
|
-
expect(file.content.to_s).to eq("test\ntest\n")
|
1782
|
+
expect(file.send(:content).to_s).to eq("test\ntest\n")
|
1783
1783
|
end
|
1784
1784
|
|
1785
1785
|
it "raises an exception if the file is not writable" do
|
@@ -135,7 +135,7 @@ module MemFs
|
|
135
135
|
describe '#clear!' do
|
136
136
|
it "clear the registred entries" do
|
137
137
|
subject.clear!
|
138
|
-
expect(subject.root.entry_names).to eq(%w[. ..])
|
138
|
+
expect(subject.root.entry_names).to eq(%w[. .. tmp])
|
139
139
|
end
|
140
140
|
|
141
141
|
it "sets the current directory to /" do
|
@@ -310,6 +310,18 @@ module MemFs
|
|
310
310
|
end
|
311
311
|
end
|
312
312
|
|
313
|
+
describe '#paths' do
|
314
|
+
before do
|
315
|
+
subject.mkdir('/test-dir/subdir')
|
316
|
+
subject.touch('/test-dir/subdir/file1', '/test-dir/subdir/file2')
|
317
|
+
end
|
318
|
+
|
319
|
+
it 'returns the list of all the existing paths' do
|
320
|
+
expect(subject.paths).to eq \
|
321
|
+
%w[/ /tmp /test-dir /test-dir/subdir /test-dir/subdir/file1 /test-dir/subdir/file2]
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
313
325
|
describe "#pwd" do
|
314
326
|
it_behaves_like 'aliased method', :pwd, :getwd
|
315
327
|
end
|
metadata
CHANGED
@@ -1,142 +1,125 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memfs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.4.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Simon COURTOIS
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2014-
|
11
|
+
date: 2014-07-18 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: coveralls
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- - ~>
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0.6'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- - ~>
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0.6'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- - ~>
|
31
|
+
- - "~>"
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '10.0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- - ~>
|
38
|
+
- - "~>"
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '10.0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rspec
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- - ~>
|
45
|
+
- - "~>"
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '2.14'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- - ~>
|
52
|
+
- - "~>"
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '2.14'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: guard
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- - ~>
|
59
|
+
- - "~>"
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: '1.5'
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- - ~>
|
66
|
+
- - "~>"
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '1.5'
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: guard-rspec
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- - ~>
|
73
|
+
- - "~>"
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: '2.1'
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- - ~>
|
80
|
+
- - "~>"
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: '2.1'
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: rb-inotify
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
|
-
- - ~>
|
87
|
+
- - "~>"
|
100
88
|
- !ruby/object:Gem::Version
|
101
89
|
version: '0.8'
|
102
90
|
type: :development
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
|
-
- - ~>
|
94
|
+
- - "~>"
|
108
95
|
- !ruby/object:Gem::Version
|
109
96
|
version: '0.8'
|
110
97
|
- !ruby/object:Gem::Dependency
|
111
98
|
name: rb-fsevent
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
113
|
-
none: false
|
114
100
|
requirements:
|
115
|
-
- - ~>
|
101
|
+
- - "~>"
|
116
102
|
- !ruby/object:Gem::Version
|
117
103
|
version: '0.9'
|
118
104
|
type: :development
|
119
105
|
prerelease: false
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
107
|
requirements:
|
123
|
-
- - ~>
|
108
|
+
- - "~>"
|
124
109
|
- !ruby/object:Gem::Version
|
125
110
|
version: '0.9'
|
126
111
|
- !ruby/object:Gem::Dependency
|
127
112
|
name: rb-fchange
|
128
113
|
requirement: !ruby/object:Gem::Requirement
|
129
|
-
none: false
|
130
114
|
requirements:
|
131
|
-
- - ~>
|
115
|
+
- - "~>"
|
132
116
|
- !ruby/object:Gem::Version
|
133
117
|
version: '0.0'
|
134
118
|
type: :development
|
135
119
|
prerelease: false
|
136
120
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
-
none: false
|
138
121
|
requirements:
|
139
|
-
- - ~>
|
122
|
+
- - "~>"
|
140
123
|
- !ruby/object:Gem::Version
|
141
124
|
version: '0.0'
|
142
125
|
description: MemFs provides a fake file system that can be used for tests. Strongly
|
@@ -147,9 +130,9 @@ executables: []
|
|
147
130
|
extensions: []
|
148
131
|
extra_rdoc_files: []
|
149
132
|
files:
|
150
|
-
- .gitignore
|
151
|
-
- .rspec
|
152
|
-
- .travis.yml
|
133
|
+
- ".gitignore"
|
134
|
+
- ".rspec"
|
135
|
+
- ".travis.yml"
|
153
136
|
- CHANGELOG.md
|
154
137
|
- Gemfile
|
155
138
|
- Guardfile
|
@@ -184,34 +167,27 @@ files:
|
|
184
167
|
homepage: http://github.com/simonc/memfs
|
185
168
|
licenses:
|
186
169
|
- MIT
|
170
|
+
metadata: {}
|
187
171
|
post_install_message:
|
188
172
|
rdoc_options: []
|
189
173
|
require_paths:
|
190
174
|
- lib
|
191
175
|
required_ruby_version: !ruby/object:Gem::Requirement
|
192
|
-
none: false
|
193
176
|
requirements:
|
194
|
-
- -
|
177
|
+
- - ">="
|
195
178
|
- !ruby/object:Gem::Version
|
196
179
|
version: '0'
|
197
|
-
segments:
|
198
|
-
- 0
|
199
|
-
hash: 711481126562546659
|
200
180
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
201
|
-
none: false
|
202
181
|
requirements:
|
203
|
-
- -
|
182
|
+
- - ">="
|
204
183
|
- !ruby/object:Gem::Version
|
205
184
|
version: '0'
|
206
|
-
segments:
|
207
|
-
- 0
|
208
|
-
hash: 711481126562546659
|
209
185
|
requirements: []
|
210
186
|
rubyforge_project:
|
211
|
-
rubygems_version:
|
187
|
+
rubygems_version: 2.2.2
|
212
188
|
signing_key:
|
213
|
-
specification_version:
|
214
|
-
summary: memfs-0.
|
189
|
+
specification_version: 4
|
190
|
+
summary: memfs-0.4.0
|
215
191
|
test_files:
|
216
192
|
- spec/fileutils_spec.rb
|
217
193
|
- spec/memfs/dir_spec.rb
|