Merge pull request #1594 from strongloop/upgrade-deps

Drop support for Node.js 4.x + update dependencies
This commit is contained in:
Miroslav Bajtoš 2018-06-12 16:26:07 +02:00 committed by GitHub
commit 751fd7b245
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 2593 additions and 2570 deletions

1
.npmrc Normal file
View File

@ -0,0 +1 @@
package-lock=false

View File

@ -1,8 +1,8 @@
sudo: false
language: node_js
node_js:
- "4"
- "6"
- "8"
- "10"
after_success: npm run coverage

View File

@ -67,8 +67,8 @@ Transient.prototype.generateId = function(model, data, idName) {
return Math.floor(Math.random() * 10000); // max. 4 digits
} else {
return crypto.randomBytes(Math.ceil(24 / 2))
.toString('hex') // convert to hexadecimal format
.slice(0, 24); // return required number of characters
.toString('hex') // convert to hexadecimal format
.slice(0, 24); // return required number of characters
}
};

View File

@ -487,7 +487,7 @@ function stillConnecting(dataSource, obj, args) {
// promise variant
var promiseArgs = Array.prototype.slice.call(args);
promiseArgs.callee = args.callee;
var cb = utils.createPromiseCallback();
var cb = utils.createPromiseCallback();
promiseArgs.push(cb);
if (dataSource.ready(obj, promiseArgs)) {
return cb.promise;
@ -801,7 +801,7 @@ DataAccessObject.upsertWithWhere = function(where, data, options, cb) {
function callConnector() {
try {
// Support an optional where object
var handleUndefined = Model._getSetting('normalizeUndefinedInQuery');
var handleUndefined = Model._getSetting('normalizeUndefinedInQuery');
// alter configuration of how removeUndefined handles undefined values
ctx.where = removeUndefined(ctx.where, handleUndefined);
ctx.where = Model._coerce(ctx.where, options);
@ -864,7 +864,7 @@ DataAccessObject.upsertWithWhere = function(where, data, options, cb) {
self.find({where: ctx.query.where}, opts, function(err, instances) {
if (err) return cb(err);
var modelsLength = instances.length;
if (modelsLength === 0) {
if (modelsLength === 0) {
self.create(data, options, cb);
} else if (modelsLength === 1) {
var modelInst = instances[0];
@ -1089,7 +1089,7 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
// query will be built from data, and method will return Promise
data = query;
query = {where: data};
} else if (options === undefined && cb === undefined) {
} else if (options === undefined && cb === undefined) {
if (typeof data === 'function') {
// findOrCreate(data, cb);
// query will be built from data
@ -1517,7 +1517,7 @@ DataAccessObject._normalize = function(filter, options) {
}
if (isNaN(offset) || offset < 0 || Math.ceil(offset) !== offset) {
err = new Error(g.f('The {{offset/skip}} parameter %j is not valid',
filter.skip || filter.offset));
filter.skip || filter.offset));
err.statusCode = 400;
throw err;
}
@ -1574,7 +1574,7 @@ DataAccessObject._normalize = function(filter, options) {
Object.keys(this.definition.properties), this.settings.strict);
}
var handleUndefined = this._getSetting('normalizeUndefinedInQuery');
var handleUndefined = this._getSetting('normalizeUndefinedInQuery');
// alter configuration of how removeUndefined handles undefined values
filter = removeUndefined(filter, handleUndefined);
this._coerce(filter.where, options);
@ -2118,7 +2118,7 @@ DataAccessObject.find = function find(query, options, cb) {
if (options.notify === false) {
invokeConnectorMethod(connector, 'all', self, [query], options, allCb);
} else {
var context = {
var context = {
Model: this,
query: query,
hookState: hookState,
@ -2271,7 +2271,7 @@ DataAccessObject.destroyAll = function destroyAll(where, options, cb) {
} else {
try {
// Support an optional where object
var handleUndefined = Model._getSetting('normalizeUndefinedInQuery');
var handleUndefined = Model._getSetting('normalizeUndefinedInQuery');
// alter configuration of how removeUndefined handles undefined values
where = removeUndefined(where, handleUndefined);
where = Model._coerce(where, options);
@ -2426,7 +2426,7 @@ DataAccessObject.count = function(where, options, cb) {
where = query.where;
try {
var handleUndefined = Model._getSetting('normalizeUndefinedInQuery');
var handleUndefined = Model._getSetting('normalizeUndefinedInQuery');
// alter configuration of how removeUndefined handles undefined values
where = removeUndefined(where, handleUndefined);
where = this._coerce(where, options);
@ -2478,7 +2478,7 @@ DataAccessObject.prototype.save = function(options, cb) {
if (isPKMissing(Model, cb)) {
return cb.promise;
} else if (this.isNewRecord()) {
} else if (this.isNewRecord()) {
return Model.create(this, options, cb);
}
@ -2719,7 +2719,7 @@ DataAccessObject.updateAll = function(where, data, options, cb) {
function doUpdate(where, data) {
try {
// Support an optional where object
var handleUndefined = Model._getSetting('normalizeUndefinedInQuery');
var handleUndefined = Model._getSetting('normalizeUndefinedInQuery');
// alter configuration of how removeUndefined handles undefined values
where = removeUndefined(where, handleUndefined);
where = Model._coerce(where, options);
@ -2982,7 +2982,7 @@ DataAccessObject.replaceById = function(id, data, options, cb) {
options = options || {};
assert((typeof data === 'object') && (data !== null),
'The data argument must be an object');
'The data argument must be an object');
assert(typeof options === 'object', 'The options argument must be an object');
assert(typeof cb === 'function', 'The cb argument must be a function');
@ -3101,7 +3101,7 @@ DataAccessObject.replaceById = function(id, data, options, cb) {
Model._warned.cannotOverwritePKInLoadedHook = true;
g.warn('WARNING: {{id}} property cannot be changed from %s to %s for model:%s in ' +
'{{\'loaded\'}} operation hook',
id, ctx.data[pkName], Model.modelName);
id, ctx.data[pkName], Model.modelName);
}
inst.__persisted = true;
@ -3208,7 +3208,7 @@ function(data, options, cb) {
if (data[idName] !== undefined && !idEquals(data[idName], inst[idName])) {
var err = new Error(g.f('{{id}} cannot be updated from ' +
'%s to %s when {{forceId}} is set to true',
inst[idName], data[idName]));
inst[idName], data[idName]));
err.statusCode = 400;
process.nextTick(function() {
cb(err);

View File

@ -227,7 +227,7 @@ function connectorModuleNames(name) {
}
// Only try the short name if the connector is not from StrongLoop
if (['mongodb', 'oracle', 'mysql', 'postgresql', 'mssql', 'rest', 'soap', 'db2', 'cloudant']
.indexOf(name) === -1) {
.indexOf(name) === -1) {
names.push(name);
}
return names;
@ -272,7 +272,7 @@ DataSource._resolveConnector = function(name, loader) {
if (!connector) {
error = g.f('\nWARNING: {{LoopBack}} connector "%s" is not installed ' +
'as any of the following modules:\n\n %s\n\nTo fix, run:\n\n {{npm install %s --save}}\n',
name, names.join('\n'), names[names.length - 1]);
name, names.join('\n'), names[names.length - 1]);
}
return {
connector: connector,
@ -498,7 +498,7 @@ DataSource.prototype.setup = function(dsName, settings) {
} catch (err) {
if (err.message) {
err.message = 'Cannot initialize connector ' +
JSON.stringify(connectorName) + ': ' +
JSON.stringify(connectorName) + ': ' +
err.message;
}
throw err;
@ -1101,7 +1101,7 @@ DataSource.prototype.autoupdate = function(models, cb) {
if (invalidModels.length) {
process.nextTick(function() {
cb(new Error(g.f('Cannot migrate models not attached to this datasource: %s',
invalidModels.join(' '))));
invalidModels.join(' '))));
});
return cb.promise;
}

View File

@ -106,7 +106,7 @@ function deprecateHook(ctor, prefixes, capitalizedName) {
var hookName = candidateNames.filter(function(hook) { return !!ctor[hook]; })[0];
if (!hookName) return; // just to be sure, this should never happen
if (ctor.modelName) hookName = ctor.modelName + '.' + hookName;
if (ctor.modelName) hookName = ctor.modelName + '.' + hookName;
deprecated(g.f('Model hook "%s" is deprecated, ' +
'use Operation hooks instead. ' +
'{{http://docs.strongloop.com/display/LB/Operation+hooks}}', hookName));

View File

@ -575,7 +575,7 @@ function lookupModelTo(modelFrom, modelToRef, params, singularize) {
if (!modelTo) {
// lookup by modelTo name was not successful. Now looking-up by relationTo name
var relationToName = params.as || modelToRef; // modelToRef might be relationTo name
var relationToName = params.as || modelToRef; // modelToRef might be relationTo name
modelToName = (singularize ? i8n.singularize(relationToName) : relationToName).toLowerCase();
modelTo = lookupModel(modelFrom.dataSource.modelBuilder.models, modelToName);
}
@ -787,7 +787,7 @@ RelationDefinition.hasMany = function hasMany(modelFrom, modelToRef, params) {
if (relation.type === RelationTypes.belongsTo &&
(relation.polymorphic && !relation.modelTo || relation.modelTo === definition.modelTo) &&
(relation.keyFrom === definition.keyThrough)
) {
) {
throughRelationName = relation.name;
break;
}
@ -992,7 +992,7 @@ var throughKeys = function(definition) {
});
} else {
fk1 = findBelongsTo(modelThrough, definition.modelFrom,
definition.keyFrom)[0];
definition.keyFrom)[0];
fk2 = findBelongsTo(modelThrough, definition.modelTo, pk2)[0];
}
return [fk1, fk2];
@ -1022,8 +1022,8 @@ HasManyThrough.prototype.findById = function(fkId, options, cb) {
if (!err) {
err = new Error(g.f('No relation found in %s' +
' for (%s.%s,%s.%s)',
modelThrough.modelName, self.definition.modelFrom.modelName,
modelInstance[pk], modelTo.modelName, fkId));
modelThrough.modelName, self.definition.modelFrom.modelName,
modelInstance[pk], modelTo.modelName, fkId));
err.statusCode = 404;
}
return cb(err);
@ -1825,7 +1825,7 @@ HasOne.prototype.create = function(targetModelData, options, cb) {
} else {
cb && cb(new Error(g.f(
'{{HasOne}} relation cannot create more than one instance of %s',
modelTo.modelName)));
modelTo.modelName)));
}
});
return cb.promise;
@ -2472,10 +2472,10 @@ RelationDefinition.embedsMany = function embedsMany(modelFrom, modelToRef, param
var opts = Object.assign(
params.options && params.options.property ? params.options.property : {},
params.options && params.options.omitDefaultEmbeddedItem ? {type: [modelTo]} :
{
type: [modelTo],
default: function() { return []; },
}
{
type: [modelTo],
default: function() { return []; },
}
);
modelFrom.dataSource.defineProperty(modelFrom.modelName, propertyName, opts);
@ -2785,12 +2785,12 @@ EmbedsMany.prototype.updateById = function(fkId, data, options, cb) {
if (typeof cb === 'function') {
modelInstance.updateAttribute(propertyName, embeddedList, options,
function(err) {
if (err) return cb(err, inst);
modelTo.notifyObserversOf('after save', context, function(err) {
cb(err, inst);
function(err) {
if (err) return cb(err, inst);
modelTo.notifyObserversOf('after save', context, function(err) {
cb(err, inst);
});
});
});
} else {
modelTo.notifyObserversOf('after save', context, function(err) {
if (!err) return;

View File

@ -63,7 +63,7 @@ function setScopeValuesFromWhere(data, where, targetModel) {
if (prop) {
var val = where[i];
if (typeof val !== 'object' || val instanceof prop.type ||
prop.type.name === 'ObjectID' || // MongoDB key
prop.type.name === 'ObjectID' || // MongoDB key
prop.type.name === 'uuidFromString') { // C*
// Only pick the {propertyName: propertyValue}
data[i] = where[i];
@ -358,7 +358,7 @@ function parseSettings(urlStr) {
settings.port = uri.port && Number(uri.port); // port is a string
settings.user = settings.username = uri.auth && uri.auth.split(':')[0]; // <username>:<password>
settings.password = uri.auth && uri.auth.split(':')[1];
settings.database = uri.pathname && uri.pathname.split('/')[1]; // remove the leading /
settings.database = uri.pathname && uri.pathname.split('/')[1]; // remove the leading /
settings.url = urlStr;
if (uri.query) {
var params = qs.parse(uri.query);

View File

@ -869,8 +869,8 @@ function ValidationError(obj) {
var context = obj && obj.constructor && obj.constructor.modelName;
this.message = g.f(
'The %s instance is not valid. Details: %s.',
context ? '`' + context + '`' : 'model',
formatErrors(obj.errors, obj.toJSON()) || '(unknown)'
context ? '`' + context + '`' : 'model',
formatErrors(obj.errors, obj.toJSON()) || '(unknown)'
);
this.statusCode = 422;

View File

@ -15,7 +15,7 @@
"ORM"
],
"engines": {
"node": ">=4.0.0"
"node": ">=6"
},
"repository": {
"type": "git",
@ -37,12 +37,12 @@
"@types/node": "^10.0.8",
"async-iterators": "^0.2.2",
"bson": "^1.0.4",
"coveralls": "^2.13.1",
"eslint": "^3.12.2",
"eslint-config-loopback": "^8.0.0",
"coveralls": "^3.0.1",
"eslint": "^4.19.1",
"eslint-config-loopback": "^10.0.0",
"loopback-connector-throwing": "file:./test/fixtures/loopback-connector-throwing",
"mocha": "^3.2.0",
"nyc": "^11.1.0",
"mocha": "^5.2.0",
"nyc": "^12.0.2",
"should": "^8.4.0",
"typescript": "^2.8.3"
},
@ -57,7 +57,7 @@
"minimatch": "^3.0.3",
"qs": "^6.5.0",
"shortid": "^2.2.6",
"strong-globalize": "^3.1.0",
"strong-globalize": "^4.1.1",
"traverse": "^0.6.6",
"uuid": "^3.0.1"
},

View File

@ -137,27 +137,27 @@ describe('basic-querying', function() {
createdUsers[1].id,
createdUsers[2].id,
createdUsers[3].id],
{where: {vip: true}}, function(err, users) {
should.exist(users);
should.not.exist(err);
var names = users.map(function(u) {
return u.name;
});
names.should.eql(createdUsers.slice(0, 4).
filter(function(u) {
return u.vip;
}).map(function(u) {
return u.name;
}));
done();
{where: {vip: true}}, function(err, users) {
should.exist(users);
should.not.exist(err);
var names = users.map(function(u) {
return u.name;
});
names.should.eql(createdUsers.slice(0, 4).
filter(function(u) {
return u.vip;
}).map(function(u) {
return u.name;
}));
done();
});
});
bdd.itIf(connectorCapabilities.nullDataValueExists !== false,
'should query by ids to check null property', function(done) {
User.findByIds([
createdUsers[0].id,
createdUsers[1].id],
'should query by ids to check null property', function(done) {
User.findByIds([
createdUsers[0].id,
createdUsers[1].id],
{where: {vip: null}}, function(err, users) {
should.not.exist(err);
should.exist(users);
@ -165,7 +165,7 @@ describe('basic-querying', function() {
users[0].name.should.eql(createdUsers[1].name);
done();
});
});
});
});
describe('find', function() {
@ -334,28 +334,28 @@ describe('basic-querying', function() {
});
bdd.itIf(connectorCapabilities.nullDataValueExists !== false,
'should support where date "neq" null', function(done) {
User.find({where: {birthday: {'neq': null},
}}, function(err, users) {
should.not.exist(err);
should.exist(users);
users.should.have.property('length', 2);
should(users[0].name).be.oneOf('John Lennon', 'Paul McCartney');
should(users[1].name).be.oneOf('John Lennon', 'Paul McCartney');
done();
'should support where date "neq" null', function(done) {
User.find({where: {birthday: {'neq': null},
}}, function(err, users) {
should.not.exist(err);
should.exist(users);
users.should.have.property('length', 2);
should(users[0].name).be.oneOf('John Lennon', 'Paul McCartney');
should(users[1].name).be.oneOf('John Lennon', 'Paul McCartney');
done();
});
});
});
bdd.itIf(connectorCapabilities.nullDataValueExists !== false,
'should support where date is null', function(done) {
User.find({where: {birthday: null,
}}, function(err, users) {
should.not.exist(err);
should.exist(users);
users.should.have.property('length', 4);
done();
'should support where date is null', function(done) {
User.find({where: {birthday: null,
}}, function(err, users) {
should.not.exist(err);
should.exist(users);
users.should.have.property('length', 4);
done();
});
});
});
it('should support date "gte" that is satisfied', function(done) {
User.find({where: {birthday: {'gte': new Date('1980-12-08')},
@ -887,13 +887,13 @@ describe('basic-querying', function() {
'should support nested property for order in query',
function(done) {
User.find({where: {'address.state': 'CA'}, order: 'address.city DESC'},
function(err, users) {
if (err) return done(err);
users.length.should.be.equal(2);
users[0].address.city.should.be.eql('San Mateo');
users[1].address.city.should.be.eql('San Jose');
done();
});
function(err, users) {
if (err) return done(err);
users.length.should.be.equal(2);
users[0].address.city.should.be.eql('San Mateo');
users[1].address.city.should.be.eql('San Jose');
done();
});
});
it('should support multi-level nested array property in query', function(done) {
@ -907,13 +907,13 @@ describe('basic-querying', function() {
});
it('should fail when querying with an invalid value for a type',
function(done) {
User.find({where: {birthday: 'notadate'}}, function(err, users) {
should.exist(err);
err.message.should.equal('Invalid date: notadate');
done();
function(done) {
User.find({where: {birthday: 'notadate'}}, function(err, users) {
should.exist(err);
err.message.should.equal('Invalid date: notadate');
done();
});
});
});
});
});
@ -1160,16 +1160,16 @@ describe.skip('queries', function() {
});
it('should return an error for deleteById/destroyById/removeById',
function(done) {
var aliases = ['deleteById', 'destroyById', 'removeById'];
async.each(aliases, function(alias, cb) {
Todo[alias](1, function(err) {
should.exist(err);
err.message.should.equal(expectedErrMsg);
cb();
});
}, done);
});
function(done) {
var aliases = ['deleteById', 'destroyById', 'removeById'];
async.each(aliases, function(alias, cb) {
Todo[alias](1, function(err) {
should.exist(err);
err.message.should.equal(expectedErrMsg);
cb();
});
}, done);
});
it('should return an error for instance.save', function(done) {
var todo = new Todo();

View File

@ -90,6 +90,7 @@ function clearAndCreate(model, data, callback) {
}
}
/* eslint-disable mocha/handle-done-callback */
function testOrm(dataSource) {
var requestsAreCounted = dataSource.name !== 'mongodb';
@ -407,7 +408,7 @@ function testOrm(dataSource) {
dataSource.name !== 'memory' &&
dataSource.name !== 'neo4j' &&
dataSource.name !== 'cradle'
)
)
it('relations key is working', function(test) {
test.ok(User.relations, 'Relations key should be defined');
test.ok(User.relations.posts, 'posts relation should exist on User');

View File

@ -124,7 +124,7 @@ describe('DataSource', function() {
/**
* new DataSource(dsName, connectorInstance)
*/
it('should accept resolved connector', function() {
it('should accept dsName and resolved connector', function() {
var mockConnector = {
name: 'loopback-connector-mock',
initialize: function(ds, cb) {

View File

@ -156,19 +156,19 @@ describe('datatypes', function() {
});
it('rejects array value converted to NaN for a required property',
function(done) {
db = getSchema();
Model = db.define('RequiredNumber', {
num: {type: Number, required: true},
});
db.automigrate(['Model'], function() {
Model.create({num: [1, 2, 3]}, function(err, inst) {
should.exist(err);
err.should.have.property('name').equal('ValidationError');
done();
function(done) {
db = getSchema();
Model = db.define('RequiredNumber', {
num: {type: Number, required: true},
});
db.automigrate(['Model'], function() {
Model.create({num: [1, 2, 3]}, function(err, inst) {
should.exist(err);
err.should.have.property('name').equal('ValidationError');
done();
});
});
});
});
it('handles null data', (done) => {
db = getSchema();

View File

@ -667,6 +667,7 @@ describe('default scope', function() {
});
});
// eslint-disable-next-line mocha/no-identical-title
it('should find a scoped instance - thing', function(done) {
Product.find({where: {name: 'Product'}}, function(err, products) {
products.should.have.length(2);

View File

@ -162,20 +162,20 @@ describe('Memory connector with mocked discovery', function() {
function(done) {
ds.connector.discoverSchemas = null;
ds.discoverSchemas('INVENTORY', {})
.then(function(schemas) {
schemas.should.have.property('STRONGLOOP.INVENTORY');
.then(function(schemas) {
schemas.should.have.property('STRONGLOOP.INVENTORY');
var s = schemas['STRONGLOOP.INVENTORY'];
s.name.should.be.eql('Inventory');
var s = schemas['STRONGLOOP.INVENTORY'];
s.name.should.be.eql('Inventory');
Object.keys(s.properties).should.be.eql(
['productId', 'locationId', 'available', 'total']
);
done();
})
.catch(function(err) {
done(err);
});
Object.keys(s.properties).should.be.eql(
['productId', 'locationId', 'available', 'total']
);
done();
})
.catch(function(err) {
done(err);
});
});
describe('discoverSchema', function() {
@ -344,9 +344,9 @@ describe('discoverModelDefinitions', function() {
);
done();
})
.catch(function(err) {
done(err);
});
.catch(function(err) {
done(err);
});
});
});
@ -430,9 +430,9 @@ describe('discoverModelProperties', function() {
schemas.should.be.eql(modelProperties);
done();
})
.catch(function(err) {
done(err);
});
.catch(function(err) {
done(err);
});
});
});
@ -599,16 +599,16 @@ describe('discoverExportedForeignKeys', function() {
});
it('should discover foreign key definitions using `discoverExportedForeignKeys` - promise variant',
function(done) {
ds.discoverExportedForeignKeys('INVENTORY', {})
.then(function(modelForeignKeys) {
modelForeignKeys.should.be.eql(exportedForeignKeys);
done();
})
.catch(function(err) {
done(err);
});
});
function(done) {
ds.discoverExportedForeignKeys('INVENTORY', {})
.then(function(modelForeignKeys) {
modelForeignKeys.should.be.eql(exportedForeignKeys);
done();
})
.catch(function(err) {
done(err);
});
});
});
describe('Mock connector', function() {

View File

@ -19,7 +19,7 @@ describe('exclude properties ', function() {
var User = ds.define('User', {name: String, password: String});
var properties = User.definition.properties;
// User should have id, name & password properties
assert(('id' in properties) && ('password' in properties) && ('name' in properties),
assert(('id' in properties) && ('password' in properties) && ('name' in properties),
'User should have id, name & password properties');
// Create sub model Customer with vip as property. id property gets automatically created here as well.
// Customer will inherit name, password and id from base User model.

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,8 @@ describe('include_util', function() {
describe('#buildOneToOneIdentityMapWithOrigKeys', function() {
it('should return an object with keys', function() {
var objs = [
{id: 11, letter: 'A'},
{id: 22, letter: 'B'},
{id: 11, letter: 'A'},
{id: 22, letter: 'B'},
];
var result = includeUtils.buildOneToOneIdentityMapWithOrigKeys(objs, 'id');
result.get(11).should.be.ok;
@ -36,19 +36,17 @@ describe('include_util', function() {
result.get(11)['letter'].should.equal('HA!');
result.get(33)['letter'].should.equal('C');
});
});
describe('#buildOneToOneIdentityMapWithOrigKeys', function() {
it('should return an object with keys', function() {
it('should return an object with no additional keys', function() {
var objs = [
{id: 11, letter: 'A'},
{id: 22, letter: 'B'},
];
var result = includeUtils.buildOneToOneIdentityMapWithOrigKeys(objs, 'id');
result.get(11).should.be.ok;
result.get(22).should.be.ok;
result.getKeys().should.have.lengthOf(2); // no additional properties
result.getKeys().should.eql([11, 22]); // no additional properties
});
});
describe('#buildOneToManyIdentityMap', function() {
it('should return an object with keys', function() {
var objs = [

View File

@ -15,7 +15,7 @@ function givenCacheItem(dataSourceFactory) {
};
function givenModel(dataSourceFactory, modelName,
modelProperties, options) {
modelProperties, options) {
const dataSource = dataSourceFactory();
const Model = dataSource.createModel(modelName, modelProperties);
const p = 'deleteAll' in dataSource.connector ?

View File

@ -69,9 +69,9 @@ module.exports = function(dataSourceFactory, connectorCapabilities) {
it('honours options.ttl', function() {
return CacheItem.set('a-key', 'a-value', {ttl: TTL_PRECISION})
.delay(2 * TTL_PRECISION)
.then(function() { return CacheItem.get('a-key'); })
.then(function(value) { should.equal(value, null); });
.delay(2 * TTL_PRECISION)
.then(function() { return CacheItem.get('a-key'); })
.then(function(value) { should.equal(value, null); });
});
describe('get', function() {

View File

@ -24,25 +24,25 @@ module.exports = function(dataSourceFactory, connectorCapabilities) {
beforeEach(setupCacheItem);
it('gets TTL when key with unexpired TTL exists - Promise API',
function() {
return Promise.resolve(
function() {
return Promise.resolve(
CacheItem.set('a-key', 'a-value', {ttl: INITIAL_TTL}))
.delay(SMALL_DELAY)
.then(function() { return CacheItem.ttl('a-key'); })
.then(function(ttl) { ttl.should.be.within(1, INITIAL_TTL); });
});
.delay(SMALL_DELAY)
.then(function() { return CacheItem.ttl('a-key'); })
.then(function(ttl) { ttl.should.be.within(1, INITIAL_TTL); });
});
it('gets TTL when key with unexpired TTL exists - Callback API',
function(done) {
CacheItem.set('a-key', 'a-value', {ttl: INITIAL_TTL}, function(err) {
if (err) return done(err);
CacheItem.ttl('a-key', function(err, ttl) {
function(done) {
CacheItem.set('a-key', 'a-value', {ttl: INITIAL_TTL}, function(err) {
if (err) return done(err);
ttl.should.be.within(1, INITIAL_TTL);
done();
CacheItem.ttl('a-key', function(err, ttl) {
if (err) return done(err);
ttl.should.be.within(1, INITIAL_TTL);
done();
});
});
});
});
it('succeeds when key without TTL exists', function() {
return CacheItem.set('a-key', 'a-value')
@ -52,7 +52,7 @@ module.exports = function(dataSourceFactory, connectorCapabilities) {
it('fails when getting TTL for a key with expired TTL', function() {
return Promise.resolve(
CacheItem.set('expired-key', 'a-value', {ttl: TTL_PRECISION}))
CacheItem.set('expired-key', 'a-value', {ttl: TTL_PRECISION}))
.delay(2 * TTL_PRECISION)
.then(function() {
return CacheItem.ttl('expired-key');

View File

@ -339,7 +339,7 @@ describe('DataSource define model', function() {
it('supports plain model definitions', function() {
var ds = new DataSource('memory');
// define models
// define models
var Post = ds.define('Post', {
title: {type: String, length: 255},
content: {type: ModelBuilder.Text},
@ -350,7 +350,7 @@ describe('DataSource define model', function() {
published: {type: Boolean, default: false, index: true},
});
// simpler way to describe model
// simpler way to describe model
var User = ds.define('User', {
name: String,
bio: ModelBuilder.Text,
@ -362,7 +362,7 @@ describe('DataSource define model', function() {
var Group = ds.define('Group', {group: String});
User.mixin(Group);
// define any custom method
// define any custom method
User.prototype.getNameAndAge = function() {
return this.name + ', ' + this.age;
};
@ -418,7 +418,7 @@ describe('DataSource define model', function() {
});
});
// should be able to attach a data source to an existing model
// should be able to attach a data source to an existing model
var modelBuilder = new ModelBuilder();
var Color = modelBuilder.define('Color', {
@ -427,7 +427,7 @@ describe('DataSource define model', function() {
Color.should.not.have.property('create');
// attach
// attach
ds.attach(Color);
Color.should.have.property('create');
@ -971,7 +971,7 @@ describe('DataSource connector types', function() {
});
});
describe('DataSource constructor', function() {
describe('DataSource._resolveConnector', function() {
// Mocked require
var loader = function(name) {
if (name.indexOf('./connectors/') !== -1) {

View File

@ -228,11 +228,11 @@ describe('manipulation', function() {
should.exist(p);
should.not.exists(p.name);
return Person.findById(p.id)
.then(function(person) {
person.id.should.eql(p.id);
should.not.exists(person.name);
done();
});
.then(function(person) {
person.id.should.eql(p.id);
should.not.exists(person.name);
done();
});
}).catch(done);
});
@ -528,20 +528,20 @@ describe('manipulation', function() {
});
it('should have updated password hashed with updateAttribute',
function(done) {
StubUser.create({password: 'foo'}, function(err, created) {
if (err) return done(err);
created.updateAttribute('password', 'test', function(err, created) {
function(done) {
StubUser.create({password: 'foo'}, function(err, created) {
if (err) return done(err);
created.password.should.equal('test-TEST');
StubUser.findById(created.id, function(err, found) {
created.updateAttribute('password', 'test', function(err, created) {
if (err) return done(err);
found.password.should.equal('test-TEST');
done();
created.password.should.equal('test-TEST');
StubUser.findById(created.id, function(err, found) {
if (err) return done(err);
found.password.should.equal('test-TEST');
done();
});
});
});
});
});
it('should reject created StubUser with empty password', function(done) {
StubUser.create({email: 'b@example.com', password: ''}, function(err, createdUser) {
@ -574,14 +574,14 @@ describe('manipulation', function() {
it('should update one attribute (promise variant)', function(done) {
person.updateAttribute('name', 'Teddy Graham')
.then(function(p) {
return Person.all()
.then(function(ps) {
ps.should.have.lengthOf(1);
ps.pop().name.should.equal('Teddy Graham');
done();
});
}).catch(done);
.then(function(p) {
return Person.all()
.then(function(ps) {
ps.should.have.lengthOf(1);
ps.pop().name.should.equal('Teddy Graham');
done();
});
}).catch(done);
});
it('should ignore undefined values on updateAttributes', function(done) {
@ -732,10 +732,10 @@ describe('manipulation', function() {
it('should fail if an id value is to be changed on updateAttributes',
function(done) {
person.updateAttributes({id: person.id + 1, name: 'John'},
function(err, p) {
should.exist(err);
done();
});
function(err, p) {
should.exist(err);
done();
});
});
it('has an alias "patchAttributes"', function(done) {
@ -996,14 +996,14 @@ describe('manipulation', function() {
});
it('fails when id does not exist in db & validate is false when using updateAttributes',
function(done) {
var unknownId = uid.fromConnector(db) || 123;
var post = new Post({id: unknownId});
post.updateAttributes({title: 'updated title', content: 'AAA'}, {validate: false}, (err) => {
should(err).have.property('statusCode', 404);
done();
function(done) {
var unknownId = uid.fromConnector(db) || 123;
var post = new Post({id: unknownId});
post.updateAttributes({title: 'updated title', content: 'AAA'}, {validate: false}, (err) => {
should(err).have.property('statusCode', 404);
done();
});
});
});
it('works on create if the request does not include an id', function(done) {
var post = {title: 'a', content: 'AAA'};
@ -1053,45 +1053,45 @@ describe('manipulation', function() {
it('works without options on create (promise variant)', function(done) {
var post = {id: unknownId, title: 'a', content: 'AAA'};
Post.replaceOrCreate(post)
.then(function(p) {
should.exist(p);
p.should.be.instanceOf(Post);
p.id.should.eql(post.id);
p.should.not.have.property('_id');
p.title.should.equal(post.title);
p.content.should.equal(post.content);
return Post.findById(p.id)
.then(function(p) {
should.exist(p);
p.should.be.instanceOf(Post);
p.id.should.eql(post.id);
p.id.should.not.have.property('_id');
p.title.should.equal(p.title);
p.content.should.equal(p.content);
done();
});
})
.catch(done);
p.should.not.have.property('_id');
p.title.should.equal(post.title);
p.content.should.equal(post.content);
return Post.findById(p.id)
.then(function(p) {
p.id.should.eql(post.id);
p.id.should.not.have.property('_id');
p.title.should.equal(p.title);
p.content.should.equal(p.content);
done();
});
})
.catch(done);
});
it('works with options on create (promise variant)', function(done) {
var post = {id: unknownId, title: 'a', content: 'AAA'};
Post.replaceOrCreate(post, {validate: false})
.then(function(p) {
should.exist(p);
p.should.be.instanceOf(Post);
p.id.should.eql(post.id);
p.should.not.have.property('_id');
p.title.should.equal(post.title);
p.content.should.equal(post.content);
return Post.findById(p.id)
.then(function(p) {
should.exist(p);
p.should.be.instanceOf(Post);
p.id.should.eql(post.id);
p.id.should.not.have.property('_id');
p.title.should.equal(p.title);
p.content.should.equal(p.content);
done();
});
})
.catch(done);
p.should.not.have.property('_id');
p.title.should.equal(post.title);
p.content.should.equal(post.content);
return Post.findById(p.id)
.then(function(p) {
p.id.should.eql(post.id);
p.id.should.not.have.property('_id');
p.title.should.equal(p.title);
p.content.should.equal(p.content);
done();
});
})
.catch(done);
});
it('works without options on update (promise variant)', function(done) {
@ -1103,26 +1103,26 @@ describe('manipulation', function() {
delete created.content;
created.title = 'b';
return Post.replaceOrCreate(created)
.then(function(p) {
should.exist(p);
p.should.be.instanceOf(Post);
p.id.should.eql(created.id);
p.should.not.have.property('_id');
p.title.should.equal('b');
p.should.have.property('content', undefined);
p.should.have.property('comments', undefined);
return Post.findById(created.id)
.then(function(p) {
should.exist(p);
p.should.be.instanceOf(Post);
p.id.should.eql(created.id);
p.should.not.have.property('_id');
p.title.should.equal('b');
should.not.exist(p.content);
should.not.exist(p.comments);
done();
p.should.have.property('content', undefined);
p.should.have.property('comments', undefined);
return Post.findById(created.id)
.then(function(p) {
p.should.not.have.property('_id');
p.title.should.equal('b');
should.not.exist(p.content);
should.not.exist(p.comments);
done();
});
});
});
})
.catch(done);
.catch(done);
});
it('works with options on update (promise variant)', function(done) {
@ -1134,26 +1134,26 @@ describe('manipulation', function() {
delete created.content;
created.title = 'b';
return Post.replaceOrCreate(created, {validate: false})
.then(function(p) {
should.exist(p);
p.should.be.instanceOf(Post);
p.id.should.eql(created.id);
p.should.not.have.property('_id');
p.title.should.equal('b');
p.should.have.property('content', undefined);
p.should.have.property('comments', undefined);
return Post.findById(created.id)
.then(function(p) {
should.exist(p);
p.should.be.instanceOf(Post);
p.id.should.eql(created.id);
p.should.not.have.property('_id');
p.title.should.equal('b');
should.not.exist(p.content);
should.not.exist(p.comments);
done();
p.should.have.property('content', undefined);
p.should.have.property('comments', undefined);
return Post.findById(created.id)
.then(function(p) {
p.should.not.have.property('_id');
p.title.should.equal('b');
should.not.exist(p.content);
should.not.exist(p.comments);
done();
});
});
});
})
.catch(done);
.catch(done);
});
it('works without options on update (callback variant)', function(done) {
@ -1279,6 +1279,7 @@ describe('manipulation', function() {
});
});
// eslint-disable-next-line mocha/no-identical-title
it('works on create if the request does not include an id', function(done) {
var post = {title: 'a', content: 'AAA'};
Post.replaceOrCreate(post, function(err, p) {
@ -1289,19 +1290,20 @@ describe('manipulation', function() {
});
});
// eslint-disable-next-line mocha/no-identical-title
it('works on update if the request includes an existing id in db', function(done) {
Post.create({title: 'a', content: 'AAA'},
function(err, post) {
function(err, post) {
if (err) return done(err);
post = post.toObject();
delete post.content;
post.title = 'b';
Post.replaceOrCreate(post, function(err, p) {
if (err) return done(err);
post = post.toObject();
delete post.content;
post.title = 'b';
Post.replaceOrCreate(post, function(err, p) {
if (err) return done(err);
p.id.should.eql(post.id);
done();
});
p.id.should.eql(post.id);
done();
});
});
});
});
@ -1333,20 +1335,20 @@ describe('manipulation', function() {
});
it('should have updated password hashed with replaceAttributes',
function(done) {
StubUser.create({password: 'foo'}, function(err, created) {
if (err) return done(err);
created.replaceAttributes({password: 'test'}, function(err, created) {
function(done) {
StubUser.create({password: 'foo'}, function(err, created) {
if (err) return done(err);
created.password.should.equal('test-TEST');
StubUser.findById(created.id, function(err, found) {
created.replaceAttributes({password: 'test'}, function(err, created) {
if (err) return done(err);
found.password.should.equal('test-TEST');
done();
created.password.should.equal('test-TEST');
StubUser.findById(created.id, function(err, found) {
if (err) return done(err);
found.password.should.equal('test-TEST');
done();
});
});
});
});
});
it('should reject updated empty password with replaceAttributes', function(done) {
StubUser.create({password: 'abc123'}, function(err, createdUser) {
@ -1427,42 +1429,42 @@ describe('manipulation', function() {
it('works without options(promise variant)', function(done) {
Post.findById(postInstance.id)
.then(function(p) {
p.replaceAttributes({title: 'b'})
.then(function(p) {
should.exist(p);
p.should.be.instanceOf(Post);
p.title.should.equal('b');
p.should.have.property('content', undefined);
return Post.findById(postInstance.id)
.then(function(p) {
p.title.should.equal('b');
should.not.exist(p.content);
done();
});
});
})
.catch(done);
p.replaceAttributes({title: 'b'})
.then(function(p) {
should.exist(p);
p.should.be.instanceOf(Post);
p.title.should.equal('b');
p.should.have.property('content', undefined);
return Post.findById(postInstance.id)
.then(function(p) {
p.title.should.equal('b');
should.not.exist(p.content);
done();
});
});
})
.catch(done);
});
it('works with options(promise variant)', function(done) {
Post.findById(postInstance.id)
.then(function(p) {
p.replaceAttributes({title: 'b'}, {validate: false})
.then(function(p) {
should.exist(p);
p.should.be.instanceOf(Post);
p.title.should.equal('b');
p.should.have.property('content', undefined);
return Post.findById(postInstance.id)
.then(function(p) {
p.title.should.equal('b');
should.not.exist(p.content);
done();
});
});
})
.catch(done);
p.replaceAttributes({title: 'b'}, {validate: false})
.then(function(p) {
should.exist(p);
p.should.be.instanceOf(Post);
p.title.should.equal('b');
p.should.have.property('content', undefined);
return Post.findById(postInstance.id)
.then(function(p) {
p.title.should.equal('b');
should.not.exist(p.content);
done();
});
});
})
.catch(done);
});
it('should fail when changing id', function(done) {
@ -1584,18 +1586,18 @@ describe('manipulation', function() {
Person.findOrCreate(
{where: {name: 'Jed'}},
{name: 'Jed', gender: 'male'})
.then(function(res) {
res.should.be.instanceOf(Array);
res.should.have.lengthOf(2);
var p = res[0];
var created = res[1];
p.should.be.instanceOf(Person);
p.name.should.equal('Jed');
p.gender.should.equal('male');
created.should.equal(false);
done();
})
.catch(done);
.then(function(res) {
res.should.be.instanceOf(Array);
res.should.have.lengthOf(2);
var p = res[0];
var created = res[1];
p.should.be.instanceOf(Person);
p.name.should.equal('Jed');
p.gender.should.equal('male');
created.should.equal(false);
done();
})
.catch(done);
});
});
@ -1690,47 +1692,47 @@ describe('manipulation', function() {
});
it('should only delete instances that satisfy the where condition',
function(done) {
Person.deleteAll({name: 'John'}, function(err, info) {
function(done) {
Person.deleteAll({name: 'John'}, function(err, info) {
if (err) return done(err);
info.should.have.property('count', 1);
Person.find({where: {name: 'John'}}, function(err, data) {
if (err) return done(err);
info.should.have.property('count', 1);
Person.find({where: {name: 'John'}}, function(err, data) {
data.should.have.length(0);
Person.find({where: {name: 'Jane'}}, function(err, data) {
if (err) return done(err);
data.should.have.length(0);
Person.find({where: {name: 'Jane'}}, function(err, data) {
if (err) return done(err);
data.should.have.length(1);
done();
});
data.should.have.length(1);
done();
});
});
});
});
it('should report zero deleted instances when no matches are found',
function(done) {
Person.deleteAll({name: 'does-not-match'}, function(err, info) {
function(done) {
Person.deleteAll({name: 'does-not-match'}, function(err, info) {
if (err) return done(err);
info.should.have.property('count', 0);
Person.count(function(err, count) {
if (err) return done(err);
info.should.have.property('count', 0);
Person.count(function(err, count) {
if (err) return done(err);
count.should.equal(2);
done();
});
count.should.equal(2);
done();
});
});
});
it('should delete all instances when the where condition is not provided',
function(done) {
Person.deleteAll(function(err, info) {
function(done) {
Person.deleteAll(function(err, info) {
if (err) return done(err);
info.should.have.property('count', 2);
Person.count(function(err, count) {
if (err) return done(err);
info.should.have.property('count', 2);
Person.count(function(err, count) {
if (err) return done(err);
count.should.equal(0);
done();
});
count.should.equal(0);
done();
});
});
});
});
bdd.describeIf(connectorCapabilities.reportDeletedCount === false &&
@ -1757,55 +1759,59 @@ describe('manipulation', function() {
});
});
// eslint-disable-next-line mocha/no-identical-title
it('should be defined as function', function() {
Person.deleteAll.should.be.a.Function;
Person.destroyAll.should.be.a.Function;
});
// eslint-disable-next-line mocha/no-identical-title
it('should only delete instances that satisfy the where condition',
function(done) {
Person.deleteAll({id: idJohn}, function(err, info) {
function(done) {
Person.deleteAll({id: idJohn}, function(err, info) {
if (err) return done(err);
should.not.exist(info.count);
Person.find({where: {name: 'John'}}, function(err, data) {
if (err) return done(err);
should.not.exist(info.count);
Person.find({where: {name: 'John'}}, function(err, data) {
should.not.exist(data.count);
data.should.have.length(0);
Person.find({where: {name: 'Jane'}}, function(err, data) {
if (err) return done(err);
should.not.exist(data.count);
data.should.have.length(0);
Person.find({where: {name: 'Jane'}}, function(err, data) {
if (err) return done(err);
data.should.have.length(1);
done();
});
data.should.have.length(1);
done();
});
});
});
});
// eslint-disable-next-line mocha/no-identical-title
it('should report zero deleted instances when no matches are found',
function(done) {
var unknownId = uid.fromConnector(db) || 1234567890;
Person.deleteAll({id: unknownId}, function(err, info) {
function(done) {
var unknownId = uid.fromConnector(db) || 1234567890;
Person.deleteAll({id: unknownId}, function(err, info) {
if (err) return done(err);
should.not.exist(info.count);
Person.count(function(err, count) {
if (err) return done(err);
should.not.exist(info.count);
Person.count(function(err, count) {
if (err) return done(err);
count.should.equal(2);
done();
});
count.should.equal(2);
done();
});
});
});
// eslint-disable-next-line mocha/no-identical-title
it('should delete all instances when the where condition is not provided',
function(done) {
Person.deleteAll(function(err, info) {
function(done) {
Person.deleteAll(function(err, info) {
if (err) return done(err);
should.not.exist(info.count);
Person.count(function(err, count) {
if (err) return done(err);
should.not.exist(info.count);
Person.count(function(err, count) {
if (err) return done(err);
count.should.equal(0);
done();
});
count.should.equal(0);
done();
});
});
});
});
describe('deleteById', function() {
@ -1903,22 +1909,22 @@ describe('manipulation', function() {
bdd.itIf(connectorCapabilities.supportStrictDelete !== false, 'should allow delete(id) - ' +
'fail with error', function(done) {
Person.settings.strictDelete = true;
Person.findOne(function(err, u) {
Person.settings.strictDelete = true;
Person.findOne(function(err, u) {
if (err) return done(err);
u.delete(function(err, info) {
if (err) return done(err);
u.delete(function(err, info) {
if (err) return done(err);
info.should.have.property('count', 1);
u.delete(function(err) {
should.exist(err);
err.message.should.equal('No instance with id ' + u.id + ' found for Person');
err.should.have.property('code', 'NOT_FOUND');
err.should.have.property('statusCode', 404);
done();
});
info.should.have.property('count', 1);
u.delete(function(err) {
should.exist(err);
err.message.should.equal('No instance with id ' + u.id + ' found for Person');
err.should.have.property('code', 'NOT_FOUND');
err.should.have.property('statusCode', 404);
done();
});
});
});
});
});
describe('initialize', function() {
@ -1933,7 +1939,7 @@ describe('manipulation', function() {
person.isNewRecord().should.be.true;
});
describe('Date $now function', function() {
describe('Date $now function (type: Date)', function() {
var CustomModel;
before(function(done) {
@ -1957,7 +1963,7 @@ describe('manipulation', function() {
});
});
describe('Date $now function', function() {
describe('Date $now function (type: String)', function() {
var CustomModel;
before(function(done) {
@ -2202,46 +2208,46 @@ describe('manipulation', function() {
});
it('should not update instances that do not satisfy the where condition',
function(done) {
idHarry = uid.fromConnector(db) || undefined;
var filter = connectorCapabilities.updateWithOtherThanId === false ?
{id: idHarry} : {name: 'Harry Hoe'};
Person.update(filter, {name: 'Marta Moe'}, function(err,
function(done) {
idHarry = uid.fromConnector(db) || undefined;
var filter = connectorCapabilities.updateWithOtherThanId === false ?
{id: idHarry} : {name: 'Harry Hoe'};
Person.update(filter, {name: 'Marta Moe'}, function(err,
info) {
if (err) return done(err);
if (connectorCapabilities.reportDeletedCount !== false) {
info.should.have.property('count', 0);
} else {
should.not.exist(info.count);
}
Person.find({where: {name: 'Harry Hoe'}}, function(err, people) {
if (err) return done(err);
if (connectorCapabilities.reportDeletedCount !== false) {
info.should.have.property('count', 0);
} else {
should.not.exist(info.count);
}
Person.find({where: {name: 'Harry Hoe'}}, function(err, people) {
if (err) return done(err);
people.should.be.empty;
done();
});
people.should.be.empty;
done();
});
});
});
it('should only update instances that satisfy the where condition',
function(done) {
var filter = connectorCapabilities.deleteWithOtherThanId === false ?
{id: idBrett} : {name: 'Brett Boe'};
Person.update(filter, {name: 'Harry Hoe'}, function(err,
function(done) {
var filter = connectorCapabilities.deleteWithOtherThanId === false ?
{id: idBrett} : {name: 'Brett Boe'};
Person.update(filter, {name: 'Harry Hoe'}, function(err,
info) {
if (err) return done(err);
if (connectorCapabilities.reportDeletedCount !== false) {
info.should.have.property('count', 1);
} else {
should.not.exist(info.count);
}
Person.find({where: {age: 19}}, function(err, people) {
if (err) return done(err);
if (connectorCapabilities.reportDeletedCount !== false) {
info.should.have.property('count', 1);
} else {
should.not.exist(info.count);
}
Person.find({where: {age: 19}}, function(err, people) {
if (err) return done(err);
people.should.have.length(1);
people[0].name.should.equal('Harry Hoe');
done();
});
people.should.have.length(1);
people[0].name.should.equal('Harry Hoe');
done();
});
});
});
it('should reject updated empty password with updateAll', function(done) {
StubUser.create({password: 'abc123'}, function(err, createdUser) {
@ -2277,16 +2283,16 @@ describe('manipulation', function() {
bdd.itIf(connectorCapabilities.ignoreUndefinedConditionValue !== false, 'should ignore where ' +
'conditions with undefined values', function(done) {
Person.update(filterBrett, {name: undefined, gender: 'male'},
function(err, info) {
if (err) return done(err);
info.should.have.property('count', 1);
Person.find({where: filterBrett}, function(err, people) {
function(err, info) {
if (err) return done(err);
people.should.have.length(1);
people[0].name.should.equal('Brett Boe');
done();
info.should.have.property('count', 1);
Person.find({where: filterBrett}, function(err, people) {
if (err) return done(err);
people.should.have.length(1);
people[0].name.should.equal('Brett Boe');
done();
});
});
});
});
it('should not coerce invalid values provided in where conditions', function(done) {
@ -2355,16 +2361,16 @@ describe('manipulation', function() {
Person.upsertWithWhere({id: 10},
{name: 'updated name'},
function(err, updated) {
if (err) return done(err);
var result = updated.toObject();
result.should.have.properties({
id: instance.id,
name: 'updated name',
});
should.equal(result.city, null);
done();
function(err, updated) {
if (err) return done(err);
var result = updated.toObject();
result.should.have.properties({
id: instance.id,
name: 'updated name',
});
should.equal(result.city, null);
done();
});
});
});

View File

@ -320,19 +320,19 @@ 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)]}}},
function(err, users) {
should(users.length).be.equal(1);
should(users[0].name).be.equal('John Lennon');
done();
});
function(err, users) {
should(users.length).be.equal(1);
should(users[0].name).be.equal('John Lennon');
done();
});
});
it('should successfully extract 2 users from the db', function(done) {
User.find({where: {birthday: {between: [new Date(1940, 0), new Date(1990, 0)]}}},
function(err, users) {
should(users.length).be.equal(2);
done();
});
function(err, users) {
should(users.length).be.equal(2);
done();
});
});
it('should successfully extract 2 users using implied and', function(done) {
@ -358,18 +358,18 @@ describe('Memory connector', function() {
it('should successfully extract 2 users using date range', function(done) {
User.find({where: {birthday: {between:
[new Date(1940, 0).toISOString(), new Date(1990, 0).toISOString()]}}},
function(err, users) {
should(users.length).be.equal(2);
done();
});
function(err, users) {
should(users.length).be.equal(2);
done();
});
});
it('should successfully extract 0 user from the db', function(done) {
User.find({where: {birthday: {between: [new Date(1990, 0), Date.now()]}}},
function(err, users) {
should(users.length).be.equal(0);
done();
});
function(err, users) {
should(users.length).be.equal(0);
done();
});
});
it('should successfully extract 2 users matching over array values', function(done) {
@ -503,14 +503,14 @@ describe('Memory connector', function() {
});
it('should work when a regex is provided without the regexp operator',
function(done) {
User.find({where: {name: /John.*/i}}, function(err, users) {
should.not.exist(err);
users.length.should.equal(1);
users[0].name.should.equal('John Lennon');
done();
});
function(done) {
User.find({where: {name: /John.*/i}}, function(err, users) {
should.not.exist(err);
users.length.should.equal(1);
users[0].name.should.equal('John Lennon');
done();
});
});
it('should support the regexp operator with regex strings', function(done) {
User.find({where: {name: {regexp: '^J'}}}, function(err, users) {
@ -532,7 +532,7 @@ describe('Memory connector', function() {
it('should support the regexp operator with regex objects', function(done) {
User.find({where: {name: {regexp: new RegExp(/^J/)}}}, function(err,
users) {
users) {
should.not.exist(err);
users.length.should.equal(1);
users[0].name.should.equal('John Lennon');
@ -568,8 +568,8 @@ describe('Memory connector', function() {
state: 'CA',
zipCode: '95131',
tags: [
{tag: 'business'},
{tag: 'rent'},
{tag: 'business'},
{tag: 'rent'},
],
},
friends: [
@ -962,14 +962,6 @@ describe('Memory connector with options', function() {
});
});
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) {

View File

@ -76,19 +76,19 @@ describe('Model class inheritance', function() {
// saving original getMergePolicy method
let originalGetMergePolicy = base.getMergePolicy;
// the injected getMergePolicy method captures the provided configureModelMerge option
// the injected getMergePolicy method captures the provided configureModelMerge option
base.getMergePolicy = function(options) {
mergePolicy = options && options.configureModelMerge;
return originalGetMergePolicy(options);
};
// calling extend() on base model calls base.getMergePolicy() internally
// child model settings are passed as 3rd parameter
// calling extend() on base model calls base.getMergePolicy() internally
// child model settings are passed as 3rd parameter
const child = base.extend('child', {}, {configureModelMerge: newMergePolicy});
should.deepEqual(mergePolicy, newMergePolicy);
// restoring original getMergePolicy method
// restoring original getMergePolicy method
base.getMergePolicy = originalGetMergePolicy;
});
@ -109,7 +109,7 @@ describe('Model class inheritance', function() {
it('is inherited by child model', function() {
const child = base.extend('child', {}, {configureModelMerge: true});
// get mergePolicy from child
// get mergePolicy from child
const mergePolicy = child.getMergePolicy({configureModelMerge: true});
should.deepEqual(mergePolicy, recommendedMergePolicy);
});
@ -128,8 +128,8 @@ describe('Model class inheritance', function() {
});
const baseChild = modelBuilder.define('baseChild');
baseChild.attachTo(memory);
// the name of this must begin with a letter < b
// for this test to fail
// the name of this must begin with a letter < b
// for this test to fail
const anotherChild = baseChild.extend('anotherChild');
assert(anotherChild.prototype instanceof baseChild);
@ -220,23 +220,23 @@ describe('Model class inheritance', function() {
});
var Customer = User.extend('Customer',
{customerId: {type: String, id: true}}, {
defaultPermission: 'DENY',
acls: [
{
principalType: 'ROLE',
principalId: '$unauthenticated',
permission: 'DENY',
},
],
relations: {
orders: {
type: 'hasMany',
model: 'Order',
},
{customerId: {type: String, id: true}}, {
defaultPermission: 'DENY',
acls: [
{
principalType: 'ROLE',
principalId: '$unauthenticated',
permission: 'DENY',
},
}
);
],
relations: {
orders: {
type: 'hasMany',
model: 'Order',
},
},
}
);
assert.deepEqual(User.settings, {
// forceId is set to 'auto' in memory if idProp.generated && forceId !== false
@ -291,8 +291,8 @@ describe('Model class inheritance', function() {
});
it('defines rank of ACLs according to model\'s inheritance rank', function() {
// a simple test is enough as we already fully tested option `{rank: true}`
// in tests with flag `configureModelMerge`
// a simple test is enough as we already fully tested option `{rank: true}`
// in tests with flag `configureModelMerge`
const modelBuilder = memory.modelBuilder;
const base = modelBuilder.define('base', {}, {acls: [
{
@ -336,7 +336,7 @@ describe('Model class inheritance', function() {
});
it('replaces baseClass relations with matching subClass relations', function() {
// merge policy of settings.relations is {patch: true}
// merge policy of settings.relations is {patch: true}
const modelBuilder = memory.modelBuilder;
const base = modelBuilder.define('base', {}, {
relations: {
@ -462,7 +462,7 @@ describe('Model class inheritance', function() {
it('`{replace: true}` replaces base model array with sub model matching ' +
'array', function() {
// merge policy of settings.description is {replace: true}
// merge policy of settings.description is {replace: true}
const modelBuilder = memory.modelBuilder;
const base = modelBuilder.define('base', {}, {
description: ['base', 'model', 'description'],
@ -515,7 +515,7 @@ describe('Model class inheritance', function() {
it('`{replace: false}` adds distinct members of matching arrays from ' +
'base model and sub model', function() {
// merge policy of settings.hidden is {replace: false}
// merge policy of settings.hidden is {replace: false}
const modelBuilder = memory.modelBuilder;
const base = modelBuilder.define('base', {}, {
hidden: ['firstProperty', 'secondProperty'],
@ -534,7 +534,7 @@ describe('Model class inheritance', function() {
it('`{patch: true}` adds distinct inner properties of matching objects ' +
'from base model and sub model', function() {
// merge policy of settings.relations is {patch: true}
// merge policy of settings.relations is {patch: true}
const modelBuilder = memory.modelBuilder;
const base = modelBuilder.define('base', {}, {
relations: {
@ -576,7 +576,7 @@ describe('Model class inheritance', function() {
it('`{patch: true}` replaces baseClass inner properties with matching ' +
'subClass inner properties', function() {
// merge policy of settings.relations is {patch: true}
// merge policy of settings.relations is {patch: true}
const modelBuilder = memory.modelBuilder;
const base = modelBuilder.define('base', {}, {
relations: {

View File

@ -22,9 +22,9 @@ describe('optional-validation', function() {
before(function(done) {
db = getSchema();
ModelWithForceId = db.createModel(
'ModelWithForceId',
{name: String},
{forceId: true});
'ModelWithForceId',
{name: String},
{forceId: true});
User = db.define('User', {
seq: {type: Number, index: true},
name: {type: String, index: true, sort: true},
@ -115,26 +115,26 @@ describe('optional-validation', function() {
describe('forceId', function() {
context('replaceAttributes', function() {
it('should not fail if you do not pass the Primary key in data object',
function(done) {
ModelWithForceId.create({name: 'foo'}, function(err, created) {
if (err) return done(err);
created.replaceAttributes({name: 'bar'}, function(err, data) {
done(err);
function(done) {
ModelWithForceId.create({name: 'foo'}, function(err, created) {
if (err) return done(err);
created.replaceAttributes({name: 'bar'}, function(err, data) {
done(err);
});
});
});
});
it('should fail if you pass the Primary key in data object',
function(done) {
ModelWithForceId.create({name: 'foo'}, function(err, created) {
if (err) return done(err);
created.replaceAttributes({name: 'bar', id: 999},
function(err, data) {
should.exist(err);
done();
function(done) {
ModelWithForceId.create({name: 'foo'}, function(err, created) {
if (err) return done(err);
created.replaceAttributes({name: 'bar', id: 999},
function(err, data) {
should.exist(err);
done();
});
});
});
});
});
});
@ -167,28 +167,28 @@ describe('optional-validation', function() {
describe('method findOrCreate', function() {
it('should throw on findOrCreate with validate:true with invalid data',
function(done) {
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: true},
expectValidationError(done));
});
function(done) {
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: true},
expectValidationError(done));
});
it('should NOT throw on findOrCreate with validate:false with invalid data',
function(done) {
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: false},
expectCreateSuccess(INVALID_DATA, done));
});
function(done) {
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: false},
expectCreateSuccess(INVALID_DATA, done));
});
it('should NOT throw on findOrCreate with validate:true with valid data',
function(done) {
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: true},
expectCreateSuccess(done));
});
function(done) {
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: true},
expectCreateSuccess(done));
});
it('should NOT throw on findOrCreate with validate:false with valid data',
function(done) {
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: false},
expectCreateSuccess(done));
});
function(done) {
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: false},
expectCreateSuccess(done));
});
it('should throw on findOrCreate with invalid data', function(done) {
User.findOrCreate(getNewWhere(), INVALID_DATA, expectValidationError(done));
@ -201,28 +201,28 @@ describe('optional-validation', function() {
describe('method updateOrCreate on existing data', function() {
it('should throw on updateOrCreate(id) with validate:true with invalid data',
function(done) {
callUpdateOrCreateWithExistingUserId(null, {validate: true},
expectValidationError(done));
});
function(done) {
callUpdateOrCreateWithExistingUserId(null, {validate: true},
expectValidationError(done));
});
it('should NOT throw on updateOrCreate(id) with validate:false with invalid data',
function(done) {
callUpdateOrCreateWithExistingUserId(null, {validate: false},
expectChangeSuccess(INVALID_DATA, done));
});
function(done) {
callUpdateOrCreateWithExistingUserId(null, {validate: false},
expectChangeSuccess(INVALID_DATA, done));
});
it('should NOT throw on updateOrCreate(id) with validate:true with valid data',
function(done) {
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: true},
expectChangeSuccess(done));
});
function(done) {
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: true},
expectChangeSuccess(done));
});
it('should NOT throw on updateOrCreate(id) with validate:false with valid data',
function(done) {
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: false},
expectChangeSuccess(done));
});
function(done) {
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: false},
expectChangeSuccess(done));
});
// backwards compatible with validateUpsert
it('should NOT throw on updateOrCreate(id) with invalid data', function(done) {
@ -310,17 +310,17 @@ describe('optional-validation', function() {
});
it('returns an error when trying to update the id property when forceId is set to true',
function(done) {
ModelWithForceId.create({name: 'foo'}, function(err, model) {
if (err) return done(err);
model.updateAttributes({id: 123}, function(err) {
err.should.be.instanceOf(Error);
err.message.should.eql('id cannot be updated from ' + model.id +
function(done) {
ModelWithForceId.create({name: 'foo'}, function(err, model) {
if (err) return done(err);
model.updateAttributes({id: 123}, function(err) {
err.should.be.instanceOf(Error);
err.message.should.eql('id cannot be updated from ' + model.id +
' to 123 when forceId is set to true');
done();
done();
});
});
});
});
});
});
@ -358,32 +358,32 @@ describe('optional-validation', function() {
describe('method findOrCreate', function() {
it('should throw on findOrCreate with validate:true with invalid data',
function(done) {
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: true},
expectValidationError(done));
});
function(done) {
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: true},
expectValidationError(done));
});
it('should NOT throw on findOrCreate with validate:false with invalid data',
function(done) {
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: false},
expectCreateSuccess(INVALID_DATA, done));
});
function(done) {
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: false},
expectCreateSuccess(INVALID_DATA, done));
});
it('should NOT throw on findOrCreate with validate:true with valid data',
function(done) {
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: true},
expectCreateSuccess(done));
});
function(done) {
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: true},
expectCreateSuccess(done));
});
it('should NOT throw on findOrCreate with validate:false with valid data',
function(done) {
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: false},
expectCreateSuccess(done));
});
function(done) {
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: false},
expectCreateSuccess(done));
});
it('should NOT throw on findOrCreate with invalid data', function(done) {
User.findOrCreate(getNewWhere(), INVALID_DATA,
expectCreateSuccess(INVALID_DATA, done));
expectCreateSuccess(INVALID_DATA, done));
});
it('should NOT throw on findOrCreate with valid data', function(done) {
@ -393,28 +393,28 @@ describe('optional-validation', function() {
describe('method updateOrCreate on existing data', function() {
it('should throw on updateOrCreate(id) with validate:true with invalid data',
function(done) {
callUpdateOrCreateWithExistingUserId(null, {validate: true},
expectValidationError(done));
});
function(done) {
callUpdateOrCreateWithExistingUserId(null, {validate: true},
expectValidationError(done));
});
it('should NOT throw on updateOrCreate(id) with validate:false with invalid data',
function(done) {
callUpdateOrCreateWithExistingUserId(null, {validate: false},
expectChangeSuccess(INVALID_DATA, done));
});
function(done) {
callUpdateOrCreateWithExistingUserId(null, {validate: false},
expectChangeSuccess(INVALID_DATA, done));
});
it('should NOT throw on updateOrCreate(id) with validate:true with valid data',
function(done) {
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: true},
expectChangeSuccess(done));
});
function(done) {
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: true},
expectChangeSuccess(done));
});
it('should NOT throw on updateOrCreate(id) with validate:false with valid data',
function(done) {
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: false},
expectChangeSuccess(done));
});
function(done) {
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: false},
expectChangeSuccess(done));
});
it('should NOT throw on updateOrCreate(id) with invalid data', function(done) {
callUpdateOrCreateWithExistingUserId(null, expectChangeSuccess(INVALID_DATA, done));
@ -498,28 +498,28 @@ describe('optional-validation', function() {
describe('method findOrCreate', function() {
it('should throw on findOrCreate with validate:true with invalid data',
function(done) {
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: true},
expectValidationError(done));
});
function(done) {
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: true},
expectValidationError(done));
});
it('should NOT throw on findOrCreate with validate:false with invalid data',
function(done) {
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: false},
expectCreateSuccess(INVALID_DATA, done));
});
function(done) {
User.findOrCreate(getNewWhere(), INVALID_DATA, {validate: false},
expectCreateSuccess(INVALID_DATA, done));
});
it('should NOT throw on findOrCreate with validate:true with valid data',
function(done) {
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: true},
expectCreateSuccess(done));
});
function(done) {
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: true},
expectCreateSuccess(done));
});
it('should NOT throw on findOrCreate with validate:false with valid data',
function(done) {
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: false},
expectCreateSuccess(done));
});
function(done) {
User.findOrCreate(getNewWhere(), VALID_DATA, {validate: false},
expectCreateSuccess(done));
});
it('should throw on findOrCreate with invalid data', function(done) {
User.findOrCreate(getNewWhere(), INVALID_DATA, expectValidationError(done));
@ -532,28 +532,28 @@ describe('optional-validation', function() {
describe('method updateOrCreate on existing data', function() {
it('should throw on updateOrCreate(id) with validate:true with invalid data',
function(done) {
callUpdateOrCreateWithExistingUserId(null, {validate: true},
expectValidationError(done));
});
function(done) {
callUpdateOrCreateWithExistingUserId(null, {validate: true},
expectValidationError(done));
});
it('should NOT throw on updateOrCreate(id) with validate:false with invalid data',
function(done) {
callUpdateOrCreateWithExistingUserId(null, {validate: false},
expectChangeSuccess(INVALID_DATA, done));
});
function(done) {
callUpdateOrCreateWithExistingUserId(null, {validate: false},
expectChangeSuccess(INVALID_DATA, done));
});
it('should NOT throw on updateOrCreate(id) with validate:true with valid data',
function(done) {
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: true},
expectChangeSuccess(done));
});
function(done) {
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: true},
expectChangeSuccess(done));
});
it('should NOT throw on updateOrCreate(id) with validate:false with valid data',
function(done) {
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: false},
expectChangeSuccess(done));
});
function(done) {
callUpdateOrCreateWithExistingUserId(NEW_NAME, {validate: false},
expectChangeSuccess(done));
});
it('should throw on updateOrCreate(id) with invalid data', function(done) {
callUpdateOrCreateWithExistingUserId(null, expectValidationError(done));

View File

@ -140,26 +140,26 @@ module.exports = function(dataSource, should, connectorCapabilities) {
});
it('triggers the loaded hook multiple times when multiple instances exist when near filter is used',
function(done) {
var hookMonitorGeoModel;
hookMonitorGeoModel = new HookMonitor({includeModelName: false});
function(done) {
var hookMonitorGeoModel;
hookMonitorGeoModel = new HookMonitor({includeModelName: false});
function monitorHookExecutionGeoModel(hookNames) {
hookMonitorGeoModel.install(GeoModel, hookNames);
}
function monitorHookExecutionGeoModel(hookNames) {
hookMonitorGeoModel.install(GeoModel, hookNames);
}
monitorHookExecutionGeoModel();
monitorHookExecutionGeoModel();
var query = {
where: {location: {near: '10,5'}},
};
GeoModel.find(query, function(err, list) {
if (err) return done(err);
var query = {
where: {location: {near: '10,5'}},
};
GeoModel.find(query, function(err, list) {
if (err) return done(err);
hookMonitorGeoModel.names.should.eql(['access', 'loaded', 'loaded']);
done();
hookMonitorGeoModel.names.should.eql(['access', 'loaded', 'loaded']);
done();
});
});
});
it('applies updates from `loaded` hook when near filter is used', function(done) {
GeoModel.observe('loaded', function(ctx, next) {
@ -179,23 +179,23 @@ module.exports = function(dataSource, should, connectorCapabilities) {
});
it('applies updates to one specific instance from `loaded` hook when near filter is used',
function(done) {
GeoModel.observe('loaded', function(ctx, next) {
if (ctx.data.name === 'Rome')
ctx.data.name = 'Berlin';
next();
});
function(done) {
GeoModel.observe('loaded', function(ctx, next) {
if (ctx.data.name === 'Rome')
ctx.data.name = 'Berlin';
next();
});
var query = {
where: {location: {near: '10,5'}},
};
var query = {
where: {location: {near: '10,5'}},
};
GeoModel.find(query, function(err, list) {
if (err) return done(err);
list.map(get('name')).should.containEql('Berlin', 'Tokyo');
done();
GeoModel.find(query, function(err, list) {
if (err) return done(err);
list.map(get('name')).should.containEql('Berlin', 'Tokyo');
done();
});
});
});
it('applies updates from `loaded` hook when near filter is not used', function(done) {
TestModel.observe('loaded', function(ctx, next) {
@ -211,33 +211,33 @@ module.exports = function(dataSource, should, connectorCapabilities) {
});
it('applies updates to one specific instance from `loaded` hook when near filter is not used',
function(done) {
TestModel.observe('loaded', function(ctx, next) {
if (ctx.data.name === 'first')
ctx.data.name = 'Paris';
next();
});
function(done) {
TestModel.observe('loaded', function(ctx, next) {
if (ctx.data.name === 'first')
ctx.data.name = 'Paris';
next();
});
TestModel.find(function(err, list) {
if (err) return done(err);
list.map(get('name')).should.eql(['Paris', 'second']);
done();
});
});
it('should not trigger hooks for geo queries, if notify is false',
function(done) {
monitorHookExecution();
TestModel.find(
{where: {geo: {near: '10,20'}}},
{notify: false},
function(err, list) {
TestModel.find(function(err, list) {
if (err) return done(err);
hookMonitor.names.should.be.empty();
list.map(get('name')).should.eql(['Paris', 'second']);
done();
});
});
});
it('should not trigger hooks for geo queries, if notify is false',
function(done) {
monitorHookExecution();
TestModel.find(
{where: {geo: {near: '10,20'}}},
{notify: false},
function(err, list) {
if (err) return done(err);
hookMonitor.names.should.be.empty();
done();
});
});
it('should apply updates from `access` hook', function(done) {
TestModel.observe('access', function(ctx, next) {
@ -805,12 +805,12 @@ module.exports = function(dataSource, should, connectorCapabilities) {
record.id.should.eql(existingInstance.id);
// `findOrCreate` creates a new instance of the object everytime.
// So, `data.id` as well as `currentInstance.id` always matches
// the newly generated UID.
// Hence, the test below asserts both `data.id` and
// `currentInstance.id` to match getLastGeneratedUid().
// On same lines, it also asserts `isNewInstance` to be true.
// `findOrCreate` creates a new instance of the object everytime.
// So, `data.id` as well as `currentInstance.id` always matches
// the newly generated UID.
// Hence, the test below asserts both `data.id` and
// `currentInstance.id` to match getLastGeneratedUid().
// On same lines, it also asserts `isNewInstance` to be true.
ctxRecorder.records.should.eql(aCtxForModel(TestModel, {
data: {
id: getLastGeneratedUid(),
@ -952,9 +952,9 @@ module.exports = function(dataSource, should, connectorCapabilities) {
record.id.should.eql(existingInstance.id);
// After the call to `connector.findOrCreate`, since the record
// already exists, `data.id` matches `existingInstance.id`
// as against the behaviour noted for `persist` hook
// After the call to `connector.findOrCreate`, since the record
// already exists, `data.id` matches `existingInstance.id`
// as against the behaviour noted for `persist` hook
ctxRecorder.records.should.eql(aCtxForModel(TestModel, {
data: {
id: existingInstance.id,
@ -2258,7 +2258,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
});
if (!dataSource.connector.replaceById) {
describe.skip('replaceById - not implemented', function() {});
describe.skip('replaceOrCreate - not implemented', function() {});
} else {
describe('PersistedModel.replaceOrCreate', function() {
it('triggers hooks in the correct order on create', function(done) {
@ -2400,19 +2400,19 @@ module.exports = function(dataSource, should, connectorCapabilities) {
it('triggers `before save` hookon create', function(done) {
TestModel.observe('before save', ctxRecorder.recordAndNext());
TestModel.replaceOrCreate({id: existingInstance.id, name: 'new name'},
function(err, instance) {
if (err)
return done(err);
function(err, instance) {
if (err)
return done(err);
var expectedContext = aCtxForModel(TestModel, {
instance: instance,
var expectedContext = aCtxForModel(TestModel, {
instance: instance,
});
if (!dataSource.connector.replaceOrCreate) {
expectedContext.isNewInstance = false;
}
done();
});
if (!dataSource.connector.replaceOrCreate) {
expectedContext.isNewInstance = false;
}
done();
});
});
it('triggers `before save` hook on replace', function(done) {
@ -2573,7 +2573,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
expected.isNewInstance =
isNewInstanceFlag ?
true : undefined;
true : undefined;
ctxRecorder.records.should.eql(aCtxForModel(TestModel, expected));
done();
@ -2597,7 +2597,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
expected.isNewInstance =
isNewInstanceFlag ?
false : undefined;
false : undefined;
ctxRecorder.records.should.eql(aCtxForModel(TestModel, expected));
done();
@ -2632,7 +2632,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
expected.isNewInstance =
isNewInstanceFlag ?
false : undefined;
false : undefined;
ctxRecorder.records.should.eql(aCtxForModel(TestModel, expected));
done();
@ -2656,7 +2656,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
};
expected.isNewInstance =
isNewInstanceFlag ?
true : undefined;
true : undefined;
ctxRecorder.records.should.eql(aCtxForModel(TestModel, expected));
done();
@ -3162,14 +3162,14 @@ module.exports = function(dataSource, should, connectorCapabilities) {
TestModel.observe('access', ctxRecorder.recordAndNext());
TestModel.upsertWithWhere({id: existingInstance.id},
{name: 'new name', extra: 'new extra'},
function(err, instance) {
if (err) return done(err);
ctxRecorder.records.should.eql(aCtxForModel(TestModel, {query: {
where: {id: existingInstance.id},
}}));
done();
});
{name: 'new name', extra: 'new extra'},
function(err, instance) {
if (err) return done(err);
ctxRecorder.records.should.eql(aCtxForModel(TestModel, {query: {
where: {id: existingInstance.id},
}}));
done();
});
});
it('triggers hooks only once', function(done) {
@ -3236,27 +3236,27 @@ module.exports = function(dataSource, should, connectorCapabilities) {
TestModel.observe('before save', ctxRecorder.recordAndNext());
TestModel.upsertWithWhere({id: existingInstance.id},
{id: existingInstance.id, name: 'updated name'},
function(err, instance) {
if (err) return done(err);
var expectedContext = aCtxForModel(TestModel, {
where: {id: existingInstance.id},
data: {
id: existingInstance.id,
name: 'updated name',
},
});
if (!dataSource.connector.upsertWithWhere) {
// the difference between `existingInstance` and the following
// plain-data object is `currentInstance` the missing fields are
// null in `currentInstance`, wehere as in `existingInstance` they
// are undefined; please see other tests for example see:
// test for "PersistedModel.create triggers `persist` hook"
expectedContext.currentInstance = {id: existingInstance.id, name: 'first', extra: null};
}
ctxRecorder.records.should.eql(expectedContext);
done();
});
{id: existingInstance.id, name: 'updated name'},
function(err, instance) {
if (err) return done(err);
var expectedContext = aCtxForModel(TestModel, {
where: {id: existingInstance.id},
data: {
id: existingInstance.id,
name: 'updated name',
},
});
if (!dataSource.connector.upsertWithWhere) {
// the difference between `existingInstance` and the following
// plain-data object is `currentInstance` the missing fields are
// null in `currentInstance`, wehere as in `existingInstance` they
// are undefined; please see other tests for example see:
// test for "PersistedModel.create triggers `persist` hook"
expectedContext.currentInstance = {id: existingInstance.id, name: 'first', extra: null};
}
ctxRecorder.records.should.eql(expectedContext);
done();
});
});
it('triggers `before save` hook on create', function(done) {
@ -3287,12 +3287,12 @@ module.exports = function(dataSource, should, connectorCapabilities) {
});
TestModel.upsertWithWhere({id: existingInstance.id},
{name: 'updated name'},
function(err, instance) {
if (err) return done(err);
instance.name.should.equal('hooked');
done();
});
{name: 'updated name'},
function(err, instance) {
if (err) return done(err);
instance.name.should.equal('hooked');
done();
});
});
it('applies updates from `before save` hook on create', function(done) {
@ -3429,11 +3429,11 @@ module.exports = function(dataSource, should, connectorCapabilities) {
it('emits error when `loaded` hook fails', function(done) {
TestModel.observe('loaded', nextWithError(expectedError));
TestModel.upsertWithWhere({id: 'new-id'},
{id: 'new-id', name: 'a name'},
function(err, instance) {
[err].should.eql([expectedError]);
done();
});
{id: 'new-id', name: 'a name'},
function(err, instance) {
[err].should.eql([expectedError]);
done();
});
});
it('triggers `after save` hook on update', function(done) {

File diff suppressed because it is too large Load Diff

View File

@ -127,7 +127,7 @@ describe('util.parseSettings', function() {
should.equal(settings.url, 'mysql://127.0.0.1:3306/mydb?x[a]=1&x[b]=2&engine=InnoDB');
});
it('Parse a url without auth into a settings object', function() {
it('Parse a Memory url without auth into a settings object', function() {
var url = 'memory://?x=1';
var settings = utils.parseSettings(url);
should.equal(settings.hostname, '');
@ -145,7 +145,7 @@ describe('util.deepMerge', function() {
var extras = {base: 'User',
relations: {accessTokens: {model: 'accessToken', type: 'hasMany',
foreignKey: 'userId'},
account: {model: 'account', type: 'belongsTo'}},
account: {model: 'account', type: 'belongsTo'}},
acls: [
{accessType: '*',
permission: 'DENY',
@ -206,7 +206,7 @@ describe('util.deepMerge', function() {
base: 'User',
relations: {accessTokens: {model: 'accessToken', type: 'hasMany',
foreignKey: 'userId'},
account: {model: 'account', type: 'belongsTo'}}};
account: {model: 'account', type: 'belongsTo'}}};
should.deepEqual(merged, expected, 'Merged objects should match the expectation');
});
@ -495,19 +495,19 @@ describe('util.toRegExp', function() {
context('with a regex string', function() {
it('should return a RegExp object when no regex flags are provided',
function() {
utils.toRegExp('^regex$').should.be.an.instanceOf(RegExp);
});
function() {
utils.toRegExp('^regex$').should.be.an.instanceOf(RegExp);
});
it('should throw an error when invalid regex flags are provided',
function() {
utils.toRegExp('^regex$/abc').should.be.an.Error;
});
function() {
utils.toRegExp('^regex$/abc').should.be.an.Error;
});
it('should return a RegExp object when valid flags are provided',
function() {
utils.toRegExp('regex/igm').should.be.an.instanceOf(RegExp);
});
function() {
utils.toRegExp('regex/igm').should.be.an.instanceOf(RegExp);
});
});
context('with a regex literal', function() {