Skip to content

Latest commit

 

History

History
795 lines (706 loc) · 20.3 KB

spec.md

File metadata and controls

795 lines (706 loc) · 20.3 KB

TOC

fs-meta

Own Properties

fs.sync

should exist.

fsm.should.have.property('sync');
fsm.sync.should.be.an.Object();

fs.unpromised

should exist.

fsm.should.have.property('unpromised');
fsm.unpromised.should.be.an.Object();

fs.filters

should exist.

fsm.should.have.property('filters');
fsm.filters.should.be.an.Object();

fs.statToObj

should exist.

fsm.should.have.property('statToObj');
fsm.statToObj.should.be.an.Function();

Promises

exists

exists(path)

say if a file exists.

fsm.exists(rootDir + '/style.css').then(function (exists) {
	exists.should.be['true']();
	done();
}).error(done);

should return an error if a file does not exist.

fsm.exists(rootDir + '/notAFile.css').then(function (exists) {
	done(new Error('this should not happen'));
}).error(function (err) {
	return done();
});

Regular fs methods

Availability

should be possible to find all fs and fs-extra methods on fs-meta.

for (i = 0; i < length; i++) {
	fsm.should.have.property(methods[i]);
}

should all be functions.

for (i = 0; i < length; i++) {
	fsm[methods[i]].should.be.a.Function();
}

getMeta

getMeta(path)

should serve a json object about a file.

fsm.getMeta(rootDir + '/style.css').then(function (meta) {
	meta.basename.should.equal('style');
	meta.filename.should.equal('style.css');
	meta.extension.should.equal('css');
	done();
}).error(done);

getMeta(path,{root:string})

should truncate file paths to the provided root.

fsm.getMeta(rootDir + '/style.css', { root: rootDir }).then(function (meta) {
	meta.dirname.should.equal('');
	meta.path.should.equal('/style.css');
	done();
}).error(done);

getMeta(path,{filters:[]})

should process the filter array.

var filterRan = false;
var options = {
	filters: [function (meta, options, next, fs) {
		if (meta.extension == 'css') {
			filterRan = true;
		}
		next(null, meta);
	}]
};
fsm.getMeta(rootDir + '/style.css', options).then(function (meta) {
	filterRan.should.be['true'];
	done();
}).error(done);

should process the filter array in order.

var filterRan = false;
var options = {
	filters: [function first(meta, options, next, fs) {
		if (meta.extension == 'css') {
			meta.number = 1;
		}
		next(null, meta);
	}, function second(meta, options, next, fs) {
		if (meta.extension == 'css') {
			meta.number = meta.number + 1;
		}
		next(null, meta);
	}]
};
fsm.getMeta(rootDir + '/style.css', options).then(function (meta) {
	meta.number.should.equal(2);
	done();
}).error(done);

getMetaRecursive

getMetaRecursive(path)

should get metadata recursively for all files in a directory.

fsm.getMetaRecursive(rootDir + '/directory').then(function (_ref) {
	var files = _ref.files;
	var indexes = _ref.indexes;
	files.length.should.equal(11);
	files[indexes[rootDir + '/directory']].files.length.should.equal(7);
	files[indexes[rootDir + '/directory/subDirectory']].files.length.should.equal(3);
	done();
}).error(done);

getMetaRecursive(path,{filters})

should apply filters recursively for all files in a directory.

fsm.getMetaRecursive(rootDir + '/directory', {
	filters: [function (meta, options, next, fs) {
		if (meta.extension == 'ini') {
			meta.filter = true;
		}
		next(null, meta);
	}]
}).then(function (_ref2) {
	var files = _ref2.files;
	var indexes = _ref2.indexes;
	var iniFileIndex = indexes[rootDir + '/directory/subDirectory/test.ini'];
	var iniFileMeta = files[iniFileIndex];
	iniFileMeta.should.have.property('filter');
	iniFileMeta.filter.should.be['true'];
	done();
}).error(done);

readdirp

readdirp(path)

should loop through first-level files in the given directory.

var counter = 0;
fsm.readdirp(rootDir, function (fileInfo) {
	counter++;
}).then(function () {
	counter.should.equal(14);
	done();
}).error(done);

readdirp(path,{depth:n})

should loop through directories and sub-directories until n level.

var counter = 0;
fsm.readdirp(rootDir, { depth: 10 }, function (fileInfo) {
	counter++;
}).then(function () {
	counter.should.equal(14);
	done();
}).error(done);

traverse

traverse(path)

should traverse all files for the given path.

var counter = 0;
fsm.traverse(rootDir, function (filePath, stats, options, next) {
	//console.log(counter,filePath)
	counter++;
	next();
}).then(function () {
	counter.should.equal(15);
	done();
}).error(done);

traverse(path,{depth:n})

should traverse all files for the given path until the given depth n.

var counter = 0;
fsm.traverse(rootDir, { depth: 1 }, function (filePath, stats, options, next) {
	counter++;
	next();
}).then(function () {
	counter.should.equal(5);
	done();
}).error(done);

traverse(path,{depth:0})

should be equivalent to calling stat on the root directory.

var counter = 0;
fsm.traverse(rootDir, { depth: 0 }, function (filePath, stats, options, next) {
	counter++;
	next();
}).then(function () {
	counter.should.equal(1);
	done();
}).error(done);

traverse(path,{lstat:true})

should use lstat instead of stat.

var calls = 0;
function bothDone(err) {
	calls++;
	if (calls > 2) {
		return;
	}
	if (err) {
		calls = 10;
		done(err);
	}
	if (calls == 2) {
		done();
	}
}
fsm.traverse(rootDir, { lstat: true }, function (filePath, stats, options, next) {
	if (filePath.match(/frontblueprintLink.jpg/)) {
		stats.isSymbolicLink().should.be['true'];
	}
	next();
}).then(function () {
	bothDone();
}).error(bothDone);
fsm.traverse(rootDir, { lstat: false }, function (filePath, stats, options, next) {
	if (filePath.match(/frontblueprintLink.jpg/)) {
		stats.isSymbolicLink().should.be['false'];
	}
	next();
}).then(function () {
	bothDone();
}).error(bothDone);

boxed

boxed(rootDir)

should return an instance of fsm boxed to the rootDir provided.

var boxed = fsm.boxed(rootDir);
boxed.readdir('').then(function (files) {
	files.length.should.equal(4);
	done();
}).error(done);

boxed(rootDir,{methods:{}})

should wrap the original function with the one provided.

var boxed = fsm.boxed(rootDir, {
	methods: {
		stat: function stat(filename, cb) {
			this['super'](filename + 'tory', function (err, stat) {
				if (err) {
					cb(err);
				}
				stat.someNewProperty = 'property';
				cb(null, stat);
			});
		}
	}
});
boxed.stat('direc').then(function (stat) {
	stat.should.have.property('someNewProperty');
	done();
}).error(done);

boxed(rootDir,{filters:[]})

should provide default filters to getMeta.

var filterRan = false;
var boxed = fsm.boxed(rootDir, {
	filters: [function (meta, options, next, fs) {
		if (meta.extension == 'css') {
			filterRan = true;
		}
		next(null, meta);
	}]
});
boxed.getMeta('/style.css').then(function (meta) {
	filterRan.should.be['true'];
	done();
}).error(done);

should provide default filters to getMetaRecursive.

var filterRan = 0;
var boxed = fsm.boxed(rootDir, {
	filters: [function (meta, options, next, fs) {
		if (meta.extension == 'css') {
			filterRan++;
		}
		next(null, meta);
	}]
});
boxed.getMetaRecursive('').then(function (meta) {
	filterRan.should.be.greaterThan(0);
	done();
}).error(done);

exists

exists(path)

say if a file exists.

var boxed = fsm.boxed(rootDir);
boxed.exists('/style.css').then(function (exists) {
	exists.should.be['true']();
	done();
}).error(done);

should return an error if a file does not exist.

var boxed = fsm.boxed(rootDir);
boxed.exists('/notAFile.css').then(function (exists) {
	done(new Error('this should not happen'));
}).error(function (err) {
	return done();
});

Regular fs methods

Availability

should be possible to find all fs and fs-extra methods on fs-meta.

var boxed = fsm.boxed(rootDir);
for (i = 0; i < length; i++) {
	boxed.should.have.property(methods[i]);
}

should all be functions.

var boxed = fsm.boxed(rootDir);
for (i = 0; i < length; i++) {
	boxed[methods[i]].should.be.a.Function();
}

getMeta

getMeta(path)

should serve a json object about a file.

var boxed = fsm.boxed(rootDir);
boxed.getMeta('/style.css').then(function (meta) {
	meta.basename.should.equal('style');
	meta.filename.should.equal('style.css');
	meta.extension.should.equal('css');
	done();
}).error(done);

getMeta(path,{root:string})

should truncate file paths to the provided root.

var boxed = fsm.boxed(rootDir);
boxed.getMeta('/style.css', { root: rootDir }).then(function (meta) {
	meta.dirname.should.equal('');
	meta.path.should.equal('/style.css');
	done();
}).error(done);

getMeta(path,{filters:[]})

should process the filter array.

var boxed = fsm.boxed(rootDir);
var filterRan = false;
var options = {
	filters: [function (meta, options, next, fs) {
		if (meta.extension == 'css') {
			filterRan = true;
		}
		next(null, meta);
	}]
};
boxed.getMeta('/style.css', options).then(function (meta) {
	filterRan.should.be['true'];
	done();
}).error(done);

should process the filter array in order.

var boxed = fsm.boxed(rootDir);
var filterRan = false;
var options = {
	filters: [function first(meta, options, next, fs) {
		if (meta.extension == 'css') {
			meta.number = 1;
		}
		next(null, meta);
	}, function second(meta, options, next, fs) {
		if (meta.extension == 'css') {
			meta.number = meta.number + 1;
		}
		next(null, meta);
	}]
};
boxed.getMeta('/style.css', options).then(function (meta) {
	meta.number.should.equal(2);
	done();
}).error(done);

getMetaRecursive

getMetaRecursive(path)

should get metadata recursively for all files in a directory.

var boxed = fsm.boxed(rootDir);
boxed.getMetaRecursive('/directory').then(function (_ref) {
	var files = _ref.files;
	var indexes = _ref.indexes;
	files.length.should.equal(11);
	files[indexes['/directory']].files.length.should.equal(7);
	files[indexes['/directory/subDirectory']].files.length.should.equal(3);
	done();
}).error(done);

getMetaRecursive(path,{filters})

should apply filters recursively for all files in a directory.

var boxed = fsm.boxed(rootDir);
boxed.getMetaRecursive('/directory', {
	filters: [function (meta, options, next, fs) {
		if (meta.extension == 'ini') {
			meta.filter = true;
		}
		next(null, meta);
	}]
}).then(function (_ref2) {
	var files = _ref2.files;
	var indexes = _ref2.indexes;
	var iniFileIndex = indexes['/directory/subDirectory/test.ini'];
	var iniFileMeta = files[iniFileIndex];
	iniFileMeta.should.have.property('filter');
	iniFileMeta.filter.should.be['true'];
	done();
}).error(done);

readdirp

readdirp(path)

should loop through first-level files in the given directory.

var boxed = fsm.boxed(rootDir);
var counter = 0;
boxed.readdirp('', function (fileInfo) {
	counter++;
}).then(function () {
	counter.should.equal(14);
	done();
}).error(done);

readdirp(path,{depth:n})

should loop through directories and sub-directories until n level.

var boxed = fsm.boxed(rootDir);
var counter = 0;
boxed.readdirp('', { depth: 10 }, function (fileInfo) {
	counter++;
}).then(function () {
	counter.should.equal(14);
	done();
}).error(done);

traverse

traverse(path)

should traverse all files for the given path.

var boxed = fsm.boxed(rootDir);
var counter = 0;
boxed.traverse('', function (filePath, stats, options, next) {
	//console.log(counter,filePath)
	counter++;
	next();
}).then(function () {
	counter.should.equal(15);
	done();
}).error(done);

traverse(path,{depth:n})

should traverse all files for the given path until the given depth n.

var boxed = fsm.boxed(rootDir);
var counter = 0;
boxed.traverse('', { depth: 1 }, function (filePath, stats, options, next) {
	counter++;
	next();
}).then(function () {
	counter.should.equal(5);
	done();
}).error(done);

traverse(path,{depth:0})

should be equivalent to calling stat on the root directory.

var boxed = fsm.boxed(rootDir);
var counter = 0;
boxed.traverse('', { depth: 0 }, function (filePath, stats, options, next) {
	counter++;
	next();
}).then(function () {
	counter.should.equal(1);
	done();
}).error(done);

traverse(path,{lstat:true})

should use lstat instead of stat.

var boxed = fsm.boxed(rootDir);
var calls = 0;
function bothDone(err) {
	calls++;
	if (calls > 2) {
		return;
	}
	if (err) {
		calls = 10;
		done(err);
	}
	if (calls == 2) {
		done();
	}
}
boxed.traverse('', { lstat: true }, function (filePath, stats, options, next) {
	if (filePath.match(/frontblueprintLink.jpg/)) {
		stats.isSymbolicLink().should.be['true'];
	}
	next();
}).then(function () {
	bothDone();
}).error(bothDone);
boxed.traverse('', { lstat: false }, function (filePath, stats, options, next) {
	if (filePath.match(/frontblueprintLink.jpg/)) {
		stats.isSymbolicLink().should.be['false'];
	}
	next();
}).then(function () {
	bothDone();
}).error(bothDone);

api

api.runCommand(commandName,args,cb)

should run the command specified by commandName.

apiFactory(fsm.boxed(rootDir), {}).then(function (api) {
	return api.runCommand('readdir', ['/']);
}).then(function (answer) {
	answer.result.should.be.an.Array();
	answer.result.should.containEql('directory');
	done();
}).error(done);

api.runPath(path,cb)

should run the command specified by commandName.

apiFactory(fsm.boxed(rootDir), {}).then(function (api) {
	return api.runPath('readdir/directory/subDirectory');
}).then(function (answer) {
	answer.result.should.be.an.Array();
	answer.result.length.should.equal(3);
	done();
}).error(done);

api.runCommand('help',cb)

should return a summary of all commands.

apiFactory(fsm.boxed(rootDir), {}).then(function (api) {
	return api.runPath('help');
}).then(function (answer) {
	answer.result.should.be.an.Object();
	answer.result.should.have.property('commands');
	done();
}).error(done);

api.middleware(req,res,next)

should call res.json on success.

var req = {
	path: '/getMeta/./',
	query: {},
	command: 'GET'
};
var res = {
	json: function json(result) {
		if (result.response == 'error') {
			return done(result);
		}
		result.result.should.have.property('basename');
		done();
	}
};
apiFactory(fsm.boxed(rootDir), {}).then(function (api) {
	return api.middleware(req, res, done);
}).error(done);