fakefs 0.2.1 → 0.3.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.
data/lib/fakefs/file.rb CHANGED
@@ -1,5 +1,7 @@
1
+ require 'stringio'
2
+
1
3
  module FakeFS
2
- class File
4
+ class File < StringIO
3
5
  PATH_SEPARATOR = '/'
4
6
 
5
7
  MODES = [
@@ -31,7 +33,7 @@ module FakeFS
31
33
  end
32
34
 
33
35
  def self.join(*parts)
34
- parts * PATH_SEPARATOR
36
+ RealFile.join(parts)
35
37
  end
36
38
 
37
39
  def self.exist?(path)
@@ -54,6 +56,26 @@ module FakeFS
54
56
  end
55
57
  end
56
58
 
59
+ def self.ctime(path)
60
+ if exists?(path)
61
+ FileSystem.find(path).ctime
62
+ else
63
+ raise Errno::ENOENT
64
+ end
65
+ end
66
+
67
+ def self.utime(atime, mtime, *paths)
68
+ paths.each do |path|
69
+ if exists?(path)
70
+ FileSystem.find(path).mtime = mtime
71
+ else
72
+ raise Errno::ENOENT
73
+ end
74
+ end
75
+
76
+ paths.size
77
+ end
78
+
57
79
  def self.size(path)
58
80
  read(path).length
59
81
  end
@@ -113,14 +135,6 @@ module FakeFS
113
135
  FileSystem.find(symlink.target).to_s
114
136
  end
115
137
 
116
- def self.open(path, mode=READ_ONLY, perm = 0644)
117
- if block_given?
118
- yield new(path, mode, perm)
119
- else
120
- new(path, mode, perm)
121
- end
122
- end
123
-
124
138
  def self.read(path)
125
139
  file = new(path)
126
140
  if file.exists?
@@ -134,6 +148,23 @@ module FakeFS
134
148
  read(path).split("\n")
135
149
  end
136
150
 
151
+ def self.rename(source, dest)
152
+ if directory?(source) && file?(dest)
153
+ raise Errno::ENOTDIR, "Not a directory - #{source} or #{dest}"
154
+ elsif file?(source) && directory?(dest)
155
+ raise Errno::EISDIR, "Is a directory - #{source} or #{dest}"
156
+ end
157
+
158
+ if target = FileSystem.find(source)
159
+ FileSystem.add(dest, target.entry.clone)
160
+ FileSystem.delete(source)
161
+ else
162
+ raise Errno::ENOENT, "No such file or directory - #{source} or #{dest}"
163
+ end
164
+
165
+ 0
166
+ end
167
+
137
168
  def self.link(source, dest)
138
169
  if directory?(source)
139
170
  raise Errno::EPERM, "Operation not permitted - #{source} or #{dest}"
@@ -180,13 +211,27 @@ module FakeFS
180
211
  File::Stat.new(file)
181
212
  end
182
213
 
214
+ def self.lstat(file)
215
+ File::Stat.new(file, true)
216
+ end
217
+
218
+ def self.split(path)
219
+ return RealFile.split(path)
220
+ end
221
+
183
222
  class Stat
184
- def initialize(file)
223
+ attr_reader :ctime, :mtime
224
+
225
+ def initialize(file, __lstat = false)
185
226
  if !File.exists?(file)
186
227
  raise(Errno::ENOENT, "No such file or directory - #{file}")
187
228
  end
188
229
 
189
- @file = file
230
+ @file = file
231
+ @fake_file = FileSystem.find(@file)
232
+ @__lstat = __lstat
233
+ @ctime = @fake_file.ctime
234
+ @mtime = @fake_file.mtime
190
235
  end
191
236
 
192
237
  def symlink?
@@ -198,7 +243,15 @@ module FakeFS
198
243
  end
199
244
 
200
245
  def nlink
201
- FileSystem.find(@file).links.size
246
+ @fake_file.links.size
247
+ end
248
+
249
+ def size
250
+ if @__lstat && symlink?
251
+ @fake_file.target.size
252
+ else
253
+ File.size(@file)
254
+ end
202
255
  end
203
256
  end
204
257
 
@@ -208,45 +261,119 @@ module FakeFS
208
261
  @path = path
209
262
  @mode = mode
210
263
  @file = FileSystem.find(path)
211
- @open = true
264
+ @autoclose = true
212
265
 
213
266
  check_modes!
214
267
 
215
268
  file_creation_mode? ? create_missing_file : check_file_existence!
216
269
 
217
- @stream = StringIO.new(@file.content, mode)
270
+ super(@file.content, mode)
218
271
  end
219
272
 
220
- def close
221
- @open = false
273
+ def exists?
274
+ true
222
275
  end
223
276
 
224
- def read(chunk = nil)
225
- @stream.read(chunk)
277
+ alias_method :tell=, :pos=
278
+ alias_method :sysread, :read
279
+ alias_method :syswrite, :write
280
+
281
+ undef_method :closed_read?
282
+ undef_method :closed_write?
283
+ undef_method :length
284
+ undef_method :size
285
+ undef_method :string
286
+ undef_method :string=
287
+
288
+ def ioctl(integer_cmd, arg)
289
+ raise NotImplementedError
226
290
  end
227
291
 
228
- def rewind
229
- @stream.rewind
292
+ def read_nonblock(maxlen, outbuf = nil)
293
+ raise NotImplementedError
230
294
  end
231
295
 
232
- def exists?
233
- true
296
+ def stat
297
+ self.class.stat(@path)
298
+ end
299
+
300
+ def lstat
301
+ self.class.lstat(@path)
302
+ end
303
+
304
+ def sysseek(position, whence = SEEK_SET)
305
+ seek(position, whence)
306
+ pos
307
+ end
308
+
309
+ alias_method :to_i, :fileno
310
+
311
+ def to_io
312
+ self
234
313
  end
235
314
 
236
- def puts(*content)
237
- @stream.puts(*content)
315
+ def write_nonblock(string)
316
+ raise NotImplementedError
238
317
  end
239
318
 
240
- def write(content)
241
- @stream.write(content)
319
+ def readpartial(maxlen, outbuf = nil)
320
+ raise NotImplementedError
242
321
  end
243
- alias_method :print, :write
244
- alias_method :<<, :write
245
322
 
246
- def flush; self; end
323
+ def atime
324
+ raise NotImplementedError
325
+ end
326
+
327
+ def chmod(mode_int)
328
+ raise NotImplementedError
329
+ end
330
+
331
+ def chown(owner_int, group_int)
332
+ raise NotImplementedError
333
+ end
334
+
335
+ def ctime
336
+ self.class.ctime(@path)
337
+ end
338
+
339
+ def flock(locking_constant)
340
+ raise NotImplementedError
341
+ end
247
342
 
248
- def seek(amount, whence = SEEK_SET)
249
- @stream.seek(amount, whence)
343
+ def mtime
344
+ self.class.mtime(@path)
345
+ end
346
+
347
+ if RUBY_VERSION >= "1.9"
348
+ def binmode?
349
+ raise NotImplementedError
350
+ end
351
+
352
+ def close_on_exec=(bool)
353
+ raise NotImplementedError
354
+ end
355
+
356
+ def close_on_exec?
357
+ raise NotImplementedError
358
+ end
359
+
360
+ def to_path
361
+ raise NotImplementedError
362
+ end
363
+ end
364
+
365
+ if RUBY_VERSION >= "1.9.2"
366
+ attr_writer :autoclose
367
+
368
+ def autoclose?
369
+ @autoclose
370
+ end
371
+
372
+ alias_method :fdatasync, :flush
373
+
374
+ def size
375
+ File.size(@path)
376
+ end
250
377
  end
251
378
 
252
379
  private
@@ -256,9 +383,7 @@ module FakeFS
256
383
  end
257
384
 
258
385
  def check_file_existence!
259
- unless @file
260
- raise Errno::ENOENT, "No such file or directory - #{@file}"
261
- end
386
+ raise Errno::ENOENT, @path unless @file
262
387
  end
263
388
 
264
389
  def file_creation_mode?
@@ -109,11 +109,14 @@ module FakeFS
109
109
  matches = case pattern
110
110
  when '**'
111
111
  case parts
112
- when ['*'], []
112
+ when ['*']
113
113
  parts = [] # end recursion
114
114
  directories_under(dir).map do |d|
115
- d.values.select{|f| f.is_a? FakeFile }
115
+ d.values.select{|f| f.is_a?(FakeFile) || f.is_a?(FakeDir) }
116
116
  end.flatten.uniq
117
+ when []
118
+ parts = [] # end recursion
119
+ dir.values.flatten.uniq
117
120
  else
118
121
  directories_under(dir)
119
122
  end
@@ -0,0 +1,11 @@
1
+ module FakeFS
2
+ class FileTest
3
+ def self.exist?(file_name)
4
+ File.exist?(file_name)
5
+ end
6
+
7
+ def self.directory?(file_name)
8
+ File.directory?(file_name)
9
+ end
10
+ end
11
+ end
@@ -2,10 +2,19 @@ module FakeFS
2
2
  module FileUtils
3
3
  extend self
4
4
 
5
- def mkdir_p(path)
5
+ def mkdir_p(path, options = {})
6
6
  FileSystem.add(path, FakeDir.new)
7
7
  end
8
8
  alias_method :mkpath, :mkdir_p
9
+ alias_method :makedirs, :mkdir_p
10
+
11
+ def mkdir(path)
12
+ parent = path.split('/')
13
+ parent.pop
14
+ raise Errno::ENOENT, "No such file or directory - #{path}" unless parent.join == "" || FileSystem.find(parent.join('/'))
15
+ raise Errno::EEXIST, "File exists - #{path}" if FileSystem.find(path)
16
+ FileSystem.add(path, FakeDir.new)
17
+ end
9
18
 
10
19
  def rmdir(list, options = {})
11
20
  list = [ list ] unless list.is_a?(Array)
@@ -19,8 +28,10 @@ module FakeFS
19
28
  end
20
29
  end
21
30
 
22
- def rm(path)
23
- FileSystem.delete(path)
31
+ def rm(list, options = {})
32
+ Array(list).each do |path|
33
+ FileSystem.delete(path)
34
+ end
24
35
  end
25
36
 
26
37
  alias_method :rm_rf, :rm
@@ -36,8 +47,6 @@ module FakeFS
36
47
  ln_s(target, path, { :force => true })
37
48
  end
38
49
 
39
-
40
-
41
50
  def cp(src, dest)
42
51
  dst_file = FileSystem.find(dest)
43
52
  src_file = FileSystem.find(src)
@@ -86,12 +95,15 @@ module FakeFS
86
95
  end
87
96
  end
88
97
 
89
- def mv(src, dest)
90
- if target = FileSystem.find(src)
91
- FileSystem.add(dest, target.entry.clone)
92
- FileSystem.delete(src)
93
- else
94
- raise Errno::ENOENT, src
98
+ def mv(src, dest, options={})
99
+ Array(src).each do |path|
100
+ if target = FileSystem.find(path)
101
+ dest_path = File.directory?(dest) ? File.join(dest, File.basename(path)) : dest
102
+ FileSystem.add(dest_path, target.entry.clone)
103
+ FileSystem.delete(path)
104
+ else
105
+ raise Errno::ENOENT, path
106
+ end
95
107
  end
96
108
  end
97
109
 
data/lib/fakefs/safe.rb CHANGED
@@ -7,5 +7,5 @@ require 'fakefs/fake/symlink'
7
7
  require 'fakefs/file_system'
8
8
  require 'fakefs/fileutils'
9
9
  require 'fakefs/file'
10
+ require 'fakefs/file_test'
10
11
  require 'fakefs/dir'
11
-
@@ -1,6 +1,6 @@
1
1
  module FakeFS
2
2
  module Version
3
- VERSION = "0.2.1"
3
+ VERSION = "0.3.2"
4
4
 
5
5
  def self.to_s
6
6
  VERSION
@@ -54,4 +54,4 @@ module FakeFS
54
54
  end
55
55
  end
56
56
  end
57
- end
57
+ end
data/spec/spec.opts CHANGED
@@ -1 +1 @@
1
- --color
1
+ --color
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
2
 
3
- require 'fakefs/spec_helpers'
3
+ require 'fakefs/spec_helpers'
@@ -0,0 +1,19 @@
1
+ require "test_helper"
2
+
3
+ class FileJoin < Test::Unit::TestCase
4
+ def setup
5
+ FakeFS.activate!
6
+ end
7
+
8
+ def teardown
9
+ FakeFS.deactivate!
10
+ end
11
+
12
+ [
13
+ ["a", "b"], ["a/", "b"], ["a", "/b"], ["a/", "/b"], ["a", "/", "b"]
14
+ ].each_with_index do |args, i|
15
+ define_method "test_file_join_#{i}" do
16
+ assert_equal RealFile.join(args), File.join(args)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,59 @@
1
+ require "test_helper"
2
+
3
+ class FileStat < Test::Unit::TestCase
4
+ def setup
5
+ FakeFS.activate!
6
+ FakeFS::FileSystem.clear
7
+ end
8
+
9
+ def teardown
10
+ FakeFS.deactivate!
11
+ end
12
+
13
+ def test_calling_lstat_should_create_a_new_file_stat_object
14
+ File.open("foo", "w") do |f|
15
+ f << "bar"
16
+ end
17
+
18
+ File.open("foo") do |f|
19
+ assert_equal File::Stat, f.lstat.class
20
+ end
21
+ end
22
+
23
+ def test_lstat_should_use_correct_file
24
+ File.open("bar", "w") do |f|
25
+ f << "1"
26
+ end
27
+
28
+ File.open("bar") do |f|
29
+ assert_equal 1, f.lstat.size
30
+ end
31
+ end
32
+
33
+ def test_lstat_should_report_on_symlink_itself
34
+ File.open("foo", "w") { |f| f << "some content" }
35
+ File.symlink "foo", "my_symlink"
36
+
37
+ assert_not_equal File.lstat("my_symlink").size, File.lstat("foo").size
38
+ end
39
+
40
+ def test_should_report_on_symlink_itself_with_size_instance_method
41
+ File.open("foo", "w") { |f| f << "some content" }
42
+ File.symlink "foo", "my_symlink"
43
+
44
+ file = File.open("foo")
45
+ symlink = File.open("my_symlink")
46
+
47
+ assert_not_equal file.lstat.size, symlink.lstat.size
48
+ end
49
+
50
+ def test_symlink_size_is_size_of_path_pointed_to
51
+ File.open("a", "w") { |x| x << "foobarbazfoobarbaz" }
52
+ File.symlink "a", "one_char_symlink"
53
+ assert_equal 1, File.lstat("one_char_symlink").size
54
+
55
+ File.open("ab", "w") { |x| x << "foobarbazfoobarbaz" }
56
+ File.symlink "ab", "two_char_symlink"
57
+ assert_equal 2, File.lstat("two_char_symlink").size
58
+ end
59
+ end
@@ -0,0 +1,39 @@
1
+ require "test_helper"
2
+
3
+ class FileStat < Test::Unit::TestCase
4
+ def setup
5
+ FakeFS.activate!
6
+ FakeFS::FileSystem.clear
7
+ end
8
+
9
+ def teardown
10
+ FakeFS.deactivate!
11
+ end
12
+
13
+ def test_calling_stat_should_create_a_new_file_stat_object
14
+ File.open("foo", "w") do |f|
15
+ f << "bar"
16
+ end
17
+
18
+ File.open("foo") do |f|
19
+ assert_equal File::Stat, f.stat.class
20
+ end
21
+ end
22
+
23
+ def test_stat_should_use_correct_file
24
+ File.open("bar", "w") do |f|
25
+ f << "1"
26
+ end
27
+
28
+ File.open("bar") do |f|
29
+ assert_equal 1, f.stat.size
30
+ end
31
+ end
32
+
33
+ def test_stat_should_report_on_symlink_pointer
34
+ File.open("foo", "w") { |f| f << "some content" }
35
+ File.symlink "foo", "my_symlink"
36
+
37
+ assert_equal File.stat("my_symlink").size, File.stat("foo").size
38
+ end
39
+ end
@@ -0,0 +1,44 @@
1
+ require "test_helper"
2
+
3
+ class FileSysSeek < Test::Unit::TestCase
4
+ def setup
5
+ FakeFS.activate!
6
+ FakeFS::FileSystem.clear
7
+ end
8
+
9
+ def teardown
10
+ FakeFS.deactivate!
11
+ end
12
+
13
+ def test_should_seek_to_position
14
+ file = File.open("foo", "w") do |f|
15
+ f << "0123456789"
16
+ end
17
+
18
+ File.open("foo", "r") do |f|
19
+ f.sysseek(3)
20
+ assert_equal 3, f.pos
21
+
22
+ f.sysseek(0)
23
+ assert_equal 0, f.pos
24
+ end
25
+ end
26
+
27
+ def test_seek_returns_offset_into_file
28
+ File.open("foo", "w") do |f|
29
+ # 66 chars long
30
+ str = "0123456789" +
31
+ "0123456789" +
32
+ "0123456789" +
33
+ "0123456789" +
34
+ "0123456789" +
35
+ "0123456789" +
36
+ "012345"
37
+
38
+ f << str
39
+ end
40
+
41
+ f = File.open("foo")
42
+ assert_equal 53, f.sysseek(-13, IO::SEEK_END)
43
+ end
44
+ end
@@ -0,0 +1,62 @@
1
+ require "test_helper"
2
+
3
+ class FileSysWriteTest < Test::Unit::TestCase
4
+ def setup
5
+ FakeFS.activate!
6
+ FakeFS::FileSystem.clear
7
+ end
8
+
9
+ def teardown
10
+ FakeFS.deactivate!
11
+ end
12
+
13
+ def test_returns_one_byte_when_written
14
+ f = File.open "foo", "w"
15
+ result = f.syswrite "a"
16
+ assert_equal 1, result
17
+ end
18
+
19
+ def test_returns_two_bytes_when_two_written
20
+ f = File.open "foo", "w"
21
+ result = f.syswrite "ab"
22
+ assert_equal 2, result
23
+ end
24
+
25
+ def test_syswrite_writes_file
26
+ f = File.open "foo", "w"
27
+ f.syswrite "abcdef"
28
+ f.close
29
+
30
+ assert_equal "abcdef", File.read("foo")
31
+ end
32
+
33
+ def test_writes_to_the_actual_position_when_called_after_buffered_io_read
34
+ File.open("foo", "w") do |file|
35
+ file.syswrite("012345678901234567890123456789")
36
+ end
37
+
38
+ file = File.open("foo", "r+")
39
+ file.read(5)
40
+ file.syswrite("abcde")
41
+
42
+ File.open("foo") do |file|
43
+ assert_equal "01234abcde", file.sysread(10)
44
+ end
45
+ end
46
+
47
+ def test_writes_all_of_the_strings_bytes_but_does_not_buffer_them
48
+ File.open("foo", "w") do |file|
49
+ file.syswrite("012345678901234567890123456789")
50
+ end
51
+
52
+ file = File.open("foo", "r+")
53
+ written = file.syswrite("abcde")
54
+
55
+ File.open("foo") do |file|
56
+ assert_equal "abcde56789", file.sysread(10)
57
+ file.seek(0)
58
+ file.fsync
59
+ assert_equal "abcde56789", file.sysread(10)
60
+ end
61
+ end
62
+ end
@@ -1,13 +1,11 @@
1
- $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
2
- require 'fakefs/safe'
3
- require 'test/unit'
1
+ require "test_helper"
4
2
 
5
3
  class FakeFileTest < Test::Unit::TestCase
6
4
  include FakeFS
7
5
 
8
6
  def setup
9
7
  FileSystem.clear
10
-
8
+
11
9
  @file = FakeFile.new
12
10
  end
13
11
 
@@ -43,9 +41,9 @@ class FakeFileTest < Test::Unit::TestCase
43
41
 
44
42
  def test_links_are_mutual
45
43
  other_file = FakeFile.new
46
-
44
+
47
45
  @file.link(other_file)
48
-
46
+
49
47
  assert_equal [@file, other_file], other_file.links
50
48
  end
51
49
 
@@ -85,4 +83,15 @@ class FakeFileTest < Test::Unit::TestCase
85
83
  assert_equal "foo", clone.content
86
84
  assert_equal "bar", @file.content
87
85
  end
86
+
87
+ def test_raises_an_error_with_the_correct_path
88
+ path = "/some/non/existing/file"
89
+ begin
90
+ FakeFS::File.new path
91
+ msg = nil
92
+ rescue Errno::ENOENT => e
93
+ msg = e.message
94
+ end
95
+ assert_equal "No such file or directory - #{path}", msg
96
+ end
88
97
  end
@@ -1,6 +1,4 @@
1
- $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
2
- require 'fakefs/safe'
3
- require 'test/unit'
1
+ require "test_helper"
4
2
 
5
3
  class FakeSymlinkTest < Test::Unit::TestCase
6
4
  include FakeFS