ember-data-factory-guy 0.4.0 → 0.4.1
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/bower.json +1 -1
- data/dist/ember-data-factory-guy.js +138 -42
- data/dist/ember-data-factory-guy.min.js +1 -1
- data/ember-data-factory-guy.gemspec +1 -1
- data/package.json +7 -8
- data/src/factory_guy_test_mixin.js +102 -38
- data/src/model_definition.js +3 -3
- data/src/store.js +33 -1
- data/tests/active_model_adapter_factory_test.js +33 -8
- data/tests/support/factories/profile_factory.js +1 -3
- data/tests/support/models/user.js +2 -1
- data/tests/support/test_helper.js +7 -2
- data/tests/test_setup.js +3 -3
- data/vendor/assets/javascripts/ember_data_factory_guy.js +138 -42
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5bdae9f46c1972abb834e6dbc097e0c078d8e97
|
4
|
+
data.tar.gz: 6587a2575c0b315ebf1e03a1157e219f051e4e72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 287ae58b03af66d6fde0256d692ce1b8ed7609487c5fa619f4fed997b980fe41eae3205aa1e97144bc643dc15f2e74b6a250721e1c097107d97af7b13fd67930
|
7
|
+
data.tar.gz: 29510c92fc6965cf66059895635de26153e14b818c9fd52f0974d06802091367ddb5cd625808632b70faac1578408a51901dd5ead3cedda9e846ec018eef9971
|
data/bower.json
CHANGED
@@ -96,9 +96,9 @@ ModelDefinition = function (model, config) {
|
|
96
96
|
/**
|
97
97
|
Build a list of fixtures
|
98
98
|
|
99
|
-
@param name model name or named model type
|
100
|
-
@param number of fixtures to build
|
101
|
-
@param opts attribute options
|
99
|
+
@param {String} name model name or named model type
|
100
|
+
@param {Integer} number of fixtures to build
|
101
|
+
@param {Object} opts attribute options
|
102
102
|
@returns array of fixtures
|
103
103
|
*/
|
104
104
|
this.buildList = function (name, number, opts) {
|
@@ -381,6 +381,12 @@ DS.Store.reopen({
|
|
381
381
|
return adapter instanceof DS.FixtureAdapter;
|
382
382
|
},
|
383
383
|
|
384
|
+
usingActiveModelSerializer: function () {
|
385
|
+
var adapter = this.adapterFor('application');
|
386
|
+
console.log('adapter.defaultSerializer', adapter.defaultSerializer)
|
387
|
+
return adapter.defaultSerializer == 'active-model';
|
388
|
+
},
|
389
|
+
|
384
390
|
/**
|
385
391
|
Make new fixture and save to store. If the store is using FixtureAdapter,
|
386
392
|
will push to FIXTURE array, otherwise will use push method on adapter.
|
@@ -400,6 +406,7 @@ DS.Store.reopen({
|
|
400
406
|
return FactoryGuy.pushFixture(modelType, fixture);
|
401
407
|
} else {
|
402
408
|
var store = this;
|
409
|
+
|
403
410
|
var model;
|
404
411
|
Em.run(function () {
|
405
412
|
store.findEmbeddedBelongsToAssociationsForRESTAdapter(modelType, fixture);
|
@@ -543,6 +550,7 @@ DS.Store.reopen({
|
|
543
550
|
*/
|
544
551
|
setAssociationsForRESTAdapter: function (modelType, modelName, model) {
|
545
552
|
var self = this;
|
553
|
+
|
546
554
|
Ember.get(modelType, 'relationshipsByName').forEach(function (name, relationship) {
|
547
555
|
if (relationship.kind == 'hasMany') {
|
548
556
|
var children = model.get(name) || [];
|
@@ -555,7 +563,9 @@ DS.Store.reopen({
|
|
555
563
|
if (relationship.options && relationship.options.inverse) {
|
556
564
|
belongsToName = relationship.options.inverse;
|
557
565
|
}
|
558
|
-
|
566
|
+
if (belongsToName) {
|
567
|
+
child.set(belongsToName, model);
|
568
|
+
}
|
559
569
|
})
|
560
570
|
}
|
561
571
|
|
@@ -570,6 +580,7 @@ DS.Store.reopen({
|
|
570
580
|
)
|
571
581
|
if (hasManyName) {
|
572
582
|
belongsToRecord.get(hasManyName).addObject(model);
|
583
|
+
return;
|
573
584
|
}
|
574
585
|
var oneToOneName = self.findRelationshipName(
|
575
586
|
'belongsTo',
|
@@ -621,6 +632,27 @@ DS.Store.reopen({
|
|
621
632
|
return relationshipName;
|
622
633
|
},
|
623
634
|
|
635
|
+
// /**
|
636
|
+
// Adding the ability to check the serializer and convert the json before
|
637
|
+
// it's pushed. For the ActiveModelSerializer, the attributes should be snake case,
|
638
|
+
// for example.
|
639
|
+
//
|
640
|
+
// @method push
|
641
|
+
// @param {String or subclass of DS.Model} type
|
642
|
+
// @param {Object} data
|
643
|
+
// @return {DS.Model} the record that was created or updated.
|
644
|
+
// */
|
645
|
+
// push: function(type, data, _partial) {
|
646
|
+
// var type = this.modelFor(type);
|
647
|
+
// var serializer = this.serializerFor(type.typeKey);
|
648
|
+
// console.log('serializer',serializer, serializer+'')
|
649
|
+
//// if (this.usingActiveModelSerializer()) {
|
650
|
+
//// var model = this.modelFor(modelName);
|
651
|
+
//// FactoryGuy.pushFixture(model, payload);
|
652
|
+
//// }
|
653
|
+
// this._super(type, data, _partial);
|
654
|
+
// },
|
655
|
+
|
624
656
|
/**
|
625
657
|
Adding a pushPayload for FixtureAdapter, but using the original with
|
626
658
|
other adapters that support pushPayload.
|
@@ -706,16 +738,27 @@ DS.FixtureAdapter.reopen({
|
|
706
738
|
FactoryGuyTestMixin = Em.Mixin.create({
|
707
739
|
|
708
740
|
// Pass in the app root, which typically is App.
|
709
|
-
setup: function(app) {
|
741
|
+
setup: function (app) {
|
710
742
|
this.set('container', app.__container__);
|
711
743
|
return this;
|
712
744
|
},
|
713
745
|
|
714
|
-
useFixtureAdapter: function(app) {
|
746
|
+
useFixtureAdapter: function (app) {
|
715
747
|
app.ApplicationAdapter = DS.FixtureAdapter;
|
716
748
|
this.getStore().adapterFor('application').simulateRemoteResponse = false;
|
717
749
|
},
|
718
750
|
|
751
|
+
/**
|
752
|
+
@param {String} model type like user for model User
|
753
|
+
@return {boolean} true if model's serializer is ActiveModelSerializer based
|
754
|
+
*/
|
755
|
+
usingActiveModelSerializer: function (type) {
|
756
|
+
var store = this.getStore()
|
757
|
+
var type = store.modelFor(type);
|
758
|
+
var serializer = store.serializerFor(type.typeKey);
|
759
|
+
return serializer instanceof DS.ActiveModelSerializer;
|
760
|
+
},
|
761
|
+
|
719
762
|
/**
|
720
763
|
Proxy to store's find method
|
721
764
|
|
@@ -723,11 +766,11 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
723
766
|
@param {Object|String|Integer|null} id
|
724
767
|
@return {Promise} promise
|
725
768
|
*/
|
726
|
-
find: function(type, id) {
|
769
|
+
find: function (type, id) {
|
727
770
|
return this.getStore().find(type, id);
|
728
771
|
},
|
729
772
|
|
730
|
-
make: function(name, opts) {
|
773
|
+
make: function (name, opts) {
|
731
774
|
return this.getStore().makeFixture(name, opts);
|
732
775
|
},
|
733
776
|
|
@@ -735,20 +778,20 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
735
778
|
return this.get('container').lookup('store:main');
|
736
779
|
},
|
737
780
|
|
738
|
-
pushPayload: function(type, hash) {
|
781
|
+
pushPayload: function (type, hash) {
|
739
782
|
return this.getStore().pushPayload(type, hash);
|
740
783
|
},
|
741
784
|
|
742
|
-
pushRecord: function(type, hash) {
|
785
|
+
pushRecord: function (type, hash) {
|
743
786
|
return this.getStore().push(type, hash);
|
744
787
|
},
|
745
788
|
|
746
789
|
/**
|
747
|
-
|
790
|
+
Using mockjax to stub an http request.
|
748
791
|
|
749
|
-
|
750
|
-
|
751
|
-
|
792
|
+
@param {String} url request url
|
793
|
+
@param {Object} json response
|
794
|
+
@param {Object} options ajax request options
|
752
795
|
*/
|
753
796
|
stubEndpointForHttpRequest: function (url, json, options) {
|
754
797
|
options = options || {};
|
@@ -768,54 +811,107 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
768
811
|
},
|
769
812
|
|
770
813
|
/**
|
771
|
-
|
814
|
+
Build the json used for creating record
|
772
815
|
|
773
|
-
|
774
|
-
|
816
|
+
@param {String} name of the fixture ( or model ) to create
|
817
|
+
@param {Object} opts fixture options
|
775
818
|
*/
|
776
|
-
|
777
|
-
var
|
778
|
-
var
|
779
|
-
|
780
|
-
|
819
|
+
buildAjaxHttpResponse: function (name, opts) {
|
820
|
+
var fixture = FactoryGuy.build(name, opts);
|
821
|
+
var modelName = FactoryGuy.lookupModelForFixtureName(name);
|
822
|
+
if (this.usingActiveModelSerializer(modelName)) {
|
823
|
+
this.toSnakeCase(fixture);
|
824
|
+
}
|
825
|
+
var hash = {};
|
826
|
+
hash[modelName] = fixture;
|
827
|
+
return hash;
|
828
|
+
},
|
829
|
+
|
830
|
+
/**
|
831
|
+
Convert Object's keys to snake case
|
832
|
+
|
833
|
+
@param {Object} fixture to convert
|
834
|
+
*/
|
835
|
+
toSnakeCase: function (fixture) {
|
836
|
+
for (key in fixture) {
|
837
|
+
if (key != Em.String.decamelize(key)) {
|
838
|
+
var value = fixture[key];
|
839
|
+
delete fixture[key];
|
840
|
+
fixture[Em.String.decamelize(key)] = value
|
841
|
+
}
|
842
|
+
}
|
843
|
+
},
|
844
|
+
|
845
|
+
/**
|
846
|
+
Handling ajax GET ( find record ) for a model. You can mock
|
847
|
+
failed find by passing in status of 500.
|
848
|
+
|
849
|
+
@param {String} name of the fixture ( or model ) to find
|
850
|
+
@param {Object} opts fixture options
|
851
|
+
@param {Integer} status Optional HTTP status response code
|
852
|
+
*/
|
853
|
+
handleFind: function (name, opts, status) {
|
854
|
+
var modelName = FactoryGuy.lookupModelForFixtureName(name);
|
855
|
+
var responseJson = this.buildAjaxHttpResponse(name, opts);
|
856
|
+
var id = responseJson[modelName].id
|
857
|
+
var url = "/" + Em.String.pluralize(modelName) + "/" + id;
|
858
|
+
this.stubEndpointForHttpRequest(
|
859
|
+
url,
|
860
|
+
responseJson,
|
861
|
+
{type: 'GET', status: (status || 200)}
|
862
|
+
)
|
781
863
|
return responseJson;
|
782
864
|
},
|
783
865
|
|
784
866
|
/**
|
785
|
-
|
867
|
+
Handling ajax POST ( create record ) for a model. You can mock
|
868
|
+
failed create by passing in status of 500.
|
786
869
|
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
var
|
793
|
-
var
|
794
|
-
|
795
|
-
|
870
|
+
@param {String} name of the fixture ( or model ) to create
|
871
|
+
@param {Object} opts fixture options
|
872
|
+
@param {Integer} status Optional HTTP status response code
|
873
|
+
*/
|
874
|
+
handleCreate: function (name, opts, status) {
|
875
|
+
var modelName = FactoryGuy.lookupModelForFixtureName(name);
|
876
|
+
var responseJson = this.buildAjaxHttpResponse(name, opts);
|
877
|
+
var url = "/" + Em.String.pluralize(modelName);
|
878
|
+
this.stubEndpointForHttpRequest(
|
879
|
+
url,
|
880
|
+
responseJson,
|
881
|
+
{type: 'POST', status: (status || 200)}
|
882
|
+
)
|
883
|
+
return responseJson;
|
796
884
|
},
|
797
885
|
|
798
886
|
/**
|
799
|
-
|
887
|
+
Handling ajax PUT ( update record ) for a model type. You can mock
|
888
|
+
failed update by passing in status of 500.
|
800
889
|
|
801
|
-
|
802
|
-
|
890
|
+
@param {String} root modelType like 'user' for User
|
891
|
+
@param {String} id id of record to update
|
892
|
+
@param {Integer} status Optional HTTP status response code
|
803
893
|
*/
|
804
|
-
handleUpdate: function (root, id) {
|
894
|
+
handleUpdate: function (root, id, status) {
|
805
895
|
this.stubEndpointForHttpRequest(
|
806
|
-
|
896
|
+
"/" + Em.String.pluralize(root) + "/" + id,
|
897
|
+
{},
|
898
|
+
{type: 'PUT', status: (status || 200)}
|
807
899
|
)
|
808
900
|
},
|
809
901
|
|
810
902
|
/**
|
811
|
-
|
903
|
+
Handling ajax DELETE ( delete record ) for a model type. You can mock
|
904
|
+
failed delete by passing in status of 500.
|
812
905
|
|
813
|
-
|
814
|
-
|
906
|
+
@param {String} root modelType like 'user' for User
|
907
|
+
@param {String} id id of record to update
|
908
|
+
@param {Integer} status Optional HTTP status response code
|
815
909
|
*/
|
816
|
-
handleDelete: function (root, id) {
|
910
|
+
handleDelete: function (root, id, status) {
|
817
911
|
this.stubEndpointForHttpRequest(
|
818
|
-
|
912
|
+
"/" + Em.String.pluralize(root) + "/" + id,
|
913
|
+
{},
|
914
|
+
{type: 'DELETE', status: (status || 200)}
|
819
915
|
)
|
820
916
|
},
|
821
917
|
|
@@ -1 +1 @@
|
|
1
|
-
Sequence=function(fn){var index=1;this.next=function(){return fn.call(this,index++)};this.reset=function(){index=1}};function MissingSequenceError(message){this.toString=function(){return message}}ModelDefinition=function(model,config){var sequences={};var defaultAttributes={};var namedModels={};var modelId=1;this.model=model;this.matchesName=function(name){return model==name||namedModels[name]};this.merge=function(config){};this.generate=function(name,sequenceFn){if(sequenceFn){if(!sequences[name]){sequences[name]=new Sequence(sequenceFn)}}var sequence=sequences[name];if(!sequence){throw new MissingSequenceError("Can not find that sequence named ["+sequenceName+"] in '"+model+"' definition")}return sequence.next()};this.build=function(name,opts){var modelAttributes=namedModels[name]||{};var fixture=$.extend({},defaultAttributes,modelAttributes,opts);for(attribute in fixture){if(Ember.typeOf(fixture[attribute])=="function"){fixture[attribute]=fixture[attribute].call(this,fixture)}else if(Ember.typeOf(fixture[attribute])=="object"){fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}if(!fixture.id){fixture.id=modelId++}return fixture};this.buildList=function(name,number,opts){var arr=[];for(var i=0;i<number;i++){arr.push(this.build(name,opts))}return arr};this.reset=function(){modelId=1;for(name in sequences){sequences[name].reset()}};var parseDefault=function(object){if(!object){return}defaultAttributes=object};var parseSequences=function(object){if(!object){return}for(sequenceName in object){var sequenceFn=object[sequenceName];if(typeof sequenceFn!="function"){throw new Error("Problem with ["+sequenceName+"] sequence definition. Sequences must be functions")}object[sequenceName]=new Sequence(sequenceFn)}sequences=object};var parseConfig=function(config){parseSequences(config.sequences);delete config.sequences;parseDefault(config.default);delete config.default;namedModels=config};parseConfig(config)};FactoryGuy={modelDefinitions:{},define:function(model,config){if(this.modelDefinitions[model]){this.modelDefinitions[model].merge(config)}else{this.modelDefinitions[model]=new ModelDefinition(model,config)}},generate:function(nameOrFunction){var sortaRandomName=Math.floor((1+Math.random())*65536).toString(16)+Date.now();return function(){if(Em.typeOf(nameOrFunction)=="function"){return this.generate(sortaRandomName,nameOrFunction)}else{return this.generate(nameOrFunction)}}},association:function(fixtureName,opts){return function(){return FactoryGuy.build(fixtureName,opts)}},lookupModelForFixtureName:function(name){var definition=this.lookupDefinitionForFixtureName(name);if(definition){return definition.model}},lookupDefinitionForFixtureName:function(name){for(model in this.modelDefinitions){var definition=this.modelDefinitions[model];if(definition.matchesName(name)){return definition}}},build:function(name,opts){var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.build(name,opts)},buildList:function(name,number,opts){var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.buildList(name,number,opts)},resetModels:function(store){for(model in this.modelDefinitions){var definition=this.modelDefinitions[model];definition.reset();try{var modelType=store.modelFor(definition.model);if(store.usingFixtureAdapter()){modelType.FIXTURES=[]}store.unloadAll(modelType)}catch(e){}}},pushFixture:function(modelClass,fixture){if(!modelClass["FIXTURES"]){modelClass["FIXTURES"]=[]}modelClass["FIXTURES"].push(fixture);return fixture},clear:function(opts){if(!opts){this.modelDefinitions={}}}};DS.Store.reopen({usingFixtureAdapter:function(){var adapter=this.adapterFor("application");return adapter instanceof DS.FixtureAdapter},makeFixture:function(name,options){var store=this;var modelName=FactoryGuy.lookupModelForFixtureName(name);var fixture=FactoryGuy.build(name,options);var modelType=store.modelFor(modelName);if(this.usingFixtureAdapter()){this.setAssociationsForFixtureAdapter(modelType,modelName,fixture);return FactoryGuy.pushFixture(modelType,fixture)}else{var store=this;var model;Em.run(function(){store.findEmbeddedBelongsToAssociationsForRESTAdapter(modelType,fixture);if(fixture.type){modelName=fixture.type.underscore();modelType=store.modelFor(modelName)}model=store.push(modelName,fixture);store.setAssociationsForRESTAdapter(modelType,modelName,model)});return model}},makeList:function(name,number,options){var arr=[];for(var i=0;i<number;i++){arr.push(this.makeFixture(name,options))}return arr},setAssociationsForFixtureAdapter:function(modelType,modelName,fixture){var self=this;var adapter=this.adapterFor("application");Ember.get(modelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="hasMany"){if(fixture[relationship.key]){fixture[relationship.key].forEach(function(id){var hasManyfixtures=adapter.fixturesForType(relationship.type);var fixture=adapter.findFixtureById(hasManyfixtures,id);fixture[modelName]=fixture.id})}}if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(belongsToRecord){if(typeof belongsToRecord=="object"){FactoryGuy.pushFixture(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord.id}var hasManyName=self.findHasManyRelationshipNameForFixtureAdapter(relationship.type,relationship.parentType);var belongsToFixtures=adapter.fixturesForType(relationship.type);var belongsTofixture=adapter.findFixtureById(belongsToFixtures,fixture[relationship.key]);if(!belongsTofixture[hasManyName]){belongsTofixture[hasManyName]=[]}belongsTofixture[hasManyName].push(fixture.id)}}})},findEmbeddedBelongsToAssociationsForRESTAdapter:function(modelType,fixture){var store=this;Ember.get(modelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="belongsTo"){var belongsToRecord=fixture[relationship.key];if(Ember.typeOf(belongsToRecord)=="object"){belongsToRecord=store.push(relationship.type,belongsToRecord);fixture[relationship.key]=belongsToRecord}}})},setAssociationsForRESTAdapter:function(modelType,modelName,model){var self=this;Ember.get(modelType,"relationshipsByName").forEach(function(name,relationship){if(relationship.kind=="hasMany"){var children=model.get(name)||[];children.forEach(function(child){var belongsToName=self.findRelationshipName("belongsTo",child.constructor,model);if(relationship.options&&relationship.options.inverse){belongsToName=relationship.options.inverse}child.set(belongsToName,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)}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(){var relationShips=Ember.get(type,"relationshipNames");if(relationShips.belongsTo){relationShips.belongsTo.forEach(function(relationship){var belongsToRecord=record.get(relationship);if(belongsToRecord){var hasManyName=store.findRelationshipName("hasMany",belongsToRecord.constructor,record);belongsToRecord.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},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)},handleCreate:function(name,opts){var model=FactoryGuy.lookupModelForFixtureName(name);var responseJson=this.buildAjaxCreateResponse(name,opts);var url="/"+Em.String.pluralize(model);this.stubEndpointForHttpRequest(url,responseJson,{type:"POST"});return responseJson},buildAjaxCreateResponse:function(name,opts){var fixture=FactoryGuy.build(name,opts);var model=FactoryGuy.lookupModelForFixtureName(name);var hash={};hash[model]=fixture;return hash},handleUpdate:function(root,id){this.stubEndpointForHttpRequest("/"+Em.String.pluralize(root)+"/"+id,{},{type:"PUT"})},handleDelete:function(root,id){this.stubEndpointForHttpRequest("/"+Em.String.pluralize(root)+"/"+id,{},{type:"DELETE"})},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 defaultAttributes={};var namedModels={};var modelId=1;this.model=model;this.matchesName=function(name){return model==name||namedModels[name]};this.merge=function(config){};this.generate=function(name,sequenceFn){if(sequenceFn){if(!sequences[name]){sequences[name]=new Sequence(sequenceFn)}}var sequence=sequences[name];if(!sequence){throw new MissingSequenceError("Can not find that sequence named ["+sequenceName+"] in '"+model+"' definition")}return sequence.next()};this.build=function(name,opts){var modelAttributes=namedModels[name]||{};var fixture=$.extend({},defaultAttributes,modelAttributes,opts);for(attribute in fixture){if(Ember.typeOf(fixture[attribute])=="function"){fixture[attribute]=fixture[attribute].call(this,fixture)}else if(Ember.typeOf(fixture[attribute])=="object"){fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}if(!fixture.id){fixture.id=modelId++}return fixture};this.buildList=function(name,number,opts){var arr=[];for(var i=0;i<number;i++){arr.push(this.build(name,opts))}return arr};this.reset=function(){modelId=1;for(name in sequences){sequences[name].reset()}};var parseDefault=function(object){if(!object){return}defaultAttributes=object};var parseSequences=function(object){if(!object){return}for(sequenceName in object){var sequenceFn=object[sequenceName];if(typeof sequenceFn!="function"){throw new Error("Problem with ["+sequenceName+"] sequence definition. Sequences must be functions")}object[sequenceName]=new Sequence(sequenceFn)}sequences=object};var parseConfig=function(config){parseSequences(config.sequences);delete config.sequences;parseDefault(config.default);delete config.default;namedModels=config};parseConfig(config)};FactoryGuy={modelDefinitions:{},define:function(model,config){if(this.modelDefinitions[model]){this.modelDefinitions[model].merge(config)}else{this.modelDefinitions[model]=new ModelDefinition(model,config)}},generate:function(nameOrFunction){var sortaRandomName=Math.floor((1+Math.random())*65536).toString(16)+Date.now();return function(){if(Em.typeOf(nameOrFunction)=="function"){return this.generate(sortaRandomName,nameOrFunction)}else{return this.generate(nameOrFunction)}}},association:function(fixtureName,opts){return function(){return FactoryGuy.build(fixtureName,opts)}},lookupModelForFixtureName:function(name){var definition=this.lookupDefinitionForFixtureName(name);if(definition){return definition.model}},lookupDefinitionForFixtureName:function(name){for(model in this.modelDefinitions){var definition=this.modelDefinitions[model];if(definition.matchesName(name)){return definition}}},build:function(name,opts){var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.build(name,opts)},buildList:function(name,number,opts){var definition=this.lookupDefinitionForFixtureName(name);if(!definition){throw new Error("Can't find that factory named ["+name+"]")}return definition.buildList(name,number,opts)},resetModels:function(store){for(model in this.modelDefinitions){var definition=this.modelDefinitions[model];definition.reset();try{var modelType=store.modelFor(definition.model);if(store.usingFixtureAdapter()){modelType.FIXTURES=[]}store.unloadAll(modelType)}catch(e){}}},pushFixture:function(modelClass,fixture){if(!modelClass["FIXTURES"]){modelClass["FIXTURES"]=[]}modelClass["FIXTURES"].push(fixture);return fixture},clear:function(opts){if(!opts){this.modelDefinitions={}}}};DS.Store.reopen({usingFixtureAdapter:function(){var adapter=this.adapterFor("application");return adapter instanceof DS.FixtureAdapter},usingActiveModelSerializer:function(){var adapter=this.adapterFor("application");console.log("adapter.defaultSerializer",adapter.defaultSerializer);return adapter.defaultSerializer=="active-model"},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);if(relationship.options&&relationship.options.inverse){belongsToName=relationship.options.inverse}if(belongsToName){child.set(belongsToName,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(){var relationShips=Ember.get(type,"relationshipNames");if(relationShips.belongsTo){relationShips.belongsTo.forEach(function(relationship){var belongsToRecord=record.get(relationship);if(belongsToRecord){var hasManyName=store.findRelationshipName("hasMany",belongsToRecord.constructor,record);belongsToRecord.get(hasManyName).addObject(record)}})}});return promise}});FactoryGuyTestMixin=Em.Mixin.create({setup:function(app){this.set("container",app.__container__);return this},useFixtureAdapter:function(app){app.ApplicationAdapter=DS.FixtureAdapter;this.getStore().adapterFor("application").simulateRemoteResponse=false},usingActiveModelSerializer:function(type){var store=this.getStore();var type=store.modelFor(type);var serializer=store.serializerFor(type.typeKey);return serializer instanceof DS.ActiveModelSerializer},find:function(type,id){return this.getStore().find(type,id)},make:function(name,opts){return this.getStore().makeFixture(name,opts)},getStore:function(){return this.get("container").lookup("store:main")},pushPayload:function(type,hash){return this.getStore().pushPayload(type,hash)},pushRecord:function(type,hash){return this.getStore().push(type,hash)},stubEndpointForHttpRequest:function(url,json,options){options=options||{};var request={url:url,dataType:"json",responseText:json,type:options.type||"GET",status:options.status||200};if(options.data){request.data=options.data}$.mockjax(request)},buildAjaxHttpResponse:function(name,opts){var fixture=FactoryGuy.build(name,opts);var modelName=FactoryGuy.lookupModelForFixtureName(name);if(this.usingActiveModelSerializer(modelName)){this.toSnakeCase(fixture)}var hash={};hash[modelName]=fixture;return hash},toSnakeCase:function(fixture){for(key in fixture){if(key!=Em.String.decamelize(key)){var value=fixture[key];delete fixture[key];fixture[Em.String.decamelize(key)]=value}}},handleFind:function(name,opts,status){var modelName=FactoryGuy.lookupModelForFixtureName(name);var responseJson=this.buildAjaxHttpResponse(name,opts);var id=responseJson[modelName].id;var url="/"+Em.String.pluralize(modelName)+"/"+id;this.stubEndpointForHttpRequest(url,responseJson,{type:"GET",status:status||200});return responseJson},handleCreate:function(name,opts,status){var modelName=FactoryGuy.lookupModelForFixtureName(name);var responseJson=this.buildAjaxHttpResponse(name,opts);var url="/"+Em.String.pluralize(modelName);this.stubEndpointForHttpRequest(url,responseJson,{type:"POST",status:status||200});return responseJson},handleUpdate:function(root,id,status){this.stubEndpointForHttpRequest("/"+Em.String.pluralize(root)+"/"+id,{},{type:"PUT",status:status||200})},handleDelete:function(root,id,status){this.stubEndpointForHttpRequest("/"+Em.String.pluralize(root)+"/"+id,{},{type:"DELETE",status:status||200})},teardown:function(){FactoryGuy.resetModels(this.getStore())}});
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
Gem::Specification.new do |s|
|
3
3
|
s.name = "ember-data-factory-guy"
|
4
|
-
s.version = "0.4.
|
4
|
+
s.version = "0.4.1"
|
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
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "ember-data-factory-guy",
|
3
|
-
"version": "0.4.
|
3
|
+
"version": "0.4.1",
|
4
4
|
"authors": [
|
5
5
|
"Daniel Sudol <dansudol@yahoo.com>",
|
6
6
|
"Opak Alex <opak.alexandr@gmail.com>"
|
@@ -24,13 +24,12 @@
|
|
24
24
|
"type": "git",
|
25
25
|
"url": ""
|
26
26
|
},
|
27
|
-
"devDependencies":
|
28
|
-
"
|
29
|
-
"
|
30
|
-
"
|
31
|
-
"
|
32
|
-
|
33
|
-
},
|
27
|
+
"devDependencies": [
|
28
|
+
"grunt-contrib-coffee",
|
29
|
+
"grunt-contrib-concat",
|
30
|
+
"grunt-contrib-uglify",
|
31
|
+
"grunt-contrib-qunit"
|
32
|
+
],
|
34
33
|
"engines": {
|
35
34
|
"node": ">=v0.10.1"
|
36
35
|
}
|
@@ -1,16 +1,27 @@
|
|
1
1
|
FactoryGuyTestMixin = Em.Mixin.create({
|
2
2
|
|
3
3
|
// Pass in the app root, which typically is App.
|
4
|
-
setup: function(app) {
|
4
|
+
setup: function (app) {
|
5
5
|
this.set('container', app.__container__);
|
6
6
|
return this;
|
7
7
|
},
|
8
8
|
|
9
|
-
useFixtureAdapter: function(app) {
|
9
|
+
useFixtureAdapter: function (app) {
|
10
10
|
app.ApplicationAdapter = DS.FixtureAdapter;
|
11
11
|
this.getStore().adapterFor('application').simulateRemoteResponse = false;
|
12
12
|
},
|
13
13
|
|
14
|
+
/**
|
15
|
+
@param {String} model type like user for model User
|
16
|
+
@return {boolean} true if model's serializer is ActiveModelSerializer based
|
17
|
+
*/
|
18
|
+
usingActiveModelSerializer: function (type) {
|
19
|
+
var store = this.getStore()
|
20
|
+
var type = store.modelFor(type);
|
21
|
+
var serializer = store.serializerFor(type.typeKey);
|
22
|
+
return serializer instanceof DS.ActiveModelSerializer;
|
23
|
+
},
|
24
|
+
|
14
25
|
/**
|
15
26
|
Proxy to store's find method
|
16
27
|
|
@@ -18,11 +29,11 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
18
29
|
@param {Object|String|Integer|null} id
|
19
30
|
@return {Promise} promise
|
20
31
|
*/
|
21
|
-
find: function(type, id) {
|
32
|
+
find: function (type, id) {
|
22
33
|
return this.getStore().find(type, id);
|
23
34
|
},
|
24
35
|
|
25
|
-
make: function(name, opts) {
|
36
|
+
make: function (name, opts) {
|
26
37
|
return this.getStore().makeFixture(name, opts);
|
27
38
|
},
|
28
39
|
|
@@ -30,20 +41,20 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
30
41
|
return this.get('container').lookup('store:main');
|
31
42
|
},
|
32
43
|
|
33
|
-
pushPayload: function(type, hash) {
|
44
|
+
pushPayload: function (type, hash) {
|
34
45
|
return this.getStore().pushPayload(type, hash);
|
35
46
|
},
|
36
47
|
|
37
|
-
pushRecord: function(type, hash) {
|
48
|
+
pushRecord: function (type, hash) {
|
38
49
|
return this.getStore().push(type, hash);
|
39
50
|
},
|
40
51
|
|
41
52
|
/**
|
42
|
-
|
53
|
+
Using mockjax to stub an http request.
|
43
54
|
|
44
|
-
|
45
|
-
|
46
|
-
|
55
|
+
@param {String} url request url
|
56
|
+
@param {Object} json response
|
57
|
+
@param {Object} options ajax request options
|
47
58
|
*/
|
48
59
|
stubEndpointForHttpRequest: function (url, json, options) {
|
49
60
|
options = options || {};
|
@@ -63,54 +74,107 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
63
74
|
},
|
64
75
|
|
65
76
|
/**
|
66
|
-
|
77
|
+
Build the json used for creating record
|
78
|
+
|
79
|
+
@param {String} name of the fixture ( or model ) to create
|
80
|
+
@param {Object} opts fixture options
|
81
|
+
*/
|
82
|
+
buildAjaxHttpResponse: function (name, opts) {
|
83
|
+
var fixture = FactoryGuy.build(name, opts);
|
84
|
+
var modelName = FactoryGuy.lookupModelForFixtureName(name);
|
85
|
+
if (this.usingActiveModelSerializer(modelName)) {
|
86
|
+
this.toSnakeCase(fixture);
|
87
|
+
}
|
88
|
+
var hash = {};
|
89
|
+
hash[modelName] = fixture;
|
90
|
+
return hash;
|
91
|
+
},
|
92
|
+
|
93
|
+
/**
|
94
|
+
Convert Object's keys to snake case
|
95
|
+
|
96
|
+
@param {Object} fixture to convert
|
97
|
+
*/
|
98
|
+
toSnakeCase: function (fixture) {
|
99
|
+
for (key in fixture) {
|
100
|
+
if (key != Em.String.decamelize(key)) {
|
101
|
+
var value = fixture[key];
|
102
|
+
delete fixture[key];
|
103
|
+
fixture[Em.String.decamelize(key)] = value
|
104
|
+
}
|
105
|
+
}
|
106
|
+
},
|
107
|
+
|
108
|
+
/**
|
109
|
+
Handling ajax GET ( find record ) for a model. You can mock
|
110
|
+
failed find by passing in status of 500.
|
67
111
|
|
68
|
-
|
69
|
-
|
112
|
+
@param {String} name of the fixture ( or model ) to find
|
113
|
+
@param {Object} opts fixture options
|
114
|
+
@param {Integer} status Optional HTTP status response code
|
70
115
|
*/
|
71
|
-
|
72
|
-
var
|
73
|
-
var responseJson = this.
|
74
|
-
var
|
75
|
-
|
116
|
+
handleFind: function (name, opts, status) {
|
117
|
+
var modelName = FactoryGuy.lookupModelForFixtureName(name);
|
118
|
+
var responseJson = this.buildAjaxHttpResponse(name, opts);
|
119
|
+
var id = responseJson[modelName].id
|
120
|
+
var url = "/" + Em.String.pluralize(modelName) + "/" + id;
|
121
|
+
this.stubEndpointForHttpRequest(
|
122
|
+
url,
|
123
|
+
responseJson,
|
124
|
+
{type: 'GET', status: (status || 200)}
|
125
|
+
)
|
76
126
|
return responseJson;
|
77
127
|
},
|
78
128
|
|
79
129
|
/**
|
80
|
-
|
130
|
+
Handling ajax POST ( create record ) for a model. You can mock
|
131
|
+
failed create by passing in status of 500.
|
81
132
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
var
|
88
|
-
var
|
89
|
-
|
90
|
-
|
133
|
+
@param {String} name of the fixture ( or model ) to create
|
134
|
+
@param {Object} opts fixture options
|
135
|
+
@param {Integer} status Optional HTTP status response code
|
136
|
+
*/
|
137
|
+
handleCreate: function (name, opts, status) {
|
138
|
+
var modelName = FactoryGuy.lookupModelForFixtureName(name);
|
139
|
+
var responseJson = this.buildAjaxHttpResponse(name, opts);
|
140
|
+
var url = "/" + Em.String.pluralize(modelName);
|
141
|
+
this.stubEndpointForHttpRequest(
|
142
|
+
url,
|
143
|
+
responseJson,
|
144
|
+
{type: 'POST', status: (status || 200)}
|
145
|
+
)
|
146
|
+
return responseJson;
|
91
147
|
},
|
92
148
|
|
93
149
|
/**
|
94
|
-
|
150
|
+
Handling ajax PUT ( update record ) for a model type. You can mock
|
151
|
+
failed update by passing in status of 500.
|
95
152
|
|
96
|
-
|
97
|
-
|
153
|
+
@param {String} root modelType like 'user' for User
|
154
|
+
@param {String} id id of record to update
|
155
|
+
@param {Integer} status Optional HTTP status response code
|
98
156
|
*/
|
99
|
-
handleUpdate: function (root, id) {
|
157
|
+
handleUpdate: function (root, id, status) {
|
100
158
|
this.stubEndpointForHttpRequest(
|
101
|
-
|
159
|
+
"/" + Em.String.pluralize(root) + "/" + id,
|
160
|
+
{},
|
161
|
+
{type: 'PUT', status: (status || 200)}
|
102
162
|
)
|
103
163
|
},
|
104
164
|
|
105
165
|
/**
|
106
|
-
|
166
|
+
Handling ajax DELETE ( delete record ) for a model type. You can mock
|
167
|
+
failed delete by passing in status of 500.
|
107
168
|
|
108
|
-
|
109
|
-
|
169
|
+
@param {String} root modelType like 'user' for User
|
170
|
+
@param {String} id id of record to update
|
171
|
+
@param {Integer} status Optional HTTP status response code
|
110
172
|
*/
|
111
|
-
handleDelete: function (root, id) {
|
173
|
+
handleDelete: function (root, id, status) {
|
112
174
|
this.stubEndpointForHttpRequest(
|
113
|
-
|
175
|
+
"/" + Em.String.pluralize(root) + "/" + id,
|
176
|
+
{},
|
177
|
+
{type: 'DELETE', status: (status || 200)}
|
114
178
|
)
|
115
179
|
},
|
116
180
|
|
data/src/model_definition.js
CHANGED
@@ -80,9 +80,9 @@ ModelDefinition = function (model, config) {
|
|
80
80
|
/**
|
81
81
|
Build a list of fixtures
|
82
82
|
|
83
|
-
@param name model name or named model type
|
84
|
-
@param number of fixtures to build
|
85
|
-
@param opts attribute options
|
83
|
+
@param {String} name model name or named model type
|
84
|
+
@param {Integer} number of fixtures to build
|
85
|
+
@param {Object} opts attribute options
|
86
86
|
@returns array of fixtures
|
87
87
|
*/
|
88
88
|
this.buildList = function (name, number, opts) {
|
data/src/store.js
CHANGED
@@ -7,6 +7,12 @@ DS.Store.reopen({
|
|
7
7
|
return adapter instanceof DS.FixtureAdapter;
|
8
8
|
},
|
9
9
|
|
10
|
+
usingActiveModelSerializer: function () {
|
11
|
+
var adapter = this.adapterFor('application');
|
12
|
+
console.log('adapter.defaultSerializer', adapter.defaultSerializer)
|
13
|
+
return adapter.defaultSerializer == 'active-model';
|
14
|
+
},
|
15
|
+
|
10
16
|
/**
|
11
17
|
Make new fixture and save to store. If the store is using FixtureAdapter,
|
12
18
|
will push to FIXTURE array, otherwise will use push method on adapter.
|
@@ -26,6 +32,7 @@ DS.Store.reopen({
|
|
26
32
|
return FactoryGuy.pushFixture(modelType, fixture);
|
27
33
|
} else {
|
28
34
|
var store = this;
|
35
|
+
|
29
36
|
var model;
|
30
37
|
Em.run(function () {
|
31
38
|
store.findEmbeddedBelongsToAssociationsForRESTAdapter(modelType, fixture);
|
@@ -169,6 +176,7 @@ DS.Store.reopen({
|
|
169
176
|
*/
|
170
177
|
setAssociationsForRESTAdapter: function (modelType, modelName, model) {
|
171
178
|
var self = this;
|
179
|
+
|
172
180
|
Ember.get(modelType, 'relationshipsByName').forEach(function (name, relationship) {
|
173
181
|
if (relationship.kind == 'hasMany') {
|
174
182
|
var children = model.get(name) || [];
|
@@ -181,7 +189,9 @@ DS.Store.reopen({
|
|
181
189
|
if (relationship.options && relationship.options.inverse) {
|
182
190
|
belongsToName = relationship.options.inverse;
|
183
191
|
}
|
184
|
-
|
192
|
+
if (belongsToName) {
|
193
|
+
child.set(belongsToName, model);
|
194
|
+
}
|
185
195
|
})
|
186
196
|
}
|
187
197
|
|
@@ -196,6 +206,7 @@ DS.Store.reopen({
|
|
196
206
|
)
|
197
207
|
if (hasManyName) {
|
198
208
|
belongsToRecord.get(hasManyName).addObject(model);
|
209
|
+
return;
|
199
210
|
}
|
200
211
|
var oneToOneName = self.findRelationshipName(
|
201
212
|
'belongsTo',
|
@@ -247,6 +258,27 @@ DS.Store.reopen({
|
|
247
258
|
return relationshipName;
|
248
259
|
},
|
249
260
|
|
261
|
+
// /**
|
262
|
+
// Adding the ability to check the serializer and convert the json before
|
263
|
+
// it's pushed. For the ActiveModelSerializer, the attributes should be snake case,
|
264
|
+
// for example.
|
265
|
+
//
|
266
|
+
// @method push
|
267
|
+
// @param {String or subclass of DS.Model} type
|
268
|
+
// @param {Object} data
|
269
|
+
// @return {DS.Model} the record that was created or updated.
|
270
|
+
// */
|
271
|
+
// push: function(type, data, _partial) {
|
272
|
+
// var type = this.modelFor(type);
|
273
|
+
// var serializer = this.serializerFor(type.typeKey);
|
274
|
+
// console.log('serializer',serializer, serializer+'')
|
275
|
+
//// if (this.usingActiveModelSerializer()) {
|
276
|
+
//// var model = this.modelFor(modelName);
|
277
|
+
//// FactoryGuy.pushFixture(model, payload);
|
278
|
+
//// }
|
279
|
+
// this._super(type, data, _partial);
|
280
|
+
// },
|
281
|
+
|
250
282
|
/**
|
251
283
|
Adding a pushPayload for FixtureAdapter, but using the original with
|
252
284
|
other adapters that support pushPayload.
|
@@ -60,10 +60,15 @@ asyncTest("creates records in the store", function() {
|
|
60
60
|
});
|
61
61
|
|
62
62
|
|
63
|
+
test("handles camelCase attributes", function() {
|
64
|
+
var profile = store.makeFixture('profile', {camelCaseDescription: 'description'});
|
65
|
+
ok(!!profile.get('camelCaseDescription'))
|
66
|
+
});
|
67
|
+
|
68
|
+
|
63
69
|
test("when hasMany associations assigned, belongTo parent is assigned", function() {
|
64
70
|
var project = store.makeFixture('project');
|
65
71
|
var user = store.makeFixture('user', {projects: [project]})
|
66
|
-
|
67
72
|
deepEqual(project.get('user').toJSON(), user.toJSON());
|
68
73
|
});
|
69
74
|
|
@@ -210,14 +215,34 @@ test("creates records in the store", function() {
|
|
210
215
|
});
|
211
216
|
|
212
217
|
|
213
|
-
|
214
|
-
|
215
|
-
|
218
|
+
|
219
|
+
module('DS.Store with ActiveModelAdapter', {
|
220
|
+
setup: function() {
|
221
|
+
testHelper = TestHelper.setup(DS.ActiveModelAdapter);
|
222
|
+
store = testHelper.getStore();
|
223
|
+
},
|
224
|
+
teardown: function() {
|
225
|
+
Em.run(function() { testHelper.teardown(); });
|
226
|
+
}
|
227
|
+
});
|
228
|
+
|
229
|
+
|
230
|
+
asyncTest("#createRecord with mockjax handles model's camelCase attributes", function() {
|
231
|
+
testHelper.handleCreate('profile', {camelCaseDescription: 'description'})
|
232
|
+
|
216
233
|
store.createRecord('profile').save().then(function(profile) {
|
217
|
-
// both types of attributes work just fine
|
218
|
-
ok(!!profile.get('snake_case_description'))
|
219
234
|
ok(!!profile.get('camelCaseDescription'))
|
220
235
|
start();
|
221
|
-
})
|
222
|
-
})
|
236
|
+
});
|
237
|
+
});
|
223
238
|
|
239
|
+
|
240
|
+
asyncTest("#find with mockjax handles camelCase attributes", function() {
|
241
|
+
var responseJson = testHelper.handleFind('profile', {camelCaseDescription: 'description'})
|
242
|
+
var id = responseJson.profile.id
|
243
|
+
|
244
|
+
store.find('profile', id).then(function(profile) {
|
245
|
+
ok(!!profile.get('camelCaseDescription'))
|
246
|
+
start();
|
247
|
+
});
|
248
|
+
});
|
@@ -8,7 +8,6 @@ TestHelper = Ember.Object.createWithMixins(FactoryGuyTestMixin,{
|
|
8
8
|
setup: function(adapter) {
|
9
9
|
$.mockjaxSettings.logging = false;
|
10
10
|
$.mockjaxSettings.responseTime = 0;
|
11
|
-
|
12
11
|
var container = new Ember.Container();
|
13
12
|
this.set('container', container);
|
14
13
|
|
@@ -21,7 +20,13 @@ TestHelper = Ember.Object.createWithMixins(FactoryGuyTestMixin,{
|
|
21
20
|
container.register("model:company", Company);
|
22
21
|
container.register("model:project", Project);
|
23
22
|
container.register("store:main", DS.Store.extend({adapter: adapter}));
|
24
|
-
|
23
|
+
if (adapter == DS.ActiveModelAdapter) {
|
24
|
+
container.register("serializer:-default", DS.ActiveModelSerializer);
|
25
|
+
} else if (adapter == DS.RESTAdapter) {
|
26
|
+
container.register("serializer:-default", DS.RESTSerializer);
|
27
|
+
} else {
|
28
|
+
container.register("serializer:-default", DS.JSONSerializer);
|
29
|
+
}
|
25
30
|
container.register('transform:string', DS.StringTransform);
|
26
31
|
|
27
32
|
if (adapter instanceof DS.FixtureAdapter) {
|
data/tests/test_setup.js
CHANGED
@@ -22,9 +22,7 @@ FactoryGuy.define('soft_material', {
|
|
22
22
|
})
|
23
23
|
FactoryGuy.define('profile', {
|
24
24
|
default: {
|
25
|
-
description: 'Text goes here'
|
26
|
-
camelCaseDescription: 'boyThisIsSilly',
|
27
|
-
snake_case_description: 'how_do_birds_find_worms'
|
25
|
+
description: 'Text goes here'
|
28
26
|
}
|
29
27
|
})
|
30
28
|
FactoryGuy.define('project', {
|
@@ -102,6 +100,8 @@ User = DS.Model.extend({
|
|
102
100
|
projects: DS.hasMany('project'),
|
103
101
|
hats: DS.hasMany('hat', {polymorphic: true})
|
104
102
|
});
|
103
|
+
|
104
|
+
|
105
105
|
/*!
|
106
106
|
* MockJax - jQuery Plugin to Mock Ajax requests
|
107
107
|
*
|
@@ -96,9 +96,9 @@ ModelDefinition = function (model, config) {
|
|
96
96
|
/**
|
97
97
|
Build a list of fixtures
|
98
98
|
|
99
|
-
@param name model name or named model type
|
100
|
-
@param number of fixtures to build
|
101
|
-
@param opts attribute options
|
99
|
+
@param {String} name model name or named model type
|
100
|
+
@param {Integer} number of fixtures to build
|
101
|
+
@param {Object} opts attribute options
|
102
102
|
@returns array of fixtures
|
103
103
|
*/
|
104
104
|
this.buildList = function (name, number, opts) {
|
@@ -381,6 +381,12 @@ DS.Store.reopen({
|
|
381
381
|
return adapter instanceof DS.FixtureAdapter;
|
382
382
|
},
|
383
383
|
|
384
|
+
usingActiveModelSerializer: function () {
|
385
|
+
var adapter = this.adapterFor('application');
|
386
|
+
console.log('adapter.defaultSerializer', adapter.defaultSerializer)
|
387
|
+
return adapter.defaultSerializer == 'active-model';
|
388
|
+
},
|
389
|
+
|
384
390
|
/**
|
385
391
|
Make new fixture and save to store. If the store is using FixtureAdapter,
|
386
392
|
will push to FIXTURE array, otherwise will use push method on adapter.
|
@@ -400,6 +406,7 @@ DS.Store.reopen({
|
|
400
406
|
return FactoryGuy.pushFixture(modelType, fixture);
|
401
407
|
} else {
|
402
408
|
var store = this;
|
409
|
+
|
403
410
|
var model;
|
404
411
|
Em.run(function () {
|
405
412
|
store.findEmbeddedBelongsToAssociationsForRESTAdapter(modelType, fixture);
|
@@ -543,6 +550,7 @@ DS.Store.reopen({
|
|
543
550
|
*/
|
544
551
|
setAssociationsForRESTAdapter: function (modelType, modelName, model) {
|
545
552
|
var self = this;
|
553
|
+
|
546
554
|
Ember.get(modelType, 'relationshipsByName').forEach(function (name, relationship) {
|
547
555
|
if (relationship.kind == 'hasMany') {
|
548
556
|
var children = model.get(name) || [];
|
@@ -555,7 +563,9 @@ DS.Store.reopen({
|
|
555
563
|
if (relationship.options && relationship.options.inverse) {
|
556
564
|
belongsToName = relationship.options.inverse;
|
557
565
|
}
|
558
|
-
|
566
|
+
if (belongsToName) {
|
567
|
+
child.set(belongsToName, model);
|
568
|
+
}
|
559
569
|
})
|
560
570
|
}
|
561
571
|
|
@@ -570,6 +580,7 @@ DS.Store.reopen({
|
|
570
580
|
)
|
571
581
|
if (hasManyName) {
|
572
582
|
belongsToRecord.get(hasManyName).addObject(model);
|
583
|
+
return;
|
573
584
|
}
|
574
585
|
var oneToOneName = self.findRelationshipName(
|
575
586
|
'belongsTo',
|
@@ -621,6 +632,27 @@ DS.Store.reopen({
|
|
621
632
|
return relationshipName;
|
622
633
|
},
|
623
634
|
|
635
|
+
// /**
|
636
|
+
// Adding the ability to check the serializer and convert the json before
|
637
|
+
// it's pushed. For the ActiveModelSerializer, the attributes should be snake case,
|
638
|
+
// for example.
|
639
|
+
//
|
640
|
+
// @method push
|
641
|
+
// @param {String or subclass of DS.Model} type
|
642
|
+
// @param {Object} data
|
643
|
+
// @return {DS.Model} the record that was created or updated.
|
644
|
+
// */
|
645
|
+
// push: function(type, data, _partial) {
|
646
|
+
// var type = this.modelFor(type);
|
647
|
+
// var serializer = this.serializerFor(type.typeKey);
|
648
|
+
// console.log('serializer',serializer, serializer+'')
|
649
|
+
//// if (this.usingActiveModelSerializer()) {
|
650
|
+
//// var model = this.modelFor(modelName);
|
651
|
+
//// FactoryGuy.pushFixture(model, payload);
|
652
|
+
//// }
|
653
|
+
// this._super(type, data, _partial);
|
654
|
+
// },
|
655
|
+
|
624
656
|
/**
|
625
657
|
Adding a pushPayload for FixtureAdapter, but using the original with
|
626
658
|
other adapters that support pushPayload.
|
@@ -706,16 +738,27 @@ DS.FixtureAdapter.reopen({
|
|
706
738
|
FactoryGuyTestMixin = Em.Mixin.create({
|
707
739
|
|
708
740
|
// Pass in the app root, which typically is App.
|
709
|
-
setup: function(app) {
|
741
|
+
setup: function (app) {
|
710
742
|
this.set('container', app.__container__);
|
711
743
|
return this;
|
712
744
|
},
|
713
745
|
|
714
|
-
useFixtureAdapter: function(app) {
|
746
|
+
useFixtureAdapter: function (app) {
|
715
747
|
app.ApplicationAdapter = DS.FixtureAdapter;
|
716
748
|
this.getStore().adapterFor('application').simulateRemoteResponse = false;
|
717
749
|
},
|
718
750
|
|
751
|
+
/**
|
752
|
+
@param {String} model type like user for model User
|
753
|
+
@return {boolean} true if model's serializer is ActiveModelSerializer based
|
754
|
+
*/
|
755
|
+
usingActiveModelSerializer: function (type) {
|
756
|
+
var store = this.getStore()
|
757
|
+
var type = store.modelFor(type);
|
758
|
+
var serializer = store.serializerFor(type.typeKey);
|
759
|
+
return serializer instanceof DS.ActiveModelSerializer;
|
760
|
+
},
|
761
|
+
|
719
762
|
/**
|
720
763
|
Proxy to store's find method
|
721
764
|
|
@@ -723,11 +766,11 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
723
766
|
@param {Object|String|Integer|null} id
|
724
767
|
@return {Promise} promise
|
725
768
|
*/
|
726
|
-
find: function(type, id) {
|
769
|
+
find: function (type, id) {
|
727
770
|
return this.getStore().find(type, id);
|
728
771
|
},
|
729
772
|
|
730
|
-
make: function(name, opts) {
|
773
|
+
make: function (name, opts) {
|
731
774
|
return this.getStore().makeFixture(name, opts);
|
732
775
|
},
|
733
776
|
|
@@ -735,20 +778,20 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
735
778
|
return this.get('container').lookup('store:main');
|
736
779
|
},
|
737
780
|
|
738
|
-
pushPayload: function(type, hash) {
|
781
|
+
pushPayload: function (type, hash) {
|
739
782
|
return this.getStore().pushPayload(type, hash);
|
740
783
|
},
|
741
784
|
|
742
|
-
pushRecord: function(type, hash) {
|
785
|
+
pushRecord: function (type, hash) {
|
743
786
|
return this.getStore().push(type, hash);
|
744
787
|
},
|
745
788
|
|
746
789
|
/**
|
747
|
-
|
790
|
+
Using mockjax to stub an http request.
|
748
791
|
|
749
|
-
|
750
|
-
|
751
|
-
|
792
|
+
@param {String} url request url
|
793
|
+
@param {Object} json response
|
794
|
+
@param {Object} options ajax request options
|
752
795
|
*/
|
753
796
|
stubEndpointForHttpRequest: function (url, json, options) {
|
754
797
|
options = options || {};
|
@@ -768,54 +811,107 @@ FactoryGuyTestMixin = Em.Mixin.create({
|
|
768
811
|
},
|
769
812
|
|
770
813
|
/**
|
771
|
-
|
814
|
+
Build the json used for creating record
|
772
815
|
|
773
|
-
|
774
|
-
|
816
|
+
@param {String} name of the fixture ( or model ) to create
|
817
|
+
@param {Object} opts fixture options
|
775
818
|
*/
|
776
|
-
|
777
|
-
var
|
778
|
-
var
|
779
|
-
|
780
|
-
|
819
|
+
buildAjaxHttpResponse: function (name, opts) {
|
820
|
+
var fixture = FactoryGuy.build(name, opts);
|
821
|
+
var modelName = FactoryGuy.lookupModelForFixtureName(name);
|
822
|
+
if (this.usingActiveModelSerializer(modelName)) {
|
823
|
+
this.toSnakeCase(fixture);
|
824
|
+
}
|
825
|
+
var hash = {};
|
826
|
+
hash[modelName] = fixture;
|
827
|
+
return hash;
|
828
|
+
},
|
829
|
+
|
830
|
+
/**
|
831
|
+
Convert Object's keys to snake case
|
832
|
+
|
833
|
+
@param {Object} fixture to convert
|
834
|
+
*/
|
835
|
+
toSnakeCase: function (fixture) {
|
836
|
+
for (key in fixture) {
|
837
|
+
if (key != Em.String.decamelize(key)) {
|
838
|
+
var value = fixture[key];
|
839
|
+
delete fixture[key];
|
840
|
+
fixture[Em.String.decamelize(key)] = value
|
841
|
+
}
|
842
|
+
}
|
843
|
+
},
|
844
|
+
|
845
|
+
/**
|
846
|
+
Handling ajax GET ( find record ) for a model. You can mock
|
847
|
+
failed find by passing in status of 500.
|
848
|
+
|
849
|
+
@param {String} name of the fixture ( or model ) to find
|
850
|
+
@param {Object} opts fixture options
|
851
|
+
@param {Integer} status Optional HTTP status response code
|
852
|
+
*/
|
853
|
+
handleFind: function (name, opts, status) {
|
854
|
+
var modelName = FactoryGuy.lookupModelForFixtureName(name);
|
855
|
+
var responseJson = this.buildAjaxHttpResponse(name, opts);
|
856
|
+
var id = responseJson[modelName].id
|
857
|
+
var url = "/" + Em.String.pluralize(modelName) + "/" + id;
|
858
|
+
this.stubEndpointForHttpRequest(
|
859
|
+
url,
|
860
|
+
responseJson,
|
861
|
+
{type: 'GET', status: (status || 200)}
|
862
|
+
)
|
781
863
|
return responseJson;
|
782
864
|
},
|
783
865
|
|
784
866
|
/**
|
785
|
-
|
867
|
+
Handling ajax POST ( create record ) for a model. You can mock
|
868
|
+
failed create by passing in status of 500.
|
786
869
|
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
var
|
793
|
-
var
|
794
|
-
|
795
|
-
|
870
|
+
@param {String} name of the fixture ( or model ) to create
|
871
|
+
@param {Object} opts fixture options
|
872
|
+
@param {Integer} status Optional HTTP status response code
|
873
|
+
*/
|
874
|
+
handleCreate: function (name, opts, status) {
|
875
|
+
var modelName = FactoryGuy.lookupModelForFixtureName(name);
|
876
|
+
var responseJson = this.buildAjaxHttpResponse(name, opts);
|
877
|
+
var url = "/" + Em.String.pluralize(modelName);
|
878
|
+
this.stubEndpointForHttpRequest(
|
879
|
+
url,
|
880
|
+
responseJson,
|
881
|
+
{type: 'POST', status: (status || 200)}
|
882
|
+
)
|
883
|
+
return responseJson;
|
796
884
|
},
|
797
885
|
|
798
886
|
/**
|
799
|
-
|
887
|
+
Handling ajax PUT ( update record ) for a model type. You can mock
|
888
|
+
failed update by passing in status of 500.
|
800
889
|
|
801
|
-
|
802
|
-
|
890
|
+
@param {String} root modelType like 'user' for User
|
891
|
+
@param {String} id id of record to update
|
892
|
+
@param {Integer} status Optional HTTP status response code
|
803
893
|
*/
|
804
|
-
handleUpdate: function (root, id) {
|
894
|
+
handleUpdate: function (root, id, status) {
|
805
895
|
this.stubEndpointForHttpRequest(
|
806
|
-
|
896
|
+
"/" + Em.String.pluralize(root) + "/" + id,
|
897
|
+
{},
|
898
|
+
{type: 'PUT', status: (status || 200)}
|
807
899
|
)
|
808
900
|
},
|
809
901
|
|
810
902
|
/**
|
811
|
-
|
903
|
+
Handling ajax DELETE ( delete record ) for a model type. You can mock
|
904
|
+
failed delete by passing in status of 500.
|
812
905
|
|
813
|
-
|
814
|
-
|
906
|
+
@param {String} root modelType like 'user' for User
|
907
|
+
@param {String} id id of record to update
|
908
|
+
@param {Integer} status Optional HTTP status response code
|
815
909
|
*/
|
816
|
-
handleDelete: function (root, id) {
|
910
|
+
handleDelete: function (root, id, status) {
|
817
911
|
this.stubEndpointForHttpRequest(
|
818
|
-
|
912
|
+
"/" + Em.String.pluralize(root) + "/" + id,
|
913
|
+
{},
|
914
|
+
{type: 'DELETE', status: (status || 200)}
|
819
915
|
)
|
820
916
|
},
|
821
917
|
|
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.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Sudol
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-07-11 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Easily create Fixtures for Ember Data
|
15
15
|
email:
|
@@ -80,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
80
|
version: 1.3.6
|
81
81
|
requirements: []
|
82
82
|
rubyforge_project: ember-data-factory-guy
|
83
|
-
rubygems_version: 2.
|
83
|
+
rubygems_version: 2.2.2
|
84
84
|
signing_key:
|
85
85
|
specification_version: 4
|
86
86
|
summary: Easily create Fixtures for Ember Data
|