不要怂,就是干,撸起袖子干!

Commit b17e7d8f by Andy Edwards Committed by GitHub

test(integration/include): asyncify (#12294)

1 parent fd11d98f
...@@ -171,7 +171,7 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -171,7 +171,7 @@ describe(Support.getTestDialectTeaser('Include'), () => {
}; };
}); });
it('should work on a nested set of relations with a where condition in between relations', function() { it('should work on a nested set of relations with a where condition in between relations', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
SubscriptionForm = this.sequelize.define('SubscriptionForm', {}), SubscriptionForm = this.sequelize.define('SubscriptionForm', {}),
Collection = this.sequelize.define('Collection', {}), Collection = this.sequelize.define('Collection', {}),
...@@ -194,8 +194,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -194,8 +194,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
Category.hasMany(SubCategory, { foreignKey: 'boundCategory' }); Category.hasMany(SubCategory, { foreignKey: 'boundCategory' });
SubCategory.belongsTo(Category, { foreignKey: 'boundCategory' }); SubCategory.belongsTo(Category, { foreignKey: 'boundCategory' });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return User.findOne({
await User.findOne({
include: [ include: [
{ {
model: SubscriptionForm, model: SubscriptionForm,
...@@ -227,9 +228,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -227,9 +228,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
] ]
}); });
}); });
});
it('should accept nested `where` and `limit` at the same time', function() { it('should accept nested `where` and `limit` at the same time', async function() {
const Product = this.sequelize.define('Product', { const Product = this.sequelize.define('Product', {
title: DataTypes.STRING title: DataTypes.STRING
}), }),
...@@ -248,8 +248,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -248,8 +248,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
Product.belongsToMany(Tag, { through: ProductTag }); Product.belongsToMany(Tag, { through: ProductTag });
Tag.belongsToMany(Product, { through: ProductTag }); Tag.belongsToMany(Product, { through: ProductTag });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([Set.bulkCreate([
await Promise.all([Set.bulkCreate([
{ title: 'office' } { title: 'office' }
]), Product.bulkCreate([ ]), Product.bulkCreate([
{ title: 'Chair' }, { title: 'Chair' },
...@@ -259,10 +260,11 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -259,10 +260,11 @@ describe(Support.getTestDialectTeaser('Include'), () => {
{ name: 'A' }, { name: 'A' },
{ name: 'B' }, { name: 'B' },
{ name: 'C' } { name: 'C' }
])]).then(() => { ])]);
return Promise.all([Set.findAll(), Product.findAll(), Tag.findAll()]);
}).then(([sets, products, tags]) => { const [sets, products, tags] = await Promise.all([Set.findAll(), Product.findAll(), Tag.findAll()]);
return Promise.all([
await Promise.all([
sets[0].addProducts([products[0], products[1]]), sets[0].addProducts([products[0], products[1]]),
products[0].addTag(tags[0], { priority: 1 }).then(() => { products[0].addTag(tags[0], { priority: 1 }).then(() => {
return products[0].addTag(tags[1], { priority: 2 }); return products[0].addTag(tags[1], { priority: 2 });
...@@ -275,8 +277,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -275,8 +277,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
return products[2].addTag(tags[2], { priority: 0 }); return products[2].addTag(tags[2], { priority: 0 });
}) })
]); ]);
}).then(() => {
return Set.findAll({ await Set.findAll({
include: [{ include: [{
model: Product, model: Product,
include: [{ include: [{
...@@ -289,8 +291,6 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -289,8 +291,6 @@ describe(Support.getTestDialectTeaser('Include'), () => {
limit: 1 limit: 1
}); });
}); });
});
});
it('should support an include with multiple different association types', async function() { it('should support an include with multiple different association types', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
...@@ -425,7 +425,7 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -425,7 +425,7 @@ describe(Support.getTestDialectTeaser('Include'), () => {
} }
}); });
it('should support many levels of belongsTo', function() { it('should support many levels of belongsTo', async function() {
const A = this.sequelize.define('a', {}), const A = this.sequelize.define('a', {}),
B = this.sequelize.define('b', {}), B = this.sequelize.define('b', {}),
C = this.sequelize.define('c', {}), C = this.sequelize.define('c', {}),
...@@ -443,8 +443,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -443,8 +443,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
F.belongsTo(G); F.belongsTo(G);
G.belongsTo(H); G.belongsTo(H);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([A.bulkCreate([
const [as0, b] = await Promise.all([A.bulkCreate([
{}, {},
{}, {},
{}, {},
...@@ -461,16 +462,16 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -461,16 +462,16 @@ describe(Support.getTestDialectTeaser('Include'), () => {
b; b;
singles.forEach(model => { singles.forEach(model => {
promise = promise.then(() => { promise = (async () => {
return model.create({}).then(instance => { await promise;
const instance = await model.create({});
if (previousInstance) { if (previousInstance) {
return previousInstance[`set${_.upperFirst(model.name)}`](instance).then(() => { await previousInstance[`set${_.upperFirst(model.name)}`](instance);
previousInstance = instance; previousInstance = instance;
}); return;
} }
previousInstance = b = instance; previousInstance = b = instance;
}); })();
});
}); });
promise = promise.then(() => { promise = promise.then(() => {
...@@ -478,12 +479,13 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -478,12 +479,13 @@ describe(Support.getTestDialectTeaser('Include'), () => {
}); });
return promise; return promise;
})([B, C, D, E, F, G, H])]).then(([as, b]) => { })([B, C, D, E, F, G, H])]);
return Promise.all(as.map(a => {
await Promise.all(as0.map(a => {
return a.setB(b); return a.setB(b);
})); }));
}).then(() => {
return A.findAll({ const as = await A.findAll({
include: [ include: [
{ model: B, include: [ { model: B, include: [
{ model: C, include: [ { model: C, include: [
...@@ -499,18 +501,16 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -499,18 +501,16 @@ describe(Support.getTestDialectTeaser('Include'), () => {
] } ] }
] } ] }
] ]
}).then(as => { });
expect(as.length).to.be.ok; expect(as.length).to.be.ok;
as.forEach(a => { as.forEach(a => {
expect(a.b.c.d.e.f.g.h).to.be.ok; expect(a.b.c.d.e.f.g.h).to.be.ok;
}); });
}); });
});
});
});
it('should support many levels of belongsTo (with a lower level having a where)', function() { it('should support many levels of belongsTo (with a lower level having a where)', async function() {
const A = this.sequelize.define('a', {}), const A = this.sequelize.define('a', {}),
B = this.sequelize.define('b', {}), B = this.sequelize.define('b', {}),
C = this.sequelize.define('c', {}), C = this.sequelize.define('c', {}),
...@@ -532,8 +532,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -532,8 +532,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
F.belongsTo(G); F.belongsTo(G);
G.belongsTo(H); G.belongsTo(H);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([A.bulkCreate([
const [as0, b] = await Promise.all([A.bulkCreate([
{}, {},
{}, {},
{}, {},
...@@ -556,16 +557,16 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -556,16 +557,16 @@ describe(Support.getTestDialectTeaser('Include'), () => {
values.name = 'yolo'; values.name = 'yolo';
} }
promise = promise.then(() => { promise = (async () => {
return model.create(values).then(instance => { await promise;
const instance = await model.create(values);
if (previousInstance) { if (previousInstance) {
return previousInstance[`set${_.upperFirst(model.name)}`](instance).then(() => { await previousInstance[`set${_.upperFirst(model.name)}`](instance);
previousInstance = instance; previousInstance = instance;
}); return;
} }
previousInstance = b = instance; previousInstance = b = instance;
}); })();
});
}); });
promise = promise.then(() => { promise = promise.then(() => {
...@@ -573,12 +574,13 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -573,12 +574,13 @@ describe(Support.getTestDialectTeaser('Include'), () => {
}); });
return promise; return promise;
})([B, C, D, E, F, G, H])]).then(([as, b]) => { })([B, C, D, E, F, G, H])]);
return Promise.all(as.map(a => {
await Promise.all(as0.map(a => {
return a.setB(b); return a.setB(b);
})); }));
}).then(() => {
return A.findAll({ const as = await A.findAll({
include: [ include: [
{ model: B, include: [ { model: B, include: [
{ model: C, include: [ { model: C, include: [
...@@ -596,18 +598,16 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -596,18 +598,16 @@ describe(Support.getTestDialectTeaser('Include'), () => {
] } ] }
] } ] }
] ]
}).then(as => { });
expect(as.length).to.be.ok; expect(as.length).to.be.ok;
as.forEach(a => { as.forEach(a => {
expect(a.b.c.d.e.f.g.h).to.be.ok; expect(a.b.c.d.e.f.g.h).to.be.ok;
}); });
}); });
});
});
});
it('should support ordering with only belongsTo includes', function() { it('should support ordering with only belongsTo includes', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
Item = this.sequelize.define('Item', { 'test': DataTypes.STRING }), Item = this.sequelize.define('Item', { 'test': DataTypes.STRING }),
Order = this.sequelize.define('Order', { 'position': DataTypes.INTEGER }); Order = this.sequelize.define('Order', { 'position': DataTypes.INTEGER });
...@@ -616,8 +616,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -616,8 +616,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
User.belongsTo(Item, { 'as': 'itemB', foreignKey: 'itemB_id' }); User.belongsTo(Item, { 'as': 'itemB', foreignKey: 'itemB_id' });
User.belongsTo(Order); User.belongsTo(Order);
return this.sequelize.sync().then(() => { await this.sequelize.sync();
return promiseProps({
const results = await promiseProps({
users: User.bulkCreate([{}, {}, {}]).then(() => { users: User.bulkCreate([{}, {}, {}]).then(() => {
return User.findAll(); return User.findAll();
}), }),
...@@ -636,7 +637,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -636,7 +637,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
]).then(() => { ]).then(() => {
return Order.findAll({ order: ['id'] }); return Order.findAll({ order: ['id'] });
}) })
}).then(results => { });
const user1 = results.users[0]; const user1 = results.users[0];
const user2 = results.users[1]; const user2 = results.users[1];
const user3 = results.users[2]; const user3 = results.users[2];
...@@ -650,7 +652,7 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -650,7 +652,7 @@ describe(Support.getTestDialectTeaser('Include'), () => {
const order2 = results.orders[1]; const order2 = results.orders[1];
const order3 = results.orders[2]; const order3 = results.orders[2];
return Promise.all([ await Promise.all([
user1.setItemA(item1), user1.setItemA(item1),
user1.setItemB(item2), user1.setItemB(item2),
user1.setOrder(order3), user1.setOrder(order3),
...@@ -661,8 +663,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -661,8 +663,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
user3.setItemB(item4), user3.setItemB(item4),
user3.setOrder(order1) user3.setOrder(order1)
]); ]);
}).then(() => {
return User.findAll({ const as = await User.findAll({
'include': [ 'include': [
{ 'model': Item, 'as': 'itemA', where: { test: 'abc' } }, { 'model': Item, 'as': 'itemA', where: { test: 'abc' } },
{ 'model': Item, 'as': 'itemB' }, { 'model': Item, 'as': 'itemB' },
...@@ -670,7 +672,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -670,7 +672,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
'order': [ 'order': [
[Order, 'position'] [Order, 'position']
] ]
}).then(as => { });
expect(as.length).to.eql(2); expect(as.length).to.eql(2);
expect(as[0].itemA.test).to.eql('abc'); expect(as[0].itemA.test).to.eql('abc');
...@@ -679,11 +682,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -679,11 +682,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
expect(as[0].Order.position).to.eql(1); expect(as[0].Order.position).to.eql(1);
expect(as[1].Order.position).to.eql(2); expect(as[1].Order.position).to.eql(2);
}); });
});
});
});
it('should include attributes from through models', function() { it('should include attributes from through models', async function() {
const Product = this.sequelize.define('Product', { const Product = this.sequelize.define('Product', {
title: DataTypes.STRING title: DataTypes.STRING
}), }),
...@@ -697,8 +697,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -697,8 +697,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
Product.belongsToMany(Tag, { through: ProductTag }); Product.belongsToMany(Tag, { through: ProductTag });
Tag.belongsToMany(Product, { through: ProductTag }); Tag.belongsToMany(Product, { through: ProductTag });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return promiseProps({
const results = await promiseProps({
products: Product.bulkCreate([ products: Product.bulkCreate([
{ title: 'Chair' }, { title: 'Chair' },
{ title: 'Desk' }, { title: 'Desk' },
...@@ -713,8 +714,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -713,8 +714,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
]).then(() => { ]).then(() => {
return Tag.findAll(); return Tag.findAll();
}) })
}).then(results => { });
return Promise.all([
await Promise.all([
results.products[0].addTag(results.tags[0], { through: { priority: 1 } }), results.products[0].addTag(results.tags[0], { through: { priority: 1 } }),
results.products[0].addTag(results.tags[1], { through: { priority: 2 } }), results.products[0].addTag(results.tags[1], { through: { priority: 2 } }),
results.products[1].addTag(results.tags[1], { through: { priority: 1 } }), results.products[1].addTag(results.tags[1], { through: { priority: 1 } }),
...@@ -722,8 +724,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -722,8 +724,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
results.products[2].addTag(results.tags[1], { through: { priority: 1 } }), results.products[2].addTag(results.tags[1], { through: { priority: 1 } }),
results.products[2].addTag(results.tags[2], { through: { priority: 2 } }) results.products[2].addTag(results.tags[2], { through: { priority: 2 } })
]); ]);
}).then(() => {
return Product.findAll({ const products = await Product.findAll({
include: [ include: [
{ model: Tag } { model: Tag }
], ],
...@@ -731,7 +733,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -731,7 +733,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
['id', 'ASC'], ['id', 'ASC'],
[Tag, 'id', 'ASC'] [Tag, 'id', 'ASC']
] ]
}).then(products => { });
expect(products[0].Tags[0].ProductTag.priority).to.equal(1); expect(products[0].Tags[0].ProductTag.priority).to.equal(1);
expect(products[0].Tags[1].ProductTag.priority).to.equal(2); expect(products[0].Tags[1].ProductTag.priority).to.equal(2);
...@@ -741,40 +744,37 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -741,40 +744,37 @@ describe(Support.getTestDialectTeaser('Include'), () => {
expect(products[2].Tags[1].ProductTag.priority).to.equal(1); expect(products[2].Tags[1].ProductTag.priority).to.equal(1);
expect(products[2].Tags[2].ProductTag.priority).to.equal(2); expect(products[2].Tags[2].ProductTag.priority).to.equal(2);
}); });
});
});
});
it('should support a required belongsTo include', function() { it('should support a required belongsTo include', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
Group = this.sequelize.define('Group', {}); Group = this.sequelize.define('Group', {});
User.belongsTo(Group); User.belongsTo(Group);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return promiseProps({
const results = await promiseProps({
groups: Group.bulkCreate([{}, {}]).then(() => { groups: Group.bulkCreate([{}, {}]).then(() => {
return Group.findAll(); return Group.findAll();
}), }),
users: User.bulkCreate([{}, {}, {}]).then(() => { users: User.bulkCreate([{}, {}, {}]).then(() => {
return User.findAll(); return User.findAll();
}) })
}).then(results => { });
return results.users[2].setGroup(results.groups[1]);
}).then(() => { await results.users[2].setGroup(results.groups[1]);
return User.findAll({
const users = await User.findAll({
include: [ include: [
{ model: Group, required: true } { model: Group, required: true }
] ]
}).then(users => { });
expect(users.length).to.equal(1); expect(users.length).to.equal(1);
expect(users[0].Group).to.be.ok; expect(users[0].Group).to.be.ok;
}); });
});
});
});
it('should be possible to extend the on clause with a where option on a belongsTo include', function() { it('should be possible to extend the on clause with a where option on a belongsTo include', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
Group = this.sequelize.define('Group', { Group = this.sequelize.define('Group', {
name: DataTypes.STRING name: DataTypes.STRING
...@@ -782,8 +782,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -782,8 +782,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
User.belongsTo(Group); User.belongsTo(Group);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return promiseProps({
const results = await promiseProps({
groups: Group.bulkCreate([ groups: Group.bulkCreate([
{ name: 'A' }, { name: 'A' },
{ name: 'B' } { name: 'B' }
...@@ -793,26 +794,25 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -793,26 +794,25 @@ describe(Support.getTestDialectTeaser('Include'), () => {
users: User.bulkCreate([{}, {}]).then(() => { users: User.bulkCreate([{}, {}]).then(() => {
return User.findAll(); return User.findAll();
}) })
}).then(results => { });
return Promise.all([
await Promise.all([
results.users[0].setGroup(results.groups[1]), results.users[0].setGroup(results.groups[1]),
results.users[1].setGroup(results.groups[0]) results.users[1].setGroup(results.groups[0])
]); ]);
}).then(() => {
return User.findAll({ const users = await User.findAll({
include: [ include: [
{ model: Group, where: { name: 'A' } } { model: Group, where: { name: 'A' } }
] ]
}).then(users => { });
expect(users.length).to.equal(1); expect(users.length).to.equal(1);
expect(users[0].Group).to.be.ok; expect(users[0].Group).to.be.ok;
expect(users[0].Group.name).to.equal('A'); expect(users[0].Group.name).to.equal('A');
}); });
});
});
});
it('should be possible to extend the on clause with a where option on a belongsTo include', function() { it('should be possible to extend the on clause with a where option on a belongsTo include', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
Group = this.sequelize.define('Group', { Group = this.sequelize.define('Group', {
name: DataTypes.STRING name: DataTypes.STRING
...@@ -820,8 +820,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -820,8 +820,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
User.belongsTo(Group); User.belongsTo(Group);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return promiseProps({
const results = await promiseProps({
groups: Group.bulkCreate([ groups: Group.bulkCreate([
{ name: 'A' }, { name: 'A' },
{ name: 'B' } { name: 'B' }
...@@ -831,26 +832,25 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -831,26 +832,25 @@ describe(Support.getTestDialectTeaser('Include'), () => {
users: User.bulkCreate([{}, {}]).then(() => { users: User.bulkCreate([{}, {}]).then(() => {
return User.findAll(); return User.findAll();
}) })
}).then(results => { });
return Promise.all([
await Promise.all([
results.users[0].setGroup(results.groups[1]), results.users[0].setGroup(results.groups[1]),
results.users[1].setGroup(results.groups[0]) results.users[1].setGroup(results.groups[0])
]); ]);
}).then(() => {
return User.findAll({ const users = await User.findAll({
include: [ include: [
{ model: Group, required: true } { model: Group, required: true }
] ]
}).then(users => { });
users.forEach(user => { users.forEach(user => {
expect(user.Group).to.be.ok; expect(user.Group).to.be.ok;
}); });
}); });
});
});
});
it('should be possible to define a belongsTo include as required with child hasMany not required', function() { it('should be possible to define a belongsTo include as required with child hasMany not required', async function() {
const Address = this.sequelize.define('Address', { 'active': DataTypes.BOOLEAN }), const Address = this.sequelize.define('Address', { 'active': DataTypes.BOOLEAN }),
Street = this.sequelize.define('Street', { 'active': DataTypes.BOOLEAN }), Street = this.sequelize.define('Street', { 'active': DataTypes.BOOLEAN }),
User = this.sequelize.define('User', { 'username': DataTypes.STRING }); User = this.sequelize.define('User', { 'username': DataTypes.STRING });
...@@ -863,11 +863,13 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -863,11 +863,13 @@ describe(Support.getTestDialectTeaser('Include'), () => {
Street.hasMany(Address, { foreignKey: 'streetId' }); Street.hasMany(Address, { foreignKey: 'streetId' });
// Sync // Sync
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Street.create({ active: true }).then(street => {
return Address.create({ active: true, streetId: street.id }).then(address => { const street = await Street.create({ active: true });
return User.create({ username: 'John', addressId: address.id }).then(() => { const address = await Address.create({ active: true, streetId: street.id });
return User.findOne({ await User.create({ username: 'John', addressId: address.id });
const john = await User.findOne({
where: { username: 'John' }, where: { username: 'John' },
include: [{ include: [{
model: Address, model: Address,
...@@ -879,17 +881,13 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -879,17 +881,13 @@ describe(Support.getTestDialectTeaser('Include'), () => {
model: Street model: Street
}] }]
}] }]
}).then(john => { });
expect(john.Address).to.be.ok; expect(john.Address).to.be.ok;
expect(john.Address.Street).to.be.ok; expect(john.Address.Street).to.be.ok;
}); });
});
});
});
});
});
it('should be possible to define a belongsTo include as required with child hasMany with limit', function() { it('should be possible to define a belongsTo include as required with child hasMany with limit', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
Group = this.sequelize.define('Group', { Group = this.sequelize.define('Group', {
name: DataTypes.STRING name: DataTypes.STRING
...@@ -901,8 +899,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -901,8 +899,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
User.belongsTo(Group); User.belongsTo(Group);
Group.hasMany(Category); Group.hasMany(Category);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return promiseProps({
const results = await promiseProps({
groups: Group.bulkCreate([ groups: Group.bulkCreate([
{ name: 'A' }, { name: 'A' },
{ name: 'B' } { name: 'B' }
...@@ -915,34 +914,33 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -915,34 +914,33 @@ describe(Support.getTestDialectTeaser('Include'), () => {
categories: Category.bulkCreate([{}, {}]).then(() => { categories: Category.bulkCreate([{}, {}]).then(() => {
return Category.findAll(); return Category.findAll();
}) })
}).then(results => { });
return Promise.all([
await Promise.all([
results.users[0].setGroup(results.groups[1]), results.users[0].setGroup(results.groups[1]),
results.users[1].setGroup(results.groups[0]), results.users[1].setGroup(results.groups[0]),
Promise.all(results.groups.map(group => { Promise.all(results.groups.map(group => {
return group.setCategories(results.categories); return group.setCategories(results.categories);
})) }))
]); ]);
}).then(() => {
return User.findAll({ const users = await User.findAll({
include: [ include: [
{ model: Group, required: true, include: [ { model: Group, required: true, include: [
{ model: Category } { model: Category }
] } ] }
], ],
limit: 1 limit: 1
}).then(users => { });
expect(users.length).to.equal(1); expect(users.length).to.equal(1);
users.forEach(user => { users.forEach(user => {
expect(user.Group).to.be.ok; expect(user.Group).to.be.ok;
expect(user.Group.Categories).to.be.ok; expect(user.Group.Categories).to.be.ok;
}); });
}); });
});
});
});
it('should be possible to define a belongsTo include as required with child hasMany with limit and aliases', function() { it('should be possible to define a belongsTo include as required with child hasMany with limit and aliases', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
Group = this.sequelize.define('Group', { Group = this.sequelize.define('Group', {
name: DataTypes.STRING name: DataTypes.STRING
...@@ -954,8 +952,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -954,8 +952,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
User.belongsTo(Group, { as: 'Team' }); User.belongsTo(Group, { as: 'Team' });
Group.hasMany(Category, { as: 'Tags' }); Group.hasMany(Category, { as: 'Tags' });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return promiseProps({
const results = await promiseProps({
groups: Group.bulkCreate([ groups: Group.bulkCreate([
{ name: 'A' }, { name: 'A' },
{ name: 'B' } { name: 'B' }
...@@ -968,34 +967,33 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -968,34 +967,33 @@ describe(Support.getTestDialectTeaser('Include'), () => {
categories: Category.bulkCreate([{}, {}]).then(() => { categories: Category.bulkCreate([{}, {}]).then(() => {
return Category.findAll(); return Category.findAll();
}) })
}).then(results => { });
return Promise.all([
await Promise.all([
results.users[0].setTeam(results.groups[1]), results.users[0].setTeam(results.groups[1]),
results.users[1].setTeam(results.groups[0]), results.users[1].setTeam(results.groups[0]),
Promise.all(results.groups.map(group => { Promise.all(results.groups.map(group => {
return group.setTags(results.categories); return group.setTags(results.categories);
})) }))
]); ]);
}).then(() => {
return User.findAll({ const users = await User.findAll({
include: [ include: [
{ model: Group, required: true, as: 'Team', include: [ { model: Group, required: true, as: 'Team', include: [
{ model: Category, as: 'Tags' } { model: Category, as: 'Tags' }
] } ] }
], ],
limit: 1 limit: 1
}).then(users => { });
expect(users.length).to.equal(1); expect(users.length).to.equal(1);
users.forEach(user => { users.forEach(user => {
expect(user.Team).to.be.ok; expect(user.Team).to.be.ok;
expect(user.Team.Tags).to.be.ok; expect(user.Team.Tags).to.be.ok;
}); });
}); });
});
});
});
it('should be possible to define a belongsTo include as required with child hasMany which is not required with limit', function() { it('should be possible to define a belongsTo include as required with child hasMany which is not required with limit', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
Group = this.sequelize.define('Group', { Group = this.sequelize.define('Group', {
name: DataTypes.STRING name: DataTypes.STRING
...@@ -1007,8 +1005,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1007,8 +1005,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
User.belongsTo(Group); User.belongsTo(Group);
Group.hasMany(Category); Group.hasMany(Category);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return promiseProps({
const results = await promiseProps({
groups: Group.bulkCreate([ groups: Group.bulkCreate([
{ name: 'A' }, { name: 'A' },
{ name: 'B' } { name: 'B' }
...@@ -1021,34 +1020,33 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1021,34 +1020,33 @@ describe(Support.getTestDialectTeaser('Include'), () => {
categories: Category.bulkCreate([{}, {}]).then(() => { categories: Category.bulkCreate([{}, {}]).then(() => {
return Category.findAll(); return Category.findAll();
}) })
}).then(results => { });
return Promise.all([
await Promise.all([
results.users[0].setGroup(results.groups[1]), results.users[0].setGroup(results.groups[1]),
results.users[1].setGroup(results.groups[0]), results.users[1].setGroup(results.groups[0]),
Promise.all(results.groups.map(group => { Promise.all(results.groups.map(group => {
return group.setCategories(results.categories); return group.setCategories(results.categories);
})) }))
]); ]);
}).then(() => {
return User.findAll({ const users = await User.findAll({
include: [ include: [
{ model: Group, required: true, include: [ { model: Group, required: true, include: [
{ model: Category, required: false } { model: Category, required: false }
] } ] }
], ],
limit: 1 limit: 1
}).then(users => { });
expect(users.length).to.equal(1); expect(users.length).to.equal(1);
users.forEach(user => { users.forEach(user => {
expect(user.Group).to.be.ok; expect(user.Group).to.be.ok;
expect(user.Group.Categories).to.be.ok; expect(user.Group.Categories).to.be.ok;
}); });
}); });
});
});
});
it('should be possible to extend the on clause with a where option on a hasOne include', function() { it('should be possible to extend the on clause with a where option on a hasOne include', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
Project = this.sequelize.define('Project', { Project = this.sequelize.define('Project', {
title: DataTypes.STRING title: DataTypes.STRING
...@@ -1056,8 +1054,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1056,8 +1054,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
User.hasOne(Project, { as: 'LeaderOf' }); User.hasOne(Project, { as: 'LeaderOf' });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return promiseProps({
const results = await promiseProps({
projects: Project.bulkCreate([ projects: Project.bulkCreate([
{ title: 'Alpha' }, { title: 'Alpha' },
{ title: 'Beta' } { title: 'Beta' }
...@@ -1067,26 +1066,25 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1067,26 +1066,25 @@ describe(Support.getTestDialectTeaser('Include'), () => {
users: User.bulkCreate([{}, {}]).then(() => { users: User.bulkCreate([{}, {}]).then(() => {
return User.findAll(); return User.findAll();
}) })
}).then(results => { });
return Promise.all([
await Promise.all([
results.users[1].setLeaderOf(results.projects[1]), results.users[1].setLeaderOf(results.projects[1]),
results.users[0].setLeaderOf(results.projects[0]) results.users[0].setLeaderOf(results.projects[0])
]); ]);
}).then(() => {
return User.findAll({ const users = await User.findAll({
include: [ include: [
{ model: Project, as: 'LeaderOf', where: { title: 'Beta' } } { model: Project, as: 'LeaderOf', where: { title: 'Beta' } }
] ]
}).then(users => { });
expect(users.length).to.equal(1); expect(users.length).to.equal(1);
expect(users[0].LeaderOf).to.be.ok; expect(users[0].LeaderOf).to.be.ok;
expect(users[0].LeaderOf.title).to.equal('Beta'); expect(users[0].LeaderOf.title).to.equal('Beta');
}); });
});
});
});
it('should be possible to extend the on clause with a where option on a hasMany include with a through model', function() { it('should be possible to extend the on clause with a where option on a hasMany include with a through model', async function() {
const Product = this.sequelize.define('Product', { const Product = this.sequelize.define('Product', {
title: DataTypes.STRING title: DataTypes.STRING
}), }),
...@@ -1100,8 +1098,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1100,8 +1098,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
Product.belongsToMany(Tag, { through: ProductTag }); Product.belongsToMany(Tag, { through: ProductTag });
Tag.belongsToMany(Product, { through: ProductTag }); Tag.belongsToMany(Product, { through: ProductTag });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return promiseProps({
const results = await promiseProps({
products: Product.bulkCreate([ products: Product.bulkCreate([
{ title: 'Chair' }, { title: 'Chair' },
{ title: 'Desk' }, { title: 'Desk' },
...@@ -1116,8 +1115,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1116,8 +1115,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
]).then(() => { ]).then(() => {
return Tag.findAll(); return Tag.findAll();
}) })
}).then(results => { });
return Promise.all([
await Promise.all([
results.products[0].addTag(results.tags[0], { priority: 1 }), results.products[0].addTag(results.tags[0], { priority: 1 }),
results.products[0].addTag(results.tags[1], { priority: 2 }), results.products[0].addTag(results.tags[1], { priority: 2 }),
results.products[1].addTag(results.tags[1], { priority: 1 }), results.products[1].addTag(results.tags[1], { priority: 1 }),
...@@ -1125,18 +1125,16 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1125,18 +1125,16 @@ describe(Support.getTestDialectTeaser('Include'), () => {
results.products[2].addTag(results.tags[1], { priority: 1 }), results.products[2].addTag(results.tags[1], { priority: 1 }),
results.products[2].addTag(results.tags[2], { priority: 2 }) results.products[2].addTag(results.tags[2], { priority: 2 })
]); ]);
}).then(() => {
return Product.findAll({ const products = await Product.findAll({
include: [ include: [
{ model: Tag, where: { name: 'C' } } { model: Tag, where: { name: 'C' } }
] ]
}).then(products => { });
expect(products.length).to.equal(1); expect(products.length).to.equal(1);
expect(products[0].Tags.length).to.equal(1); expect(products[0].Tags.length).to.equal(1);
}); });
});
});
});
it('should be possible to extend the on clause with a where option on nested includes', async function() { it('should be possible to extend the on clause with a where option on nested includes', async function() {
const User = this.sequelize.define('User', { const User = this.sequelize.define('User', {
...@@ -1203,10 +1201,13 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1203,10 +1201,13 @@ describe(Support.getTestDialectTeaser('Include'), () => {
]); ]);
for (const i of [0, 1, 2, 3, 4]) { for (const i of [0, 1, 2, 3, 4]) {
const user = await User.create({ name: 'FooBarzz' }); const user = await User.create({ name: 'FooBarzz' });
const products = await Product.bulkCreate([
await Product.bulkCreate([
{ title: 'Chair' }, { title: 'Chair' },
{ title: 'Desk' } { title: 'Desk' }
]).then(() => Product.findAll()); ]);
const products = await Product.findAll();
await Promise.all([ await Promise.all([
GroupMember.bulkCreate([ GroupMember.bulkCreate([
{ UserId: user.id, GroupId: groups[0].id, RankId: ranks[0].id }, { UserId: user.id, GroupId: groups[0].id, RankId: ranks[0].id },
...@@ -1262,7 +1263,7 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1262,7 +1263,7 @@ describe(Support.getTestDialectTeaser('Include'), () => {
} }
}); });
it('should be possible to use limit and a where with a belongsTo include', function() { it('should be possible to use limit and a where with a belongsTo include', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
Group = this.sequelize.define('Group', { Group = this.sequelize.define('Group', {
name: DataTypes.STRING name: DataTypes.STRING
...@@ -1270,8 +1271,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1270,8 +1271,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
User.belongsTo(Group); User.belongsTo(Group);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return promiseProps({
const results = await promiseProps({
groups: Group.bulkCreate([ groups: Group.bulkCreate([
{ name: 'A' }, { name: 'A' },
{ name: 'B' } { name: 'B' }
...@@ -1281,33 +1283,33 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1281,33 +1283,33 @@ describe(Support.getTestDialectTeaser('Include'), () => {
users: User.bulkCreate([{}, {}, {}, {}]).then(() => { users: User.bulkCreate([{}, {}, {}, {}]).then(() => {
return User.findAll(); return User.findAll();
}) })
}).then(results => { });
return Promise.all([
await Promise.all([
results.users[0].setGroup(results.groups[0]), results.users[0].setGroup(results.groups[0]),
results.users[1].setGroup(results.groups[0]), results.users[1].setGroup(results.groups[0]),
results.users[2].setGroup(results.groups[0]), results.users[2].setGroup(results.groups[0]),
results.users[3].setGroup(results.groups[1]) results.users[3].setGroup(results.groups[1])
]); ]);
}).then(() => {
return User.findAll({ const users = await User.findAll({
include: [ include: [
{ model: Group, where: { name: 'A' } } { model: Group, where: { name: 'A' } }
], ],
limit: 2 limit: 2
}).then(users => { });
expect(users.length).to.equal(2); expect(users.length).to.equal(2);
users.forEach(user => { users.forEach(user => {
expect(user.Group.name).to.equal('A'); expect(user.Group.name).to.equal('A');
}); });
}); });
});
});
});
it('should be possible use limit, attributes and a where on a belongsTo with additional hasMany includes', function() { it('should be possible use limit, attributes and a where on a belongsTo with additional hasMany includes', async function() {
return this.fixtureA().then(() => { await this.fixtureA();
return this.models.Product.findAll({
const products = await this.models.Product.findAll({
attributes: ['id', 'title'], attributes: ['id', 'title'],
include: [ include: [
{ model: this.models.Company, where: { name: 'NYSE' } }, { model: this.models.Company, where: { name: 'NYSE' } },
...@@ -1318,7 +1320,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1318,7 +1320,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: [ order: [
[this.sequelize.col(`${this.models.Product.name}.id`), 'ASC'] [this.sequelize.col(`${this.models.Product.name}.id`), 'ASC']
] ]
}).then(products => { });
expect(products.length).to.equal(3); expect(products.length).to.equal(3);
products.forEach(product => { products.forEach(product => {
...@@ -1327,27 +1330,25 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1327,27 +1330,25 @@ describe(Support.getTestDialectTeaser('Include'), () => {
expect(product.Prices.length).to.be.ok; expect(product.Prices.length).to.be.ok;
}); });
}); });
});
});
it('should be possible to have the primary key in attributes', function() { it('should be possible to have the primary key in attributes', async function() {
const Parent = this.sequelize.define('Parent', {}); const Parent = this.sequelize.define('Parent', {});
const Child1 = this.sequelize.define('Child1', {}); const Child1 = this.sequelize.define('Child1', {});
Parent.hasMany(Child1); Parent.hasMany(Child1);
Child1.belongsTo(Parent); Child1.belongsTo(Parent);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([
const [parent0, child] = await Promise.all([
Parent.create(), Parent.create(),
Child1.create() Child1.create()
]); ]);
}).then(([parent, child]) => {
return parent.addChild1(child).then(() => { await parent0.addChild1(child);
return parent; const parent = parent0;
});
}).then(parent => { await Child1.findOne({
return Child1.findOne({
include: [ include: [
{ {
model: Parent, model: Parent,
...@@ -1359,16 +1360,17 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1359,16 +1360,17 @@ describe(Support.getTestDialectTeaser('Include'), () => {
] ]
}); });
}); });
});
it('should be possible to turn off the attributes for the through table', function() { it('should be possible to turn off the attributes for the through table', async function() {
return this.fixtureA().then(() => { await this.fixtureA();
return this.models.Product.findAll({
const products = await this.models.Product.findAll({
attributes: ['title'], attributes: ['title'],
include: [ include: [
{ model: this.models.Tag, through: { attributes: [] }, required: true } { model: this.models.Tag, through: { attributes: [] }, required: true }
] ]
}).then(products => { });
products.forEach(product => { products.forEach(product => {
expect(product.Tags.length).to.be.ok; expect(product.Tags.length).to.be.ok;
product.Tags.forEach(tag => { product.Tags.forEach(tag => {
...@@ -1376,12 +1378,11 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1376,12 +1378,11 @@ describe(Support.getTestDialectTeaser('Include'), () => {
}); });
}); });
}); });
});
});
it('should be possible to select on columns inside a through table', function() { it('should be possible to select on columns inside a through table', async function() {
return this.fixtureA().then(() => { await this.fixtureA();
return this.models.Product.findAll({
const products = await this.models.Product.findAll({
attributes: ['title'], attributes: ['title'],
include: [ include: [
{ {
...@@ -1394,15 +1395,15 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1394,15 +1395,15 @@ describe(Support.getTestDialectTeaser('Include'), () => {
required: true required: true
} }
] ]
}).then(products => {
expect(products).have.length(1);
});
}); });
expect(products).have.length(1);
}); });
it('should be possible to select on columns inside a through table and a limit', function() { it('should be possible to select on columns inside a through table and a limit', async function() {
return this.fixtureA().then(() => { await this.fixtureA();
return this.models.Product.findAll({
const products = await this.models.Product.findAll({
attributes: ['title'], attributes: ['title'],
include: [ include: [
{ {
...@@ -1416,14 +1417,13 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1416,14 +1417,13 @@ describe(Support.getTestDialectTeaser('Include'), () => {
} }
], ],
limit: 5 limit: 5
}).then(products => {
expect(products).have.length(1);
});
}); });
expect(products).have.length(1);
}); });
// Test case by @eshell // Test case by @eshell
it('should be possible not to include the main id in the attributes', function() { it('should be possible not to include the main id in the attributes', async function() {
const Member = this.sequelize.define('Member', { const Member = this.sequelize.define('Member', {
id: { id: {
type: Sequelize.BIGINT, type: Sequelize.BIGINT,
...@@ -1457,7 +1457,7 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1457,7 +1457,7 @@ describe(Support.getTestDialectTeaser('Include'), () => {
Album.belongsTo(Member); Album.belongsTo(Member);
Member.hasMany(Album); Member.hasMany(Album);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
const members = [], const members = [],
albums = [], albums = [],
memberCount = 20; memberCount = 20;
...@@ -1474,30 +1474,29 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1474,30 +1474,29 @@ describe(Support.getTestDialectTeaser('Include'), () => {
}); });
} }
return Member.bulkCreate(members).then(() => { await Member.bulkCreate(members);
return Album.bulkCreate(albums).then(() => { await Album.bulkCreate(albums);
return Member.findAll({
const members0 = await Member.findAll({
attributes: ['email'], attributes: ['email'],
include: [ include: [
{ {
model: Album model: Album
} }
] ]
}).then(members => { });
expect(members.length).to.equal(20);
members.forEach(member => { expect(members0.length).to.equal(20);
members0.forEach(member => {
expect(member.get('id')).not.to.be.ok; expect(member.get('id')).not.to.be.ok;
expect(member.Albums.length).to.equal(1); expect(member.Albums.length).to.equal(1);
}); });
}); });
});
});
});
});
it('should be possible to use limit and a where on a hasMany with additional includes', function() { it('should be possible to use limit and a where on a hasMany with additional includes', async function() {
return this.fixtureA().then(() => { await this.fixtureA();
return this.models.Product.findAll({
const products = await this.models.Product.findAll({
include: [ include: [
{ model: this.models.Company }, { model: this.models.Company },
{ model: this.models.Tag }, { model: this.models.Tag },
...@@ -1509,7 +1508,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1509,7 +1508,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: [ order: [
['id', 'ASC'] ['id', 'ASC']
] ]
}).then(products => { });
expect(products.length).to.equal(6); expect(products.length).to.equal(6);
products.forEach(product => { products.forEach(product => {
...@@ -1521,12 +1521,11 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1521,12 +1521,11 @@ describe(Support.getTestDialectTeaser('Include'), () => {
}); });
}); });
}); });
});
});
it('should be possible to use limit and a where on a hasMany with a through model with additional includes', function() { it('should be possible to use limit and a where on a hasMany with a through model with additional includes', async function() {
return this.fixtureA().then(() => { await this.fixtureA();
return this.models.Product.findAll({
const products = await this.models.Product.findAll({
include: [ include: [
{ model: this.models.Company }, { model: this.models.Company },
{ model: this.models.Tag, where: { name: ['A', 'B', 'C'] } }, { model: this.models.Tag, where: { name: ['A', 'B', 'C'] } },
...@@ -1536,7 +1535,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1536,7 +1535,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: [ order: [
['id', 'ASC'] ['id', 'ASC']
] ]
}).then(products => { });
expect(products.length).to.equal(10); expect(products.length).to.equal(10);
products.forEach(product => { products.forEach(product => {
...@@ -1548,10 +1548,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1548,10 +1548,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
}); });
}); });
}); });
});
});
it('should support including date fields, with the correct timeszone', function() { it('should support including date fields, with the correct timeszone', async function() {
const User = this.sequelize.define('user', { const User = this.sequelize.define('user', {
dateField: Sequelize.DATE dateField: Sequelize.DATE
}, { timestamps: false }), }, { timestamps: false }),
...@@ -1562,54 +1560,48 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1562,54 +1560,48 @@ describe(Support.getTestDialectTeaser('Include'), () => {
User.belongsToMany(Group, { through: 'group_user' }); User.belongsToMany(Group, { through: 'group_user' });
Group.belongsToMany(User, { through: 'group_user' }); Group.belongsToMany(User, { through: 'group_user' });
return this.sequelize.sync().then(() => { await this.sequelize.sync();
return User.create({ dateField: Date.UTC(2014, 1, 20) }).then(user => { const user = await User.create({ dateField: Date.UTC(2014, 1, 20) });
return Group.create({ dateField: Date.UTC(2014, 1, 20) }).then(group => { const group = await Group.create({ dateField: Date.UTC(2014, 1, 20) });
return user.addGroup(group).then(() => { await user.addGroup(group);
return User.findAll({
const users = await User.findAll({
where: { where: {
id: user.id id: user.id
}, },
include: [Group] include: [Group]
}).then(users => { });
expect(users[0].dateField.getTime()).to.equal(Date.UTC(2014, 1, 20)); expect(users[0].dateField.getTime()).to.equal(Date.UTC(2014, 1, 20));
expect(users[0].groups[0].dateField.getTime()).to.equal(Date.UTC(2014, 1, 20)); expect(users[0].groups[0].dateField.getTime()).to.equal(Date.UTC(2014, 1, 20));
}); });
});
});
});
});
});
it('should still pull the main record(s) when an included model is not required and has where restrictions without matches', function() { it('should still pull the main record(s) when an included model is not required and has where restrictions without matches', async function() {
const A = this.sequelize.define('a', { name: DataTypes.STRING(40) }), const A = this.sequelize.define('a', { name: DataTypes.STRING(40) }),
B = this.sequelize.define('b', { name: DataTypes.STRING(40) }); B = this.sequelize.define('b', { name: DataTypes.STRING(40) });
A.belongsToMany(B, { through: 'a_b' }); A.belongsToMany(B, { through: 'a_b' });
B.belongsToMany(A, { through: 'a_b' }); B.belongsToMany(A, { through: 'a_b' });
return this.sequelize await this.sequelize
.sync({ force: true }) .sync({ force: true });
.then(() => {
return A.create({ await A.create({
name: 'Foobar' name: 'Foobar'
}); });
})
.then(() => { const as = await A.findAll({
return A.findAll({
where: { name: 'Foobar' }, where: { name: 'Foobar' },
include: [ include: [
{ model: B, where: { name: 'idontexist' }, required: false } { model: B, where: { name: 'idontexist' }, required: false }
] ]
}); });
})
.then(as => {
expect(as.length).to.equal(1); expect(as.length).to.equal(1);
expect(as[0].get('bs')).deep.equal([]); expect(as[0].get('bs')).deep.equal([]);
}); });
});
it('should work with paranoid, a main record where, an include where, and a limit', function() { it('should work with paranoid, a main record where, an include where, and a limit', async function() {
const Post = this.sequelize.define('post', { const Post = this.sequelize.define('post', {
date: DataTypes.DATE, date: DataTypes.DATE,
'public': DataTypes.BOOLEAN 'public': DataTypes.BOOLEAN
...@@ -1623,18 +1615,20 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1623,18 +1615,20 @@ describe(Support.getTestDialectTeaser('Include'), () => {
Post.hasMany(Category); Post.hasMany(Category);
Category.belongsTo(Post); Category.belongsTo(Post);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([
const posts0 = await Promise.all([
Post.create({ 'public': true }), Post.create({ 'public': true }),
Post.create({ 'public': true }), Post.create({ 'public': true }),
Post.create({ 'public': true }), Post.create({ 'public': true }),
Post.create({ 'public': true }) Post.create({ 'public': true })
]).then(posts => { ]);
return Promise.all(posts.slice(1, 3).map(post => {
await Promise.all(posts0.slice(1, 3).map(post => {
return post.createCategory({ slug: 'food' }); return post.createCategory({ slug: 'food' });
})); }));
}).then(() => {
return Post.findAll({ const posts = await Post.findAll({
limit: 2, limit: 2,
where: { where: {
'public': true 'public': true
...@@ -1647,14 +1641,12 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1647,14 +1641,12 @@ describe(Support.getTestDialectTeaser('Include'), () => {
} }
} }
] ]
}).then(posts => {
expect(posts.length).to.equal(2);
});
});
}); });
expect(posts.length).to.equal(2);
}); });
it('should work on a nested set of required 1:1 relations', function() { it('should work on a nested set of required 1:1 relations', async function() {
const Person = this.sequelize.define('Person', { const Person = this.sequelize.define('Person', {
name: { name: {
type: Sequelize.STRING, type: Sequelize.STRING,
...@@ -1714,8 +1706,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1714,8 +1706,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
onDelete: 'CASCADE' onDelete: 'CASCADE'
}); });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Person.findAll({
await Person.findAll({
offset: 0, offset: 0,
limit: 20, limit: 20,
attributes: ['id', 'name'], attributes: ['id', 'name'],
...@@ -1731,9 +1724,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1731,9 +1724,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
}] }]
}); });
}); });
});
it('should work with an empty include.where', function() { it('should work with an empty include.where', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
Company = this.sequelize.define('Company', {}), Company = this.sequelize.define('Company', {}),
Group = this.sequelize.define('Group', {}); Group = this.sequelize.define('Group', {});
...@@ -1742,17 +1734,17 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1742,17 +1734,17 @@ describe(Support.getTestDialectTeaser('Include'), () => {
User.belongsToMany(Group, { through: 'UsersGroups' }); User.belongsToMany(Group, { through: 'UsersGroups' });
Group.belongsToMany(User, { through: 'UsersGroups' }); Group.belongsToMany(User, { through: 'UsersGroups' });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return User.findAll({
await User.findAll({
include: [ include: [
{ model: Group, where: {} }, { model: Group, where: {} },
{ model: Company, where: {} } { model: Company, where: {} }
] ]
}); });
}); });
});
it('should be able to order on the main table and a required belongsTo relation with custom tablenames and limit ', function() { it('should be able to order on the main table and a required belongsTo relation with custom tablenames and limit ', async function() {
const User = this.sequelize.define('User', { const User = this.sequelize.define('User', {
lastName: DataTypes.STRING lastName: DataTypes.STRING
}, { tableName: 'dem_users' }); }, { tableName: 'dem_users' });
...@@ -1763,21 +1755,23 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1763,21 +1755,23 @@ describe(Support.getTestDialectTeaser('Include'), () => {
User.belongsTo(Company); User.belongsTo(Company);
Company.hasMany(User); Company.hasMany(User);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([
const [albertsen, zenith, hansen, company1, company2] = await Promise.all([
User.create({ lastName: 'Albertsen' }), User.create({ lastName: 'Albertsen' }),
User.create({ lastName: 'Zenith' }), User.create({ lastName: 'Zenith' }),
User.create({ lastName: 'Hansen' }), User.create({ lastName: 'Hansen' }),
Company.create({ rank: 1 }), Company.create({ rank: 1 }),
Company.create({ rank: 2 }) Company.create({ rank: 2 })
]).then(([albertsen, zenith, hansen, company1, company2]) => { ]);
return Promise.all([
await Promise.all([
albertsen.setCompany(company1), albertsen.setCompany(company1),
zenith.setCompany(company2), zenith.setCompany(company2),
hansen.setCompany(company2) hansen.setCompany(company2)
]); ]);
}).then(() => {
return User.findAll({ const users = await User.findAll({
include: [ include: [
{ model: Company, required: true } { model: Company, required: true }
], ],
...@@ -1786,7 +1780,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1786,7 +1780,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
['lastName', 'DESC'] ['lastName', 'DESC']
], ],
limit: 5 limit: 5
}).then(users => { });
expect(users[0].lastName).to.equal('Albertsen'); expect(users[0].lastName).to.equal('Albertsen');
expect(users[0].Company.rank).to.equal(1); expect(users[0].Company.rank).to.equal(1);
...@@ -1796,11 +1791,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1796,11 +1791,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
expect(users[2].lastName).to.equal('Hansen'); expect(users[2].lastName).to.equal('Hansen');
expect(users[2].Company.rank).to.equal(2); expect(users[2].Company.rank).to.equal(2);
}); });
});
});
});
it('should ignore include with attributes: [] (used for aggregates)', function() { it('should ignore include with attributes: [] (used for aggregates)', async function() {
const Post = this.sequelize.define('Post', { const Post = this.sequelize.define('Post', {
title: DataTypes.STRING title: DataTypes.STRING
}), }),
...@@ -1810,8 +1802,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1810,8 +1802,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
Post.Comments = Post.hasMany(Comment, { as: 'comments' }); Post.Comments = Post.hasMany(Comment, { as: 'comments' });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Post.create({
await Post.create({
title: Math.random().toString(), title: Math.random().toString(),
comments: [ comments: [
{ content: Math.random().toString() }, { content: Math.random().toString() },
...@@ -1821,8 +1814,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1821,8 +1814,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
}, { }, {
include: [Post.Comments] include: [Post.Comments]
}); });
}).then(() => {
return Post.findAll({ const posts = await Post.findAll({
attributes: [ attributes: [
[this.sequelize.fn('COUNT', this.sequelize.col('comments.id')), 'commentCount'] [this.sequelize.fn('COUNT', this.sequelize.col('comments.id')), 'commentCount']
], ],
...@@ -1833,7 +1826,7 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1833,7 +1826,7 @@ describe(Support.getTestDialectTeaser('Include'), () => {
'Post.id' 'Post.id'
] ]
}); });
}).then(posts => {
expect(posts.length).to.equal(1); expect(posts.length).to.equal(1);
const post = posts[0]; const post = posts[0];
...@@ -1841,9 +1834,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1841,9 +1834,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
expect(post.get('comments')).not.to.be.ok; expect(post.get('comments')).not.to.be.ok;
expect(parseInt(post.get('commentCount'), 10)).to.equal(3); expect(parseInt(post.get('commentCount'), 10)).to.equal(3);
}); });
});
it('should not add primary key when including and aggregating with raw: true', function() { it('should not add primary key when including and aggregating with raw: true', async function() {
const Post = this.sequelize.define('Post', { const Post = this.sequelize.define('Post', {
title: DataTypes.STRING title: DataTypes.STRING
}), }),
...@@ -1853,8 +1845,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1853,8 +1845,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
Post.Comments = Post.hasMany(Comment, { as: 'comments' }); Post.Comments = Post.hasMany(Comment, { as: 'comments' });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Post.create({
await Post.create({
title: Math.random().toString(), title: Math.random().toString(),
comments: [ comments: [
{ content: Math.random().toString() }, { content: Math.random().toString() },
...@@ -1864,8 +1857,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1864,8 +1857,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
}, { }, {
include: [Post.Comments] include: [Post.Comments]
}); });
}).then(() => {
return Post.findAll({ const posts = await Post.findAll({
attributes: [], attributes: [],
include: [ include: [
{ {
...@@ -1875,17 +1868,15 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1875,17 +1868,15 @@ describe(Support.getTestDialectTeaser('Include'), () => {
], ],
raw: true raw: true
}); });
}).then(posts => {
expect(posts.length).to.equal(1); expect(posts.length).to.equal(1);
const post = posts[0]; const post = posts[0];
expect(post.id).not.to.be.ok; expect(post.id).not.to.be.ok;
expect(parseInt(post['comments.commentCount'], 10)).to.equal(3); expect(parseInt(post['comments.commentCount'], 10)).to.equal(3);
}); });
});
it('Should return posts with nested include with inner join with a m:n association', function() {
it('Should return posts with nested include with inner join with a m:n association', async function() {
const User = this.sequelize.define('User', { const User = this.sequelize.define('User', {
username: { username: {
type: DataTypes.STRING, type: DataTypes.STRING,
...@@ -1942,15 +1933,17 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1942,15 +1933,17 @@ describe(Support.getTestDialectTeaser('Include'), () => {
otherKey: 'entity_id' otherKey: 'entity_id'
}); });
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => User.create({ username: 'bob' })) await User.create({ username: 'bob' });
.then(() => TaggableSentient.create({ nametag: 'bob' })) await TaggableSentient.create({ nametag: 'bob' });
.then(() => Entity.create({ creator: 'bob' })) const entity = await Entity.create({ creator: 'bob' });
.then(entity => Promise.all([
await Promise.all([
Post.create({ post_id: entity.entity_id }), Post.create({ post_id: entity.entity_id }),
entity.addTags('bob') entity.addTags('bob')
])) ]);
.then(() => Post.findAll({
const posts = await Post.findAll({
include: [{ include: [{
model: Entity, model: Entity,
required: true, required: true,
...@@ -1970,17 +1963,16 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1970,17 +1963,16 @@ describe(Support.getTestDialectTeaser('Include'), () => {
}], }],
limit: 5, limit: 5,
offset: 0 offset: 0
})) });
.then(posts => {
expect(posts.length).to.equal(1); expect(posts.length).to.equal(1);
expect(posts[0].Entity.creator).to.equal('bob'); expect(posts[0].Entity.creator).to.equal('bob');
expect(posts[0].Entity.tags.length).to.equal(1); expect(posts[0].Entity.tags.length).to.equal(1);
expect(posts[0].Entity.tags[0].EntityTag.tag_name).to.equal('bob'); expect(posts[0].Entity.tags[0].EntityTag.tag_name).to.equal('bob');
expect(posts[0].Entity.tags[0].EntityTag.entity_id).to.equal(posts[0].post_id); expect(posts[0].Entity.tags[0].EntityTag.entity_id).to.equal(posts[0].post_id);
}); });
});
it('should be able to generate a correct request with inner and outer join', function() { it('should be able to generate a correct request with inner and outer join', async function() {
const Customer = this.sequelize.define('customer', { const Customer = this.sequelize.define('customer', {
name: DataTypes.STRING name: DataTypes.STRING
}); });
...@@ -2007,8 +1999,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -2007,8 +1999,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
Shipment.belongsTo(Order); Shipment.belongsTo(Order);
Order.hasOne(Shipment); Order.hasOne(Shipment);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Shipment.findOne({
await Shipment.findOne({
include: [{ include: [{
model: Order, model: Order,
required: true, required: true,
...@@ -2022,18 +2015,19 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -2022,18 +2015,19 @@ describe(Support.getTestDialectTeaser('Include'), () => {
}] }]
}); });
}); });
});
it('should be able to generate a correct request for entity with 1:n and m:1 associations and limit', function() { it('should be able to generate a correct request for entity with 1:n and m:1 associations and limit', async function() {
return this.fixtureA().then(() => { await this.fixtureA();
return this.models.Product.findAll({
const products = await this.models.Product.findAll({
attributes: ['title'], attributes: ['title'],
include: [ include: [
{ model: this.models.User }, { model: this.models.User },
{ model: this.models.Price } { model: this.models.Price }
], ],
limit: 10 limit: 10
}).then( products => { });
expect(products).to.be.an('array'); expect(products).to.be.an('array');
expect(products).to.be.lengthOf(10); expect(products).to.be.lengthOf(10);
for (const product of products) { for (const product of products) {
...@@ -2046,6 +2040,4 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -2046,6 +2040,4 @@ describe(Support.getTestDialectTeaser('Include'), () => {
} }
}); });
}); });
});
});
}); });
...@@ -17,7 +17,7 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -17,7 +17,7 @@ describe(Support.getTestDialectTeaser('Include'), () => {
}); });
describe('findAndCountAll', () => { describe('findAndCountAll', () => {
it('should be able to include two required models with a limit. Result rows should match limit.', function() { it('should be able to include two required models with a limit. Result rows should match limit.', async function() {
const Project = this.sequelize.define('Project', { id: { type: DataTypes.INTEGER, primaryKey: true }, name: DataTypes.STRING(40) }), const Project = this.sequelize.define('Project', { id: { type: DataTypes.INTEGER, primaryKey: true }, name: DataTypes.STRING(40) }),
Task = this.sequelize.define('Task', { name: DataTypes.STRING(40), fk: DataTypes.INTEGER }), Task = this.sequelize.define('Task', { name: DataTypes.STRING(40), fk: DataTypes.INTEGER }),
Employee = this.sequelize.define('Employee', { name: DataTypes.STRING(40), fk: DataTypes.INTEGER }); Employee = this.sequelize.define('Employee', { name: DataTypes.STRING(40), fk: DataTypes.INTEGER });
...@@ -29,9 +29,10 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -29,9 +29,10 @@ describe(Support.getTestDialectTeaser('Include'), () => {
Employee.belongsTo(Project, { foreignKey: 'fk', constraints: false }); Employee.belongsTo(Project, { foreignKey: 'fk', constraints: false });
// Sync them // Sync them
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
// Create an enviroment // Create an enviroment
return Promise.all([Project.bulkCreate([ await Promise.all([Project.bulkCreate([
{ id: 1, name: 'No tasks' }, { id: 1, name: 'No tasks' },
{ id: 2, name: 'No tasks no employees' }, { id: 2, name: 'No tasks no employees' },
{ id: 3, name: 'No employees' }, { id: 3, name: 'No employees' },
...@@ -48,12 +49,13 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -48,12 +49,13 @@ describe(Support.getTestDialectTeaser('Include'), () => {
{ name: 'John Doe', fk: 4 }, { name: 'John Doe', fk: 4 },
{ name: 'Jane John Doe', fk: 5 }, { name: 'Jane John Doe', fk: 5 },
{ name: 'John Jane Doe', fk: 6 } { name: 'John Jane Doe', fk: 6 }
])]).then(() =>{ ])]);
//Find all projects with tasks and employees //Find all projects with tasks and employees
const availableProjects = 3; const availableProjects = 3;
const limit = 2; const limit = 2;
return Project.findAndCountAll({ const result = await Project.findAndCountAll({
include: [{ include: [{
model: Task, required: true model: Task, required: true
}, },
...@@ -61,15 +63,13 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -61,15 +63,13 @@ describe(Support.getTestDialectTeaser('Include'), () => {
model: Employee, required: true model: Employee, required: true
}], }],
limit limit
}).then(result => { });
expect(result.count).to.be.equal(availableProjects); expect(result.count).to.be.equal(availableProjects);
expect(result.rows.length).to.be.equal(limit, 'Complete set of available rows were not returned.'); expect(result.rows.length).to.be.equal(limit, 'Complete set of available rows were not returned.');
}); });
});
});
});
it('should be able to include a required model. Result rows should match count', function() { it('should be able to include a required model. Result rows should match count', async function() {
const User = this.sequelize.define('User', { name: DataTypes.STRING(40) }, { paranoid: true }), const User = this.sequelize.define('User', { name: DataTypes.STRING(40) }, { paranoid: true }),
SomeConnection = this.sequelize.define('SomeConnection', { SomeConnection = this.sequelize.define('SomeConnection', {
m: DataTypes.STRING(40), m: DataTypes.STRING(40),
...@@ -93,10 +93,11 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -93,10 +93,11 @@ describe(Support.getTestDialectTeaser('Include'), () => {
C.hasMany(SomeConnection, { foreignKey: 'fk', constraints: false }); C.hasMany(SomeConnection, { foreignKey: 'fk', constraints: false });
// Sync them // Sync them
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
// Create an enviroment // Create an enviroment
return Promise.all([User.bulkCreate([ await Promise.all([User.bulkCreate([
{ name: 'Youtube' }, { name: 'Youtube' },
{ name: 'Facebook' }, { name: 'Facebook' },
{ name: 'Google' }, { name: 'Google' },
...@@ -138,16 +139,19 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -138,16 +139,19 @@ describe(Support.getTestDialectTeaser('Include'), () => {
{ name: 'be loaded' } { name: 'be loaded' }
]), C.bulkCreate([ ]), C.bulkCreate([
{ name: 'because we only want A' } { name: 'because we only want A' }
])]).then(() => { ])]);
// Delete some of conns to prove the concept // Delete some of conns to prove the concept
return SomeConnection.destroy({ where: { await SomeConnection.destroy({ where: {
m: 'A', m: 'A',
u: 1, u: 1,
fk: [1, 2] fk: [1, 2]
} }).then(() => { } });
this.clock.tick(1000); this.clock.tick(1000);
// Last and most important queries ( we connected 4, but deleted 2, witch means we must get 2 only ) // Last and most important queries ( we connected 4, but deleted 2, witch means we must get 2 only )
return A.findAndCountAll({ const result = await A.findAndCountAll({
include: [{ include: [{
model: SomeConnection, required: true, model: SomeConnection, required: true,
where: { where: {
...@@ -156,16 +160,13 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -156,16 +160,13 @@ describe(Support.getTestDialectTeaser('Include'), () => {
} }
}], }],
limit: 5 limit: 5
}).then(result => { });
expect(result.count).to.be.equal(2); expect(result.count).to.be.equal(2);
expect(result.rows.length).to.be.equal(2); expect(result.rows.length).to.be.equal(2);
}); });
});
});
});
});
it('should count on a where and not use an uneeded include', function() { it('should count on a where and not use an uneeded include', async function() {
const Project = this.sequelize.define('Project', { const Project = this.sequelize.define('Project', {
id: { type: DataTypes.INTEGER, allowNull: false, primaryKey: true, autoIncrement: true }, id: { type: DataTypes.INTEGER, allowNull: false, primaryKey: true, autoIncrement: true },
project_name: { type: DataTypes.STRING } project_name: { type: DataTypes.STRING }
...@@ -180,28 +181,25 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -180,28 +181,25 @@ describe(Support.getTestDialectTeaser('Include'), () => {
let userId = null; let userId = null;
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return Project.sync({ force: true }); await Project.sync({ force: true });
}).then(() => { const results = await Promise.all([User.create(), Project.create(), Project.create(), Project.create()]);
return Promise.all([User.create(), Project.create(), Project.create(), Project.create()]);
}).then(results => {
const user = results[0]; const user = results[0];
userId = user.id; userId = user.id;
return user.setProjects([results[1], results[2], results[3]]); await user.setProjects([results[1], results[2], results[3]]);
}).then(() => {
return User.findAndCountAll({ const result = await User.findAndCountAll({
where: { id: userId }, where: { id: userId },
include: [Project], include: [Project],
distinct: true distinct: true
}); });
}).then(result => {
expect(result.rows.length).to.equal(1); expect(result.rows.length).to.equal(1);
expect(result.rows[0].Projects.length).to.equal(3); expect(result.rows[0].Projects.length).to.equal(3);
expect(result.count).to.equal(1); expect(result.count).to.equal(1);
}); });
});
it('should return the correct count and rows when using a required belongsTo and a limit', function() { it('should return the correct count and rows when using a required belongsTo and a limit', async function() {
const s = this.sequelize, const s = this.sequelize,
Foo = s.define('Foo', {}), Foo = s.define('Foo', {}),
Bar = s.define('Bar', {}); Bar = s.define('Bar', {});
...@@ -209,63 +207,60 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -209,63 +207,60 @@ describe(Support.getTestDialectTeaser('Include'), () => {
Foo.hasMany(Bar); Foo.hasMany(Bar);
Bar.belongsTo(Foo); Bar.belongsTo(Foo);
return s.sync({ force: true }).then(() => { await s.sync({ force: true });
// Make five instances of Foo // Make five instances of Foo
return Foo.bulkCreate([{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }]); await Foo.bulkCreate([{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }]);
}).then(() => {
// Make four instances of Bar, related to the last four instances of Foo // Make four instances of Bar, related to the last four instances of Foo
return Bar.bulkCreate([{ 'FooId': 2 }, { 'FooId': 3 }, { 'FooId': 4 }, { 'FooId': 5 }]); await Bar.bulkCreate([{ 'FooId': 2 }, { 'FooId': 3 }, { 'FooId': 4 }, { 'FooId': 5 }]);
}).then(() => {
// Query for the first two instances of Foo which have related Bars // Query for the first two instances of Foo which have related Bars
return Foo.findAndCountAll({ const result0 = await Foo.findAndCountAll({
include: [{ model: Bar, required: true }], include: [{ model: Bar, required: true }],
limit: 2 limit: 2
}).then(result => { });
return Promise.resolve(Foo.findAll({
const items = await Foo.findAll({
include: [{ model: Bar, required: true }], include: [{ model: Bar, required: true }],
limit: 2 limit: 2
}).then(items => {
expect(items.length).to.equal(2);
})).then(() => result);
}); });
}).then(result => {
expect(items.length).to.equal(2);
const result = result0;
expect(result.count).to.equal(4); expect(result.count).to.equal(4);
// The first two of those should be returned due to the limit (Foo // The first two of those should be returned due to the limit (Foo
// instances 2 and 3) // instances 2 and 3)
expect(result.rows.length).to.equal(2); expect(result.rows.length).to.equal(2);
}); });
});
it('should return the correct count and rows when using a required belongsTo with a where condition and a limit', function() { it('should return the correct count and rows when using a required belongsTo with a where condition and a limit', async function() {
const Foo = this.sequelize.define('Foo', {}), const Foo = this.sequelize.define('Foo', {}),
Bar = this.sequelize.define('Bar', { m: DataTypes.STRING(40) }); Bar = this.sequelize.define('Bar', { m: DataTypes.STRING(40) });
Foo.hasMany(Bar); Foo.hasMany(Bar);
Bar.belongsTo(Foo); Bar.belongsTo(Foo);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Foo.bulkCreate([{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }]); await Foo.bulkCreate([{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }]);
}).then(() => {
// Make four instances of Bar, related to the first two instances of Foo // Make four instances of Bar, related to the first two instances of Foo
return Bar.bulkCreate([{ 'FooId': 1, m: 'yes' }, { 'FooId': 1, m: 'yes' }, { 'FooId': 1, m: 'no' }, { 'FooId': 2, m: 'yes' }]); await Bar.bulkCreate([{ 'FooId': 1, m: 'yes' }, { 'FooId': 1, m: 'yes' }, { 'FooId': 1, m: 'no' }, { 'FooId': 2, m: 'yes' }]);
}).then(() => {
// Query for the first instance of Foo which have related Bars with m === 'yes' // Query for the first instance of Foo which have related Bars with m === 'yes'
return Foo.findAndCountAll({ const result = await Foo.findAndCountAll({
include: [{ model: Bar, where: { m: 'yes' } }], include: [{ model: Bar, where: { m: 'yes' } }],
limit: 1, limit: 1,
distinct: true distinct: true
}); });
}).then(result => {
// There should be 2 instances matching the query (Instances 1 and 2), see the findAll statement // There should be 2 instances matching the query (Instances 1 and 2), see the findAll statement
expect(result.count).to.equal(2); expect(result.count).to.equal(2);
// The first one of those should be returned due to the limit (Foo instance 1) // The first one of those should be returned due to the limit (Foo instance 1)
expect(result.rows.length).to.equal(1); expect(result.rows.length).to.equal(1);
}); });
});
it('should correctly filter, limit and sort when multiple includes and types of associations are present.', function() { it('should correctly filter, limit and sort when multiple includes and types of associations are present.', async function() {
const TaskTag = this.sequelize.define('TaskTag', { const TaskTag = this.sequelize.define('TaskTag', {
id: { type: DataTypes.INTEGER, allowNull: false, primaryKey: true, autoIncrement: true }, id: { type: DataTypes.INTEGER, allowNull: false, primaryKey: true, autoIncrement: true },
name: { type: DataTypes.STRING } name: { type: DataTypes.STRING }
...@@ -293,28 +288,30 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -293,28 +288,30 @@ describe(Support.getTestDialectTeaser('Include'), () => {
Project.belongsTo(User); Project.belongsTo(User);
Task.belongsTo(Project); Task.belongsTo(Project);
Task.belongsToMany(Tag, { through: TaskTag }); Task.belongsToMany(Tag, { through: TaskTag });
// Sync them // Sync them
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
// Create an enviroment // Create an enviroment
return User.bulkCreate([ await User.bulkCreate([
{ name: 'user-name-1' }, { name: 'user-name-1' },
{ name: 'user-name-2' } { name: 'user-name-2' }
]).then(() => { ]);
return Project.bulkCreate([
await Project.bulkCreate([
{ m: 'A', UserId: 1 }, { m: 'A', UserId: 1 },
{ m: 'A', UserId: 2 } { m: 'A', UserId: 2 }
]); ]);
}).then(() => {
return Task.bulkCreate([ await Task.bulkCreate([
{ ProjectId: 1, name: 'Just' }, { ProjectId: 1, name: 'Just' },
{ ProjectId: 1, name: 'for' }, { ProjectId: 1, name: 'for' },
{ ProjectId: 2, name: 'testing' }, { ProjectId: 2, name: 'testing' },
{ ProjectId: 2, name: 'proposes' } { ProjectId: 2, name: 'proposes' }
]); ]);
})
.then(() => {
// Find All Tasks with Project(m=a) and User(name=user-name-2) // Find All Tasks with Project(m=a) and User(name=user-name-2)
return Task.findAndCountAll({ const result = await Task.findAndCountAll({
limit: 1, limit: 1,
offset: 0, offset: 0,
order: [['id', 'DESC']], order: [['id', 'DESC']],
...@@ -331,14 +328,12 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -331,14 +328,12 @@ describe(Support.getTestDialectTeaser('Include'), () => {
{ model: Tag } { model: Tag }
] ]
}); });
});
}).then(result => {
expect(result.count).to.equal(2); expect(result.count).to.equal(2);
expect(result.rows.length).to.equal(1); expect(result.rows.length).to.equal(1);
}); });
});
it('should properly work with sequelize.function', function() { it('should properly work with sequelize.function', async function() {
const sequelize = this.sequelize; const sequelize = this.sequelize;
const User = this.sequelize.define('User', { const User = this.sequelize.define('User', {
id: { type: DataTypes.INTEGER, allowNull: false, primaryKey: true, autoIncrement: true }, id: { type: DataTypes.INTEGER, allowNull: false, primaryKey: true, autoIncrement: true },
...@@ -353,20 +348,21 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -353,20 +348,21 @@ describe(Support.getTestDialectTeaser('Include'), () => {
User.hasMany(Project); User.hasMany(Project);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return User.bulkCreate([
await User.bulkCreate([
{ first_name: 'user-fname-1', last_name: 'user-lname-1' }, { first_name: 'user-fname-1', last_name: 'user-lname-1' },
{ first_name: 'user-fname-2', last_name: 'user-lname-2' }, { first_name: 'user-fname-2', last_name: 'user-lname-2' },
{ first_name: 'user-xfname-1', last_name: 'user-xlname-1' } { first_name: 'user-xfname-1', last_name: 'user-xlname-1' }
]); ]);
}).then(() => {
return Project.bulkCreate([ await Project.bulkCreate([
{ name: 'naam-satya', UserId: 1 }, { name: 'naam-satya', UserId: 1 },
{ name: 'guru-satya', UserId: 2 }, { name: 'guru-satya', UserId: 2 },
{ name: 'app-satya', UserId: 2 } { name: 'app-satya', UserId: 2 }
]); ]);
}).then(() => {
return User.findAndCountAll({ const result = await User.findAndCountAll({
limit: 1, limit: 1,
offset: 1, offset: 1,
where: sequelize.or( where: sequelize.or(
...@@ -383,11 +379,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -383,11 +379,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
} }
] ]
}); });
}).then(result => {
expect(result.count).to.equal(2); expect(result.count).to.equal(2);
expect(result.rows.length).to.equal(1); expect(result.rows.length).to.equal(1);
}); });
});
}); });
}); });
...@@ -9,7 +9,7 @@ const chai = require('chai'), ...@@ -9,7 +9,7 @@ const chai = require('chai'),
describe(Support.getTestDialectTeaser('Include'), () => { describe(Support.getTestDialectTeaser('Include'), () => {
describe('findOne', () => { describe('findOne', () => {
it('should include a non required model, with conditions and two includes N:M 1:M', function( ) { it('should include a non required model, with conditions and two includes N:M 1:M', async function() {
const A = this.sequelize.define('A', { name: DataTypes.STRING(40) }, { paranoid: true }), const A = this.sequelize.define('A', { name: DataTypes.STRING(40) }, { paranoid: true }),
B = this.sequelize.define('B', { name: DataTypes.STRING(40) }, { paranoid: true }), B = this.sequelize.define('B', { name: DataTypes.STRING(40) }, { paranoid: true }),
C = this.sequelize.define('C', { name: DataTypes.STRING(40) }, { paranoid: true }), C = this.sequelize.define('C', { name: DataTypes.STRING(40) }, { paranoid: true }),
...@@ -29,8 +29,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -29,8 +29,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
D.hasMany(B); D.hasMany(B);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return A.findOne({
await A.findOne({
include: [ include: [
{ model: B, required: false, include: [ { model: B, required: false, include: [
{ model: C, required: false }, { model: C, required: false },
...@@ -39,9 +40,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -39,9 +40,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
] ]
}); });
}); });
});
it('should work with a 1:M to M:1 relation with a where on the last include', function() { it('should work with a 1:M to M:1 relation with a where on the last include', async function() {
const Model = this.sequelize.define('Model', {}); const Model = this.sequelize.define('Model', {});
const Model2 = this.sequelize.define('Model2', {}); const Model2 = this.sequelize.define('Model2', {});
const Model4 = this.sequelize.define('Model4', { something: { type: DataTypes.INTEGER } }); const Model4 = this.sequelize.define('Model4', { something: { type: DataTypes.INTEGER } });
...@@ -52,8 +52,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -52,8 +52,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
Model2.hasMany(Model4); Model2.hasMany(Model4);
Model4.belongsTo(Model2); Model4.belongsTo(Model2);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Model.findOne({
await Model.findOne({
include: [ include: [
{ model: Model2, include: [ { model: Model2, include: [
{ model: Model4, where: { something: 2 } } { model: Model4, where: { something: 2 } }
...@@ -61,9 +62,8 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -61,9 +62,8 @@ describe(Support.getTestDialectTeaser('Include'), () => {
] ]
}); });
}); });
});
it('should include a model with a where condition but no required', function() { it('should include a model with a where condition but no required', async function() {
const User = this.sequelize.define('User', {}, { paranoid: false }), const User = this.sequelize.define('User', {}, { paranoid: false }),
Task = this.sequelize.define('Task', { Task = this.sequelize.define('Task', {
deletedAt: { deletedAt: {
...@@ -74,29 +74,29 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -74,29 +74,29 @@ describe(Support.getTestDialectTeaser('Include'), () => {
User.hasMany(Task, { foreignKey: 'userId' }); User.hasMany(Task, { foreignKey: 'userId' });
Task.belongsTo(User, { foreignKey: 'userId' }); Task.belongsTo(User, { foreignKey: 'userId' });
return this.sequelize.sync({ await this.sequelize.sync({
force: true force: true
}).then(() => { });
return User.create();
}).then(user => { const user0 = await User.create();
return Task.bulkCreate([
{ userId: user.get('id'), deletedAt: new Date() }, await Task.bulkCreate([
{ userId: user.get('id'), deletedAt: new Date() }, { userId: user0.get('id'), deletedAt: new Date() },
{ userId: user.get('id'), deletedAt: new Date() } { userId: user0.get('id'), deletedAt: new Date() },
{ userId: user0.get('id'), deletedAt: new Date() }
]); ]);
}).then(() => {
return User.findOne({ const user = await User.findOne({
include: [ include: [
{ model: Task, where: { deletedAt: null }, required: false } { model: Task, where: { deletedAt: null }, required: false }
] ]
}); });
}).then(user => {
expect(user).to.be.ok; expect(user).to.be.ok;
expect(user.Tasks.length).to.equal(0); expect(user.Tasks.length).to.equal(0);
}); });
});
it('should include a model with a where clause when the PK field name and attribute name are different', function() { it('should include a model with a where clause when the PK field name and attribute name are different', async function() {
const User = this.sequelize.define('User', { const User = this.sequelize.define('User', {
id: { id: {
type: DataTypes.UUID, type: DataTypes.UUID,
...@@ -112,28 +112,28 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -112,28 +112,28 @@ describe(Support.getTestDialectTeaser('Include'), () => {
User.hasMany(Task, { foreignKey: 'userId' }); User.hasMany(Task, { foreignKey: 'userId' });
Task.belongsTo(User, { foreignKey: 'userId' }); Task.belongsTo(User, { foreignKey: 'userId' });
return this.sequelize.sync({ await this.sequelize.sync({
force: true force: true
}).then(() => { });
return User.create();
}).then(user => { const user0 = await User.create();
return Task.bulkCreate([
{ userId: user.get('id'), searchString: 'one' }, await Task.bulkCreate([
{ userId: user.get('id'), searchString: 'two' } { userId: user0.get('id'), searchString: 'one' },
{ userId: user0.get('id'), searchString: 'two' }
]); ]);
}).then(() => {
return User.findOne({ const user = await User.findOne({
include: [ include: [
{ model: Task, where: { searchString: 'one' } } { model: Task, where: { searchString: 'one' } }
] ]
}); });
}).then(user => {
expect(user).to.be.ok; expect(user).to.be.ok;
expect(user.Tasks.length).to.equal(1); expect(user.Tasks.length).to.equal(1);
}); });
});
it('should include a model with a through.where and required true clause when the PK field name and attribute name are different', function() { it('should include a model with a through.where and required true clause when the PK field name and attribute name are different', async function() {
const A = this.sequelize.define('a', {}), const A = this.sequelize.define('a', {}),
B = this.sequelize.define('b', {}), B = this.sequelize.define('b', {}),
AB = this.sequelize.define('a_b', { AB = this.sequelize.define('a_b', {
...@@ -147,29 +147,24 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -147,29 +147,24 @@ describe(Support.getTestDialectTeaser('Include'), () => {
A.belongsToMany(B, { through: AB }); A.belongsToMany(B, { through: AB });
B.belongsToMany(A, { through: AB }); B.belongsToMany(A, { through: AB });
return this.sequelize await this.sequelize
.sync({ force: true }) .sync({ force: true });
.then(() => {
return Promise.all([A.create({}), B.create({})]); const [a0, b] = await Promise.all([A.create({}), B.create({})]);
}) await a0.addB(b, { through: { name: 'Foobar' } });
.then(([a, b]) => {
return a.addB(b, { through: { name: 'Foobar' } }); const a = await A.findOne({
})
.then(() => {
return A.findOne({
include: [ include: [
{ model: B, through: { where: { name: 'Foobar' } }, required: true } { model: B, through: { where: { name: 'Foobar' } }, required: true }
] ]
}); });
})
.then(a => {
expect(a).to.not.equal(null); expect(a).to.not.equal(null);
expect(a.get('bs')).to.have.length(1); expect(a.get('bs')).to.have.length(1);
}); });
});
it('should still pull the main record when an included model is not required and has where restrictions without matches', function() { it('should still pull the main record when an included model is not required and has where restrictions without matches', async function() {
const A = this.sequelize.define('a', { const A = this.sequelize.define('a', {
name: DataTypes.STRING(40) name: DataTypes.STRING(40)
}), }),
...@@ -180,28 +175,25 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -180,28 +175,25 @@ describe(Support.getTestDialectTeaser('Include'), () => {
A.belongsToMany(B, { through: 'a_b' }); A.belongsToMany(B, { through: 'a_b' });
B.belongsToMany(A, { through: 'a_b' }); B.belongsToMany(A, { through: 'a_b' });
return this.sequelize await this.sequelize
.sync({ force: true }) .sync({ force: true });
.then(() => {
return A.create({ await A.create({
name: 'Foobar' name: 'Foobar'
}); });
})
.then(() => { const a = await A.findOne({
return A.findOne({
where: { name: 'Foobar' }, where: { name: 'Foobar' },
include: [ include: [
{ model: B, where: { name: 'idontexist' }, required: false } { model: B, where: { name: 'idontexist' }, required: false }
] ]
}); });
})
.then(a => {
expect(a).to.not.equal(null); expect(a).to.not.equal(null);
expect(a.get('bs')).to.deep.equal([]); expect(a.get('bs')).to.deep.equal([]);
}); });
});
it('should support a nested include (with a where)', function() { it('should support a nested include (with a where)', async function() {
const A = this.sequelize.define('A', { const A = this.sequelize.define('A', {
name: DataTypes.STRING name: DataTypes.STRING
}); });
...@@ -220,10 +212,10 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -220,10 +212,10 @@ describe(Support.getTestDialectTeaser('Include'), () => {
B.hasMany(C); B.hasMany(C);
C.belongsTo(B); C.belongsTo(B);
return this.sequelize await this.sequelize
.sync({ force: true }) .sync({ force: true });
.then(() => {
return A.findOne({ const a = await A.findOne({
include: [ include: [
{ {
model: B, model: B,
...@@ -236,37 +228,31 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -236,37 +228,31 @@ describe(Support.getTestDialectTeaser('Include'), () => {
} }
] ]
}); });
})
.then(a => {
expect(a).to.not.exist; expect(a).to.not.exist;
}); });
});
it('should support a belongsTo with the targetKey option', function() { it('should support a belongsTo with the targetKey option', async function() {
const User = this.sequelize.define('User', { username: { type: DataTypes.STRING, unique: true } }), const User = this.sequelize.define('User', { username: { type: DataTypes.STRING, unique: true } }),
Task = this.sequelize.define('Task', { title: DataTypes.STRING }); Task = this.sequelize.define('Task', { title: DataTypes.STRING });
User.removeAttribute('id'); User.removeAttribute('id');
Task.belongsTo(User, { foreignKey: 'user_name', targetKey: 'username' }); Task.belongsTo(User, { foreignKey: 'user_name', targetKey: 'username' });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return User.create({ username: 'bob' }).then(newUser => { const newUser = await User.create({ username: 'bob' });
return Task.create({ title: 'some task' }).then(newTask => { const newTask = await Task.create({ title: 'some task' });
return newTask.setUser(newUser).then(() => { await newTask.setUser(newUser);
return Task.findOne({
const foundTask = await Task.findOne({
where: { title: 'some task' }, where: { title: 'some task' },
include: [{ model: User }] include: [{ model: User }]
}) });
.then(foundTask => {
expect(foundTask).to.be.ok; expect(foundTask).to.be.ok;
expect(foundTask.User.username).to.equal('bob'); expect(foundTask.User.username).to.equal('bob');
}); });
});
});
});
});
});
it('should support many levels of belongsTo (with a lower level having a where)', function() { it('should support many levels of belongsTo (with a lower level having a where)', async function() {
const A = this.sequelize.define('a', {}), const A = this.sequelize.define('a', {}),
B = this.sequelize.define('b', {}), B = this.sequelize.define('b', {}),
C = this.sequelize.define('c', {}), C = this.sequelize.define('c', {}),
...@@ -288,8 +274,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -288,8 +274,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
F.belongsTo(G); F.belongsTo(G);
G.belongsTo(H); G.belongsTo(H);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([A.create({}), (function(singles) {
const [a0, b] = await Promise.all([A.create({}), (function(singles) {
let promise = Promise.resolve(), let promise = Promise.resolve(),
previousInstance, previousInstance,
b; b;
...@@ -301,16 +288,16 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -301,16 +288,16 @@ describe(Support.getTestDialectTeaser('Include'), () => {
values.name = 'yolo'; values.name = 'yolo';
} }
promise = promise.then(() => { promise = (async () => {
return model.create(values).then(instance => { await promise;
const instance = await model.create(values);
if (previousInstance) { if (previousInstance) {
return previousInstance[`set${_.upperFirst(model.name)}`](instance).then(() => { await previousInstance[`set${_.upperFirst(model.name)}`](instance);
previousInstance = instance; previousInstance = instance;
}); return;
} }
previousInstance = b = instance; previousInstance = b = instance;
}); })();
});
}); });
promise = promise.then(() => { promise = promise.then(() => {
...@@ -318,10 +305,11 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -318,10 +305,11 @@ describe(Support.getTestDialectTeaser('Include'), () => {
}); });
return promise; return promise;
})([B, C, D, E, F, G, H])]).then(([a, b]) => { })([B, C, D, E, F, G, H])]);
return a.setB(b);
}).then(() => { await a0.setB(b);
return A.findOne({
const a = await A.findOne({
include: [ include: [
{ model: B, include: [ { model: B, include: [
{ model: C, include: [ { model: C, include: [
...@@ -339,14 +327,12 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -339,14 +327,12 @@ describe(Support.getTestDialectTeaser('Include'), () => {
] } ] }
] } ] }
] ]
}).then(a => {
expect(a.b.c.d.e.f.g.h).to.be.ok;
});
});
}); });
expect(a.b.c.d.e.f.g.h).to.be.ok;
}); });
it('should work with combinding a where and a scope', function() { it('should work with combinding a where and a scope', async function() {
const User = this.sequelize.define('User', { const User = this.sequelize.define('User', {
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true }, id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
name: DataTypes.STRING name: DataTypes.STRING
...@@ -362,8 +348,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -362,8 +348,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
User.hasMany(Post, { foreignKey: 'owner_id', scope: { owner_type: 'user' }, as: 'UserPosts', constraints: false }); User.hasMany(Post, { foreignKey: 'owner_id', scope: { owner_type: 'user' }, as: 'UserPosts', constraints: false });
Post.belongsTo(User, { foreignKey: 'owner_id', as: 'Owner', constraints: false }); Post.belongsTo(User, { foreignKey: 'owner_id', as: 'Owner', constraints: false });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return User.findOne({
await User.findOne({
where: { id: 2 }, where: { id: 2 },
include: [ include: [
{ model: Post, as: 'UserPosts', where: { 'private': true } } { model: Post, as: 'UserPosts', where: { 'private': true } }
...@@ -371,5 +358,4 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -371,5 +358,4 @@ describe(Support.getTestDialectTeaser('Include'), () => {
}); });
}); });
}); });
});
}); });
...@@ -125,18 +125,21 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -125,18 +125,21 @@ describe(Support.getTestDialectTeaser('Include'), () => {
/* /*
* many-to-many * many-to-many
*/ */
it('supports many-to-many association with where clause', function() { it('supports many-to-many association with where clause', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [projects, users] = await Promise.all([
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')), this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')),
this.User.bulkCreate(build('Alice', 'Bob')) this.User.bulkCreate(build('Alice', 'Bob'))
])) ]);
.then(([projects, users]) => Promise.all([
await Promise.all([
projects[0].addUser(users[0]), projects[0].addUser(users[0]),
projects[1].addUser(users[1]), projects[1].addUser(users[1]),
projects[2].addUser(users[0]) projects[2].addUser(users[0])
])) ]);
.then(() => this.Project.findAll({
const result = await this.Project.findAll({
include: [{ include: [{
model: this.User, model: this.User,
where: { where: {
...@@ -146,27 +149,29 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -146,27 +149,29 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: ['name'], order: ['name'],
limit: 1, limit: 1,
offset: 1 offset: 1
})) });
.then(result => {
expect(result.length).to.equal(1); expect(result.length).to.equal(1);
expect(result[0].name).to.equal('charlie'); expect(result[0].name).to.equal('charlie');
}); });
});
it('supports 2 levels of required many-to-many associations', function() { it('supports 2 levels of required many-to-many associations', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [projects, users, hobbies] = await Promise.all([
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')), this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')),
this.User.bulkCreate(build('Alice', 'Bob')), this.User.bulkCreate(build('Alice', 'Bob')),
this.Hobby.bulkCreate(build('archery', 'badminton')) this.Hobby.bulkCreate(build('archery', 'badminton'))
])) ]);
.then(([projects, users, hobbies]) => Promise.all([
await Promise.all([
projects[0].addUser(users[0]), projects[0].addUser(users[0]),
projects[1].addUser(users[1]), projects[1].addUser(users[1]),
projects[2].addUser(users[0]), projects[2].addUser(users[0]),
users[0].addHobby(hobbies[0]) users[0].addHobby(hobbies[0])
])) ]);
.then(() => this.Project.findAll({
const result = await this.Project.findAll({
include: [{ include: [{
model: this.User, model: this.User,
required: true, required: true,
...@@ -178,28 +183,30 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -178,28 +183,30 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: ['name'], order: ['name'],
limit: 1, limit: 1,
offset: 1 offset: 1
})) });
.then(result => {
expect(result.length).to.equal(1); expect(result.length).to.equal(1);
expect(result[0].name).to.equal('charlie'); expect(result[0].name).to.equal('charlie');
}); });
});
it('supports 2 levels of required many-to-many associations with where clause', function() { it('supports 2 levels of required many-to-many associations with where clause', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [projects, users, hobbies] = await Promise.all([
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')), this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')),
this.User.bulkCreate(build('Alice', 'Bob')), this.User.bulkCreate(build('Alice', 'Bob')),
this.Hobby.bulkCreate(build('archery', 'badminton')) this.Hobby.bulkCreate(build('archery', 'badminton'))
])) ]);
.then(([projects, users, hobbies]) => Promise.all([
await Promise.all([
projects[0].addUser(users[0]), projects[0].addUser(users[0]),
projects[1].addUser(users[1]), projects[1].addUser(users[1]),
projects[2].addUser(users[0]), projects[2].addUser(users[0]),
users[0].addHobby(hobbies[0]), users[0].addHobby(hobbies[0]),
users[1].addHobby(hobbies[1]) users[1].addHobby(hobbies[1])
])) ]);
.then(() => this.Project.findAll({
const result = await this.Project.findAll({
include: [{ include: [{
model: this.User, model: this.User,
required: true, required: true,
...@@ -213,28 +220,30 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -213,28 +220,30 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: ['name'], order: ['name'],
limit: 1, limit: 1,
offset: 1 offset: 1
})) });
.then(result => {
expect(result.length).to.equal(1); expect(result.length).to.equal(1);
expect(result[0].name).to.equal('charlie'); expect(result[0].name).to.equal('charlie');
}); });
});
it('supports 2 levels of required many-to-many associations with through.where clause', function() { it('supports 2 levels of required many-to-many associations with through.where clause', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [projects, users, hobbies] = await Promise.all([
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')), this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')),
this.User.bulkCreate(build('Alice', 'Bob')), this.User.bulkCreate(build('Alice', 'Bob')),
this.Hobby.bulkCreate(build('archery', 'badminton')) this.Hobby.bulkCreate(build('archery', 'badminton'))
])) ]);
.then(([projects, users, hobbies]) => Promise.all([
await Promise.all([
projects[0].addUser(users[0]), projects[0].addUser(users[0]),
projects[1].addUser(users[1]), projects[1].addUser(users[1]),
projects[2].addUser(users[0]), projects[2].addUser(users[0]),
users[0].addHobby(hobbies[0]), users[0].addHobby(hobbies[0]),
users[1].addHobby(hobbies[1]) users[1].addHobby(hobbies[1])
])) ]);
.then(() => this.Project.findAll({
const result = await this.Project.findAll({
include: [{ include: [{
model: this.User, model: this.User,
required: true, required: true,
...@@ -251,22 +260,23 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -251,22 +260,23 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: ['name'], order: ['name'],
limit: 1, limit: 1,
offset: 1 offset: 1
})) });
.then(result => {
expect(result.length).to.equal(1); expect(result.length).to.equal(1);
expect(result[0].name).to.equal('charlie'); expect(result[0].name).to.equal('charlie');
}); });
});
it('supports 3 levels of required many-to-many associations with where clause', function() { it('supports 3 levels of required many-to-many associations with where clause', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [tasks, projects, users, hobbies] = await Promise.all([
this.Task.bulkCreate(build('alpha', 'bravo', 'charlie')), this.Task.bulkCreate(build('alpha', 'bravo', 'charlie')),
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')), this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')),
this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte')), this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte')),
this.Hobby.bulkCreate(build('archery', 'badminton')) this.Hobby.bulkCreate(build('archery', 'badminton'))
])) ]);
.then(([tasks, projects, users, hobbies]) => Promise.all([
await Promise.all([
tasks[0].addProject(projects[0]), tasks[0].addProject(projects[0]),
tasks[1].addProject(projects[1]), tasks[1].addProject(projects[1]),
tasks[2].addProject(projects[2]), tasks[2].addProject(projects[2]),
...@@ -275,8 +285,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -275,8 +285,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
projects[2].addUser(users[0]), projects[2].addUser(users[0]),
users[0].addHobby(hobbies[0]), users[0].addHobby(hobbies[0]),
users[1].addHobby(hobbies[1]) users[1].addHobby(hobbies[1])
])) ]);
.then(() => this.Task.findAll({
const result = await this.Task.findAll({
include: [{ include: [{
model: this.Project, model: this.Project,
required: true, required: true,
...@@ -294,23 +305,25 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -294,23 +305,25 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: ['name'], order: ['name'],
limit: 1, limit: 1,
offset: 1 offset: 1
})) });
.then(result => {
expect(result.length).to.equal(1); expect(result.length).to.equal(1);
expect(result[0].name).to.equal('charlie'); expect(result[0].name).to.equal('charlie');
}); });
});
it('supports required many-to-many association', function() { it('supports required many-to-many association', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [projects, users] = await Promise.all([
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')), this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')),
this.User.bulkCreate(build('Alice', 'Bob')) this.User.bulkCreate(build('Alice', 'Bob'))
])) ]);
.then(([projects, users]) => Promise.all([// alpha
await Promise.all([// alpha
projects[0].addUser(users[0]), // charlie projects[0].addUser(users[0]), // charlie
projects[2].addUser(users[0])])) projects[2].addUser(users[0])]);
.then(() => this.Project.findAll({
const result = await this.Project.findAll({
include: [{ include: [{
model: this.User, model: this.User,
required: true required: true
...@@ -318,29 +331,31 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -318,29 +331,31 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: ['name'], order: ['name'],
limit: 1, limit: 1,
offset: 1 offset: 1
})) });
.then(result => {
expect(result.length).to.equal(1); expect(result.length).to.equal(1);
expect(result[0].name).to.equal('charlie'); expect(result[0].name).to.equal('charlie');
}); });
});
it('supports 2 required many-to-many association', function() { it('supports 2 required many-to-many association', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [projects, users, tasks] = await Promise.all([
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie', 'delta')), this.Project.bulkCreate(build('alpha', 'bravo', 'charlie', 'delta')),
this.User.bulkCreate(build('Alice', 'Bob', 'David')), this.User.bulkCreate(build('Alice', 'Bob', 'David')),
this.Task.bulkCreate(build('a', 'c', 'd')) this.Task.bulkCreate(build('a', 'c', 'd'))
])) ]);
.then(([projects, users, tasks]) => Promise.all([
await Promise.all([
projects[0].addUser(users[0]), projects[0].addUser(users[0]),
projects[0].addTask(tasks[0]), projects[0].addTask(tasks[0]),
projects[1].addUser(users[1]), projects[1].addUser(users[1]),
projects[2].addTask(tasks[1]), projects[2].addTask(tasks[1]),
projects[3].addUser(users[2]), projects[3].addUser(users[2]),
projects[3].addTask(tasks[2]) projects[3].addTask(tasks[2])
])) ]);
.then(() => this.Project.findAll({
const result = await this.Project.findAll({
include: [{ include: [{
model: this.User, model: this.User,
required: true required: true
...@@ -351,24 +366,26 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -351,24 +366,26 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: ['name'], order: ['name'],
limit: 1, limit: 1,
offset: 1 offset: 1
})) });
.then(result => {
expect(result.length).to.equal(1); expect(result.length).to.equal(1);
expect(result[0].name).to.equal('delta'); expect(result[0].name).to.equal('delta');
}); });
});
/* /*
* one-to-many * one-to-many
*/ */
it('supports required one-to-many association', function() { it('supports required one-to-many association', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [posts, comments] = await Promise.all([
this.Post.bulkCreate(build('alpha', 'bravo', 'charlie')), this.Post.bulkCreate(build('alpha', 'bravo', 'charlie')),
this.Comment.bulkCreate(build('comment0', 'comment1')) this.Comment.bulkCreate(build('comment0', 'comment1'))
])) ]);
.then(([posts, comments]) => Promise.all([posts[0].addComment(comments[0]), posts[2].addComment(comments[1])]))
.then(() => this.Post.findAll({ await Promise.all([posts[0].addComment(comments[0]), posts[2].addComment(comments[1])]);
const result = await this.Post.findAll({
include: [{ include: [{
model: this.Comment, model: this.Comment,
required: true required: true
...@@ -376,25 +393,27 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -376,25 +393,27 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: ['name'], order: ['name'],
limit: 1, limit: 1,
offset: 1 offset: 1
})) });
.then(result => {
expect(result.length).to.equal(1); expect(result.length).to.equal(1);
expect(result[0].name).to.equal('charlie'); expect(result[0].name).to.equal('charlie');
}); });
});
it('supports required one-to-many association with where clause', function() { it('supports required one-to-many association with where clause', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [posts, comments] = await Promise.all([
this.Post.bulkCreate(build('alpha', 'bravo', 'charlie')), this.Post.bulkCreate(build('alpha', 'bravo', 'charlie')),
this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2')) this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2'))
])) ]);
.then(([posts, comments]) => Promise.all([
await Promise.all([
posts[0].addComment(comments[0]), posts[0].addComment(comments[0]),
posts[1].addComment(comments[1]), posts[1].addComment(comments[1]),
posts[2].addComment(comments[2]) posts[2].addComment(comments[2])
])) ]);
.then(() => this.Post.findAll({
const result = await this.Post.findAll({
include: [{ include: [{
model: this.Comment, model: this.Comment,
required: true, required: true,
...@@ -409,25 +428,27 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -409,25 +428,27 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: ['name'], order: ['name'],
limit: 1, limit: 1,
offset: 1 offset: 1
})) });
.then(result => {
expect(result.length).to.equal(1); expect(result.length).to.equal(1);
expect(result[0].name).to.equal('charlie'); expect(result[0].name).to.equal('charlie');
}); });
});
it('supports required one-to-many association with where clause (findOne)', function() { it('supports required one-to-many association with where clause (findOne)', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [posts, comments] = await Promise.all([
this.Post.bulkCreate(build('alpha', 'bravo', 'charlie')), this.Post.bulkCreate(build('alpha', 'bravo', 'charlie')),
this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2')) this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2'))
])) ]);
.then(([posts, comments]) => Promise.all([
await Promise.all([
posts[0].addComment(comments[0]), posts[0].addComment(comments[0]),
posts[1].addComment(comments[1]), posts[1].addComment(comments[1]),
posts[2].addComment(comments[2]) posts[2].addComment(comments[2])
])) ]);
.then(() => this.Post.findOne({
const post = await this.Post.findOne({
include: [{ include: [{
model: this.Comment, model: this.Comment,
required: true, required: true,
...@@ -435,27 +456,29 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -435,27 +456,29 @@ describe(Support.getTestDialectTeaser('Include'), () => {
name: 'comment2' name: 'comment2'
} }
}] }]
}))
.then(post => {
expect(post.name).to.equal('charlie');
}); });
expect(post.name).to.equal('charlie');
}); });
it('supports 2 levels of required one-to-many associations', function() { it('supports 2 levels of required one-to-many associations', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [users, posts, comments] = await Promise.all([
this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte', 'David')), this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte', 'David')),
this.Post.bulkCreate(build('post0', 'post1', 'post2')), this.Post.bulkCreate(build('post0', 'post1', 'post2')),
this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2')) this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2'))
])) ]);
.then(([users, posts, comments]) => Promise.all([
await Promise.all([
users[0].addPost(posts[0]), users[0].addPost(posts[0]),
users[1].addPost(posts[1]), users[1].addPost(posts[1]),
users[3].addPost(posts[2]), users[3].addPost(posts[2]),
posts[0].addComment(comments[0]), posts[0].addComment(comments[0]),
posts[2].addComment(comments[2]) posts[2].addComment(comments[2])
])) ]);
.then(() => this.User.findAll({
const result = await this.User.findAll({
include: [{ include: [{
model: this.Post, model: this.Post,
required: true, required: true,
...@@ -467,31 +490,33 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -467,31 +490,33 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: ['name'], order: ['name'],
limit: 1, limit: 1,
offset: 1 offset: 1
})) });
.then(result => {
expect(result.length).to.equal(1); expect(result.length).to.equal(1);
expect(result[0].name).to.equal('David'); expect(result[0].name).to.equal('David');
}); });
});
/* /*
* mixed many-to-many, one-to-many and many-to-one * mixed many-to-many, one-to-many and many-to-one
*/ */
it('supports required one-to-many association with nested required many-to-many association', function() { it('supports required one-to-many association with nested required many-to-many association', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [users, posts, tags] = await Promise.all([
this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte', 'David')), this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte', 'David')),
this.Post.bulkCreate(build('alpha', 'charlie', 'delta')), this.Post.bulkCreate(build('alpha', 'charlie', 'delta')),
this.Tag.bulkCreate(build('atag', 'btag', 'dtag')) this.Tag.bulkCreate(build('atag', 'btag', 'dtag'))
])) ]);
.then(([users, posts, tags]) => Promise.all([
await Promise.all([
users[0].addPost(posts[0]), users[0].addPost(posts[0]),
users[2].addPost(posts[1]), users[2].addPost(posts[1]),
users[3].addPost(posts[2]), users[3].addPost(posts[2]),
posts[0].addTag([tags[0]]), posts[0].addTag([tags[0]]),
posts[2].addTag([tags[2]]) posts[2].addTag([tags[2]])
])) ]);
.then(() => this.User.findAll({
const result = await this.User.findAll({
include: [{ include: [{
model: this.Post, model: this.Post,
required: true, required: true,
...@@ -503,28 +528,30 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -503,28 +528,30 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: ['name'], order: ['name'],
limit: 1, limit: 1,
offset: 1 offset: 1
})) });
.then(result => {
expect(result.length).to.equal(1); expect(result.length).to.equal(1);
expect(result[0].name).to.equal('David'); expect(result[0].name).to.equal('David');
}); });
});
it('supports required many-to-many association with nested required one-to-many association', function() { it('supports required many-to-many association with nested required one-to-many association', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [projects, users, posts] = await Promise.all([
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie', 'delta')), this.Project.bulkCreate(build('alpha', 'bravo', 'charlie', 'delta')),
this.User.bulkCreate(build('Alice', 'Bob', 'David')), this.User.bulkCreate(build('Alice', 'Bob', 'David')),
this.Post.bulkCreate(build('post0', 'post1', 'post2')) this.Post.bulkCreate(build('post0', 'post1', 'post2'))
])) ]);
.then(([projects, users, posts]) => Promise.all([
await Promise.all([
projects[0].addUser(users[0]), projects[0].addUser(users[0]),
projects[1].addUser(users[1]), projects[1].addUser(users[1]),
projects[3].addUser(users[2]), projects[3].addUser(users[2]),
users[0].addPost([posts[0]]), users[0].addPost([posts[0]]),
users[2].addPost([posts[2]]) users[2].addPost([posts[2]])
])) ]);
.then(() => this.Project.findAll({
const result = await this.Project.findAll({
include: [{ include: [{
model: this.User, model: this.User,
required: true, required: true,
...@@ -537,29 +564,31 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -537,29 +564,31 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: ['name'], order: ['name'],
limit: 1, limit: 1,
offset: 1 offset: 1
})) });
.then(result => {
expect(result.length).to.equal(1); expect(result.length).to.equal(1);
expect(result[0].name).to.equal('delta'); expect(result[0].name).to.equal('delta');
}); });
});
it('supports required many-to-one association with nested many-to-many association with where clause', function() { it('supports required many-to-one association with nested many-to-many association with where clause', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [posts, users, hobbies] = await Promise.all([
this.Post.bulkCreate(build('post0', 'post1', 'post2', 'post3')), this.Post.bulkCreate(build('post0', 'post1', 'post2', 'post3')),
this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte', 'David')), this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte', 'David')),
this.Hobby.bulkCreate(build('archery', 'badminton')) this.Hobby.bulkCreate(build('archery', 'badminton'))
])) ]);
.then(([posts, users, hobbies]) => Promise.all([
await Promise.all([
posts[0].setUser(users[0]), posts[0].setUser(users[0]),
posts[1].setUser(users[1]), posts[1].setUser(users[1]),
posts[3].setUser(users[3]), posts[3].setUser(users[3]),
users[0].addHobby(hobbies[0]), users[0].addHobby(hobbies[0]),
users[1].addHobby(hobbies[1]), users[1].addHobby(hobbies[1]),
users[3].addHobby(hobbies[0]) users[3].addHobby(hobbies[0])
])) ]);
.then(() => this.Post.findAll({
const result = await this.Post.findAll({
include: [{ include: [{
model: this.User, model: this.User,
required: true, required: true,
...@@ -573,29 +602,31 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -573,29 +602,31 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: ['name'], order: ['name'],
limit: 1, limit: 1,
offset: 1 offset: 1
})) });
.then(result => {
expect(result.length).to.equal(1); expect(result.length).to.equal(1);
expect(result[0].name).to.equal('post3'); expect(result[0].name).to.equal('post3');
}); });
});
it('supports required many-to-one association with nested many-to-many association with through.where clause', function() { it('supports required many-to-one association with nested many-to-many association with through.where clause', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [posts, users, hobbies] = await Promise.all([
this.Post.bulkCreate(build('post0', 'post1', 'post2', 'post3')), this.Post.bulkCreate(build('post0', 'post1', 'post2', 'post3')),
this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte', 'David')), this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte', 'David')),
this.Hobby.bulkCreate(build('archery', 'badminton')) this.Hobby.bulkCreate(build('archery', 'badminton'))
])) ]);
.then(([posts, users, hobbies]) => Promise.all([
await Promise.all([
posts[0].setUser(users[0]), posts[0].setUser(users[0]),
posts[1].setUser(users[1]), posts[1].setUser(users[1]),
posts[3].setUser(users[3]), posts[3].setUser(users[3]),
users[0].addHobby(hobbies[0]), users[0].addHobby(hobbies[0]),
users[1].addHobby(hobbies[1]), users[1].addHobby(hobbies[1]),
users[3].addHobby(hobbies[0]) users[3].addHobby(hobbies[0])
])) ]);
.then(() => this.Post.findAll({
const result = await this.Post.findAll({
include: [{ include: [{
model: this.User, model: this.User,
required: true, required: true,
...@@ -612,22 +643,23 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -612,22 +643,23 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: ['name'], order: ['name'],
limit: 1, limit: 1,
offset: 1 offset: 1
})) });
.then(result => {
expect(result.length).to.equal(1); expect(result.length).to.equal(1);
expect(result[0].name).to.equal('post3'); expect(result[0].name).to.equal('post3');
}); });
});
it('supports required many-to-one association with multiple nested associations with where clause', function() { it('supports required many-to-one association with multiple nested associations with where clause', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [comments, posts, users, tags] = await Promise.all([
this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2', 'comment3', 'comment4', 'comment5')), this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2', 'comment3', 'comment4', 'comment5')),
this.Post.bulkCreate(build('post0', 'post1', 'post2', 'post3', 'post4')), this.Post.bulkCreate(build('post0', 'post1', 'post2', 'post3', 'post4')),
this.User.bulkCreate(build('Alice', 'Bob')), this.User.bulkCreate(build('Alice', 'Bob')),
this.Tag.bulkCreate(build('tag0', 'tag1')) this.Tag.bulkCreate(build('tag0', 'tag1'))
])) ]);
.then(([comments, posts, users, tags]) => Promise.all([
await Promise.all([
comments[0].setPost(posts[0]), comments[0].setPost(posts[0]),
comments[1].setPost(posts[1]), comments[1].setPost(posts[1]),
comments[3].setPost(posts[2]), comments[3].setPost(posts[2]),
...@@ -641,8 +673,9 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -641,8 +673,9 @@ describe(Support.getTestDialectTeaser('Include'), () => {
posts[2].setUser(users[0]), posts[2].setUser(users[0]),
posts[4].setUser(users[0]), posts[4].setUser(users[0]),
posts[1].setUser(users[1]) posts[1].setUser(users[1])
])) ]);
.then(() => this.Comment.findAll({
const result = await this.Comment.findAll({
include: [{ include: [{
model: this.Post, model: this.Post,
required: true, required: true,
...@@ -661,29 +694,31 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -661,29 +694,31 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: ['name'], order: ['name'],
limit: 1, limit: 1,
offset: 1 offset: 1
})) });
.then(result => {
expect(result.length).to.equal(1); expect(result.length).to.equal(1);
expect(result[0].name).to.equal('comment5'); expect(result[0].name).to.equal('comment5');
}); });
});
it('supports required many-to-one association with nested one-to-many association with where clause', function() { it('supports required many-to-one association with nested one-to-many association with where clause', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
const [comments, posts, footnotes] = await Promise.all([
this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2')), this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2')),
this.Post.bulkCreate(build('post0', 'post1', 'post2')), this.Post.bulkCreate(build('post0', 'post1', 'post2')),
this.Footnote.bulkCreate(build('footnote0', 'footnote1', 'footnote2')) this.Footnote.bulkCreate(build('footnote0', 'footnote1', 'footnote2'))
])) ]);
.then(([comments, posts, footnotes]) => Promise.all([
await Promise.all([
comments[0].setPost(posts[0]), comments[0].setPost(posts[0]),
comments[1].setPost(posts[1]), comments[1].setPost(posts[1]),
comments[2].setPost(posts[2]), comments[2].setPost(posts[2]),
posts[0].addFootnote(footnotes[0]), posts[0].addFootnote(footnotes[0]),
posts[1].addFootnote(footnotes[1]), posts[1].addFootnote(footnotes[1]),
posts[2].addFootnote(footnotes[2]) posts[2].addFootnote(footnotes[2])
])) ]);
.then(() => this.Comment.findAll({
const result = await this.Comment.findAll({
include: [{ include: [{
model: this.Post, model: this.Post,
required: true, required: true,
...@@ -701,11 +736,10 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -701,11 +736,10 @@ describe(Support.getTestDialectTeaser('Include'), () => {
order: ['name'], order: ['name'],
limit: 1, limit: 1,
offset: 1 offset: 1
})) });
.then(result => {
expect(result.length).to.equal(1); expect(result.length).to.equal(1);
expect(result[0].name).to.equal('comment2'); expect(result[0].name).to.equal('comment2');
}); });
}); });
});
}); });
...@@ -8,7 +8,7 @@ const chai = require('chai'), ...@@ -8,7 +8,7 @@ const chai = require('chai'),
describe(Support.getTestDialectTeaser('Paranoid'), () => { describe(Support.getTestDialectTeaser('Paranoid'), () => {
beforeEach(function( ) { beforeEach(async function() {
const S = this.sequelize, const S = this.sequelize,
DT = DataTypes, DT = DataTypes,
...@@ -29,7 +29,7 @@ describe(Support.getTestDialectTeaser('Paranoid'), () => { ...@@ -29,7 +29,7 @@ describe(Support.getTestDialectTeaser('Paranoid'), () => {
D.belongsToMany(A, { through: 'a_d' }); D.belongsToMany(A, { through: 'a_d' });
return S.sync({ force: true }); await S.sync({ force: true });
}); });
before(function() { before(function() {
...@@ -40,7 +40,7 @@ describe(Support.getTestDialectTeaser('Paranoid'), () => { ...@@ -40,7 +40,7 @@ describe(Support.getTestDialectTeaser('Paranoid'), () => {
this.clock.restore(); this.clock.restore();
}); });
it('paranoid with timestamps: false should be ignored / not crash', function() { it('paranoid with timestamps: false should be ignored / not crash', async function() {
const S = this.sequelize, const S = this.sequelize,
Test = S.define('Test', { Test = S.define('Test', {
name: DataTypes.STRING name: DataTypes.STRING
...@@ -49,12 +49,12 @@ describe(Support.getTestDialectTeaser('Paranoid'), () => { ...@@ -49,12 +49,12 @@ describe(Support.getTestDialectTeaser('Paranoid'), () => {
paranoid: true paranoid: true
}); });
return S.sync({ force: true }).then(() => { await S.sync({ force: true });
return Test.findByPk(1);
}); await Test.findByPk(1);
}); });
it('test if non required is marked as false', function( ) { it('test if non required is marked as false', async function() {
const A = this.A, const A = this.A,
B = this.B, B = this.B,
options = { options = {
...@@ -66,12 +66,11 @@ describe(Support.getTestDialectTeaser('Paranoid'), () => { ...@@ -66,12 +66,11 @@ describe(Support.getTestDialectTeaser('Paranoid'), () => {
] ]
}; };
return A.findOne(options).then(() => { await A.findOne(options);
expect(options.include[0].required).to.be.equal(false); expect(options.include[0].required).to.be.equal(false);
}); });
});
it('test if required is marked as true', function( ) { it('test if required is marked as true', async function() {
const A = this.A, const A = this.A,
B = this.B, B = this.B,
options = { options = {
...@@ -83,12 +82,11 @@ describe(Support.getTestDialectTeaser('Paranoid'), () => { ...@@ -83,12 +82,11 @@ describe(Support.getTestDialectTeaser('Paranoid'), () => {
] ]
}; };
return A.findOne(options).then(() => { await A.findOne(options);
expect(options.include[0].required).to.be.equal(true); expect(options.include[0].required).to.be.equal(true);
}); });
});
it('should not load paranoid, destroyed instances, with a non-paranoid parent', function() { it('should not load paranoid, destroyed instances, with a non-paranoid parent', async function() {
const X = this.sequelize.define('x', { const X = this.sequelize.define('x', {
name: DataTypes.STRING name: DataTypes.STRING
}, { }, {
...@@ -104,27 +102,26 @@ describe(Support.getTestDialectTeaser('Paranoid'), () => { ...@@ -104,27 +102,26 @@ describe(Support.getTestDialectTeaser('Paranoid'), () => {
X.hasMany(Y); X.hasMany(Y);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([
const [x0, y] = await Promise.all([
X.create(), X.create(),
Y.create() Y.create()
]); ]);
}).then(([x, y]) => {
this.x = x; this.x = x0;
this.y = y; this.y = y;
return x.addY(y); await x0.addY(y);
}).then(() => { await this.y.destroy();
return this.y.destroy();
}).then(() => {
//prevent CURRENT_TIMESTAMP to be same //prevent CURRENT_TIMESTAMP to be same
this.clock.tick(1000); this.clock.tick(1000);
return X.findAll({ const obj = await X.findAll({
include: [Y] include: [Y]
}).then(obj => obj[0]);
}).then(x => {
expect(x.ys).to.have.length(0);
}); });
const x = await obj[0];
expect(x.ys).to.have.length(0);
}); });
}); });
...@@ -16,11 +16,11 @@ const sortById = function(a, b) { ...@@ -16,11 +16,11 @@ const sortById = function(a, b) {
describe(Support.getTestDialectTeaser('Includes with schemas'), () => { describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
describe('findAll', () => { describe('findAll', () => {
afterEach(function() { afterEach(async function() {
return this.sequelize.dropSchema('account'); await this.sequelize.dropSchema('account');
}); });
beforeEach(function() { beforeEach(async function() {
this.fixtureA = async function() { this.fixtureA = async function() {
await this.sequelize.dropSchema('account'); await this.sequelize.dropSchema('account');
await this.sequelize.createSchema('account'); await this.sequelize.createSchema('account');
...@@ -176,7 +176,7 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -176,7 +176,7 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
]); ]);
} }
}; };
return this.sequelize.createSchema('account'); await this.sequelize.createSchema('account');
}); });
it('should support an include with multiple different association types', async function() { it('should support an include with multiple different association types', async function() {
...@@ -383,7 +383,7 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -383,7 +383,7 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
}); });
}); });
it('should support ordering with only belongsTo includes', function() { it('should support ordering with only belongsTo includes', async function() {
const User = this.sequelize.define('SpecialUser', {}, { schema: 'account' }), const User = this.sequelize.define('SpecialUser', {}, { schema: 'account' }),
Item = this.sequelize.define('Item', { 'test': DataTypes.STRING }, { schema: 'account' }), Item = this.sequelize.define('Item', { 'test': DataTypes.STRING }, { schema: 'account' }),
Order = this.sequelize.define('Order', { 'position': DataTypes.INTEGER }, { schema: 'account' }); Order = this.sequelize.define('Order', { 'position': DataTypes.INTEGER }, { schema: 'account' });
...@@ -392,8 +392,9 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -392,8 +392,9 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
User.belongsTo(Item, { 'as': 'itemB', foreignKey: 'itemB_id' }); User.belongsTo(Item, { 'as': 'itemB', foreignKey: 'itemB_id' });
User.belongsTo(Order); User.belongsTo(Order);
return this.sequelize.sync().then(() => { await this.sequelize.sync();
return Promise.all([
await Promise.all([
User.bulkCreate([{}, {}, {}]), User.bulkCreate([{}, {}, {}]),
Item.bulkCreate([ Item.bulkCreate([
{ 'test': 'abc' }, { 'test': 'abc' },
...@@ -406,14 +407,15 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -406,14 +407,15 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
{ 'position': 3 }, { 'position': 3 },
{ 'position': 1 } { 'position': 1 }
]) ])
]).then(() => { ]);
return Promise.all([
const [users, items, orders] = await Promise.all([
User.findAll(), User.findAll(),
Item.findAll({ order: ['id'] }), Item.findAll({ order: ['id'] }),
Order.findAll({ order: ['id'] }) Order.findAll({ order: ['id'] })
]); ]);
}).then(([users, items, orders]) => {
return Promise.all([ await Promise.all([
users[0].setItemA(items[0]), users[0].setItemA(items[0]),
users[0].setItemB(items[1]), users[0].setItemB(items[1]),
users[0].setOrder(orders[2]), users[0].setOrder(orders[2]),
...@@ -424,8 +426,8 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -424,8 +426,8 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
users[2].setItemB(items[3]), users[2].setItemB(items[3]),
users[2].setOrder(orders[0]) users[2].setOrder(orders[0])
]); ]);
}).then(() => {
return User.findAll({ const as = await User.findAll({
'include': [ 'include': [
{ 'model': Item, 'as': 'itemA', where: { test: 'abc' } }, { 'model': Item, 'as': 'itemA', where: { test: 'abc' } },
{ 'model': Item, 'as': 'itemB' }, { 'model': Item, 'as': 'itemB' },
...@@ -433,18 +435,16 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -433,18 +435,16 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
'order': [ 'order': [
[Order, 'position'] [Order, 'position']
] ]
}).then(as => { });
expect(as.length).to.eql(2); expect(as.length).to.eql(2);
expect(as[0].itemA.test).to.eql('abc'); expect(as[0].itemA.test).to.eql('abc');
expect(as[1].itemA.test).to.eql('abc'); expect(as[1].itemA.test).to.eql('abc');
expect(as[0].Order.position).to.eql(1); expect(as[0].Order.position).to.eql(1);
expect(as[1].Order.position).to.eql(2); expect(as[1].Order.position).to.eql(2);
}); });
});
});
});
it('should include attributes from through models', function() { it('should include attributes from through models', async function() {
const Product = this.sequelize.define('Product', { const Product = this.sequelize.define('Product', {
title: DataTypes.STRING title: DataTypes.STRING
}, { schema: 'account' }), }, { schema: 'account' }),
...@@ -458,8 +458,9 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -458,8 +458,9 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
Product.belongsToMany(Tag, { through: ProductTag }); Product.belongsToMany(Tag, { through: ProductTag });
Tag.belongsToMany(Product, { through: ProductTag }); Tag.belongsToMany(Product, { through: ProductTag });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([
await Promise.all([
Product.bulkCreate([ Product.bulkCreate([
{ title: 'Chair' }, { title: 'Chair' },
{ title: 'Desk' }, { title: 'Desk' },
...@@ -470,22 +471,23 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -470,22 +471,23 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
{ name: 'B' }, { name: 'B' },
{ name: 'C' } { name: 'C' }
]) ])
]).then(() => { ]);
return Promise.all([
const [products0, tags] = await Promise.all([
Product.findAll(), Product.findAll(),
Tag.findAll() Tag.findAll()
]); ]);
}).then(([products, tags]) => {
return Promise.all([ await Promise.all([
products[0].addTag(tags[0], { through: { priority: 1 } }), products0[0].addTag(tags[0], { through: { priority: 1 } }),
products[0].addTag(tags[1], { through: { priority: 2 } }), products0[0].addTag(tags[1], { through: { priority: 2 } }),
products[1].addTag(tags[1], { through: { priority: 1 } }), products0[1].addTag(tags[1], { through: { priority: 1 } }),
products[2].addTag(tags[0], { through: { priority: 3 } }), products0[2].addTag(tags[0], { through: { priority: 3 } }),
products[2].addTag(tags[1], { through: { priority: 1 } }), products0[2].addTag(tags[1], { through: { priority: 1 } }),
products[2].addTag(tags[2], { through: { priority: 2 } }) products0[2].addTag(tags[2], { through: { priority: 2 } })
]); ]);
}).then(() => {
return Product.findAll({ const products = await Product.findAll({
include: [ include: [
{ model: Tag } { model: Tag }
], ],
...@@ -493,7 +495,8 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -493,7 +495,8 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
['id', 'ASC'], ['id', 'ASC'],
[Tag, 'id', 'ASC'] [Tag, 'id', 'ASC']
] ]
}).then(products => { });
expect(products[0].Tags[0].ProductTag.priority).to.equal(1); expect(products[0].Tags[0].ProductTag.priority).to.equal(1);
expect(products[0].Tags[1].ProductTag.priority).to.equal(2); expect(products[0].Tags[1].ProductTag.priority).to.equal(2);
expect(products[1].Tags[0].ProductTag.priority).to.equal(1); expect(products[1].Tags[0].ProductTag.priority).to.equal(1);
...@@ -501,41 +504,38 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -501,41 +504,38 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
expect(products[2].Tags[1].ProductTag.priority).to.equal(1); expect(products[2].Tags[1].ProductTag.priority).to.equal(1);
expect(products[2].Tags[2].ProductTag.priority).to.equal(2); expect(products[2].Tags[2].ProductTag.priority).to.equal(2);
}); });
});
});
});
it('should support a required belongsTo include', function() { it('should support a required belongsTo include', async function() {
const User = this.sequelize.define('User', {}, { schema: 'account' }), const User = this.sequelize.define('User', {}, { schema: 'account' }),
Group = this.sequelize.define('Group', {}, { schema: 'account' }); Group = this.sequelize.define('Group', {}, { schema: 'account' });
User.belongsTo(Group); User.belongsTo(Group);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([
await Promise.all([
Group.bulkCreate([{}, {}]), Group.bulkCreate([{}, {}]),
User.bulkCreate([{}, {}, {}]) User.bulkCreate([{}, {}, {}])
]).then(() => { ]);
return Promise.all([
const [groups, users0] = await Promise.all([
Group.findAll(), Group.findAll(),
User.findAll() User.findAll()
]); ]);
}).then(([groups, users]) => {
return users[2].setGroup(groups[1]); await users0[2].setGroup(groups[1]);
}).then(() => {
return User.findAll({ const users = await User.findAll({
include: [ include: [
{ model: Group, required: true } { model: Group, required: true }
] ]
}).then(users => { });
expect(users.length).to.equal(1); expect(users.length).to.equal(1);
expect(users[0].Group).to.be.ok; expect(users[0].Group).to.be.ok;
}); });
});
});
});
it('should be possible to extend the on clause with a where option on a belongsTo include', function() { it('should be possible to extend the on clause with a where option on a belongsTo include', async function() {
const User = this.sequelize.define('User', {}, { schema: 'account' }), const User = this.sequelize.define('User', {}, { schema: 'account' }),
Group = this.sequelize.define('Group', { Group = this.sequelize.define('Group', {
name: DataTypes.STRING name: DataTypes.STRING
...@@ -543,38 +543,38 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -543,38 +543,38 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
User.belongsTo(Group); User.belongsTo(Group);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([
await Promise.all([
Group.bulkCreate([ Group.bulkCreate([
{ name: 'A' }, { name: 'A' },
{ name: 'B' } { name: 'B' }
]), ]),
User.bulkCreate([{}, {}]) User.bulkCreate([{}, {}])
]).then(() => { ]);
return Promise.all([
const [groups, users0] = await Promise.all([
Group.findAll(), Group.findAll(),
User.findAll() User.findAll()
]); ]);
}).then(([groups, users]) => {
return Promise.all([ await Promise.all([
users[0].setGroup(groups[1]), users0[0].setGroup(groups[1]),
users[1].setGroup(groups[0]) users0[1].setGroup(groups[0])
]); ]);
}).then(() => {
return User.findAll({ const users = await User.findAll({
include: [ include: [
{ model: Group, where: { name: 'A' } } { model: Group, where: { name: 'A' } }
] ]
}).then(users => { });
expect(users.length).to.equal(1); expect(users.length).to.equal(1);
expect(users[0].Group).to.be.ok; expect(users[0].Group).to.be.ok;
expect(users[0].Group.name).to.equal('A'); expect(users[0].Group.name).to.equal('A');
}); });
});
});
});
it('should be possible to extend the on clause with a where option on a belongsTo include', function() { it('should be possible to extend the on clause with a where option on a belongsTo include', async function() {
const User = this.sequelize.define('User', {}, { schema: 'account' }), const User = this.sequelize.define('User', {}, { schema: 'account' }),
Group = this.sequelize.define('Group', { Group = this.sequelize.define('Group', {
name: DataTypes.STRING name: DataTypes.STRING
...@@ -582,38 +582,38 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -582,38 +582,38 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
User.belongsTo(Group); User.belongsTo(Group);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([
await Promise.all([
Group.bulkCreate([ Group.bulkCreate([
{ name: 'A' }, { name: 'A' },
{ name: 'B' } { name: 'B' }
]), ]),
User.bulkCreate([{}, {}]) User.bulkCreate([{}, {}])
]).then(() => { ]);
return Promise.all([
const [groups, users0] = await Promise.all([
Group.findAll(), Group.findAll(),
User.findAll() User.findAll()
]); ]);
}).then(([groups, users]) => {
return Promise.all([ await Promise.all([
users[0].setGroup(groups[1]), users0[0].setGroup(groups[1]),
users[1].setGroup(groups[0]) users0[1].setGroup(groups[0])
]); ]);
}).then(() => {
return User.findAll({ const users = await User.findAll({
include: [ include: [
{ model: Group, required: true } { model: Group, required: true }
] ]
}).then(users => { });
users.forEach(user => { users.forEach(user => {
expect(user.Group).to.be.ok; expect(user.Group).to.be.ok;
}); });
}); });
});
});
});
it('should be possible to define a belongsTo include as required with child hasMany with limit', function() { it('should be possible to define a belongsTo include as required with child hasMany with limit', async function() {
const User = this.sequelize.define('User', {}, { schema: 'account' }), const User = this.sequelize.define('User', {}, { schema: 'account' }),
Group = this.sequelize.define('Group', { Group = this.sequelize.define('Group', {
name: DataTypes.STRING name: DataTypes.STRING
...@@ -625,49 +625,49 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -625,49 +625,49 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
User.belongsTo(Group); User.belongsTo(Group);
Group.hasMany(Category); Group.hasMany(Category);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([
await Promise.all([
Group.bulkCreate([ Group.bulkCreate([
{ name: 'A' }, { name: 'A' },
{ name: 'B' } { name: 'B' }
]), ]),
User.bulkCreate([{}, {}]), User.bulkCreate([{}, {}]),
Category.bulkCreate([{}, {}]) Category.bulkCreate([{}, {}])
]).then(() => { ]);
return Promise.all([
const [groups, users0, categories] = await Promise.all([
Group.findAll(), Group.findAll(),
User.findAll(), User.findAll(),
Category.findAll() Category.findAll()
]); ]);
}).then(([groups, users, categories]) => {
const promises = [ const promises = [
users[0].setGroup(groups[1]), users0[0].setGroup(groups[1]),
users[1].setGroup(groups[0]) users0[1].setGroup(groups[0])
]; ];
groups.forEach(group => { groups.forEach(group => {
promises.push(group.setCategories(categories)); promises.push(group.setCategories(categories));
}); });
return Promise.all(promises); await Promise.all(promises);
}).then(() => {
return User.findAll({ const users = await User.findAll({
include: [ include: [
{ model: Group, required: true, include: [ { model: Group, required: true, include: [
{ model: Category } { model: Category }
] } ] }
], ],
limit: 1 limit: 1
}).then(users => { });
expect(users.length).to.equal(1); expect(users.length).to.equal(1);
users.forEach(user => { users.forEach(user => {
expect(user.Group).to.be.ok; expect(user.Group).to.be.ok;
expect(user.Group.Categories).to.be.ok; expect(user.Group.Categories).to.be.ok;
}); });
}); });
});
});
});
it('should be possible to define a belongsTo include as required with child hasMany with limit and aliases', function() { it('should be possible to define a belongsTo include as required with child hasMany with limit and aliases', async function() {
const User = this.sequelize.define('User', {}, { schema: 'account' }), const User = this.sequelize.define('User', {}, { schema: 'account' }),
Group = this.sequelize.define('Group', { Group = this.sequelize.define('Group', {
name: DataTypes.STRING name: DataTypes.STRING
...@@ -679,49 +679,49 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -679,49 +679,49 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
User.belongsTo(Group, { as: 'Team' }); User.belongsTo(Group, { as: 'Team' });
Group.hasMany(Category, { as: 'Tags' }); Group.hasMany(Category, { as: 'Tags' });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([
await Promise.all([
Group.bulkCreate([ Group.bulkCreate([
{ name: 'A' }, { name: 'A' },
{ name: 'B' } { name: 'B' }
]), ]),
User.bulkCreate([{}, {}]), User.bulkCreate([{}, {}]),
Category.bulkCreate([{}, {}]) Category.bulkCreate([{}, {}])
]).then(() => { ]);
return Promise.all([
const [groups, users0, categories] = await Promise.all([
Group.findAll(), Group.findAll(),
User.findAll(), User.findAll(),
Category.findAll() Category.findAll()
]); ]);
}).then(([groups, users, categories]) => {
const promises = [ const promises = [
users[0].setTeam(groups[1]), users0[0].setTeam(groups[1]),
users[1].setTeam(groups[0]) users0[1].setTeam(groups[0])
]; ];
groups.forEach(group => { groups.forEach(group => {
promises.push(group.setTags(categories)); promises.push(group.setTags(categories));
}); });
return Promise.all(promises); await Promise.all(promises);
}).then(() => {
return User.findAll({ const users = await User.findAll({
include: [ include: [
{ model: Group, required: true, as: 'Team', include: [ { model: Group, required: true, as: 'Team', include: [
{ model: Category, as: 'Tags' } { model: Category, as: 'Tags' }
] } ] }
], ],
limit: 1 limit: 1
}).then(users => { });
expect(users.length).to.equal(1); expect(users.length).to.equal(1);
users.forEach(user => { users.forEach(user => {
expect(user.Team).to.be.ok; expect(user.Team).to.be.ok;
expect(user.Team.Tags).to.be.ok; expect(user.Team.Tags).to.be.ok;
}); });
}); });
});
});
});
it('should be possible to define a belongsTo include as required with child hasMany which is not required with limit', function() { it('should be possible to define a belongsTo include as required with child hasMany which is not required with limit', async function() {
const User = this.sequelize.define('User', {}, { schema: 'account' }), const User = this.sequelize.define('User', {}, { schema: 'account' }),
Group = this.sequelize.define('Group', { Group = this.sequelize.define('Group', {
name: DataTypes.STRING name: DataTypes.STRING
...@@ -733,49 +733,49 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -733,49 +733,49 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
User.belongsTo(Group); User.belongsTo(Group);
Group.hasMany(Category); Group.hasMany(Category);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([
await Promise.all([
Group.bulkCreate([ Group.bulkCreate([
{ name: 'A' }, { name: 'A' },
{ name: 'B' } { name: 'B' }
]), ]),
User.bulkCreate([{}, {}]), User.bulkCreate([{}, {}]),
Category.bulkCreate([{}, {}]) Category.bulkCreate([{}, {}])
]).then(() => { ]);
return Promise.all([
const [groups, users0, categories] = await Promise.all([
Group.findAll(), Group.findAll(),
User.findAll(), User.findAll(),
Category.findAll() Category.findAll()
]); ]);
}).then(([groups, users, categories]) => {
const promises = [ const promises = [
users[0].setGroup(groups[1]), users0[0].setGroup(groups[1]),
users[1].setGroup(groups[0]) users0[1].setGroup(groups[0])
]; ];
groups.forEach(group => { groups.forEach(group => {
promises.push(group.setCategories(categories)); promises.push(group.setCategories(categories));
}); });
return Promise.all(promises); await Promise.all(promises);
}).then(() => {
return User.findAll({ const users = await User.findAll({
include: [ include: [
{ model: Group, required: true, include: [ { model: Group, required: true, include: [
{ model: Category, required: false } { model: Category, required: false }
] } ] }
], ],
limit: 1 limit: 1
}).then(users => { });
expect(users.length).to.equal(1); expect(users.length).to.equal(1);
users.forEach(user => { users.forEach(user => {
expect(user.Group).to.be.ok; expect(user.Group).to.be.ok;
expect(user.Group.Categories).to.be.ok; expect(user.Group.Categories).to.be.ok;
}); });
}); });
});
});
});
it('should be possible to extend the on clause with a where option on a hasOne include', function() { it('should be possible to extend the on clause with a where option on a hasOne include', async function() {
const User = this.sequelize.define('User', {}, { schema: 'account' }), const User = this.sequelize.define('User', {}, { schema: 'account' }),
Project = this.sequelize.define('Project', { Project = this.sequelize.define('Project', {
title: DataTypes.STRING title: DataTypes.STRING
...@@ -783,38 +783,38 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -783,38 +783,38 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
User.hasOne(Project, { as: 'LeaderOf' }); User.hasOne(Project, { as: 'LeaderOf' });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([
await Promise.all([
Project.bulkCreate([ Project.bulkCreate([
{ title: 'Alpha' }, { title: 'Alpha' },
{ title: 'Beta' } { title: 'Beta' }
]), ]),
User.bulkCreate([{}, {}]) User.bulkCreate([{}, {}])
]).then(() => { ]);
return Promise.all([
const [projects, users0] = await Promise.all([
Project.findAll(), Project.findAll(),
User.findAll() User.findAll()
]); ]);
}).then(([projects, users]) => {
return Promise.all([ await Promise.all([
users[1].setLeaderOf(projects[1]), users0[1].setLeaderOf(projects[1]),
users[0].setLeaderOf(projects[0]) users0[0].setLeaderOf(projects[0])
]); ]);
}).then(() => {
return User.findAll({ const users = await User.findAll({
include: [ include: [
{ model: Project, as: 'LeaderOf', where: { title: 'Beta' } } { model: Project, as: 'LeaderOf', where: { title: 'Beta' } }
] ]
}).then(users => { });
expect(users.length).to.equal(1); expect(users.length).to.equal(1);
expect(users[0].LeaderOf).to.be.ok; expect(users[0].LeaderOf).to.be.ok;
expect(users[0].LeaderOf.title).to.equal('Beta'); expect(users[0].LeaderOf.title).to.equal('Beta');
}); });
});
});
});
it('should be possible to extend the on clause with a where option on a hasMany include with a through model', function() { it('should be possible to extend the on clause with a where option on a hasMany include with a through model', async function() {
const Product = this.sequelize.define('Product', { const Product = this.sequelize.define('Product', {
title: DataTypes.STRING title: DataTypes.STRING
}, { schema: 'account' }), }, { schema: 'account' }),
...@@ -828,8 +828,9 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -828,8 +828,9 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
Product.belongsToMany(Tag, { through: ProductTag }); Product.belongsToMany(Tag, { through: ProductTag });
Tag.belongsToMany(Product, { through: ProductTag }); Tag.belongsToMany(Product, { through: ProductTag });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([
await Promise.all([
Product.bulkCreate([ Product.bulkCreate([
{ title: 'Chair' }, { title: 'Chair' },
{ title: 'Desk' }, { title: 'Desk' },
...@@ -840,32 +841,31 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -840,32 +841,31 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
{ name: 'B' }, { name: 'B' },
{ name: 'C' } { name: 'C' }
]) ])
]).then(() => { ]);
return Promise.all([
const [products0, tags] = await Promise.all([
Product.findAll(), Product.findAll(),
Tag.findAll() Tag.findAll()
]); ]);
}).then(([products, tags]) => {
return Promise.all([ await Promise.all([
products[0].addTag(tags[0], { priority: 1 }), products0[0].addTag(tags[0], { priority: 1 }),
products[0].addTag(tags[1], { priority: 2 }), products0[0].addTag(tags[1], { priority: 2 }),
products[1].addTag(tags[1], { priority: 1 }), products0[1].addTag(tags[1], { priority: 1 }),
products[2].addTag(tags[0], { priority: 3 }), products0[2].addTag(tags[0], { priority: 3 }),
products[2].addTag(tags[1], { priority: 1 }), products0[2].addTag(tags[1], { priority: 1 }),
products[2].addTag(tags[2], { priority: 2 }) products0[2].addTag(tags[2], { priority: 2 })
]); ]);
}).then(() => {
return Product.findAll({ const products = await Product.findAll({
include: [ include: [
{ model: Tag, where: { name: 'C' } } { model: Tag, where: { name: 'C' } }
] ]
}).then(products => { });
expect(products.length).to.equal(1); expect(products.length).to.equal(1);
expect(products[0].Tags.length).to.equal(1); expect(products[0].Tags.length).to.equal(1);
}); });
});
});
});
it('should be possible to extend the on clause with a where option on nested includes', async function() { it('should be possible to extend the on clause with a where option on nested includes', async function() {
const User = this.sequelize.define('User', { const User = this.sequelize.define('User', {
...@@ -993,7 +993,7 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -993,7 +993,7 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
} }
}); });
it('should be possible to use limit and a where with a belongsTo include', function() { it('should be possible to use limit and a where with a belongsTo include', async function() {
const User = this.sequelize.define('User', {}, { schema: 'account' }), const User = this.sequelize.define('User', {}, { schema: 'account' }),
Group = this.sequelize.define('Group', { Group = this.sequelize.define('Group', {
name: DataTypes.STRING name: DataTypes.STRING
...@@ -1001,8 +1001,9 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -1001,8 +1001,9 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
User.belongsTo(Group); User.belongsTo(Group);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return promiseProps({
const results = await promiseProps({
groups: Group.bulkCreate([ groups: Group.bulkCreate([
{ name: 'A' }, { name: 'A' },
{ name: 'B' } { name: 'B' }
...@@ -1012,33 +1013,33 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -1012,33 +1013,33 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
users: User.bulkCreate([{}, {}, {}, {}]).then(() => { users: User.bulkCreate([{}, {}, {}, {}]).then(() => {
return User.findAll(); return User.findAll();
}) })
}).then(results => { });
return Promise.all([
await Promise.all([
results.users[1].setGroup(results.groups[0]), results.users[1].setGroup(results.groups[0]),
results.users[2].setGroup(results.groups[0]), results.users[2].setGroup(results.groups[0]),
results.users[3].setGroup(results.groups[1]), results.users[3].setGroup(results.groups[1]),
results.users[0].setGroup(results.groups[0]) results.users[0].setGroup(results.groups[0])
]); ]);
}).then(() => {
return User.findAll({ const users = await User.findAll({
include: [ include: [
{ model: Group, where: { name: 'A' } } { model: Group, where: { name: 'A' } }
], ],
limit: 2 limit: 2
}).then(users => { });
expect(users.length).to.equal(2); expect(users.length).to.equal(2);
users.forEach(user => { users.forEach(user => {
expect(user.Group.name).to.equal('A'); expect(user.Group.name).to.equal('A');
}); });
}); });
});
});
});
it('should be possible use limit, attributes and a where on a belongsTo with additional hasMany includes', function() { it('should be possible use limit, attributes and a where on a belongsTo with additional hasMany includes', async function() {
return this.fixtureA().then(() => { await this.fixtureA();
return this.models.Product.findAll({
const products = await this.models.Product.findAll({
attributes: ['title'], attributes: ['title'],
include: [ include: [
{ model: this.models.Company, where: { name: 'NYSE' } }, { model: this.models.Company, where: { name: 'NYSE' } },
...@@ -1049,7 +1050,8 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -1049,7 +1050,8 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
order: [ order: [
['id', 'ASC'] ['id', 'ASC']
] ]
}).then(products => { });
expect(products.length).to.equal(3); expect(products.length).to.equal(3);
products.forEach(product => { products.forEach(product => {
...@@ -1058,12 +1060,11 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -1058,12 +1060,11 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
expect(product.Prices.length).to.be.ok; expect(product.Prices.length).to.be.ok;
}); });
}); });
});
});
it('should be possible to use limit and a where on a hasMany with additional includes', function() { it('should be possible to use limit and a where on a hasMany with additional includes', async function() {
return this.fixtureA().then(() => { await this.fixtureA();
return this.models.Product.findAll({
const products = await this.models.Product.findAll({
include: [ include: [
{ model: this.models.Company }, { model: this.models.Company },
{ model: this.models.Tag }, { model: this.models.Tag },
...@@ -1075,7 +1076,8 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -1075,7 +1076,8 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
order: [ order: [
['id', 'ASC'] ['id', 'ASC']
] ]
}).then(products => { });
expect(products.length).to.equal(6); expect(products.length).to.equal(6);
products.forEach(product => { products.forEach(product => {
...@@ -1087,12 +1089,11 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -1087,12 +1089,11 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
}); });
}); });
}); });
});
});
it('should be possible to use limit and a where on a hasMany with a through model with additional includes', function() { it('should be possible to use limit and a where on a hasMany with a through model with additional includes', async function() {
return this.fixtureA().then(() => { await this.fixtureA();
return this.models.Product.findAll({
const products = await this.models.Product.findAll({
include: [ include: [
{ model: this.models.Company }, { model: this.models.Company },
{ model: this.models.Tag, where: { name: ['A', 'B', 'C'] } }, { model: this.models.Tag, where: { name: ['A', 'B', 'C'] } },
...@@ -1102,7 +1103,8 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -1102,7 +1103,8 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
order: [ order: [
['id', 'ASC'] ['id', 'ASC']
] ]
}).then(products => { });
expect(products.length).to.equal(10); expect(products.length).to.equal(10);
products.forEach(product => { products.forEach(product => {
...@@ -1114,10 +1116,8 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -1114,10 +1116,8 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
}); });
}); });
}); });
});
});
it('should support including date fields, with the correct timezone', function() { it('should support including date fields, with the correct timezone', async function() {
const User = this.sequelize.define('user', { const User = this.sequelize.define('user', {
dateField: Sequelize.DATE dateField: Sequelize.DATE
}, { timestamps: false, schema: 'account' }), }, { timestamps: false, schema: 'account' }),
...@@ -1128,16 +1128,18 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -1128,16 +1128,18 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
User.belongsToMany(Group, { through: 'group_user' }); User.belongsToMany(Group, { through: 'group_user' });
Group.belongsToMany(User, { through: 'group_user' }); Group.belongsToMany(User, { through: 'group_user' });
return this.sequelize.sync().then(() => { await this.sequelize.sync();
return User.create({ dateField: Date.UTC(2014, 1, 20) }).then(user => { const user = await User.create({ dateField: Date.UTC(2014, 1, 20) });
return Group.create({ dateField: Date.UTC(2014, 1, 20) }).then(group => { const group = await Group.create({ dateField: Date.UTC(2014, 1, 20) });
return user.addGroup(group).then(() => { await user.addGroup(group);
return User.findAll({
const users = await User.findAll({
where: { where: {
id: user.id id: user.id
}, },
include: [Group] include: [Group]
}).then(users => { });
if (dialect === 'sqlite') { if (dialect === 'sqlite') {
expect(new Date(users[0].dateField).getTime()).to.equal(Date.UTC(2014, 1, 20)); expect(new Date(users[0].dateField).getTime()).to.equal(Date.UTC(2014, 1, 20));
expect(new Date(users[0].groups[0].dateField).getTime()).to.equal(Date.UTC(2014, 1, 20)); expect(new Date(users[0].groups[0].dateField).getTime()).to.equal(Date.UTC(2014, 1, 20));
...@@ -1146,16 +1148,11 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -1146,16 +1148,11 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
expect(users[0].groups[0].dateField.getTime()).to.equal(Date.UTC(2014, 1, 20)); expect(users[0].groups[0].dateField.getTime()).to.equal(Date.UTC(2014, 1, 20));
} }
}); });
});
});
});
});
});
}); });
describe('findOne', () => { describe('findOne', () => {
it('should work with schemas', function() { it('should work with schemas', async function() {
const UserModel = this.sequelize.define('User', { const UserModel = this.sequelize.define('User', {
Id: { Id: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
...@@ -1207,11 +1204,11 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -1207,11 +1204,11 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
foreignKey: 'UserId' foreignKey: 'UserId'
}); });
return this.sequelize.dropSchema('hero').then(() => { await this.sequelize.dropSchema('hero');
return this.sequelize.createSchema('hero'); await this.sequelize.createSchema('hero');
}).then(() => { await this.sequelize.sync({ force: true });
return this.sequelize.sync({ force: true }).then(() => {
return UserModel.findOne({ await UserModel.findOne({
where: { where: {
Id: 1 Id: 1
}, },
...@@ -1220,8 +1217,8 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -1220,8 +1217,8 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => {
as: 'Resume' as: 'Resume'
}] }]
}); });
});
}).then(() => this.sequelize.dropSchema('hero')); await this.sequelize.dropSchema('hero');
}); });
}); });
}); });
...@@ -11,15 +11,16 @@ const chai = require('chai'), ...@@ -11,15 +11,16 @@ const chai = require('chai'),
if (current.dialect.supports.groupedLimit) { if (current.dialect.supports.groupedLimit) {
describe(Support.getTestDialectTeaser('Include'), () => { describe(Support.getTestDialectTeaser('Include'), () => {
describe('separate', () => { describe('separate', () => {
it('should run a hasMany association in a separate query', function() { it('should run a hasMany association in a separate query', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
Task = this.sequelize.define('Task', {}), Task = this.sequelize.define('Task', {}),
sqlSpy = sinon.spy(); sqlSpy = sinon.spy();
User.Tasks = User.hasMany(Task, { as: 'tasks' }); User.Tasks = User.hasMany(Task, { as: 'tasks' });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([User.create({
await Promise.all([User.create({
id: 1, id: 1,
tasks: [ tasks: [
{}, {},
...@@ -35,8 +36,9 @@ if (current.dialect.supports.groupedLimit) { ...@@ -35,8 +36,9 @@ if (current.dialect.supports.groupedLimit) {
] ]
}, { }, {
include: [User.Tasks] include: [User.Tasks]
})]).then(() => { })]);
return User.findAll({
const users = await User.findAll({
include: [ include: [
{ association: User.Tasks, separate: true } { association: User.Tasks, separate: true }
], ],
...@@ -45,7 +47,7 @@ if (current.dialect.supports.groupedLimit) { ...@@ -45,7 +47,7 @@ if (current.dialect.supports.groupedLimit) {
], ],
logging: sqlSpy logging: sqlSpy
}); });
}).then(users => {
expect(users[0].get('tasks')).to.be.ok; expect(users[0].get('tasks')).to.be.ok;
expect(users[0].get('tasks').length).to.equal(3); expect(users[0].get('tasks').length).to.equal(3);
expect(users[1].get('tasks')).to.be.ok; expect(users[1].get('tasks')).to.be.ok;
...@@ -56,10 +58,8 @@ if (current.dialect.supports.groupedLimit) { ...@@ -56,10 +58,8 @@ if (current.dialect.supports.groupedLimit) {
expect(sqlSpy).to.have.been.calledTwice; expect(sqlSpy).to.have.been.calledTwice;
}); });
});
});
it('should work even if the id was not included', function() { it('should work even if the id was not included', async function() {
const User = this.sequelize.define('User', { const User = this.sequelize.define('User', {
name: DataTypes.STRING name: DataTypes.STRING
}), }),
...@@ -68,8 +68,9 @@ if (current.dialect.supports.groupedLimit) { ...@@ -68,8 +68,9 @@ if (current.dialect.supports.groupedLimit) {
User.Tasks = User.hasMany(Task, { as: 'tasks' }); User.Tasks = User.hasMany(Task, { as: 'tasks' });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return User.create({
await User.create({
id: 1, id: 1,
tasks: [ tasks: [
{}, {},
...@@ -78,8 +79,9 @@ if (current.dialect.supports.groupedLimit) { ...@@ -78,8 +79,9 @@ if (current.dialect.supports.groupedLimit) {
] ]
}, { }, {
include: [User.Tasks] include: [User.Tasks]
}).then(() => { });
return User.findAll({
const users = await User.findAll({
attributes: ['name'], attributes: ['name'],
include: [ include: [
{ association: User.Tasks, separate: true } { association: User.Tasks, separate: true }
...@@ -89,15 +91,13 @@ if (current.dialect.supports.groupedLimit) { ...@@ -89,15 +91,13 @@ if (current.dialect.supports.groupedLimit) {
], ],
logging: sqlSpy logging: sqlSpy
}); });
}).then(users => {
expect(users[0].get('tasks')).to.be.ok; expect(users[0].get('tasks')).to.be.ok;
expect(users[0].get('tasks').length).to.equal(3); expect(users[0].get('tasks').length).to.equal(3);
expect(sqlSpy).to.have.been.calledTwice; expect(sqlSpy).to.have.been.calledTwice;
}); });
});
});
it('should work even if include does not specify foreign key attribute with custom sourceKey', function() { it('should work even if include does not specify foreign key attribute with custom sourceKey', async function() {
const User = this.sequelize.define('User', { const User = this.sequelize.define('User', {
name: DataTypes.STRING, name: DataTypes.STRING,
userExtraId: { userExtraId: {
...@@ -116,10 +116,10 @@ if (current.dialect.supports.groupedLimit) { ...@@ -116,10 +116,10 @@ if (current.dialect.supports.groupedLimit) {
sourceKey: 'userExtraId' sourceKey: 'userExtraId'
}); });
return this.sequelize await this.sequelize
.sync({ force: true }) .sync({ force: true });
.then(() => {
return User.create({ await User.create({
id: 1, id: 1,
userExtraId: 222, userExtraId: 222,
tasks: [ tasks: [
...@@ -130,9 +130,8 @@ if (current.dialect.supports.groupedLimit) { ...@@ -130,9 +130,8 @@ if (current.dialect.supports.groupedLimit) {
}, { }, {
include: [User.Tasks] include: [User.Tasks]
}); });
})
.then(() => { const users = await User.findAll({
return User.findAll({
attributes: ['name'], attributes: ['name'],
include: [ include: [
{ {
...@@ -148,15 +147,13 @@ if (current.dialect.supports.groupedLimit) { ...@@ -148,15 +147,13 @@ if (current.dialect.supports.groupedLimit) {
], ],
logging: sqlSpy logging: sqlSpy
}); });
})
.then(users => {
expect(users[0].get('tasks')).to.be.ok; expect(users[0].get('tasks')).to.be.ok;
expect(users[0].get('tasks').length).to.equal(3); expect(users[0].get('tasks').length).to.equal(3);
expect(sqlSpy).to.have.been.calledTwice; expect(sqlSpy).to.have.been.calledTwice;
}); });
});
it('should not break a nested include with null values', function() { it('should not break a nested include with null values', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
Team = this.sequelize.define('Team', {}), Team = this.sequelize.define('Team', {}),
Company = this.sequelize.define('Company', {}); Company = this.sequelize.define('Company', {});
...@@ -164,18 +161,17 @@ if (current.dialect.supports.groupedLimit) { ...@@ -164,18 +161,17 @@ if (current.dialect.supports.groupedLimit) {
User.Team = User.belongsTo(Team); User.Team = User.belongsTo(Team);
Team.Company = Team.belongsTo(Company); Team.Company = Team.belongsTo(Company);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return User.create({}); await User.create({});
}).then(() => {
return User.findAll({ await User.findAll({
include: [ include: [
{ association: User.Team, include: [Team.Company] } { association: User.Team, include: [Team.Company] }
] ]
}); });
}); });
});
it('should run a hasMany association with limit in a separate query', function() { it('should run a hasMany association with limit in a separate query', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
Task = this.sequelize.define('Task', { Task = this.sequelize.define('Task', {
userId: { userId: {
...@@ -187,8 +183,9 @@ if (current.dialect.supports.groupedLimit) { ...@@ -187,8 +183,9 @@ if (current.dialect.supports.groupedLimit) {
User.Tasks = User.hasMany(Task, { as: 'tasks', foreignKey: 'userId' }); User.Tasks = User.hasMany(Task, { as: 'tasks', foreignKey: 'userId' });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([User.create({
await Promise.all([User.create({
id: 1, id: 1,
tasks: [ tasks: [
{}, {},
...@@ -207,8 +204,9 @@ if (current.dialect.supports.groupedLimit) { ...@@ -207,8 +204,9 @@ if (current.dialect.supports.groupedLimit) {
] ]
}, { }, {
include: [User.Tasks] include: [User.Tasks]
})]).then(() => { })]);
return User.findAll({
const users = await User.findAll({
include: [ include: [
{ association: User.Tasks, limit: 2 } { association: User.Tasks, limit: 2 }
], ],
...@@ -217,17 +215,15 @@ if (current.dialect.supports.groupedLimit) { ...@@ -217,17 +215,15 @@ if (current.dialect.supports.groupedLimit) {
], ],
logging: sqlSpy logging: sqlSpy
}); });
}).then(users => {
expect(users[0].get('tasks')).to.be.ok; expect(users[0].get('tasks')).to.be.ok;
expect(users[0].get('tasks').length).to.equal(2); expect(users[0].get('tasks').length).to.equal(2);
expect(users[1].get('tasks')).to.be.ok; expect(users[1].get('tasks')).to.be.ok;
expect(users[1].get('tasks').length).to.equal(2); expect(users[1].get('tasks').length).to.equal(2);
expect(sqlSpy).to.have.been.calledTwice; expect(sqlSpy).to.have.been.calledTwice;
}); });
});
});
it('should run a nested (from a non-separate include) hasMany association in a separate query', function() { it('should run a nested (from a non-separate include) hasMany association in a separate query', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
Company = this.sequelize.define('Company'), Company = this.sequelize.define('Company'),
Task = this.sequelize.define('Task', {}), Task = this.sequelize.define('Task', {}),
...@@ -236,8 +232,9 @@ if (current.dialect.supports.groupedLimit) { ...@@ -236,8 +232,9 @@ if (current.dialect.supports.groupedLimit) {
User.Company = User.belongsTo(Company, { as: 'company' }); User.Company = User.belongsTo(Company, { as: 'company' });
Company.Tasks = Company.hasMany(Task, { as: 'tasks' }); Company.Tasks = Company.hasMany(Task, { as: 'tasks' });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([User.create({
await Promise.all([User.create({
id: 1, id: 1,
company: { company: {
tasks: [ tasks: [
...@@ -261,8 +258,9 @@ if (current.dialect.supports.groupedLimit) { ...@@ -261,8 +258,9 @@ if (current.dialect.supports.groupedLimit) {
include: [ include: [
{ association: User.Company, include: [Company.Tasks] } { association: User.Company, include: [Company.Tasks] }
] ]
})]).then(() => { })]);
return User.findAll({
const users = await User.findAll({
include: [ include: [
{ association: User.Company, include: [ { association: User.Company, include: [
{ association: Company.Tasks, separate: true } { association: Company.Tasks, separate: true }
...@@ -273,17 +271,15 @@ if (current.dialect.supports.groupedLimit) { ...@@ -273,17 +271,15 @@ if (current.dialect.supports.groupedLimit) {
], ],
logging: sqlSpy logging: sqlSpy
}); });
}).then(users => {
expect(users[0].get('company').get('tasks')).to.be.ok; expect(users[0].get('company').get('tasks')).to.be.ok;
expect(users[0].get('company').get('tasks').length).to.equal(3); expect(users[0].get('company').get('tasks').length).to.equal(3);
expect(users[1].get('company').get('tasks')).to.be.ok; expect(users[1].get('company').get('tasks')).to.be.ok;
expect(users[1].get('company').get('tasks').length).to.equal(1); expect(users[1].get('company').get('tasks').length).to.equal(1);
expect(sqlSpy).to.have.been.calledTwice; expect(sqlSpy).to.have.been.calledTwice;
}); });
});
});
it('should work having a separate include between a parent and child include', function() { it('should work having a separate include between a parent and child include', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
Project = this.sequelize.define('Project'), Project = this.sequelize.define('Project'),
Company = this.sequelize.define('Company'), Company = this.sequelize.define('Company'),
...@@ -294,8 +290,9 @@ if (current.dialect.supports.groupedLimit) { ...@@ -294,8 +290,9 @@ if (current.dialect.supports.groupedLimit) {
User.Tasks = User.hasMany(Task, { as: 'tasks' }); User.Tasks = User.hasMany(Task, { as: 'tasks' });
Task.Project = Task.belongsTo(Project, { as: 'project' }); Task.Project = Task.belongsTo(Project, { as: 'project' });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([Company.create({
await Promise.all([Company.create({
id: 1, id: 1,
users: [ users: [
{ {
...@@ -314,8 +311,9 @@ if (current.dialect.supports.groupedLimit) { ...@@ -314,8 +311,9 @@ if (current.dialect.supports.groupedLimit) {
] } ] }
] } ] }
] ]
})]).then(() => { })]);
return Company.findAll({
const companies = await Company.findAll({
include: [ include: [
{ association: Company.Users, include: [ { association: Company.Users, include: [
{ association: User.Tasks, separate: true, include: [ { association: User.Tasks, separate: true, include: [
...@@ -328,15 +326,13 @@ if (current.dialect.supports.groupedLimit) { ...@@ -328,15 +326,13 @@ if (current.dialect.supports.groupedLimit) {
], ],
logging: sqlSpy logging: sqlSpy
}); });
}).then(companies => {
expect(sqlSpy).to.have.been.calledTwice; expect(sqlSpy).to.have.been.calledTwice;
expect(companies[0].users[0].tasks[0].project).to.be.ok; expect(companies[0].users[0].tasks[0].project).to.be.ok;
}); });
});
});
it('should run two nested hasMany association in a separate queries', function() { it('should run two nested hasMany association in a separate queries', async function() {
const User = this.sequelize.define('User', {}), const User = this.sequelize.define('User', {}),
Project = this.sequelize.define('Project', {}), Project = this.sequelize.define('Project', {}),
Task = this.sequelize.define('Task', {}), Task = this.sequelize.define('Task', {}),
...@@ -345,8 +341,9 @@ if (current.dialect.supports.groupedLimit) { ...@@ -345,8 +341,9 @@ if (current.dialect.supports.groupedLimit) {
User.Projects = User.hasMany(Project, { as: 'projects' }); User.Projects = User.hasMany(Project, { as: 'projects' });
Project.Tasks = Project.hasMany(Task, { as: 'tasks' }); Project.Tasks = Project.hasMany(Task, { as: 'tasks' });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([User.create({
await Promise.all([User.create({
id: 1, id: 1,
projects: [ projects: [
{ {
...@@ -383,8 +380,9 @@ if (current.dialect.supports.groupedLimit) { ...@@ -383,8 +380,9 @@ if (current.dialect.supports.groupedLimit) {
include: [ include: [
{ association: User.Projects, include: [Project.Tasks] } { association: User.Projects, include: [Project.Tasks] }
] ]
})]).then(() => { })]);
return User.findAll({
const users = await User.findAll({
include: [ include: [
{ association: User.Projects, separate: true, include: [ { association: User.Projects, separate: true, include: [
{ association: Project.Tasks, separate: true } { association: Project.Tasks, separate: true }
...@@ -395,7 +393,7 @@ if (current.dialect.supports.groupedLimit) { ...@@ -395,7 +393,7 @@ if (current.dialect.supports.groupedLimit) {
], ],
logging: sqlSpy logging: sqlSpy
}); });
}).then(users => {
const u1projects = users[0].get('projects'); const u1projects = users[0].get('projects');
expect(u1projects).to.be.ok; expect(u1projects).to.be.ok;
...@@ -414,10 +412,8 @@ if (current.dialect.supports.groupedLimit) { ...@@ -414,10 +412,8 @@ if (current.dialect.supports.groupedLimit) {
expect(sqlSpy).to.have.been.calledThrice; expect(sqlSpy).to.have.been.calledThrice;
}); });
});
});
it('should work with two schema models in a hasMany association', function() { it('should work with two schema models in a hasMany association', async function() {
const User = this.sequelize.define('User', {}, { schema: 'archive' }), const User = this.sequelize.define('User', {}, { schema: 'archive' }),
Task = this.sequelize.define('Task', { Task = this.sequelize.define('Task', {
id: { type: DataTypes.INTEGER, primaryKey: true }, id: { type: DataTypes.INTEGER, primaryKey: true },
...@@ -426,10 +422,11 @@ if (current.dialect.supports.groupedLimit) { ...@@ -426,10 +422,11 @@ if (current.dialect.supports.groupedLimit) {
User.Tasks = User.hasMany(Task, { as: 'tasks' }); User.Tasks = User.hasMany(Task, { as: 'tasks' });
return Support.dropTestSchemas(this.sequelize).then(() => { await Support.dropTestSchemas(this.sequelize);
return this.sequelize.createSchema('archive').then(() => { await this.sequelize.createSchema('archive');
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Promise.all([User.create({
await Promise.all([User.create({
id: 1, id: 1,
tasks: [ tasks: [
{ id: 1, title: 'b' }, { id: 1, title: 'b' },
...@@ -449,13 +446,14 @@ if (current.dialect.supports.groupedLimit) { ...@@ -449,13 +446,14 @@ if (current.dialect.supports.groupedLimit) {
}, { }, {
include: [User.Tasks] include: [User.Tasks]
})]); })]);
}).then(() => {
return User.findAll({ const result = await User.findAll({
include: [{ model: Task, limit: 2, as: 'tasks', order: [['id', 'ASC']] }], include: [{ model: Task, limit: 2, as: 'tasks', order: [['id', 'ASC']] }],
order: [ order: [
['id', 'ASC'] ['id', 'ASC']
] ]
}).then(result => { });
expect(result[0].tasks.length).to.equal(2); expect(result[0].tasks.length).to.equal(2);
expect(result[0].tasks[0].title).to.equal('b'); expect(result[0].tasks[0].title).to.equal('b');
expect(result[0].tasks[1].title).to.equal('d'); expect(result[0].tasks[1].title).to.equal('d');
...@@ -463,18 +461,12 @@ if (current.dialect.supports.groupedLimit) { ...@@ -463,18 +461,12 @@ if (current.dialect.supports.groupedLimit) {
expect(result[1].tasks.length).to.equal(2); expect(result[1].tasks.length).to.equal(2);
expect(result[1].tasks[0].title).to.equal('a'); expect(result[1].tasks[0].title).to.equal('a');
expect(result[1].tasks[1].title).to.equal('c'); expect(result[1].tasks[1].title).to.equal('c');
return this.sequelize.dropSchema('archive').then(() => { await this.sequelize.dropSchema('archive');
return this.sequelize.showAllSchemas().then(schemas => { const schemas = await this.sequelize.showAllSchemas();
if (dialect === 'postgres' || dialect === 'mssql' || dialect === 'mariadb') { if (dialect === 'postgres' || dialect === 'mssql' || dialect === 'mariadb') {
expect(schemas).to.not.have.property('archive'); expect(schemas).to.not.have.property('archive');
} }
}); });
});
});
});
});
});
});
it('should work with required non-separate parent and required child', async function() { it('should work with required non-separate parent and required child', async function() {
const User = this.sequelize.define('User', {}); const User = this.sequelize.define('User', {});
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!