module MemFs

Provides a clean way to interact with a fake file system.

@example Calling activate with a block.

MemFs.activate do
  Dir.mkdir '/hello_world'
  # /hello_world exists here, in memory
end
# /hello_world doesn't exist and has never been on the real FS

@example Calling activate! and deactivate!.

MemFs.activate!
  # The fake file system is running here
MemFs.deactivate!
# Everything back to normal

Constants

OriginalDir

Keeps track of the original Ruby Dir class.

OriginalFile

Keeps track of the original Ruby File class.

OriginalIO

Keeps track of the original Ruby IO class.

VERSION

Public Class Methods

activate() { || ... } click to toggle source

Calls the given block with MemFs activated.

The advantage of using {#activate} against {#activate!} is that, in case an exception occurs, MemFs is deactivated.

@yield with no argument.

@example

MemFs.activate do
  Dir.mkdir '/hello_world'
  # /hello_world exists here, in memory
end
# /hello_world doesn't exist and has never been on the real FS

@example Exception in activate block.

MemFs.activate do
  raise "Some Error"
end
# Still back to the original Ruby classes

@return nothing.

# File lib/memfs.rb, line 54
def activate
  activate!
  yield
ensure
  deactivate!
end
activate!(clear: true) click to toggle source

Activates the fake file system.

@note Don't forget to call {#deactivate!} to disable the fake file system,

you may have some issues in your scripts or tests otherwise.

@example

MemFs.activate!
Dir.mkdir '/hello_world'
# /hello_world exists here, in memory
MemFs.deactivate!
# /hello_world doesn't exist and has never been on the real FS

@see deactivate! @return nothing.

# File lib/memfs.rb, line 76
def activate!(clear: true)
  Object.class_eval do
    remove_const :Dir
    remove_const :File
    remove_const :IO

    const_set :Dir, MemFs::Dir
    const_set :IO, MemFs::IO
    const_set :File, MemFs::File
  end

  MemFs::FileSystem.instance.clear! if clear
end
deactivate!() click to toggle source

Deactivates the fake file system.

@note This method should always be called when using activate!

@see activate! @return nothing.

# File lib/memfs.rb, line 97
def deactivate!
  Object.class_eval do
    remove_const :Dir
    remove_const :File
    remove_const :IO

    const_set :Dir, MemFs::OriginalDir
    const_set :IO, MemFs::OriginalIO
    const_set :File, MemFs::OriginalFile
  end
end
halt() { || ... } click to toggle source

Switches back to the original file system, calls the given block (if any), and switches back afterwards.

If a block is given, all file & dir operations (like reading dir contents or requiring files) will operate on the original fs.

@example

MemFs.halt do
  puts Dir.getwd
end

@return nothing

# File lib/memfs.rb, line 121
def halt
  deactivate!

  yield if block_given?
ensure
  activate!(clear: false)
end
touch(*paths) click to toggle source

Creates a file and all its parent directories.

@param path: The path of the file to create.

@return nothing.

# File lib/memfs.rb, line 135
def touch(*paths)
  if ::File != MemFs::File
    fail 'Always call MemFs.touch inside a MemFs active context.'
  end

  paths.each do |path|
    FileUtils.mkdir_p File.dirname(path)
    FileUtils.touch path
  end
end

Private Instance Methods

activate() { || ... } click to toggle source

Calls the given block with MemFs activated.

The advantage of using {#activate} against {#activate!} is that, in case an exception occurs, MemFs is deactivated.

@yield with no argument.

@example

MemFs.activate do
  Dir.mkdir '/hello_world'
  # /hello_world exists here, in memory
end
# /hello_world doesn't exist and has never been on the real FS

@example Exception in activate block.

MemFs.activate do
  raise "Some Error"
end
# Still back to the original Ruby classes

@return nothing.

# File lib/memfs.rb, line 54
def activate
  activate!
  yield
ensure
  deactivate!
end
activate!(clear: true) click to toggle source

Activates the fake file system.

@note Don't forget to call {#deactivate!} to disable the fake file system,

you may have some issues in your scripts or tests otherwise.

@example

MemFs.activate!
Dir.mkdir '/hello_world'
# /hello_world exists here, in memory
MemFs.deactivate!
# /hello_world doesn't exist and has never been on the real FS

@see deactivate! @return nothing.

# File lib/memfs.rb, line 76
def activate!(clear: true)
  Object.class_eval do
    remove_const :Dir
    remove_const :File
    remove_const :IO

    const_set :Dir, MemFs::Dir
    const_set :IO, MemFs::IO
    const_set :File, MemFs::File
  end

  MemFs::FileSystem.instance.clear! if clear
end
deactivate!() click to toggle source

Deactivates the fake file system.

@note This method should always be called when using activate!

@see activate! @return nothing.

# File lib/memfs.rb, line 97
def deactivate!
  Object.class_eval do
    remove_const :Dir
    remove_const :File
    remove_const :IO

    const_set :Dir, MemFs::OriginalDir
    const_set :IO, MemFs::OriginalIO
    const_set :File, MemFs::OriginalFile
  end
end
halt() { || ... } click to toggle source

Switches back to the original file system, calls the given block (if any), and switches back afterwards.

If a block is given, all file & dir operations (like reading dir contents or requiring files) will operate on the original fs.

@example

MemFs.halt do
  puts Dir.getwd
end

@return nothing

# File lib/memfs.rb, line 121
def halt
  deactivate!

  yield if block_given?
ensure
  activate!(clear: false)
end
touch(*paths) click to toggle source

Creates a file and all its parent directories.

@param path: The path of the file to create.

@return nothing.

# File lib/memfs.rb, line 135
def touch(*paths)
  if ::File != MemFs::File
    fail 'Always call MemFs.touch inside a MemFs active context.'
  end

  paths.each do |path|
    FileUtils.mkdir_p File.dirname(path)
    FileUtils.touch path
  end
end