diff --git a/lib/schema/boolean.js b/lib/schema/boolean.js index 099270c2136..f90c86a6c2f 100644 --- a/lib/schema/boolean.js +++ b/lib/schema/boolean.js @@ -52,15 +52,25 @@ SchemaBoolean.prototype.checkRequired = function(value) { * Casts to boolean * * @param {Object} value + * @param {Object} model - this value is optional * @api private */ -SchemaBoolean.prototype.cast = function(value) { +SchemaBoolean.prototype.cast = function(value, model) { if (value === null) { return value; } - if (!this.options.strictBool) { + if (this.options.strictBool || (model && model.schema.options.strictBool && this.options.strictBool !== false)) { + // strict mode (throws if value is not a boolean, instead of converting) + if (value === true || value === 'true' || value === 1 || value === '1') { + return true; + } + if (value === false || value === 'false' || value === 0 || value === '0') { + return false; + } + throw new CastError('boolean', value, this.path); + } else { // legacy mode if (value === '0') { return false; @@ -72,15 +82,6 @@ SchemaBoolean.prototype.cast = function(value) { return false; } return !!value; - } else { - // strict mode (throws if value is not a boolean, instead of converting) - if (value === true || value === 'true' || value === 1 || value === '1') { - return true; - } - if (value === false || value === 'false' || value === 0 || value === '0') { - return false; - } - throw new CastError('boolean', value, this.path); } }; diff --git a/test/schema.boolean.test.js b/test/schema.boolean.test.js index d367bb78ca3..59b77b916aa 100644 --- a/test/schema.boolean.test.js +++ b/test/schema.boolean.test.js @@ -29,6 +29,7 @@ describe('schematype', function() { assert.strictEqual(true, m3.b); done(); }); + it('strictBool option (gh-5211)', function(done) { var db = start(), s1 = new Schema({b: {type: Boolean, strictBool: true}}), @@ -51,7 +52,37 @@ describe('schematype', function() { } }); }); + }); + + it('strictBool schema option', function(done) { + var db = start(), + s1 = new Schema({b: {type: Boolean}}, {strictBool: true}), + M1 = db.model('StrictBoolTrue', s1); + db.close(); + var strictValues = [true, false, 'true', 'false', 0, 1, '0', '1']; + + strictValues.forEach(function(value) { + var doc = new M1; + doc.b = value; + doc.validate(function(error) { + if (error) { + // test fails as soon as one value fails + return done(error); + } + }); + }); + + var doc = new M1; + doc.b = 'Not a boolean'; + doc.validate(function(error) { + if (error) { + done(); + } else { + done(new Error('ValidationError expected')); + } + }); }); + }); });