ember-data-factory-guy 0.3.9 → 0.4.0

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: f9b67c07e091270fd561c057ce6b0e3402b14ad4
4
- data.tar.gz: 7568ead17270e5c135bfdc4d572d1734aa9553b2
3
+ metadata.gz: a79807f71868de1b78d4749f7d4a6ae1da807ede
4
+ data.tar.gz: a45cf559a2cbbd4d2c2169bcab63748148988a92
5
5
  SHA512:
6
- metadata.gz: 819e5a60c11d219b1fe68bcf0ae5d04c2e7e33c38e5b748d5177381b53e2c122dc287265e8136196e00ef406e742927c4455776b69dd34685bb8f61286416310
7
- data.tar.gz: 37e73744a1f68bcf7c0dc197a03f86a2ffa8041b2e19816e826b0c33c411924c15a88fecb9875abc4a69ca6e43025edef962c81c0b53b11f82c32a8e65c2111e
6
+ metadata.gz: a3f8360c4ec985b6077dc1e4cc169a531ec8803313a431eba7e03d87cc6282686ce3205bfef824ab386128ed2952617acf4f29a6f06331c0065d5467ad2e54be
7
+ data.tar.gz: d294092adde0d91d1cb8feffccd5cd15f09854509cafe3966674bd0b9ec8220c94c2fb3c8954f21fd8075ede0ad0db2fab1a2779b08a735470189113017d7a4f
data/.gitignore CHANGED
@@ -4,4 +4,5 @@ factory_guy_presentation/
4
4
  factory_guy_presents/
5
5
  stats/
6
6
  *.gem
7
- *.ruby*
7
+ *.ruby*
8
+ .idea/*
data/bower.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-data-factory-guy",
3
- "version": "0.3.8",
3
+ "version": "0.4.0",
4
4
  "authors": [
5
5
  "Daniel Sudol <dansudol@yahoo.com>",
6
6
  "Opak Alex <opak.alexandr@gmail.com>"
@@ -390,9 +390,10 @@ DS.Store.reopen({
390
390
  @returns {Object|DS.Model} json or record depending on the adapter type
391
391
  */
392
392
  makeFixture: function (name, options) {
393
+ var store = this;
393
394
  var modelName = FactoryGuy.lookupModelForFixtureName(name);
394
395
  var fixture = FactoryGuy.build(name, options);
395
- var modelType = this.modelFor(modelName);
396
+ var modelType = store.modelFor(modelName);
396
397
 
397
398
  if (this.usingFixtureAdapter()) {
398
399
  this.setAssociationsForFixtureAdapter(modelType, modelName, fixture);
@@ -406,6 +407,7 @@ DS.Store.reopen({
406
407
  // assuming its polymorphic if there is a type attribute
407
408
  // is this too bold an assumption?
408
409
  modelName = fixture.type.underscore();
410
+ modelType = store.modelFor(modelName);
409
411
  }
410
412
  model = store.push(modelName, fixture);
411
413
  store.setAssociationsForRESTAdapter(modelType, modelName, model);
@@ -543,12 +545,16 @@ DS.Store.reopen({
543
545
  var self = this;
544
546
  Ember.get(modelType, 'relationshipsByName').forEach(function (name, relationship) {
545
547
  if (relationship.kind == 'hasMany') {
546
- var belongsToName = modelName;
547
- if (relationship.options && relationship.options.inverse) {
548
- belongsToName = relationship.options.inverse;
549
- }
550
548
  var children = model.get(name) || [];
551
549
  children.forEach(function (child) {
550
+ var belongsToName = self.findRelationshipName(
551
+ 'belongsTo',
552
+ child.constructor,
553
+ model
554
+ );
555
+ if (relationship.options && relationship.options.inverse) {
556
+ belongsToName = relationship.options.inverse;
557
+ }
552
558
  child.set(belongsToName, model);
553
559
  })
554
560
  }
@@ -769,11 +775,10 @@ FactoryGuyTestMixin = Em.Mixin.create({
769
775
  */
770
776
  handleCreate: function (name, opts) {
771
777
  var model = FactoryGuy.lookupModelForFixtureName(name);
772
- this.stubEndpointForHttpRequest(
773
- "/" + Em.String.pluralize(model),
774
- this.buildAjaxCreateResponse(name, opts),
775
- {type: 'POST'}
776
- )
778
+ var responseJson = this.buildAjaxCreateResponse(name, opts);
779
+ var url = "/" + Em.String.pluralize(model);
780
+ this.stubEndpointForHttpRequest(url, responseJson, {type: 'POST'})
781
+ return responseJson;
777
782
  },
778
783
 
779
784
  /**
@@ -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 modelName=FactoryGuy.lookupModelForFixtureName(name);var fixture=FactoryGuy.build(name,options);var modelType=this.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()}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 belongsToName=modelName;if(relationship.options&&relationship.options.inverse){belongsToName=relationship.options.inverse}var children=model.get(name)||[];children.forEach(function(child){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);this.stubEndpointForHttpRequest("/"+Em.String.pluralize(model),this.buildAjaxCreateResponse(name,opts),{type:"POST"})},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},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,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.3.9"
4
+ s.version = "0.4.0"
5
5
  s.platform = Gem::Platform::RUBY
6
6
  s.authors = ["Daniel Sudol", "Alex Opak"]
7
7
  s.email = ["dansudol@yahoo.com", "opak.alexandr@gmail.com"]
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-data-factory-guy",
3
- "version": "0.3.8",
3
+ "version": "0.4.0",
4
4
  "authors": [
5
5
  "Daniel Sudol <dansudol@yahoo.com>",
6
6
  "Opak Alex <opak.alexandr@gmail.com>"
@@ -24,12 +24,13 @@
24
24
  "type": "git",
25
25
  "url": ""
26
26
  },
27
- "devDependencies": [
28
- "grunt-contrib-coffee",
29
- "grunt-contrib-concat",
30
- "grunt-contrib-uglify",
31
- "grunt-contrib-qunit"
32
- ],
27
+ "devDependencies": {
28
+ "0": "grunt-contrib-coffee",
29
+ "1": "grunt-contrib-concat",
30
+ "2": "grunt-contrib-uglify",
31
+ "3": "grunt-contrib-qunit",
32
+ "grunt-bump": "0.0.14"
33
+ },
33
34
  "engines": {
34
35
  "node": ">=v0.10.1"
35
36
  }
@@ -70,11 +70,10 @@ FactoryGuyTestMixin = Em.Mixin.create({
70
70
  */
71
71
  handleCreate: function (name, opts) {
72
72
  var model = FactoryGuy.lookupModelForFixtureName(name);
73
- this.stubEndpointForHttpRequest(
74
- "/" + Em.String.pluralize(model),
75
- this.buildAjaxCreateResponse(name, opts),
76
- {type: 'POST'}
77
- )
73
+ var responseJson = this.buildAjaxCreateResponse(name, opts);
74
+ var url = "/" + Em.String.pluralize(model);
75
+ this.stubEndpointForHttpRequest(url, responseJson, {type: 'POST'})
76
+ return responseJson;
78
77
  },
79
78
 
80
79
  /**
data/src/store.js CHANGED
@@ -16,9 +16,10 @@ DS.Store.reopen({
16
16
  @returns {Object|DS.Model} json or record depending on the adapter type
17
17
  */
18
18
  makeFixture: function (name, options) {
19
+ var store = this;
19
20
  var modelName = FactoryGuy.lookupModelForFixtureName(name);
20
21
  var fixture = FactoryGuy.build(name, options);
21
- var modelType = this.modelFor(modelName);
22
+ var modelType = store.modelFor(modelName);
22
23
 
23
24
  if (this.usingFixtureAdapter()) {
24
25
  this.setAssociationsForFixtureAdapter(modelType, modelName, fixture);
@@ -32,6 +33,7 @@ DS.Store.reopen({
32
33
  // assuming its polymorphic if there is a type attribute
33
34
  // is this too bold an assumption?
34
35
  modelName = fixture.type.underscore();
36
+ modelType = store.modelFor(modelName);
35
37
  }
36
38
  model = store.push(modelName, fixture);
37
39
  store.setAssociationsForRESTAdapter(modelType, modelName, model);
@@ -169,12 +171,16 @@ DS.Store.reopen({
169
171
  var self = this;
170
172
  Ember.get(modelType, 'relationshipsByName').forEach(function (name, relationship) {
171
173
  if (relationship.kind == 'hasMany') {
172
- var belongsToName = modelName;
173
- if (relationship.options && relationship.options.inverse) {
174
- belongsToName = relationship.options.inverse;
175
- }
176
174
  var children = model.get(name) || [];
177
175
  children.forEach(function (child) {
176
+ var belongsToName = self.findRelationshipName(
177
+ 'belongsTo',
178
+ child.constructor,
179
+ model
180
+ );
181
+ if (relationship.options && relationship.options.inverse) {
182
+ belongsToName = relationship.options.inverse;
183
+ }
178
184
  child.set(belongsToName, model);
179
185
  })
180
186
  }
@@ -100,6 +100,13 @@ test("when hasMany associations are assigned, belongsTo parent is assigned using
100
100
  });
101
101
 
102
102
 
103
+ test("when hasMany associations are assigned, belongsTo parent is assigned using actual belongsTo name", function() {
104
+ var silk = store.makeFixture('silk');
105
+ var bh = store.makeFixture('big_hat', {materials: [silk]});
106
+ ok(silk.get('hat') == bh)
107
+ });
108
+
109
+
103
110
  test("when belongTo parent is assigned, parent adds to hasMany records", function() {
104
111
  var user = store.makeFixture('user');
105
112
  var project1 = store.makeFixture('project', {user: user});
@@ -142,6 +149,13 @@ test("when belongTo parent is assigned, parent adds to hasMany record using inve
142
149
  });
143
150
 
144
151
 
152
+ test("when belongTo parent is assigned, parent adds to hasMany record using actual hasMany name", function() {
153
+ var bh = store.makeFixture('big_hat');
154
+ var silk = store.makeFixture('silk', {hat: bh});
155
+ ok(bh.get('materials.firstObject') == silk)
156
+ });
157
+
158
+
145
159
  test("when belongTo parent is assigned, parent adds to belongsTo record", function() {
146
160
  var company = store.makeFixture('company');
147
161
  var profile = store.makeFixture('profile', {company: company});
@@ -194,3 +208,16 @@ test("creates records in the store", function() {
194
208
  deepEqual(storeUsers[0].toJSON(), users[0].toJSON());
195
209
  deepEqual(storeUsers[1].toJSON(), users[1].toJSON());
196
210
  });
211
+
212
+
213
+ asyncTest("#store.createRecord with FactoryGuy fixtures handles snake_case or camelCase attributes", function() {
214
+ var json = testHelper.handleCreate('profile', {})
215
+ // if you examine the json .. you'll see both attributes in there
216
+ store.createRecord('profile').save().then(function(profile) {
217
+ // both types of attributes work just fine
218
+ ok(!!profile.get('snake_case_description'))
219
+ ok(!!profile.get('camelCaseDescription'))
220
+ start();
221
+ })
222
+ })
223
+
@@ -147,9 +147,9 @@ test("#lookupDefinitionForFixtureName", function() {
147
147
  equal(!!FactoryGuy.lookupDefinitionForFixtureName('fake'), false, "return nothing if can't find definition");
148
148
  });
149
149
 
150
-
151
150
  test("#lookupModelForFixtureName", function() {
152
151
  equal(FactoryGuy.lookupModelForFixtureName('person'), 'person', "finds model if its the same as model name");
153
152
  equal(FactoryGuy.lookupModelForFixtureName('funny_person'), 'person', "finds model if it's definition has this named fixture");
154
153
  equal(FactoryGuy.lookupModelForFixtureName('fake'), undefined, "return nothing if can't find definition");
155
- });
154
+ });
155
+
@@ -100,6 +100,13 @@ test("when hasMany associations are assigned, belongsTo parent is assigned using
100
100
  });
101
101
 
102
102
 
103
+ test("when hasMany associations are assigned, belongsTo parent is assigned using actual belongsTo name", function() {
104
+ var silk = store.makeFixture('silk');
105
+ var bh = store.makeFixture('big_hat', {materials: [silk]});
106
+ ok(silk.get('hat') == bh)
107
+ });
108
+
109
+
103
110
  test("when belongTo parent is assigned, parent adds to hasMany records", function() {
104
111
  var user = store.makeFixture('user');
105
112
  var project1 = store.makeFixture('project', {user: user});
@@ -142,6 +149,13 @@ test("when belongTo parent is assigned, parent adds to hasMany record using inve
142
149
  });
143
150
 
144
151
 
152
+ test("when belongTo parent is assigned, parent adds to hasMany record using actual hasMany name", function() {
153
+ var bh = store.makeFixture('big_hat');
154
+ var silk = store.makeFixture('silk', {hat: bh});
155
+ ok(bh.get('materials.firstObject') == silk)
156
+ });
157
+
158
+
145
159
  test("when belongTo parent is assigned, parent adds to belongsTo record", function() {
146
160
  var company = store.makeFixture('company');
147
161
  var profile = store.makeFixture('profile', {company: company});
@@ -0,0 +1,8 @@
1
+ FactoryGuy.define('soft_material', {
2
+ default: {
3
+ name: 'Soft material'
4
+ },
5
+ silk: {
6
+ name: 'silk'
7
+ }
8
+ })
@@ -1,5 +1,7 @@
1
1
  FactoryGuy.define('profile', {
2
2
  default: {
3
- description: 'Text goes here'
3
+ description: 'Text goes here',
4
+ camelCaseDescription: 'boyThisIsSilly',
5
+ snake_case_description: 'how_do_birds_find_worms'
4
6
  }
5
7
  })
@@ -0,0 +1,600 @@
1
+ /*!
2
+ * MockJax - jQuery Plugin to Mock Ajax requests
3
+ *
4
+ * Version: 1.5.3
5
+ * Released:
6
+ * Home: http://github.com/appendto/jquery-mockjax
7
+ * Author: Jonathan Sharp (http://jdsharp.com)
8
+ * License: MIT,GPL
9
+ *
10
+ * Copyright (c) 2011 appendTo LLC.
11
+ * Dual licensed under the MIT or GPL licenses.
12
+ * http://appendto.com/open-source-licenses
13
+ */
14
+ (function($) {
15
+ var _ajax = $.ajax,
16
+ mockHandlers = [],
17
+ mockedAjaxCalls = [],
18
+ CALLBACK_REGEX = /=\?(&|$)/,
19
+ jsc = (new Date()).getTime();
20
+
21
+
22
+ // Parse the given XML string.
23
+ function parseXML(xml) {
24
+ if ( window.DOMParser == undefined && window.ActiveXObject ) {
25
+ DOMParser = function() { };
26
+
27
+ DOMParser.prototype.parseFromString = function( xmlString ) {
28
+ var doc = new ActiveXObject('Microsoft.XMLDOM');
29
+ doc.async = 'false';
30
+ doc.loadXML( xmlString );
31
+ return doc;
32
+ };
33
+ }
34
+
35
+ try {
36
+ var xmlDoc = ( new DOMParser() ).parseFromString( xml, 'text/xml' );
37
+ if ( $.isXMLDoc( xmlDoc ) ) {
38
+ var err = $('parsererror', xmlDoc);
39
+ if ( err.length == 1 ) {
40
+ throw('Error: ' + $(xmlDoc).text() );
41
+ }
42
+ } else {
43
+ throw('Unable to parse XML');
44
+ }
45
+ return xmlDoc;
46
+ } catch( e ) {
47
+ var msg = ( e.name == undefined ? e : e.name + ': ' + e.message );
48
+ $(document).trigger('xmlParseError', [ msg ]);
49
+ return undefined;
50
+ }
51
+ }
52
+
53
+ // Trigger a jQuery event
54
+ function trigger(s, type, args) {
55
+ (s.context ? $(s.context) : $.event).trigger(type, args);
56
+ }
57
+
58
+ // Check if the data field on the mock handler and the request match. This
59
+ // can be used to restrict a mock handler to being used only when a certain
60
+ // set of data is passed to it.
61
+ function isMockDataEqual( mock, live ) {
62
+ var identical = true;
63
+ // Test for situations where the data is a querystring (not an object)
64
+ if (typeof live === 'string') {
65
+ // Querystring may be a regex
66
+ return $.isFunction( mock.test ) ? mock.test(live) : mock == live;
67
+ }
68
+ $.each(mock, function(k) {
69
+ if ( live[k] === undefined ) {
70
+ identical = false;
71
+ return identical;
72
+ } else {
73
+ // This will allow to compare Arrays
74
+ if ( typeof live[k] === 'object' && live[k] !== null ) {
75
+ identical = identical && isMockDataEqual(mock[k], live[k]);
76
+ } else {
77
+ if ( mock[k] && $.isFunction( mock[k].test ) ) {
78
+ identical = identical && mock[k].test(live[k]);
79
+ } else {
80
+ identical = identical && ( mock[k] == live[k] );
81
+ }
82
+ }
83
+ }
84
+ });
85
+
86
+ return identical;
87
+ }
88
+
89
+ // See if a mock handler property matches the default settings
90
+ function isDefaultSetting(handler, property) {
91
+ return handler[property] === $.mockjaxSettings[property];
92
+ }
93
+
94
+ // Check the given handler should mock the given request
95
+ function getMockForRequest( handler, requestSettings ) {
96
+
97
+ // If the mock was registered with a function, let the function decide if we
98
+ // want to mock this request
99
+ if ( $.isFunction(handler) ) {
100
+ return handler( requestSettings );
101
+ }
102
+
103
+ // Inspect the URL of the request and check if the mock handler's url
104
+ // matches the url for this ajax request
105
+ if ( $.isFunction(handler.url.test) ) {
106
+ // The user provided a regex for the url, test it
107
+ if ( !handler.url.test( requestSettings.url ) ) {
108
+ return null;
109
+ }
110
+ } else {
111
+ // Look for a simple wildcard '*' or a direct URL match
112
+ var star = handler.url.indexOf('*');
113
+ if (handler.url !== requestSettings.url && star === -1 ||
114
+ !new RegExp(handler.url.replace(/[-[\]{}()+?.,\\^$|#\s]/g, "\\$&").replace(/\*/g, '.+')).test(requestSettings.url)) {
115
+ return null;
116
+ }
117
+ }
118
+ // console.log(handler.url, handler.data, requestSettings.data)
119
+ // Inspect the data submitted in the request (either POST body or GET query string)
120
+ if ( handler.data && requestSettings.data ) {
121
+ if ( !isMockDataEqual(handler.data, requestSettings.data) ) {
122
+ // They're not identical, do not mock this request
123
+ return null;
124
+ }
125
+ }
126
+ // Inspect the request type
127
+ if ( handler && handler.type &&
128
+ handler.type.toLowerCase() != requestSettings.type.toLowerCase() ) {
129
+ // The request type doesn't match (GET vs. POST)
130
+ return null;
131
+ }
132
+
133
+ return handler;
134
+ }
135
+
136
+ // Process the xhr objects send operation
137
+ function _xhrSend(mockHandler, requestSettings, origSettings) {
138
+
139
+ // This is a substitute for < 1.4 which lacks $.proxy
140
+ var process = (function(that) {
141
+ return function() {
142
+ return (function() {
143
+ var onReady;
144
+
145
+ // The request has returned
146
+ this.status = mockHandler.status;
147
+ this.statusText = mockHandler.statusText;
148
+ this.readyState = 4;
149
+
150
+ // We have an executable function, call it to give
151
+ // the mock handler a chance to update it's data
152
+ if ( $.isFunction(mockHandler.response) ) {
153
+ mockHandler.response(origSettings);
154
+ }
155
+ // Copy over our mock to our xhr object before passing control back to
156
+ // jQuery's onreadystatechange callback
157
+ if ( requestSettings.dataType == 'json' && ( typeof mockHandler.responseText == 'object' ) ) {
158
+ this.responseText = JSON.stringify(mockHandler.responseText);
159
+ } else if ( requestSettings.dataType == 'xml' ) {
160
+ if ( typeof mockHandler.responseXML == 'string' ) {
161
+ this.responseXML = parseXML(mockHandler.responseXML);
162
+ //in jQuery 1.9.1+, responseXML is processed differently and relies on responseText
163
+ this.responseText = mockHandler.responseXML;
164
+ } else {
165
+ this.responseXML = mockHandler.responseXML;
166
+ }
167
+ } else {
168
+ this.responseText = mockHandler.responseText;
169
+ }
170
+ if( typeof mockHandler.status == 'number' || typeof mockHandler.status == 'string' ) {
171
+ this.status = mockHandler.status;
172
+ }
173
+ if( typeof mockHandler.statusText === "string") {
174
+ this.statusText = mockHandler.statusText;
175
+ }
176
+ // jQuery 2.0 renamed onreadystatechange to onload
177
+ onReady = this.onreadystatechange || this.onload;
178
+
179
+ // jQuery < 1.4 doesn't have onreadystate change for xhr
180
+ if ( $.isFunction( onReady ) ) {
181
+ if( mockHandler.isTimeout) {
182
+ this.status = -1;
183
+ }
184
+ onReady.call( this, mockHandler.isTimeout ? 'timeout' : undefined );
185
+ } else if ( mockHandler.isTimeout ) {
186
+ // Fix for 1.3.2 timeout to keep success from firing.
187
+ this.status = -1;
188
+ }
189
+ }).apply(that);
190
+ };
191
+ })(this);
192
+
193
+ if ( mockHandler.proxy ) {
194
+ // We're proxying this request and loading in an external file instead
195
+ _ajax({
196
+ global: false,
197
+ url: mockHandler.proxy,
198
+ type: mockHandler.proxyType,
199
+ data: mockHandler.data,
200
+ dataType: requestSettings.dataType === "script" ? "text/plain" : requestSettings.dataType,
201
+ complete: function(xhr) {
202
+ mockHandler.responseXML = xhr.responseXML;
203
+ mockHandler.responseText = xhr.responseText;
204
+ // Don't override the handler status/statusText if it's specified by the config
205
+ if (isDefaultSetting(mockHandler, 'status')) {
206
+ mockHandler.status = xhr.status;
207
+ }
208
+ if (isDefaultSetting(mockHandler, 'statusText')) {
209
+ mockHandler.statusText = xhr.statusText;
210
+ }
211
+
212
+ this.responseTimer = setTimeout(process, mockHandler.responseTime || 0);
213
+ }
214
+ });
215
+ } else {
216
+ // type == 'POST' || 'GET' || 'DELETE'
217
+ if ( requestSettings.async === false ) {
218
+ // TODO: Blocking delay
219
+ process();
220
+ } else {
221
+ this.responseTimer = setTimeout(process, mockHandler.responseTime || 50);
222
+ }
223
+ }
224
+ }
225
+
226
+ // Construct a mocked XHR Object
227
+ function xhr(mockHandler, requestSettings, origSettings, origHandler) {
228
+ // Extend with our default mockjax settings
229
+ mockHandler = $.extend(true, {}, $.mockjaxSettings, mockHandler);
230
+
231
+ if (typeof mockHandler.headers === 'undefined') {
232
+ mockHandler.headers = {};
233
+ }
234
+ if ( mockHandler.contentType ) {
235
+ mockHandler.headers['content-type'] = mockHandler.contentType;
236
+ }
237
+
238
+ return {
239
+ status: mockHandler.status,
240
+ statusText: mockHandler.statusText,
241
+ readyState: 1,
242
+ open: function() { },
243
+ send: function() {
244
+ origHandler.fired = true;
245
+ _xhrSend.call(this, mockHandler, requestSettings, origSettings);
246
+ },
247
+ abort: function() {
248
+ clearTimeout(this.responseTimer);
249
+ },
250
+ setRequestHeader: function(header, value) {
251
+ mockHandler.headers[header] = value;
252
+ },
253
+ getResponseHeader: function(header) {
254
+ // 'Last-modified', 'Etag', 'content-type' are all checked by jQuery
255
+ if ( mockHandler.headers && mockHandler.headers[header] ) {
256
+ // Return arbitrary headers
257
+ return mockHandler.headers[header];
258
+ } else if ( header.toLowerCase() == 'last-modified' ) {
259
+ return mockHandler.lastModified || (new Date()).toString();
260
+ } else if ( header.toLowerCase() == 'etag' ) {
261
+ return mockHandler.etag || '';
262
+ } else if ( header.toLowerCase() == 'content-type' ) {
263
+ return mockHandler.contentType || 'text/plain';
264
+ }
265
+ },
266
+ getAllResponseHeaders: function() {
267
+ var headers = '';
268
+ $.each(mockHandler.headers, function(k, v) {
269
+ headers += k + ': ' + v + "\n";
270
+ });
271
+ return headers;
272
+ }
273
+ };
274
+ }
275
+
276
+ // Process a JSONP mock request.
277
+ function processJsonpMock( requestSettings, mockHandler, origSettings ) {
278
+ // Handle JSONP Parameter Callbacks, we need to replicate some of the jQuery core here
279
+ // because there isn't an easy hook for the cross domain script tag of jsonp
280
+
281
+ processJsonpUrl( requestSettings );
282
+
283
+ requestSettings.dataType = "json";
284
+ if(requestSettings.data && CALLBACK_REGEX.test(requestSettings.data) || CALLBACK_REGEX.test(requestSettings.url)) {
285
+ createJsonpCallback(requestSettings, mockHandler, origSettings);
286
+
287
+ // We need to make sure
288
+ // that a JSONP style response is executed properly
289
+
290
+ var rurl = /^(\w+:)?\/\/([^\/?#]+)/,
291
+ parts = rurl.exec( requestSettings.url ),
292
+ remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
293
+
294
+ requestSettings.dataType = "script";
295
+ if(requestSettings.type.toUpperCase() === "GET" && remote ) {
296
+ var newMockReturn = processJsonpRequest( requestSettings, mockHandler, origSettings );
297
+
298
+ // Check if we are supposed to return a Deferred back to the mock call, or just
299
+ // signal success
300
+ if(newMockReturn) {
301
+ return newMockReturn;
302
+ } else {
303
+ return true;
304
+ }
305
+ }
306
+ }
307
+ return null;
308
+ }
309
+
310
+ // Append the required callback parameter to the end of the request URL, for a JSONP request
311
+ function processJsonpUrl( requestSettings ) {
312
+ if ( requestSettings.type.toUpperCase() === "GET" ) {
313
+ if ( !CALLBACK_REGEX.test( requestSettings.url ) ) {
314
+ requestSettings.url += (/\?/.test( requestSettings.url ) ? "&" : "?") +
315
+ (requestSettings.jsonp || "callback") + "=?";
316
+ }
317
+ } else if ( !requestSettings.data || !CALLBACK_REGEX.test(requestSettings.data) ) {
318
+ requestSettings.data = (requestSettings.data ? requestSettings.data + "&" : "") + (requestSettings.jsonp || "callback") + "=?";
319
+ }
320
+ }
321
+
322
+ // Process a JSONP request by evaluating the mocked response text
323
+ function processJsonpRequest( requestSettings, mockHandler, origSettings ) {
324
+ // Synthesize the mock request for adding a script tag
325
+ var callbackContext = origSettings && origSettings.context || requestSettings,
326
+ newMock = null;
327
+
328
+
329
+ // If the response handler on the moock is a function, call it
330
+ if ( mockHandler.response && $.isFunction(mockHandler.response) ) {
331
+ mockHandler.response(origSettings);
332
+ } else {
333
+
334
+ // Evaluate the responseText javascript in a global context
335
+ if( typeof mockHandler.responseText === 'object' ) {
336
+ $.globalEval( '(' + JSON.stringify( mockHandler.responseText ) + ')');
337
+ } else {
338
+ $.globalEval( '(' + mockHandler.responseText + ')');
339
+ }
340
+ }
341
+
342
+ // Successful response
343
+ jsonpSuccess( requestSettings, callbackContext, mockHandler );
344
+ jsonpComplete( requestSettings, callbackContext, mockHandler );
345
+
346
+ // If we are running under jQuery 1.5+, return a deferred object
347
+ if($.Deferred){
348
+ newMock = new $.Deferred();
349
+ if(typeof mockHandler.responseText == "object"){
350
+ newMock.resolveWith( callbackContext, [mockHandler.responseText] );
351
+ }
352
+ else{
353
+ newMock.resolveWith( callbackContext, [$.parseJSON( mockHandler.responseText )] );
354
+ }
355
+ }
356
+ return newMock;
357
+ }
358
+
359
+
360
+ // Create the required JSONP callback function for the request
361
+ function createJsonpCallback( requestSettings, mockHandler, origSettings ) {
362
+ var callbackContext = origSettings && origSettings.context || requestSettings;
363
+ var jsonp = requestSettings.jsonpCallback || ("jsonp" + jsc++);
364
+
365
+ // Replace the =? sequence both in the query string and the data
366
+ if ( requestSettings.data ) {
367
+ requestSettings.data = (requestSettings.data + "").replace(CALLBACK_REGEX, "=" + jsonp + "$1");
368
+ }
369
+
370
+ requestSettings.url = requestSettings.url.replace(CALLBACK_REGEX, "=" + jsonp + "$1");
371
+
372
+
373
+ // Handle JSONP-style loading
374
+ window[ jsonp ] = window[ jsonp ] || function( tmp ) {
375
+ data = tmp;
376
+ jsonpSuccess( requestSettings, callbackContext, mockHandler );
377
+ jsonpComplete( requestSettings, callbackContext, mockHandler );
378
+ // Garbage collect
379
+ window[ jsonp ] = undefined;
380
+
381
+ try {
382
+ delete window[ jsonp ];
383
+ } catch(e) {}
384
+
385
+ if ( head ) {
386
+ head.removeChild( script );
387
+ }
388
+ };
389
+ }
390
+
391
+ // The JSONP request was successful
392
+ function jsonpSuccess(requestSettings, callbackContext, mockHandler) {
393
+ // If a local callback was specified, fire it and pass it the data
394
+ if ( requestSettings.success ) {
395
+ requestSettings.success.call( callbackContext, mockHandler.responseText || "", status, {} );
396
+ }
397
+
398
+ // Fire the global callback
399
+ if ( requestSettings.global ) {
400
+ trigger(requestSettings, "ajaxSuccess", [{}, requestSettings] );
401
+ }
402
+ }
403
+
404
+ // The JSONP request was completed
405
+ function jsonpComplete(requestSettings, callbackContext) {
406
+ // Process result
407
+ if ( requestSettings.complete ) {
408
+ requestSettings.complete.call( callbackContext, {} , status );
409
+ }
410
+
411
+ // The request was completed
412
+ if ( requestSettings.global ) {
413
+ trigger( "ajaxComplete", [{}, requestSettings] );
414
+ }
415
+
416
+ // Handle the global AJAX counter
417
+ if ( requestSettings.global && ! --$.active ) {
418
+ $.event.trigger( "ajaxStop" );
419
+ }
420
+ }
421
+
422
+
423
+ // The core $.ajax replacement.
424
+ function handleAjax( url, origSettings ) {
425
+ var mockRequest, requestSettings, mockHandler;
426
+ // console.log('handleAjax', url)
427
+ // If url is an object, simulate pre-1.5 signature
428
+ if ( typeof url === "object" ) {
429
+ origSettings = url;
430
+ url = undefined;
431
+ } else {
432
+ // work around to support 1.5 signature
433
+ origSettings.url = url;
434
+ }
435
+
436
+ // Extend the original settings for the request
437
+ requestSettings = $.extend(true, {}, $.ajaxSettings, origSettings);
438
+
439
+ // Iterate over our mock handlers (in registration order) until we find
440
+ // one that is willing to intercept the request
441
+ for(var k = 0; k < mockHandlers.length; k++) {
442
+ if ( !mockHandlers[k] ) {
443
+ continue;
444
+ }
445
+
446
+ mockHandler = getMockForRequest( mockHandlers[k], requestSettings );
447
+ if(!mockHandler) {
448
+ // No valid mock found for this request
449
+ continue;
450
+ }
451
+
452
+ mockedAjaxCalls.push(requestSettings);
453
+
454
+ // If logging is enabled, log the mock to the console
455
+ $.mockjaxSettings.log( mockHandler, requestSettings );
456
+
457
+
458
+ if ( requestSettings.dataType === "jsonp" ) {
459
+ if ((mockRequest = processJsonpMock( requestSettings, mockHandler, origSettings ))) {
460
+ // This mock will handle the JSONP request
461
+ return mockRequest;
462
+ }
463
+ }
464
+
465
+
466
+ // Removed to fix #54 - keep the mocking data object intact
467
+ //mockHandler.data = requestSettings.data;
468
+
469
+ mockHandler.cache = requestSettings.cache;
470
+ mockHandler.timeout = requestSettings.timeout;
471
+ mockHandler.global = requestSettings.global;
472
+
473
+ copyUrlParameters(mockHandler, origSettings);
474
+
475
+ (function(mockHandler, requestSettings, origSettings, origHandler) {
476
+ mockRequest = _ajax.call($, $.extend(true, {}, origSettings, {
477
+ // Mock the XHR object
478
+ xhr: function() { return xhr( mockHandler, requestSettings, origSettings, origHandler ); }
479
+ }));
480
+ })(mockHandler, requestSettings, origSettings, mockHandlers[k]);
481
+
482
+ return mockRequest;
483
+ }
484
+
485
+ // We don't have a mock request
486
+ if($.mockjaxSettings.throwUnmocked === true) {
487
+ throw('AJAX not mocked: ' + origSettings.url);
488
+ }
489
+ else { // trigger a normal request
490
+ return _ajax.apply($, [origSettings]);
491
+ }
492
+ }
493
+
494
+ /**
495
+ * Copies URL parameter values if they were captured by a regular expression
496
+ * @param {Object} mockHandler
497
+ * @param {Object} origSettings
498
+ */
499
+ function copyUrlParameters(mockHandler, origSettings) {
500
+ //parameters aren't captured if the URL isn't a RegExp
501
+ if (!(mockHandler.url instanceof RegExp)) {
502
+ return;
503
+ }
504
+ //if no URL params were defined on the handler, don't attempt a capture
505
+ if (!mockHandler.hasOwnProperty('urlParams')) {
506
+ return;
507
+ }
508
+ var captures = mockHandler.url.exec(origSettings.url);
509
+ //the whole RegExp match is always the first value in the capture results
510
+ if (captures.length === 1) {
511
+ return;
512
+ }
513
+ captures.shift();
514
+ //use handler params as keys and capture resuts as values
515
+ var i = 0,
516
+ capturesLength = captures.length,
517
+ paramsLength = mockHandler.urlParams.length,
518
+ //in case the number of params specified is less than actual captures
519
+ maxIterations = Math.min(capturesLength, paramsLength),
520
+ paramValues = {};
521
+ for (i; i < maxIterations; i++) {
522
+ var key = mockHandler.urlParams[i];
523
+ paramValues[key] = captures[i];
524
+ }
525
+ origSettings.urlParams = paramValues;
526
+ }
527
+
528
+
529
+ // Public
530
+
531
+ $.extend({
532
+ ajax: handleAjax
533
+ });
534
+
535
+ $.mockjaxSettings = {
536
+ //url: null,
537
+ //type: 'GET',
538
+ log: function( mockHandler, requestSettings ) {
539
+ if ( mockHandler.logging === false ||
540
+ ( typeof mockHandler.logging === 'undefined' && $.mockjaxSettings.logging === false ) ) {
541
+ return;
542
+ }
543
+ if ( window.console && console.log ) {
544
+ var message = 'MOCK ' + requestSettings.type.toUpperCase() + ': ' + requestSettings.url;
545
+ var request = $.extend({}, requestSettings);
546
+
547
+ if (typeof console.log === 'function') {
548
+ console.log(message, request);
549
+ } else {
550
+ try {
551
+ console.log( message + ' ' + JSON.stringify(request) );
552
+ } catch (e) {
553
+ console.log(message);
554
+ }
555
+ }
556
+ }
557
+ },
558
+ logging: true,
559
+ status: 200,
560
+ statusText: "OK",
561
+ responseTime: 500,
562
+ isTimeout: false,
563
+ throwUnmocked: false,
564
+ contentType: 'text/plain',
565
+ response: '',
566
+ responseText: '',
567
+ responseXML: '',
568
+ proxy: '',
569
+ proxyType: 'GET',
570
+
571
+ lastModified: null,
572
+ etag: '',
573
+ headers: {
574
+ etag: 'IJF@H#@923uf8023hFO@I#H#',
575
+ 'content-type' : 'text/plain'
576
+ }
577
+ };
578
+
579
+ $.mockjax = function(settings) {
580
+ var i = mockHandlers.length;
581
+ mockHandlers[i] = settings;
582
+ return i;
583
+ };
584
+ $.mockjaxClear = function(i) {
585
+ if ( arguments.length == 1 ) {
586
+ mockHandlers[i] = null;
587
+ } else {
588
+ mockHandlers = [];
589
+ }
590
+ mockedAjaxCalls = [];
591
+ };
592
+ $.mockjax.handler = function(i) {
593
+ if ( arguments.length == 1 ) {
594
+ return mockHandlers[i];
595
+ }
596
+ };
597
+ $.mockjax.mockedAjaxCalls = function() {
598
+ return mockedAjaxCalls;
599
+ };
600
+ })(jQuery);