Add model tests
This commit is contained in:
parent
2582c3fc65
commit
a0e595dce8
|
@ -338,6 +338,20 @@ Model.checkpoint = function(cb) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current checkpoint id.
|
||||||
|
*
|
||||||
|
* @callback {Function} callback
|
||||||
|
* @param {Error} err
|
||||||
|
* @param {Number} currentCheckpointId
|
||||||
|
* @end
|
||||||
|
*/
|
||||||
|
|
||||||
|
Model.currentCheckpoint = function(cb) {
|
||||||
|
var Checkpoint = this.getChangeModel().getCheckpointModel();
|
||||||
|
Checkpoint.current(cb);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replicate changes since the given checkpoint to the given target model.
|
* Replicate changes since the given checkpoint to the given target model.
|
||||||
*
|
*
|
||||||
|
@ -489,6 +503,12 @@ Model.bulkUpdate = function(updates, callback) {
|
||||||
async.parallel(tasks, callback);
|
async.parallel(tasks, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the `Change` model.
|
||||||
|
*
|
||||||
|
* @return {Change}
|
||||||
|
*/
|
||||||
|
|
||||||
Model.getChangeModel = function() {
|
Model.getChangeModel = function() {
|
||||||
var changeModel = this.Change;
|
var changeModel = this.Change;
|
||||||
if(changeModel) return changeModel;
|
if(changeModel) return changeModel;
|
||||||
|
@ -497,8 +517,25 @@ Model.getChangeModel = function() {
|
||||||
return changeModel;
|
return changeModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the source identifier for this model / dataSource.
|
||||||
|
*
|
||||||
|
* @callback {Function} callback
|
||||||
|
* @param {Error} err
|
||||||
|
* @param {String} sourceId
|
||||||
|
*/
|
||||||
|
|
||||||
Model.getSourceId = function(cb) {
|
Model.getSourceId = function(cb) {
|
||||||
cb(null, 'foo')
|
var dataSource = this.dataSource;
|
||||||
|
if(!dataSource) {
|
||||||
|
this.once('dataSourceAttached', this.getSourceId.bind(this, cb));
|
||||||
|
}
|
||||||
|
assert(
|
||||||
|
dataSource.connector.name,
|
||||||
|
'Model.getSourceId: cannot get id without dataSource.connector.name'
|
||||||
|
);
|
||||||
|
var id = [dataSource.connector.name, this.modelName].join('-');
|
||||||
|
cb(null, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -253,8 +253,11 @@ describe('Change', function(){
|
||||||
|
|
||||||
it('should return delta and conflict lists', function (done) {
|
it('should return delta and conflict lists', function (done) {
|
||||||
var remoteChanges = [
|
var remoteChanges = [
|
||||||
|
// an update => should result in a delta
|
||||||
{rev: 'foo2', prev: 'foo', modelName: this.modelName, modelId: 9, checkpoint: 1},
|
{rev: 'foo2', prev: 'foo', modelName: this.modelName, modelId: 9, checkpoint: 1},
|
||||||
|
// no change => should not result in a delta / conflict
|
||||||
{rev: 'bar', prev: 'bar', modelName: this.modelName, modelId: 10, checkpoint: 1},
|
{rev: 'bar', prev: 'bar', modelName: this.modelName, modelId: 10, checkpoint: 1},
|
||||||
|
// a conflict => should result in a conflict
|
||||||
{rev: 'bat2', prev: 'bat0', modelName: this.modelName, modelId: 11, checkpoint: 1},
|
{rev: 'bat2', prev: 'bat0', modelName: this.modelName, modelId: 11, checkpoint: 1},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
var ACL = require('../').ACL;
|
var async = require('async');
|
||||||
|
var loopback = require('../');
|
||||||
|
var ACL = loopback.ACL;
|
||||||
|
var Change = loopback.Change;
|
||||||
|
|
||||||
describe('Model', function() {
|
describe('Model', function() {
|
||||||
|
|
||||||
|
@ -523,33 +526,33 @@ describe('Model', function() {
|
||||||
|
|
||||||
describe('Model.extend() events', function() {
|
describe('Model.extend() events', function() {
|
||||||
it('create isolated emitters for subclasses', function() {
|
it('create isolated emitters for subclasses', function() {
|
||||||
var User1 = loopback.createModel('User1', {
|
var User1 = loopback.createModel('User1', {
|
||||||
'first': String,
|
'first': String,
|
||||||
'last': String
|
'last': String
|
||||||
});
|
});
|
||||||
|
|
||||||
var User2 = loopback.createModel('User2', {
|
var User2 = loopback.createModel('User2', {
|
||||||
'name': String
|
'name': String
|
||||||
});
|
});
|
||||||
|
|
||||||
var user1Triggered = false;
|
var user1Triggered = false;
|
||||||
User1.once('x', function(event) {
|
User1.once('x', function(event) {
|
||||||
user1Triggered = true;
|
user1Triggered = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var user2Triggered = false;
|
var user2Triggered = false;
|
||||||
User2.once('x', function(event) {
|
User2.once('x', function(event) {
|
||||||
user2Triggered = true;
|
user2Triggered = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
assert(User1.once !== User2.once);
|
assert(User1.once !== User2.once);
|
||||||
assert(User1.once !== loopback.Model.once);
|
assert(User1.once !== loopback.Model.once);
|
||||||
|
|
||||||
User1.emit('x', User1);
|
User1.emit('x', User1);
|
||||||
|
|
||||||
assert(user1Triggered);
|
assert(user1Triggered);
|
||||||
assert(!user2Triggered);
|
assert(!user2Triggered);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -581,80 +584,125 @@ describe('Model', function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// describe('Model.hasAndBelongsToMany()', function() {
|
describe('Model.getChangeModel()', function() {
|
||||||
// it("TODO: implement / document", function(done) {
|
it('Get the Change Model', function () {
|
||||||
// /* example -
|
var UserChange = User.getChangeModel();
|
||||||
//
|
var change = new UserChange();
|
||||||
// */
|
assert(change instanceof Change);
|
||||||
// done(new Error('test not implemented'));
|
});
|
||||||
// });
|
});
|
||||||
// });
|
|
||||||
|
|
||||||
// describe('Model.remoteMethods()', function() {
|
describe('Model.getSourceId(callback)', function() {
|
||||||
// it("Return a list of enabled remote methods", function() {
|
it('Get the Source Id', function (done) {
|
||||||
// app.model(User);
|
User.getSourceId(function(err, id) {
|
||||||
// User.remoteMethods(); // ['save', ...]
|
assert.equal('memory-user', id);
|
||||||
// });
|
done();
|
||||||
// });
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// describe('Model.availableMethods()', function() {
|
describe('Model.checkpoint(callback)', function() {
|
||||||
// it("Returns the currently available api of a model as well as descriptions of any modified behavior or methods from attached data sources", function(done) {
|
it('Create a checkpoint', function (done) {
|
||||||
// /* example -
|
var Checkpoint = User.getChangeModel().getCheckpointModel();
|
||||||
// User.attachTo(oracle);
|
var tasks = [
|
||||||
// console.log(User.availableMethods());
|
getCurrentCheckpoint,
|
||||||
//
|
checkpoint
|
||||||
// {
|
];
|
||||||
// 'User.all': {
|
var result;
|
||||||
// accepts: [{arg: 'filter', type: 'object', description: '...'}],
|
var current;
|
||||||
// returns: [{arg: 'users', type: ['User']}]
|
|
||||||
// },
|
async.parallel(tasks, function(err) {
|
||||||
// 'User.find': {
|
if(err) return done(err);
|
||||||
// accepts: [{arg: 'id', type: 'any'}],
|
|
||||||
// returns: [{arg: 'items', type: 'User'}]
|
assert.equal(result, current + 1);
|
||||||
// },
|
done();
|
||||||
// ...
|
});
|
||||||
// }
|
|
||||||
// var oracle = loopback.createDataSource({
|
function getCurrentCheckpoint(cb) {
|
||||||
// connector: 'oracle',
|
Checkpoint.current(function(err, cp) {
|
||||||
// host: '111.22.333.44',
|
current = cp;
|
||||||
// database: 'MYDB',
|
cb(err);
|
||||||
// username: 'username',
|
});
|
||||||
// password: 'password'
|
}
|
||||||
// });
|
|
||||||
//
|
function checkpoint(cb) {
|
||||||
// */
|
User.checkpoint(function(err, cp) {
|
||||||
// done(new Error('test not implemented'));
|
result = cp.id;
|
||||||
// });
|
cb(err);
|
||||||
// });
|
});
|
||||||
|
}
|
||||||
// describe('Model.before(name, fn)', function(){
|
});
|
||||||
// it('Run a function before a method is called', function() {
|
});
|
||||||
// // User.before('save', function(user, next) {
|
|
||||||
// // console.log('about to save', user);
|
describe('Replication / Change APIs', function() {
|
||||||
// //
|
beforeEach(function(done) {
|
||||||
// // next();
|
var test = this;
|
||||||
// // });
|
this.dataSource = loopback.createDataSource({connector: loopback.Memory});
|
||||||
// //
|
var SourceModel = this.SourceModel = this.dataSource.createModel('SourceModel', {}, {
|
||||||
// // User.before('delete', function(user, next) {
|
trackChanges: true
|
||||||
// // // prevent all delete calls
|
});
|
||||||
// // next(new Error('deleting is disabled'));
|
var TargetModel = this.TargetModel = this.dataSource.createModel('TargetModel', {}, {
|
||||||
// // });
|
trackChanges: true
|
||||||
// // User.beforeRemote('save', function(ctx, user, next) {
|
});
|
||||||
// // if(ctx.user.id === user.id) {
|
|
||||||
// // next();
|
var createOne = SourceModel.create.bind(SourceModel, {
|
||||||
// // } else {
|
name: 'baz'
|
||||||
// // next(new Error('must be logged in to update'))
|
});
|
||||||
// // }
|
|
||||||
// // });
|
async.parallel([
|
||||||
//
|
createOne,
|
||||||
// throw new Error('not implemented');
|
function(cb) {
|
||||||
// });
|
SourceModel.currentCheckpoint(function(err, id) {
|
||||||
// });
|
if(err) return cb(err);
|
||||||
//
|
test.startingCheckpoint = id;
|
||||||
// describe('Model.after(name, fn)', function(){
|
cb();
|
||||||
// it('Run a function after a method is called', function() {
|
});
|
||||||
//
|
}
|
||||||
// throw new Error('not implemented');
|
], process.nextTick.bind(process, done));
|
||||||
// });
|
});
|
||||||
// });
|
|
||||||
|
describe('Model.changes(since, filter, callback)', function() {
|
||||||
|
it('Get changes since the given checkpoint', function (done) {
|
||||||
|
this.SourceModel.changes(this.startingCheckpoint, {}, function(err, changes) {
|
||||||
|
assert.equal(changes.length, 1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Model.replicate(since, targetModel, options, callback)', function() {
|
||||||
|
it('Replicate data using the target model', function (done) {
|
||||||
|
var test = this;
|
||||||
|
var options = {};
|
||||||
|
var sourceData;
|
||||||
|
var targetData;
|
||||||
|
|
||||||
|
this.SourceModel.replicate(this.startingCheckpoint, this.TargetModel,
|
||||||
|
options, function(err, conflicts) {
|
||||||
|
assert(conflicts.length === 0);
|
||||||
|
async.parallel([
|
||||||
|
function(cb) {
|
||||||
|
test.SourceModel.find(function(err, result) {
|
||||||
|
if(err) return cb(err);
|
||||||
|
sourceData = result;
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function(cb) {
|
||||||
|
test.TargetModel.find(function(err, result) {
|
||||||
|
if(err) return cb(err);
|
||||||
|
targetData = result;
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
], function(err) {
|
||||||
|
if(err) return done(err);
|
||||||
|
|
||||||
|
assert.deepEqual(sourceData, targetData);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue