fakefs / fakefs Goto Github PK
View Code? Open in Web Editor NEWA fake filesystem. Use it in your tests.
License: MIT License
A fake filesystem. Use it in your tests.
License: MIT License
I've added the ability to run individual test files. When running the main test file, "fakefs_test.rb", there's is a single failure that's not present when running the whole suite with rake:
Finished in 0.222511 seconds.
1) Failure:
test_clone_clones_dot_files_even_hard_to_find_ones(FakeFSTest) [test/fakefs_test.rb:800]:
<false> is not true.
300 tests, 412 assertions, 1 failures, 0 errors
I've tried to debug it but gave up after half an hour. The failure is here:
RealFileUtils.mkdir_p(here('subdir/.bar/baz/.quux/foo'))
assert !File.exists?(here('subdir'))
First a directory is created on the real filesystem, then tried to read from the fake filesystem. The directory should not be present on the fake filesystem, but is still found.
Apps that depends on file system hard links won't work.
The FakeFS method currently returns the result of FakeFS#deactivate!, rather than the result of the yield. This makes grabbing the result of the block a bit cumbersome. I've pushed a patch here: http://github.com/msassak/fakefs/tree/return-yield-result. Let me know if you'd like a pull request.
Dir.glob takes a block which it passes on to #each. Here's a monkey patch.
module FakeFS
class Dir
class << self
alias glob_without_block glob
def glob(pattern, &block)
ary = glob_without_block(pattern)
ary.each &block if block_given?
ary
end
end
end
end
Is there any particular reason File.ctime
and File.stat(file).ctime
is not implemented?
In generally, Dir.mkdir raise error when given path already exists.
For example in irb
irb(main):001:0> Dir.mkdir "test"
=> 0
irb(main):002:0> Dir.mkdir "test"
Errno::EEXIST: File exists - test
from (irb):2:in `mkdir'
from (irb):2
I know that FileUtild.mkdir has been faked, and I wish to use Dir.mkdir yet.
Thank you :-)
Standard lib FileUtils.mv takes an options hash as a third argument, FakeFS bombs on this:
With real FileUtils:
irb(main):005:0> FileUtils.mv '/tmp/foo', '/tmp/bar', :force => true
=> 0
With FakeFS
irb(main):006:0> FileUtils.mv '/tmp/foo', '/tmp/bar', :force => true
ArgumentError: wrong number of arguments (3 for 2)
Function 'open' is not faked.
For example
#!/usr/bin/ruby
require "rubygems"
require "fakefs"
FileUtils.touch("fileutils")
open("kernel", "a"){}
This code does not create a file 'fileutils', but do create 'kernel'.
In the following example, FakeFS would not be deactivated after the block raises an exception:
FakeFS do
raise 'an error'
end
This can cause problems for other portions of your code which expect FakeFS to be deactivated.
This commit fixes the problem for me: http://github.com/jameswilding/fakefs/commit/c3c14658758d4ac7f883908e1aa2d2f90e8eb6cd
YMMV :)
In the standard lib Dir
class the **
recursive glob matches zero or more directories. In FakeFS it matches one or more.
>> File.open('/tmp/in_tmp.txt', 'w')
=> #<File:/tmp/in_tmp.txt>
>> Dir['/tmp/**/*']
=> ["/tmp/in_tmp.txt"]
>> require 'fakefs'
=> true
>> File.open('/tmp/in_tmp.txt', 'w')
=> #<FakeFS::File:0x12165dc @mode="w", @file=(FakeFile name:"in_tmp.txt" parent:"/tmp" size:0), @path="/tmp/in_tmp.txt", @open=true>
>> Dir['/tmp/**/*']
=> []
>> Dir['/tmp/*']
=> ["/tmp/in_tmp.txt"]
The FakeFS behavior should mimic the standard lib.
http://ruby-doc.org/core/classes/Dir.src/M002322.html
Look for another issue with what caused the problem, or better yet a fork. Here's the error though:
[~/git/forks/fakefs][master] ruby test/fake_fs.rb
./test/../lib/fakefs.rb:165:in `initialize': wrong number of arguments (1 for 0) (ArgumentError)
from ./test/../lib/fakefs.rb:165:in `new'
from ./test/../lib/fakefs.rb:165
from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `require'
from test/fake_fs.rb:2
Doesn't work out of the box for me unfortunately.
undefined method `syswrite' for FakeFS::File
fakefs and rspec 2.x seem to be at odds, although I don't know why. As soon as I require fakefs into a spec:
/Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- rspec/mocks (LoadError)
from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `require'
from /Library/Ruby/Gems/1.8/gems/rspec-core-2.3.1/lib/rspec/core/mocking/with_rspec.rb:1
from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `require'
from /Library/Ruby/Gems/1.8/gems/rspec-core-2.3.1/lib/rspec/core/configuration.rb:116:in `mock_framework'
from /Library/Ruby/Gems/1.8/gems/rspec-core-2.3.1/lib/rspec/core/configuration.rb:378:in `configure_mock_framework'
from /Library/Ruby/Gems/1.8/gems/rspec-core-2.3.1/lib/rspec/core/command_line.rb:19:in `run'
from /Library/Ruby/Gems/1.8/gems/rspec-core-2.3.1/lib/rspec/core/runner.rb:55:in `run_in_process'
from /Library/Ruby/Gems/1.8/gems/rspec-core-2.3.1/lib/rspec/core/runner.rb:46:in `run'
from /Library/Ruby/Gems/1.8/gems/rspec-core-2.3.1/lib/rspec/core/runner.rb:10:in `autorun'
from /usr/bin/rspec:19
I don't seem to be the only one with this issue, although I don't see a reported issue in the issue list.
Jruby test failures:
FileUtils.mkdir is not handled by FakeFS.
I've fixed it inside of this branch: http://github.com/flavio/fakefs/tree/fileutils_mkdir
See the following:
scott-taylors-macbook-pro:git_supermodule(master) scotttaylor$ irb
Pathname
NameError: uninitialized constant Pathname
from (irb):1
require 'fakefs'
=> true
Pathname
=> Pathname
This caused a test suite to pass, yet the real implementation would raise an error simply because I had forgotten to add 'require "pathname"'
If whoever's maintaining this nowadays is able, I'd really appreciate an updated gem. The latest code in the repository has a bugfix I need and I'd prefer to have a gem over a submodule or something like that.
Thank you.
Attempting to create a Tempfile when I have the FS faked gives me an error, because Tempfile is trying to make the lockfile in the current directory, which hasn't been created in the fake filesystem. I'm not sure what can be done about this, except maybe to have FakeFS redefine Dir::tmpdir and automatically create it. I'm working on a patch, but wanted this documented.
I was using Pathname#exist? within some code, and noticed it was not being wrapped by fakefs. It looks like Pathname uses FileTest, rather than File (no idea why). I worked around it with a monkey patch:
# fakefs does not wrap FileTest methods, which Pathname delegates to
class Pathname
def exist?
File.exist?(self)
end
end
I'm using fakefs to wrap Rack::File specs, and it explodes when the "b" mode is passed to File.open. I worked around this temporarily with a monkey patch:
# fakefs does not handle the "b" open mode
module FakeFS
class File
def mode_in?(list)
list.include?(@mode.sub('b', ''))
end
end
end
Please add support for File.rename, which is a primitive of FileUtils.mv.
I have a patch (with tests) on my topic branch:
http://github.com/ktheory/fakefs/tree/file_rename
See File.rename's rdoc: http://ruby-doc.org/core/classes/File.html#M002537
File.rename and FileUtils.mv are similar. FileUtils.mv calls File.rename internally. FWIW, the differences are:
Hi,
it would be nice to also mock Kernel#require and Kernel#load. Is it possible or are these two too complicated?
Best regards,
Lars
On ruby ruby-1.8.7-p302 via rvm, I get this backtrace when opening a file:
NameError: uninitialized constant File::StringIO
/Users/davec/.rvm/gems/ruby-1.8.7-p302/gems/fakefs-0.2.1/lib/fakefs/file.rb:70:in `const_get'
/Users/davec/.rvm/gems/ruby-1.8.7-p302/gems/fakefs-0.2.1/lib/fakefs/file.rb:70:in `const_missing'
/Users/davec/.rvm/gems/ruby-1.8.7-p302/gems/fakefs-0.2.1/lib/fakefs/file.rb:255:in `check_modes!'
/Users/davec/.rvm/gems/ruby-1.8.7-p302/gems/fakefs-0.2.1/lib/fakefs/file.rb:213:in `initialize'
/Users/davec/.rvm/gems/ruby-1.8.7-p302/gems/fakefs-0.2.1/lib/fakefs/file.rb:118:in `new'
/Users/davec/.rvm/gems/ruby-1.8.7-p302/gems/fakefs-0.2.1/lib/fakefs/file.rb:118:in `open'
If I require 'stringio'
, everything works. Why doesn't FakeFS require this itself?
This is not an issue with FakeFS directly (as far as I can tell), I'm more looking for a best-practice method of using FakeFS with Cucumber since the most logical method seems to cause problems.
Namely, using the pre/post hook method of JIT-invoking FakeFS before step execution seems to "hide" classes that reside in RAILS_ROOT/lib.
Within the hook just before the FakeFS.activate!
, the lib classes exist and are visible. Immediately after the method call, they're gone, so it doesn't seem to be a timing issue wrt the hooks (which Aslak assures me fire off well after the Rails environment is done loading).
Any ideas?
the patch below
From 19f9e2082ef6aa818bc4b91f6bf2f8135d0a1b14 Mon Sep 17 00:00:00 2001 From: Keita Urashima Date: Tue, 10 Nov 2009 03:10:10 +0900 Subject: [PATCH] FileUtils.rm should be able to delete two or more files --- lib/fakefs/fileutils.rb | 6 ++++-- test/fakefs_test.rb | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/fakefs/fileutils.rb b/lib/fakefs/fileutils.rb index bb61c07..34fec0e 100644 --- a/lib/fakefs/fileutils.rb +++ b/lib/fakefs/fileutils.rb @@ -19,8 +19,10 @@ module FakeFS end end - def rm(path) - FileSystem.delete(path) + def rm(list, options = {}) + Array(list).each do |path| + FileSystem.delete(path) + end end alias_method :rm_rf, :rm diff --git a/test/fakefs_test.rb b/test/fakefs_test.rb index 3f0e6ab..18942eb 100644 --- a/test/fakefs_test.rb +++ b/test/fakefs_test.rb @@ -37,6 +37,13 @@ class FakeFSTest < Test::Unit::TestCase assert File.exists?("/path/to/dir") == false end + def test_can_delete_multiple_files + FileUtils.touch(["foo", "bar"]) + FileUtils.rm(["foo", "bar"]) + assert File.exists?("foo") == false + assert File.exists?("bar") == false + end + def test_knows_directories_exist FileUtils.mkdir_p(path = "/path/to/dir") assert File.exists?(path) -- 1.6.5.2
Fix here: nakajima/fakefs@bf6f121
Hi,
Kernel#test isn't faked. Tenjin for example uses this to check if a template file exists. I overwrote the Tenjin::Engine#find_template_file for my tests, but I think this should be in FakeFS.
Best regards,
Lars
Would you accept changes if I did the work to make this a gem?
I can't really use this in my projects (or at least I don't know how) without it being a gem. I need to put it in 'gem dependencies'... I know 'rip' will install it fine, but yeah...
FileUtils.mv [file1, file2], dest
is perfectly legal. fakefs currently breaks in:
def mv(src, dest)
if target = FileSystem.find(src)
as it isn't valid to pass an array as the arg to FileSystem.find. The error message is:
TypeError: can't convert Array into String
project/tmp/isolate/ruby-1.8/gems/fakefs-0.2.1/lib/fakefs/file.rb:104:in `basename:'
Hi,
the error message raised in File#check_file_existence! uses the wrong variable to output the file's path. It will always print an empty path.
Patch: http://gist.github.com/310707
Best regards,
Lars
Reproduced with:
File.open('file', 'w')
File.file?('file') # => true
Pathname.new('file').file? # => false
I checked internals of Pathname and it uses FileTest.file? instead of File.file?. So FakeFS needs to fake FileTest module too.
When calling File.unlink
or File.delete
raises an error like
undefined method `delete' for FakeFS::File:Class
loading autotest/merb_rspec
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -S spec -O spec/spec.opts spec/models/user_spec.rb spec/models/site_spec.rb spec/spec_custom_matchers.rb
/Library/Ruby/Gems/1.8/gems/merb-core-1.0.12/lib/merb-core.rb:389:in log_stream': uninitialized constant FakeFS::File::WRONLY (NameError) from /Library/Ruby/Gems/1.8/gems/merb-core-1.0.12/lib/merb-core/bootloader.rb:223:in
run'
from /Library/Ruby/Gems/1.8/gems/merb-core-1.0.12/lib/merb-core/bootloader.rb:99:in run' from /Library/Ruby/Gems/1.8/gems/merb-core-1.0.12/lib/merb-core/server.rb:172:in
bootup'
from /Library/Ruby/Gems/1.8/gems/merb-core-1.0.12/lib/merb-core/server.rb:42:in start' from /Library/Ruby/Gems/1.8/gems/merb-core-1.0.12/lib/merb-core.rb:170:in
start'
from /Library/Ruby/Gems/1.8/gems/merb-core-1.0.12/lib/merb-core.rb:183:in start_environment' from ./spec/models/../spec_helper.rb:16 from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in
gem_original_require'
... 7 levels...
from /Library/Ruby/Gems/1.8/gems/rspec-1.2.6/lib/spec/runner/command_line.rb:9:in run' from /Library/Ruby/Gems/1.8/gems/rspec-1.2.6/bin/spec:4 from /opt/local/bin/spec:19:in
load'
from /opt/local/bin/spec:19
Please add support for File.utime, which updates the atime and mtime of a file.
I have a patch (with tests) on my topic branch:
http://github.com/ktheory/fakefs/tree/file_utime
The rdoc for the real File.utime is:
File.utime(atime, mtime, file_name,...) => integer
Sets the access and modification times of each named file to the first two arguments. Returns the number of file names in the argument list.
See http://ruby-doc.org/core/classes/File.html#M002527
Note that my FakeFS implementation ignores the atime value, since FakeFS doesn't implement atime.
After temporarily working around #16, I found that Tempfiles still couldn't be created because the File.open call on tempfile.rb:60 uses an integer mode instead of a string. FakeFS only accepts string file modes, but the rdoc for IO says
I/O ports may be opened in any one of several different modes,
which are shown in this section as mode. The mode may either be a
Fixnum or a String.
1) Error:
test_logrotate_with_fakefs(TestBuild):
NoMethodError: private method `split' called for FakeFS::File:Class
/home/yerbie/gem/gems/logrotate-1.2.1/lib/logrotate/impl.rb:302:in `rotate_file_date_extension'
/home/yerbie/gem/gems/logrotate-1.2.1/lib/logrotate/impl.rb:270:in `rotate_single_file'
/home/yerbie/gem/gems/logrotate-1.2.1/lib/logrotate/logrotate.rb:87:in `send'
/home/yerbie/gem/gems/logrotate-1.2.1/lib/logrotate/logrotate.rb:87:in `rotate_file'
./build.rb:26:in `test'
test/test_build.rb:36:in `test_logrotate_with_fakefs'
/common/ruby-1.8.6-p287/lib/ruby/gems/1.8/gems/mocha-0.9.8/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:19:in `__send__'
/common/ruby-1.8.6-p287/lib/ruby/gems/1.8/gems/mocha-0.9.8/lib/mocha/integration/test_unit/ruby_version_186_and_above.rb:19:in `run'
require 'rubygems'
require 'test'
require 'fakefs'
include FakeFS
class TestTest < Test::Unit::TestCase
def setup
FakeFS.activate!
FileSystem.clear
end
def teardown
FakeFS.deactivate!
end
def test_logrotate_with_fakefs
Test.new('xx').test
assert(true)
end
end
require 'logrotate'
require 'fileutils'
class Test
def test
options = {
:date_time_ext => true,
:date_time_format => '%F_%T',
:count => 2
}
FileUtils.touch("blah")
result = LogRotate.rotate_file("blah", options)
end
end
Update FakeFS::File and FakeFile to modify the mtime when a file is touched and when it's modified. Includes tests.
In my code I have this:
require 'find'
files = File.find(model_path) do |file|
Which throws this error with fakefs:
NoMethodError: undefined method `lstat' for FakeFS::File:Class
/Users/christian/.rvm/ruby-1.8.7-tv1_8_7_72/lib/ruby/1.8/find.rb:42:in `find'
/Users/christian/.rvm/ruby-1.8.7-tv1_8_7_72/lib/ruby/1.8/find.rb:38:in `catch'
Dir.glob works...
gem gem gem gem gem
While working on #6 I discovered that File.expand_path is not faked by FakeFS. This causes problems when using paths that rely on the current working directory:
irb(main):001:0> require 'fakefs'
=> true
irb(main):002:0> Dir.glob '/*'
=> []
irb(main):003:0> Dir.pwd
=> ""
irb(main):004:0> File.expand_path 'test.txt'
=> "/Users/narnach/Projects/WesOldenbeuving/fakefs/test.txt"
irb(main):005:0> Dir.chdir '/'
=> nil
irb(main):006:0> File.expand_path 'test.txt'
=> "/Users/narnach/Projects/WesOldenbeuving/fakefs/test.txt"
irb(main):007:0>
I'm not very familiar with the internals of FakeFS::FileSystem, so it will take me a while to figure out how to make this work. I'll look into this when I have the time for it, but if someone sees an obvious way to implement it, please do :-)
I'm reading a file line by line:
io = File.open("myfile", "r")
while !io.eof?
io.readlines
end
io.rewind
# Keep at it
This fails since all three methods are missing from FakeFS::File
The recursive globbing behavior for patterns ending in wildcards (introduced at 1c6825fb9b4d5c8c73fee01a8fbd328cea2b78f) differs from the standard library Dir
behavior by only returning files rather than files and directories. For example, given:
File.open('/one/two/three/four.rb', 'w')
File.open('/one/five.rb', 'w')
FakeFS
does this:
Dir['/one/**/*'] #=> ['/one/five.rb', '/one/two/three/four.rb']
Dir['/one/**'] #=> ['/one/five.rb', '/one/two/three/four.rb']
Whereas the standard lib Dir
does this:
Dir['/one/**/*'] #=> ['/one/five.rb', '/one/two', '/one/two/three', '/one/two/three/four.rb']
Dir['/one/**'] #=> ['/one/five.rb', '/one/two']
This commit on this branch aims to help FakeFS
more accurately mimic the standard Dir
class.
When doing a Dir[], using a path which contains */, the resulting array will contain only files, not the folders. To follow the actual behavior it should also fetch folders recursively, not only files.
The current fake implementation of File.join is incorrect for arguments like
File.join("a/", "/b") # => "a///b"
RealFile.join("a/", "/b") # => "a/b
I have a patch (with tests) on my topic branch:
http://github.com/ktheory/fakefs/tree/fix_file_join
My patch simply delegates FakeFS::File.join to RealFile.join. IMHO, this is correct because RealFile.join manipulates strings in memory and doesn't touch the filesystem.
I also include some tests flexing RealFile.join's slash-squashing muscles.
Trying to run rcov in rip or fakefs:
$ ruby -S rcov -o coverage -T -x '/Library/Ruby/*' /usr/bin/spec -- "test/commands_test.rb" "test/dir_test.rb" "test/env_test.rb" "test/file_test.rb" "test/git_test.rb" "test/rip_test.rb" "test/ui_test.rb"
/Library/Ruby/Gems/1.8/gems/rcov-0.8.1.2.0/lib/rcov/report.rb:116:in normalize_filename': undefined method
getwd' for FakeFS::Dir:Class (NoMethodError)
from /Library/Ruby/Gems/1.8/gems/rcov-0.8.1.2.0/lib/rcov/report.rb:101:in add_file' from /Library/Ruby/Gems/1.8/gems/rcov-0.8.1.2.0/lib/rcov.rb:637:in
dump_coverage_info'
It seems that rcov's Dir is being taken by fakefs. Is there a way to avoid this?
In regular Ruby, File#open with the 'w' write flag clears the file. FakeFS did not yet do this.
The fix with a test can be found on my topic branch: http://github.com/Narnach/fakefs/tree/file_open_with_write
require 'fileutils'
FileUtils.mkdir_p "test", :mode => 0755 # => "test"
require 'fakefs'
FileUtils.mkdir_p "test2", :mode => 0755 # ArgumentError: wrong number of arguments (2 for 1)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.