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