memfs 0.1.0 → 0.2.0
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 +4 -4
- data/CHANGELOG.md +14 -2
- data/README.md +31 -0
- data/Rakefile +32 -0
- data/lib/memfs/dir.rb +34 -0
- data/lib/memfs/file.rb +6 -0
- data/lib/memfs/version.rb +1 -1
- data/lib/memfs.rb +17 -0
- data/memfs.gemspec +1 -1
- data/spec/fileutils_spec.rb +10 -10
- data/spec/memfs/dir_spec.rb +125 -3
- data/spec/memfs/file_spec.rb +38 -35
- data/spec/memfs/file_system_spec.rb +16 -20
- data/spec/memfs_spec.rb +27 -0
- metadata +27 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b6b4c8b1d42a534f1cbd453777b69953e9938c6e
|
4
|
+
data.tar.gz: 3380c5e4a95927aa42d69f97f7a94943222659c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5df0d4bc1a1e21810d7486f88bc210254a93240f6421691e89b4e29799b87d097ad7bde48f1fbe43ab763863b41990d6043ac7de4faf5a55a2af2fd7843f1e0
|
7
|
+
data.tar.gz: e216b80ba6337aa655ee91650cf68ccb51996e7610bed863733edfaa238873afb2e63fcc93151be79f6f52a1c022c7447dfac46f7235b1cc6be6dd310f34b87c
|
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,21 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.2.0
|
4
|
+
|
5
|
+
* ADD: Allowing magic creation of files with `MemFs.touch`
|
6
|
+
* ADD: `Dir#each`
|
7
|
+
* ADD: `Dir.delete`
|
8
|
+
* ADD: `Dir.exist?`
|
9
|
+
* ADD: `Dir.foreach`
|
10
|
+
* ADD: `Dir.home`
|
11
|
+
* ADD: `Dir.new`
|
12
|
+
* ADD: `Dir.unlink`
|
13
|
+
* FIX: File.new now truncates a file when opening mode says so
|
14
|
+
|
3
15
|
## 0.1.0
|
4
16
|
|
5
|
-
* Adding `File` missing methods - #3
|
17
|
+
* ADD: Adding `File` missing methods - #3
|
6
18
|
|
7
19
|
## 0.0.2
|
8
20
|
|
9
|
-
* Adding the MIT license to the gemspec file - #2
|
21
|
+
* ADD: Adding the MIT license to the gemspec file - #2
|
data/README.md
CHANGED
@@ -77,6 +77,26 @@ end
|
|
77
77
|
|
78
78
|
All the spec will be sandboxed in MemFs.
|
79
79
|
|
80
|
+
If you want to set it globally with flag activation, you can do the following in
|
81
|
+
you `spec_helper.rb` file:
|
82
|
+
|
83
|
+
``` ruby
|
84
|
+
Rspec.configure do |c|
|
85
|
+
c.around(:each, memfs: true) do |example|
|
86
|
+
MemFs.activate { example.run }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
And then write your specs like this:
|
92
|
+
|
93
|
+
``` ruby
|
94
|
+
it "creates a file", memfs: true do
|
95
|
+
subject.create_file('test.rb')
|
96
|
+
expect(File.exists?('test.rb')).to be_true
|
97
|
+
end
|
98
|
+
```
|
99
|
+
|
80
100
|
### Local activation
|
81
101
|
|
82
102
|
You can choose to activate MemFs only for a specific test:
|
@@ -112,6 +132,17 @@ describe FileCreator do
|
|
112
132
|
end
|
113
133
|
```
|
114
134
|
|
135
|
+
### Utilities
|
136
|
+
|
137
|
+
You can use `MemFs.touch` to quickly create a file and its parent directories:
|
138
|
+
|
139
|
+
``` ruby
|
140
|
+
MemFs.activate do
|
141
|
+
MemFs.touch('/path/to/some/file.rb')
|
142
|
+
File.exist?('/path/to/some/file.rb') # => true
|
143
|
+
end
|
144
|
+
```
|
145
|
+
|
115
146
|
## Requirements
|
116
147
|
|
117
148
|
* Ruby 2.0+
|
data/Rakefile
CHANGED
@@ -1,6 +1,38 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
2
|
require 'rspec/core/rake_task'
|
3
|
+
require 'memfs'
|
3
4
|
|
4
5
|
RSpec::Core::RakeTask.new(:spec)
|
5
6
|
|
6
7
|
task :default => :spec
|
8
|
+
|
9
|
+
desc 'Compares a MemFs class to the original Ruby one ' \
|
10
|
+
'(set CLASS to the compared class)'
|
11
|
+
task :compare do
|
12
|
+
class_name = ENV['CLASS'] || 'File'
|
13
|
+
klass = Object.const_get(class_name)
|
14
|
+
memfs_klass = MemFs.const_get(class_name)
|
15
|
+
|
16
|
+
original_methods = (klass.methods - Object.methods).sort
|
17
|
+
original_i_methods = (klass.instance_methods - Object.methods).sort
|
18
|
+
implemented_methods = MemFs.activate { (memfs_klass.methods - Object.methods).sort }
|
19
|
+
implemented_i_methods = MemFs.activate { (memfs_klass.instance_methods - Object.methods).sort }
|
20
|
+
|
21
|
+
puts "CLASS: #{class_name}"
|
22
|
+
puts
|
23
|
+
puts 'MISSING CLASS METHODS'
|
24
|
+
puts
|
25
|
+
puts original_methods - implemented_methods
|
26
|
+
puts
|
27
|
+
puts 'MISSING INSTANCE METHODS'
|
28
|
+
puts
|
29
|
+
puts original_i_methods - implemented_i_methods
|
30
|
+
puts
|
31
|
+
puts 'ADDITIONAL METHODS'
|
32
|
+
puts
|
33
|
+
puts implemented_methods - original_methods
|
34
|
+
puts
|
35
|
+
puts 'ADDITIONAL INSTANCE METHODS'
|
36
|
+
puts
|
37
|
+
puts implemented_i_methods - original_i_methods
|
38
|
+
end
|
data/lib/memfs/dir.rb
CHANGED
@@ -3,6 +3,7 @@ require 'memfs/filesystem_access'
|
|
3
3
|
module MemFs
|
4
4
|
class Dir
|
5
5
|
extend FilesystemAccess
|
6
|
+
include Enumerable
|
6
7
|
|
7
8
|
def self.chdir(path, &block)
|
8
9
|
fs.chdir path, &block
|
@@ -16,12 +17,23 @@ module MemFs
|
|
16
17
|
def self.exists?(path)
|
17
18
|
File.directory?(path)
|
18
19
|
end
|
20
|
+
class << self; alias :exist? :exists?; end
|
21
|
+
|
22
|
+
def self.foreach(dirname, &block)
|
23
|
+
return to_enum(__callee__, dirname) unless block
|
24
|
+
|
25
|
+
entries(dirname).each(&block)
|
26
|
+
end
|
19
27
|
|
20
28
|
def self.getwd
|
21
29
|
fs.getwd
|
22
30
|
end
|
23
31
|
class << self; alias :pwd :getwd; end
|
24
32
|
|
33
|
+
def self.home(*args)
|
34
|
+
original_dir_class.home(*args)
|
35
|
+
end
|
36
|
+
|
25
37
|
def self.mkdir(path)
|
26
38
|
fs.mkdir path
|
27
39
|
end
|
@@ -29,5 +41,27 @@ module MemFs
|
|
29
41
|
def self.rmdir(path)
|
30
42
|
fs.rmdir path
|
31
43
|
end
|
44
|
+
|
45
|
+
class << self
|
46
|
+
alias :delete :rmdir
|
47
|
+
alias :unlink :rmdir
|
48
|
+
end
|
49
|
+
|
50
|
+
def initialize(path)
|
51
|
+
self.entry = fs.find_directory!(path)
|
52
|
+
end
|
53
|
+
|
54
|
+
def each(&block)
|
55
|
+
return to_enum(__callee__) unless block
|
56
|
+
entry.entry_names.each(&block)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
attr_accessor :entry
|
62
|
+
|
63
|
+
def self.original_dir_class
|
64
|
+
MemFs::OriginalDir
|
65
|
+
end
|
32
66
|
end
|
33
67
|
end
|
data/lib/memfs/file.rb
CHANGED
@@ -238,6 +238,8 @@ module MemFs
|
|
238
238
|
fs.touch(filename) if create_file?
|
239
239
|
|
240
240
|
self.entry = fs.find(filename)
|
241
|
+
|
242
|
+
entry.content.clear if truncate_file?
|
241
243
|
end
|
242
244
|
|
243
245
|
def chmod(mode_int)
|
@@ -358,6 +360,10 @@ module MemFs
|
|
358
360
|
(opening_mode & File::CREAT).nonzero?
|
359
361
|
end
|
360
362
|
|
363
|
+
def truncate_file?
|
364
|
+
(opening_mode & File::TRUNC).nonzero?
|
365
|
+
end
|
366
|
+
|
361
367
|
def writable?
|
362
368
|
(opening_mode & File::WRONLY).nonzero? ||
|
363
369
|
(opening_mode & File::RDWR).nonzero?
|
data/lib/memfs/version.rb
CHANGED
data/lib/memfs.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'memfs/version'
|
2
|
+
require 'fileutils'
|
2
3
|
|
3
4
|
# Provides a clean way to interact with a fake file system.
|
4
5
|
#
|
@@ -97,4 +98,20 @@ module MemFs
|
|
97
98
|
const_set :File, MemFs::OriginalFile
|
98
99
|
end
|
99
100
|
end
|
101
|
+
|
102
|
+
# Creates a file and all its parent directories.
|
103
|
+
#
|
104
|
+
# @param path: The path of the file to create.
|
105
|
+
#
|
106
|
+
# @return nothing.
|
107
|
+
def touch(*paths)
|
108
|
+
if ::File != MemFs::File
|
109
|
+
fail 'Always call MemFs.touch inside a MemFs active context.'
|
110
|
+
end
|
111
|
+
|
112
|
+
paths.each do |path|
|
113
|
+
FileUtils.mkdir_p File.dirname(path)
|
114
|
+
FileUtils.touch path
|
115
|
+
end
|
116
|
+
end
|
100
117
|
end
|
data/memfs.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |gem|
|
|
22
22
|
|
23
23
|
gem.add_development_dependency "coveralls", "~> 0.6"
|
24
24
|
gem.add_development_dependency "rake", "~> 10.0"
|
25
|
-
gem.add_development_dependency "rspec", "~> 2.
|
25
|
+
gem.add_development_dependency "rspec", "~> 2.14"
|
26
26
|
gem.add_development_dependency "guard", "~> 1.5"
|
27
27
|
gem.add_development_dependency "guard-rspec", "~> 2.1"
|
28
28
|
gem.add_development_dependency "rb-inotify", "~> 0.8"
|
data/spec/fileutils_spec.rb
CHANGED
@@ -42,9 +42,9 @@ describe FileUtils do
|
|
42
42
|
|
43
43
|
it "resumes to the old working directory after the block execution finished" do
|
44
44
|
FileUtils.cd '/'
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
expect {
|
46
|
+
FileUtils.cd('/test') {}
|
47
|
+
}.to_not change{FileUtils.pwd}
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -343,7 +343,7 @@ describe FileUtils do
|
|
343
343
|
context "when +remove_destination+ is true" do
|
344
344
|
it "removes each destination file before copy" do
|
345
345
|
FileUtils.touch(['/test-file', '/test-copy'])
|
346
|
-
File.
|
346
|
+
expect(File).to receive(:unlink).with('/test-copy')
|
347
347
|
FileUtils.copy_entry('/test-file', '/test-copy', false, false, true)
|
348
348
|
end
|
349
349
|
end
|
@@ -462,7 +462,7 @@ describe FileUtils do
|
|
462
462
|
|
463
463
|
context "when +:mode+ is set" do
|
464
464
|
it "changes the permission mode to +mode+" do
|
465
|
-
File.
|
465
|
+
expect(File).to receive(:chmod).with(0777, '/test-file2')
|
466
466
|
FileUtils.install('/test-file', '/test-file2', mode: 0777)
|
467
467
|
end
|
468
468
|
end
|
@@ -477,7 +477,7 @@ describe FileUtils do
|
|
477
477
|
|
478
478
|
context "when +dest+ already exists" do
|
479
479
|
it "removes destination before copy" do
|
480
|
-
File.
|
480
|
+
expect(File).to receive(:unlink).with('/test-file2')
|
481
481
|
FileUtils.install('/test-file', '/test-file2')
|
482
482
|
end
|
483
483
|
|
@@ -781,14 +781,14 @@ describe FileUtils do
|
|
781
781
|
it "calls chown(2) on it" do
|
782
782
|
FileUtils.chmod(01777, '/')
|
783
783
|
directory = fs.find('/test-dir')
|
784
|
-
directory.
|
784
|
+
expect(directory).to receive(:uid=).at_least(:once)
|
785
785
|
FileUtils.remove_entry_secure('/test-dir')
|
786
786
|
end
|
787
787
|
|
788
788
|
it "calls chmod(2) on all sub directories" do
|
789
789
|
FileUtils.chmod(01777, '/')
|
790
790
|
directory = fs.find('/test-dir')
|
791
|
-
directory.
|
791
|
+
expect(directory).to receive(:mode=).at_least(:once)
|
792
792
|
FileUtils.remove_entry_secure('/test-dir')
|
793
793
|
end
|
794
794
|
end
|
@@ -839,7 +839,7 @@ describe FileUtils do
|
|
839
839
|
|
840
840
|
describe '.rm_f' do
|
841
841
|
it "calls rm with +:force+ set to true" do
|
842
|
-
FileUtils.
|
842
|
+
expect(FileUtils).to receive(:rm).with('test', force: true)
|
843
843
|
FileUtils.rm_f('test')
|
844
844
|
end
|
845
845
|
end
|
@@ -874,7 +874,7 @@ describe FileUtils do
|
|
874
874
|
|
875
875
|
describe '.rm_rf' do
|
876
876
|
it "calls rm with +:force+ set to true" do
|
877
|
-
FileUtils.
|
877
|
+
expect(FileUtils).to receive(:rm_r).with('test', force: true)
|
878
878
|
FileUtils.rm_rf('test')
|
879
879
|
end
|
880
880
|
end
|
data/spec/memfs/dir_spec.rb
CHANGED
@@ -4,10 +4,16 @@ module MemFs
|
|
4
4
|
describe Dir do
|
5
5
|
subject { MemFs::Dir }
|
6
6
|
|
7
|
+
let(:instance) { MemFs::Dir.new('/test') }
|
8
|
+
|
7
9
|
before :each do
|
8
10
|
subject.mkdir '/test'
|
9
11
|
end
|
10
12
|
|
13
|
+
it 'is Enumerable' do
|
14
|
+
expect(instance).to be_an(Enumerable)
|
15
|
+
end
|
16
|
+
|
11
17
|
describe '.chdir' do
|
12
18
|
it "changes the current working directory" do
|
13
19
|
subject.chdir '/test'
|
@@ -31,13 +37,17 @@ module MemFs
|
|
31
37
|
|
32
38
|
it "gets back to previous directory once the block is finished" do
|
33
39
|
subject.chdir '/'
|
34
|
-
|
35
|
-
|
36
|
-
|
40
|
+
expect {
|
41
|
+
subject.chdir('/test') {}
|
42
|
+
}.to_not change{subject.pwd}
|
37
43
|
end
|
38
44
|
end
|
39
45
|
end
|
40
46
|
|
47
|
+
describe ".delete" do
|
48
|
+
it_behaves_like 'aliased method', :delete, :rmdir
|
49
|
+
end
|
50
|
+
|
41
51
|
describe '.entries' do
|
42
52
|
it "returns an array containing all of the filenames in the given directory" do
|
43
53
|
%w[/test/dir1 /test/dir2].each { |dir| subject.mkdir dir }
|
@@ -46,6 +56,10 @@ module MemFs
|
|
46
56
|
end
|
47
57
|
end
|
48
58
|
|
59
|
+
describe ".exist?" do
|
60
|
+
it_behaves_like 'aliased method', :exist?, :exists?
|
61
|
+
end
|
62
|
+
|
49
63
|
describe ".exists?" do
|
50
64
|
it "returns true if the given +path+ exists and is a directory" do
|
51
65
|
subject.mkdir('/test-dir')
|
@@ -62,12 +76,80 @@ module MemFs
|
|
62
76
|
end
|
63
77
|
end
|
64
78
|
|
79
|
+
describe ".foreach" do
|
80
|
+
before :each do
|
81
|
+
fs.touch('/test/test-file', '/test/test-file2')
|
82
|
+
end
|
83
|
+
|
84
|
+
context "when a block is given" do
|
85
|
+
it "calls the block once for each entry in the named directory" do
|
86
|
+
expect{ |blk|
|
87
|
+
subject.foreach('/test', &blk)
|
88
|
+
}.to yield_control.exactly(4).times
|
89
|
+
end
|
90
|
+
|
91
|
+
it "passes each entry as a parameter to the block" do
|
92
|
+
expect{ |blk|
|
93
|
+
subject.foreach('/test', &blk)
|
94
|
+
}.to yield_successive_args('.', '..', 'test-file', 'test-file2')
|
95
|
+
end
|
96
|
+
|
97
|
+
context "and the directory doesn't exist" do
|
98
|
+
it "raises an exception" do
|
99
|
+
expect{ subject.foreach('/no-dir') {} }.to raise_error
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "and the given path is not a directory" do
|
104
|
+
it "raises an exception" do
|
105
|
+
expect{
|
106
|
+
subject.foreach('/test/test-file') {}
|
107
|
+
}.to raise_error
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "when no block is given" do
|
113
|
+
it "returns an enumerator" do
|
114
|
+
list = subject.foreach('/test-dir')
|
115
|
+
expect(list).to be_an(Enumerator)
|
116
|
+
end
|
117
|
+
|
118
|
+
context "and the directory doesn't exist" do
|
119
|
+
it "returns an enumerator" do
|
120
|
+
list = subject.foreach('/no-dir')
|
121
|
+
expect(list).to be_an(Enumerator)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "and the given path is not a directory" do
|
126
|
+
it "returns an enumerator" do
|
127
|
+
list = subject.foreach('/test-dir/test-file')
|
128
|
+
expect(list).to be_an(Enumerator)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
65
134
|
describe '.getwd' do
|
66
135
|
it "returns the path to the current working directory" do
|
67
136
|
expect(subject.getwd).to eq(FileSystem.instance.getwd)
|
68
137
|
end
|
69
138
|
end
|
70
139
|
|
140
|
+
describe '.home' do
|
141
|
+
it 'returns the home directory of the current user' do
|
142
|
+
expect(subject.home).to eq ENV['HOME']
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'when a username is given' do
|
146
|
+
it 'returns the home directory of the given user' do
|
147
|
+
home_dir = subject.home(ENV['USER'])
|
148
|
+
expect(home_dir).to eq ENV['HOME']
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
71
153
|
describe '.mkdir' do
|
72
154
|
it "creates a directory" do
|
73
155
|
subject.mkdir '/new-folder'
|
@@ -81,6 +163,22 @@ module MemFs
|
|
81
163
|
end
|
82
164
|
end
|
83
165
|
|
166
|
+
describe '.new' do
|
167
|
+
context "when the given directory doesn't exist" do
|
168
|
+
it 'raises an exception' do
|
169
|
+
expect{ subject.new('/no-dir') }.to raise_error
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'when the given path is not a directory' do
|
174
|
+
before { fs.touch('/test/test-file') }
|
175
|
+
|
176
|
+
it 'raises an exception' do
|
177
|
+
expect{ subject.new('/test/test-file') }.to raise_error
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
84
182
|
describe ".pwd" do
|
85
183
|
it_behaves_like 'aliased method', :pwd, :getwd
|
86
184
|
end
|
@@ -100,5 +198,29 @@ module MemFs
|
|
100
198
|
end
|
101
199
|
end
|
102
200
|
end
|
201
|
+
|
202
|
+
describe ".unlink" do
|
203
|
+
it_behaves_like 'aliased method', :unlink, :rmdir
|
204
|
+
end
|
205
|
+
|
206
|
+
describe '#each' do
|
207
|
+
before { fs.touch('/test/test-file', '/test/test-file2') }
|
208
|
+
|
209
|
+
it 'calls the block once for each entry in this directory' do
|
210
|
+
expect{ |blk| instance.each(&blk) }.to yield_control.exactly(4).times
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'passes the filename of each entry as a parameter to the block' do
|
214
|
+
expect{ |blk|
|
215
|
+
instance.each(&blk)
|
216
|
+
}.to yield_successive_args('.', '..', 'test-file', 'test-file2')
|
217
|
+
end
|
218
|
+
|
219
|
+
context 'when no block is given' do
|
220
|
+
it 'returns an enumerator' do
|
221
|
+
expect(instance.each).to be_an(Enumerator)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
103
225
|
end
|
104
226
|
end
|
data/spec/memfs/file_spec.rb
CHANGED
@@ -162,31 +162,27 @@ module MemFs
|
|
162
162
|
end
|
163
163
|
|
164
164
|
it "ignores nil user id" do
|
165
|
-
|
166
|
-
|
167
|
-
subject.
|
168
|
-
expect(subject.stat('/test-file').uid).to eq(previous_uid)
|
165
|
+
expect {
|
166
|
+
subject.chown(nil, 42, '/test-file')
|
167
|
+
}.to_not change{subject.stat('/test-file').uid}
|
169
168
|
end
|
170
169
|
|
171
170
|
it "ignores nil group id" do
|
172
|
-
|
173
|
-
|
174
|
-
subject.
|
175
|
-
expect(subject.stat('/test-file').gid).to eq(previous_gid)
|
171
|
+
expect {
|
172
|
+
subject.chown(42, nil, '/test-file')
|
173
|
+
}.to_not change{subject.stat('/test-file').gid}
|
176
174
|
end
|
177
175
|
|
178
176
|
it "ignores -1 user id" do
|
179
|
-
|
180
|
-
|
181
|
-
subject.
|
182
|
-
expect(subject.stat('/test-file').uid).to eq(previous_uid)
|
177
|
+
expect {
|
178
|
+
subject.chown(-1, 42, '/test-file')
|
179
|
+
}.to_not change{subject.stat('/test-file').uid}
|
183
180
|
end
|
184
181
|
|
185
182
|
it "ignores -1 group id" do
|
186
|
-
|
187
|
-
|
188
|
-
subject.
|
189
|
-
expect(subject.stat('/test-file').gid).to eq(previous_gid)
|
183
|
+
expect {
|
184
|
+
subject.chown(42, -1, '/test-file')
|
185
|
+
}.to_not change{subject.stat('/test-file').gid}
|
190
186
|
end
|
191
187
|
|
192
188
|
context "when the named entry is a symlink" do
|
@@ -717,11 +713,22 @@ module MemFs
|
|
717
713
|
context "and it specifies that the file must be created" do
|
718
714
|
context "and the file already exists" do
|
719
715
|
it "changes the mtime of the file" do
|
720
|
-
fs.
|
716
|
+
expect(fs).to receive(:touch).with('/test-file')
|
721
717
|
subject.new('/test-file', 'w')
|
722
718
|
end
|
723
719
|
end
|
724
720
|
end
|
721
|
+
|
722
|
+
context 'and it specifies that the file must be truncated' do
|
723
|
+
context 'and the file already exists' do
|
724
|
+
it 'truncates its content' do
|
725
|
+
subject.open('/test-file', 'w') { |f| f.puts 'hello' }
|
726
|
+
file = subject.new('/test-file', 'w')
|
727
|
+
file.close
|
728
|
+
expect(subject.read('/test-file')).to eq ''
|
729
|
+
end
|
730
|
+
end
|
731
|
+
end
|
725
732
|
end
|
726
733
|
|
727
734
|
context "when no argument is given" do
|
@@ -825,7 +832,7 @@ module MemFs
|
|
825
832
|
|
826
833
|
context "when the last argument is a hash" do
|
827
834
|
it "passes the contained options to +open+" do
|
828
|
-
subject.
|
835
|
+
expect(subject).to receive(:open)
|
829
836
|
.with('/test-file', File::RDONLY, encoding: 'UTF-8')
|
830
837
|
.and_return(file)
|
831
838
|
subject.read('/test-file', encoding: 'UTF-8')
|
@@ -833,7 +840,7 @@ module MemFs
|
|
833
840
|
|
834
841
|
context "when it contains the +open_args+ key" do
|
835
842
|
it "takes precedence over the other options" do
|
836
|
-
subject.
|
843
|
+
expect(subject).to receive(:open)
|
837
844
|
.with('/test-file', 'r')
|
838
845
|
.and_return(file)
|
839
846
|
subject.read('/test-file', mode: 'w', open_args: ['r'])
|
@@ -1647,31 +1654,27 @@ module MemFs
|
|
1647
1654
|
end
|
1648
1655
|
|
1649
1656
|
it "ignores nil user id" do
|
1650
|
-
|
1651
|
-
|
1652
|
-
file.
|
1653
|
-
expect(file.stat.uid).to eq(previous_uid)
|
1657
|
+
expect {
|
1658
|
+
file.chown(nil, 42)
|
1659
|
+
}.to_not change{file.stat.uid}
|
1654
1660
|
end
|
1655
1661
|
|
1656
1662
|
it "ignores nil group id" do
|
1657
|
-
|
1658
|
-
|
1659
|
-
file.
|
1660
|
-
expect(file.stat.gid).to eq(previous_gid)
|
1663
|
+
expect {
|
1664
|
+
file.chown(42, nil)
|
1665
|
+
}.to_not change{file.stat.gid}
|
1661
1666
|
end
|
1662
1667
|
|
1663
1668
|
it "ignores -1 user id" do
|
1664
|
-
|
1665
|
-
|
1666
|
-
file.
|
1667
|
-
expect(file.stat.uid).to eq(previous_uid)
|
1669
|
+
expect {
|
1670
|
+
file.chown(-1, 42)
|
1671
|
+
}.to_not change{file.stat.uid}
|
1668
1672
|
end
|
1669
1673
|
|
1670
1674
|
it "ignores -1 group id" do
|
1671
|
-
|
1672
|
-
|
1673
|
-
file.
|
1674
|
-
expect(file.stat.gid).to eq(previous_gid)
|
1675
|
+
expect {
|
1676
|
+
file.chown(42, -1)
|
1677
|
+
}.to_not change{file.stat.gid}
|
1675
1678
|
end
|
1676
1679
|
|
1677
1680
|
context "when the named entry is a symlink" do
|
@@ -34,9 +34,9 @@ module MemFs
|
|
34
34
|
|
35
35
|
it "gets back to previous directory once the block is finished" do
|
36
36
|
subject.chdir '/'
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
expect {
|
38
|
+
subject.chdir('/test-dir') {}
|
39
|
+
}.to_not change{subject.getwd}
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -82,31 +82,27 @@ module MemFs
|
|
82
82
|
end
|
83
83
|
|
84
84
|
it "ignores nil user id" do
|
85
|
-
|
86
|
-
|
87
|
-
subject.
|
88
|
-
expect(subject.find!('/test-file').uid).to eq(previous_uid)
|
85
|
+
expect {
|
86
|
+
subject.chown(nil, 42, '/test-file')
|
87
|
+
}.to_not change{subject.find!('/test-file').uid}
|
89
88
|
end
|
90
89
|
|
91
90
|
it "ignores nil group id" do
|
92
|
-
|
93
|
-
|
94
|
-
subject.
|
95
|
-
expect(subject.find!('/test-file').gid).to eq(previous_gid)
|
91
|
+
expect {
|
92
|
+
subject.chown(42, nil, '/test-file')
|
93
|
+
}.to_not change{subject.find!('/test-file').gid}
|
96
94
|
end
|
97
95
|
|
98
96
|
it "ignores -1 user id" do
|
99
|
-
|
100
|
-
|
101
|
-
subject.
|
102
|
-
expect(subject.find!('/test-file').uid).to eq(previous_uid)
|
97
|
+
expect {
|
98
|
+
subject.chown(-1, 42, '/test-file')
|
99
|
+
}.to_not change{subject.find!('/test-file').uid}
|
103
100
|
end
|
104
101
|
|
105
102
|
it "ignores -1 group id" do
|
106
|
-
|
107
|
-
|
108
|
-
subject.
|
109
|
-
expect(subject.find!('/test-file').gid).to eq(previous_gid)
|
103
|
+
expect {
|
104
|
+
subject.chown(42, -1, '/test-file')
|
105
|
+
}.to_not change{subject.find!('/test-file').gid}
|
110
106
|
end
|
111
107
|
|
112
108
|
context "when the named entry is a symlink" do
|
@@ -380,7 +376,7 @@ module MemFs
|
|
380
376
|
|
381
377
|
it "creates an entry only if it doesn't exist" do
|
382
378
|
subject.touch '/some-file'
|
383
|
-
MemFs::Fake::File.
|
379
|
+
expect(MemFs::Fake::File).not_to receive(:new)
|
384
380
|
subject.touch '/some-file'
|
385
381
|
end
|
386
382
|
|
data/spec/memfs_spec.rb
CHANGED
@@ -51,4 +51,31 @@ describe MemFs do
|
|
51
51
|
expect(::File).to be(MemFs::OriginalFile)
|
52
52
|
end
|
53
53
|
end
|
54
|
+
|
55
|
+
describe '.touch' do
|
56
|
+
around(:each) { |example| MemFs.activate { example.run } }
|
57
|
+
|
58
|
+
it 'creates the specified file' do
|
59
|
+
fs.mkdir('/path')
|
60
|
+
fs.mkdir('/path/to')
|
61
|
+
fs.mkdir('/path/to/some')
|
62
|
+
subject.touch('/path/to/some/file.rb')
|
63
|
+
expect(File.exist?('/path/to/some/file.rb')).to be_true
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'when the parent folder do not exist' do
|
67
|
+
it 'creates them all' do
|
68
|
+
subject.touch('/path/to/some/file.rb')
|
69
|
+
expect(File.exist?('/path/to/some/file.rb')).to be_true
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'when several files are specified' do
|
74
|
+
it 'creates every file' do
|
75
|
+
subject.touch('/some/path', '/other/path')
|
76
|
+
expect(File.exist?('/some/path')).to be_true
|
77
|
+
expect(File.exist?('/other/path')).to be_true
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
54
81
|
end
|
metadata
CHANGED
@@ -1,125 +1,125 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memfs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simon COURTOIS
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: coveralls
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0.6'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0.6'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '10.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '2.
|
47
|
+
version: '2.14'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '2.
|
54
|
+
version: '2.14'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: guard
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '1.5'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '1.5'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: guard-rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '2.1'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - ~>
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '2.1'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rb-inotify
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - ~>
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0.8'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - ~>
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0.8'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rb-fsevent
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - ~>
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0.9'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - ~>
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0.9'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: rb-fchange
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- - ~>
|
115
|
+
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0.0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- - ~>
|
122
|
+
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0.0'
|
125
125
|
description: MemFs provides a fake file system that can be used for tests. Strongly
|
@@ -130,9 +130,9 @@ executables: []
|
|
130
130
|
extensions: []
|
131
131
|
extra_rdoc_files: []
|
132
132
|
files:
|
133
|
-
- .gitignore
|
134
|
-
- .rspec
|
135
|
-
- .travis.yml
|
133
|
+
- ".gitignore"
|
134
|
+
- ".rspec"
|
135
|
+
- ".travis.yml"
|
136
136
|
- CHANGELOG.md
|
137
137
|
- Gemfile
|
138
138
|
- Guardfile
|
@@ -174,20 +174,20 @@ require_paths:
|
|
174
174
|
- lib
|
175
175
|
required_ruby_version: !ruby/object:Gem::Requirement
|
176
176
|
requirements:
|
177
|
-
- -
|
177
|
+
- - ">="
|
178
178
|
- !ruby/object:Gem::Version
|
179
179
|
version: '0'
|
180
180
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
181
181
|
requirements:
|
182
|
-
- -
|
182
|
+
- - ">="
|
183
183
|
- !ruby/object:Gem::Version
|
184
184
|
version: '0'
|
185
185
|
requirements: []
|
186
186
|
rubyforge_project:
|
187
|
-
rubygems_version: 2.
|
187
|
+
rubygems_version: 2.2.2
|
188
188
|
signing_key:
|
189
189
|
specification_version: 4
|
190
|
-
summary: memfs-0.
|
190
|
+
summary: memfs-0.2.0
|
191
191
|
test_files:
|
192
192
|
- spec/fileutils_spec.rb
|
193
193
|
- spec/memfs/dir_spec.rb
|