ember-data-factory-guy 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|