From 56ced1e226c8dd419e06e94e236315f56a1fef27 Mon Sep 17 00:00:00 2001 From: megawac Date: Wed, 18 Dec 2013 02:22:12 -0500 Subject: [PATCH 1/5] Property setters can now return value Allow model property setters to return a value after processing so custom handling is not necessary. --- src/epitome-model.js | 8 ++++++-- test/tests/epitome-model-test.js | 17 ++++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/epitome-model.js b/src/epitome-model.js index 7994084..d5cb5c6 100644 --- a/src/epitome-model.js +++ b/src/epitome-model.js @@ -71,8 +71,12 @@ if (!key || typeof value === 'undefined') return this; // custom setter - see bit further down - if (this.properties[key] && this.properties[key]['set']) - return this.properties[key]['set'].call(this, value); + if (this.properties[key] && this.properties[key]['set']) { + value = this.properties[key]['set'].call(this, value);//if value is returned by setter proceed to set the new value normally + if(!value) { + return; + } + } // no change? this is crude and works for primitives. if (this._attributes[key] && isEqual(this._attributes[key], value)) diff --git a/test/tests/epitome-model-test.js b/test/tests/epitome-model-test.js index 069d3f2..3387cd2 100644 --- a/test/tests/epitome-model-test.js +++ b/test/tests/epitome-model-test.js @@ -224,7 +224,22 @@ buster.testCase('Basic Epitome model creation with initial data >', { }); this.model.empty(); - } + }, + + 'Expect model `set` with custom property setter to override value and continue setting if anything is returned >': function() { + var spy = this.spy(); + + this.model.properties = Object.merge({ + foo: { + set: function(val) { + return 'my ' + val; + } + } + }, this.model.properties); + + this.model.set('foo', 'bar'); + buster.assert.same(this.model.get('foo'), 'my bar'); + } }); From 70d58d1baa7dd448a86dbef97cd80dd13e2e4d73 Mon Sep 17 00:00:00 2001 From: megawac Date: Wed, 18 Dec 2013 02:29:22 -0500 Subject: [PATCH 2/5] Fix bad indentation :( --- src/epitome-model.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/epitome-model.js b/src/epitome-model.js index d5cb5c6..220913e 100644 --- a/src/epitome-model.js +++ b/src/epitome-model.js @@ -72,11 +72,11 @@ // custom setter - see bit further down if (this.properties[key] && this.properties[key]['set']) { - value = this.properties[key]['set'].call(this, value);//if value is returned by setter proceed to set the new value normally - if(!value) { - return; - } - } + value = this.properties[key]['set'].call(this, value);//if value is returned by setter proceed to set the new value normally + if(!value) { + return; + } + } // no change? this is crude and works for primitives. if (this._attributes[key] && isEqual(this._attributes[key], value)) @@ -127,8 +127,8 @@ unset: function(){ // can remove keys from model, passed on as multiple string arguments or an array of string keys var keys = Array.prototype.slice.apply(arguments), - obj = {}, - len = keys.length; + obj = {}, + len = keys.length; if (!len) return this; @@ -149,7 +149,7 @@ empty: function(){ // empty the model and fire change event var keys = Object.keys(this.toJSON()), - self = this; + self = this; // let the instance know. this.trigger('change', [keys]); From 7d8e04edc0846f212ea874a6314aae379c2406c5 Mon Sep 17 00:00:00 2001 From: megawac Date: Wed, 18 Dec 2013 02:43:00 -0500 Subject: [PATCH 3/5] Allow non truthy values to be returned by setter --- src/epitome-model.js | 9 +++--- test/tests/epitome-model-test.js | 55 ++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/epitome-model.js b/src/epitome-model.js index 220913e..9bbdb68 100644 --- a/src/epitome-model.js +++ b/src/epitome-model.js @@ -2,6 +2,7 @@ 'use strict'; // wrapper function for requirejs or normal object + var undef = 'undefined'; var wrap = function(isEqual, Events){ return new Class({ @@ -68,12 +69,12 @@ // private, real setter functions, not on prototype, see note above _set: function(key, value){ // needs to be bound the the instance. - if (!key || typeof value === 'undefined') return this; + if (!key || typeof value === undef) return this; // custom setter - see bit further down if (this.properties[key] && this.properties[key]['set']) { value = this.properties[key]['set'].call(this, value);//if value is returned by setter proceed to set the new value normally - if(!value) { + if(typeof value === undef) { return; } } @@ -121,7 +122,7 @@ } // else, return from attributes or return null when undefined. - return (key && typeof this._attributes[key] !== 'undefined') ? this._attributes[key] : null; + return (key && typeof this._attributes[key] !== undef) ? this._attributes[key] : null; }.overloadGetter(), unset: function(){ @@ -179,7 +180,7 @@ if (typeof define === 'function' && define.amd){ define(['./epitome-isequal', './epitome-events'], wrap); } - else if (typeof module !== 'undefined' && module.exports){ + else if (typeof module !== undef && module.exports){ require('mootools'); module.exports = wrap(require('./epitome-isequal'), require('./epitome-events')); } diff --git a/test/tests/epitome-model-test.js b/test/tests/epitome-model-test.js index 3387cd2..01b9b1e 100644 --- a/test/tests/epitome-model-test.js +++ b/test/tests/epitome-model-test.js @@ -226,20 +226,47 @@ buster.testCase('Basic Epitome model creation with initial data >', { this.model.empty(); }, - 'Expect model `set` with custom property setter to override value and continue setting if anything is returned >': function() { - var spy = this.spy(); - - this.model.properties = Object.merge({ - foo: { - set: function(val) { - return 'my ' + val; - } - } - }, this.model.properties); - - this.model.set('foo', 'bar'); - buster.assert.same(this.model.get('foo'), 'my bar'); - } + 'Expect model `set` with custom property setter to override value and continue setting if anything is returned >': function() { + var spy = this.spy(); + + var pre = this.model.get('foo'); + this.model.properties = Object.merge(this.model.properties, { + foo: { + set: function(val) { + //do nothing so dont change + } + } + }); + + this.model.set('foo', 'something'); + buster.assert.same(this.model.get('foo'), pre); + + this.model.properties = Object.merge(this.model.properties, { + foo: { + set: function(val) { + return 'my ' + val; + } + } + }); + + this.model.set('foo', 'bar'); + buster.assert.same(this.model.get('foo'), 'my bar'); + }, + + 'Expect returning a non truthy value (besides undef) to set the property >': function() { + var spy = this.spy(); + + this.model.properties = Object.merge({ + foo: { + set: function(val) { + return false; + } + } + }, this.model.properties); + + this.model.set('foo', 'bar'); + buster.assert.same(this.model.get('foo'), false); + } }); From 34368b3bf36c69033468d5a3182c2d5cd12826fb Mon Sep 17 00:00:00 2001 From: megawac Date: Wed, 18 Dec 2013 02:47:18 -0500 Subject: [PATCH 4/5] Property setters can now return value Rollback- recommit to bundle changes... Allow model property setters to return a value after processing so custom handling is not necessary. --- src/epitome-model.js | 15 ++++++++---- test/tests/epitome-model-test.js | 42 ++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/epitome-model.js b/src/epitome-model.js index 7994084..b6ce226 100644 --- a/src/epitome-model.js +++ b/src/epitome-model.js @@ -2,6 +2,7 @@ 'use strict'; // wrapper function for requirejs or normal object + var undef = 'undefined'; var wrap = function(isEqual, Events){ return new Class({ @@ -68,11 +69,15 @@ // private, real setter functions, not on prototype, see note above _set: function(key, value){ // needs to be bound the the instance. - if (!key || typeof value === 'undefined') return this; + if (!key || typeof value === undef) return this; // custom setter - see bit further down - if (this.properties[key] && this.properties[key]['set']) - return this.properties[key]['set'].call(this, value); + if (this.properties[key] && this.properties[key]['set']) { + value = this.properties[key]['set'].call(this, value);//if value is returned by setter proceed to set the new value normally + if(typeof value === undef) { + return; + } + } // no change? this is crude and works for primitives. if (this._attributes[key] && isEqual(this._attributes[key], value)) @@ -117,7 +122,7 @@ } // else, return from attributes or return null when undefined. - return (key && typeof this._attributes[key] !== 'undefined') ? this._attributes[key] : null; + return (key && typeof this._attributes[key] !== undef) ? this._attributes[key] : null; }.overloadGetter(), unset: function(){ @@ -175,7 +180,7 @@ if (typeof define === 'function' && define.amd){ define(['./epitome-isequal', './epitome-events'], wrap); } - else if (typeof module !== 'undefined' && module.exports){ + else if (typeof module !== undef && module.exports){ require('mootools'); module.exports = wrap(require('./epitome-isequal'), require('./epitome-events')); } diff --git a/test/tests/epitome-model-test.js b/test/tests/epitome-model-test.js index 069d3f2..01b9b1e 100644 --- a/test/tests/epitome-model-test.js +++ b/test/tests/epitome-model-test.js @@ -224,6 +224,48 @@ buster.testCase('Basic Epitome model creation with initial data >', { }); this.model.empty(); + }, + + 'Expect model `set` with custom property setter to override value and continue setting if anything is returned >': function() { + var spy = this.spy(); + + var pre = this.model.get('foo'); + this.model.properties = Object.merge(this.model.properties, { + foo: { + set: function(val) { + //do nothing so dont change + } + } + }); + + this.model.set('foo', 'something'); + buster.assert.same(this.model.get('foo'), pre); + + this.model.properties = Object.merge(this.model.properties, { + foo: { + set: function(val) { + return 'my ' + val; + } + } + }); + + this.model.set('foo', 'bar'); + buster.assert.same(this.model.get('foo'), 'my bar'); + }, + + 'Expect returning a non truthy value (besides undef) to set the property >': function() { + var spy = this.spy(); + + this.model.properties = Object.merge({ + foo: { + set: function(val) { + return false; + } + } + }, this.model.properties); + + this.model.set('foo', 'bar'); + buster.assert.same(this.model.get('foo'), false); } }); From 7fe93d0175a1d64e587fe7d770609f02fccd209b Mon Sep 17 00:00:00 2001 From: megawac Date: Wed, 18 Dec 2013 02:54:12 -0500 Subject: [PATCH 5/5] reindentation... --- src/epitome-model.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/epitome-model.js b/src/epitome-model.js index 9bbdb68..b6ce226 100644 --- a/src/epitome-model.js +++ b/src/epitome-model.js @@ -128,8 +128,8 @@ unset: function(){ // can remove keys from model, passed on as multiple string arguments or an array of string keys var keys = Array.prototype.slice.apply(arguments), - obj = {}, - len = keys.length; + obj = {}, + len = keys.length; if (!len) return this; @@ -150,7 +150,7 @@ empty: function(){ // empty the model and fire change event var keys = Object.keys(this.toJSON()), - self = this; + self = this; // let the instance know. this.trigger('change', [keys]);