fabricator
Advanced tools
Comparing version 0.4.1 to 0.4.2
56
index.js
@@ -13,2 +13,3 @@ 'use strict'; | ||
* - recursive: {Boolean} Should file paths be recursively discovered. | ||
* - name: {String} Force a name for a given constructor. | ||
* | ||
@@ -20,3 +21,3 @@ * @param {Mixed} stack String, array or object that contains constructible entities | ||
*/ | ||
module.exports = function fabricator(stack, options) { | ||
function fabricator(stack, options) { | ||
options = options || {}; | ||
@@ -38,7 +39,11 @@ | ||
default: | ||
throw new Error('Unsupported type, cannot fabricate an: '+ is(stack)); | ||
if ('function' !== typeof stack) { | ||
throw new Error('Unsupported type, cannot fabricate an: '+ is(stack)); | ||
} | ||
stack = [init(stack, undefined, options)]; | ||
} | ||
return (stack || []).filter(Boolean); | ||
}; | ||
} | ||
@@ -54,2 +59,3 @@ /** | ||
function read(filepath, options) { | ||
if ('string' !== is(filepath)) return fabricator(filepath, options); | ||
if (options.source) filepath = path.resolve(options.source, filepath); | ||
@@ -61,3 +67,3 @@ | ||
if (js(filepath) || options.recursive === false) return [ | ||
init(filepath, path.basename(filepath, '.js')) | ||
init(filepath, path.basename(filepath, '.js'), options) | ||
]; | ||
@@ -78,3 +84,3 @@ | ||
// | ||
return init(path.join(file, 'index.js'), path.basename(file, '.js')); | ||
return init(path.join(file, 'index.js'), path.basename(file, '.js'), options); | ||
} | ||
@@ -86,3 +92,4 @@ | ||
if (!stat.isFile() || !js(file)) return; | ||
return init(file, path.basename(file, '.js')); | ||
return init(file, path.basename(file, '.js'), options); | ||
}); | ||
@@ -96,3 +103,3 @@ } | ||
* @param {Object} obj Original object, if set values are fetched by entity. | ||
* @param {Object} options | ||
* @param {Object} options Configuration. | ||
* @return {Function} iterator | ||
@@ -103,3 +110,4 @@ * @api private | ||
return function reduce(stack, entity) { | ||
var base = obj ? obj[entity] : entity; | ||
var base = obj ? obj[entity] : entity | ||
, name = options.name || entity; | ||
@@ -109,3 +117,19 @@ // | ||
// | ||
if (js(base)) return stack.concat(init(base, entity)); | ||
if (js(base)) return stack.concat(init( | ||
base, | ||
'string' === is(name) ? name : '', | ||
options | ||
)); | ||
// | ||
// When we've been supplied with an array as base assume we want to keep it | ||
// as array and do not want it to be merged. | ||
// | ||
if (Array.isArray(base)) { | ||
options.name = name; // Force the name of the entry for all items in array. | ||
stack.push(traverse(base, options)); | ||
return stack; | ||
} | ||
return stack.concat(traverse(base, options)); | ||
@@ -154,3 +178,3 @@ }; | ||
*/ | ||
function init(constructor, name) { | ||
function init(constructor, name, options) { | ||
constructor = ('string' === is(constructor)) ? require(constructor) : constructor; | ||
@@ -164,2 +188,5 @@ | ||
name = constructor.prototype.name || name || constructor.name; | ||
if (options.name) name = options.name; | ||
// | ||
@@ -169,5 +196,3 @@ // Sets the lowercase name on the prototype if required. | ||
if ('name' in constructor.prototype) { | ||
constructor.prototype.name = ( | ||
constructor.prototype.name || name || constructor.name | ||
).toLowerCase(); | ||
constructor.prototype.name = name.toString().toLowerCase(); | ||
} | ||
@@ -177,1 +202,6 @@ | ||
} | ||
// | ||
// Expose the module. | ||
// | ||
module.exports = fabricator; |
{ | ||
"name": "fabricator", | ||
"version": "0.4.1", | ||
"version": "0.4.2", | ||
"description": "Discover collections of constructible instances from strings (filepaths), arrays or objects", | ||
@@ -28,8 +28,9 @@ "main": "index.js", | ||
"devDependencies": { | ||
"assume": "0.0.x", | ||
"coveralls": "2.10.x", | ||
"illuminati": "0.0.x", | ||
"istanbul": "0.2.x", | ||
"mocha": "1.20.x", | ||
"mocha-lcov-reporter": "0.0.x", | ||
"illuminati": "0.0.x" | ||
"mocha-lcov-reporter": "0.0.x" | ||
} | ||
} |
@@ -0,1 +1,16 @@ | ||
'use strict'; | ||
/** | ||
* Return a constructor with a name field. | ||
* | ||
* @returns {Function} created constructor; | ||
* @api private | ||
*/ | ||
function fn() { | ||
function Y() { /* nope */ } | ||
Y.prototype.name = ''; | ||
return Y; | ||
} | ||
// | ||
@@ -22,6 +37,11 @@ // Constructor inside JS file. | ||
// | ||
// Just a simple function. | ||
// | ||
exports.fn = fn(); | ||
// | ||
// Mix of types on array. | ||
// | ||
exports.array = [ | ||
function Test() { /* noop */ }, | ||
fn(), | ||
exports.directory | ||
@@ -34,5 +54,15 @@ ]; | ||
exports.object = { | ||
Status: function Status() { /* noop */ }, | ||
another: function Another() { /* noop */ }, | ||
Status: fn(), | ||
another: fn(), | ||
latest: exports.string | ||
}; | ||
// | ||
// Mix of multiple things. | ||
// | ||
exports.objectarray = { | ||
placeholder: [fn(), fn(), exports.directory], | ||
another: [exports.string, fn()], | ||
last: [fn()], | ||
latest: exports.string | ||
}; |
@@ -1,1 +0,3 @@ | ||
module.exports = function () {}; | ||
function Bar() {} | ||
Bar.prototype.name = ''; | ||
module.exports = Bar; |
@@ -1,1 +0,3 @@ | ||
module.exports = function () {}; | ||
function Foo() {} | ||
Foo.prototype.name = ''; | ||
module.exports = Foo; |
@@ -1,3 +0,7 @@ | ||
module.exports = module.exports = function Is() { | ||
function Index() { | ||
/* noop */ | ||
}; | ||
} | ||
Index.prototype.name = ''; | ||
module.exports = Index; |
@@ -1,3 +0,7 @@ | ||
module.exports = module.exports = function Is() { | ||
function Is() { | ||
/* noop */ | ||
}; | ||
} | ||
Is.prototype.name = ''; | ||
module.exports = Is; |
@@ -17,2 +17,6 @@ describe('Fabricator', function () { | ||
assume(result.length).to.equal(3); | ||
result.forEach(function (fn) { | ||
assume(fn).to.be.a('function'); | ||
}); | ||
}); | ||
@@ -25,4 +29,32 @@ | ||
assume(result.length).to.equal(1); | ||
result.forEach(function (fn) { | ||
assume(fn).to.be.a('function'); | ||
assume(fn.prototype.name).to.equal('with name'); | ||
}); | ||
}); | ||
it('can force a name on constructors', function () { | ||
var result = fabricator(fixtures.string, { name: 'foo' }); | ||
assume(result).to.be.an('array'); | ||
assume(result.length).to.equal(1); | ||
result.forEach(function (fn) { | ||
assume(fn).to.be.a('function'); | ||
assume(fn.prototype.name).to.equal('foo'); | ||
}); | ||
}); | ||
it('transforms functions in to arrays', function () { | ||
var result = fabricator(fixtures.fn); | ||
assume(result).to.be.an('array'); | ||
assume(result.length).to.equal(1); | ||
result.forEach(function (fn) { | ||
assume(fn).to.be.a('function'); | ||
}); | ||
}); | ||
it('will discover constructors in subdirectories and ignore other JS files', function () { | ||
@@ -33,2 +65,6 @@ var result = fabricator(fixtures.directory); | ||
assume(result.length).to.equal(2); | ||
result.forEach(function (fn) { | ||
assume(fn).to.be.a('function'); | ||
}); | ||
}); | ||
@@ -47,18 +83,28 @@ | ||
assume(result.length).to.equal(2); | ||
result.forEach(function (fn) { | ||
assume(fn).to.be.a('function'); | ||
}); | ||
}); | ||
it('can be prevented from recursing a directory', function () { | ||
var path = __dirname + '/fixtures' | ||
, result = fabricator(fixtures.directory, { recursive: false }); | ||
var result = fabricator(fixtures.directory, { recursive: false }); | ||
assume(result).to.be.an('array'); | ||
assume(result.length).to.equal(1); | ||
result.forEach(function (fn) { | ||
assume(fn).to.be.a('function'); | ||
}); | ||
}); | ||
it('can read out sub directories', function () { | ||
var path = __dirname + '/fixtures' | ||
, result = fabricator(fixtures.nested); | ||
var result = fabricator(fixtures.nested); | ||
assume(result).to.be.an('array'); | ||
assume(result.length).to.equal(2); | ||
result.forEach(function (fn) { | ||
assume(fn).to.be.a('function'); | ||
}); | ||
}); | ||
@@ -71,2 +117,6 @@ | ||
assume(result.length).to.equal(3); | ||
result.forEach(function (fn) { | ||
assume(fn).to.be.a('function'); | ||
}); | ||
}); | ||
@@ -79,4 +129,30 @@ | ||
assume(result.length).to.equal(3); | ||
result.forEach(function (fn) { | ||
assume(fn).to.be.a('function'); | ||
}); | ||
}); | ||
it('will discover multiple constructors', function () { | ||
var result = fabricator(fixtures.objectarray); | ||
assume(result).to.be.an('array'); | ||
assume(result.length).to.equal(4); | ||
var last = result.pop(); | ||
assume(last).to.be.a('function'); | ||
result.forEach(function (thing) { | ||
assume(thing).to.be.a('array'); | ||
thing.forEach(function (fn) { | ||
assume(fn).to.be.a('function'); | ||
}); | ||
}); | ||
result[0].forEach(function (fn) { | ||
assume(fn.prototype.name).to.equal('placeholder'); | ||
}); | ||
}); | ||
it('sets prototype.name to lowercase object key if prototype.name is falsy', function () { | ||
@@ -83,0 +159,0 @@ fixtures.object.Status.prototype.name = ''; |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
15223
360
0
6