ember-data-factory-guy 0.9.9 → 0.9.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6e4648a11858529bb5355b440b02b0ca24a7f8bf
4
- data.tar.gz: 423900ef7416682118d3c180677af2f8fcf77468
3
+ metadata.gz: 5e79cf8c600cf6d977adb4d9c988e0d31486785a
4
+ data.tar.gz: 64dd2732df1804268becf7d76c3f3c593d05be12
5
5
  SHA512:
6
- metadata.gz: 611b82bee5d7602ed3d0294fe0d4cc1e66061ab0c98f103de3250a9be83b9e082652505dccd4c6b5bf33ee45f3008b4c9a62bac5f131741f4ab95b9a85c7d970
7
- data.tar.gz: 9efc3f1265f49dc5ebec18410d018e67077132be6298b9aaa547acab83fe839c70d961c6771d81e6bab0c97cd3711c65ed6ef01a86d9b477c26290414dd67c21
6
+ metadata.gz: d3b8ab0f269111f6b6583e4cae4936e3e7b3f055a1ae56bb2128494d61729790172fe6f5768f94f6a810077918fdfb9adf34502d5dc391ff07464e19c767ce25
7
+ data.tar.gz: f2dba9d3a2e780cd58afadf3f32c913924a53e927c7c36886f8906116dc6497ffcdc39f80c437ff6920ff50406a31f6bd035feb7f0f7a89a9b246a36044a3d7d
data/Gruntfile.js CHANGED
@@ -11,6 +11,7 @@ module.exports = function(grunt) {
11
11
  'src/model_definition.js',
12
12
  'src/factory_guy.js',
13
13
  'src/mock_create_request.js',
14
+ 'src/mock_update_request.js',
14
15
  'src/store.js',
15
16
  'src/factory_guy_test_mixin.js',
16
17
  ],
@@ -23,6 +24,7 @@ module.exports = function(grunt) {
23
24
  'src/model_definition.js',
24
25
  'src/factory_guy.js',
25
26
  'src/mock_create_request.js',
27
+ 'src/mock_update_request.js',
26
28
  'src/store.js',
27
29
  'src/factory_guy_test_mixin.js',
28
30
  'src/epilogue.js'
@@ -40,6 +42,7 @@ module.exports = function(grunt) {
40
42
  'src/model_definition.js',
41
43
  'src/factory_guy.js',
42
44
  'src/mock_create_request.js',
45
+ 'src/mock_update_request.js',
43
46
  'src/store.js',
44
47
  'src/factory_guy_test_mixin.js',
45
48
  'bower_components/jquery-mockjax/jquery.mockjax.js'],
data/README.md CHANGED
@@ -15,7 +15,7 @@ of ember-data-factory-guy.
15
15
  - 0.7.1.1 -> ember-data-1.0.0-beta.10
16
16
  - 0.8.6 -> ember-data-1.0.0-beta.11
17
17
  - 0.9.8 -> ember-data-1.0.0-beta.12
18
- - 0.9.9 -> ember-data-1.0.0-beta.15
18
+ - 0.9.10 -> ember-data-1.0.0-beta.15
19
19
 
20
20
  **Support for fixture adapter is working for versions 0.9.3 -> 0.9.8**
21
21
 
@@ -44,7 +44,7 @@ gem 'ember-data-factory-guy', group: test
44
44
  or for particular version:
45
45
 
46
46
  ```ruby
47
- gem 'ember-data-factory-guy', '0.9.9', group: test
47
+ gem 'ember-data-factory-guy', '0.9.10', group: test
48
48
  ```
49
49
 
50
50
  then:
@@ -79,7 +79,7 @@ or for particular version:
79
79
  "dependencies": {
80
80
  "foo-dependency": "latest",
81
81
  "other-foo-dependency": "latest",
82
- "ember-data-factory-guy": "0.9.9"
82
+ "ember-data-factory-guy": "0.9.10"
83
83
  }
84
84
  ```
85
85
 
@@ -814,8 +814,17 @@ chainable methods, or options hash.
814
814
 
815
815
 
816
816
  ##### handleUpdate
817
+
818
+ - Use chainable methods to build response:
819
+ - andFail - request should fail, use options argument to pass status and response text
820
+ - andSucceed - update should succeed, this is the default behavior, use this after a ```andFail``` call
821
+
817
822
  - handleUpdate(model)
818
823
  - handleUpdate(modelType, id)
824
+ - Use hash of options to build response:
825
+ - status - HTTP status code, defaults to 200.
826
+ - response - what the server has responded, only used on failure cases, default is empty on failure and model json on succees.
827
+ - succeed - indicates if the resquest should succeed, defaults to true.
819
828
  - need to wrap tests using handleUpdate with: Ember.run.function() { 'your test' })
820
829
 
821
830
  *success case is the default*
@@ -834,15 +843,54 @@ chainable methods, or options hash.
834
843
  profile.save() //=> will succeed
835
844
  ````
836
845
 
846
+ ######Using chainable methods
847
+
848
+ *mocking a failed update*
849
+
850
+ ```javascript
851
+ var profile = FactoryGuy.make('profile');
852
+
853
+ // set the succeed flag to 'false'
854
+ testHelper.handleUpdate('profile', profile.id).andFail({status: 422, response: "{error: 'Invalid data'}"});
855
+ // or
856
+ testHelper.handleUpdate(profile).andFail({status: 422, response: "{error: 'Invalid data'}"});
857
+
858
+ profile.set('description', 'bad value');
859
+ profile.save() //=> will fail
860
+ ````
861
+
862
+ *mocking a failed update and retry with succees*
863
+
864
+ ```javascript
865
+ var profile = FactoryGuy.make('profile');
866
+
867
+ // set the succeed flag to 'false'
868
+ var mockUpdate = testHelper.handleUpdate('profile', profile.id);
869
+ // or
870
+ var mockUpdate = testHelper.handleUpdate(profile);
871
+
872
+ mockUpdate.andFail({status: 422, response: "{error: 'Invalid data'}"});
873
+
874
+ profile.set('description', 'bad value');
875
+ profile.save() //=> will fail
876
+
877
+ // Some logic for retrying...
878
+
879
+ mockUpdate.andSucceed();
880
+ profile.save() //=> will succeed!
881
+ ````
882
+
883
+ ######Using hash of options
884
+
837
885
  *mocking a failed update*
838
886
 
839
887
  ```javascript
840
888
  var profile = FactoryGuy.make('profile');
841
889
 
842
890
  // set the succeed flag to 'false'
843
- testHelper.handleUpdate('profile', profile.id, false);
891
+ testHelper.handleUpdate('profile', profile.id, {succeed: false});
844
892
  // or
845
- testHelper.handleUpdate(profile, false);
893
+ testHelper.handleUpdate(profile, {succeed: false});
846
894
 
847
895
  profile.set('description', 'bad value');
848
896
  profile.save() //=> will fail
data/bower.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-data-factory-guy",
3
- "version": "0.9.9",
3
+ "version": "0.9.10",
4
4
  "authors": [
5
5
  "Daniel Sudol <dansudol@yahoo.com>",
6
6
  "Opak Alex <opak.alexandr@gmail.com>"
@@ -649,6 +649,55 @@ var MockCreateRequest = function(url, store, modelName, options) {
649
649
  $.mockjax(this.handler);
650
650
  };
651
651
 
652
+ var MockUpdateRequest = function(url, model, mapFind, options) {
653
+ var status = options.status || 200;
654
+ var succeed = true;
655
+ var response = null;
656
+
657
+ if ('succeed' in options) {
658
+ succeed = options.succeed;
659
+ }
660
+
661
+ if ('response' in options) {
662
+ response = options.response;
663
+ }
664
+
665
+ this.andSucceed = function(options) {
666
+ succeed = true;
667
+ return this;
668
+ };
669
+
670
+ this.andFail = function(options) {
671
+ succeed = false;
672
+ status = options.status || 500;
673
+ if ('response' in options) {
674
+ response = options.response;
675
+ }
676
+ return this;
677
+ };
678
+
679
+ this.handler = function(settings) {
680
+ if (!succeed) {
681
+ this.status = status;
682
+ if (response !== null) {
683
+ this.responseText = response;
684
+ }
685
+ } else {
686
+ var json = model.toJSON({includeId: true});
687
+ this.responseText = mapFind(model.constructor.typeKey, json);
688
+ this.status = 200;
689
+ }
690
+ };
691
+
692
+ var requestConfig = {
693
+ url: url,
694
+ dataType: 'json',
695
+ type: 'PUT',
696
+ response: this.handler
697
+ };
698
+
699
+ $.mockjax(requestConfig);
700
+ };
652
701
  (function () {
653
702
  DS.Store.reopen({
654
703
  /**
@@ -1196,34 +1245,35 @@ var FactoryGuyTestMixin = Em.Mixin.create({
1196
1245
  Handling ajax PUT ( update record ) for a model type. You can mock
1197
1246
  failed update by passing in success argument as false.
1198
1247
 
1199
- @param {String} type model type like 'user' for User model
1248
+ @param {String} type model type like 'user' for User model, or a model instance
1200
1249
  @param {String} id id of record to update
1201
- @param {Boolean} succeed optional flag to indicate if the request
1202
- should succeed ( default is true )
1250
+ @param {Object} options options object
1203
1251
  */
1204
1252
  handleUpdate: function () {
1205
- var args = Array.prototype.slice.call(arguments)
1253
+ var args = Array.prototype.slice.call(arguments);
1206
1254
  Ember.assert("To handleUpdate pass in a model instance or a type and an id", args.length>0)
1207
- var succeed = true;
1208
- if (typeof args[args.length-1] == 'boolean') {
1209
- args.pop()
1210
- succeed = false;
1255
+
1256
+ var options = {};
1257
+ if (args.length > 1 && typeof args[args.length - 1] === 'object') {
1258
+ options = args.pop();
1211
1259
  }
1212
- Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0)
1213
- var type, id;
1260
+
1261
+ var model, type, id;
1262
+ var store = this.getStore();
1263
+
1214
1264
  if (args[0] instanceof DS.Model) {
1215
- var model = args[0];
1216
- type = model.constructor.typeKey;
1265
+ model = args[0];
1217
1266
  id = model.id;
1267
+ type = model.constructor.typeKey;
1218
1268
  } else if (typeof args[0] == "string" && typeof parseInt(args[1]) == "number") {
1219
1269
  type = args[0];
1220
1270
  id = args[1];
1271
+ model = store.getById(type, id)
1221
1272
  }
1222
- Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id)
1223
- this.stubEndpointForHttpRequest(this.buildURL(type, id), {}, {
1224
- type: 'PUT',
1225
- status: succeed ? 200 : 500
1226
- });
1273
+ Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id);
1274
+
1275
+ var url = this.buildURL(type, id);
1276
+ return new MockUpdateRequest(url, model, this.mapFind, options);
1227
1277
  },
1228
1278
  /**
1229
1279
  Handling ajax DELETE ( delete record ) for a model type. You can mock
@@ -644,6 +644,55 @@ var MockCreateRequest = function(url, store, modelName, options) {
644
644
  $.mockjax(this.handler);
645
645
  };
646
646
 
647
+ var MockUpdateRequest = function(url, model, mapFind, options) {
648
+ var status = options.status || 200;
649
+ var succeed = true;
650
+ var response = null;
651
+
652
+ if ('succeed' in options) {
653
+ succeed = options.succeed;
654
+ }
655
+
656
+ if ('response' in options) {
657
+ response = options.response;
658
+ }
659
+
660
+ this.andSucceed = function(options) {
661
+ succeed = true;
662
+ return this;
663
+ };
664
+
665
+ this.andFail = function(options) {
666
+ succeed = false;
667
+ status = options.status || 500;
668
+ if ('response' in options) {
669
+ response = options.response;
670
+ }
671
+ return this;
672
+ };
673
+
674
+ this.handler = function(settings) {
675
+ if (!succeed) {
676
+ this.status = status;
677
+ if (response !== null) {
678
+ this.responseText = response;
679
+ }
680
+ } else {
681
+ var json = model.toJSON({includeId: true});
682
+ this.responseText = mapFind(model.constructor.typeKey, json);
683
+ this.status = 200;
684
+ }
685
+ };
686
+
687
+ var requestConfig = {
688
+ url: url,
689
+ dataType: 'json',
690
+ type: 'PUT',
691
+ response: this.handler
692
+ };
693
+
694
+ $.mockjax(requestConfig);
695
+ };
647
696
  (function () {
648
697
  DS.Store.reopen({
649
698
  /**
@@ -1191,34 +1240,35 @@ var FactoryGuyTestMixin = Em.Mixin.create({
1191
1240
  Handling ajax PUT ( update record ) for a model type. You can mock
1192
1241
  failed update by passing in success argument as false.
1193
1242
 
1194
- @param {String} type model type like 'user' for User model
1243
+ @param {String} type model type like 'user' for User model, or a model instance
1195
1244
  @param {String} id id of record to update
1196
- @param {Boolean} succeed optional flag to indicate if the request
1197
- should succeed ( default is true )
1245
+ @param {Object} options options object
1198
1246
  */
1199
1247
  handleUpdate: function () {
1200
- var args = Array.prototype.slice.call(arguments)
1248
+ var args = Array.prototype.slice.call(arguments);
1201
1249
  Ember.assert("To handleUpdate pass in a model instance or a type and an id", args.length>0)
1202
- var succeed = true;
1203
- if (typeof args[args.length-1] == 'boolean') {
1204
- args.pop()
1205
- succeed = false;
1250
+
1251
+ var options = {};
1252
+ if (args.length > 1 && typeof args[args.length - 1] === 'object') {
1253
+ options = args.pop();
1206
1254
  }
1207
- Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0)
1208
- var type, id;
1255
+
1256
+ var model, type, id;
1257
+ var store = this.getStore();
1258
+
1209
1259
  if (args[0] instanceof DS.Model) {
1210
- var model = args[0];
1211
- type = model.constructor.typeKey;
1260
+ model = args[0];
1212
1261
  id = model.id;
1262
+ type = model.constructor.typeKey;
1213
1263
  } else if (typeof args[0] == "string" && typeof parseInt(args[1]) == "number") {
1214
1264
  type = args[0];
1215
1265
  id = args[1];
1266
+ model = store.getById(type, id)
1216
1267
  }
1217
- Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id)
1218
- this.stubEndpointForHttpRequest(this.buildURL(type, id), {}, {
1219
- type: 'PUT',
1220
- status: succeed ? 200 : 500
1221
- });
1268
+ Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id);
1269
+
1270
+ var url = this.buildURL(type, id);
1271
+ return new MockUpdateRequest(url, model, this.mapFind, options);
1222
1272
  },
1223
1273
  /**
1224
1274
  Handling ajax DELETE ( delete record ) for a model type. You can mock
@@ -1 +1 @@
1
- var Sequence=function(fn){var index=1;this.next=function(){return fn.call(this,index++)};this.reset=function(){index=1}};var MissingSequenceError=function(message){this.toString=function(){return message}};if(FactoryGuy!==undefined){FactoryGuy.sequence=Sequence;FactoryGuy.missingSequenceError=MissingSequenceError}var ModelDefinition=function(model,config){var sequences={};var traits={};var defaultAttributes={};var namedModels={};var modelId=1;var sequenceName=null;this.model=model;this.matchesName=function(name){return model==name||namedModels[name]};this.nextId=function(){return modelId++};this.generate=function(name,sequenceFn){if(sequenceFn){if(!sequences[name]){sequences[name]=new Sequence(sequenceFn)}}var sequence=sequences[name];if(!sequence){throw new MissingSequenceError("Can not find that sequence named ["+sequenceName+"] in '"+model+"' definition")}return sequence.next()};this.build=function(name,opts,traitArgs){var traitsObj={};traitArgs.forEach(function(trait){$.extend(traitsObj,traits[trait])});var modelAttributes=namedModels[name]||{};var fixture=$.extend({},defaultAttributes,modelAttributes,traitsObj,opts);for(var attribute in fixture){if(Ember.typeOf(fixture[attribute])=="function"){fixture[attribute]=fixture[attribute].call(this,fixture)}else if(Ember.typeOf(fixture[attribute])=="object"){if(FactoryGuy.getStore()){if(FactoryGuy.isAttributeRelationship(this.model,attribute)){fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}else{fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}}if(!fixture.id){fixture.id=this.nextId()}return fixture};this.buildList=function(name,number,traits,opts){var arr=[];for(var i=0;i<number;i++){arr.push(this.build(name,opts,traits))}return arr};this.reset=function(){modelId=1;for(var name in sequences){sequences[name].reset()}};var parseDefault=function(object){if(!object){return}defaultAttributes=object};var parseTraits=function(object){if(!object){return}traits=object};var parseSequences=function(object){if(!object){return}for(sequenceName in object){var sequenceFn=object[sequenceName];if(Ember.typeOf(sequenceFn)!="function"){throw new Error("Problem with ["+sequenceName+"] sequence definition. Sequences must be functions")}object[sequenceName]=new Sequence(sequenceFn)}sequences=object};var parseConfig=function(config){parseSequences(config.sequences);delete config.sequences;parseTraits(config.traits);delete config.traits;parseDefault(config.default);delete config.default;namedModels=config};parseConfig(config)};if(FactoryGuy!==undefined){FactoryGuy.modelDefiniton=ModelDefinition}var FactoryGuy={modelDefinitions:{},define:function(model,config){if(this.modelDefinitions[model]){this.modelDefinitions[model].merge(config)}else{this.modelDefinitions[model]=new ModelDefinition(model,config)}},setStore:function(store){Ember.assert("FactoryGuy#setStore needs a valid store instance.You passed in ["+store+"]",store instanceof DS.Store);this.store=store},getStore:function(){return this.store},isAttributeRelationship:function(typeName,attribute){if(!this.store){Ember.debug("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures");return true}var model=this.store.modelFor(typeName);return!!model.typeForRelationship(attribute)},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){Ember.deprecate("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)},make:function(){var store=this.store;Ember.assert("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures",store);var fixture=this.build.apply(this,arguments);var name=arguments[0];var modelName=this.lookupModelForFixtureName(name);var modelType=store.modelFor(modelName);if(store.usingFixtureAdapter()){store.setAssociationsForFixtureAdapter(modelType,modelName,fixture);fixture=FactoryGuy.pushFixture(modelType,fixture);store.loadModelForFixtureAdapter(modelType,fixture);return fixture}else{return store.makeModel(modelType,fixture)}},makeList:function(){Ember.assert("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures",this.store);var arr=[];var args=Array.prototype.slice.call(arguments);Ember.assert("makeList needs at least 2 arguments, a name and a number",args.length>=2);var number=args.splice(1,1)[0];Ember.assert("Second argument to makeList should be a number (of fixtures to make.)",typeof number=="number");for(var i=0;i<number;i++){arr.push(this.make.apply(this,args))}return arr},resetModels:function(store){for(var model in this.modelDefinitions){var definition=this.modelDefinitions[model];definition.reset();try{var modelType=store.modelFor(definition.model);if(store.usingFixtureAdapter()){modelType.FIXTURES=[]}store.unloadAll(modelType)}catch(e){console.log("resetModels",e)}}},pushFixture:function(modelClass,fixture){var index;if(!modelClass.FIXTURES){modelClass.FIXTURES=[]}index=this.indexOfFixture(modelClass.FIXTURES,fixture);if(index>-1){modelClass.FIXTURES.splice(index,1)}modelClass.FIXTURES.push(fixture);return fixture},indexOfFixture:function(fixtures,fixture){var index=-1,id=fixture.id+"";Ember.A(fixtures).find(function(r,i){if(""+Ember.get(r,"id")===id){index=i;return true}else{return false}});return index},clear:function(opts){if(!opts){this.modelDefinitions={}}}};var MockCreateRequest=function(url,store,modelName,options){var succeed=options.succeed===undefined?true:options.succeed;var matchArgs=options.match;var returnArgs=options.returns;var responseJson={};var expectedRequest={};var modelType=store.modelFor(modelName);this.calculate=function(){if(matchArgs){var tmpRecord=store.createRecord(modelName,matchArgs);expectedRequest=tmpRecord.serialize(matchArgs);tmpRecord.deleteRecord()}if(succeed){var definition=FactoryGuy.modelDefinitions[modelName];if(responseJson[modelName]){responseJson[modelName]=$.extend({id:responseJson[modelName].id},matchArgs,returnArgs)}else{responseJson[modelName]=$.extend({id:definition.nextId()},matchArgs,returnArgs)}Ember.get(modelType,"relationshipsByName").forEach(function(relationship){if(relationship.kind=="belongsTo"){delete responseJson[modelName][relationship.key]}})}};this.match=function(matches){matchArgs=matches;this.calculate();return this};this.andReturn=function(returns){returnArgs=returns;this.calculate();return this};this.andFail=function(){succeed=false;return this};this.handler=function(settings){if(settings.url!=url||settings.type!="POST"){return false}if(matchArgs){var requestData=JSON.parse(settings.data)[modelName];for(var attribute in expectedRequest){if(expectedRequest[attribute]&&requestData[attribute]!=expectedRequest[attribute]){return false}}}var responseStatus=succeed?200:500;return{responseText:responseJson,status:responseStatus}};this.calculate();$.mockjax(this.handler)};(function(){DS.Store.reopen({usingFixtureAdapter:function(){var adapter=this.adapterFor("application");return adapter instanceof DS.FixtureAdapter},makeFixture:function(){Ember.deprecate("DEPRECATION Warning: use FactoryGuy.make instead");FactoryGuy.make.call(FactoryGuy,arguments)},makeList:function(){Ember.deprecate("DEPRECATION Warning: use FactoryGuy.makeList instead");FactoryGuy.makeList.call(FactoryGuy,arguments)},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},setAssociationsForFixtureAdapter:function(modelType,modelName,fixture){var self=this;var adapter=this.adapterFor("application");Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){var hasManyRelation,belongsToRecord;if(relationship.kind=="hasMany"){hasManyRelation=fixture[relationship.key];if(hasManyRelation){$.each(fixture[relationship.key],function(index,object){var id=object;if(Ember.typeOf(object)=="object"){FactoryGuy.pushFixture(relationship.type,object);id=object.id;hasManyRelation[index]=id}var hasManyfixtures=adapter.fixturesForType(relationship.type);var hasManyFixture=adapter.findFixtureById(hasManyfixtures,id);hasManyFixture[modelName]=fixture.id;self.loadModelForFixtureAdapter(relationship.type,hasManyFixture)})}}if(relationship.kind=="belongsTo"){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);self.loadModelForFixtureAdapter(relationship.type,belongsTofixture)}}})},loadModelForFixtureAdapter:function(modelType,fixture){var storeModel=this.getById(modelType,fixture.id),that=this;if(!Ember.isPresent(storeModel)||storeModel.get("isEmpty")){Ember.run(function(){var dup=Ember.copy(fixture,true);that.push(modelType,fixture);Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(fixture[relationship.key]){fixture[relationship.key]=dup[relationship.key]}})})}},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){var typeName,model;if(this.usingFixtureAdapter()){if(Ember.typeOf(type)==="string"&&Ember.isPresent(payload)&&Ember.isPresent(payload.id)){model=this.modelFor(type);FactoryGuy.pushFixture(model,payload);this.push(model,Ember.copy(payload,true))}else if(Ember.typeOf(type)==="object"||Ember.typeOf(payload)==="object"){if(Ember.isBlank(payload)){payload=type}for(var prop in payload){typeName=Ember.String.camelize(Ember.String.singularize(prop));model=this.modelFor(typeName);this.pushMany(model,Ember.makeArray(Ember.copy(payload[prop],true)));Ember.ArrayPolyfills.forEach.call(Ember.makeArray(payload[prop]),function(hash){FactoryGuy.pushFixture(model,hash)},this)}}else{throw new Ember.Error("Assertion Failed: You cannot use `store#pushPayload` with this method signature pushPayload("+type+","+payload+")")}}else{this._super(type,payload)}}})})();var FactoryGuyTestMixin=Em.Mixin.create({setup:function(app){this.set("container",app.__container__);FactoryGuy.setStore(this.getStore());return this},useFixtureAdapter:function(app){app.ApplicationAdapter=DS.FixtureAdapter;this.getStore().adapterFor("application").simulateRemoteResponse=false},usingActiveModelSerializer:function(type){var store=this.getStore();var modelType=store.modelFor(type);var serializer=store.serializerFor(modelType.typeKey);return serializer instanceof DS.ActiveModelSerializer},find:function(type,id){return this.getStore().find(type,id)},make:function(){return FactoryGuy.make.apply(FactoryGuy,arguments)},getStore:function(){return this.get("container").lookup("store:main")},stubEndpointForHttpRequest:function(url,json,options){options=options||{};var request={url:url,dataType:"json",responseText:json,type:options.type||"GET",status:options.status||200};if(options.urlParams){request.urlParams=options.urlParams}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)},mapFindAll:function(modelName,json){var responseJson={};responseJson[modelName.pluralize()]=json;return responseJson},mapFind:function(modelName,json){var responseJson={};responseJson[modelName.pluralize()]=json;return responseJson},handleFindAll:function(){var records=FactoryGuy.makeList.apply(FactoryGuy,arguments);var name=arguments[0];var modelName=FactoryGuy.lookupModelForFixtureName(name);var json=records.map(function(record){return record.toJSON({includeId:true})});var responseJson=this.mapFindAll(modelName,json);var url=this.buildURL(modelName);this.stubEndpointForHttpRequest(url,responseJson)},handleFindMany:function(){Ember.deprecate("DEPRECATION Warning: use handleFindAll instead");this.handleFindAll.apply(this,arguments)},handleFind:function(){var args=Array.prototype.slice.call(arguments);Ember.assert("To handleFindOne pass in a model instance or a type and model options",args.length>0);var record,modelName;if(args[0]instanceof DS.Model){record=args[0];modelName=record.constructor.typeKey}else{record=FactoryGuy.make.apply(FactoryGuy,arguments);var name=arguments[0];modelName=FactoryGuy.lookupModelForFixtureName(name)}var json=record.toJSON({includeId:true});var responseJson=this.mapFind(modelName,json);var url=this.buildURL(modelName,record.id);this.stubEndpointForHttpRequest(url,responseJson)},handleFindOne:function(){this.handleFind.apply(this,arguments)},handleFindQuery:function(modelName,searchParams,records){Ember.assert("The second argument of searchParams must be an array",Em.typeOf(searchParams)=="array");if(records){Ember.assert("The third argument ( records ) must be an array - found type:"+Em.typeOf(records),Em.typeOf(records)=="array")}else{records=[]}var json=records.map(function(record){return record.toJSON({includeId:true})});var responseJson=this.mapFindAll(modelName,json);var url=this.buildURL(modelName);this.stubEndpointForHttpRequest(url,responseJson,{urlParams:searchParams})},handleCreate:function(modelName,options){var url=this.buildURL(modelName);var store=this.getStore();var opts=options===undefined?{}:options;return new MockCreateRequest(url,store,modelName,opts)},handleUpdate:function(){var args=Array.prototype.slice.call(arguments);Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0);var succeed=true;if(typeof args[args.length-1]=="boolean"){args.pop();succeed=false}Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0);var type,id;if(args[0]instanceof DS.Model){var model=args[0];type=model.constructor.typeKey;id=model.id}else if(typeof args[0]=="string"&&typeof parseInt(args[1])=="number"){type=args[0];id=args[1]}Ember.assert("To handleUpdate pass in a model instance or a type and an id",type&&id);this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"PUT",status:succeed?200:500})},handleDelete:function(type,id,succeed){succeed=succeed===undefined?true:succeed;this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"DELETE",status:succeed?200:500})},teardown:function(){FactoryGuy.resetModels(this.getStore());$.mockjax.clear()}});if(FactoryGuy!==undefined){FactoryGuy.testMixin=FactoryGuyTestMixin}
1
+ var Sequence=function(fn){var index=1;this.next=function(){return fn.call(this,index++)};this.reset=function(){index=1}};var MissingSequenceError=function(message){this.toString=function(){return message}};if(FactoryGuy!==undefined){FactoryGuy.sequence=Sequence;FactoryGuy.missingSequenceError=MissingSequenceError}var ModelDefinition=function(model,config){var sequences={};var traits={};var defaultAttributes={};var namedModels={};var modelId=1;var sequenceName=null;this.model=model;this.matchesName=function(name){return model==name||namedModels[name]};this.nextId=function(){return modelId++};this.generate=function(name,sequenceFn){if(sequenceFn){if(!sequences[name]){sequences[name]=new Sequence(sequenceFn)}}var sequence=sequences[name];if(!sequence){throw new MissingSequenceError("Can not find that sequence named ["+sequenceName+"] in '"+model+"' definition")}return sequence.next()};this.build=function(name,opts,traitArgs){var traitsObj={};traitArgs.forEach(function(trait){$.extend(traitsObj,traits[trait])});var modelAttributes=namedModels[name]||{};var fixture=$.extend({},defaultAttributes,modelAttributes,traitsObj,opts);for(var attribute in fixture){if(Ember.typeOf(fixture[attribute])=="function"){fixture[attribute]=fixture[attribute].call(this,fixture)}else if(Ember.typeOf(fixture[attribute])=="object"){if(FactoryGuy.getStore()){if(FactoryGuy.isAttributeRelationship(this.model,attribute)){fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}else{fixture[attribute]=FactoryGuy.build(attribute,fixture[attribute])}}}if(!fixture.id){fixture.id=this.nextId()}return fixture};this.buildList=function(name,number,traits,opts){var arr=[];for(var i=0;i<number;i++){arr.push(this.build(name,opts,traits))}return arr};this.reset=function(){modelId=1;for(var name in sequences){sequences[name].reset()}};var parseDefault=function(object){if(!object){return}defaultAttributes=object};var parseTraits=function(object){if(!object){return}traits=object};var parseSequences=function(object){if(!object){return}for(sequenceName in object){var sequenceFn=object[sequenceName];if(Ember.typeOf(sequenceFn)!="function"){throw new Error("Problem with ["+sequenceName+"] sequence definition. Sequences must be functions")}object[sequenceName]=new Sequence(sequenceFn)}sequences=object};var parseConfig=function(config){parseSequences(config.sequences);delete config.sequences;parseTraits(config.traits);delete config.traits;parseDefault(config.default);delete config.default;namedModels=config};parseConfig(config)};if(FactoryGuy!==undefined){FactoryGuy.modelDefiniton=ModelDefinition}var FactoryGuy={modelDefinitions:{},define:function(model,config){if(this.modelDefinitions[model]){this.modelDefinitions[model].merge(config)}else{this.modelDefinitions[model]=new ModelDefinition(model,config)}},setStore:function(store){Ember.assert("FactoryGuy#setStore needs a valid store instance.You passed in ["+store+"]",store instanceof DS.Store);this.store=store},getStore:function(){return this.store},isAttributeRelationship:function(typeName,attribute){if(!this.store){Ember.debug("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures");return true}var model=this.store.modelFor(typeName);return!!model.typeForRelationship(attribute)},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){Ember.deprecate("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)},make:function(){var store=this.store;Ember.assert("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures",store);var fixture=this.build.apply(this,arguments);var name=arguments[0];var modelName=this.lookupModelForFixtureName(name);var modelType=store.modelFor(modelName);if(store.usingFixtureAdapter()){store.setAssociationsForFixtureAdapter(modelType,modelName,fixture);fixture=FactoryGuy.pushFixture(modelType,fixture);store.loadModelForFixtureAdapter(modelType,fixture);return fixture}else{return store.makeModel(modelType,fixture)}},makeList:function(){Ember.assert("FactoryGuy does not have the application's store. Use FactoryGuy.setStore(store) before making any fixtures",this.store);var arr=[];var args=Array.prototype.slice.call(arguments);Ember.assert("makeList needs at least 2 arguments, a name and a number",args.length>=2);var number=args.splice(1,1)[0];Ember.assert("Second argument to makeList should be a number (of fixtures to make.)",typeof number=="number");for(var i=0;i<number;i++){arr.push(this.make.apply(this,args))}return arr},resetModels:function(store){for(var model in this.modelDefinitions){var definition=this.modelDefinitions[model];definition.reset();try{var modelType=store.modelFor(definition.model);if(store.usingFixtureAdapter()){modelType.FIXTURES=[]}store.unloadAll(modelType)}catch(e){console.log("resetModels",e)}}},pushFixture:function(modelClass,fixture){var index;if(!modelClass.FIXTURES){modelClass.FIXTURES=[]}index=this.indexOfFixture(modelClass.FIXTURES,fixture);if(index>-1){modelClass.FIXTURES.splice(index,1)}modelClass.FIXTURES.push(fixture);return fixture},indexOfFixture:function(fixtures,fixture){var index=-1,id=fixture.id+"";Ember.A(fixtures).find(function(r,i){if(""+Ember.get(r,"id")===id){index=i;return true}else{return false}});return index},clear:function(opts){if(!opts){this.modelDefinitions={}}}};var MockCreateRequest=function(url,store,modelName,options){var succeed=options.succeed===undefined?true:options.succeed;var matchArgs=options.match;var returnArgs=options.returns;var responseJson={};var expectedRequest={};var modelType=store.modelFor(modelName);this.calculate=function(){if(matchArgs){var tmpRecord=store.createRecord(modelName,matchArgs);expectedRequest=tmpRecord.serialize(matchArgs);tmpRecord.deleteRecord()}if(succeed){var definition=FactoryGuy.modelDefinitions[modelName];if(responseJson[modelName]){responseJson[modelName]=$.extend({id:responseJson[modelName].id},matchArgs,returnArgs)}else{responseJson[modelName]=$.extend({id:definition.nextId()},matchArgs,returnArgs)}Ember.get(modelType,"relationshipsByName").forEach(function(relationship){if(relationship.kind=="belongsTo"){delete responseJson[modelName][relationship.key]}})}};this.match=function(matches){matchArgs=matches;this.calculate();return this};this.andReturn=function(returns){returnArgs=returns;this.calculate();return this};this.andFail=function(){succeed=false;return this};this.handler=function(settings){if(settings.url!=url||settings.type!="POST"){return false}if(matchArgs){var requestData=JSON.parse(settings.data)[modelName];for(var attribute in expectedRequest){if(expectedRequest[attribute]&&requestData[attribute]!=expectedRequest[attribute]){return false}}}var responseStatus=succeed?200:500;return{responseText:responseJson,status:responseStatus}};this.calculate();$.mockjax(this.handler)};var MockUpdateRequest=function(url,model,mapFind,options){var status=options.status||200;var succeed=true;var response=null;if("succeed"in options){succeed=options.succeed}if("response"in options){response=options.response}this.andSucceed=function(options){succeed=true;return this};this.andFail=function(options){succeed=false;status=options.status||500;if("response"in options){response=options.response}return this};this.handler=function(settings){if(!succeed){this.status=status;if(response!==null){this.responseText=response}}else{var json=model.toJSON({includeId:true});this.responseText=mapFind(model.constructor.typeKey,json);this.status=200}};var requestConfig={url:url,dataType:"json",type:"PUT",response:this.handler};$.mockjax(requestConfig)};(function(){DS.Store.reopen({usingFixtureAdapter:function(){var adapter=this.adapterFor("application");return adapter instanceof DS.FixtureAdapter},makeFixture:function(){Ember.deprecate("DEPRECATION Warning: use FactoryGuy.make instead");FactoryGuy.make.call(FactoryGuy,arguments)},makeList:function(){Ember.deprecate("DEPRECATION Warning: use FactoryGuy.makeList instead");FactoryGuy.makeList.call(FactoryGuy,arguments)},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},setAssociationsForFixtureAdapter:function(modelType,modelName,fixture){var self=this;var adapter=this.adapterFor("application");Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){var hasManyRelation,belongsToRecord;if(relationship.kind=="hasMany"){hasManyRelation=fixture[relationship.key];if(hasManyRelation){$.each(fixture[relationship.key],function(index,object){var id=object;if(Ember.typeOf(object)=="object"){FactoryGuy.pushFixture(relationship.type,object);id=object.id;hasManyRelation[index]=id}var hasManyfixtures=adapter.fixturesForType(relationship.type);var hasManyFixture=adapter.findFixtureById(hasManyfixtures,id);hasManyFixture[modelName]=fixture.id;self.loadModelForFixtureAdapter(relationship.type,hasManyFixture)})}}if(relationship.kind=="belongsTo"){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);self.loadModelForFixtureAdapter(relationship.type,belongsTofixture)}}})},loadModelForFixtureAdapter:function(modelType,fixture){var storeModel=this.getById(modelType,fixture.id),that=this;if(!Ember.isPresent(storeModel)||storeModel.get("isEmpty")){Ember.run(function(){var dup=Ember.copy(fixture,true);that.push(modelType,fixture);Ember.get(modelType,"relationshipsByName").forEach(function(relationship,name){if(fixture[relationship.key]){fixture[relationship.key]=dup[relationship.key]}})})}},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){var typeName,model;if(this.usingFixtureAdapter()){if(Ember.typeOf(type)==="string"&&Ember.isPresent(payload)&&Ember.isPresent(payload.id)){model=this.modelFor(type);FactoryGuy.pushFixture(model,payload);this.push(model,Ember.copy(payload,true))}else if(Ember.typeOf(type)==="object"||Ember.typeOf(payload)==="object"){if(Ember.isBlank(payload)){payload=type}for(var prop in payload){typeName=Ember.String.camelize(Ember.String.singularize(prop));model=this.modelFor(typeName);this.pushMany(model,Ember.makeArray(Ember.copy(payload[prop],true)));Ember.ArrayPolyfills.forEach.call(Ember.makeArray(payload[prop]),function(hash){FactoryGuy.pushFixture(model,hash)},this)}}else{throw new Ember.Error("Assertion Failed: You cannot use `store#pushPayload` with this method signature pushPayload("+type+","+payload+")")}}else{this._super(type,payload)}}})})();var FactoryGuyTestMixin=Em.Mixin.create({setup:function(app){this.set("container",app.__container__);FactoryGuy.setStore(this.getStore());return this},useFixtureAdapter:function(app){app.ApplicationAdapter=DS.FixtureAdapter;this.getStore().adapterFor("application").simulateRemoteResponse=false},usingActiveModelSerializer:function(type){var store=this.getStore();var modelType=store.modelFor(type);var serializer=store.serializerFor(modelType.typeKey);return serializer instanceof DS.ActiveModelSerializer},find:function(type,id){return this.getStore().find(type,id)},make:function(){return FactoryGuy.make.apply(FactoryGuy,arguments)},getStore:function(){return this.get("container").lookup("store:main")},stubEndpointForHttpRequest:function(url,json,options){options=options||{};var request={url:url,dataType:"json",responseText:json,type:options.type||"GET",status:options.status||200};if(options.urlParams){request.urlParams=options.urlParams}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)},mapFindAll:function(modelName,json){var responseJson={};responseJson[modelName.pluralize()]=json;return responseJson},mapFind:function(modelName,json){var responseJson={};responseJson[modelName.pluralize()]=json;return responseJson},handleFindAll:function(){var records=FactoryGuy.makeList.apply(FactoryGuy,arguments);var name=arguments[0];var modelName=FactoryGuy.lookupModelForFixtureName(name);var json=records.map(function(record){return record.toJSON({includeId:true})});var responseJson=this.mapFindAll(modelName,json);var url=this.buildURL(modelName);this.stubEndpointForHttpRequest(url,responseJson)},handleFindMany:function(){Ember.deprecate("DEPRECATION Warning: use handleFindAll instead");this.handleFindAll.apply(this,arguments)},handleFind:function(){var args=Array.prototype.slice.call(arguments);Ember.assert("To handleFindOne pass in a model instance or a type and model options",args.length>0);var record,modelName;if(args[0]instanceof DS.Model){record=args[0];modelName=record.constructor.typeKey}else{record=FactoryGuy.make.apply(FactoryGuy,arguments);var name=arguments[0];modelName=FactoryGuy.lookupModelForFixtureName(name)}var json=record.toJSON({includeId:true});var responseJson=this.mapFind(modelName,json);var url=this.buildURL(modelName,record.id);this.stubEndpointForHttpRequest(url,responseJson)},handleFindOne:function(){this.handleFind.apply(this,arguments)},handleFindQuery:function(modelName,searchParams,records){Ember.assert("The second argument of searchParams must be an array",Em.typeOf(searchParams)=="array");if(records){Ember.assert("The third argument ( records ) must be an array - found type:"+Em.typeOf(records),Em.typeOf(records)=="array")}else{records=[]}var json=records.map(function(record){return record.toJSON({includeId:true})});var responseJson=this.mapFindAll(modelName,json);var url=this.buildURL(modelName);this.stubEndpointForHttpRequest(url,responseJson,{urlParams:searchParams})},handleCreate:function(modelName,options){var url=this.buildURL(modelName);var store=this.getStore();var opts=options===undefined?{}:options;return new MockCreateRequest(url,store,modelName,opts)},handleUpdate:function(){var args=Array.prototype.slice.call(arguments);Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0);var options={};if(args.length>1&&typeof args[args.length-1]==="object"){options=args.pop()}var model,type,id;var store=this.getStore();if(args[0]instanceof DS.Model){model=args[0];id=model.id;type=model.constructor.typeKey}else if(typeof args[0]=="string"&&typeof parseInt(args[1])=="number"){type=args[0];id=args[1];model=store.getById(type,id)}Ember.assert("To handleUpdate pass in a model instance or a type and an id",type&&id);var url=this.buildURL(type,id);return new MockUpdateRequest(url,model,this.mapFind,options)},handleDelete:function(type,id,succeed){succeed=succeed===undefined?true:succeed;this.stubEndpointForHttpRequest(this.buildURL(type,id),{},{type:"DELETE",status:succeed?200:500})},teardown:function(){FactoryGuy.resetModels(this.getStore());$.mockjax.clear()}});if(FactoryGuy!==undefined){FactoryGuy.testMixin=FactoryGuyTestMixin}
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-data-factory-guy",
3
- "version": "0.9.9",
3
+ "version": "0.9.10",
4
4
  "authors": [
5
5
  "Daniel Sudol <dansudol@yahoo.com>",
6
6
  "Opak Alex <opak.alexandr@gmail.com>"
@@ -268,34 +268,35 @@ var FactoryGuyTestMixin = Em.Mixin.create({
268
268
  Handling ajax PUT ( update record ) for a model type. You can mock
269
269
  failed update by passing in success argument as false.
270
270
 
271
- @param {String} type model type like 'user' for User model
271
+ @param {String} type model type like 'user' for User model, or a model instance
272
272
  @param {String} id id of record to update
273
- @param {Boolean} succeed optional flag to indicate if the request
274
- should succeed ( default is true )
273
+ @param {Object} options options object
275
274
  */
276
275
  handleUpdate: function () {
277
- var args = Array.prototype.slice.call(arguments)
276
+ var args = Array.prototype.slice.call(arguments);
278
277
  Ember.assert("To handleUpdate pass in a model instance or a type and an id", args.length>0)
279
- var succeed = true;
280
- if (typeof args[args.length-1] == 'boolean') {
281
- args.pop()
282
- succeed = false;
278
+
279
+ var options = {};
280
+ if (args.length > 1 && typeof args[args.length - 1] === 'object') {
281
+ options = args.pop();
283
282
  }
284
- Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0)
285
- var type, id;
283
+
284
+ var model, type, id;
285
+ var store = this.getStore();
286
+
286
287
  if (args[0] instanceof DS.Model) {
287
- var model = args[0];
288
- type = model.constructor.typeKey;
288
+ model = args[0];
289
289
  id = model.id;
290
+ type = model.constructor.typeKey;
290
291
  } else if (typeof args[0] == "string" && typeof parseInt(args[1]) == "number") {
291
292
  type = args[0];
292
293
  id = args[1];
294
+ model = store.getById(type, id)
293
295
  }
294
- Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id)
295
- this.stubEndpointForHttpRequest(this.buildURL(type, id), {}, {
296
- type: 'PUT',
297
- status: succeed ? 200 : 500
298
- });
296
+ Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id);
297
+
298
+ var url = this.buildURL(type, id);
299
+ return new MockUpdateRequest(url, model, this.mapFind, options);
299
300
  },
300
301
  /**
301
302
  Handling ajax DELETE ( delete record ) for a model type. You can mock
@@ -0,0 +1,49 @@
1
+ var MockUpdateRequest = function(url, model, mapFind, options) {
2
+ var status = options.status || 200;
3
+ var succeed = true;
4
+ var response = null;
5
+
6
+ if ('succeed' in options) {
7
+ succeed = options.succeed;
8
+ }
9
+
10
+ if ('response' in options) {
11
+ response = options.response;
12
+ }
13
+
14
+ this.andSucceed = function(options) {
15
+ succeed = true;
16
+ return this;
17
+ };
18
+
19
+ this.andFail = function(options) {
20
+ succeed = false;
21
+ status = options.status || 500;
22
+ if ('response' in options) {
23
+ response = options.response;
24
+ }
25
+ return this;
26
+ };
27
+
28
+ this.handler = function(settings) {
29
+ if (!succeed) {
30
+ this.status = status;
31
+ if (response !== null) {
32
+ this.responseText = response;
33
+ }
34
+ } else {
35
+ var json = model.toJSON({includeId: true});
36
+ this.responseText = mapFind(model.constructor.typeKey, json);
37
+ this.status = 200;
38
+ }
39
+ };
40
+
41
+ var requestConfig = {
42
+ url: url,
43
+ dataType: 'json',
44
+ type: 'PUT',
45
+ response: this.handler
46
+ };
47
+
48
+ $.mockjax(requestConfig);
49
+ };
@@ -28,7 +28,7 @@ module('FactoryGuyTestMixin (using mockjax) with DS.RESTAdapter', {
28
28
  setup: function () {
29
29
  testHelper = TestHelper.setup(DS.RESTAdapter);
30
30
  store = testHelper.getStore();
31
- make = function() {return FactoryGuy.make.apply(FactoryGuy,arguments)}
31
+ make = function() {return FactoryGuy.make.apply(FactoryGuy,arguments);}
32
32
  },
33
33
  teardown: function () {
34
34
  Em.run(function() {
@@ -623,17 +623,16 @@ asyncTest("#handleFindAll with traits and fixture options", function () {
623
623
  test("#handleUpdate with incorrect parameters", function(assert) {
624
624
  assert.throws(function(){testHelper.handleUpdate()},"missing everything");
625
625
  assert.throws(function(){testHelper.handleUpdate('profile')},"missing id");
626
- assert.throws(function(){testHelper.handleUpdate('profile', false)},"missing id");
627
- assert.throws(function(){testHelper.handleUpdate('profile', true)},"missing id");
626
+ assert.throws(function(){testHelper.handleUpdate('profile', {})},"missing id");
628
627
  });
629
628
 
630
- asyncTest("#handleUpdate the with modelType and id", function() {
631
- Em.run(function() {
629
+ asyncTest("#handleUpdate the with modelType and id", function () {
630
+ Em.run(function () {
632
631
  var profile = make('profile');
633
632
  testHelper.handleUpdate('profile', profile.id);
634
633
 
635
- profile.set('description','new desc');
636
- profile.save().then(function(profile) {
634
+ profile.set('description', 'new desc');
635
+ profile.save().then(function (profile) {
637
636
  ok(profile.get('description') == 'new desc');
638
637
  start();
639
638
  });
@@ -641,52 +640,170 @@ asyncTest("#handleUpdate the with modelType and id", function() {
641
640
  });
642
641
 
643
642
 
644
- asyncTest("#handleUpdate the with model", function() {
645
- Em.run(function() {
643
+ asyncTest("#handleUpdate the with model", function () {
644
+ Em.run(function () {
646
645
  var profile = make('profile');
647
- testHelper.handleUpdate(profile, true, {e:1});
646
+ testHelper.handleUpdate(profile);
648
647
 
649
- profile.set('description','new desc');
650
- profile.save().then(function(profile) {
648
+ profile.set('description', 'new desc');
649
+ profile.save().then(function (profile) {
651
650
  ok(profile.get('description') == 'new desc');
652
651
  start();
653
652
  });
654
653
  });
655
654
  });
656
655
 
657
- asyncTest("#handleUpdate the with modelType and id that fails", function() {
658
- Em.run(function() {
656
+ asyncTest("#handleUpdate the with modelType and id that fails", function () {
657
+ Em.run(function () {
659
658
  var profile = make('profile');
660
- testHelper.handleUpdate('profile', profile.id, false);
661
659
 
662
- profile.set('description','new desc');
660
+ testHelper.handleUpdate('profile', profile.id, {succeed: false, status: 500});
661
+
662
+ profile.set('description', 'new desc');
663
663
  profile.save().then(
664
- function() {},
665
- function() {
666
- ok(true)
664
+ function () {
665
+ },
666
+ function () {
667
+ ok(true);
667
668
  start();
668
669
  }
669
- )
670
+ );
670
671
  });
671
672
  });
672
673
 
673
- asyncTest("#handleUpdate with model that fails", function() {
674
- Em.run(function() {
674
+ asyncTest("#handleUpdate with model that fails", function () {
675
+ Em.run(function () {
675
676
  var profile = make('profile');
676
677
 
677
- testHelper.handleUpdate(profile, false);
678
+ testHelper.handleUpdate(profile, {succeed: false, status: 500});
678
679
 
679
- profile.set('description','new desc');
680
+ profile.set('description', 'new desc');
680
681
  profile.save().then(
681
- function() {},
682
- function() {
683
- ok(true)
684
- start();
685
- }
686
- )
682
+ function () {
683
+ },
684
+ function () {
685
+ ok(true);
686
+ start();
687
+ }
688
+ );
687
689
  });
688
690
  });
689
691
 
692
+ asyncTest("#handleUpdate with model that fails with custom response", function () {
693
+ Em.run(function () {
694
+ var profile = make('profile');
695
+
696
+ testHelper.handleUpdate(profile, {succeed: false, status: 400, response: "{error: 'invalid data'}"});
697
+
698
+ profile.set('description', 'new desc');
699
+ profile.save().then(
700
+ function () {
701
+ },
702
+ function (reason) {
703
+ ok(true);
704
+ equal(reason.status, 400);
705
+ equal(reason.responseText, "{error: 'invalid data'}");
706
+ start();
707
+ }
708
+ );
709
+ });
710
+ });
711
+
712
+ asyncTest("#handleUpdate the with modelType and id that fails chained", function () {
713
+ Em.run(function () {
714
+ var profile = make('profile');
715
+
716
+ testHelper.handleUpdate('profile', profile.id).andFail({
717
+ status: 500
718
+ });
719
+
720
+ profile.set('description', 'new desc');
721
+ profile.save().then(
722
+ function () {
723
+ },
724
+ function (reason) {
725
+ ok(true);
726
+ equal(reason.status, 500);
727
+ start();
728
+ }
729
+ );
730
+ });
731
+ });
732
+
733
+ asyncTest("#handleUpdate with model that fails chained", function () {
734
+ Em.run(function () {
735
+ var profile = make('profile');
736
+
737
+ testHelper.handleUpdate(profile).andFail({
738
+ status: 500
739
+ });
740
+
741
+ profile.set('description', 'new desc');
742
+ profile.save().then(
743
+ function () {
744
+ },
745
+ function (reason) {
746
+ ok(true);
747
+ equal(reason.status, 500);
748
+ start();
749
+ }
750
+ );
751
+ });
752
+ });
753
+
754
+ asyncTest("#handleUpdate with model that fail with custom response", function () {
755
+ Em.run(function () {
756
+ var profile = make('profile');
757
+
758
+ testHelper.handleUpdate(profile).andFail({
759
+ status: 400,
760
+ response: "{error: 'invalid data'}"
761
+ });
762
+
763
+ profile.set('description', 'new desc');
764
+ profile.save().then(
765
+ function () {
766
+ },
767
+ function (reason) {
768
+ ok(true);
769
+ equal(reason.responseText, "{error: 'invalid data'}");
770
+ start();
771
+ }
772
+ );
773
+ });
774
+ });
775
+
776
+ asyncTest("#handleUpdate with model that fail and then succeeds", function () {
777
+ Em.run(function () {
778
+ var profile = make('profile');
779
+
780
+ var updateMock = testHelper.handleUpdate(profile).andFail({
781
+ status: 400,
782
+ response: "{error: 'invalid data'}"
783
+ });
784
+
785
+ profile.set('description', 'new desc');
786
+ profile.save().then(
787
+ function () {
788
+ },
789
+ function (reason) {
790
+ equal(reason.responseText, "{error: 'invalid data'}", "Could not save model.");
791
+ }
792
+ ).then(function () {
793
+ updateMock.andSucceed();
794
+
795
+ ok(!profile.get('valid'), "Profile is invalid.");
796
+
797
+ profile.save().then(
798
+ function () {
799
+ ok(!profile.get('saving'), "Saved model");
800
+ ok(profile.get('description') == 'new desc', "Description was updated.");
801
+ start();
802
+ }
803
+ );
804
+ });
805
+ });
806
+ });
690
807
 
691
808
  /////// handleDelete //////////
692
809
 
@@ -644,6 +644,55 @@ var MockCreateRequest = function(url, store, modelName, options) {
644
644
  $.mockjax(this.handler);
645
645
  };
646
646
 
647
+ var MockUpdateRequest = function(url, model, mapFind, options) {
648
+ var status = options.status || 200;
649
+ var succeed = true;
650
+ var response = null;
651
+
652
+ if ('succeed' in options) {
653
+ succeed = options.succeed;
654
+ }
655
+
656
+ if ('response' in options) {
657
+ response = options.response;
658
+ }
659
+
660
+ this.andSucceed = function(options) {
661
+ succeed = true;
662
+ return this;
663
+ };
664
+
665
+ this.andFail = function(options) {
666
+ succeed = false;
667
+ status = options.status || 500;
668
+ if ('response' in options) {
669
+ response = options.response;
670
+ }
671
+ return this;
672
+ };
673
+
674
+ this.handler = function(settings) {
675
+ if (!succeed) {
676
+ this.status = status;
677
+ if (response !== null) {
678
+ this.responseText = response;
679
+ }
680
+ } else {
681
+ var json = model.toJSON({includeId: true});
682
+ this.responseText = mapFind(model.constructor.typeKey, json);
683
+ this.status = 200;
684
+ }
685
+ };
686
+
687
+ var requestConfig = {
688
+ url: url,
689
+ dataType: 'json',
690
+ type: 'PUT',
691
+ response: this.handler
692
+ };
693
+
694
+ $.mockjax(requestConfig);
695
+ };
647
696
  (function () {
648
697
  DS.Store.reopen({
649
698
  /**
@@ -1191,34 +1240,35 @@ var FactoryGuyTestMixin = Em.Mixin.create({
1191
1240
  Handling ajax PUT ( update record ) for a model type. You can mock
1192
1241
  failed update by passing in success argument as false.
1193
1242
 
1194
- @param {String} type model type like 'user' for User model
1243
+ @param {String} type model type like 'user' for User model, or a model instance
1195
1244
  @param {String} id id of record to update
1196
- @param {Boolean} succeed optional flag to indicate if the request
1197
- should succeed ( default is true )
1245
+ @param {Object} options options object
1198
1246
  */
1199
1247
  handleUpdate: function () {
1200
- var args = Array.prototype.slice.call(arguments)
1248
+ var args = Array.prototype.slice.call(arguments);
1201
1249
  Ember.assert("To handleUpdate pass in a model instance or a type and an id", args.length>0)
1202
- var succeed = true;
1203
- if (typeof args[args.length-1] == 'boolean') {
1204
- args.pop()
1205
- succeed = false;
1250
+
1251
+ var options = {};
1252
+ if (args.length > 1 && typeof args[args.length - 1] === 'object') {
1253
+ options = args.pop();
1206
1254
  }
1207
- Ember.assert("To handleUpdate pass in a model instance or a type and an id",args.length>0)
1208
- var type, id;
1255
+
1256
+ var model, type, id;
1257
+ var store = this.getStore();
1258
+
1209
1259
  if (args[0] instanceof DS.Model) {
1210
- var model = args[0];
1211
- type = model.constructor.typeKey;
1260
+ model = args[0];
1212
1261
  id = model.id;
1262
+ type = model.constructor.typeKey;
1213
1263
  } else if (typeof args[0] == "string" && typeof parseInt(args[1]) == "number") {
1214
1264
  type = args[0];
1215
1265
  id = args[1];
1266
+ model = store.getById(type, id)
1216
1267
  }
1217
- Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id)
1218
- this.stubEndpointForHttpRequest(this.buildURL(type, id), {}, {
1219
- type: 'PUT',
1220
- status: succeed ? 200 : 500
1221
- });
1268
+ Ember.assert("To handleUpdate pass in a model instance or a type and an id",type && id);
1269
+
1270
+ var url = this.buildURL(type, id);
1271
+ return new MockUpdateRequest(url, model, this.mapFind, options);
1222
1272
  },
1223
1273
  /**
1224
1274
  Handling ajax DELETE ( delete record ) for a model type. You can mock
@@ -1361,12 +1411,10 @@ if (FactoryGuy !== undefined) {
1361
1411
  return null;
1362
1412
  }
1363
1413
  }
1414
+
1364
1415
  // Inspect the data submitted in the request (either POST body or GET query string)
1365
1416
  if ( handler.data ) {
1366
- // console.log('request.data', requestSettings.data )
1367
- // console.log('handler.data', handler.data )
1368
- // console.log('data equal', isMockDataEqual(handler.data, requestSettings.data) )
1369
- if ( ! requestSettings.data || !isMockDataEqual(handler.data, requestSettings.data) ) {
1417
+ if ( ! requestSettings.data || !isMockDataEqual(handler.data, requestSettings.data) ) {
1370
1418
  // They're not identical, do not mock this request
1371
1419
  return null;
1372
1420
  }
@@ -1377,6 +1425,7 @@ if (FactoryGuy !== undefined) {
1377
1425
  // The request type doesn't match (GET vs. POST)
1378
1426
  return null;
1379
1427
  }
1428
+
1380
1429
  return handler;
1381
1430
  }
1382
1431
 
@@ -1740,7 +1789,6 @@ if (FactoryGuy !== undefined) {
1740
1789
  }
1741
1790
 
1742
1791
  mockHandler = getMockForRequest( mockHandlers[k], requestSettings );
1743
-
1744
1792
  if(!mockHandler) {
1745
1793
  // No valid mock found for this request
1746
1794
  continue;
@@ -1792,7 +1840,7 @@ if (FactoryGuy !== undefined) {
1792
1840
  }
1793
1841
 
1794
1842
  copyUrlParameters(mockHandler, origSettings);
1795
- //console.log('here copyUrlParameters', 'mockHandler=>',mockHandler, 'requestSettings=>',requestSettings, 'origSettings=>',origSettings)
1843
+
1796
1844
  (function(mockHandler, requestSettings, origSettings, origHandler) {
1797
1845
 
1798
1846
  mockRequest = _ajax.call($, $.extend(true, {}, origSettings, {
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.9.9
4
+ version: 0.9.10
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: 2015-02-20 00:00:00.000000000 Z
12
+ date: 2015-02-23 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Easily create Fixtures for Ember Data
15
15
  email:
@@ -37,6 +37,7 @@ files:
37
37
  - src/factory_guy_test_mixin.js
38
38
  - src/has_many.js
39
39
  - src/mock_create_request.js
40
+ - src/mock_update_request.js
40
41
  - src/model_definition.js
41
42
  - src/prologue.js
42
43
  - src/sequence.js