ember-data-factory-guy 0.8.7 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gruntfile.js +1 -1
- data/README.md +83 -68
- data/bower.json +1 -1
- data/dist/amd/factory-guy.js +75 -13
- data/dist/ember-data-factory-guy.js +75 -13
- 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 +38 -0
- data/src/factory_guy_test_mixin.js +25 -11
- data/src/model_definition.js +12 -2
- data/tests/active_model_adapter_factory_test.js +61 -52
- data/tests/factory_guy_test.js +52 -3
- data/tests/factory_guy_test_mixin_test.js +46 -11
- data/tests/rest_adapter_factory_test.js +58 -50
- data/tests/support/models/user.js +1 -0
- data/tests/support/test_helper.js +14 -0
- data/tests/test_setup.js +104 -103
- data/vendor/assets/javascripts/ember_data_factory_guy.js +78 -17
- metadata +7 -7
@@ -90,9 +90,19 @@ var ModelDefinition = function (model, config) {
|
|
90
90
|
// function might be a sequence of a named association
|
91
91
|
fixture[attribute] = fixture[attribute].call(this, fixture);
|
92
92
|
} else if (Ember.typeOf(fixture[attribute]) == 'object') {
|
93
|
-
//
|
93
|
+
// If it's an object and it's a model association attribute, build the json
|
94
94
|
// for the association and replace the attribute with that json
|
95
|
-
|
95
|
+
if (FactoryGuy.getStore()) {
|
96
|
+
if (FactoryGuy.isAttributeRelationship(this.model, attribute)) {
|
97
|
+
fixture[attribute] = FactoryGuy.build(attribute, fixture[attribute]);
|
98
|
+
}
|
99
|
+
} else {
|
100
|
+
// For legacy reasons, if the store is not set in FactoryGuy, keep
|
101
|
+
// this code the way it is ( though it will cause failures when the object is actually
|
102
|
+
// a custom attribute and not a relationship ), while users start setting the store
|
103
|
+
// in FactoryGuy, or using testHelper.make instead of store.makeFixture
|
104
|
+
fixture[attribute] = FactoryGuy.build(attribute, fixture[attribute]);
|
105
|
+
}
|
96
106
|
}
|
97
107
|
}
|
98
108
|
// set the id, unless it was already set in opts
|
@@ -213,6 +223,44 @@ var FactoryGuy = {
|
|
213
223
|
this.modelDefinitions[model] = new ModelDefinition(model, config);
|
214
224
|
}
|
215
225
|
},
|
226
|
+
/**
|
227
|
+
Setting the store so FactoryGuy can do some model introspection.
|
228
|
+
*/
|
229
|
+
setStore: function(store) {
|
230
|
+
Ember.assert("FactoryGuy#setStore needs a valid store instance.You passed in ["+store+"]",store instanceof DS.Store)
|
231
|
+
this.store = store;
|
232
|
+
},
|
233
|
+
getStore: function() {
|
234
|
+
return this.store;
|
235
|
+
},
|
236
|
+
/**
|
237
|
+
Checks a model's attribute to determine if it's a relationship.
|
238
|
+
|
239
|
+
@param {String} typeName model type name like 'user' for User model class
|
240
|
+
@param {String} attribute attribute you want to check
|
241
|
+
@returns {Boolean} true if the attribute is a relationship, false if not
|
242
|
+
*/
|
243
|
+
isAttributeRelationship: function(typeName, attribute) {
|
244
|
+
if (!this.store) {
|
245
|
+
console.log("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures")
|
246
|
+
// The legacy value was true.
|
247
|
+
return true;
|
248
|
+
}
|
249
|
+
var model = this.store.modelFor(typeName);
|
250
|
+
return !!model.typeForRelationship(attribute);
|
251
|
+
},
|
252
|
+
/**
|
253
|
+
Make new fixture and save to store. Proxy to store#makeFixture method
|
254
|
+
|
255
|
+
@param {String} name fixture name
|
256
|
+
@param {String} trait optional trait names ( one or more )
|
257
|
+
@param {Object} opts optional fixture options that will override default fixture values
|
258
|
+
@returns {Object|DS.Model} json or record depending on the adapter type
|
259
|
+
*/
|
260
|
+
make: function() {
|
261
|
+
Ember.assert("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures", this.store);
|
262
|
+
return this.store.makeFixture.apply(this.store,arguments);
|
263
|
+
},
|
216
264
|
/**
|
217
265
|
Used in model definitions to declare use of a sequence. For example:
|
218
266
|
|
@@ -736,6 +784,7 @@ var FactoryGuyTestMixin = Em.Mixin.create({
|
|
736
784
|
// Pass in the app root, which typically is App.
|
737
785
|
setup: function (app) {
|
738
786
|
this.set('container', app.__container__);
|
787
|
+
FactoryGuy.setStore(this.getStore());
|
739
788
|
return this;
|
740
789
|
},
|
741
790
|
useFixtureAdapter: function (app) {
|
@@ -763,8 +812,7 @@ var FactoryGuyTestMixin = Em.Mixin.create({
|
|
763
812
|
return this.getStore().find(type, id);
|
764
813
|
},
|
765
814
|
/**
|
766
|
-
Proxy to store
|
767
|
-
|
815
|
+
Make new fixture and save to store. Proxy to store#makeFixture method
|
768
816
|
*/
|
769
817
|
make: function () {
|
770
818
|
var store = this.getStore();
|
@@ -773,12 +821,6 @@ var FactoryGuyTestMixin = Em.Mixin.create({
|
|
773
821
|
getStore: function () {
|
774
822
|
return this.get('container').lookup('store:main');
|
775
823
|
},
|
776
|
-
pushPayload: function (type, hash) {
|
777
|
-
return this.getStore().pushPayload(type, hash);
|
778
|
-
},
|
779
|
-
pushRecord: function (type, hash) {
|
780
|
-
return this.getStore().push(type, hash);
|
781
|
-
},
|
782
824
|
/**
|
783
825
|
Using mockjax to stub an http request.
|
784
826
|
|
@@ -855,7 +897,10 @@ var FactoryGuyTestMixin = Em.Mixin.create({
|
|
855
897
|
so you don't need to include them in the returns hash as well.
|
856
898
|
|
857
899
|
2) If you don't use match options for exact match, there will be no id returned to the model.
|
858
|
-
|
900
|
+
The reason being, that this method purposely returns an empty hash response with a 'don't match'
|
901
|
+
style handleCreate, because if the responseJson returns a non empty data hash ( with even only
|
902
|
+
the id), this essentially empty hash of attributes will override ( and nullify ) all the attributes
|
903
|
+
that set when you created the record.
|
859
904
|
3) If you match on a belongsTo association, you don't have to include that in the
|
860
905
|
returns hash.
|
861
906
|
|
@@ -908,8 +953,25 @@ var FactoryGuyTestMixin = Em.Mixin.create({
|
|
908
953
|
@param {Boolean} succeed optional flag to indicate if the request
|
909
954
|
should succeed ( default is true )
|
910
955
|
*/
|
911
|
-
handleUpdate: function (
|
912
|
-
|
956
|
+
handleUpdate: function () {
|
957
|
+
var args = Array.prototype.slice.call(arguments)
|
958
|
+
Ember.assert("To handleUpdate pass in a model instance or a type and an id", args.length>0)
|
959
|
+
var succeed = true;
|
960
|
+
if (typeof args[args.length-1] == 'boolean') {
|
961
|
+
args.pop()
|
962
|
+
succeed = false;
|
963
|
+
}
|
964
|
+
Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0)
|
965
|
+
var type, id;
|
966
|
+
if (args[0] instanceof DS.Model) {
|
967
|
+
var model = args[0];
|
968
|
+
type = model.constructor.typeKey;
|
969
|
+
id = model.id;
|
970
|
+
} else if (typeof args[0] == "string" && typeof parseInt(args[1]) == "number") {
|
971
|
+
type = args[0];
|
972
|
+
id = args[1];
|
973
|
+
}
|
974
|
+
Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id)
|
913
975
|
this.stubEndpointForHttpRequest(this.buildURL(type, id), {}, {
|
914
976
|
type: 'PUT',
|
915
977
|
status: succeed ? 200 : 500
|
@@ -1 +1 @@
|
|
1
|
-
var Sequence=function(fn){var index=1;this.next=function(){return fn.call(this,index++)};this.reset=function(){index=1}};var MissingSequenceError=function(message){this.toString=function(){return message}};if(FactoryGuy!==undefined){FactoryGuy.sequence=Sequence;FactoryGuy.missingSequenceError=MissingSequenceError}var ModelDefinition=function(model,config){var sequences={};var traits={};var defaultAttributes={};var namedModels={};var modelId=1;var sequenceName=null;this.model=model;this.matchesName=function(name){return model==name||namedModels[name]};this.nextId=function(){return modelId++};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(var 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=this.nextId()}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(var 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)};if(FactoryGuy!==undefined){FactoryGuy.modelDefiniton=ModelDefinition}var 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)}}},belongsTo:function(fixtureName,opts){return function(){return FactoryGuy.build(fixtureName,opts)}},association:function(fixtureName,opts){console.log("DEPRECATION Warning: use FactoryGuy.belongsTo instead");return this.belongsTo(fixtureName,opts)},hasMany:function(fixtureName,number,opts){return function(){return FactoryGuy.buildList(fixtureName,number,opts)}},lookupModelForFixtureName:function(name){var definition=this.lookupDefinitionForFixtureName(name);if(definition){return definition.model}},lookupDefinitionForFixtureName:function(name){for(var 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;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(var 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){console.log("resetModels",e)}}},pushFixture:function(modelClass,fixture){var index;if(!modelClass.FIXTURES){modelClass.FIXTURES=[]}index=this.indexOfFixture(modelClass.FIXTURES,fixture);if(index>-1){modelClass.FIXTURES.splice(index,1)}modelClass.FIXTURES.push(fixture);return fixture},indexOfFixture:function(fixtures,fixture){var index=-1,id=fixture.id+"";Ember.A(fixtures).find(function(r,i){if(""+Ember.get(r,"id")===id){index=i;return true}else{return false}});return index},clear:function(opts){if(!opts){this.modelDefinitions={}}}};(function(){DS.Store.reopen({usingFixtureAdapter:function(){var adapter=this.adapterFor("application");return adapter instanceof DS.FixtureAdapter},makeFixture:function(){var store=this;var fixture=FactoryGuy.build.apply(FactoryGuy,arguments);var name=arguments[0];var modelName=FactoryGuy.lookupModelForFixtureName(name);var modelType=store.modelFor(modelName);if(this.usingFixtureAdapter()){this.setAssociationsForFixtureAdapter(modelType,modelName,fixture);return FactoryGuy.pushFixture(modelType,fixture)}else{return store.makeModel(modelType,fixture)}},makeModel:function(modelType,fixture){var store=this,modelName=store.modelFor(modelType).typeKey,model;Em.run(function(){store.findEmbeddedAssociationsForRESTAdapter(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(){var arr=[];var number=arguments[1];for(var i=0;i<number;i++){arr.push(this.makeFixture.apply(this,arguments))}return arr},setAssociationsForFixtureAdapter:function(modelType,modelName,fixture){var self=this;var adapter=this.adapterFor("application");Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="hasMany"){var hasManyRelation=fixture[relationship.key];if(hasManyRelation){$.each(fixture[relationship.key],function(index,object){var id=object;if(Ember.typeOf(object)=="object"){id=object.id;hasManyRelation[index]=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)}}})},findEmbeddedAssociationsForRESTAdapter:function(modelType,fixture){var store=this;Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(Ember.typeOf(belongsToRecord)=="object"){store.findEmbeddedAssociationsForRESTAdapter(relationship.type,belongsToRecord);belongsToRecord=store.push(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord}}if(relationship.kind=="hasMany"){var hasManyRecords=fixture[relationship.key];if(Ember.typeOf(hasManyRecords)=="array"){if(Ember.typeOf(hasManyRecords[0])=="object"){var records=Em.A();hasManyRecords.map(function(object){store.findEmbeddedAssociationsForRESTAdapter(relationship.type,object);var record=store.push(relationship.type,object);records.push(record);return record});fixture[relationship.key]=records}}}})},setAssociationsForRESTAdapter:function(modelType,modelName,model){var self=this;Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="hasMany"){var children=model.get(name)||[];children.forEach(function(child){var belongsToName=self.findRelationshipName("belongsTo",child.constructor,model);if(belongsToName){child.set(belongsToName,model)}})}})},findRelationshipName:function(kind,belongToModelType,childModel){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(relationship,name){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(relationship,name){if(relationship.kind=="hasMany"&&childModelType==relationship.type){relationshipName=relationship.key}});return relationshipName},pushPayload:function(type,payload){if(this.usingFixtureAdapter()){var model=this.modelFor(type);FactoryGuy.pushFixture(model,payload)}else{this._super(type,payload)}}})})();var 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 modelType=store.modelFor(type);var serializer=store.serializerFor(modelType.typeKey);return serializer instanceof DS.ActiveModelSerializer},find:function(type,id){return this.getStore().find(type,id)},make:function(){var store=this.getStore();return store.makeFixture.apply(store,arguments)},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)},buildURL:function(typeName,id){var type=this.getStore().modelFor(typeName);return this.getStore().adapterFor(type).buildURL(type.typeKey,id)},handleFindMany:function(){var store=this.getStore();store.makeList.apply(store,arguments);var name=arguments[0];var modelName=FactoryGuy.lookupModelForFixtureName(name);var responseJson={};responseJson[modelName]=[];var url=this.buildURL(modelName);this.stubEndpointForHttpRequest(url,responseJson,{type:"GET"})},handleCreate:function(modelName,options){var opts=options===undefined?{}:options;var succeed=opts.succeed===undefined?true:opts.succeed;var match=opts.match||{};var returnArgs=opts.returns||{};var url=this.buildURL(modelName);var definition=FactoryGuy.modelDefinitions[modelName];var httpOptions={type:"POST"};if(opts.match){var expectedRequest={};var record=this.getStore().createRecord(modelName,match);expectedRequest[modelName]=record.serialize();httpOptions.data=JSON.stringify(expectedRequest)}var modelType=this.getStore().modelFor(modelName);var responseJson={};if(succeed){if(options){responseJson[modelName]=$.extend({id:definition.nextId()},match,returnArgs);Ember.get(modelType,"relationshipsByName").forEach(function(relationship){if(relationship.kind=="belongsTo"){delete responseJson[modelName][relationship.key]}})}}else{httpOptions.status=500}this.stubEndpointForHttpRequest(url,responseJson,httpOptions)},handleUpdate:function(type,id,succeed){succeed=succeed===undefined?true:succeed;this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"PUT",status:succeed?200:500})},handleDelete:function(type,id,succeed){succeed=succeed===undefined?true:succeed;this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"DELETE",status:succeed?200:500})},teardown:function(){FactoryGuy.resetModels(this.getStore());$.mockjax.clear()}});if(FactoryGuy!==undefined){FactoryGuy.testMixin=FactoryGuyTestMixin}
|
1
|
+
var Sequence=function(fn){var index=1;this.next=function(){return fn.call(this,index++)};this.reset=function(){index=1}};var MissingSequenceError=function(message){this.toString=function(){return message}};if(FactoryGuy!==undefined){FactoryGuy.sequence=Sequence;FactoryGuy.missingSequenceError=MissingSequenceError}var ModelDefinition=function(model,config){var sequences={};var traits={};var defaultAttributes={};var namedModels={};var modelId=1;var sequenceName=null;this.model=model;this.matchesName=function(name){return model==name||namedModels[name]};this.nextId=function(){return modelId++};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(var attribute in fixture){if(Ember.typeOf(fixture[attribute])=="function"){fixture[attribute]=fixture[attribute].call(this,fixture)}else if(Ember.typeOf(fixture[attribute])=="object"){if(FactoryGuy.getStore()){if(FactoryGuy.isAttributeRelationship(this.model,attribute)){fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}else{fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}}if(!fixture.id){fixture.id=this.nextId()}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(var 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)};if(FactoryGuy!==undefined){FactoryGuy.modelDefiniton=ModelDefinition}var FactoryGuy={modelDefinitions:{},define:function(model,config){if(this.modelDefinitions[model]){this.modelDefinitions[model].merge(config)}else{this.modelDefinitions[model]=new ModelDefinition(model,config)}},setStore:function(store){Ember.assert("FactoryGuy#setStore needs a valid store instance.You passed in ["+store+"]",store instanceof DS.Store);this.store=store},getStore:function(){return this.store},isAttributeRelationship:function(typeName,attribute){if(!this.store){console.log("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures");return true}var model=this.store.modelFor(typeName);return!!model.typeForRelationship(attribute)},make:function(){Ember.assert("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures",this.store);return this.store.makeFixture.apply(this.store,arguments)},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)}}},belongsTo:function(fixtureName,opts){return function(){return FactoryGuy.build(fixtureName,opts)}},association:function(fixtureName,opts){console.log("DEPRECATION Warning: use FactoryGuy.belongsTo instead");return this.belongsTo(fixtureName,opts)},hasMany:function(fixtureName,number,opts){return function(){return FactoryGuy.buildList(fixtureName,number,opts)}},lookupModelForFixtureName:function(name){var definition=this.lookupDefinitionForFixtureName(name);if(definition){return definition.model}},lookupDefinitionForFixtureName:function(name){for(var 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;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(var 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){console.log("resetModels",e)}}},pushFixture:function(modelClass,fixture){var index;if(!modelClass.FIXTURES){modelClass.FIXTURES=[]}index=this.indexOfFixture(modelClass.FIXTURES,fixture);if(index>-1){modelClass.FIXTURES.splice(index,1)}modelClass.FIXTURES.push(fixture);return fixture},indexOfFixture:function(fixtures,fixture){var index=-1,id=fixture.id+"";Ember.A(fixtures).find(function(r,i){if(""+Ember.get(r,"id")===id){index=i;return true}else{return false}});return index},clear:function(opts){if(!opts){this.modelDefinitions={}}}};(function(){DS.Store.reopen({usingFixtureAdapter:function(){var adapter=this.adapterFor("application");return adapter instanceof DS.FixtureAdapter},makeFixture:function(){var store=this;var fixture=FactoryGuy.build.apply(FactoryGuy,arguments);var name=arguments[0];var modelName=FactoryGuy.lookupModelForFixtureName(name);var modelType=store.modelFor(modelName);if(this.usingFixtureAdapter()){this.setAssociationsForFixtureAdapter(modelType,modelName,fixture);return FactoryGuy.pushFixture(modelType,fixture)}else{return store.makeModel(modelType,fixture)}},makeModel:function(modelType,fixture){var store=this,modelName=store.modelFor(modelType).typeKey,model;Em.run(function(){store.findEmbeddedAssociationsForRESTAdapter(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(){var arr=[];var number=arguments[1];for(var i=0;i<number;i++){arr.push(this.makeFixture.apply(this,arguments))}return arr},setAssociationsForFixtureAdapter:function(modelType,modelName,fixture){var self=this;var adapter=this.adapterFor("application");Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="hasMany"){var hasManyRelation=fixture[relationship.key];if(hasManyRelation){$.each(fixture[relationship.key],function(index,object){var id=object;if(Ember.typeOf(object)=="object"){id=object.id;hasManyRelation[index]=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)}}})},findEmbeddedAssociationsForRESTAdapter:function(modelType,fixture){var store=this;Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(Ember.typeOf(belongsToRecord)=="object"){store.findEmbeddedAssociationsForRESTAdapter(relationship.type,belongsToRecord);belongsToRecord=store.push(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord}}if(relationship.kind=="hasMany"){var hasManyRecords=fixture[relationship.key];if(Ember.typeOf(hasManyRecords)=="array"){if(Ember.typeOf(hasManyRecords[0])=="object"){var records=Em.A();hasManyRecords.map(function(object){store.findEmbeddedAssociationsForRESTAdapter(relationship.type,object);var record=store.push(relationship.type,object);records.push(record);return record});fixture[relationship.key]=records}}}})},setAssociationsForRESTAdapter:function(modelType,modelName,model){var self=this;Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="hasMany"){var children=model.get(name)||[];children.forEach(function(child){var belongsToName=self.findRelationshipName("belongsTo",child.constructor,model);if(belongsToName){child.set(belongsToName,model)}})}})},findRelationshipName:function(kind,belongToModelType,childModel){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(relationship,name){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(relationship,name){if(relationship.kind=="hasMany"&&childModelType==relationship.type){relationshipName=relationship.key}});return relationshipName},pushPayload:function(type,payload){if(this.usingFixtureAdapter()){var model=this.modelFor(type);FactoryGuy.pushFixture(model,payload)}else{this._super(type,payload)}}})})();var FactoryGuyTestMixin=Em.Mixin.create({setup:function(app){this.set("container",app.__container__);FactoryGuy.setStore(this.getStore());return this},useFixtureAdapter:function(app){app.ApplicationAdapter=DS.FixtureAdapter;this.getStore().adapterFor("application").simulateRemoteResponse=false},usingActiveModelSerializer:function(type){var store=this.getStore();var modelType=store.modelFor(type);var serializer=store.serializerFor(modelType.typeKey);return serializer instanceof DS.ActiveModelSerializer},find:function(type,id){return this.getStore().find(type,id)},make:function(){var store=this.getStore();return store.makeFixture.apply(store,arguments)},getStore:function(){return this.get("container").lookup("store:main")},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)},buildURL:function(typeName,id){var type=this.getStore().modelFor(typeName);return this.getStore().adapterFor(type).buildURL(type.typeKey,id)},handleFindMany:function(){var store=this.getStore();store.makeList.apply(store,arguments);var name=arguments[0];var modelName=FactoryGuy.lookupModelForFixtureName(name);var responseJson={};responseJson[modelName]=[];var url=this.buildURL(modelName);this.stubEndpointForHttpRequest(url,responseJson,{type:"GET"})},handleCreate:function(modelName,options){var opts=options===undefined?{}:options;var succeed=opts.succeed===undefined?true:opts.succeed;var match=opts.match||{};var returnArgs=opts.returns||{};var url=this.buildURL(modelName);var definition=FactoryGuy.modelDefinitions[modelName];var httpOptions={type:"POST"};if(opts.match){var expectedRequest={};var record=this.getStore().createRecord(modelName,match);expectedRequest[modelName]=record.serialize();httpOptions.data=JSON.stringify(expectedRequest)}var modelType=this.getStore().modelFor(modelName);var responseJson={};if(succeed){if(options){responseJson[modelName]=$.extend({id:definition.nextId()},match,returnArgs);Ember.get(modelType,"relationshipsByName").forEach(function(relationship){if(relationship.kind=="belongsTo"){delete responseJson[modelName][relationship.key]}})}}else{httpOptions.status=500}this.stubEndpointForHttpRequest(url,responseJson,httpOptions)},handleUpdate:function(){var args=Array.prototype.slice.call(arguments);Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0);var succeed=true;if(typeof args[args.length-1]=="boolean"){args.pop();succeed=false}Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0);var type,id;if(args[0]instanceof DS.Model){var model=args[0];type=model.constructor.typeKey;id=model.id}else if(typeof args[0]=="string"&&typeof parseInt(args[1])=="number"){type=args[0];id=args[1]}Ember.assert("To handleUpdate pass in a model instance or a type and an id",type&&id);this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"PUT",status:succeed?200:500})},handleDelete:function(type,id,succeed){succeed=succeed===undefined?true:succeed;this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"DELETE",status:succeed?200:500})},teardown:function(){FactoryGuy.resetModels(this.getStore());$.mockjax.clear()}});if(FactoryGuy!==undefined){FactoryGuy.testMixin=FactoryGuyTestMixin}
|
@@ -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.9.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
@@ -45,6 +45,44 @@ var FactoryGuy = {
|
|
45
45
|
this.modelDefinitions[model] = new ModelDefinition(model, config);
|
46
46
|
}
|
47
47
|
},
|
48
|
+
/**
|
49
|
+
Setting the store so FactoryGuy can do some model introspection.
|
50
|
+
*/
|
51
|
+
setStore: function(store) {
|
52
|
+
Ember.assert("FactoryGuy#setStore needs a valid store instance.You passed in ["+store+"]",store instanceof DS.Store)
|
53
|
+
this.store = store;
|
54
|
+
},
|
55
|
+
getStore: function() {
|
56
|
+
return this.store;
|
57
|
+
},
|
58
|
+
/**
|
59
|
+
Checks a model's attribute to determine if it's a relationship.
|
60
|
+
|
61
|
+
@param {String} typeName model type name like 'user' for User model class
|
62
|
+
@param {String} attribute attribute you want to check
|
63
|
+
@returns {Boolean} true if the attribute is a relationship, false if not
|
64
|
+
*/
|
65
|
+
isAttributeRelationship: function(typeName, attribute) {
|
66
|
+
if (!this.store) {
|
67
|
+
console.log("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures")
|
68
|
+
// The legacy value was true.
|
69
|
+
return true;
|
70
|
+
}
|
71
|
+
var model = this.store.modelFor(typeName);
|
72
|
+
return !!model.typeForRelationship(attribute);
|
73
|
+
},
|
74
|
+
/**
|
75
|
+
Make new fixture and save to store. Proxy to store#makeFixture method
|
76
|
+
|
77
|
+
@param {String} name fixture name
|
78
|
+
@param {String} trait optional trait names ( one or more )
|
79
|
+
@param {Object} opts optional fixture options that will override default fixture values
|
80
|
+
@returns {Object|DS.Model} json or record depending on the adapter type
|
81
|
+
*/
|
82
|
+
make: function() {
|
83
|
+
Ember.assert("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures", this.store);
|
84
|
+
return this.store.makeFixture.apply(this.store,arguments);
|
85
|
+
},
|
48
86
|
/**
|
49
87
|
Used in model definitions to declare use of a sequence. For example:
|
50
88
|
|
@@ -2,6 +2,7 @@ var FactoryGuyTestMixin = Em.Mixin.create({
|
|
2
2
|
// Pass in the app root, which typically is App.
|
3
3
|
setup: function (app) {
|
4
4
|
this.set('container', app.__container__);
|
5
|
+
FactoryGuy.setStore(this.getStore());
|
5
6
|
return this;
|
6
7
|
},
|
7
8
|
useFixtureAdapter: function (app) {
|
@@ -29,8 +30,7 @@ var FactoryGuyTestMixin = Em.Mixin.create({
|
|
29
30
|
return this.getStore().find(type, id);
|
30
31
|
},
|
31
32
|
/**
|
32
|
-
Proxy to store
|
33
|
-
|
33
|
+
Make new fixture and save to store. Proxy to store#makeFixture method
|
34
34
|
*/
|
35
35
|
make: function () {
|
36
36
|
var store = this.getStore();
|
@@ -39,12 +39,6 @@ var FactoryGuyTestMixin = Em.Mixin.create({
|
|
39
39
|
getStore: function () {
|
40
40
|
return this.get('container').lookup('store:main');
|
41
41
|
},
|
42
|
-
pushPayload: function (type, hash) {
|
43
|
-
return this.getStore().pushPayload(type, hash);
|
44
|
-
},
|
45
|
-
pushRecord: function (type, hash) {
|
46
|
-
return this.getStore().push(type, hash);
|
47
|
-
},
|
48
42
|
/**
|
49
43
|
Using mockjax to stub an http request.
|
50
44
|
|
@@ -121,7 +115,10 @@ var FactoryGuyTestMixin = Em.Mixin.create({
|
|
121
115
|
so you don't need to include them in the returns hash as well.
|
122
116
|
|
123
117
|
2) If you don't use match options for exact match, there will be no id returned to the model.
|
124
|
-
|
118
|
+
The reason being, that this method purposely returns an empty hash response with a 'don't match'
|
119
|
+
style handleCreate, because if the responseJson returns a non empty data hash ( with even only
|
120
|
+
the id), this essentially empty hash of attributes will override ( and nullify ) all the attributes
|
121
|
+
that set when you created the record.
|
125
122
|
3) If you match on a belongsTo association, you don't have to include that in the
|
126
123
|
returns hash.
|
127
124
|
|
@@ -174,8 +171,25 @@ var FactoryGuyTestMixin = Em.Mixin.create({
|
|
174
171
|
@param {Boolean} succeed optional flag to indicate if the request
|
175
172
|
should succeed ( default is true )
|
176
173
|
*/
|
177
|
-
handleUpdate: function (
|
178
|
-
|
174
|
+
handleUpdate: function () {
|
175
|
+
var args = Array.prototype.slice.call(arguments)
|
176
|
+
Ember.assert("To handleUpdate pass in a model instance or a type and an id", args.length>0)
|
177
|
+
var succeed = true;
|
178
|
+
if (typeof args[args.length-1] == 'boolean') {
|
179
|
+
args.pop()
|
180
|
+
succeed = false;
|
181
|
+
}
|
182
|
+
Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0)
|
183
|
+
var type, id;
|
184
|
+
if (args[0] instanceof DS.Model) {
|
185
|
+
var model = args[0];
|
186
|
+
type = model.constructor.typeKey;
|
187
|
+
id = model.id;
|
188
|
+
} else if (typeof args[0] == "string" && typeof parseInt(args[1]) == "number") {
|
189
|
+
type = args[0];
|
190
|
+
id = args[1];
|
191
|
+
}
|
192
|
+
Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id)
|
179
193
|
this.stubEndpointForHttpRequest(this.buildURL(type, id), {}, {
|
180
194
|
type: 'PUT',
|
181
195
|
status: succeed ? 200 : 500
|
data/src/model_definition.js
CHANGED
@@ -69,9 +69,19 @@ var ModelDefinition = function (model, config) {
|
|
69
69
|
// function might be a sequence of a named association
|
70
70
|
fixture[attribute] = fixture[attribute].call(this, fixture);
|
71
71
|
} else if (Ember.typeOf(fixture[attribute]) == 'object') {
|
72
|
-
//
|
72
|
+
// If it's an object and it's a model association attribute, build the json
|
73
73
|
// for the association and replace the attribute with that json
|
74
|
-
|
74
|
+
if (FactoryGuy.getStore()) {
|
75
|
+
if (FactoryGuy.isAttributeRelationship(this.model, attribute)) {
|
76
|
+
fixture[attribute] = FactoryGuy.build(attribute, fixture[attribute]);
|
77
|
+
}
|
78
|
+
} else {
|
79
|
+
// For legacy reasons, if the store is not set in FactoryGuy, keep
|
80
|
+
// this code the way it is ( though it will cause failures when the object is actually
|
81
|
+
// a custom attribute and not a relationship ), while users start setting the store
|
82
|
+
// in FactoryGuy, or using testHelper.make instead of store.makeFixture
|
83
|
+
fixture[attribute] = FactoryGuy.build(attribute, fixture[attribute]);
|
84
|
+
}
|
75
85
|
}
|
76
86
|
}
|
77
87
|
// set the id, unless it was already set in opts
|
@@ -1,9 +1,11 @@
|
|
1
|
-
var testHelper, store;
|
1
|
+
var testHelper, store, make;
|
2
|
+
|
2
3
|
|
3
4
|
module('FactoryGuy with ActiveModelAdapter', {
|
4
5
|
setup: function() {
|
5
6
|
testHelper = TestHelper.setup(DS.ActiveModelAdapter);
|
6
7
|
store = testHelper.getStore();
|
8
|
+
make = function() {return testHelper.make.apply(testHelper,arguments)}
|
7
9
|
},
|
8
10
|
teardown: function() {
|
9
11
|
testHelper.teardown();
|
@@ -12,8 +14,8 @@ module('FactoryGuy with ActiveModelAdapter', {
|
|
12
14
|
|
13
15
|
|
14
16
|
test("#resetModels clears the store of models, and resets the model definition", function() {
|
15
|
-
var project =
|
16
|
-
var user =
|
17
|
+
var project = make('project');
|
18
|
+
var user = make('user', {projects: [project]});
|
17
19
|
|
18
20
|
for (model in FactoryGuy.modelDefinitions) {
|
19
21
|
var definition = FactoryGuy.modelDefinitions[model];
|
@@ -37,6 +39,7 @@ module('DS.Store#makeFixture with ActiveModelAdapter', {
|
|
37
39
|
setup: function() {
|
38
40
|
testHelper = TestHelper.setup(DS.ActiveModelAdapter);
|
39
41
|
store = testHelper.getStore();
|
42
|
+
make = function() {return testHelper.make.apply(testHelper,arguments)}
|
40
43
|
},
|
41
44
|
teardown: function() {
|
42
45
|
Em.run(function() { testHelper.teardown(); });
|
@@ -45,9 +48,9 @@ module('DS.Store#makeFixture with ActiveModelAdapter', {
|
|
45
48
|
|
46
49
|
|
47
50
|
asyncTest("creates records in the store", function() {
|
48
|
-
var user =
|
49
|
-
ok(user instanceof User);
|
51
|
+
var user = make('user');
|
50
52
|
|
53
|
+
ok(user instanceof User);
|
51
54
|
store.find('user', user.id).then(function(store_user) {
|
52
55
|
ok(store_user == user);
|
53
56
|
start()
|
@@ -55,38 +58,44 @@ asyncTest("creates records in the store", function() {
|
|
55
58
|
});
|
56
59
|
|
57
60
|
|
61
|
+
test("handles custom attribute type attributes", function() {
|
62
|
+
var info = {first:1}
|
63
|
+
var user = make('user', {info: info});
|
64
|
+
ok(user.get('info') == info)
|
65
|
+
});
|
66
|
+
|
58
67
|
test("handles camelCase attributes", function() {
|
59
|
-
var profile =
|
68
|
+
var profile = make('profile', {camelCaseDescription: 'description'});
|
60
69
|
ok(profile.get('camelCaseDescription') == 'description')
|
61
70
|
});
|
62
71
|
|
63
72
|
test("makeFixture with fixture options", function() {
|
64
|
-
var profile =
|
73
|
+
var profile = make('profile', {description: 'dude'});
|
65
74
|
ok(profile.get('description') == 'dude');
|
66
75
|
});
|
67
76
|
|
68
77
|
test("makeFixture with attributes in traits", function() {
|
69
|
-
var profile =
|
78
|
+
var profile = make('profile', 'goofy_description');
|
70
79
|
ok(profile.get('description') == 'goofy');
|
71
80
|
});
|
72
81
|
|
73
82
|
test("makeFixture with attributes in traits and fixture options ", function() {
|
74
|
-
var profile =
|
83
|
+
var profile = make('profile', 'goofy_description', {description: 'dude'});
|
75
84
|
ok(profile.get('description') == 'dude');
|
76
85
|
});
|
77
86
|
|
78
87
|
|
79
88
|
test("when hasMany associations assigned, belongTo parent is assigned", function() {
|
80
|
-
var project =
|
81
|
-
var user =
|
89
|
+
var project = make('project');
|
90
|
+
var user = make('user', {projects: [project]})
|
82
91
|
|
83
92
|
ok(project.get('user') == user);
|
84
93
|
});
|
85
94
|
|
86
95
|
|
87
96
|
asyncTest("when hasMany ( asnyc ) associations assigned, belongTo parent is assigned", function() {
|
88
|
-
var user =
|
89
|
-
var company =
|
97
|
+
var user = make('user');
|
98
|
+
var company = make('company', {users: [user]});
|
90
99
|
|
91
100
|
user.get('company').then(function(c){
|
92
101
|
ok(c == company);
|
@@ -96,9 +105,9 @@ asyncTest("when hasMany ( asnyc ) associations assigned, belongTo parent is assi
|
|
96
105
|
|
97
106
|
|
98
107
|
test("when hasMany ( polymorphic ) associations are assigned, belongTo parent is assigned", function() {
|
99
|
-
var bh =
|
100
|
-
var sh =
|
101
|
-
var user =
|
108
|
+
var bh = make('big_hat');
|
109
|
+
var sh = make('small_hat');
|
110
|
+
var user = make('user', {hats: [bh, sh]})
|
102
111
|
|
103
112
|
equal(user.get('hats.length'), 2);
|
104
113
|
ok(user.get('hats.firstObject') instanceof BigHat)
|
@@ -110,40 +119,40 @@ test("when hasMany ( polymorphic ) associations are assigned, belongTo parent is
|
|
110
119
|
|
111
120
|
|
112
121
|
test("when hasMany ( self referential ) associations are assigned, belongsTo parent is assigned", function() {
|
113
|
-
var big_group =
|
114
|
-
var group =
|
122
|
+
var big_group = make('big_group');
|
123
|
+
var group = make('group', {versions: [big_group]});
|
115
124
|
ok(big_group.get('group') == group)
|
116
125
|
});
|
117
126
|
|
118
127
|
|
119
128
|
test("when hasMany associations are assigned, belongsTo parent is assigned using inverse", function() {
|
120
|
-
var project =
|
121
|
-
var project2 =
|
129
|
+
var project = make('project');
|
130
|
+
var project2 = make('project', {children: [project]});
|
122
131
|
|
123
132
|
ok(project.get('parent') == project2);
|
124
133
|
});
|
125
134
|
|
126
135
|
|
127
136
|
test("when hasMany associations are assigned, belongsTo parent is assigned using actual belongsTo name", function() {
|
128
|
-
var silk =
|
129
|
-
var big_hat =
|
137
|
+
var silk = make('silk');
|
138
|
+
var big_hat = make('big_hat', {materials: [silk]});
|
130
139
|
|
131
140
|
ok(silk.get('hat') == big_hat)
|
132
141
|
});
|
133
142
|
|
134
143
|
|
135
144
|
test("when hasMany associations are assigned, belongsTo ( polymorphic ) parent is assigned", function() {
|
136
|
-
var fluff =
|
137
|
-
var big_hat =
|
145
|
+
var fluff = make('fluffy_material');
|
146
|
+
var big_hat = make('big_hat', {fluffy_materials: [fluff]});
|
138
147
|
|
139
148
|
ok(fluff.get('hat') == big_hat)
|
140
149
|
});
|
141
150
|
|
142
151
|
|
143
152
|
test("when belongTo parent is assigned, parent adds to hasMany records", function() {
|
144
|
-
var user =
|
145
|
-
var project1 =
|
146
|
-
var project2 =
|
153
|
+
var user = make('user');
|
154
|
+
var project1 = make('project', {user: user});
|
155
|
+
var project2 = make('project', {user: user});
|
147
156
|
|
148
157
|
equal(user.get('projects.length'), 2);
|
149
158
|
ok(user.get('projects.firstObject') == project1);
|
@@ -152,9 +161,9 @@ test("when belongTo parent is assigned, parent adds to hasMany records", functio
|
|
152
161
|
|
153
162
|
|
154
163
|
test("when belongTo parent is assigned, parent adds to polymorphic hasMany records", function() {
|
155
|
-
var user =
|
156
|
-
|
157
|
-
|
164
|
+
var user = make('user');
|
165
|
+
make('big_hat', {user: user});
|
166
|
+
make('small_hat', {user: user});
|
158
167
|
|
159
168
|
equal(user.get('hats.length'), 2);
|
160
169
|
ok(user.get('hats.firstObject') instanceof BigHat)
|
@@ -163,9 +172,9 @@ test("when belongTo parent is assigned, parent adds to polymorphic hasMany recor
|
|
163
172
|
|
164
173
|
|
165
174
|
asyncTest("when async hasMany relationship is assigned, model relationship is synced on both sides", function() {
|
166
|
-
var property =
|
167
|
-
var user1 =
|
168
|
-
var user2 =
|
175
|
+
var property = make('property');
|
176
|
+
var user1 = make('user', {properties: [property]});
|
177
|
+
var user2 = make('user', {properties: [property]});
|
169
178
|
|
170
179
|
equal(property.get('owners.length'), 2);
|
171
180
|
ok(property.get('owners.firstObject') == user1);
|
@@ -175,9 +184,9 @@ asyncTest("when async hasMany relationship is assigned, model relationship is sy
|
|
175
184
|
|
176
185
|
|
177
186
|
asyncTest("when async belongsTo parent is assigned, parent adds to hasMany records", function() {
|
178
|
-
var company =
|
179
|
-
var user1 =
|
180
|
-
var user2 =
|
187
|
+
var company = make('company');
|
188
|
+
var user1 = make('user', {company: company});
|
189
|
+
var user2 = make('user', {company: company});
|
181
190
|
|
182
191
|
equal(company.get('users.length'), 2);
|
183
192
|
ok(company.get('users.firstObject') == user1);
|
@@ -187,8 +196,8 @@ asyncTest("when async belongsTo parent is assigned, parent adds to hasMany recor
|
|
187
196
|
|
188
197
|
|
189
198
|
test("when belongTo parent is assigned, parent adds to hasMany record using inverse", function() {
|
190
|
-
var project =
|
191
|
-
var project2 =
|
199
|
+
var project = make('project');
|
200
|
+
var project2 = make('project', {parent: project});
|
192
201
|
|
193
202
|
equal(project.get('children.length'), 1);
|
194
203
|
ok(project.get('children.firstObject') == project2);
|
@@ -196,43 +205,43 @@ test("when belongTo parent is assigned, parent adds to hasMany record using inve
|
|
196
205
|
|
197
206
|
|
198
207
|
test("when belongTo parent is assigned, parent adds to hasMany record using actual hasMany name", function() {
|
199
|
-
var bh =
|
200
|
-
var silk =
|
208
|
+
var bh = make('big_hat');
|
209
|
+
var silk = make('silk', {hat: bh});
|
201
210
|
|
202
211
|
ok(bh.get('materials.firstObject') == silk)
|
203
212
|
});
|
204
213
|
|
205
214
|
|
206
215
|
test("when belongTo parent is assigned, parent adds to belongsTo record", function() {
|
207
|
-
var company =
|
208
|
-
var profile =
|
216
|
+
var company = make('company');
|
217
|
+
var profile = make('profile', {company: company});
|
209
218
|
ok(company.get('profile') == profile);
|
210
219
|
|
211
220
|
// but guard against a situation where a model can belong to itself
|
212
221
|
// and do not want to set the belongsTo on this case.
|
213
|
-
var hat1 =
|
214
|
-
var hat2 =
|
222
|
+
var hat1 = make('big_hat')
|
223
|
+
var hat2 = make('big_hat', {hat: hat1})
|
215
224
|
ok(hat1.get('hat') == null);
|
216
225
|
ok(hat2.get('hat') == hat1);
|
217
226
|
});
|
218
227
|
|
219
228
|
|
220
229
|
test("belongsTo associations defined as attributes in fixture", function() {
|
221
|
-
var project =
|
230
|
+
var project = make('project_with_user');
|
222
231
|
equal(project.get('user') instanceof User, true)
|
223
232
|
ok(project.get('user.name') == 'User1');
|
224
233
|
|
225
|
-
var project =
|
234
|
+
var project = make('project_with_dude');
|
226
235
|
ok(project.get('user.name') == 'Dude');
|
227
236
|
|
228
|
-
var project =
|
237
|
+
var project = make('project_with_admin');
|
229
238
|
ok(project.get('user.name') == 'Admin');
|
230
239
|
});
|
231
240
|
|
232
241
|
|
233
242
|
|
234
243
|
test("hasMany associations defined as attributes in fixture", function() {
|
235
|
-
var user =
|
244
|
+
var user = make('user_with_projects');
|
236
245
|
equal(user.get('projects.length'), 2)
|
237
246
|
ok(user.get('projects.firstObject.user') == user)
|
238
247
|
ok(user.get('projects.lastObject.user') == user)
|
@@ -240,7 +249,7 @@ test("hasMany associations defined as attributes in fixture", function() {
|
|
240
249
|
|
241
250
|
|
242
251
|
test("hasMany associations defined with traits", function() {
|
243
|
-
var user =
|
252
|
+
var user = make('user', 'with_projects');
|
244
253
|
equal(user.get('projects.length'), 2)
|
245
254
|
ok(user.get('projects.firstObject.user') == user)
|
246
255
|
ok(user.get('projects.lastObject.user') == user)
|
@@ -249,17 +258,17 @@ test("hasMany associations defined with traits", function() {
|
|
249
258
|
|
250
259
|
|
251
260
|
test("belongsTo associations defined with traits", function() {
|
252
|
-
var hat1 =
|
261
|
+
var hat1 = make('hat', 'with_user');
|
253
262
|
equal(hat1.get('user') instanceof User, true)
|
254
263
|
|
255
|
-
var hat2 =
|
264
|
+
var hat2 = make('hat', 'with_user', 'with_outfit');
|
256
265
|
equal(hat2.get('user') instanceof User, true)
|
257
266
|
equal(hat2.get('outfit') instanceof Outfit, true)
|
258
267
|
})
|
259
268
|
|
260
269
|
|
261
270
|
test("with (nested json fixture) belongsTo has a hasMany association which has a belongsTo", function() {
|
262
|
-
var project =
|
271
|
+
var project = make('project', 'with_user_having_hats_belonging_to_outfit');
|
263
272
|
var user = project.get('user');
|
264
273
|
var hats = user.get('hats');
|
265
274
|
var firstHat = hats.get('firstObject');
|