fakefs 0.5.4 → 0.6.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/.gitignore +2 -0
- data/.rubocop.yml +50 -0
- data/.travis.yml +0 -1
- data/Rakefile +16 -9
- data/fakefs.gemspec +1 -0
- data/lib/fakefs/base.rb +6 -5
- data/lib/fakefs/dir.rb +55 -45
- data/lib/fakefs/fake/dir.rb +5 -3
- data/lib/fakefs/fake/file.rb +9 -4
- data/lib/fakefs/fake/symlink.rb +2 -1
- data/lib/fakefs/file.rb +98 -103
- data/lib/fakefs/file_system.rb +50 -33
- data/lib/fakefs/file_test.rb +1 -0
- data/lib/fakefs/fileutils.rb +72 -71
- data/lib/fakefs/kernel.rb +8 -7
- data/lib/fakefs/pathname.rb +356 -202
- data/lib/fakefs/safe.rb +1 -1
- data/lib/fakefs/spec_helpers.rb +19 -11
- data/lib/fakefs/version.rb +2 -1
- data/spec/fakefs/fakefs_bug_ruby_2.1.0-preview2_spec.rb +2 -2
- data/spec/fakefs/spec_helpers_spec.rb +24 -23
- data/test/dir/tempfile_test.rb +1 -0
- data/test/fake/file/join_test.rb +4 -3
- data/test/fake/file/lstat_test.rb +22 -21
- data/test/fake/file/stat_test.rb +12 -11
- data/test/fake/file/sysseek_test.rb +15 -14
- data/test/fake/file/syswrite_test.rb +25 -24
- data/test/fake/file_test.rb +12 -11
- data/test/fake/symlink_test.rb +18 -10
- data/test/fakefs_test.rb +543 -542
- data/test/file/stat_test.rb +45 -41
- data/test/kernel_test.rb +5 -8
- data/test/safe_test.rb +9 -7
- data/test/test_helper.rb +2 -1
- data/test/verify.rb +6 -3
- metadata +28 -14
data/lib/fakefs/file_system.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
module FakeFS
|
2
|
+
# FileSystem module
|
2
3
|
module FileSystem
|
3
4
|
extend self
|
4
5
|
|
@@ -32,10 +33,10 @@ module FakeFS
|
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
35
|
-
def add(path, object=FakeDir.new)
|
36
|
+
def add(path, object = FakeDir.new)
|
36
37
|
parts = path_parts(normalize_path(path))
|
37
38
|
|
38
|
-
d = parts[0...-1].
|
39
|
+
d = parts[0...-1].reduce(fs) do |dir, part|
|
39
40
|
assert_dir dir[part] if dir[part]
|
40
41
|
dir[part] ||= FakeDir.new(part, dir)
|
41
42
|
end
|
@@ -51,7 +52,11 @@ module FakeFS
|
|
51
52
|
def clone(path, target = nil)
|
52
53
|
path = RealFile.expand_path(path)
|
53
54
|
pattern = File.join(path, '**', '*')
|
54
|
-
files = RealFile.file?(path)
|
55
|
+
files = if RealFile.file?(path)
|
56
|
+
[path]
|
57
|
+
else
|
58
|
+
[path] + RealDir.glob(pattern, RealFile::FNM_DOTMATCH)
|
59
|
+
end
|
55
60
|
|
56
61
|
files.each do |f|
|
57
62
|
target_path = target ? f.gsub(path, target) : f
|
@@ -60,7 +65,7 @@ module FakeFS
|
|
60
65
|
elsif RealFile.file?(f)
|
61
66
|
FileUtils.mkdir_p(File.dirname(f))
|
62
67
|
File.open(target_path, File::WRITE_ONLY) do |g|
|
63
|
-
g.print RealFile.open(f){|h| h.read }
|
68
|
+
g.print RealFile.open(f) { |h| h.read }
|
64
69
|
end
|
65
70
|
elsif RealFile.directory?(f)
|
66
71
|
FileUtils.mkdir_p(target_path)
|
@@ -69,26 +74,25 @@ module FakeFS
|
|
69
74
|
end
|
70
75
|
|
71
76
|
def delete(path)
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
end
|
77
|
+
return unless (node = FileSystem.find(path))
|
78
|
+
node.delete
|
79
|
+
true
|
76
80
|
end
|
77
81
|
|
78
82
|
def chdir(dir, &blk)
|
79
83
|
new_dir = find(dir)
|
80
84
|
dir_levels.push dir if blk
|
81
85
|
|
82
|
-
|
86
|
+
fail Errno::ENOENT, dir unless new_dir
|
83
87
|
|
84
|
-
dir_levels.push dir
|
88
|
+
dir_levels.push dir unless blk
|
85
89
|
blk.call if blk
|
86
90
|
ensure
|
87
91
|
dir_levels.pop if blk
|
88
92
|
end
|
89
93
|
|
90
94
|
def path_parts(path)
|
91
|
-
drop_root(path.split(File::SEPARATOR)).reject
|
95
|
+
drop_root(path.split(File::SEPARATOR)).reject(&:empty?)
|
92
96
|
end
|
93
97
|
|
94
98
|
def normalize_path(path)
|
@@ -96,7 +100,9 @@ module FakeFS
|
|
96
100
|
RealFile.expand_path(path)
|
97
101
|
else
|
98
102
|
parts = dir_levels + [path]
|
99
|
-
RealFile.expand_path(parts.
|
103
|
+
RealFile.expand_path(parts.reduce do |base, part|
|
104
|
+
Pathname(base) + part
|
105
|
+
end.to_s)
|
100
106
|
end
|
101
107
|
end
|
102
108
|
|
@@ -117,39 +123,50 @@ module FakeFS
|
|
117
123
|
def find_recurser(dir, parts)
|
118
124
|
return [] unless dir.respond_to? :[]
|
119
125
|
|
120
|
-
pattern
|
126
|
+
pattern, *parts = parts
|
121
127
|
matches = case pattern
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
128
|
+
when '**'
|
129
|
+
case parts
|
130
|
+
when ['*']
|
131
|
+
parts = [] # end recursion
|
132
|
+
directories_under(dir).map do |d|
|
133
|
+
d.entries.select do |f|
|
134
|
+
f.is_a?(FakeFile) || f.is_a?(FakeDir)
|
135
|
+
end
|
136
|
+
end.flatten.uniq
|
137
|
+
when []
|
138
|
+
parts = [] # end recursion
|
139
|
+
dir.entries.flatten.uniq
|
140
|
+
else
|
141
|
+
directories_under(dir)
|
142
|
+
end
|
143
|
+
else
|
144
|
+
regex_body = pattern.gsub('.', '\.')
|
145
|
+
.gsub('?', '.')
|
146
|
+
.gsub('*', '.*')
|
147
|
+
.gsub('(', '\(')
|
148
|
+
.gsub(')', '\)')
|
149
|
+
.gsub(/\{(.*?)\}/) do
|
150
|
+
"(#{Regexp.last_match[1].gsub(',', '|')})"
|
151
|
+
end
|
152
|
+
dir.matches(/\A#{regex_body}\Z/)
|
153
|
+
end
|
138
154
|
|
139
155
|
if parts.empty? # we're done recursing
|
140
156
|
matches
|
141
157
|
else
|
142
|
-
matches.map{|entry| find_recurser(entry, parts) }
|
158
|
+
matches.map { |entry| find_recurser(entry, parts) }
|
143
159
|
end
|
144
160
|
end
|
145
161
|
|
146
162
|
def directories_under(dir)
|
147
|
-
children = dir.entries.select{|f| f.is_a? FakeDir}
|
148
|
-
([dir] + children + children.map{|c| directories_under(c)})
|
163
|
+
children = dir.entries.select { |f| f.is_a? FakeDir }
|
164
|
+
([dir] + children + children.map { |c| directories_under(c) })
|
165
|
+
.flatten.uniq
|
149
166
|
end
|
150
167
|
|
151
168
|
def assert_dir(dir)
|
152
|
-
|
169
|
+
fail Errno::EEXIST, dir.name unless dir.is_a?(FakeDir)
|
153
170
|
end
|
154
171
|
end
|
155
172
|
end
|
data/lib/fakefs/file_test.rb
CHANGED
data/lib/fakefs/fileutils.rb
CHANGED
@@ -1,42 +1,47 @@
|
|
1
1
|
module FakeFS
|
2
|
+
# FileUtils module
|
2
3
|
module FileUtils
|
3
4
|
extend self
|
4
5
|
|
5
|
-
def mkdir_p(list,
|
6
|
-
list = [
|
6
|
+
def mkdir_p(list, _options = {})
|
7
|
+
list = [list] unless list.is_a?(Array)
|
7
8
|
list.each do |path|
|
8
9
|
FileSystem.add(path, FakeDir.new)
|
9
10
|
end
|
10
11
|
end
|
12
|
+
|
11
13
|
alias_method :mkpath, :mkdir_p
|
12
14
|
alias_method :makedirs, :mkdir_p
|
13
15
|
|
14
|
-
def mkdir(list,
|
15
|
-
list = [
|
16
|
+
def mkdir(list, _ignored_options = {})
|
17
|
+
list = [list] unless list.is_a?(Array)
|
16
18
|
list.each do |path|
|
17
19
|
parent = path.split('/')
|
18
20
|
parent.pop
|
19
|
-
|
20
|
-
|
21
|
+
fail Errno::ENOENT, path unless parent.join == '' ||
|
22
|
+
parent.join == '.' || FileSystem.find(parent.join('/'))
|
23
|
+
fail Errno::EEXIST, path if FileSystem.find(path)
|
21
24
|
FileSystem.add(path, FakeDir.new)
|
22
25
|
end
|
23
26
|
end
|
24
27
|
|
25
|
-
def rmdir(list,
|
26
|
-
list = [
|
28
|
+
def rmdir(list, _options = {})
|
29
|
+
list = [list] unless list.is_a?(Array)
|
27
30
|
list.each do |l|
|
28
31
|
parent = l.split('/')
|
29
32
|
parent.pop
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
+
fail Errno::ENOENT, l unless parent.join == '' ||
|
34
|
+
FileSystem.find(parent.join('/'))
|
35
|
+
fail Errno::ENOENT, l unless FileSystem.find(l)
|
36
|
+
fail Errno::ENOTEMPTY, l unless FileSystem.find(l).empty?
|
33
37
|
rm(l)
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
37
41
|
def rm(list, options = {})
|
38
42
|
Array(list).each do |path|
|
39
|
-
FileSystem.delete(path)
|
43
|
+
FileSystem.delete(path) ||
|
44
|
+
(!options[:force] && fail(Errno::ENOENT, path))
|
40
45
|
end
|
41
46
|
end
|
42
47
|
|
@@ -49,92 +54,81 @@ module FakeFS
|
|
49
54
|
alias_method :remove_entry_secure, :rm_rf
|
50
55
|
|
51
56
|
def ln_s(target, path, options = {})
|
52
|
-
options = { :
|
53
|
-
(FileSystem.find(path) && !options[:force]
|
54
|
-
|
55
|
-
FileSystem.delete(path)
|
57
|
+
options = { force: false }.merge(options)
|
58
|
+
fail(Errno::EEXIST, path) if FileSystem.find(path) && !options[:force]
|
59
|
+
FileSystem.delete(path)
|
56
60
|
|
57
|
-
if !options[:force] && !Dir.
|
58
|
-
|
61
|
+
if !options[:force] && !Dir.exist?(File.dirname(path))
|
62
|
+
fail Errno::ENOENT, path
|
59
63
|
end
|
60
64
|
|
61
65
|
FileSystem.add(path, FakeSymlink.new(target))
|
62
66
|
end
|
63
67
|
|
64
68
|
def ln_sf(target, path)
|
65
|
-
ln_s(target, path,
|
69
|
+
ln_s(target, path, force: true)
|
66
70
|
end
|
67
71
|
|
68
72
|
alias_method :symlink, :ln_s
|
69
73
|
|
70
|
-
def cp(src, dest, options={})
|
71
|
-
if src.is_a?(Array) && !File.directory?(dest)
|
72
|
-
raise Errno::ENOTDIR, dest
|
73
|
-
end
|
74
|
+
def cp(src, dest, options = {})
|
75
|
+
fail Errno::ENOTDIR, dest if src.is_a?(Array) && !File.directory?(dest)
|
74
76
|
|
75
77
|
# handle `verbose' flag
|
76
|
-
RealFileUtils.cp src, dest, options.merge(:
|
78
|
+
RealFileUtils.cp src, dest, options.merge(noop: true)
|
77
79
|
|
78
80
|
# handle `noop' flag
|
79
81
|
return if options[:noop]
|
80
82
|
|
81
|
-
Array(src).each do |
|
83
|
+
Array(src).each do |source|
|
82
84
|
dst_file = FileSystem.find(dest)
|
83
|
-
src_file = FileSystem.find(
|
85
|
+
src_file = FileSystem.find(source)
|
84
86
|
|
85
|
-
|
86
|
-
|
87
|
-
end
|
88
|
-
|
89
|
-
if File.directory? src_file
|
90
|
-
raise Errno::EISDIR, src
|
91
|
-
end
|
87
|
+
fail Errno::ENOENT, source unless src_file
|
88
|
+
fail Errno::EISDIR, source if File.directory? src_file
|
92
89
|
|
93
90
|
if dst_file && File.directory?(dst_file)
|
94
|
-
FileSystem.add(
|
91
|
+
FileSystem.add(
|
92
|
+
File.join(
|
93
|
+
dest, File.basename(source)), src_file.entry.clone(dst_file))
|
95
94
|
else
|
96
95
|
FileSystem.delete(dest)
|
97
96
|
FileSystem.add(dest, src_file.entry.clone)
|
98
97
|
end
|
99
98
|
end
|
100
99
|
|
101
|
-
|
100
|
+
nil
|
102
101
|
end
|
103
102
|
|
104
103
|
alias_method :copy, :cp
|
105
104
|
|
106
|
-
def copy_file(src, dest,
|
105
|
+
def copy_file(src, dest, _preserve = false, _dereference = true)
|
107
106
|
# Not a perfect match, but similar to what regular FileUtils does.
|
108
107
|
cp(src, dest)
|
109
108
|
end
|
110
109
|
|
111
|
-
def cp_r(src, dest, options={})
|
110
|
+
def cp_r(src, dest, options = {})
|
112
111
|
# handle `verbose' flag
|
113
|
-
RealFileUtils.cp_r src, dest, options.merge(:
|
112
|
+
RealFileUtils.cp_r src, dest, options.merge(noop: true)
|
114
113
|
|
115
114
|
# handle `noop' flag
|
116
115
|
return if options[:noop]
|
117
116
|
|
118
|
-
Array(src).each do |
|
117
|
+
Array(src).each do |source|
|
119
118
|
# This error sucks, but it conforms to the original Ruby
|
120
119
|
# method.
|
121
|
-
|
122
|
-
|
120
|
+
fail "unknown file type: #{source}" unless
|
121
|
+
(dir = FileSystem.find(source))
|
123
122
|
new_dir = FileSystem.find(dest)
|
124
123
|
|
125
|
-
if new_dir && !File.directory?(dest)
|
126
|
-
|
127
|
-
end
|
128
|
-
|
129
|
-
if !new_dir && !FileSystem.find(dest+'/../')
|
130
|
-
raise Errno::ENOENT, dest
|
131
|
-
end
|
124
|
+
fail Errno::EEXIST, dest if new_dir && !File.directory?(dest)
|
125
|
+
fail Errno::ENOENT, dest if !new_dir && !FileSystem.find(dest + '/../')
|
132
126
|
|
133
127
|
# This last bit is a total abuse and should be thought hard
|
134
128
|
# about and cleaned up.
|
135
129
|
if new_dir
|
136
130
|
if src[-2..-1] == '/.'
|
137
|
-
dir.entries.each{|f| new_dir[f.name] = f.clone(new_dir) }
|
131
|
+
dir.entries.each { |f| new_dir[f.name] = f.clone(new_dir) }
|
138
132
|
else
|
139
133
|
new_dir[dir.name] = dir.entry.clone(new_dir)
|
140
134
|
end
|
@@ -143,61 +137,67 @@ module FakeFS
|
|
143
137
|
end
|
144
138
|
end
|
145
139
|
|
146
|
-
|
140
|
+
nil
|
147
141
|
end
|
148
142
|
|
149
|
-
def mv(src, dest, options={})
|
143
|
+
def mv(src, dest, options = {})
|
150
144
|
# handle `verbose' flag
|
151
|
-
RealFileUtils.mv src, dest, options.merge(:
|
145
|
+
RealFileUtils.mv src, dest, options.merge(noop: true)
|
152
146
|
|
153
147
|
# handle `noop' flag
|
154
148
|
return if options[:noop]
|
155
149
|
|
156
150
|
Array(src).each do |path|
|
157
|
-
if target = FileSystem.find(path)
|
158
|
-
dest_path = File.directory?(dest)
|
151
|
+
if (target = FileSystem.find(path))
|
152
|
+
dest_path = if File.directory?(dest)
|
153
|
+
File.join(dest, File.basename(path))
|
154
|
+
else
|
155
|
+
dest
|
156
|
+
end
|
159
157
|
if File.directory?(dest_path)
|
160
|
-
|
158
|
+
fail Errno::EEXIST, dest_path unless options[:force]
|
161
159
|
elsif File.directory?(File.dirname(dest_path))
|
162
160
|
FileSystem.delete(dest_path)
|
163
161
|
FileSystem.add(dest_path, target.entry.clone)
|
164
162
|
FileSystem.delete(path)
|
165
163
|
else
|
166
|
-
|
164
|
+
fail Errno::ENOENT, dest_path unless options[:force]
|
167
165
|
end
|
168
166
|
else
|
169
|
-
|
167
|
+
fail Errno::ENOENT, path
|
170
168
|
end
|
171
169
|
end
|
172
170
|
|
173
|
-
|
171
|
+
nil
|
174
172
|
end
|
175
173
|
|
176
174
|
alias_method :move, :mv
|
177
175
|
|
178
|
-
def chown(user, group, list,
|
176
|
+
def chown(user, group, list, _options = {})
|
179
177
|
list = Array(list)
|
180
178
|
list.each do |f|
|
181
|
-
if File.
|
179
|
+
if File.exist?(f)
|
182
180
|
uid = if user
|
183
|
-
user.to_s.match(/[0-9]+/) ? user.to_i :
|
181
|
+
user.to_s.match(/[0-9]+/) ? user.to_i :
|
182
|
+
Etc.getpwnam(user).uid
|
184
183
|
else
|
185
184
|
nil
|
186
185
|
end
|
187
186
|
gid = if group
|
188
|
-
group.to_s.match(/[0-9]+/) ? group.to_i :
|
187
|
+
group.to_s.match(/[0-9]+/) ? group.to_i :
|
188
|
+
Etc.getgrnam(group).gid
|
189
189
|
else
|
190
190
|
nil
|
191
191
|
end
|
192
192
|
File.chown(uid, gid, f)
|
193
193
|
else
|
194
|
-
|
194
|
+
fail Errno::ENOENT, f
|
195
195
|
end
|
196
196
|
end
|
197
197
|
list
|
198
198
|
end
|
199
199
|
|
200
|
-
def chown_R(user, group, list,
|
200
|
+
def chown_R(user, group, list, _options = {})
|
201
201
|
list = Array(list)
|
202
202
|
list.each do |file|
|
203
203
|
chown(user, group, file)
|
@@ -208,19 +208,19 @@ module FakeFS
|
|
208
208
|
list
|
209
209
|
end
|
210
210
|
|
211
|
-
def chmod(mode, list,
|
211
|
+
def chmod(mode, list, _options = {})
|
212
212
|
list = Array(list)
|
213
213
|
list.each do |f|
|
214
|
-
if File.
|
214
|
+
if File.exist?(f)
|
215
215
|
File.chmod(mode, f)
|
216
216
|
else
|
217
|
-
|
217
|
+
fail Errno::ENOENT, f
|
218
218
|
end
|
219
219
|
end
|
220
220
|
list
|
221
221
|
end
|
222
222
|
|
223
|
-
def chmod_R(mode, list,
|
223
|
+
def chmod_R(mode, list, _options = {})
|
224
224
|
list = Array(list)
|
225
225
|
list.each do |file|
|
226
226
|
chmod(mode, file)
|
@@ -231,9 +231,9 @@ module FakeFS
|
|
231
231
|
list
|
232
232
|
end
|
233
233
|
|
234
|
-
def touch(list, options={})
|
234
|
+
def touch(list, options = {})
|
235
235
|
Array(list).each do |f|
|
236
|
-
if fs = FileSystem.find(f)
|
236
|
+
if (fs = FileSystem.find(f))
|
237
237
|
now = Time.now
|
238
238
|
fs.mtime = options[:mtime] || now
|
239
239
|
fs.atime = now
|
@@ -241,7 +241,7 @@ module FakeFS
|
|
241
241
|
file = File.open(f, 'w')
|
242
242
|
file.close
|
243
243
|
|
244
|
-
if mtime = options[:mtime]
|
244
|
+
if (mtime = options[:mtime])
|
245
245
|
fs = FileSystem.find(f)
|
246
246
|
fs.mtime = mtime
|
247
247
|
end
|
@@ -258,6 +258,7 @@ module FakeFS
|
|
258
258
|
# we do a strict comparison of both files content
|
259
259
|
File.readlines(file1) == File.readlines(file2)
|
260
260
|
end
|
261
|
+
|
261
262
|
alias_method :cmp, :compare_file
|
262
263
|
alias_method :identical?, :compare_file
|
263
264
|
end
|