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

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,42 +194,42 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -194,42 +194,42 @@ 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({
include: [ await User.findOne({
{ include: [
model: SubscriptionForm, {
include: [ model: SubscriptionForm,
{ include: [
model: Collection, {
where: { model: Collection,
id: 13 where: {
} id: 13
},
{
model: Category,
include: [
{
model: SubCategory
},
{
model: Capital,
include: [
{
model: Category
}
]
}
]
} }
] },
} {
] model: Category,
}); include: [
{
model: SubCategory
},
{
model: Capital,
include: [
{
model: Category
}
]
}
]
}
]
}
]
}); });
}); });
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,47 +248,47 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -248,47 +248,47 @@ 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([
{ title: 'office' } await Promise.all([Set.bulkCreate([
]), Product.bulkCreate([ { title: 'office' }
{ title: 'Chair' }, ]), Product.bulkCreate([
{ title: 'Desk' }, { title: 'Chair' },
{ title: 'Dress' } { title: 'Desk' },
]), Tag.bulkCreate([ { title: 'Dress' }
{ name: 'A' }, ]), Tag.bulkCreate([
{ name: 'B' }, { name: 'A' },
{ name: 'C' } { name: 'B' },
])]).then(() => { { name: 'C' }
return Promise.all([Set.findAll(), Product.findAll(), Tag.findAll()]); ])]);
}).then(([sets, products, tags]) => {
return Promise.all([ const [sets, products, tags] = await Promise.all([Set.findAll(), Product.findAll(), Tag.findAll()]);
sets[0].addProducts([products[0], products[1]]),
products[0].addTag(tags[0], { priority: 1 }).then(() => { await Promise.all([
return products[0].addTag(tags[1], { priority: 2 }); sets[0].addProducts([products[0], products[1]]),
}).then(() => { products[0].addTag(tags[0], { priority: 1 }).then(() => {
return products[0].addTag(tags[2], { priority: 1 }); return products[0].addTag(tags[1], { priority: 2 });
}),
products[1].addTag(tags[1], { priority: 2 }).then(() => {
return products[2].addTag(tags[1], { priority: 3 });
}).then(() => {
return products[2].addTag(tags[2], { priority: 0 });
})
]);
}).then(() => { }).then(() => {
return Set.findAll({ return products[0].addTag(tags[2], { priority: 1 });
include: [{ }),
model: Product, products[1].addTag(tags[1], { priority: 2 }).then(() => {
include: [{ return products[2].addTag(tags[1], { priority: 3 });
model: Tag, }).then(() => {
where: { return products[2].addTag(tags[2], { priority: 0 });
name: 'A' })
} ]);
}]
}], await Set.findAll({
limit: 1 include: [{
}); model: Product,
}); include: [{
model: Tag,
where: {
name: 'A'
}
}]
}],
limit: 1
}); });
}); });
...@@ -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,74 +443,74 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -443,74 +443,74 @@ 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([
{},
{},
{},
{},
{},
{},
{},
{}
]).then(() => {
return A.findAll();
}), (function(singles) {
let promise = Promise.resolve(),
previousInstance,
b;
singles.forEach(model => {
promise = promise.then(() => {
return model.create({}).then(instance => {
if (previousInstance) {
return previousInstance[`set${_.upperFirst(model.name)}`](instance).then(() => {
previousInstance = instance;
});
}
previousInstance = b = instance;
});
});
});
promise = promise.then(() => { const [as0, b] = await Promise.all([A.bulkCreate([
return b; {},
}); {},
{},
{},
{},
{},
{},
{}
]).then(() => {
return A.findAll();
}), (function(singles) {
let promise = Promise.resolve(),
previousInstance,
b;
singles.forEach(model => {
promise = (async () => {
await promise;
const instance = await model.create({});
if (previousInstance) {
await previousInstance[`set${_.upperFirst(model.name)}`](instance);
previousInstance = instance;
return;
}
previousInstance = b = instance;
})();
});
return promise; promise = promise.then(() => {
})([B, C, D, E, F, G, H])]).then(([as, b]) => { return b;
return Promise.all(as.map(a => { });
return a.setB(b);
})); return promise;
}).then(() => { })([B, C, D, E, F, G, H])]);
return A.findAll({
include: [ await Promise.all(as0.map(a => {
{ model: B, include: [ return a.setB(b);
{ model: C, include: [ }));
{ model: D, include: [
{ model: E, include: [ const as = await A.findAll({
{ model: F, include: [ include: [
{ model: G, include: [ { model: B, include: [
{ model: H } { model: C, include: [
] } { model: D, include: [
] } { model: E, include: [
{ model: F, include: [
{ model: G, include: [
{ model: H }
] } ] }
] } ] }
] } ] }
] } ] }
] ] }
}).then(as => { ] }
expect(as.length).to.be.ok; ]
});
as.forEach(a => { expect(as.length).to.be.ok;
expect(a.b.c.d.e.f.g.h).to.be.ok;
}); as.forEach(a => {
}); 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,82 +532,82 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -532,82 +532,82 @@ 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([
{},
{},
{},
{},
{},
{},
{},
{}
]).then(() => {
return A.findAll();
}), (function(singles) {
let promise = Promise.resolve(),
previousInstance,
b;
singles.forEach(model => { const [as0, b] = await Promise.all([A.bulkCreate([
const values = {}; {},
{},
{},
{},
{},
{},
{},
{}
]).then(() => {
return A.findAll();
}), (function(singles) {
let promise = Promise.resolve(),
previousInstance,
b;
singles.forEach(model => {
const values = {};
if (model.name === 'g') {
values.name = 'yolo';
}
if (model.name === 'g') { promise = (async () => {
values.name = 'yolo'; await promise;
const instance = await model.create(values);
if (previousInstance) {
await previousInstance[`set${_.upperFirst(model.name)}`](instance);
previousInstance = instance;
return;
} }
previousInstance = b = instance;
})();
});
promise = promise.then(() => { promise = promise.then(() => {
return model.create(values).then(instance => { return b;
if (previousInstance) { });
return previousInstance[`set${_.upperFirst(model.name)}`](instance).then(() => {
previousInstance = instance;
});
}
previousInstance = b = instance;
});
});
});
promise = promise.then(() => { return promise;
return b; })([B, C, D, E, F, G, H])]);
});
return promise; await Promise.all(as0.map(a => {
})([B, C, D, E, F, G, H])]).then(([as, b]) => { return a.setB(b);
return Promise.all(as.map(a => { }));
return a.setB(b);
})); const as = await A.findAll({
}).then(() => { include: [
return A.findAll({ { model: B, include: [
include: [ { model: C, include: [
{ model: B, include: [ { model: D, include: [
{ model: C, include: [ { model: E, include: [
{ model: D, include: [ { model: F, include: [
{ model: E, include: [ { model: G, where: {
{ model: F, include: [ name: 'yolo'
{ model: G, where: { }, include: [
name: 'yolo' { model: H }
}, include: [
{ model: H }
] }
] }
] } ] }
] } ] }
] } ] }
] } ] }
] ] }
}).then(as => { ] }
expect(as.length).to.be.ok; ]
});
as.forEach(a => { expect(as.length).to.be.ok;
expect(a.b.c.d.e.f.g.h).to.be.ok;
}); as.forEach(a => {
}); 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,74 +616,74 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -616,74 +616,74 @@ 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({
users: User.bulkCreate([{}, {}, {}]).then(() => { const results = await promiseProps({
return User.findAll(); users: User.bulkCreate([{}, {}, {}]).then(() => {
}), return User.findAll();
items: Item.bulkCreate([ }),
{ 'test': 'abc' }, items: Item.bulkCreate([
{ 'test': 'def' }, { 'test': 'abc' },
{ 'test': 'ghi' }, { 'test': 'def' },
{ 'test': 'jkl' } { 'test': 'ghi' },
]).then(() => { { 'test': 'jkl' }
return Item.findAll({ order: ['id'] }); ]).then(() => {
}), return Item.findAll({ order: ['id'] });
orders: Order.bulkCreate([ }),
{ 'position': 2 }, orders: Order.bulkCreate([
{ 'position': 3 }, { 'position': 2 },
{ 'position': 1 } { 'position': 3 },
]).then(() => { { 'position': 1 }
return Order.findAll({ order: ['id'] }); ]).then(() => {
}) return Order.findAll({ order: ['id'] });
}).then(results => { })
const user1 = results.users[0]; });
const user2 = results.users[1];
const user3 = results.users[2];
const item1 = results.items[0];
const item2 = results.items[1];
const item3 = results.items[2];
const item4 = results.items[3];
const order1 = results.orders[0];
const order2 = results.orders[1];
const order3 = results.orders[2];
return Promise.all([
user1.setItemA(item1),
user1.setItemB(item2),
user1.setOrder(order3),
user2.setItemA(item3),
user2.setItemB(item4),
user2.setOrder(order2),
user3.setItemA(item1),
user3.setItemB(item4),
user3.setOrder(order1)
]);
}).then(() => {
return User.findAll({
'include': [
{ 'model': Item, 'as': 'itemA', where: { test: 'abc' } },
{ 'model': Item, 'as': 'itemB' },
Order],
'order': [
[Order, 'position']
]
}).then(as => {
expect(as.length).to.eql(2);
expect(as[0].itemA.test).to.eql('abc'); const user1 = results.users[0];
expect(as[1].itemA.test).to.eql('abc'); const user2 = results.users[1];
const user3 = results.users[2];
const item1 = results.items[0];
const item2 = results.items[1];
const item3 = results.items[2];
const item4 = results.items[3];
const order1 = results.orders[0];
const order2 = results.orders[1];
const order3 = results.orders[2];
await Promise.all([
user1.setItemA(item1),
user1.setItemB(item2),
user1.setOrder(order3),
user2.setItemA(item3),
user2.setItemB(item4),
user2.setOrder(order2),
user3.setItemA(item1),
user3.setItemB(item4),
user3.setOrder(order1)
]);
expect(as[0].Order.position).to.eql(1); const as = await User.findAll({
expect(as[1].Order.position).to.eql(2); 'include': [
}); { 'model': Item, 'as': 'itemA', where: { test: 'abc' } },
}); { 'model': Item, 'as': 'itemB' },
Order],
'order': [
[Order, 'position']
]
}); });
expect(as.length).to.eql(2);
expect(as[0].itemA.test).to.eql('abc');
expect(as[1].itemA.test).to.eql('abc');
expect(as[0].Order.position).to.eql(1);
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,84 +697,84 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -697,84 +697,84 @@ 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({
products: Product.bulkCreate([
{ title: 'Chair' },
{ title: 'Desk' },
{ title: 'Dress' }
]).then(() => {
return Product.findAll();
}),
tags: Tag.bulkCreate([
{ name: 'A' },
{ name: 'B' },
{ name: 'C' }
]).then(() => {
return Tag.findAll();
})
}).then(results => {
return Promise.all([
results.products[0].addTag(results.tags[0], { through: { priority: 1 } }),
results.products[0].addTag(results.tags[1], { through: { priority: 2 } }),
results.products[1].addTag(results.tags[1], { through: { priority: 1 } }),
results.products[2].addTag(results.tags[0], { through: { priority: 3 } }),
results.products[2].addTag(results.tags[1], { through: { priority: 1 } }),
results.products[2].addTag(results.tags[2], { through: { priority: 2 } })
]);
}).then(() => {
return Product.findAll({
include: [
{ model: Tag }
],
order: [
['id', 'ASC'],
[Tag, 'id', 'ASC']
]
}).then(products => {
expect(products[0].Tags[0].ProductTag.priority).to.equal(1);
expect(products[0].Tags[1].ProductTag.priority).to.equal(2);
expect(products[1].Tags[0].ProductTag.priority).to.equal(1); const results = await promiseProps({
products: Product.bulkCreate([
{ title: 'Chair' },
{ title: 'Desk' },
{ title: 'Dress' }
]).then(() => {
return Product.findAll();
}),
tags: Tag.bulkCreate([
{ name: 'A' },
{ name: 'B' },
{ name: 'C' }
]).then(() => {
return Tag.findAll();
})
});
expect(products[2].Tags[0].ProductTag.priority).to.equal(3); await Promise.all([
expect(products[2].Tags[1].ProductTag.priority).to.equal(1); results.products[0].addTag(results.tags[0], { through: { priority: 1 } }),
expect(products[2].Tags[2].ProductTag.priority).to.equal(2); results.products[0].addTag(results.tags[1], { through: { priority: 2 } }),
}); results.products[1].addTag(results.tags[1], { through: { priority: 1 } }),
}); results.products[2].addTag(results.tags[0], { through: { priority: 3 } }),
results.products[2].addTag(results.tags[1], { through: { priority: 1 } }),
results.products[2].addTag(results.tags[2], { through: { priority: 2 } })
]);
const products = await Product.findAll({
include: [
{ model: Tag }
],
order: [
['id', 'ASC'],
[Tag, 'id', 'ASC']
]
}); });
expect(products[0].Tags[0].ProductTag.priority).to.equal(1);
expect(products[0].Tags[1].ProductTag.priority).to.equal(2);
expect(products[1].Tags[0].ProductTag.priority).to.equal(1);
expect(products[2].Tags[0].ProductTag.priority).to.equal(3);
expect(products[2].Tags[1].ProductTag.priority).to.equal(1);
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({
groups: Group.bulkCreate([{}, {}]).then(() => { const results = await promiseProps({
return Group.findAll(); groups: Group.bulkCreate([{}, {}]).then(() => {
}), return Group.findAll();
users: User.bulkCreate([{}, {}, {}]).then(() => { }),
return User.findAll(); users: User.bulkCreate([{}, {}, {}]).then(() => {
}) return User.findAll();
}).then(results => { })
return results.users[2].setGroup(results.groups[1]);
}).then(() => {
return User.findAll({
include: [
{ model: Group, required: true }
]
}).then(users => {
expect(users.length).to.equal(1);
expect(users[0].Group).to.be.ok;
});
});
}); });
await results.users[2].setGroup(results.groups[1]);
const users = await User.findAll({
include: [
{ model: Group, required: true }
]
});
expect(users.length).to.equal(1);
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,37 +782,37 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -782,37 +782,37 @@ 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({
groups: Group.bulkCreate([ const results = await promiseProps({
{ name: 'A' }, groups: Group.bulkCreate([
{ name: 'B' } { name: 'A' },
]).then(() => { { name: 'B' }
return Group.findAll(); ]).then(() => {
}), return Group.findAll();
users: User.bulkCreate([{}, {}]).then(() => { }),
return User.findAll(); users: User.bulkCreate([{}, {}]).then(() => {
}) return User.findAll();
}).then(results => { })
return Promise.all([ });
results.users[0].setGroup(results.groups[1]),
results.users[1].setGroup(results.groups[0]) await Promise.all([
]); results.users[0].setGroup(results.groups[1]),
}).then(() => { results.users[1].setGroup(results.groups[0])
return User.findAll({ ]);
include: [
{ model: Group, where: { name: 'A' } } const users = await User.findAll({
] include: [
}).then(users => { { model: Group, where: { name: 'A' } }
expect(users.length).to.equal(1); ]
expect(users[0].Group).to.be.ok;
expect(users[0].Group.name).to.equal('A');
});
});
}); });
expect(users.length).to.equal(1);
expect(users[0].Group).to.be.ok;
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,39 +820,39 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -820,39 +820,39 @@ 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({
groups: Group.bulkCreate([ const results = await promiseProps({
{ name: 'A' }, groups: Group.bulkCreate([
{ name: 'B' } { name: 'A' },
]).then(() => { { name: 'B' }
return Group.findAll(); ]).then(() => {
}), return Group.findAll();
users: User.bulkCreate([{}, {}]).then(() => { }),
return User.findAll(); users: User.bulkCreate([{}, {}]).then(() => {
}) return User.findAll();
}).then(results => { })
return Promise.all([ });
results.users[0].setGroup(results.groups[1]),
results.users[1].setGroup(results.groups[0]) await Promise.all([
]); results.users[0].setGroup(results.groups[1]),
}).then(() => { results.users[1].setGroup(results.groups[0])
return User.findAll({ ]);
include: [
{ model: Group, required: true } const users = await User.findAll({
] include: [
}).then(users => { { model: Group, required: true }
users.forEach(user => { ]
expect(user.Group).to.be.ok; });
});
}); users.forEach(user => {
}); 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 });
// Associate // Associate
...@@ -863,33 +863,31 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -863,33 +863,31 @@ 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 });
where: { username: 'John' },
include: [{ const john = await User.findOne({
model: Address, where: { username: 'John' },
required: true, include: [{
where: { model: Address,
active: true required: true,
}, where: {
include: [{ active: true
model: Street },
}] include: [{
}] model: Street
}).then(john => { }]
expect(john.Address).to.be.ok; }]
expect(john.Address.Street).to.be.ok;
});
});
});
});
}); });
expect(john.Address).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,48 +899,48 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -901,48 +899,48 @@ 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({
groups: Group.bulkCreate([ const results = await promiseProps({
{ name: 'A' }, groups: Group.bulkCreate([
{ name: 'B' } { name: 'A' },
]).then(() => { { name: 'B' }
return Group.findAll(); ]).then(() => {
}), return Group.findAll();
users: User.bulkCreate([{}, {}]).then(() => { }),
return User.findAll(); users: User.bulkCreate([{}, {}]).then(() => {
}), return User.findAll();
categories: Category.bulkCreate([{}, {}]).then(() => { }),
return Category.findAll(); categories: Category.bulkCreate([{}, {}]).then(() => {
}) return Category.findAll();
}).then(results => { })
return Promise.all([ });
results.users[0].setGroup(results.groups[1]),
results.users[1].setGroup(results.groups[0]), await Promise.all([
Promise.all(results.groups.map(group => { results.users[0].setGroup(results.groups[1]),
return group.setCategories(results.categories); results.users[1].setGroup(results.groups[0]),
})) Promise.all(results.groups.map(group => {
]); return group.setCategories(results.categories);
}).then(() => { }))
return User.findAll({ ]);
include: [
{ model: Group, required: true, include: [ const users = await User.findAll({
{ model: Category } include: [
] } { model: Group, required: true, include: [
], { model: Category }
limit: 1 ] }
}).then(users => { ],
expect(users.length).to.equal(1); limit: 1
users.forEach(user => { });
expect(user.Group).to.be.ok;
expect(user.Group.Categories).to.be.ok; expect(users.length).to.equal(1);
}); users.forEach(user => {
}); expect(user.Group).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,48 +952,48 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -954,48 +952,48 @@ 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({
groups: Group.bulkCreate([ const results = await promiseProps({
{ name: 'A' }, groups: Group.bulkCreate([
{ name: 'B' } { name: 'A' },
]).then(() => { { name: 'B' }
return Group.findAll(); ]).then(() => {
}), return Group.findAll();
users: User.bulkCreate([{}, {}]).then(() => { }),
return User.findAll(); users: User.bulkCreate([{}, {}]).then(() => {
}), return User.findAll();
categories: Category.bulkCreate([{}, {}]).then(() => { }),
return Category.findAll(); categories: Category.bulkCreate([{}, {}]).then(() => {
}) return Category.findAll();
}).then(results => { })
return Promise.all([ });
results.users[0].setTeam(results.groups[1]),
results.users[1].setTeam(results.groups[0]), await Promise.all([
Promise.all(results.groups.map(group => { results.users[0].setTeam(results.groups[1]),
return group.setTags(results.categories); results.users[1].setTeam(results.groups[0]),
})) Promise.all(results.groups.map(group => {
]); return group.setTags(results.categories);
}).then(() => { }))
return User.findAll({ ]);
include: [
{ model: Group, required: true, as: 'Team', include: [ const users = await User.findAll({
{ model: Category, as: 'Tags' } include: [
] } { model: Group, required: true, as: 'Team', include: [
], { model: Category, as: 'Tags' }
limit: 1 ] }
}).then(users => { ],
expect(users.length).to.equal(1); limit: 1
users.forEach(user => { });
expect(user.Team).to.be.ok;
expect(user.Team.Tags).to.be.ok; expect(users.length).to.equal(1);
}); users.forEach(user => {
}); expect(user.Team).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,48 +1005,48 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1007,48 +1005,48 @@ 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({
groups: Group.bulkCreate([ const results = await promiseProps({
{ name: 'A' }, groups: Group.bulkCreate([
{ name: 'B' } { name: 'A' },
]).then(() => { { name: 'B' }
return Group.findAll(); ]).then(() => {
}), return Group.findAll();
users: User.bulkCreate([{}, {}]).then(() => { }),
return User.findAll(); users: User.bulkCreate([{}, {}]).then(() => {
}), return User.findAll();
categories: Category.bulkCreate([{}, {}]).then(() => { }),
return Category.findAll(); categories: Category.bulkCreate([{}, {}]).then(() => {
}) return Category.findAll();
}).then(results => { })
return Promise.all([ });
results.users[0].setGroup(results.groups[1]),
results.users[1].setGroup(results.groups[0]), await Promise.all([
Promise.all(results.groups.map(group => { results.users[0].setGroup(results.groups[1]),
return group.setCategories(results.categories); results.users[1].setGroup(results.groups[0]),
})) Promise.all(results.groups.map(group => {
]); return group.setCategories(results.categories);
}).then(() => { }))
return User.findAll({ ]);
include: [
{ model: Group, required: true, include: [ const users = await User.findAll({
{ model: Category, required: false } include: [
] } { model: Group, required: true, include: [
], { model: Category, required: false }
limit: 1 ] }
}).then(users => { ],
expect(users.length).to.equal(1); limit: 1
users.forEach(user => { });
expect(user.Group).to.be.ok;
expect(user.Group.Categories).to.be.ok; expect(users.length).to.equal(1);
}); users.forEach(user => {
}); expect(user.Group).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,37 +1054,37 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1056,37 +1054,37 @@ 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({
projects: Project.bulkCreate([ const results = await promiseProps({
{ title: 'Alpha' }, projects: Project.bulkCreate([
{ title: 'Beta' } { title: 'Alpha' },
]).then(() => { { title: 'Beta' }
return Project.findAll(); ]).then(() => {
}), return Project.findAll();
users: User.bulkCreate([{}, {}]).then(() => { }),
return User.findAll(); users: User.bulkCreate([{}, {}]).then(() => {
}) return User.findAll();
}).then(results => { })
return Promise.all([ });
results.users[1].setLeaderOf(results.projects[1]),
results.users[0].setLeaderOf(results.projects[0]) await Promise.all([
]); results.users[1].setLeaderOf(results.projects[1]),
}).then(() => { results.users[0].setLeaderOf(results.projects[0])
return User.findAll({ ]);
include: [
{ model: Project, as: 'LeaderOf', where: { title: 'Beta' } } const users = await User.findAll({
] include: [
}).then(users => { { model: Project, as: 'LeaderOf', where: { title: 'Beta' } }
expect(users.length).to.equal(1); ]
expect(users[0].LeaderOf).to.be.ok;
expect(users[0].LeaderOf.title).to.equal('Beta');
});
});
}); });
expect(users.length).to.equal(1);
expect(users[0].LeaderOf).to.be.ok;
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,42 +1098,42 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1100,42 +1098,42 @@ 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({
products: Product.bulkCreate([ const results = await promiseProps({
{ title: 'Chair' }, products: Product.bulkCreate([
{ title: 'Desk' }, { title: 'Chair' },
{ title: 'Dress' } { title: 'Desk' },
]).then(() => { { title: 'Dress' }
return Product.findAll(); ]).then(() => {
}), return Product.findAll();
tags: Tag.bulkCreate([ }),
{ name: 'A' }, tags: Tag.bulkCreate([
{ name: 'B' }, { name: 'A' },
{ name: 'C' } { name: 'B' },
]).then(() => { { name: 'C' }
return Tag.findAll(); ]).then(() => {
}) return Tag.findAll();
}).then(results => { })
return Promise.all([
results.products[0].addTag(results.tags[0], { priority: 1 }),
results.products[0].addTag(results.tags[1], { priority: 2 }),
results.products[1].addTag(results.tags[1], { priority: 1 }),
results.products[2].addTag(results.tags[0], { priority: 3 }),
results.products[2].addTag(results.tags[1], { priority: 1 }),
results.products[2].addTag(results.tags[2], { priority: 2 })
]);
}).then(() => {
return Product.findAll({
include: [
{ model: Tag, where: { name: 'C' } }
]
}).then(products => {
expect(products.length).to.equal(1);
expect(products[0].Tags.length).to.equal(1);
});
});
}); });
await Promise.all([
results.products[0].addTag(results.tags[0], { priority: 1 }),
results.products[0].addTag(results.tags[1], { priority: 2 }),
results.products[1].addTag(results.tags[1], { priority: 1 }),
results.products[2].addTag(results.tags[0], { priority: 3 }),
results.products[2].addTag(results.tags[1], { priority: 1 }),
results.products[2].addTag(results.tags[2], { priority: 2 })
]);
const products = await Product.findAll({
include: [
{ model: Tag, where: { name: 'C' } }
]
});
expect(products.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() {
...@@ -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,160 +1271,159 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1270,160 +1271,159 @@ 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({
groups: Group.bulkCreate([ const results = await promiseProps({
{ name: 'A' }, groups: Group.bulkCreate([
{ name: 'B' } { name: 'A' },
]).then(() => { { name: 'B' }
return Group.findAll(); ]).then(() => {
}), return Group.findAll();
users: User.bulkCreate([{}, {}, {}, {}]).then(() => { }),
return User.findAll(); users: User.bulkCreate([{}, {}, {}, {}]).then(() => {
}) return User.findAll();
}).then(results => { })
return Promise.all([ });
results.users[0].setGroup(results.groups[0]),
results.users[1].setGroup(results.groups[0]), await Promise.all([
results.users[2].setGroup(results.groups[0]), results.users[0].setGroup(results.groups[0]),
results.users[3].setGroup(results.groups[1]) results.users[1].setGroup(results.groups[0]),
]); results.users[2].setGroup(results.groups[0]),
}).then(() => { results.users[3].setGroup(results.groups[1])
return User.findAll({ ]);
include: [
{ model: Group, where: { name: 'A' } } const users = await User.findAll({
], include: [
limit: 2 { model: Group, where: { name: 'A' } }
}).then(users => { ],
expect(users.length).to.equal(2); limit: 2
});
users.forEach(user => {
expect(user.Group.name).to.equal('A'); expect(users.length).to.equal(2);
});
}); users.forEach(user => {
}); 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({
attributes: ['id', 'title'],
include: [
{ model: this.models.Company, where: { name: 'NYSE' } },
{ model: this.models.Tag },
{ model: this.models.Price }
],
limit: 3,
order: [
[this.sequelize.col(`${this.models.Product.name}.id`), 'ASC']
]
}).then(products => {
expect(products.length).to.equal(3);
products.forEach(product => { const products = await this.models.Product.findAll({
expect(product.Company.name).to.equal('NYSE'); attributes: ['id', 'title'],
expect(product.Tags.length).to.be.ok; include: [
expect(product.Prices.length).to.be.ok; { model: this.models.Company, where: { name: 'NYSE' } },
}); { model: this.models.Tag },
}); { model: this.models.Price }
],
limit: 3,
order: [
[this.sequelize.col(`${this.models.Product.name}.id`), 'ASC']
]
});
expect(products.length).to.equal(3);
products.forEach(product => {
expect(product.Company.name).to.equal('NYSE');
expect(product.Tags.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([
Parent.create(), const [parent0, child] = await Promise.all([
Child1.create() Parent.create(),
]); Child1.create()
}).then(([parent, child]) => { ]);
return parent.addChild1(child).then(() => {
return parent; await parent0.addChild1(child);
}); const parent = parent0;
}).then(parent => {
return Child1.findOne({ await Child1.findOne({
include: [ include: [
{ {
model: Parent, model: Parent,
attributes: ['id'], // This causes a duplicated entry in the query attributes: ['id'], // This causes a duplicated entry in the query
where: { where: {
id: parent.id id: parent.id
}
} }
] }
}); ]
}); });
}); });
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({
attributes: ['title'], const products = await this.models.Product.findAll({
include: [ attributes: ['title'],
{ model: this.models.Tag, through: { attributes: [] }, required: true } include: [
] { model: this.models.Tag, through: { attributes: [] }, required: true }
}).then(products => { ]
products.forEach(product => { });
expect(product.Tags.length).to.be.ok;
product.Tags.forEach(tag => { products.forEach(product => {
expect(tag.get().productTags).not.to.be.ok; expect(product.Tags.length).to.be.ok;
}); product.Tags.forEach(tag => {
}); expect(tag.get().productTags).not.to.be.ok;
}); });
}); });
}); });
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({
attributes: ['title'], const products = await this.models.Product.findAll({
include: [ attributes: ['title'],
{ include: [
model: this.models.Tag, {
through: { model: this.models.Tag,
where: { through: {
ProductId: 3 where: {
} ProductId: 3
}, }
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({
attributes: ['title'], const products = await this.models.Product.findAll({
include: [ attributes: ['title'],
{ include: [
model: this.models.Tag, {
through: { model: this.models.Tag,
where: { through: {
ProductId: 3 where: {
} ProductId: 3
}, }
required: true },
} required: true
], }
limit: 5 ],
}).then(products => { limit: 5
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,101 +1457,99 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1457,101 +1457,99 @@ 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;
for (let i = 1; i <= memberCount; i++) {
members.push({
id: i,
email: `email${i}@lmu.com`,
password: `testing${i}`
});
albums.push({
title: `Album${i}`,
MemberId: i
});
}
for (let i = 1; i <= memberCount; i++) { await Member.bulkCreate(members);
members.push({ await Album.bulkCreate(albums);
id: i,
email: `email${i}@lmu.com`,
password: `testing${i}`
});
albums.push({
title: `Album${i}`,
MemberId: i
});
}
return Member.bulkCreate(members).then(() => { const members0 = await Member.findAll({
return Album.bulkCreate(albums).then(() => { attributes: ['email'],
return Member.findAll({ include: [
attributes: ['email'], {
include: [ model: Album
{ }
model: Album ]
} });
]
}).then(members => { expect(members0.length).to.equal(20);
expect(members.length).to.equal(20); members0.forEach(member => {
members.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({
include: [
{ model: this.models.Company },
{ model: this.models.Tag },
{ model: this.models.Price, where: {
value: { [Op.gt]: 5 }
} }
],
limit: 6,
order: [
['id', 'ASC']
]
}).then(products => {
expect(products.length).to.equal(6);
products.forEach(product => { const products = await this.models.Product.findAll({
expect(product.Tags.length).to.be.ok; include: [
expect(product.Prices.length).to.be.ok; { model: this.models.Company },
{ model: this.models.Tag },
{ model: this.models.Price, where: {
value: { [Op.gt]: 5 }
} }
],
limit: 6,
order: [
['id', 'ASC']
]
});
product.Prices.forEach(price => { expect(products.length).to.equal(6);
expect(price.value).to.be.above(5);
}); products.forEach(product => {
}); expect(product.Tags.length).to.be.ok;
expect(product.Prices.length).to.be.ok;
product.Prices.forEach(price => {
expect(price.value).to.be.above(5);
}); });
}); });
}); });
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({
include: [ const products = await this.models.Product.findAll({
{ model: this.models.Company }, include: [
{ model: this.models.Tag, where: { name: ['A', 'B', 'C'] } }, { model: this.models.Company },
{ model: this.models.Price } { model: this.models.Tag, where: { name: ['A', 'B', 'C'] } },
], { model: this.models.Price }
limit: 10, ],
order: [ limit: 10,
['id', 'ASC'] order: [
] ['id', 'ASC']
}).then(products => { ]
expect(products.length).to.equal(10); });
products.forEach(product => { expect(products.length).to.equal(10);
expect(product.Tags.length).to.be.ok;
expect(product.Prices.length).to.be.ok;
product.Tags.forEach(tag => { products.forEach(product => {
expect(['A', 'B', 'C']).to.include(tag.name); expect(product.Tags.length).to.be.ok;
}); expect(product.Prices.length).to.be.ok;
});
product.Tags.forEach(tag => {
expect(['A', 'B', 'C']).to.include(tag.name);
}); });
}); });
}); });
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({
where: { const users = await User.findAll({
id: user.id where: {
}, id: user.id
include: [Group] },
}).then(users => { include: [Group]
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].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 } ]
] });
});
}) expect(as.length).to.equal(1);
.then(as => { expect(as[0].get('bs')).deep.equal([]);
expect(as.length).to.equal(1);
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,38 +1615,38 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1623,38 +1615,38 @@ 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([
Post.create({ 'public': true }), 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 }),
]).then(posts => { Post.create({ 'public': true })
return Promise.all(posts.slice(1, 3).map(post => { ]);
return post.createCategory({ slug: 'food' });
})); await Promise.all(posts0.slice(1, 3).map(post => {
}).then(() => { return post.createCategory({ slug: 'food' });
return Post.findAll({ }));
limit: 2,
const posts = await Post.findAll({
limit: 2,
where: {
'public': true
},
include: [
{
model: Category,
where: { where: {
'public': true slug: 'food'
}, }
include: [ }
{ ]
model: Category,
where: {
slug: 'food'
}
}
]
}).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,26 +1706,26 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1714,26 +1706,26 @@ describe(Support.getTestDialectTeaser('Include'), () => {
onDelete: 'CASCADE' onDelete: 'CASCADE'
}); });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Person.findAll({
offset: 0, await Person.findAll({
limit: 20, offset: 0,
attributes: ['id', 'name'], limit: 20,
attributes: ['id', 'name'],
include: [{
model: UserPerson,
required: true,
attributes: ['rank'],
include: [{ include: [{
model: UserPerson, model: User,
required: true, required: true,
attributes: ['rank'], attributes: ['login']
include: [{
model: User,
required: true,
attributes: ['login']
}]
}] }]
}); }]
}); });
}); });
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({
include: [ await User.findAll({
{ model: Group, where: {} }, include: [
{ model: Company, where: {} } { model: Group, 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,44 +1755,44 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1763,44 +1755,44 @@ 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([
User.create({ lastName: 'Albertsen' }), const [albertsen, zenith, hansen, company1, company2] = await Promise.all([
User.create({ lastName: 'Zenith' }), User.create({ lastName: 'Albertsen' }),
User.create({ lastName: 'Hansen' }), User.create({ lastName: 'Zenith' }),
Company.create({ rank: 1 }), User.create({ lastName: 'Hansen' }),
Company.create({ rank: 2 }) Company.create({ rank: 1 }),
]).then(([albertsen, zenith, hansen, company1, company2]) => { Company.create({ rank: 2 })
return Promise.all([ ]);
albertsen.setCompany(company1),
zenith.setCompany(company2), await Promise.all([
hansen.setCompany(company2) albertsen.setCompany(company1),
]); zenith.setCompany(company2),
}).then(() => { hansen.setCompany(company2)
return User.findAll({ ]);
include: [
{ model: Company, required: true } const users = await User.findAll({
], include: [
order: [ { model: Company, required: true }
[Company, 'rank', 'ASC'], ],
['lastName', 'DESC'] order: [
], [Company, 'rank', 'ASC'],
limit: 5 ['lastName', 'DESC']
}).then(users => { ],
expect(users[0].lastName).to.equal('Albertsen'); limit: 5
expect(users[0].Company.rank).to.equal(1);
expect(users[1].lastName).to.equal('Zenith');
expect(users[1].Company.rank).to.equal(2);
expect(users[2].lastName).to.equal('Hansen');
expect(users[2].Company.rank).to.equal(2);
});
});
}); });
expect(users[0].lastName).to.equal('Albertsen');
expect(users[0].Company.rank).to.equal(1);
expect(users[1].lastName).to.equal('Zenith');
expect(users[1].Company.rank).to.equal(2);
expect(users[2].lastName).to.equal('Hansen');
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,40 +1802,40 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1810,40 +1802,40 @@ 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({
title: Math.random().toString(),
comments: [
{ content: Math.random().toString() },
{ content: Math.random().toString() },
{ content: Math.random().toString() }
]
}, {
include: [Post.Comments]
});
}).then(() => {
return Post.findAll({
attributes: [
[this.sequelize.fn('COUNT', this.sequelize.col('comments.id')), 'commentCount']
],
include: [
{ association: Post.Comments, attributes: [] }
],
group: [
'Post.id'
]
});
}).then(posts => {
expect(posts.length).to.equal(1);
const post = posts[0]; await Post.create({
title: Math.random().toString(),
comments: [
{ content: Math.random().toString() },
{ content: Math.random().toString() },
{ content: Math.random().toString() }
]
}, {
include: [Post.Comments]
});
expect(post.get('comments')).not.to.be.ok; const posts = await Post.findAll({
expect(parseInt(post.get('commentCount'), 10)).to.equal(3); attributes: [
[this.sequelize.fn('COUNT', this.sequelize.col('comments.id')), 'commentCount']
],
include: [
{ association: Post.Comments, attributes: [] }
],
group: [
'Post.id'
]
}); });
expect(posts.length).to.equal(1);
const post = posts[0];
expect(post.get('comments')).not.to.be.ok;
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,39 +1845,38 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1853,39 +1845,38 @@ 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({
title: Math.random().toString(),
comments: [
{ content: Math.random().toString() },
{ content: Math.random().toString() },
{ content: Math.random().toString() }
]
}, {
include: [Post.Comments]
});
}).then(() => {
return Post.findAll({
attributes: [],
include: [
{
association: Post.Comments,
attributes: [[this.sequelize.fn('COUNT', this.sequelize.col('comments.id')), 'commentCount']]
}
],
raw: true
});
}).then(posts => {
expect(posts.length).to.equal(1);
const post = posts[0]; await Post.create({
expect(post.id).not.to.be.ok; title: Math.random().toString(),
expect(parseInt(post['comments.commentCount'], 10)).to.equal(3); comments: [
{ content: Math.random().toString() },
{ content: Math.random().toString() },
{ content: Math.random().toString() }
]
}, {
include: [Post.Comments]
}); });
});
it('Should return posts with nested include with inner join with a m:n association', function() { const posts = await Post.findAll({
attributes: [],
include: [
{
association: Post.Comments,
attributes: [[this.sequelize.fn('COUNT', this.sequelize.col('comments.id')), 'commentCount']]
}
],
raw: true
});
expect(posts.length).to.equal(1);
const post = posts[0];
expect(post.id).not.to.be.ok;
expect(parseInt(post['comments.commentCount'], 10)).to.equal(3);
});
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,45 +1933,46 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -1942,45 +1933,46 @@ 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([
Post.create({ post_id: entity.entity_id }), await Promise.all([
entity.addTags('bob') Post.create({ post_id: entity.entity_id }),
])) entity.addTags('bob')
.then(() => Post.findAll({ ]);
const posts = await Post.findAll({
include: [{
model: Entity,
required: true,
include: [{ include: [{
model: Entity, model: User,
required: true
}, {
model: TaggableSentient,
as: 'tags',
required: true, required: true,
include: [{ through: {
model: User, where: {
required: true tag_name: ['bob']
}, {
model: TaggableSentient,
as: 'tags',
required: true,
through: {
where: {
tag_name: ['bob']
}
} }
}] }
}], }]
limit: 5, }],
offset: 0 limit: 5,
})) offset: 0
.then(posts => { });
expect(posts.length).to.equal(1);
expect(posts[0].Entity.creator).to.equal('bob'); expect(posts.length).to.equal(1);
expect(posts[0].Entity.tags.length).to.equal(1); expect(posts[0].Entity.creator).to.equal('bob');
expect(posts[0].Entity.tags[0].EntityTag.tag_name).to.equal('bob'); expect(posts[0].Entity.tags.length).to.equal(1);
expect(posts[0].Entity.tags[0].EntityTag.entity_id).to.equal(posts[0].post_id); 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);
}); });
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,45 +1999,45 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -2007,45 +1999,45 @@ 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: [{
model: Order,
required: true,
include: [{ include: [{
model: Order, model: Customer,
required: true,
include: [{ include: [{
model: Customer, model: ShippingAddress,
include: [{ where: { verified: true }
model: ShippingAddress,
where: { verified: true }
}]
}] }]
}] }]
}); }]
}); });
}); });
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({
attributes: ['title'], const products = await this.models.Product.findAll({
include: [ attributes: ['title'],
{ model: this.models.User }, include: [
{ model: this.models.Price } { model: this.models.User },
], { model: this.models.Price }
limit: 10 ],
}).then( products => { limit: 10
expect(products).to.be.an('array');
expect(products).to.be.lengthOf(10);
for (const product of products) {
expect(product.title).to.be.a('string');
// checking that internally added fields used to handle 'BelongsTo' associations are not leaked to result
expect(product.UserId).to.be.equal(undefined);
// checking that included models are on their places
expect(product.User).to.satisfy( User => User === null || User instanceof this.models.User );
expect(product.Prices).to.be.an('array');
}
});
}); });
expect(products).to.be.an('array');
expect(products).to.be.lengthOf(10);
for (const product of products) {
expect(product.title).to.be.a('string');
// checking that internally added fields used to handle 'BelongsTo' associations are not leaked to result
expect(product.UserId).to.be.equal(undefined);
// checking that included models are on their places
expect(product.User).to.satisfy( User => User === null || User instanceof this.models.User );
expect(product.Prices).to.be.an('array');
}
}); });
}); });
}); });
...@@ -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,47 +29,47 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -29,47 +29,47 @@ 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
return Promise.all([Project.bulkCreate([ // Create an enviroment
{ id: 1, name: 'No tasks' }, await Promise.all([Project.bulkCreate([
{ id: 2, name: 'No tasks no employees' }, { id: 1, name: 'No tasks' },
{ id: 3, name: 'No employees' }, { id: 2, name: 'No tasks no employees' },
{ id: 4, name: 'In progress A' }, { id: 3, name: 'No employees' },
{ id: 5, name: 'In progress B' }, { id: 4, name: 'In progress A' },
{ id: 6, name: 'In progress C' } { id: 5, name: 'In progress B' },
]), Task.bulkCreate([ { id: 6, name: 'In progress C' }
{ name: 'Important task', fk: 3 }, ]), Task.bulkCreate([
{ name: 'Important task', fk: 4 }, { name: 'Important task', fk: 3 },
{ name: 'Important task', fk: 5 }, { name: 'Important task', fk: 4 },
{ name: 'Important task', fk: 6 } { name: 'Important task', fk: 5 },
]), Employee.bulkCreate([ { name: 'Important task', fk: 6 }
{ name: 'Jane Doe', fk: 1 }, ]), Employee.bulkCreate([
{ name: 'John Doe', fk: 4 }, { name: 'Jane Doe', fk: 1 },
{ name: 'Jane John Doe', fk: 5 }, { name: 'John Doe', fk: 4 },
{ name: 'John Jane Doe', fk: 6 } { name: 'Jane John Doe', fk: 5 },
])]).then(() =>{ { name: 'John Jane Doe', fk: 6 }
//Find all projects with tasks and employees ])]);
const availableProjects = 3;
const limit = 2; //Find all projects with tasks and employees
const availableProjects = 3;
return Project.findAndCountAll({ const limit = 2;
include: [{
model: Task, required: true const result = await Project.findAndCountAll({
}, include: [{
{ model: Task, required: true
model: Employee, required: true },
}], {
limit model: Employee, required: true
}).then(result => { }],
expect(result.count).to.be.equal(availableProjects); limit
expect(result.rows.length).to.be.equal(limit, 'Complete set of available rows were not returned.');
});
});
}); });
expect(result.count).to.be.equal(availableProjects);
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,79 +93,80 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -93,79 +93,80 @@ 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([
{ name: 'Youtube' }, await Promise.all([User.bulkCreate([
{ name: 'Facebook' }, { name: 'Youtube' },
{ name: 'Google' }, { name: 'Facebook' },
{ name: 'Yahoo' }, { name: 'Google' },
{ name: '404' } { name: 'Yahoo' },
]), SomeConnection.bulkCreate([ // Lets count, m: A and u: 1 { name: '404' }
{ u: 1, m: 'A', fk: 1 }, // 1 // Will be deleted ]), SomeConnection.bulkCreate([ // Lets count, m: A and u: 1
{ u: 2, m: 'A', fk: 1 }, { u: 1, m: 'A', fk: 1 }, // 1 // Will be deleted
{ u: 3, m: 'A', fk: 1 }, { u: 2, m: 'A', fk: 1 },
{ u: 4, m: 'A', fk: 1 }, { u: 3, m: 'A', fk: 1 },
{ u: 5, m: 'A', fk: 1 }, { u: 4, m: 'A', fk: 1 },
{ u: 1, m: 'B', fk: 1 }, { u: 5, m: 'A', fk: 1 },
{ u: 2, m: 'B', fk: 1 }, { u: 1, m: 'B', fk: 1 },
{ u: 3, m: 'B', fk: 1 }, { u: 2, m: 'B', fk: 1 },
{ u: 4, m: 'B', fk: 1 }, { u: 3, m: 'B', fk: 1 },
{ u: 5, m: 'B', fk: 1 }, { u: 4, m: 'B', fk: 1 },
{ u: 1, m: 'C', fk: 1 }, { u: 5, m: 'B', fk: 1 },
{ u: 2, m: 'C', fk: 1 }, { u: 1, m: 'C', fk: 1 },
{ u: 3, m: 'C', fk: 1 }, { u: 2, m: 'C', fk: 1 },
{ u: 4, m: 'C', fk: 1 }, { u: 3, m: 'C', fk: 1 },
{ u: 5, m: 'C', fk: 1 }, { u: 4, m: 'C', fk: 1 },
{ u: 1, m: 'A', fk: 2 }, // 2 // Will be deleted { u: 5, m: 'C', fk: 1 },
{ u: 4, m: 'A', fk: 2 }, { u: 1, m: 'A', fk: 2 }, // 2 // Will be deleted
{ u: 2, m: 'A', fk: 2 }, { u: 4, m: 'A', fk: 2 },
{ u: 1, m: 'A', fk: 3 }, // 3 { u: 2, m: 'A', fk: 2 },
{ u: 2, m: 'A', fk: 3 }, { u: 1, m: 'A', fk: 3 }, // 3
{ u: 3, m: 'A', fk: 3 }, { u: 2, m: 'A', fk: 3 },
{ u: 2, m: 'B', fk: 2 }, { u: 3, m: 'A', fk: 3 },
{ u: 1, m: 'A', fk: 4 }, // 4 { u: 2, m: 'B', fk: 2 },
{ u: 4, m: 'A', fk: 2 } { u: 1, m: 'A', fk: 4 }, // 4
]), A.bulkCreate([ { u: 4, m: 'A', fk: 2 }
{ name: 'Just' }, ]), A.bulkCreate([
{ name: 'for' }, { name: 'Just' },
{ name: 'testing' }, { name: 'for' },
{ name: 'proposes' }, { name: 'testing' },
{ name: 'only' } { name: 'proposes' },
]), B.bulkCreate([ { name: 'only' }
{ name: 'this should not' }, ]), B.bulkCreate([
{ name: 'be loaded' } { name: 'this should not' },
]), C.bulkCreate([ { name: 'be loaded' }
{ name: 'because we only want A' } ]), C.bulkCreate([
])]).then(() => { { name: 'because we only want A' }
// Delete some of conns to prove the concept ])]);
return SomeConnection.destroy({ where: {
m: 'A', // Delete some of conns to prove the concept
u: 1, await SomeConnection.destroy({ where: {
fk: [1, 2] m: 'A',
} }).then(() => { u: 1,
this.clock.tick(1000); fk: [1, 2]
// Last and most important queries ( we connected 4, but deleted 2, witch means we must get 2 only ) } });
return A.findAndCountAll({
include: [{ this.clock.tick(1000);
model: SomeConnection, required: true,
where: { // Last and most important queries ( we connected 4, but deleted 2, witch means we must get 2 only )
m: 'A', // Pseudo Polymorphy const result = await A.findAndCountAll({
u: 1 include: [{
} model: SomeConnection, required: true,
}], where: {
limit: 5 m: 'A', // Pseudo Polymorphy
}).then(result => { u: 1
expect(result.count).to.be.equal(2); }
expect(result.rows.length).to.be.equal(2); }],
}); limit: 5
});
});
}); });
expect(result.count).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()]); const user = results[0];
}).then(results => { userId = user.id;
const user = results[0]; await user.setProjects([results[1], results[2], results[3]]);
userId = user.id;
return user.setProjects([results[1], results[2], results[3]]); const result = await User.findAndCountAll({
}).then(() => { where: { id: userId },
return User.findAndCountAll({ include: [Project],
where: { id: userId }, distinct: true
include: [Project],
distinct: true
});
}).then(result => {
expect(result.rows.length).to.equal(1);
expect(result.rows[0].Projects.length).to.equal(3);
expect(result.count).to.equal(1);
}); });
expect(result.rows.length).to.equal(1);
expect(result.rows[0].Projects.length).to.equal(3);
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 await Bar.bulkCreate([{ 'FooId': 2 }, { 'FooId': 3 }, { 'FooId': 4 }, { 'FooId': 5 }]);
return 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 const result0 = await Foo.findAndCountAll({
return Foo.findAndCountAll({ include: [{ model: Bar, required: true }],
include: [{ model: Bar, required: true }], limit: 2
limit: 2
}).then(result => {
return Promise.resolve(Foo.findAll({
include: [{ model: Bar, required: true }],
limit: 2
}).then(items => {
expect(items.length).to.equal(2);
})).then(() => result);
});
}).then(result => {
expect(result.count).to.equal(4);
// The first two of those should be returned due to the limit (Foo
// instances 2 and 3)
expect(result.rows.length).to.equal(2);
}); });
const items = await Foo.findAll({
include: [{ model: Bar, required: true }],
limit: 2
});
expect(items.length).to.equal(2);
const result = result0;
expect(result.count).to.equal(4);
// The first two of those should be returned due to the limit (Foo
// instances 2 and 3)
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 await Bar.bulkCreate([{ 'FooId': 1, m: 'yes' }, { 'FooId': 1, m: 'yes' }, { 'FooId': 1, m: 'no' }, { 'FooId': 2, m: 'yes' }]);
return 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' const result = await Foo.findAndCountAll({
return 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
expect(result.count).to.equal(2);
// The first one of those should be returned due to the limit (Foo instance 1)
expect(result.rows.length).to.equal(1);
}); });
// There should be 2 instances matching the query (Instances 1 and 2), see the findAll statement
expect(result.count).to.equal(2);
// The first one of those should be returned due to the limit (Foo instance 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,52 +288,52 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -293,52 +288,52 @@ 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
return User.bulkCreate([ // Create an enviroment
{ name: 'user-name-1' }, await User.bulkCreate([
{ name: 'user-name-2' } { name: 'user-name-1' },
]).then(() => { { name: 'user-name-2' }
return Project.bulkCreate([ ]);
{ m: 'A', UserId: 1 },
{ m: 'A', UserId: 2 } await Project.bulkCreate([
]); { m: 'A', UserId: 1 },
}).then(() => { { m: 'A', UserId: 2 }
return Task.bulkCreate([ ]);
{ ProjectId: 1, name: 'Just' },
{ ProjectId: 1, name: 'for' }, await Task.bulkCreate([
{ ProjectId: 2, name: 'testing' }, { ProjectId: 1, name: 'Just' },
{ ProjectId: 2, name: 'proposes' } { ProjectId: 1, name: 'for' },
]); { ProjectId: 2, name: 'testing' },
}) { ProjectId: 2, name: 'proposes' }
.then(() => { ]);
// Find All Tasks with Project(m=a) and User(name=user-name-2)
return Task.findAndCountAll({ // Find All Tasks with Project(m=a) and User(name=user-name-2)
limit: 1, const result = await Task.findAndCountAll({
offset: 0, limit: 1,
order: [['id', 'DESC']], offset: 0,
include: [ order: [['id', 'DESC']],
{ include: [
model: Project, {
where: { [Op.and]: [{ m: 'A' }] }, model: Project,
include: [{ where: { [Op.and]: [{ m: 'A' }] },
model: User, include: [{
where: { [Op.and]: [{ name: 'user-name-2' }] } model: User,
} where: { [Op.and]: [{ name: 'user-name-2' }] }
] }
}, ]
{ model: Tag } },
] { model: Tag }
}); ]
});
}).then(result => {
expect(result.count).to.equal(2);
expect(result.rows.length).to.equal(1);
}); });
expect(result.count).to.equal(2);
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,41 +348,40 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -353,41 +348,40 @@ 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([
{ first_name: 'user-fname-1', last_name: 'user-lname-1' }, await User.bulkCreate([
{ first_name: 'user-fname-2', last_name: 'user-lname-2' }, { first_name: 'user-fname-1', last_name: 'user-lname-1' },
{ first_name: 'user-xfname-1', last_name: 'user-xlname-1' } { first_name: 'user-fname-2', last_name: 'user-lname-2' },
]); { first_name: 'user-xfname-1', last_name: 'user-xlname-1' }
}).then(() => { ]);
return Project.bulkCreate([
{ name: 'naam-satya', UserId: 1 }, await Project.bulkCreate([
{ name: 'guru-satya', UserId: 2 }, { name: 'naam-satya', UserId: 1 },
{ name: 'app-satya', UserId: 2 } { name: 'guru-satya', UserId: 2 },
]); { name: 'app-satya', UserId: 2 }
}).then(() => { ]);
return User.findAndCountAll({
limit: 1, const result = await User.findAndCountAll({
offset: 1, limit: 1,
where: sequelize.or( offset: 1,
{ first_name: { [Op.like]: '%user-fname%' } }, where: sequelize.or(
{ last_name: { [Op.like]: '%user-lname%' } } { first_name: { [Op.like]: '%user-fname%' } },
), { last_name: { [Op.like]: '%user-lname%' } }
include: [ ),
{ include: [
model: Project, {
required: true, model: Project,
where: { name: { required: true,
[Op.in]: ['naam-satya', 'guru-satya'] where: { name: {
} } [Op.in]: ['naam-satya', 'guru-satya']
} } }
] }
}); ]
}).then(result => {
expect(result.count).to.equal(2);
expect(result.rows.length).to.equal(1);
}); });
expect(result.count).to.equal(2);
expect(result.rows.length).to.equal(1);
}); });
}); });
}); });
...@@ -9,10 +9,10 @@ const chai = require('chai'), ...@@ -9,10 +9,10 @@ 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 }),
D = this.sequelize.define('D', { name: DataTypes.STRING(40) }, { paranoid: true }); D = this.sequelize.define('D', { name: DataTypes.STRING(40) }, { paranoid: true });
// Associations // Associations
...@@ -29,19 +29,19 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -29,19 +29,19 @@ 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({
include: [ await A.findOne({
{ model: B, required: false, include: [ include: [
{ model: C, required: false }, { model: B, required: false, include: [
{ model: D } { model: C, required: false },
] } { model: D }
] ] }
}); ]
}); });
}); });
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,18 +52,18 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -52,18 +52,18 @@ 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({
include: [ await Model.findOne({
{ model: Model2, include: [ include: [
{ model: Model4, where: { something: 2 } } { model: Model2, include: [
] } { model: Model4, where: { something: 2 } }
] ] }
}); ]
}); });
}); });
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 => {
return Task.bulkCreate([
{ userId: user.get('id'), deletedAt: new Date() },
{ userId: user.get('id'), deletedAt: new Date() },
{ userId: user.get('id'), deletedAt: new Date() }
]);
}).then(() => {
return User.findOne({
include: [
{ model: Task, where: { deletedAt: null }, required: false }
]
});
}).then(user => {
expect(user).to.be.ok;
expect(user.Tasks.length).to.equal(0);
}); });
const user0 = await User.create();
await Task.bulkCreate([
{ userId: user0.get('id'), deletedAt: new Date() },
{ userId: user0.get('id'), deletedAt: new Date() },
{ userId: user0.get('id'), deletedAt: new Date() }
]);
const user = await User.findOne({
include: [
{ model: Task, where: { deletedAt: null }, required: false }
]
});
expect(user).to.be.ok;
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 => {
return Task.bulkCreate([
{ userId: user.get('id'), searchString: 'one' },
{ userId: user.get('id'), searchString: 'two' }
]);
}).then(() => {
return User.findOne({
include: [
{ model: Task, where: { searchString: 'one' } }
]
});
}).then(user => {
expect(user).to.be.ok;
expect(user.Tasks.length).to.equal(1);
}); });
const user0 = await User.create();
await Task.bulkCreate([
{ userId: user0.get('id'), searchString: 'one' },
{ userId: user0.get('id'), searchString: 'two' }
]);
const user = await User.findOne({
include: [
{ model: Task, where: { searchString: 'one' } }
]
});
expect(user).to.be.ok;
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({
}) include: [
.then(() => { { model: B, through: { where: { name: 'Foobar' } }, required: true }
return A.findOne({ ]
include: [ });
{ model: B, through: { where: { name: 'Foobar' } }, required: true }
] expect(a).to.not.equal(null);
}); expect(a.get('bs')).to.have.length(1);
})
.then(a => {
expect(a).to.not.equal(null);
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 } ]
] });
});
}) expect(a).to.not.equal(null);
.then(a => { expect(a.get('bs')).to.deep.equal([]);
expect(a).to.not.equal(null);
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,53 +212,47 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -220,53 +212,47 @@ 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: [
{
model: B,
where: { flag: true },
include: [ include: [
{ {
model: B, model: C
where: { flag: true },
include: [
{
model: C
}
]
} }
] ]
}); }
}) ]
.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({
where: { title: 'some task' }, const foundTask = await Task.findOne({
include: [{ model: User }] where: { title: 'some task' },
}) include: [{ model: User }]
.then(foundTask => {
expect(foundTask).to.be.ok;
expect(foundTask.User.username).to.equal('bob');
});
});
});
});
}); });
expect(foundTask).to.be.ok;
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,65 +274,65 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -288,65 +274,65 @@ 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) {
let promise = Promise.resolve(),
previousInstance,
b;
singles.forEach(model => { const [a0, b] = await Promise.all([A.create({}), (function(singles) {
const values = {}; let promise = Promise.resolve(),
previousInstance,
b;
if (model.name === 'g') { singles.forEach(model => {
values.name = 'yolo'; const values = {};
if (model.name === 'g') {
values.name = 'yolo';
}
promise = (async () => {
await promise;
const instance = await model.create(values);
if (previousInstance) {
await previousInstance[`set${_.upperFirst(model.name)}`](instance);
previousInstance = instance;
return;
} }
previousInstance = b = instance;
})();
});
promise = promise.then(() => { promise = promise.then(() => {
return model.create(values).then(instance => { return b;
if (previousInstance) { });
return previousInstance[`set${_.upperFirst(model.name)}`](instance).then(() => {
previousInstance = instance; return promise;
}); })([B, C, D, E, F, G, H])]);
}
previousInstance = b = instance; await a0.setB(b);
});
}); const a = await A.findOne({
}); include: [
{ model: B, include: [
promise = promise.then(() => { { model: C, include: [
return b; { model: D, include: [
}); { model: E, include: [
{ model: F, include: [
return promise; { model: G, where: {
})([B, C, D, E, F, G, H])]).then(([a, b]) => { name: 'yolo'
return a.setB(b); }, include: [
}).then(() => { { model: H }
return A.findOne({
include: [
{ model: B, include: [
{ model: C, include: [
{ model: D, include: [
{ model: E, include: [
{ model: F, include: [
{ model: G, where: {
name: 'yolo'
}, include: [
{ model: H }
] }
] }
] } ] }
] } ] }
] } ] }
] } ] }
] ] }
}).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,13 +348,13 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -362,13 +348,13 @@ 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({
where: { id: 2 }, await User.findOne({
include: [ where: { id: 2 },
{ model: Post, as: 'UserPosts', where: { 'private': true } } include: [
] { model: Post, as: 'UserPosts', where: { 'private': true } }
}); ]
}); });
}); });
}); });
......
...@@ -125,587 +125,621 @@ describe(Support.getTestDialectTeaser('Include'), () => { ...@@ -125,587 +125,621 @@ 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([
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')), const [projects, users] = await Promise.all([
this.User.bulkCreate(build('Alice', 'Bob')) this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')),
])) this.User.bulkCreate(build('Alice', 'Bob'))
.then(([projects, users]) => Promise.all([ ]);
projects[0].addUser(users[0]),
projects[1].addUser(users[1]), await Promise.all([
projects[2].addUser(users[0]) projects[0].addUser(users[0]),
])) projects[1].addUser(users[1]),
.then(() => this.Project.findAll({ projects[2].addUser(users[0])
]);
const result = await this.Project.findAll({
include: [{
model: this.User,
where: {
name: 'Alice'
}
}],
order: ['name'],
limit: 1,
offset: 1
});
expect(result.length).to.equal(1);
expect(result[0].name).to.equal('charlie');
});
it('supports 2 levels of required many-to-many associations', async function() {
await this.sequelize.sync({ force: true });
const [projects, users, hobbies] = await Promise.all([
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')),
this.User.bulkCreate(build('Alice', 'Bob')),
this.Hobby.bulkCreate(build('archery', 'badminton'))
]);
await Promise.all([
projects[0].addUser(users[0]),
projects[1].addUser(users[1]),
projects[2].addUser(users[0]),
users[0].addHobby(hobbies[0])
]);
const result = await this.Project.findAll({
include: [{
model: this.User,
required: true,
include: [{ include: [{
model: this.User, model: this.Hobby,
where: { required: true
name: 'Alice' }]
} }],
}], 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 with where clause', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')), const [projects, users, hobbies] = await Promise.all([
this.User.bulkCreate(build('Alice', 'Bob')), this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')),
this.Hobby.bulkCreate(build('archery', 'badminton')) this.User.bulkCreate(build('Alice', 'Bob')),
])) this.Hobby.bulkCreate(build('archery', 'badminton'))
.then(([projects, users, hobbies]) => Promise.all([ ]);
projects[0].addUser(users[0]),
projects[1].addUser(users[1]), await Promise.all([
projects[2].addUser(users[0]), projects[0].addUser(users[0]),
users[0].addHobby(hobbies[0]) projects[1].addUser(users[1]),
])) projects[2].addUser(users[0]),
.then(() => this.Project.findAll({ users[0].addHobby(hobbies[0]),
users[1].addHobby(hobbies[1])
]);
const result = await this.Project.findAll({
include: [{
model: this.User,
required: true,
include: [{ include: [{
model: this.User, model: this.Hobby,
required: true, where: {
include: [{ name: 'archery'
model: this.Hobby, }
required: true }]
}] }],
}], 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 through.where clause', async function() {
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => Promise.all([
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')), const [projects, users, hobbies] = await Promise.all([
this.User.bulkCreate(build('Alice', 'Bob')), this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')),
this.Hobby.bulkCreate(build('archery', 'badminton')) this.User.bulkCreate(build('Alice', 'Bob')),
])) this.Hobby.bulkCreate(build('archery', 'badminton'))
.then(([projects, users, hobbies]) => Promise.all([ ]);
projects[0].addUser(users[0]),
projects[1].addUser(users[1]), await Promise.all([
projects[2].addUser(users[0]), projects[0].addUser(users[0]),
users[0].addHobby(hobbies[0]), projects[1].addUser(users[1]),
users[1].addHobby(hobbies[1]) projects[2].addUser(users[0]),
])) users[0].addHobby(hobbies[0]),
.then(() => this.Project.findAll({ users[1].addHobby(hobbies[1])
]);
const result = await this.Project.findAll({
include: [{
model: this.User,
required: true,
include: [{ include: [{
model: this.User, model: this.Hobby,
required: true, required: true,
include: [{ through: {
model: this.Hobby,
where: { where: {
name: 'archery' HobbyName: 'archery'
} }
}] }
}], }]
order: ['name'], }],
limit: 1, order: ['name'],
offset: 1 limit: 1,
})) offset: 1
.then(result => { });
expect(result.length).to.equal(1);
expect(result[0].name).to.equal('charlie'); expect(result.length).to.equal(1);
}); expect(result[0].name).to.equal('charlie');
}); });
it('supports 2 levels of required many-to-many associations with through.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([
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')), const [tasks, projects, users, hobbies] = await Promise.all([
this.User.bulkCreate(build('Alice', 'Bob')), this.Task.bulkCreate(build('alpha', 'bravo', 'charlie')),
this.Hobby.bulkCreate(build('archery', 'badminton')) this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')),
])) this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte')),
.then(([projects, users, hobbies]) => Promise.all([ this.Hobby.bulkCreate(build('archery', 'badminton'))
projects[0].addUser(users[0]), ]);
projects[1].addUser(users[1]),
projects[2].addUser(users[0]), await Promise.all([
users[0].addHobby(hobbies[0]), tasks[0].addProject(projects[0]),
users[1].addHobby(hobbies[1]) tasks[1].addProject(projects[1]),
])) tasks[2].addProject(projects[2]),
.then(() => this.Project.findAll({ projects[0].addUser(users[0]),
projects[1].addUser(users[1]),
projects[2].addUser(users[0]),
users[0].addHobby(hobbies[0]),
users[1].addHobby(hobbies[1])
]);
const result = await this.Task.findAll({
include: [{
model: this.Project,
required: true,
include: [{ include: [{
model: this.User, model: this.User,
required: true, required: true,
include: [{ include: [{
model: this.Hobby, model: this.Hobby,
required: true, where: {
through: { name: 'archery'
where: {
HobbyName: 'archery'
}
} }
}] }]
}], }]
order: ['name'], }],
limit: 1, order: ['name'],
offset: 1 limit: 1,
})) offset: 1
.then(result => { });
expect(result.length).to.equal(1);
expect(result[0].name).to.equal('charlie'); expect(result.length).to.equal(1);
}); expect(result[0].name).to.equal('charlie');
});
it('supports 3 levels of required many-to-many associations with where clause', function() {
return this.sequelize.sync({ force: true })
.then(() => Promise.all([
this.Task.bulkCreate(build('alpha', 'bravo', 'charlie')),
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')),
this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte')),
this.Hobby.bulkCreate(build('archery', 'badminton'))
]))
.then(([tasks, projects, users, hobbies]) => Promise.all([
tasks[0].addProject(projects[0]),
tasks[1].addProject(projects[1]),
tasks[2].addProject(projects[2]),
projects[0].addUser(users[0]),
projects[1].addUser(users[1]),
projects[2].addUser(users[0]),
users[0].addHobby(hobbies[0]),
users[1].addHobby(hobbies[1])
]))
.then(() => this.Task.findAll({
include: [{
model: this.Project,
required: true,
include: [{
model: this.User,
required: true,
include: [{
model: this.Hobby,
where: {
name: 'archery'
}
}]
}]
}],
order: ['name'],
limit: 1,
offset: 1
}))
.then(result => {
expect(result.length).to.equal(1);
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([
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')), const [projects, users] = await Promise.all([
this.User.bulkCreate(build('Alice', 'Bob')) this.Project.bulkCreate(build('alpha', 'bravo', 'charlie')),
])) this.User.bulkCreate(build('Alice', 'Bob'))
.then(([projects, users]) => Promise.all([// alpha ]);
projects[0].addUser(users[0]), // charlie
projects[2].addUser(users[0])])) await Promise.all([// alpha
.then(() => this.Project.findAll({ projects[0].addUser(users[0]), // charlie
include: [{ projects[2].addUser(users[0])]);
model: this.User,
required: true const result = await this.Project.findAll({
}], include: [{
order: ['name'], model: this.User,
limit: 1, required: true
offset: 1 }],
})) order: ['name'],
.then(result => { limit: 1,
expect(result.length).to.equal(1); offset: 1
expect(result[0].name).to.equal('charlie'); });
});
expect(result.length).to.equal(1);
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([
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie', 'delta')), const [projects, users, tasks] = await Promise.all([
this.User.bulkCreate(build('Alice', 'Bob', 'David')), this.Project.bulkCreate(build('alpha', 'bravo', 'charlie', 'delta')),
this.Task.bulkCreate(build('a', 'c', 'd')) this.User.bulkCreate(build('Alice', 'Bob', 'David')),
])) this.Task.bulkCreate(build('a', 'c', 'd'))
.then(([projects, users, tasks]) => Promise.all([ ]);
projects[0].addUser(users[0]),
projects[0].addTask(tasks[0]), await Promise.all([
projects[1].addUser(users[1]), projects[0].addUser(users[0]),
projects[2].addTask(tasks[1]), projects[0].addTask(tasks[0]),
projects[3].addUser(users[2]), projects[1].addUser(users[1]),
projects[3].addTask(tasks[2]) projects[2].addTask(tasks[1]),
])) projects[3].addUser(users[2]),
.then(() => this.Project.findAll({ projects[3].addTask(tasks[2])
include: [{ ]);
model: this.User,
required: true const result = await this.Project.findAll({
}, { include: [{
model: this.Task, model: this.User,
required: true required: true
}], }, {
order: ['name'], model: this.Task,
limit: 1, required: true
offset: 1 }],
})) order: ['name'],
.then(result => { limit: 1,
expect(result.length).to.equal(1); offset: 1
expect(result[0].name).to.equal('delta'); });
});
expect(result.length).to.equal(1);
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([
this.Post.bulkCreate(build('alpha', 'bravo', 'charlie')), const [posts, comments] = await Promise.all([
this.Comment.bulkCreate(build('comment0', 'comment1')) this.Post.bulkCreate(build('alpha', 'bravo', 'charlie')),
])) 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({
include: [{ await Promise.all([posts[0].addComment(comments[0]), posts[2].addComment(comments[1])]);
model: this.Comment,
required: true const result = await this.Post.findAll({
}], include: [{
order: ['name'], model: this.Comment,
limit: 1, required: true
offset: 1 }],
})) order: ['name'],
.then(result => { limit: 1,
expect(result.length).to.equal(1); offset: 1
expect(result[0].name).to.equal('charlie'); });
});
expect(result.length).to.equal(1);
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([
this.Post.bulkCreate(build('alpha', 'bravo', 'charlie')), const [posts, comments] = await Promise.all([
this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2')) this.Post.bulkCreate(build('alpha', 'bravo', 'charlie')),
])) this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2'))
.then(([posts, comments]) => Promise.all([ ]);
posts[0].addComment(comments[0]),
posts[1].addComment(comments[1]), await Promise.all([
posts[2].addComment(comments[2]) posts[0].addComment(comments[0]),
])) posts[1].addComment(comments[1]),
.then(() => this.Post.findAll({ posts[2].addComment(comments[2])
include: [{ ]);
model: this.Comment,
required: true, const result = await this.Post.findAll({
where: { include: [{
[Op.or]: [{ model: this.Comment,
name: 'comment0' required: true,
}, { where: {
name: 'comment2' [Op.or]: [{
}] name: 'comment0'
} }, {
}], name: 'comment2'
order: ['name'], }]
limit: 1, }
offset: 1 }],
})) order: ['name'],
.then(result => { limit: 1,
expect(result.length).to.equal(1); offset: 1
expect(result[0].name).to.equal('charlie'); });
});
expect(result.length).to.equal(1);
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([
this.Post.bulkCreate(build('alpha', 'bravo', 'charlie')), const [posts, comments] = await Promise.all([
this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2')) this.Post.bulkCreate(build('alpha', 'bravo', 'charlie')),
])) this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2'))
.then(([posts, comments]) => Promise.all([ ]);
posts[0].addComment(comments[0]),
posts[1].addComment(comments[1]), await Promise.all([
posts[2].addComment(comments[2]) posts[0].addComment(comments[0]),
])) posts[1].addComment(comments[1]),
.then(() => this.Post.findOne({ posts[2].addComment(comments[2])
include: [{ ]);
model: this.Comment,
required: true, const post = await this.Post.findOne({
where: { include: [{
name: 'comment2' model: this.Comment,
} required: true,
}] where: {
})) 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([
this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte', 'David')), const [users, posts, comments] = await Promise.all([
this.Post.bulkCreate(build('post0', 'post1', 'post2')), this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte', 'David')),
this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2')) this.Post.bulkCreate(build('post0', 'post1', 'post2')),
])) this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2'))
.then(([users, posts, comments]) => Promise.all([ ]);
users[0].addPost(posts[0]),
users[1].addPost(posts[1]), await Promise.all([
users[3].addPost(posts[2]), users[0].addPost(posts[0]),
posts[0].addComment(comments[0]), users[1].addPost(posts[1]),
posts[2].addComment(comments[2]) users[3].addPost(posts[2]),
])) posts[0].addComment(comments[0]),
.then(() => this.User.findAll({ posts[2].addComment(comments[2])
]);
const result = await this.User.findAll({
include: [{
model: this.Post,
required: true,
include: [{ include: [{
model: this.Post, model: this.Comment,
required: true, required: true
include: [{ }]
model: this.Comment, }],
required: true order: ['name'],
}] limit: 1,
}], offset: 1
order: ['name'], });
limit: 1,
offset: 1 expect(result.length).to.equal(1);
})) expect(result[0].name).to.equal('David');
.then(result => {
expect(result.length).to.equal(1);
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([
this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte', 'David')), const [users, posts, tags] = await Promise.all([
this.Post.bulkCreate(build('alpha', 'charlie', 'delta')), this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte', 'David')),
this.Tag.bulkCreate(build('atag', 'btag', 'dtag')) this.Post.bulkCreate(build('alpha', 'charlie', 'delta')),
])) this.Tag.bulkCreate(build('atag', 'btag', 'dtag'))
.then(([users, posts, tags]) => Promise.all([ ]);
users[0].addPost(posts[0]),
users[2].addPost(posts[1]), await Promise.all([
users[3].addPost(posts[2]), users[0].addPost(posts[0]),
posts[0].addTag([tags[0]]), users[2].addPost(posts[1]),
posts[2].addTag([tags[2]]) users[3].addPost(posts[2]),
])) posts[0].addTag([tags[0]]),
.then(() => this.User.findAll({ posts[2].addTag([tags[2]])
]);
const result = await this.User.findAll({
include: [{
model: this.Post,
required: true,
include: [{ include: [{
model: this.Post, model: this.Tag,
required: true, required: true
include: [{ }]
model: this.Tag, }],
required: true order: ['name'],
}] limit: 1,
}], offset: 1
order: ['name'], });
limit: 1,
offset: 1 expect(result.length).to.equal(1);
})) expect(result[0].name).to.equal('David');
.then(result => {
expect(result.length).to.equal(1);
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([
this.Project.bulkCreate(build('alpha', 'bravo', 'charlie', 'delta')), const [projects, users, posts] = await Promise.all([
this.User.bulkCreate(build('Alice', 'Bob', 'David')), this.Project.bulkCreate(build('alpha', 'bravo', 'charlie', 'delta')),
this.Post.bulkCreate(build('post0', 'post1', 'post2')) this.User.bulkCreate(build('Alice', 'Bob', 'David')),
])) this.Post.bulkCreate(build('post0', 'post1', 'post2'))
.then(([projects, users, posts]) => Promise.all([ ]);
projects[0].addUser(users[0]),
projects[1].addUser(users[1]), await Promise.all([
projects[3].addUser(users[2]), projects[0].addUser(users[0]),
users[0].addPost([posts[0]]), projects[1].addUser(users[1]),
users[2].addPost([posts[2]]) projects[3].addUser(users[2]),
])) users[0].addPost([posts[0]]),
.then(() => this.Project.findAll({ users[2].addPost([posts[2]])
]);
const result = await this.Project.findAll({
include: [{
model: this.User,
required: true,
include: [{ include: [{
model: this.User, model: this.Post,
required: true, required: true,
include: [{ duplicating: true
model: this.Post, }]
required: true, }],
duplicating: true order: ['name'],
}] limit: 1,
}], offset: 1
order: ['name'], });
limit: 1,
offset: 1 expect(result.length).to.equal(1);
})) expect(result[0].name).to.equal('delta');
.then(result => {
expect(result.length).to.equal(1);
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([
this.Post.bulkCreate(build('post0', 'post1', 'post2', 'post3')), const [posts, users, hobbies] = await Promise.all([
this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte', 'David')), this.Post.bulkCreate(build('post0', 'post1', 'post2', 'post3')),
this.Hobby.bulkCreate(build('archery', 'badminton')) this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte', 'David')),
])) this.Hobby.bulkCreate(build('archery', 'badminton'))
.then(([posts, users, hobbies]) => Promise.all([ ]);
posts[0].setUser(users[0]),
posts[1].setUser(users[1]), await Promise.all([
posts[3].setUser(users[3]), posts[0].setUser(users[0]),
users[0].addHobby(hobbies[0]), posts[1].setUser(users[1]),
users[1].addHobby(hobbies[1]), posts[3].setUser(users[3]),
users[3].addHobby(hobbies[0]) users[0].addHobby(hobbies[0]),
])) users[1].addHobby(hobbies[1]),
.then(() => this.Post.findAll({ users[3].addHobby(hobbies[0])
]);
const result = await this.Post.findAll({
include: [{
model: this.User,
required: true,
include: [{ include: [{
model: this.User, model: this.Hobby,
required: true, where: {
include: [{ name: 'archery'
model: this.Hobby, }
where: { }]
name: 'archery' }],
} order: ['name'],
}] limit: 1,
}], offset: 1
order: ['name'], });
limit: 1,
offset: 1 expect(result.length).to.equal(1);
})) expect(result[0].name).to.equal('post3');
.then(result => {
expect(result.length).to.equal(1);
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([
this.Post.bulkCreate(build('post0', 'post1', 'post2', 'post3')), const [posts, users, hobbies] = await Promise.all([
this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte', 'David')), this.Post.bulkCreate(build('post0', 'post1', 'post2', 'post3')),
this.Hobby.bulkCreate(build('archery', 'badminton')) this.User.bulkCreate(build('Alice', 'Bob', 'Charlotte', 'David')),
])) this.Hobby.bulkCreate(build('archery', 'badminton'))
.then(([posts, users, hobbies]) => Promise.all([ ]);
posts[0].setUser(users[0]),
posts[1].setUser(users[1]), await Promise.all([
posts[3].setUser(users[3]), posts[0].setUser(users[0]),
users[0].addHobby(hobbies[0]), posts[1].setUser(users[1]),
users[1].addHobby(hobbies[1]), posts[3].setUser(users[3]),
users[3].addHobby(hobbies[0]) users[0].addHobby(hobbies[0]),
])) users[1].addHobby(hobbies[1]),
.then(() => this.Post.findAll({ users[3].addHobby(hobbies[0])
]);
const result = await this.Post.findAll({
include: [{
model: this.User,
required: true,
include: [{ include: [{
model: this.User, model: this.Hobby,
required: true, required: true,
include: [{ through: {
model: this.Hobby, where: {
required: true, HobbyName: 'archery'
through: {
where: {
HobbyName: 'archery'
}
} }
}] }
}], }]
order: ['name'], }],
limit: 1, order: ['name'],
offset: 1 limit: 1,
})) offset: 1
.then(result => { });
expect(result.length).to.equal(1);
expect(result[0].name).to.equal('post3'); expect(result.length).to.equal(1);
}); 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([
this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2', 'comment3', 'comment4', 'comment5')), const [comments, posts, users, tags] = await Promise.all([
this.Post.bulkCreate(build('post0', 'post1', 'post2', 'post3', 'post4')), this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2', 'comment3', 'comment4', 'comment5')),
this.User.bulkCreate(build('Alice', 'Bob')), this.Post.bulkCreate(build('post0', 'post1', 'post2', 'post3', 'post4')),
this.Tag.bulkCreate(build('tag0', 'tag1')) this.User.bulkCreate(build('Alice', 'Bob')),
])) this.Tag.bulkCreate(build('tag0', 'tag1'))
.then(([comments, posts, users, tags]) => Promise.all([ ]);
comments[0].setPost(posts[0]),
comments[1].setPost(posts[1]), await Promise.all([
comments[3].setPost(posts[2]), comments[0].setPost(posts[0]),
comments[4].setPost(posts[3]), comments[1].setPost(posts[1]),
comments[5].setPost(posts[4]), comments[3].setPost(posts[2]),
posts[0].addTag(tags[0]), comments[4].setPost(posts[3]),
posts[3].addTag(tags[0]), comments[5].setPost(posts[4]),
posts[4].addTag(tags[0]), posts[0].addTag(tags[0]),
posts[1].addTag(tags[1]), posts[3].addTag(tags[0]),
posts[0].setUser(users[0]), posts[4].addTag(tags[0]),
posts[2].setUser(users[0]), posts[1].addTag(tags[1]),
posts[4].setUser(users[0]), posts[0].setUser(users[0]),
posts[1].setUser(users[1]) posts[2].setUser(users[0]),
])) posts[4].setUser(users[0]),
.then(() => this.Comment.findAll({ posts[1].setUser(users[1])
]);
const result = await this.Comment.findAll({
include: [{
model: this.Post,
required: true,
include: [{ include: [{
model: this.Post, model: this.User,
required: true, where: {
include: [{ name: 'Alice'
model: this.User, }
where: { }, {
name: 'Alice' model: this.Tag,
} where: {
}, { name: 'tag0'
model: this.Tag, }
where: { }]
name: 'tag0' }],
} order: ['name'],
}] limit: 1,
}], offset: 1
order: ['name'], });
limit: 1,
offset: 1 expect(result.length).to.equal(1);
})) expect(result[0].name).to.equal('comment5');
.then(result => {
expect(result.length).to.equal(1);
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([
this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2')), const [comments, posts, footnotes] = await Promise.all([
this.Post.bulkCreate(build('post0', 'post1', 'post2')), this.Comment.bulkCreate(build('comment0', 'comment1', 'comment2')),
this.Footnote.bulkCreate(build('footnote0', 'footnote1', 'footnote2')) this.Post.bulkCreate(build('post0', 'post1', 'post2')),
])) this.Footnote.bulkCreate(build('footnote0', 'footnote1', 'footnote2'))
.then(([comments, posts, footnotes]) => Promise.all([ ]);
comments[0].setPost(posts[0]),
comments[1].setPost(posts[1]), await Promise.all([
comments[2].setPost(posts[2]), comments[0].setPost(posts[0]),
posts[0].addFootnote(footnotes[0]), comments[1].setPost(posts[1]),
posts[1].addFootnote(footnotes[1]), comments[2].setPost(posts[2]),
posts[2].addFootnote(footnotes[2]) posts[0].addFootnote(footnotes[0]),
])) posts[1].addFootnote(footnotes[1]),
.then(() => this.Comment.findAll({ posts[2].addFootnote(footnotes[2])
]);
const result = await this.Comment.findAll({
include: [{
model: this.Post,
required: true,
include: [{ include: [{
model: this.Post, model: this.Footnote,
required: true, where: {
include: [{ [Op.or]: [{
model: this.Footnote, name: 'footnote0'
where: { }, {
[Op.or]: [{ name: 'footnote2'
name: 'footnote0' }]
}, { }
name: 'footnote2' }]
}] }],
} order: ['name'],
}] limit: 1,
}], offset: 1
order: ['name'], });
limit: 1,
offset: 1 expect(result.length).to.equal(1);
})) expect(result[0].name).to.equal('comment2');
.then(result => {
expect(result.length).to.equal(1);
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([
X.create(), const [x0, y] = await Promise.all([
Y.create() X.create(),
]); Y.create()
}).then(([x, y]) => { ]);
this.x = x;
this.y = y; this.x = x0;
this.y = y;
return x.addY(y);
}).then(() => { await x0.addY(y);
return this.y.destroy(); await this.y.destroy();
}).then(() => { //prevent CURRENT_TIMESTAMP to be same
//prevent CURRENT_TIMESTAMP to be same this.clock.tick(1000);
this.clock.tick(1000);
const obj = await X.findAll({
return 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,59 +392,59 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -392,59 +392,59 @@ 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([
User.bulkCreate([{}, {}, {}]), await Promise.all([
Item.bulkCreate([ User.bulkCreate([{}, {}, {}]),
{ 'test': 'abc' }, Item.bulkCreate([
{ 'test': 'def' }, { 'test': 'abc' },
{ 'test': 'ghi' }, { 'test': 'def' },
{ 'test': 'jkl' } { 'test': 'ghi' },
]), { 'test': 'jkl' }
Order.bulkCreate([ ]),
{ 'position': 2 }, Order.bulkCreate([
{ 'position': 3 }, { 'position': 2 },
{ 'position': 1 } { 'position': 3 },
]) { 'position': 1 }
]).then(() => { ])
return Promise.all([ ]);
User.findAll(),
Item.findAll({ order: ['id'] }), const [users, items, orders] = await Promise.all([
Order.findAll({ order: ['id'] }) User.findAll(),
]); Item.findAll({ order: ['id'] }),
}).then(([users, items, orders]) => { Order.findAll({ order: ['id'] })
return Promise.all([ ]);
users[0].setItemA(items[0]),
users[0].setItemB(items[1]), await Promise.all([
users[0].setOrder(orders[2]), users[0].setItemA(items[0]),
users[1].setItemA(items[2]), users[0].setItemB(items[1]),
users[1].setItemB(items[3]), users[0].setOrder(orders[2]),
users[1].setOrder(orders[1]), users[1].setItemA(items[2]),
users[2].setItemA(items[0]), users[1].setItemB(items[3]),
users[2].setItemB(items[3]), users[1].setOrder(orders[1]),
users[2].setOrder(orders[0]) users[2].setItemA(items[0]),
]); users[2].setItemB(items[3]),
}).then(() => { users[2].setOrder(orders[0])
return User.findAll({ ]);
'include': [
{ 'model': Item, 'as': 'itemA', where: { test: 'abc' } }, const as = await User.findAll({
{ 'model': Item, 'as': 'itemB' }, 'include': [
Order], { 'model': Item, 'as': 'itemA', where: { test: 'abc' } },
'order': [ { 'model': Item, 'as': 'itemB' },
[Order, 'position'] Order],
] 'order': [
}).then(as => { [Order, 'position']
expect(as.length).to.eql(2); ]
expect(as[0].itemA.test).to.eql('abc');
expect(as[1].itemA.test).to.eql('abc');
expect(as[0].Order.position).to.eql(1);
expect(as[1].Order.position).to.eql(2);
});
});
}); });
expect(as.length).to.eql(2);
expect(as[0].itemA.test).to.eql('abc');
expect(as[1].itemA.test).to.eql('abc');
expect(as[0].Order.position).to.eql(1);
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,84 +458,84 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -458,84 +458,84 @@ 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([
Product.bulkCreate([ await Promise.all([
{ title: 'Chair' }, Product.bulkCreate([
{ title: 'Desk' }, { title: 'Chair' },
{ title: 'Dress' } { title: 'Desk' },
]), { title: 'Dress' }
Tag.bulkCreate([ ]),
{ name: 'A' }, Tag.bulkCreate([
{ name: 'B' }, { name: 'A' },
{ name: 'C' } { name: 'B' },
]) { name: 'C' }
]).then(() => { ])
return Promise.all([ ]);
Product.findAll(),
Tag.findAll() const [products0, tags] = await Promise.all([
]); Product.findAll(),
}).then(([products, tags]) => { Tag.findAll()
return Promise.all([ ]);
products[0].addTag(tags[0], { through: { priority: 1 } }),
products[0].addTag(tags[1], { through: { priority: 2 } }), await Promise.all([
products[1].addTag(tags[1], { through: { priority: 1 } }), products0[0].addTag(tags[0], { through: { priority: 1 } }),
products[2].addTag(tags[0], { through: { priority: 3 } }), products0[0].addTag(tags[1], { through: { priority: 2 } }),
products[2].addTag(tags[1], { through: { priority: 1 } }), products0[1].addTag(tags[1], { through: { priority: 1 } }),
products[2].addTag(tags[2], { through: { priority: 2 } }) products0[2].addTag(tags[0], { through: { priority: 3 } }),
]); products0[2].addTag(tags[1], { through: { priority: 1 } }),
}).then(() => { products0[2].addTag(tags[2], { through: { priority: 2 } })
return Product.findAll({ ]);
include: [
{ model: Tag } const products = await Product.findAll({
], include: [
order: [ { model: Tag }
['id', 'ASC'], ],
[Tag, 'id', 'ASC'] order: [
] ['id', 'ASC'],
}).then(products => { [Tag, 'id', 'ASC']
expect(products[0].Tags[0].ProductTag.priority).to.equal(1); ]
expect(products[0].Tags[1].ProductTag.priority).to.equal(2);
expect(products[1].Tags[0].ProductTag.priority).to.equal(1);
expect(products[2].Tags[0].ProductTag.priority).to.equal(3);
expect(products[2].Tags[1].ProductTag.priority).to.equal(1);
expect(products[2].Tags[2].ProductTag.priority).to.equal(2);
});
});
}); });
expect(products[0].Tags[0].ProductTag.priority).to.equal(1);
expect(products[0].Tags[1].ProductTag.priority).to.equal(2);
expect(products[1].Tags[0].ProductTag.priority).to.equal(1);
expect(products[2].Tags[0].ProductTag.priority).to.equal(3);
expect(products[2].Tags[1].ProductTag.priority).to.equal(1);
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([
Group.bulkCreate([{}, {}]), await Promise.all([
User.bulkCreate([{}, {}, {}]) Group.bulkCreate([{}, {}]),
]).then(() => { User.bulkCreate([{}, {}, {}])
return Promise.all([ ]);
Group.findAll(),
User.findAll() const [groups, users0] = await Promise.all([
]); Group.findAll(),
}).then(([groups, users]) => { User.findAll()
return users[2].setGroup(groups[1]); ]);
}).then(() => {
return User.findAll({ await users0[2].setGroup(groups[1]);
include: [
{ model: Group, required: true } const users = await User.findAll({
] include: [
}).then(users => { { model: Group, required: true }
expect(users.length).to.equal(1); ]
expect(users[0].Group).to.be.ok;
});
});
}); });
expect(users.length).to.equal(1);
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([
Group.bulkCreate([ await Promise.all([
{ name: 'A' }, Group.bulkCreate([
{ name: 'B' } { name: 'A' },
]), { name: 'B' }
User.bulkCreate([{}, {}]) ]),
]).then(() => { User.bulkCreate([{}, {}])
return Promise.all([ ]);
Group.findAll(),
User.findAll() const [groups, users0] = await Promise.all([
]); Group.findAll(),
}).then(([groups, users]) => { User.findAll()
return Promise.all([ ]);
users[0].setGroup(groups[1]),
users[1].setGroup(groups[0]) await Promise.all([
]); users0[0].setGroup(groups[1]),
}).then(() => { users0[1].setGroup(groups[0])
return User.findAll({ ]);
include: [
{ model: Group, where: { name: 'A' } } const users = await User.findAll({
] include: [
}).then(users => { { model: Group, where: { name: 'A' } }
expect(users.length).to.equal(1); ]
expect(users[0].Group).to.be.ok;
expect(users[0].Group.name).to.equal('A');
});
});
}); });
expect(users.length).to.equal(1);
expect(users[0].Group).to.be.ok;
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([
Group.bulkCreate([ await Promise.all([
{ name: 'A' }, Group.bulkCreate([
{ name: 'B' } { name: 'A' },
]), { name: 'B' }
User.bulkCreate([{}, {}]) ]),
]).then(() => { User.bulkCreate([{}, {}])
return Promise.all([ ]);
Group.findAll(),
User.findAll() const [groups, users0] = await Promise.all([
]); Group.findAll(),
}).then(([groups, users]) => { User.findAll()
return Promise.all([ ]);
users[0].setGroup(groups[1]),
users[1].setGroup(groups[0]) await Promise.all([
]); users0[0].setGroup(groups[1]),
}).then(() => { users0[1].setGroup(groups[0])
return User.findAll({ ]);
include: [
{ model: Group, required: true } const users = await User.findAll({
] include: [
}).then(users => { { model: Group, required: true }
users.forEach(user => { ]
expect(user.Group).to.be.ok; });
});
}); users.forEach(user => {
}); 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([
Group.bulkCreate([ await Promise.all([
{ name: 'A' }, Group.bulkCreate([
{ name: 'B' } { name: 'A' },
]), { name: 'B' }
User.bulkCreate([{}, {}]), ]),
Category.bulkCreate([{}, {}]) User.bulkCreate([{}, {}]),
]).then(() => { Category.bulkCreate([{}, {}])
return Promise.all([ ]);
Group.findAll(),
User.findAll(), const [groups, users0, categories] = await Promise.all([
Category.findAll() Group.findAll(),
]); User.findAll(),
}).then(([groups, users, categories]) => { Category.findAll()
const promises = [ ]);
users[0].setGroup(groups[1]),
users[1].setGroup(groups[0]) const promises = [
]; users0[0].setGroup(groups[1]),
groups.forEach(group => { users0[1].setGroup(groups[0])
promises.push(group.setCategories(categories)); ];
}); groups.forEach(group => {
return Promise.all(promises); promises.push(group.setCategories(categories));
}).then(() => { });
return User.findAll({ await Promise.all(promises);
include: [
{ model: Group, required: true, include: [ const users = await User.findAll({
{ model: Category } include: [
] } { model: Group, required: true, include: [
], { model: Category }
limit: 1 ] }
}).then(users => { ],
expect(users.length).to.equal(1); limit: 1
users.forEach(user => { });
expect(user.Group).to.be.ok;
expect(user.Group.Categories).to.be.ok; expect(users.length).to.equal(1);
}); users.forEach(user => {
}); expect(user.Group).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([
Group.bulkCreate([ await Promise.all([
{ name: 'A' }, Group.bulkCreate([
{ name: 'B' } { name: 'A' },
]), { name: 'B' }
User.bulkCreate([{}, {}]), ]),
Category.bulkCreate([{}, {}]) User.bulkCreate([{}, {}]),
]).then(() => { Category.bulkCreate([{}, {}])
return Promise.all([ ]);
Group.findAll(),
User.findAll(), const [groups, users0, categories] = await Promise.all([
Category.findAll() Group.findAll(),
]); User.findAll(),
}).then(([groups, users, categories]) => { Category.findAll()
const promises = [ ]);
users[0].setTeam(groups[1]),
users[1].setTeam(groups[0]) const promises = [
]; users0[0].setTeam(groups[1]),
groups.forEach(group => { users0[1].setTeam(groups[0])
promises.push(group.setTags(categories)); ];
}); groups.forEach(group => {
return Promise.all(promises); promises.push(group.setTags(categories));
}).then(() => { });
return User.findAll({ await Promise.all(promises);
include: [
{ model: Group, required: true, as: 'Team', include: [ const users = await User.findAll({
{ model: Category, as: 'Tags' } include: [
] } { model: Group, required: true, as: 'Team', include: [
], { model: Category, as: 'Tags' }
limit: 1 ] }
}).then(users => { ],
expect(users.length).to.equal(1); limit: 1
users.forEach(user => { });
expect(user.Team).to.be.ok;
expect(user.Team.Tags).to.be.ok; expect(users.length).to.equal(1);
}); users.forEach(user => {
}); expect(user.Team).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([
Group.bulkCreate([ await Promise.all([
{ name: 'A' }, Group.bulkCreate([
{ name: 'B' } { name: 'A' },
]), { name: 'B' }
User.bulkCreate([{}, {}]), ]),
Category.bulkCreate([{}, {}]) User.bulkCreate([{}, {}]),
]).then(() => { Category.bulkCreate([{}, {}])
return Promise.all([ ]);
Group.findAll(),
User.findAll(), const [groups, users0, categories] = await Promise.all([
Category.findAll() Group.findAll(),
]); User.findAll(),
}).then(([groups, users, categories]) => { Category.findAll()
const promises = [ ]);
users[0].setGroup(groups[1]),
users[1].setGroup(groups[0]) const promises = [
]; users0[0].setGroup(groups[1]),
groups.forEach(group => { users0[1].setGroup(groups[0])
promises.push(group.setCategories(categories)); ];
}); groups.forEach(group => {
return Promise.all(promises); promises.push(group.setCategories(categories));
}).then(() => { });
return User.findAll({ await Promise.all(promises);
include: [
{ model: Group, required: true, include: [ const users = await User.findAll({
{ model: Category, required: false } include: [
] } { model: Group, required: true, include: [
], { model: Category, required: false }
limit: 1 ] }
}).then(users => { ],
expect(users.length).to.equal(1); limit: 1
users.forEach(user => { });
expect(user.Group).to.be.ok;
expect(user.Group.Categories).to.be.ok; expect(users.length).to.equal(1);
}); users.forEach(user => {
}); expect(user.Group).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([
Project.bulkCreate([ await Promise.all([
{ title: 'Alpha' }, Project.bulkCreate([
{ title: 'Beta' } { title: 'Alpha' },
]), { title: 'Beta' }
User.bulkCreate([{}, {}]) ]),
]).then(() => { User.bulkCreate([{}, {}])
return Promise.all([ ]);
Project.findAll(),
User.findAll() const [projects, users0] = await Promise.all([
]); Project.findAll(),
}).then(([projects, users]) => { User.findAll()
return Promise.all([ ]);
users[1].setLeaderOf(projects[1]),
users[0].setLeaderOf(projects[0]) await Promise.all([
]); users0[1].setLeaderOf(projects[1]),
}).then(() => { users0[0].setLeaderOf(projects[0])
return User.findAll({ ]);
include: [
{ model: Project, as: 'LeaderOf', where: { title: 'Beta' } } const users = await User.findAll({
] include: [
}).then(users => { { model: Project, as: 'LeaderOf', where: { title: 'Beta' } }
expect(users.length).to.equal(1); ]
expect(users[0].LeaderOf).to.be.ok;
expect(users[0].LeaderOf.title).to.equal('Beta');
});
});
}); });
expect(users.length).to.equal(1);
expect(users[0].LeaderOf).to.be.ok;
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,43 +828,43 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -828,43 +828,43 @@ 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([
Product.bulkCreate([ await Promise.all([
{ title: 'Chair' }, Product.bulkCreate([
{ title: 'Desk' }, { title: 'Chair' },
{ title: 'Dress' } { title: 'Desk' },
]), { title: 'Dress' }
Tag.bulkCreate([ ]),
{ name: 'A' }, Tag.bulkCreate([
{ name: 'B' }, { name: 'A' },
{ name: 'C' } { name: 'B' },
]) { name: 'C' }
]).then(() => { ])
return Promise.all([ ]);
Product.findAll(),
Tag.findAll() const [products0, tags] = await Promise.all([
]); Product.findAll(),
}).then(([products, tags]) => { Tag.findAll()
return Promise.all([ ]);
products[0].addTag(tags[0], { priority: 1 }),
products[0].addTag(tags[1], { priority: 2 }), await Promise.all([
products[1].addTag(tags[1], { priority: 1 }), products0[0].addTag(tags[0], { priority: 1 }),
products[2].addTag(tags[0], { priority: 3 }), products0[0].addTag(tags[1], { priority: 2 }),
products[2].addTag(tags[1], { priority: 1 }), products0[1].addTag(tags[1], { priority: 1 }),
products[2].addTag(tags[2], { priority: 2 }) products0[2].addTag(tags[0], { priority: 3 }),
]); products0[2].addTag(tags[1], { priority: 1 }),
}).then(() => { products0[2].addTag(tags[2], { priority: 2 })
return Product.findAll({ ]);
include: [
{ model: Tag, where: { name: 'C' } } const products = await Product.findAll({
] include: [
}).then(products => { { model: Tag, where: { name: 'C' } }
expect(products.length).to.equal(1); ]
expect(products[0].Tags.length).to.equal(1);
});
});
}); });
expect(products.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() {
...@@ -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,123 +1001,123 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -1001,123 +1001,123 @@ 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({
groups: Group.bulkCreate([ const results = await promiseProps({
{ name: 'A' }, groups: Group.bulkCreate([
{ name: 'B' } { name: 'A' },
]).then(() => { { name: 'B' }
return Group.findAll(); ]).then(() => {
}), return Group.findAll();
users: User.bulkCreate([{}, {}, {}, {}]).then(() => { }),
return User.findAll(); users: User.bulkCreate([{}, {}, {}, {}]).then(() => {
}) return User.findAll();
}).then(results => { })
return Promise.all([ });
results.users[1].setGroup(results.groups[0]),
results.users[2].setGroup(results.groups[0]), await Promise.all([
results.users[3].setGroup(results.groups[1]), results.users[1].setGroup(results.groups[0]),
results.users[0].setGroup(results.groups[0]) results.users[2].setGroup(results.groups[0]),
]); results.users[3].setGroup(results.groups[1]),
}).then(() => { results.users[0].setGroup(results.groups[0])
return User.findAll({ ]);
include: [
{ model: Group, where: { name: 'A' } } const users = await User.findAll({
], include: [
limit: 2 { model: Group, where: { name: 'A' } }
}).then(users => { ],
expect(users.length).to.equal(2); limit: 2
});
users.forEach(user => {
expect(user.Group.name).to.equal('A'); expect(users.length).to.equal(2);
});
}); users.forEach(user => {
}); 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({
attributes: ['title'], const products = await this.models.Product.findAll({
include: [ attributes: ['title'],
{ model: this.models.Company, where: { name: 'NYSE' } }, include: [
{ model: this.models.Tag }, { model: this.models.Company, where: { name: 'NYSE' } },
{ model: this.models.Price } { model: this.models.Tag },
], { model: this.models.Price }
limit: 3, ],
order: [ limit: 3,
['id', 'ASC'] order: [
] ['id', 'ASC']
}).then(products => { ]
expect(products.length).to.equal(3); });
products.forEach(product => { expect(products.length).to.equal(3);
expect(product.Company.name).to.equal('NYSE');
expect(product.Tags.length).to.be.ok; products.forEach(product => {
expect(product.Prices.length).to.be.ok; expect(product.Company.name).to.equal('NYSE');
}); expect(product.Tags.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({
include: [ const products = await this.models.Product.findAll({
{ model: this.models.Company }, include: [
{ model: this.models.Tag }, { model: this.models.Company },
{ model: this.models.Price, where: { { model: this.models.Tag },
value: { [Op.gt]: 5 } { model: this.models.Price, where: {
} } value: { [Op.gt]: 5 }
], } }
limit: 6, ],
order: [ limit: 6,
['id', 'ASC'] order: [
] ['id', 'ASC']
}).then(products => { ]
expect(products.length).to.equal(6); });
expect(products.length).to.equal(6);
products.forEach(product => { products.forEach(product => {
expect(product.Tags.length).to.be.ok; expect(product.Tags.length).to.be.ok;
expect(product.Prices.length).to.be.ok; expect(product.Prices.length).to.be.ok;
product.Prices.forEach(price => { product.Prices.forEach(price => {
expect(price.value).to.be.above(5); expect(price.value).to.be.above(5);
});
});
}); });
}); });
}); });
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({
include: [
{ model: this.models.Company },
{ model: this.models.Tag, where: { name: ['A', 'B', 'C'] } },
{ model: this.models.Price }
],
limit: 10,
order: [
['id', 'ASC']
]
}).then(products => {
expect(products.length).to.equal(10);
products.forEach(product => { const products = await this.models.Product.findAll({
expect(product.Tags.length).to.be.ok; include: [
expect(product.Prices.length).to.be.ok; { model: this.models.Company },
{ model: this.models.Tag, where: { name: ['A', 'B', 'C'] } },
{ model: this.models.Price }
],
limit: 10,
order: [
['id', 'ASC']
]
});
product.Tags.forEach(tag => { expect(products.length).to.equal(10);
expect(['A', 'B', 'C']).to.include(tag.name);
}); products.forEach(product => {
}); expect(product.Tags.length).to.be.ok;
expect(product.Prices.length).to.be.ok;
product.Tags.forEach(tag => {
expect(['A', 'B', 'C']).to.include(tag.name);
}); });
}); });
}); });
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,34 +1128,31 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -1128,34 +1128,31 @@ 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({
where: { const users = await User.findAll({
id: user.id where: {
}, id: user.id
include: [Group] },
}).then(users => { include: [Group]
if (dialect === 'sqlite') {
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));
} else {
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));
}
});
});
});
});
}); });
if (dialect === 'sqlite') {
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));
} else {
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));
}
}); });
}); });
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,21 +1204,21 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), () => { ...@@ -1207,21 +1204,21 @@ 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
}, },
include: [{ include: [{
model: ResumeModel, model: ResumeModel,
as: 'Resume' as: 'Resume'
}] }]
}); });
});
}).then(() => this.sequelize.dropSchema('hero')); await this.sequelize.dropSchema('hero');
}); });
}); });
}); });
...@@ -11,55 +11,55 @@ const chai = require('chai'), ...@@ -11,55 +11,55 @@ 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({
id: 1, await Promise.all([User.create({
tasks: [ id: 1,
{}, tasks: [
{}, {},
{} {},
] {}
}, { ]
include: [User.Tasks] }, {
}), User.create({ include: [User.Tasks]
id: 2, }), User.create({
tasks: [ id: 2,
{} tasks: [
] {}
}, { ]
include: [User.Tasks] }, {
})]).then(() => { include: [User.Tasks]
return User.findAll({ })]);
include: [
{ association: User.Tasks, separate: true } const users = await User.findAll({
], include: [
order: [ { association: User.Tasks, separate: true }
['id', 'ASC'] ],
], order: [
logging: sqlSpy ['id', 'ASC']
}); ],
}).then(users => { logging: sqlSpy
expect(users[0].get('tasks')).to.be.ok;
expect(users[0].get('tasks').length).to.equal(3);
expect(users[1].get('tasks')).to.be.ok;
expect(users[1].get('tasks').length).to.equal(1);
expect(users[0].get('tasks')[0].createdAt).to.be.ok;
expect(users[0].get('tasks')[0].updatedAt).to.be.ok;
expect(sqlSpy).to.have.been.calledTwice;
});
}); });
expect(users[0].get('tasks')).to.be.ok;
expect(users[0].get('tasks').length).to.equal(3);
expect(users[1].get('tasks')).to.be.ok;
expect(users[1].get('tasks').length).to.equal(1);
expect(users[0].get('tasks')[0].createdAt).to.be.ok;
expect(users[0].get('tasks')[0].updatedAt).to.be.ok;
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,36 +68,36 @@ if (current.dialect.supports.groupedLimit) { ...@@ -68,36 +68,36 @@ 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({
id: 1, await User.create({
tasks: [ id: 1,
{}, tasks: [
{}, {},
{} {},
] {}
}, { ]
include: [User.Tasks] }, {
}).then(() => { include: [User.Tasks]
return User.findAll({
attributes: ['name'],
include: [
{ association: User.Tasks, separate: true }
],
order: [
['id', 'ASC']
],
logging: sqlSpy
});
}).then(users => {
expect(users[0].get('tasks')).to.be.ok;
expect(users[0].get('tasks').length).to.equal(3);
expect(sqlSpy).to.have.been.calledTwice;
});
}); });
const users = await User.findAll({
attributes: ['name'],
include: [
{ association: User.Tasks, separate: true }
],
order: [
['id', 'ASC']
],
logging: sqlSpy
});
expect(users[0].get('tasks')).to.be.ok;
expect(users[0].get('tasks').length).to.equal(3);
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,47 +116,44 @@ if (current.dialect.supports.groupedLimit) { ...@@ -116,47 +116,44 @@ 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: [
{}, {},
{}, {},
{} {}
] ]
}, { }, {
include: [User.Tasks] include: [User.Tasks]
}); });
})
.then(() => { const users = await User.findAll({
return User.findAll({ attributes: ['name'],
attributes: ['name'], include: [
include: [ {
{ attributes: [
attributes: [ 'title'
'title'
],
association: User.Tasks,
separate: true
}
],
order: [
['id', 'ASC']
], ],
logging: sqlSpy association: User.Tasks,
}); separate: true
}) }
.then(users => { ],
expect(users[0].get('tasks')).to.be.ok; order: [
expect(users[0].get('tasks').length).to.equal(3); ['id', 'ASC']
expect(sqlSpy).to.have.been.calledTwice; ],
}); logging: sqlSpy
});
expect(users[0].get('tasks')).to.be.ok;
expect(users[0].get('tasks').length).to.equal(3);
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,47 +183,47 @@ if (current.dialect.supports.groupedLimit) { ...@@ -187,47 +183,47 @@ 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({
id: 1, await Promise.all([User.create({
tasks: [ id: 1,
{}, tasks: [
{}, {},
{} {},
] {}
}, { ]
include: [User.Tasks] }, {
}), User.create({ include: [User.Tasks]
id: 2, }), User.create({
tasks: [ id: 2,
{}, tasks: [
{}, {},
{}, {},
{} {},
] {}
}, { ]
include: [User.Tasks] }, {
})]).then(() => { include: [User.Tasks]
return User.findAll({ })]);
include: [
{ association: User.Tasks, limit: 2 } const users = await User.findAll({
], include: [
order: [ { association: User.Tasks, limit: 2 }
['id', 'ASC'] ],
], order: [
logging: sqlSpy ['id', 'ASC']
}); ],
}).then(users => { logging: sqlSpy
expect(users[0].get('tasks')).to.be.ok;
expect(users[0].get('tasks').length).to.equal(2);
expect(users[1].get('tasks')).to.be.ok;
expect(users[1].get('tasks').length).to.equal(2);
expect(sqlSpy).to.have.been.calledTwice;
});
}); });
expect(users[0].get('tasks')).to.be.ok;
expect(users[0].get('tasks').length).to.equal(2);
expect(users[1].get('tasks')).to.be.ok;
expect(users[1].get('tasks').length).to.equal(2);
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,54 +232,54 @@ if (current.dialect.supports.groupedLimit) { ...@@ -236,54 +232,54 @@ 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({
id: 1, await Promise.all([User.create({
company: { id: 1,
tasks: [ company: {
{}, tasks: [
{}, {},
{} {},
] {}
}
}, {
include: [
{ association: User.Company, include: [Company.Tasks] }
] ]
}), User.create({ }
id: 2, }, {
company: { include: [
tasks: [ { association: User.Company, include: [Company.Tasks] }
{} ]
] }), User.create({
} id: 2,
}, { company: {
include: [ tasks: [
{ association: User.Company, include: [Company.Tasks] } {}
] ]
})]).then(() => { }
return User.findAll({ }, {
include: [ include: [
{ association: User.Company, include: [ { association: User.Company, include: [Company.Tasks] }
{ association: Company.Tasks, separate: true } ]
] } })]);
],
order: [ const users = await User.findAll({
['id', 'ASC'] include: [
], { association: User.Company, include: [
logging: sqlSpy { association: Company.Tasks, separate: true }
}); ] }
}).then(users => { ],
expect(users[0].get('company').get('tasks')).to.be.ok; order: [
expect(users[0].get('company').get('tasks').length).to.equal(3); ['id', 'ASC']
expect(users[1].get('company').get('tasks')).to.be.ok; ],
expect(users[1].get('company').get('tasks').length).to.equal(1); logging: sqlSpy
expect(sqlSpy).to.have.been.calledTwice;
});
}); });
expect(users[0].get('company').get('tasks')).to.be.ok;
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').length).to.equal(1);
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,49 +290,49 @@ if (current.dialect.supports.groupedLimit) { ...@@ -294,49 +290,49 @@ 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({
id: 1,
users: [
{
tasks: [
{ project: {} },
{ project: {} },
{ project: {} }
]
}
]
}, {
include: [
{ association: Company.Users, include: [
{ association: User.Tasks, include: [
Task.Project
] }
] }
]
})]).then(() => {
return Company.findAll({
include: [
{ association: Company.Users, include: [
{ association: User.Tasks, separate: true, include: [
Task.Project
] }
] }
],
order: [
['id', 'ASC']
],
logging: sqlSpy
});
}).then(companies => {
expect(sqlSpy).to.have.been.calledTwice;
expect(companies[0].users[0].tasks[0].project).to.be.ok; await Promise.all([Company.create({
}); id: 1,
users: [
{
tasks: [
{ project: {} },
{ project: {} },
{ project: {} }
]
}
]
}, {
include: [
{ association: Company.Users, include: [
{ association: User.Tasks, include: [
Task.Project
] }
] }
]
})]);
const companies = await Company.findAll({
include: [
{ association: Company.Users, include: [
{ association: User.Tasks, separate: true, include: [
Task.Project
] }
] }
],
order: [
['id', 'ASC']
],
logging: sqlSpy
}); });
expect(sqlSpy).to.have.been.calledTwice;
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,79 +341,79 @@ if (current.dialect.supports.groupedLimit) { ...@@ -345,79 +341,79 @@ 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({
id: 1, await Promise.all([User.create({
projects: [ id: 1,
{ projects: [
id: 1, {
tasks: [ id: 1,
{}, tasks: [
{}, {},
{} {},
] {}
}, ]
{ },
id: 2, {
tasks: [ id: 2,
{} tasks: [
] {}
} ]
] }
}, { ]
include: [ }, {
{ association: User.Projects, include: [Project.Tasks] } include: [
] { association: User.Projects, include: [Project.Tasks] }
}), User.create({ ]
id: 2, }), User.create({
projects: [ id: 2,
{ projects: [
id: 3, {
tasks: [ id: 3,
{}, tasks: [
{} {},
] {}
} ]
] }
}, { ]
include: [ }, {
{ association: User.Projects, include: [Project.Tasks] } include: [
] { association: User.Projects, include: [Project.Tasks] }
})]).then(() => { ]
return User.findAll({ })]);
include: [
{ association: User.Projects, separate: true, include: [ const users = await User.findAll({
{ association: Project.Tasks, separate: true } include: [
] } { association: User.Projects, separate: true, include: [
], { association: Project.Tasks, separate: true }
order: [ ] }
['id', 'ASC'] ],
], order: [
logging: sqlSpy ['id', 'ASC']
}); ],
}).then(users => { logging: sqlSpy
const u1projects = users[0].get('projects');
expect(u1projects).to.be.ok;
expect(u1projects[0].get('tasks')).to.be.ok;
expect(u1projects[1].get('tasks')).to.be.ok;
expect(u1projects.length).to.equal(2);
// WTB ES2015 syntax ...
expect(u1projects.find(p => p.id === 1).get('tasks').length).to.equal(3);
expect(u1projects.find(p => p.id === 2).get('tasks').length).to.equal(1);
expect(users[1].get('projects')).to.be.ok;
expect(users[1].get('projects')[0].get('tasks')).to.be.ok;
expect(users[1].get('projects').length).to.equal(1);
expect(users[1].get('projects')[0].get('tasks').length).to.equal(2);
expect(sqlSpy).to.have.been.calledThrice;
});
}); });
const u1projects = users[0].get('projects');
expect(u1projects).to.be.ok;
expect(u1projects[0].get('tasks')).to.be.ok;
expect(u1projects[1].get('tasks')).to.be.ok;
expect(u1projects.length).to.equal(2);
// WTB ES2015 syntax ...
expect(u1projects.find(p => p.id === 1).get('tasks').length).to.equal(3);
expect(u1projects.find(p => p.id === 2).get('tasks').length).to.equal(1);
expect(users[1].get('projects')).to.be.ok;
expect(users[1].get('projects')[0].get('tasks')).to.be.ok;
expect(users[1].get('projects').length).to.equal(1);
expect(users[1].get('projects')[0].get('tasks').length).to.equal(2);
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,54 +422,50 @@ if (current.dialect.supports.groupedLimit) { ...@@ -426,54 +422,50 @@ 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({
id: 1, await Promise.all([User.create({
tasks: [ id: 1,
{ id: 1, title: 'b' }, tasks: [
{ id: 2, title: 'd' }, { id: 1, title: 'b' },
{ id: 3, title: 'c' }, { id: 2, title: 'd' },
{ id: 4, title: 'a' } { id: 3, title: 'c' },
] { id: 4, title: 'a' }
}, { ]
include: [User.Tasks] }, {
}), User.create({ include: [User.Tasks]
id: 2, }), User.create({
tasks: [ id: 2,
{ id: 5, title: 'a' }, tasks: [
{ id: 6, title: 'c' }, { id: 5, title: 'a' },
{ id: 7, title: 'b' } { id: 6, title: 'c' },
] { id: 7, title: 'b' }
}, { ]
include: [User.Tasks] }, {
})]); include: [User.Tasks]
}).then(() => { })]);
return User.findAll({
include: [{ model: Task, limit: 2, as: 'tasks', order: [['id', 'ASC']] }], const result = await User.findAll({
order: [ include: [{ model: Task, limit: 2, as: 'tasks', order: [['id', 'ASC']] }],
['id', 'ASC'] order: [
] ['id', 'ASC']
}).then(result => { ]
expect(result[0].tasks.length).to.equal(2);
expect(result[0].tasks[0].title).to.equal('b');
expect(result[0].tasks[1].title).to.equal('d');
expect(result[1].tasks.length).to.equal(2);
expect(result[1].tasks[0].title).to.equal('a');
expect(result[1].tasks[1].title).to.equal('c');
return this.sequelize.dropSchema('archive').then(() => {
return this.sequelize.showAllSchemas().then(schemas => {
if (dialect === 'postgres' || dialect === 'mssql' || dialect === 'mariadb') {
expect(schemas).to.not.have.property('archive');
}
});
});
});
});
});
}); });
expect(result[0].tasks.length).to.equal(2);
expect(result[0].tasks[0].title).to.equal('b');
expect(result[0].tasks[1].title).to.equal('d');
expect(result[1].tasks.length).to.equal(2);
expect(result[1].tasks[0].title).to.equal('a');
expect(result[1].tasks[1].title).to.equal('c');
await this.sequelize.dropSchema('archive');
const schemas = await this.sequelize.showAllSchemas();
if (dialect === 'postgres' || dialect === 'mssql' || dialect === 'mariadb') {
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() {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!