From 5ef444e45d72ff18df5c99818e2ab25b09748740 Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Wed, 13 May 2015 09:36:29 -0700 Subject: [PATCH] Conditionally pass options to connector CRUD methods --- lib/connectors/memory.js | 36 +++--- lib/dao.js | 253 ++++++++++++++++++++++++++++----------- test/datatype.test.js | 41 +++++-- test/memory.test.js | 84 ++++++++++++- 4 files changed, 304 insertions(+), 110 deletions(-) diff --git a/lib/connectors/memory.js b/lib/connectors/memory.js index 9e83b31c..613798a1 100644 --- a/lib/connectors/memory.js +++ b/lib/connectors/memory.js @@ -189,7 +189,7 @@ Memory.prototype.define = function defineModel(definition) { if(!this.collection(m)) this.initCollection(m); }; -Memory.prototype.create = function create(model, data, callback) { +Memory.prototype.create = function create(model, data, options, callback) { // FIXME: [rfeng] We need to generate unique ids based on the id type // FIXME: [rfeng] We don't support composite ids yet var currentId = this.collectionSeq(model); @@ -221,15 +221,15 @@ Memory.prototype.create = function create(model, data, callback) { this.saveToFile(id, callback); }; -Memory.prototype.updateOrCreate = function (model, data, callback) { +Memory.prototype.updateOrCreate = function (model, data, options, callback) { var self = this; - this.exists(model, self.getIdValue(model, data), function (err, exists) { + this.exists(model, self.getIdValue(model, data), options, function (err, exists) { if (exists) { - self.save(model, data, function(err, data) { + self.save(model, data, options, function(err, data) { callback(err, data, { isNewInstance: false }); }); } else { - self.create(model, data, function (err, id) { + self.create(model, data, options, function (err, id) { self.setIdValue(model, data, id); callback(err, data, { isNewInstance: true }); }); @@ -237,7 +237,7 @@ Memory.prototype.updateOrCreate = function (model, data, callback) { }); }; -Memory.prototype.save = function save(model, data, callback) { +Memory.prototype.save = function save(model, data, options, callback) { var id = this.getIdValue(model, data); var cachedModels = this.collection(model); var modelData = cachedModels && this.collection(model)[id]; @@ -251,19 +251,19 @@ Memory.prototype.save = function save(model, data, callback) { }); }; -Memory.prototype.exists = function exists(model, id, callback) { +Memory.prototype.exists = function exists(model, id, options, callback) { process.nextTick(function () { callback(null, this.collection(model) && this.collection(model).hasOwnProperty(id)); }.bind(this)); }; -Memory.prototype.find = function find(model, id, callback) { +Memory.prototype.find = function find(model, id, options, callback) { process.nextTick(function () { callback(null, id in this.collection(model) && this.fromDb(model, this.collection(model)[id])); }.bind(this)); }; -Memory.prototype.destroy = function destroy(model, id, callback) { +Memory.prototype.destroy = function destroy(model, id, options, callback) { delete this.collection(model)[id]; this.saveToFile(null, callback); }; @@ -310,7 +310,7 @@ function getValue(obj, path) { return val; } -Memory.prototype.all = function all(model, filter, callback) { +Memory.prototype.all = function all(model, filter, options, callback) { var self = this; var nodes = Object.keys(this.collection(model)).map(function (key) { return this.fromDb(model, this.collection(model)[key]); @@ -559,11 +559,7 @@ function applyFilter(filter) { } } -Memory.prototype.destroyAll = function destroyAll(model, where, callback) { - if (!callback && 'function' === typeof where) { - callback = where; - where = undefined; - } +Memory.prototype.destroyAll = function destroyAll(model, where, options, callback) { var cache = this.collection(model); var filter = null; var count = 0; @@ -582,7 +578,7 @@ Memory.prototype.destroyAll = function destroyAll(model, where, callback) { this.saveToFile({ count: count }, callback); }; -Memory.prototype.count = function count(model, callback, where) { +Memory.prototype.count = function count(model, where, options, callback) { var cache = this.collection(model); var data = Object.keys(cache); if (where) { @@ -598,7 +594,7 @@ Memory.prototype.count = function count(model, callback, where) { }; Memory.prototype.update = - Memory.prototype.updateAll = function updateAll(model, where, data, cb) { + Memory.prototype.updateAll = function updateAll(model, where, data, options, cb) { var self = this; var cache = this.collection(model); var filter = null; @@ -614,7 +610,7 @@ Memory.prototype.update = // The id value from the cache is string // Get the real id from the inst id = self.getIdValue(model, inst); - self.updateAttributes(model, id, data, done); + self.updateAttributes(model, id, data, options, done); } else { process.nextTick(done); } @@ -624,7 +620,7 @@ Memory.prototype.update = }); }; -Memory.prototype.updateAttributes = function updateAttributes(model, id, data, cb) { +Memory.prototype.updateAttributes = function updateAttributes(model, id, data, options, cb) { if (!id) { var err = new Error('You must provide an id when updating attributes!'); if (cb) { @@ -643,7 +639,7 @@ Memory.prototype.updateAttributes = function updateAttributes(model, id, data, c var modelData = cachedModels && this.collection(model)[id]; if (modelData) { - this.save(model, data, cb); + this.save(model, data, options, cb); } else { cb(new Error('Could not update attributes. Object with id ' + id + ' does not exist!')); } diff --git a/lib/dao.js b/lib/dao.js index fdc1cfa8..8492c3bc 100644 --- a/lib/dao.js +++ b/lib/dao.js @@ -124,6 +124,14 @@ DataAccessObject.lookupModel = function(data) { return this; }; +/** + * Get the connector instance for the given model class + * @returns {Connector} The connector instance + */ +DataAccessObject.getConnector = function() { + return this.getDataSource().connector; +} + // Empty callback function function noCallback(err, result) { // NOOP @@ -154,6 +162,10 @@ DataAccessObject.create = function (data, options, cb) { } var Model = this; + var connector = Model.getConnector(); + assert(typeof connector.create === 'function', + 'create() must be implemented by the connector'); + var self = this; if (options === undefined && cb === undefined) { @@ -260,7 +272,7 @@ DataAccessObject.create = function (data, options, cb) { var _idName = idName(Model); var modelName = Model.modelName; var val = removeUndefined(obj.toObject(true)); - this._adapter().create(modelName, this.constructor._forDB(val), function (err, id, rev) { + function createCallback(err, id, rev) { if (id) { obj.__data[_idName] = id; defineReadonlyProp(obj, _idName, id); @@ -290,7 +302,13 @@ DataAccessObject.create = function (data, options, cb) { }); }); }); - }, obj); + } + + if (connector.create.length === 4) { + connector.create(modelName, this.constructor._forDB(val), options, createCallback); + } else { + connector.create(modelName, this.constructor._forDB(val), createCallback); + } }, obj, cb); }, obj, cb); } @@ -363,6 +381,7 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data var self = this; var Model = this; + var connector = Model.getConnector(); var id = getIdValue(this, data); if (id === undefined || id === null) { @@ -381,7 +400,7 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data if (err) return cb(err); var isOriginalQuery = isWhereByGivenId(Model, ctx.query.where, id) - if (Model.getDataSource().connector.updateOrCreate && isOriginalQuery) { + if (connector.updateOrCreate && isOriginalQuery) { var context = { Model: Model, where: ctx.query.where, @@ -403,10 +422,15 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data Model.applyProperties(update, inst); Model = Model.lookupModel(update); + var connector = self.getConnector(); + if (Model.settings.validateUpsert === false) { update = removeUndefined(update); - self.getDataSource().connector - .updateOrCreate(Model.modelName, update, done); + if (connector.updateOrCreate.length === 4) { + connector.updateOrCreate(Model.modelName, update, options, done); + } else { + connector.updateOrCreate(Model.modelName, update, done); + } } else { inst.isValid(function(valid) { if (!valid) { @@ -421,8 +445,11 @@ DataAccessObject.updateOrCreate = DataAccessObject.upsert = function upsert(data } update = removeUndefined(update); - self.getDataSource().connector - .updateOrCreate(Model.modelName, update, done); + if (connector.updateOrCreate.length === 4) { + connector.updateOrCreate(Model.modelName, update, options, done); + } else { + connector.updateOrCreate(Model.modelName, update, done); + } }, update); } @@ -533,47 +560,52 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb) var Model = this; var self = this; + var connector = Model.getConnector(); function _findOrCreate(query, data) { var modelName = self.modelName; data = removeUndefined(data); - self.getDataSource().connector.findOrCreate(modelName, query, - self._forDB(data), - function(err, data, created) { - var obj, Model = self.lookupModel(data); + function findOrCreateCallback(err, data, created) { + var obj, Model = self.lookupModel(data); - if (data) { - obj = new Model(data, {fields: query.fields, applySetters: false, - persisted: true}); - } + if (data) { + obj = new Model(data, {fields: query.fields, applySetters: false, + persisted: true}); + } - if (created) { - var context = { - Model: Model, - instance: obj, - isNewInstance: true, - hookState: hookState, - options: options - }; - Model.notifyObserversOf('after save', context, function(err) { - if (cb.promise) { - cb(err, [obj, created]); - } else { - cb(err, obj, created); - } - if (!err) Model.emit('changed', obj); - }); - } else { + if (created) { + var context = { + Model: Model, + instance: obj, + isNewInstance: true, + hookState: hookState, + options: options + }; + Model.notifyObserversOf('after save', context, function(err) { if (cb.promise) { cb(err, [obj, created]); } else { cb(err, obj, created); } + if (!err) Model.emit('changed', obj); + }); + } else { + if (cb.promise) { + cb(err, [obj, created]); + } else { + cb(err, obj, created); } - }); + } + } + + if (connector.findOrCreate.length === 5) { + connector.findOrCreate(modelName, query, self._forDB(data), options, findOrCreateCallback); + } else { + connector.findOrCreate(modelName, query, self._forDB(data), findOrCreateCallback); + } } - if (this.getDataSource().connector.findOrCreate) { + if (connector.findOrCreate) { query.limit = 1; try { @@ -707,7 +739,7 @@ DataAccessObject.exists = function exists(id, options, cb) { * @param {Object} [options] Options * @param {Function} cb Callback called with (err, instance) */ -DataAccessObject.findById = function find(id, filter, options, cb) { +DataAccessObject.findById = function findById(id, filter, options, cb) { var connectionPromise = stillConnecting(this.getDataSource(), this, arguments); if (connectionPromise) { return connectionPromise; @@ -1179,6 +1211,10 @@ DataAccessObject.find = function find(query, options, cb) { var hookState = {}; var self = this; + var connector = self.getConnector(); + + assert(typeof connector.all === 'function', + 'all() must be implemented by the connector'); try { this._normalize(query); @@ -1192,12 +1228,12 @@ DataAccessObject.find = function find(query, options, cb) { this.applyScope(query); var near = query && geo.nearFilter(query.where); - var supportsGeo = !!this.getDataSource().connector.buildNearFilter; + var supportsGeo = !!connector.buildNearFilter; if (near) { if (supportsGeo) { // convert it - this.getDataSource().connector.buildNearFilter(query, near); + connector.buildNearFilter(query, near); } else if (query.where) { // do in memory query // using all documents @@ -1212,7 +1248,7 @@ DataAccessObject.find = function find(query, options, cb) { self.notifyObserversOf('access', context, function(err, ctx) { if (err) return cb(err); - self.getDataSource().connector.all(self.modelName, {}, function (err, data) { + function geoCallback(err, data) { var memory = new Memory(); var modelName = self.modelName; @@ -1225,18 +1261,24 @@ DataAccessObject.find = function find(query, options, cb) { model: self }); - data.forEach(function (obj) { - memory.create(modelName, obj, function () { + data.forEach(function(obj) { + memory.create(modelName, obj, options, function() { // noop }); }); // FIXME: apply "includes" and other transforms - see allCb below - memory.all(modelName, ctx.query, cb); + memory.all(modelName, ctx.query, options, cb); } else { cb(null, []); } - }); + } + + if (connector.all.length === 4) { + connector.all(self.modelName, {}, options, geoCallback); + } else { + connector.all(self.modelName, {}, geoCallback); + } }); // already handled @@ -1301,7 +1343,11 @@ DataAccessObject.find = function find(query, options, cb) { }; if (options.notify === false) { - self.getDataSource().connector.all(self.modelName, query, allCb); + if (connector.all.length === 4) { + connector.all(self.modelName, query, options, allCb); + } else { + connector.all(self.modelName, query, allCb); + } } else { var context = { Model: this, @@ -1312,7 +1358,11 @@ DataAccessObject.find = function find(query, options, cb) { this.notifyObserversOf('access', context, function(err, ctx) { if (err) return cb(err); var query = ctx.query; - self.getDataSource().connector.all(self.modelName, query, allCb); + if (connector.all.length === 4) { + connector.all(self.modelName, query, options, allCb); + } else { + connector.all(self.modelName, query, allCb); + } }); } return cb.promise; @@ -1381,6 +1431,10 @@ DataAccessObject.remove = DataAccessObject.deleteAll = DataAccessObject.destroyA } var Model = this; + var connector = Model.getConnector(); + + assert(typeof connector.destroyAll === 'function', + 'destroyAll() must be implemented by the connector'); if (options === undefined && cb === undefined) { if (typeof where === 'function') { @@ -1442,7 +1496,11 @@ DataAccessObject.remove = DataAccessObject.deleteAll = DataAccessObject.destroyA function doDelete(where) { if (whereIsEmpty(where)) { - Model.getDataSource().connector.destroyAll(Model.modelName, done); + if (connector.destroyAll.length === 4) { + connector.destroyAll(Model.modelName, {}, options, done); + } else { + connector.destroyAll(Model.modelName, {}, done); + } } else { try { // Support an optional where object @@ -1454,7 +1512,11 @@ DataAccessObject.remove = DataAccessObject.deleteAll = DataAccessObject.destroyA }); } - Model.getDataSource().connector.destroyAll(Model.modelName, where, done); + if (connector.destroyAll.length === 4) { + connector.destroyAll(Model.modelName, where, options, done); + } else { + connector.destroyAll(Model.modelName, where, done); + } } @@ -1577,6 +1639,13 @@ DataAccessObject.count = function (where, options, cb) { assert(typeof options === 'object', 'The options argument must be an object'); assert(typeof cb === 'function', 'The cb argument must be a function'); + var Model = this; + var connector = Model.getConnector(); + assert(typeof connector.count === 'function', + 'count() must be implemented by the connector'); + assert(connector.count.length >= 3, + 'count() must take at least 3 arguments'); + var hookState = {}; var query = { where: where }; @@ -1593,8 +1662,6 @@ DataAccessObject.count = function (where, options, cb) { return cb.promise; } - var Model = this; - var context = { Model: Model, query: { where: where }, @@ -1602,10 +1669,19 @@ DataAccessObject.count = function (where, options, cb) { options: options }; this.notifyObserversOf('access', context, function(err, ctx) { - if (err) return cb(err); - where = ctx.query.where; - Model.getDataSource().connector.count(Model.modelName, cb, where); - }); + if (err) return cb(err); + where = ctx.query.where; + + if (connector.count.length <= 3) { + // Old signature, please note where is the last + // count(model, cb, where) + connector.count(Model.modelName, cb, where); + } else { + // New signature + // count(model, where, options, cb) + connector.count(Model.modelName, where, options, cb); + } + }); return cb.promise; }; @@ -1649,6 +1725,7 @@ DataAccessObject.prototype.save = function (options, cb) { } var inst = this; + var connector = inst.getConnector(); var modelName = Model.modelName; var context = { @@ -1687,7 +1764,7 @@ DataAccessObject.prototype.save = function (options, cb) { inst.trigger('save', function (saveDone) { inst.trigger('update', function (updateDone) { data = removeUndefined(data); - inst._adapter().save(modelName, inst.constructor._forDB(data), function (err, unusedData, result) { + function saveCallback(err, unusedData, result) { if (err) { return cb(err, inst); } @@ -1710,7 +1787,13 @@ DataAccessObject.prototype.save = function (options, cb) { }); }); }); - }); + } + + if (connector.save.length === 4) { + connector.save(modelName, inst.constructor._forDB(data), options, saveCallback); + } else { + connector.save(modelName, inst.constructor._forDB(data), saveCallback); + } }, data, cb); }, data, cb); } @@ -1775,6 +1858,11 @@ DataAccessObject.updateAll = function (where, data, options, cb) { assert(typeof options === 'object', 'The options argument must be an object'); assert(typeof cb === 'function', 'The cb argument must be a function'); + var Model = this; + var connector = Model.getDataSource().connector; + assert(typeof connector.update === 'function', + 'update() must be implemented by the connector'); + var hookState = {}; var query = { where: where }; @@ -1783,8 +1871,6 @@ DataAccessObject.updateAll = function (where, data, options, cb) { where = query.where; - var Model = this; - var context = { Model: Model, query: { where: where }, @@ -1807,7 +1893,6 @@ DataAccessObject.updateAll = function (where, data, options, cb) { }); }); - function doUpdate(where, data) { try { where = removeUndefined(where); @@ -1820,8 +1905,7 @@ DataAccessObject.updateAll = function (where, data, options, cb) { }); } - var connector = Model.getDataSource().connector; - connector.update(Model.modelName, where, data, function(err, info) { + function updateCallback(err, info) { if (err) return cb (err); var context = { Model: Model, @@ -1831,9 +1915,15 @@ DataAccessObject.updateAll = function (where, data, options, cb) { options: options }; Model.notifyObserversOf('after save', context, function(err, ctx) { - return cb(err, info); - }); - }); + return cb(err, info); + }); + } + + if (connector.update.length === 5) { + connector.update(Model.modelName, where, data, options, updateCallback); + } else { + connector.update(Model.modelName, where, data, updateCallback); + } } return cb.promise; }; @@ -1846,7 +1936,7 @@ DataAccessObject.prototype.isNewRecord = function () { * Return connector of current record * @private */ -DataAccessObject.prototype._adapter = function () { +DataAccessObject.prototype.getConnector = function () { return this.getDataSource().connector; }; @@ -1877,11 +1967,12 @@ DataAccessObject.prototype.remove = assert(typeof options === 'object', 'The options argument should be an object'); assert(typeof cb === 'function', 'The cb argument should be a function'); - var hookState = {}; - var inst = this; + var connector = this.getConnector(); + var Model = this.constructor; var id = getIdValue(this.constructor, this); + var hookState = {}; var context = { Model: Model, @@ -1928,12 +2019,12 @@ DataAccessObject.prototype.remove = } inst.trigger('destroy', function (destroyed) { - inst._adapter().destroy(inst.constructor.modelName, id, function (err) { + function destroyCallback(err) { if (err) { return cb(err); } - destroyed(function () { + destroyed(function() { var context = { Model: Model, where: where, @@ -1946,7 +2037,13 @@ DataAccessObject.prototype.remove = if (!err) Model.emit('deleted', id); }); }); - }); + } + + if (connector.destroy.length === 4) { + connector.destroy(inst.constructor.modelName, id, options, destroyCallback); + } else { + connector.destroy(inst.constructor.modelName, id, destroyCallback); + } }, null, cb); } return cb.promise; @@ -2066,11 +2163,14 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op assert(typeof options === 'object', 'The options argument must be an object'); assert(typeof cb === 'function', 'The cb argument must be a function'); - var hookState = {}; - var inst = this; var Model = this.constructor; + var connector = inst.getConnector(); + assert(typeof connector.updateAttributes === 'function', + 'updateAttributes() must be implemented by the connector'); + var model = Model.modelName; + var hookState = {}; // Convert the data to be plain object so that update won't be confused if (data instanceof Model) { @@ -2129,8 +2229,7 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op } } - inst._adapter().updateAttributes(model, getIdValue(inst.constructor, inst), - inst.constructor._forDB(typedData), function (err) { + function updateAttributesCallback(err) { if (!err) inst.__persisted = true; done.call(inst, function () { saveDone.call(inst, function () { @@ -2148,7 +2247,15 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op }); }); }); - }); + } + + if (connector.updateAttributes.length === 5) { + connector.updateAttributes(model, getIdValue(inst.constructor, inst), + inst.constructor._forDB(typedData), options, updateAttributesCallback); + } else { + connector.updateAttributes(model, getIdValue(inst.constructor, inst), + inst.constructor._forDB(typedData), updateAttributesCallback); + } }, data, cb); }, data, cb); }, data); diff --git a/test/datatype.test.js b/test/datatype.test.js index 5dace33d..e01b984b 100644 --- a/test/datatype.test.js +++ b/test/datatype.test.js @@ -136,11 +136,17 @@ describe('datatypes', function () { function testDataInDB(done) { // verify that the value stored in the db is still an object - db.connector.find(Model.modelName, id, function (err, data) { + function cb(err, data) { should.exist(data); data.num.should.be.type('number'); done(); - }); + } + + if (db.connector.find.length === 4) { + db.connector.find(Model.modelName, id, {}, cb); + } else { + db.connector.find(Model.modelName, id, cb); + } } }); @@ -252,16 +258,27 @@ describe('datatypes', function () { created.should.have.properties(EXPECTED); saved.should.have.properties(EXPECTED); - TestModel.dataSource.connector.all( - TestModel.modelName, - { where: { id: created.id } }, - function(err, found) { - if (err) return done(err); - should.exist(found[0]); - found[0].should.have.properties(EXPECTED); - done(); - } - ); + function cb(err, found) { + if (err) return done(err); + should.exist(found[0]); + found[0].should.have.properties(EXPECTED); + done(); + } + + if (TestModel.dataSource.connector.all.length === 4) { + TestModel.dataSource.connector.all( + TestModel.modelName, + {where: {id: created.id}}, + {}, + cb + ); + } else { + TestModel.dataSource.connector.all( + TestModel.modelName, + {where: {id: created.id}}, + cb + ); + } }); }); }); diff --git a/test/memory.test.js b/test/memory.test.js index c39b6295..afd3b8df 100644 --- a/test/memory.test.js +++ b/test/memory.test.js @@ -238,7 +238,7 @@ describe('Memory connector', function() { }); it('should successfully extract 1 user (Lennon) from the db', function(done) { - User.find({where: {birthday: {between: [new Date(1970,0),new Date(1990,0)]}}}, + User.find({where: {birthday: {between: [new Date(1970,0),new Date(1990,0)]}}}, function(err, users) { should(users.length).be.equal(1); should(users[0].name).be.equal('John Lennon'); @@ -247,7 +247,7 @@ describe('Memory connector', function() { }); it('should successfully extract 2 users from the db', function(done) { - User.find({where: {birthday: {between: [new Date(1940,0),new Date(1990,0)]}}}, + User.find({where: {birthday: {between: [new Date(1940,0),new Date(1990,0)]}}}, function(err, users) { should(users.length).be.equal(2); done(); @@ -255,7 +255,7 @@ describe('Memory connector', function() { }); it('should successfully extract 0 user from the db', function(done) { - User.find({where: {birthday: {between: [new Date(1990,0), Date.now()]}}}, + User.find({where: {birthday: {between: [new Date(1990,0), Date.now()]}}}, function(err, users) { should(users.length).be.equal(0); done(); @@ -489,9 +489,9 @@ describe('Optimized connector', function() { // optimized methods ds.connector.findOrCreate = function (model, query, data, callback) { - this.all(model, query, function (err, list) { + this.all(model, query, {}, function (err, list) { if (err || (list && list[0])) return callback(err, list && list[0], false); - this.create(model, data, function (err) { + this.create(model, data, {}, function (err) { callback(err, data, true); }); }.bind(this)); @@ -509,5 +509,79 @@ describe('Unoptimized connector', function() { require('./persistence-hooks.suite')(ds, should); }); +describe('Memory connector with options', function() { + var ds, savedOptions = {}, Post; + + before(function() { + ds = new DataSource({connector: 'memory'}); + ds.connector.create = function(model, data, options, cb) { + savedOptions.create = options; + process.nextTick(function() { + cb(null, 1); + }); + }; + + ds.connector.update = function(model, where, data, options, cb) { + savedOptions.update = options; + process.nextTick(function() { + cb(null, {count: 1}); + }); + }; + + ds.connector.all = function(model, filter, options, cb) { + savedOptions.find = options; + process.nextTick(function() { + cb(null, [{title: 't1', content: 'c1'}]); + }); + }; + + Post = ds.define('Post', { + title: String, + content: String + }); + }); + + it('should receive options from the find method', function(done) { + var opts = {transaction: 'tx1'}; + Post.find({where: {title: 't1'}}, opts, function(err, p) { + savedOptions.find.should.be.eql(opts); + done(err); + }); + }); + + it('should receive options from the find method', function(done) { + var opts = {transaction: 'tx2'}; + Post.find({}, opts, function(err, p) { + savedOptions.find.should.be.eql(opts); + done(err); + }); + }); + + it('should treat first object arg as filter for find', function(done) { + var filter = {title: 't1'}; + Post.find(filter, function(err, p) { + savedOptions.find.should.be.eql({}); + done(err); + }); + }); + + it('should receive options from the create method', function(done) { + var opts = {transaction: 'tx3'}; + Post.create({title: 't1', content: 'c1'}, opts, function(err, p) { + savedOptions.create.should.be.eql(opts); + done(err); + }); + }); + + it('should receive options from the update method', function(done) { + var opts = {transaction: 'tx4'}; + Post.update({title: 't1'}, {content: 'c1 --> c2'}, + opts, function(err, p) { + savedOptions.update.should.be.eql(opts); + done(err); + }); + }); + +});