UNPKG

factory-js

Version:

Building JavaScript objects inspired by rosie and factory_girl

343 lines (295 loc) 9.6 kB
/*! factory-js 1.3.1 */ var Factory, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, __slice = [].slice; Factory = (function() { var Adapter; function Factory() {} Factory.Adapter = Adapter = (function() { function Adapter(factory) { this.factory = factory; } Adapter.prototype.build = function(name, attrs) { return attrs; }; Adapter.prototype.create = function(name, attrs) { return attrs; }; Adapter.prototype.push = function(name, object) { return this[name].push(object); }; return Adapter; })(); Factory.factories = {}; Factory.adapter = Factory.Adapter; Factory.clear = function() { this.factories = {}; return this.adapter = Factory.Adapter; }; Factory.reset = function() { var factory, name, _ref, _results; _ref = this.factories; _results = []; for (name in _ref) { factory = _ref[name]; _results.push(factory.sequences = {}); } return _results; }; Factory.define = function(name, block) { var definition, k; definition = new FactoryDefinition(name); if (typeof block === 'function') { block.call(definition); } else { for (k in block) { definition.attr(k, block[k]); } } return this.factories[name] = definition; }; Factory.getFactory = function(name) { var factory; factory = this.factories[name]; return factory != null ? factory : { factory: (function() { throw new Error("undefined factory \"" + name + "\""); })() }; }; Factory.getTrait = function(factory, name) { var trait; trait = factory.traits[name]; return trait != null ? trait : { trait: (function() { throw new Error("undefined trait \"" + name + "\" for factory \"" + this.name + "\""); }).call(this) }; }; Factory.abstractBuild = function(buildType, names, attrs) { var attributes, factory, name, result, traits; names = names.split(/\s+/); name = names[0]; factory = this.getFactory(name); traits = names.slice(1, +names.length + 1 || 9e9).map((function(_this) { return function(name) { return _this.getTrait(factory, name); }; })(this)); attributes = factory.attributes(attrs, traits); result = factory.build(buildType, name, attributes.withoutIgnored); traits.unshift(factory); traits.map(function(factory) { return factory.applyCallbacks(result, attributes.withIgnored); }); return result; }; Factory.abstractBuildList = function(buildType, names, list, attrs) { var _i, _results; if (typeof list === 'number') { return (function() { _results = []; for (var _i = 0; 0 <= list ? _i < list : _i > list; 0 <= list ? _i++ : _i--){ _results.push(_i); } return _results; }).apply(this).map((function(_this) { return function() { return _this.abstractBuild(buildType, names, attrs); }; })(this)); } else if (list instanceof Array) { return list.map((function(_this) { return function(listItem) { if (typeof listItem === 'string') { return _this.abstractBuild(buildType, "" + names + " " + listItem, attrs); } else if (listItem.constructor === Object) { return _this.abstractBuild(buildType, names, _this.hash.merge({}, attrs, listItem)); } else { return listItem; } }; })(this)); } }; Factory.attributes = function(names, attrs) { return this.abstractBuild('attributes', names, attrs); }; Factory.build = function(names, attrs) { return this.abstractBuild('build', names, attrs); }; Factory.create = function(names, attrs) { return this.abstractBuild('create', names, attrs); }; Factory.buildList = function(names, list, attrs) { return this.abstractBuildList('build', names, list, attrs); }; Factory.createList = function(names, list, attrs) { return this.abstractBuildList('create', names, list, attrs); }; Factory.setupForEmber = function(namespace) { if (namespace == null) { throw new Error("undefined \"" + namespace + "\""); } Factory.EmberDataAdapter = (function(_super) { __extends(EmberDataAdapter, _super); function EmberDataAdapter() { return EmberDataAdapter.__super__.constructor.apply(this, arguments); } EmberDataAdapter.prototype.build = function(name, attrs) { return Ember.run(function() { return namespace.__container__.lookup('store:main').createRecord(name, attrs); }); }; EmberDataAdapter.prototype.create = function(name, attrs) { return this.build(name, attrs); }; EmberDataAdapter.prototype.push = function(name, object) { return Ember.run((function(_this) { return function() { return _this.get(name).addObject(object); }; })(this)); }; return EmberDataAdapter; })(Factory.Adapter); return Factory.adapter = Factory.EmberDataAdapter; }; Factory.hash = { merge: function() { var dest, k, obj, objs, v, _i, _len; dest = arguments[0], objs = 2 <= arguments.length ? __slice.call(arguments, 1) : []; for (_i = 0, _len = objs.length; _i < _len; _i++) { obj = objs[_i]; for (k in obj) { v = obj[k]; dest[k] = v; } } return dest; }, evaluate: function(obj) { var k, _results; _results = []; for (k in obj) { _results.push(obj[k] = typeof obj[k] === 'function' ? obj[k]() : obj[k]); } return _results; } }; return Factory; })(); if (typeof module !== "undefined" && module !== null ? module.exports : void 0) { module.exports = Factory; } else { window.Factory = Factory; } var FactoryDefinition; FactoryDefinition = (function() { function FactoryDefinition(name) { this.name = name; this.buildAdapter = new Factory.adapter(this); this.attrs = {}; this.ignores = {}; this.sequences = {}; this.traits = {}; this.callbacks = []; } FactoryDefinition.prototype.adapter = function(adapter) { this.buildAdapter = new adapter(this); return this; }; FactoryDefinition.prototype.build = function(buildType, name, attrs) { if (this.buildAdapter[buildType]) { return this.buildAdapter[buildType](name, attrs); } else { return attrs; } }; FactoryDefinition.prototype.after = function(callback) { this.callbacks.push(callback); return this; }; FactoryDefinition.prototype.attr = function(attr, value) { this.attrs[attr] = (typeof value === 'function' ? value : function() { return value; }); return this; }; FactoryDefinition.prototype.hasMany = function(attr, factoryName) { this.ignore(attr, []); this.after(function(attributes, factory) { if (!(this[attr] instanceof Array)) { this[attr] = []; } return Factory.buildList(factoryName, attributes[attr]).forEach((function(_this) { return function(object) { return factory.buildAdapter['push'].call(_this, attr, object); }; })(this)); }); return this; }; FactoryDefinition.prototype.ignore = function(attr, value) { this.ignores[attr] = (typeof value === 'function' ? value : function() { return value; }); return this; }; FactoryDefinition.prototype.sequence = function(attr, block) { var factory; factory = this; block = block || function(i) { return i; }; this.attrs[attr] = function() { factory.sequences[attr] = factory.sequences[attr] || 0; return block.call(this, ++factory.sequences[attr]); }; return this; }; FactoryDefinition.prototype.trait = function(name, block) { var definition; definition = new FactoryDefinition(name); if (typeof block === 'function') { block.call(definition); } this.traits[name] = definition; return this; }; FactoryDefinition.prototype.attributes = function(attrs, traits) { var attr, attributes, ignoredAttributes; attributes = Factory.hash.merge({}, attrs); ignoredAttributes = {}; traits.forEach(function(trait) { var attr, _results; _results = []; for (attr in trait.attrs) { _results.push(attributes[attr] = trait.attrs[attr]); } return _results; }); for (attr in this.attrs) { if (!attributes.hasOwnProperty(attr)) { attributes[attr] = this.attrs[attr]; } } for (attr in this.ignores) { ignoredAttributes[attr] = attributes.hasOwnProperty(attr) ? attributes[attr] : this.ignores[attr]; delete attributes[attr]; } Factory.hash.evaluate(attributes); Factory.hash.evaluate(ignoredAttributes); return { withIgnored: Factory.hash.merge({}, attributes, ignoredAttributes), withoutIgnored: attributes }; }; FactoryDefinition.prototype.applyCallbacks = function(result, attributes) { return this.callbacks.forEach((function(_this) { return function(callback) { return callback.call(result, attributes, _this); }; })(this)); }; return FactoryDefinition; })();