diff --git a/src/shell.js b/src/shell.js index 2bdbeca..0106b9a 100644 --- a/src/shell.js +++ b/src/shell.js @@ -339,22 +339,22 @@ define(function(require) { /** * Moves the file or directory at the `source` path to the * `destination` path by relinking the source to the destination - * path. Currently there are no options, but it might be nice - * to implement an interactive mode at some point. + * path. */ - Shell.prototype.mv = function(source, destination, options, callback) { + Shell.prototype.mv = function(source, destination, callback) { var fs = this.fs; - if(typeof options === 'function') { - callback = options; - options = {}; - } - options = options || {}; + callback = callback || function() {}; if(!source) { callback(new Error("Missing source path argument")); return; } + else if(source === '/') { + callback(new Error("Root is not a valid source argument")); + return; + } + if(!destination) { callback(new Error("Missing destination path argument")); return; @@ -363,6 +363,18 @@ define(function(require) { function move(sourcepath, destpath, callback) { sourcepath = Path.resolve(this.cwd, sourcepath); destpath = Path.resolve(this.cwd, destpath); + destdir = Path.resolve(this.cwd, destpath.dirname); + + fs.stat(destdir, function(error, stats) { + if(error && error.code === 'ENOENT') { + fs.mkdirp(destdir, function(error) { + callback(error); + throw error; + return; + }); + } + }); + fs.stat(sourcepath, function(error, stats) { if(error) { callback(error); @@ -370,7 +382,7 @@ define(function(require) { } // If the source is a file, stat the destination path - if(stats.type === 'FILE') { + if(stats.isFile()) { fs.stat(destpath, function(error, stats) { // If the destination doesn't exist, relink source and we're done if(error) { @@ -379,7 +391,7 @@ define(function(require) { } // If the destination is a file, delete the destination, relink source and we're done - if(stats.type === 'FILE') { + if(stats.isFile()) { fs.unlink(destpath, callback); fs.link(sourcepath, destpath, callback); return; diff --git a/tests/spec/shell/mv.spec.js b/tests/spec/shell/mv.spec.js index 3fd8ec7..3bc0794 100644 --- a/tests/spec/shell/mv.spec.js +++ b/tests/spec/shell/mv.spec.js @@ -38,19 +38,60 @@ define(["Filer", "util"], function(Filer, util) { var fs = util.fs(); var shell = fs.Shell(); + fs.mkdir('/dir', function(error) { + expect(error).not.to.exist; + }); + shell.mv('/file', '/dir', function(error) { expect(error).to.exist; done(); }); }); - it('should move a file to a destination which does not currently exist', function(done) { + it('should fail when root is provided as source argument', function(done) { + var fs = util.fs(); + var shell = fs.Shell(); + + fs.mkdir('/dir', function(error) { + expect(error).not.to.exist; + }); + + shell.mv('/', '/dir', function(error) { + expect(error).to.exist; + done(); + }); + }); + + it('should rename a file which is moved to the same directory under a different name', function(done) { var fs = util.fs(); var shell = fs.Shell(); var contents = "a"; fs.writeFile('/file', contents, function(error) { - if(error) throw error; + expect(error).not.to.exist; + + shell.mv('/file', '/newfile', function(error) { + expect(error).not.to.exist; + fs.stat('/file', function(error, stats) { + expect(error).to.exist; + expect(stats).not.to.exist; + fs.stat('/newfile', function(error,stats) { + expect(error).not.to.exist; + expect(stats).to.exist; + done(); + }); + }); + }); + }); + }); + + it('should move a file to a directory which does not currently exist', function(done) { + var fs = util.fs(); + var shell = fs.Shell(); + var contents = "a"; + + fs.writeFile('/file', contents, function(error) { + expect(error).not.to.exist; shell.mv('/file', '/dir/newfile', function(error) { expect(error).not.to.exist; @@ -74,5 +115,11 @@ define(["Filer", "util"], function(Filer, util) { it('should move a file into a directory that has a file of the same name', function(done) { done(); }); + + it('should move a directory to a destination that does not currently exist', function(done) { + done(); + }); + + }); });