Comparing version 1.8.0 to 1.8.1
{ | ||
"name": "sharedb", | ||
"version": "1.8.0", | ||
"version": "1.8.1", | ||
"description": "JSON OT database backend", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -6,3 +6,3 @@ var expect = require('chai').expect; | ||
var getQuery = options.getQuery; | ||
var matchAllQuery = getQuery({query: {}}); | ||
var matchAllQuery = getQuery && getQuery({query: {}}); | ||
@@ -30,14 +30,16 @@ describe('client projections', function() { | ||
['createFetchQuery', 'createSubscribeQuery'].forEach(function(method) { | ||
it('snapshot ' + method, function(done) { | ||
var connection2 = this.backend.connect(); | ||
connection2[method]('dogs_summary', matchAllQuery, null, function(err, results) { | ||
if (err) return done(err); | ||
expect(results.length).eql(1); | ||
expect(results[0].data).eql({age: 3, owner: {name: 'jim'}}); | ||
expect(results[0].version).eql(1); | ||
done(); | ||
if (getQuery) { | ||
['createFetchQuery', 'createSubscribeQuery'].forEach(function(method) { | ||
it('snapshot ' + method, function(done) { | ||
var connection2 = this.backend.connect(); | ||
connection2[method]('dogs_summary', matchAllQuery, null, function(err, results) { | ||
if (err) return done(err); | ||
expect(results.length).eql(1); | ||
expect(results[0].data).eql({age: 3, owner: {name: 'jim'}}); | ||
expect(results[0].version).eql(1); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
} | ||
@@ -138,13 +140,32 @@ function opTests(test) { | ||
describe('op fetch query', function() { | ||
function test(op, expected, done) { | ||
var connection = this.connection; | ||
var connection2 = this.backend.connect(); | ||
var fido = connection2.get('dogs_summary', 'fido'); | ||
fido.fetch(function(err) { | ||
if (err) return done(err); | ||
connection.get('dogs', 'fido').submitOp(op, function(err) { | ||
if (getQuery) { | ||
describe('op fetch query', function() { | ||
function test(op, expected, done) { | ||
var connection = this.connection; | ||
var connection2 = this.backend.connect(); | ||
var fido = connection2.get('dogs_summary', 'fido'); | ||
fido.fetch(function(err) { | ||
if (err) return done(err); | ||
connection2.createFetchQuery('dogs_summary', matchAllQuery, null, function(err) { | ||
connection.get('dogs', 'fido').submitOp(op, function(err) { | ||
if (err) return done(err); | ||
connection2.createFetchQuery('dogs_summary', matchAllQuery, null, function(err) { | ||
if (err) return done(err); | ||
expect(fido.data).eql(expected); | ||
expect(fido.version).eql(2); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}; | ||
opTests(test); | ||
}); | ||
describe('op subscribe query', function() { | ||
function test(op, expected, done) { | ||
var connection = this.connection; | ||
var connection2 = this.backend.connect(); | ||
var fido = connection2.get('dogs_summary', 'fido'); | ||
connection2.createSubscribeQuery('dogs_summary', matchAllQuery, null, function(err) { | ||
if (err) return done(err); | ||
fido.on('op', function() { | ||
expect(fido.data).eql(expected); | ||
@@ -154,97 +175,80 @@ expect(fido.version).eql(2); | ||
}); | ||
connection.get('dogs', 'fido').submitOp(op); | ||
}); | ||
}); | ||
}; | ||
opTests(test); | ||
}); | ||
describe('op subscribe query', function() { | ||
function test(op, expected, done) { | ||
var connection = this.connection; | ||
var connection2 = this.backend.connect(); | ||
var fido = connection2.get('dogs_summary', 'fido'); | ||
connection2.createSubscribeQuery('dogs_summary', matchAllQuery, null, function(err) { | ||
if (err) return done(err); | ||
fido.on('op', function() { | ||
expect(fido.data).eql(expected); | ||
expect(fido.version).eql(2); | ||
done(); | ||
}); | ||
connection.get('dogs', 'fido').submitOp(op); | ||
}); | ||
}; | ||
opTests(test); | ||
}); | ||
function queryUpdateTests(test) { | ||
it('doc create', function(done) { | ||
test.call(this, | ||
function(connection, callback) { | ||
var data = {age: 5, color: 'spotted', owner: {name: 'sue'}, litter: {count: 6}}; | ||
connection.get('dogs', 'spot').create(data, callback); | ||
}, | ||
function(err, results) { | ||
var sorted = util.sortById(results.slice()); | ||
expect(sorted.length).eql(2); | ||
expect(util.pluck(sorted, 'id')).eql(['fido', 'spot']); | ||
expect(util.pluck(sorted, 'data')).eql([ | ||
{age: 3, owner: {name: 'jim'}}, | ||
{age: 5, owner: {name: 'sue'}} | ||
]); | ||
done(); | ||
} | ||
); | ||
}; | ||
opTests(test); | ||
}); | ||
} | ||
describe('subscribe query', function() { | ||
function test(trigger, callback) { | ||
var connection = this.connection; | ||
var connection2 = this.backend.connect(); | ||
var query = connection2.createSubscribeQuery('dogs_summary', matchAllQuery, null, function(err) { | ||
if (err) return callback(err); | ||
query.on('insert', function() { | ||
callback(null, query.results); | ||
}); | ||
trigger(connection); | ||
function queryUpdateTests(test) { | ||
it('doc create', function(done) { | ||
test.call(this, | ||
function(connection, callback) { | ||
var data = {age: 5, color: 'spotted', owner: {name: 'sue'}, litter: {count: 6}}; | ||
connection.get('dogs', 'spot').create(data, callback); | ||
}, | ||
function(err, results) { | ||
var sorted = util.sortById(results.slice()); | ||
expect(sorted.length).eql(2); | ||
expect(util.pluck(sorted, 'id')).eql(['fido', 'spot']); | ||
expect(util.pluck(sorted, 'data')).eql([ | ||
{age: 3, owner: {name: 'jim'}}, | ||
{age: 5, owner: {name: 'sue'}} | ||
]); | ||
done(); | ||
} | ||
); | ||
}); | ||
} | ||
queryUpdateTests(test); | ||
it('query subscribe on projection will update based on fields not in projection', function(done) { | ||
// Create a query on a field not in the projection. The query doesn't | ||
// match the doc created in beforeEach | ||
var fido = this.connection.get('dogs', 'fido'); | ||
var connection2 = this.backend.connect(); | ||
var dbQuery = getQuery({query: {color: 'black'}}); | ||
var query = connection2.createSubscribeQuery('dogs_summary', dbQuery, null, function(err, results) { | ||
if (err) return done(err); | ||
expect(results).to.have.length(0); | ||
describe('subscribe query', function() { | ||
function test(trigger, callback) { | ||
var connection = this.connection; | ||
var connection2 = this.backend.connect(); | ||
var query = connection2.createSubscribeQuery('dogs_summary', matchAllQuery, null, function(err) { | ||
if (err) return callback(err); | ||
query.on('insert', function() { | ||
callback(null, query.results); | ||
}); | ||
trigger(connection); | ||
}); | ||
} | ||
queryUpdateTests(test); | ||
// Submit an op on a field not in the projection, where the op should | ||
// cause the doc to be included in the query results | ||
fido.submitOp({p: ['color'], od: 'gold', oi: 'black'}, null, function(err) { | ||
it('query subscribe on projection will update based on fields not in projection', function(done) { | ||
// Create a query on a field not in the projection. The query doesn't | ||
// match the doc created in beforeEach | ||
var fido = this.connection.get('dogs', 'fido'); | ||
var connection2 = this.backend.connect(); | ||
var dbQuery = getQuery({query: {color: 'black'}}); | ||
var query = connection2.createSubscribeQuery('dogs_summary', dbQuery, null, function(err, results) { | ||
if (err) return done(err); | ||
setTimeout(function() { | ||
expect(query.results).to.have.length(1); | ||
expect(query.results[0].id).to.equal('fido'); | ||
expect(query.results[0].data).to.eql({age: 3, owner: {name: 'jim'}}); | ||
done(); | ||
}, 10); | ||
expect(results).to.have.length(0); | ||
// Submit an op on a field not in the projection, where the op should | ||
// cause the doc to be included in the query results | ||
fido.submitOp({p: ['color'], od: 'gold', oi: 'black'}, null, function(err) { | ||
if (err) return done(err); | ||
setTimeout(function() { | ||
expect(query.results).to.have.length(1); | ||
expect(query.results[0].id).to.equal('fido'); | ||
expect(query.results[0].data).to.eql({age: 3, owner: {name: 'jim'}}); | ||
done(); | ||
}, 10); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('fetch query', function() { | ||
function test(trigger, callback) { | ||
var connection = this.connection; | ||
var connection2 = this.backend.connect(); | ||
trigger(connection, function(err) { | ||
if (err) return callback(err); | ||
connection2.createFetchQuery('dogs_summary', matchAllQuery, null, callback); | ||
}); | ||
} | ||
queryUpdateTests(test); | ||
}); | ||
describe('fetch query', function() { | ||
function test(trigger, callback) { | ||
var connection = this.connection; | ||
var connection2 = this.backend.connect(); | ||
trigger(connection, function(err) { | ||
if (err) return callback(err); | ||
connection2.createFetchQuery('dogs_summary', matchAllQuery, null, callback); | ||
}); | ||
} | ||
queryUpdateTests(test); | ||
}); | ||
} | ||
@@ -251,0 +255,0 @@ describe('submit on projected doc', function() { |
@@ -11,3 +11,2 @@ var expect = require('chai').expect; | ||
before(function() { | ||
if (!getQuery) return this.skip(); | ||
this.matchAllDbQuery = getQuery({query: {}}); | ||
@@ -14,0 +13,0 @@ }); |
@@ -10,3 +10,2 @@ var expect = require('chai').expect; | ||
before(function() { | ||
if (!getQuery) return this.skip(); | ||
this.matchAllDbQuery = getQuery({query: {}}); | ||
@@ -13,0 +12,0 @@ }); |
179
test/db.js
@@ -6,11 +6,23 @@ var async = require('async'); | ||
/** | ||
* Run the DB test suite. Useful for testing external DB adapters: | ||
* require('sharedb/test/db')(options); | ||
* | ||
* options.create() should instantiate a database adapter and call the | ||
* provided callback with it. | ||
* options.create = function(callback) { | ||
* // Create instance of Db | ||
* callback(error, db); | ||
* } | ||
* | ||
* options.getQuery() is optional, and only needed if the adapter supports | ||
* queries. It needs to accept the "generic" query provided by the | ||
* test suite, and return a query specific to the adapter. | ||
* options.getQuery = function(genericQuery) { | ||
* // map genericQuery into adapter-specific query | ||
* return mappedQuery; | ||
* } | ||
*/ | ||
module.exports = function(options) { | ||
var create = options.create; | ||
function getQuery(queryOptions) { | ||
for (var key in queryOptions.query) { | ||
var mongoKey = (key[0] === '$' || (key.indexOf('.') !== -1)); | ||
if (mongoKey) throw new Error('unsupported in tests: ' + key); | ||
} | ||
return options.getQuery(queryOptions); | ||
} | ||
@@ -50,5 +62,8 @@ describe('db', function() { | ||
require('./client/projections')({getQuery: getQuery}); | ||
require('./client/query-subscribe')({getQuery: getQuery}); | ||
require('./client/query')({getQuery: getQuery}); | ||
if (options.getQuery) { | ||
require('./client/query-subscribe')({getQuery: options.getQuery}); | ||
require('./client/query')({getQuery: options.getQuery}); | ||
} | ||
require('./client/projections')({getQuery: options.getQuery}); | ||
require('./client/submit')(); | ||
@@ -744,100 +759,102 @@ require('./client/submit-json1')(); | ||
describe('queryPoll', function() { | ||
it('returns data in the collection', function(done) { | ||
var snapshot = {v: 1, type: 'json0', data: {x: 5, y: 6}}; | ||
var db = this.db; | ||
db.commit('testcollection', 'test', {v: 0, create: {}}, snapshot, null, function(err) { | ||
if (err) return done(err); | ||
var dbQuery = getQuery({query: {x: 5}}); | ||
db.queryPoll('testcollection', dbQuery, null, function(err, ids) { | ||
if (options.getQuery) { | ||
describe('queryPoll', function() { | ||
it('returns data in the collection', function(done) { | ||
var snapshot = {v: 1, type: 'json0', data: {x: 5, y: 6}}; | ||
var db = this.db; | ||
db.commit('testcollection', 'test', {v: 0, create: {}}, snapshot, null, function(err) { | ||
if (err) return done(err); | ||
expect(ids).eql(['test']); | ||
done(); | ||
var dbQuery = options.getQuery({query: {x: 5}}); | ||
db.queryPoll('testcollection', dbQuery, null, function(err, ids) { | ||
if (err) return done(err); | ||
expect(ids).eql(['test']); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
it('returns nothing when there is no data', function(done) { | ||
var dbQuery = getQuery({query: {x: 5}}); | ||
this.db.queryPoll('testcollection', dbQuery, null, function(err, ids) { | ||
if (err) return done(err); | ||
expect(ids).eql([]); | ||
done(); | ||
it('returns nothing when there is no data', function(done) { | ||
var dbQuery = options.getQuery({query: {x: 5}}); | ||
this.db.queryPoll('testcollection', dbQuery, null, function(err, ids) { | ||
if (err) return done(err); | ||
expect(ids).eql([]); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('queryPollDoc', function() { | ||
it('returns false when the document does not exist', function(done) { | ||
var dbQuery = getQuery({query: {}}); | ||
if (!this.db.canPollDoc('testcollection', dbQuery)) return done(); | ||
describe('queryPollDoc', function() { | ||
it('returns false when the document does not exist', function(done) { | ||
var dbQuery = options.getQuery({query: {}}); | ||
if (!this.db.canPollDoc('testcollection', dbQuery)) return done(); | ||
var db = this.db; | ||
db.queryPollDoc('testcollection', 'doesnotexist', dbQuery, null, function(err, result) { | ||
if (err) return done(err); | ||
expect(result).equal(false); | ||
done(); | ||
var db = this.db; | ||
db.queryPollDoc('testcollection', 'doesnotexist', dbQuery, null, function(err, result) { | ||
if (err) return done(err); | ||
expect(result).equal(false); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('returns true when the document matches', function(done) { | ||
var dbQuery = getQuery({query: {x: 5}}); | ||
if (!this.db.canPollDoc('testcollection', dbQuery)) return done(); | ||
it('returns true when the document matches', function(done) { | ||
var dbQuery = options.getQuery({query: {x: 5}}); | ||
if (!this.db.canPollDoc('testcollection', dbQuery)) return done(); | ||
var snapshot = {type: 'json0', v: 1, data: {x: 5, y: 6}}; | ||
var db = this.db; | ||
db.commit('testcollection', 'test', {v: 0, create: {}}, snapshot, null, function(err) { | ||
if (err) return done(err); | ||
db.queryPollDoc('testcollection', 'test', dbQuery, null, function(err, result) { | ||
var snapshot = {type: 'json0', v: 1, data: {x: 5, y: 6}}; | ||
var db = this.db; | ||
db.commit('testcollection', 'test', {v: 0, create: {}}, snapshot, null, function(err) { | ||
if (err) return done(err); | ||
expect(result).equal(true); | ||
done(); | ||
db.queryPollDoc('testcollection', 'test', dbQuery, null, function(err, result) { | ||
if (err) return done(err); | ||
expect(result).equal(true); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
it('returns false when the document does not match', function(done) { | ||
var dbQuery = getQuery({query: {x: 6}}); | ||
if (!this.db.canPollDoc('testcollection', dbQuery)) return done(); | ||
it('returns false when the document does not match', function(done) { | ||
var dbQuery = options.getQuery({query: {x: 6}}); | ||
if (!this.db.canPollDoc('testcollection', dbQuery)) return done(); | ||
var snapshot = {type: 'json0', v: 1, data: {x: 5, y: 6}}; | ||
var db = this.db; | ||
db.commit('testcollection', 'test', {v: 0, create: {}}, snapshot, null, function(err) { | ||
if (err) return done(err); | ||
db.queryPollDoc('testcollection', 'test', dbQuery, null, function(err, result) { | ||
var snapshot = {type: 'json0', v: 1, data: {x: 5, y: 6}}; | ||
var db = this.db; | ||
db.commit('testcollection', 'test', {v: 0, create: {}}, snapshot, null, function(err) { | ||
if (err) return done(err); | ||
expect(result).equal(false); | ||
done(); | ||
db.queryPollDoc('testcollection', 'test', dbQuery, null, function(err, result) { | ||
if (err) return done(err); | ||
expect(result).equal(false); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('getQuery', function() { | ||
it('getQuery argument order', function(done) { | ||
// test that getQuery({query: {}, sort: [['foo', 1], ['bar', -1]]}) | ||
// sorts by foo first, then bar | ||
var snapshots = [ | ||
{type: 'json0', id: '0', v: 1, data: {foo: 1, bar: 1}, m: null}, | ||
{type: 'json0', id: '1', v: 1, data: {foo: 2, bar: 1}, m: null}, | ||
{type: 'json0', id: '2', v: 1, data: {foo: 1, bar: 2}, m: null}, | ||
{type: 'json0', id: '3', v: 1, data: {foo: 2, bar: 2}, m: null} | ||
]; | ||
var db = this.db; | ||
var dbQuery = getQuery({query: {}, sort: [['foo', 1], ['bar', -1]]}); | ||
describe('getQuery', function() { | ||
it('getQuery argument order', function(done) { | ||
// test that options.getQuery({query: {}, sort: [['foo', 1], ['bar', -1]]}) | ||
// sorts by foo first, then bar | ||
var snapshots = [ | ||
{type: 'json0', id: '0', v: 1, data: {foo: 1, bar: 1}, m: null}, | ||
{type: 'json0', id: '1', v: 1, data: {foo: 2, bar: 1}, m: null}, | ||
{type: 'json0', id: '2', v: 1, data: {foo: 1, bar: 2}, m: null}, | ||
{type: 'json0', id: '3', v: 1, data: {foo: 2, bar: 2}, m: null} | ||
]; | ||
var db = this.db; | ||
var dbQuery = options.getQuery({query: {}, sort: [['foo', 1], ['bar', -1]]}); | ||
async.each(snapshots, function(snapshot, cb) { | ||
db.commit('testcollection', snapshot.id, {v: 0, create: {}}, snapshot, null, cb); | ||
}, function(err) { | ||
if (err) throw err; | ||
db.query('testcollection', dbQuery, null, null, function(err, results) { | ||
async.each(snapshots, function(snapshot, cb) { | ||
db.commit('testcollection', snapshot.id, {v: 0, create: {}}, snapshot, null, cb); | ||
}, function(err) { | ||
if (err) throw err; | ||
expect(results).eql( | ||
[snapshots[2], snapshots[0], snapshots[3], snapshots[1]]); | ||
done(); | ||
db.query('testcollection', dbQuery, null, null, function(err, results) { | ||
if (err) throw err; | ||
expect(results).eql( | ||
[snapshots[2], snapshots[0], snapshots[3], snapshots[1]]); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
} | ||
}); | ||
}; |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
2635837
15992
17