ember-data-factory-guy 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +20 -0
- data/README.md +7 -3
- data/bower.json +1 -1
- data/dist/ember-data-factory-guy.js +83 -15
- 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 +50 -3
- data/src/factory_guy_test_mixin.js +19 -8
- data/src/model_definition.js +1 -1
- data/src/store.js +13 -3
- data/tests/factory_guy_test.js +24 -4
- data/tests/factory_guy_test_mixin_test.js +32 -0
- data/tests/fixture_adapter_factory_test.js +40 -36
- data/tests/index.html +1 -0
- data/tests/rest_adapter_factory_test.js +15 -0
- data/tests/support/factories/company_factory.js +1 -1
- data/tests/support/factories/project_factory.js +8 -3
- data/tests/support/factories/user_factory.js +8 -0
- data/tests/test_setup.js +23 -10
- data/vendor/assets/javascripts/ember_data_factory_guy.js +78 -20
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21456baccb82088ae063f86ee70e3582848c760a
|
4
|
+
data.tar.gz: 82e3178d129e0d7bb44e9a6c778cdf240a3b3f1b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 37c4c45d592490dd3f80068cf75c8838d0bc2599164805b172331760827564d5e74246a129651c9c5e80357a01b1746ab923157e64c7ab65aeee55bc3ab33673
|
7
|
+
data.tar.gz: 295339f7367bbd5e604f3ec8dd18419658c97a8d4471dea0658bfda7a5b883b5c31e09cade02d5adf32efacbc8f282421eedba56fe8351e66cb8cd4f944ede37
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2014 Daniel Sudol and contributors
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -106,13 +106,16 @@ Let's say you have a few models like these:
|
|
106
106
|
// use the 'userName' sequence for this attribute
|
107
107
|
name: FactoryGuy.generate('userName')
|
108
108
|
},
|
109
|
-
|
109
|
+
//
|
110
110
|
// named 'user' type with custom attributes
|
111
|
+
//
|
111
112
|
admin: {
|
112
113
|
type: 'superuser',
|
113
114
|
name: 'Admin'
|
114
115
|
}
|
116
|
+
//
|
115
117
|
// using a function for an attribute that refers to other attributes
|
118
|
+
//
|
116
119
|
funny_user: {
|
117
120
|
type: function(f) { return 'funny ' + f.name }
|
118
121
|
}
|
@@ -140,9 +143,10 @@ Let's say you have a few models like these:
|
|
140
143
|
user: {name: 'Dude'}
|
141
144
|
},
|
142
145
|
project_with_admin: {
|
143
|
-
// for named association, use
|
144
|
-
user: FactoryGuy.
|
146
|
+
// for named association, use the FactoryGuy.belongsTo helper method
|
147
|
+
user: FactoryGuy.belongsTo('admin')
|
145
148
|
}
|
149
|
+
|
146
150
|
});
|
147
151
|
|
148
152
|
FactoryGuy.define('hat', {
|
data/bower.json
CHANGED
@@ -70,7 +70,7 @@ ModelDefinition = function (model, config) {
|
|
70
70
|
|
71
71
|
@param {String} name fixture name
|
72
72
|
@param {Object} opts attributes to override
|
73
|
-
@param {String}
|
73
|
+
@param {String} traitArgs array of traits
|
74
74
|
@returns {Object} json
|
75
75
|
*/
|
76
76
|
this.build = function (name, opts, traitArgs) {
|
@@ -260,23 +260,70 @@ FactoryGuy = {
|
|
260
260
|
default: {
|
261
261
|
title: 'Project'
|
262
262
|
},
|
263
|
+
|
264
|
+
// setup named project with built in associated user
|
263
265
|
project_with_admin: {
|
264
|
-
|
265
|
-
user: FactoryGuy.association('admin')
|
266
|
+
user: FactoryGuy.belongsTo('admin')
|
266
267
|
}
|
267
268
|
|
269
|
+
// or use as a trait
|
270
|
+
traits: {
|
271
|
+
with_admin: {
|
272
|
+
user: FactoryGuy.belongsTo('admin')
|
273
|
+
}
|
274
|
+
}
|
275
|
+
})
|
268
276
|
```
|
269
277
|
|
270
278
|
@param {String} fixtureName fixture name
|
271
279
|
@param {Object} opts options
|
272
280
|
@returns {Function} wrapper function that will build the association json
|
273
281
|
*/
|
274
|
-
|
282
|
+
belongsTo: function (fixtureName, opts) {
|
275
283
|
return function () {
|
276
284
|
return FactoryGuy.build(fixtureName, opts);
|
277
285
|
}
|
278
286
|
},
|
279
287
|
|
288
|
+
association: function(fixtureName, opts) {
|
289
|
+
console.log('DEPRECATION Warning: use FactoryGuy.belongsTo instead')
|
290
|
+
return this.belongsTo(fixtureName, opts);
|
291
|
+
},
|
292
|
+
|
293
|
+
/**
|
294
|
+
Used in model definitions to define a hasMany association attribute.
|
295
|
+
For example:
|
296
|
+
|
297
|
+
```
|
298
|
+
FactoryGuy.define('user', {
|
299
|
+
default: {
|
300
|
+
name: 'Bob'
|
301
|
+
},
|
302
|
+
|
303
|
+
// define the named user type that will have projects
|
304
|
+
user_with_projects: { FactoryGuy.hasMany('project', 2) }
|
305
|
+
|
306
|
+
// or use as a trait
|
307
|
+
traits: {
|
308
|
+
with_projects: {
|
309
|
+
projects: FactoryGuy.hasMany('project', 2)
|
310
|
+
}
|
311
|
+
}
|
312
|
+
})
|
313
|
+
|
314
|
+
```
|
315
|
+
|
316
|
+
@param {String} fixtureName fixture name
|
317
|
+
@param {Number} number of hasMany association items to build
|
318
|
+
@param {Object} opts options
|
319
|
+
@returns {Function} wrapper function that will build the association json
|
320
|
+
*/
|
321
|
+
hasMany: function (fixtureName, number, opts) {
|
322
|
+
return function () {
|
323
|
+
return FactoryGuy.buildList(fixtureName, number, opts);
|
324
|
+
}
|
325
|
+
},
|
326
|
+
|
280
327
|
/**
|
281
328
|
Given a fixture name like 'person' or 'dude' determine what model this name
|
282
329
|
refers to. In this case it's 'person' for each one.
|
@@ -543,9 +590,6 @@ DS.Store.reopen({
|
|
543
590
|
then push that model to the store and set the id of that new model
|
544
591
|
as the attribute value in the fixture
|
545
592
|
|
546
|
-
If it's a hasMany association, and its polymorphic, then convert the
|
547
|
-
attribute value to a polymorphic style
|
548
|
-
|
549
593
|
@param modelType
|
550
594
|
@param fixture
|
551
595
|
*/
|
@@ -559,6 +603,19 @@ DS.Store.reopen({
|
|
559
603
|
fixture[relationship.key] = belongsToRecord;
|
560
604
|
}
|
561
605
|
}
|
606
|
+
if (relationship.kind == 'hasMany') {
|
607
|
+
var hasManyRecords = fixture[relationship.key];
|
608
|
+
// if the records are objects and not instances they need to be converted to
|
609
|
+
// instances
|
610
|
+
if (Ember.typeOf(hasManyRecords) == 'array' && Ember.typeOf(hasManyRecords[0]) == 'object') {
|
611
|
+
var records = Em.A()
|
612
|
+
hasManyRecords.forEach(function(record) {
|
613
|
+
var record = store.push(relationship.type, record);
|
614
|
+
records.push(record);
|
615
|
+
})
|
616
|
+
fixture[relationship.key] = records;
|
617
|
+
}
|
618
|
+
}
|
562
619
|
})
|
563
620
|
},
|
564
621
|
|
@@ -895,6 +952,17 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
895
952
|
}
|
896
953
|
},
|
897
954
|
|
955
|
+
/**
|
956
|
+
Build url for the mockjax call. Proxy to the adapters buildURL method.
|
957
|
+
|
958
|
+
@param {String} type model type name like 'user' for User model
|
959
|
+
@param {String} id
|
960
|
+
@return {String} url
|
961
|
+
*/
|
962
|
+
buildURL: function (type, id) {
|
963
|
+
return this.getStore().adapterFor('application').buildURL(type, id);
|
964
|
+
},
|
965
|
+
|
898
966
|
/**
|
899
967
|
Handling ajax GET ( find record ) for a model. You can mock
|
900
968
|
failed find by passing in status of 500.
|
@@ -907,7 +975,7 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
907
975
|
var modelName = FactoryGuy.lookupModelForFixtureName(name);
|
908
976
|
var responseJson = this.buildAjaxHttpResponse(name, opts);
|
909
977
|
var id = responseJson[modelName].id
|
910
|
-
var url =
|
978
|
+
var url = this.buildURL(modelName, id);
|
911
979
|
this.stubEndpointForHttpRequest(
|
912
980
|
url,
|
913
981
|
responseJson,
|
@@ -927,7 +995,7 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
927
995
|
handleCreate: function (name, opts, status) {
|
928
996
|
var modelName = FactoryGuy.lookupModelForFixtureName(name);
|
929
997
|
var responseJson = this.buildAjaxHttpResponse(name, opts);
|
930
|
-
var url =
|
998
|
+
var url = this.buildURL(modelName);
|
931
999
|
this.stubEndpointForHttpRequest(
|
932
1000
|
url,
|
933
1001
|
responseJson,
|
@@ -940,13 +1008,13 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
940
1008
|
Handling ajax PUT ( update record ) for a model type. You can mock
|
941
1009
|
failed update by passing in status of 500.
|
942
1010
|
|
943
|
-
@param {String}
|
1011
|
+
@param {String} type model type like 'user' for User model
|
944
1012
|
@param {String} id id of record to update
|
945
1013
|
@param {Integer} status Optional HTTP status response code
|
946
1014
|
*/
|
947
|
-
handleUpdate: function (
|
1015
|
+
handleUpdate: function (type, id, status) {
|
948
1016
|
this.stubEndpointForHttpRequest(
|
949
|
-
|
1017
|
+
this.buildURL(type, id),
|
950
1018
|
{},
|
951
1019
|
{type: 'PUT', status: (status || 200)}
|
952
1020
|
)
|
@@ -956,13 +1024,13 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
956
1024
|
Handling ajax DELETE ( delete record ) for a model type. You can mock
|
957
1025
|
failed delete by passing in status of 500.
|
958
1026
|
|
959
|
-
@param {String}
|
1027
|
+
@param {String} type model type like 'user' for User model
|
960
1028
|
@param {String} id id of record to update
|
961
1029
|
@param {Integer} status Optional HTTP status response code
|
962
1030
|
*/
|
963
|
-
handleDelete: function (
|
1031
|
+
handleDelete: function (type, id, status) {
|
964
1032
|
this.stubEndpointForHttpRequest(
|
965
|
-
|
1033
|
+
this.buildURL(type, id),
|
966
1034
|
{},
|
967
1035
|
{type: 'DELETE', status: (status || 200)}
|
968
1036
|
)
|
@@ -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 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;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
|
+
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)}}},belongsTo:function(fixtureName,opts){return function(){return FactoryGuy.build(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(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(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}}if(relationship.kind=="hasMany"){var hasManyRecords=fixture[relationship.key];if(Ember.typeOf(hasManyRecords)=="array"&&Ember.typeOf(hasManyRecords[0])=="object"){var records=Em.A();hasManyRecords.forEach(function(record){var record=store.push(relationship.type,record);records.push(record)});fixture[relationship.key]=records}}})},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);if(hasManyName){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}}},buildURL:function(type,id){return this.getStore().adapterFor("application").buildURL(type,id)},handleFind:function(name,opts,status){var modelName=FactoryGuy.lookupModelForFixtureName(name);var responseJson=this.buildAjaxHttpResponse(name,opts);var id=responseJson[modelName].id;var url=this.buildURL(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=this.buildURL(modelName);this.stubEndpointForHttpRequest(url,responseJson,{type:"POST",status:status||200});return responseJson},handleUpdate:function(type,id,status){this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"PUT",status:status||200})},handleDelete:function(type,id,status){this.stubEndpointForHttpRequest(this.buildURL(type,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.6.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
@@ -90,23 +90,70 @@ FactoryGuy = {
|
|
90
90
|
default: {
|
91
91
|
title: 'Project'
|
92
92
|
},
|
93
|
+
|
94
|
+
// setup named project with built in associated user
|
93
95
|
project_with_admin: {
|
94
|
-
|
95
|
-
user: FactoryGuy.association('admin')
|
96
|
+
user: FactoryGuy.belongsTo('admin')
|
96
97
|
}
|
97
98
|
|
99
|
+
// or use as a trait
|
100
|
+
traits: {
|
101
|
+
with_admin: {
|
102
|
+
user: FactoryGuy.belongsTo('admin')
|
103
|
+
}
|
104
|
+
}
|
105
|
+
})
|
98
106
|
```
|
99
107
|
|
100
108
|
@param {String} fixtureName fixture name
|
101
109
|
@param {Object} opts options
|
102
110
|
@returns {Function} wrapper function that will build the association json
|
103
111
|
*/
|
104
|
-
|
112
|
+
belongsTo: function (fixtureName, opts) {
|
105
113
|
return function () {
|
106
114
|
return FactoryGuy.build(fixtureName, opts);
|
107
115
|
}
|
108
116
|
},
|
109
117
|
|
118
|
+
association: function(fixtureName, opts) {
|
119
|
+
console.log('DEPRECATION Warning: use FactoryGuy.belongsTo instead')
|
120
|
+
return this.belongsTo(fixtureName, opts);
|
121
|
+
},
|
122
|
+
|
123
|
+
/**
|
124
|
+
Used in model definitions to define a hasMany association attribute.
|
125
|
+
For example:
|
126
|
+
|
127
|
+
```
|
128
|
+
FactoryGuy.define('user', {
|
129
|
+
default: {
|
130
|
+
name: 'Bob'
|
131
|
+
},
|
132
|
+
|
133
|
+
// define the named user type that will have projects
|
134
|
+
user_with_projects: { FactoryGuy.hasMany('project', 2) }
|
135
|
+
|
136
|
+
// or use as a trait
|
137
|
+
traits: {
|
138
|
+
with_projects: {
|
139
|
+
projects: FactoryGuy.hasMany('project', 2)
|
140
|
+
}
|
141
|
+
}
|
142
|
+
})
|
143
|
+
|
144
|
+
```
|
145
|
+
|
146
|
+
@param {String} fixtureName fixture name
|
147
|
+
@param {Number} number of hasMany association items to build
|
148
|
+
@param {Object} opts options
|
149
|
+
@returns {Function} wrapper function that will build the association json
|
150
|
+
*/
|
151
|
+
hasMany: function (fixtureName, number, opts) {
|
152
|
+
return function () {
|
153
|
+
return FactoryGuy.buildList(fixtureName, number, opts);
|
154
|
+
}
|
155
|
+
},
|
156
|
+
|
110
157
|
/**
|
111
158
|
Given a fixture name like 'person' or 'dude' determine what model this name
|
112
159
|
refers to. In this case it's 'person' for each one.
|
@@ -112,6 +112,17 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
112
112
|
}
|
113
113
|
},
|
114
114
|
|
115
|
+
/**
|
116
|
+
Build url for the mockjax call. Proxy to the adapters buildURL method.
|
117
|
+
|
118
|
+
@param {String} type model type name like 'user' for User model
|
119
|
+
@param {String} id
|
120
|
+
@return {String} url
|
121
|
+
*/
|
122
|
+
buildURL: function (type, id) {
|
123
|
+
return this.getStore().adapterFor('application').buildURL(type, id);
|
124
|
+
},
|
125
|
+
|
115
126
|
/**
|
116
127
|
Handling ajax GET ( find record ) for a model. You can mock
|
117
128
|
failed find by passing in status of 500.
|
@@ -124,7 +135,7 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
124
135
|
var modelName = FactoryGuy.lookupModelForFixtureName(name);
|
125
136
|
var responseJson = this.buildAjaxHttpResponse(name, opts);
|
126
137
|
var id = responseJson[modelName].id
|
127
|
-
var url =
|
138
|
+
var url = this.buildURL(modelName, id);
|
128
139
|
this.stubEndpointForHttpRequest(
|
129
140
|
url,
|
130
141
|
responseJson,
|
@@ -144,7 +155,7 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
144
155
|
handleCreate: function (name, opts, status) {
|
145
156
|
var modelName = FactoryGuy.lookupModelForFixtureName(name);
|
146
157
|
var responseJson = this.buildAjaxHttpResponse(name, opts);
|
147
|
-
var url =
|
158
|
+
var url = this.buildURL(modelName);
|
148
159
|
this.stubEndpointForHttpRequest(
|
149
160
|
url,
|
150
161
|
responseJson,
|
@@ -157,13 +168,13 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
157
168
|
Handling ajax PUT ( update record ) for a model type. You can mock
|
158
169
|
failed update by passing in status of 500.
|
159
170
|
|
160
|
-
@param {String}
|
171
|
+
@param {String} type model type like 'user' for User model
|
161
172
|
@param {String} id id of record to update
|
162
173
|
@param {Integer} status Optional HTTP status response code
|
163
174
|
*/
|
164
|
-
handleUpdate: function (
|
175
|
+
handleUpdate: function (type, id, status) {
|
165
176
|
this.stubEndpointForHttpRequest(
|
166
|
-
|
177
|
+
this.buildURL(type, id),
|
167
178
|
{},
|
168
179
|
{type: 'PUT', status: (status || 200)}
|
169
180
|
)
|
@@ -173,13 +184,13 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
173
184
|
Handling ajax DELETE ( delete record ) for a model type. You can mock
|
174
185
|
failed delete by passing in status of 500.
|
175
186
|
|
176
|
-
@param {String}
|
187
|
+
@param {String} type model type like 'user' for User model
|
177
188
|
@param {String} id id of record to update
|
178
189
|
@param {Integer} status Optional HTTP status response code
|
179
190
|
*/
|
180
|
-
handleDelete: function (
|
191
|
+
handleDelete: function (type, id, status) {
|
181
192
|
this.stubEndpointForHttpRequest(
|
182
|
-
|
193
|
+
this.buildURL(type, id),
|
183
194
|
{},
|
184
195
|
{type: 'DELETE', status: (status || 200)}
|
185
196
|
)
|
data/src/model_definition.js
CHANGED
@@ -54,7 +54,7 @@ ModelDefinition = function (model, config) {
|
|
54
54
|
|
55
55
|
@param {String} name fixture name
|
56
56
|
@param {Object} opts attributes to override
|
57
|
-
@param {String}
|
57
|
+
@param {String} traitArgs array of traits
|
58
58
|
@returns {Object} json
|
59
59
|
*/
|
60
60
|
this.build = function (name, opts, traitArgs) {
|
data/src/store.js
CHANGED
@@ -125,9 +125,6 @@ DS.Store.reopen({
|
|
125
125
|
then push that model to the store and set the id of that new model
|
126
126
|
as the attribute value in the fixture
|
127
127
|
|
128
|
-
If it's a hasMany association, and its polymorphic, then convert the
|
129
|
-
attribute value to a polymorphic style
|
130
|
-
|
131
128
|
@param modelType
|
132
129
|
@param fixture
|
133
130
|
*/
|
@@ -141,6 +138,19 @@ DS.Store.reopen({
|
|
141
138
|
fixture[relationship.key] = belongsToRecord;
|
142
139
|
}
|
143
140
|
}
|
141
|
+
if (relationship.kind == 'hasMany') {
|
142
|
+
var hasManyRecords = fixture[relationship.key];
|
143
|
+
// if the records are objects and not instances they need to be converted to
|
144
|
+
// instances
|
145
|
+
if (Ember.typeOf(hasManyRecords) == 'array' && Ember.typeOf(hasManyRecords[0]) == 'object') {
|
146
|
+
var records = Em.A()
|
147
|
+
hasManyRecords.forEach(function(record) {
|
148
|
+
var record = store.push(relationship.type, record);
|
149
|
+
records.push(record);
|
150
|
+
})
|
151
|
+
fixture[relationship.key] = records;
|
152
|
+
}
|
153
|
+
}
|
144
154
|
})
|
145
155
|
},
|
146
156
|
|
data/tests/factory_guy_test.js
CHANGED
@@ -88,15 +88,28 @@ test("Referring to other attributes in attribute definition", function() {
|
|
88
88
|
});
|
89
89
|
|
90
90
|
|
91
|
-
test("Using associations in attribute definition", function() {
|
91
|
+
test("Using belongsTo associations in attribute definition", function() {
|
92
92
|
var json = FactoryGuy.build('project_with_user');
|
93
|
-
deepEqual(json, {id: 1, title: 'Project1', user: {id: 1, name: 'User1'}}, 'creates default
|
93
|
+
deepEqual(json, {id: 1, title: 'Project1', user: {id: 1, name: 'User1'}}, 'creates default association');
|
94
94
|
|
95
95
|
var json = FactoryGuy.build('project_with_dude');
|
96
|
-
deepEqual(json, {id: 2, title: 'Project2', user: {id: 2, name: 'Dude'}}, 'creates
|
96
|
+
deepEqual(json, {id: 2, title: 'Project2', user: {id: 2, name: 'Dude'}}, 'creates association with optional attributes');
|
97
97
|
|
98
98
|
var json = FactoryGuy.build('project_with_admin');
|
99
|
-
deepEqual(json, {id: 3, title: 'Project3', user: {id: 3, name: 'Admin'}}, 'creates
|
99
|
+
deepEqual(json, {id: 3, title: 'Project3', user: {id: 3, name: 'Admin'}}, 'creates association using named attribute');
|
100
|
+
|
101
|
+
var json = FactoryGuy.build('project_with_parent');
|
102
|
+
deepEqual(json, {id: 5, title: 'Project4', parent: {id: 4, title: 'Project5'}}, 'belongsTo association name differs from model name');
|
103
|
+
});
|
104
|
+
|
105
|
+
|
106
|
+
test("Using hasMany associations in attribute definition", function() {
|
107
|
+
var json = FactoryGuy.build('user_with_projects');
|
108
|
+
deepEqual(json, {
|
109
|
+
id: 1,
|
110
|
+
name: 'User1',
|
111
|
+
projects: [{id: 1, title: 'Project1'},{id: 2, title: 'Project2'}]
|
112
|
+
}, 'creates list of hasMany association items');
|
100
113
|
});
|
101
114
|
|
102
115
|
|
@@ -121,6 +134,13 @@ test("#build with traits", function() {
|
|
121
134
|
|
122
135
|
var json = FactoryGuy.build('project', 'with_title_sequence');
|
123
136
|
deepEqual(json, {id: 7, title: 'Project3'}, 'trait with attribute using sequence');
|
137
|
+
|
138
|
+
var json = FactoryGuy.build('user', 'with_projects');
|
139
|
+
deepEqual(json, {
|
140
|
+
id: 6,
|
141
|
+
name: 'User1',
|
142
|
+
projects: [{id: 8, title: 'Project4'},{id: 9, title: 'Project5'}]
|
143
|
+
}, 'trait with hasMany association');
|
124
144
|
});
|
125
145
|
|
126
146
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
var testHelper, store;
|
2
|
+
|
3
|
+
module('FactoryGuyTestMixin with DS.RESTAdapter', {
|
4
|
+
setup: function () {
|
5
|
+
testHelper = TestHelper.setup(DS.RESTAdapter);
|
6
|
+
store = testHelper.getStore();
|
7
|
+
},
|
8
|
+
teardown: function () {
|
9
|
+
DS.RESTAdapter.reopen({
|
10
|
+
namespace: '',
|
11
|
+
host: ''
|
12
|
+
})
|
13
|
+
Em.run(function () {
|
14
|
+
testHelper.teardown();
|
15
|
+
});
|
16
|
+
}
|
17
|
+
});
|
18
|
+
|
19
|
+
|
20
|
+
test("#buildURL without namespace", function () {
|
21
|
+
equal(testHelper.buildURL('project'), '/projects', 'has no namespace by default');
|
22
|
+
})
|
23
|
+
|
24
|
+
test("#buildURL with namespace and host", function () {
|
25
|
+
DS.RESTAdapter.reopen({
|
26
|
+
host: 'https://dude.com',
|
27
|
+
namespace: 'api/v1'
|
28
|
+
})
|
29
|
+
|
30
|
+
equal(testHelper.buildURL('project'), 'https://dude.com/api/v1/projects');
|
31
|
+
})
|
32
|
+
|
@@ -1,17 +1,19 @@
|
|
1
1
|
var testHelper, store;
|
2
2
|
|
3
3
|
module('FactoryGuy with DS.FixtureAdapter', {
|
4
|
-
setup: function() {
|
4
|
+
setup: function () {
|
5
5
|
testHelper = TestHelper.setup(DS.FixtureAdapter);
|
6
6
|
store = testHelper.getStore();
|
7
7
|
},
|
8
|
-
teardown: function() {
|
9
|
-
Em.run(function() {
|
8
|
+
teardown: function () {
|
9
|
+
Em.run(function () {
|
10
|
+
testHelper.teardown();
|
11
|
+
});
|
10
12
|
}
|
11
13
|
});
|
12
14
|
|
13
15
|
|
14
|
-
test("#pushFixture adds fixture to Fixture array on model", function() {
|
16
|
+
test("#pushFixture adds fixture to Fixture array on model", function () {
|
15
17
|
var fixtureJson = FactoryGuy.build('user');
|
16
18
|
FactoryGuy.pushFixture(User, fixtureJson);
|
17
19
|
equal(User.FIXTURES.length, 1);
|
@@ -22,18 +24,18 @@ test("#pushFixture adds fixture to Fixture array on model", function() {
|
|
22
24
|
});
|
23
25
|
|
24
26
|
|
25
|
-
asyncTest("can change fixture attributes after creation", function() {
|
27
|
+
asyncTest("can change fixture attributes after creation", function () {
|
26
28
|
var user = store.makeFixture('user');
|
27
29
|
user.name = "new name";
|
28
30
|
|
29
|
-
store.find('user', 1).then(
|
31
|
+
store.find('user', 1).then(function (user) {
|
30
32
|
equal(user.get('name'), "new name", "changes local attributes");
|
31
33
|
start();
|
32
34
|
});
|
33
35
|
});
|
34
36
|
|
35
37
|
|
36
|
-
test("#resetModels clears the store of models, clears the FIXTURES arrays for each model and resets the model definition", function() {
|
38
|
+
test("#resetModels clears the store of models, clears the FIXTURES arrays for each model and resets the model definition", function () {
|
37
39
|
var project = store.makeFixture('project');
|
38
40
|
var user = store.makeFixture('user', {projects: [project.id]});
|
39
41
|
|
@@ -59,32 +61,34 @@ test("#resetModels clears the store of models, clears the FIXTURES arrays for ea
|
|
59
61
|
|
60
62
|
|
61
63
|
module('DS.Store with DS.FixtureAdapter', {
|
62
|
-
setup: function() {
|
64
|
+
setup: function () {
|
63
65
|
testHelper = TestHelper.setup(DS.FixtureAdapter);
|
64
66
|
store = testHelper.getStore();
|
65
67
|
},
|
66
|
-
teardown: function() {
|
67
|
-
Em.run(function() {
|
68
|
+
teardown: function () {
|
69
|
+
Em.run(function () {
|
70
|
+
testHelper.teardown();
|
71
|
+
});
|
68
72
|
}
|
69
73
|
});
|
70
74
|
|
71
75
|
|
72
|
-
test("#makeFixture builds and pushes fixture into the models FIXTURE array", function() {
|
76
|
+
test("#makeFixture builds and pushes fixture into the models FIXTURE array", function () {
|
73
77
|
var json = store.makeFixture('user');
|
74
78
|
equal(User.FIXTURES.length, 1);
|
75
79
|
equal(User.FIXTURES[0], json);
|
76
80
|
});
|
77
81
|
|
78
82
|
|
79
|
-
asyncTest("#makeFixture sets belongsTo on hasMany associations", function() {
|
83
|
+
asyncTest("#makeFixture sets belongsTo on hasMany associations", function () {
|
80
84
|
var p1 = store.makeFixture('project');
|
81
85
|
// second project not added on purpose to make sure only one is
|
82
86
|
// assigned in hasMany
|
83
87
|
store.makeFixture('project');
|
84
88
|
var user = store.makeFixture('user', {projects: [p1.id]})
|
85
89
|
|
86
|
-
store.find('user', 1).then(
|
87
|
-
user.get('projects').then(
|
90
|
+
store.find('user', 1).then(function (user) {
|
91
|
+
user.get('projects').then(function (projects) {
|
88
92
|
equal(projects.get('length'), 1, "adds hasMany records");
|
89
93
|
equal(projects.get('firstObject.user.id'), user.id, "sets belongsTo record");
|
90
94
|
start();
|
@@ -93,12 +97,12 @@ asyncTest("#makeFixture sets belongsTo on hasMany associations", function() {
|
|
93
97
|
})
|
94
98
|
|
95
99
|
|
96
|
-
asyncTest("#makeFixture adds record to hasMany association array for which it belongsTo", function() {
|
100
|
+
asyncTest("#makeFixture adds record to hasMany association array for which it belongsTo", function () {
|
97
101
|
var userJson = store.makeFixture('user');
|
98
102
|
var projectJson = store.makeFixture('project', {user: userJson.id});
|
99
103
|
|
100
|
-
store.find('user', userJson.id).then(
|
101
|
-
user.get('projects').then(
|
104
|
+
store.find('user', userJson.id).then(function (user) {
|
105
|
+
user.get('projects').then(function (projects) {
|
102
106
|
equal(projects.get('length'), 1, "adds hasMany records");
|
103
107
|
equal(projects.get('firstObject.user.id'), user.id, "sets belongsTo record");
|
104
108
|
start();
|
@@ -106,12 +110,12 @@ asyncTest("#makeFixture adds record to hasMany association array for which it be
|
|
106
110
|
})
|
107
111
|
})
|
108
112
|
|
109
|
-
asyncTest("#makeFixture handles default belongsTo associations in fixture", function() {
|
113
|
+
asyncTest("#makeFixture handles default belongsTo associations in fixture", function () {
|
110
114
|
var projectWithUser = store.makeFixture('project_with_user');
|
111
115
|
equal(User.FIXTURES.length, 1);
|
112
116
|
|
113
|
-
store.find('user', 1).then(
|
114
|
-
user.get('projects').then(
|
117
|
+
store.find('user', 1).then(function (user) {
|
118
|
+
user.get('projects').then(function (projects) {
|
115
119
|
equal(projects.get('length'), 1, "adds hasMany records");
|
116
120
|
equal(projects.get('firstObject.user.id'), 1, "sets belongsTo record");
|
117
121
|
start();
|
@@ -130,17 +134,17 @@ asyncTest("#makeFixture handles default belongsTo associations in fixture", func
|
|
130
134
|
})
|
131
135
|
|
132
136
|
|
133
|
-
asyncTest("#createRecord adds belongsTo association to records it hasMany of", function() {
|
137
|
+
asyncTest("#createRecord adds belongsTo association to records it hasMany of", function () {
|
134
138
|
var user = store.makeFixture('user');
|
135
139
|
|
136
|
-
store.find('user', user.id).then(function(user) {
|
140
|
+
store.find('user', user.id).then(function (user) {
|
137
141
|
|
138
|
-
var projectJson = {title:'project', user: user};
|
142
|
+
var projectJson = {title: 'project', user: user};
|
139
143
|
|
140
144
|
store.createRecord('project', projectJson).save()
|
141
|
-
.then(
|
145
|
+
.then(function (project) {
|
142
146
|
return Ember.RSVP.all([project.get('user'), user.get('projects')]);
|
143
|
-
}).then(
|
147
|
+
}).then(function (promises) {
|
144
148
|
var projectUser = promises[0], projects = promises[1];
|
145
149
|
equal(projectUser.get('id'), user.get('id'));
|
146
150
|
equal(projects.get('length'), 1);
|
@@ -149,36 +153,36 @@ asyncTest("#createRecord adds belongsTo association to records it hasMany of", f
|
|
149
153
|
})
|
150
154
|
})
|
151
155
|
|
152
|
-
asyncTest("#createRecord can work for one-to-none associations", function() {
|
156
|
+
asyncTest("#createRecord can work for one-to-none associations", function () {
|
153
157
|
var user = store.makeFixture('user');
|
154
158
|
|
155
|
-
store.find('user', user.id).then(function(user) {
|
159
|
+
store.find('user', user.id).then(function (user) {
|
156
160
|
|
157
|
-
var smallCompanyJson = {name:'small company', owner: user};
|
161
|
+
var smallCompanyJson = {name: 'small company', owner: user};
|
158
162
|
|
159
163
|
store.createRecord('small_company', smallCompanyJson).save()
|
160
|
-
.then(
|
164
|
+
.then(function (smallCompany) {
|
161
165
|
return smallCompany.get('owner');
|
162
|
-
}).then(
|
166
|
+
}).then(function (owner) {
|
163
167
|
equal(owner.get('id'), user.get('id'));
|
164
168
|
start();
|
165
169
|
});
|
166
170
|
})
|
167
171
|
})
|
168
172
|
|
169
|
-
asyncTest("#createRecord adds hasMany association to records it hasMany of ", function() {
|
173
|
+
asyncTest("#createRecord adds hasMany association to records it hasMany of ", function () {
|
170
174
|
var usersJson = store.makeList('user', 3);
|
171
175
|
|
172
|
-
Em.RSVP.all([store.find('user', usersJson[0].id),store.find('user', usersJson[1].id),store.find('user', usersJson[2].id)]).then(function(users) {
|
176
|
+
Em.RSVP.all([store.find('user', usersJson[0].id), store.find('user', usersJson[1].id), store.find('user', usersJson[2].id)]).then(function (users) {
|
173
177
|
|
174
|
-
var propertyJson = {name:'beach front property'};
|
178
|
+
var propertyJson = {name: 'beach front property'};
|
175
179
|
|
176
180
|
property = store.createRecord('property', propertyJson);
|
177
|
-
property.get('owners').then(function(owners){
|
181
|
+
property.get('owners').then(function (owners) {
|
178
182
|
owners.addObjects(users);
|
179
|
-
}).then(
|
183
|
+
}).then(function () {
|
180
184
|
return property.get('owners');
|
181
|
-
}).then(
|
185
|
+
}).then(function (users) {
|
182
186
|
equal(users.get('length'), usersJson.length);
|
183
187
|
start();
|
184
188
|
});
|
data/tests/index.html
CHANGED
@@ -30,6 +30,7 @@
|
|
30
30
|
<script src='rest_adapter_factory_test.js'></script>
|
31
31
|
<script src='store_test.js'></script>
|
32
32
|
<script src='factory_guy_test.js'></script>
|
33
|
+
<script src='factory_guy_test_mixin_test.js'></script>
|
33
34
|
<div id='qunit-fixture'>
|
34
35
|
|
35
36
|
<!-- any HTML you want to be present in each test (will be reset for each test) -->
|
@@ -195,6 +195,21 @@ test("belongsTo associations defined as attributes in fixture", function() {
|
|
195
195
|
});
|
196
196
|
|
197
197
|
|
198
|
+
test("hasMany associations defined as attributes in fixture", function() {
|
199
|
+
var user = store.makeFixture('user_with_projects');
|
200
|
+
equal(user.get('projects.length'), 2)
|
201
|
+
equal(user.get('projects.firstObject.user'), user)
|
202
|
+
equal(user.get('projects.lastObject.user'), user)
|
203
|
+
})
|
204
|
+
|
205
|
+
test("hasMany associations defined with traits", function() {
|
206
|
+
var user = store.makeFixture('user', 'with_projects');
|
207
|
+
equal(user.get('projects.length'), 2)
|
208
|
+
equal(user.get('projects.firstObject.user'), user)
|
209
|
+
equal(user.get('projects.lastObject.user'), user)
|
210
|
+
})
|
211
|
+
|
212
|
+
|
198
213
|
module('DS.Store#makeList with DS.RESTAdapter', {
|
199
214
|
setup: function() {
|
200
215
|
testHelper = TestHelper.setup(DS.RESTAdapter);
|
@@ -1,4 +1,4 @@
|
|
1
|
-
FactoryGuy.define(
|
1
|
+
FactoryGuy.define("project", {
|
2
2
|
sequences: {
|
3
3
|
title: function(num) {return 'Project' + num}
|
4
4
|
},
|
@@ -7,7 +7,7 @@ FactoryGuy.define('project', {
|
|
7
7
|
with_title_sequence: { title: FactoryGuy.generate('title') },
|
8
8
|
with_user: { user: {} },
|
9
9
|
with_dude: { user: {name: 'Dude'} },
|
10
|
-
with_admin: { user: FactoryGuy.
|
10
|
+
with_admin: { user: FactoryGuy.belongsTo('admin') }
|
11
11
|
},
|
12
12
|
default: {
|
13
13
|
title: FactoryGuy.generate('title')
|
@@ -22,6 +22,11 @@ FactoryGuy.define('project', {
|
|
22
22
|
},
|
23
23
|
project_with_admin: {
|
24
24
|
// for named association, use this FactoryGuy.association helper method
|
25
|
-
user: FactoryGuy.
|
25
|
+
user: FactoryGuy.belongsTo('admin')
|
26
|
+
},
|
27
|
+
project_with_parent: {
|
28
|
+
// refer to belongsTo association where the name of the association
|
29
|
+
// differs from the model name
|
30
|
+
parent: FactoryGuy.belongsTo('project')
|
26
31
|
}
|
27
32
|
});
|
@@ -6,5 +6,13 @@ FactoryGuy.define('user', {
|
|
6
6
|
// named 'user' type with custom attributes
|
7
7
|
admin: {
|
8
8
|
name: 'Admin'
|
9
|
+
},
|
10
|
+
user_with_projects: {
|
11
|
+
projects: FactoryGuy.hasMany('project', 2)
|
12
|
+
},
|
13
|
+
traits: {
|
14
|
+
with_projects: {
|
15
|
+
projects: FactoryGuy.hasMany('project', 2)
|
16
|
+
}
|
9
17
|
}
|
10
18
|
});
|
data/tests/test_setup.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
FactoryGuy.define(
|
1
|
+
FactoryGuy.define("company", {
|
2
2
|
default: {
|
3
3
|
name: 'Silly corp'
|
4
4
|
}
|
@@ -25,7 +25,7 @@ FactoryGuy.define('profile', {
|
|
25
25
|
description: 'Text goes here'
|
26
26
|
}
|
27
27
|
})
|
28
|
-
FactoryGuy.define(
|
28
|
+
FactoryGuy.define("project", {
|
29
29
|
sequences: {
|
30
30
|
title: function(num) {return 'Project' + num}
|
31
31
|
},
|
@@ -34,7 +34,7 @@ FactoryGuy.define('project', {
|
|
34
34
|
with_title_sequence: { title: FactoryGuy.generate('title') },
|
35
35
|
with_user: { user: {} },
|
36
36
|
with_dude: { user: {name: 'Dude'} },
|
37
|
-
with_admin: { user: FactoryGuy.
|
37
|
+
with_admin: { user: FactoryGuy.belongsTo('admin') }
|
38
38
|
},
|
39
39
|
default: {
|
40
40
|
title: FactoryGuy.generate('title')
|
@@ -49,7 +49,12 @@ FactoryGuy.define('project', {
|
|
49
49
|
},
|
50
50
|
project_with_admin: {
|
51
51
|
// for named association, use this FactoryGuy.association helper method
|
52
|
-
user: FactoryGuy.
|
52
|
+
user: FactoryGuy.belongsTo('admin')
|
53
|
+
},
|
54
|
+
project_with_parent: {
|
55
|
+
// refer to belongsTo association where the name of the association
|
56
|
+
// differs from the model name
|
57
|
+
parent: FactoryGuy.belongsTo('project')
|
53
58
|
}
|
54
59
|
});
|
55
60
|
FactoryGuy.define('property', {
|
@@ -65,6 +70,14 @@ FactoryGuy.define('user', {
|
|
65
70
|
// named 'user' type with custom attributes
|
66
71
|
admin: {
|
67
72
|
name: 'Admin'
|
73
|
+
},
|
74
|
+
user_with_projects: {
|
75
|
+
projects: FactoryGuy.hasMany('project', 2)
|
76
|
+
},
|
77
|
+
traits: {
|
78
|
+
with_projects: {
|
79
|
+
projects: FactoryGuy.hasMany('project', 2)
|
80
|
+
}
|
68
81
|
}
|
69
82
|
});
|
70
83
|
Company = DS.Model.extend({
|
@@ -112,16 +125,16 @@ Project = DS.Model.extend({
|
|
112
125
|
});
|
113
126
|
|
114
127
|
Property = DS.Model.extend({
|
115
|
-
name:
|
116
|
-
company:
|
128
|
+
name: DS.attr('string'),
|
129
|
+
company: DS.belongsTo('company', {async: true}),
|
117
130
|
owners: DS.hasMany('user', {async: true, inverse: 'properties'})
|
118
131
|
});
|
119
132
|
User = DS.Model.extend({
|
120
|
-
name:
|
121
|
-
company:
|
122
|
-
properties:
|
133
|
+
name: DS.attr('string'),
|
134
|
+
company: DS.belongsTo('company', {async: true, inverse: 'users'}),
|
135
|
+
properties: DS.hasMany('property', {async: true, inverse: 'owners'}),
|
123
136
|
projects: DS.hasMany('project'),
|
124
|
-
hats:
|
137
|
+
hats: DS.hasMany('hat', {polymorphic: true})
|
125
138
|
});
|
126
139
|
|
127
140
|
|
@@ -70,7 +70,7 @@ ModelDefinition = function (model, config) {
|
|
70
70
|
|
71
71
|
@param {String} name fixture name
|
72
72
|
@param {Object} opts attributes to override
|
73
|
-
@param {String}
|
73
|
+
@param {String} traitArgs array of traits
|
74
74
|
@returns {Object} json
|
75
75
|
*/
|
76
76
|
this.build = function (name, opts, traitArgs) {
|
@@ -135,11 +135,6 @@ ModelDefinition = function (model, config) {
|
|
135
135
|
if (!object) {
|
136
136
|
return
|
137
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
138
|
traits = object;
|
144
139
|
}
|
145
140
|
|
@@ -265,23 +260,65 @@ FactoryGuy = {
|
|
265
260
|
default: {
|
266
261
|
title: 'Project'
|
267
262
|
},
|
263
|
+
|
264
|
+
// setup named project with built in associated user
|
268
265
|
project_with_admin: {
|
269
|
-
|
270
|
-
user: FactoryGuy.association('admin')
|
266
|
+
user: FactoryGuy.belongsTo('admin')
|
271
267
|
}
|
272
268
|
|
269
|
+
// or use as a trait
|
270
|
+
traits: {
|
271
|
+
with_admin: {
|
272
|
+
user: FactoryGuy.belongsTo('admin')
|
273
|
+
}
|
274
|
+
}
|
275
|
+
})
|
273
276
|
```
|
274
277
|
|
275
278
|
@param {String} fixtureName fixture name
|
276
279
|
@param {Object} opts options
|
277
280
|
@returns {Function} wrapper function that will build the association json
|
278
281
|
*/
|
279
|
-
|
282
|
+
belongsTo: function (fixtureName, opts) {
|
280
283
|
return function () {
|
281
284
|
return FactoryGuy.build(fixtureName, opts);
|
282
285
|
}
|
283
286
|
},
|
284
287
|
|
288
|
+
/**
|
289
|
+
Used in model definitions to define a hasMany association attribute.
|
290
|
+
For example:
|
291
|
+
|
292
|
+
```
|
293
|
+
FactoryGuy.define('user', {
|
294
|
+
default: {
|
295
|
+
name: 'Bob'
|
296
|
+
},
|
297
|
+
|
298
|
+
// define the named user type that will have projects
|
299
|
+
user_with_projects: { FactoryGuy.hasMany('project', 2) }
|
300
|
+
|
301
|
+
// or use as a trait
|
302
|
+
traits: {
|
303
|
+
with_projects: {
|
304
|
+
projects: FactoryGuy.hasMany('project', 2)
|
305
|
+
}
|
306
|
+
}
|
307
|
+
})
|
308
|
+
|
309
|
+
```
|
310
|
+
|
311
|
+
@param {String} fixtureName fixture name
|
312
|
+
@param {Number} number of hasMany association items to build
|
313
|
+
@param {Object} opts options
|
314
|
+
@returns {Function} wrapper function that will build the association json
|
315
|
+
*/
|
316
|
+
hasMany: function (fixtureName, number, opts) {
|
317
|
+
return function () {
|
318
|
+
return FactoryGuy.buildList(fixtureName, number, opts);
|
319
|
+
}
|
320
|
+
},
|
321
|
+
|
285
322
|
/**
|
286
323
|
Given a fixture name like 'person' or 'dude' determine what model this name
|
287
324
|
refers to. In this case it's 'person' for each one.
|
@@ -548,9 +585,6 @@ DS.Store.reopen({
|
|
548
585
|
then push that model to the store and set the id of that new model
|
549
586
|
as the attribute value in the fixture
|
550
587
|
|
551
|
-
If it's a hasMany association, and its polymorphic, then convert the
|
552
|
-
attribute value to a polymorphic style
|
553
|
-
|
554
588
|
@param modelType
|
555
589
|
@param fixture
|
556
590
|
*/
|
@@ -564,6 +598,19 @@ DS.Store.reopen({
|
|
564
598
|
fixture[relationship.key] = belongsToRecord;
|
565
599
|
}
|
566
600
|
}
|
601
|
+
if (relationship.kind == 'hasMany') {
|
602
|
+
var hasManyRecords = fixture[relationship.key];
|
603
|
+
// if the records are objects and not instances they need to be converted to
|
604
|
+
// instances
|
605
|
+
if (Ember.typeOf(hasManyRecords) == 'array' && Ember.typeOf(hasManyRecords[0]) == 'object') {
|
606
|
+
var records = Em.A()
|
607
|
+
hasManyRecords.forEach(function(record) {
|
608
|
+
var record = store.push(relationship.type, record);
|
609
|
+
records.push(record);
|
610
|
+
})
|
611
|
+
fixture[relationship.key] = records;
|
612
|
+
}
|
613
|
+
}
|
567
614
|
})
|
568
615
|
},
|
569
616
|
|
@@ -900,6 +947,17 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
900
947
|
}
|
901
948
|
},
|
902
949
|
|
950
|
+
/**
|
951
|
+
Build url for the mockjax call. Proxy to the adapters buildURL method.
|
952
|
+
|
953
|
+
@param {String} type model type name like 'user' for User model
|
954
|
+
@param {String} id
|
955
|
+
@return {String} url
|
956
|
+
*/
|
957
|
+
buildURL: function (type, id) {
|
958
|
+
return this.getStore().adapterFor('application').buildURL(type, id);
|
959
|
+
},
|
960
|
+
|
903
961
|
/**
|
904
962
|
Handling ajax GET ( find record ) for a model. You can mock
|
905
963
|
failed find by passing in status of 500.
|
@@ -912,7 +970,7 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
912
970
|
var modelName = FactoryGuy.lookupModelForFixtureName(name);
|
913
971
|
var responseJson = this.buildAjaxHttpResponse(name, opts);
|
914
972
|
var id = responseJson[modelName].id
|
915
|
-
var url =
|
973
|
+
var url = this.buildURL(modelName, id);
|
916
974
|
this.stubEndpointForHttpRequest(
|
917
975
|
url,
|
918
976
|
responseJson,
|
@@ -932,7 +990,7 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
932
990
|
handleCreate: function (name, opts, status) {
|
933
991
|
var modelName = FactoryGuy.lookupModelForFixtureName(name);
|
934
992
|
var responseJson = this.buildAjaxHttpResponse(name, opts);
|
935
|
-
var url =
|
993
|
+
var url = this.buildURL(modelName);
|
936
994
|
this.stubEndpointForHttpRequest(
|
937
995
|
url,
|
938
996
|
responseJson,
|
@@ -945,13 +1003,13 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
945
1003
|
Handling ajax PUT ( update record ) for a model type. You can mock
|
946
1004
|
failed update by passing in status of 500.
|
947
1005
|
|
948
|
-
@param {String}
|
1006
|
+
@param {String} type model type like 'user' for User model
|
949
1007
|
@param {String} id id of record to update
|
950
1008
|
@param {Integer} status Optional HTTP status response code
|
951
1009
|
*/
|
952
|
-
handleUpdate: function (
|
1010
|
+
handleUpdate: function (type, id, status) {
|
953
1011
|
this.stubEndpointForHttpRequest(
|
954
|
-
|
1012
|
+
this.buildURL(type, id),
|
955
1013
|
{},
|
956
1014
|
{type: 'PUT', status: (status || 200)}
|
957
1015
|
)
|
@@ -961,13 +1019,13 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
961
1019
|
Handling ajax DELETE ( delete record ) for a model type. You can mock
|
962
1020
|
failed delete by passing in status of 500.
|
963
1021
|
|
964
|
-
@param {String}
|
1022
|
+
@param {String} type model type like 'user' for User model
|
965
1023
|
@param {String} id id of record to update
|
966
1024
|
@param {Integer} status Optional HTTP status response code
|
967
1025
|
*/
|
968
|
-
handleDelete: function (
|
1026
|
+
handleDelete: function (type, id, status) {
|
969
1027
|
this.stubEndpointForHttpRequest(
|
970
|
-
|
1028
|
+
this.buildURL(type, id),
|
971
1029
|
{},
|
972
1030
|
{type: 'DELETE', status: (status || 200)}
|
973
1031
|
)
|
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.6.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-08-
|
12
|
+
date: 2014-08-21 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Easily create Fixtures for Ember Data
|
15
15
|
email:
|
@@ -22,6 +22,7 @@ files:
|
|
22
22
|
- .gitignore
|
23
23
|
- .travis.yml
|
24
24
|
- Gruntfile.js
|
25
|
+
- LICENSE
|
25
26
|
- README.md
|
26
27
|
- bower.json
|
27
28
|
- dist/ember-data-factory-guy.js
|
@@ -38,6 +39,7 @@ files:
|
|
38
39
|
- src/store.js
|
39
40
|
- tests/active_model_adapter_factory_test.js
|
40
41
|
- tests/factory_guy_test.js
|
42
|
+
- tests/factory_guy_test_mixin_test.js
|
41
43
|
- tests/fixture_adapter_factory_test.js
|
42
44
|
- tests/index.html
|
43
45
|
- tests/rest_adapter_factory_test.js
|