UNPKG

mongoose-number

Version:

Provides Mongoose v2 sub-classed Number with atomic increment/decrement support

253 lines (222 loc) 7.37 kB
var assert = require('assert') var NumberModule = require('../') var mongoose = require('mongoose') var Schema = mongoose.Schema; var NumberSchema; var MongooseNumber; describe('MongooseNumber', function(){ before(function(){ NumberSchema = NumberModule(mongoose) MongooseNumber = mongoose.Types.MongooseNumber; }) it('has a version', function(){ assert.equal('string', typeof NumberModule.version); console.log(NumberModule.version); }) it('is a function', function(){ assert.equal('function', typeof NumberSchema); }) it('extends mongoose.Schema.Types', function(){ assert.ok(Schema.Types.MongooseNumber); assert.equal(NumberSchema, Schema.Types.MongooseNumber); }) it('extends mongoose.Types', function(){ assert.ok(mongoose.Types.MongooseNumber); }) it('can be used in schemas', function(){ var s = new Schema({ num: NumberSchema }); var num = s.path('num') assert.ok(num instanceof mongoose.SchemaType); assert.equal('function', typeof num.get); var s = new Schema({ num: 'MongooseNumber' }); var num = s.path('num') assert.ok(num instanceof mongoose.SchemaType); assert.equal('function', typeof num.get); }) describe('integration', function(){ var db, S, schema, id; before(function(done){ db = mongoose.createConnection('localhost', 'mongoose_number') db.once('open', function () { schema = new Schema({ num: NumberSchema, name: String, docs: [{ title: String }] }); S = db.model('MNumber', schema); done(); }); }) // inc, dec, querycasting null describe('subclassing', function(){ it('is an instanceof Number', function(){ var n = new MongooseNumber('5'); assert.ok(n instanceof Number); assert.ok(n instanceof MongooseNumber); assert.equal('5', n.toString()); assert.equal(Object, n._atomics.constructor); }) }) describe('casts', function(){ it('numbers', function(){ var v = 20; var s = new S({ num: v }); assert.ok(s.num instanceof mongoose.Types.MongooseNumber); assert.equal(v, s.num.valueOf()); v = new Number(20); s = new S({ num: v }); assert.ok(s.num instanceof mongoose.Types.MongooseNumber); assert.equal(v, +s.num); }); describe('strings', function(){ it('with length', function(){ var v = '20'; var s = new S({ num: v }); assert.ok(s.num instanceof mongoose.Types.MongooseNumber); assert.equal(+v, s.num.valueOf()); }) it('that are empty to null', function(){ var v = ''; var s = new S({ num: v }); assert.equal(null, s.num); }) }); it('null', function(){ var s = new S({ num: null }); assert.equal(null, s.num); }) it('MongooseNumber', function(){ var s = new S({ num: new mongoose.Types.MongooseNumber("90") }); assert.ok(s.num instanceof mongoose.Types.MongooseNumber); assert.equal(90, s.num.valueOf()); }) it('non-castables produce _saveErrors', function(done){ var schema = new Schema({ num: 'MongooseNumber' }, { strict: 'throw' }); var M = db.model('throws', schema); var m = new M({ num: [] }); m.save(function (err) { assert.ok(err); assert.equal('MongooseNumber', err.type); assert.equal('CastError', err.name); done(); }); }) it('queries with null properly', function(done){ S.create({ num: null }, function (err) { assert.ifError(err); S.findOne({ num: null }, function (err, doc) { assert.ifError(err); assert.equal(null, doc.num); done(); }) }) }) }) it('can be saved', function(done){ var s = new S({ num: 20, name: 'Skyler', docs: [{ title: 'Jesse' }] }); id = s.id; s.save(function (err) { assert.ifError(err); done(); }) }) it('is queryable', function(done){ S.findById(id, function (err, doc) { assert.ifError(err); assert.ok(doc.num instanceof MongooseNumber); assert.equal(20, +doc.num); done(); }); }) it('can be updated', function(done){ S.findById(id, function (err, doc) { assert.ifError(err); doc.num += 10; doc.save(function (err) { assert.ifError(err); S.findById(id, function (err, doc) { assert.ifError(err); assert.equal(30, doc.num); done(); }); }) }) }) it('can be incremented atomically', function(done){ S.findById(id, function (err, doc) { assert.ifError(err); assert.equal(1, doc.docs.length); doc.name = 'Walt'; doc.docs.push({ title: 'Gus' }); doc.num.increment(); var delta = doc.$__delta(); assert.equal(2, delta.length); assert.ok(delta[1].$inc); assert.equal(1, delta[1].$inc.num); assert.ok(delta[1].$set); assert.equal('Walt', delta[1].$set.name); assert.equal('Gus', delta[1].$pushAll.docs[0].title); doc.save(function (err) { assert.ifError(err); S.findById(id, function (err, doc) { assert.ifError(err); assert.equal(31, doc.num); assert.equal('Walt', doc.name); assert.equal(2, doc.docs.length); assert.equal('Jesse', doc.docs[0].title); assert.equal('Gus', doc.docs[1].title); // gh-1 doc.num.increment(); doc.num.increment(); doc.num.increment(2); doc.save(function (err) { assert.ifError(err); S.findById(id, function (err, doc) { assert.ifError(err); assert.equal(35, doc.num); done(); }) }) }); }) }) }) it('can be decremented atomically', function(done){ S.findById(id, function (err, doc) { assert.ifError(err); doc.num.decrement(); var delta = doc.$__delta(); assert.equal(2, delta.length); assert.ok(delta[1].$inc); assert.equal(-1, delta[1].$inc.num); doc.save(function (err) { assert.ifError(err); S.findById(id, function (err, doc) { assert.ifError(err); assert.equal(34, doc.num); doc.num.$dec({}); doc.num.$dec(3.1); assert.equal(-4.1, doc.num._atomics.$inc); doc.save(function (err) { assert.ifError(err); S.findById(id, function (err, doc) { assert.ifError(err); assert.equal(29.9, doc.num); done(); }) }) }); }) }) }) it('can be required', function(done){ var s = new Schema({ num: { type: MongooseNumber, required: true }}); var M = db.model('required', s); var m = new M; m.save(function (err) { assert.ok(err); m.num = 10; m.validate(function (err) { assert.ifError(err); done(); }) }) }) }) })