Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

updated gallery-model-relate to work with yui 3.5 (attribute state ob…

…ject flip flopped key/value order in 3.5)
  • Loading branch information...
commit 179163bbb5d4b5ac1d3a86e82be29a77179a8ecf 1 parent c5c9180
Lee Shepherd authored
15 build/gallery-model-relate/gallery-model-relate-debug.js
View
@@ -1127,10 +1127,19 @@ ModelRelate.prototype = {
@private
**/
_destroyRelationships: function() {
- var relationships = this._state.data[RELS];
+ var state = this._state.data;
+
+ // check each object in the state data for a
+ // relationship property. if it has one, remove
+ // that relationship
+ Y.each(state, function(o, n) {
+ var relName = o[RELS];
+
+ if (relName) {
+ console.log('removing relationship', relName);
+ this.removeRelationship(relName);
+ }
- Y.each(relationships, function(name) {
- this.removeRelationship(name);
}, this);
},
2  build/gallery-model-relate/gallery-model-relate-min.js
View
@@ -1,2 +1,2 @@
YUI.add("gallery-model-relate",function(g){var h={type:"toMany",_initRelated:function(){var i=this;i.related=new i.listType({model:i.relatedModel});i._handles.push(i.related.on("remove",i._onRelatedRemove,i));i._refreshRelationship();},_destroyRelated:function(){this.related.destroy();},_setRelated:function(k){var j=this.related,i=j.isEmpty()?"add":"reset";j[i](k);},_setRelatedAttr:function(j,k,i){this.related.each(function(l){l.set(j,k,i);});},_afterStoreAdd:function(k){var i=this,j=k.model;if(i._checkRelationship(j)){i.related.add(j,k);i.fire("add",k);}},_afterStoreRemove:function(k){var i=this,j=k.model;if(i.related.indexOf(j)!==-1){i.related.remove(j,k);i.fire("remove",k);}},_afterRelatedKeyChange:function(i){i.model=i.target;if(i.src==="create"){return;}else{if(this.related.indexOf(i.model)!==-1){i.unregister=true;this._afterStoreRemove(i);}else{this._afterStoreAdd(i);}}},_onRelatedRemove:function(i){if(i.unregister||i["delete"]){}else{i.preventDefault();}}};var b={type:"toOne",_initRelated:function(){this._refreshRelationship();},_setRelated:function(k){var j=this,i;k=g.Array(k);i=k[0]||null;if(j.related){this.fire("remove",{model:j.related});}j.related=i;if(j.related){this.fire("add",{model:j.related});}},_setRelatedAttr:function(j,k,i){this.related&&this.related.set(j,k,i);},_afterStoreAdd:function(k){var i=this,j=k.model;if(!i.related&&i._checkRelationship(j)){i._setRelated(j);}},_afterStoreRemove:function(k){var j=this,i=k.model;if(i===j.related){j._refreshRelationship();}},_afterRelatedKeyChange:function(i){i.model=i.target;if(i.src==="create"){return;}else{if(this.related===i.model){i.unregister=true;this._afterStoreRemove(i);}else{this._afterStoreAdd(i);}}}};var c=g.ModelStore;function e(j){var i=this;if(!c){g.error("Cannot create relationship. ModelStore not found.");}g.stamp(this);i.name=j.name;i.model=j.model;i.key=j.key||j.model.idAttribute||"id";i.relatedModel=c._getModelCtor(j.relatedModel);i.relatedKey=j.relatedKey||i.key;if(j.type==="toMany"){i.listType=j.listType||g.ModelList;g.mix(i,h,true);}else{if(j.type==="toOne"){g.mix(i,b,true);}else{g.error("Cannot create relationship. "+j.type+" is not a valid relationship type.");}}i.init();}e.toOne="toOne";e.toMany="toMany";e.prototype={type:null,related:null,init:function(j){var i=this;i._handles=[];i._storeList=c.getList(i.relatedModel);i._initRelated();i._initEvents();},destroy:function(){this._detachEvents();this._storeList=null;this._destroyRelated();this._related=null;},toString:function(){var i=this;return i.model.toString()+" "+i.type+" relationship "+i.name+"["+g.stamp(this,true)+"]";},_checkRelationship:function(i){return i.get(this.relatedKey)==this.model.get(this.key);},_destroyRelated:function(){},_detachEvents:function(){g.each(this._handles,function(i){i.detach();});this._handles=[];},_findRelated:function(j){var i=this;return g.Array.filter(i._storeList._items,i._checkRelationship,i);},_initEvents:function(){var j=this,k=j._handles,i={bubbles:true,emitFacade:true,prefix:"modelRelationship",preventable:false};this.publish("add",i);this.publish("remove",i);k.push(j.model.on(j.key+"Change",j._onKeyChange,j));k.push(j.model.after(j.key+"Change",j._afterKeyChange,j));k.push(j._storeList.after("*:"+j.relatedKey+"Change",j._afterRelatedKeyChange,j));k.push(j._storeList.on("error",function(l){}));k.push(j._storeList.after("add",j._afterStoreAdd,j));k.push(j._storeList.after("remove",j._afterStoreRemove,j));},_initRelated:function(){},_refreshRelationship:function(i){this._setRelated(this._findRelated());},_setRelated:function(i){},_setRelatedAttr:function(j,k,i){},_afterKeyChange:function(i){if(i.src==="create"){this._setRelatedAttr(i.attrName,i.newVal,{src:"create",silent:true});}else{this._refreshRelationship();}},_afterStoreAdd:function(i){},_afterStoreRemove:function(i){},_afterRelatedKeyChange:function(i){},_onKeyChange:function(j){var i=j.target;if(j.attrName===i.idAttribute&&i.isNew()){j.src="create";}}};g.ModelRelationship=g.augment(e,g.EventTarget);var f="relationships",a="_rel_";function d(){}d.ATTRS={id:{valueFn:function(){return this.get("clientId");}},outputRelationships:{value:false}};d.prototype={_registered:false,initializer:function(j){var i=this,k=i._aggregateRelationships();j=j||{};i._modelRelateHandles=[g.Do.before(i._doBeforeDestroy,i,"destroy",i),g.Do.after(i._doAfterGetAttrs,i,"getAttrs",i)];g.each(k,function(l){g.each(l,i._addRelationshipAttr,i);});i.after("initializedChange",function(l){if(j.register!==false){i.register();}});},destructor:function(){var i=this._modelRelateHandles;g.each(i,function(j){j.detach();});this._modelRelateHandles=null;this._destroyRelationships();},addRelationship:function(j,i){this._addRelationshipAttr(i,j);return this;},getRelated:function(j){var i=this.getRelationship(j);return i&&i.related;},getRelationship:function(i){return this.get(this._relName(i));},isNew:function(){return this.get("clientId")===this.get("id");},isRegistered:function(){return this._registered;},register:function(){if(!c){}else{if(this.isRegistered()){}else{this._registered=(c.registerModel(this)===this);}}return this;},removeRelationship:function(l){var k=this,i=k.getRelationship(l),j=k._relName(l);if(i){i.destroy();}k.removeAttr(j);k._state.remove(j,f);return k;},toString:function(){return this.name+"["+this.get("id")+":"+g.stamp(this,true)+"]";},unregister:function(){if(!c){}else{if(!this.isRegistered()){}else{this._registered=(c.unregisterModel(this)===this);}}this._destroyRelationships();return this;},_addRelationshipAttr:function(l,k){var j=this,i=j._relName(k),m={};m.readOnly=true;m.lazyAdd=true;m.setter=function(n){return new g.ModelRelationship(n);};m.value=g.merge(l,{name:k,model:this});j.addAttr(i,m,true);if(j._state.get(i,"added")){j._state.add(i,f,k);}},_aggregateRelationships:function(){var j=this.constructor,i=[];while(j){if(j.RELATIONSHIPS){i[i.length]=j.RELATIONSHIPS;}j=j.superclass?j.superclass.constructor:null;}return i;},_doAfterGetAttrs:function(){var i=this._state,j=g.Do.currentRetVal;
-if(!this.get("outputRelationships")){g.each(j,function(m,k,l){if(i.get(k,f)){delete l[k];}});}delete j.outputRelationships;return new g.Do.AlterReturn("removed relationship meta from getAttrs return",j);},_doBeforeDestroy:function(i,k){var j;if(typeof i==="function"){k=i;i={};}if(i&&(i.unregister||i["delete"])){this.deleted=true;j=g.bind(function(l){if(l){this.deleted=false;}else{this._destroyRelationships();}k&&k.apply(null,arguments);},this);return new g.Do.AlterArgs(this.toString()+" deleted, modifying callback to destroy model relationships",[i,j]);}},_destroyRelationships:function(){var i=this._state.data[f];g.each(i,function(j){this.removeRelationship(j);},this);},_relName:function(i){return a+i;}};g.ModelRelate=d;},"@VERSION@",{requires:["base","event-custom","array-extras","model-list","gallery-model-store"]});
+if(!this.get("outputRelationships")){g.each(j,function(m,k,l){if(i.get(k,f)){delete l[k];}});}delete j.outputRelationships;return new g.Do.AlterReturn("removed relationship meta from getAttrs return",j);},_doBeforeDestroy:function(i,k){var j;if(typeof i==="function"){k=i;i={};}if(i&&(i.unregister||i["delete"])){this.deleted=true;j=g.bind(function(l){if(l){this.deleted=false;}else{this._destroyRelationships();}k&&k.apply(null,arguments);},this);return new g.Do.AlterArgs(this.toString()+" deleted, modifying callback to destroy model relationships",[i,j]);}},_destroyRelationships:function(){var i=this._state.data;g.each(i,function(k,l){var j=k[f];if(j){console.log("removing relationship",j);this.removeRelationship(j);}},this);},_relName:function(i){return a+i;}};g.ModelRelate=d;},"@VERSION@",{requires:["base","event-custom","array-extras","model-list","gallery-model-store"]});
15 build/gallery-model-relate/gallery-model-relate.js
View
@@ -1109,10 +1109,19 @@ ModelRelate.prototype = {
@private
**/
_destroyRelationships: function() {
- var relationships = this._state.data[RELS];
+ var state = this._state.data;
+
+ // check each object in the state data for a
+ // relationship property. if it has one, remove
+ // that relationship
+ Y.each(state, function(o, n) {
+ var relName = o[RELS];
+
+ if (relName) {
+ console.log('removing relationship', relName);
+ this.removeRelationship(relName);
+ }
- Y.each(relationships, function(name) {
- this.removeRelationship(name);
}, this);
},
15 src/gallery-model-relate/js/model-relate.js
View
@@ -449,10 +449,19 @@ ModelRelate.prototype = {
@private
**/
_destroyRelationships: function() {
- var relationships = this._state.data[RELS];
+ var state = this._state.data;
+
+ // check each object in the state data for a
+ // relationship property. if it has one, remove
+ // that relationship
+ Y.each(state, function(o, n) {
+ var relName = o[RELS];
+
+ if (relName) {
+ console.log('removing relationship', relName);
+ this.removeRelationship(relName);
+ }
- Y.each(relationships, function(name) {
- this.removeRelationship(name);
}, this);
},
280 src/gallery-model-relate/tests/model-relate-tests.js
View
@@ -0,0 +1,280 @@
+YUI.add('model-relate-tests', function(Y) {
+ var ArrayAssert = Y.ArrayAssert,
+ Assert = Y.Assert,
+ ObjectAssert = Y.ObjectAssert,
+
+ suite,
+ relatedModelSuite;
+
+ // -- Global Suite -------------------------------------------------------------
+ suite = new Y.Test.Suite('Model Relationships');
+
+ // -- RelatedModel Extension ----------------------------------------------------------
+ relatedModelSuite = new Y.Test.Suite('RelatedModel extension');
+
+ // -- RelatedModel Extension: Lifecycle -------------------------------------------------------
+ relatedModelSuite.add(new Y.Test.Case({
+ name: 'Lifecycle',
+
+ setUp: function () {
+ Y.ParentModel = Y.Base.create('parentModel', Y.Model, [Y.ModelRelate], {}, {
+ ATTRS: {
+ childId: {}
+ },
+
+ RELATIONSHIPS: {
+ children: {
+ type: 'toMany',
+ key: 'id',
+ relatedModel: 'ChildModel',
+ relatedKey: 'parentId'
+ }
+ }
+ });
+
+ Y.ChildModel = Y.Base.create('childModel', Y.Model, [Y.ModelRelate], {}, {
+ ATTRS: {
+ parentId: {}
+ },
+
+ RELATIONSHIPS: {
+ parents: {
+ type: 'toOne',
+ key: 'parentId',
+ relatedModel: 'ParentModel',
+ relatedKey: 'id'
+ }
+ }
+ });
+
+ this.parentModel = new Y.ParentModel({id: 1, childId: 1});
+
+ this.childList = new Y.ModelList({model: Y.ChildModel});
+
+ this.childList.add([
+ {id: 1, parentId: 1},
+ {id: 2, parentId: 2},
+ {id: 3, parentId: 3}
+ ]);
+ },
+
+ tearDown: function () {
+ Y.ModelStore.unregisterAll();
+ delete Y.ParentModel;
+ delete Y.ChildModel;
+ delete this.parentModel;
+ delete this.childlist;
+ },
+
+ 'test RelatedModel Methods': function () {
+ var pm = this.parentModel,
+ cm = this.childList.item(0);
+
+ Assert.isFunction(pm.addRelationship);
+ Assert.isFunction(pm.removeRelationship);
+ Assert.isFunction(pm.getRelated);
+ Assert.isFunction(cm.addRelationship);
+ Assert.isFunction(cm.removeRelationship);
+ Assert.isFunction(cm.getRelated);
+ },
+
+ 'test RelatedModel Properties': function () {
+ var pm = this.parentModel;
+
+ Assert.areSame(pm._state.get('_rel_children', 'relationships'), 'children');
+ },
+
+ 'test Destroy Model': function () {
+ var pm = this.parentModel.destroy();
+
+ Assert.isUndefined(pm._state.get('_rel_children', 'relationships'));
+ },
+
+ 'test getAttrs Model': function () {
+ var pm = this.parentModel,
+ attrs;
+
+ attrs = pm.getAttrs();
+
+ Assert.isUndefined(attrs['_rel_children']);
+
+ pm.set('outputRelationships', true);
+
+ attrs = pm.getAttrs();
+
+ Assert.isObject(attrs['_rel_children']);
+ },
+
+ 'test toJSON Model': function () {
+ var pm = this.parentModel,
+ attrs;
+
+ attrs = pm.toJSON();
+
+ Assert.isUndefined(attrs['_rel_children']);
+
+ pm.set('outputRelationships', true);
+
+ attrs = pm.toJSON();
+
+ Assert.isObject(attrs['_rel_children']);
+ }
+
+ }));
+
+
+ // -- RelatedModel Extension: Relationships -------------------------------------------------------
+ relatedModelSuite.add(new Y.Test.Case({
+ name: 'Relationships',
+
+ setUp: function () {
+ Y.ParentModel = Y.Base.create('parentModel', Y.Model, [Y.ModelRelate], {}, {
+ ATTRS: {
+ childId: {}
+ },
+
+ RELATIONSHIPS: {
+ children: {
+ type: 'toMany',
+ key: 'id',
+ relatedModel: 'ChildModel',
+ relatedKey: 'parentId'
+ }
+ }
+ });
+
+ Y.ChildModel = Y.Base.create('childModel', Y.Model, [Y.ModelRelate], {}, {
+ ATTRS: {
+ parentId: {}
+ },
+
+ RELATIONSHIPS: {
+ parent: {
+ type: 'toOne',
+ key: 'parentId',
+ relatedModel: 'ParentModel',
+ relatedKey: 'id'
+ }
+ }
+ });
+
+ this.parentModel = new Y.ParentModel({id: 1, childId: 1});
+
+ this.childList = new Y.ModelList({model: Y.ChildModel});
+
+ this.childList.add([
+ {id: 1, parentId: 1},
+ {id: 2, parentId: 2},
+ {id: 3, parentId: 3}
+ ]);
+ },
+
+ tearDown: function () {
+ Y.ModelStore.unregisterAll();
+ delete Y.ParentModel;
+ delete Y.ChildModel;
+ delete this.parentModel;
+ delete this.childlist;
+ },
+
+ 'test toMany Relationship at init': function () {
+ var children = this.parentModel.getRelated('children');
+
+ Assert.isInstanceOf(Y.ModelList, children);
+ Assert.areSame(1, children.size());
+ Assert.areSame(this.childList.item(0), children.item(0));
+ },
+
+ 'test toOne Relationship at init': function () {
+ var parent = this.childList.item(0).getRelated('parent');
+
+ Assert.isInstanceOf(Y.ParentModel, parent);
+ Assert.areSame(this.parentModel, parent);
+
+ Assert.isNull(this.childList.item(1).getRelated('parent'));
+ Assert.isNull(this.childList.item(2).getRelated('parent'));
+ },
+
+ 'test addRelationship method': function() {
+ this.parentModel.addRelationship('child', {
+ type: 'toOne',
+ key: 'childId',
+ relatedModel: 'ChildModel',
+ relatedKey: 'id'
+ });
+
+ Assert.areSame(this.childList.item(0), this.parentModel.getRelated('child'));
+ },
+
+ 'test removeRelationship method': function() {
+ this.parentModel.removeRelationship('children');
+
+ Assert.isUndefined(this.parentModel.getRelated('children'));
+ },
+
+ 'test extending relatedModel': function() {
+ var Parent2 = Y.Base.create('parent2', Y.ParentModel, [], {}, {
+ RELATIONSHIPS: {
+ child: {
+ type: 'toOne',
+ key: 'childId',
+ relatedModel: 'ChildModel',
+ relatedKey: 'id'
+ }
+ }
+ }),
+
+ parent2 = new Parent2({id: 2, childId: 2});
+
+ Assert.isInstanceOf(Y.ModelRelationship, parent2.getRelationship('children'), 'parent2 should have a children relationship');
+ Assert.isInstanceOf(Y.ModelList, parent2.getRelated('children'));
+ Assert.isInstanceOf(Y.ModelRelationship, parent2.getRelationship('child'), 'parent2 should have a child relationship');
+ Assert.areSame(this.childList.item(1), parent2.getRelated('child'));
+ },
+
+ 'test adding a related model should add it to a toMany relationship': function () {
+ var children = this.parentModel.getRelated('children'),
+ child;
+
+ this.childList.add({id: 4, parentId: 1});
+
+ Assert.areSame(2, children.size());
+ Assert.areSame(this.childList.item(3), children.item(1));
+
+ child = new Y.ChildModel({id: 5, parentId: 1});
+
+ Assert.areSame(3, children.size());
+ Assert.areSame(child, children.item(2));
+ },
+
+ 'test destroying a related model should not remove it from a toMany relationship': function () {
+ var children = this.parentModel.getRelated('children'),
+ child = this.childList.item(0);
+
+ child.destroy();
+
+ Assert.areSame(1, children.size());
+ },
+
+ 'test deleting a related model should remove it from a toMany relationship': function () {
+ var children = this.parentModel.getRelated('children'),
+ child = this.childList.item(0);
+
+ child.destroy({'delete': true});
+
+ Assert.areSame(0, children.size());
+ }
+ }));
+
+ suite.add(relatedModelSuite);
+
+ Y.Test.Runner.add(suite);
+}, '@VERSION@', {
+ requires: [
+ 'test',
+ 'model',
+ 'model-list',
+ 'gallery-model-store',
+ 'gallery-model-relate'
+ ]
+});
45 src/gallery-model-relate/tests/model-relate.html
View
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<title>Model Relate Tests</title>
+<body class="yui3-skin-sam">
+ <h1>Model Relate Tests</h1>
+ <div id="log"></div>
+</body>
+</html>
+<script src="../../../../yui3/build/yui/yui-min.js"></script>
+<script>
+YUI({
+ allowRollup: false,
+ filter: (window.location.search.match(/[?&]filter=([^&]+)/) || [])[1] || 'min',
+ modules: {
+ 'gallery-model-store' : {
+ fullpath: '../../../build/gallery-model-store/gallery-model-store-min.js',
+ requires: ['base', 'model', 'model-list']
+ },
+
+ 'gallery-model-relate' : {
+ fullpath: '../../../build/gallery-model-relate/gallery-model-relate-min.js',
+ requires: ['base', 'event-custom', 'array-extras', 'model-list', 'gallery-model-store']
+ },
+
+ 'model-relate-tests': {
+ fullpath: 'model-relate-tests.js',
+ requires: ['test', 'model', 'model-list', 'gallery-model-store', 'gallery-model-relate']
+ }
+ },
+ useBrowserConsole: false
+}).use(
+ 'model-relate-tests',
+ 'test-console',
+
+function (Y) {
+ new Y.Test.Console({
+ filters: {
+ pass: true,
+ fail: true
+ }
+ }).render('#log');
+
+ Y.Test.Runner.run();
+});
+</script>
430 src/gallery-model-relate/tests/model-relationship-tests.js
View
@@ -0,0 +1,430 @@
+YUI.add('model-relationship-tests', function(Y) {
+ var ArrayAssert = Y.ArrayAssert,
+ Assert = Y.Assert,
+ ObjectAssert = Y.ObjectAssert,
+
+ suite,
+ oneToManySuite,
+ oneToOneSuite,
+ relatedModelSuite;
+
+ // -- Global Suite -------------------------------------------------------------
+ suite = new Y.Test.Suite('Model Relationships');
+
+ // -- ModelRelation - One to Many Suite ----------------------------------------------------------
+ oneToManySuite = new Y.Test.Suite('One to Many Relationship');
+
+ // -- OneToMany: Lifecycle -------------------------------------------------------
+ oneToManySuite.add(new Y.Test.Case({
+ name: 'Lifecycle',
+
+ setUp: function () {
+ this.ParentModel = Y.Base.create('parentModel', Y.Model, [], {
+ initializer: function() {
+ Y.ModelStore.registerModel(this);
+ }
+ });
+
+ this.ChildModel = Y.Base.create('childModel', Y.Model, [], {
+ initializer: function() {
+ Y.ModelStore.registerModel(this);
+ }
+ }, {
+ ATTRS: {
+ parentId: {value: null}
+ }
+ });
+
+ this.parentModel = new this.ParentModel({id: 1});
+
+ this.childList = new Y.ModelList({model: this.ChildModel});
+
+ this.childList.add([
+ {id: 1, parentId: 1},
+ {id: 2, parentId: 1},
+ {id: 3, parentId: 2}
+ ]);
+
+ this.config = {
+ name: 'children',
+ type: Y.ModelRelationship.toMany,
+ model: this.parentModel,
+ key: 'id',
+ relatedModel: this.ChildModel,
+ relatedKey: 'parentId'
+ };
+
+ this.relation = new Y.ModelRelationship(this.config);
+ },
+
+ tearDown: function () {
+ Y.ModelStore.unregisterAll();
+ delete this.ParentModel;
+ delete this.ChildModel;
+ delete this.parentModel;
+ delete this.childlist;
+ delete this.config;
+ delete this.relation;
+ },
+
+ 'Relation should be instance of Relationship': function () {
+ Assert.isInstanceOf(Y.ModelRelationship, this.relation);
+ },
+
+ 'Relation.model should be the parentModel': function () {
+ Assert.areSame(this.parentModel, this.relation.model);
+ },
+
+ 'Relation.key should be id': function () {
+ Assert.areSame(this.config.key, this.relation.key);
+ },
+
+ 'Relation.relatedModel should be the childModel': function () {
+ Assert.areSame(this.ChildModel, this.relation.relatedModel);
+ },
+
+ 'Relation.relatedKey should be parentId': function () {
+ Assert.areSame(this.config.relatedKey, this.relation.relatedKey);
+ },
+
+ 'Relation.type should be toMany': function () {
+ Assert.areSame(Y.ModelRelationship.toMany, this.relation.type);
+ },
+
+ 'Relation.related should be a Y.ModelList': function () {
+ Assert.isInstanceOf(Y.ModelList, this.relation.related);
+ },
+
+ 'Relation.related should contain 2 models with parentId of parentModel': function () {
+ var relation = this.relation;
+
+ Assert.areSame(2, relation.related.size());
+
+ relation.related.each(function(model) {
+ Assert.areSame(relation.model.get(relation.key), model.get(relation.relatedKey));
+ }, this);
+ }
+ }));
+
+
+ // -- OneToMany: Events --------------------------------------------------------
+ oneToManySuite.add(new Y.Test.Case({
+ name: 'Events',
+
+ setUp: function () {
+ this.ParentModel = Y.Base.create('parentModel', Y.Model, [], {
+ initializer: function() {
+ Y.ModelStore.registerModel(this);
+ }
+ });
+
+ this.ChildModel = Y.Base.create('childModel', Y.Model, [], {
+ initializer: function() {
+ Y.ModelStore.registerModel(this);
+ }
+ }, {
+ ATTRS: {
+ parentId: {value: null}
+ }
+ });
+
+ this.parentModel = new this.ParentModel({id: 1});
+
+ this.childList = new Y.ModelList({model: this.ChildModel});
+
+ this.childList.add([
+ {id: 1, parentId: 1},
+ {id: 2, parentId: 1},
+ {id: 3, parentId: 2}
+ ]);
+
+ this.config = {
+ name: 'children',
+ type: Y.ModelRelationship.toMany,
+ model: this.parentModel,
+ key: 'id',
+ relatedModel: this.ChildModel,
+ relatedKey: 'parentId'
+ };
+
+ this.relation = new Y.ModelRelationship(this.config);
+ },
+
+ tearDown: function () {
+ Y.ModelStore.unregisterAll();
+ delete this.ParentModel;
+ delete this.ChildModel;
+ delete this.parentModel;
+ delete this.childlist;
+ delete this.config;
+ delete this.relation;
+ },
+
+
+ 'changing the key of the parent model should refresh the relationship': function () {
+ var relation = this.relation;
+
+ this.parentModel.set('id', 2);
+
+ Assert.areSame(1, relation.related.size());
+
+ relation.related.each(function(model) {
+ Assert.areSame(relation.model.get(relation.key), model.get(relation.relatedKey));
+ }, this);
+ },
+
+ 'adding a related model to the childList should add it to the relationship': function () {
+ var relation = this.relation;
+
+ this.childList.add({
+ name: 'childModel4',
+ id: 4,
+ parentId: 1
+ });
+
+ Assert.areSame(3, relation.related.size());
+
+ relation.related.each(function(model) {
+ Assert.areSame(relation.model.get(relation.key), model.get(relation.relatedKey));
+ }, this);
+ },
+
+ 'destroying a model in the childList should not remove it from the relationship': function () {
+ var relation = this.relation;
+
+ this.childList.getById(1).destroy();
+
+ Assert.areSame(2, relation.related.size());
+
+ relation.related.each(function(model) {
+ Assert.areSame(relation.model.get(relation.key), model.get(relation.relatedKey));
+ }, this);
+ },
+
+ 'deleting a model in the childList should remove it from the relationship': function () {
+ var relation = this.relation;
+
+ this.childList.getById(1).destroy({'delete': true});
+
+ Assert.areSame(1, relation.related.size());
+
+ relation.related.each(function(model) {
+ Assert.areSame(relation.model.get(relation.key), model.get(relation.relatedKey));
+ }, this);
+ },
+
+ 'changing the key on a related model should remove it from the relationship': function () {
+ var relation = this.relation;
+
+ this.childList.getById(1).set('parentId', 2);
+
+ Assert.areSame(1, relation.related.size());
+
+ relation.related.each(function(model) {
+ Assert.areSame(relation.model.get(relation.key), model.get(relation.relatedKey));
+ }, this);
+ },
+
+ 'changing the key on a non-related model should add it to the relationship': function () {
+ var relation = this.relation;
+
+ this.childList.getById(3).set('parentId', 1);
+
+ Assert.areSame(3, relation.related.size());
+
+ relation.related.each(function(model) {
+ Assert.areSame(relation.model.get(relation.key), model.get(relation.relatedKey));
+ }, this);
+ }
+
+ }));
+
+ // -- ModelRelation - One to One Suite ----------------------------------------------------------
+ oneToOneSuite = new Y.Test.Suite('One to One Relationship');
+
+ // -- OneToOne: Lifecycle -------------------------------------------------------
+ oneToOneSuite.add(new Y.Test.Case({
+ name: 'Lifecycle',
+
+ setUp: function () {
+ this.ParentModel = Y.Base.create('parentModel', Y.Model, [], {
+ initializer: function() {
+ Y.ModelStore.registerModel(this);
+ }
+ });
+
+ this.ChildModel = Y.Base.create('childModel', Y.Model, [], {
+ initializer: function() {
+ Y.ModelStore.registerModel(this);
+ }
+ }, {
+ ATTRS: {
+ parentId: {value: null}
+ }
+ });
+
+ this.parentModel = new this.ParentModel({id: 1});
+
+ this.childList = new Y.ModelList({model: this.ChildModel});
+
+ this.childList.add([
+ {id: 1, parentId: 1},
+ {id: 2, parentId: 2},
+ {id: 3, parentId: 3}
+ ]);
+
+ this.config = {
+ name: 'child',
+ type: Y.ModelRelationship.toOne,
+ model: this.parentModel,
+ key: 'id',
+ relatedModel: this.ChildModel,
+ relatedKey: 'parentId'
+ };
+
+ this.relation = new Y.ModelRelationship(this.config);
+ },
+
+ tearDown: function () {
+ Y.ModelStore.unregisterAll();
+ delete this.ParentModel;
+ delete this.ChildModel;
+ delete this.parentModel;
+ delete this.childlist;
+ delete this.config;
+ delete this.relation;
+ },
+
+ 'Relation should be instance of Relationship': function () {
+ Assert.isInstanceOf(Y.ModelRelationship, this.relation);
+ },
+
+ 'Relation.model should be the parentModel': function () {
+ Assert.areSame(this.parentModel, this.relation.model);
+ },
+
+ 'Relation.key should be id': function () {
+ Assert.areSame(this.config.key, this.relation.key);
+ },
+
+ 'Relation.relatedModel should be the childModel': function () {
+ Assert.areSame(this.ChildModel, this.relation.relatedModel);
+ },
+
+ 'Relation.relatedKey should be parentId': function () {
+ Assert.areSame(this.config.relatedKey, this.relation.relatedKey);
+ },
+
+ 'Relation.type should be toOne': function () {
+ Assert.areSame(Y.ModelRelationship.toOne, this.relation.type);
+ },
+
+ 'Relation.related should be a Y.Model': function () {
+ Assert.isInstanceOf(Y.Model, this.relation.related);
+ },
+
+ 'Relation.related should be the childModel with parentId = parentModel.id': function () {
+ var relation = this.relation;
+
+ Assert.areSame(this.childList.item(0), relation.related);
+ }
+ }));
+
+
+ // -- OneToOne: Events --------------------------------------------------------
+ oneToOneSuite.add(new Y.Test.Case({
+ name: 'Events',
+
+ setUp: function () {
+ this.ParentModel = Y.Base.create('parentModel', Y.Model, [], {
+ initializer: function() {
+ Y.ModelStore.registerModel(this);
+ }
+ });
+
+ this.ChildModel = Y.Base.create('childModel', Y.Model, [], {
+ initializer: function() {
+ Y.ModelStore.registerModel(this);
+ }
+ }, {
+ ATTRS: {
+ parentId: {value: null}
+ }
+ });
+
+ this.parentModel = new this.ParentModel({id: 1});
+
+ this.childList = new Y.ModelList({model: this.ChildModel});
+
+ this.childList.add([
+ {id: 1, parentId: 1},
+ {id: 2, parentId: 2},
+ {id: 3, parentId: 3}
+ ]);
+
+ this.config = {
+ name: 'child',
+ type: Y.ModelRelationship.toOne,
+ model: this.parentModel,
+ key: 'id',
+ relatedModel: this.ChildModel,
+ relatedKey: 'parentId'
+ };
+
+ this.relation = new Y.ModelRelationship(this.config);
+ },
+
+ tearDown: function () {
+ Y.ModelStore.unregisterAll();
+ delete this.ParentModel;
+ delete this.ChildModel;
+ delete this.parentModel;
+ delete this.childlist;
+ delete this.config;
+ delete this.relation;
+ },
+
+
+ 'changing the key of the parent model should refresh the relationship': function () {
+ var relation = this.relation;
+
+ this.parentModel.set('id', 2);
+
+ Assert.areSame(this.childList.item(1), relation.related);
+ },
+
+ 'changing the key on the related model should remove it from the relationship': function () {
+ var relation = this.relation;
+
+ this.childList.item(0).set('parentId', 2);
+
+ Assert.isNull(relation.related);
+ },
+
+ 'changing a key on a related model to match the relationship should add it to the relationship if the relationship doesnt currently have a match': function () {
+ var relation = this.relation;
+
+ this.childList.item(0).set('parentId', 2);
+
+ Assert.isNull(relation.related);
+
+ this.childList.item(1).set('parentId', 1);
+
+ Assert.areSame(this.childList.item(1), relation.related);
+ }
+ }));
+
+
+ suite.add(oneToManySuite);
+ suite.add(oneToOneSuite);
+
+ Y.Test.Runner.add(suite);
+}, '@VERSION@', {
+ requires: [
+ 'test',
+ 'model',
+ 'model-list',
+ 'gallery-model-store',
+ 'gallery-model-relate'
+ ]
+});
45 src/gallery-model-relate/tests/model-relationship.html
View
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<title>Model Relationship Tests</title>
+<body class="yui3-skin-sam">
+ <h1>Model Relationship Tests</h1>
+ <div id="log"></div>
+</body>
+</html>
+<script src="../../../../yui3/build/yui/yui-min.js"></script>
+<script>
+YUI({
+ allowRollup: false,
+ filter: (window.location.search.match(/[?&]filter=([^&]+)/) || [])[1] || 'min',
+ modules: {
+ 'gallery-model-store' : {
+ fullpath: '../../../build/gallery-model-store/gallery-model-store-min.js',
+ requires: ['base', 'model', 'model-list']
+ },
+
+ 'gallery-model-relate' : {
+ fullpath: '../../../build/gallery-model-relate/gallery-model-relate-min.js',
+ requires: ['base', 'event-custom', 'array-extras', 'model-list', 'gallery-model-store']
+ },
+
+ 'model-relationship-tests': {
+ fullpath: 'model-relationship-tests.js',
+ requires: ['test', 'model', 'model-list', 'gallery-model-store', 'gallery-model-relate']
+ }
+ },
+ useBrowserConsole: false
+}).use(
+ 'model-relationship-tests',
+ 'test-console',
+
+function (Y) {
+ new Y.Test.Console({
+ filters: {
+ pass: true,
+ fail: true
+ }
+ }).render('#log');
+
+ Y.Test.Runner.run();
+});
+</script>
Please sign in to comment.
Something went wrong with that request. Please try again.