ember-data-factory-guy 0.8.2 → 0.8.3
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/README.md +28 -17
- data/bower.json +1 -1
- data/dist/ember-data-factory-guy.js +26 -19
- 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_test_mixin.js +26 -19
- data/tests/factory_guy_test_mixin_test.js +10 -0
- data/tests/support/models/profile.js +1 -1
- data/tests/test_setup.js +1 -1
- data/vendor/assets/javascripts/ember_data_factory_guy.js +26 -19
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6cec722b2159388b70506a21e8a83f4023b7af30
|
4
|
+
data.tar.gz: 35e7f0e16e331d54fca3e5e9d783b411db4b459d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 935baa72d03b250f8164f8861a8d0ca46d97e4acd731c2088222a71fa69f7e97f1e2cf4823e0ec4f04af0f2b035843cce9b9b86c3080689678511ecf067b1bf8
|
7
|
+
data.tar.gz: 499d2a19b0118865c5fff04b64ea9258f4ff6f190aaf8f7defd0cce946b9e7443ca34f7b12f9ced4cf8a77afe63b78231a409a23da4a947d5fdf1ae33f53e7a4
|
data/README.md
CHANGED
@@ -9,12 +9,12 @@ of ember-data-factory-guy.
|
|
9
9
|
- Versions:
|
10
10
|
- 0.6.4 -> ember-data-1.0.0-beta.8 and under
|
11
11
|
- 0.7.1.1 -> ember-data-1.0.0-beta.10
|
12
|
-
- 0.8.
|
13
|
-
- 0.8.
|
12
|
+
- 0.8.2 -> ember-data-1.0.0-beta.11
|
13
|
+
- 0.8.2 -> ember-data-1.0.0-beta.12
|
14
14
|
|
15
|
-
**For versions ( 0.7.1 -> 0.8.
|
15
|
+
**For versions ( 0.7.1 -> 0.8.2 ), support for the fixture adapter is currently broken.**
|
16
16
|
|
17
|
-
*Version 0.8.
|
17
|
+
*Version 0.8.2 has many bug fixes and improvements that the earlier versions don't have, so
|
18
18
|
hopefully you can switch to newer version of ember-data and therefore the best
|
19
19
|
ember-data-factory-guy version, but if not, send me bug report and I will try and go back
|
20
20
|
and fix the older version you are using.*
|
@@ -34,7 +34,7 @@ gem 'ember-data-factory-guy', group: test
|
|
34
34
|
or for particular version:
|
35
35
|
|
36
36
|
```ruby
|
37
|
-
gem 'ember-data-factory-guy', '0.8.
|
37
|
+
gem 'ember-data-factory-guy', '0.8.2', group: test
|
38
38
|
```
|
39
39
|
|
40
40
|
then:
|
@@ -69,7 +69,7 @@ or for particular version:
|
|
69
69
|
"dependencies": {
|
70
70
|
"foo-dependency": "latest",
|
71
71
|
"other-foo-dependency": "latest",
|
72
|
-
"ember-data-factory-guy": "0.8.
|
72
|
+
"ember-data-factory-guy": "0.8.2"
|
73
73
|
}
|
74
74
|
```
|
75
75
|
|
@@ -578,9 +578,9 @@ test("make a user using your applications default adapter", function() {
|
|
578
578
|
- Uses mockjax
|
579
579
|
- Has helper methods
|
580
580
|
- handleFindMany
|
581
|
-
- handleCreate
|
582
|
-
- handleUpdate
|
583
|
-
- handleDelete
|
581
|
+
- handleCreate
|
582
|
+
- handleUpdate
|
583
|
+
- handleDelete
|
584
584
|
|
585
585
|
Since it is recommended to use your normal adapter ( which is usually a subclass of RESTAdapter, )
|
586
586
|
FactoryGuyTestMixin assumes you will want to use that adapter to do your integration tests.
|
@@ -609,14 +609,23 @@ and this is already bundled for you when you use the ember-data-factory-guy libr
|
|
609
609
|
```
|
610
610
|
|
611
611
|
##### handleCreate
|
612
|
+
- options
|
613
|
+
- match - attributes that must be in request json
|
614
|
+
- returns - attributes to include in response json
|
615
|
+
- succeed - flag to indicate if the request should succeed ( default is true )
|
616
|
+
|
617
|
+
*Note*
|
618
|
+
That any attributes in match will be added to the response json automatically,
|
619
|
+
so you don't need to include them in the returns hash as well.
|
620
|
+
|
621
|
+
If you don't use match options for exact match, there will be no id returned to the model.
|
622
|
+
|
623
|
+
If you match on a belongsTo association, you don't have to include that in the
|
624
|
+
returns hash.
|
612
625
|
|
613
|
-
|
614
|
-
*success case is the default*
|
615
626
|
|
616
627
|
Realistically, you will have code in a view action or controller action that will
|
617
628
|
create the record, and setup any associations.
|
618
|
-
Therefore, all you need to pass in to handleCreate are the attributes on the model
|
619
|
-
that are being tested ( excluding associations .. you don't need those)
|
620
629
|
|
621
630
|
```javascript
|
622
631
|
|
@@ -632,11 +641,13 @@ Realistically, you will have code in a view action or controller action that wil
|
|
632
641
|
```
|
633
642
|
|
634
643
|
In this case, you are are creating a 'project' record with a specific name, and belonging
|
635
|
-
to a particular user. To mock this createRecord call do this
|
644
|
+
to a particular user. To mock this createRecord call here are a few ways to do this using
|
645
|
+
match and or returns options.
|
636
646
|
|
637
647
|
```javascript
|
638
|
-
// note that you don't
|
639
|
-
|
648
|
+
// note that you don't need the returns option since the
|
649
|
+
// match options are returned automatically
|
650
|
+
testHelper.handleCreate('project', {match: {name: "Moo", user: user}})
|
640
651
|
|
641
652
|
```
|
642
653
|
|
@@ -644,7 +655,7 @@ to a particular user. To mock this createRecord call do this:
|
|
644
655
|
|
645
656
|
```javascript
|
646
657
|
// set the succeed flag to 'false'
|
647
|
-
testHelper.handleCreate('profile',
|
658
|
+
testHelper.handleCreate('profile', {succeed: false});
|
648
659
|
|
649
660
|
// when the createRecord on the 'project' is called, it will fail
|
650
661
|
store.createRecord('project').save() //=> fails
|
data/bower.json
CHANGED
@@ -806,42 +806,49 @@ var FactoryGuyTestMixin = Em.Mixin.create({
|
|
806
806
|
returns - attributes to include in response json,
|
807
807
|
succeed - flag to indicate if the request should succeed ( default is true )
|
808
808
|
|
809
|
-
Note
|
809
|
+
Note:
|
810
|
+
1) that any attributes in match will be added to the response json automatically,
|
810
811
|
so you don't need to include them in the returns hash as well.
|
811
812
|
|
812
|
-
|
813
|
+
2) If you don't use match options for exact match, there will be no id returned to the model.
|
814
|
+
|
815
|
+
3) If you match on a belongsTo association, you don't have to include that in the
|
813
816
|
returns hash.
|
814
817
|
|
815
818
|
@param {String} modelName name of model your creating like 'profile' for Profile
|
816
819
|
@param {Object} options hash of options for handling request
|
817
820
|
*/
|
818
821
|
handleCreate: function (modelName, options) {
|
819
|
-
|
820
|
-
var succeed =
|
821
|
-
var match =
|
822
|
-
var returnArgs =
|
822
|
+
var opts = options === undefined ? {} : options;
|
823
|
+
var succeed = opts.succeed === undefined ? true : opts.succeed;
|
824
|
+
var match = opts.match || {};
|
825
|
+
var returnArgs = opts.returns || {};
|
823
826
|
|
824
827
|
var url = this.buildURL(modelName);
|
825
828
|
var definition = FactoryGuy.modelDefinitions[modelName];
|
826
829
|
|
827
|
-
var
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
830
|
+
var httpOptions = {type: 'POST'};
|
831
|
+
if (opts.match) {
|
832
|
+
var expectedRequest = {};
|
833
|
+
var record = this.getStore().createRecord(modelName, match);
|
834
|
+
expectedRequest[modelName] = record.serialize();
|
835
|
+
httpOptions.data = JSON.stringify(expectedRequest);
|
836
|
+
}
|
832
837
|
|
833
838
|
var modelType = this.getStore().modelFor(modelName)
|
834
839
|
|
835
840
|
var responseJson = {};
|
836
841
|
if (succeed) {
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
842
|
+
if (options) {
|
843
|
+
responseJson[modelName] = $.extend({id: definition.nextId()}, match, returnArgs);
|
844
|
+
// Remove belongsTo associations since they will already be set when you called
|
845
|
+
// createRecord, and included them in those attributes
|
846
|
+
Ember.get(modelType, 'relationshipsByName').forEach(function (relationship) {
|
847
|
+
if (relationship.kind == 'belongsTo') {
|
848
|
+
delete responseJson[modelName][relationship.key];
|
849
|
+
}
|
850
|
+
})
|
851
|
+
}
|
845
852
|
} else {
|
846
853
|
httpOptions.status = 500;
|
847
854
|
}
|
@@ -1 +1 @@
|
|
1
|
-
(function(){var Sequence=function(fn){var index=1;this.next=function(){return fn.call(this,index++)};this.reset=function(){index=1}};var MissingSequenceError=function(message){this.toString=function(){return message}};var ModelDefinition=function(model,config){var sequences={};var traits={};var defaultAttributes={};var namedModels={};var modelId=1;var sequenceName=null;this.model=model;this.matchesName=function(name){return model==name||namedModels[name]};this.nextId=function(){return modelId++};this.generate=function(name,sequenceFn){if(sequenceFn){if(!sequences[name]){sequences[name]=new Sequence(sequenceFn)}}var sequence=sequences[name];if(!sequence){throw new MissingSequenceError("Can not find that sequence named ["+sequenceName+"] in '"+model+"' definition")}return sequence.next()};this.build=function(name,opts,traitArgs){var traitsObj={};traitArgs.forEach(function(trait){$.extend(traitsObj,traits[trait])});var modelAttributes=namedModels[name]||{};var fixture=$.extend({},defaultAttributes,modelAttributes,traitsObj,opts);for(var attribute in fixture){if(Ember.typeOf(fixture[attribute])=="function"){fixture[attribute]=fixture[attribute].call(this,fixture)}else if(Ember.typeOf(fixture[attribute])=="object"){fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}if(!fixture.id){fixture.id=this.nextId()}return fixture};this.buildList=function(name,number,traits,opts){var arr=[];for(var i=0;i<number;i++){arr.push(this.build(name,opts,traits))}return arr};this.reset=function(){modelId=1;for(var name in sequences){sequences[name].reset()}};var parseDefault=function(object){if(!object){return}defaultAttributes=object};var parseTraits=function(object){if(!object){return}traits=object};var parseSequences=function(object){if(!object){return}for(sequenceName in object){var sequenceFn=object[sequenceName];if(Ember.typeOf(sequenceFn)!="function"){throw new Error("Problem with ["+sequenceName+"] sequence definition. Sequences must be functions")}object[sequenceName]=new Sequence(sequenceFn)}sequences=object};var parseConfig=function(config){parseSequences(config.sequences);delete config.sequences;parseTraits(config.traits);delete config.traits;parseDefault(config.default);delete config.default;namedModels=config};parseConfig(config)};var FactoryGuy={modelDefinitions:{},define:function(model,config){if(this.modelDefinitions[model]){this.modelDefinitions[model].merge(config)}else{this.modelDefinitions[model]=new ModelDefinition(model,config)}},generate:function(nameOrFunction){var sortaRandomName=Math.floor((1+Math.random())*65536).toString(16)+Date.now();return function(){if(Em.typeOf(nameOrFunction)=="function"){return this.generate(sortaRandomName,nameOrFunction)}else{return this.generate(nameOrFunction)}}},belongsTo:function(fixtureName,opts){return function(){return FactoryGuy.build(fixtureName,opts)}},association:function(fixtureName,opts){console.log("DEPRECATION Warning: use FactoryGuy.belongsTo instead");return this.belongsTo(fixtureName,opts)},hasMany:function(fixtureName,number,opts){return function(){return FactoryGuy.buildList(fixtureName,number,opts)}},lookupModelForFixtureName:function(name){var definition=this.lookupDefinitionForFixtureName(name);if(definition){return definition.model}},lookupDefinitionForFixtureName:function(name){for(var model in this.modelDefinitions){var definition=this.modelDefinitions[model];if(definition.matchesName(name)){return definition}}},build:function(){var args=Array.prototype.slice.call(arguments);var opts={};var name=args.shift();if(!name){throw new Error("Build needs a factory name to build")}if(Ember.typeOf(args[args.length-1])=="object"){opts=args.pop()}var traits=args;var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.build(name,opts,traits)},buildList:function(){var args=Array.prototype.slice.call(arguments);var name=args.shift();var number=args.shift();if(!name||!number){throw new Error("buildList needs a name and a number ( at least ) to build with")}var opts={};if(Ember.typeOf(args[args.length-1])=="object"){opts=args.pop()}var traits=args;var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.buildList(name,number,traits,opts)},resetModels:function(store){for(var model in this.modelDefinitions){var definition=this.modelDefinitions[model];definition.reset();try{var modelType=store.modelFor(definition.model);if(store.usingFixtureAdapter()){modelType.FIXTURES=[]}store.unloadAll(modelType)}catch(e){console.log("resetModels",e)}}},pushFixture:function(modelClass,fixture){if(!modelClass.FIXTURES){modelClass.FIXTURES=[]}modelClass.FIXTURES.push(fixture);return fixture},clear:function(opts){if(!opts){this.modelDefinitions={}}}};(function(){DS.Store.reopen({usingFixtureAdapter:function(){var adapter=this.adapterFor("application");return adapter instanceof DS.FixtureAdapter},makeFixture:function(){var store=this;var fixture=FactoryGuy.build.apply(FactoryGuy,arguments);var name=arguments[0];var modelName=FactoryGuy.lookupModelForFixtureName(name);var modelType=store.modelFor(modelName);if(this.usingFixtureAdapter()){this.setAssociationsForFixtureAdapter(modelType,modelName,fixture);return FactoryGuy.pushFixture(modelType,fixture)}else{return store.makeModel(modelType,fixture)}},makeModel:function(modelType,fixture){var store=this,modelName=store.modelFor(modelType).typeKey,model;Em.run(function(){store.findEmbeddedAssociationsForRESTAdapter(modelType,fixture);if(fixture.type){modelName=fixture.type.underscore();modelType=store.modelFor(modelName)}model=store.push(modelName,fixture);store.setAssociationsForRESTAdapter(modelType,modelName,model)});return model},makeList:function(){var arr=[];var number=arguments[1];for(var i=0;i<number;i++){arr.push(this.makeFixture.apply(this,arguments))}return arr},setAssociationsForFixtureAdapter:function(modelType,modelName,fixture){var self=this;var adapter=this.adapterFor("application");Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="hasMany"){var hasManyRelation=fixture[relationship.key];if(hasManyRelation){$.each(fixture[relationship.key],function(index,object){var id=object;if(Ember.typeOf(object)=="object"){id=object.id;hasManyRelation[index]=id}var hasManyfixtures=adapter.fixturesForType(relationship.type);var fixture=adapter.findFixtureById(hasManyfixtures,id);fixture[modelName]=fixture.id})}}if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(belongsToRecord){if(typeof belongsToRecord=="object"){FactoryGuy.pushFixture(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord.id}var hasManyName=self.findHasManyRelationshipNameForFixtureAdapter(relationship.type,relationship.parentType);var belongsToFixtures=adapter.fixturesForType(relationship.type);var belongsTofixture=adapter.findFixtureById(belongsToFixtures,fixture[relationship.key]);if(!belongsTofixture[hasManyName]){belongsTofixture[hasManyName]=[]}belongsTofixture[hasManyName].push(fixture.id)}}})},findEmbeddedAssociationsForRESTAdapter:function(modelType,fixture){var store=this;Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(Ember.typeOf(belongsToRecord)=="object"){store.findEmbeddedAssociationsForRESTAdapter(relationship.type,belongsToRecord);belongsToRecord=store.push(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord}}if(relationship.kind=="hasMany"){var hasManyRecords=fixture[relationship.key];if(Ember.typeOf(hasManyRecords)=="array"){if(Ember.typeOf(hasManyRecords[0])=="object"){var records=Em.A();hasManyRecords.map(function(object){store.findEmbeddedAssociationsForRESTAdapter(relationship.type,object);var record=store.push(relationship.type,object);records.push(record);return record});fixture[relationship.key]=records}}}})},setAssociationsForRESTAdapter:function(modelType,modelName,model){var self=this;Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="hasMany"){var children=model.get(name)||[];children.forEach(function(child){var belongsToName=self.findRelationshipName("belongsTo",child.constructor,model);if(belongsToName){child.set(belongsToName,model)}})}})},findRelationshipName:function(kind,belongToModelType,childModel){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind==kind&&childModel instanceof relationship.type){relationshipName=relationship.key}});return relationshipName},findHasManyRelationshipNameForFixtureAdapter:function(belongToModelType,childModelType){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="hasMany"&&childModelType==relationship.type){relationshipName=relationship.key}});return relationshipName},pushPayload:function(type,payload){if(this.usingFixtureAdapter()){var model=this.modelFor(modelName);FactoryGuy.pushFixture(model,payload)}else{this._super(type,payload)}}})})();var FactoryGuyTestMixin=Em.Mixin.create({setup:function(app){this.set("container",app.__container__);return this},useFixtureAdapter:function(app){app.ApplicationAdapter=DS.FixtureAdapter;this.getStore().adapterFor("application").simulateRemoteResponse=false},usingActiveModelSerializer:function(type){var store=this.getStore();var modelType=store.modelFor(type);var serializer=store.serializerFor(modelType.typeKey);return serializer instanceof DS.ActiveModelSerializer},find:function(type,id){return this.getStore().find(type,id)},make:function(){var store=this.getStore();return store.makeFixture.apply(store,arguments)},getStore:function(){return this.get("container").lookup("store:main")},pushPayload:function(type,hash){return this.getStore().pushPayload(type,hash)},pushRecord:function(type,hash){return this.getStore().push(type,hash)},stubEndpointForHttpRequest:function(url,json,options){options=options||{};var request={url:url,dataType:"json",responseText:json,type:options.type||"GET",status:options.status||200};if(options.data){request.data=options.data}$.mockjax(request)},buildURL:function(typeName,id){var type=this.getStore().modelFor(typeName);return this.getStore().adapterFor(type).buildURL(type.typeKey,id)},handleFindMany:function(){var store=this.getStore();store.makeList.apply(store,arguments);var name=arguments[0];var modelName=FactoryGuy.lookupModelForFixtureName(name);var responseJson={};responseJson[modelName]=[];var url=this.buildURL(modelName);this.stubEndpointForHttpRequest(url,responseJson,{type:"GET"})},handleCreate:function(modelName,options){options=options===undefined?{}:options;var succeed=options.succeed===undefined?true:options.succeed;var match=options.match||{};var returnArgs=options.returns||{};var url=this.buildURL(modelName);var definition=FactoryGuy.modelDefinitions[modelName];var record=this.getStore().createRecord(modelName,match);var expectedRequest={};expectedRequest[modelName]=record.serialize();var httpOptions={type:"POST",data:JSON.stringify(expectedRequest)};var modelType=this.getStore().modelFor(modelName);var responseJson={};if(succeed){responseJson[modelName]=$.extend({id:definition.nextId()},match,returnArgs);Ember.get(modelType,"relationshipsByName").forEach(function(relationship){if(relationship.kind=="belongsTo"){delete responseJson[modelName][relationship.key]}})}else{httpOptions.status=500}this.stubEndpointForHttpRequest(url,responseJson,httpOptions)},handleUpdate:function(type,id,succeed){succeed=succeed===undefined?true:succeed;this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"PUT",status:succeed?200:500})},handleDelete:function(type,id,succeed){succeed=succeed===undefined?true:succeed;this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"DELETE",status:succeed?200:500})},teardown:function(){FactoryGuy.resetModels(this.getStore());$.mockjax.clear()}});FactoryGuy.testMixin=FactoryGuyTestMixin;FactoryGuy.sequence=Sequence;FactoryGuy.sequence.missingSequenceError=MissingSequenceError;if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=FactoryGuy}exports.FactoryGuy=FactoryGuy}if(typeof define==="function"&&define.amd){define("factory-guy",[],function(){return FactoryGuy})}if(typeof window==="object"&&typeof window.document==="object"){window.FactoryGuy=FactoryGuy}})();
|
1
|
+
(function(){var Sequence=function(fn){var index=1;this.next=function(){return fn.call(this,index++)};this.reset=function(){index=1}};var MissingSequenceError=function(message){this.toString=function(){return message}};var ModelDefinition=function(model,config){var sequences={};var traits={};var defaultAttributes={};var namedModels={};var modelId=1;var sequenceName=null;this.model=model;this.matchesName=function(name){return model==name||namedModels[name]};this.nextId=function(){return modelId++};this.generate=function(name,sequenceFn){if(sequenceFn){if(!sequences[name]){sequences[name]=new Sequence(sequenceFn)}}var sequence=sequences[name];if(!sequence){throw new MissingSequenceError("Can not find that sequence named ["+sequenceName+"] in '"+model+"' definition")}return sequence.next()};this.build=function(name,opts,traitArgs){var traitsObj={};traitArgs.forEach(function(trait){$.extend(traitsObj,traits[trait])});var modelAttributes=namedModels[name]||{};var fixture=$.extend({},defaultAttributes,modelAttributes,traitsObj,opts);for(var attribute in fixture){if(Ember.typeOf(fixture[attribute])=="function"){fixture[attribute]=fixture[attribute].call(this,fixture)}else if(Ember.typeOf(fixture[attribute])=="object"){fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}if(!fixture.id){fixture.id=this.nextId()}return fixture};this.buildList=function(name,number,traits,opts){var arr=[];for(var i=0;i<number;i++){arr.push(this.build(name,opts,traits))}return arr};this.reset=function(){modelId=1;for(var name in sequences){sequences[name].reset()}};var parseDefault=function(object){if(!object){return}defaultAttributes=object};var parseTraits=function(object){if(!object){return}traits=object};var parseSequences=function(object){if(!object){return}for(sequenceName in object){var sequenceFn=object[sequenceName];if(Ember.typeOf(sequenceFn)!="function"){throw new Error("Problem with ["+sequenceName+"] sequence definition. Sequences must be functions")}object[sequenceName]=new Sequence(sequenceFn)}sequences=object};var parseConfig=function(config){parseSequences(config.sequences);delete config.sequences;parseTraits(config.traits);delete config.traits;parseDefault(config.default);delete config.default;namedModels=config};parseConfig(config)};var FactoryGuy={modelDefinitions:{},define:function(model,config){if(this.modelDefinitions[model]){this.modelDefinitions[model].merge(config)}else{this.modelDefinitions[model]=new ModelDefinition(model,config)}},generate:function(nameOrFunction){var sortaRandomName=Math.floor((1+Math.random())*65536).toString(16)+Date.now();return function(){if(Em.typeOf(nameOrFunction)=="function"){return this.generate(sortaRandomName,nameOrFunction)}else{return this.generate(nameOrFunction)}}},belongsTo:function(fixtureName,opts){return function(){return FactoryGuy.build(fixtureName,opts)}},association:function(fixtureName,opts){console.log("DEPRECATION Warning: use FactoryGuy.belongsTo instead");return this.belongsTo(fixtureName,opts)},hasMany:function(fixtureName,number,opts){return function(){return FactoryGuy.buildList(fixtureName,number,opts)}},lookupModelForFixtureName:function(name){var definition=this.lookupDefinitionForFixtureName(name);if(definition){return definition.model}},lookupDefinitionForFixtureName:function(name){for(var model in this.modelDefinitions){var definition=this.modelDefinitions[model];if(definition.matchesName(name)){return definition}}},build:function(){var args=Array.prototype.slice.call(arguments);var opts={};var name=args.shift();if(!name){throw new Error("Build needs a factory name to build")}if(Ember.typeOf(args[args.length-1])=="object"){opts=args.pop()}var traits=args;var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.build(name,opts,traits)},buildList:function(){var args=Array.prototype.slice.call(arguments);var name=args.shift();var number=args.shift();if(!name||!number){throw new Error("buildList needs a name and a number ( at least ) to build with")}var opts={};if(Ember.typeOf(args[args.length-1])=="object"){opts=args.pop()}var traits=args;var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.buildList(name,number,traits,opts)},resetModels:function(store){for(var model in this.modelDefinitions){var definition=this.modelDefinitions[model];definition.reset();try{var modelType=store.modelFor(definition.model);if(store.usingFixtureAdapter()){modelType.FIXTURES=[]}store.unloadAll(modelType)}catch(e){console.log("resetModels",e)}}},pushFixture:function(modelClass,fixture){if(!modelClass.FIXTURES){modelClass.FIXTURES=[]}modelClass.FIXTURES.push(fixture);return fixture},clear:function(opts){if(!opts){this.modelDefinitions={}}}};(function(){DS.Store.reopen({usingFixtureAdapter:function(){var adapter=this.adapterFor("application");return adapter instanceof DS.FixtureAdapter},makeFixture:function(){var store=this;var fixture=FactoryGuy.build.apply(FactoryGuy,arguments);var name=arguments[0];var modelName=FactoryGuy.lookupModelForFixtureName(name);var modelType=store.modelFor(modelName);if(this.usingFixtureAdapter()){this.setAssociationsForFixtureAdapter(modelType,modelName,fixture);return FactoryGuy.pushFixture(modelType,fixture)}else{return store.makeModel(modelType,fixture)}},makeModel:function(modelType,fixture){var store=this,modelName=store.modelFor(modelType).typeKey,model;Em.run(function(){store.findEmbeddedAssociationsForRESTAdapter(modelType,fixture);if(fixture.type){modelName=fixture.type.underscore();modelType=store.modelFor(modelName)}model=store.push(modelName,fixture);store.setAssociationsForRESTAdapter(modelType,modelName,model)});return model},makeList:function(){var arr=[];var number=arguments[1];for(var i=0;i<number;i++){arr.push(this.makeFixture.apply(this,arguments))}return arr},setAssociationsForFixtureAdapter:function(modelType,modelName,fixture){var self=this;var adapter=this.adapterFor("application");Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="hasMany"){var hasManyRelation=fixture[relationship.key];if(hasManyRelation){$.each(fixture[relationship.key],function(index,object){var id=object;if(Ember.typeOf(object)=="object"){id=object.id;hasManyRelation[index]=id}var hasManyfixtures=adapter.fixturesForType(relationship.type);var fixture=adapter.findFixtureById(hasManyfixtures,id);fixture[modelName]=fixture.id})}}if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(belongsToRecord){if(typeof belongsToRecord=="object"){FactoryGuy.pushFixture(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord.id}var hasManyName=self.findHasManyRelationshipNameForFixtureAdapter(relationship.type,relationship.parentType);var belongsToFixtures=adapter.fixturesForType(relationship.type);var belongsTofixture=adapter.findFixtureById(belongsToFixtures,fixture[relationship.key]);if(!belongsTofixture[hasManyName]){belongsTofixture[hasManyName]=[]}belongsTofixture[hasManyName].push(fixture.id)}}})},findEmbeddedAssociationsForRESTAdapter:function(modelType,fixture){var store=this;Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(Ember.typeOf(belongsToRecord)=="object"){store.findEmbeddedAssociationsForRESTAdapter(relationship.type,belongsToRecord);belongsToRecord=store.push(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord}}if(relationship.kind=="hasMany"){var hasManyRecords=fixture[relationship.key];if(Ember.typeOf(hasManyRecords)=="array"){if(Ember.typeOf(hasManyRecords[0])=="object"){var records=Em.A();hasManyRecords.map(function(object){store.findEmbeddedAssociationsForRESTAdapter(relationship.type,object);var record=store.push(relationship.type,object);records.push(record);return record});fixture[relationship.key]=records}}}})},setAssociationsForRESTAdapter:function(modelType,modelName,model){var self=this;Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="hasMany"){var children=model.get(name)||[];children.forEach(function(child){var belongsToName=self.findRelationshipName("belongsTo",child.constructor,model);if(belongsToName){child.set(belongsToName,model)}})}})},findRelationshipName:function(kind,belongToModelType,childModel){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind==kind&&childModel instanceof relationship.type){relationshipName=relationship.key}});return relationshipName},findHasManyRelationshipNameForFixtureAdapter:function(belongToModelType,childModelType){var relationshipName;Ember.get(belongToModelType,"relationshipsByName").forEach(function(relationship,name){if(relationship.kind=="hasMany"&&childModelType==relationship.type){relationshipName=relationship.key}});return relationshipName},pushPayload:function(type,payload){if(this.usingFixtureAdapter()){var model=this.modelFor(modelName);FactoryGuy.pushFixture(model,payload)}else{this._super(type,payload)}}})})();var FactoryGuyTestMixin=Em.Mixin.create({setup:function(app){this.set("container",app.__container__);return this},useFixtureAdapter:function(app){app.ApplicationAdapter=DS.FixtureAdapter;this.getStore().adapterFor("application").simulateRemoteResponse=false},usingActiveModelSerializer:function(type){var store=this.getStore();var modelType=store.modelFor(type);var serializer=store.serializerFor(modelType.typeKey);return serializer instanceof DS.ActiveModelSerializer},find:function(type,id){return this.getStore().find(type,id)},make:function(){var store=this.getStore();return store.makeFixture.apply(store,arguments)},getStore:function(){return this.get("container").lookup("store:main")},pushPayload:function(type,hash){return this.getStore().pushPayload(type,hash)},pushRecord:function(type,hash){return this.getStore().push(type,hash)},stubEndpointForHttpRequest:function(url,json,options){options=options||{};var request={url:url,dataType:"json",responseText:json,type:options.type||"GET",status:options.status||200};if(options.data){request.data=options.data}$.mockjax(request)},buildURL:function(typeName,id){var type=this.getStore().modelFor(typeName);return this.getStore().adapterFor(type).buildURL(type.typeKey,id)},handleFindMany:function(){var store=this.getStore();store.makeList.apply(store,arguments);var name=arguments[0];var modelName=FactoryGuy.lookupModelForFixtureName(name);var responseJson={};responseJson[modelName]=[];var url=this.buildURL(modelName);this.stubEndpointForHttpRequest(url,responseJson,{type:"GET"})},handleCreate:function(modelName,options){var opts=options===undefined?{}:options;var succeed=opts.succeed===undefined?true:opts.succeed;var match=opts.match||{};var returnArgs=opts.returns||{};var url=this.buildURL(modelName);var definition=FactoryGuy.modelDefinitions[modelName];var httpOptions={type:"POST"};if(opts.match){var expectedRequest={};var record=this.getStore().createRecord(modelName,match);expectedRequest[modelName]=record.serialize();httpOptions.data=JSON.stringify(expectedRequest)}var modelType=this.getStore().modelFor(modelName);var responseJson={};if(succeed){if(options){responseJson[modelName]=$.extend({id:definition.nextId()},match,returnArgs);Ember.get(modelType,"relationshipsByName").forEach(function(relationship){if(relationship.kind=="belongsTo"){delete responseJson[modelName][relationship.key]}})}}else{httpOptions.status=500}this.stubEndpointForHttpRequest(url,responseJson,httpOptions)},handleUpdate:function(type,id,succeed){succeed=succeed===undefined?true:succeed;this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"PUT",status:succeed?200:500})},handleDelete:function(type,id,succeed){succeed=succeed===undefined?true:succeed;this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"DELETE",status:succeed?200:500})},teardown:function(){FactoryGuy.resetModels(this.getStore());$.mockjax.clear()}});FactoryGuy.testMixin=FactoryGuyTestMixin;FactoryGuy.sequence=Sequence;FactoryGuy.sequence.missingSequenceError=MissingSequenceError;if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports){exports=module.exports=FactoryGuy}exports.FactoryGuy=FactoryGuy}if(typeof define==="function"&&define.amd){define("factory-guy",[],function(){return FactoryGuy})}if(typeof window==="object"&&typeof window.document==="object"){window.FactoryGuy=FactoryGuy}})();
|
@@ -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.8.
|
4
|
+
s.version = "0.8.3"
|
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
@@ -116,42 +116,49 @@ var FactoryGuyTestMixin = Em.Mixin.create({
|
|
116
116
|
returns - attributes to include in response json,
|
117
117
|
succeed - flag to indicate if the request should succeed ( default is true )
|
118
118
|
|
119
|
-
Note
|
119
|
+
Note:
|
120
|
+
1) that any attributes in match will be added to the response json automatically,
|
120
121
|
so you don't need to include them in the returns hash as well.
|
121
122
|
|
122
|
-
|
123
|
+
2) If you don't use match options for exact match, there will be no id returned to the model.
|
124
|
+
|
125
|
+
3) If you match on a belongsTo association, you don't have to include that in the
|
123
126
|
returns hash.
|
124
127
|
|
125
128
|
@param {String} modelName name of model your creating like 'profile' for Profile
|
126
129
|
@param {Object} options hash of options for handling request
|
127
130
|
*/
|
128
131
|
handleCreate: function (modelName, options) {
|
129
|
-
|
130
|
-
var succeed =
|
131
|
-
var match =
|
132
|
-
var returnArgs =
|
132
|
+
var opts = options === undefined ? {} : options;
|
133
|
+
var succeed = opts.succeed === undefined ? true : opts.succeed;
|
134
|
+
var match = opts.match || {};
|
135
|
+
var returnArgs = opts.returns || {};
|
133
136
|
|
134
137
|
var url = this.buildURL(modelName);
|
135
138
|
var definition = FactoryGuy.modelDefinitions[modelName];
|
136
139
|
|
137
|
-
var
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
140
|
+
var httpOptions = {type: 'POST'};
|
141
|
+
if (opts.match) {
|
142
|
+
var expectedRequest = {};
|
143
|
+
var record = this.getStore().createRecord(modelName, match);
|
144
|
+
expectedRequest[modelName] = record.serialize();
|
145
|
+
httpOptions.data = JSON.stringify(expectedRequest);
|
146
|
+
}
|
142
147
|
|
143
148
|
var modelType = this.getStore().modelFor(modelName)
|
144
149
|
|
145
150
|
var responseJson = {};
|
146
151
|
if (succeed) {
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
152
|
+
if (options) {
|
153
|
+
responseJson[modelName] = $.extend({id: definition.nextId()}, match, returnArgs);
|
154
|
+
// Remove belongsTo associations since they will already be set when you called
|
155
|
+
// createRecord, and included them in those attributes
|
156
|
+
Ember.get(modelType, 'relationshipsByName').forEach(function (relationship) {
|
157
|
+
if (relationship.kind == 'belongsTo') {
|
158
|
+
delete responseJson[modelName][relationship.key];
|
159
|
+
}
|
160
|
+
})
|
161
|
+
}
|
155
162
|
} else {
|
156
163
|
httpOptions.status = 500;
|
157
164
|
}
|
@@ -111,6 +111,16 @@ module('FactoryGuyTestMixin (using mockjax) with DS.ActiveModelAdapter', {
|
|
111
111
|
|
112
112
|
/////// handleCreate //////////
|
113
113
|
|
114
|
+
asyncTest("#handleCreate with no specific match (which returns no id)", function() {
|
115
|
+
testHelper.handleCreate('profile');
|
116
|
+
|
117
|
+
store.createRecord('profile', {description: 'whatever'}).save().then(function(profile) {
|
118
|
+
ok(profile.id == null) // no id returned when non specific matching
|
119
|
+
ok(profile.get('description') == 'whatever')
|
120
|
+
start();
|
121
|
+
});
|
122
|
+
});
|
123
|
+
|
114
124
|
asyncTest("#handleCreate matches attributes and returns these", function() {
|
115
125
|
var customDescription = "special description"
|
116
126
|
|
data/tests/test_setup.js
CHANGED
@@ -240,7 +240,7 @@ Person = DS.Model.extend({
|
|
240
240
|
})
|
241
241
|
|
242
242
|
Profile = DS.Model.extend({
|
243
|
-
created_at:
|
243
|
+
created_at: DS.attr('date'),
|
244
244
|
description: DS.attr('string'),
|
245
245
|
camelCaseDescription: DS.attr('string'),
|
246
246
|
snake_case_description: DS.attr('string'),
|
@@ -804,42 +804,49 @@ var FactoryGuyTestMixin = Em.Mixin.create({
|
|
804
804
|
returns - attributes to include in response json,
|
805
805
|
succeed - flag to indicate if the request should succeed ( default is true )
|
806
806
|
|
807
|
-
Note
|
807
|
+
Note:
|
808
|
+
1) that any attributes in match will be added to the response json automatically,
|
808
809
|
so you don't need to include them in the returns hash as well.
|
809
810
|
|
810
|
-
|
811
|
+
2) If you don't use match options for exact match, there will be no id returned to the model.
|
812
|
+
|
813
|
+
3) If you match on a belongsTo association, you don't have to include that in the
|
811
814
|
returns hash.
|
812
815
|
|
813
816
|
@param {String} modelName name of model your creating like 'profile' for Profile
|
814
817
|
@param {Object} options hash of options for handling request
|
815
818
|
*/
|
816
819
|
handleCreate: function (modelName, options) {
|
817
|
-
|
818
|
-
var succeed =
|
819
|
-
var match =
|
820
|
-
var returnArgs =
|
820
|
+
var opts = options === undefined ? {} : options;
|
821
|
+
var succeed = opts.succeed === undefined ? true : opts.succeed;
|
822
|
+
var match = opts.match || {};
|
823
|
+
var returnArgs = opts.returns || {};
|
821
824
|
|
822
825
|
var url = this.buildURL(modelName);
|
823
826
|
var definition = FactoryGuy.modelDefinitions[modelName];
|
824
827
|
|
825
|
-
var
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
828
|
+
var httpOptions = {type: 'POST'};
|
829
|
+
if (opts.match) {
|
830
|
+
var expectedRequest = {};
|
831
|
+
var record = this.getStore().createRecord(modelName, match);
|
832
|
+
expectedRequest[modelName] = record.serialize();
|
833
|
+
httpOptions.data = JSON.stringify(expectedRequest);
|
834
|
+
}
|
830
835
|
|
831
836
|
var modelType = this.getStore().modelFor(modelName)
|
832
837
|
|
833
838
|
var responseJson = {};
|
834
839
|
if (succeed) {
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
840
|
+
if (options) {
|
841
|
+
responseJson[modelName] = $.extend({id: definition.nextId()}, match, returnArgs);
|
842
|
+
// Remove belongsTo associations since they will already be set when you called
|
843
|
+
// createRecord, and included them in those attributes
|
844
|
+
Ember.get(modelType, 'relationshipsByName').forEach(function (relationship) {
|
845
|
+
if (relationship.kind == 'belongsTo') {
|
846
|
+
delete responseJson[modelName][relationship.key];
|
847
|
+
}
|
848
|
+
})
|
849
|
+
}
|
843
850
|
} else {
|
844
851
|
httpOptions.status = 500;
|
845
852
|
}
|