mock-fs-require-fix
Version:
Fork of the tschaub/mock-fs project.
1,474 lines (1,267 loc) • 52 kB
JavaScript
'use strict';
var path = require('path');
var Binding = require('../../lib/binding');
var Directory = require('../../lib/directory');
var SymbolicLink = require('../../lib/symlink');
var File = require('../../lib/file');
var FileSystem = require('../../lib/filesystem');
var helper = require('../helper');
var constants = require('constants');
var assert = helper.assert;
var flags = helper.flags;
describe('Binding', function() {
var system;
beforeEach(function() {
system = FileSystem.create({
'mock-dir': {
'one.txt': 'one content',
'two.txt': FileSystem.file({
content: 'two content',
mode: parseInt('0644', 8),
atime: new Date(1),
ctime: new Date(2),
mtime: new Date(3),
birthtime: new Date(4)
}),
'one-link.txt': FileSystem.symlink({path: './one.txt'}),
'one-link2.txt': FileSystem.symlink({path: './one-link.txt'}),
'three.bin': new Buffer([1, 2, 3]),
'empty': {},
'non-empty': {
'a.txt': FileSystem.file({
content: 'a content',
mode: parseInt('0644', 8),
atime: new Date(1),
ctime: new Date(2),
mtime: new Date(3),
birthtime: new Date(4)
}),
'b.txt': 'b content'
},
'dir-link': FileSystem.symlink({path: './non-empty'}),
'dir-link2': FileSystem.symlink({path: './dir-link'}),
'dead-link': FileSystem.symlink({path: './non-a-real-file'})
}
});
});
describe('constructor', function() {
it('creates a new instance', function() {
var binding = new Binding(system);
assert.instanceOf(binding, Binding);
});
});
describe('#getSystem()', function() {
var binding = new Binding(system);
assert.equal(binding.getSystem(), system);
});
describe('#setSystem()', function() {
var firstSystem = new FileSystem();
var binding = new Binding(firstSystem);
assert.equal(binding.getSystem(), firstSystem);
binding.setSystem(system);
assert.equal(binding.getSystem(), system);
});
describe('#Stats', function() {
it('is a stats constructor', function() {
var binding = new Binding(system);
assert.isFunction(binding.Stats);
});
});
describe('#stat()', function() {
it('calls callback with a Stats instance', function(done) {
var binding = new Binding(system);
binding.stat(path.join('mock-dir', 'one.txt'), function(err, stats) {
if (err) {
return done(err);
}
assert.instanceOf(stats, binding.Stats);
done();
});
});
it('returns a Stats instance when called synchronously', function() {
var binding = new Binding(system);
var stats = binding.stat(path.join('mock-dir', 'one.txt'));
assert.instanceOf(stats, binding.Stats);
});
it('identifies files (async)', function(done) {
var binding = new Binding(system);
binding.stat(path.join('mock-dir', 'one.txt'), function(err, stats) {
if (err) {
return done(err);
}
assert.equal(stats.mode & constants.S_IFMT, constants.S_IFREG);
done();
});
});
it('identifies files (sync)', function() {
var binding = new Binding(system);
var stats = binding.stat(path.join('mock-dir', 'one.txt'));
assert.equal(stats.mode & constants.S_IFMT, constants.S_IFREG);
});
it('identifies directories (async)', function(done) {
var binding = new Binding(system);
binding.stat('mock-dir', function(err, stats) {
if (err) {
return done(err);
}
assert.equal(stats.mode & constants.S_IFMT, constants.S_IFDIR);
done();
});
});
it('identifies directories (sync)', function() {
var binding = new Binding(system);
var stats = binding.stat('mock-dir');
assert.equal(stats.mode & constants.S_IFMT, constants.S_IFDIR);
});
it('includes atime, ctime, mtime and birthtime', function(done) {
var binding = new Binding(system);
binding.stat(path.join('mock-dir', 'two.txt'), function(err, stats) {
if (err) {
return done(err);
}
assert.equal(stats.atime.getTime(), new Date(1).getTime());
assert.equal(stats.ctime.getTime(), new Date(2).getTime());
assert.equal(stats.mtime.getTime(), new Date(3).getTime());
assert.equal(stats.birthtime.getTime(), new Date(4).getTime());
done();
});
});
it('includes mode with file permissions (default)', function(done) {
var binding = new Binding(system);
binding.stat(path.join('mock-dir', 'one.txt'), function(err, stats) {
if (err) {
return done(err);
}
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0666', 8));
done();
});
});
it('includes mode with file permissions (custom)', function(done) {
var binding = new Binding(system);
binding.stat(path.join('mock-dir', 'two.txt'), function(err, stats) {
if (err) {
return done(err);
}
assert.equal(stats.mode & parseInt('0777', 8), parseInt('0644', 8));
done();
});
});
it('includes size in bytes (async)', function(done) {
var binding = new Binding(system);
binding.stat(path.join('mock-dir', 'two.txt'), function(err, stats) {
if (err) {
return done(err);
}
assert.equal(stats.size, 11);
done();
});
});
it('includes size in bytes (sync)', function() {
var binding = new Binding(system);
var stats = binding.stat(path.join('mock-dir', 'three.bin'));
assert.equal(stats.size, 3);
});
it('includes non-zero size for directories', function() {
var binding = new Binding(system);
var stats = binding.stat('mock-dir');
assert.isNumber(stats.size);
assert.isTrue(stats.size > 0);
});
it('includes uid for files', function() {
var binding = new Binding(system);
var stats = binding.stat(path.join('mock-dir', 'two.txt'));
if (process.getuid) {
assert.equal(stats.uid, process.getuid());
}
});
it('includes uid for directories', function() {
var binding = new Binding(system);
var stats = binding.stat(path.join('mock-dir', 'empty'));
if (process.getuid) {
assert.equal(stats.uid, process.getuid());
}
});
it('includes gid for files', function() {
var binding = new Binding(system);
var stats = binding.stat(path.join('mock-dir', 'two.txt'));
if (process.getgid) {
assert.equal(stats.gid, process.getgid());
}
});
it('includes gid for directories', function() {
var binding = new Binding(system);
var stats = binding.stat(path.join('mock-dir', 'empty'));
if (process.getgid) {
assert.equal(stats.gid, process.getgid());
}
});
it('retrieves stats of files relative to symbolic linked directories', function() {
var binding = new Binding(system);
var stats = binding.stat(path.join('mock-dir', 'dir-link', 'a.txt'));
assert.equal(stats.mode & constants.S_IFMT, constants.S_IFREG);
assert.equal(stats.mode & 0x1FF, parseInt('0644', 8));
if (process.getuid) {
assert.equal(stats.uid, process.getuid());
}
if (process.getgid) {
assert.equal(stats.gid, process.getgid());
}
});
});
describe('#realpath()', function() {
function assertEqualPaths(actual, expected) {
if (path._makeLong(expected) === expected) {
// not on Windows
assert.equal(actual, expected);
} else {
assert.equal(actual.toLowerCase(), path._makeLong(expected).toLowerCase());
}
}
it('returns the real path for a regular file', function(done) {
var binding = new Binding(system);
binding.realpath('mock-dir/one.txt', 'utf-8', function(err, realPath) {
if (err) {
return done(err);
}
assertEqualPaths(realPath, path.resolve('mock-dir/one.txt'));
done();
});
});
it('returns the real path for a directory', function(done) {
var binding = new Binding(system);
binding.realpath('mock-dir/empty', 'utf-8', function(err, realPath) {
if (err) {
return done(err);
}
assertEqualPaths(realPath, path.resolve('mock-dir/empty'));
done();
});
});
it('returns the real path for a symlinked file', function(done) {
var binding = new Binding(system);
binding.realpath('mock-dir/one-link.txt', 'utf-8', function(err, realPath) {
if (err) {
return done(err);
}
assertEqualPaths(realPath, path.resolve('mock-dir/one.txt'));
done();
});
});
it('returns the real path for a deeply symlinked file', function(done) {
var binding = new Binding(system);
binding.realpath('mock-dir/one-link2.txt', 'utf-8', function(err, realPath) {
if (err) {
return done(err);
}
assertEqualPaths(realPath, path.resolve('mock-dir/one.txt'));
done();
});
});
it('returns the real path for a symlinked directory', function(done) {
var binding = new Binding(system);
binding.realpath('mock-dir/dir-link', 'utf-8', function(err, realPath) {
if (err) {
return done(err);
}
assertEqualPaths(realPath, path.resolve('mock-dir/non-empty'));
done();
});
});
it('returns the real path for a deeply symlinked directory', function(done) {
var binding = new Binding(system);
binding.realpath('mock-dir/dir-link2', 'utf-8', function(err, realPath) {
if (err) {
return done(err);
}
assertEqualPaths(realPath, path.resolve('mock-dir/non-empty'));
done();
});
});
it('returns the real path for a file in a symlinked directory', function(done) {
var binding = new Binding(system);
binding.realpath('mock-dir/dir-link/b.txt', 'utf-8', function(err, realPath) {
if (err) {
return done(err);
}
assertEqualPaths(realPath, path.resolve('mock-dir/non-empty/b.txt'));
done();
});
});
it('accepts a buffer', function(done) {
var binding = new Binding(system);
binding.realpath(new Buffer('mock-dir/one.txt'), 'utf-8', function(err, realPath) {
if (err) {
return done(err);
}
assertEqualPaths(realPath, path.resolve('mock-dir/one.txt'));
done();
});
});
it('can return a buffer', function(done) {
var binding = new Binding(system);
binding.realpath('mock-dir/one.txt', 'buffer', function(err, realPath) {
if (err) {
return done(err);
}
assert.equal(Buffer.isBuffer(realPath), true);
assertEqualPaths(realPath.toString(), path.resolve('mock-dir/one.txt'));
done();
});
});
it('throws ENOENT for a non-existent file', function(done) {
var binding = new Binding(system);
binding.realpath('mock-dir/bogus-path', 'utf-8', function(err, realPath) {
if (!err || realPath) {
return done(new Error('Expected ENOENT'));
}
assert.equal(err.code, 'ENOENT');
done();
});
});
it('throws ENOTDIR for a file treated like a directory', function(done) {
var binding = new Binding(system);
binding.realpath('mock-dir/one.txt/foo', 'utf-8', function(err, realPath) {
if (!err || realPath) {
return done(new Error('Expected ENOTDIR'));
}
assert.equal(err.code, 'ENOTDIR');
done();
});
});
});
describe('#fstat()', function() {
it('calls callback with a Stats instance', function(done) {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'one.txt'), flags('r'));
binding.fstat(fd, function(err, stats) {
if (err) {
return done(err);
}
assert.instanceOf(stats, binding.Stats);
done();
});
});
it('returns a Stats instance when called synchronously', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'one.txt'), flags('r'));
var stats = binding.fstat(fd);
assert.instanceOf(stats, binding.Stats);
});
it('identifies files (async)', function(done) {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'one.txt'), flags('r'));
binding.fstat(fd, function(err, stats) {
if (err) {
return done(err);
}
assert.equal(stats.mode & constants.S_IFMT, constants.S_IFREG);
done();
});
});
it('identifies directories (async)', function(done) {
var binding = new Binding(system);
var fd = binding.open('mock-dir', flags('r'));
binding.fstat(fd, function(err, stats) {
if (err) {
return done(err);
}
assert.equal(stats.mode & constants.S_IFMT, constants.S_IFDIR);
done();
});
});
it('includes size in bytes (async)', function(done) {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'two.txt'), flags('r'));
binding.fstat(fd, function(err, stats) {
if (err) {
return done(err);
}
assert.equal(stats.size, 11);
done();
});
});
it('includes size in bytes (sync)', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'three.bin'), flags('r'));
var stats = binding.fstat(fd);
assert.equal(stats.size, 3);
});
it('includes non-zero size for directories', function() {
var binding = new Binding(system);
var fd = binding.open('mock-dir', flags('r'));
var stats = binding.fstat(fd);
assert.isNumber(stats.size);
assert.isTrue(stats.size > 0);
});
});
describe('#readdir()', function() {
it('calls callback with file list', function(done) {
var binding = new Binding(system);
binding.readdir('mock-dir', function(err, items) {
assert.isNull(err);
assert.isArray(items);
assert.deepEqual(items.sort(),
['dead-link', 'dir-link', 'dir-link2', 'empty', 'non-empty',
'one-link.txt', 'one-link2.txt', 'one.txt', 'three.bin',
'two.txt']);
done();
});
});
it('accepts "buffer" encoding', function(done) {
var binding = new Binding(system);
binding.readdir('mock-dir', 'buffer', function(err, items) {
assert.isNull(err);
assert.isArray(items);
items.forEach(function(item) {
assert.equal(Buffer.isBuffer(item), true);
});
var strings = items.map(function(item) {
return item.toString();
});
assert.deepEqual(strings.sort(),
['dead-link', 'dir-link', 'dir-link2', 'empty', 'non-empty',
'one-link.txt', 'one-link2.txt', 'one.txt', 'three.bin',
'two.txt']);
done();
});
});
it('returns a file list (sync)', function() {
var binding = new Binding(system);
var items = binding.readdir('mock-dir');
assert.isArray(items);
assert.deepEqual(items.sort(),
['dead-link', 'dir-link', 'dir-link2', 'empty', 'non-empty',
'one-link.txt', 'one-link2.txt', 'one.txt', 'three.bin',
'two.txt']);
});
it('calls callback with file list for symbolic linked dir', function(done) {
var binding = new Binding(system);
binding.readdir(path.join('mock-dir', 'dir-link'), function(err, items) {
assert.isNull(err);
assert.isArray(items);
assert.deepEqual(items.sort(), ['a.txt', 'b.txt']);
done();
});
});
it('calls callback with file list for link to symbolic linked dir', function(done) {
var binding = new Binding(system);
binding.readdir(path.join('mock-dir', 'dir-link2'), function(err, items) {
assert.isNull(err);
assert.isArray(items);
assert.deepEqual(items.sort(), ['a.txt', 'b.txt']);
done();
});
});
it('calls callback with file list for symbolic linked dir (sync)', function() {
var binding = new Binding(system);
var items = binding.readdir(path.join('mock-dir', 'dir-link'));
assert.isArray(items);
assert.deepEqual(items.sort(), ['a.txt', 'b.txt']);
});
it('calls callback with error for bogus dir', function(done) {
var binding = new Binding(system);
binding.readdir('bogus', function(err, items) {
assert.instanceOf(err, Error);
assert.isUndefined(items);
done();
});
});
it('calls callback with error for file path', function(done) {
var binding = new Binding(system);
binding.readdir(path.join('mock-dir', 'one.txt'), function(err, items) {
assert.instanceOf(err, Error);
assert.isUndefined(items);
done();
});
});
it('calls callback with error for dead symbolic link', function(done) {
var binding = new Binding(system);
binding.readdir(path.join('mock-dir', 'dead-link'), function(err, items) {
assert.instanceOf(err, Error);
assert.isUndefined(items);
done();
});
});
it('calls callback with error for symbolic link to file', function(done) {
var binding = new Binding(system);
binding.readdir(path.join('mock-dir', 'one-link.txt'), function(err, items) {
assert.instanceOf(err, Error);
assert.isUndefined(items);
done();
});
});
it('calls callback with error for link to symbolic link to file', function(done) {
var binding = new Binding(system);
binding.readdir(path.join('mock-dir', 'one-link2.txt'), function(err, items) {
assert.instanceOf(err, Error);
assert.isUndefined(items);
done();
});
});
});
describe('#open()', function() {
it('creates a file descriptor for reading (r)', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'one.txt'), flags('r'));
assert.isNumber(fd);
});
it('generates error if file does not exist (r)', function() {
var binding = new Binding(system);
assert.throws(function() {
binding.open('bogus', flags('r'));
});
});
it('creates a file descriptor for reading and writing (r+)', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'one.txt'), flags('r+'));
assert.isNumber(fd);
});
it('does not truncate (r+)', function() {
var binding = new Binding(system);
binding.open(path.join('mock-dir', 'two.txt'), flags('r+'));
var file = system.getItem(path.join('mock-dir', 'two.txt'));
assert.instanceOf(file, File);
assert.equal(String(file.getContent()), 'two content');
});
it('generates error if file does not exist (r+)', function() {
var binding = new Binding(system);
assert.throws(function() {
binding.open('bogus', flags('r+'));
});
});
it('creates a file descriptor for reading (rs)', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'two.txt'), flags('rs'));
assert.isNumber(fd);
});
it('generates error if file does not exist (rs)', function() {
var binding = new Binding(system);
assert.throws(function() {
binding.open('bogus', flags('rs'));
});
});
it('creates a file descriptor for reading and writing (rs+)', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'two.txt'), flags('rs+'));
assert.isNumber(fd);
});
it('generates error if file does not exist (rs+)', function() {
var binding = new Binding(system);
assert.throws(function() {
binding.open('bogus', flags('rs+'));
});
});
it('opens a new file for writing (w)', function() {
var binding = new Binding(system);
binding.open('new.txt', flags('w'), parseInt('0644', 8));
var file = system.getItem('new.txt');
assert.instanceOf(file, File);
assert.equal(file.getMode(), parseInt('0644', 8));
});
it('truncates an existing file for writing (w)', function() {
var binding = new Binding(system);
binding.open(path.join('mock-dir', 'two.txt'), flags('w'),
parseInt('0666', 8));
var file = system.getItem(path.join('mock-dir', 'two.txt'));
assert.instanceOf(file, File);
assert.equal(String(file.getContent()), '');
});
it('generates error if file exists (wx)', function() {
var binding = new Binding(system);
assert.throws(function() {
binding.open(path.join('mock-dir', 'two.txt'), flags('wx'));
});
});
it('opens a new file for reading and writing (w+)', function() {
var binding = new Binding(system);
binding.open('new.txt', flags('w+'), parseInt('0644', 8));
var file = system.getItem('new.txt');
assert.instanceOf(file, File);
assert.equal(file.getMode(), parseInt('0644', 8));
assert.equal(String(file.getContent()), '');
});
it('truncates an existing file for writing (w+)', function() {
var binding = new Binding(system);
binding.open(
path.join('mock-dir', 'one.txt'), flags('w+'), parseInt('0666', 8));
var file = system.getItem(path.join('mock-dir', 'one.txt'));
assert.instanceOf(file, File);
assert.equal(String(file.getContent()), '');
});
it('opens a new file for reading and writing (wx+)', function() {
var binding = new Binding(system);
binding.open('new.txt', flags('wx+'), parseInt('0644', 8));
var file = system.getItem('new.txt');
assert.instanceOf(file, File);
assert.equal(file.getMode(), parseInt('0644', 8));
assert.equal(String(file.getContent()), '');
});
it('generates error if file exists (wx+)', function() {
var binding = new Binding(system);
assert.throws(function() {
binding.open(path.join('mock-dir', 'one.txt'), flags('wx+'),
parseInt('0666', 8));
});
});
it('opens a new file for appending (a)', function() {
var binding = new Binding(system);
binding.open('new.txt', flags('a'), parseInt('0666', 8));
var file = system.getItem('new.txt');
assert.instanceOf(file, File);
assert.equal(file.getMode(), parseInt('0666', 8));
assert.equal(String(file.getContent()), '');
});
it('opens an existing file for appending (a)', function() {
var binding = new Binding(system);
binding.open(
path.join('mock-dir', 'one.txt'), flags('a'), parseInt('0666', 8));
var file = system.getItem(path.join('mock-dir', 'one.txt'));
assert.instanceOf(file, File);
assert.equal(String(file.getContent()), 'one content');
});
it('opens a new file for appending (ax)', function() {
var binding = new Binding(system);
binding.open('new.txt', flags('ax'), parseInt('0664', 8));
var file = system.getItem('new.txt');
assert.instanceOf(file, File);
assert.equal(file.getMode(), parseInt('0664', 8));
assert.equal(String(file.getContent()), '');
});
it('generates error if file exists (ax)', function() {
var binding = new Binding(system);
assert.throws(function() {
binding.open(path.join('mock-dir', 'one.txt'), flags('ax'),
parseInt('0666', 8));
});
});
it('opens a new file for appending and reading (a+)', function() {
var binding = new Binding(system);
binding.open('new.txt', flags('a+'), parseInt('0666', 8));
var file = system.getItem('new.txt');
assert.instanceOf(file, File);
assert.equal(file.getMode(), parseInt('0666', 8));
assert.equal(String(file.getContent()), '');
});
it('opens an existing file for appending and reading (a+)', function() {
var binding = new Binding(system);
binding.open(
path.join('mock-dir', 'one.txt'), flags('a+'), parseInt('0666', 8));
var file = system.getItem(path.join('mock-dir', 'two.txt'));
assert.instanceOf(file, File);
assert.equal(String(file.getContent()), 'two content');
});
it('opens a new file for appending and reading (ax+)', function() {
var binding = new Binding(system);
binding.open('new.txt', flags('ax+'), parseInt('0666', 8));
var file = system.getItem('new.txt');
assert.instanceOf(file, File);
assert.equal(file.getMode(), parseInt('0666', 8));
assert.equal(String(file.getContent()), '');
});
it('opens an existing file for appending and reading (ax+)', function() {
var binding = new Binding(system);
assert.throws(function() {
binding.open(path.join('mock-dir', 'two.txt'), flags('ax+'),
parseInt('0666', 8));
});
});
});
describe('#close()', function() {
it('closes an existing file descriptor', function() {
var binding = new Binding(system);
var fd = binding.open('new.txt', flags('w'), parseInt('0644', 8));
binding.close(fd);
});
it('fails for closed file descriptor', function() {
var binding = new Binding(system);
var fd = binding.open('new.txt', flags('w'), parseInt('0644', 8));
binding.close(fd);
assert.throws(function() {
binding.close(fd);
});
});
});
describe('#read()', function() {
it('reads from a file', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'two.txt'), flags('r'));
var buffer = new Buffer(11);
var read = binding.read(fd, buffer, 0, 11, 0);
assert.equal(read, 11);
assert.equal(String(buffer), 'two content');
});
it('interprets null position as current position', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'one.txt'), flags('r'));
var buffer = new Buffer(4);
// chunk 1
assert.equal(binding.read(fd, buffer, 0, 11, null), 4);
assert.equal(String(buffer), 'one ');
// chunk 2
assert.equal(binding.read(fd, buffer, 0, 11, null), 4);
assert.equal(String(buffer), 'cont');
// chunk 3
assert.equal(binding.read(fd, buffer, 0, 11, null), 3);
assert.equal(String(buffer.slice(0, 3)), 'ent');
});
it('reads from a symbolic link', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'one-link.txt'), flags('r'));
var buffer = new Buffer(11);
var read = binding.read(fd, buffer, 0, 11, 0);
assert.equal(read, 11);
assert.equal(String(buffer), 'one content');
});
it('throws if not open for reading', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'two.txt'), flags('w'));
var buffer = new Buffer(11);
assert.throws(function() {
binding.read(fd, buffer, 0, 11, 0);
});
});
});
describe('#write()', function() {
it('writes to a file', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'new.txt'), flags('w'));
var buffer = new Buffer('new content');
var written = binding.write(fd, buffer, 0, 11, 0);
assert.equal(written, 11);
var file = system.getItem(path.join('mock-dir', 'new.txt'));
assert.instanceOf(file, File);
var content = file.getContent();
assert.isTrue(Buffer.isBuffer(content));
assert.equal(String(content), 'new content');
});
it('can overwrite a file', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'one.txt'), flags('w'));
var buffer = new Buffer('bingo');
var written = binding.write(fd, buffer, 0, 5, null);
assert.equal(written, 5);
var file = system.getItem(path.join('mock-dir', 'one.txt'));
assert.instanceOf(file, File);
var content = file.getContent();
assert.isTrue(Buffer.isBuffer(content));
assert.equal(String(content), 'bingo');
});
it('can append to a file', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'one.txt'), flags('a'));
var buffer = new Buffer(' more');
var written = binding.write(fd, buffer, 0, 5, null);
assert.equal(written, 5);
var file = system.getItem(path.join('mock-dir', 'one.txt'));
assert.instanceOf(file, File);
var content = file.getContent();
assert.isTrue(Buffer.isBuffer(content));
assert.equal(String(content), 'one content more');
});
it('can overwrite part of a file', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'one.txt'), flags('a'));
var buffer = new Buffer('new');
var written = binding.write(fd, buffer, 0, 3, 0);
assert.equal(written, 3);
var file = system.getItem(path.join('mock-dir', 'one.txt'));
assert.instanceOf(file, File);
var content = file.getContent();
assert.isTrue(Buffer.isBuffer(content));
assert.equal(String(content), 'new content');
});
it('throws if not open for writing', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'two.txt'), flags('r'));
var buffer = new Buffer('some content');
assert.throws(function() {
binding.write(fd, buffer, 0, 12, 0);
});
});
});
describe('#writeBuffers()', function() {
it('writes to a file', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'new.txt'), flags('w'));
var buffers = [
new Buffer('new '),
new Buffer('content')
];
var written = binding.writeBuffers(fd, buffers);
assert.equal(written, 11);
var file = system.getItem(path.join('mock-dir', 'new.txt'));
assert.instanceOf(file, File);
var content = file.getContent();
assert.isTrue(Buffer.isBuffer(content));
assert.equal(String(content), 'new content');
});
it('can append to a file', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'one.txt'), flags('a'));
var buffers = [
new Buffer(' more'),
new Buffer(' content')
];
var written = binding.writeBuffers(fd, buffers);
assert.equal(written, 13);
var file = system.getItem(path.join('mock-dir', 'one.txt'));
assert.instanceOf(file, File);
var content = file.getContent();
assert.isTrue(Buffer.isBuffer(content));
assert.equal(String(content), 'one content more content');
});
it('can overwrite part of a file', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'one.txt'), flags('a'));
var buffers = [
new Buffer('n'),
new Buffer('e'),
new Buffer('w')
];
var written = binding.writeBuffers(fd, buffers, 0);
assert.equal(written, 3);
var file = system.getItem(path.join('mock-dir', 'one.txt'));
assert.instanceOf(file, File);
var content = file.getContent();
assert.isTrue(Buffer.isBuffer(content));
assert.equal(String(content), 'new content');
});
it('throws if not open for writing', function() {
var binding = new Binding(system);
var fd = binding.open(path.join('mock-dir', 'two.txt'), flags('r'));
var buffers = [new Buffer('some content')];
assert.throws(function() {
binding.writeBuffers(fd, buffers);
});
});
});
describe('#rename()', function() {
it('allows files to be renamed', function(done) {
var binding = new Binding(system);
var oldPath = path.join('mock-dir', 'one.txt');
var newPath = path.join('mock-dir', 'empty', 'new.txt');
binding.rename(oldPath, newPath, function(_) {
var stats = binding.stat(newPath);
assert.equal(stats.mode & constants.S_IFMT, constants.S_IFREG);
assert.equal(stats.size, 11);
done();
});
});
it('allows files to be renamed (sync)', function() {
var binding = new Binding(system);
var oldPath = path.join('mock-dir', 'one.txt');
var newPath = path.join('mock-dir', 'new.txt');
binding.rename(oldPath, newPath);
var stats = binding.stat(newPath);
assert.equal(stats.mode & constants.S_IFMT, constants.S_IFREG);
assert.equal(stats.size, 11);
});
it('replaces existing files (sync)', function() {
var binding = new Binding(system);
var oldPath = path.join('mock-dir', 'one.txt');
var newPath = path.join('mock-dir', 'two.txt');
binding.rename(oldPath, newPath);
var stats = binding.stat(newPath);
assert.equal(stats.mode & constants.S_IFMT, constants.S_IFREG);
assert.equal(stats.size, 11);
});
it('allows directories to be renamed', function(done) {
var binding = new Binding(system);
var oldPath = path.join('mock-dir', 'empty');
var newPath = path.join('mock-dir', 'new');
binding.rename(oldPath, newPath, function(_) {
var stats = binding.stat(newPath);
assert.equal(stats.mode & constants.S_IFMT, constants.S_IFDIR);
done();
});
});
it('allows directories to be renamed (sync)', function() {
var binding = new Binding(system);
var oldPath = path.join('mock-dir');
var newPath = path.join('new-dir');
binding.rename(oldPath, newPath);
var stats = binding.stat(newPath);
assert.equal(stats.mode & constants.S_IFMT, constants.S_IFDIR);
var items = binding.readdir(newPath);
assert.isArray(items);
assert.deepEqual(items.sort(),
['dead-link', 'dir-link', 'dir-link2', 'empty', 'non-empty',
'one-link.txt', 'one-link2.txt', 'one.txt', 'three.bin',
'two.txt']);
});
it('calls callback with error for bogus old path', function(done) {
var binding = new Binding(system);
var oldPath = path.join('mock-dir', 'bogus');
var newPath = path.join('mock-dir', 'new');
binding.rename(oldPath, newPath, function(err) {
assert.instanceOf(err, Error);
done();
});
});
it('calls callback with error for file->dir rename', function(done) {
var binding = new Binding(system);
var oldPath = path.join('mock-dir', 'one.txt');
var newPath = path.join('mock-dir', 'empty');
binding.rename(oldPath, newPath, function(err) {
assert.instanceOf(err, Error);
done();
});
});
it('calls callback with error for dir->file rename', function(done) {
var binding = new Binding(system);
var oldPath = path.join('mock-dir', 'one.txt');
var newPath = path.join('mock-dir', 'empty');
binding.rename(oldPath, newPath, function(err) {
assert.instanceOf(err, Error);
done();
});
});
});
describe('#mkdir()', function() {
it('creates a new directory', function() {
var binding = new Binding(system);
var dirPath = path.join('mock-dir', 'foo');
binding.mkdir(dirPath, parseInt('0755', 8));
var dir = system.getItem(dirPath);
assert.instanceOf(dir, Directory);
assert.equal(dir.getMode(), parseInt('0755', 8));
});
it('fails if parent does not exist', function() {
var binding = new Binding(system);
var dirPath = path.join('bogus', 'path');
assert.throws(function() {
binding.mkdir(dirPath, parseInt('0755', 8));
});
});
it('fails if directory exists', function() {
var binding = new Binding(system);
var dirPath = 'mock-dir';
assert.throws(function() {
binding.mkdir(dirPath, parseInt('0755', 8));
});
});
it('fails if file exists', function() {
var binding = new Binding(system);
var dirPath = path.join('mock-dir', 'one.txt');
assert.throws(function() {
binding.mkdir(dirPath, parseInt('0755', 8));
});
});
});
describe('#rmdir()', function() {
it('removes an empty directory', function() {
var binding = new Binding(system);
var dirPath = path.join('mock-dir', 'empty');
binding.rmdir(dirPath);
assert.isNull(system.getItem(dirPath));
});
it('fails if directory is not empty', function() {
var binding = new Binding(system);
var dirPath = 'mock-dir';
assert.throws(function() {
binding.rmdir(dirPath);
});
});
it('fails if directory does not exist', function() {
var binding = new Binding(system);
var dirPath = path.join('bogus', 'path');
assert.throws(function() {
binding.rmdir(dirPath);
});
});
it('fails if a file exists', function() {
var binding = new Binding(system);
var dirPath = path.join('mock-dir', 'one.txt');
assert.throws(function() {
binding.rmdir(dirPath);
});
});
});
describe('#ftruncate()', function() {
it('truncates a file', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'one.txt');
var fd = binding.open(pathname, flags('r+'));
binding.ftruncate(fd, 3);
var file = system.getItem(pathname);
assert.equal(String(file.getContent()), 'one');
});
it('fails if directory', function() {
var binding = new Binding(system);
var fd = binding.open('mock-dir', flags('r'));
assert.throws(function() {
binding.ftruncate(fd, 3);
});
});
it('fails if not open for writing', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'one.txt');
var fd = binding.open(pathname, flags('r'));
assert.throws(function() {
binding.ftruncate(fd, 4);
});
});
});
describe('#chown()', function() {
it('sets the uid and gid for a file', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'one.txt');
binding.chown(pathname, 3, 4);
var file = system.getItem(pathname);
assert.equal(file.getUid(), 3);
assert.equal(file.getGid(), 4);
});
it('sets the uid and gid for a directory', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'empty');
binding.chown(pathname, 5, 6);
var dir = system.getItem(pathname);
assert.equal(dir.getUid(), 5);
assert.equal(dir.getGid(), 6);
});
});
describe('#fchown()', function() {
it('sets the uid and gid for a file', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'one.txt');
var fd = binding.open(pathname, flags('r'));
binding.fchown(fd, 3, 4);
var file = system.getItem(pathname);
assert.equal(file.getUid(), 3);
assert.equal(file.getGid(), 4);
});
it('sets the uid and gid for a directory', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'empty');
var fd = binding.open(pathname, flags('r'));
binding.fchown(fd, 5, 6);
var dir = system.getItem(pathname);
assert.equal(dir.getUid(), 5);
assert.equal(dir.getGid(), 6);
});
});
describe('#chmod()', function() {
it('sets the mode for a file', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'two.txt');
binding.chmod(pathname, parseInt('0644', 8));
var file = system.getItem(pathname);
assert.equal(file.getMode(), parseInt('0644', 8));
});
it('sets the mode for a directory', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'empty');
binding.chmod(pathname, parseInt('0755', 8));
var dir = system.getItem(pathname);
assert.equal(dir.getMode(), parseInt('0755', 8));
});
});
describe('#fchmod()', function() {
it('sets the mode for a file', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'one.txt');
var fd = binding.open(pathname, flags('r'));
binding.fchmod(fd, parseInt('0664', 8));
var file = system.getItem(pathname);
assert.equal(file.getMode(), parseInt('0664', 8));
});
it('sets the mode for a directory', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'empty');
var fd = binding.open(pathname, flags('r'));
binding.fchmod(fd, parseInt('0775', 8));
var dir = system.getItem(pathname);
assert.equal(dir.getMode(), parseInt('0775', 8));
});
});
describe('#unlink()', function() {
it('deletes a file', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'one.txt');
binding.unlink(pathname);
assert.isNull(system.getItem(pathname));
});
it('fails for directory', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'empty');
assert.throws(function() {
binding.unlink(pathname);
});
});
it('fails for bogus path', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'bogus.txt');
assert.throws(function() {
binding.unlink(pathname);
});
});
});
describe('#utimes()', function() {
it('updates atime and mtime for a file', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'one.txt');
binding.utimes(pathname, 100, 200);
var item = system.getItem(pathname);
assert.equal(item.getATime().getTime(), 100 * 1000);
assert.equal(item.getMTime().getTime(), 200 * 1000);
});
it('updates atime and mtime for a directory', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'empty');
binding.utimes(pathname, 300, 400);
var item = system.getItem(pathname);
assert.equal(item.getATime().getTime(), 300 * 1000);
assert.equal(item.getMTime().getTime(), 400 * 1000);
});
it('fails for a bogus path', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'bogus.txt');
assert.throws(function() {
binding.utimes(pathname, 300, 400);
});
});
});
describe('#futimes()', function() {
it('updates atime and mtime for a file', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'one.txt');
var fd = binding.open(pathname, flags('r'));
binding.futimes(fd, 100, 200);
var item = system.getItem(pathname);
assert.equal(item.getATime().getTime(), 100 * 1000);
assert.equal(item.getMTime().getTime(), 200 * 1000);
});
it('updates atime and mtime for a directory', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'empty');
var fd = binding.open(pathname, flags('r'));
binding.futimes(fd, 300, 400);
var item = system.getItem(pathname);
assert.equal(item.getATime().getTime(), 300 * 1000);
assert.equal(item.getMTime().getTime(), 400 * 1000);
});
});
describe('#fsync()', function() {
it('synchronize file state (noop)', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'one.txt');
var fd = binding.open(pathname, flags('r'));
binding.fsync(fd);
});
it('fails for closed file descriptor', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'one.txt');
var fd = binding.open(pathname, flags('r'));
binding.close(fd);
assert.throws(function() {
binding.fsync(fd);
});
});
});
describe('#fdatasync()', function() {
it('synchronize file state (noop)', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'one.txt');
var fd = binding.open(pathname, flags('r'));
binding.fdatasync(fd);
});
it('fails for closed file descriptor', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'one.txt');
var fd = binding.open(pathname, flags('r'));
binding.close(fd);
assert.throws(function() {
binding.fdatasync(fd);
});
});
});
describe('#link()', function() {
it('creates a link to a file', function() {
var binding = new Binding(system);
var source = path.join('mock-dir', 'one.txt');
var dest = path.join('mock-dir', 'link.txt');
binding.link(source, dest);
var link = system.getItem(dest);
assert.instanceOf(link, File);
assert.equal(String(link.getContent()), 'one content');
});
it('fails if dest exists', function() {
var binding = new Binding(system);
var source = path.join('mock-dir', 'one.txt');
var dest = path.join('mock-dir', 'two.txt');
assert.throws(function() {
binding.link(source, dest);
});
});
it('fails if source is directory', function() {
var binding = new Binding(system);
var source = path.join('mock-dir', 'empty');
var dest = path.join('mock-dir', 'link');
assert.throws(function() {
binding.link(source, dest);
});
});
});
describe('#symlink()', function() {
it('creates a symbolic link to a file', function() {
var binding = new Binding(system);
var source = path.join('.', 'one.txt');
var dest = path.join('mock-dir', 'link.txt');
binding.symlink(source, dest);
var link = system.getItem(dest);
assert.instanceOf(link, SymbolicLink);
assert.equal(link.getPath(), source);
});
it('fails if dest exists', function() {
var binding = new Binding(system);
var source = path.join('.', 'one.txt');
var dest = path.join('mock-dir', 'two.txt');
assert.throws(function() {
binding.symlink(source, dest);
});
});
it('works if source is directory', function() {
var binding = new Binding(system);
var source = path.join('mock-dir', 'empty');
var dest = path.join('mock-dir', 'link');
binding.symlink(source, dest);
var link = system.getItem(dest);
assert.instanceOf(link, SymbolicLink);
assert.equal(link.getPath(), source);
});
});
describe('#readlink()', function() {
it('reads the symbolic link', function() {
var binding = new Binding(system);
var srcPath = binding.readlink(path.join('mock-dir', 'one-link.txt'));
assert.equal(srcPath, './one.txt');
});
it('can return "buffer" encoding', function() {
var binding = new Binding(system);
var srcPath = binding.readlink(path.join('mock-dir', 'one-link.txt'), 'buffer');
assert.equal(Buffer.isBuffer(srcPath), true);
assert.equal(srcPath.toString(), './one.txt');
});
it('fails for regular files', function() {
var binding = new Binding(system);
assert.throws(function() {
binding.readlink(path.join('mock-dir', 'one.txt'));
});
});
it('fails for directories', function() {
var binding = new Binding(system);
assert.throws(function() {
binding.readlink(path.join('mock-dir', 'empty'));
});
});
it('fails for bogus paths', function() {
var binding = new Binding(system);
assert.throws(function() {
binding.readlink(path.join('mock-dir', 'bogus'));
});
});
});
describe('#lstat()', function() {
it('stats symbolic links', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'o