diff --git a/lib/validatable.js b/lib/validatable.js index 686507c7..54bcce2a 100644 --- a/lib/validatable.js +++ b/lib/validatable.js @@ -9,6 +9,7 @@ Validatable.validatesLengthOf = getConfigurator('length'); Validatable.validatesNumericalityOf = getConfigurator('numericality'); Validatable.validatesInclusionOf = getConfigurator('inclusion'); Validatable.validatesExclusionOf = getConfigurator('exclusion'); +Validatable.validatesFormatOf = getConfigurator('format'); function getConfigurator(name) { return function () { @@ -96,6 +97,24 @@ var defaultMessages = { exclusion: 'is reserved' }; +function nullCheck(attr, conf, err) { + var isNull = this[attr] === null || !(attr in this); + if (isNull) { + if (!conf.allowNull) { + err('null'); + } + return true; + } else { + if (blank(this[attr])) { + if (!conf.allowBlank) { + err('blank'); + } + return true; + } + } + return false; +} + var validators = { presence: function (attr, conf, err) { if (blank(this[attr])) { @@ -103,22 +122,8 @@ var validators = { } }, length: function (attr, conf, err) { - var isNull = this[attr] === null || !(attr in this); - if (isNull) { - if (conf.allowNull) { - return true; - } else { - return err('null'); - } - } else { - if (blank(this[attr])) { - if (conf.allowBlank) { - return true; - } else { - return err('blank'); - } - } - } + if (nullCheck.call(this, attr, conf, err)) return; + var len = this[attr].length; if (conf.min && len < conf.min) { err('min'); @@ -131,6 +136,8 @@ var validators = { } }, numericality: function (attr, conf, err) { + if (nullCheck.call(this, attr, conf, err)) return; + if (typeof this[attr] !== 'number') { return err('number'); } @@ -139,14 +146,29 @@ var validators = { } }, inclusion: function (attr, conf, err) { + if (nullCheck.call(this, attr, conf, err)) return; + if (!~conf.in.indexOf(this[attr])) { err() } }, exclusion: function (attr, conf, err) { + if (nullCheck.call(this, attr, conf, err)) return; + if (~conf.in.indexOf(this[attr])) { err() } + }, + format: function (attr, conf, err) { + if (nullCheck.call(this, attr, conf, err)) return; + + if (typeof this[attr] === 'string') { + if (!this[attr].match(conf['with'])) { + err(); + } + } else { + err(); + } } }; diff --git a/test/validations_test.coffee b/test/validations_test.coffee index bba9af2b..aeba758f 100644 --- a/test/validations_test.coffee +++ b/test/validations_test.coffee @@ -151,7 +151,7 @@ it 'should validate inclusion', (test) -> user.gender = 'male' test.ok user.isValid() - user.gender = '' + user.gender = 'man' test.ok not user.isValid() test.equal user.errors.gender[0], 'is not included in the list' @@ -170,3 +170,15 @@ it 'should validate exclusion', (test) -> test.done() +it 'should validate format', (test) -> + User.validatesFormatOf 'email', with: /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i + user = new User validAttributes + + user.email = 'invalid email' + test.ok not user.isValid() + + user.email = 'valid@email.tld' + test.ok user.isValid() + + test.done() +