Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #2 from tgeorgiev/rename

  • Loading branch information...
commit 81509e6e4229bebf30f050f976ec46c20bab763c 2 parents 36f3a0f + 52a56d2
@eldargab authored
Showing with 135 additions and 2 deletions.
  1. +31 −1 lib/fake-fs.js
  2. +104 −1 test/fake-fs.js
View
32 lib/fake-fs.js
@@ -133,6 +133,25 @@ Fs.prototype.unlinkSync = function (path) {
this._rem(path);
}
+Fs.prototype.renameSync = function (oldPath, newPath) {
+ if (!this.existsSync(oldPath)) throw FsError('ENOENT');
+
+ if (this.existsSync(newPath)) throw FsError('EPERM');
+
+ var newParent = this._get(dirname(newPath));
+ if (!newParent.isDirectory()) throw FsError('ENOTDIR');
+
+
+ var fileOrDir = this._get(oldPath);
+
+ var oldParent = this._get(dirname(oldPath));
+ updateTimes(oldParent);
+ this._rem(oldPath);
+
+ updateTimes(newParent);
+ this._add(resolve(newPath), fileOrDir);
+}
+
;['readdir', 'stat', 'rmdir', 'unlink'].forEach(function (meth) {
var sync = meth + 'Sync'
Fs.prototype[meth] = function (p, cb) {
@@ -192,6 +211,16 @@ Fs.prototype.mkdir = function (dir, mode, cb) {
cb && cb(err, res)
}
+Fs.prototype.rename = function (oldPath, newPath, cb) {
+ var res, err
+ try {
+ res = this.renameSync(oldPath, newPath);
+ } catch (e) {
+ err = e
+ }
+ cb && cb(err, res)
+}
+
Fs.prototype.patch = function () {
this._orig = {}
var fs = require('fs')
@@ -216,7 +245,8 @@ var methods = [
'readFile',
'writeFile',
'rmdir',
- 'unlink'
+ 'unlink',
+ 'rename'
].reduce(function (res, meth) {
res.push(meth)
res.push(meth + 'Sync')
View
105 test/fake-fs.js
@@ -255,7 +255,7 @@ describe('Fake FS', function () {
it('Should update dir times on directory removal', function (done) {
fs.dir('a/b')
-
+
testTimesUpdated('a', function () {
fs.rmdir('a/b')
}, done)
@@ -288,6 +288,109 @@ describe('Fake FS', function () {
})
})
+ describe('.rename()', function () {
+ it('Should rename an existing file', function () {
+ fs.file('a/file.txt')
+
+ fs.renameSync('a/file.txt', 'a/file-new.txt')
+
+ fs.existsSync('a/file.txt').should.be.false
+ fs.existsSync('a/file-new.txt').should.be.true
+ })
+
+ it('Should rename (move) an existing file', function () {
+ fs.file('a/file.txt')
+ fs.dir('c/d')
+
+ fs.renameSync('a/file.txt', 'c/d/file-new.txt')
+
+ fs.existsSync('a/file.txt').should.be.false
+ fs.existsSync('c/d/file-new.txt').should.be.true
+ })
+
+ it('Should rename an existing directory', function () {
+ fs.dir('a/b')
+
+ fs.renameSync('a/b', 'a/b-new')
+
+ fs.existsSync('a/b').should.be.false
+ fs.existsSync('a/b-new').should.be.true
+ })
+
+ it('Should rename (move) an existing directory', function () {
+ fs.dir('a/b')
+ fs.dir('c/d')
+
+ fs.renameSync('a/b', 'c/d/b-new')
+
+ fs.existsSync('a/b').should.be.false
+ fs.existsSync('c/d/b-new').should.be.true
+ })
+
+ it('Should throw EPERM when new path points to an existing directory', function () {
+ fs.dir('a/b')
+ fs.dir('c/d')
+
+ fs.rename('a/b', 'c/d', cb)
+
+ cb.error('EPERM')
+ })
+
+ /*
+ One could argue about this, since with node.js fs, when renaming a file or a directory
+ you can overwrite an existing file (you CANNOT overwrite an existing directory).
+ */
+ it('Should throw EPERM when new path points to existing file', function () {
+ fs.file('a/file1.txt')
+ fs.file('c/file2.txt')
+
+ fs.rename('a/file1.txt', 'c/file2.txt', cb)
+
+ cb.error('EPERM')
+ })
+
+ it('Should throw ENOENT when new (directory) path points to a non-existent parent', function () {
+ fs.dir('a/b')
+
+ fs.rename('a/b', 'c/d', cb)
+
+ cb.error('ENOENT')
+ })
+
+ it('Should throw ENOTDIR when new path points to a parent that is not a directory', function () {
+ fs.dir('a/b')
+ fs.file('c');
+
+ fs.rename('a/b', 'c/d', cb)
+
+ cb.error('ENOTDIR')
+ })
+
+ it('Should update dir times on rename (move)', function (done) {
+ fs.dir('a/b')
+ fs.dir('c/d')
+
+ var oldPathBefore = snapshotTimes('a')
+ var newPathBefore = snapshotTimes('c/d')
+
+ setTimeout(function () {
+ fs.renameSync('a/b', 'c/d/b-new')
+ var oldPathNow = snapshotTimes('a')
+ var newPathNow = snapshotTimes('c/d')
+
+ var testTimesInner = function (before, now) {
+ now.mtime.should.be.above(before.mtime)
+ now.mtime.should.be.equal(now.ctime)
+ }
+
+ testTimesInner(oldPathBefore, oldPathNow)
+ testTimesInner(newPathBefore, newPathNow)
+
+ done()
+ })
+ })
+ });
+
describe('.readFile()', function () {
it('Should read file contents', function () {
var content = new Buffer([1, 2, 3])
Please sign in to comment.
Something went wrong with that request. Please try again.