Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fake-fs pull request #1

Merged
merged 7 commits into from
Jan 28, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 47 additions & 4 deletions lib/fake-fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ var PATH = require('path')
var normalize = PATH.normalize
var join = PATH.join
var dirname = PATH.dirname
var basename = PATH.basename

function resolve (p) {
return PATH.resolve(p).replace('\\', '/') // Windows support
return PATH.resolve(p).replace(/\\/g, '/') // Windows support
}

function FsError (code) {
Expand All @@ -31,6 +32,11 @@ Fs.prototype.file = function (path, content, encoding) {

Fs.prototype._add = function (path, item) {
var segs = path.split('/'); segs.shift()

if (segs[segs.length - 1] === "") {
segs.pop();
}

var dir = this.root
for (var i = 0; i < segs.length - 1; i++) {
dir = dir.childs[segs[i]] || (dir.childs[segs[i]] = new stat.Dir)
Expand All @@ -44,6 +50,11 @@ Fs.prototype._add = function (path, item) {

Fs.prototype._itemAt = function (path) {
var segs = resolve(path).split('/'); segs.shift()

if (segs[segs.length - 1] === "") {
segs.pop();
}

var item = this.root
for (var i = 0; i < segs.length; i++) {
item = item.childs && item.childs[segs[i]]
Expand All @@ -58,6 +69,14 @@ Fs.prototype._get = function (path) {
return item
}

Fs.prototype._rem = function (path) {
var parent = this._get(dirname(path));
if (!parent.isDirectory()) throw FsError('ENOTDIR');

var itemName = basename(path);
delete parent.childs[itemName];
}


Fs.prototype.statSync = function (path) {
return this._get(path)
Expand Down Expand Up @@ -96,7 +115,29 @@ Fs.prototype.mkdirSync = function (dir, mode) {
this.dir(dir)
}

;['readdir', 'stat'].forEach(function (meth) {
Fs.prototype.rmdirSync = function (path) {
if (!this.existsSync(path)) throw FsError('ENOENT');

var item = this._get(path);
if (!item.isDirectory()) throw FsError('ENOTDIR');

var parent = this._get(dirname(path));
updateTimes(parent);
this._rem(path);
}

Fs.prototype.unlinkSync = function (path) {
if (!this.existsSync(path)) throw FsError('ENOENT');

var item = this._get(path);
if (item.isDirectory()) throw FsError('EISDIR');

var parent = this._get(dirname(path));
updateTimes(parent);
this._rem(path);
}

;['readdir', 'stat', 'rmdir', 'unlink'].forEach(function (meth) {
var sync = meth + 'Sync'
Fs.prototype[meth] = function (p, cb) {
var res, err
Expand Down Expand Up @@ -177,7 +218,9 @@ var methods = [
'readdir',
'mkdir',
'readFile',
'writeFile'
'writeFile',
'rmdir',
'unlink'
].reduce(function (res, meth) {
res.push(meth)
res.push(meth + 'Sync')
Expand Down Expand Up @@ -214,4 +257,4 @@ function updateTimes (stat) {
var now = new Date
stat.mtime = now
stat.ctime = now
}
}
70 changes: 70 additions & 0 deletions test/fake-fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,13 @@ describe('Fake FS', function () {
done()
})
})

it('Should return true for root path', function (done) {
fs.exists('/', function (exists) {
exists.should.be.true
done()
})
})
})

describe('.mkdir()', function () {
Expand Down Expand Up @@ -218,6 +225,69 @@ describe('Fake FS', function () {
})
})

describe('.rmdir()', function () {
it('Should remove an existing direcory', function () {
fs.dir('a/b')
fs.rmdirSync('a/b')
fs.existsSync('a/b').should.be.false
})

it('Should remove an existing direcory, its subdirectories and files', function () {
fs.dir('a/b/c')
fs.file('a/b/file.txt')

fs.rmdirSync('a/b')

fs.existsSync('a/b/c').should.be.false
fs.existsSync('a/b/file.txt').should.be.false
fs.existsSync('a/b').should.be.false

fs.existsSync('a').should.be.true
})

it('Should throw an ENOTDIR error on file', function () {
fs.file('a/file.txt')

fs.rmdir('a/file.txt', cb)

cb.error('ENOTDIR')
})

it('Should update dir times on directory removal', function (done) {
fs.dir('a/b')

testTimesUpdated('a', function () {
fs.rmdir('a/b')
}, done)
})
})

describe('.unlink()', function () {
it('Should remove an existing file', function () {
fs.file('a/file.txt')

fs.unlinkSync('a/file.txt')

fs.existsSync('a/file.txt').should.be.false
})

it('Should throw an EISDIR error on directory', function () {
fs.dir('a/b')

fs.unlink('a/b', cb)

cb.error('EISDIR')
})

it('Should update dir times on file removal', function (done) {
fs.file('a/file.txt')

testTimesUpdated('a', function () {
fs.unlink('a/file.txt')
}, done)
})
})

describe('.readFile()', function () {
it('Should read file contents', function () {
var content = new Buffer([1, 2, 3])
Expand Down