Add support for shell.env, PWD, TMP, and tempDir, with tests

This commit is contained in:
David Humphrey (:humph) david.humphrey@senecacollege.ca 2014-02-19 12:15:02 -05:00
parent 83c55308dc
commit 21f5d15f51
4 changed files with 167 additions and 2 deletions

View File

@ -8,18 +8,45 @@ define(function(require) {
function Shell(fs, options) { function Shell(fs, options) {
options = options || {}; options = options || {};
var env = options.env || {};
env.TMP = env.TMP || '/tmp';
env.PATH = env.PATH || '';
var cwd = '/'; var cwd = '/';
/**
* The bound FileSystem (cannot be changed)
*/
Object.defineProperty(this, 'fs', { Object.defineProperty(this, 'fs', {
get: function() { return fs; }, get: function() { return fs; },
enumerable: true enumerable: true
}); });
/**
* The current working directory (changed with `cd()`)
*/
Object.defineProperty(this, 'cwd', { Object.defineProperty(this, 'cwd', {
get: function() { return cwd; }, get: function() { return cwd; },
enumerable: true 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 include `cd` on the this vs. proto so that
// we can access cwd without exposing it externally. // we can access cwd without exposing it externally.
this.cd = function(path, callback) { this.cd = function(path, callback) {
@ -242,6 +269,13 @@ define(function(require) {
list(dir, callback); 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) { Shell.prototype.rm = function(path, options, callback) {
var fs = this.fs; var fs = this.fs;
if(typeof options === 'function') { if(typeof options === 'function') {
@ -308,6 +342,23 @@ define(function(require) {
remove(path, callback); 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; return Shell;
}); });

View File

@ -68,8 +68,8 @@ function(Filer, IndexedDBTestProvider, WebSQLTestProvider, MemoryTestProvider) {
return _provider; return _provider;
} }
function shell() { function shell(options) {
return fs().Shell(); return fs().Shell(options);
} }
function cleanup(callback) { function cleanup(callback) {

View File

@ -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();
});
});
});
});
});

View File

@ -49,6 +49,7 @@ define([
"spec/shell/cat.spec", "spec/shell/cat.spec",
"spec/shell/ls.spec", "spec/shell/ls.spec",
"spec/shell/rm.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) // Ported node.js tests (filenames match names in https://github.com/joyent/node/tree/master/test)
"spec/node-js/simple/test-fs-mkdir", "spec/node-js/simple/test-fs-mkdir",