memfs 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -14,20 +14,20 @@ module MemFs
|
|
14
14
|
let(:dir_stat) { File::Stat.new('/test-dir') }
|
15
15
|
let(:dereferenced_dir_stat) { File::Stat.new('/test-dir', true) }
|
16
16
|
|
17
|
-
let(:entry) {
|
17
|
+
let(:entry) { _fs.find!('/test-file') }
|
18
18
|
|
19
19
|
before :each do
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
_fs.mkdir('/test-dir')
|
21
|
+
_fs.touch('/test-file')
|
22
|
+
_fs.symlink('/test-file', '/test-link')
|
23
|
+
_fs.symlink('/test-dir', '/test-dir-link')
|
24
|
+
_fs.symlink('/no-file', '/test-no-file-link')
|
25
25
|
end
|
26
26
|
|
27
27
|
describe '.new' do
|
28
|
-
context
|
29
|
-
context
|
30
|
-
it
|
28
|
+
context 'when optional dereference argument is set to true' do
|
29
|
+
context 'when the last target of the link chain does not exist' do
|
30
|
+
it 'raises an exception' do
|
31
31
|
expect {
|
32
32
|
File::Stat.new('/test-no-file-link', true)
|
33
33
|
}.to raise_error(Errno::ENOENT)
|
@@ -37,24 +37,24 @@ module MemFs
|
|
37
37
|
end
|
38
38
|
|
39
39
|
describe '#atime' do
|
40
|
-
let(:time) { Time.now -
|
40
|
+
let(:time) { Time.now - 500_000 }
|
41
41
|
|
42
|
-
it
|
43
|
-
entry =
|
42
|
+
it 'returns the access time of the entry' do
|
43
|
+
entry = _fs.find!('/test-file')
|
44
44
|
entry.atime = time
|
45
45
|
expect(file_stat.atime).to eq(time)
|
46
46
|
end
|
47
47
|
|
48
|
-
context
|
49
|
-
context
|
50
|
-
it
|
48
|
+
context 'when the entry is a symlink' do
|
49
|
+
context 'and the optional dereference argument is true' do
|
50
|
+
it 'returns the access time of the last target of the link chain' do
|
51
51
|
entry.atime = time
|
52
52
|
expect(dereferenced_link_stat.atime).to eq(time)
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
context
|
57
|
-
it
|
56
|
+
context 'and the optional dereference argument is false' do
|
57
|
+
it 'returns the access time of the symlink itself' do
|
58
58
|
entry.atime = time
|
59
59
|
expect(link_stat.atime).not_to eq(time)
|
60
60
|
end
|
@@ -62,66 +62,66 @@ module MemFs
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
describe
|
66
|
-
it
|
65
|
+
describe '#blksize' do
|
66
|
+
it 'returns the block size of the file' do
|
67
67
|
expect(file_stat.blksize).to be(4096)
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
describe
|
72
|
-
context
|
73
|
-
it
|
74
|
-
|
75
|
-
file =
|
71
|
+
describe '#blockdev?' do
|
72
|
+
context 'when the file is a block device' do
|
73
|
+
it 'returns true' do
|
74
|
+
_fs.touch('/block-file')
|
75
|
+
file = _fs.find('/block-file')
|
76
76
|
file.block_device = true
|
77
77
|
block_stat = File::Stat.new('/block-file')
|
78
|
-
expect(block_stat.blockdev?).to
|
78
|
+
expect(block_stat.blockdev?).to be true
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
context
|
83
|
-
it
|
84
|
-
expect(file_stat.blockdev?).to
|
82
|
+
context 'when the file is not a block device' do
|
83
|
+
it 'returns false' do
|
84
|
+
expect(file_stat.blockdev?).to be false
|
85
85
|
end
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
-
describe
|
90
|
-
context
|
91
|
-
it
|
92
|
-
|
93
|
-
file =
|
89
|
+
describe '#chardev?' do
|
90
|
+
context 'when the file is a character device' do
|
91
|
+
it 'returns true' do
|
92
|
+
_fs.touch('/character-file')
|
93
|
+
file = _fs.find('/character-file')
|
94
94
|
file.character_device = true
|
95
95
|
character_stat = File::Stat.new('/character-file')
|
96
|
-
expect(character_stat.chardev?).to
|
96
|
+
expect(character_stat.chardev?).to be true
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
100
|
-
context
|
101
|
-
it
|
102
|
-
expect(file_stat.chardev?).to
|
100
|
+
context 'when the file is not a character device' do
|
101
|
+
it 'returns false' do
|
102
|
+
expect(file_stat.chardev?).to be false
|
103
103
|
end
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
107
|
describe '#ctime' do
|
108
|
-
let(:time) { Time.now -
|
108
|
+
let(:time) { Time.now - 500_000 }
|
109
109
|
|
110
|
-
it
|
110
|
+
it 'returns the access time of the entry' do
|
111
111
|
entry.ctime = time
|
112
112
|
expect(file_stat.ctime).to eq(time)
|
113
113
|
end
|
114
114
|
|
115
|
-
context
|
116
|
-
context
|
117
|
-
it
|
115
|
+
context 'when the entry is a symlink' do
|
116
|
+
context 'and the optional dereference argument is true' do
|
117
|
+
it 'returns the access time of the last target of the link chain' do
|
118
118
|
entry.ctime = time
|
119
119
|
expect(dereferenced_link_stat.ctime).to eq(time)
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
|
-
context
|
124
|
-
it
|
123
|
+
context 'and the optional dereference argument is false' do
|
124
|
+
it 'returns the access time of the symlink itself' do
|
125
125
|
entry.ctime = time
|
126
126
|
expect(link_stat.ctime).not_to eq(time)
|
127
127
|
end
|
@@ -129,64 +129,64 @@ module MemFs
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
-
describe
|
133
|
-
it
|
132
|
+
describe '#dev' do
|
133
|
+
it 'returns an integer representing the device on which stat resides' do
|
134
134
|
expect(file_stat.dev).to be_a(Fixnum)
|
135
135
|
end
|
136
136
|
end
|
137
137
|
|
138
138
|
describe '#directory?' do
|
139
139
|
context 'when dereference is true' do
|
140
|
-
context
|
141
|
-
it
|
142
|
-
expect(dereferenced_dir_stat.directory?).to
|
140
|
+
context 'when the entry is a directory' do
|
141
|
+
it 'returns true' do
|
142
|
+
expect(dereferenced_dir_stat.directory?).to be true
|
143
143
|
end
|
144
144
|
end
|
145
145
|
|
146
|
-
context
|
147
|
-
it
|
148
|
-
expect(dereferenced_file_stat.directory?).to
|
146
|
+
context 'when the entry is not a directory' do
|
147
|
+
it 'returns false' do
|
148
|
+
expect(dereferenced_file_stat.directory?).to be false
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
152
|
-
context
|
153
|
-
context
|
154
|
-
it
|
155
|
-
expect(dereferenced_dir_link_stat.directory?).to
|
152
|
+
context 'when the entry is a symlink' do
|
153
|
+
context 'and the last target of the link chain is a directory' do
|
154
|
+
it 'returns true' do
|
155
|
+
expect(dereferenced_dir_link_stat.directory?).to be true
|
156
156
|
end
|
157
157
|
end
|
158
158
|
|
159
|
-
context
|
160
|
-
it
|
161
|
-
expect(dereferenced_link_stat.directory?).to
|
159
|
+
context 'and the last target of the link chain is not a directory' do
|
160
|
+
it 'returns false' do
|
161
|
+
expect(dereferenced_link_stat.directory?).to be false
|
162
162
|
end
|
163
163
|
end
|
164
164
|
end
|
165
165
|
end
|
166
166
|
|
167
167
|
context 'when dereference is false' do
|
168
|
-
context
|
169
|
-
it
|
170
|
-
expect(dir_stat.directory?).to
|
168
|
+
context 'when the entry is a directory' do
|
169
|
+
it 'returns true' do
|
170
|
+
expect(dir_stat.directory?).to be true
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
174
|
-
context
|
175
|
-
it
|
176
|
-
expect(file_stat.directory?).to
|
174
|
+
context 'when the entry is not a directory' do
|
175
|
+
it 'returns false' do
|
176
|
+
expect(file_stat.directory?).to be false
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
180
|
-
context
|
181
|
-
context
|
182
|
-
it
|
183
|
-
expect(dir_link_stat.directory?).to
|
180
|
+
context 'when the entry is a symlink' do
|
181
|
+
context 'and the last target of the link chain is a directory' do
|
182
|
+
it 'returns false' do
|
183
|
+
expect(dir_link_stat.directory?).to be false
|
184
184
|
end
|
185
185
|
end
|
186
186
|
|
187
|
-
context
|
188
|
-
it
|
189
|
-
expect(link_stat.directory?).to
|
187
|
+
context 'and the last target of the link chain is not a directory' do
|
188
|
+
it 'returns false' do
|
189
|
+
expect(link_stat.directory?).to be false
|
190
190
|
end
|
191
191
|
end
|
192
192
|
end
|
@@ -194,12 +194,12 @@ module MemFs
|
|
194
194
|
end
|
195
195
|
|
196
196
|
describe '#entry' do
|
197
|
-
it
|
197
|
+
it 'returns the comcerned entry' do
|
198
198
|
expect(file_stat.entry).to be_a(Fake::File)
|
199
199
|
end
|
200
200
|
end
|
201
201
|
|
202
|
-
describe
|
202
|
+
describe '#executable?' do
|
203
203
|
let(:access) { 0 }
|
204
204
|
let(:gid) { 0 }
|
205
205
|
let(:uid) { 0 }
|
@@ -210,54 +210,54 @@ module MemFs
|
|
210
210
|
entry.gid = gid
|
211
211
|
end
|
212
212
|
|
213
|
-
context
|
214
|
-
it
|
215
|
-
expect(file_stat.executable?).to
|
213
|
+
context 'when the file is not executable by anyone' do
|
214
|
+
it 'return false' do
|
215
|
+
expect(file_stat.executable?).to be false
|
216
216
|
end
|
217
217
|
end
|
218
218
|
|
219
|
-
context
|
219
|
+
context 'when the file is user executable' do
|
220
220
|
let(:access) { MemFs::Fake::Entry::UEXEC }
|
221
221
|
|
222
|
-
context
|
222
|
+
context 'and the current user owns the file' do
|
223
223
|
let(:uid) { Process.euid }
|
224
224
|
|
225
|
-
it
|
226
|
-
expect(file_stat.executable?).to
|
225
|
+
it 'returns true' do
|
226
|
+
expect(file_stat.executable?).to be true
|
227
227
|
end
|
228
228
|
end
|
229
229
|
end
|
230
230
|
|
231
|
-
context
|
231
|
+
context 'when the file is group executable' do
|
232
232
|
let(:access) { MemFs::Fake::Entry::GEXEC }
|
233
233
|
|
234
|
-
context
|
234
|
+
context 'and the current user is part of the owner group' do
|
235
235
|
let(:gid) { Process.egid }
|
236
236
|
|
237
|
-
it
|
238
|
-
expect(file_stat.executable?).to
|
237
|
+
it 'returns true' do
|
238
|
+
expect(file_stat.executable?).to be true
|
239
239
|
end
|
240
240
|
end
|
241
241
|
end
|
242
242
|
|
243
|
-
context
|
243
|
+
context 'when the file is executable by anyone' do
|
244
244
|
let(:access) { MemFs::Fake::Entry::OEXEC }
|
245
245
|
|
246
|
-
context
|
247
|
-
it
|
248
|
-
expect(file_stat.executable?).to
|
246
|
+
context 'and the user has no specific right on it' do
|
247
|
+
it 'returns true' do
|
248
|
+
expect(file_stat.executable?).to be true
|
249
249
|
end
|
250
250
|
end
|
251
251
|
end
|
252
252
|
|
253
|
-
context
|
254
|
-
it
|
255
|
-
expect(file_stat.executable?).to
|
253
|
+
context 'when the file does not exist' do
|
254
|
+
it 'returns false' do
|
255
|
+
expect(file_stat.executable?).to be false
|
256
256
|
end
|
257
257
|
end
|
258
258
|
end
|
259
259
|
|
260
|
-
describe
|
260
|
+
describe '#executable_real?' do
|
261
261
|
let(:access) { 0 }
|
262
262
|
let(:gid) { 0 }
|
263
263
|
let(:uid) { 0 }
|
@@ -268,145 +268,145 @@ module MemFs
|
|
268
268
|
entry.gid = gid
|
269
269
|
end
|
270
270
|
|
271
|
-
context
|
272
|
-
it
|
273
|
-
expect(file_stat.executable_real?).to
|
271
|
+
context 'when the file is not executable by anyone' do
|
272
|
+
it 'return false' do
|
273
|
+
expect(file_stat.executable_real?).to be false
|
274
274
|
end
|
275
275
|
end
|
276
276
|
|
277
|
-
context
|
277
|
+
context 'when the file is user executable' do
|
278
278
|
let(:access) { MemFs::Fake::Entry::UEXEC }
|
279
279
|
|
280
|
-
context
|
280
|
+
context 'and the current user owns the file' do
|
281
281
|
let(:uid) { Process.uid }
|
282
282
|
|
283
|
-
it
|
284
|
-
expect(file_stat.executable_real?).to
|
283
|
+
it 'returns true' do
|
284
|
+
expect(file_stat.executable_real?).to be true
|
285
285
|
end
|
286
286
|
end
|
287
287
|
end
|
288
288
|
|
289
|
-
context
|
289
|
+
context 'when the file is group executable' do
|
290
290
|
let(:access) { MemFs::Fake::Entry::GEXEC }
|
291
291
|
|
292
|
-
context
|
292
|
+
context 'and the current user is part of the owner group' do
|
293
293
|
let(:gid) { Process.gid }
|
294
294
|
|
295
|
-
it
|
296
|
-
expect(file_stat.executable_real?).to
|
295
|
+
it 'returns true' do
|
296
|
+
expect(file_stat.executable_real?).to be true
|
297
297
|
end
|
298
298
|
end
|
299
299
|
end
|
300
300
|
|
301
|
-
context
|
301
|
+
context 'when the file is executable by anyone' do
|
302
302
|
let(:access) { MemFs::Fake::Entry::OEXEC }
|
303
303
|
|
304
|
-
context
|
305
|
-
it
|
306
|
-
expect(file_stat.executable_real?).to
|
304
|
+
context 'and the user has no specific right on it' do
|
305
|
+
it 'returns true' do
|
306
|
+
expect(file_stat.executable_real?).to be true
|
307
307
|
end
|
308
308
|
end
|
309
309
|
end
|
310
310
|
|
311
|
-
context
|
312
|
-
it
|
313
|
-
expect(file_stat.executable_real?).to
|
311
|
+
context 'when the file does not exist' do
|
312
|
+
it 'returns false' do
|
313
|
+
expect(file_stat.executable_real?).to be false
|
314
314
|
end
|
315
315
|
end
|
316
316
|
end
|
317
317
|
|
318
|
-
describe
|
318
|
+
describe '#file?' do
|
319
319
|
context 'when dereference is true' do
|
320
|
-
context
|
321
|
-
it
|
322
|
-
expect(dereferenced_file_stat.file?).to
|
320
|
+
context 'when the entry is a regular file' do
|
321
|
+
it 'returns true' do
|
322
|
+
expect(dereferenced_file_stat.file?).to be true
|
323
323
|
end
|
324
324
|
end
|
325
325
|
|
326
|
-
context
|
327
|
-
it
|
328
|
-
expect(dereferenced_dir_stat.file?).to
|
326
|
+
context 'when the entry is not a regular file' do
|
327
|
+
it 'returns false' do
|
328
|
+
expect(dereferenced_dir_stat.file?).to be false
|
329
329
|
end
|
330
330
|
end
|
331
331
|
|
332
|
-
context
|
333
|
-
context
|
334
|
-
it
|
335
|
-
expect(dereferenced_link_stat.file?).to
|
332
|
+
context 'when the entry is a symlink' do
|
333
|
+
context 'and the last target of the link chain is a regular file' do
|
334
|
+
it 'returns true' do
|
335
|
+
expect(dereferenced_link_stat.file?).to be true
|
336
336
|
end
|
337
337
|
end
|
338
338
|
|
339
|
-
context
|
340
|
-
it
|
341
|
-
expect(dereferenced_dir_link_stat.file?).to
|
339
|
+
context 'and the last target of the link chain is not a regular file' do
|
340
|
+
it 'returns false' do
|
341
|
+
expect(dereferenced_dir_link_stat.file?).to be false
|
342
342
|
end
|
343
343
|
end
|
344
344
|
end
|
345
345
|
end
|
346
346
|
|
347
347
|
context 'when dereference is false' do
|
348
|
-
context
|
349
|
-
it
|
350
|
-
expect(file_stat.file?).to
|
348
|
+
context 'when the entry is a regular file' do
|
349
|
+
it 'returns true' do
|
350
|
+
expect(file_stat.file?).to be true
|
351
351
|
end
|
352
352
|
end
|
353
353
|
|
354
|
-
context
|
355
|
-
it
|
356
|
-
expect(dir_stat.file?).to
|
354
|
+
context 'when the entry is not a regular file' do
|
355
|
+
it 'returns false' do
|
356
|
+
expect(dir_stat.file?).to be false
|
357
357
|
end
|
358
358
|
end
|
359
359
|
|
360
|
-
context
|
361
|
-
context
|
362
|
-
it
|
363
|
-
expect(link_stat.file?).to
|
360
|
+
context 'when the entry is a symlink' do
|
361
|
+
context 'and the last target of the link chain is a regular file' do
|
362
|
+
it 'returns false' do
|
363
|
+
expect(link_stat.file?).to be false
|
364
364
|
end
|
365
365
|
end
|
366
366
|
|
367
|
-
context
|
368
|
-
it
|
369
|
-
expect(dir_link_stat.file?).to
|
367
|
+
context 'and the last target of the link chain is not a regular file' do
|
368
|
+
it 'returns false' do
|
369
|
+
expect(dir_link_stat.file?).to be false
|
370
370
|
end
|
371
371
|
end
|
372
372
|
end
|
373
373
|
end
|
374
374
|
end
|
375
375
|
|
376
|
-
describe
|
377
|
-
context
|
376
|
+
describe '#ftype' do
|
377
|
+
context 'when the entry is a regular file' do
|
378
378
|
it "returns 'file'" do
|
379
379
|
expect(file_stat.ftype).to eq('file')
|
380
380
|
end
|
381
381
|
end
|
382
382
|
|
383
|
-
context
|
383
|
+
context 'when the entry is a directory' do
|
384
384
|
it "returns 'directory'" do
|
385
385
|
expect(dir_stat.ftype).to eq('directory')
|
386
386
|
end
|
387
387
|
end
|
388
388
|
|
389
|
-
context
|
389
|
+
context 'when the entry is a block device' do
|
390
390
|
it "returns 'blockSpecial'" do
|
391
|
-
|
392
|
-
file =
|
391
|
+
_fs.touch('/block-file')
|
392
|
+
file = _fs.find('/block-file')
|
393
393
|
file.block_device = true
|
394
394
|
block_stat = File::Stat.new('/block-file')
|
395
395
|
expect(block_stat.ftype).to eq('blockSpecial')
|
396
396
|
end
|
397
397
|
end
|
398
398
|
|
399
|
-
context
|
399
|
+
context 'when the entry is a character device' do
|
400
400
|
it "returns 'characterSpecial'" do
|
401
|
-
|
402
|
-
file =
|
401
|
+
_fs.touch('/character-file')
|
402
|
+
file = _fs.find('/character-file')
|
403
403
|
file.character_device = true
|
404
404
|
character_stat = File::Stat.new('/character-file')
|
405
405
|
expect(character_stat.ftype).to eq('characterSpecial')
|
406
406
|
end
|
407
407
|
end
|
408
408
|
|
409
|
-
context
|
409
|
+
context 'when the entry is a symlink' do
|
410
410
|
it "returns 'link'" do
|
411
411
|
expect(link_stat.ftype).to eq('link')
|
412
412
|
end
|
@@ -414,9 +414,9 @@ module MemFs
|
|
414
414
|
|
415
415
|
# fifo and socket not handled for now
|
416
416
|
|
417
|
-
context
|
417
|
+
context 'when the entry has no specific type' do
|
418
418
|
it "returns 'unknown'" do
|
419
|
-
root =
|
419
|
+
root = _fs.find('/')
|
420
420
|
root.add_entry Fake::Entry.new('test-entry')
|
421
421
|
entry_stat = File::Stat.new('/test-entry')
|
422
422
|
expect(entry_stat.ftype).to eq('unknown')
|
@@ -424,69 +424,69 @@ module MemFs
|
|
424
424
|
end
|
425
425
|
end
|
426
426
|
|
427
|
-
describe
|
428
|
-
it
|
429
|
-
|
427
|
+
describe '#gid' do
|
428
|
+
it 'returns the group id of the named entry' do
|
429
|
+
_fs.chown(nil, 42, '/test-file')
|
430
430
|
expect(file_stat.gid).to be(42)
|
431
431
|
end
|
432
432
|
end
|
433
433
|
|
434
|
-
describe
|
435
|
-
context
|
436
|
-
it
|
437
|
-
|
438
|
-
expect(file_stat.grpowned?).to
|
434
|
+
describe '#grpowned?' do
|
435
|
+
context 'when the effective user group owns of the file' do
|
436
|
+
it 'returns true' do
|
437
|
+
_fs.chown(0, Process.egid, '/test-file')
|
438
|
+
expect(file_stat.grpowned?).to be true
|
439
439
|
end
|
440
440
|
end
|
441
441
|
|
442
|
-
context
|
443
|
-
it
|
444
|
-
|
445
|
-
expect(file_stat.grpowned?).to
|
442
|
+
context 'when the effective user group does not own of the file' do
|
443
|
+
it 'returns false' do
|
444
|
+
_fs.chown(0, 0, '/test-file')
|
445
|
+
expect(file_stat.grpowned?).to be false
|
446
446
|
end
|
447
447
|
end
|
448
448
|
end
|
449
449
|
|
450
|
-
describe
|
451
|
-
it
|
450
|
+
describe '#ino' do
|
451
|
+
it 'returns the inode number for stat.' do
|
452
452
|
expect(file_stat.ino).to be_a(Fixnum)
|
453
453
|
end
|
454
454
|
end
|
455
455
|
|
456
456
|
describe '#mode' do
|
457
|
-
it
|
458
|
-
|
457
|
+
it 'returns an integer representing the permission bits of stat' do
|
458
|
+
_fs.chmod(0777, '/test-file')
|
459
459
|
expect(file_stat.mode).to be(0100777)
|
460
460
|
end
|
461
461
|
end
|
462
462
|
|
463
|
-
describe
|
464
|
-
context
|
465
|
-
it
|
466
|
-
|
467
|
-
expect(file_stat.owned?).to
|
463
|
+
describe '#owned?' do
|
464
|
+
context 'when the effective user owns of the file' do
|
465
|
+
it 'returns true' do
|
466
|
+
_fs.chown(Process.euid, 0, '/test-file')
|
467
|
+
expect(file_stat.owned?).to be true
|
468
468
|
end
|
469
469
|
end
|
470
470
|
|
471
|
-
context
|
472
|
-
it
|
473
|
-
|
474
|
-
expect(file_stat.owned?).to
|
471
|
+
context 'when the effective user does not own of the file' do
|
472
|
+
it 'returns false' do
|
473
|
+
_fs.chown(0, 0, '/test-file')
|
474
|
+
expect(file_stat.owned?).to be false
|
475
475
|
end
|
476
476
|
end
|
477
477
|
end
|
478
478
|
|
479
|
-
describe
|
479
|
+
describe '#pipe?' do
|
480
480
|
# Pipes are not handled for now
|
481
481
|
|
482
|
-
context
|
483
|
-
it
|
484
|
-
expect(file_stat.pipe?).to
|
482
|
+
context 'when the file is not a pipe' do
|
483
|
+
it 'returns false' do
|
484
|
+
expect(file_stat.pipe?).to be false
|
485
485
|
end
|
486
486
|
end
|
487
487
|
end
|
488
488
|
|
489
|
-
describe
|
489
|
+
describe '#readable?' do
|
490
490
|
let(:access) { 0 }
|
491
491
|
let(:gid) { 0 }
|
492
492
|
let(:uid) { 0 }
|
@@ -497,48 +497,48 @@ module MemFs
|
|
497
497
|
entry.gid = gid
|
498
498
|
end
|
499
499
|
|
500
|
-
context
|
501
|
-
it
|
502
|
-
expect(file_stat.readable?).to
|
500
|
+
context 'when the file is not readable by anyone' do
|
501
|
+
it 'return false' do
|
502
|
+
expect(file_stat.readable?).to be false
|
503
503
|
end
|
504
504
|
end
|
505
505
|
|
506
|
-
context
|
506
|
+
context 'when the file is user readable' do
|
507
507
|
let(:access) { MemFs::Fake::Entry::UREAD }
|
508
508
|
|
509
|
-
context
|
509
|
+
context 'and the current user owns the file' do
|
510
510
|
let(:uid) { Process.euid }
|
511
511
|
|
512
|
-
it
|
513
|
-
expect(file_stat.readable?).to
|
512
|
+
it 'returns true' do
|
513
|
+
expect(file_stat.readable?).to be true
|
514
514
|
end
|
515
515
|
end
|
516
516
|
end
|
517
517
|
|
518
|
-
context
|
518
|
+
context 'when the file is group readable' do
|
519
519
|
let(:access) { MemFs::Fake::Entry::GREAD }
|
520
520
|
|
521
|
-
context
|
521
|
+
context 'and the current user is part of the owner group' do
|
522
522
|
let(:gid) { Process.egid }
|
523
523
|
|
524
|
-
it
|
525
|
-
expect(file_stat.readable?).to
|
524
|
+
it 'returns true' do
|
525
|
+
expect(file_stat.readable?).to be true
|
526
526
|
end
|
527
527
|
end
|
528
528
|
end
|
529
529
|
|
530
|
-
context
|
530
|
+
context 'when the file is readable by anyone' do
|
531
531
|
let(:access) { MemFs::Fake::Entry::OREAD }
|
532
532
|
|
533
|
-
context
|
534
|
-
it
|
535
|
-
expect(file_stat.readable?).to
|
533
|
+
context 'and the user has no specific right on it' do
|
534
|
+
it 'returns true' do
|
535
|
+
expect(file_stat.readable?).to be true
|
536
536
|
end
|
537
537
|
end
|
538
538
|
end
|
539
539
|
end
|
540
540
|
|
541
|
-
describe
|
541
|
+
describe '#readable_real?' do
|
542
542
|
let(:access) { 0 }
|
543
543
|
let(:gid) { 0 }
|
544
544
|
let(:uid) { 0 }
|
@@ -549,174 +549,174 @@ module MemFs
|
|
549
549
|
entry.gid = gid
|
550
550
|
end
|
551
551
|
|
552
|
-
context
|
553
|
-
it
|
554
|
-
expect(file_stat.readable_real?).to
|
552
|
+
context 'when the file is not readable by anyone' do
|
553
|
+
it 'return false' do
|
554
|
+
expect(file_stat.readable_real?).to be false
|
555
555
|
end
|
556
556
|
end
|
557
557
|
|
558
|
-
context
|
558
|
+
context 'when the file is user readable' do
|
559
559
|
let(:access) { MemFs::Fake::Entry::UREAD }
|
560
560
|
|
561
|
-
context
|
561
|
+
context 'and the current user owns the file' do
|
562
562
|
let(:uid) { Process.euid }
|
563
563
|
|
564
|
-
it
|
565
|
-
expect(file_stat.readable_real?).to
|
564
|
+
it 'returns true' do
|
565
|
+
expect(file_stat.readable_real?).to be true
|
566
566
|
end
|
567
567
|
end
|
568
568
|
end
|
569
569
|
|
570
|
-
context
|
570
|
+
context 'when the file is group readable' do
|
571
571
|
let(:access) { MemFs::Fake::Entry::GREAD }
|
572
572
|
|
573
|
-
context
|
573
|
+
context 'and the current user is part of the owner group' do
|
574
574
|
let(:gid) { Process.egid }
|
575
575
|
|
576
|
-
it
|
577
|
-
expect(file_stat.readable_real?).to
|
576
|
+
it 'returns true' do
|
577
|
+
expect(file_stat.readable_real?).to be true
|
578
578
|
end
|
579
579
|
end
|
580
580
|
end
|
581
581
|
|
582
|
-
context
|
582
|
+
context 'when the file is readable by anyone' do
|
583
583
|
let(:access) { MemFs::Fake::Entry::OREAD }
|
584
584
|
|
585
|
-
context
|
586
|
-
it
|
587
|
-
expect(file_stat.readable_real?).to
|
585
|
+
context 'and the user has no specific right on it' do
|
586
|
+
it 'returns true' do
|
587
|
+
expect(file_stat.readable_real?).to be true
|
588
588
|
end
|
589
589
|
end
|
590
590
|
end
|
591
591
|
|
592
|
-
context
|
593
|
-
it
|
594
|
-
expect(file_stat.readable_real?).to
|
592
|
+
context 'when the file does not exist' do
|
593
|
+
it 'returns false' do
|
594
|
+
expect(file_stat.readable_real?).to be false
|
595
595
|
end
|
596
596
|
end
|
597
597
|
end
|
598
598
|
|
599
|
-
describe
|
600
|
-
context
|
601
|
-
it
|
602
|
-
|
603
|
-
expect(file_stat.setgid?).to
|
599
|
+
describe '#setgid?' do
|
600
|
+
context 'when the file has the setgid bit set' do
|
601
|
+
it 'returns true' do
|
602
|
+
_fs.chmod(02000, '/test-file')
|
603
|
+
expect(file_stat.setgid?).to be true
|
604
604
|
end
|
605
605
|
end
|
606
606
|
|
607
|
-
context
|
608
|
-
it
|
609
|
-
expect(file_stat.setgid?).to
|
607
|
+
context 'when the file does not have the setgid bit set' do
|
608
|
+
it 'returns false' do
|
609
|
+
expect(file_stat.setgid?).to be false
|
610
610
|
end
|
611
611
|
end
|
612
612
|
end
|
613
613
|
|
614
|
-
describe
|
615
|
-
context
|
616
|
-
it
|
617
|
-
|
618
|
-
expect(file_stat.setuid?).to
|
614
|
+
describe '#setuid?' do
|
615
|
+
context 'when the file has the setuid bit set' do
|
616
|
+
it 'returns true' do
|
617
|
+
_fs.chmod(04000, '/test-file')
|
618
|
+
expect(file_stat.setuid?).to be true
|
619
619
|
end
|
620
620
|
end
|
621
621
|
|
622
|
-
context
|
623
|
-
it
|
624
|
-
expect(file_stat.setuid?).to
|
622
|
+
context 'when the file does not have the setuid bit set' do
|
623
|
+
it 'returns false' do
|
624
|
+
expect(file_stat.setuid?).to be false
|
625
625
|
end
|
626
626
|
end
|
627
627
|
end
|
628
628
|
|
629
|
-
describe
|
629
|
+
describe '#socket?' do
|
630
630
|
# Sockets are not handled for now
|
631
631
|
|
632
|
-
context
|
633
|
-
it
|
634
|
-
expect(file_stat.socket?).to
|
632
|
+
context 'when the file is not a socket' do
|
633
|
+
it 'returns false' do
|
634
|
+
expect(file_stat.socket?).to be false
|
635
635
|
end
|
636
636
|
end
|
637
637
|
end
|
638
638
|
|
639
|
-
describe
|
640
|
-
it
|
641
|
-
|
642
|
-
expect(file_stat.sticky?).to
|
639
|
+
describe '#sticky?' do
|
640
|
+
it 'returns true if the named file has the sticky bit set' do
|
641
|
+
_fs.chmod(01777, '/test-file')
|
642
|
+
expect(file_stat.sticky?).to be true
|
643
643
|
end
|
644
644
|
|
645
645
|
it "returns false if the named file hasn't' the sticky bit set" do
|
646
|
-
expect(file_stat.sticky?).to
|
646
|
+
expect(file_stat.sticky?).to be false
|
647
647
|
end
|
648
648
|
end
|
649
649
|
|
650
650
|
describe '#symlink?' do
|
651
651
|
context 'when dereference is true' do
|
652
|
-
context
|
653
|
-
it
|
654
|
-
expect(dereferenced_link_stat.symlink?).to
|
652
|
+
context 'when the entry is a symlink' do
|
653
|
+
it 'returns false' do
|
654
|
+
expect(dereferenced_link_stat.symlink?).to be false
|
655
655
|
end
|
656
656
|
end
|
657
657
|
|
658
|
-
context
|
659
|
-
it
|
660
|
-
expect(dereferenced_file_stat.symlink?).to
|
658
|
+
context 'when the entry is not a symlink' do
|
659
|
+
it 'returns false' do
|
660
|
+
expect(dereferenced_file_stat.symlink?).to be false
|
661
661
|
end
|
662
662
|
end
|
663
663
|
end
|
664
664
|
|
665
665
|
context 'when dereference is false' do
|
666
|
-
context
|
667
|
-
it
|
668
|
-
expect(link_stat.symlink?).to
|
666
|
+
context 'when the entry is a symlink' do
|
667
|
+
it 'returns true' do
|
668
|
+
expect(link_stat.symlink?).to be true
|
669
669
|
end
|
670
670
|
end
|
671
671
|
|
672
|
-
context
|
673
|
-
it
|
674
|
-
expect(file_stat.symlink?).to
|
672
|
+
context 'when the entry is not a symlink' do
|
673
|
+
it 'returns false' do
|
674
|
+
expect(file_stat.symlink?).to be false
|
675
675
|
end
|
676
676
|
end
|
677
677
|
end
|
678
678
|
end
|
679
679
|
|
680
|
-
describe
|
681
|
-
it
|
682
|
-
|
680
|
+
describe '#uid' do
|
681
|
+
it 'returns the user id of the named entry' do
|
682
|
+
_fs.chown(42, nil, '/test-file')
|
683
683
|
expect(file_stat.uid).to be(42)
|
684
684
|
end
|
685
685
|
end
|
686
686
|
|
687
|
-
describe
|
688
|
-
context
|
689
|
-
it
|
690
|
-
|
687
|
+
describe '#world_reable?' do
|
688
|
+
context 'when +file_name+ is readable by others' do
|
689
|
+
it 'returns an integer representing the file permission bits of +file_name+' do
|
690
|
+
_fs.chmod(MemFs::Fake::Entry::OREAD, '/test-file')
|
691
691
|
expect(file_stat.world_readable?).to eq(MemFs::Fake::Entry::OREAD)
|
692
692
|
end
|
693
693
|
end
|
694
694
|
|
695
|
-
context
|
696
|
-
it
|
697
|
-
|
695
|
+
context 'when +file_name+ is not readable by others' do
|
696
|
+
it 'returns nil' do
|
697
|
+
_fs.chmod(MemFs::Fake::Entry::UREAD, '/test-file')
|
698
698
|
expect(file_stat.world_readable?).to be_nil
|
699
699
|
end
|
700
700
|
end
|
701
701
|
end
|
702
702
|
|
703
|
-
describe
|
704
|
-
context
|
705
|
-
it
|
706
|
-
|
703
|
+
describe '#world_writable?' do
|
704
|
+
context 'when +file_name+ is writable by others' do
|
705
|
+
it 'returns an integer representing the file permission bits of +file_name+' do
|
706
|
+
_fs.chmod(MemFs::Fake::Entry::OWRITE, '/test-file')
|
707
707
|
expect(file_stat.world_writable?).to eq(MemFs::Fake::Entry::OWRITE)
|
708
708
|
end
|
709
709
|
end
|
710
710
|
|
711
|
-
context
|
712
|
-
it
|
713
|
-
|
711
|
+
context 'when +file_name+ is not writable by others' do
|
712
|
+
it 'returns nil' do
|
713
|
+
_fs.chmod(MemFs::Fake::Entry::UWRITE, '/test-file')
|
714
714
|
expect(file_stat.world_writable?).to be_nil
|
715
715
|
end
|
716
716
|
end
|
717
717
|
end
|
718
718
|
|
719
|
-
describe
|
719
|
+
describe '#writable?' do
|
720
720
|
let(:access) { 0 }
|
721
721
|
let(:gid) { 0 }
|
722
722
|
let(:uid) { 0 }
|
@@ -727,54 +727,54 @@ module MemFs
|
|
727
727
|
entry.gid = gid
|
728
728
|
end
|
729
729
|
|
730
|
-
context
|
731
|
-
it
|
732
|
-
expect(file_stat.writable?).to
|
730
|
+
context 'when the file is not executable by anyone' do
|
731
|
+
it 'return false' do
|
732
|
+
expect(file_stat.writable?).to be false
|
733
733
|
end
|
734
734
|
end
|
735
735
|
|
736
|
-
context
|
736
|
+
context 'when the file is user executable' do
|
737
737
|
let(:access) { MemFs::Fake::Entry::UWRITE }
|
738
738
|
|
739
|
-
context
|
739
|
+
context 'and the current user owns the file' do
|
740
740
|
let(:uid) { Process.euid }
|
741
741
|
|
742
|
-
it
|
743
|
-
expect(file_stat.writable?).to
|
742
|
+
it 'returns true' do
|
743
|
+
expect(file_stat.writable?).to be true
|
744
744
|
end
|
745
745
|
end
|
746
746
|
end
|
747
747
|
|
748
|
-
context
|
748
|
+
context 'when the file is group executable' do
|
749
749
|
let(:access) { MemFs::Fake::Entry::GWRITE }
|
750
750
|
|
751
|
-
context
|
751
|
+
context 'and the current user is part of the owner group' do
|
752
752
|
let(:gid) { Process.egid }
|
753
753
|
|
754
|
-
it
|
755
|
-
expect(file_stat.writable?).to
|
754
|
+
it 'returns true' do
|
755
|
+
expect(file_stat.writable?).to be true
|
756
756
|
end
|
757
757
|
end
|
758
758
|
end
|
759
759
|
|
760
|
-
context
|
760
|
+
context 'when the file is executable by anyone' do
|
761
761
|
let(:access) { MemFs::Fake::Entry::OWRITE }
|
762
762
|
|
763
|
-
context
|
764
|
-
it
|
765
|
-
expect(file_stat.writable?).to
|
763
|
+
context 'and the user has no specific right on it' do
|
764
|
+
it 'returns true' do
|
765
|
+
expect(file_stat.writable?).to be true
|
766
766
|
end
|
767
767
|
end
|
768
768
|
end
|
769
769
|
|
770
|
-
context
|
771
|
-
it
|
772
|
-
expect(file_stat.writable?).to
|
770
|
+
context 'when the file does not exist' do
|
771
|
+
it 'returns false' do
|
772
|
+
expect(file_stat.writable?).to be false
|
773
773
|
end
|
774
774
|
end
|
775
775
|
end
|
776
776
|
|
777
|
-
describe
|
777
|
+
describe '#writable_real?' do
|
778
778
|
let(:access) { 0 }
|
779
779
|
let(:gid) { 0 }
|
780
780
|
let(:uid) { 0 }
|
@@ -785,67 +785,67 @@ module MemFs
|
|
785
785
|
entry.gid = gid
|
786
786
|
end
|
787
787
|
|
788
|
-
context
|
789
|
-
it
|
790
|
-
expect(file_stat.writable_real?).to
|
788
|
+
context 'when the file is not executable by anyone' do
|
789
|
+
it 'return false' do
|
790
|
+
expect(file_stat.writable_real?).to be false
|
791
791
|
end
|
792
792
|
end
|
793
793
|
|
794
|
-
context
|
794
|
+
context 'when the file is user executable' do
|
795
795
|
let(:access) { MemFs::Fake::Entry::UWRITE }
|
796
796
|
|
797
|
-
context
|
797
|
+
context 'and the current user owns the file' do
|
798
798
|
let(:uid) { Process.euid }
|
799
799
|
|
800
|
-
it
|
801
|
-
expect(file_stat.writable_real?).to
|
800
|
+
it 'returns true' do
|
801
|
+
expect(file_stat.writable_real?).to be true
|
802
802
|
end
|
803
803
|
end
|
804
804
|
end
|
805
805
|
|
806
|
-
context
|
806
|
+
context 'when the file is group executable' do
|
807
807
|
let(:access) { MemFs::Fake::Entry::GWRITE }
|
808
808
|
|
809
|
-
context
|
809
|
+
context 'and the current user is part of the owner group' do
|
810
810
|
let(:gid) { Process.egid }
|
811
811
|
|
812
|
-
it
|
813
|
-
expect(file_stat.writable_real?).to
|
812
|
+
it 'returns true' do
|
813
|
+
expect(file_stat.writable_real?).to be true
|
814
814
|
end
|
815
815
|
end
|
816
816
|
end
|
817
817
|
|
818
|
-
context
|
818
|
+
context 'when the file is executable by anyone' do
|
819
819
|
let(:access) { MemFs::Fake::Entry::OWRITE }
|
820
820
|
|
821
|
-
context
|
822
|
-
it
|
823
|
-
expect(file_stat.writable_real?).to
|
821
|
+
context 'and the user has no specific right on it' do
|
822
|
+
it 'returns true' do
|
823
|
+
expect(file_stat.writable_real?).to be true
|
824
824
|
end
|
825
825
|
end
|
826
826
|
end
|
827
827
|
|
828
|
-
context
|
829
|
-
it
|
830
|
-
expect(file_stat.writable_real?).to
|
828
|
+
context 'when the file does not exist' do
|
829
|
+
it 'returns false' do
|
830
|
+
expect(file_stat.writable_real?).to be false
|
831
831
|
end
|
832
832
|
end
|
833
833
|
end
|
834
834
|
|
835
|
-
describe
|
836
|
-
context
|
837
|
-
it
|
838
|
-
expect(file_stat.zero?).to
|
835
|
+
describe '#zero?' do
|
836
|
+
context 'when the file has a zero size' do
|
837
|
+
it 'returns true' do
|
838
|
+
expect(file_stat.zero?).to be true
|
839
839
|
end
|
840
840
|
end
|
841
841
|
|
842
|
-
context
|
842
|
+
context 'when the file does not have a zero size' do
|
843
843
|
before :each do
|
844
|
-
|
844
|
+
_fs.find!('/test-file').content << 'test'
|
845
845
|
end
|
846
846
|
|
847
|
-
it
|
848
|
-
expect(file_stat.zero?).to
|
847
|
+
it 'returns false' do
|
848
|
+
expect(file_stat.zero?).to be false
|
849
849
|
end
|
850
850
|
end
|
851
851
|
end
|