ember-data-factory-guy 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bower.json +1 -1
- data/dist/ember-data-factory-guy.js +60 -11
- data/dist/ember-data-factory-guy.min.js +1 -1
- data/ember-data-factory-guy.gemspec +1 -1
- data/package.json +1 -1
- data/src/factory_guy.js +32 -5
- data/src/model_definition.js +28 -6
- data/tests/factory_guy_test.js +33 -0
- data/tests/support/factories/project_factory.js +7 -0
- data/tests/test_setup.js +7 -0
- data/vendor/assets/javascripts/ember_data_factory_guy.js +60 -11
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10cce63c16d71075b39d7d4b3134fc97687dd359
|
4
|
+
data.tar.gz: f8273a32c925bf4c2791e946435b89d7271fa71a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 60cb0d5dcaf087c7bc4996306c11b1775eab501cac9f1434fc77dcc9019eaf453f4a41303c802f9dea1f02f21237769b8e32191da5525c2caa5e632cbdc4e856
|
7
|
+
data.tar.gz: 79591c97aa1841f941cb4298524269286282b50f7510da8a154d784e4ddcf8afabc2bd8430a05d82f54886fa7a4e6f324a3377b557898f1d2f77c797ea095bee
|
data/bower.json
CHANGED
@@ -23,6 +23,7 @@ function MissingSequenceError(message) {
|
|
23
23
|
*/
|
24
24
|
ModelDefinition = function (model, config) {
|
25
25
|
var sequences = {};
|
26
|
+
var traits = {};
|
26
27
|
var defaultAttributes = {};
|
27
28
|
var namedModels = {};
|
28
29
|
var modelId = 1;
|
@@ -69,12 +70,17 @@ ModelDefinition = function (model, config) {
|
|
69
70
|
|
70
71
|
@param {String} name fixture name
|
71
72
|
@param {Object} opts attributes to override
|
73
|
+
@param {String} traits array of traits
|
72
74
|
@returns {Object} json
|
73
75
|
*/
|
74
|
-
this.build = function (name, opts) {
|
76
|
+
this.build = function (name, opts, traitArgs) {
|
77
|
+
var traitsObj = {}
|
78
|
+
traitArgs.forEach(function(trait) {
|
79
|
+
$.extend(traitsObj, traits[trait]);
|
80
|
+
})
|
75
81
|
var modelAttributes = namedModels[name] || {};
|
76
|
-
// merge default, modelAttributes and opts to get the rough fixture
|
77
|
-
var fixture = $.extend({}, defaultAttributes, modelAttributes, opts);
|
82
|
+
// merge default, modelAttributes, traits and opts to get the rough fixture
|
83
|
+
var fixture = $.extend({}, defaultAttributes, modelAttributes, traitsObj, opts);
|
78
84
|
// deal with attributes that are functions or objects
|
79
85
|
for (attribute in fixture) {
|
80
86
|
if (Ember.typeOf(fixture[attribute]) == 'function') {
|
@@ -98,13 +104,14 @@ ModelDefinition = function (model, config) {
|
|
98
104
|
|
99
105
|
@param {String} name model name or named model type
|
100
106
|
@param {Integer} number of fixtures to build
|
107
|
+
@param {Array} array of traits to build with
|
101
108
|
@param {Object} opts attribute options
|
102
109
|
@returns array of fixtures
|
103
110
|
*/
|
104
|
-
this.buildList = function (name, number, opts) {
|
111
|
+
this.buildList = function (name, number, traits, opts) {
|
105
112
|
var arr = [];
|
106
113
|
for (var i = 0; i < number; i++) {
|
107
|
-
arr.push(this.build(name, opts))
|
114
|
+
arr.push(this.build(name, opts, traits))
|
108
115
|
}
|
109
116
|
return arr;
|
110
117
|
}
|
@@ -124,13 +131,25 @@ ModelDefinition = function (model, config) {
|
|
124
131
|
defaultAttributes = object;
|
125
132
|
}
|
126
133
|
|
134
|
+
var parseTraits = function (object) {
|
135
|
+
if (!object) {
|
136
|
+
return
|
137
|
+
}
|
138
|
+
// for (trait in object) {
|
139
|
+
// var trait = object[trait];
|
140
|
+
// if (Ember.typeOf(trait) == 'function') {}
|
141
|
+
// object[trait] = new Trait(trait);
|
142
|
+
// }
|
143
|
+
traits = object;
|
144
|
+
}
|
145
|
+
|
127
146
|
var parseSequences = function (object) {
|
128
147
|
if (!object) {
|
129
148
|
return
|
130
149
|
}
|
131
150
|
for (sequenceName in object) {
|
132
151
|
var sequenceFn = object[sequenceName];
|
133
|
-
if (
|
152
|
+
if (Ember.typeOf(sequenceFn) != 'function') {
|
134
153
|
throw new Error('Problem with [' + sequenceName + '] sequence definition. Sequences must be functions')
|
135
154
|
}
|
136
155
|
object[sequenceName] = new Sequence(sequenceFn);
|
@@ -142,6 +161,9 @@ ModelDefinition = function (model, config) {
|
|
142
161
|
parseSequences(config.sequences);
|
143
162
|
delete config.sequences;
|
144
163
|
|
164
|
+
parseTraits(config.traits);
|
165
|
+
delete config.traits;
|
166
|
+
|
145
167
|
parseDefault(config.default);
|
146
168
|
delete config.default;
|
147
169
|
|
@@ -293,18 +315,32 @@ FactoryGuy = {
|
|
293
315
|
Build fixtures for model or specific fixture name. For example:
|
294
316
|
|
295
317
|
FactoryGuy.build('user') for User model
|
296
|
-
FactoryGuy.build('bob') for
|
318
|
+
FactoryGuy.build('bob') for a 'bob' User
|
319
|
+
FactoryGuy.build('bob', 'dude') for a 'bob' User with dude traits
|
320
|
+
FactoryGuy.build('bob', 'dude', 'funny') for a 'bob' User with dude and funny traits
|
321
|
+
FactoryGuy.build('bob', 'dude', name: 'wombat') for a 'bob' User with dude trait and custom attribute name of 'wombat'
|
297
322
|
|
298
323
|
@param {String} name Fixture name
|
324
|
+
@param {String} trait trait name ( can be more than one )
|
299
325
|
@param {Object} opts Options that will override default fixture values
|
300
326
|
@returns {Object} json fixture
|
301
327
|
*/
|
302
|
-
build: function (
|
328
|
+
build: function () {
|
329
|
+
var args = Array.prototype.slice.call(arguments);
|
330
|
+
var opts = {}
|
331
|
+
var name = args.shift();
|
332
|
+
if (!name) {
|
333
|
+
throw new Error("Build needs a factory name to build");
|
334
|
+
}
|
335
|
+
if (Ember.typeOf(args[args.length-1]) == 'object') {
|
336
|
+
opts = args.pop();
|
337
|
+
}
|
338
|
+
var traits = args; // whatever is left are traits
|
303
339
|
var definition = this.lookupDefinitionForFixtureName(name);
|
304
340
|
if (!definition) {
|
305
341
|
throw new Error("Can't find that factory named [" + name + "]");
|
306
342
|
}
|
307
|
-
return definition.build(name, opts);
|
343
|
+
return definition.build(name, opts, traits);
|
308
344
|
},
|
309
345
|
|
310
346
|
/**
|
@@ -315,15 +351,28 @@ FactoryGuy = {
|
|
315
351
|
|
316
352
|
@param {String} name fixture name
|
317
353
|
@param {Number} number number of fixtures to create
|
354
|
+
@param {String} trait (one or more)
|
318
355
|
@param {Object} opts options that will override default fixture values
|
319
356
|
@returns {Array} list of fixtures
|
320
357
|
*/
|
321
|
-
buildList: function (
|
358
|
+
buildList: function () {
|
359
|
+
var args = Array.prototype.slice.call(arguments);
|
360
|
+
var name = args.shift();
|
361
|
+
var number = args.shift();
|
362
|
+
if (!name || !number) {
|
363
|
+
throw new Error("buildList needs a name and a number ( at least ) to build with");
|
364
|
+
}
|
365
|
+
var opts = {}
|
366
|
+
if (Ember.typeOf(args[args.length-1]) == 'object') {
|
367
|
+
opts = args.pop();
|
368
|
+
}
|
369
|
+
var traits = args; // whatever is left are traits
|
370
|
+
console.log(name, number, traits+'', opts)
|
322
371
|
var definition = this.lookupDefinitionForFixtureName(name);
|
323
372
|
if (!definition) {
|
324
373
|
throw new Error("Can't find that factory named [" + name + "]");
|
325
374
|
}
|
326
|
-
return definition.buildList(name, number, opts);
|
375
|
+
return definition.buildList(name, number, traits, opts);
|
327
376
|
},
|
328
377
|
|
329
378
|
/**
|
@@ -1 +1 @@
|
|
1
|
-
Sequence=function(fn){var index=1;this.next=function(){return fn.call(this,index++)};this.reset=function(){index=1}};function MissingSequenceError(message){this.toString=function(){return message}}ModelDefinition=function(model,config){var sequences={};var defaultAttributes={};var namedModels={};var modelId=1;this.model=model;this.matchesName=function(name){return model==name||namedModels[name]};this.merge=function(config){};this.generate=function(name,sequenceFn){if(sequenceFn){if(!sequences[name]){sequences[name]=new Sequence(sequenceFn)}}var sequence=sequences[name];if(!sequence){throw new MissingSequenceError("Can not find that sequence named ["+sequenceName+"] in '"+model+"' definition")}return sequence.next()};this.build=function(name,opts){var modelAttributes=namedModels[name]||{};var fixture=$.extend({},defaultAttributes,modelAttributes,opts);for(attribute in fixture){if(Ember.typeOf(fixture[attribute])=="function"){fixture[attribute]=fixture[attribute].call(this,fixture)}else if(Ember.typeOf(fixture[attribute])=="object"){fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}if(!fixture.id){fixture.id=modelId++}return fixture};this.buildList=function(name,number,opts){var arr=[];for(var i=0;i<number;i++){arr.push(this.build(name,opts))}return arr};this.reset=function(){modelId=1;for(name in sequences){sequences[name].reset()}};var parseDefault=function(object){if(!object){return}defaultAttributes=object};var parseSequences=function(object){if(!object){return}for(sequenceName in object){var sequenceFn=object[sequenceName];if(typeof sequenceFn!="function"){throw new Error("Problem with ["+sequenceName+"] sequence definition. Sequences must be functions")}object[sequenceName]=new Sequence(sequenceFn)}sequences=object};var parseConfig=function(config){parseSequences(config.sequences);delete config.sequences;parseDefault(config.default);delete config.default;namedModels=config};parseConfig(config)};FactoryGuy={modelDefinitions:{},define:function(model,config){if(this.modelDefinitions[model]){this.modelDefinitions[model].merge(config)}else{this.modelDefinitions[model]=new ModelDefinition(model,config)}},generate:function(nameOrFunction){var sortaRandomName=Math.floor((1+Math.random())*65536).toString(16)+Date.now();return function(){if(Em.typeOf(nameOrFunction)=="function"){return this.generate(sortaRandomName,nameOrFunction)}else{return this.generate(nameOrFunction)}}},association:function(fixtureName,opts){return function(){return FactoryGuy.build(fixtureName,opts)}},lookupModelForFixtureName:function(name){var definition=this.lookupDefinitionForFixtureName(name);if(definition){return definition.model}},lookupDefinitionForFixtureName:function(name){for(model in this.modelDefinitions){var definition=this.modelDefinitions[model];if(definition.matchesName(name)){return definition}}},build:function(name,opts){var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.build(name,opts)},buildList:function(name,number,opts){var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.buildList(name,number,opts)},resetModels:function(store){for(model in this.modelDefinitions){var definition=this.modelDefinitions[model];definition.reset();try{var modelType=store.modelFor(definition.model);if(store.usingFixtureAdapter()){modelType.FIXTURES=[]}store.unloadAll(modelType)}catch(e){}}},pushFixture:function(modelClass,fixture){if(!modelClass["FIXTURES"]){modelClass["FIXTURES"]=[]}modelClass["FIXTURES"].push(fixture);return fixture},clear:function(opts){if(!opts){this.modelDefinitions={}}}};DS.Store.reopen({usingFixtureAdapter:function(){var adapter=this.adapterFor("application");return adapter instanceof DS.FixtureAdapter},makeFixture:function(name,options){var store=this;var modelName=FactoryGuy.lookupModelForFixtureName(name);var fixture=FactoryGuy.build(name,options);var modelType=store.modelFor(modelName);if(this.usingFixtureAdapter()){this.setAssociationsForFixtureAdapter(modelType,modelName,fixture);return FactoryGuy.pushFixture(modelType,fixture)}else{var store=this;var model;Em.run(function(){store.findEmbeddedBelongsToAssociationsForRESTAdapter(modelType,fixture);if(fixture.type){modelName=fixture.type.underscore();modelType=store.modelFor(modelName)}model=store.push(modelName,fixture);store.setAssociationsForRESTAdapter(modelType,modelName,model)});return model}},makeList:function(name,number,options){var arr=[];for(var i=0;i<number;i++){arr.push(this.makeFixture(name,options))}return arr},setAssociationsForFixtureAdapter:function(modelType,modelName,fixture){var self=this;var adapter=this.adapterFor("application");Ember.get(modelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="hasMany"){if(fixture[relationship.key]){fixture[relationship.key].forEach(function(id){var hasManyfixtures=adapter.fixturesForType(relationship.type);var fixture=adapter.findFixtureById(hasManyfixtures,id);fixture[modelName]=fixture.id})}}if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(belongsToRecord){if(typeof belongsToRecord=="object"){FactoryGuy.pushFixture(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord.id}var hasManyName=self.findHasManyRelationshipNameForFixtureAdapter(relationship.type,relationship.parentType);var belongsToFixtures=adapter.fixturesForType(relationship.type);var belongsTofixture=adapter.findFixtureById(belongsToFixtures,fixture[relationship.key]);if(!belongsTofixture[hasManyName]){belongsTofixture[hasManyName]=[]}belongsTofixture[hasManyName].push(fixture.id)}}})},findEmbeddedBelongsToAssociationsForRESTAdapter:function(modelType,fixture){var store=this;Ember.get(modelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(Ember.typeOf(belongsToRecord)=="object"){belongsToRecord=store.push(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord}}})},setAssociationsForRESTAdapter:function(modelType,modelName,model){var self=this;Ember.get(modelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="hasMany"){var children=model.get(name)||[];children.forEach(function(child){var belongsToName=self.findRelationshipName("belongsTo",child.constructor,model);var hasManyName=self.findRelationshipName("hasMany",child.constructor,model);var inverseName=relationship.options&&relationship.options.inverse;if(belongsToName){child.set(belongsToName||inverseName,model)}else if(hasManyName){relation=child.get(hasManyName||inverseName)||[];relation.pushObject(model)}})}if(relationship.kind=="belongsTo"){var belongsToRecord=model.get(name);if(belongsToRecord){var setAssociations=function(){var hasManyName=self.findRelationshipName("hasMany",belongsToRecord.constructor,model);if(hasManyName){belongsToRecord.get(hasManyName).addObject(model);return}var oneToOneName=self.findRelationshipName("belongsTo",belongsToRecord.constructor,model);if(oneToOneName&&!(belongsToRecord.constructor==model.constructor)){belongsToRecord.set(oneToOneName,model)}};if(belongsToRecord.then){belongsToRecord.then(function(record){belongsToRecord=record;setAssociations()})}else{setAssociations()}}}})},findRelationshipName:function(kind,belongToModelType,childModel){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind==kind&&childModel instanceof relationship.type){relationshipName=relationship.key}});return relationshipName},findHasManyRelationshipNameForFixtureAdapter:function(belongToModelType,childModelType){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="hasMany"&&childModelType==relationship.type){relationshipName=relationship.key}});return relationshipName},pushPayload:function(type,payload){if(this.usingFixtureAdapter()){var model=this.modelFor(modelName);FactoryGuy.pushFixture(model,payload)}else{this._super(type,payload)}}});DS.FixtureAdapter.reopen({createRecord:function(store,type,record){var promise=this._super(store,type,record);promise.then(function(){Em.RSVP.Promise.resolve(Ember.get(type,"relationshipNames")).then(function(relationShips){if(relationShips.belongsTo){relationShips.belongsTo.forEach(function(relationship){Em.RSVP.Promise.resolve(record.get(relationship)).then(function(belongsToRecord){if(belongsToRecord){var hasManyName=store.findRelationshipName("hasMany",belongsToRecord.constructor,record);Ember.RSVP.resolve(belongsToRecord.get(hasManyName)).then(function(relationship){relationship.addObject(record)})}})})}if(relationShips.hasMany){relationShips.hasMany.forEach(function(relationship){Em.RSVP.Promise.resolve(record.get(relationship)).then(function(belongsToRecord){if(belongsToRecord&&belongsToRecord.get("length")>0){var hasManyName=store.findRelationshipName("hasMany",belongsToRecord.constructor,record);belongsToRecord.forEach(function(child){child.get(hasManyName).addObject(record)})}})})}})});return promise}});FactoryGuyTestMixin=Em.Mixin.create({setup:function(app){this.set("container",app.__container__);return this},useFixtureAdapter:function(app){app.ApplicationAdapter=DS.FixtureAdapter;this.getStore().adapterFor("application").simulateRemoteResponse=false},usingActiveModelSerializer:function(type){var store=this.getStore();var type=store.modelFor(type);var serializer=store.serializerFor(type.typeKey);return serializer instanceof DS.ActiveModelSerializer},find:function(type,id){return this.getStore().find(type,id)},make:function(name,opts){return this.getStore().makeFixture(name,opts)},getStore:function(){return this.get("container").lookup("store:main")},pushPayload:function(type,hash){return this.getStore().pushPayload(type,hash)},pushRecord:function(type,hash){return this.getStore().push(type,hash)},stubEndpointForHttpRequest:function(url,json,options){options=options||{};var request={url:url,dataType:"json",responseText:json,type:options.type||"GET",status:options.status||200};if(options.data){request.data=options.data}$.mockjax(request)},buildAjaxHttpResponse:function(name,opts){var fixture=FactoryGuy.build(name,opts);var modelName=FactoryGuy.lookupModelForFixtureName(name);if(this.usingActiveModelSerializer(modelName)){this.toSnakeCase(fixture)}var hash={};hash[modelName]=fixture;return hash},toSnakeCase:function(fixture){for(key in fixture){if(key!=Em.String.decamelize(key)){var value=fixture[key];delete fixture[key];fixture[Em.String.decamelize(key)]=value}}},handleFind:function(name,opts,status){var modelName=FactoryGuy.lookupModelForFixtureName(name);var responseJson=this.buildAjaxHttpResponse(name,opts);var id=responseJson[modelName].id;var url="/"+Em.String.pluralize(modelName)+"/"+id;this.stubEndpointForHttpRequest(url,responseJson,{type:"GET",status:status||200});return responseJson},handleCreate:function(name,opts,status){var modelName=FactoryGuy.lookupModelForFixtureName(name);var responseJson=this.buildAjaxHttpResponse(name,opts);var url="/"+Em.String.pluralize(modelName);this.stubEndpointForHttpRequest(url,responseJson,{type:"POST",status:status||200});return responseJson},handleUpdate:function(root,id,status){this.stubEndpointForHttpRequest("/"+Em.String.pluralize(root)+"/"+id,{},{type:"PUT",status:status||200})},handleDelete:function(root,id,status){this.stubEndpointForHttpRequest("/"+Em.String.pluralize(root)+"/"+id,{},{type:"DELETE",status:status||200})},teardown:function(){FactoryGuy.resetModels(this.getStore())}});
|
1
|
+
Sequence=function(fn){var index=1;this.next=function(){return fn.call(this,index++)};this.reset=function(){index=1}};function MissingSequenceError(message){this.toString=function(){return message}}ModelDefinition=function(model,config){var sequences={};var traits={};var defaultAttributes={};var namedModels={};var modelId=1;this.model=model;this.matchesName=function(name){return model==name||namedModels[name]};this.merge=function(config){};this.generate=function(name,sequenceFn){if(sequenceFn){if(!sequences[name]){sequences[name]=new Sequence(sequenceFn)}}var sequence=sequences[name];if(!sequence){throw new MissingSequenceError("Can not find that sequence named ["+sequenceName+"] in '"+model+"' definition")}return sequence.next()};this.build=function(name,opts,traitArgs){var traitsObj={};traitArgs.forEach(function(trait){$.extend(traitsObj,traits[trait])});var modelAttributes=namedModels[name]||{};var fixture=$.extend({},defaultAttributes,modelAttributes,traitsObj,opts);for(attribute in fixture){if(Ember.typeOf(fixture[attribute])=="function"){fixture[attribute]=fixture[attribute].call(this,fixture)}else if(Ember.typeOf(fixture[attribute])=="object"){fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}if(!fixture.id){fixture.id=modelId++}return fixture};this.buildList=function(name,number,traits,opts){var arr=[];for(var i=0;i<number;i++){arr.push(this.build(name,opts,traits))}return arr};this.reset=function(){modelId=1;for(name in sequences){sequences[name].reset()}};var parseDefault=function(object){if(!object){return}defaultAttributes=object};var parseTraits=function(object){if(!object){return}traits=object};var parseSequences=function(object){if(!object){return}for(sequenceName in object){var sequenceFn=object[sequenceName];if(Ember.typeOf(sequenceFn)!="function"){throw new Error("Problem with ["+sequenceName+"] sequence definition. Sequences must be functions")}object[sequenceName]=new Sequence(sequenceFn)}sequences=object};var parseConfig=function(config){parseSequences(config.sequences);delete config.sequences;parseTraits(config.traits);delete config.traits;parseDefault(config.default);delete config.default;namedModels=config};parseConfig(config)};FactoryGuy={modelDefinitions:{},define:function(model,config){if(this.modelDefinitions[model]){this.modelDefinitions[model].merge(config)}else{this.modelDefinitions[model]=new ModelDefinition(model,config)}},generate:function(nameOrFunction){var sortaRandomName=Math.floor((1+Math.random())*65536).toString(16)+Date.now();return function(){if(Em.typeOf(nameOrFunction)=="function"){return this.generate(sortaRandomName,nameOrFunction)}else{return this.generate(nameOrFunction)}}},association:function(fixtureName,opts){return function(){return FactoryGuy.build(fixtureName,opts)}},lookupModelForFixtureName:function(name){var definition=this.lookupDefinitionForFixtureName(name);if(definition){return definition.model}},lookupDefinitionForFixtureName:function(name){for(model in this.modelDefinitions){var definition=this.modelDefinitions[model];if(definition.matchesName(name)){return definition}}},build:function(){var args=Array.prototype.slice.call(arguments);var opts={};var name=args.shift();if(!name){throw new Error("Build needs a factory name to build")}if(Ember.typeOf(args[args.length-1])=="object"){opts=args.pop()}var traits=args;var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.build(name,opts,traits)},buildList:function(){var args=Array.prototype.slice.call(arguments);var name=args.shift();var number=args.shift();if(!name||!number){throw new Error("buildList needs a name and a number ( at least ) to build with")}var opts={};if(Ember.typeOf(args[args.length-1])=="object"){opts=args.pop()}var traits=args;console.log(name,number,traits+"",opts);var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.buildList(name,number,traits,opts)},resetModels:function(store){for(model in this.modelDefinitions){var definition=this.modelDefinitions[model];definition.reset();try{var modelType=store.modelFor(definition.model);if(store.usingFixtureAdapter()){modelType.FIXTURES=[]}store.unloadAll(modelType)}catch(e){}}},pushFixture:function(modelClass,fixture){if(!modelClass["FIXTURES"]){modelClass["FIXTURES"]=[]}modelClass["FIXTURES"].push(fixture);return fixture},clear:function(opts){if(!opts){this.modelDefinitions={}}}};DS.Store.reopen({usingFixtureAdapter:function(){var adapter=this.adapterFor("application");return adapter instanceof DS.FixtureAdapter},makeFixture:function(name,options){var store=this;var modelName=FactoryGuy.lookupModelForFixtureName(name);var fixture=FactoryGuy.build(name,options);var modelType=store.modelFor(modelName);if(this.usingFixtureAdapter()){this.setAssociationsForFixtureAdapter(modelType,modelName,fixture);return FactoryGuy.pushFixture(modelType,fixture)}else{var store=this;var model;Em.run(function(){store.findEmbeddedBelongsToAssociationsForRESTAdapter(modelType,fixture);if(fixture.type){modelName=fixture.type.underscore();modelType=store.modelFor(modelName)}model=store.push(modelName,fixture);store.setAssociationsForRESTAdapter(modelType,modelName,model)});return model}},makeList:function(name,number,options){var arr=[];for(var i=0;i<number;i++){arr.push(this.makeFixture(name,options))}return arr},setAssociationsForFixtureAdapter:function(modelType,modelName,fixture){var self=this;var adapter=this.adapterFor("application");Ember.get(modelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="hasMany"){if(fixture[relationship.key]){fixture[relationship.key].forEach(function(id){var hasManyfixtures=adapter.fixturesForType(relationship.type);var fixture=adapter.findFixtureById(hasManyfixtures,id);fixture[modelName]=fixture.id})}}if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(belongsToRecord){if(typeof belongsToRecord=="object"){FactoryGuy.pushFixture(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord.id}var hasManyName=self.findHasManyRelationshipNameForFixtureAdapter(relationship.type,relationship.parentType);var belongsToFixtures=adapter.fixturesForType(relationship.type);var belongsTofixture=adapter.findFixtureById(belongsToFixtures,fixture[relationship.key]);if(!belongsTofixture[hasManyName]){belongsTofixture[hasManyName]=[]}belongsTofixture[hasManyName].push(fixture.id)}}})},findEmbeddedBelongsToAssociationsForRESTAdapter:function(modelType,fixture){var store=this;Ember.get(modelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(Ember.typeOf(belongsToRecord)=="object"){belongsToRecord=store.push(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord}}})},setAssociationsForRESTAdapter:function(modelType,modelName,model){var self=this;Ember.get(modelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="hasMany"){var children=model.get(name)||[];children.forEach(function(child){var belongsToName=self.findRelationshipName("belongsTo",child.constructor,model);var hasManyName=self.findRelationshipName("hasMany",child.constructor,model);var inverseName=relationship.options&&relationship.options.inverse;if(belongsToName){child.set(belongsToName||inverseName,model)}else if(hasManyName){relation=child.get(hasManyName||inverseName)||[];relation.pushObject(model)}})}if(relationship.kind=="belongsTo"){var belongsToRecord=model.get(name);if(belongsToRecord){var setAssociations=function(){var hasManyName=self.findRelationshipName("hasMany",belongsToRecord.constructor,model);if(hasManyName){belongsToRecord.get(hasManyName).addObject(model);return}var oneToOneName=self.findRelationshipName("belongsTo",belongsToRecord.constructor,model);if(oneToOneName&&!(belongsToRecord.constructor==model.constructor)){belongsToRecord.set(oneToOneName,model)}};if(belongsToRecord.then){belongsToRecord.then(function(record){belongsToRecord=record;setAssociations()})}else{setAssociations()}}}})},findRelationshipName:function(kind,belongToModelType,childModel){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind==kind&&childModel instanceof relationship.type){relationshipName=relationship.key}});return relationshipName},findHasManyRelationshipNameForFixtureAdapter:function(belongToModelType,childModelType){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="hasMany"&&childModelType==relationship.type){relationshipName=relationship.key}});return relationshipName},pushPayload:function(type,payload){if(this.usingFixtureAdapter()){var model=this.modelFor(modelName);FactoryGuy.pushFixture(model,payload)}else{this._super(type,payload)}}});DS.FixtureAdapter.reopen({createRecord:function(store,type,record){var promise=this._super(store,type,record);promise.then(function(){Em.RSVP.Promise.resolve(Ember.get(type,"relationshipNames")).then(function(relationShips){if(relationShips.belongsTo){relationShips.belongsTo.forEach(function(relationship){Em.RSVP.Promise.resolve(record.get(relationship)).then(function(belongsToRecord){if(belongsToRecord){var hasManyName=store.findRelationshipName("hasMany",belongsToRecord.constructor,record);Ember.RSVP.resolve(belongsToRecord.get(hasManyName)).then(function(relationship){relationship.addObject(record)})}})})}if(relationShips.hasMany){relationShips.hasMany.forEach(function(relationship){Em.RSVP.Promise.resolve(record.get(relationship)).then(function(belongsToRecord){if(belongsToRecord&&belongsToRecord.get("length")>0){var hasManyName=store.findRelationshipName("hasMany",belongsToRecord.constructor,record);belongsToRecord.forEach(function(child){child.get(hasManyName).addObject(record)})}})})}})});return promise}});FactoryGuyTestMixin=Em.Mixin.create({setup:function(app){this.set("container",app.__container__);return this},useFixtureAdapter:function(app){app.ApplicationAdapter=DS.FixtureAdapter;this.getStore().adapterFor("application").simulateRemoteResponse=false},usingActiveModelSerializer:function(type){var store=this.getStore();var type=store.modelFor(type);var serializer=store.serializerFor(type.typeKey);return serializer instanceof DS.ActiveModelSerializer},find:function(type,id){return this.getStore().find(type,id)},make:function(name,opts){return this.getStore().makeFixture(name,opts)},getStore:function(){return this.get("container").lookup("store:main")},pushPayload:function(type,hash){return this.getStore().pushPayload(type,hash)},pushRecord:function(type,hash){return this.getStore().push(type,hash)},stubEndpointForHttpRequest:function(url,json,options){options=options||{};var request={url:url,dataType:"json",responseText:json,type:options.type||"GET",status:options.status||200};if(options.data){request.data=options.data}$.mockjax(request)},buildAjaxHttpResponse:function(name,opts){var fixture=FactoryGuy.build(name,opts);var modelName=FactoryGuy.lookupModelForFixtureName(name);if(this.usingActiveModelSerializer(modelName)){this.toSnakeCase(fixture)}var hash={};hash[modelName]=fixture;return hash},toSnakeCase:function(fixture){for(key in fixture){if(key!=Em.String.decamelize(key)){var value=fixture[key];delete fixture[key];fixture[Em.String.decamelize(key)]=value}}},handleFind:function(name,opts,status){var modelName=FactoryGuy.lookupModelForFixtureName(name);var responseJson=this.buildAjaxHttpResponse(name,opts);var id=responseJson[modelName].id;var url="/"+Em.String.pluralize(modelName)+"/"+id;this.stubEndpointForHttpRequest(url,responseJson,{type:"GET",status:status||200});return responseJson},handleCreate:function(name,opts,status){var modelName=FactoryGuy.lookupModelForFixtureName(name);var responseJson=this.buildAjaxHttpResponse(name,opts);var url="/"+Em.String.pluralize(modelName);this.stubEndpointForHttpRequest(url,responseJson,{type:"POST",status:status||200});return responseJson},handleUpdate:function(root,id,status){this.stubEndpointForHttpRequest("/"+Em.String.pluralize(root)+"/"+id,{},{type:"PUT",status:status||200})},handleDelete:function(root,id,status){this.stubEndpointForHttpRequest("/"+Em.String.pluralize(root)+"/"+id,{},{type:"DELETE",status:status||200})},teardown:function(){FactoryGuy.resetModels(this.getStore())}});
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
Gem::Specification.new do |s|
|
3
3
|
s.name = "ember-data-factory-guy"
|
4
|
-
s.version = "0.
|
4
|
+
s.version = "0.5.0"
|
5
5
|
s.platform = Gem::Platform::RUBY
|
6
6
|
s.authors = ["Daniel Sudol", "Alex Opak"]
|
7
7
|
s.email = ["dansudol@yahoo.com", "opak.alexandr@gmail.com"]
|
data/package.json
CHANGED
data/src/factory_guy.js
CHANGED
@@ -140,18 +140,32 @@ FactoryGuy = {
|
|
140
140
|
Build fixtures for model or specific fixture name. For example:
|
141
141
|
|
142
142
|
FactoryGuy.build('user') for User model
|
143
|
-
FactoryGuy.build('bob') for
|
143
|
+
FactoryGuy.build('bob') for a 'bob' User
|
144
|
+
FactoryGuy.build('bob', 'dude') for a 'bob' User with dude traits
|
145
|
+
FactoryGuy.build('bob', 'dude', 'funny') for a 'bob' User with dude and funny traits
|
146
|
+
FactoryGuy.build('bob', 'dude', name: 'wombat') for a 'bob' User with dude trait and custom attribute name of 'wombat'
|
144
147
|
|
145
148
|
@param {String} name Fixture name
|
149
|
+
@param {String} trait trait name ( can be more than one )
|
146
150
|
@param {Object} opts Options that will override default fixture values
|
147
151
|
@returns {Object} json fixture
|
148
152
|
*/
|
149
|
-
build: function (
|
153
|
+
build: function () {
|
154
|
+
var args = Array.prototype.slice.call(arguments);
|
155
|
+
var opts = {}
|
156
|
+
var name = args.shift();
|
157
|
+
if (!name) {
|
158
|
+
throw new Error("Build needs a factory name to build");
|
159
|
+
}
|
160
|
+
if (Ember.typeOf(args[args.length-1]) == 'object') {
|
161
|
+
opts = args.pop();
|
162
|
+
}
|
163
|
+
var traits = args; // whatever is left are traits
|
150
164
|
var definition = this.lookupDefinitionForFixtureName(name);
|
151
165
|
if (!definition) {
|
152
166
|
throw new Error("Can't find that factory named [" + name + "]");
|
153
167
|
}
|
154
|
-
return definition.build(name, opts);
|
168
|
+
return definition.build(name, opts, traits);
|
155
169
|
},
|
156
170
|
|
157
171
|
/**
|
@@ -162,15 +176,28 @@ FactoryGuy = {
|
|
162
176
|
|
163
177
|
@param {String} name fixture name
|
164
178
|
@param {Number} number number of fixtures to create
|
179
|
+
@param {String} trait (one or more)
|
165
180
|
@param {Object} opts options that will override default fixture values
|
166
181
|
@returns {Array} list of fixtures
|
167
182
|
*/
|
168
|
-
buildList: function (
|
183
|
+
buildList: function () {
|
184
|
+
var args = Array.prototype.slice.call(arguments);
|
185
|
+
var name = args.shift();
|
186
|
+
var number = args.shift();
|
187
|
+
if (!name || !number) {
|
188
|
+
throw new Error("buildList needs a name and a number ( at least ) to build with");
|
189
|
+
}
|
190
|
+
var opts = {}
|
191
|
+
if (Ember.typeOf(args[args.length-1]) == 'object') {
|
192
|
+
opts = args.pop();
|
193
|
+
}
|
194
|
+
var traits = args; // whatever is left are traits
|
195
|
+
console.log(name, number, traits+'', opts)
|
169
196
|
var definition = this.lookupDefinitionForFixtureName(name);
|
170
197
|
if (!definition) {
|
171
198
|
throw new Error("Can't find that factory named [" + name + "]");
|
172
199
|
}
|
173
|
-
return definition.buildList(name, number, opts);
|
200
|
+
return definition.buildList(name, number, traits, opts);
|
174
201
|
},
|
175
202
|
|
176
203
|
/**
|
data/src/model_definition.js
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
*/
|
8
8
|
ModelDefinition = function (model, config) {
|
9
9
|
var sequences = {};
|
10
|
+
var traits = {};
|
10
11
|
var defaultAttributes = {};
|
11
12
|
var namedModels = {};
|
12
13
|
var modelId = 1;
|
@@ -53,12 +54,17 @@ ModelDefinition = function (model, config) {
|
|
53
54
|
|
54
55
|
@param {String} name fixture name
|
55
56
|
@param {Object} opts attributes to override
|
57
|
+
@param {String} traits array of traits
|
56
58
|
@returns {Object} json
|
57
59
|
*/
|
58
|
-
this.build = function (name, opts) {
|
60
|
+
this.build = function (name, opts, traitArgs) {
|
61
|
+
var traitsObj = {}
|
62
|
+
traitArgs.forEach(function(trait) {
|
63
|
+
$.extend(traitsObj, traits[trait]);
|
64
|
+
})
|
59
65
|
var modelAttributes = namedModels[name] || {};
|
60
|
-
// merge default, modelAttributes and opts to get the rough fixture
|
61
|
-
var fixture = $.extend({}, defaultAttributes, modelAttributes, opts);
|
66
|
+
// merge default, modelAttributes, traits and opts to get the rough fixture
|
67
|
+
var fixture = $.extend({}, defaultAttributes, modelAttributes, traitsObj, opts);
|
62
68
|
// deal with attributes that are functions or objects
|
63
69
|
for (attribute in fixture) {
|
64
70
|
if (Ember.typeOf(fixture[attribute]) == 'function') {
|
@@ -82,13 +88,14 @@ ModelDefinition = function (model, config) {
|
|
82
88
|
|
83
89
|
@param {String} name model name or named model type
|
84
90
|
@param {Integer} number of fixtures to build
|
91
|
+
@param {Array} array of traits to build with
|
85
92
|
@param {Object} opts attribute options
|
86
93
|
@returns array of fixtures
|
87
94
|
*/
|
88
|
-
this.buildList = function (name, number, opts) {
|
95
|
+
this.buildList = function (name, number, traits, opts) {
|
89
96
|
var arr = [];
|
90
97
|
for (var i = 0; i < number; i++) {
|
91
|
-
arr.push(this.build(name, opts))
|
98
|
+
arr.push(this.build(name, opts, traits));
|
92
99
|
}
|
93
100
|
return arr;
|
94
101
|
}
|
@@ -108,13 +115,25 @@ ModelDefinition = function (model, config) {
|
|
108
115
|
defaultAttributes = object;
|
109
116
|
}
|
110
117
|
|
118
|
+
var parseTraits = function (object) {
|
119
|
+
if (!object) {
|
120
|
+
return
|
121
|
+
}
|
122
|
+
// for (trait in object) {
|
123
|
+
// var trait = object[trait];
|
124
|
+
// if (Ember.typeOf(trait) == 'function') {}
|
125
|
+
// object[trait] = new Trait(trait);
|
126
|
+
// }
|
127
|
+
traits = object;
|
128
|
+
}
|
129
|
+
|
111
130
|
var parseSequences = function (object) {
|
112
131
|
if (!object) {
|
113
132
|
return
|
114
133
|
}
|
115
134
|
for (sequenceName in object) {
|
116
135
|
var sequenceFn = object[sequenceName];
|
117
|
-
if (
|
136
|
+
if (Ember.typeOf(sequenceFn) != 'function') {
|
118
137
|
throw new Error('Problem with [' + sequenceName + '] sequence definition. Sequences must be functions')
|
119
138
|
}
|
120
139
|
object[sequenceName] = new Sequence(sequenceFn);
|
@@ -126,6 +145,9 @@ ModelDefinition = function (model, config) {
|
|
126
145
|
parseSequences(config.sequences);
|
127
146
|
delete config.sequences;
|
128
147
|
|
148
|
+
parseTraits(config.traits);
|
149
|
+
delete config.traits;
|
150
|
+
|
129
151
|
parseDefault(config.default);
|
130
152
|
delete config.default;
|
131
153
|
|
data/tests/factory_guy_test.js
CHANGED
@@ -100,6 +100,30 @@ test("Using associations in attribute definition", function() {
|
|
100
100
|
});
|
101
101
|
|
102
102
|
|
103
|
+
test("#build with traits", function() {
|
104
|
+
var json = FactoryGuy.build('project', 'big');
|
105
|
+
deepEqual(json, {id: 1, title: 'Big Project'}, 'trait with model attributes');
|
106
|
+
|
107
|
+
var json = FactoryGuy.build('project', 'with_user');
|
108
|
+
deepEqual(json, {id: 2, title: 'Project1', user: {id: 1, name: 'User1'}}, 'trait with belongsTo attributes');
|
109
|
+
|
110
|
+
var json = FactoryGuy.build('project', 'big', 'with_user');
|
111
|
+
deepEqual(json, {id: 3, title: 'Big Project', user: {id: 2, name: 'User1'}}, 'more than one trait used together');
|
112
|
+
|
113
|
+
var json = FactoryGuy.build('project', 'big', 'with_user', {title: 'Crazy Project'});
|
114
|
+
deepEqual(json, {id: 4, title: 'Crazy Project', user: {id: 3, name: 'User1'}}, 'more than one trait used together with custom attributes');
|
115
|
+
|
116
|
+
var json = FactoryGuy.build('project', 'big', 'with_dude');
|
117
|
+
deepEqual(json, {id: 5, title: 'Big Project', user: {id: 4, name: 'Dude'}}, 'trait with custom belongsTo association object');
|
118
|
+
|
119
|
+
var json = FactoryGuy.build('project', 'with_admin');
|
120
|
+
deepEqual(json, {id: 6, title: 'Project2', user: {id: 5, name: 'Admin'}}, 'trait with attribute using FactoryGuy.association method');
|
121
|
+
|
122
|
+
var json = FactoryGuy.build('project', 'with_title_sequence');
|
123
|
+
deepEqual(json, {id: 7, title: 'Project3'}, 'trait with attribute using sequence');
|
124
|
+
});
|
125
|
+
|
126
|
+
|
103
127
|
test("#build creates default json for model", function() {
|
104
128
|
var json = FactoryGuy.build('user');
|
105
129
|
deepEqual(json, {id: 1, name: 'User1'});
|
@@ -138,6 +162,15 @@ test("#buildList creates list of fixtures", function() {
|
|
138
162
|
var userList = FactoryGuy.buildList('user', 2);
|
139
163
|
deepEqual(userList[0], {id: 1, name: 'User1'});
|
140
164
|
deepEqual(userList[1], {id: 2, name: 'User1'});
|
165
|
+
|
166
|
+
var userList = FactoryGuy.buildList('user', 1, {name: 'Crazy'});
|
167
|
+
deepEqual(userList[0], {id: 3, name: 'Crazy'},'using custom attributes');
|
168
|
+
|
169
|
+
var projectList = FactoryGuy.buildList('project', 1, 'big');
|
170
|
+
deepEqual(projectList[0], {id: 1, title: 'Big Project'}, 'using traits');
|
171
|
+
|
172
|
+
var projectList = FactoryGuy.buildList('project', 1, 'big', {title: 'Really Big'});
|
173
|
+
deepEqual(projectList[0], {id: 2, title: 'Really Big'}, 'using traits and custom attributes');
|
141
174
|
});
|
142
175
|
|
143
176
|
|
@@ -2,6 +2,13 @@ FactoryGuy.define('project', {
|
|
2
2
|
sequences: {
|
3
3
|
title: function(num) {return 'Project' + num}
|
4
4
|
},
|
5
|
+
traits: {
|
6
|
+
big: { title: 'Big Project' },
|
7
|
+
with_title_sequence: { title: FactoryGuy.generate('title') },
|
8
|
+
with_user: { user: {} },
|
9
|
+
with_dude: { user: {name: 'Dude'} },
|
10
|
+
with_admin: { user: FactoryGuy.association('admin') }
|
11
|
+
},
|
5
12
|
default: {
|
6
13
|
title: FactoryGuy.generate('title')
|
7
14
|
},
|
data/tests/test_setup.js
CHANGED
@@ -29,6 +29,13 @@ FactoryGuy.define('project', {
|
|
29
29
|
sequences: {
|
30
30
|
title: function(num) {return 'Project' + num}
|
31
31
|
},
|
32
|
+
traits: {
|
33
|
+
big: { title: 'Big Project' },
|
34
|
+
with_title_sequence: { title: FactoryGuy.generate('title') },
|
35
|
+
with_user: { user: {} },
|
36
|
+
with_dude: { user: {name: 'Dude'} },
|
37
|
+
with_admin: { user: FactoryGuy.association('admin') }
|
38
|
+
},
|
32
39
|
default: {
|
33
40
|
title: FactoryGuy.generate('title')
|
34
41
|
},
|
@@ -23,6 +23,7 @@ function MissingSequenceError(message) {
|
|
23
23
|
*/
|
24
24
|
ModelDefinition = function (model, config) {
|
25
25
|
var sequences = {};
|
26
|
+
var traits = {};
|
26
27
|
var defaultAttributes = {};
|
27
28
|
var namedModels = {};
|
28
29
|
var modelId = 1;
|
@@ -69,12 +70,17 @@ ModelDefinition = function (model, config) {
|
|
69
70
|
|
70
71
|
@param {String} name fixture name
|
71
72
|
@param {Object} opts attributes to override
|
73
|
+
@param {String} traits array of traits
|
72
74
|
@returns {Object} json
|
73
75
|
*/
|
74
|
-
this.build = function (name, opts) {
|
76
|
+
this.build = function (name, opts, traitArgs) {
|
77
|
+
var traitsObj = {}
|
78
|
+
traitArgs.forEach(function(trait) {
|
79
|
+
$.extend(traitsObj, traits[trait]);
|
80
|
+
})
|
75
81
|
var modelAttributes = namedModels[name] || {};
|
76
|
-
// merge default, modelAttributes and opts to get the rough fixture
|
77
|
-
var fixture = $.extend({}, defaultAttributes, modelAttributes, opts);
|
82
|
+
// merge default, modelAttributes, traits and opts to get the rough fixture
|
83
|
+
var fixture = $.extend({}, defaultAttributes, modelAttributes, traitsObj, opts);
|
78
84
|
// deal with attributes that are functions or objects
|
79
85
|
for (attribute in fixture) {
|
80
86
|
if (Ember.typeOf(fixture[attribute]) == 'function') {
|
@@ -98,13 +104,14 @@ ModelDefinition = function (model, config) {
|
|
98
104
|
|
99
105
|
@param {String} name model name or named model type
|
100
106
|
@param {Integer} number of fixtures to build
|
107
|
+
@param {Array} array of traits to build with
|
101
108
|
@param {Object} opts attribute options
|
102
109
|
@returns array of fixtures
|
103
110
|
*/
|
104
|
-
this.buildList = function (name, number, opts) {
|
111
|
+
this.buildList = function (name, number, traits, opts) {
|
105
112
|
var arr = [];
|
106
113
|
for (var i = 0; i < number; i++) {
|
107
|
-
arr.push(this.build(name, opts))
|
114
|
+
arr.push(this.build(name, opts, traits))
|
108
115
|
}
|
109
116
|
return arr;
|
110
117
|
}
|
@@ -124,13 +131,25 @@ ModelDefinition = function (model, config) {
|
|
124
131
|
defaultAttributes = object;
|
125
132
|
}
|
126
133
|
|
134
|
+
var parseTraits = function (object) {
|
135
|
+
if (!object) {
|
136
|
+
return
|
137
|
+
}
|
138
|
+
// for (trait in object) {
|
139
|
+
// var trait = object[trait];
|
140
|
+
// if (Ember.typeOf(trait) == 'function') {}
|
141
|
+
// object[trait] = new Trait(trait);
|
142
|
+
// }
|
143
|
+
traits = object;
|
144
|
+
}
|
145
|
+
|
127
146
|
var parseSequences = function (object) {
|
128
147
|
if (!object) {
|
129
148
|
return
|
130
149
|
}
|
131
150
|
for (sequenceName in object) {
|
132
151
|
var sequenceFn = object[sequenceName];
|
133
|
-
if (
|
152
|
+
if (Ember.typeOf(sequenceFn) != 'function') {
|
134
153
|
throw new Error('Problem with [' + sequenceName + '] sequence definition. Sequences must be functions')
|
135
154
|
}
|
136
155
|
object[sequenceName] = new Sequence(sequenceFn);
|
@@ -142,6 +161,9 @@ ModelDefinition = function (model, config) {
|
|
142
161
|
parseSequences(config.sequences);
|
143
162
|
delete config.sequences;
|
144
163
|
|
164
|
+
parseTraits(config.traits);
|
165
|
+
delete config.traits;
|
166
|
+
|
145
167
|
parseDefault(config.default);
|
146
168
|
delete config.default;
|
147
169
|
|
@@ -293,18 +315,32 @@ FactoryGuy = {
|
|
293
315
|
Build fixtures for model or specific fixture name. For example:
|
294
316
|
|
295
317
|
FactoryGuy.build('user') for User model
|
296
|
-
FactoryGuy.build('bob') for
|
318
|
+
FactoryGuy.build('bob') for a 'bob' User
|
319
|
+
FactoryGuy.build('bob', 'dude') for a 'bob' User with dude traits
|
320
|
+
FactoryGuy.build('bob', 'dude', 'funny') for a 'bob' User with dude and funny traits
|
321
|
+
FactoryGuy.build('bob', 'dude', name: 'wombat') for a 'bob' User with dude trait and custom attribute name of 'wombat'
|
297
322
|
|
298
323
|
@param {String} name Fixture name
|
324
|
+
@param {String} trait trait name ( can be more than one )
|
299
325
|
@param {Object} opts Options that will override default fixture values
|
300
326
|
@returns {Object} json fixture
|
301
327
|
*/
|
302
|
-
build: function (
|
328
|
+
build: function () {
|
329
|
+
var args = Array.prototype.slice.call(arguments);
|
330
|
+
var opts = {}
|
331
|
+
var name = args.shift();
|
332
|
+
if (!name) {
|
333
|
+
throw new Error("Build needs a factory name to build");
|
334
|
+
}
|
335
|
+
if (Ember.typeOf(args[args.length-1]) == 'object') {
|
336
|
+
opts = args.pop();
|
337
|
+
}
|
338
|
+
var traits = args; // whatever is left are traits
|
303
339
|
var definition = this.lookupDefinitionForFixtureName(name);
|
304
340
|
if (!definition) {
|
305
341
|
throw new Error("Can't find that factory named [" + name + "]");
|
306
342
|
}
|
307
|
-
return definition.build(name, opts);
|
343
|
+
return definition.build(name, opts, traits);
|
308
344
|
},
|
309
345
|
|
310
346
|
/**
|
@@ -315,15 +351,28 @@ FactoryGuy = {
|
|
315
351
|
|
316
352
|
@param {String} name fixture name
|
317
353
|
@param {Number} number number of fixtures to create
|
354
|
+
@param {String} trait (one or more)
|
318
355
|
@param {Object} opts options that will override default fixture values
|
319
356
|
@returns {Array} list of fixtures
|
320
357
|
*/
|
321
|
-
buildList: function (
|
358
|
+
buildList: function () {
|
359
|
+
var args = Array.prototype.slice.call(arguments);
|
360
|
+
var name = args.shift();
|
361
|
+
var number = args.shift();
|
362
|
+
if (!name || !number) {
|
363
|
+
throw new Error("buildList needs a name and a number ( at least ) to build with");
|
364
|
+
}
|
365
|
+
var opts = {}
|
366
|
+
if (Ember.typeOf(args[args.length-1]) == 'object') {
|
367
|
+
opts = args.pop();
|
368
|
+
}
|
369
|
+
var traits = args; // whatever is left are traits
|
370
|
+
console.log(name, number, traits+'', opts)
|
322
371
|
var definition = this.lookupDefinitionForFixtureName(name);
|
323
372
|
if (!definition) {
|
324
373
|
throw new Error("Can't find that factory named [" + name + "]");
|
325
374
|
}
|
326
|
-
return definition.buildList(name, number, opts);
|
375
|
+
return definition.buildList(name, number, traits, opts);
|
327
376
|
},
|
328
377
|
|
329
378
|
/**
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ember-data-factory-guy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Sudol
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-08-01 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Easily create Fixtures for Ember Data
|
15
15
|
email:
|