factory-girl
Advanced tools
Comparing version 1.2.0 to 1.3.0
325
index.js
@@ -9,88 +9,25 @@ (function() { | ||
factory.create = function(name, attrs, callback) { | ||
if (typeof attrs === 'function') { | ||
callback = attrs; | ||
attrs = {}; | ||
} | ||
if (!factories[name]) { | ||
return callback(new Error("No factory defined for model '" + name + "'")); | ||
} | ||
factory.build(name, attrs, function(err, doc) { | ||
if (err) return callback(err); | ||
save(name, doc, callback); | ||
}); | ||
}; | ||
factory.define = function(name, model, attributes, options) { | ||
options = options || {}; | ||
function save(name, doc, callback) { | ||
var model = factories[name].model; | ||
factory.adapterFor(name).save(doc, model, function (err) { | ||
if (!err) created.push([name, doc]); | ||
callback(err, doc); | ||
}); | ||
} | ||
factory.define = function(name, model, attributes) { | ||
factories[name] = { | ||
model: model, | ||
attributes: attributes | ||
attributes: attributes, | ||
options: options | ||
}; | ||
}; | ||
factory.build = function(name, attrs, callback) { | ||
if (typeof attrs === 'function') { | ||
callback = attrs; | ||
attrs = {}; | ||
} | ||
if (!factories[name]) { | ||
return callback(new Error("No factory defined for model '" + name + "'")); | ||
} | ||
var model = factories[name].model; | ||
attrs = merge(copy(factories[name].attributes), attrs); | ||
asyncForEach(keys(attrs), function(key, cb) { | ||
var fn = attrs[key]; | ||
if (typeof fn === 'function') { | ||
if (!fn.length) { | ||
attrs[key] = fn.call(attrs); | ||
cb(); | ||
} | ||
else { | ||
fn.call(attrs, function(err, value) { | ||
if (err) return cb(err); | ||
attrs[key] = value; | ||
cb(); | ||
}); | ||
} | ||
} | ||
else { | ||
cb(); | ||
} | ||
}, function(err) { | ||
if (err) return callback(err); | ||
var adapter = factory.adapterFor(name), | ||
doc = adapter.build(model, attrs); | ||
callback(null, doc); | ||
}); | ||
var builderProxy = function(fnName) { | ||
return function() { | ||
var builder = new Builder(); | ||
return builder[fnName].apply(this, arguments); | ||
}; | ||
}; | ||
factory.buildSync = function(name, attrs) { | ||
if (!factories[name]) { | ||
throw new Error("No factory defined for model '" + name + "'"); | ||
} | ||
var model = factories[name].model; | ||
attrs = merge(copy(factories[name].attributes), attrs); | ||
var names = keys(attrs); | ||
for (var i = 0; i < names.length; i++) { | ||
var key = names[i], fn = attrs[key]; | ||
if (typeof fn == 'function') { | ||
if (fn.length) { | ||
throw new Error("buildSync only supports synchronous property functions (with no arguments): the function for '" + name + "." + key + "' expects " + fn.length + " arguments"); | ||
} | ||
attrs[key] = fn.call(attrs); | ||
} | ||
} | ||
var adapter = factory.adapterFor(name); | ||
return adapter.build(model, attrs); | ||
}; | ||
factory.withOptions = builderProxy('withOptions'); | ||
factory.build = builderProxy('build'); | ||
factory.buildSync = builderProxy('buildSync'); | ||
factory.buildMany = builderProxy('buildMany'); | ||
factory.create = builderProxy('create'); | ||
factory.createMany = builderProxy('createMany'); | ||
@@ -119,68 +56,2 @@ factory.assoc = function(name, attr) { | ||
factory.buildMany = function(name, attrsArray, num, callback) { | ||
var args = parseBuildManyArgs.apply(null, arguments); | ||
_buildMany(args); | ||
}; | ||
function _buildMany(args) { | ||
var results = []; | ||
asyncForEach(args.attrsArray, function(attrs, cb, index) { | ||
factory.build(args.name, attrs, function(err, doc) { | ||
if (!err) results[index] = doc; | ||
cb(err); | ||
}); | ||
}, function(err) { | ||
args.callback(err, results); | ||
}); | ||
} | ||
function parseBuildManyArgs(name, attrsArray, num, callback) { | ||
if (typeof num == 'function') { // name, Array, callback | ||
callback = num; | ||
num = attrsArray.length; | ||
} | ||
if (typeof attrsArray == 'number') { // name, num, callback | ||
num = attrsArray; | ||
attrsArray = null; | ||
} | ||
if (!(attrsArray instanceof Array)) { // name, Object, num, callback | ||
if (typeof num != 'number') throw new Error("num must be specified when attrsArray is not an array"); | ||
var attrs = attrsArray; | ||
attrsArray = new Array(num); | ||
for (var i = 0; i < num; i++) { | ||
attrsArray[i] = attrs; | ||
} | ||
} | ||
if (!attrsArray) { | ||
attrsArray = new Array(num); | ||
} | ||
else if( attrsArray.length !== num ) { | ||
attrsArray.length = num; | ||
} | ||
return { | ||
name: name, | ||
attrsArray: attrsArray, | ||
num: num, | ||
callback: callback | ||
}; | ||
} | ||
factory.createMany = function(name, attrsArray, num, callback) { | ||
var args = parseBuildManyArgs.apply(null, arguments), | ||
results = []; | ||
callback = args.callback; | ||
args.callback = function(err, docs) { | ||
if (err) return callback(err); | ||
asyncForEach(docs, function(doc, cb, index) { | ||
save(name, doc, function(err) { | ||
if (!err) results[index] = doc; | ||
cb(err); | ||
}); | ||
}, function(err) { | ||
callback(err, results); | ||
}); | ||
}; | ||
_buildMany(args); | ||
}; | ||
factory.promisify = function(promiseLibrary) { | ||
@@ -213,2 +84,168 @@ var promisify = promiseLibrary.promisify || promiseLibrary.denodeify; | ||
}; | ||
var Builder = function() { | ||
var builder = this; | ||
builder.options = {}; | ||
builder.withOptions = function(options) { | ||
merge(builder.options, options); | ||
return builder; | ||
} | ||
builder.create = function(name, attrs, callback) { | ||
if (typeof attrs === 'function') { | ||
callback = attrs; | ||
attrs = {}; | ||
} | ||
if (!factories[name]) { | ||
return callback(new Error("No factory defined for model '" + name + "'")); | ||
} | ||
builder.build(name, attrs, function(err, doc) { | ||
if (err) return callback(err); | ||
save(name, doc, function(saveErr, saveDoc) { | ||
if(saveErr) return callback(saveErr); | ||
if (factories[name].options.afterCreate) { | ||
factories[name].options.afterCreate.call(this, saveDoc, builder.options, callback); | ||
} else { | ||
callback(saveErr, saveDoc); | ||
} | ||
}); | ||
}); | ||
}; | ||
builder.build = function(name, attrs, callback) { | ||
if (typeof attrs === 'function') { | ||
callback = attrs; | ||
attrs = {}; | ||
} | ||
if (!factories[name]) { | ||
return callback(new Error("No factory defined for model '" + name + "'")); | ||
} | ||
var model = factories[name].model; | ||
attrs = merge(copy(factories[name].attributes), attrs); | ||
asyncForEach(keys(attrs), function(key, cb) { | ||
var fn = attrs[key]; | ||
if (typeof fn === 'function') { | ||
if (!fn.length) { | ||
attrs[key] = fn.call(attrs); | ||
cb(); | ||
} | ||
else { | ||
fn.call(attrs, function(err, value) { | ||
if (err) return cb(err); | ||
attrs[key] = value; | ||
cb(); | ||
}); | ||
} | ||
} | ||
else { | ||
cb(); | ||
} | ||
}, function(err) { | ||
if (err) return callback(err); | ||
var adapter = factory.adapterFor(name), | ||
doc = adapter.build(model, attrs); | ||
callback(null, doc); | ||
}); | ||
}; | ||
builder.buildSync = function(name, attrs) { | ||
if (!factories[name]) { | ||
throw new Error("No factory defined for model '" + name + "'"); | ||
} | ||
var model = factories[name].model; | ||
attrs = merge(copy(factories[name].attributes), attrs); | ||
var names = keys(attrs); | ||
for (var i = 0; i < names.length; i++) { | ||
var key = names[i], fn = attrs[key]; | ||
if (typeof fn == 'function') { | ||
if (fn.length) { | ||
throw new Error("buildSync only supports synchronous property functions (with no arguments): the function for '" + name + "." + key + "' expects " + fn.length + " arguments"); | ||
} | ||
attrs[key] = fn.call(attrs); | ||
} | ||
} | ||
var adapter = factory.adapterFor(name); | ||
return adapter.build(model, attrs); | ||
}; | ||
builder.buildMany = function(name, attrsArray, num, callback) { | ||
var args = parseBuildManyArgs.apply(null, arguments); | ||
buildMany(args); | ||
}; | ||
builder.createMany = function(name, attrsArray, num, callback) { | ||
var args = parseBuildManyArgs.apply(null, arguments), | ||
results = []; | ||
callback = args.callback; | ||
args.callback = function(err, docs) { | ||
if (err) return callback(err); | ||
asyncForEach(docs, function(doc, cb, index) { | ||
save(name, doc, function(err) { | ||
if (!err) results[index] = doc; | ||
cb(err); | ||
}); | ||
}, function(err) { | ||
callback(err, results); | ||
}); | ||
}; | ||
buildMany(args); | ||
}; | ||
function buildMany(args) { | ||
var results = []; | ||
asyncForEach(args.attrsArray, function(attrs, cb, index) { | ||
builder.build(args.name, attrs, function(err, doc) { | ||
if (!err) results[index] = doc; | ||
cb(err); | ||
}); | ||
}, function(err) { | ||
args.callback(err, results); | ||
}); | ||
} | ||
function parseBuildManyArgs(name, attrsArray, num, callback) { | ||
if (typeof num == 'function') { // name, Array, callback | ||
callback = num; | ||
num = attrsArray.length; | ||
} | ||
if (typeof attrsArray == 'number') { // name, num, callback | ||
num = attrsArray; | ||
attrsArray = null; | ||
} | ||
if (!(attrsArray instanceof Array)) { // name, Object, num, callback | ||
if (typeof num != 'number') throw new Error("num must be specified when attrsArray is not an array"); | ||
var attrs = attrsArray; | ||
attrsArray = new Array(num); | ||
for (var i = 0; i < num; i++) { | ||
attrsArray[i] = attrs; | ||
} | ||
} | ||
if (!attrsArray) { | ||
attrsArray = new Array(num); | ||
} | ||
else if( attrsArray.length !== num ) { | ||
attrsArray.length = num; | ||
} | ||
return { | ||
name: name, | ||
attrsArray: attrsArray, | ||
num: num, | ||
callback: callback | ||
}; | ||
} | ||
function save(name, doc, callback) { | ||
var model = factories[name].model; | ||
factory.adapterFor(name).save(doc, model, function (err) { | ||
if (!err) created.push([name, doc]); | ||
callback(err, doc); | ||
}); | ||
} | ||
} | ||
}; | ||
@@ -215,0 +252,0 @@ |
@@ -6,3 +6,3 @@ { | ||
"author": "Simon Wade", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"keywords": [ | ||
@@ -32,3 +32,4 @@ "factory", | ||
"mocha": ">= 0.7.1", | ||
"should": ">= 0.4.2" | ||
"should": ">= 0.4.2", | ||
"sinon": "^1.14.1" | ||
}, | ||
@@ -35,0 +36,0 @@ "scripts": { |
@@ -5,2 +5,3 @@ /* global describe, beforeEach, afterEach */ | ||
var context = describe; | ||
var sinon = require('sinon'); | ||
@@ -151,2 +152,31 @@ describe('factory', function() { | ||
context('defined with an afterCreate handler', function() { | ||
var spy = sinon.spy(); | ||
before(function() { | ||
factory.define('job with after create', Job, { | ||
title: 'Engineer', | ||
company: 'Foobar Inc.' | ||
}, { | ||
afterCreate: function(doc, options, done) { | ||
spy.apply(null, arguments); | ||
doc.title = 'Astronaut'; | ||
done(null, doc); | ||
} | ||
}); | ||
}); | ||
it('calls afterCreate', function() { | ||
factory.create('job with after create', function(err, job) { | ||
spy.called.should.be.true; | ||
}); | ||
}); | ||
it('allows afterCreate to mutate the model', function() { | ||
factory.create('job with after create', function(err, job) { | ||
job.title.should.eql('Astronaut') | ||
}); | ||
}); | ||
}); | ||
}); | ||
@@ -261,3 +291,3 @@ | ||
job.destroyCalled.should.be.true; | ||
done(err); | ||
done(err); | ||
}); | ||
@@ -344,3 +374,52 @@ }); | ||
describe('#withOptions', function() { | ||
it('chains to expose the builder functions', function() { | ||
var builder = factory.withOptions({ key: 'value' }); | ||
builder.should.have.property('build'); | ||
builder.should.have.property('buildSync'); | ||
builder.should.have.property('buildMany'); | ||
builder.should.have.property('create'); | ||
builder.should.have.property('createMany'); | ||
var job = builder.buildSync('job', { title: 'Mechanic' }); | ||
(job instanceof Job).should.be.true; | ||
job.company.should.eql('Foobar Inc.'); | ||
job.title.should.eql('Mechanic'); | ||
}); | ||
it('passes options through to defined afterCreate handler', function() { | ||
factory.define('job with after create', Job, { | ||
title: 'Engineer', | ||
company: 'Foobar Inc.' | ||
}, { | ||
afterCreate: function(doc, options, done) { | ||
options.key.should.eql('value'); | ||
done(null, doc); | ||
} | ||
}); | ||
factory.withOptions({ key: 'value' }).create('job with after create', function() {}); | ||
}); | ||
it('allows for chaining to merge options', function() { | ||
factory.define('job with after create', Job, { | ||
title: 'Engineer', | ||
company: 'Foobar Inc.' | ||
}, { | ||
afterCreate: function(doc, options, done) { | ||
options.key.should.eql('value 2'); | ||
options.anotherKey.should.eql('value'); | ||
done(null, doc); | ||
} | ||
}); | ||
var builder = factory.withOptions({ key: 'value' }); | ||
builder.withOptions({ key: 'value 2', anotherKey: 'value' }); | ||
builder.create('job with after create', function() {}); | ||
}); | ||
}); | ||
}); | ||
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
108757
27
799
4