rsanheim-fakefs 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Chris Wanstrath
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,68 @@
1
+ FakeFS
2
+ ======
3
+
4
+ Mocha is great. But when your library is all about manipulating the
5
+ filesystem, you really want to test the behavior and not the implementation.
6
+
7
+ If you're mocking and stubbing every call to FileUtils or File, you're
8
+ tightly coupling your tests with the implementation.
9
+
10
+ def test_creates_directory
11
+ FileUtils.expects(:mkdir).with("directory").once
12
+ Library.add "directory"
13
+ end
14
+
15
+ The above test will break if we decide to use `mkdir_p` in our code. Refactoring
16
+ code shouldn't necessitate refactoring tests.
17
+
18
+ With FakeFS:
19
+
20
+ def test_creates_directory
21
+ Library.add "directory"
22
+ assert File.directory?("directory")
23
+ end
24
+
25
+ Woot.
26
+
27
+
28
+ Usage
29
+ -----
30
+
31
+ require 'fakefs'
32
+
33
+ # That's it.
34
+
35
+
36
+ Don't Fake the FS Immediately
37
+ -----------------------------
38
+
39
+ require 'fakefs/safe'
40
+
41
+ FakeFS.activate!
42
+ # your code
43
+ FakeFS.deactivate!
44
+
45
+ # or
46
+ FakeFS do
47
+ # your code
48
+ end
49
+
50
+
51
+ How is this different than MockFS?
52
+ ----------------------------------
53
+
54
+ FakeFS provides a test suite and works with symlinks. It's also strictly a
55
+ test-time dependency: your actual library does not need to use or know about
56
+ FakeFS.
57
+
58
+
59
+ Speed?
60
+ ------
61
+ http://gist.github.com/156091
62
+
63
+
64
+ Authors
65
+ -------
66
+
67
+ * Chris Wanstrath [chris@ozmm.org]
68
+ * Pat Nakajima [http://github.com/nakajima]
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ task :default do
2
+ Dir['test/*_test.rb'].each { |file| require file }
3
+ end
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gemspec|
8
+ gemspec.name = "fakefs"
9
+ gemspec.summary = "A fake filesystem. Use it in your tests."
10
+ gemspec.email = "chris@ozmm.org"
11
+ gemspec.homepage = "http://github.com/defunkt/fakefs"
12
+ gemspec.description = "A fake filesystem. Use it in your tests."
13
+ gemspec.authors = ["Chris Wanstrath"]
14
+ gemspec.has_rdoc = false
15
+ end
16
+ rescue LoadError
17
+ puts "Jeweler not available."
18
+ puts "Install it with: gem install technicalpickles-jeweler"
19
+ end
@@ -0,0 +1,37 @@
1
+ RealFile = File
2
+ RealFileUtils = FileUtils
3
+ RealDir = Dir
4
+ RealFileUtils::Dir = RealDir
5
+ RealFileUtils::File = RealFile
6
+
7
+ module FakeFS
8
+ def self.activate!
9
+ Object.class_eval do
10
+ remove_const(:Dir)
11
+ remove_const(:File)
12
+ remove_const(:FileUtils)
13
+ const_set(:Dir, FakeFS::Dir)
14
+ const_set(:File, FakeFS::File)
15
+ const_set(:FileUtils, FakeFS::FileUtils)
16
+ end
17
+ end
18
+
19
+ def self.deactivate!
20
+ Object.class_eval do
21
+ remove_const(:Dir)
22
+ remove_const(:File)
23
+ remove_const(:FileUtils)
24
+ const_set(:Dir, RealDir)
25
+ const_set(:File, RealFile)
26
+ const_set(:FileUtils, RealFileUtils)
27
+ end
28
+ end
29
+ end
30
+
31
+ def FakeFS
32
+ return ::FakeFS unless block_given?
33
+ ::FakeFS.activate!
34
+ yield
35
+ ::FakeFS.deactivate!
36
+ end
37
+
data/lib/fakefs/dir.rb ADDED
@@ -0,0 +1,23 @@
1
+ module FakeFS
2
+ class Dir
3
+ def self.glob(pattern)
4
+ [FileSystem.find(pattern) || []].flatten.map{|e| e.to_s}.sort
5
+ end
6
+
7
+ def self.[](pattern)
8
+ glob(pattern)
9
+ end
10
+
11
+ def self.chdir(dir, &blk)
12
+ FileSystem.chdir(dir, &blk)
13
+ end
14
+
15
+ def self.pwd
16
+ FileSystem.current_dir.to_s
17
+ end
18
+
19
+ class << self
20
+ alias_method :getwd, :pwd
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,37 @@
1
+ module FakeFS
2
+ class FakeDir < Hash
3
+ attr_accessor :name, :parent
4
+
5
+ def initialize(name = nil, parent = nil)
6
+ @name = name
7
+ @parent = parent
8
+ end
9
+
10
+ def entry
11
+ self
12
+ end
13
+
14
+ def inspect
15
+ "(FakeDir name:#{name.inspect} parent:#{parent.to_s.inspect} size:#{size})"
16
+ end
17
+
18
+ def clone(parent = nil)
19
+ clone = Marshal.load(Marshal.dump(self))
20
+ clone.each do |key, value|
21
+ value.parent = clone
22
+ end
23
+ clone.parent = parent if parent
24
+ clone
25
+ end
26
+
27
+ def to_s
28
+ if parent && parent.to_s != '.'
29
+ File.join(parent.to_s, name)
30
+ elsif parent && parent.to_s == '.'
31
+ "#{File::PATH_SEPARATOR}#{name}"
32
+ else
33
+ name
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,29 @@
1
+ module FakeFS
2
+ class FakeFile
3
+ attr_accessor :name, :parent, :content
4
+
5
+ def initialize(name = nil, parent = nil)
6
+ @name = name
7
+ @parent = parent
8
+ @content = ''
9
+ end
10
+
11
+ def clone(parent = nil)
12
+ clone = super()
13
+ clone.parent = parent if parent
14
+ clone
15
+ end
16
+
17
+ def entry
18
+ self
19
+ end
20
+
21
+ def inspect
22
+ "(FakeFile name:#{name.inspect} parent:#{parent.to_s.inspect} size:#{content.size})"
23
+ end
24
+
25
+ def to_s
26
+ File.join(parent.to_s, name)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ module FakeFS
2
+ class FakeSymlink
3
+ attr_accessor :name, :target
4
+ alias_method :to_s, :name
5
+
6
+ def initialize(target)
7
+ @target = target
8
+ end
9
+
10
+ def inspect
11
+ "symlink(#{target.split('/').last})"
12
+ end
13
+
14
+ def entry
15
+ FileSystem.find(target)
16
+ end
17
+
18
+ def method_missing(*args, &block)
19
+ entry.send(*args, &block)
20
+ end
21
+
22
+ def respond_to?(method)
23
+ entry.respond_to?(method)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,126 @@
1
+ module FakeFS
2
+ class File
3
+ PATH_SEPARATOR = '/'
4
+
5
+ def self.join(*parts)
6
+ parts * PATH_SEPARATOR
7
+ end
8
+
9
+ def self.exist?(path)
10
+ !!FileSystem.find(path)
11
+ end
12
+
13
+ class << self
14
+ alias_method :exists?, :exist?
15
+ end
16
+
17
+ def self.const_missing(name)
18
+ RealFile.const_get(name)
19
+ end
20
+
21
+ def self.directory?(path)
22
+ if path.respond_to? :entry
23
+ path.entry.is_a? FakeDir
24
+ else
25
+ result = FileSystem.find(path)
26
+ result ? result.entry.is_a?(FakeDir) : false
27
+ end
28
+ end
29
+
30
+ def self.symlink?(path)
31
+ if path.respond_to? :entry
32
+ path.is_a? FakeSymlink
33
+ else
34
+ FileSystem.find(path).is_a? FakeSymlink
35
+ end
36
+ end
37
+
38
+ def self.file?(path)
39
+ if path.respond_to? :entry
40
+ path.entry.is_a? FakeFile
41
+ else
42
+ result = FileSystem.find(path)
43
+ result ? result.entry.is_a?(FakeFile) : false
44
+ end
45
+ end
46
+
47
+ def self.expand_path(*args)
48
+ RealFile.expand_path(*args)
49
+ end
50
+
51
+ def self.basename(*args)
52
+ RealFile.basename(*args)
53
+ end
54
+
55
+ def self.dirname(path)
56
+ RealFile.dirname(path)
57
+ end
58
+
59
+ def self.readlink(path)
60
+ symlink = FileSystem.find(path)
61
+ FileSystem.find(symlink.target).to_s
62
+ end
63
+
64
+ def self.open(path, mode='r')
65
+ if block_given?
66
+ yield new(path, mode)
67
+ else
68
+ new(path, mode)
69
+ end
70
+ end
71
+
72
+ def self.read(path)
73
+ file = new(path)
74
+ if file.exists?
75
+ file.read
76
+ else
77
+ raise Errno::ENOENT
78
+ end
79
+ end
80
+
81
+ def self.readlines(path)
82
+ read(path).split("\n")
83
+ end
84
+
85
+ attr_reader :path
86
+ def initialize(path, mode = nil)
87
+ @path = path
88
+ @mode = mode
89
+ @file = FileSystem.find(path)
90
+ @open = true
91
+ end
92
+
93
+ def close
94
+ @open = false
95
+ end
96
+
97
+ def read
98
+ raise IOError.new('closed stream') unless @open
99
+ @file.content
100
+ end
101
+
102
+ def exists?
103
+ @file
104
+ end
105
+
106
+ def puts(*content)
107
+ content.flatten.each do |obj|
108
+ write(obj.to_s + "\n")
109
+ end
110
+ end
111
+
112
+ def write(content)
113
+ raise IOError.new('closed stream') unless @open
114
+
115
+ if !File.exists?(@path)
116
+ @file = FileSystem.add(path, FakeFile.new)
117
+ end
118
+
119
+ @file.content += content
120
+ end
121
+ alias_method :print, :write
122
+ alias_method :<<, :write
123
+
124
+ def flush; self; end
125
+ end
126
+ end
@@ -0,0 +1,118 @@
1
+ module FakeFS
2
+ module FileSystem
3
+ extend self
4
+
5
+ def dir_levels
6
+ @dir_levels ||= []
7
+ end
8
+
9
+ def fs
10
+ @fs ||= FakeDir.new('.')
11
+ end
12
+
13
+ def clear
14
+ @dir_levels = nil
15
+ @fs = nil
16
+ end
17
+
18
+ def files
19
+ fs.values
20
+ end
21
+
22
+ def find(path)
23
+ parts = path_parts(normalize_path(path))
24
+ return fs if parts.empty? # '/'
25
+
26
+ entries = find_recurser(fs, parts).flatten
27
+
28
+ case entries.length
29
+ when 0 then nil
30
+ when 1 then entries.first
31
+ else entries
32
+ end
33
+ end
34
+
35
+ def add(path, object=FakeDir.new)
36
+ parts = path_parts(normalize_path(path))
37
+
38
+ d = parts[0...-1].inject(fs) do |dir, part|
39
+ dir[part] ||= FakeDir.new(part, dir)
40
+ end
41
+
42
+ object.name = parts.last
43
+ object.parent = d
44
+ d[parts.last] ||= object
45
+ end
46
+
47
+ # copies directories and files from the real filesystem
48
+ # into our fake one
49
+ def clone(path)
50
+ path = File.expand_path(path)
51
+ pattern = File.join(path, '**', '*')
52
+ files = RealFile.file?(path) ? [path] : [path] + RealDir.glob(pattern, RealFile::FNM_DOTMATCH)
53
+
54
+ files.each do |f|
55
+ if RealFile.file?(f)
56
+ FileUtils.mkdir_p(File.dirname(f))
57
+ File.open(f, 'w') do |g|
58
+ g.print RealFile.open(f){|h| h.read }
59
+ end
60
+ elsif RealFile.directory?(f)
61
+ FileUtils.mkdir_p(f)
62
+ elsif RealFile.symlink?(f)
63
+ FileUtils.ln_s()
64
+ end
65
+ end
66
+ end
67
+
68
+ def delete(path)
69
+ if dir = FileSystem.find(path)
70
+ dir.parent.delete(dir.name)
71
+ end
72
+ end
73
+
74
+ def chdir(dir, &blk)
75
+ new_dir = find(dir)
76
+ dir_levels.push dir if blk
77
+
78
+ raise Errno::ENOENT, dir unless new_dir
79
+
80
+ dir_levels.push dir if !blk
81
+ blk.call if blk
82
+ ensure
83
+ dir_levels.pop if blk
84
+ end
85
+
86
+ def path_parts(path)
87
+ path.split(File::PATH_SEPARATOR).reject { |part| part.empty? }
88
+ end
89
+
90
+ def normalize_path(path)
91
+ if Pathname.new(path).absolute?
92
+ File.expand_path(path)
93
+ else
94
+ parts = dir_levels + [path]
95
+ File.expand_path(File.join(*parts))
96
+ end
97
+ end
98
+
99
+ def current_dir
100
+ find(normalize_path('.'))
101
+ end
102
+
103
+ private
104
+
105
+ def find_recurser(dir, parts)
106
+ return [] unless dir.respond_to? :[]
107
+
108
+ pattern , *parts = parts
109
+ matches = dir.reject {|k,v| /\A#{pattern.gsub('?','.').gsub('*', '.*')}\Z/ !~ k }.values
110
+
111
+ if parts.empty? # we're done recursing
112
+ matches
113
+ else
114
+ matches.map{|entry| find_recurser(entry, parts) }
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,109 @@
1
+ module FakeFS
2
+ module FileUtils
3
+ extend self
4
+
5
+ def mkdir_p(path)
6
+ FileSystem.add(path, FakeDir.new)
7
+ end
8
+ alias_method :mkpath, :mkdir_p
9
+
10
+ def rm(path)
11
+ FileSystem.delete(path)
12
+ end
13
+ alias_method :rm_rf, :rm
14
+ alias_method :rm_r, :rm
15
+
16
+ def ln_s(target, path)
17
+ raise Errno::EEXIST, path if FileSystem.find(path)
18
+ FileSystem.add(path, FakeSymlink.new(target))
19
+ end
20
+
21
+ def cp(src, dest)
22
+ dst_file = FileSystem.find(dest)
23
+ src_file = FileSystem.find(src)
24
+
25
+ if !src_file
26
+ raise Errno::ENOENT, src
27
+ end
28
+
29
+ if File.directory? src_file
30
+ raise Errno::EISDIR, src
31
+ end
32
+
33
+ if dst_file && File.directory?(dst_file)
34
+ FileSystem.add(File.join(dest, src), src_file.entry.clone(dst_file))
35
+ else
36
+ FileSystem.delete(dest)
37
+ FileSystem.add(dest, src_file.entry.clone)
38
+ end
39
+ end
40
+
41
+ def cp_r(src, dest)
42
+ # This error sucks, but it conforms to the original Ruby
43
+ # method.
44
+ raise "unknown file type: #{src}" unless dir = FileSystem.find(src)
45
+
46
+ new_dir = FileSystem.find(dest)
47
+
48
+ if new_dir && !File.directory?(dest)
49
+ raise Errno::EEXIST, dest
50
+ end
51
+
52
+ if !new_dir && !FileSystem.find(dest+'/../')
53
+ raise Errno::ENOENT, dest
54
+ end
55
+
56
+ # This last bit is a total abuse and should be thought hard
57
+ # about and cleaned up.
58
+ if new_dir
59
+ if src[-2..-1] == '/.'
60
+ dir.values.each{|f| new_dir[f.name] = f.clone(new_dir) }
61
+ else
62
+ new_dir[dir.name] = dir.entry.clone(new_dir)
63
+ end
64
+ else
65
+ FileSystem.add(dest, dir.entry.clone)
66
+ end
67
+ end
68
+
69
+ def mv(src, dest)
70
+ if target = FileSystem.find(src)
71
+ FileSystem.add(dest, target.entry.clone)
72
+ FileSystem.delete(src)
73
+ else
74
+ raise Errno::ENOENT, src
75
+ end
76
+ end
77
+
78
+ def chown(user, group, list, options={})
79
+ list = Array(list)
80
+ list.each do |f|
81
+ unless File.exists?(f)
82
+ raise Errno::ENOENT, f
83
+ end
84
+ end
85
+ list
86
+ end
87
+
88
+ def chown_R(user, group, list, options={})
89
+ chown(user, group, list, options={})
90
+ end
91
+
92
+ def touch(list, options={})
93
+ Array(list).each do |f|
94
+ directory = File.dirname(f)
95
+ # FIXME this explicit check for '.' shouldn't need to happen
96
+ if File.exists?(directory) || directory == '.'
97
+ FileSystem.add(f, FakeFile.new)
98
+ else
99
+ raise Errno::ENOENT, f
100
+ end
101
+ end
102
+ end
103
+
104
+ def cd(dir)
105
+ FileSystem.chdir(dir)
106
+ end
107
+ alias_method :chdir, :cd
108
+ end
109
+ end
@@ -0,0 +1,11 @@
1
+ require 'fileutils'
2
+ require 'pathname'
3
+ require 'fakefs/base'
4
+ require 'fakefs/fake/file'
5
+ require 'fakefs/fake/dir'
6
+ require 'fakefs/fake/symlink'
7
+ require 'fakefs/file_system'
8
+ require 'fakefs/fileutils'
9
+ require 'fakefs/file'
10
+ require 'fakefs/dir'
11
+
@@ -0,0 +1,9 @@
1
+ module FakeFS
2
+ module Version
3
+ VERSION = "0.1.0"
4
+
5
+ def self.to_s
6
+ VERSION
7
+ end
8
+ end
9
+ end
data/lib/fakefs.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'fakefs/safe'
2
+
3
+ FakeFS.activate!
@@ -0,0 +1,543 @@
1
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'fakefs'
3
+ require 'test/unit'
4
+
5
+ class FakeFSTest < Test::Unit::TestCase
6
+ include FakeFS
7
+
8
+ def setup
9
+ FileSystem.clear
10
+ end
11
+
12
+ def test_can_be_initialized_empty
13
+ fs = FileSystem
14
+ assert_equal 0, fs.files.size
15
+ end
16
+
17
+ def xtest_can_be_initialized_with_an_existing_directory
18
+ fs = FileSystem
19
+ fs.clone(File.expand_path(File.dirname(__FILE__))).inspect
20
+ puts fs.files.inspect
21
+ assert_equal 1, fs.files.size
22
+ end
23
+
24
+ def test_can_create_directories
25
+ FileUtils.mkdir_p("/path/to/dir")
26
+ assert_kind_of FakeDir, FileSystem.fs['path']['to']['dir']
27
+ end
28
+
29
+ def test_can_create_directories_with_mkpath
30
+ FileUtils.mkpath("/path/to/dir")
31
+ assert_kind_of FakeDir, FileSystem.fs['path']['to']['dir']
32
+ end
33
+
34
+ def test_knows_directories_exist
35
+ FileUtils.mkdir_p(path = "/path/to/dir")
36
+ assert File.exists?(path)
37
+ end
38
+
39
+ def test_knows_directories_are_directories
40
+ FileUtils.mkdir_p(path = "/path/to/dir")
41
+ assert File.directory?(path)
42
+ end
43
+
44
+ def test_knows_symlink_directories_are_directories
45
+ FileUtils.mkdir_p(path = "/path/to/dir")
46
+ FileUtils.ln_s path, sympath = '/sympath'
47
+ assert File.directory?(sympath)
48
+ end
49
+
50
+ def test_knows_non_existent_directories_arent_directories
51
+ path = 'does/not/exist/'
52
+ assert_equal RealFile.directory?(path), File.directory?(path)
53
+ end
54
+
55
+ def test_doesnt_overwrite_existing_directories
56
+ FileUtils.mkdir_p(path = "/path/to/dir")
57
+ assert File.exists?(path)
58
+ FileUtils.mkdir_p("/path/to")
59
+ assert File.exists?(path)
60
+ end
61
+
62
+ def test_can_create_symlinks
63
+ FileUtils.mkdir_p(target = "/path/to/target")
64
+ FileUtils.ln_s(target, "/path/to/link")
65
+ assert_kind_of FakeSymlink, FileSystem.fs['path']['to']['link']
66
+
67
+ assert_raises(Errno::EEXIST) {
68
+ FileUtils.ln_s(target, '/path/to/link')
69
+ }
70
+ end
71
+
72
+ def test_can_follow_symlinks
73
+ FileUtils.mkdir_p(target = "/path/to/target")
74
+ FileUtils.ln_s(target, link = "/path/to/symlink")
75
+ assert_equal target, File.readlink(link)
76
+ end
77
+
78
+ def test_knows_symlinks_are_symlinks
79
+ FileUtils.mkdir_p(target = "/path/to/target")
80
+ FileUtils.ln_s(target, link = "/path/to/symlink")
81
+ assert File.symlink?(link)
82
+ end
83
+
84
+ def test_can_create_files
85
+ path = '/path/to/file.txt'
86
+ File.open(path, 'w') do |f|
87
+ f.write "Yatta!"
88
+ end
89
+
90
+ assert File.exists?(path)
91
+ end
92
+
93
+ def test_can_read_files_once_written
94
+ path = '/path/to/file.txt'
95
+ File.open(path, 'w') do |f|
96
+ f.write "Yatta!"
97
+ end
98
+
99
+ assert_equal "Yatta!", File.read(path)
100
+ end
101
+
102
+ def test_can_write_to_files
103
+ path = '/path/to/file.txt'
104
+ File.open(path, 'w') do |f|
105
+ f << 'Yada Yada'
106
+ end
107
+ assert_equal 'Yada Yada', File.read(path)
108
+ end
109
+
110
+ def test_can_read_with_File_readlines
111
+ path = '/path/to/file.txt'
112
+ File.open(path, 'w') do |f|
113
+ f.puts "Yatta!", "Gatta!"
114
+ f.puts ["woot","toot"]
115
+ end
116
+
117
+ assert_equal %w(Yatta! Gatta! woot toot), File.readlines(path)
118
+ end
119
+
120
+ def test_File_close_disallows_further_access
121
+ path = '/path/to/file.txt'
122
+ file = File.open(path, 'w')
123
+ file.write 'Yada'
124
+ file.close
125
+ assert_raise IOError do
126
+ file.read
127
+ end
128
+ end
129
+
130
+ def test_can_read_from_file_objects
131
+ path = '/path/to/file.txt'
132
+ File.open(path, 'w') do |f|
133
+ f.write "Yatta!"
134
+ end
135
+
136
+ assert_equal "Yatta!", File.new(path).read
137
+ end
138
+
139
+ def test_file_read_errors_appropriately
140
+ assert_raise Errno::ENOENT do
141
+ File.read('anything')
142
+ end
143
+ end
144
+
145
+ def test_knows_files_are_files
146
+ path = '/path/to/file.txt'
147
+ File.open(path, 'w') do |f|
148
+ f.write "Yatta!"
149
+ end
150
+
151
+ assert File.file?(path)
152
+ end
153
+
154
+ def test_knows_symlink_files_are_files
155
+ path = '/path/to/file.txt'
156
+ File.open(path, 'w') do |f|
157
+ f.write "Yatta!"
158
+ end
159
+ FileUtils.ln_s path, sympath='/sympath'
160
+
161
+ assert File.file?(sympath)
162
+ end
163
+
164
+ def test_knows_non_existent_files_arent_files
165
+ assert_equal RealFile.file?('does/not/exist.txt'), File.file?('does/not/exist.txt')
166
+ end
167
+
168
+ def test_can_chown_files
169
+ good = 'file.txt'
170
+ bad = 'nofile.txt'
171
+ File.open(good,'w'){|f| f.write "foo" }
172
+
173
+ assert_equal [good], FileUtils.chown('noone', 'nogroup', good, :verbose => true)
174
+ assert_raises(Errno::ENOENT) do
175
+ FileUtils.chown('noone', 'nogroup', bad, :verbose => true)
176
+ end
177
+
178
+ assert_equal [good], FileUtils.chown('noone', 'nogroup', good)
179
+ assert_raises(Errno::ENOENT) do
180
+ FileUtils.chown('noone', 'nogroup', bad)
181
+ end
182
+
183
+ assert_equal [good], FileUtils.chown('noone', 'nogroup', [good])
184
+ assert_raises(Errno::ENOENT) do
185
+ FileUtils.chown('noone', 'nogroup', [good, bad])
186
+ end
187
+ end
188
+
189
+ def test_can_chown_R_files
190
+ FileUtils.mkdir_p '/path/'
191
+ File.open('/path/foo', 'w'){|f| f.write 'foo' }
192
+ File.open('/path/foobar', 'w'){|f| f.write 'foo' }
193
+ resp = FileUtils.chown_R('no', 'no', '/path')
194
+ assert_equal ['/path'], resp
195
+ end
196
+
197
+ def test_dir_globs_paths
198
+ FileUtils.mkdir_p '/path'
199
+ File.open('/path/foo', 'w'){|f| f.write 'foo' }
200
+ File.open('/path/foobar', 'w'){|f| f.write 'foo' }
201
+
202
+ FileUtils.mkdir_p '/path/bar'
203
+ File.open('/path/bar/baz', 'w'){|f| f.write 'foo' }
204
+
205
+ FileUtils.cp_r '/path/bar', '/path/bar2'
206
+
207
+ assert_equal ['/path'], Dir['/path']
208
+ assert_equal %w( /path/bar /path/bar2 /path/foo /path/foobar ), Dir['/path/*']
209
+
210
+ assert_equal ['/path/bar/baz'], Dir['/path/bar/*']
211
+ assert_equal ['/path/foo'], Dir['/path/foo']
212
+
213
+ assert_equal ['/path'], Dir['/path*']
214
+ assert_equal ['/path/foo', '/path/foobar'], Dir['/p*h/foo*']
215
+ assert_equal ['/path/foo', '/path/foobar'], Dir['/p??h/foo*']
216
+
217
+ FileUtils.cp_r '/path', '/otherpath'
218
+
219
+ assert_equal %w( /otherpath/foo /otherpath/foobar /path/foo /path/foobar ), Dir['/*/foo*']
220
+ end
221
+
222
+ def test_dir_glob_handles_root
223
+ FileUtils.mkdir_p '/path'
224
+
225
+ # this fails. the root dir should be named '/' but it is '.'
226
+ #assert_equal ['/'], Dir['/']
227
+ end
228
+
229
+ def test_chdir_changes_directories_like_a_boss
230
+ # I know memes!
231
+ FileUtils.mkdir_p '/path'
232
+ assert_equal '.', FileSystem.fs.name
233
+ assert_equal({}, FileSystem.fs['path'])
234
+ Dir.chdir '/path' do
235
+ File.open('foo', 'w'){|f| f.write 'foo'}
236
+ File.open('foobar', 'w'){|f| f.write 'foo'}
237
+ end
238
+
239
+ assert_equal '.', FileSystem.fs.name
240
+ assert_equal(['foo', 'foobar'], FileSystem.fs['path'].keys.sort)
241
+
242
+ c = nil
243
+ Dir.chdir '/path' do
244
+ c = File.open('foo', 'r'){|f| f.read }
245
+ end
246
+
247
+ assert_equal 'foo', c
248
+ end
249
+
250
+ def test_chdir_shouldnt_keep_us_from_absolute_paths
251
+ FileUtils.mkdir_p '/path'
252
+
253
+ Dir.chdir '/path' do
254
+ File.open('foo', 'w'){|f| f.write 'foo'}
255
+ File.open('/foobar', 'w'){|f| f.write 'foo'}
256
+ end
257
+ assert_equal ['foo'], FileSystem.fs['path'].keys.sort
258
+ assert_equal ['foobar', 'path'], FileSystem.fs.keys.sort
259
+
260
+ Dir.chdir '/path' do
261
+ FileUtils.rm('foo')
262
+ FileUtils.rm('/foobar')
263
+ end
264
+
265
+ assert_equal [], FileSystem.fs['path'].keys.sort
266
+ assert_equal ['path'], FileSystem.fs.keys.sort
267
+ end
268
+
269
+ def test_chdir_should_be_nestable
270
+ FileUtils.mkdir_p '/path/me'
271
+ Dir.chdir '/path' do
272
+ File.open('foo', 'w'){|f| f.write 'foo'}
273
+ Dir.chdir 'me' do
274
+ File.open('foobar', 'w'){|f| f.write 'foo'}
275
+ end
276
+ end
277
+
278
+ assert_equal ['foo','me'], FileSystem.fs['path'].keys.sort
279
+ assert_equal ['foobar'], FileSystem.fs['path']['me'].keys.sort
280
+ end
281
+
282
+ def test_chdir_should_flop_over_and_die_if_the_dir_doesnt_exist
283
+ assert_raise(Errno::ENOENT) do
284
+ Dir.chdir('/nope') do
285
+ 1
286
+ end
287
+ end
288
+ end
289
+
290
+ def test_chdir_shouldnt_lose_state_because_of_errors
291
+ FileUtils.mkdir_p '/path'
292
+
293
+ Dir.chdir '/path' do
294
+ File.open('foo', 'w'){|f| f.write 'foo'}
295
+ File.open('foobar', 'w'){|f| f.write 'foo'}
296
+ end
297
+
298
+ begin
299
+ Dir.chdir('/path') do
300
+ raise Exception
301
+ end
302
+ rescue Exception # hardcore
303
+ end
304
+
305
+ Dir.chdir('/path') do
306
+ begin
307
+ Dir.chdir('nope'){ }
308
+ rescue Errno::ENOENT
309
+ end
310
+
311
+ assert_equal ['/path'], FileSystem.dir_levels
312
+ end
313
+
314
+ assert_equal(['foo', 'foobar'], FileSystem.fs['path'].keys.sort)
315
+ end
316
+
317
+ def test_chdir_with_no_block_is_awesome
318
+ FileUtils.mkdir_p '/path'
319
+ Dir.chdir('/path')
320
+ FileUtils.mkdir_p 'subdir'
321
+ assert_equal ['subdir'], FileSystem.current_dir.keys
322
+ Dir.chdir('subdir')
323
+ File.open('foo', 'w'){|f| f.write 'foo'}
324
+ assert_equal ['foo'], FileSystem.current_dir.keys
325
+
326
+ assert_raises(Errno::ENOENT) do
327
+ Dir.chdir('subsubdir')
328
+ end
329
+
330
+ assert_equal ['foo'], FileSystem.current_dir.keys
331
+ end
332
+
333
+ def test_current_dir_reflected_by_pwd
334
+ FileUtils.mkdir_p '/path'
335
+ Dir.chdir('/path')
336
+
337
+ assert_equal '/path', Dir.pwd
338
+ assert_equal '/path', Dir.getwd
339
+
340
+ FileUtils.mkdir_p 'subdir'
341
+ Dir.chdir('subdir')
342
+
343
+ assert_equal '/path/subdir', Dir.pwd
344
+ assert_equal '/path/subdir', Dir.getwd
345
+ end
346
+
347
+ def test_file_open_defaults_to_read
348
+ File.open('foo','w'){|f| f.write 'bar' }
349
+ assert_equal 'bar', File.open('foo'){|f| f.read }
350
+ end
351
+
352
+ def test_flush_exists_on_file
353
+ r = File.open('foo','w'){|f| f.write 'bar'; f.flush }
354
+ assert_equal 'foo', r.path
355
+ end
356
+
357
+ def test_mv_should_raise_error_on_missing_file
358
+ assert_raise(Errno::ENOENT) do
359
+ FileUtils.mv 'blafgag', 'foo'
360
+ end
361
+ end
362
+
363
+ def test_mv_actually_works
364
+ File.open('foo', 'w') {|f| f.write 'bar' }
365
+ FileUtils.mv 'foo', 'baz'
366
+ assert_equal 'bar', File.open('baz'){|f| f.read }
367
+ end
368
+
369
+ def test_cp_actually_works
370
+ File.open('foo', 'w') {|f| f.write 'bar' }
371
+ FileUtils.cp('foo', 'baz')
372
+ assert_equal 'bar', File.read('baz')
373
+ end
374
+
375
+ def test_cp_file_into_dir
376
+ File.open('foo', 'w') {|f| f.write 'bar' }
377
+ FileUtils.mkdir_p 'baz'
378
+
379
+ FileUtils.cp('foo', 'baz')
380
+ assert_equal 'bar', File.read('baz/foo')
381
+ end
382
+
383
+ def test_cp_overwrites_dest_file
384
+ File.open('foo', 'w') {|f| f.write 'FOO' }
385
+ File.open('bar', 'w') {|f| f.write 'BAR' }
386
+
387
+ FileUtils.cp('foo', 'bar')
388
+ assert_equal 'FOO', File.read('bar')
389
+ end
390
+
391
+ def test_cp_fails_on_no_source
392
+ assert_raise Errno::ENOENT do
393
+ FileUtils.cp('foo', 'baz')
394
+ end
395
+ end
396
+
397
+ def test_cp_fails_on_directory_copy
398
+ FileUtils.mkdir_p 'baz'
399
+
400
+ assert_raise Errno::EISDIR do
401
+ FileUtils.cp('baz', 'bar')
402
+ end
403
+ end
404
+
405
+ def test_cp_r_doesnt_tangle_files_together
406
+ File.open('foo', 'w') {|f| f.write 'bar' }
407
+ FileUtils.cp_r('foo', 'baz')
408
+ File.open('baz', 'w') {|f| f.write 'quux' }
409
+ assert_equal 'bar', File.open('foo'){|f| f.read }
410
+ end
411
+
412
+ def test_cp_r_should_raise_error_on_missing_file
413
+ # Yes, this error sucks, but it conforms to the original Ruby
414
+ # method.
415
+ assert_raise(RuntimeError) do
416
+ FileUtils.cp_r 'blafgag', 'foo'
417
+ end
418
+ end
419
+
420
+ def test_cp_r_handles_copying_directories
421
+ FileUtils.mkdir_p 'subdir'
422
+ Dir.chdir('subdir'){ File.open('foo', 'w'){|f| f.write 'footext' } }
423
+
424
+ FileUtils.mkdir_p 'baz'
425
+
426
+ # To a previously uncreated directory
427
+ FileUtils.cp_r('subdir', 'quux')
428
+ assert_equal 'footext', File.open('quux/foo'){|f| f.read }
429
+
430
+ # To a directory that already exists
431
+ FileUtils.cp_r('subdir', 'baz')
432
+ assert_equal 'footext', File.open('baz/subdir/foo'){|f| f.read }
433
+
434
+ # To a subdirectory of a directory that does not exist
435
+ assert_raises(Errno::ENOENT) {
436
+ FileUtils.cp_r('subdir', 'nope/something')
437
+ }
438
+ end
439
+
440
+ def test_cp_r_only_copies_into_directories
441
+ FileUtils.mkdir_p 'subdir'
442
+ Dir.chdir('subdir'){ File.open('foo', 'w'){|f| f.write 'footext' } }
443
+
444
+ File.open('bar', 'w') {|f| f.write 'bartext' }
445
+
446
+ assert_raises(Errno::EEXIST) do
447
+ FileUtils.cp_r 'subdir', 'bar'
448
+ end
449
+
450
+ FileUtils.mkdir_p 'otherdir'
451
+ FileUtils.ln_s 'otherdir', 'symdir'
452
+
453
+ FileUtils.cp_r 'subdir', 'symdir'
454
+ assert_equal 'footext', File.open('symdir/subdir/foo'){|f| f.read }
455
+ end
456
+
457
+ def test_cp_r_sets_parent_correctly
458
+ FileUtils.mkdir_p '/path/foo'
459
+ File.open('/path/foo/bar', 'w'){|f| f.write 'foo' }
460
+ File.open('/path/foo/baz', 'w'){|f| f.write 'foo' }
461
+
462
+ FileUtils.cp_r '/path/foo', '/path/bar'
463
+
464
+ assert File.exists?('/path/bar/baz')
465
+ FileUtils.rm_rf '/path/bar/baz'
466
+ assert_equal %w( /path/bar/bar ), Dir['/path/bar/*']
467
+ end
468
+
469
+ def test_clone_clones_normal_files
470
+ RealFile.open(here('foo'), 'w'){|f| f.write 'bar' }
471
+ assert !File.exists?(here('foo'))
472
+ FileSystem.clone(here('foo'))
473
+ assert_equal 'bar', File.open(here('foo')){|f| f.read }
474
+ ensure
475
+ RealFile.unlink(here('foo')) if RealFile.exists?(here('foo'))
476
+ end
477
+
478
+ def test_clone_clones_directories
479
+ RealFileUtils.mkdir_p(here('subdir'))
480
+
481
+ FileSystem.clone(here('subdir'))
482
+
483
+ assert File.exists?(here('subdir')), 'subdir was cloned'
484
+ assert File.directory?(here('subdir')), 'subdir is a directory'
485
+ ensure
486
+ RealFileUtils.rm_rf(here('subdir')) if RealFile.exists?(here('subdir'))
487
+ end
488
+
489
+ def test_clone_clones_dot_files_even_hard_to_find_ones
490
+ RealFileUtils.mkdir_p(here('subdir/.bar/baz/.quux/foo'))
491
+ assert !File.exists?(here('subdir'))
492
+
493
+ FileSystem.clone(here('subdir'))
494
+ assert_equal ['.bar'], FileSystem.find(here('subdir')).keys
495
+ assert_equal ['foo'], FileSystem.find(here('subdir/.bar/baz/.quux')).keys
496
+ ensure
497
+ RealFileUtils.rm_rf(here('subdir')) if RealFile.exists?(here('subdir'))
498
+ end
499
+
500
+ def test_putting_a_dot_at_end_copies_the_contents
501
+ FileUtils.mkdir_p 'subdir'
502
+ Dir.chdir('subdir'){ File.open('foo', 'w'){|f| f.write 'footext' } }
503
+
504
+ FileUtils.mkdir_p 'newdir'
505
+ FileUtils.cp_r 'subdir/.', 'newdir'
506
+ assert_equal 'footext', File.open('newdir/foo'){|f| f.read }
507
+ end
508
+
509
+ def test_file_can_read_from_symlinks
510
+ File.open('first', 'w'){|f| f.write '1'}
511
+ FileUtils.ln_s 'first', 'one'
512
+ assert_equal '1', File.open('one'){|f| f.read }
513
+
514
+ FileUtils.mkdir_p 'subdir'
515
+ File.open('subdir/nother','w'){|f| f.write 'works' }
516
+ FileUtils.ln_s 'subdir', 'new'
517
+ assert_equal 'works', File.open('new/nother'){|f| f.read }
518
+ end
519
+
520
+ def test_files_can_be_touched
521
+ FileUtils.touch('touched_file')
522
+ assert File.exists?('touched_file')
523
+ list = ['newfile', 'another']
524
+ FileUtils.touch(list)
525
+ list.each { |fp| assert(File.exists?(fp)) }
526
+ end
527
+
528
+ def test_touch_does_not_work_if_the_dir_path_cannot_be_found
529
+ assert_raises(Errno::ENOENT) {
530
+ FileUtils.touch('this/path/should/not/be/here')
531
+ }
532
+ FileUtils.mkdir_p('subdir')
533
+ list = ['subdir/foo', 'nosubdir/bar']
534
+
535
+ assert_raises(Errno::ENOENT) {
536
+ FileUtils.touch(list)
537
+ }
538
+ end
539
+
540
+ def here(fname)
541
+ RealFile.expand_path(RealFile.dirname(__FILE__)+'/'+fname)
542
+ end
543
+ end
data/test/safe_test.rb ADDED
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'fakefs/safe'
3
+ require 'test/unit'
4
+
5
+ class FakeFSSafeTest < Test::Unit::TestCase
6
+ def setup
7
+ FakeFS.deactivate!
8
+ end
9
+
10
+ def test_FakeFS_method_does_not_intrude_on_global_namespace
11
+ path = '/path/to/file.txt'
12
+
13
+ FakeFS do
14
+ File.open(path, 'w') { |f| f.write "Yatta!" }
15
+ assert File.exists?(path)
16
+ end
17
+
18
+ assert ! File.exists?(path)
19
+ end
20
+ end
data/test/verify.rb ADDED
@@ -0,0 +1,27 @@
1
+ # Figure out what's missing from fakefs
2
+ #
3
+ # USAGE
4
+ #
5
+ # $ ruby test/verify.rb | grep "not implemented"
6
+ require 'fakefs'
7
+ require 'test/unit'
8
+
9
+ class FakeFSVerifierTest < Test::Unit::TestCase
10
+ (RealFile.methods - Class.new.methods).each do |name|
11
+ define_method("test #{name} class method") do
12
+ assert File.respond_to?(name), "File.#{name} not implemented"
13
+ end
14
+ end
15
+
16
+ (RealFile.instance_methods - Enumerable.instance_methods).each do |name|
17
+ define_method("test #{name} instance method") do
18
+ assert File.instance_methods.include?(name), "File##{name} not implemented"
19
+ end
20
+ end
21
+
22
+ (RealFileUtils.methods - Class.new.methods).each do |name|
23
+ define_method("test #{name} module method") do
24
+ assert FileUtils.respond_to?(name), "FileUtils.#{name} not implemented"
25
+ end
26
+ end
27
+ end
data/version.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 0
4
+ :patch: 1
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rsanheim-fakefs
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Chris Wanstrath
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-09-12 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: A fake filesystem. Use it in your tests.
17
+ email: chris@ozmm.org
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.markdown
25
+ files:
26
+ - LICENSE
27
+ - README.markdown
28
+ - Rakefile
29
+ - lib/fakefs.rb
30
+ - lib/fakefs/base.rb
31
+ - lib/fakefs/dir.rb
32
+ - lib/fakefs/fake/dir.rb
33
+ - lib/fakefs/fake/file.rb
34
+ - lib/fakefs/fake/symlink.rb
35
+ - lib/fakefs/file.rb
36
+ - lib/fakefs/file_system.rb
37
+ - lib/fakefs/fileutils.rb
38
+ - lib/fakefs/safe.rb
39
+ - lib/fakefs/version.rb
40
+ - test/fakefs_test.rb
41
+ - test/safe_test.rb
42
+ - test/verify.rb
43
+ - version.yml
44
+ has_rdoc: false
45
+ homepage: http://github.com/defunkt/fakefs
46
+ licenses:
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --charset=UTF-8
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ requirements: []
65
+
66
+ rubyforge_project:
67
+ rubygems_version: 1.3.5
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: A fake filesystem. Use it in your tests.
71
+ test_files:
72
+ - test/fakefs_test.rb
73
+ - test/safe_test.rb
74
+ - test/verify.rb