diff --git a/src/shell.js b/src/shell.js index c53699a..4b31b81 100644 --- a/src/shell.js +++ b/src/shell.js @@ -2,11 +2,12 @@ define(function(require) { var Path = require('src/path'); + var Error = require('src/error'); function Shell(fs, options) { options = options || {}; - var cwd = options.cwd || '/'; + var cwd = '/'; Object.defineProperty(this, 'fs', { get: function() { return fs; }, @@ -20,10 +21,22 @@ define(function(require) { // We include `cd` on the this vs. proto so that // we can access cwd without exposing it externally. - this.cd = function(path) { - this.cwd = Path.resolve(this.cwd, path); + this.cd = function(path, callback) { + path = Path.resolve(this.cwd, path); + // Make sure the path actually exists, and is a dir + fs.stat(path, function(err, stats) { + if(err) { + callback(new Error.ENotDirectory()); + return; + } + if(stats.type === 'DIRECTORY') { + cwd = path; + callback(); + } else { + callback(new Error.ENotDirectory()); + } + }); }; - } /** @@ -83,9 +96,7 @@ define(function(require) { path = Path.resolve(this.cwd, path); function createFile(path) { - fs.writeFile(path, '', function(error) { - callback(error); - }); + fs.writeFile(path, '', callback); } function updateTimes(path) { @@ -93,9 +104,7 @@ define(function(require) { var atime = options.date || now; var mtime = options.date || now; - fs.utimes(path, atime, mtime, function(error) { - callback(error); - }); + fs.utimes(path, atime, mtime, callback); } fs.stat(path, function(error, stats) { diff --git a/tests/spec/shell/cd.spec.js b/tests/spec/shell/cd.spec.js new file mode 100644 index 0000000..8f01264 --- /dev/null +++ b/tests/spec/shell/cd.spec.js @@ -0,0 +1,104 @@ +define(["Filer", "util"], function(Filer, util) { + + describe('FileSystemShell.cd', function() { + beforeEach(util.setup); + afterEach(util.cleanup); + + it('should be a function', function() { + var shell = util.shell(); + expect(shell.cd).to.be.a('function'); + }); + + it('should default to a cwd of /', function() { + var shell = util.shell(); + expect(shell.cwd).to.equal('/'); + }); + + it('should allow changing the path to a valid dir', function(done) { + var fs = util.fs(); + var shell = fs.Shell(); + + fs.mkdir('/dir', function(err) { + if(err) throw err; + + expect(shell.cwd).to.equal('/'); + shell.cd('/dir', function(err) { + expect(err).not.to.exist; + expect(shell.cwd).to.equal('/dir'); + done(); + }); + }); + }); + + it('should fail when changing the path to an invalid dir', function(done) { + var fs = util.fs(); + var shell = fs.Shell(); + + fs.mkdir('/dir', function(err) { + if(err) throw err; + + expect(shell.cwd).to.equal('/'); + shell.cd('/nodir', function(err) { + expect(err).to.exist; + expect(err.name).to.equal('ENotDirectory'); + expect(shell.cwd).to.equal('/'); + done(); + }); + }); + }); + + it('should fail when changing the path to a file', function(done) { + var fs = util.fs(); + var shell = fs.Shell(); + + fs.writeFile('/file', 'file', function(err) { + if(err) throw err; + + expect(shell.cwd).to.equal('/'); + shell.cd('/file', function(err) { + expect(err).to.exist; + expect(err.name).to.equal('ENotDirectory'); + expect(shell.cwd).to.equal('/'); + done(); + }); + }); + }); + + it('should allow relative paths for a valid dir', function(done) { + var fs = util.fs(); + var shell = fs.Shell(); + + fs.mkdir('/dir', function(err) { + if(err) throw err; + + expect(shell.cwd).to.equal('/'); + shell.cd('./dir', function(err) { + expect(err).not.to.exist; + expect(shell.cwd).to.equal('/dir'); + done(); + }); + }); + }); + + it('should allow .. in paths for a valid dir', function(done) { + var fs = util.fs(); + var shell = fs.Shell(); + + fs.mkdir('/dir', function(err) { + if(err) throw err; + + expect(shell.cwd).to.equal('/'); + shell.cd('./dir', function(err) { + expect(err).not.to.exist; + expect(shell.cwd).to.equal('/dir'); + shell.cd('..', function(err) { + expect(err).not.to.exist; + expect(shell.cwd).to.equal('/'); + done(); + }); + }); + }); + }); + + }); +}); diff --git a/tests/test-manifest.js b/tests/test-manifest.js index 3faf91d..2fa4f63 100644 --- a/tests/test-manifest.js +++ b/tests/test-manifest.js @@ -43,6 +43,7 @@ define([ "spec/adapters/adapters.general.spec", // Filer.FileSystemShell.* + "spec/shell/cd.spec", "spec/shell/touch.spec", "spec/shell/exec.spec",