memfs 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,393 @@
1
+ require 'spec_helper'
2
+
3
+ module MemFs
4
+ describe FileSystem do
5
+ subject { fs }
6
+
7
+ before :each do
8
+ subject.mkdir '/test-dir'
9
+ end
10
+
11
+ describe '#directory?' do
12
+ it "returns true if an entry is a directory" do
13
+ expect(subject.directory?('/test-dir')).to be_true
14
+ end
15
+
16
+ it "returns false if an entry is not a directory" do
17
+ subject.touch('/some-file')
18
+ expect(subject.directory?('/some-file')).to be_false
19
+ end
20
+ end
21
+
22
+ describe '#chdir' do
23
+ it "changes the current working directory" do
24
+ subject.chdir '/test-dir'
25
+ expect(subject.getwd).to eq('/test-dir')
26
+ end
27
+
28
+ it "raises an error if directory does not exist" do
29
+ expect { subject.chdir('/nowhere') }.to raise_error(Errno::ENOENT)
30
+ end
31
+
32
+ it "raises an error if the destination is not a directory" do
33
+ subject.touch('/test-file')
34
+ expect { subject.chdir('/test-file') }.to raise_error(Errno::ENOTDIR)
35
+ end
36
+
37
+ context "when a block is given" do
38
+ it "changes current working directory for the block" do
39
+ location = nil
40
+ subject.chdir '/test-dir' do
41
+ location = subject.getwd
42
+ end
43
+ expect(location).to eq('/test-dir')
44
+ end
45
+
46
+ it "gets back to previous directory once the block is finished" do
47
+ subject.chdir '/'
48
+ previous_dir = subject.getwd
49
+ subject.chdir('/test-dir') {}
50
+ expect(subject.getwd).to eq(previous_dir)
51
+ end
52
+ end
53
+
54
+ context "when the destination is a symlink" do
55
+ it "sets current directory as the last link chain target" do
56
+ subject.symlink('/test-dir', '/test-link')
57
+ subject.chdir('/test-link')
58
+ expect(subject.getwd).to eq('/test-dir')
59
+ end
60
+ end
61
+ end
62
+
63
+ describe '#chmod' do
64
+ it "changes permission bits on the named file" do
65
+ subject.touch('/some-file')
66
+ subject.chmod(0777, '/some-file')
67
+ expect(subject.find!('/some-file').mode).to be(0100777)
68
+ end
69
+
70
+ context "when the named file is a symlink" do
71
+ it "changes the permission bits on the symlink itself" do
72
+ subject.touch('/some-file')
73
+ subject.symlink('/some-file', '/some-link')
74
+ subject.chmod(0777, '/some-link')
75
+ expect(subject.find!('/some-link').mode).to be(0100777)
76
+ end
77
+ end
78
+ end
79
+
80
+ describe "#chown" do
81
+ before :each do
82
+ subject.touch '/test-file'
83
+ end
84
+
85
+ it "changes the owner of the named file to the given numeric owner id" do
86
+ subject.chown(42, nil, '/test-file')
87
+ expect(subject.find!('/test-file').uid).to be(42)
88
+ end
89
+
90
+ it "changes the group of the named file to the given numeric group id" do
91
+ subject.chown(nil, 42, '/test-file')
92
+ expect(subject.find!('/test-file').gid).to be(42)
93
+ end
94
+
95
+ it "ignores nil user id" do
96
+ previous_uid = subject.find!('/test-file').uid
97
+
98
+ subject.chown(nil, 42, '/test-file')
99
+ expect(subject.find!('/test-file').uid).to eq(previous_uid)
100
+ end
101
+
102
+ it "ignores nil group id" do
103
+ previous_gid = subject.find!('/test-file').gid
104
+
105
+ subject.chown(42, nil, '/test-file')
106
+ expect(subject.find!('/test-file').gid).to eq(previous_gid)
107
+ end
108
+
109
+ it "ignores -1 user id" do
110
+ previous_uid = subject.find!('/test-file').uid
111
+
112
+ subject.chown(-1, 42, '/test-file')
113
+ expect(subject.find!('/test-file').uid).to eq(previous_uid)
114
+ end
115
+
116
+ it "ignores -1 group id" do
117
+ previous_gid = subject.find!('/test-file').gid
118
+
119
+ subject.chown(42, -1, '/test-file')
120
+ expect(subject.find!('/test-file').gid).to eq(previous_gid)
121
+ end
122
+
123
+ context "when the named entry is a symlink" do
124
+ before :each do
125
+ subject.symlink '/test-file', '/test-link'
126
+ end
127
+
128
+ it "changes the owner on the last target of the link chain" do
129
+ subject.chown(42, nil, '/test-link')
130
+ expect(subject.find!('/test-file').uid).to be(42)
131
+ end
132
+
133
+ it "changes the group on the last target of the link chain" do
134
+ subject.chown(nil, 42, '/test-link')
135
+ expect(subject.find!('/test-file').gid).to be(42)
136
+ end
137
+
138
+ it "doesn't change the owner of the symlink" do
139
+ subject.chown(42, nil, '/test-link')
140
+ expect(subject.find!('/test-link').uid).not_to eq(42)
141
+ end
142
+
143
+ it "doesn't change the group of the symlink" do
144
+ subject.chown(nil, 42, '/test-link')
145
+ expect(subject.find!('/test-link').gid).not_to eq(42)
146
+ end
147
+ end
148
+ end
149
+
150
+ describe '#clear!' do
151
+ it "clear the registred entries" do
152
+ subject.clear!
153
+ expect(subject.root.entry_names).to eq(%w[. ..])
154
+ end
155
+
156
+ it "sets the current directory to /" do
157
+ subject.clear!
158
+ expect(subject.getwd).to eq('/')
159
+ end
160
+ end
161
+
162
+ describe '#entries' do
163
+ it "returns an array containing all of the filenames in the given directory" do
164
+ %w[/test-dir/new-dir /test-dir/new-dir2].each { |dir| subject.mkdir dir }
165
+ subject.touch '/test-dir/test-file', '/test-dir/test-file2'
166
+ expect(subject.entries('/test-dir')).to eq(%w[. .. new-dir new-dir2 test-file test-file2])
167
+ end
168
+ end
169
+
170
+ describe '#find' do
171
+ it "finds the entry if it exists" do
172
+ expect(subject.find('/test-dir').name).to eq('test-dir')
173
+ end
174
+
175
+ it "doesn't raise an error if path does not exist" do
176
+ expect { subject.find('/nowhere') }.not_to raise_error(Errno::ENOENT)
177
+ end
178
+ end
179
+
180
+ describe '#find!' do
181
+ it "finds the entry if it exists" do
182
+ expect(subject.find!('/test-dir').name).to eq('test-dir')
183
+ end
184
+
185
+ it "raises an error if path does not exist" do
186
+ expect { subject.find!('/nowhere') }.to raise_error(Errno::ENOENT)
187
+ end
188
+ end
189
+
190
+ describe '#find_directory!' do
191
+ it "returns the named directory" do
192
+ expect(subject.find_directory!('/test-dir')).to be_a(Fake::Directory)
193
+ end
194
+
195
+ it "raises an error if the named entry is not a directory" do
196
+ subject.touch '/test-file'
197
+ expect { subject.find_directory!('/test-file') }.to raise_error(Errno::ENOTDIR)
198
+ end
199
+ end
200
+
201
+ describe '#find_parent!' do
202
+ it "returns the parent directory of the named entry" do
203
+ expect(subject.find_parent!('/test-dir/test-file')).to be_a(Fake::Directory)
204
+ end
205
+
206
+ it "raises an error if the parent directory does not exist" do
207
+ expect { subject.find_parent!('/no-dir/test-file') }.to raise_error(Errno::ENOENT)
208
+ end
209
+
210
+ it "raises an error if the parent is not a directory" do
211
+ subject.touch('/test-file')
212
+ expect { subject.find_parent!('/test-file/test') }.to raise_error(Errno::ENOTDIR)
213
+ end
214
+ end
215
+
216
+ describe '#getwd' do
217
+ it "returns the current working directory" do
218
+ subject.chdir '/test-dir'
219
+ expect(subject.getwd).to eq('/test-dir')
220
+ end
221
+ end
222
+
223
+ describe '#link' do
224
+ before :each do
225
+ subject.touch('/some-file')
226
+ end
227
+
228
+ it "creates a hard link +dest+ that points to +src+" do
229
+ subject.link('/some-file', '/some-link')
230
+ expect(subject.find!('/some-link').content).to be(subject.find!('/some-file').content)
231
+ end
232
+
233
+ it "does not create a symbolic link" do
234
+ subject.link('/some-file', '/some-link')
235
+ expect(subject.find!('/some-link')).not_to be_a(Fake::Symlink)
236
+ end
237
+
238
+ context "when +new_name+ already exists" do
239
+ it "raises an exception" do
240
+ subject.touch('/some-link')
241
+ expect { subject.link('/some-file', '/some-link') }.to raise_error(SystemCallError)
242
+ end
243
+ end
244
+ end
245
+
246
+ describe '#mkdir' do
247
+ it "creates a directory" do
248
+ subject.mkdir '/new-dir'
249
+ expect(subject.find!('/new-dir')).to be_a(Fake::Directory)
250
+ end
251
+
252
+ context "when a relative path is given" do
253
+ it "creates a directory in current directory" do
254
+ subject.chdir '/test-dir'
255
+ subject.mkdir 'new-dir'
256
+ expect(subject.find!('/test-dir/new-dir')).to be_a(Fake::Directory)
257
+ end
258
+ end
259
+
260
+ context "when the directory already exists" do
261
+ it "raises an exception" do
262
+ expect { subject.mkdir('/') }.to raise_error(Errno::EEXIST)
263
+ end
264
+ end
265
+ end
266
+
267
+ describe '#new' do
268
+ it "creates the root directory" do
269
+ expect(subject.find!('/')).to be(subject.root)
270
+ end
271
+ end
272
+
273
+ describe "#pwd" do
274
+ it_behaves_like 'aliased method', :pwd, :getwd
275
+ end
276
+
277
+ describe "#rename" do
278
+ it "renames the given file to the new name" do
279
+ subject.touch('/test-file')
280
+ subject.rename('/test-file', '/test-file2')
281
+ expect(subject.find('/test-file2')).not_to be_nil
282
+ end
283
+
284
+ it "removes the old file" do
285
+ subject.touch('/test-file')
286
+ subject.rename('/test-file', '/test-file2')
287
+ expect(subject.find('/test-file')).to be_nil
288
+ end
289
+
290
+ it "can move a file in another directory" do
291
+ subject.touch('/test-file')
292
+ subject.rename('/test-file', '/test-dir/test-file')
293
+ expect(subject.find('/test-dir/test-file')).not_to be_nil
294
+ end
295
+ end
296
+
297
+ describe "#rmdir" do
298
+ it "removes the given directory" do
299
+ subject.rmdir('/test-dir')
300
+ expect(subject.find('/test-dir')).to be_nil
301
+ end
302
+
303
+ context "when the directory is not empty" do
304
+ it "raises an exception" do
305
+ subject.mkdir('/test-dir/test-sub-dir')
306
+ expect { subject.rmdir('/test-dir') }.to raise_error(Errno::ENOTEMPTY)
307
+ end
308
+ end
309
+ end
310
+
311
+ describe '#symlink' do
312
+ it "creates a symbolic link" do
313
+ subject.symlink('/some-file', '/some-link')
314
+ expect(subject.find!('/some-link')).to be_a(Fake::Symlink)
315
+ end
316
+
317
+ context "when +new_name+ already exists" do
318
+ it "raises an exception" do
319
+ subject.touch('/some-file')
320
+ subject.touch('/some-file2')
321
+ expect { subject.symlink('/some-file', '/some-file2') }.to raise_error(Errno::EEXIST)
322
+ end
323
+ end
324
+ end
325
+
326
+ describe '#symlink?' do
327
+ it "returns true if the entry is a symlink" do
328
+ subject.symlink('/test-file', '/test-link')
329
+ expect(subject.symlink?('/test-link')).to be_true
330
+ end
331
+
332
+ it "returns false if the entry is not a symlink" do
333
+ subject.touch('/test-file')
334
+ expect(subject.symlink?('/test-file')).to be_false
335
+ end
336
+
337
+ it "returns false if the entry doesn't exist" do
338
+ expect(subject.symlink?('/test-file')).to be_false
339
+ end
340
+ end
341
+
342
+ describe '#touch' do
343
+ it "creates a regular file" do
344
+ subject.touch '/some-file'
345
+ expect(subject.find!('/some-file')).to be_a(Fake::File)
346
+ end
347
+
348
+ it "creates a regular file for each named filed" do
349
+ subject.touch '/some-file', '/some-file2'
350
+ expect(subject.find!('/some-file2')).to be_a(Fake::File)
351
+ end
352
+
353
+ it "creates an entry only if it doesn't exist" do
354
+ subject.touch '/some-file'
355
+ MemFs::Fake::File.should_not_receive(:new)
356
+ subject.touch '/some-file'
357
+ end
358
+
359
+ context "when the named file already exists" do
360
+ let(:time) { Time.now - 5000 }
361
+ before :each do
362
+ subject.touch '/some-file'
363
+ file = subject.find!('/some-file')
364
+ file.atime = file.mtime = time
365
+ end
366
+
367
+ it "sets the access time of the touched file" do
368
+ subject.touch '/some-file'
369
+ expect(subject.find!('/some-file').atime).not_to eq(time)
370
+ end
371
+
372
+ it "sets the modification time of the touched file" do
373
+ subject.touch '/some-file'
374
+ expect(subject.find!('/some-file').atime).not_to eq(time)
375
+ end
376
+ end
377
+ end
378
+
379
+ describe "#unlink" do
380
+ it "deletes the named file" do
381
+ subject.touch('/some-file')
382
+ subject.unlink('/some-file')
383
+ expect(subject.find('/some-file')).to be_nil
384
+ end
385
+
386
+ context "when the entry is a directory" do
387
+ it "raises an exception" do
388
+ expect { subject.unlink('/test-dir') }.to raise_error
389
+ end
390
+ end
391
+ end
392
+ end
393
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe MemFs do
4
+ subject { MemFs }
5
+
6
+ describe '.activate' do
7
+ it "calls the given block with MemFs activated" do
8
+ subject.activate do
9
+ expect(::Dir).to be(MemFs::Dir)
10
+ end
11
+ end
12
+
13
+ it "resets the original classes once finished" do
14
+ subject.activate {}
15
+ expect(::Dir).to be(MemFs::OriginalDir)
16
+ end
17
+
18
+ it "deactivates MemFs even when an exception occurs" do
19
+ begin
20
+ subject.activate { raise 'Some error' }
21
+ rescue
22
+ end
23
+ expect(::Dir).to be(MemFs::OriginalDir)
24
+ end
25
+ end
26
+
27
+ describe '.activate!' do
28
+ before(:each) { subject.activate! }
29
+ after(:each) { subject.deactivate! }
30
+
31
+ it "replaces Ruby Dir class with a fake one" do
32
+ expect(::Dir).to be(MemFs::Dir)
33
+ end
34
+
35
+ it "replaces Ruby File class with a fake one" do
36
+ expect(::File).to be(MemFs::File)
37
+ end
38
+ end
39
+
40
+ describe '.deactivate!' do
41
+ before :each do
42
+ subject.activate!
43
+ subject.deactivate!
44
+ end
45
+
46
+ it "sets back the Ruby Dir class to the original one" do
47
+ expect(::Dir).to be(MemFs::OriginalDir)
48
+ end
49
+
50
+ it "sets back the Ruby File class to the original one" do
51
+ expect(::File).to be(MemFs::OriginalFile)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,20 @@
1
+ require 'coveralls'
2
+ require 'memfs'
3
+
4
+ Coveralls.wear!
5
+
6
+ RSpec.configure do |config|
7
+ config.before :each do
8
+ MemFs::FileSystem.instance.clear!
9
+ end
10
+
11
+ shared_examples 'aliased method' do |method, original_method|
12
+ it "##{original_method}" do
13
+ expect(subject.method(method)).to eq(subject.method(original_method))
14
+ end
15
+ end
16
+ end
17
+
18
+ def fs
19
+ MemFs::FileSystem.instance
20
+ end
metadata ADDED
@@ -0,0 +1,203 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: memfs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Simon COURTOIS
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: coveralls
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '0.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '0.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '2.12'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '2.12'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.5'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '1.5'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '2.1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '2.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rb-inotify
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '0.8'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '0.8'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rb-fsevent
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '0.9'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '0.9'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rb-fchange
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '0.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: '0.0'
125
+ description: MemFs provides a fake file system that can be used for tests. Strongly
126
+ inspired by FakeFS.
127
+ email:
128
+ - scourtois@cubyx.fr
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - .DS_Store
134
+ - .gitignore
135
+ - .rspec
136
+ - .travis.yml
137
+ - Gemfile
138
+ - Guardfile
139
+ - LICENSE.txt
140
+ - README.md
141
+ - Rakefile
142
+ - lib/fileutils.rb
143
+ - lib/memfs.rb
144
+ - lib/memfs/dir.rb
145
+ - lib/memfs/fake/directory.rb
146
+ - lib/memfs/fake/entry.rb
147
+ - lib/memfs/fake/file.rb
148
+ - lib/memfs/fake/file/content.rb
149
+ - lib/memfs/fake/symlink.rb
150
+ - lib/memfs/file.rb
151
+ - lib/memfs/file/stat.rb
152
+ - lib/memfs/file_system.rb
153
+ - lib/memfs/filesystem_access.rb
154
+ - lib/memfs/version.rb
155
+ - memfs.gemspec
156
+ - spec/fileutils_spec.rb
157
+ - spec/memfs/dir_spec.rb
158
+ - spec/memfs/fake/directory_spec.rb
159
+ - spec/memfs/fake/entry_spec.rb
160
+ - spec/memfs/fake/file/content_spec.rb
161
+ - spec/memfs/fake/file_spec.rb
162
+ - spec/memfs/fake/symlink_spec.rb
163
+ - spec/memfs/file/stat_spec.rb
164
+ - spec/memfs/file_spec.rb
165
+ - spec/memfs/file_system_spec.rb
166
+ - spec/memfs_spec.rb
167
+ - spec/spec_helper.rb
168
+ homepage: http://github.com/simonc/memfs
169
+ licenses: []
170
+ metadata: {}
171
+ post_install_message:
172
+ rdoc_options: []
173
+ require_paths:
174
+ - lib
175
+ required_ruby_version: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - '>='
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ required_rubygems_version: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - '>='
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ requirements: []
186
+ rubyforge_project:
187
+ rubygems_version: 2.0.3
188
+ signing_key:
189
+ specification_version: 4
190
+ summary: memfs-0.0.1
191
+ test_files:
192
+ - spec/fileutils_spec.rb
193
+ - spec/memfs/dir_spec.rb
194
+ - spec/memfs/fake/directory_spec.rb
195
+ - spec/memfs/fake/entry_spec.rb
196
+ - spec/memfs/fake/file/content_spec.rb
197
+ - spec/memfs/fake/file_spec.rb
198
+ - spec/memfs/fake/symlink_spec.rb
199
+ - spec/memfs/file/stat_spec.rb
200
+ - spec/memfs/file_spec.rb
201
+ - spec/memfs/file_system_spec.rb
202
+ - spec/memfs_spec.rb
203
+ - spec/spec_helper.rb