From 21f5d15f518cba2a785028004452cc6ed6d0a7dd Mon Sep 17 00:00:00 2001 From: "David Humphrey (:humph) david.humphrey@senecacollege.ca" Date: Wed, 19 Feb 2014 12:15:02 -0500 Subject: [PATCH] Add support for shell.env, PWD, TMP, and tempDir, with tests --- src/shell.js | 51 ++++++++++++++++ tests/lib/test-utils.js | 4 +- tests/spec/shell/env.spec.js | 113 +++++++++++++++++++++++++++++++++++ tests/test-manifest.js | 1 + 4 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 tests/spec/shell/env.spec.js diff --git a/src/shell.js b/src/shell.js index d70058e..b29a2f9 100644 --- a/src/shell.js +++ b/src/shell.js @@ -8,18 +8,45 @@ define(function(require) { function Shell(fs, options) { options = options || {}; + var env = options.env || {}; + env.TMP = env.TMP || '/tmp'; + env.PATH = env.PATH || ''; + var cwd = '/'; + /** + * The bound FileSystem (cannot be changed) + */ Object.defineProperty(this, 'fs', { get: function() { return fs; }, enumerable: true }); + /** + * The current working directory (changed with `cd()`) + */ Object.defineProperty(this, 'cwd', { get: function() { return cwd; }, enumerable: true }); + /** + * Support bash's $PWD on the env + */ + Object.defineProperty(env, 'PWD', { + get: function() { return cwd; }, + enumerable: true + }); + + /** + * The shell's environment (e.g., for things like + * path, tmp, and other env vars) + */ + Object.defineProperty(this, 'env', { + get: function() { return env; }, + enumerable: true + }); + // We include `cd` on the this vs. proto so that // we can access cwd without exposing it externally. this.cd = function(path, callback) { @@ -242,6 +269,13 @@ define(function(require) { list(dir, callback); }; + /** + * Removes the file or directory at `path`. If `path` is a file + * it will be removed. If `path` is a directory, it will be + * removed if it is empty, otherwise the callback will receive + * an error. In order to remove non-empty directories, use the + * `recursive=true` option. + */ Shell.prototype.rm = function(path, options, callback) { var fs = this.fs; if(typeof options === 'function') { @@ -308,6 +342,23 @@ define(function(require) { remove(path, callback); }; + /** + * Gets the path to the temporary directory, creating it if not + * present. The directory used is the one specified in + * env.TMP. The callback receives (error, tempDirName). + */ + Shell.prototype.tempDir = function(callback) { + var fs = this.fs; + var tmp = this.env.TMP; + callback = callback || function(){}; + + // Try and create it, and it will either work or fail + // but either way it's now there. + fs.mkdir(tmp, function(err) { + callback(null, tmp); + }); + }; + return Shell; }); diff --git a/tests/lib/test-utils.js b/tests/lib/test-utils.js index bca7658..94e1940 100644 --- a/tests/lib/test-utils.js +++ b/tests/lib/test-utils.js @@ -68,8 +68,8 @@ function(Filer, IndexedDBTestProvider, WebSQLTestProvider, MemoryTestProvider) { return _provider; } - function shell() { - return fs().Shell(); + function shell(options) { + return fs().Shell(options); } function cleanup(callback) { diff --git a/tests/spec/shell/env.spec.js b/tests/spec/shell/env.spec.js new file mode 100644 index 0000000..af0c321 --- /dev/null +++ b/tests/spec/shell/env.spec.js @@ -0,0 +1,113 @@ +define(["Filer", "util"], function(Filer, util) { + + describe('FileSystemShell.env', function() { + beforeEach(util.setup); + afterEach(util.cleanup); + + it('should get default env options', function() { + var shell = util.shell(); + expect(shell.env).to.exist; + expect(shell.env.TMP).to.equal('/tmp'); + expect(shell.env.PATH).to.equal(''); + expect(shell.env.PWD).to.equal('/'); + }); + + it('should be able to specify env options', function() { + var options = { + env: { + TMP: '/tempdir', + PATH: '/dir' + } + }; + var shell = util.shell(options); + expect(shell.env).to.exist; + expect(shell.env.TMP).to.equal('/tempdir'); + expect(shell.env.PATH).to.equal('/dir'); + expect(shell.env.PWD).to.equal('/'); + }); + + it('should fail when dirs argument is absent', function(done) { + var fs = util.fs(); + var shell = fs.Shell(); + + shell.cat(null, function(error, list) { + expect(error).to.exist; + expect(list).not.to.exist; + done(); + }); + }); + + it('should update the value of env.PWD when cwd changes', function(done) { + var fs = util.fs(); + var shell = fs.Shell(); + + fs.mkdir('/dir', function(err) { + if(err) throw err; + + expect(shell.cwd).to.equal('/'); + expect(shell.env.PWD).to.equal('/'); + + shell.cd('/dir', function(err) { + expect(err).not.to.exist; + expect(shell.cwd).to.equal('/dir'); + expect(shell.env.PWD).to.equal('/dir'); + done(); + }); + }); + }); + + it('should create/return the default tmp dir', function(done) { + var fs = util.fs(); + var shell = fs.Shell(); + + expect(shell.env.TMP).to.equal('/tmp'); + shell.tempDir(function(err, tmp) { + expect(err).not.to.exist; + shell.cd(tmp, function(err) { + expect(err).not.to.exist; + expect(shell.cwd).to.equal('/tmp'); + expect(shell.env.PWD).to.equal('/tmp'); + done(); + }); + }); + }); + + it('should create/return the tmp dir specified in env.TMP', function(done) { + var fs = util.fs(); + var shell = fs.Shell({ + env: { + TMP: '/tempdir' + } + }); + + expect(shell.env.TMP).to.equal('/tempdir'); + shell.tempDir(function(err, tmp) { + expect(err).not.to.exist; + shell.cd(tmp, function(err) { + expect(err).not.to.exist; + expect(shell.cwd).to.equal('/tempdir'); + expect(shell.env.PWD).to.equal('/tempdir'); + done(); + }); + }); + }); + + it('should allow repeated calls to tempDir()', function(done) { + var fs = util.fs(); + var shell = fs.Shell(); + + expect(shell.env.TMP).to.equal('/tmp'); + shell.tempDir(function(err, tmp) { + expect(err).not.to.exist; + expect(tmp).to.equal('/tmp'); + + shell.tempDir(function(err, tmp) { + expect(err).not.to.exist; + expect(tmp).to.equal('/tmp'); + done(); + }); + }); + }); + + }); +}); diff --git a/tests/test-manifest.js b/tests/test-manifest.js index 55cd181..3b903a6 100644 --- a/tests/test-manifest.js +++ b/tests/test-manifest.js @@ -49,6 +49,7 @@ define([ "spec/shell/cat.spec", "spec/shell/ls.spec", "spec/shell/rm.spec", + "spec/shell/env.spec", // Ported node.js tests (filenames match names in https://github.com/joyent/node/tree/master/test) "spec/node-js/simple/test-fs-mkdir",