Merge pull request #310 from sedge/issue245-ShellConstructor

Fix #245 - Forced the user to manually instantiate FileSystemShell objec...
This commit is contained in:
Alan K 2014-11-11 16:36:06 -05:00
commit 9612cbcbdc
17 changed files with 109 additions and 59 deletions

View File

@ -498,8 +498,8 @@ fs.link("/data/logs/august", "/data/logs/current", function(err) {
#### fs.exists(path, callback)<a name="exists"></a>
Test whether or not the given path exists by checking with the file system.
Then call the callback argument with either true or false.
Test whether or not the given path exists by checking with the file system.
Then call the callback argument with either true or false.
Example:
@ -596,7 +596,7 @@ Example:
fs.mknod('/dir', 'DIRECTORY', function(err) {
if(err) throw err;
// /dir is now created
// Create a file inside /dir
fs.mknod('/dir/myfile', 'FILE', function(err) {
if(err) throw err;
@ -897,7 +897,7 @@ fs.writeFile('/myfile', data, function (err) {
fs.appendFile('/myfile', more, function (err) {
if (err) throw err;
// '/myfile' would now contain [1, 2, 3, 4, 5, 6, 7, 8]
});
});
@ -1088,20 +1088,31 @@ fs.writeFile('/data/subdir/file', 'data');
### FileSystemShell<a name="FileSystemShell"></a>
Many common file system shell operations are available by using a `FileSystemShell` object.
The `FileSystemShell` is obtained from, and used in conjuction with a `FileSystem`,
The `FileSystemShell` is used in conjuction with a `FileSystem`,
and provides augmented features. Many separate `FileSystemShell` objects can exist per
`FileSystem`, but each `FileSystemShell` is bound to a single instance of a `FileSystem`
for its lifetime.
A `FileSystemShell` is created using the `FileSystem.Shell()` function:
A `FileSystemShell` is created by calling `Filer.FileSystem().shell()`:
```javascript
var fs = new Filer.FileSystem();
var sh = fs.Shell(options);
var sh2 = fs.Shell(options);
var sh = fs.shell(options);
var sh2 = fs.shell(options);
// sh and sh2 are two separate shells, each bound to fs
```
Or, the original object can be accessed through `Filer`:
```javascript
var fs = new Filer.FileSystem();
var sh = fs.shell();
Filer.Shell.prototype.newFunction = ...;
sh.newFunction();
```
The `FileSystemShell` can take an optional `options` object. The `options` object
can include `env`, which is a set of environment variables. Currently supported variables
include `TMP` (the path to the temporary directory), and `PATH` (the list of known paths) and
@ -1109,7 +1120,7 @@ others may be added in the future. You can also add your own, or update existing
```javascript
var fs = new Filer.FileSystem();
var sh = fs.Shell({
var sh = fs.shell({
env: {
TMP: '/tempdir',
PATH: '/one:/two'
@ -1135,7 +1146,7 @@ Example:
```javascript
var fs = new Filer.FileSystem();
var sh = fs.Shell();
var sh = fs.shell();
var p = sh.env.get('PATH');
// Store the current location
@ -1155,7 +1166,7 @@ examples below assume a `FileSystemShell` instance named `sh` has been created l
```javascript
var fs = new Filer.FileSystem();
var sh = fs.Shell();
var sh = fs.shell();
```
* [sh.cd(path, callback)](#cd)
@ -1360,9 +1371,9 @@ sh.tempDir(function(err, tmp) {
#### sh.mkdirp(path, callback)<a name="mkdirp"></a>
Recursively creates the directory at the provided path. If the
Recursively creates the directory at the provided path. If the
directory already exists, no error is returned. All parents must
be valid directories (not files).
be valid directories (not files).
Example:

View File

@ -87,6 +87,9 @@ function FileSystem(options, callback) {
fs.stdout = STDOUT;
fs.stderr = STDERR;
// Expose Shell constructor
this.Shell = Shell.bind(undefined, this);
// Safely expose the list of open files and file
// descriptor management functions
var openFiles = {};
@ -334,8 +337,4 @@ FileSystem.providers = providers;
};
});
FileSystem.prototype.Shell = function(options) {
return new Shell(this, options);
};
module.exports = FileSystem;

View File

@ -2,5 +2,6 @@ module.exports = {
FileSystem: require('./filesystem/interface.js'),
Buffer: require('./buffer.js'),
Path: require('./path.js'),
Errors: require('./errors.js')
Errors: require('./errors.js'),
Shell: require('./shell/shell.js')
};

View File

@ -8,7 +8,7 @@ describe('sh.cd doesn\'t seem to be working from a relative path if I am one or
it('should properly deal with relative paths missing ./ and ../', function(done) {
var fs = util.fs();
var sh = fs.Shell();
var sh = new fs.Shell();
sh.mkdirp('/home/scott', function(err) {
if(err) throw err;

View File

@ -9,7 +9,7 @@ describe('sh.ls and deep directory trees', function() {
it('should not crash when calling sh.ls() on deep directory layouts', function(done) {
var fs = util.fs();
var sh = fs.Shell();
var sh = new fs.Shell();
var path = '';
for(var i=0; i<50; i++) {
@ -29,7 +29,7 @@ describe('sh.ls and deep directory trees', function() {
it('should not crash when calling sh.ls() on wide directory layouts', function(done) {
var fs = util.fs();
var sh = fs.Shell();
var sh = new fs.Shell();
var dirName = '/dir';

View File

@ -38,6 +38,7 @@ require("./spec/times.spec");
require("./spec/time-flags.spec");
require("./spec/fs.watch.spec");
require("./spec/errors.spec");
require("./spec/fs.shell.spec");
// Filer.FileSystem.providers.*
require("./spec/providers/providers.spec");

View File

@ -85,7 +85,8 @@
}
function shell(options) {
return fs().Shell(options);
var _fs = fs();
return new _fs.Shell(options);
}
function cleanup(callback) {

View File

@ -9,4 +9,8 @@ describe("Filer", function() {
it("has FileSystem constructor", function() {
expect(typeof Filer.FileSystem).to.equal('function');
});
it("has Shell constructor", function() {
expect(typeof Filer.Shell).to.equal('function');
});
});

View File

@ -0,0 +1,33 @@
var Filer = require('../..');
var util = require('../lib/test-utils.js');
var expect = require('chai').expect;
describe("fs.shell", function() {
beforeEach(util.setup);
afterEach(util.cleanup);
it("is a function", function(done) {
var fs = util.fs();
expect(typeof fs.Shell).to.equal('function');
done();
});
it('should return a FileSystemShell instance', function(done) {
var fs = util.fs();
var sh = new fs.Shell();
expect(sh.prototype).to.deep.equal((new Filer.Shell(fs)).prototype);
done();
});
it('should reflect changes to the prototype', function(done){
var fs = util.fs();
var sh = new fs.Shell();
Filer.Shell.prototype.test = "foo";
expect(sh.test).to.equal("foo");
done();
});
});

View File

@ -13,7 +13,7 @@ describe('FileSystemShell.cat', function() {
it('should fail when files argument is absent', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
shell.cat(null, function(error, data) {
expect(error).to.exist;
@ -25,7 +25,7 @@ describe('FileSystemShell.cat', function() {
it('should return the contents of a single file', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
var contents = "file contents";
fs.writeFile('/file', contents, function(err) {
@ -41,7 +41,7 @@ describe('FileSystemShell.cat', function() {
it('should return the contents of multiple files', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
var contents = "file contents";
var contents2 = contents + '\n' + contents;
@ -62,7 +62,7 @@ describe('FileSystemShell.cat', function() {
it('should fail if any of multiple file paths is invalid', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
var contents = "file contents";
var contents2 = contents + '\n' + contents;

View File

@ -18,7 +18,7 @@ describe('FileSystemShell.cd', function() {
it('should allow changing the path to a valid dir', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
fs.mkdir('/dir', function(err) {
if(err) throw err;
@ -34,7 +34,7 @@ describe('FileSystemShell.cd', function() {
it('should fail when changing the path to an invalid dir', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
fs.mkdir('/dir', function(err) {
if(err) throw err;
@ -51,7 +51,7 @@ describe('FileSystemShell.cd', function() {
it('should fail when changing the path to a file', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
fs.writeFile('/file', 'file', function(err) {
if(err) throw err;
@ -68,7 +68,7 @@ describe('FileSystemShell.cd', function() {
it('should allow relative paths for a valid dir', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
fs.mkdir('/dir', function(err) {
if(err) throw err;
@ -84,7 +84,7 @@ describe('FileSystemShell.cd', function() {
it('should allow .. in paths for a valid dir', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
fs.mkdir('/dir', function(err) {
if(err) throw err;
@ -111,7 +111,7 @@ describe('FileSystemShell.cd', function() {
fs.symlink('/dir', '/link', function(error) {
if(error) throw error;
var shell = fs.Shell();
var shell = new fs.Shell();
shell.cd('link', function(error) {
expect(error).not.to.exist;
expect(shell.pwd()).to.equal('/link');

View File

@ -34,7 +34,7 @@ describe('FileSystemShell.env', function() {
it('should fail when dirs argument is absent', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
shell.cat(null, function(error, list) {
expect(error).to.exist;
@ -46,7 +46,7 @@ describe('FileSystemShell.env', function() {
it('should give new value for shell.pwd() when cwd changes', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
fs.mkdir('/dir', function(err) {
if(err) throw err;
@ -62,7 +62,7 @@ describe('FileSystemShell.env', function() {
it('should create/return the default tmp dir', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
expect(shell.env.get('TMP')).to.equal('/tmp');
shell.tempDir(function(err, tmp) {
@ -77,7 +77,7 @@ describe('FileSystemShell.env', function() {
it('should create/return the tmp dir specified in env.TMP', function(done) {
var fs = util.fs();
var shell = fs.Shell({
var shell = new fs.Shell({
env: {
TMP: '/tempdir'
}
@ -96,7 +96,7 @@ describe('FileSystemShell.env', function() {
it('should allow repeated calls to tempDir()', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
expect(shell.env.get('TMP')).to.equal('/tmp');
shell.tempDir(function(err, tmp) {

View File

@ -13,7 +13,7 @@ describe('FileSystemShell.exec', function() {
it('should be able to execute a command .js file from the filesystem', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
var cmdString = "fs.writeFile(args[0], args[1], callback);";
fs.writeFile('/cmd.js', cmdString, function(error) {

View File

@ -13,7 +13,7 @@ describe('FileSystemShell.ls', function() {
it('should fail when dirs argument is absent', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
shell.cat(null, function(error, list) {
expect(error).to.exist;
@ -25,7 +25,7 @@ describe('FileSystemShell.ls', function() {
it('should return the contents of a simple dir', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
var contents = "a";
var contents2 = "bb";
@ -63,7 +63,7 @@ describe('FileSystemShell.ls', function() {
it('should return the shallow contents of a dir tree', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
var contents = "a";
fs.mkdir('/dir', function(err) {
@ -119,7 +119,7 @@ describe('FileSystemShell.ls', function() {
it('should return the deep contents of a dir tree', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
var contents = "a";
fs.mkdir('/dir', function(err) {

View File

@ -13,7 +13,7 @@ describe('FileSystemShell.mkdirp', function() {
it('should fail without a path provided', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
shell.mkdirp(null, function(err) {
expect(err).to.exist;
@ -24,7 +24,7 @@ describe('FileSystemShell.mkdirp', function() {
it('should succeed if provided path is root', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
shell.mkdirp('/', function(err) {
expect(err).to.not.exist;
done();
@ -33,7 +33,7 @@ describe('FileSystemShell.mkdirp', function() {
it('should succeed if the directory exists', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
fs.mkdir('/test', function(err){
expect(err).to.not.exist;
shell.mkdirp('/test',function(err) {
@ -45,7 +45,7 @@ describe('FileSystemShell.mkdirp', function() {
it('fail if a file name is provided', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
fs.writeFile('/test.txt', 'test', function(err){
expect(err).to.not.exist;
shell.mkdirp('/test.txt', function(err) {
@ -58,7 +58,7 @@ describe('FileSystemShell.mkdirp', function() {
it('should succeed on a folder on root (\'/test\')', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
shell.mkdirp('/test', function(err) {
expect(err).to.not.exist;
fs.exists('/test', function(dir){
@ -70,7 +70,7 @@ describe('FileSystemShell.mkdirp', function() {
it('should succeed on a folder with a nonexistant parent (\'/test/test\')', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
shell.mkdirp('/test/test', function(err) {
expect(err).to.not.exist;
fs.exists('/test', function(dir1){
@ -85,7 +85,7 @@ describe('FileSystemShell.mkdirp', function() {
it('should fail on a folder with a file for its parent (\'/test.txt/test\')', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
fs.writeFile('/test.txt', 'test', function(err){
expect(err).to.not.exist;
shell.mkdirp('/test.txt/test', function(err) {

View File

@ -13,7 +13,7 @@ describe('FileSystemShell.rm', function() {
it('should fail when path argument is absent', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
shell.rm(null, function(error, list) {
expect(error).to.exist;
@ -25,7 +25,7 @@ describe('FileSystemShell.rm', function() {
it('should remove a single file', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
var contents = "a";
fs.writeFile('/file', contents, function(err) {
@ -45,7 +45,7 @@ describe('FileSystemShell.rm', function() {
it('should remove an empty dir', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
fs.mkdir('/dir', function(err) {
if(err) throw err;
@ -64,7 +64,7 @@ describe('FileSystemShell.rm', function() {
it('should fail to remove a non-empty dir', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
fs.mkdir('/dir', function(err) {
if(err) throw err;
@ -83,7 +83,7 @@ describe('FileSystemShell.rm', function() {
it('should remove a non-empty dir with option.recursive set', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
fs.mkdir('/dir', function(err) {
if(err) throw err;
@ -106,7 +106,7 @@ describe('FileSystemShell.rm', function() {
it('should work on a complex dir structure', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
var contents = "a";
fs.mkdir('/dir', function(err) {

View File

@ -20,7 +20,7 @@ describe('FileSystemShell.touch', function() {
it('should create a new file if path does not exist', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
shell.touch('/newfile', function(error) {
if(error) throw error;
@ -35,7 +35,7 @@ describe('FileSystemShell.touch', function() {
it('should skip creating a new file if options.updateOnly is true', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
shell.touch('/newfile', { updateOnly: true }, function(error) {
if(error) throw error;
@ -49,7 +49,7 @@ describe('FileSystemShell.touch', function() {
it('should update times if path does exist', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
var atime = Date.parse('1 Oct 2000 15:33:22');
var mtime = Date.parse('30 Sep 2000 06:43:54');
@ -80,7 +80,7 @@ describe('FileSystemShell.touch', function() {
it('should update times to specified date if path does exist', function(done) {
var fs = util.fs();
var shell = fs.Shell();
var shell = new fs.Shell();
var date = Date.parse('1 Oct 2001 15:33:22');
fs.open('/newfile', 'w', function (error, fd) {