diff --git a/.travis.yml b/.travis.yml index ddcb0f18..24395319 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,18 @@ language: node_js node_js: - - "6" - - "8" + - "12" - "10" + - "8" services: - docker env: - - MONGODB_VERSION="2.6" - - MONGODB_VERSION="3.6" + - MONGODB_VERSION="4.2" - MONGODB_VERSION="4.0" + - MONGODB_VERSION="3.6" + - MONGODB_VERSION="3.4" before_install: - docker run -d -p 127.0.0.1:27017:27017 mongo:$MONGODB_VERSION diff --git a/index.js b/index.js index db1e4b2a..d3c7d552 100644 --- a/index.js +++ b/index.js @@ -77,7 +77,7 @@ ShareDbMongo.prototype.getCollection = function(collectionName, callback) { // Gotcha: calls back sync if connected or async if not this.getDbs(function(err, mongo) { if (err) return callback(err); - var collection = mongo.collection(collectionName); + var collection = mongo.db().collection(collectionName); return callback(null, collection); }); }; @@ -89,7 +89,7 @@ ShareDbMongo.prototype._getCollectionPoll = function(collectionName, callback) { // Gotcha: calls back sync if connected or async if not this.getDbs(function(err, mongo, mongoPoll) { if (err) return callback(err); - var collection = (mongoPoll || mongo).collection(collectionName); + var collection = (mongoPoll || mongo).db().collection(collectionName); return callback(null, collection); }); }; @@ -312,7 +312,7 @@ ShareDbMongo.prototype.getOpCollection = function(collectionName, callback) { this.getDbs(function(err, mongo) { if (err) return callback(err); var name = self.getOplogCollectionName(collectionName); - var collection = mongo.collection(name); + var collection = mongo.db().collection(name); // Given the potential problems with creating indexes on the fly, it might // be preferrable to disable automatic creation if (self.disableIndexCreation) { @@ -1311,7 +1311,7 @@ function MongoSnapshot(id, version, type, data, meta, opLink) { this.v = version; this.type = type; this.data = data; - this.m = meta == null ? null : meta; + this.m = (meta == null) ? null : meta; if (opLink) this._opLink = opLink; } @@ -1364,23 +1364,9 @@ var collectionOperationsMap = { collection.distinct(value.field, query, cb); }, $aggregate: function(collection, query, value, cb) { - collection.aggregate(value, function(err, resultsOrCursor) { - if (err) { - return cb(err); - } - if (Array.isArray(resultsOrCursor)) { - // 2.x Mongo driver directly produces a results array: - // https://mongodb.github.io/node-mongodb-native/2.2/api/Collection.html#aggregate - var resultsArray = resultsOrCursor; - cb(null, resultsArray); - } else { - // 3.x Mongo driver produces an AggregationCursor: - // https://mongodb.github.io/node-mongodb-native/3.0/api/Collection.html#aggregate - // - // ShareDB expects serializable result data, so use `Cursor#toArray` for that. - var cursor = resultsOrCursor; - cursor.toArray(cb); - } + collection.aggregate(value, function(err, cursor) { + if (err) return cb(err); + cursor.toArray(cb); }); }, $mapReduce: function(collection, query, value, cb) { diff --git a/package.json b/package.json index 49e729df..77e8339d 100644 --- a/package.json +++ b/package.json @@ -4,25 +4,29 @@ "description": "MongoDB database adapter for ShareDB", "main": "index.js", "dependencies": { - "async": "^1.4.2", - "mongodb": "^2.1.2", + "async": "^1.5.2" + }, + "peerDependencies": { + "mongodb": "^3.0.0", "sharedb": "^1.0.0-beta" }, "devDependencies": { - "coveralls": "^2.11.8", + "chai": "^4.2.0", + "coveralls": "^3.0.7", "eslint": "^5.16.0", "eslint-config-google": "^0.13.0", - "expect.js": "^0.3.1", - "istanbul": "^0.4.2", - "mocha": "^2.3.3", - "sharedb-mingo-memory": "^1.0.2", + "mocha": "^6.2.2", + "mongodb": "^3.3.3", + "nyc": "^14.1.1", + "sharedb": "^1.0.0-beta", + "sharedb-mingo-memory": "^1.1.1", "sinon": "^6.1.5" }, "scripts": { "lint": "./node_modules/.bin/eslint --ignore-path .gitignore '**/*.js'", "lint:fix": "npm run lint -- --fix", "test": "npm run lint && node_modules/.bin/mocha", - "test-cover": "npm run lint && node_modules/istanbul/lib/cli.js cover node_modules/mocha/bin/_mocha" + "test-cover": "npm run lint && node_modules/nyc/bin/nyc.js --temp-dir=coverage -r text -r lcov node_modules/mocha/bin/_mocha" }, "repository": "git://github.com/share/sharedb-mongo.git", "author": "Nate Smith and Joseph Gentle", diff --git a/test/test_get_ops_without_strict_linking.js b/test/test_get_ops_without_strict_linking.js index c789946c..ce11631f 100644 --- a/test/test_get_ops_without_strict_linking.js +++ b/test/test_get_ops_without_strict_linking.js @@ -1,4 +1,4 @@ -var expect = require('expect.js'); +var expect = require('chai').expect; var mongodb = require('mongodb'); var ShareDbMongo = require('..'); var getQuery = require('sharedb-mingo-memory/get-query'); @@ -11,7 +11,7 @@ function create(callback) { mongo: function(shareDbCallback) { mongodb.connect(mongoUrl, function(err, mongo) { if (err) return callback(err); - mongo.dropDatabase(function(err) { + mongo.db().dropDatabase(function(err) { if (err) return callback(err); shareDbCallback(null, mongo); callback(null, db, mongo); @@ -67,11 +67,11 @@ describe('getOpsWithoutStrictLinking: true', function() { it('fetches ops 0-1 without fetching all ops', function(done) { db.getOps(collection, id, 0, 2, null, function(error, ops) { if (error) return done(error); - expect(ops.length).to.be(2); - expect(ops[0].v).to.be(0); - expect(ops[1].v).to.be(1); - expect(db._getSnapshotOpLink.notCalled).to.be(true); - expect(db._getOps.calledOnceWith(collection, id, 0, 2)).to.be(true); + expect(ops.length).to.equal(2); + expect(ops[0].v).to.equal(0); + expect(ops[1].v).to.equal(1); + expect(db._getSnapshotOpLink.notCalled).to.equal(true); + expect(db._getOps.calledOnceWith(collection, id, 0, 2)).to.equal(true); done(); }); }); @@ -81,16 +81,16 @@ describe('getOpsWithoutStrictLinking: true', function() { callInSeries([ function(next) { - mongo.collection('o_' + collection).insert(spuriousOp, next); + mongo.db().collection('o_' + collection).insertOne(spuriousOp, next); }, function(result, next) { db.getOps(collection, id, 0, 2, null, next); }, function(ops, next) { - expect(ops.length).to.be(2); - expect(ops[1].oi).to.be('bar'); - expect(db._getSnapshotOpLink.notCalled).to.be(true); - expect(db._getOps.calledOnceWith(collection, id, 0, 2)).to.be(true); + expect(ops.length).to.equal(2); + expect(ops[1].oi).to.equal('bar'); + expect(db._getSnapshotOpLink.notCalled).to.equal(true); + expect(db._getOps.calledOnceWith(collection, id, 0, 2)).to.equal(true); next(); }, done @@ -102,16 +102,16 @@ describe('getOpsWithoutStrictLinking: true', function() { callInSeries([ function(next) { - mongo.collection('o_' + collection).insert(spuriousOp, next); + mongo.db().collection('o_' + collection).insertOne(spuriousOp, next); }, function(result, next) { db.getOps(collection, id, 0, 2, null, next); }, function(ops, next) { - expect(ops.length).to.be(2); - expect(ops[1].oi).to.be('bar'); - expect(db._getSnapshotOpLink.notCalled).to.be(true); - expect(db._getOps.calledOnceWith(collection, id, 0, 3)).to.be(true); + expect(ops.length).to.equal(2); + expect(ops[1].oi).to.equal('bar'); + expect(db._getSnapshotOpLink.notCalled).to.equal(true); + expect(db._getOps.calledOnceWith(collection, id, 0, 3)).to.equal(true); next(); }, done @@ -128,16 +128,16 @@ describe('getOpsWithoutStrictLinking: true', function() { callInSeries([ function(next) { - mongo.collection('o_' + collection).insertMany(spuriousOps, next); + mongo.db().collection('o_' + collection).insertMany(spuriousOps, next); }, function(result, next) { db.getOps(collection, id, 0, 2, null, next); }, function(ops, next) { - expect(ops.length).to.be(2); + expect(ops.length).to.equal(2); expect(ops[0].create).to.eql({}); - expect(ops[1].oi).to.be('bar'); - expect(db._getSnapshotOpLink.calledOnce).to.be(true); + expect(ops[1].oi).to.equal('bar'); + expect(db._getSnapshotOpLink.calledOnce).to.equal(true); next(); }, done @@ -163,7 +163,7 @@ function commitOpChain(db, mongo, collection, id, ops, previousOpId, version, ca var snapshot = {id: id, v: version + 1, type: 'json0', data: {}, m: null, _opLink: previousOpId}; db.commit(collection, id, op, snapshot, null, function(error) { if (error) return callback(error); - mongo.collection('o_' + collection).find({d: id, v: version}).next(function(error, op) { + mongo.db().collection('o_' + collection).find({d: id, v: version}).next(function(error, op) { if (error) return callback(error); commitOpChain(db, mongo, collection, id, ops, op._id, ++version, callback); }); diff --git a/test/test_mongo.js b/test/test_mongo.js index 7a75c955..1de639cf 100644 --- a/test/test_mongo.js +++ b/test/test_mongo.js @@ -1,4 +1,4 @@ -var expect = require('expect.js'); +var expect = require('chai').expect; var mongodb = require('mongodb'); var ShareDbMongo = require('../index'); var getQuery = require('sharedb-mingo-memory/get-query'); @@ -9,7 +9,7 @@ function create(callback) { var db = new ShareDbMongo({mongo: function(shareDbCallback) { mongodb.connect(mongoUrl, function(err, mongo) { if (err) return callback(err); - mongo.dropDatabase(function(err) { + mongo.db().dropDatabase(function(err) { if (err) return callback(err); shareDbCallback(null, mongo); callback(null, db, mongo); @@ -40,12 +40,12 @@ describe('mongo db', function() { var mongo = this.mongo; this.db.commit('testcollection', 'foo', {v: 0, create: {}}, {}, null, function(err) { if (err) return done(err); - mongo.collection('o_testcollection').indexInformation(function(err, indexes) { + mongo.db().collection('o_testcollection').indexInformation(function(err, indexes) { if (err) return done(err); // Index for getting document(s) ops - expect(indexes['d_1_v_1']).ok(); + expect(indexes['d_1_v_1']).ok; // Index for checking committed op(s) by src and seq - expect(indexes['src_1_seq_1_v_1']).ok(); + expect(indexes['src_1_seq_1_v_1']).ok; done(); }); }); @@ -53,7 +53,7 @@ describe('mongo db', function() { it('respects unique indexes', function(done) { var db = this.db; - this.mongo.collection('testcollection').createIndex({x: 1}, {unique: true}, function(err) { + this.mongo.db().collection('testcollection').createIndex({x: 1}, {unique: true}, function(err) { if (err) return done(err); db.commit('testcollection', 'foo', {v: 0, create: {}}, {v: 1, data: {x: 7}}, null, function(err) { if (err) return done(err); @@ -70,9 +70,9 @@ describe('mongo db', function() { it('does not allow editing the system collection', function(done) { var db = this.db; db.commit('system', 'test', {v: 0, create: {}}, {}, null, function(err) { - expect(err).ok(); + expect(err).ok; db.getSnapshot('system', 'test', null, null, function(err) { - expect(err).ok(); + expect(err).ok; done(); }); }); @@ -85,21 +85,21 @@ describe('mongo db', function() { it('does not allow $where queries', function(done) { this.db.query('testcollection', {$where: 'true'}, null, null, function(err) { - expect(err).ok(); + expect(err).ok; done(); }); }); it('queryPollDoc does not allow $where queries', function(done) { this.db.queryPollDoc('testcollection', 'somedoc', {$where: 'true'}, null, function(err) { - expect(err).ok(); + expect(err).ok; done(); }); }); it('$query is deprecated', function(done) { this.db.query('testcollection', {$query: {}}, null, null, function(err) { - expect(err).ok(); + expect(err).ok; expect(err.code).eql(4106); done(); }); @@ -107,7 +107,7 @@ describe('mongo db', function() { it('only one collection operation allowed', function(done) { this.db.query('testcollection', {$distinct: {y: 1}, $aggregate: {}}, null, null, function(err) { - expect(err).ok(); + expect(err).ok; expect(err.code).eql(4108); done(); }); @@ -115,7 +115,7 @@ describe('mongo db', function() { it('only one cursor operation allowed', function(done) { this.db.query('testcollection', {$count: true, $explain: true}, null, null, function(err) { - expect(err).ok(); + expect(err).ok; expect(err.code).eql(4109); done(); }); @@ -123,7 +123,7 @@ describe('mongo db', function() { it('cursor transform can\'t run after collection operation', function(done) { this.db.query('testcollection', {$distinct: {y: 1}, $sort: {y: 1}}, null, null, function(err) { - expect(err).ok(); + expect(err).ok; expect(err.code).eql(4110); done(); }); @@ -131,7 +131,7 @@ describe('mongo db', function() { it('cursor operation can\'t run after collection operation', function(done) { this.db.query('testcollection', {$distinct: {y: 1}, $count: true}, null, null, function(err) { - expect(err).ok(); + expect(err).ok; expect(err.code).eql(4110); done(); }); @@ -139,7 +139,7 @@ describe('mongo db', function() { it('non-object $readPref should return error', function(done) { this.db.query('testcollection', {$readPref: true}, null, null, function(err) { - expect(err).ok(); + expect(err).ok; expect(err.code).eql(4107); done(); }); @@ -148,7 +148,7 @@ describe('mongo db', function() { it('malformed $mapReduce should return error', function(done) { this.db.allowJSQueries = true; // required for $mapReduce this.db.query('testcollection', {$mapReduce: true}, null, null, function(err) { - expect(err).ok(); + expect(err).ok; expect(err.code).eql(4107); done(); }); @@ -255,7 +255,7 @@ describe('mongo db', function() { {$sort: {count: 1}} ]}; this.db.query('testcollection', query, null, null, function(err) { - expect(err).ok(); + expect(err).ok; done(); }); }); @@ -286,7 +286,7 @@ describe('mongo db', function() { } }; db.query('testcollection', query, null, null, function(err) { - expect(err).ok(); + expect(err).ok; done(); }); }); @@ -341,7 +341,7 @@ describe('mongo db connection', function() { // logic. this.db.getDbs(function(err, mongo) { if (err) return done(err); - mongo.dropDatabase(function(err) { + mongo.db().dropDatabase(function(err) { if (err) return done(err); done(); }); diff --git a/test/test_op_link_validator.js b/test/test_op_link_validator.js index c2366aed..70aa8324 100644 --- a/test/test_op_link_validator.js +++ b/test/test_op_link_validator.js @@ -1,16 +1,16 @@ var OpLinkValidator = require('../op-link-validator'); -var expect = require('expect.js'); +var expect = require('chai').expect; describe('OpLinkValidator', function() { it('starts with no unique op', function() { var validator = new OpLinkValidator(); var opWithUniqueVersion = validator.opWithUniqueVersion(); - expect(opWithUniqueVersion).to.be(null); + expect(opWithUniqueVersion).to.equal(null); }); it('starts not at the end of the list', function() { var validator = new OpLinkValidator(); - expect(validator.isAtEndOfList()).to.be(false); + expect(validator.isAtEndOfList()).to.equal(false); }); it('has no unique op with just one op', function() { @@ -20,7 +20,7 @@ describe('OpLinkValidator', function() { validator.push(op); var opWithUniqueVersion = validator.opWithUniqueVersion(); - expect(opWithUniqueVersion).to.be(null); + expect(opWithUniqueVersion).to.equal(null); }); it('has a unique op with just two different ops', function() { @@ -32,7 +32,7 @@ describe('OpLinkValidator', function() { validator.push(op2); var opWithUniqueVersion = validator.opWithUniqueVersion(); - expect(opWithUniqueVersion).to.be(op1); + expect(opWithUniqueVersion).to.equal(op1); }); it('does not have a uniquye op with just two identical ops', function() { @@ -44,7 +44,7 @@ describe('OpLinkValidator', function() { validator.push(op2); var opWithUniqueVersion = validator.opWithUniqueVersion(); - expect(opWithUniqueVersion).to.be(null); + expect(opWithUniqueVersion).to.equal(null); }); it('has a unique op with three ops with different versions', function() { @@ -58,7 +58,7 @@ describe('OpLinkValidator', function() { validator.push(op3); var opWithUniqueVersion = validator.opWithUniqueVersion(); - expect(opWithUniqueVersion).to.be(op2); + expect(opWithUniqueVersion).to.equal(op2); }); it('is not at the end of the list with three ops', function() { @@ -71,7 +71,7 @@ describe('OpLinkValidator', function() { validator.push(op2); validator.push(op3); - expect(validator.isAtEndOfList()).to.be(false); + expect(validator.isAtEndOfList()).to.equal(false); }); it('does not have a unique op with three ops with the same version', function() { @@ -83,7 +83,7 @@ describe('OpLinkValidator', function() { validator.push(op); var opWithUniqueVersion = validator.opWithUniqueVersion(); - expect(opWithUniqueVersion).to.be(null); + expect(opWithUniqueVersion).to.equal(null); }); it('does not have a unique op if the first two ops are the same', function() { @@ -97,7 +97,7 @@ describe('OpLinkValidator', function() { validator.push(op3); var opWithUniqueVersion = validator.opWithUniqueVersion(); - expect(opWithUniqueVersion).to.be(null); + expect(opWithUniqueVersion).to.equal(null); }); it('does not have a unique op if the last two ops are the same', function() { @@ -111,7 +111,7 @@ describe('OpLinkValidator', function() { validator.push(op3); var opWithUniqueVersion = validator.opWithUniqueVersion(); - expect(opWithUniqueVersion).to.be(null); + expect(opWithUniqueVersion).to.equal(null); }); it('has a unique op in a long chain', function() { @@ -133,7 +133,7 @@ describe('OpLinkValidator', function() { validator.push(op7); var opWithUniqueVersion = validator.opWithUniqueVersion(); - expect(opWithUniqueVersion).to.be(op6); + expect(opWithUniqueVersion).to.equal(op6); }); it('has a unique op with two ops and a current op of null', function() { @@ -147,13 +147,13 @@ describe('OpLinkValidator', function() { validator.push(op3); var opWithUniqueVersion = validator.opWithUniqueVersion(); - expect(opWithUniqueVersion).to.be(op2); + expect(opWithUniqueVersion).to.equal(op2); }); it('is at the end of the list with a current op of null', function() { var op = null; var validator = new OpLinkValidator(); validator.push(op); - expect(validator.isAtEndOfList()).to.be(true); + expect(validator.isAtEndOfList()).to.equal(true); }); }); diff --git a/test/test_skip_poll.js b/test/test_skip_poll.js index fae3a679..587f4058 100644 --- a/test/test_skip_poll.js +++ b/test/test_skip_poll.js @@ -1,4 +1,4 @@ -var expect = require('expect.js'); +var expect = require('chai').expect; var ShareDbMongo = require('../index'); describe('skipPoll', function() {