backbone-base-view
Advanced tools
Comparing version 2.1.0 to 3.0.0
{ | ||
"name": "backboneBaseView", | ||
"version": "2.1.0", | ||
"version": "3.0.0", | ||
"description": "Baseview is a extended backbone view with convenient methods for manipulating subviews and events.", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/dbrekalo/backbone-base-view", |
@@ -14,2 +14,25 @@ (function(root, factory) { | ||
var simpleTypes = [String, Number, Boolean, Function, Object, Array]; | ||
var simpleTypeNames = ['string', 'number', 'boolean', 'function', 'object', 'array']; | ||
function validateType(value, Type, errorCallback) { | ||
var simpleTypeIndex = simpleTypes.indexOf(Type); | ||
var isComplexType = simpleTypeIndex < 0; | ||
var typeName = simpleTypeIndex >= 0 && simpleTypeNames[simpleTypeIndex]; | ||
if (isComplexType) { | ||
if (!(value instanceof Type)) { | ||
errorCallback(); | ||
} | ||
} else { | ||
if (typeName === 'array') { | ||
!_.isArray(value) && errorCallback(); | ||
} else if (typeof value !== typeName) { | ||
errorCallback(); | ||
} | ||
} | ||
} | ||
var variableInEventStringRE = /{{\s*(\S+)\s*}}/g; | ||
@@ -20,4 +43,5 @@ var specialSelectors = { | ||
}; | ||
var parseEventVariables = function(eventString, context) { | ||
function parseEventVariables(eventString, context) { | ||
return eventString.replace(variableInEventStringRE, function(match, namespace) { | ||
@@ -40,3 +64,3 @@ | ||
}; | ||
} | ||
@@ -67,3 +91,5 @@ var BaseView = Backbone.View.extend({ | ||
this.optionRules && _.each(this.optionRules, function(data, optionName) { | ||
ruleDefaults[optionName] = data.default; | ||
if ($.isPlainObject(data) && typeof data.default !== 'undefined') { | ||
ruleDefaults[optionName] = _.result(data, 'default'); | ||
} | ||
}); | ||
@@ -83,5 +109,5 @@ | ||
var errors = []; | ||
var errorMessages = []; | ||
_.each(rules, function(data, optionName) { | ||
_.each(rules, function(optionRules, optionName) { | ||
@@ -91,14 +117,16 @@ var optionValue = options[optionName]; | ||
if (data.required !== false || optionValueType !== 'undefined') { | ||
if (optionRules.required !== false || optionValueType !== 'undefined') { | ||
if (data.type && optionValueType !== data.type) { | ||
errors.push('Option "' + optionName +'" is ' + optionValueType + ', expected ' + data.type + '.'); | ||
} | ||
var userType = $.isPlainObject(optionRules) ? optionRules.type : optionRules; | ||
if (data.rule && !data.rule(optionValue)) { | ||
errors.push('Option "' + optionName +'" breaks defined rule.'); | ||
if (userType) { | ||
validateType(optionValue, userType, function() { | ||
errorMessages.push('Invalid type for option "' + optionName +'" ("' + optionValueType + '").'); | ||
}); | ||
} | ||
if (data.instanceOf && !(optionValue instanceof data.instanceOf)) { | ||
errors.push('Option "' + optionName +'" is not instance of defined constructor.'); | ||
if (optionRules.validator && !optionRules.validator(optionValue)) { | ||
errorMessages.push('Validation of option "' + optionName + '" failed.'); | ||
} | ||
@@ -110,6 +138,10 @@ | ||
if (errors.length) { | ||
throw new Error(errors.join(' ')); | ||
} else { | ||
return this; | ||
return this.handleValidateOptionsErrors(errorMessages); | ||
}, | ||
handleValidateOptionsErrors: function(errorMessages) { | ||
if (errorMessages.length) { | ||
throw new Error(errorMessages.join(' ')); | ||
} | ||
@@ -116,0 +148,0 @@ |
@@ -1,1 +0,1 @@ | ||
!function(e,i){"function"==typeof define&&define.amd?define(["jquery","backbone","underscore"],i):"object"==typeof module&&module.exports?module.exports=i(require("jquery"),require("backbone"),require("underscore")):e.BaseView=i(e.jQuery,e.Backbone,e._)}(this,function(e,i,t){var s=/{{\s*(\S+)\s*}}/g,n={window:window,document:window.document},o=function(e,i){return e.replace(s,function(e,t){var s=0===t.indexOf("this."),n=s?i:window,o=(s?t.slice(5):t).split(".");for(var r in o)if(void 0===(n=n[o[r]]))throw new Error("Undefined variable in event string");return n})},r=i.View.extend({constructor:function(e){this.assignOptions&&(this.writeOptions.apply(this,arguments),this.optionRules&&this.validateOptions(this.options,this.optionRules)),i.View.apply(this,arguments),this.events&&this.setupEvents()},delegatedEvents:!0,parseEventVariables:!0,assignOptions:!1,writeOptions:function(i){var s=t.result(this,"defaults"),n={};return this.optionRules&&t.each(this.optionRules,function(e,i){n[i]=e.default}),"deep"===this.assignOptions?this.options=e.extend(!0,{},s,n,i):this.options=e.extend({},s,n,i),this},validateOptions:function(e,i){var s=[];if(t.each(i,function(i,t){var n=e[t],o=typeof n;!1===i.required&&"undefined"===o||(i.type&&o!==i.type&&s.push('Option "'+t+'" is '+o+", expected "+i.type+"."),i.rule&&!i.rule(n)&&s.push('Option "'+t+'" breaks defined rule.'),!i.instanceOf||n instanceof i.instanceOf||s.push('Option "'+t+'" is not instance of defined constructor.'))}),s.length)throw new Error(s.join(" "));return this},setupEvents:function(i){var s=i||this.events,r="function"==typeof s?s.call(this):s,h=this;if(r){var d=this.ens=this.ens||"."+this.cid;t.each(r,function(i,t){h.parseEventVariables&&(t=o(t,h));var s=0===t.indexOf("one:"),r=(s?t.slice(4):t).split(" "),u=r[0]+d,c=r.slice(1).join(" "),f=h.$el;n[c]?(f=h["$"+c]=h["$"+c]||e(n[c]),c=void 0):h.delegatedEvents||((h.elementsWithBoundEvents=h.elementsWithBoundEvents||[]).push(f=f.find(c)),c=void 0),f[s?"one":"on"](u,c,function(){("function"==typeof i?i:h[i]).apply(h,arguments)})})}return this},addDismissListener:function(i,t){var s=this;if(!i)throw new Error("Dismiss listener name not speficied");return t=e.extend({$el:this.$el},t),this.$document=this.$document||e(document),this.ens=this.ens||"."+this.cid,this.dismissListeners=this.dismissListeners||{},this.dismissListeners[i]||(this.dismissListeners[i]=function(n){27!==n.keyCode&&(e(n.target).is(t.$el)||e.contains(t.$el.get(0),n.target))||s[i].call(s)},this.$document.on("click"+this.ens+" keyup"+this.ens,this.dismissListeners[i])),this},removeDismissListener:function(e){if(!e)throw new Error("Name of dismiss listener to remove not specified");return this.dismissListeners&&this.dismissListeners[e]&&(this.$document.off("click keyup",this.dismissListeners[e]),delete this.dismissListeners[e]),this},removeEvents:function(){var e=this.ens;return e&&(this.$el&&this.$el.off(e),this.$document&&this.$document.off(e),this.$window&&this.$window.off(e),this.elementsWithBoundEvents&&(t.each(this.elementsWithBoundEvents,function(i){i.off(e)}),delete this.elementsWithBoundEvents),delete this.dismissListeners),this},addView:function(e,i){return this.views=this.views||{},this.views[e.cid]=e,e.model&&(this.viewsWithModel=this.viewsWithModel||{},this.viewsWithModel[e.model.cid]=e),i&&(this.viewsGroups=this.viewsGroups||{},this.viewsGroups[i]=this.viewsGroups[i]||{},this.viewsGroups[i][e.cid]=e),this.listenToOnce(e,"afterRemove detachView",function(){delete this.views[e.cid],e.model&&this.viewsWithModel&&delete this.viewsWithModel[e.model.cid],i&&this.viewsGroups&&this.viewsGroups[i]&&delete this.viewsGroups[i][e.cid]}),e},getGroupViews:function(e){return this.viewsGroups&&this.viewsGroups[e]?t.values(this.viewsGroups[e]):[]},hasView:function(e){return this.views&&Boolean(this.views[e.cid])},detachView:function(){return this.trigger("detachView"),this},attachToView:function(e,i){return this.detachView(),e.addView(this,i),this},removeViews:function(e){return e?this.viewsGroups&&this.viewsGroups[e]&&(t.invoke(this.viewsGroups[e],"remove"),delete this.viewsGroups[e]):(this.views&&t.invoke(this.views,"remove"),delete this.views,delete this.viewsWithModel,delete this.viewsGroups),this},getViewByModel:function(e){return this.viewsWithModel&&this.viewsWithModel[e.cid]},removeViewByModel:function(e){return this.viewsWithModel&&this.viewsWithModel[e.cid]&&this.viewsWithModel[e.cid].remove(),this},addDeferred:function(e){return this.deferreds=this.deferreds||[],t.indexOf(this.deferreds,e)<0&&this.deferreds.push(e),e},abortDeferreds:function(){return this.deferreds&&t.each(this.deferreds,function(e){"object"==typeof e&&e.state&&"pending"===e.state()&&(e.abort?e.abort():e.reject())}),delete this.deferreds,this},when:function(i,s,n){t.each(i=t.isArray(i)?i:[i],function(e){this.addDeferred(e)},this);var o=e.when.apply(e,i);return s&&o.done(t.bind(s,this)),n&&o.fail(t.bind(n,this)),o},remove:function(){return this.trigger("beforeRemove"),this.removeEvents().abortDeferreds().removeViews(),i.View.prototype.remove.call(this),this.trigger("afterRemove"),this},setElement:function(e){return this._setElement(e),this}});return t.extend(r.prototype,{undelegateEvents:r.prototype.removeEvents,delegateEvents:r.prototype.setupEvents}),t.each(["appendTo","prependTo","insertBefore","insertAfter"],function(e){r.prototype[e]=function(i){return this.$el[e](i instanceof r?i.$el:i),this}}),r}); | ||
!function(e,i){"function"==typeof define&&define.amd?define(["jquery","backbone","underscore"],i):"object"==typeof module&&module.exports?module.exports=i(require("jquery"),require("backbone"),require("underscore")):e.BaseView=i(e.jQuery,e.Backbone,e._)}(this,function(e,i,t){function s(e,i,s){var n=o.indexOf(i),h=n<0,d=n>=0&&r[n];h?e instanceof i||s():"array"===d?!t.isArray(e)&&s():typeof e!==d&&s()}function n(e,i){return e.replace(h,function(e,t){var s=0===t.indexOf("this."),n=s?i:window,o=(s?t.slice(5):t).split(".");for(var r in o)if(void 0===(n=n[o[r]]))throw new Error("Undefined variable in event string");return n})}var o=[String,Number,Boolean,Function,Object,Array],r=["string","number","boolean","function","object","array"],h=/{{\s*(\S+)\s*}}/g,d={window:window,document:window.document},u=i.View.extend({constructor:function(e){this.assignOptions&&(this.writeOptions.apply(this,arguments),this.optionRules&&this.validateOptions(this.options,this.optionRules)),i.View.apply(this,arguments),this.events&&this.setupEvents()},delegatedEvents:!0,parseEventVariables:!0,assignOptions:!1,writeOptions:function(i){var s=t.result(this,"defaults"),n={};return this.optionRules&&t.each(this.optionRules,function(i,s){e.isPlainObject(i)&&void 0!==i.default&&(n[s]=t.result(i,"default"))}),"deep"===this.assignOptions?this.options=e.extend(!0,{},s,n,i):this.options=e.extend({},s,n,i),this},validateOptions:function(i,n){var o=[];return t.each(n,function(t,n){var r=i[n],h=typeof r;if(!1!==t.required||"undefined"!==h){var d=e.isPlainObject(t)?t.type:t;d&&s(r,d,function(){o.push('Invalid type for option "'+n+'" ("'+h+'").')}),t.validator&&!t.validator(r)&&o.push('Validation of option "'+n+'" failed.')}}),this.handleValidateOptionsErrors(o)},handleValidateOptionsErrors:function(e){if(e.length)throw new Error(e.join(" "))},setupEvents:function(i){var s=i||this.events,o="function"==typeof s?s.call(this):s,r=this;if(o){var h=this.ens=this.ens||"."+this.cid;t.each(o,function(i,t){r.parseEventVariables&&(t=n(t,r));var s=0===t.indexOf("one:"),o=(s?t.slice(4):t).split(" "),u=o[0]+h,a=o.slice(1).join(" "),c=r.$el;d[a]?(c=r["$"+a]=r["$"+a]||e(d[a]),a=void 0):r.delegatedEvents||((r.elementsWithBoundEvents=r.elementsWithBoundEvents||[]).push(c=c.find(a)),a=void 0),c[s?"one":"on"](u,a,function(){("function"==typeof i?i:r[i]).apply(r,arguments)})})}return this},addDismissListener:function(i,t){var s=this;if(!i)throw new Error("Dismiss listener name not speficied");return t=e.extend({$el:this.$el},t),this.$document=this.$document||e(document),this.ens=this.ens||"."+this.cid,this.dismissListeners=this.dismissListeners||{},this.dismissListeners[i]||(this.dismissListeners[i]=function(n){27!==n.keyCode&&(e(n.target).is(t.$el)||e.contains(t.$el.get(0),n.target))||s[i].call(s)},this.$document.on("click"+this.ens+" keyup"+this.ens,this.dismissListeners[i])),this},removeDismissListener:function(e){if(!e)throw new Error("Name of dismiss listener to remove not specified");return this.dismissListeners&&this.dismissListeners[e]&&(this.$document.off("click keyup",this.dismissListeners[e]),delete this.dismissListeners[e]),this},removeEvents:function(){var e=this.ens;return e&&(this.$el&&this.$el.off(e),this.$document&&this.$document.off(e),this.$window&&this.$window.off(e),this.elementsWithBoundEvents&&(t.each(this.elementsWithBoundEvents,function(i){i.off(e)}),delete this.elementsWithBoundEvents),delete this.dismissListeners),this},addView:function(e,i){return this.views=this.views||{},this.views[e.cid]=e,e.model&&(this.viewsWithModel=this.viewsWithModel||{},this.viewsWithModel[e.model.cid]=e),i&&(this.viewsGroups=this.viewsGroups||{},this.viewsGroups[i]=this.viewsGroups[i]||{},this.viewsGroups[i][e.cid]=e),this.listenToOnce(e,"afterRemove detachView",function(){delete this.views[e.cid],e.model&&this.viewsWithModel&&delete this.viewsWithModel[e.model.cid],i&&this.viewsGroups&&this.viewsGroups[i]&&delete this.viewsGroups[i][e.cid]}),e},getGroupViews:function(e){return this.viewsGroups&&this.viewsGroups[e]?t.values(this.viewsGroups[e]):[]},hasView:function(e){return this.views&&Boolean(this.views[e.cid])},detachView:function(){return this.trigger("detachView"),this},attachToView:function(e,i){return this.detachView(),e.addView(this,i),this},removeViews:function(e){return e?this.viewsGroups&&this.viewsGroups[e]&&(t.invoke(this.viewsGroups[e],"remove"),delete this.viewsGroups[e]):(this.views&&t.invoke(this.views,"remove"),delete this.views,delete this.viewsWithModel,delete this.viewsGroups),this},getViewByModel:function(e){return this.viewsWithModel&&this.viewsWithModel[e.cid]},removeViewByModel:function(e){return this.viewsWithModel&&this.viewsWithModel[e.cid]&&this.viewsWithModel[e.cid].remove(),this},addDeferred:function(e){return this.deferreds=this.deferreds||[],t.indexOf(this.deferreds,e)<0&&this.deferreds.push(e),e},abortDeferreds:function(){return this.deferreds&&t.each(this.deferreds,function(e){"object"==typeof e&&e.state&&"pending"===e.state()&&(e.abort?e.abort():e.reject())}),delete this.deferreds,this},when:function(i,s,n){t.each(i=t.isArray(i)?i:[i],function(e){this.addDeferred(e)},this);var o=e.when.apply(e,i);return s&&o.done(t.bind(s,this)),n&&o.fail(t.bind(n,this)),o},remove:function(){return this.trigger("beforeRemove"),this.removeEvents().abortDeferreds().removeViews(),i.View.prototype.remove.call(this),this.trigger("afterRemove"),this},setElement:function(e){return this._setElement(e),this}});return t.extend(u.prototype,{undelegateEvents:u.prototype.removeEvents,delegateEvents:u.prototype.setupEvents}),t.each(["appendTo","prependTo","insertBefore","insertAfter"],function(e){u.prototype[e]=function(i){return this.$el[e](i instanceof u?i.$el:i),this}}),u}); |
@@ -58,4 +58,4 @@ var attire = require('attire'); | ||
options: { | ||
files: ['package.json', 'bower.json'], | ||
commitFiles: ['package.json', 'bower.json'], | ||
files: ['package.json', 'package-lock.json', 'bower.json'], | ||
commitFiles: ['package.json', 'package-lock.json', 'bower.json'], | ||
tagName: '%VERSION%', | ||
@@ -62,0 +62,0 @@ push: false |
{ | ||
"name": "backbone-base-view", | ||
"version": "2.1.0", | ||
"version": "3.0.0", | ||
"description": "Baseview is a extended backbone view with convenient methods for manipulating subviews and events.", | ||
@@ -5,0 +5,0 @@ "main": "src/baseView.js", |
@@ -44,11 +44,11 @@ # Backbone base view | ||
### Options type checking and validation | ||
Options provided by type defaults and and constructor parameters can be type checked. | ||
Options provided by type defaults and and constructor parameters can be type checked and validated. | ||
```js | ||
var MusicianView = BaseView.extend({ | ||
optionRules: { | ||
instrument: {type: 'string'}, | ||
age: {type: 'number', default: 18, rule: function(age) { | ||
instrument: String, | ||
age: {type: Number, default: 18, validator: function(age) { | ||
return age >= 18; | ||
}}, | ||
mentor: {instanceOf: BaseView} | ||
mentorView: {type: BaseView, required: false} | ||
} | ||
@@ -55,0 +55,0 @@ }); |
@@ -14,2 +14,25 @@ (function(root, factory) { | ||
var simpleTypes = [String, Number, Boolean, Function, Object, Array]; | ||
var simpleTypeNames = ['string', 'number', 'boolean', 'function', 'object', 'array']; | ||
function validateType(value, Type, errorCallback) { | ||
var simpleTypeIndex = simpleTypes.indexOf(Type); | ||
var isComplexType = simpleTypeIndex < 0; | ||
var typeName = simpleTypeIndex >= 0 && simpleTypeNames[simpleTypeIndex]; | ||
if (isComplexType) { | ||
if (!(value instanceof Type)) { | ||
errorCallback(); | ||
} | ||
} else { | ||
if (typeName === 'array') { | ||
!_.isArray(value) && errorCallback(); | ||
} else if (typeof value !== typeName) { | ||
errorCallback(); | ||
} | ||
} | ||
} | ||
var variableInEventStringRE = /{{\s*(\S+)\s*}}/g; | ||
@@ -20,4 +43,5 @@ var specialSelectors = { | ||
}; | ||
var parseEventVariables = function(eventString, context) { | ||
function parseEventVariables(eventString, context) { | ||
return eventString.replace(variableInEventStringRE, function(match, namespace) { | ||
@@ -40,3 +64,3 @@ | ||
}; | ||
} | ||
@@ -67,3 +91,5 @@ var BaseView = Backbone.View.extend({ | ||
this.optionRules && _.each(this.optionRules, function(data, optionName) { | ||
ruleDefaults[optionName] = data.default; | ||
if ($.isPlainObject(data) && typeof data.default !== 'undefined') { | ||
ruleDefaults[optionName] = _.result(data, 'default'); | ||
} | ||
}); | ||
@@ -83,5 +109,5 @@ | ||
var errors = []; | ||
var errorMessages = []; | ||
_.each(rules, function(data, optionName) { | ||
_.each(rules, function(optionRules, optionName) { | ||
@@ -91,14 +117,16 @@ var optionValue = options[optionName]; | ||
if (data.required !== false || optionValueType !== 'undefined') { | ||
if (optionRules.required !== false || optionValueType !== 'undefined') { | ||
if (data.type && optionValueType !== data.type) { | ||
errors.push('Option "' + optionName +'" is ' + optionValueType + ', expected ' + data.type + '.'); | ||
} | ||
var userType = $.isPlainObject(optionRules) ? optionRules.type : optionRules; | ||
if (data.rule && !data.rule(optionValue)) { | ||
errors.push('Option "' + optionName +'" breaks defined rule.'); | ||
if (userType) { | ||
validateType(optionValue, userType, function() { | ||
errorMessages.push('Invalid type for option "' + optionName +'" ("' + optionValueType + '").'); | ||
}); | ||
} | ||
if (data.instanceOf && !(optionValue instanceof data.instanceOf)) { | ||
errors.push('Option "' + optionName +'" is not instance of defined constructor.'); | ||
if (optionRules.validator && !optionRules.validator(optionValue)) { | ||
errorMessages.push('Validation of option "' + optionName + '" failed.'); | ||
} | ||
@@ -110,6 +138,10 @@ | ||
if (errors.length) { | ||
throw new Error(errors.join(' ')); | ||
} else { | ||
return this; | ||
return this.handleValidateOptionsErrors(errorMessages); | ||
}, | ||
handleValidateOptionsErrors: function(errorMessages) { | ||
if (errorMessages.length) { | ||
throw new Error(errorMessages.join(' ')); | ||
} | ||
@@ -116,0 +148,0 @@ |
@@ -72,92 +72,160 @@ var assert = require('chai').assert; | ||
it('type check provided options', function() { | ||
var TypedView = BaseView.extend({ | ||
assignOptions: true | ||
}); | ||
var Guitarist = BaseView.extend({ | ||
assignOptions: true, | ||
optionRules: { | ||
name: {type: 'string'}, | ||
instrument: {type: 'string', required: false}, | ||
} | ||
}); | ||
it('type checks string options', function() { | ||
var Guitarist = TypedView.extend({optionRules: { | ||
name: String | ||
}}); | ||
assert.throws(function() { | ||
new Guitarist(); | ||
}, 'Option "name" is undefined, expected string.'); | ||
}, 'Invalid type for option "name" ("undefined").'); | ||
}); | ||
it('type checks respect rquired attribyte', function() { | ||
var Guitarist = TypedView.extend({optionRules: { | ||
name: {type: String, required: false} | ||
}}); | ||
assert.doesNotThrow(function() { | ||
new Guitarist({foo: 'bar'}); | ||
}); | ||
assert.throws(function() { | ||
new Guitarist({ | ||
name: 'George', | ||
instrument: 42 | ||
}); | ||
}, 'Option "instrument" is number, expected string.'); | ||
new Guitarist({name: 47}); | ||
}, 'Invalid type for option "name" ("number").'); | ||
}); | ||
it('validate options with rule callback', function() { | ||
it('type checks number options with custom validator', function() { | ||
var Guitarist = BaseView.extend({ | ||
assignOptions: true, | ||
optionRules: { | ||
age: {type: 'number', rule: function(age) { | ||
return age > 18; | ||
}} | ||
} | ||
var Guitarist = TypedView.extend({optionRules: { | ||
age: {type: Number, validator: function(age) { | ||
return age > 18; | ||
}}} | ||
}); | ||
var GuitarPro = Guitarist.extend(); | ||
assert.throws(function() { | ||
new Guitarist({age: '17'}); | ||
}, 'Invalid type for option "age" ("string").'); | ||
assert.throws(function() { | ||
new Guitarist({ | ||
age: 'teen' | ||
}); | ||
}, 'Option "age" is string, expected number. Option "age" breaks defined rule.'); | ||
new Guitarist({age: 15}); | ||
}, 'Validation of option "age" failed.'); | ||
assert.doesNotThrow(function() { | ||
new Guitarist({age: 20}); | ||
}); | ||
}); | ||
it('type checks boolean options', function() { | ||
var Guitarist = TypedView.extend({optionRules: { | ||
published: Boolean | ||
}}); | ||
assert.throws(function() { | ||
new GuitarPro({ | ||
age: 15 | ||
}); | ||
}, 'Option "age" breaks defined rule.'); | ||
new Guitarist({published: 'yes'}); | ||
}, 'Invalid type for option "published" ("string").'); | ||
}); | ||
it('do option instance of checks', function() { | ||
it('type checks function options', function() { | ||
var Person = function() {}; | ||
var Guitarist = TypedView.extend({optionRules: { | ||
afterGig: Function | ||
}}); | ||
var Guitarist = BaseView.extend({ | ||
assignOptions: true, | ||
optionRules: { | ||
mentor: {instanceOf: Person} | ||
} | ||
assert.throws(function() { | ||
new Guitarist(); | ||
}, 'Invalid type for option "afterGig" ("undefined").'); | ||
assert.doesNotThrow(function() { | ||
new Guitarist({afterGig: function() {}}); | ||
}); | ||
}); | ||
it('type checks object options', function() { | ||
var Guitarist = TypedView.extend({optionRules: { | ||
data: Object | ||
}}); | ||
assert.throws(function() { | ||
new Guitarist({ | ||
mentor: 'pero' | ||
}); | ||
}, 'Option "mentor" is not instance of defined constructor.'); | ||
new Guitarist({data: ''}); | ||
}, 'Invalid type for option "data" ("string").'); | ||
}); | ||
it('type checks array options', function() { | ||
var Guitarist = TypedView.extend({optionRules: { | ||
data: Array | ||
}}); | ||
assert.throws(function() { | ||
new Guitarist({ | ||
mentor: new Date() | ||
}); | ||
}, 'Option "mentor" is not instance of defined constructor.'); | ||
new Guitarist({data: {}}); | ||
}, 'Invalid type for option "data" ("object").'); | ||
assert.doesNotThrow(function() { | ||
new Guitarist({data: [1, 2, 3]}); | ||
}); | ||
}); | ||
it('type checks date options', function() { | ||
var Guitarist = TypedView.extend({optionRules: { | ||
dateOfBirth: Date | ||
}}); | ||
assert.throws(function() { | ||
new Guitarist(); | ||
}, 'Option "mentor" is not instance of defined constructor.'); | ||
new Guitarist({dateOfBirth: '2017-05-05'}); | ||
}, 'Invalid type for option "dateOfBirth" ("string").'); | ||
assert.doesNotThrow(function() { | ||
new Guitarist({dateOfBirth: new Date()}); | ||
}); | ||
}); | ||
it('merge default values', function() { | ||
it('type checks custom constructors options', function() { | ||
var Guitarist = BaseView.extend({ | ||
assignOptions: true, | ||
var Guitarist = TypedView.extend({optionRules: { | ||
mentor: TypedView | ||
}}); | ||
assert.throws(function() { | ||
new Guitarist({mentor: {}}); | ||
}, 'Invalid type for option "mentor" ("object").'); | ||
assert.doesNotThrow(function() { | ||
new Guitarist({mentor: new TypedView()}); | ||
}); | ||
assert.doesNotThrow(function() { | ||
var ExtendedView = TypedView.extend({}); | ||
new Guitarist({mentor: new ExtendedView()}); | ||
}); | ||
}); | ||
it('merges default values with rule options defaults', function() { | ||
var Guitarist = TypedView.extend({ | ||
defaults: { | ||
instrument: 'guitar' | ||
instrument: 'guitar', | ||
dateOfBirth: '1985-01-01' | ||
}, | ||
optionRules: { | ||
name: {type: 'string', default: ''}, | ||
instrument: {type: 'string'}, | ||
age: {type: 'number', default: 18} | ||
name: {type: String, default: ''}, | ||
instrument: {type: String}, | ||
age: {type: Number, default: 18} | ||
} | ||
@@ -169,3 +237,4 @@ }); | ||
instrument: 'guitar', | ||
age: 18 | ||
age: 18, | ||
dateOfBirth: '1985-01-01' | ||
}); | ||
@@ -172,0 +241,0 @@ |
Sorry, the diff of this file is not supported yet
92278
1323