diff --git a/lib/filesystem.js b/lib/filesystem.js
index 92425c4c..14c345b7 100644
--- a/lib/filesystem.js
+++ b/lib/filesystem.js
@@ -30,14 +30,31 @@ function getPathParts(filepath) {
/**
* Create a new file system.
+ * @param {Object} options Any filesystem options.
+ * @param {boolean} options.createCwd Create a directory for `process.cwd()`
+ * (defaults to `true`).
+ * @param {boolean} options.createTmp Create a directory for `os.tmpdir()`
+ * (defaults to `true`).
* @constructor
*/
-function FileSystem() {
+function FileSystem(options) {
+ options = options || {};
+
+ var createCwd = 'createCwd' in options ? options.createCwd : true;
+ var createTmp = 'createTmp' in options ? options.createTmp : true;
var root = new Directory();
// populate with default directories
- var defaults = [os.tmpdir && os.tmpdir() || os.tmpDir(), process.cwd()];
+ var defaults = [];
+ if (createCwd) {
+ defaults.push(process.cwd());
+ }
+
+ if (createTmp) {
+ defaults.push(os.tmpdir && os.tmpdir() || os.tmpDir());
+ }
+
defaults.forEach(function(dir) {
var parts = getPathParts(dir);
var directory = root;
@@ -141,10 +158,15 @@ function populate(directory, name, obj) {
/**
* Configure a mock file system.
* @param {Object} paths Config object.
+ * @param {Object} options Any filesystem options.
+ * @param {boolean} options.createCwd Create a directory for `process.cwd()`
+ * (defaults to `true`).
+ * @param {boolean} options.createTmp Create a directory for `os.tmpdir()`
+ * (defaults to `true`).
* @return {FileSystem} Mock file system.
*/
-FileSystem.create = function(paths) {
- var system = new FileSystem();
+FileSystem.create = function(paths, options) {
+ var system = new FileSystem(options);
for (var filepath in paths) {
var parts = getPathParts(filepath);
diff --git a/lib/index.js b/lib/index.js
index 32caa676..98226735 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -71,9 +71,14 @@ function setProcess(cwd, chdir) {
/**
* Swap out the fs bindings for a mock file system.
* @param {Object} config Mock file system configuration.
+ * @param {Object} options Any filesystem options.
+ * @param {boolean} options.createCwd Create a directory for `process.cwd()`
+ * (defaults to `true`).
+ * @param {boolean} options.createTmp Create a directory for `os.tmpdir()`
+ * (defaults to `true`).
*/
-var exports = module.exports = function mock(config) {
- var system = FileSystem.create(config);
+var exports = module.exports = function mock(config, options) {
+ var system = FileSystem.create(config, options);
var binding = new Binding(system);
setBinding(binding, binding.Stats);
@@ -104,10 +109,15 @@ exports.restore = function() {
/**
* Create a mock fs module based on the given file system configuration.
* @param {Object} config File system configuration.
+ * @param {Object} options Any filesystem options.
+ * @param {boolean} options.createCwd Create a directory for `process.cwd()`
+ * (defaults to `true`).
+ * @param {boolean} options.createTmp Create a directory for `os.tmpdir()`
+ * (defaults to `true`).
* @return {Object} A fs module with a mock file system.
*/
-exports.fs = function(config) {
- var system = FileSystem.create(config);
+exports.fs = function(config, options) {
+ var system = FileSystem.create(config, options);
var binding = new Binding(system);
// inject the mock binding
diff --git a/readme.md b/readme.md
index d16cb5ff..20593243 100644
--- a/readme.md
+++ b/readme.md
@@ -28,16 +28,23 @@ mock.restore();
## Docs
-### `mock(config)`
+### `mock(config, options)`
Configure the `fs` module so it is backed by an in-memory file system.
-Calling `mock` sets up a mock file system with at least two directories: `process.cwd()` and `os.tmpdir()` (or `os.tmpDir()` for older Node). When called with no arguments, just these two directories are created. When called with a `config` object, additional files, directories, and symlinks are created.
+Calling `mock` sets up a mock file system with two directories by default: `process.cwd()` and `os.tmpdir()` (or `os.tmpDir()` for older Node). When called with no arguments, just these two directories are created. When called with a `config` object, additional files, directories, and symlinks are created. To avoid creating a directory for `process.cwd()` and `os.tmpdir()`, see the [`options`](#options) below.
Property names of the `config` object are interpreted as relative paths to resources (relative from `process.cwd()`). Property values of the `config` object are interpreted as content or configuration for the generated resources.
*Note that paths should always use forward slashes (`/`) - even on Windows.*
+### `options`
+
+The second (optional) argument may include the properties below.
+
+ * `createCwd` - `boolean` Create a directory for `process.cwd()`. This is `true` by default.
+ * `createTmp` - `boolean` Create a directory for `os.tmpdir()`. This is `true` by default.
+
### Creating files
When `config` property values are a `string` or `Buffer`, a file is created with the provided content. For example, the following configuration creates a single file with string content (in addition to the two default directories).
@@ -169,9 +176,9 @@ afterEach(mock.restore);
### Creating a new `fs` module instead of modifying the original
-### `mock.fs(config)`
+### `mock.fs(config, options)`
-Calling `mock()` modifies Node's built-in `fs` module. This is useful when you want to test with a mock file system. If for some reason you want to work with the real file system and an in-memory version at the same time, you can call the `mock.fs()` function. This takes the same `config` object [described above](#mockconfig) and sets up a in-memory file system. Instead of modifying the binding for the built-in `fs` module (as is done when calling `mock(config)`), the `mock.fs(config)` function returns an object with the same interface as the `fs` module, but backed by your mock file system.
+Calling `mock()` modifies Node's built-in `fs` module. This is useful when you want to test with a mock file system. If for some reason you want to work with the real file system and an in-memory version at the same time, you can call the `mock.fs()` function. This takes the same `config` and `options` objects [described above](#mockconfigoptions) and sets up a in-memory file system. Instead of modifying the binding for the built-in `fs` module (as is done when calling `mock(config)`), the `mock.fs(config)` function returns an object with the same interface as the `fs` module, but backed by your mock file system.
## Install
diff --git a/test/lib/filesystem.spec.js b/test/lib/filesystem.spec.js
index 7bdd7855..6d028497 100644
--- a/test/lib/filesystem.spec.js
+++ b/test/lib/filesystem.spec.js
@@ -1,6 +1,7 @@
/* eslint-env mocha */
'use strict';
+var os = require('os');
var path = require('path');
var Directory = require('../../lib/directory');
@@ -18,6 +19,24 @@ describe('FileSystem', function() {
assert.instanceOf(system, FileSystem);
});
+ it('accepts a createCwd option', function() {
+ var cwd = process.cwd();
+ var withCwd = new FileSystem({createCwd: true});
+ var withoutCwd = new FileSystem({createCwd: false});
+
+ assert.instanceOf(withCwd.getItem(cwd), Directory);
+ assert.isNull(withoutCwd.getItem(cwd));
+ });
+
+ it('accepts a createTmp option', function() {
+ var tmp = os.tmpdir ? os.tmpdir() : os.tmpDir();
+ var withTmp = new FileSystem({createTmp: true});
+ var withoutTmp = new FileSystem({createTmp: false});
+
+ assert.instanceOf(withTmp.getItem(tmp), Directory);
+ assert.isNull(withoutTmp.getItem(tmp));
+ });
+
});
describe('#getItem()', function() {
@@ -160,6 +179,22 @@ describe('FileSystem.create', function() {
});
+ it('passes options to the FileSystem constructor', function() {
+
+ var cwd = process.cwd();
+ var tmp = os.tmpdir ? os.tmpdir() : os.tmpDir();
+
+ var withoutCwd = FileSystem.create({}, {createCwd: false});
+ var withoutTmp = FileSystem.create({}, {createTmp: false});
+
+ assert.isNull(withoutCwd.getItem(cwd));
+ assert.instanceOf(withoutCwd.getItem(tmp), Directory);
+
+ assert.isNull(withoutTmp.getItem(tmp));
+ assert.instanceOf(withoutTmp.getItem(cwd), Directory);
+
+ });
+
it('accepts file factory', function() {
var system = FileSystem.create({
diff --git a/test/lib/index.spec.js b/test/lib/index.spec.js
index ef010573..f196e5db 100644
--- a/test/lib/index.spec.js
+++ b/test/lib/index.spec.js
@@ -22,10 +22,6 @@ describe('The API', function() {
mock.restore();
});
- });
-
- describe('mock()', function() {
-
it('creates process.cwd() and os.tmpdir() by default', function() {
mock();
@@ -43,6 +39,30 @@ describe('The API', function() {
mock.restore();
});
+ it('passes the createCwd option to the FileSystem constructor', function() {
+ mock({}, {createCwd: false});
+
+ assert.isFalse(fs.existsSync(process.cwd()));
+
+ mock.restore();
+ });
+
+ it('passes the createTmp option to the FileSystem constructor', function() {
+ mock({}, {createTmp: false});
+
+ var tmp;
+ if (os.tmpdir) {
+ tmp = os.tmpdir();
+ } else if (os.tmpDir) {
+ tmp = os.tmpDir();
+ }
+ if (tmp) {
+ assert.isFalse(fs.existsSync(tmp));
+ }
+
+ mock.restore();
+ });
+
});
describe('mock.restore()', function() {
@@ -179,6 +199,20 @@ describe('The API', function() {
});
+ it('passes options to the FileSystem constructor', function() {
+
+ var mockFs = mock.fs({
+ '/path/to/file.txt': 'file content'
+ }, {
+ createCwd: false,
+ createTmp: false
+ });
+
+ assert.isTrue(mockFs.existsSync('/path/to/file.txt'));
+ assert.deepEqual(mockFs.readdirSync('/'), ['path']);
+
+ });
+
it('accepts an arbitrary nesting of files and directories', function() {
var mockFs = mock.fs({