memfs 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rubocop.yml +29 -0
- data/CHANGELOG.md +7 -0
- data/Guardfile +5 -6
- data/README.md +6 -6
- data/Rakefile +9 -1
- data/lib/memfs.rb +6 -4
- data/lib/memfs/dir.rb +17 -21
- data/lib/memfs/fake/entry.rb +2 -2
- data/lib/memfs/fake/file/content.rb +3 -2
- data/lib/memfs/file.rb +54 -116
- data/lib/memfs/file/stat.rb +2 -2
- data/lib/memfs/file_system.rb +11 -13
- data/lib/memfs/io.rb +201 -0
- data/lib/memfs/version.rb +1 -1
- data/memfs.gemspec +17 -17
- data/memfs.png +0 -0
- data/spec/fileutils_spec.rb +233 -228
- data/spec/memfs/dir_spec.rb +76 -76
- data/spec/memfs/fake/directory_spec.rb +20 -20
- data/spec/memfs/fake/entry_spec.rb +24 -24
- data/spec/memfs/fake/file/content_spec.rb +43 -45
- data/spec/memfs/fake/file_spec.rb +14 -14
- data/spec/memfs/fake/symlink_spec.rb +22 -22
- data/spec/memfs/file/stat_spec.rb +314 -314
- data/spec/memfs/file_spec.rb +1636 -970
- data/spec/memfs/file_system_spec.rb +83 -83
- data/spec/memfs_spec.rb +15 -15
- data/spec/spec_helper.rb +17 -1
- metadata +36 -57
@@ -62,7 +62,7 @@ module MemFs
|
|
62
62
|
let(:value) { parent }
|
63
63
|
end
|
64
64
|
|
65
|
-
describe
|
65
|
+
describe '.new' do
|
66
66
|
it "sets its default uid to the current user's uid" do
|
67
67
|
expect(entry.uid).to eq(Process.euid)
|
68
68
|
end
|
@@ -71,72 +71,72 @@ module MemFs
|
|
71
71
|
expect(entry.gid).to eq(Process.egid)
|
72
72
|
end
|
73
73
|
|
74
|
-
it
|
74
|
+
it 'extract its name from the path passed as argument' do
|
75
75
|
expect(entry.name).to eq('test')
|
76
76
|
end
|
77
77
|
|
78
|
-
it
|
78
|
+
it 'sets an empty string as name if none is given' do
|
79
79
|
expect(Entry.new.name).to be_empty
|
80
80
|
end
|
81
81
|
|
82
|
-
it
|
82
|
+
it 'sets the access time' do
|
83
83
|
expect(Entry.new.atime).to be_a(Time)
|
84
84
|
end
|
85
85
|
|
86
|
-
it
|
86
|
+
it 'sets the modification time' do
|
87
87
|
expect(entry.mtime).to be_a(Time)
|
88
88
|
end
|
89
89
|
|
90
|
-
it
|
90
|
+
it 'sets atime and mtime to the same value' do
|
91
91
|
expect(entry.atime).to eq(entry.mtime)
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
|
-
describe
|
96
|
-
it
|
95
|
+
describe '#delete' do
|
96
|
+
it 'removes the entry from its parent' do
|
97
97
|
entry.delete
|
98
98
|
expect(parent.entries).not_to have_value(entry)
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
102
|
describe '#dereferenced' do
|
103
|
-
it
|
103
|
+
it 'returns the entry itself' do
|
104
104
|
expect(entry.dereferenced).to be(entry)
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
|
-
describe
|
109
|
-
it
|
108
|
+
describe '#dereferenced_name' do
|
109
|
+
it 'returns the entry name' do
|
110
110
|
expect(entry.dereferenced_name).to eq('test')
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
-
describe
|
115
|
-
it
|
114
|
+
describe '#dereferenced_path' do
|
115
|
+
it 'returns the entry path' do
|
116
116
|
expect(entry.dereferenced_path).to eq('/parent/test')
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
120
|
describe '#find' do
|
121
|
-
it
|
121
|
+
it 'raises an error' do
|
122
122
|
expect { entry.find('test') }.to raise_error(Errno::ENOTDIR)
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
|
-
describe
|
127
|
-
it
|
126
|
+
describe '#dev' do
|
127
|
+
it 'returns an integer representing the device on which the entry resides' do
|
128
128
|
expect(entry.dev).to be_a(Fixnum)
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
-
describe
|
133
|
-
it
|
132
|
+
describe '#ino' do
|
133
|
+
it 'Returns the inode number for the entry' do
|
134
134
|
expect(entry.ino).to be_a(Fixnum)
|
135
135
|
end
|
136
136
|
end
|
137
137
|
|
138
|
-
describe
|
139
|
-
it
|
138
|
+
describe '#path' do
|
139
|
+
it 'returns the complete path of the entry' do
|
140
140
|
expect(entry.path).to eq('/parent/test')
|
141
141
|
end
|
142
142
|
end
|
@@ -147,7 +147,7 @@ module MemFs
|
|
147
147
|
end
|
148
148
|
end
|
149
149
|
|
150
|
-
describe
|
150
|
+
describe '#touch' do
|
151
151
|
let(:time) { Time.now - 5000 }
|
152
152
|
|
153
153
|
before :each do
|
@@ -155,18 +155,18 @@ module MemFs
|
|
155
155
|
entry.mtime = time
|
156
156
|
end
|
157
157
|
|
158
|
-
it
|
158
|
+
it 'sets the access time to now' do
|
159
159
|
entry.touch
|
160
160
|
expect(entry.atime).not_to eq(time)
|
161
161
|
end
|
162
162
|
|
163
|
-
it
|
163
|
+
it 'sets the modification time to now' do
|
164
164
|
entry.touch
|
165
165
|
expect(entry.mtime).not_to eq(time)
|
166
166
|
end
|
167
167
|
end
|
168
168
|
|
169
|
-
describe
|
169
|
+
describe '#type' do
|
170
170
|
it "returns 'unknown" do
|
171
171
|
expect(entry.type).to eq('unknown')
|
172
172
|
end
|
@@ -3,61 +3,60 @@ require 'spec_helper'
|
|
3
3
|
|
4
4
|
module MemFs
|
5
5
|
module Fake
|
6
|
-
|
7
6
|
describe File::Content do
|
8
7
|
subject { File::Content.new }
|
9
8
|
|
10
|
-
describe
|
11
|
-
it
|
9
|
+
describe '#<<' do
|
10
|
+
it 'writes the given string to the contained string' do
|
12
11
|
subject << 'test'
|
13
12
|
expect(subject.to_s).to eq('test')
|
14
13
|
end
|
15
14
|
end
|
16
15
|
|
17
|
-
describe
|
18
|
-
context
|
19
|
-
it
|
16
|
+
describe '#initialize' do
|
17
|
+
context 'when no argument is given' do
|
18
|
+
it 'initialize the contained string to an empty one' do
|
20
19
|
expect(subject.to_s).to eq('')
|
21
20
|
end
|
22
21
|
end
|
23
22
|
|
24
|
-
context
|
23
|
+
context 'when an argument is given' do
|
25
24
|
subject { File::Content.new(base_value) }
|
26
25
|
|
27
|
-
context
|
26
|
+
context 'when the argument is a string' do
|
28
27
|
let(:base_value) { 'test' }
|
29
28
|
|
30
|
-
it
|
29
|
+
it 'initialize the contained string with the given one' do
|
31
30
|
expect(subject.to_s).to eq('test')
|
32
31
|
end
|
33
32
|
|
34
|
-
it
|
33
|
+
it 'duplicates the original string to prevent modifications on it' do
|
35
34
|
expect(subject.to_s).not_to be(base_value)
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
39
|
-
context
|
38
|
+
context 'when the argument is not a string' do
|
40
39
|
let(:base_value) { 42 }
|
41
40
|
|
42
|
-
it
|
41
|
+
it 'converts it to a string' do
|
43
42
|
expect(subject.to_s).to eq('42')
|
44
43
|
end
|
45
44
|
end
|
46
45
|
end
|
47
46
|
end
|
48
47
|
|
49
|
-
describe
|
50
|
-
it
|
48
|
+
describe '#puts' do
|
49
|
+
it 'appends the given string to the contained string' do
|
51
50
|
subject.puts 'test'
|
52
51
|
expect(subject.to_s).to eq("test\n")
|
53
52
|
end
|
54
53
|
|
55
|
-
it
|
54
|
+
it 'appends all given strings to the contained string' do
|
56
55
|
subject.puts 'this', 'is', 'a', 'test'
|
57
56
|
expect(subject.to_s).to eq("this\nis\na\ntest\n")
|
58
57
|
end
|
59
58
|
|
60
|
-
context
|
59
|
+
context 'when a line break is present at the end of the given string' do
|
61
60
|
it "doesn't add any line break" do
|
62
61
|
subject.puts "test\n"
|
63
62
|
expect(subject.to_s).not_to eq("test\n\n")
|
@@ -65,14 +64,14 @@ module MemFs
|
|
65
64
|
end
|
66
65
|
end
|
67
66
|
|
68
|
-
describe
|
69
|
-
context
|
70
|
-
it
|
67
|
+
describe '#to_s' do
|
68
|
+
context 'when the content is empty' do
|
69
|
+
it 'returns an empty string' do
|
71
70
|
expect(subject.to_s).to eq('')
|
72
71
|
end
|
73
72
|
end
|
74
73
|
|
75
|
-
context
|
74
|
+
context 'when the content is not empty' do
|
76
75
|
it "returns the content's string" do
|
77
76
|
subject << 'test'
|
78
77
|
expect(subject.to_s).to eq('test')
|
@@ -80,56 +79,56 @@ module MemFs
|
|
80
79
|
end
|
81
80
|
end
|
82
81
|
|
83
|
-
describe
|
84
|
-
subject { File::Content.new('x'*50) }
|
82
|
+
describe '#truncate' do
|
83
|
+
subject { File::Content.new('x' * 50) }
|
85
84
|
|
86
|
-
it
|
85
|
+
it 'truncates the content to length characters' do
|
87
86
|
subject.truncate(5)
|
88
87
|
expect(subject.length).to eq(5)
|
89
88
|
end
|
90
89
|
end
|
91
90
|
|
92
|
-
describe
|
93
|
-
it
|
91
|
+
describe '#write' do
|
92
|
+
it 'writes the given string in content' do
|
94
93
|
subject.write 'test'
|
95
94
|
expect(subject.to_s).to eq('test')
|
96
95
|
end
|
97
96
|
|
98
|
-
it
|
97
|
+
it 'returns the number of bytes written' do
|
99
98
|
expect(subject.write('test')).to eq(4)
|
100
99
|
end
|
101
100
|
|
102
|
-
context
|
103
|
-
it
|
101
|
+
context 'when the argument is not a string' do
|
102
|
+
it 'converts it to a string' do
|
104
103
|
subject.write 42
|
105
104
|
expect(subject.to_s).to eq('42')
|
106
105
|
end
|
107
106
|
end
|
108
107
|
|
109
|
-
context
|
110
|
-
it
|
108
|
+
context 'when the argument is a non-ascii string' do
|
109
|
+
it 'returns the correct number of bytes written' do
|
111
110
|
expect(subject.write('é')).to eq(1)
|
112
111
|
end
|
113
112
|
end
|
114
113
|
end
|
115
114
|
|
116
|
-
context
|
115
|
+
context 'when initialized with a string argument' do
|
117
116
|
subject { File::Content.new('test') }
|
118
117
|
|
119
|
-
describe
|
120
|
-
it
|
118
|
+
describe '#read' do
|
119
|
+
it 'reads +length+ bytes from the contained string' do
|
121
120
|
expect(subject.read(2)).to eq('te')
|
122
121
|
end
|
123
122
|
|
124
|
-
context
|
125
|
-
it
|
123
|
+
context 'when there is nothing else to read' do
|
124
|
+
it 'returns nil' do
|
126
125
|
subject.read 4
|
127
126
|
expect(subject.read(1)).to be_nil
|
128
127
|
end
|
129
128
|
end
|
130
129
|
|
131
|
-
context
|
132
|
-
it
|
130
|
+
context 'when the optional +buffer+ argument is provided' do
|
131
|
+
it 'inserts the output in the buffer' do
|
133
132
|
string = String.new
|
134
133
|
subject.read(2, string)
|
135
134
|
expect(string).to eq('te')
|
@@ -137,28 +136,27 @@ module MemFs
|
|
137
136
|
end
|
138
137
|
end
|
139
138
|
|
140
|
-
describe
|
141
|
-
context
|
142
|
-
it
|
139
|
+
describe '#pos' do
|
140
|
+
context 'when the string has not been read' do
|
141
|
+
it 'returns 0' do
|
143
142
|
expect(subject.pos).to eq(0)
|
144
143
|
end
|
145
144
|
end
|
146
145
|
|
147
|
-
context
|
148
|
-
it
|
146
|
+
context 'when the string has been read' do
|
147
|
+
it 'returns the current offset' do
|
149
148
|
subject.read 2
|
150
149
|
expect(subject.pos).to eq(2)
|
151
150
|
end
|
152
151
|
end
|
153
152
|
end
|
154
153
|
|
155
|
-
describe
|
156
|
-
it
|
154
|
+
describe '#close' do
|
155
|
+
it 'responds to close' do
|
157
156
|
expect(subject).to respond_to(:close)
|
158
157
|
end
|
159
158
|
end
|
160
159
|
end
|
161
160
|
end
|
162
|
-
|
163
161
|
end
|
164
162
|
end
|
@@ -3,51 +3,51 @@ require 'spec_helper'
|
|
3
3
|
module MemFs
|
4
4
|
module Fake
|
5
5
|
describe File do
|
6
|
-
let(:file) {
|
6
|
+
let(:file) { _fs.find!('/test-file') }
|
7
7
|
|
8
8
|
before do
|
9
|
-
|
9
|
+
_fs.touch('/test-file')
|
10
10
|
end
|
11
11
|
|
12
|
-
it
|
12
|
+
it 'stores the modification made on its content' do
|
13
13
|
file.content << 'test'
|
14
|
-
expect(
|
14
|
+
expect(_fs.find!('/test-file').content.to_s).to eq('test')
|
15
15
|
end
|
16
16
|
|
17
|
-
describe
|
18
|
-
it
|
17
|
+
describe '#close' do
|
18
|
+
it 'sets the file as closed?' do
|
19
19
|
file.close
|
20
20
|
expect(file).to be_closed
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
describe
|
25
|
-
it
|
24
|
+
describe '#content' do
|
25
|
+
it 'returns the file content' do
|
26
26
|
expect(file.content).not_to be_nil
|
27
27
|
end
|
28
28
|
|
29
|
-
context
|
30
|
-
it
|
29
|
+
context 'when the file is empty' do
|
30
|
+
it 'returns an empty string container' do
|
31
31
|
expect(file.content.to_s).to be_empty
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
describe
|
37
|
-
context
|
36
|
+
describe '#type' do
|
37
|
+
context 'when the file is a regular file' do
|
38
38
|
it "returns 'file'" do
|
39
39
|
expect(file.type).to eq('file')
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
context
|
43
|
+
context 'when the file is a block device' do
|
44
44
|
it "returns 'blockSpecial'" do
|
45
45
|
file.block_device = true
|
46
46
|
expect(file.type).to eq('blockSpecial')
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
context
|
50
|
+
context 'when the file is a character device' do
|
51
51
|
it "returns 'characterSpecial'" do
|
52
52
|
file.character_device = true
|
53
53
|
expect(file.type).to eq('characterSpecial')
|
@@ -5,7 +5,7 @@ module MemFs
|
|
5
5
|
describe Symlink do
|
6
6
|
describe '#content' do
|
7
7
|
it "returns the target's content" do
|
8
|
-
MemFs::File.open('/test-file', 'w') { |f| f.puts
|
8
|
+
MemFs::File.open('/test-file', 'w') { |f| f.puts 'test' }
|
9
9
|
s = Symlink.new('/test-link', '/test-file')
|
10
10
|
expect(s.content).to be(s.dereferenced.content)
|
11
11
|
end
|
@@ -13,53 +13,53 @@ module MemFs
|
|
13
13
|
|
14
14
|
describe '#dereferenced' do
|
15
15
|
it "returns the target if it's not a symlink" do
|
16
|
-
|
17
|
-
target =
|
16
|
+
_fs.touch '/test-file'
|
17
|
+
target = _fs.find!('/test-file')
|
18
18
|
|
19
19
|
s = Symlink.new('/test-link', '/test-file')
|
20
20
|
|
21
21
|
expect(s.dereferenced).to eq(target)
|
22
22
|
end
|
23
23
|
|
24
|
-
it
|
25
|
-
|
26
|
-
target =
|
24
|
+
it 'returns the last target of the chain' do
|
25
|
+
_fs.touch '/test-file'
|
26
|
+
target = _fs.find!('/test-file')
|
27
27
|
|
28
|
-
|
28
|
+
_fs.symlink '/test-file', '/test-link'
|
29
29
|
s = Symlink.new('/test-link2', '/test-link')
|
30
30
|
|
31
31
|
expect(s.dereferenced).to eq(target)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
describe
|
35
|
+
describe '#dereferenced_name' do
|
36
36
|
context "when the symlink's target exists" do
|
37
|
-
it
|
38
|
-
|
37
|
+
it 'returns its target name' do
|
38
|
+
_fs.touch('/test-file')
|
39
39
|
symlink = Symlink.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
|
-
it
|
45
|
+
it 'returns its target name' do
|
46
46
|
symlink = Symlink.new('/test-link', '/no-file')
|
47
47
|
expect(symlink.dereferenced_name).to eq('no-file')
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
describe
|
52
|
+
describe '#dereferenced_path' do
|
53
53
|
context "when the symlink's target exists" do
|
54
|
-
it
|
55
|
-
|
54
|
+
it 'returns its target path' do
|
55
|
+
_fs.touch('/test-file')
|
56
56
|
symlink = Symlink.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
|
-
it
|
62
|
+
it 'raises an exception' do
|
63
63
|
symlink = Symlink.new('/test-link', '/no-file')
|
64
64
|
expect {
|
65
65
|
symlink.dereferenced_path
|
@@ -69,17 +69,17 @@ module MemFs
|
|
69
69
|
end
|
70
70
|
|
71
71
|
describe '#find' do
|
72
|
-
let(:file) {
|
72
|
+
let(:file) { _fs.find!('/test-dir/test-file') }
|
73
73
|
|
74
74
|
before :each do
|
75
|
-
|
76
|
-
|
75
|
+
_fs.mkdir '/test-dir'
|
76
|
+
_fs.touch '/test-dir/test-file'
|
77
77
|
end
|
78
78
|
|
79
79
|
context "when the symlink's target exists" do
|
80
80
|
subject { Symlink.new('/test-dir-link', '/test-dir') }
|
81
81
|
|
82
|
-
it
|
82
|
+
it 'forwards the search to it' do
|
83
83
|
entry = subject.find('test-file')
|
84
84
|
expect(entry).to eq(file)
|
85
85
|
end
|
@@ -88,7 +88,7 @@ module MemFs
|
|
88
88
|
context "when the symlink's target does not exist" do
|
89
89
|
subject { Symlink.new('/test-no-link', '/no-dir') }
|
90
90
|
|
91
|
-
it
|
91
|
+
it 'returns nil' do
|
92
92
|
entry = subject.find('test-file')
|
93
93
|
expect(entry).to be_nil
|
94
94
|
end
|
@@ -96,13 +96,13 @@ module MemFs
|
|
96
96
|
end
|
97
97
|
|
98
98
|
describe '#target' do
|
99
|
-
it
|
99
|
+
it 'returns the target of the symlink' do
|
100
100
|
s = Symlink.new('/test-link', '/test-file')
|
101
101
|
expect(s.target).to eq('/test-file')
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
-
describe
|
105
|
+
describe '#type' do
|
106
106
|
it "returns 'link'" do
|
107
107
|
s = Symlink.new('/test-link', '/test-file')
|
108
108
|
expect(s.type).to eq('link')
|