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