diff --git a/lib/fakefs.rb b/lib/fakefs.rb index 07a937d..0753734 100644 --- a/lib/fakefs.rb +++ b/lib/fakefs.rb @@ -152,11 +152,16 @@ module FakeFS module FileSystem extend self + def dir_levels + @dir_levels + end + def fs @fs ||= MockDir.new('.') end def clear + @dir_levels = [] @fs = nil end @@ -165,7 +170,7 @@ module FakeFS end def find(path) - parts = path_parts(path) + parts = path_parts(normalize_path(path)) target = parts[0...-1].inject(fs) do |dir, part| dir[part] || {} @@ -180,7 +185,7 @@ module FakeFS end def add(path, object=MockDir.new) - parts = path_parts(path) + parts = path_parts(normalize_path(path)) d = parts[0...-1].inject(fs) do |dir, part| dir[part] ||= MockDir.new(part, dir) @@ -220,16 +225,27 @@ module FakeFS def chdir(dir, &blk) raise "you must pass in a block" unless blk - @old_fs = @fs - @fs = find(dir) + + new_dir = find(dir) + raise Errno::ENOENT unless new_dir + dir_levels.push dir blk.call ensure - @fs = @old_fs + dir_levels.pop end def path_parts(path) path.split(File::PATH_SEPARATOR).reject { |part| part.empty? } end + + def normalize_path(path) + if path[0,1] == '/' + File.expand_path(path) + else + parts = dir_levels + [path] + File.expand_path(File.join(*parts)) + end + end end class MockFile diff --git a/test/fakefs_test.rb b/test/fakefs_test.rb index a8c0d36..456524b 100644 --- a/test/fakefs_test.rb +++ b/test/fakefs_test.rb @@ -171,6 +171,46 @@ class FakeFSTest < Test::Unit::TestCase end end + def test_chdir_shouldnt_keep_us_from_absolute_paths + FileUtils.mkdir_p '/path' + + Dir.chdir '/path' do + File.open('foo', 'w'){|f| f.write 'foo'} + File.open('/foobar', 'w'){|f| f.write 'foo'} + end + assert_equal ['foo'], FileSystem.fs['path'].keys.sort + assert_equal ['foobar', 'path'], FileSystem.fs.keys.sort + + Dir.chdir '/path' do + FileUtils.rm('foo') + FileUtils.rm('/foobar') + end + + assert_equal [], FileSystem.fs['path'].keys.sort + assert_equal ['path'], FileSystem.fs.keys.sort + end + + def test_chdir_should_be_nestable + FileUtils.mkdir_p '/path/me' + Dir.chdir '/path' do + File.open('foo', 'w'){|f| f.write 'foo'} + Dir.chdir 'me' do + File.open('foobar', 'w'){|f| f.write 'foo'} + end + end + + assert_equal ['foo','me'], FileSystem.fs['path'].keys.sort + assert_equal ['foobar'], FileSystem.fs['path']['me'].keys.sort + end + + def test_chdir_should_flop_over_and_die_if_the_dir_doesnt_exist + assert_raise(Errno::ENOENT) do + Dir.chdir('/nope') do + 1 + end + end + end + def test_chdir_shouldnt_lose_state_because_of_errors FileUtils.mkdir_p '/path'