From 662458dc2c78c0066ae9b122e189270ec9513470 Mon Sep 17 00:00:00 2001 From: CerealGuy Date: Fri, 23 Sep 2016 11:26:29 +0200 Subject: [PATCH] Fix validateNumericality, nullCheck & add tests validateNumericality didn't test if attributes value is a number only if it's type is number. Further nullCheck had a wrong testing order. It first checked if value is null, later if blank. Also null check only used two equals, not three. We don't use blank() anymore, testing if variable is undefined should be fine too. Added tests covering validateNumericality. --- lib/validations.js | 24 +++++++++++----- test/validations.test.js | 60 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/lib/validations.js b/lib/validations.js index 3455edf7..41f919b8 100644 --- a/lib/validations.js +++ b/lib/validations.js @@ -287,7 +287,7 @@ function validateLength(attr, conf, err, options) { function validateNumericality(attr, conf, err, options) { if (nullCheck.call(this, attr, conf, err)) return; - if (typeof this[attr] !== 'number') { + if (typeof this[attr] !== 'number' || isNaN(this[attr])) { return err('number'); } if (conf.int && this[attr] !== Math.round(this[attr])) { @@ -633,16 +633,26 @@ var defaultMessages = { uniqueness: 'is not unique', }; +/** + * Checks if attribute is undefined or null. Calls err function with 'blank' or 'null'. + * See defaultMessages. You can affect this behaviour with conf.allowBlank and conf.allowNull. + * @param {String} attr Property name of attribute + * @param {Object} conf conf object for validator + * @param {Function} err + * @return {Boolean} returns true if attribute is null or blank + */ function nullCheck(attr, conf, err) { - if (this[attr] == null) { - if (!conf.allowNull) { - err('null'); + // First determine if attribute is defined + if (typeof this[attr] === 'undefined') { + if (!conf.allowBlank) { + err('blank'); } return true; } else { - if (blank(this[attr])) { - if (!conf.allowBlank) { - err('blank'); + // Now check if attribute is null + if (this[attr] === null) { + if (!conf.allowNull) { + err('null'); } return true; } diff --git a/test/validations.test.js b/test/validations.test.js index daed9985..fd79f613 100644 --- a/test/validations.test.js +++ b/test/validations.test.js @@ -558,7 +558,65 @@ describe('validations', function() { }); describe('numericality', function() { - it('should validate numericality'); + it('passes when given numeric values', function() { + User.validatesNumericalityOf('age'); + var user = new User({age: 10}); + user.isValid().should.be.true(); + }); + + it('fails when given non-numeric values', function() { + User.validatesNumericalityOf('age'); + var user = new User({age: 'notanumber'}); + user.isValid().should.be.false(); + user.errors.should.eql({age: ['is not a number']}); + }); + + it('fails when given undefined values', function() { + User.validatesNumericalityOf('age'); + var u = new User({}); + u.isValid().should.be.false(); + u.errors.should.eql({age: ['is blank']}); + }); + + it('skips undefined values when allowBlank option is true', function() { + User.validatesNumericalityOf('age', {allowBlank: true}); + var user = new User({}); + user.isValid().should.be.true(); + }); + + it('fails when given non-numeric values when allowBlank option is true', function() { + User.validatesNumericalityOf('age', {allowBlank: true}); + var user = new User({age: 'test'}); + user.isValid().should.be.false(); + user.errors.should.eql({age: ['is not a number']}); + + }); + + it('fails when given null values', function() { + User.validatesNumericalityOf('age'); + var user = new User({age: null}); + user.isValid().should.be.false(); + user.errors.should.eql({age: ['is null']}); + }); + + it('passes when given null values when allowNull option is true', function() { + User.validatesNumericalityOf('age', {allowNull: true}); + var user = new User({age: null}); + user.isValid().should.be.true(); + }); + + it('passes when given float values', function() { + User.validatesNumericalityOf('age'); + var user = new User({age: 13.37}); + user.isValid().should.be.true(); + }); + + it('fails when given non-integer values when int option is true', function() { + User.validatesNumericalityOf('age', {int: true}); + var user = new User({age: 13.37}); + user.isValid().should.be.false(); + user.errors.should.eql({age: ['is not an integer']}); + }); }); describe('inclusion', function() {