fix remaining eslint issues

This commit is contained in:
Miroslav Bajtoš 2016-04-01 15:23:42 +02:00 committed by Miroslav Bajtoš
parent 39e04a1756
commit 27c6279d6c
40 changed files with 574 additions and 484 deletions

View File

@ -22,7 +22,7 @@ var application = {
'pushOptions': { 'pushOptions': {
'gateway': 'gateway.sandbox.push.apple.com', 'gateway': 'gateway.sandbox.push.apple.com',
'cert': 'credentials/apns_cert_dev.pem', 'cert': 'credentials/apns_cert_dev.pem',
'key': "credentials/apns_key_dev.pem", 'key': 'credentials/apns_key_dev.pem',
}, },
'feedbackOptions': { 'feedbackOptions': {

View File

@ -9,7 +9,6 @@ var User, Post, Passport, City, Street, Building;
var nbSchemaRequests = 0; var nbSchemaRequests = 0;
setup(function() { setup(function() {
Passport.find({ include: 'owner' }, function(err, passports) { Passport.find({ include: 'owner' }, function(err, passports) {
console.log('passports.owner', passports); console.log('passports.owner', passports);
}); });
@ -31,7 +30,6 @@ setup(function() {
User.find({ include: ['posts', 'passports'] }, function(err, users) { User.find({ include: ['posts', 'passports'] }, function(err, users) {
console.log('users.passports && users.posts', users); console.log('users.passports && users.posts', users);
}); });
}); });
function setup(done) { function setup(done) {
@ -108,7 +106,6 @@ function setup(done) {
} }
); );
} }
}); });
} }

View File

@ -22,7 +22,6 @@ function loadSchemasSync(schemaFile, dataSource) {
var schemas = JSON.parse(fs.readFileSync(schemaFile)); var schemas = JSON.parse(fs.readFileSync(schemaFile));
return dataSource.buildModels(schemas); return dataSource.buildModels(schemas);
} }
var models = loadSchemasSync(path.join(__dirname, 'jdb-schemas.json')); var models = loadSchemasSync(path.join(__dirname, 'jdb-schemas.json'));

View File

@ -29,10 +29,14 @@ var User = modelBuilder.define('User', {
friends: [String], friends: [String],
}); });
var user = new User({ name: 'Joe', age: 20, address: { street: '123 Main St', 'city': 'San Jose', state: 'CA' }, var user = new User({
name: 'Joe',
age: 20,
address: { street: '123 Main St', 'city': 'San Jose', state: 'CA' },
emails: [ emails: [
{ label: 'work', email: 'xyz@sample.com' }, { label: 'work', email: 'xyz@sample.com' },
], ],
friends: ['John', 'Mary'] }); friends: ['John', 'Mary'],
});
console.log(user); console.log(user);
console.log(user.toObject()); console.log(user.toObject());

View File

@ -33,7 +33,6 @@ Customer.create({ name: 'John' }, function(err, customer) {
}); });
Order.create({ orderDate: new Date(), items: ['Phone'] }, function(err, order) { Order.create({ orderDate: new Date(), items: ['Phone'] }, function(err, order) {
order.customer.create({ name: 'Smith' }, function(err, customer2) { order.customer.create({ name: 'Smith' }, function(err, customer2) {
console.log(order, customer2); console.log(order, customer2);
order.save(function(err, order) { order.save(function(err, order) {
@ -90,9 +89,11 @@ Physician.create({ name: 'Dr John' }, function(err, physician1) {
Physician.create({ name: 'Dr Smith' }, function(err, physician2) { Physician.create({ name: 'Dr Smith' }, function(err, physician2) {
Patient.create({ name: 'Mary' }, function(err, patient1) { Patient.create({ name: 'Mary' }, function(err, patient1) {
Patient.create({ name: 'Ben' }, function(err, patient2) { Patient.create({ name: 'Ben' }, function(err, patient2) {
Appointment.create({ appointmentDate: new Date(), physicianId: physician1.id, patientId: patient1.id }, Appointment.create(
{ appointmentDate: new Date(), physicianId: physician1.id, patientId: patient1.id },
function(err, appt1) { function(err, appt1) {
Appointment.create({ appointmentDate: new Date(), physicianId: physician1.id, patientId: patient2.id }, Appointment.create(
{ appointmentDate: new Date(), physicianId: physician1.id, patientId: patient2.id },
function(err, appt2) { function(err, appt2) {
physician1.patients(console.log); physician1.patients(console.log);
physician1.patients({ where: { name: 'Mary' }}, console.log); physician1.patients({ where: { name: 'Mary' }}, console.log);
@ -106,8 +107,6 @@ Physician.create({ name: 'Dr John' }, function(err, physician1) {
patient1.physicians.create({ name: 'Dr X' }, function(err, patient4) { patient1.physicians.create({ name: 'Dr X' }, function(err, patient4) {
console.log('Physician 4: ', patient4, patient4.constructor.modelName); console.log('Physician 4: ', patient4, patient4.constructor.modelName);
}); });
}); });
}); });
}); });
@ -146,7 +145,6 @@ Assembly.create({ name: 'car' }, function(err, assembly) {
}); });
}); });
}); });
}); });
}); });

View File

@ -381,7 +381,7 @@ Memory.prototype._findAllSkippingIncludes = function(model, filter) {
key = key.replace(/\s+(A|DE)SC/i, ''); key = key.replace(/\s+(A|DE)SC/i, '');
if (m[1].toLowerCase() === 'de') reverse = -1; if (m[1].toLowerCase() === 'de') reverse = -1;
} }
orders[i] = {'key': key, 'reverse': reverse }; orders[i] = { 'key': key, 'reverse': reverse };
}); });
nodes = nodes.sort(sorting.bind(orders)); nodes = nodes.sort(sorting.bind(orders));
} }
@ -526,8 +526,7 @@ function applyFilter(filter) {
regex += '\\.'; regex += '\\.';
} else if (char === '*') { } else if (char === '*') {
regex += '\\*'; regex += '\\*';
} } else {
else {
regex += char; regex += char;
} }
} }
@ -568,12 +567,11 @@ function applyFilter(filter) {
} }
if ('between' in example) { if ('between' in example) {
return (testInEquality({ gte:example.between[0] }, value) && return (testInEquality({ gte: example.between[0] }, value) &&
testInEquality({ lte:example.between[1] }, value)); testInEquality({ lte: example.between[1] }, value));
} }
if (example.like || example.nlike) { if (example.like || example.nlike) {
var like = example.like || example.nlike; var like = example.like || example.nlike;
if (typeof like === 'string') { if (typeof like === 'string') {
like = toRegExp(like); like = toRegExp(like);
@ -592,8 +590,8 @@ function applyFilter(filter) {
} }
} }
// not strict equality // not strict equality
return (example !== null ? example.toString() : example) return (example !== null ? example.toString() : example) ==
== (value != null ? value.toString() : value); (value != null ? value.toString() : value);
} }
/** /**

View File

@ -67,9 +67,9 @@ function convertSubsetOfPropertiesByType(inst, data) {
for (var key in data) { for (var key in data) {
// Convert the properties by type // Convert the properties by type
typedData[key] = inst[key]; typedData[key] = inst[key];
if (typeof typedData[key] === 'object' if (typeof typedData[key] === 'object' &&
&& typedData[key] !== null typedData[key] !== null &&
&& typeof typedData[key].toObject === 'function') { typeof typedData[key].toObject === 'function') {
typedData[key] = typedData[key].toObject(); typedData[key] = typedData[key].toObject();
} }
} }
@ -906,7 +906,6 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
} }
if (!err) Model.emit('changed', obj); if (!err) Model.emit('changed', obj);
}); });
} else { } else {
if (cb.promise) { if (cb.promise) {
cb(err, [obj, created]); cb(err, [obj, created]);
@ -923,7 +922,7 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, options, cb)
where: query.where, where: query.where,
data: data, data: data,
isNewInstance: true, isNewInstance: true,
currentInstance : currentInstance, currentInstance: currentInstance,
hookState: hookState, hookState: hookState,
options: options, options: options,
}; };
@ -1755,8 +1754,7 @@ DataAccessObject.find = function find(query, options, cb) {
cb(err, results); cb(err, results);
}); });
} } else {
else {
cb(err, data || []); cb(err, data || []);
} }
}; };
@ -1841,7 +1839,9 @@ DataAccessObject.findOne = function findOne(query, options, cb) {
* @param {Object) [options] Options * @param {Object) [options] Options
* @param {Function} [cb] Callback called with (err, info) * @param {Function} [cb] Callback called with (err, info)
*/ */
DataAccessObject.remove = DataAccessObject.deleteAll = DataAccessObject.destroyAll = function destroyAll(where, options, cb) { DataAccessObject.remove =
DataAccessObject.deleteAll =
DataAccessObject.destroyAll = function destroyAll(where, options, cb) {
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments); var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
if (connectionPromise) { if (connectionPromise) {
return connectionPromise; return connectionPromise;
@ -1899,15 +1899,15 @@ DataAccessObject.remove = DataAccessObject.deleteAll = DataAccessObject.destroyA
Model.notifyObserversOf('access', context, function(err, ctx) { Model.notifyObserversOf('access', context, function(err, ctx) {
if (err) return cb(err); if (err) return cb(err);
var context = { var context = {
Model: Model, Model: Model,
where: ctx.query.where, where: ctx.query.where,
hookState: hookState, hookState: hookState,
options: options, options: options,
}; };
Model.notifyObserversOf('before delete', context, function(err, ctx) { Model.notifyObserversOf('before delete', context, function(err, ctx) {
if (err) return cb(err); if (err) return cb(err);
doDelete(ctx.where); doDelete(ctx.where);
}); });
}); });
} }
@ -1934,7 +1934,6 @@ DataAccessObject.remove = DataAccessObject.deleteAll = DataAccessObject.destroyA
} else { } else {
connector.destroyAll(Model.modelName, where, done); connector.destroyAll(Model.modelName, where, done);
} }
} }
function done(err, info) { function done(err, info) {
@ -1975,7 +1974,9 @@ function whereIsEmpty(where) {
// [FIXME] rfeng: This is a hack to set up 'deleteById' first so that // [FIXME] rfeng: This is a hack to set up 'deleteById' first so that
// 'deleteById' will be used as the name for strong-remoting to keep it backward // 'deleteById' will be used as the name for strong-remoting to keep it backward
// compatible for angular SDK // compatible for angular SDK
DataAccessObject.removeById = DataAccessObject.destroyById = DataAccessObject.deleteById = function deleteById(id, options, cb) { DataAccessObject.removeById =
DataAccessObject.destroyById =
DataAccessObject.deleteById = function deleteById(id, options, cb) {
var connectionPromise = stillConnecting(this.getDataSource(), this, arguments); var connectionPromise = stillConnecting(this.getDataSource(), this, arguments);
if (connectionPromise) { if (connectionPromise) {
return connectionPromise; return connectionPromise;
@ -2253,7 +2254,6 @@ DataAccessObject.prototype.save = function(options, cb) {
connector.save(modelName, inst.constructor._forDB(data), saveCallback); connector.save(modelName, inst.constructor._forDB(data), saveCallback);
} }
}); });
}, data, cb); }, data, cb);
}, data, cb); }, data, cb);
} }
@ -2298,7 +2298,6 @@ DataAccessObject.updateAll = function(where, data, options, cb) {
data = where; data = where;
where = {}; where = {};
} }
} else if (cb === undefined) { } else if (cb === undefined) {
// One of: // One of:
// updateAll(where, data, options) -> Promise // updateAll(where, data, options) -> Promise
@ -2459,16 +2458,16 @@ DataAccessObject.prototype.remove =
Model.notifyObserversOf('access', context, function(err, ctx) { Model.notifyObserversOf('access', context, function(err, ctx) {
if (err) return cb(err); if (err) return cb(err);
var context = { var context = {
Model: Model, Model: Model,
where: ctx.query.where, where: ctx.query.where,
instance: inst, instance: inst,
hookState: hookState, hookState: hookState,
options: options, options: options,
}; };
Model.notifyObserversOf('before delete', context, function(err, ctx) { Model.notifyObserversOf('before delete', context, function(err, ctx) {
if (err) return cb(err); if (err) return cb(err);
doDeleteInstance(ctx.where); doDeleteInstance(ctx.where);
}); });
}); });
function doDeleteInstance(where) { function doDeleteInstance(where) {
@ -2721,7 +2720,7 @@ DataAccessObject.replaceById = function(id, data, options, cb) {
Model: Model, Model: Model,
hookState: hookState, hookState: hookState,
data: context.data, data: context.data,
isNewInstance:false, isNewInstance: false,
options: options, options: options,
}; };
Model.notifyObserversOf('loaded', ctx, function(err) { Model.notifyObserversOf('loaded', ctx, function(err) {
@ -2749,7 +2748,7 @@ DataAccessObject.replaceById = function(id, data, options, cb) {
Model: Model, Model: Model,
where: byIdQuery(Model, id).where, where: byIdQuery(Model, id).where,
data: context.data, data: context.data,
isNewInstance:false, isNewInstance: false,
currentInstance: inst, currentInstance: inst,
hookState: hookState, hookState: hookState,
options: options, options: options,
@ -2811,8 +2810,8 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, op
if (isPKMissing(Model, cb)) if (isPKMissing(Model, cb))
return cb.promise; return cb.promise;
var allowExtendedOperators = connector.settings var allowExtendedOperators = connector.settings &&
&& connector.settings.allowExtendedOperators; connector.settings.allowExtendedOperators;
var strict = this.__strict; var strict = this.__strict;
var model = Model.modelName; var model = Model.modelName;

View File

@ -156,7 +156,6 @@ function DataSource(name, settings, modelBuilder) {
}); });
} }
}.bind(this)); }.bind(this));
} }
util.inherits(DataSource, EventEmitter); util.inherits(DataSource, EventEmitter);
@ -314,22 +313,22 @@ DataSource.prototype.setup = function(name, settings) {
if (connector) { if (connector) {
var postInit = function postInit(err, result) { var postInit = function postInit(err, result) {
this._setupConnector(); this._setupConnector();
// we have an connector now? // we have an connector now?
if (!this.connector) { if (!this.connector) {
throw new Error('Connector is not defined correctly: it should create `connector` member of dataSource'); throw new Error('Connector is not defined correctly: ' +
'it should create `connector` member of dataSource');
} }
this.connected = !err; // Connected now this.connected = !err; // Connected now
if (this.connected) { if (this.connected) {
this.emit('connected'); this.emit('connected');
} else { } else {
// The connection fails, let's report it and hope it will be recovered in the next call // The connection fails, let's report it and hope it will be recovered in the next call
console.error('Connection fails: ', err, '\nIt will be retried for the next request.'); console.error('Connection fails: ', err,
'\nIt will be retried for the next request.');
this.emit('error', err); this.emit('error', err);
this.connecting = false; this.connecting = false;
} }
}.bind(this); }.bind(this);
try { try {
@ -434,8 +433,8 @@ DataSource.prototype.defineRelations = function(modelClass, relations) {
modelClass[relation.type].call(modelClass, name, params); modelClass[relation.type].call(modelClass, name, params);
} }
}); });
} }
if (throughModel && !isModelDataSourceAttached(throughModel)) { if (throughModel && !isModelDataSourceAttached(throughModel)) {
// Set up a listener to the through model // Set up a listener to the through model
throughModel.once('dataAccessConfigured', function(model) { throughModel.once('dataAccessConfigured', function(model) {
@ -480,8 +479,8 @@ DataSource.prototype.defineRelations = function(modelClass, relations) {
throughModel = isModelClass(r.through) ? r.through : self.getModel(r.through, true); throughModel = isModelClass(r.through) ? r.through : self.getModel(r.through, true);
} }
if ((targetModel && !isModelDataSourceAttached(targetModel)) if ((targetModel && !isModelDataSourceAttached(targetModel)) ||
|| (throughModel && !isModelDataSourceAttached(throughModel))) { (throughModel && !isModelDataSourceAttached(throughModel))) {
// Create a listener to defer the relation set up // Create a listener to defer the relation set up
createListener(rn, r, targetModel, throughModel); createListener(rn, r, targetModel, throughModel);
} else { } else {
@ -542,7 +541,6 @@ DataSource.prototype.setupDataAccess = function(modelClass, settings) {
// define scopes from LDL (options.relations) // define scopes from LDL (options.relations)
var scopes = settings.scopes || {}; var scopes = settings.scopes || {};
this.defineScopes(modelClass, scopes); this.defineScopes(modelClass, scopes);
}; };
/** /**
@ -594,7 +592,8 @@ DataSource.prototype.setupDataAccess = function(modelClass, settings) {
* *
*/ */
DataSource.prototype.createModel = DataSource.prototype.define = function defineClass(className, properties, settings) { DataSource.prototype.createModel =
DataSource.prototype.define = function defineClass(className, properties, settings) {
var args = slice.call(arguments); var args = slice.call(arguments);
if (!className) { if (!className) {
@ -752,7 +751,6 @@ DataSource.prototype.attach = function(modelClass) {
this.setupDataAccess(modelClass, modelClass.settings); this.setupDataAccess(modelClass, modelClass.settings);
modelClass.emit('dataSourceAttached', modelClass); modelClass.emit('dataSourceAttached', modelClass);
return modelClass; return modelClass;
}; };
/** /**
@ -1311,7 +1309,6 @@ DataSource.prototype.discoverSchemas = function(modelName, options, cb) {
} }
async.parallel(tasks, function(err, results) { async.parallel(tasks, function(err, results) {
if (err) { if (err) {
cb(err); cb(err);
return cb.promise; return cb.promise;
@ -1351,8 +1348,8 @@ DataSource.prototype.discoverSchemas = function(modelName, options, cb) {
var propName = nameMapper('column', item.columnName); var propName = nameMapper('column', item.columnName);
schema.properties[propName] = { schema.properties[propName] = {
type: item.type, type: item.type,
required: (item.nullable === 'N' || item.nullable === 'NO' required: (item.nullable === 'N' || item.nullable === 'NO' ||
|| item.nullable === 0 || item.nullable === false), item.nullable === 0 || item.nullable === false),
length: item.dataLength, length: item.dataLength,
precision: item.dataPrecision, precision: item.dataPrecision,
scale: item.dataScale, scale: item.dataScale,
@ -1593,7 +1590,6 @@ DataSource.prototype.discoverSchemasSync = function(modelName, options) {
self.discoverSchemasSync(otherTables[t].tableName, newOptions); self.discoverSchemasSync(otherTables[t].tableName, newOptions);
} }
return options.visited; return options.visited;
} }
}; };
@ -1675,7 +1671,6 @@ DataSource.prototype.discoverAndBuildModelsSync = function(modelName, options) {
* @returns {*} * @returns {*}
*/ */
DataSource.prototype.buildModelFromInstance = function(name, json, options) { DataSource.prototype.buildModelFromInstance = function(name, json, options) {
// Introspect the JSON document to generate a schema // Introspect the JSON document to generate a schema
var schema = ModelBuilder.introspect(json); var schema = ModelBuilder.introspect(json);
@ -1863,7 +1858,6 @@ DataSource.prototype.defineForeignKey = function defineForeignKey(className, key
// Add the foreign key property to the data source _models // Add the foreign key property to the data source _models
this.defineProperty(className, key, fkDef); this.defineProperty(className, key, fkDef);
} }
}; };
/** /**
@ -1909,10 +1903,10 @@ DataSource.prototype.copyModel = function copyModel(Master) {
hiddenProperty(Slave, 'relations', Master.relations); hiddenProperty(Slave, 'relations', Master.relations);
if (!(className in dataSource.modelBuilder.models)) { if (!(className in dataSource.modelBuilder.models)) {
// store class in model pool // store class in model pool
dataSource.modelBuilder.models[className] = Slave; dataSource.modelBuilder.models[className] = Slave;
dataSource.modelBuilder.definitions[className] = new ModelDefinition(dataSource.modelBuilder, md.name, md.properties, md.settings); dataSource.modelBuilder.definitions[className] =
new ModelDefinition(dataSource.modelBuilder, md.name, md.properties, md.settings);
if ((!dataSource.isTransaction) && dataSource.connector && dataSource.connector.define) { if ((!dataSource.isTransaction) && dataSource.connector && dataSource.connector.define) {
dataSource.connector.define({ dataSource.connector.define({
@ -1921,7 +1915,6 @@ DataSource.prototype.copyModel = function copyModel(Master) {
settings: md.settings, settings: md.settings,
}); });
} }
} }
return Slave; return Slave;

View File

@ -138,7 +138,8 @@ function GeoPoint(data) {
}; };
} }
assert(Array.isArray(data) || typeof data === 'object' || typeof data === 'string', 'must provide valid geo-coordinates array [lat, lng] or object or a "lat, lng" string'); assert(Array.isArray(data) || typeof data === 'object' || typeof data === 'string',
'must provide valid geo-coordinates array [lat, lng] or object or a "lat, lng" string');
if (typeof data === 'string') { if (typeof data === 'string') {
data = data.split(/,\s*/); data = data.split(/,\s*/);
@ -259,7 +260,6 @@ var EARTH_RADIUS = {
}; };
function geoDistance(x1, y1, x2, y2, options) { function geoDistance(x1, y1, x2, y2, options) {
var type = (options && options.type) || 'miles'; var type = (options && options.type) || 'miles';
// Convert to radians // Convert to radians

View File

@ -36,10 +36,10 @@ Hookable.afterDestroy = null;
// TODO: Evaluate https://github.com/bnoguchi/hooks-js/ // TODO: Evaluate https://github.com/bnoguchi/hooks-js/
Hookable.prototype.trigger = function trigger(actionName, work, data, callback) { Hookable.prototype.trigger = function trigger(actionName, work, data, callback) {
var capitalizedName = capitalize(actionName); var capitalizedName = capitalize(actionName);
var beforeHook = this.constructor['before' + capitalizedName] var beforeHook = this.constructor['before' + capitalizedName] ||
|| this.constructor['pre' + capitalizedName]; this.constructor['pre' + capitalizedName];
var afterHook = this.constructor['after' + capitalizedName] var afterHook = this.constructor['after' + capitalizedName] ||
|| this.constructor['post' + capitalizedName]; this.constructor['post' + capitalizedName];
if (actionName === 'validate') { if (actionName === 'validate') {
beforeHook = beforeHook || this.constructor.beforeValidation; beforeHook = beforeHook || this.constructor.beforeValidation;
afterHook = afterHook || this.constructor.afterValidation; afterHook = afterHook || this.constructor.afterValidation;

View File

@ -198,16 +198,15 @@ Inclusion.include = function(objects, include, options, cb) {
subInclude = null; subInclude = null;
} }
} }
} } else {
else {
relationName = include; relationName = include;
subInclude = null; subInclude = null;
} }
var relation = relations[relationName]; var relation = relations[relationName];
if (!relation) { if (!relation) {
cb(new Error('Relation "' + relationName + '" is not defined for ' cb(new Error('Relation "' + relationName + '" is not defined for ' +
+ self.modelName + ' model')); self.modelName + ' model'));
return; return;
} }
var polymorphic = relation.polymorphic; var polymorphic = relation.polymorphic;
@ -251,8 +250,7 @@ Inclusion.include = function(objects, include, options, cb) {
var fields = filter.fields; var fields = filter.fields;
if (Array.isArray(fields) && fields.indexOf(relation.keyTo) === -1) { if (Array.isArray(fields) && fields.indexOf(relation.keyTo) === -1) {
fields.push(relation.keyTo); fields.push(relation.keyTo);
} } else if (isPlainObject(fields) && !fields[relation.keyTo]) {
else if (isPlainObject(fields) && !fields[relation.keyTo]) {
fields[relation.keyTo] = true; fields[relation.keyTo] = true;
} }
@ -281,8 +279,7 @@ Inclusion.include = function(objects, include, options, cb) {
} }
//assuming all other relations with multiple=true as hasMany //assuming all other relations with multiple=true as hasMany
return includeHasMany(cb); return includeHasMany(cb);
} } else {
else {
if (polymorphic) { if (polymorphic) {
if (relation.type === 'hasOne') { if (relation.type === 'hasOne') {
return includePolymorphicHasOne(cb); return includePolymorphicHasOne(cb);
@ -373,8 +370,7 @@ Inclusion.include = function(objects, include, options, cb) {
//make sure that the modelToIdName is included if fields are specified //make sure that the modelToIdName is included if fields are specified
if (Array.isArray(fields) && fields.indexOf(modelToIdName) === -1) { if (Array.isArray(fields) && fields.indexOf(modelToIdName) === -1) {
fields.push(modelToIdName); fields.push(modelToIdName);
} } else if (isPlainObject(fields) && !fields[modelToIdName]) {
else if (isPlainObject(fields) && !fields[modelToIdName]) {
fields[modelToIdName] = true; fields[modelToIdName] = true;
} }
@ -486,7 +482,6 @@ Inclusion.include = function(objects, include, options, cb) {
obj.__cachedRelations[relationName].push(target); obj.__cachedRelations[relationName].push(target);
processTargetObj(obj, next); processTargetObj(obj, next);
}, next); }, next);
} }
} }
@ -850,7 +845,6 @@ Inclusion.include = function(objects, include, options, cb) {
* @returns {*} * @returns {*}
*/ */
function processTargetObj(obj, callback) { function processTargetObj(obj, callback) {
var isInst = obj instanceof self; var isInst = obj instanceof self;
// Calling the relation method on the instance // Calling the relation method on the instance
@ -925,7 +919,6 @@ Inclusion.include = function(objects, include, options, cb) {
if (err) { if (err) {
return callback(err); return callback(err);
} else { } else {
defineCachedRelations(obj); defineCachedRelations(obj);
obj.__cachedRelations[relationName] = result; obj.__cachedRelations[relationName] = result;
@ -933,7 +926,5 @@ Inclusion.include = function(objects, include, options, cb) {
} }
}); });
} }
} }
}; };

View File

@ -4,9 +4,7 @@
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
module.exports = function getIntrospector(ModelBuilder) { module.exports = function getIntrospector(ModelBuilder) {
function introspectType(value) { function introspectType(value) {
// Unknown type, using Any // Unknown type, using Any
if (value === null || value === undefined) { if (value === null || value === undefined) {
return ModelBuilder.Any; return ModelBuilder.Any;

View File

@ -20,8 +20,8 @@ exports.inherits = function(newClass, baseClass, options) {
if (options.staticProperties) { if (options.staticProperties) {
Object.keys(baseClass).forEach(function(classProp) { Object.keys(baseClass).forEach(function(classProp) {
if (classProp !== 'super_' && (!newClass.hasOwnProperty(classProp) if (classProp !== 'super_' && (!newClass.hasOwnProperty(classProp) ||
|| options.override)) { options.override)) {
var pd = Object.getOwnPropertyDescriptor(baseClass, classProp); var pd = Object.getOwnPropertyDescriptor(baseClass, classProp);
Object.defineProperty(newClass, classProp, pd); Object.defineProperty(newClass, classProp, pd);
} }

View File

@ -532,7 +532,6 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
ModelClass.emit('defined', ModelClass); ModelClass.emit('defined', ModelClass);
return ModelClass; return ModelClass;
}; };
// DataType for Date // DataType for Date
@ -639,7 +638,6 @@ ModelBuilder.prototype.copyModel = function copyModel(Master) {
hiddenProperty(Slave, 'relations', Master.relations); hiddenProperty(Slave, 'relations', Master.relations);
if (!(className in modelBuilder.models)) { if (!(className in modelBuilder.models)) {
// store class in model pool // store class in model pool
modelBuilder.models[className] = Slave; modelBuilder.models[className] = Slave;
modelBuilder.definitions[className] = { modelBuilder.definitions[className] = {
@ -692,8 +690,7 @@ ModelBuilder.prototype.resolveType = function(type) {
var itemType = this.resolveType(type[0]); var itemType = this.resolveType(type[0]);
if (typeof itemType === 'function') { if (typeof itemType === 'function') {
return [itemType]; return [itemType];
} } else {
else {
return itemType; // Not resolved, return the type string return itemType; // Not resolved, return the type string
} }
} }
@ -788,13 +785,9 @@ ModelBuilder.prototype.buildModels = function(schemas, createModel) {
* @returns {} * @returns {}
*/ */
ModelBuilder.prototype.buildModelFromInstance = function(name, json, options) { ModelBuilder.prototype.buildModelFromInstance = function(name, json, options) {
// Introspect the JSON document to generate a schema // Introspect the JSON document to generate a schema
var schema = introspect(json); var schema = introspect(json);
// Create a model for the generated schema // Create a model for the generated schema
return this.define(name, schema, options); return this.define(name, schema, options);
}; };

View File

@ -217,7 +217,11 @@ ModelBaseClass.prototype._initProperties = function(data, options) {
if (!~fields.indexOf(ctor.relations[p].keyTo)) { if (!~fields.indexOf(ctor.relations[p].keyTo)) {
fields.push(ctor.relations[p].keyTo); fields.push(ctor.relations[p].keyTo);
} }
self.__data[p] = new modelTo(propVal, { fields: fields, applySetters: false, persisted: options.persisted }); self.__data[p] = new modelTo(propVal, {
fields: fields,
applySetters: false,
persisted: options.persisted,
});
} }
} }
@ -313,7 +317,6 @@ ModelBaseClass.prototype._initProperties = function(data, options) {
// Handle complex types (JSON/Object) // Handle complex types (JSON/Object)
if (!BASE_TYPES[type.name]) { if (!BASE_TYPES[type.name]) {
if (typeof self.__data[p] !== 'object' && self.__data[p]) { if (typeof self.__data[p] !== 'object' && self.__data[p]) {
try { try {
self.__data[p] = JSON.parse(self.__data[p] + ''); self.__data[p] = JSON.parse(self.__data[p] + '');
@ -323,15 +326,15 @@ ModelBaseClass.prototype._initProperties = function(data, options) {
} }
if (type.prototype instanceof ModelBaseClass) { if (type.prototype instanceof ModelBaseClass) {
if (!(self.__data[p] instanceof type) if (!(self.__data[p] instanceof type) &&
&& typeof self.__data[p] === 'object' typeof self.__data[p] === 'object' &&
&& self.__data[p] !== null) { self.__data[p] !== null) {
self.__data[p] = new type(self.__data[p]); self.__data[p] = new type(self.__data[p]);
} }
} else if (type.name === 'Array' || Array.isArray(type)) { } else if (type.name === 'Array' || Array.isArray(type)) {
if (!(self.__data[p] instanceof List) if (!(self.__data[p] instanceof List) &&
&& self.__data[p] !== undefined self.__data[p] !== undefined &&
&& self.__data[p] !== null) { self.__data[p] !== null) {
self.__data[p] = List(self.__data[p], type, self); self.__data[p] = List(self.__data[p], type, self);
} }
} }

View File

@ -203,8 +203,8 @@ RelationDefinition.prototype.defineMethod = function(name, fn) {
RelationDefinition.prototype.applyScope = function(modelInstance, filter) { RelationDefinition.prototype.applyScope = function(modelInstance, filter) {
filter = filter || {}; filter = filter || {};
filter.where = filter.where || {}; filter.where = filter.where || {};
if ((this.type !== 'belongsTo' || this.type === 'hasOne') if ((this.type !== 'belongsTo' || this.type === 'hasOne') &&
&& typeof this.polymorphic === 'object') { // polymorphic typeof this.polymorphic === 'object') { // polymorphic
var discriminator = this.polymorphic.discriminator; var discriminator = this.polymorphic.discriminator;
if (this.polymorphic.invert) { if (this.polymorphic.invert) {
filter.where[discriminator] = this.modelTo.modelName; filter.where[discriminator] = this.modelTo.modelName;
@ -255,8 +255,8 @@ RelationDefinition.prototype.applyProperties = function(modelInstance, obj) {
target[key] = source[k]; target[key] = source[k];
} }
} }
if ((this.type !== 'belongsTo' || this.type === 'hasOne') if ((this.type !== 'belongsTo' || this.type === 'hasOne') &&
&& typeof this.polymorphic === 'object') { // polymorphic typeof this.polymorphic === 'object') { // polymorphic
var discriminator = this.polymorphic.discriminator; var discriminator = this.polymorphic.discriminator;
if (this.polymorphic.invert) { if (this.polymorphic.invert) {
target[discriminator] = this.modelTo.modelName; target[discriminator] = this.modelTo.modelName;
@ -792,9 +792,9 @@ HasMany.prototype.findById = function(fkId, options, cb) {
if (inst[fk] != null && idEquals(inst[fk], modelInstance[pk])) { if (inst[fk] != null && idEquals(inst[fk], modelInstance[pk])) {
cb(null, inst); cb(null, inst);
} else { } else {
err = new Error('Key mismatch: ' + modelFrom.modelName + '.' + pk err = new Error('Key mismatch: ' + modelFrom.modelName + '.' + pk +
+ ': ' + modelInstance[pk] ': ' + modelInstance[pk] +
+ ', ' + modelTo.modelName + '.' + fk + ': ' + inst[fk]); ', ' + modelTo.modelName + '.' + fk + ': ' + inst[fk]);
err.statusCode = 400; err.statusCode = 400;
cb(err); cb(err);
} }
@ -930,9 +930,10 @@ HasManyThrough.prototype.findById = function(fkId, options, cb) {
self.exists(fkId, options, function(err, exists) { self.exists(fkId, options, function(err, exists) {
if (err || !exists) { if (err || !exists) {
if (!err) { if (!err) {
err = new Error('No relation found in ' + modelThrough.modelName err = new Error('No relation found in ' + modelThrough.modelName +
+ ' for (' + self.definition.modelFrom.modelName + '.' + modelInstance[pk] ' for (' + self.definition.modelFrom.modelName + '.' +
+ ',' + modelTo.modelName + '.' + fkId + ')'); modelInstance[pk] + ',' +
modelTo.modelName + '.' + fkId + ')');
err.statusCode = 404; err.statusCode = 404;
} }
return cb(err); return cb(err);
@ -974,9 +975,10 @@ HasManyThrough.prototype.destroyById = function(fkId, options, cb) {
self.exists(fkId, options, function(err, exists) { self.exists(fkId, options, function(err, exists) {
if (err || !exists) { if (err || !exists) {
if (!err) { if (!err) {
err = new Error('No record found in ' + modelThrough.modelName err = new Error('No record found in ' + modelThrough.modelName +
+ ' for (' + self.definition.modelFrom.modelName + '.' + modelInstance[pk] ' for (' + self.definition.modelFrom.modelName + '.' +
+ ' ,' + modelTo.modelName + '.' + fkId + ')'); modelInstance[pk] + ' ,' +
modelTo.modelName + '.' + fkId + ')');
err.statusCode = 404; err.statusCode = 404;
} }
return cb(err); return cb(err);
@ -1023,7 +1025,7 @@ HasManyThrough.prototype.create = function create(data, options, cb) {
var fk2 = keys[1]; var fk2 = keys[1];
function createRelation(to, next) { function createRelation(to, next) {
var d = {}, q = {}, filter = { where:q }; var d = {}, q = {}, filter = { where: q };
d[fk1] = q[fk1] = modelInstance[definition.keyFrom]; d[fk1] = q[fk1] = modelInstance[definition.keyFrom];
d[fk2] = q[fk2] = to[pk2]; d[fk2] = q[fk2] = to[pk2];
definition.applyProperties(modelInstance, d); definition.applyProperties(modelInstance, d);
@ -1357,8 +1359,7 @@ BelongsTo.prototype.update = function(targetModelData, options, cb) {
if (inst instanceof ModelBaseClass) { if (inst instanceof ModelBaseClass) {
inst.updateAttributes(targetModelData, options, cb); inst.updateAttributes(targetModelData, options, cb);
} else { } else {
cb(new Error('BelongsTo relation ' + definition.name cb(new Error('BelongsTo relation ' + definition.name + ' is empty'));
+ ' is empty'));
} }
}); });
return cb.promise; return cb.promise;
@ -1383,8 +1384,7 @@ BelongsTo.prototype.destroy = function(options, cb) {
cb && cb(err, targetModel); cb && cb(err, targetModel);
}); });
} else { } else {
cb(new Error('BelongsTo relation ' + definition.name cb(new Error('BelongsTo relation ' + definition.name + ' is empty'));
+ ' is empty'));
} }
}); });
return cb.promise; return cb.promise;
@ -1450,7 +1450,6 @@ BelongsTo.prototype.related = function(condOrRefresh, options, cb) {
self.resetCache(newValue); self.resetCache(newValue);
} else if (typeof cb === 'function') { // acts as async getter } else if (typeof cb === 'function') { // acts as async getter
if (discriminator) { if (discriminator) {
var modelToName = modelInstance[discriminator]; var modelToName = modelInstance[discriminator];
if (typeof modelToName !== 'string') { if (typeof modelToName !== 'string') {
@ -1467,8 +1466,7 @@ BelongsTo.prototype.related = function(condOrRefresh, options, cb) {
var query = { where: {}}; var query = { where: {}};
query.where[pk] = modelInstance[fk]; query.where[pk] = modelInstance[fk];
if (query.where[pk] === undefined if (query.where[pk] === undefined || query.where[pk] === null) {
|| query.where[pk] === null) {
// Foreign key is undefined // Foreign key is undefined
return process.nextTick(cb); return process.nextTick(cb);
} }
@ -1489,14 +1487,15 @@ BelongsTo.prototype.related = function(condOrRefresh, options, cb) {
return cb(null, null); return cb(null, null);
} }
// Check if the foreign key matches the primary key // Check if the foreign key matches the primary key
if (inst[pk] != null && modelInstance[fk] != null if (inst[pk] != null && modelInstance[fk] != null &&
&& inst[pk].toString() === modelInstance[fk].toString()) { inst[pk].toString() === modelInstance[fk].toString()) {
self.resetCache(inst); self.resetCache(inst);
cb(null, inst); cb(null, inst);
} else { } else {
err = new Error('Key mismatch: ' + self.definition.modelFrom.modelName + '.' + fk err = new Error('Key mismatch: ' +
+ ': ' + modelInstance[fk] self.definition.modelFrom.modelName + '.' + fk +
+ ', ' + modelTo.modelName + '.' + pk + ': ' + inst[pk]); ': ' + modelInstance[fk] +
', ' + modelTo.modelName + '.' + pk + ': ' + inst[pk]);
err.statusCode = 400; err.statusCode = 400;
cb(err); cb(err);
} }
@ -1724,8 +1723,9 @@ HasOne.prototype.create = function(targetModelData, options, cb) {
self.resetCache(targetModel); self.resetCache(targetModel);
cb && cb(err, targetModel); cb && cb(err, targetModel);
} else { } else {
cb && cb(new Error('HasOne relation cannot create more than one instance of ' cb && cb(new Error(
+ modelTo.modelName)); 'HasOne relation cannot create more than one instance of ' +
modelTo.modelName));
} }
}); });
return cb.promise; return cb.promise;
@ -1745,8 +1745,7 @@ HasOne.prototype.update = function(targetModelData, options, cb) {
delete targetModelData[fk]; delete targetModelData[fk];
targetModel.updateAttributes(targetModelData, cb); targetModel.updateAttributes(targetModelData, cb);
} else { } else {
cb(new Error('HasOne relation ' + definition.name cb(new Error('HasOne relation ' + definition.name + ' is empty'));
+ ' is empty'));
} }
}); });
return cb.promise; return cb.promise;
@ -1764,8 +1763,7 @@ HasOne.prototype.destroy = function(options, cb) {
if (targetModel instanceof ModelBaseClass) { if (targetModel instanceof ModelBaseClass) {
targetModel.destroy(options, cb); targetModel.destroy(options, cb);
} else { } else {
cb(new Error('HasOne relation ' + definition.name cb(new Error('HasOne relation ' + definition.name + ' is empty'));
+ ' is empty'));
} }
}); });
return cb.promise; return cb.promise;
@ -1897,14 +1895,15 @@ HasOne.prototype.related = function(condOrRefresh, options, cb) {
return cb(null, null); return cb(null, null);
} }
// Check if the foreign key matches the primary key // Check if the foreign key matches the primary key
if (inst[fk] != null && modelInstance[pk] != null if (inst[fk] != null && modelInstance[pk] != null &&
&& inst[fk].toString() === modelInstance[pk].toString()) { inst[fk].toString() === modelInstance[pk].toString()) {
self.resetCache(inst); self.resetCache(inst);
cb(null, inst); cb(null, inst);
} else { } else {
err = new Error('Key mismatch: ' + self.definition.modelFrom.modelName + '.' + pk err = new Error('Key mismatch: ' +
+ ': ' + modelInstance[pk] self.definition.modelFrom.modelName + '.' + pk +
+ ', ' + modelTo.modelName + '.' + fk + ': ' + inst[fk]); ': ' + modelInstance[pk] +
', ' + modelTo.modelName + '.' + fk + ': ' + inst[fk]);
err.statusCode = 400; err.statusCode = 400;
cb(err); cb(err);
} }
@ -2416,12 +2415,12 @@ EmbedsMany.prototype.prepareEmbeddedInstance = function(inst) {
}; };
EmbedsMany.prototype.embeddedList = EmbedsMany.prototype.embeddedList =
EmbedsMany.prototype.embeddedValue = function(modelInstance) { EmbedsMany.prototype.embeddedValue = function(modelInstance) {
modelInstance = modelInstance || this.modelInstance; modelInstance = modelInstance || this.modelInstance;
var embeddedList = modelInstance[this.definition.keyFrom] || []; var embeddedList = modelInstance[this.definition.keyFrom] || [];
embeddedList.forEach(this.prepareEmbeddedInstance.bind(this)); embeddedList.forEach(this.prepareEmbeddedInstance.bind(this));
return embeddedList; return embeddedList;
}; };
EmbedsMany.prototype.related = function(receiver, scopeParams, condOrRefresh, options, cb) { EmbedsMany.prototype.related = function(receiver, scopeParams, condOrRefresh, options, cb) {
var modelTo = this.definition.modelTo; var modelTo = this.definition.modelTo;
@ -2543,10 +2542,10 @@ EmbedsMany.prototype.updateById = function(fkId, data, options, cb) {
} }
if (typeof cb === 'function') { if (typeof cb === 'function') {
modelInstance.updateAttribute(propertyName, modelInstance.updateAttribute(propertyName, embeddedList, options,
embeddedList, options, function(err) { function(err) {
cb(err, inst); cb(err, inst);
}); });
} }
} else if (typeof cb === 'function') { } else if (typeof cb === 'function') {
process.nextTick(function() { process.nextTick(function() {
@ -3014,9 +3013,9 @@ ReferencesMany.prototype.findById = function(fkId, options, cb) {
if (utils.findIndexOf(ids, inst[pk], idEquals) > -1) { if (utils.findIndexOf(ids, inst[pk], idEquals) > -1) {
cb(null, inst); cb(null, inst);
} else { } else {
err = new Error('Key mismatch: ' + modelFrom.modelName + '.' + fk err = new Error('Key mismatch: ' + modelFrom.modelName + '.' + fk +
+ ': ' + modelInstance[fk] ': ' + modelInstance[fk] +
+ ', ' + modelTo.modelName + '.' + pk + ': ' + inst[pk]); ', ' + modelTo.modelName + '.' + pk + ': ' + inst[pk]);
err.statusCode = 400; err.statusCode = 400;
cb(err); cb(err);
} }

View File

@ -80,8 +80,8 @@ ScopeDefinition.prototype.related = function(receiver, scopeParams, condOrRefres
} }
cb = cb || utils.createPromiseCallback(); cb = cb || utils.createPromiseCallback();
if (!self.__cachedRelations || self.__cachedRelations[name] === undefined if (!self.__cachedRelations || self.__cachedRelations[name] === undefined ||
|| actualRefresh) { actualRefresh) {
// It either doesn't hit the cache or refresh is required // It either doesn't hit the cache or refresh is required
var params = mergeQuery(actualCond, scopeParams, { nestedInclude: true }); var params = mergeQuery(actualCond, scopeParams, { nestedInclude: true });
var targetModel = this.targetModel(receiver); var targetModel = this.targetModel(receiver);
@ -181,8 +181,8 @@ function defineScope(cls, targetClass, name, params, methods, options) {
return self.__cachedRelations[name]; return self.__cachedRelations[name];
} }
} else { } else {
if (typeof condOrRefresh === 'function' if (typeof condOrRefresh === 'function' &&
&& options === undefined && cb === undefined) { options === undefined && cb === undefined) {
// customer.orders(cb) // customer.orders(cb)
cb = condOrRefresh; cb = condOrRefresh;
options = {}; options = {};
@ -200,9 +200,9 @@ function defineScope(cls, targetClass, name, params, methods, options) {
//extract the paging filters to the through model //extract the paging filters to the through model
['limit', 'offset', 'skip', 'order'].forEach(function(pagerFilter) { ['limit', 'offset', 'skip', 'order'].forEach(function(pagerFilter) {
if (typeof(condOrRefresh[pagerFilter]) !== 'undefined') { if (typeof(condOrRefresh[pagerFilter]) !== 'undefined') {
f._scope[pagerFilter] = condOrRefresh[pagerFilter]; f._scope[pagerFilter] = condOrRefresh[pagerFilter];
delete condOrRefresh[pagerFilter]; delete condOrRefresh[pagerFilter];
} }
}); });
// Adjust the include so that the condition will be applied to // Adjust the include so that the condition will be applied to
// the target model // the target model
@ -226,8 +226,8 @@ function defineScope(cls, targetClass, name, params, methods, options) {
} }
f.getAsync = function(condOrRefresh, options, cb) { f.getAsync = function(condOrRefresh, options, cb) {
if (typeof condOrRefresh === 'function' if (typeof condOrRefresh === 'function' &&
&& options === undefined && cb === undefined) { options === undefined && cb === undefined) {
// customer.orders.getAsync(cb) // customer.orders.getAsync(cb)
cb = condOrRefresh; cb = condOrRefresh;
options = {}; options = {};
@ -282,47 +282,47 @@ function defineScope(cls, targetClass, name, params, methods, options) {
cls['__get__' + name] = fn; cls['__get__' + name] = fn;
var fn_create = function() { var fnCreate = function() {
var f = this[name].create; var f = this[name].create;
f.apply(this[name], arguments); f.apply(this[name], arguments);
}; };
cls['__create__' + name] = fn_create; cls['__create__' + name] = fnCreate;
var fn_delete = function() { var fnDelete = function() {
var f = this[name].destroyAll; var f = this[name].destroyAll;
f.apply(this[name], arguments); f.apply(this[name], arguments);
}; };
cls['__delete__' + name] = fn_delete; cls['__delete__' + name] = fnDelete;
var fn_update = function() { var fnUpdate = function() {
var f = this[name].updateAll; var f = this[name].updateAll;
f.apply(this[name], arguments); f.apply(this[name], arguments);
}; };
cls['__update__' + name] = fn_update; cls['__update__' + name] = fnUpdate;
var fn_findById = function(cb) { var fnFindById = function(cb) {
var f = this[name].findById; var f = this[name].findById;
f.apply(this[name], arguments); f.apply(this[name], arguments);
}; };
cls['__findById__' + name] = fn_findById; cls['__findById__' + name] = fnFindById;
var fn_findOne = function(cb) { var fnFindOne = function(cb) {
var f = this[name].findOne; var f = this[name].findOne;
f.apply(this[name], arguments); f.apply(this[name], arguments);
}; };
cls['__findOne__' + name] = fn_findOne; cls['__findOne__' + name] = fnFindOne;
var fn_count = function(cb) { var fnCount = function(cb) {
var f = this[name].count; var f = this[name].count;
f.apply(this[name], arguments); f.apply(this[name], arguments);
}; };
cls['__count__' + name] = fn_count; cls['__count__' + name] = fnCount;
// and it should have create/build methods with binded thisModelNameId param // and it should have create/build methods with binded thisModelNameId param
function build(data) { function build(data) {

View File

@ -39,7 +39,6 @@ Types.Any.prototype.toObject = Types.Any.prototype.toJSON = function() {
}; };
module.exports = function(modelTypes) { module.exports = function(modelTypes) {
var GeoPoint = require('./geo').GeoPoint; var GeoPoint = require('./geo').GeoPoint;
for (var t in Types) { for (var t in Types) {

View File

@ -30,9 +30,9 @@ function safeRequire(module) {
try { try {
return require(module); return require(module);
} catch (e) { } catch (e) {
console.log('Run "npm install loopback-datasource-juggler ' + module console.log('Run "npm install loopback-datasource-juggler ' + module +
+ '" command to use loopback-datasource-juggler using ' + module '" command to use loopback-datasource-juggler using ' + module +
+ ' database engine'); ' database engine');
process.exit(1); process.exit(1);
} }
} }
@ -56,9 +56,8 @@ function setScopeValuesFromWhere(data, where, targetModel) {
var prop = targetModel.definition.properties[i]; var prop = targetModel.definition.properties[i];
if (prop) { if (prop) {
var val = where[i]; var val = where[i];
if (typeof val !== 'object' || val instanceof prop.type if (typeof val !== 'object' || val instanceof prop.type ||
|| prop.type.name === 'ObjectID') // MongoDB key prop.type.name === 'ObjectID') { // MongoDB key
{
// Only pick the {propertyName: propertyValue} // Only pick the {propertyName: propertyValue}
data[i] = where[i]; data[i] = where[i];
} }
@ -137,8 +136,7 @@ function convertToArray(include) {
var obj = {}; var obj = {};
obj[includeEntry] = true; obj[includeEntry] = true;
normalized.push(obj); normalized.push(obj);
} } else {
else {
normalized.push(includeEntry); normalized.push(includeEntry);
} }
} }
@ -182,8 +180,7 @@ function mergeQuery(base, update, spec) {
var saved = base.include; var saved = base.include;
base.include = {}; base.include = {};
base.include[update.include] = saved; base.include[update.include] = saved;
} } else {
else {
//default behaviour of inclusion merge - merge inclusions at the same //default behaviour of inclusion merge - merge inclusions at the same
//level. - https://github.com/strongloop/loopback-datasource-juggler/pull/569#issuecomment-95310874 //level. - https://github.com/strongloop/loopback-datasource-juggler/pull/569#issuecomment-95310874
base.include = mergeIncludes(base.include, update.include); base.include = mergeIncludes(base.include, update.include);
@ -324,8 +321,8 @@ function removeUndefined(query, handleUndefined) {
} }
} }
if (!Array.isArray(x) && (typeof x === 'object' && x !== null if (!Array.isArray(x) && (typeof x === 'object' && x !== null &&
&& x.constructor !== Object)) { x.constructor !== Object)) {
// This object is not a plain object // This object is not a plain object
this.update(x, true); // Stop navigating into this object this.update(x, true); // Stop navigating into this object
return x; return x;
@ -442,12 +439,10 @@ function defineCachedRelations(obj) {
* @returns {boolean} * @returns {boolean}
*/ */
function isPlainObject(obj) { function isPlainObject(obj) {
return (typeof obj === 'object') && (obj !== null) return (typeof obj === 'object') && (obj !== null) &&
&& (obj.constructor === Object); (obj.constructor === Object);
} }
function sortObjectsByIds(idName, ids, objects, strict) { function sortObjectsByIds(idName, ids, objects, strict) {
ids = ids.map(function(id) { ids = ids.map(function(id) {
return (typeof id === 'object') ? String(id) : id; return (typeof id === 'object') ? String(id) : id;

View File

@ -356,7 +356,9 @@ function validateUniqueness(attr, conf, err, done) {
err(); err();
} else if (found.length === 1 && idName === attr && isNewRecord) { } else if (found.length === 1 && idName === attr && isNewRecord) {
err(); err();
} else if (found.length === 1 && (!this.id || !found[0].id || found[0].id.toString() != this.id.toString())) { } else if (found.length === 1 && (
!this.id || !found[0].id || found[0].id.toString() != this.id.toString()
)) {
err(); err();
} }
done(); done();
@ -494,7 +496,6 @@ Validatable.prototype.isValid = function(callback, data) {
}); });
} }
} }
}, data, callback); }, data, callback);
if (async) { if (async) {
@ -504,7 +505,6 @@ Validatable.prototype.isValid = function(callback, data) {
} else { } else {
return valid; return valid;
} }
}; };
function cleanErrors(inst) { function cleanErrors(inst) {
@ -522,8 +522,8 @@ function validationFailed(inst, attr, conf, cb) {
// here we should check skip validation conditions (if, unless) // here we should check skip validation conditions (if, unless)
// that can be specified in conf // that can be specified in conf
if (skipValidation(inst, conf, 'if') if (skipValidation(inst, conf, 'if') ||
|| skipValidation(inst, conf, 'unless')) { skipValidation(inst, conf, 'unless')) {
if (cb) cb(false); if (cb) cb(false);
return false; return false;
} }

View File

@ -32,6 +32,7 @@ Promise.onPossiblyUnhandledRejection(function(err) {
console.error('POSSIBLY UNHANDLED REJECTION', err.stack); console.error('POSSIBLY UNHANDLED REJECTION', err.stack);
}); });
/* eslint-disable camelcase */
var operations = [ var operations = [
function find(ds) { function find(ds) {
return ds.TestModel.find({ where: { id: '1' }}); return ds.TestModel.find({ where: { id: '1' }});
@ -102,6 +103,7 @@ var operations = [
return ds.TestModel.deleteAll({ name: ds.existingInstance.name }); return ds.TestModel.deleteAll({ name: ds.existingInstance.name });
}, },
]; ];
/* eslint-enable camelcase */
var p = setupTestModels(); var p = setupTestModels();
operations.forEach(function(op) { operations.forEach(function(op) {

View File

@ -13,21 +13,21 @@ describe('Datasource-specific field types for foreign keys', function() {
before(function() { before(function() {
ds = new DataSource('memory'); ds = new DataSource('memory');
Item = ds.define('Item', { Item = ds.define('Item', {
'myProp': { myProp: {
'id': true, id: true,
'type': 'string', type: 'string',
'memory': { memory: {
'dataType': "string", dataType: 'string',
}, },
}, },
}); });
Variant = ds.define('Variant', {}, { Variant = ds.define('Variant', {}, {
relations: { relations: {
'item': { item: {
'type': 'belongsTo', type: 'belongsTo',
'as': 'item', as: 'item',
'model': 'Item', model: 'Item',
'foreignKey': "myProp", foreignKey: 'myProp',
}, },
}, },
}); });

View File

@ -304,7 +304,7 @@ describe('basic-querying', function() {
}); });
it('should support number "gte" that is satisfied', function(done) { it('should support number "gte" that is satisfied', function(done) {
User.find({ order: 'seq', where: { order: { 'gte': 3 }, User.find({ order: 'seq', where: { order: { 'gte': 3 },
}}, function(err, users) { }}, function(err, users) {
should.not.exist(err); should.not.exist(err);
users.should.have.property('length', 4); users.should.have.property('length', 4);
@ -361,7 +361,7 @@ describe('basic-querying', function() {
}); });
it('should support string "gte" that is satisfied by null value', function(done) { it('should support string "gte" that is satisfied by null value', function(done) {
User.find({ order: 'seq', where: { name: { 'gte': null }, User.find({ order: 'seq', where: { name: { 'gte': null },
}}, function(err, users) { }}, function(err, users) {
should.not.exist(err); should.not.exist(err);
users.should.have.property('length', 0); users.should.have.property('length', 0);
@ -370,7 +370,7 @@ describe('basic-querying', function() {
}); });
it('should support string "gte" that is satisfied', function(done) { it('should support string "gte" that is satisfied', function(done) {
User.find({ order: 'seq', where: { name: { 'gte': 'Paul McCartney' }, User.find({ order: 'seq', where: { name: { 'gte': 'Paul McCartney' },
}}, function(err, users) { }}, function(err, users) {
should.not.exist(err); should.not.exist(err);
users.should.have.property('length', 4); users.should.have.property('length', 4);
@ -409,7 +409,7 @@ describe('basic-querying', function() {
}); });
it('should support boolean "gte" that is satisfied', function(done) { it('should support boolean "gte" that is satisfied', function(done) {
User.find({ order: 'seq', where: { vip: { 'gte': true }, User.find({ order: 'seq', where: { vip: { 'gte': true },
}}, function(err, users) { }}, function(err, users) {
should.not.exist(err); should.not.exist(err);
users.should.have.property('length', 3); users.should.have.property('length', 3);
@ -741,16 +741,16 @@ describe.skip('queries', function() {
}); });
it('should return an error for deleteById/destroyById/removeById', it('should return an error for deleteById/destroyById/removeById',
function(done) { function(done) {
var aliases = ['deleteById', 'destroyById', 'removeById']; var aliases = ['deleteById', 'destroyById', 'removeById'];
async.each(aliases, function(alias, cb) { async.each(aliases, function(alias, cb) {
Todo[alias](1, function(err) { Todo[alias](1, function(err) {
should.exist(err); should.exist(err);
err.message.should.equal(expectedErrMsg); err.message.should.equal(expectedErrMsg);
cb(); cb();
}); });
}, done); }, done);
}); });
it('should return an error for instance.save', function(done) { it('should return an error for instance.save', function(done) {
var todo = new Todo(); var todo = new Todo();

View File

@ -317,7 +317,8 @@ function testOrm(dataSource) {
post.destroy(function() { post.destroy(function() {
Post.exists(post.id, function(err, exists) { Post.exists(post.id, function(err, exists) {
if (err) console.log(err); if (err) console.log(err);
test.ok(!exists, 'Hey! ORM told me that object exists, but it looks like it doesn\'t. Something went wrong...'); test.ok(!exists, 'Hey! ORM told me that object exists, ' +
' but it looks like it doesn\'t. Something went wrong...');
Post.findById(post.id, function(err, obj) { Post.findById(post.id, function(err, obj) {
test.equal(obj, null, 'Param obj should be null'); test.equal(obj, null, 'Param obj should be null');
test.done(); test.done();
@ -480,6 +481,7 @@ function testOrm(dataSource) {
}); });
/* eslint-disable max-len */
it('hasMany should be cached', function(test) { it('hasMany should be cached', function(test) {
//User.create(function (e, u) { //User.create(function (e, u) {
// u.posts.create({}, function (e, p) { // u.posts.create({}, function (e, p) {
@ -546,8 +548,8 @@ function testOrm(dataSource) {
} }
} }
}); });
}); });
/* eslint-enable max-len */
// it('should handle hasOne relationship', function (test) { // it('should handle hasOne relationship', function (test) {
// User.create(function (err, u) { // User.create(function (err, u) {
@ -697,7 +699,7 @@ function testOrm(dataSource) {
function doMultipleSortTest() { function doMultipleSortTest() {
tests += 1; tests += 1;
Post.all({ order: "title ASC, subject ASC" }, function(err, posts) { Post.all({ order: 'title ASC, subject ASC' }, function(err, posts) {
if (err) console.log(err); if (err) console.log(err);
test.equal(posts.length, 6); test.equal(posts.length, 6);
test.equal(posts[0].title, 'Title A'); test.equal(posts[0].title, 'Title A');
@ -711,7 +713,7 @@ function testOrm(dataSource) {
function doMultipleReverseSortTest() { function doMultipleReverseSortTest() {
tests += 1; tests += 1;
Post.all({ order: "title ASC, subject DESC" }, function(err, posts) { Post.all({ order: 'title ASC, subject DESC' }, function(err, posts) {
if (err) console.log(err); if (err) console.log(err);
test.equal(posts.length, 6); test.equal(posts.length, 6);
test.equal(posts[0].title, 'Title A'); test.equal(posts[0].title, 'Title A');

View File

@ -140,7 +140,7 @@ describe('default scope', function() {
}); });
it('should return a scoped instance', function() { it('should return a scoped instance', function() {
var p = new Tool({ name: 'Product A', kind:'ignored' }); var p = new Tool({ name: 'Product A', kind: 'ignored' });
p.name.should.equal('Product A'); p.name.should.equal('Product A');
p.kind.should.equal('Tool'); p.kind.should.equal('Tool');
p.setAttributes({ kind: 'ignored' }); p.setAttributes({ kind: 'ignored' });
@ -649,7 +649,7 @@ describe('default scope', function() {
}); });
it('should create a scoped instance - widget', function(done) { it('should create a scoped instance - widget', function(done) {
Widget.create({ name: 'Product', kind:'ignored' }, function(err, p) { Widget.create({ name: 'Product', kind: 'ignored' }, function(err, p) {
p.name.should.equal('Product'); p.name.should.equal('Product');
p.kind.should.equal('Widget'); p.kind.should.equal('Widget');
done(); done();
@ -657,7 +657,7 @@ describe('default scope', function() {
}); });
it('should create a scoped instance - thing', function(done) { it('should create a scoped instance - thing', function(done) {
Thing.create({ name: 'Product', kind:'ignored' }, function(err, p) { Thing.create({ name: 'Product', kind: 'ignored' }, function(err, p) {
p.name.should.equal('Product'); p.name.should.equal('Product');
p.kind.should.equal('Thing'); p.kind.should.equal('Thing');
done(); done();

View File

@ -65,7 +65,7 @@ describe('defaults', function() {
it('should preserve defaults in upsert update', function(done) { it('should preserve defaults in upsert update', function(done) {
Server.findOne({}, function(err, server) { Server.findOne({}, function(err, server) {
Server.upsert({ id:server.id, port: 1337 }, function(err, s) { Server.upsert({ id: server.id, port: 1337 }, function(err, s) {
should.not.exist(err); should.not.exist(err);
(Number(1337)).should.equal(s.port); (Number(1337)).should.equal(s.port);
server.createdAt.should.eql(s.createdAt); server.createdAt.should.eql(s.createdAt);

View File

@ -446,14 +446,14 @@ describe('discoverPrimaryKeys', function() {
tableName: 'INVENTORY', tableName: 'INVENTORY',
columnName: 'PRODUCT_ID', columnName: 'PRODUCT_ID',
keySeq: 1, keySeq: 1,
pkName: 'ID_PK' pkName: 'ID_PK',
}, },
{ {
owner: 'STRONGLOOP', owner: 'STRONGLOOP',
tableName: 'INVENTORY', tableName: 'INVENTORY',
columnName: 'LOCATION_ID', columnName: 'LOCATION_ID',
keySeq: 2, keySeq: 2,
pkName: 'ID_PK' pkName: 'ID_PK',
}]; }];
ds.connector.discoverPrimaryKeys = function(modelName, options, cb) { ds.connector.discoverPrimaryKeys = function(modelName, options, cb) {
@ -596,7 +596,8 @@ describe('discoverExportedForeignKeys', function() {
ds.discoverExportedForeignKeys('INVENTORY', options); ds.discoverExportedForeignKeys('INVENTORY', options);
}); });
it('should discover foreign key definitions using `discoverExportedForeignKeys` - promise variant', function(done) { it('should discover foreign key definitions using `discoverExportedForeignKeys` - promise variant',
function(done) {
ds.discoverExportedForeignKeys('INVENTORY', {}) ds.discoverExportedForeignKeys('INVENTORY', {})
.then(function(modelForeignKeys) { .then(function(modelForeignKeys) {
modelForeignKeys.should.be.eql(exportedForeignKeys); modelForeignKeys.should.be.eql(exportedForeignKeys);

View File

@ -156,7 +156,7 @@ describe('include', function() {
it('should fetch Passports with include scope on Posts', function(done) { it('should fetch Passports with include scope on Posts', function(done) {
Passport.find({ Passport.find({
include: { owner: { relation: 'posts', scope:{ include: { owner: { relation: 'posts', scope: {
fields: ['title'], include: ['author'], fields: ['title'], include: ['author'],
order: 'title DESC', order: 'title DESC',
}}}, }}},
@ -211,24 +211,24 @@ describe('include', function() {
it('should fetch Users with include scope on Posts - belongsTo', function(done) { it('should fetch Users with include scope on Posts - belongsTo', function(done) {
Post.find({ Post.find({
include: { relation: 'author', scope:{ fields: ['name'] }}, include: { relation: 'author', scope: { fields: ['name'] }},
}, function(err, posts) { }, function(err, posts) {
should.not.exist(err); should.not.exist(err);
should.exist(posts); should.exist(posts);
posts.length.should.equal(5); posts.length.should.equal(5);
var author = posts[0].author(); var author = posts[0].author();
author.name.should.equal('User A'); author.name.should.equal('User A');
author.should.have.property('id'); author.should.have.property('id');
author.should.have.property('age', undefined); author.should.have.property('age', undefined);
done(); done();
}); });
}); });
it('should fetch Users with include scope on Posts - hasMany', function(done) { it('should fetch Users with include scope on Posts - hasMany', function(done) {
User.find({ User.find({
include: { relation: 'posts', scope:{ include: { relation: 'posts', scope: {
order: 'title DESC', order: 'title DESC',
}}, }},
}, function(err, users) { }, function(err, users) {
@ -258,7 +258,7 @@ describe('include', function() {
it('should fetch Users with include scope on Passports - hasMany', function(done) { it('should fetch Users with include scope on Passports - hasMany', function(done) {
User.find({ User.find({
include: { relation: 'passports', scope:{ include: { relation: 'passports', scope: {
where: { number: '2' }, where: { number: '2' },
}}, }},
}, function(err, users) { }, function(err, users) {
@ -401,8 +401,7 @@ describe('include', function() {
if (profile) { if (profile) {
profile.should.be.an.instanceOf(Profile); profile.should.be.an.instanceOf(Profile);
usersWithProfile++; usersWithProfile++;
} } else {
else {
(profile === null).should.be.true; (profile === null).should.be.true;
} }
// The __cachedRelations should be removed from json output // The __cachedRelations should be removed from json output

View File

@ -3,8 +3,8 @@
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
var assert = require("assert"); var assert = require('assert');
var should = require("should"); var should = require('should');
var includeUtils = require('../lib/include_utils'); var includeUtils = require('../lib/include_utils');
@ -12,8 +12,8 @@ describe('include_util', function() {
describe('#buildOneToOneIdentityMapWithOrigKeys', function() { describe('#buildOneToOneIdentityMapWithOrigKeys', function() {
it('should return an object with keys', function() { it('should return an object with keys', function() {
var objs = [ var objs = [
{ id: 11, letter: "A" }, { id: 11, letter: 'A' },
{ id: 22, letter: "B" }, { id: 22, letter: 'B' },
]; ];
var result = includeUtils.buildOneToOneIdentityMapWithOrigKeys(objs, 'id'); var result = includeUtils.buildOneToOneIdentityMapWithOrigKeys(objs, 'id');
result.get(11).should.be.ok; result.get(11).should.be.ok;
@ -22,11 +22,11 @@ describe('include_util', function() {
it('should overwrite keys in case of collision', function() { it('should overwrite keys in case of collision', function() {
var objs = [ var objs = [
{ id: 11, letter: "A" }, { id: 11, letter: 'A' },
{ id: 22, letter: "B" }, { id: 22, letter: 'B' },
{ id: 33, letter: "C" }, { id: 33, letter: 'C' },
{ id: 11, letter: "HA!" }, { id: 11, letter: 'HA!' },
]; ];
var result = includeUtils.buildOneToOneIdentityMapWithOrigKeys(objs, 'id'); var result = includeUtils.buildOneToOneIdentityMapWithOrigKeys(objs, 'id');
result.getKeys().should.containEql(11); result.getKeys().should.containEql(11);
@ -39,8 +39,8 @@ describe('include_util', function() {
describe('#buildOneToOneIdentityMapWithOrigKeys', function() { describe('#buildOneToOneIdentityMapWithOrigKeys', function() {
it('should return an object with keys', function() { it('should return an object with keys', function() {
var objs = [ var objs = [
{ id: 11, letter: "A" }, { id: 11, letter: 'A' },
{ id: 22, letter: "B" }, { id: 22, letter: 'B' },
]; ];
var result = includeUtils.buildOneToOneIdentityMapWithOrigKeys(objs, 'id'); var result = includeUtils.buildOneToOneIdentityMapWithOrigKeys(objs, 'id');
result.get(11).should.be.ok; result.get(11).should.be.ok;
@ -50,28 +50,28 @@ describe('include_util', function() {
}); });
describe('#buildOneToManyIdentityMap', function() { describe('#buildOneToManyIdentityMap', function() {
it('should return an object with keys', function() { it('should return an object with keys', function() {
var objs = [ var objs = [
{ id: 11, letter: "A" }, { id: 11, letter: 'A' },
{ id: 22, letter: "B" }, { id: 22, letter: 'B' },
]; ];
var result = includeUtils.buildOneToManyIdentityMapWithOrigKeys(objs, 'id'); var result = includeUtils.buildOneToManyIdentityMapWithOrigKeys(objs, 'id');
result.exist(11).should.be.true; result.exist(11).should.be.true;
result.exist(22).should.be.true; result.exist(22).should.be.true;
}); });
it('should collect keys in case of collision', function() { it('should collect keys in case of collision', function() {
var objs = [ var objs = [
{ fk_id: 11, letter: "A" }, { 'fk_id': 11, letter: 'A' },
{ fk_id: 22, letter: "B" }, { 'fk_id': 22, letter: 'B' },
{ fk_id: 33, letter: "C" }, { 'fk_id': 33, letter: 'C' },
{ fk_id: 11, letter: "HA!" }, { 'fk_id': 11, letter: 'HA!' },
]; ];
var result = includeUtils.buildOneToManyIdentityMapWithOrigKeys(objs, 'fk_id'); var result = includeUtils.buildOneToManyIdentityMapWithOrigKeys(objs, 'fk_id');
result.get(11)[0]['letter'].should.equal('A'); result.get(11)[0]['letter'].should.equal('A');
result.get(11)[1]['letter'].should.equal('HA!'); result.get(11)[1]['letter'].should.equal('HA!');
result.get(33)[0]['letter'].should.equal('C'); result.get(33)[0]['letter'].should.equal('C');
}); });
}); });
}); });

View File

@ -30,7 +30,7 @@ describe('JSON property', function() {
it('should accept object in setter and return object', function() { it('should accept object in setter and return object', function() {
var m = new Model; var m = new Model;
m.propertyName = {'foo': "bar" }; m.propertyName = { 'foo': 'bar' };
m.propertyName.should.be.an.Object; m.propertyName.should.be.an.Object;
m.propertyName.foo.should.equal('bar'); m.propertyName.foo.should.equal('bar');
}); });

View File

@ -1013,7 +1013,9 @@ describe('Load models with relations', function() {
var ds = new DataSource('memory'); var ds = new DataSource('memory');
var Post = ds.define('Post', { userId: Number, content: String }); var Post = ds.define('Post', { userId: Number, content: String });
var User = ds.define('User', { name: String }, { relations: { posts: { type: 'hasMany', model: 'Post' }}}); var User = ds.define('User', { name: String }, {
relations: { posts: { type: 'hasMany', model: 'Post' }},
});
assert(User.relations['posts']); assert(User.relations['posts']);
done(); done();
@ -1023,7 +1025,9 @@ describe('Load models with relations', function() {
var ds = new DataSource('memory'); var ds = new DataSource('memory');
var User = ds.define('User', { name: String }); var User = ds.define('User', { name: String });
var Post = ds.define('Post', { userId: Number, content: String }, { relations: { user: { type: 'belongsTo', model: 'User' }}}); var Post = ds.define('Post', { userId: Number, content: String }, {
relations: { user: { type: 'belongsTo', model: 'User' }},
});
assert(Post.relations['user']); assert(Post.relations['user']);
done(); done();
@ -1033,7 +1037,9 @@ describe('Load models with relations', function() {
var ds = new DataSource('memory'); var ds = new DataSource('memory');
var Post = ds.define('Post', { userId: Number, content: String }); var Post = ds.define('Post', { userId: Number, content: String });
var User = ds.define('User', { name: String }, { relations: { posts: { type: 'referencesMany', model: 'Post' }}}); var User = ds.define('User', { name: String }, {
relations: { posts: { type: 'referencesMany', model: 'Post' }},
});
assert(User.relations['posts']); assert(User.relations['posts']);
done(); done();
@ -1043,7 +1049,9 @@ describe('Load models with relations', function() {
var ds = new DataSource('memory'); var ds = new DataSource('memory');
var Post = ds.define('Post', { userId: Number, content: String }); var Post = ds.define('Post', { userId: Number, content: String });
var User = ds.define('User', { name: String }, { relations: { posts: { type: 'embedsMany', model: 'Post' }}}); var User = ds.define('User', { name: String }, {
relations: { posts: { type: 'embedsMany', model: 'Post' }},
});
assert(User.relations['posts']); assert(User.relations['posts']);
done(); done();
@ -1097,7 +1105,9 @@ describe('Load models with relations', function() {
var ds = new DataSource('memory'); var ds = new DataSource('memory');
var User = ds.define('User', { name: String, id: { type: String, id: true }}); var User = ds.define('User', { name: String, id: { type: String, id: true }});
var Post = ds.define('Post', { content: String }, { relations: { user: { type: 'belongsTo', model: 'User' }}}); var Post = ds.define('Post', { content: String }, { relations: {
user: { type: 'belongsTo', model: 'User' }},
});
var fk = Post.definition.properties['userId']; var fk = Post.definition.properties['userId'];
assert(fk, 'The foreign key should be added'); assert(fk, 'The foreign key should be added');
@ -1109,14 +1119,23 @@ describe('Load models with relations', function() {
it('should set up hasMany and belongsTo relations', function(done) { it('should set up hasMany and belongsTo relations', function(done) {
var ds = new DataSource('memory'); var ds = new DataSource('memory');
var User = ds.define('User', { name: String }, { relations: { posts: { type: 'hasMany', model: 'Post' }, accounts: { type: 'hasMany', model: 'Account' }}}); var User = ds.define('User', { name: String }, {
relations: {
posts: { type: 'hasMany', model: 'Post' },
accounts: { type: 'hasMany', model: 'Account' },
},
});
assert(!User.relations['posts']); assert(!User.relations['posts']);
assert(!User.relations['accounts']); assert(!User.relations['accounts']);
var Post = ds.define('Post', { userId: Number, content: String }, { relations: { user: { type: 'belongsTo', model: 'User' }}}); var Post = ds.define('Post', { userId: Number, content: String }, {
relations: { user: { type: 'belongsTo', model: 'User' }},
});
var Account = ds.define('Account', { userId: Number, type: String }, { relations: { user: { type: 'belongsTo', model: 'User' }}}); var Account = ds.define('Account', { userId: Number, type: String }, {
relations: { user: { type: 'belongsTo', model: 'User' }},
});
assert(Post.relations['user']); assert(Post.relations['user']);
assert.deepEqual(Post.relations['user'].toJSON(), { assert.deepEqual(Post.relations['user'].toJSON(), {
@ -1158,7 +1177,9 @@ describe('Load models with relations', function() {
var Post = ds.define('Post', { userId: Number, content: String }); var Post = ds.define('Post', { userId: Number, content: String });
try { try {
var User = ds.define('User', { name: String }, { relations: { posts: { model: 'Post' }}}); var User = ds.define('User', { name: String }, {
relations: { posts: { model: 'Post' }},
});
} catch (e) { } catch (e) {
done(); done();
} }
@ -1171,7 +1192,9 @@ describe('Load models with relations', function() {
var Post = ds.define('Post', { userId: Number, content: String }); var Post = ds.define('Post', { userId: Number, content: String });
try { try {
var User = ds.define('User', { name: String }, { relations: { posts: { type: 'hasXYZ', model: 'Post' }}}); var User = ds.define('User', { name: String }, {
relations: { posts: { type: 'hasXYZ', model: 'Post' }},
});
} catch (e) { } catch (e) {
done(); done();
} }
@ -1182,11 +1205,19 @@ describe('Load models with relations', function() {
var ds = new DataSource('memory'); var ds = new DataSource('memory');
var Physician = ds.createModel('Physician', { var Physician = ds.createModel('Physician', {
name: String, name: String,
}, { relations: { patients: { model: 'Patient', type: 'hasMany', through: 'Appointment' }}}); }, {
relations: {
patients: { model: 'Patient', type: 'hasMany', through: 'Appointment' },
},
});
var Patient = ds.createModel('Patient', { var Patient = ds.createModel('Patient', {
name: String, name: String,
}, { relations: { physicians: { model: 'Physician', type: 'hasMany', through: 'Appointment' }}}); }, {
relations: {
physicians: { model: 'Physician', type: 'hasMany', through: 'Appointment' },
},
});
assert(!Physician.relations['patients']); // Appointment hasn't been resolved yet assert(!Physician.relations['patients']); // Appointment hasn't been resolved yet
assert(!Patient.relations['physicians']); // Appointment hasn't been resolved yet assert(!Patient.relations['physicians']); // Appointment hasn't been resolved yet
@ -1195,7 +1226,12 @@ describe('Load models with relations', function() {
physicianId: Number, physicianId: Number,
patientId: Number, patientId: Number,
appointmentDate: Date, appointmentDate: Date,
}, { relations: { patient: { type: 'belongsTo', model: 'Patient' }, physician: { type: 'belongsTo', model: 'Physician' }}}); }, {
relations: {
patient: { type: 'belongsTo', model: 'Patient' },
physician: { type: 'belongsTo', model: 'Physician' },
},
});
assert(Physician.relations['patients']); assert(Physician.relations['patients']);
assert(Patient.relations['physicians']); assert(Patient.relations['physicians']);
@ -1206,17 +1242,30 @@ describe('Load models with relations', function() {
var ds = new DataSource('memory'); var ds = new DataSource('memory');
var Physician = ds.createModel('Physician', { var Physician = ds.createModel('Physician', {
name: String, name: String,
}, { relations: { patients: { model: 'Patient', type: 'hasMany', foreignKey: 'leftId', through: 'Appointment' }}}); }, {
relations: {
patients: { model: 'Patient', type: 'hasMany', foreignKey: 'leftId', through: 'Appointment' },
},
});
var Patient = ds.createModel('Patient', { var Patient = ds.createModel('Patient', {
name: String, name: String,
}, { relations: { physicians: { model: 'Physician', type: 'hasMany', foreignKey: 'rightId', through: 'Appointment' }}}); }, {
relations: {
physicians: { model: 'Physician', type: 'hasMany', foreignKey: 'rightId', through: 'Appointment' },
},
});
var Appointment = ds.createModel('Appointment', { var Appointment = ds.createModel('Appointment', {
physicianId: Number, physicianId: Number,
patientId: Number, patientId: Number,
appointmentDate: Date, appointmentDate: Date,
}, { relations: { patient: { type: 'belongsTo', model: 'Patient' }, physician: { type: 'belongsTo', model: 'Physician' }}}); }, {
relations: {
patient: { type: 'belongsTo', model: 'Patient' },
physician: { type: 'belongsTo', model: 'Physician' },
},
});
assert(Physician.relations['patients'].keyTo === 'leftId'); assert(Physician.relations['patients'].keyTo === 'leftId');
assert(Patient.relations['physicians'].keyTo === 'rightId'); assert(Patient.relations['physicians'].keyTo === 'rightId');
@ -1228,7 +1277,9 @@ describe('Load models with relations', function() {
var modelBuilder = new ModelBuilder(); var modelBuilder = new ModelBuilder();
var Post = modelBuilder.define('Post', { userId: Number, content: String }); var Post = modelBuilder.define('Post', { userId: Number, content: String });
var User = modelBuilder.define('User', { name: String }, { relations: { posts: { type: 'hasMany', model: 'Post' }}}); var User = modelBuilder.define('User', { name: String }, {
relations: { posts: { type: 'hasMany', model: 'Post' },
}});
assert(!User.relations['posts']); assert(!User.relations['posts']);
Post.attachTo(ds); Post.attachTo(ds);

View File

@ -500,7 +500,7 @@ describe('manipulation', function() {
// Using {foo: 'bar'} only causes dependent test failures due to the // Using {foo: 'bar'} only causes dependent test failures due to the
// stripping of object properties when in strict mode (ie. {foo: 'bar'} // stripping of object properties when in strict mode (ie. {foo: 'bar'}
// changes to '{}' and breaks other tests // changes to '{}' and breaks other tests
person.updateAttributes({ name: 'John', foo:'bar' }, person.updateAttributes({ name: 'John', foo: 'bar' },
function(err, p) { function(err, p) {
if (err) return done(err); if (err) return done(err);
should.not.exist(p.foo); should.not.exist(p.foo);
@ -515,7 +515,7 @@ describe('manipulation', function() {
it('should throw error on unknown attributes when strict: throw', function(done) { it('should throw error on unknown attributes when strict: throw', function(done) {
Person.definition.settings.strict = 'throw'; Person.definition.settings.strict = 'throw';
Person.findById(person.id, function(err, p) { Person.findById(person.id, function(err, p) {
p.updateAttributes({ foo:'bar' }, p.updateAttributes({ foo: 'bar' },
function(err, p) { function(err, p) {
should.exist(err); should.exist(err);
err.name.should.equal('Error'); err.name.should.equal('Error');
@ -533,7 +533,7 @@ describe('manipulation', function() {
it('should throw error on unknown attributes when strict: throw', function(done) { it('should throw error on unknown attributes when strict: throw', function(done) {
Person.definition.settings.strict = 'validate'; Person.definition.settings.strict = 'validate';
Person.findById(person.id, function(err, p) { Person.findById(person.id, function(err, p) {
p.updateAttributes({ foo:'bar' }, p.updateAttributes({ foo: 'bar' },
function(err, p) { function(err, p) {
should.exist(err); should.exist(err);
err.name.should.equal('ValidationError'); err.name.should.equal('ValidationError');
@ -935,7 +935,7 @@ describe('manipulation', function() {
}); });
it('works without options(promise variant)', function(done) { it('works without options(promise variant)', function(done) {
Post.findById(postInstance.id) Post.findById(postInstance.id)
.then(function(p) { .then(function(p) {
p.replaceAttributes({ title: 'b' }) p.replaceAttributes({ title: 'b' })
.then(function(p) { .then(function(p) {
@ -952,10 +952,10 @@ describe('manipulation', function() {
}); });
}) })
.catch(done); .catch(done);
}); });
it('works with options(promise variant)', function(done) { it('works with options(promise variant)', function(done) {
Post.findById(postInstance.id) Post.findById(postInstance.id)
.then(function(p) { .then(function(p) {
p.replaceAttributes({ title: 'b' }, { validate: false }) p.replaceAttributes({ title: 'b' }, { validate: false })
.then(function(p) { .then(function(p) {
@ -972,32 +972,32 @@ describe('manipulation', function() {
}); });
}) })
.catch(done); .catch(done);
}); });
it('works without options(callback variant)', function(done) { it('works without options(callback variant)', function(done) {
Post.findById(postInstance.id, function(err, p) { Post.findById(postInstance.id, function(err, p) {
if (err) return done(err);
p.replaceAttributes({ title: 'b' }, function(err, p) {
if (err) return done(err); if (err) return done(err);
p.should.not.have.property('content', undefined); p.replaceAttributes({ title: 'b' }, function(err, p) {
p.title.should.equal('b'); if (err) return done(err);
done(); p.should.not.have.property('content', undefined);
p.title.should.equal('b');
done();
});
}); });
}); });
});
it('works with options(callback variant)', function(done) { it('works with options(callback variant)', function(done) {
Post.findById(postInstance.id, function(err, p) { Post.findById(postInstance.id, function(err, p) {
if (err) return done(err);
p.replaceAttributes({ title: 'b' }, { validate: false }, function(err, p) {
if (err) return done(err); if (err) return done(err);
p.should.not.have.property('content', undefined); p.replaceAttributes({ title: 'b' }, { validate: false }, function(err, p) {
p.title.should.equal('b'); if (err) return done(err);
done(); p.should.not.have.property('content', undefined);
p.title.should.equal('b');
done();
});
}); });
}); });
}); });
});
} }
describe('findOrCreate', function() { describe('findOrCreate', function() {
@ -1152,44 +1152,44 @@ describe('manipulation', function() {
it('should only delete instances that satisfy the where condition', it('should only delete instances that satisfy the where condition',
function(done) { function(done) {
Person.deleteAll({ name: 'John' }, function(err, info) { 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);
data.should.have.length(0);
Person.find({ where: { name: 'Jane' }}, function(err, data) {
if (err) return done(err); if (err) return done(err);
data.should.have.length(1); info.should.have.property('count', 1);
done(); Person.find({ where: { name: 'John' }}, 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();
});
});
}); });
}); });
});
});
it('should report zero deleted instances when no matches are found', it('should report zero deleted instances when no matches are found',
function(done) { function(done) {
Person.deleteAll({ name: 'does-not-match' }, function(err, info) { Person.deleteAll({ name: 'does-not-match' }, function(err, info) {
if (err) return done(err); if (err) return done(err);
info.should.have.property('count', 0); info.should.have.property('count', 0);
Person.count(function(err, count) { Person.count(function(err, count) {
if (err) return done(err); if (err) return done(err);
count.should.equal(2); count.should.equal(2);
done(); done();
}); });
}); });
}); });
it('should delete all instances when the where condition is not provided', it('should delete all instances when the where condition is not provided',
function(done) { function(done) {
Person.deleteAll(function(err, info) { Person.deleteAll(function(err, info) {
if (err) return done(err); if (err) return done(err);
info.should.have.property('count', 2); info.should.have.property('count', 2);
Person.count(function(err, count) { Person.count(function(err, count) {
if (err) return done(err); if (err) return done(err);
count.should.equal(0); count.should.equal(0);
done(); done();
}); });
}); });
}); });
}); });
@ -1528,47 +1528,47 @@ describe('manipulation', function() {
function(done) { function(done) {
Person.update({ name: 'Harry Hoe' }, { name: 'Marta Moe' }, function(err, Person.update({ name: 'Harry Hoe' }, { name: 'Marta Moe' }, function(err,
info) { info) {
if (err) return done(err); if (err) return done(err);
info.should.have.property('count', 0); info.should.have.property('count', 0);
Person.find({ where: { name: 'Harry Hoe' }}, function(err, people) { Person.find({ where: { name: 'Harry Hoe' }}, function(err, people) {
if (err) return done(err); if (err) return done(err);
people.should.be.empty; people.should.be.empty;
done(); done();
}); });
}); });
}); });
it('should only update instances that satisfy the where condition', it('should only update instances that satisfy the where condition',
function(done) { function(done) {
Person.update({ name: 'Brett Boe' }, { name: 'Harry Hoe' }, function(err, Person.update({ name: 'Brett Boe' }, { name: 'Harry Hoe' }, function(err,
info) { info) {
if (err) return done(err); if (err) return done(err);
info.should.have.property('count', 1); info.should.have.property('count', 1);
Person.find({ where: { age: 19 }}, function(err, people) { Person.find({ where: { age: 19 }}, function(err, people) {
if (err) return done(err); if (err) return done(err);
people.should.have.length(1); people.should.have.length(1);
people[0].name.should.equal('Harry Hoe'); people[0].name.should.equal('Harry Hoe');
done(); done();
}); });
}); });
}); });
it('should update all instances when the where condition is not provided', it('should update all instances when the where condition is not provided',
function(done) { function(done) {
Person.update({ name: 'Harry Hoe' }, function(err, info) { Person.update({ name: 'Harry Hoe' }, function(err, info) {
if (err) return done(err);
info.should.have.property('count', 5);
Person.find({ where: { name: 'Brett Boe' }}, function(err, people) {
if (err) return done(err);
people.should.be.empty;
Person.find({ where: { name: 'Harry Hoe' }}, function(err, people) {
if (err) return done(err); if (err) return done(err);
people.should.have.length(5); info.should.have.property('count', 5);
done(); Person.find({ where: { name: 'Brett Boe' }}, function(err, people) {
if (err) return done(err);
people.should.be.empty;
Person.find({ where: { name: 'Harry Hoe' }}, function(err, people) {
if (err) return done(err);
people.should.have.length(5);
done();
});
});
}); });
}); });
});
});
it('should ignore where conditions with undefined values', it('should ignore where conditions with undefined values',
function(done) { function(done) {
@ -1577,21 +1577,21 @@ describe('manipulation', function() {
if (err) return done(err); if (err) return done(err);
info.should.have.property('count', 1); info.should.have.property('count', 1);
Person.find({ where: { name: 'Brett Boe' }}, function(err, people) { Person.find({ where: { name: 'Brett Boe' }}, function(err, people) {
if (err) return done(err); if (err) return done(err);
people.should.have.length(1); people.should.have.length(1);
people[0].name.should.equal('Brett Boe'); people[0].name.should.equal('Brett Boe');
done(); done();
}); });
}); });
}); });
it('should not coerce invalid values provided in where conditions', it('should not coerce invalid values provided in where conditions',
function(done) { function(done) {
Person.update({ name: 'Brett Boe' }, { dob: 'Carla Coe' }, function(err) { Person.update({ name: 'Brett Boe' }, { dob: 'Carla Coe' }, function(err) {
should.exist(err); should.exist(err);
err.message.should.equal('Invalid date: Carla Coe'); err.message.should.equal('Invalid date: Carla Coe');
done(); done();
}); });
}); });
}); });
}); });

View File

@ -281,7 +281,7 @@ describe('Memory connector', function() {
}); });
it('should successfully extract 2 users using implied and', function(done) { it('should successfully extract 2 users using implied and', function(done) {
User.find({ where: { role:'lead', vip:true }}, function(err, users) { User.find({ where: { role: 'lead', vip: true }}, function(err, users) {
should(users.length).be.equal(2); should(users.length).be.equal(2);
should(users[0].name).be.equal('John Lennon'); should(users[0].name).be.equal('John Lennon');
should(users[1].name).be.equal('Paul McCartney'); should(users[1].name).be.equal('Paul McCartney');
@ -290,7 +290,10 @@ describe('Memory connector', function() {
}); });
it('should successfully extract 2 users using implied and & and', function(done) { it('should successfully extract 2 users using implied and & and', function(done) {
User.find({ where: { name: 'John Lennon', and: [{ role:'lead' }, { vip:true }] }}, function(err, users) { User.find({ where: {
name: 'John Lennon',
and: [{ role: 'lead' }, { vip: true }],
}}, function(err, users) {
should(users.length).be.equal(1); should(users.length).be.equal(1);
should(users[0].name).be.equal('John Lennon'); should(users[0].name).be.equal('John Lennon');
done(); done();
@ -427,11 +430,11 @@ describe('Memory connector', function() {
it('should work when a regex is provided without the regexp operator', it('should work when a regex is provided without the regexp operator',
function(done) { function(done) {
User.find({ where: { name: /John.*/i }}, function(err, users) { User.find({ where: { name: /John.*/i }}, function(err, users) {
should.not.exist(err); should.not.exist(err);
users.length.should.equal(1); users.length.should.equal(1);
users[0].name.should.equal('John Lennon'); users[0].name.should.equal('John Lennon');
done(); done();
}); });
}); });
it('should support the regexp operator with regex strings', function(done) { it('should support the regexp operator with regex strings', function(done) {
@ -485,13 +488,13 @@ describe('Memory connector', function() {
it('should support nested property with gt in query', function(done) { it('should support nested property with gt in query', function(done) {
User.find({ where: { 'address.city': { gt: 'San' }}}, function(err, users) { User.find({ where: { 'address.city': { gt: 'San' }}}, function(err, users) {
should.not.exist(err); should.not.exist(err);
users.length.should.be.equal(2); users.length.should.be.equal(2);
for (var i = 0; i < users.length; i++) { for (var i = 0; i < users.length; i++) {
users[i].address.state.should.be.eql('CA'); users[i].address.state.should.be.eql('CA');
} }
done(); done();
}); });
}); });
it('should support nested property for order in query', function(done) { it('should support nested property for order in query', function(done) {

View File

@ -28,7 +28,7 @@ describe('ModelDefinition class', function() {
bio: ModelBuilder.Text, bio: ModelBuilder.Text,
approved: Boolean, approved: Boolean,
joinedAt: Date, joinedAt: Date,
age: "number", age: 'number',
}); });
User.build(); User.build();
@ -60,7 +60,7 @@ describe('ModelDefinition class', function() {
bio: ModelBuilder.Text, bio: ModelBuilder.Text,
approved: Boolean, approved: Boolean,
joinedAt: Date, joinedAt: Date,
age: "number", age: 'number',
}); });
User.build(); User.build();
@ -216,7 +216,7 @@ describe('ModelDefinition class', function() {
bio: ModelBuilder.Text, bio: ModelBuilder.Text,
approved: Boolean, approved: Boolean,
joinedAt: Date, joinedAt: Date,
age: "number", age: 'number',
}); });
assert.equal(User.idName(), 'userId'); assert.equal(User.idName(), 'userId');
@ -234,7 +234,7 @@ describe('ModelDefinition class', function() {
bio: ModelBuilder.Text, bio: ModelBuilder.Text,
approved: Boolean, approved: Boolean,
joinedAt: Date, joinedAt: Date,
age: "number", age: 'number',
}); });
var ids = User.ids(); var ids = User.ids();
@ -251,7 +251,7 @@ describe('ModelDefinition class', function() {
var User = new ModelDefinition(modelBuilder, 'User', { var User = new ModelDefinition(modelBuilder, 'User', {
userId: { type: String, id: true, oracle: { column: 'ID' }}, userId: { type: String, id: true, oracle: { column: 'ID' }},
name: "string", name: 'string',
}, { oracle: { table: 'USER' }}); }, { oracle: { table: 'USER' }});
assert.equal(User.tableName('oracle'), 'USER'); assert.equal(User.tableName('oracle'), 'USER');

View File

@ -136,20 +136,28 @@ describe('optional-validation', function() {
}); });
describe('method findOrCreate', function() { describe('method findOrCreate', function() {
it('should throw on findOrCreate with validate:true with invalid data', function(done) { it('should throw on findOrCreate with validate:true with invalid data',
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) { it('should NOT throw on findOrCreate with validate:false with invalid data',
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) { it('should NOT throw on findOrCreate with validate:true with valid data',
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) { it('should NOT throw on findOrCreate with validate:false with valid data',
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) { it('should throw on findOrCreate with invalid data', function(done) {
@ -162,20 +170,28 @@ describe('optional-validation', function() {
}); });
describe('method updateOrCreate on existing data', function() { describe('method updateOrCreate on existing data', function() {
it('should throw on updateOrCreate(id) with validate:true with invalid data', function(done) { it('should throw on updateOrCreate(id) with validate:true with invalid data',
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) { it('should NOT throw on updateOrCreate(id) with validate:false with invalid data',
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) { it('should NOT throw on updateOrCreate(id) with validate:true with valid data',
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) { it('should NOT throw on updateOrCreate(id) with validate:false with valid data',
callUpdateOrCreateWithExistingUserId(NEW_NAME, { validate: false }, expectChangeSuccess(done)); function(done) {
callUpdateOrCreateWithExistingUserId(NEW_NAME, { validate: false },
expectChangeSuccess(done));
}); });
// backwards compatible with validateUpsert // backwards compatible with validateUpsert
@ -300,24 +316,33 @@ describe('optional-validation', function() {
}); });
describe('method findOrCreate', function() { describe('method findOrCreate', function() {
it('should throw on findOrCreate with validate:true with invalid data', function(done) { it('should throw on findOrCreate with validate:true with invalid data',
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) { it('should NOT throw on findOrCreate with validate:false with invalid data',
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) { it('should NOT throw on findOrCreate with validate:true with valid data',
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) { it('should NOT throw on findOrCreate with validate:false with valid data',
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) { it('should NOT throw on findOrCreate with invalid data', function(done) {
User.findOrCreate(getNewWhere(), INVALID_DATA, expectCreateSuccess(INVALID_DATA, done)); User.findOrCreate(getNewWhere(), INVALID_DATA,
expectCreateSuccess(INVALID_DATA, done));
}); });
it('should NOT throw on findOrCreate with valid data', function(done) { it('should NOT throw on findOrCreate with valid data', function(done) {
@ -326,20 +351,28 @@ describe('optional-validation', function() {
}); });
describe('method updateOrCreate on existing data', function() { describe('method updateOrCreate on existing data', function() {
it('should throw on updateOrCreate(id) with validate:true with invalid data', function(done) { it('should throw on updateOrCreate(id) with validate:true with invalid data',
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) { it('should NOT throw on updateOrCreate(id) with validate:false with invalid data',
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) { it('should NOT throw on updateOrCreate(id) with validate:true with valid data',
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) { it('should NOT throw on updateOrCreate(id) with validate:false with valid data',
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) { it('should NOT throw on updateOrCreate(id) with invalid data', function(done) {
@ -425,20 +458,28 @@ describe('optional-validation', function() {
}); });
describe('method findOrCreate', function() { describe('method findOrCreate', function() {
it('should throw on findOrCreate with validate:true with invalid data', function(done) { it('should throw on findOrCreate with validate:true with invalid data',
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) { it('should NOT throw on findOrCreate with validate:false with invalid data',
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) { it('should NOT throw on findOrCreate with validate:true with valid data',
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) { it('should NOT throw on findOrCreate with validate:false with valid data',
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) { it('should throw on findOrCreate with invalid data', function(done) {
@ -451,20 +492,28 @@ describe('optional-validation', function() {
}); });
describe('method updateOrCreate on existing data', function() { describe('method updateOrCreate on existing data', function() {
it('should throw on updateOrCreate(id) with validate:true with invalid data', function(done) { it('should throw on updateOrCreate(id) with validate:true with invalid data',
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) { it('should NOT throw on updateOrCreate(id) with validate:false with invalid data',
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) { it('should NOT throw on updateOrCreate(id) with validate:true with valid data',
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) { it('should NOT throw on updateOrCreate(id) with validate:false with valid data',
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) { it('should throw on updateOrCreate(id) with invalid data', function(done) {

View File

@ -9,7 +9,8 @@ var traverse = require('traverse');
module.exports = function(dataSource, should, connectorCapabilities) { module.exports = function(dataSource, should, connectorCapabilities) {
if (!connectorCapabilities) connectorCapabilities = {}; if (!connectorCapabilities) connectorCapabilities = {};
if (connectorCapabilities.replaceOrCreateReportsNewInstance === undefined) { if (connectorCapabilities.replaceOrCreateReportsNewInstance === undefined) {
console.warn('The connector does not support a recently added feature: replaceOrCreateReportsNewInstance'); console.warn('The connector does not support a recently added feature:' +
' replaceOrCreateReportsNewInstance');
} }
describe('Persistence hooks', function() { describe('Persistence hooks', function() {
var observedContexts, expectedError, observersCalled; var observedContexts, expectedError, observersCalled;
@ -150,7 +151,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
data: { data: {
id: '1', id: '1',
name: 'first', name: 'first',
extra: "hook data", extra: 'hook data',
}, },
isNewInstance: false, isNewInstance: false,
hookState: { test: true }, hookState: { test: true },
@ -1559,7 +1560,7 @@ module.exports = function(dataSource, should, connectorCapabilities) {
name: 'changed', name: 'changed',
id: data.id, id: data.id,
}, },
isNewInstance : false, isNewInstance: false,
})); }));
done(); done();
}); });
@ -2347,15 +2348,16 @@ module.exports = function(dataSource, should, connectorCapabilities) {
if (err) return done(err); if (err) return done(err);
var expectedContext = aTestModelCtx({ var expectedContext = aTestModelCtx({
currentInstance: { currentInstance: {
id: 'new-id', id: 'new-id',
name: 'a name', name: 'a name',
extra: undefined, extra: undefined,
}, data: { },
id: 'new-id', data: {
name: 'a name', id: 'new-id',
}, name: 'a name',
}); },
});

View File

@ -725,13 +725,13 @@ describe('relations', function() {
}); });
function verify(physician) { function verify(physician) {
//limit plus skip //limit plus skip
physician.patients({ limit:1, skip:1 }, function(err, ch) { physician.patients({ limit: 1, skip: 1 }, function(err, ch) {
should.not.exist(err); should.not.exist(err);
should.exist(ch); should.exist(ch);
ch.should.have.lengthOf(1); ch.should.have.lengthOf(1);
ch[0].name.should.eql('z'); ch[0].name.should.eql('z');
//offset plus skip //offset plus skip
physician.patients({ limit:1, offset:1 }, function(err1, ch1) { physician.patients({ limit: 1, offset: 1 }, function(err1, ch1) {
should.not.exist(err1); should.not.exist(err1);
should.exist(ch1); should.exist(ch1);
ch1.should.have.lengthOf(1); ch1.should.have.lengthOf(1);
@ -1162,8 +1162,12 @@ describe('relations', function() {
describe('when custom reverse belongsTo names for both sides', function() { describe('when custom reverse belongsTo names for both sides', function() {
it('can determine the collect via keyThrough', function() { it('can determine the collect via keyThrough', function() {
Physician.hasMany(Patient, { through: Appointment, foreignKey: 'fooId', keyThrough: 'barId' }); Physician.hasMany(Patient, {
Patient.hasMany(Physician, { through: Appointment, foreignKey: 'barId', keyThrough: 'fooId', as: 'yyy' }); through: Appointment, foreignKey: 'fooId', keyThrough: 'barId',
});
Patient.hasMany(Physician, {
through: Appointment, foreignKey: 'barId', keyThrough: 'fooId', as: 'yyy',
});
Appointment.belongsTo(Physician, { as: 'foo' }); Appointment.belongsTo(Physician, { as: 'foo' });
Appointment.belongsTo(Patient, { as: 'bar' }); Appointment.belongsTo(Patient, { as: 'bar' });
Patient.belongsTo(Address); // jam. Patient.belongsTo(Address); // jam.
@ -1255,8 +1259,12 @@ describe('relations', function() {
} }}); } }});
Address = db.define('Address', { name: String }); Address = db.define('Address', { name: String });
User.hasMany(User, { as: 'followers', foreignKey: 'followeeId', keyThrough: 'followerId', through: Follow }); User.hasMany(User, {
User.hasMany(User, { as: 'following', foreignKey: 'followerId', keyThrough: 'followeeId', through: Follow }); as: 'followers', foreignKey: 'followeeId', keyThrough: 'followerId', through: Follow,
});
User.hasMany(User, {
as: 'following', foreignKey: 'followerId', keyThrough: 'followeeId', through: Follow,
});
User.belongsTo(Address); User.belongsTo(Address);
Follow.belongsTo(User, { as: 'follower' }); Follow.belongsTo(User, { as: 'follower' });
Follow.belongsTo(User, { as: 'followee' }); Follow.belongsTo(User, { as: 'followee' });
@ -1303,8 +1311,12 @@ describe('relations', function() {
} }}); } }});
Address = db.define('Address', { name: String }); Address = db.define('Address', { name: String });
User.hasMany(User, { as: 'followers', foreignKey: 'followeeId', keyThrough: 'followerId', through: Follow }); User.hasMany(User, {
User.hasMany(User, { as: 'following', foreignKey: 'followerId', keyThrough: 'followeeId', through: Follow }); as: 'followers', foreignKey: 'followeeId', keyThrough: 'followerId', through: Follow,
});
User.hasMany(User, {
as: 'following', foreignKey: 'followerId', keyThrough: 'followeeId', through: Follow,
});
User.belongsTo(Address); User.belongsTo(Address);
Follow.belongsTo(User, { as: 'follower' }); Follow.belongsTo(User, { as: 'follower' });
Follow.belongsTo(User, { as: 'followee' }); Follow.belongsTo(User, { as: 'followee' });
@ -2204,7 +2216,8 @@ describe('relations', function() {
}); });
it('should create polymorphic through model', function(done) { it('should create polymorphic through model', function(done) {
PictureLink.findOne({ where: { pictureId: anotherPicture.id, imageableType: 'Author' }}, function(err, link) { PictureLink.findOne({ where: { pictureId: anotherPicture.id, imageableType: 'Author' }},
function(err, link) {
should.not.exist(err); should.not.exist(err);
link.pictureId.should.eql(anotherPicture.id); link.pictureId.should.eql(anotherPicture.id);
link.imageableId.should.eql(author.id); link.imageableId.should.eql(author.id);
@ -3484,7 +3497,7 @@ describe('relations', function() {
// db = getSchema(); // db = getSchema();
Person = db.define('Person', { name: String }); Person = db.define('Person', { name: String });
Passport = tmp.define('Passport', Passport = tmp.define('Passport',
{ name:{ type:'string', required: true }}, { name: { type: 'string', required: true }},
{ idInjection: false } { idInjection: false }
); );
Address = tmp.define('Address', { street: String }, { idInjection: false }); Address = tmp.define('Address', { street: String }, { idInjection: false });
@ -3775,7 +3788,7 @@ describe('relations', function() {
db = getMemoryDataSource(); db = getMemoryDataSource();
Person = db.define('Person', { name: String }); Person = db.define('Person', { name: String });
Passport = db.define('Passport', Passport = db.define('Passport',
{ name:{ type:'string', required: true }} { name: { type: 'string', required: true }}
); );
}); });
@ -3787,7 +3800,7 @@ describe('relations', function() {
}); });
it('should create an item - to offset id', function(done) { it('should create an item - to offset id', function(done) {
Passport.create({ name:'Wilma' }, function(err, p) { Passport.create({ name: 'Wilma' }, function(err, p) {
should.not.exist(err); should.not.exist(err);
p.id.should.equal(1); p.id.should.equal(1);
p.name.should.equal('Wilma'); p.name.should.equal('Wilma');
@ -3828,8 +3841,8 @@ describe('relations', function() {
// db = getSchema(); // db = getSchema();
Person = db.define('Person', { name: String }); Person = db.define('Person', { name: String });
Passport = tmp.define('Passport', Passport = tmp.define('Passport',
{ id: { type:'string', id: true, generated:true }}, { id: { type: 'string', id: true, generated: true }},
{ name: { type:'string', required: true }} { name: { type: 'string', required: true }}
); );
}); });
@ -4097,7 +4110,7 @@ describe('relations', function() {
// db = getSchema(); // db = getSchema();
Person = db.define('Person', { name: String }); Person = db.define('Person', { name: String });
Address = tmp.define('Address', { Address = tmp.define('Address', {
id: { type: Number, id:true }, id: { type: Number, id: true },
street: String, street: String,
}); });

View File

@ -421,16 +421,16 @@ describe('scope - dynamic function', function() {
before(function() { before(function() {
db = getSchema(); db = getSchema();
Item = db.define('Item', { title: Number, creator:Number }); Item = db.define('Item', { title: Number, creator: Number });
Item.scope('dynamicQuery', function() { Item.scope('dynamicQuery', function() {
seed++; seed++;
return { where:{ creator:seed }}; return { where: { creator: seed }};
}); });
}); });
beforeEach(function(done) { beforeEach(function(done) {
Item.create({ title:1, creator:1 }, function() { Item.create({ title: 1, creator: 1 }, function() {
Item.create({ title:2, creator:2 }, done); Item.create({ title: 2, creator: 2 }, done);
}); });
}); });

View File

@ -3,6 +3,8 @@
// This file is licensed under the MIT License. // This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT // License text available at https://opensource.org/licenses/MIT
/* eslint-disable camelcase */
/* /*
if (!process.env.TRAVIS) { if (!process.env.TRAVIS) {
var semicov = require('semicov'); var semicov = require('semicov');

View File

@ -280,7 +280,7 @@ describe('validations', function() {
}); });
it('should return validation metadata', function() { it('should return validation metadata', function() {
var expected = { name:[{ validation: 'presence', options: {}}] }; var expected = { name: [{ validation: 'presence', options: {}}] };
delete User.validations; delete User.validations;
User.validatesPresenceOf('name'); User.validatesPresenceOf('name');
var validations = User.validations; var validations = User.validations;