From 710b1af882e06cc1b869ee10ceafd78df1e3e550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luiz=20Am=C3=A9rico?= Date: Sat, 21 Apr 2018 19:19:46 -0300 Subject: [PATCH] Pre validate multiple attributes #303 --- src/backbone-validation.js | 18 ++++++++++----- test/preValidate.js | 47 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/backbone-validation.js b/src/backbone-validation.js index 9c637415..615e6978 100644 --- a/src/backbone-validation.js +++ b/src/backbone-validation.js @@ -206,20 +206,26 @@ Backbone.Validation = (function(_){ preValidate: function(attr, value) { var self = this, result = {}, - error; + error, + allAttrs = _.extend({}, this.attributes); if(_.isObject(attr)){ - _.each(attr, function(value, key) { - error = self.preValidate(key, value); + // if multiple attributes are passed at once we would like for the validation functions to + // have access to the fresh values sent for all attributes, in the same way they do in the + // regular validation + _.extend(allAttrs, attr); + + _.each(attr, _.bind(function(value, attrKey) { + error = validateAttr(this, attrKey, value, allAttrs); if(error){ - result[key] = error; + result[attrKey] = error; } - }); + }, this)); return _.isEmpty(result) ? undefined : result; } else { - return validateAttr(this, attr, value, _.extend({}, this.attributes)); + return validateAttr(this, attr, value, allAttrs); } }, diff --git a/test/preValidate.js b/test/preValidate.js index 2e6c8b6a..d1c8d17c 100644 --- a/test/preValidate.js +++ b/test/preValidate.js @@ -68,7 +68,50 @@ module.exports = { refute(this.model.preValidate({ name: 'name' })); } } - } - } + }, + + "when model has dependancies between validation functions": { + setUp: function() { + var CARD_TYPES = { + VISA : 0, + AMEX : 1 + }; + var Model = Backbone.Model.extend({ + validation: { + card_type: { + required: true + }, + security_code: function(value, attr, computedState){ + var requiredLength = (computedState.card_type === CARD_TYPES.AMEX? 4 : 3); + if(value && _.isString(value) && value.length !== requiredLength) { + return 'Please enter a valid security code.'; + } + } + } + }); + Model.CARD_TYPES = CARD_TYPES; + this.ModelDefinition = Model; + this.model = new Model(); + Backbone.Validation.bind(new Backbone.View({model: this.model})); + }, + + "and pre-validating hash of attributes": { + "returns error object when value is not valid": function() { + var result = this.model.preValidate({card_type: this.ModelDefinition.CARD_TYPES.VISA, security_code: '1234'}); + assert(result.security_code); + refute(result.card_type); + }, + "returns error object when values are not valid": function() { + var result = this.model.preValidate({card_type: '', security_code: '12345'}); + assert(result.card_type); + assert(result.security_code); + }, + + "returns nothing when value is valid": function() { + refute(this.model.preValidate({card_type: this.ModelDefinition.CARD_TYPES.AMEX, security_code: '1234'})); + } + } + } + } }