diff --git a/lib/index.js b/lib/index.js index cae3323..eb38bbc 100644 --- a/lib/index.js +++ b/lib/index.js @@ -34,8 +34,10 @@ class Double extends mongoose.SchemaType { return new DoubleType(val.value); } + // MongoDB allows storing NaNs in Number type attributes + // So testing for type number is truer to MongoDB behavior than testing for NaNs const _val = Number(val); - if (isNaN(_val)) { + if (isNaN(_val) && typeof val !== 'number') { throw new mongoose.SchemaType.CastError('Double', val + ' is not a valid double'); } diff --git a/test/index.js b/test/index.js index 31b923f..e5a8bcb 100644 --- a/test/index.js +++ b/test/index.js @@ -59,6 +59,38 @@ describe('Double', function() { }); }); + describe('NaNs', () => { + it('saves explicit NaNs', function() { + return co(function*() { + const schema = new mongoose.Schema({ val: Double }); + const Model = mongoose.model('DoubleTest3', schema, 'doubletest3'); + + const doc = new Model({ val: NaN }); + ++doc.val; + yield doc.save(); + + assert.ok(yield Model.findOne({ val: { $type: 1 } })); + assert.ok(yield Model.findOne({ val: NaN })); + }); + }); + + it('does not save implicit NaNs', function() { + return co(function*() { + const schema = new mongoose.Schema({ val: Double }); + const Model = mongoose.model('DoubleTest4', schema, 'doubletest4'); + + const doc = new Model({ val: 'hi' }); + ++doc.val; + return doc.save().then(() => { + throw new Error('This should not save') + }).catch(e => { + assert.ok(true) + }) + }); + }); + }) + + it('works in update', function() { return co(function*() { const doc = yield Model.create({ double: 1 });