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

Commit 796b6b7d by Andy Edwards Committed by GitHub

test(integration/instance): asyncify (#12285)

1 parent 3e4b5ed7
...@@ -20,7 +20,7 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -20,7 +20,7 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
this.clock.restore(); this.clock.restore();
}); });
beforeEach(function() { beforeEach(async function() {
this.User = this.sequelize.define('User', { this.User = this.sequelize.define('User', {
username: { type: DataTypes.STRING }, username: { type: DataTypes.STRING },
uuidv1: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV1 }, uuidv1: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV1 },
...@@ -52,170 +52,137 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -52,170 +52,137 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
} }
}); });
return this.User.sync({ force: true }); await this.User.sync({ force: true });
}); });
describe('decrement', () => { describe('decrement', () => {
beforeEach(function() { beforeEach(async function() {
return this.User.create({ id: 1, aNumber: 0, bNumber: 0 }); await this.User.create({ id: 1, aNumber: 0, bNumber: 0 });
}); });
if (current.dialect.supports.transactions) { if (current.dialect.supports.transactions) {
it('supports transactions', function() { it('supports transactions', async function() {
return Support.prepareTransactionTest(this.sequelize).then(sequelize => { const sequelize = await Support.prepareTransactionTest(this.sequelize);
const User = sequelize.define('User', { number: Support.Sequelize.INTEGER }); const User = sequelize.define('User', { number: Support.Sequelize.INTEGER });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({ number: 3 }).then(user => { const user = await User.create({ number: 3 });
return sequelize.transaction().then(t => { const t = await sequelize.transaction();
return user.decrement('number', { by: 2, transaction: t }).then(() => { await user.decrement('number', { by: 2, transaction: t });
return User.findAll().then(users1 => { const users1 = await User.findAll();
return User.findAll({ transaction: t }).then(users2 => { const users2 = await User.findAll({ transaction: t });
expect(users1[0].number).to.equal(3); expect(users1[0].number).to.equal(3);
expect(users2[0].number).to.equal(1); expect(users2[0].number).to.equal(1);
return t.rollback(); await t.rollback();
});
});
});
});
});
});
});
}); });
} }
if (current.dialect.supports.returnValues.returning) { if (current.dialect.supports.returnValues.returning) {
it('supports returning', function() { it('supports returning', async function() {
return this.User.findByPk(1).then(user1 => { const user1 = await this.User.findByPk(1);
return user1.decrement('aNumber', { by: 2 }).then(() => { await user1.decrement('aNumber', { by: 2 });
expect(user1.aNumber).to.be.equal(-2); expect(user1.aNumber).to.be.equal(-2);
return user1.decrement('bNumber', { by: 2, returning: false }).then(user3 => { const user3 = await user1.decrement('bNumber', { by: 2, returning: false });
expect(user3.bNumber).to.be.equal(0); expect(user3.bNumber).to.be.equal(0);
});
});
});
}); });
} }
it('with array', function() { it('with array', async function() {
return this.User.findByPk(1).then(user1 => { const user1 = await this.User.findByPk(1);
return user1.decrement(['aNumber'], { by: 2 }).then(() => { await user1.decrement(['aNumber'], { by: 2 });
return this.User.findByPk(1).then(user3 => { const user3 = await this.User.findByPk(1);
expect(user3.aNumber).to.be.equal(-2); expect(user3.aNumber).to.be.equal(-2);
});
});
});
}); });
it('with single field', function() { it('with single field', async function() {
return this.User.findByPk(1).then(user1 => { const user1 = await this.User.findByPk(1);
return user1.decrement('aNumber', { by: 2 }).then(() => { await user1.decrement('aNumber', { by: 2 });
return this.User.findByPk(1).then(user3 => { const user3 = await this.User.findByPk(1);
expect(user3.aNumber).to.be.equal(-2); expect(user3.aNumber).to.be.equal(-2);
});
});
});
}); });
it('with single field and no value', function() { it('with single field and no value', async function() {
return this.User.findByPk(1).then(user1 => { const user1 = await this.User.findByPk(1);
return user1.decrement('aNumber').then(() => { await user1.decrement('aNumber');
return this.User.findByPk(1).then(user2 => { const user2 = await this.User.findByPk(1);
expect(user2.aNumber).to.be.equal(-1); expect(user2.aNumber).to.be.equal(-1);
});
});
});
}); });
it('should still work right with other concurrent updates', function() { it('should still work right with other concurrent updates', async function() {
return this.User.findByPk(1).then(user1 => { const user1 = await this.User.findByPk(1);
// Select the user again (simulating a concurrent query) // Select the user again (simulating a concurrent query)
return this.User.findByPk(1).then(user2 => { const user2 = await this.User.findByPk(1);
return user2.update({
aNumber: user2.aNumber + 1 await user2.update({
}).then(() => { aNumber: user2.aNumber + 1
return user1.decrement(['aNumber'], { by: 2 }).then(() => {
return this.User.findByPk(1).then(user5 => {
expect(user5.aNumber).to.be.equal(-1);
});
});
});
});
}); });
await user1.decrement(['aNumber'], { by: 2 });
const user5 = await this.User.findByPk(1);
expect(user5.aNumber).to.be.equal(-1);
}); });
it('should still work right with other concurrent increments', function() { it('should still work right with other concurrent increments', async function() {
return this.User.findByPk(1).then(user1 => { const user1 = await this.User.findByPk(1);
return Promise.all([
user1.decrement(['aNumber'], { by: 2 }), await Promise.all([
user1.decrement(['aNumber'], { by: 2 }), user1.decrement(['aNumber'], { by: 2 }),
user1.decrement(['aNumber'], { by: 2 }) user1.decrement(['aNumber'], { by: 2 }),
]).then(() => { user1.decrement(['aNumber'], { by: 2 })
return this.User.findByPk(1).then(user2 => { ]);
expect(user2.aNumber).to.equal(-6);
}); const user2 = await this.User.findByPk(1);
}); expect(user2.aNumber).to.equal(-6);
});
}); });
it('with key value pair', function() { it('with key value pair', async function() {
return this.User.findByPk(1).then(user1 => { const user1 = await this.User.findByPk(1);
return user1.decrement({ 'aNumber': 1, 'bNumber': 2 }).then(() => { await user1.decrement({ 'aNumber': 1, 'bNumber': 2 });
return this.User.findByPk(1).then(user3 => { const user3 = await this.User.findByPk(1);
expect(user3.aNumber).to.be.equal(-1); expect(user3.aNumber).to.be.equal(-1);
expect(user3.bNumber).to.be.equal(-2); expect(user3.bNumber).to.be.equal(-2);
});
});
});
}); });
it('with negative value', function() { it('with negative value', async function() {
return this.User.findByPk(1).then(user1 => { const user1 = await this.User.findByPk(1);
return Promise.all([
user1.decrement('aNumber', { by: -2 }), await Promise.all([
user1.decrement(['aNumber', 'bNumber'], { by: -2 }), user1.decrement('aNumber', { by: -2 }),
user1.decrement({ 'aNumber': -1, 'bNumber': -2 }) user1.decrement(['aNumber', 'bNumber'], { by: -2 }),
]).then(() => { user1.decrement({ 'aNumber': -1, 'bNumber': -2 })
return this.User.findByPk(1).then(user3 => { ]);
expect(user3.aNumber).to.be.equal(+5);
expect(user3.bNumber).to.be.equal(+4); const user3 = await this.User.findByPk(1);
}); expect(user3.aNumber).to.be.equal(+5);
}); expect(user3.bNumber).to.be.equal(+4);
});
}); });
it('with timestamps set to true', function() { it('with timestamps set to true', async function() {
const User = this.sequelize.define('IncrementUser', { const User = this.sequelize.define('IncrementUser', {
aNumber: DataTypes.INTEGER aNumber: DataTypes.INTEGER
}, { timestamps: true }); }, { timestamps: true });
let oldDate;
await User.sync({ force: true });
return User.sync({ force: true }).then(() => { const user = await User.create({ aNumber: 1 });
return User.create({ aNumber: 1 }); const oldDate = user.updatedAt;
}).then(user => { this.clock.tick(1000);
oldDate = user.updatedAt; await user.decrement('aNumber', { by: 1 });
this.clock.tick(1000);
return user.decrement('aNumber', { by: 1 }); await expect(User.findByPk(1)).to.eventually.have.property('updatedAt').afterTime(oldDate);
}).then(() => {
return expect(User.findByPk(1)).to.eventually.have.property('updatedAt').afterTime(oldDate);
});
}); });
it('with timestamps set to true and options.silent set to true', function() { it('with timestamps set to true and options.silent set to true', async function() {
const User = this.sequelize.define('IncrementUser', { const User = this.sequelize.define('IncrementUser', {
aNumber: DataTypes.INTEGER aNumber: DataTypes.INTEGER
}, { timestamps: true }); }, { timestamps: true });
let oldDate;
await User.sync({ force: true });
return User.sync({ force: true }).then(() => { const user = await User.create({ aNumber: 1 });
return User.create({ aNumber: 1 }); const oldDate = user.updatedAt;
}).then(user => { this.clock.tick(1000);
oldDate = user.updatedAt; await user.decrement('aNumber', { by: 1, silent: true });
this.clock.tick(1000);
return user.decrement('aNumber', { by: 1, silent: true }); await expect(User.findByPk(1)).to.eventually.have.property('updatedAt').equalTime(oldDate);
}).then(() => {
return expect(User.findByPk(1)).to.eventually.have.property('updatedAt').equalTime(oldDate);
});
}); });
}); });
}); });
...@@ -11,272 +11,241 @@ const chai = require('chai'), ...@@ -11,272 +11,241 @@ const chai = require('chai'),
describe(Support.getTestDialectTeaser('Instance'), () => { describe(Support.getTestDialectTeaser('Instance'), () => {
describe('destroy', () => { describe('destroy', () => {
if (current.dialect.supports.transactions) { if (current.dialect.supports.transactions) {
it('supports transactions', function() { it('supports transactions', async function() {
return Support.prepareTransactionTest(this.sequelize).then(sequelize => { const sequelize = await Support.prepareTransactionTest(this.sequelize);
const User = sequelize.define('User', { username: Support.Sequelize.STRING }); const User = sequelize.define('User', { username: Support.Sequelize.STRING });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({ username: 'foo' }).then(user => { const user = await User.create({ username: 'foo' });
return sequelize.transaction().then(t => { const t = await sequelize.transaction();
return user.destroy({ transaction: t }).then(() => { await user.destroy({ transaction: t });
return User.count().then(count1 => { const count1 = await User.count();
return User.count({ transaction: t }).then(count2 => { const count2 = await User.count({ transaction: t });
expect(count1).to.equal(1); expect(count1).to.equal(1);
expect(count2).to.equal(0); expect(count2).to.equal(0);
return t.rollback(); await t.rollback();
});
});
});
});
});
});
});
}); });
} }
it('does not set the deletedAt date in subsequent destroys if dao is paranoid', function() { it('does not set the deletedAt date in subsequent destroys if dao is paranoid', async function() {
const UserDestroy = this.sequelize.define('UserDestroy', { const UserDestroy = this.sequelize.define('UserDestroy', {
name: Support.Sequelize.STRING, name: Support.Sequelize.STRING,
bio: Support.Sequelize.TEXT bio: Support.Sequelize.TEXT
}, { paranoid: true }); }, { paranoid: true });
return UserDestroy.sync({ force: true }).then(() => { await UserDestroy.sync({ force: true });
return UserDestroy.create({ name: 'hallo', bio: 'welt' }).then(user => { const user = await UserDestroy.create({ name: 'hallo', bio: 'welt' });
return user.destroy().then(() => { await user.destroy();
return user.reload({ paranoid: false }).then(() => { await user.reload({ paranoid: false });
const deletedAt = user.deletedAt; const deletedAt = user.deletedAt;
return user.destroy().then(() => { await user.destroy();
return user.reload({ paranoid: false }).then(() => { await user.reload({ paranoid: false });
expect(user.deletedAt).to.eql(deletedAt); expect(user.deletedAt).to.eql(deletedAt);
});
});
});
});
});
});
}); });
it('does not update deletedAt with custom default in subsequent destroys', function() { it('does not update deletedAt with custom default in subsequent destroys', async function() {
const ParanoidUser = this.sequelize.define('ParanoidUser', { const ParanoidUser = this.sequelize.define('ParanoidUser', {
username: Support.Sequelize.STRING, username: Support.Sequelize.STRING,
deletedAt: { type: Support.Sequelize.DATE, defaultValue: new Date(0) } deletedAt: { type: Support.Sequelize.DATE, defaultValue: new Date(0) }
}, { paranoid: true }); }, { paranoid: true });
let deletedAt; await ParanoidUser.sync({ force: true });
return ParanoidUser.sync({ force: true }).then(() => {
return ParanoidUser.create({ const user1 = await ParanoidUser.create({
username: 'username' username: 'username'
});
}).then(user => {
return user.destroy();
}).then(user => {
deletedAt = user.deletedAt;
expect(deletedAt).to.be.ok;
expect(deletedAt.getTime()).to.be.ok;
return user.destroy();
}).then(user => {
expect(user).to.be.ok;
expect(user.deletedAt).to.be.ok;
expect(user.deletedAt.toISOString()).to.equal(deletedAt.toISOString());
}); });
const user0 = await user1.destroy();
const deletedAt = user0.deletedAt;
expect(deletedAt).to.be.ok;
expect(deletedAt.getTime()).to.be.ok;
const user = await user0.destroy();
expect(user).to.be.ok;
expect(user.deletedAt).to.be.ok;
expect(user.deletedAt.toISOString()).to.equal(deletedAt.toISOString());
}); });
it('deletes a record from the database if dao is not paranoid', function() { it('deletes a record from the database if dao is not paranoid', async function() {
const UserDestroy = this.sequelize.define('UserDestroy', { const UserDestroy = this.sequelize.define('UserDestroy', {
name: Support.Sequelize.STRING, name: Support.Sequelize.STRING,
bio: Support.Sequelize.TEXT bio: Support.Sequelize.TEXT
}); });
return UserDestroy.sync({ force: true }).then(() => { await UserDestroy.sync({ force: true });
return UserDestroy.create({ name: 'hallo', bio: 'welt' }).then(u => { const u = await UserDestroy.create({ name: 'hallo', bio: 'welt' });
return UserDestroy.findAll().then(users => { const users = await UserDestroy.findAll();
expect(users.length).to.equal(1); expect(users.length).to.equal(1);
return u.destroy().then(() => { await u.destroy();
return UserDestroy.findAll().then(users => { const users0 = await UserDestroy.findAll();
expect(users.length).to.equal(0); expect(users0.length).to.equal(0);
});
});
});
});
});
}); });
it('allows updating soft deleted instance', function() { it('allows updating soft deleted instance', async function() {
const ParanoidUser = this.sequelize.define('ParanoidUser', { const ParanoidUser = this.sequelize.define('ParanoidUser', {
username: Support.Sequelize.STRING username: Support.Sequelize.STRING
}, { paranoid: true }); }, { paranoid: true });
let deletedAt; await ParanoidUser.sync({ force: true });
return ParanoidUser.sync({ force: true }).then(() => {
return ParanoidUser.create({ const user2 = await ParanoidUser.create({
username: 'username' username: 'username'
}); });
}).then(user => {
return user.destroy(); const user1 = await user2.destroy();
}).then(user => { expect(user1.deletedAt).to.be.ok;
expect(user.deletedAt).to.be.ok; const deletedAt = user1.deletedAt;
deletedAt = user.deletedAt; user1.username = 'foo';
user.username = 'foo'; const user0 = await user1.save();
return user.save(); expect(user0.username).to.equal('foo');
}).then(user => { expect(user0.deletedAt).to.equal(deletedAt, 'should not update deletedAt');
expect(user.username).to.equal('foo');
expect(user.deletedAt).to.equal(deletedAt, 'should not update deletedAt'); const user = await ParanoidUser.findOne({
paranoid: false,
return ParanoidUser.findOne({ where: {
paranoid: false, username: 'foo'
where: { }
username: 'foo'
}
});
}).then(user => {
expect(user).to.be.ok;
expect(user.deletedAt).to.be.ok;
}); });
expect(user).to.be.ok;
expect(user.deletedAt).to.be.ok;
}); });
it('supports custom deletedAt field', function() { it('supports custom deletedAt field', async function() {
const ParanoidUser = this.sequelize.define('ParanoidUser', { const ParanoidUser = this.sequelize.define('ParanoidUser', {
username: Support.Sequelize.STRING, username: Support.Sequelize.STRING,
destroyTime: Support.Sequelize.DATE destroyTime: Support.Sequelize.DATE
}, { paranoid: true, deletedAt: 'destroyTime' }); }, { paranoid: true, deletedAt: 'destroyTime' });
return ParanoidUser.sync({ force: true }).then(() => { await ParanoidUser.sync({ force: true });
return ParanoidUser.create({
const user1 = await ParanoidUser.create({
username: 'username'
});
const user0 = await user1.destroy();
expect(user0.destroyTime).to.be.ok;
expect(user0.deletedAt).to.not.be.ok;
const user = await ParanoidUser.findOne({
paranoid: false,
where: {
username: 'username' username: 'username'
}); }
}).then(user => {
return user.destroy();
}).then(user => {
expect(user.destroyTime).to.be.ok;
expect(user.deletedAt).to.not.be.ok;
return ParanoidUser.findOne({
paranoid: false,
where: {
username: 'username'
}
});
}).then(user => {
expect(user).to.be.ok;
expect(user.destroyTime).to.be.ok;
expect(user.deletedAt).to.not.be.ok;
}); });
expect(user).to.be.ok;
expect(user.destroyTime).to.be.ok;
expect(user.deletedAt).to.not.be.ok;
}); });
it('supports custom deletedAt database column', function() { it('supports custom deletedAt database column', async function() {
const ParanoidUser = this.sequelize.define('ParanoidUser', { const ParanoidUser = this.sequelize.define('ParanoidUser', {
username: Support.Sequelize.STRING, username: Support.Sequelize.STRING,
deletedAt: { type: Support.Sequelize.DATE, field: 'deleted_at' } deletedAt: { type: Support.Sequelize.DATE, field: 'deleted_at' }
}, { paranoid: true }); }, { paranoid: true });
return ParanoidUser.sync({ force: true }).then(() => { await ParanoidUser.sync({ force: true });
return ParanoidUser.create({
const user1 = await ParanoidUser.create({
username: 'username'
});
const user0 = await user1.destroy();
expect(user0.dataValues.deletedAt).to.be.ok;
expect(user0.dataValues.deleted_at).to.not.be.ok;
const user = await ParanoidUser.findOne({
paranoid: false,
where: {
username: 'username' username: 'username'
}); }
}).then(user => {
return user.destroy();
}).then(user => {
expect(user.dataValues.deletedAt).to.be.ok;
expect(user.dataValues.deleted_at).to.not.be.ok;
return ParanoidUser.findOne({
paranoid: false,
where: {
username: 'username'
}
});
}).then(user => {
expect(user).to.be.ok;
expect(user.deletedAt).to.be.ok;
expect(user.deleted_at).to.not.be.ok;
}); });
expect(user).to.be.ok;
expect(user.deletedAt).to.be.ok;
expect(user.deleted_at).to.not.be.ok;
}); });
it('supports custom deletedAt field and database column', function() { it('supports custom deletedAt field and database column', async function() {
const ParanoidUser = this.sequelize.define('ParanoidUser', { const ParanoidUser = this.sequelize.define('ParanoidUser', {
username: Support.Sequelize.STRING, username: Support.Sequelize.STRING,
destroyTime: { type: Support.Sequelize.DATE, field: 'destroy_time' } destroyTime: { type: Support.Sequelize.DATE, field: 'destroy_time' }
}, { paranoid: true, deletedAt: 'destroyTime' }); }, { paranoid: true, deletedAt: 'destroyTime' });
return ParanoidUser.sync({ force: true }).then(() => { await ParanoidUser.sync({ force: true });
return ParanoidUser.create({
const user1 = await ParanoidUser.create({
username: 'username'
});
const user0 = await user1.destroy();
expect(user0.dataValues.destroyTime).to.be.ok;
expect(user0.dataValues.destroy_time).to.not.be.ok;
const user = await ParanoidUser.findOne({
paranoid: false,
where: {
username: 'username' username: 'username'
}); }
}).then(user => {
return user.destroy();
}).then(user => {
expect(user.dataValues.destroyTime).to.be.ok;
expect(user.dataValues.destroy_time).to.not.be.ok;
return ParanoidUser.findOne({
paranoid: false,
where: {
username: 'username'
}
});
}).then(user => {
expect(user).to.be.ok;
expect(user.destroyTime).to.be.ok;
expect(user.destroy_time).to.not.be.ok;
}); });
expect(user).to.be.ok;
expect(user.destroyTime).to.be.ok;
expect(user.destroy_time).to.not.be.ok;
}); });
it('persists other model changes when soft deleting', function() { it('persists other model changes when soft deleting', async function() {
const ParanoidUser = this.sequelize.define('ParanoidUser', { const ParanoidUser = this.sequelize.define('ParanoidUser', {
username: Support.Sequelize.STRING username: Support.Sequelize.STRING
}, { paranoid: true }); }, { paranoid: true });
let deletedAt; await ParanoidUser.sync({ force: true });
return ParanoidUser.sync({ force: true }).then(() => {
return ParanoidUser.create({ const user4 = await ParanoidUser.create({
username: 'username' username: 'username'
}); });
}).then(user => {
user.username = 'foo'; user4.username = 'foo';
return user.destroy(); const user3 = await user4.destroy();
}).then(user => { expect(user3.username).to.equal('foo');
expect(user.username).to.equal('foo'); expect(user3.deletedAt).to.be.ok;
expect(user.deletedAt).to.be.ok; const deletedAt = user3.deletedAt;
deletedAt = user.deletedAt;
const user2 = await ParanoidUser.findOne({
return ParanoidUser.findOne({ paranoid: false,
paranoid: false, where: {
where: { username: 'foo'
username: 'foo' }
} });
});
}).then(user => { expect(user2).to.be.ok;
expect(user).to.be.ok; expect(moment.utc(user2.deletedAt).startOf('second').toISOString())
expect(moment.utc(user.deletedAt).startOf('second').toISOString()) .to.equal(moment.utc(deletedAt).startOf('second').toISOString());
.to.equal(moment.utc(deletedAt).startOf('second').toISOString()); expect(user2.username).to.equal('foo');
expect(user.username).to.equal('foo'); const user1 = user2;
return user; // update model and delete again
}).then(user => { user1.username = 'bar';
// update model and delete again const user0 = await user1.destroy();
user.username = 'bar'; expect(moment.utc(user0.deletedAt).startOf('second').toISOString())
return user.destroy(); .to.equal(moment.utc(deletedAt).startOf('second').toISOString(),
}).then(user => { 'should not updated deletedAt when destroying multiple times');
expect(moment.utc(user.deletedAt).startOf('second').toISOString())
.to.equal(moment.utc(deletedAt).startOf('second').toISOString(), const user = await ParanoidUser.findOne({
'should not updated deletedAt when destroying multiple times'); paranoid: false,
where: {
return ParanoidUser.findOne({ username: 'bar'
paranoid: false, }
where: {
username: 'bar'
}
});
}).then(user => {
expect(user).to.be.ok;
expect(moment.utc(user.deletedAt).startOf('second').toISOString())
.to.equal(moment.utc(deletedAt).startOf('second').toISOString());
expect(user.username).to.equal('bar');
}); });
expect(user).to.be.ok;
expect(moment.utc(user.deletedAt).startOf('second').toISOString())
.to.equal(moment.utc(deletedAt).startOf('second').toISOString());
expect(user.username).to.equal('bar');
}); });
it('allows sql logging of delete statements', function() { it('allows sql logging of delete statements', async function() {
const UserDelete = this.sequelize.define('UserDelete', { const UserDelete = this.sequelize.define('UserDelete', {
name: Support.Sequelize.STRING, name: Support.Sequelize.STRING,
bio: Support.Sequelize.TEXT bio: Support.Sequelize.TEXT
...@@ -284,22 +253,18 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -284,22 +253,18 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
const logging = sinon.spy(); const logging = sinon.spy();
return UserDelete.sync({ force: true }).then(() => { await UserDelete.sync({ force: true });
return UserDelete.create({ name: 'hallo', bio: 'welt' }).then(u => { const u = await UserDelete.create({ name: 'hallo', bio: 'welt' });
return UserDelete.findAll().then(users => { const users = await UserDelete.findAll();
expect(users.length).to.equal(1); expect(users.length).to.equal(1);
return u.destroy({ logging }); await u.destroy({ logging });
}); expect(logging.callCount).to.equal(1, 'should call logging');
}); const sql = logging.firstCall.args[0];
}).then(() => { expect(sql).to.exist;
expect(logging.callCount).to.equal(1, 'should call logging'); expect(sql.toUpperCase()).to.include('DELETE');
const sql = logging.firstCall.args[0];
expect(sql).to.exist;
expect(sql.toUpperCase()).to.include('DELETE');
});
}); });
it('allows sql logging of update statements', function() { it('allows sql logging of update statements', async function() {
const UserDelete = this.sequelize.define('UserDelete', { const UserDelete = this.sequelize.define('UserDelete', {
name: Support.Sequelize.STRING, name: Support.Sequelize.STRING,
bio: Support.Sequelize.TEXT bio: Support.Sequelize.TEXT
...@@ -307,22 +272,18 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -307,22 +272,18 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
const logging = sinon.spy(); const logging = sinon.spy();
return UserDelete.sync({ force: true }).then(() => { await UserDelete.sync({ force: true });
return UserDelete.create({ name: 'hallo', bio: 'welt' }).then(u => { const u = await UserDelete.create({ name: 'hallo', bio: 'welt' });
return UserDelete.findAll().then(users => { const users = await UserDelete.findAll();
expect(users.length).to.equal(1); expect(users.length).to.equal(1);
return u.destroy({ logging }); await u.destroy({ logging });
}); expect(logging.callCount).to.equal(1, 'should call logging');
}); const sql = logging.firstCall.args[0];
}).then(() => { expect(sql).to.exist;
expect(logging.callCount).to.equal(1, 'should call logging'); expect(sql.toUpperCase()).to.include('UPDATE');
const sql = logging.firstCall.args[0];
expect(sql).to.exist;
expect(sql.toUpperCase()).to.include('UPDATE');
});
}); });
it('should not call save hooks when soft deleting', function() { it('should not call save hooks when soft deleting', async function() {
const beforeSave = sinon.spy(); const beforeSave = sinon.spy();
const afterSave = sinon.spy(); const afterSave = sinon.spy();
...@@ -336,31 +297,28 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -336,31 +297,28 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
} }
}); });
return ParanoidUser.sync({ force: true }).then(() => { await ParanoidUser.sync({ force: true });
return ParanoidUser.create({
username: 'username' const user0 = await ParanoidUser.create({
}); username: 'username'
}).then(user => {
// clear out calls from .create
beforeSave.resetHistory();
afterSave.resetHistory();
return user.destroy();
}).then(result => {
expect(beforeSave.callCount).to.equal(0, 'should not call beforeSave');
expect(afterSave.callCount).to.equal(0, 'should not call afterSave');
return result;
}).then(user => {
// now try with `hooks: true`
return user.destroy({ hooks: true });
}).then(result => {
expect(beforeSave.callCount).to.equal(0, 'should not call beforeSave even if `hooks: true`');
expect(afterSave.callCount).to.equal(0, 'should not call afterSave even if `hooks: true`');
return result;
}); });
// clear out calls from .create
beforeSave.resetHistory();
afterSave.resetHistory();
const result0 = await user0.destroy();
expect(beforeSave.callCount).to.equal(0, 'should not call beforeSave');
expect(afterSave.callCount).to.equal(0, 'should not call afterSave');
const user = result0;
const result = await user.destroy({ hooks: true });
expect(beforeSave.callCount).to.equal(0, 'should not call beforeSave even if `hooks: true`');
expect(afterSave.callCount).to.equal(0, 'should not call afterSave even if `hooks: true`');
await result;
}); });
it('delete a record of multiple primary keys table', function() { it('delete a record of multiple primary keys table', async function() {
const MultiPrimary = this.sequelize.define('MultiPrimary', { const MultiPrimary = this.sequelize.define('MultiPrimary', {
bilibili: { bilibili: {
type: Support.Sequelize.CHAR(2), type: Support.Sequelize.CHAR(2),
...@@ -373,33 +331,29 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -373,33 +331,29 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
} }
}); });
return MultiPrimary.sync({ force: true }).then(() => { await MultiPrimary.sync({ force: true });
return MultiPrimary.create({ bilibili: 'bl', guruguru: 'gu' }).then(() => { await MultiPrimary.create({ bilibili: 'bl', guruguru: 'gu' });
return MultiPrimary.create({ bilibili: 'bl', guruguru: 'ru' }).then(m2 => { const m2 = await MultiPrimary.create({ bilibili: 'bl', guruguru: 'ru' });
return MultiPrimary.findAll().then(ms => { const ms = await MultiPrimary.findAll();
expect(ms.length).to.equal(2); expect(ms.length).to.equal(2);
return m2.destroy({
logging(sql) { await m2.destroy({
expect(sql).to.exist; logging(sql) {
expect(sql.toUpperCase()).to.include('DELETE'); expect(sql).to.exist;
expect(sql).to.include('ru'); expect(sql.toUpperCase()).to.include('DELETE');
expect(sql).to.include('bl'); expect(sql).to.include('ru');
} expect(sql).to.include('bl');
}).then(() => { }
return MultiPrimary.findAll().then(ms => {
expect(ms.length).to.equal(1);
expect(ms[0].bilibili).to.equal('bl');
expect(ms[0].guruguru).to.equal('gu');
});
});
});
});
});
}); });
const ms0 = await MultiPrimary.findAll();
expect(ms0.length).to.equal(1);
expect(ms0[0].bilibili).to.equal('bl');
expect(ms0[0].guruguru).to.equal('gu');
}); });
if (dialect.match(/^postgres/)) { if (dialect.match(/^postgres/)) {
it('converts Infinity in where clause to a timestamp', function() { it('converts Infinity in where clause to a timestamp', async function() {
const Date = this.sequelize.define('Date', const Date = this.sequelize.define('Date',
{ {
date: { date: {
...@@ -413,14 +367,12 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -413,14 +367,12 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
}, },
{ paranoid: true }); { paranoid: true });
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => {
return Date.build({ date: Infinity }) const date = await Date.build({ date: Infinity })
.save() .save();
.then(date => {
return date.destroy(); await date.destroy();
});
});
}); });
} }
}); });
......
...@@ -20,7 +20,7 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -20,7 +20,7 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
this.clock.restore(); this.clock.restore();
}); });
beforeEach(function() { beforeEach(async function() {
this.User = this.sequelize.define('User', { this.User = this.sequelize.define('User', {
username: { type: DataTypes.STRING }, username: { type: DataTypes.STRING },
uuidv1: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV1 }, uuidv1: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV1 },
...@@ -52,169 +52,132 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -52,169 +52,132 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
} }
}); });
return this.User.sync({ force: true }); await this.User.sync({ force: true });
}); });
describe('increment', () => { describe('increment', () => {
beforeEach(function() { beforeEach(async function() {
return this.User.create({ id: 1, aNumber: 0, bNumber: 0 }); await this.User.create({ id: 1, aNumber: 0, bNumber: 0 });
}); });
if (current.dialect.supports.transactions) { if (current.dialect.supports.transactions) {
it('supports transactions', function() { it('supports transactions', async function() {
return Support.prepareTransactionTest(this.sequelize).then(sequelize => { const sequelize = await Support.prepareTransactionTest(this.sequelize);
const User = sequelize.define('User', { number: Support.Sequelize.INTEGER }); const User = sequelize.define('User', { number: Support.Sequelize.INTEGER });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({ number: 1 }).then(user => { const user = await User.create({ number: 1 });
return sequelize.transaction().then(t => { const t = await sequelize.transaction();
return user.increment('number', { by: 2, transaction: t }).then(() => { await user.increment('number', { by: 2, transaction: t });
return User.findAll().then(users1 => { const users1 = await User.findAll();
return User.findAll({ transaction: t }).then(users2 => { const users2 = await User.findAll({ transaction: t });
expect(users1[0].number).to.equal(1); expect(users1[0].number).to.equal(1);
expect(users2[0].number).to.equal(3); expect(users2[0].number).to.equal(3);
return t.rollback(); await t.rollback();
});
});
});
});
});
});
});
}); });
} }
if (current.dialect.supports.returnValues.returning) { if (current.dialect.supports.returnValues.returning) {
it('supports returning', function() { it('supports returning', async function() {
return this.User.findByPk(1).then(user1 => { const user1 = await this.User.findByPk(1);
return user1.increment('aNumber', { by: 2 }).then(() => { await user1.increment('aNumber', { by: 2 });
expect(user1.aNumber).to.be.equal(2); expect(user1.aNumber).to.be.equal(2);
return user1.increment('bNumber', { by: 2, returning: false }).then(user3 => { const user3 = await user1.increment('bNumber', { by: 2, returning: false });
expect(user3.bNumber).to.be.equal(0); expect(user3.bNumber).to.be.equal(0);
});
});
});
}); });
} }
it('supports where conditions', function() { it('supports where conditions', async function() {
return this.User.findByPk(1).then(user1 => { const user1 = await this.User.findByPk(1);
return user1.increment(['aNumber'], { by: 2, where: { bNumber: 1 } }).then(() => { await user1.increment(['aNumber'], { by: 2, where: { bNumber: 1 } });
return this.User.findByPk(1).then(user3 => { const user3 = await this.User.findByPk(1);
expect(user3.aNumber).to.be.equal(0); expect(user3.aNumber).to.be.equal(0);
});
});
});
}); });
it('with array', function() { it('with array', async function() {
return this.User.findByPk(1).then(user1 => { const user1 = await this.User.findByPk(1);
return user1.increment(['aNumber'], { by: 2 }).then(() => { await user1.increment(['aNumber'], { by: 2 });
return this.User.findByPk(1).then(user3 => { const user3 = await this.User.findByPk(1);
expect(user3.aNumber).to.be.equal(2); expect(user3.aNumber).to.be.equal(2);
});
});
});
}); });
it('with single field', function() { it('with single field', async function() {
return this.User.findByPk(1).then(user1 => { const user1 = await this.User.findByPk(1);
return user1.increment('aNumber', { by: 2 }).then(() => { await user1.increment('aNumber', { by: 2 });
return this.User.findByPk(1).then(user3 => { const user3 = await this.User.findByPk(1);
expect(user3.aNumber).to.be.equal(2); expect(user3.aNumber).to.be.equal(2);
});
});
});
}); });
it('with single field and no value', function() { it('with single field and no value', async function() {
return this.User.findByPk(1).then(user1 => { const user1 = await this.User.findByPk(1);
return user1.increment('aNumber').then(() => { await user1.increment('aNumber');
return this.User.findByPk(1).then(user2 => { const user2 = await this.User.findByPk(1);
expect(user2.aNumber).to.be.equal(1); expect(user2.aNumber).to.be.equal(1);
});
});
});
}); });
it('should still work right with other concurrent updates', function() { it('should still work right with other concurrent updates', async function() {
return this.User.findByPk(1).then(user1 => { const user1 = await this.User.findByPk(1);
// Select the user again (simulating a concurrent query) // Select the user again (simulating a concurrent query)
return this.User.findByPk(1).then(user2 => { const user2 = await this.User.findByPk(1);
return user2.update({
aNumber: user2.aNumber + 1 await user2.update({
}).then(() => { aNumber: user2.aNumber + 1
return user1.increment(['aNumber'], { by: 2 }).then(() => {
return this.User.findByPk(1).then(user5 => {
expect(user5.aNumber).to.be.equal(3);
});
});
});
});
}); });
await user1.increment(['aNumber'], { by: 2 });
const user5 = await this.User.findByPk(1);
expect(user5.aNumber).to.be.equal(3);
}); });
it('should still work right with other concurrent increments', function() { it('should still work right with other concurrent increments', async function() {
return this.User.findByPk(1).then(user1 => { const user1 = await this.User.findByPk(1);
return Promise.all([
user1.increment(['aNumber'], { by: 2 }), await Promise.all([
user1.increment(['aNumber'], { by: 2 }), user1.increment(['aNumber'], { by: 2 }),
user1.increment(['aNumber'], { by: 2 }) user1.increment(['aNumber'], { by: 2 }),
]).then(() => { user1.increment(['aNumber'], { by: 2 })
return this.User.findByPk(1).then(user2 => { ]);
expect(user2.aNumber).to.equal(6);
}); const user2 = await this.User.findByPk(1);
}); expect(user2.aNumber).to.equal(6);
});
}); });
it('with key value pair', function() { it('with key value pair', async function() {
return this.User.findByPk(1).then(user1 => { const user1 = await this.User.findByPk(1);
return user1.increment({ 'aNumber': 1, 'bNumber': 2 }).then(() => { await user1.increment({ 'aNumber': 1, 'bNumber': 2 });
return this.User.findByPk(1).then(user3 => { const user3 = await this.User.findByPk(1);
expect(user3.aNumber).to.be.equal(1); expect(user3.aNumber).to.be.equal(1);
expect(user3.bNumber).to.be.equal(2); expect(user3.bNumber).to.be.equal(2);
});
});
});
}); });
it('with timestamps set to true', function() { it('with timestamps set to true', async function() {
const User = this.sequelize.define('IncrementUser', { const User = this.sequelize.define('IncrementUser', {
aNumber: DataTypes.INTEGER aNumber: DataTypes.INTEGER
}, { timestamps: true }); }, { timestamps: true });
let oldDate; await User.sync({ force: true });
const user1 = await User.create({ aNumber: 1 });
const oldDate = user1.get('updatedAt');
return User.sync({ force: true }) this.clock.tick(1000);
.then(() => User.create({ aNumber: 1 })) const user0 = await user1.increment('aNumber', { by: 1 });
.then(user => { const user = await user0.reload();
oldDate = user.get('updatedAt');
this.clock.tick(1000); await expect(user).to.have.property('updatedAt').afterTime(oldDate);
return user.increment('aNumber', { by: 1 });
})
.then(user => user.reload())
.then(user => {
return expect(user).to.have.property('updatedAt').afterTime(oldDate);
});
}); });
it('with timestamps set to true and options.silent set to true', function() { it('with timestamps set to true and options.silent set to true', async function() {
const User = this.sequelize.define('IncrementUser', { const User = this.sequelize.define('IncrementUser', {
aNumber: DataTypes.INTEGER aNumber: DataTypes.INTEGER
}, { timestamps: true }); }, { timestamps: true });
let oldDate;
await User.sync({ force: true });
return User.sync({ force: true }).then(() => { const user = await User.create({ aNumber: 1 });
return User.create({ aNumber: 1 }); const oldDate = user.updatedAt;
}).then(user => { this.clock.tick(1000);
oldDate = user.updatedAt; await user.increment('aNumber', { by: 1, silent: true });
this.clock.tick(1000);
return user.increment('aNumber', { by: 1, silent: true }); await expect(User.findByPk(1)).to.eventually.have.property('updatedAt').equalTime(oldDate);
}).then(() => {
return expect(User.findByPk(1)).to.eventually.have.property('updatedAt').equalTime(oldDate);
});
}); });
}); });
}); });
...@@ -21,7 +21,7 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -21,7 +21,7 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
this.clock.restore(); this.clock.restore();
}); });
beforeEach(function() { beforeEach(async function() {
this.User = this.sequelize.define('User', { this.User = this.sequelize.define('User', {
username: { type: DataTypes.STRING }, username: { type: DataTypes.STRING },
uuidv1: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV1 }, uuidv1: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV1 },
...@@ -53,42 +53,32 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -53,42 +53,32 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
} }
}); });
return this.User.sync({ force: true }); await this.User.sync({ force: true });
}); });
describe('reload', () => { describe('reload', () => {
if (current.dialect.supports.transactions) { if (current.dialect.supports.transactions) {
it('supports transactions', function() { it('supports transactions', async function() {
return Support.prepareTransactionTest(this.sequelize).then(sequelize => { const sequelize = await Support.prepareTransactionTest(this.sequelize);
const User = sequelize.define('User', { username: Support.Sequelize.STRING }); const User = sequelize.define('User', { username: Support.Sequelize.STRING });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({ username: 'foo' }).then(user => { const user = await User.create({ username: 'foo' });
return sequelize.transaction().then(t => { const t = await sequelize.transaction();
return User.update({ username: 'bar' }, { where: { username: 'foo' }, transaction: t }).then(() => { await User.update({ username: 'bar' }, { where: { username: 'foo' }, transaction: t });
return user.reload().then(user => { const user1 = await user.reload();
expect(user.username).to.equal('foo'); expect(user1.username).to.equal('foo');
return user.reload({ transaction: t }).then(user => { const user0 = await user1.reload({ transaction: t });
expect(user.username).to.equal('bar'); expect(user0.username).to.equal('bar');
return t.rollback(); await t.rollback();
});
});
});
});
});
});
});
}); });
} }
it('should return a reference to the same DAO instead of creating a new one', function() { it('should return a reference to the same DAO instead of creating a new one', async function() {
return this.User.create({ username: 'John Doe' }).then(originalUser => { const originalUser = await this.User.create({ username: 'John Doe' });
return originalUser.update({ username: 'Doe John' }).then(() => { await originalUser.update({ username: 'Doe John' });
return originalUser.reload().then(updatedUser => { const updatedUser = await originalUser.reload();
expect(originalUser === updatedUser).to.be.true; expect(originalUser === updatedUser).to.be.true;
});
});
});
}); });
it('should use default internal where', async function() { it('should use default internal where', async function() {
...@@ -105,202 +95,183 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -105,202 +95,183 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
expect(user.get('id')).to.equal(primaryKey).and.not.equal(anotherUser.get('id')); expect(user.get('id')).to.equal(primaryKey).and.not.equal(anotherUser.get('id'));
}); });
it('should update the values on all references to the DAO', function() { it('should update the values on all references to the DAO', async function() {
return this.User.create({ username: 'John Doe' }).then(originalUser => { const originalUser = await this.User.create({ username: 'John Doe' });
return this.User.findByPk(originalUser.id).then(updater => { const updater = await this.User.findByPk(originalUser.id);
return updater.update({ username: 'Doe John' }).then(() => { await updater.update({ username: 'Doe John' });
// We used a different reference when calling update, so originalUser is now out of sync // We used a different reference when calling update, so originalUser is now out of sync
expect(originalUser.username).to.equal('John Doe'); expect(originalUser.username).to.equal('John Doe');
return originalUser.reload().then(updatedUser => { const updatedUser = await originalUser.reload();
expect(originalUser.username).to.equal('Doe John'); expect(originalUser.username).to.equal('Doe John');
expect(updatedUser.username).to.equal('Doe John'); expect(updatedUser.username).to.equal('Doe John');
});
});
});
});
}); });
it('should support updating a subset of attributes', function() { it('should support updating a subset of attributes', async function() {
return this.User.create({ const user1 = await this.User.create({
aNumber: 1, aNumber: 1,
bNumber: 1 bNumber: 1
}).then(user => {
return Promise.resolve(this.User.update({
bNumber: 2
}, {
where: {
id: user.get('id')
}
})).then(() => user);
}).then(user => {
return user.reload({
attributes: ['bNumber']
});
}).then(user => {
expect(user.get('aNumber')).to.equal(1);
expect(user.get('bNumber')).to.equal(2);
}); });
});
it('should update read only attributes as well (updatedAt)', function() { await this.User.update({
return this.User.create({ username: 'John Doe' }).then(originalUser => { bNumber: 2
this.originallyUpdatedAt = originalUser.updatedAt; }, {
this.originalUser = originalUser; where: {
id: user1.get('id')
// Wait for a second, so updatedAt will actually be different }
this.clock.tick(1000);
return this.User.findByPk(originalUser.id);
}).then(updater => {
return updater.update({ username: 'Doe John' });
}).then(updatedUser => {
this.updatedUser = updatedUser;
return this.originalUser.reload();
}).then(() => {
expect(this.originalUser.updatedAt).to.be.above(this.originallyUpdatedAt);
expect(this.updatedUser.updatedAt).to.be.above(this.originallyUpdatedAt);
}); });
const user0 = user1;
const user = await user0.reload({
attributes: ['bNumber']
});
expect(user.get('aNumber')).to.equal(1);
expect(user.get('bNumber')).to.equal(2);
}); });
it('should update the associations as well', function() { it('should update read only attributes as well (updatedAt)', async function() {
const originalUser = await this.User.create({ username: 'John Doe' });
this.originallyUpdatedAt = originalUser.updatedAt;
this.originalUser = originalUser;
// Wait for a second, so updatedAt will actually be different
this.clock.tick(1000);
const updater = await this.User.findByPk(originalUser.id);
const updatedUser = await updater.update({ username: 'Doe John' });
this.updatedUser = updatedUser;
await this.originalUser.reload();
expect(this.originalUser.updatedAt).to.be.above(this.originallyUpdatedAt);
expect(this.updatedUser.updatedAt).to.be.above(this.originallyUpdatedAt);
});
it('should update the associations as well', async function() {
const Book = this.sequelize.define('Book', { title: DataTypes.STRING }), const Book = this.sequelize.define('Book', { title: DataTypes.STRING }),
Page = this.sequelize.define('Page', { content: DataTypes.TEXT }); Page = this.sequelize.define('Page', { content: DataTypes.TEXT });
Book.hasMany(Page); Book.hasMany(Page);
Page.belongsTo(Book); Page.belongsTo(Book);
return Book.sync({ force: true }).then(() => { await Book.sync({ force: true });
return Page.sync({ force: true }).then(() => { await Page.sync({ force: true });
return Book.create({ title: 'A very old book' }).then(book => { const book = await Book.create({ title: 'A very old book' });
return Page.create({ content: 'om nom nom' }).then(page => { const page = await Page.create({ content: 'om nom nom' });
return book.setPages([page]).then(() => { await book.setPages([page]);
return Book.findOne({
where: { id: book.id }, const leBook = await Book.findOne({
include: [Page] where: { id: book.id },
}).then(leBook => { include: [Page]
return page.update({ content: 'something totally different' }).then(page => {
expect(leBook.Pages.length).to.equal(1);
expect(leBook.Pages[0].content).to.equal('om nom nom');
expect(page.content).to.equal('something totally different');
return leBook.reload().then(leBook => {
expect(leBook.Pages.length).to.equal(1);
expect(leBook.Pages[0].content).to.equal('something totally different');
expect(page.content).to.equal('something totally different');
});
});
});
});
});
});
});
}); });
const page0 = await page.update({ content: 'something totally different' });
expect(leBook.Pages.length).to.equal(1);
expect(leBook.Pages[0].content).to.equal('om nom nom');
expect(page0.content).to.equal('something totally different');
const leBook0 = await leBook.reload();
expect(leBook0.Pages.length).to.equal(1);
expect(leBook0.Pages[0].content).to.equal('something totally different');
expect(page0.content).to.equal('something totally different');
}); });
it('should update internal options of the instance', function() { it('should update internal options of the instance', async function() {
const Book = this.sequelize.define('Book', { title: DataTypes.STRING }), const Book = this.sequelize.define('Book', { title: DataTypes.STRING }),
Page = this.sequelize.define('Page', { content: DataTypes.TEXT }); Page = this.sequelize.define('Page', { content: DataTypes.TEXT });
Book.hasMany(Page); Book.hasMany(Page);
Page.belongsTo(Book); Page.belongsTo(Book);
return Book.sync({ force: true }).then(() => { await Book.sync({ force: true });
return Page.sync({ force: true }).then(() => { await Page.sync({ force: true });
return Book.create({ title: 'A very old book' }).then(book => { const book = await Book.create({ title: 'A very old book' });
return Page.create().then(page => { const page = await Page.create();
return book.setPages([page]).then(() => { await book.setPages([page]);
return Book.findOne({
where: { id: book.id } const leBook = await Book.findOne({
}).then(leBook => { where: { id: book.id }
const oldOptions = leBook._options;
return leBook.reload({
include: [Page]
}).then(leBook => {
expect(oldOptions).not.to.equal(leBook._options);
expect(leBook._options.include.length).to.equal(1);
expect(leBook.Pages.length).to.equal(1);
expect(leBook.get({ plain: true }).Pages.length).to.equal(1);
});
});
});
});
});
});
}); });
});
it('should return an error when reload fails', function() { const oldOptions = leBook._options;
return this.User.create({ username: 'John Doe' }).then(user => {
return user.destroy().then(() => { const leBook0 = await leBook.reload({
return expect(user.reload()).to.be.rejectedWith( include: [Page]
Sequelize.InstanceError,
'Instance could not be reloaded because it does not exist anymore (find call returned null)'
);
});
}); });
expect(oldOptions).not.to.equal(leBook0._options);
expect(leBook0._options.include.length).to.equal(1);
expect(leBook0.Pages.length).to.equal(1);
expect(leBook0.get({ plain: true }).Pages.length).to.equal(1);
});
it('should return an error when reload fails', async function() {
const user = await this.User.create({ username: 'John Doe' });
await user.destroy();
await expect(user.reload()).to.be.rejectedWith(
Sequelize.InstanceError,
'Instance could not be reloaded because it does not exist anymore (find call returned null)'
);
}); });
it('should set an association to null after deletion, 1-1', function() { it('should set an association to null after deletion, 1-1', async function() {
const Shoe = this.sequelize.define('Shoe', { brand: DataTypes.STRING }), const Shoe = this.sequelize.define('Shoe', { brand: DataTypes.STRING }),
Player = this.sequelize.define('Player', { name: DataTypes.STRING }); Player = this.sequelize.define('Player', { name: DataTypes.STRING });
Player.hasOne(Shoe); Player.hasOne(Shoe);
Shoe.belongsTo(Player); Shoe.belongsTo(Player);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Shoe.create({
brand: 'the brand', const shoe = await Shoe.create({
Player: { brand: 'the brand',
name: 'the player' Player: {
} name: 'the player'
}, { include: [Player] }); }
}).then(shoe => { }, { include: [Player] });
return Player.findOne({
where: { id: shoe.Player.id }, const lePlayer1 = await Player.findOne({
include: [Shoe] where: { id: shoe.Player.id },
}).then(lePlayer => { include: [Shoe]
expect(lePlayer.Shoe).not.to.be.null;
return lePlayer.Shoe.destroy().then(() => lePlayer);
}).then(lePlayer => {
return lePlayer.reload();
}).then(lePlayer => {
expect(lePlayer.Shoe).to.be.null;
});
}); });
expect(lePlayer1.Shoe).not.to.be.null;
await lePlayer1.Shoe.destroy();
const lePlayer0 = lePlayer1;
const lePlayer = await lePlayer0.reload();
expect(lePlayer.Shoe).to.be.null;
}); });
it('should set an association to empty after all deletion, 1-N', function() { it('should set an association to empty after all deletion, 1-N', async function() {
const Team = this.sequelize.define('Team', { name: DataTypes.STRING }), const Team = this.sequelize.define('Team', { name: DataTypes.STRING }),
Player = this.sequelize.define('Player', { name: DataTypes.STRING }); Player = this.sequelize.define('Player', { name: DataTypes.STRING });
Team.hasMany(Player); Team.hasMany(Player);
Player.belongsTo(Team); Player.belongsTo(Team);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Team.create({
name: 'the team', const team = await Team.create({
Players: [{ name: 'the team',
name: 'the player1' Players: [{
}, { name: 'the player1'
name: 'the player2' }, {
}] name: 'the player2'
}, { include: [Player] }); }]
}).then(team => { }, { include: [Player] });
return Team.findOne({
where: { id: team.id }, const leTeam1 = await Team.findOne({
include: [Player] where: { id: team.id },
}).then(leTeam => { include: [Player]
expect(leTeam.Players).not.to.be.empty;
return leTeam.Players[1].destroy().then(() => {
return leTeam.Players[0].destroy();
}).then(() => leTeam);
}).then(leTeam => {
return leTeam.reload();
}).then(leTeam => {
expect(leTeam.Players).to.be.empty;
});
}); });
expect(leTeam1.Players).not.to.be.empty;
await leTeam1.Players[1].destroy();
await leTeam1.Players[0].destroy();
const leTeam0 = leTeam1;
const leTeam = await leTeam0.reload();
expect(leTeam.Players).to.be.empty;
}); });
it('should update the associations after one element deleted', function() { it('should update the associations after one element deleted', async function() {
const Team = this.sequelize.define('Team', { name: DataTypes.STRING }), const Team = this.sequelize.define('Team', { name: DataTypes.STRING }),
Player = this.sequelize.define('Player', { name: DataTypes.STRING }); Player = this.sequelize.define('Player', { name: DataTypes.STRING });
...@@ -308,28 +279,27 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -308,28 +279,27 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
Player.belongsTo(Team); Player.belongsTo(Team);
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return Team.create({
name: 'the team', const team = await Team.create({
Players: [{ name: 'the team',
name: 'the player1' Players: [{
}, { name: 'the player1'
name: 'the player2' }, {
}] name: 'the player2'
}, { include: [Player] }); }]
}).then(team => { }, { include: [Player] });
return Team.findOne({
where: { id: team.id }, const leTeam1 = await Team.findOne({
include: [Player] where: { id: team.id },
}).then(leTeam => { include: [Player]
expect(leTeam.Players).to.have.length(2);
return leTeam.Players[0].destroy().then(() => leTeam);
}).then(leTeam => {
return leTeam.reload();
}).then(leTeam => {
expect(leTeam.Players).to.have.length(1);
});
}); });
expect(leTeam1.Players).to.have.length(2);
await leTeam1.Players[0].destroy();
const leTeam0 = leTeam1;
const leTeam = await leTeam0.reload();
expect(leTeam.Players).to.have.length(1);
}); });
}); });
}); });
...@@ -22,7 +22,7 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -22,7 +22,7 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
this.clock.restore(); this.clock.restore();
}); });
beforeEach(function() { beforeEach(async function() {
this.User = this.sequelize.define('User', { this.User = this.sequelize.define('User', {
username: { type: DataTypes.STRING }, username: { type: DataTypes.STRING },
uuidv1: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV1 }, uuidv1: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV1 },
...@@ -54,83 +54,74 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -54,83 +54,74 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
} }
}); });
return this.User.sync({ force: true }); await this.User.sync({ force: true });
}); });
describe('save', () => { describe('save', () => {
if (current.dialect.supports.transactions) { if (current.dialect.supports.transactions) {
it('supports transactions', function() { it('supports transactions', async function() {
return Support.prepareTransactionTest(this.sequelize).then(sequelize => { const sequelize = await Support.prepareTransactionTest(this.sequelize);
const User = sequelize.define('User', { username: Support.Sequelize.STRING }); const User = sequelize.define('User', { username: Support.Sequelize.STRING });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return sequelize.transaction().then(t => { const t = await sequelize.transaction();
return User.build({ username: 'foo' }).save({ transaction: t }).then(() => { await User.build({ username: 'foo' }).save({ transaction: t });
return User.count().then(count1 => { const count1 = await User.count();
return User.count({ transaction: t }).then(count2 => { const count2 = await User.count({ transaction: t });
expect(count1).to.equal(0); expect(count1).to.equal(0);
expect(count2).to.equal(1); expect(count2).to.equal(1);
return t.rollback(); await t.rollback();
});
});
});
});
});
});
}); });
} }
it('only updates fields in passed array', function() { it('only updates fields in passed array', async function() {
const date = new Date(1990, 1, 1); const date = new Date(1990, 1, 1);
return this.User.create({ const user = await this.User.create({
username: 'foo', username: 'foo',
touchedAt: new Date() touchedAt: new Date()
}).then(user => {
user.username = 'fizz';
user.touchedAt = date;
return user.save({ fields: ['username'] }).then(() => {
// re-select user
return this.User.findByPk(user.id).then(user2 => {
// name should have changed
expect(user2.username).to.equal('fizz');
// bio should be unchanged
expect(user2.birthDate).not.to.equal(date);
});
});
}); });
user.username = 'fizz';
user.touchedAt = date;
await user.save({ fields: ['username'] });
// re-select user
const user2 = await this.User.findByPk(user.id);
// name should have changed
expect(user2.username).to.equal('fizz');
// bio should be unchanged
expect(user2.birthDate).not.to.equal(date);
}); });
it('should work on a model with an attribute named length', function() { it('should work on a model with an attribute named length', async function() {
const Box = this.sequelize.define('box', { const Box = this.sequelize.define('box', {
length: DataTypes.INTEGER, length: DataTypes.INTEGER,
width: DataTypes.INTEGER, width: DataTypes.INTEGER,
height: DataTypes.INTEGER height: DataTypes.INTEGER
}); });
return Box.sync({ force: true }).then(() => { await Box.sync({ force: true });
return Box.create({
length: 1, const box0 = await Box.create({
width: 2, length: 1,
height: 3 width: 2,
}).then(box => { height: 3
return box.update({ });
length: 4,
width: 5, await box0.update({
height: 6 length: 4,
}); width: 5,
}).then(() => { height: 6
return Box.findOne({}).then(box => {
expect(box.get('length')).to.equal(4);
expect(box.get('width')).to.equal(5);
expect(box.get('height')).to.equal(6);
});
});
}); });
const box = await Box.findOne({});
expect(box.get('length')).to.equal(4);
expect(box.get('width')).to.equal(5);
expect(box.get('height')).to.equal(6);
}); });
it('only validates fields in passed array', function() { it('only validates fields in passed array', async function() {
return this.User.build({ await this.User.build({
validateTest: 'cake', // invalid, but not saved validateTest: 'cake', // invalid, but not saved
validateCustom: '1' validateCustom: '1'
}).save({ }).save({
...@@ -139,7 +130,7 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -139,7 +130,7 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
}); });
describe('hooks', () => { describe('hooks', () => {
it('should update attributes added in hooks when default fields are used', function() { it('should update attributes added in hooks when default fields are used', async function() {
const User = this.sequelize.define(`User${config.rand()}`, { const User = this.sequelize.define(`User${config.rand()}`, {
name: DataTypes.STRING, name: DataTypes.STRING,
bio: DataTypes.TEXT, bio: DataTypes.TEXT,
...@@ -150,27 +141,26 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -150,27 +141,26 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
instance.set('email', 'B'); instance.set('email', 'B');
}); });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({
name: 'A', const user0 = await User.create({
bio: 'A', name: 'A',
email: 'A' bio: 'A',
}).then(user => { email: 'A'
return user.set({
name: 'B',
bio: 'B'
}).save();
}).then(() => {
return User.findOne({});
}).then(user => {
expect(user.get('name')).to.equal('B');
expect(user.get('bio')).to.equal('B');
expect(user.get('email')).to.equal('B');
});
}); });
await user0.set({
name: 'B',
bio: 'B'
}).save();
const user = await User.findOne({});
expect(user.get('name')).to.equal('B');
expect(user.get('bio')).to.equal('B');
expect(user.get('email')).to.equal('B');
}); });
it('should update attributes changed in hooks when default fields are used', function() { it('should update attributes changed in hooks when default fields are used', async function() {
const User = this.sequelize.define(`User${config.rand()}`, { const User = this.sequelize.define(`User${config.rand()}`, {
name: DataTypes.STRING, name: DataTypes.STRING,
bio: DataTypes.TEXT, bio: DataTypes.TEXT,
...@@ -181,28 +171,27 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -181,28 +171,27 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
instance.set('email', 'C'); instance.set('email', 'C');
}); });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({
name: 'A', const user0 = await User.create({
bio: 'A', name: 'A',
email: 'A' bio: 'A',
}).then(user => { email: 'A'
return user.set({
name: 'B',
bio: 'B',
email: 'B'
}).save();
}).then(() => {
return User.findOne({});
}).then(user => {
expect(user.get('name')).to.equal('B');
expect(user.get('bio')).to.equal('B');
expect(user.get('email')).to.equal('C');
});
}); });
await user0.set({
name: 'B',
bio: 'B',
email: 'B'
}).save();
const user = await User.findOne({});
expect(user.get('name')).to.equal('B');
expect(user.get('bio')).to.equal('B');
expect(user.get('email')).to.equal('C');
}); });
it('should validate attributes added in hooks when default fields are used', function() { it('should validate attributes added in hooks when default fields are used', async function() {
const User = this.sequelize.define(`User${config.rand()}`, { const User = this.sequelize.define(`User${config.rand()}`, {
name: DataTypes.STRING, name: DataTypes.STRING,
bio: DataTypes.TEXT, bio: DataTypes.TEXT,
...@@ -218,24 +207,23 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -218,24 +207,23 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
instance.set('email', 'B'); instance.set('email', 'B');
}); });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({
name: 'A', const user0 = await User.create({
bio: 'A', name: 'A',
email: 'valid.email@gmail.com' bio: 'A',
}).then(user => { email: 'valid.email@gmail.com'
return expect(user.set({
name: 'B'
}).save()).to.be.rejectedWith(Sequelize.ValidationError);
}).then(() => {
return User.findOne({}).then(user => {
expect(user.get('email')).to.equal('valid.email@gmail.com');
});
});
}); });
await expect(user0.set({
name: 'B'
}).save()).to.be.rejectedWith(Sequelize.ValidationError);
const user = await User.findOne({});
expect(user.get('email')).to.equal('valid.email@gmail.com');
}); });
it('should validate attributes changed in hooks when default fields are used', function() { it('should validate attributes changed in hooks when default fields are used', async function() {
const User = this.sequelize.define(`User${config.rand()}`, { const User = this.sequelize.define(`User${config.rand()}`, {
name: DataTypes.STRING, name: DataTypes.STRING,
bio: DataTypes.TEXT, bio: DataTypes.TEXT,
...@@ -251,26 +239,25 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -251,26 +239,25 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
instance.set('email', 'B'); instance.set('email', 'B');
}); });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({
name: 'A', const user0 = await User.create({
bio: 'A', name: 'A',
email: 'valid.email@gmail.com' bio: 'A',
}).then(user => { email: 'valid.email@gmail.com'
return expect(user.set({
name: 'B',
email: 'still.valid.email@gmail.com'
}).save()).to.be.rejectedWith(Sequelize.ValidationError);
}).then(() => {
return User.findOne({}).then(user => {
expect(user.get('email')).to.equal('valid.email@gmail.com');
});
});
}); });
await expect(user0.set({
name: 'B',
email: 'still.valid.email@gmail.com'
}).save()).to.be.rejectedWith(Sequelize.ValidationError);
const user = await User.findOne({});
expect(user.get('email')).to.equal('valid.email@gmail.com');
}); });
}); });
it('stores an entry in the database', function() { it('stores an entry in the database', async function() {
const username = 'user', const username = 'user',
User = this.User, User = this.User,
user = this.User.build({ user = this.User.build({
...@@ -278,20 +265,17 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -278,20 +265,17 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
touchedAt: new Date(1984, 8, 23) touchedAt: new Date(1984, 8, 23)
}); });
return User.findAll().then(users => { const users = await User.findAll();
expect(users).to.have.length(0); expect(users).to.have.length(0);
return user.save().then(() => { await user.save();
return User.findAll().then(users => { const users0 = await User.findAll();
expect(users).to.have.length(1); expect(users0).to.have.length(1);
expect(users[0].username).to.equal(username); expect(users0[0].username).to.equal(username);
expect(users[0].touchedAt).to.be.instanceof(Date); expect(users0[0].touchedAt).to.be.instanceof(Date);
expect(users[0].touchedAt).to.equalDate(new Date(1984, 8, 23)); expect(users0[0].touchedAt).to.equalDate(new Date(1984, 8, 23));
});
});
});
}); });
it('handles an entry with primaryKey of zero', function() { it('handles an entry with primaryKey of zero', async function() {
const username = 'user', const username = 'user',
newUsername = 'newUser', newUsername = 'newUser',
User2 = this.sequelize.define('User2', User2 = this.sequelize.define('User2',
...@@ -304,100 +288,84 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -304,100 +288,84 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
username: { type: DataTypes.STRING } username: { type: DataTypes.STRING }
}); });
return User2.sync().then(() => { await User2.sync();
return User2.create({ id: 0, username }).then(user => { const user = await User2.create({ id: 0, username });
expect(user).to.be.ok; expect(user).to.be.ok;
expect(user.id).to.equal(0); expect(user.id).to.equal(0);
expect(user.username).to.equal(username); expect(user.username).to.equal(username);
return User2.findByPk(0).then(user => { const user1 = await User2.findByPk(0);
expect(user).to.be.ok; expect(user1).to.be.ok;
expect(user.id).to.equal(0); expect(user1.id).to.equal(0);
expect(user.username).to.equal(username); expect(user1.username).to.equal(username);
return user.update({ username: newUsername }).then(user => { const user0 = await user1.update({ username: newUsername });
expect(user).to.be.ok; expect(user0).to.be.ok;
expect(user.id).to.equal(0); expect(user0.id).to.equal(0);
expect(user.username).to.equal(newUsername); expect(user0.username).to.equal(newUsername);
});
});
});
});
}); });
it('updates the timestamps', function() { it('updates the timestamps', async function() {
const now = new Date(); const now = new Date();
now.setMilliseconds(0); now.setMilliseconds(0);
const user = this.User.build({ username: 'user' }); const user = this.User.build({ username: 'user' });
this.clock.tick(1000); this.clock.tick(1000);
return user.save().then(savedUser => { const savedUser = await user.save();
expect(savedUser).have.property('updatedAt').afterTime(now); expect(savedUser).have.property('updatedAt').afterTime(now);
this.clock.tick(1000); this.clock.tick(1000);
return savedUser.save(); const updatedUser = await savedUser.save();
}).then(updatedUser => { expect(updatedUser).have.property('updatedAt').afterTime(now);
expect(updatedUser).have.property('updatedAt').afterTime(now);
});
}); });
it('does not update timestamps when passing silent=true', function() { it('does not update timestamps when passing silent=true', async function() {
return this.User.create({ username: 'user' }).then(user => { const user = await this.User.create({ username: 'user' });
const updatedAt = user.updatedAt; const updatedAt = user.updatedAt;
this.clock.tick(1000); this.clock.tick(1000);
return expect(user.update({
username: 'userman' await expect(user.update({
}, { username: 'userman'
silent: true }, {
})).to.eventually.have.property('updatedAt').equalTime(updatedAt); silent: true
}); })).to.eventually.have.property('updatedAt').equalTime(updatedAt);
}); });
it('does not update timestamps when passing silent=true in a bulk update', function() { it('does not update timestamps when passing silent=true in a bulk update', async function() {
const data = [ const data = [
{ username: 'Paul' }, { username: 'Paul' },
{ username: 'Peter' } { username: 'Peter' }
]; ];
let updatedAtPeter,
updatedAtPaul; await this.User.bulkCreate(data);
const users0 = await this.User.findAll();
return this.User.bulkCreate(data).then(() => { const updatedAtPaul = users0[0].updatedAt;
return this.User.findAll(); const updatedAtPeter = users0[1].updatedAt;
}).then(users => { this.clock.tick(150);
updatedAtPaul = users[0].updatedAt;
updatedAtPeter = users[1].updatedAt; await this.User.update(
}) { aNumber: 1 },
.then(() => { { where: {}, silent: true }
this.clock.tick(150); );
return this.User.update(
{ aNumber: 1 }, const users = await this.User.findAll();
{ where: {}, silent: true } expect(users[0].updatedAt).to.equalTime(updatedAtPeter);
); expect(users[1].updatedAt).to.equalTime(updatedAtPaul);
}).then(() => {
return this.User.findAll();
}).then(users => {
expect(users[0].updatedAt).to.equalTime(updatedAtPeter);
expect(users[1].updatedAt).to.equalTime(updatedAtPaul);
});
}); });
describe('when nothing changed', () => { describe('when nothing changed', () => {
it('does not update timestamps', function() { it('does not update timestamps', async function() {
return this.User.create({ username: 'John' }).then(() => { await this.User.create({ username: 'John' });
return this.User.findOne({ where: { username: 'John' } }).then(user => { const user = await this.User.findOne({ where: { username: 'John' } });
const updatedAt = user.updatedAt; const updatedAt = user.updatedAt;
this.clock.tick(2000); this.clock.tick(2000);
return user.save().then(newlySavedUser => { const newlySavedUser = await user.save();
expect(newlySavedUser.updatedAt).to.equalTime(updatedAt); expect(newlySavedUser.updatedAt).to.equalTime(updatedAt);
return this.User.findOne({ where: { username: 'John' } }).then(newlySavedUser => { const newlySavedUser0 = await this.User.findOne({ where: { username: 'John' } });
expect(newlySavedUser.updatedAt).to.equalTime(updatedAt); expect(newlySavedUser0.updatedAt).to.equalTime(updatedAt);
});
});
});
});
}); });
it('should not throw ER_EMPTY_QUERY if changed only virtual fields', function() { it('should not throw ER_EMPTY_QUERY if changed only virtual fields', async function() {
const User = this.sequelize.define(`User${config.rand()}`, { const User = this.sequelize.define(`User${config.rand()}`, {
name: DataTypes.STRING, name: DataTypes.STRING,
bio: { bio: {
...@@ -407,55 +375,48 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -407,55 +375,48 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
}, { }, {
timestamps: false timestamps: false
}); });
return User.sync({ force: true }).then(() => await User.sync({ force: true });
User.create({ name: 'John', bio: 'swag 1' }).then(user => user.update({ bio: 'swag 2' }).should.be.fulfilled) const user = await User.create({ name: 'John', bio: 'swag 1' });
); await user.update({ bio: 'swag 2' }).should.be.fulfilled;
}); });
}); });
it('updates with function and column value', function() { it('updates with function and column value', async function() {
return this.User.create({ const user = await this.User.create({
aNumber: 42 aNumber: 42
}).then(user => {
user.bNumber = this.sequelize.col('aNumber');
user.username = this.sequelize.fn('upper', 'sequelize');
return user.save().then(() => {
return this.User.findByPk(user.id).then(user2 => {
expect(user2.username).to.equal('SEQUELIZE');
expect(user2.bNumber).to.equal(42);
});
});
}); });
user.bNumber = this.sequelize.col('aNumber');
user.username = this.sequelize.fn('upper', 'sequelize');
await user.save();
const user2 = await this.User.findByPk(user.id);
expect(user2.username).to.equal('SEQUELIZE');
expect(user2.bNumber).to.equal(42);
}); });
it('updates with function that contains escaped dollar symbol', function() { it('updates with function that contains escaped dollar symbol', async function() {
return this.User.create({}).then(user => { const user = await this.User.create({});
user.username = this.sequelize.fn('upper', '$sequelize'); user.username = this.sequelize.fn('upper', '$sequelize');
return user.save().then(() => { await user.save();
return this.User.findByPk(user.id).then(userAfterUpdate => { const userAfterUpdate = await this.User.findByPk(user.id);
expect(userAfterUpdate.username).to.equal('$SEQUELIZE'); expect(userAfterUpdate.username).to.equal('$SEQUELIZE');
});
});
});
}); });
describe('without timestamps option', () => { describe('without timestamps option', () => {
it("doesn't update the updatedAt column", function() { it("doesn't update the updatedAt column", async function() {
const User2 = this.sequelize.define('User2', { const User2 = this.sequelize.define('User2', {
username: DataTypes.STRING, username: DataTypes.STRING,
updatedAt: DataTypes.DATE updatedAt: DataTypes.DATE
}, { timestamps: false }); }, { timestamps: false });
return User2.sync().then(() => { await User2.sync();
return User2.create({ username: 'john doe' }).then(johnDoe => { const johnDoe = await User2.create({ username: 'john doe' });
// sqlite and mysql return undefined, whereas postgres returns null // sqlite and mysql return undefined, whereas postgres returns null
expect([undefined, null]).to.include(johnDoe.updatedAt); expect([undefined, null]).to.include(johnDoe.updatedAt);
});
});
}); });
}); });
describe('with custom timestamp options', () => { describe('with custom timestamp options', () => {
it('updates the createdAt column if updatedAt is disabled', function() { it('updates the createdAt column if updatedAt is disabled', async function() {
const now = new Date(); const now = new Date();
this.clock.tick(1000); this.clock.tick(1000);
...@@ -463,15 +424,13 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -463,15 +424,13 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
username: DataTypes.STRING username: DataTypes.STRING
}, { updatedAt: false }); }, { updatedAt: false });
return User2.sync().then(() => { await User2.sync();
return User2.create({ username: 'john doe' }).then(johnDoe => { const johnDoe = await User2.create({ username: 'john doe' });
expect(johnDoe.updatedAt).to.be.undefined; expect(johnDoe.updatedAt).to.be.undefined;
expect(now).to.be.beforeTime(johnDoe.createdAt); expect(now).to.be.beforeTime(johnDoe.createdAt);
});
});
}); });
it('updates the updatedAt column if createdAt is disabled', function() { it('updates the updatedAt column if createdAt is disabled', async function() {
const now = new Date(); const now = new Date();
this.clock.tick(1000); this.clock.tick(1000);
...@@ -479,15 +438,13 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -479,15 +438,13 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
username: DataTypes.STRING username: DataTypes.STRING
}, { createdAt: false }); }, { createdAt: false });
return User2.sync().then(() => { await User2.sync();
return User2.create({ username: 'john doe' }).then(johnDoe => { const johnDoe = await User2.create({ username: 'john doe' });
expect(johnDoe.createdAt).to.be.undefined; expect(johnDoe.createdAt).to.be.undefined;
expect(now).to.be.beforeTime(johnDoe.updatedAt); expect(now).to.be.beforeTime(johnDoe.updatedAt);
});
});
}); });
it('works with `allowNull: false` on createdAt and updatedAt columns', function() { it('works with `allowNull: false` on createdAt and updatedAt columns', async function() {
const User2 = this.sequelize.define('User2', { const User2 = this.sequelize.define('User2', {
username: DataTypes.STRING, username: DataTypes.STRING,
createdAt: { createdAt: {
...@@ -500,86 +457,88 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -500,86 +457,88 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
} }
}, { timestamps: true }); }, { timestamps: true });
return User2.sync().then(() => { await User2.sync();
return User2.create({ username: 'john doe' }).then(johnDoe => { const johnDoe = await User2.create({ username: 'john doe' });
expect(johnDoe.createdAt).to.be.an.instanceof(Date); expect(johnDoe.createdAt).to.be.an.instanceof(Date);
expect( ! isNaN(johnDoe.createdAt.valueOf()) ).to.be.ok; expect( ! isNaN(johnDoe.createdAt.valueOf()) ).to.be.ok;
expect(johnDoe.createdAt).to.equalTime(johnDoe.updatedAt); expect(johnDoe.createdAt).to.equalTime(johnDoe.updatedAt);
});
});
}); });
}); });
it('should fail a validation upon creating', function() { it('should fail a validation upon creating', async function() {
return this.User.create({ aNumber: 0, validateTest: 'hello' }).catch(err => { try {
await this.User.create({ aNumber: 0, validateTest: 'hello' });
} catch (err) {
expect(err).to.exist; expect(err).to.exist;
expect(err).to.be.instanceof(Object); expect(err).to.be.instanceof(Object);
expect(err.get('validateTest')).to.be.instanceof(Array); expect(err.get('validateTest')).to.be.instanceof(Array);
expect(err.get('validateTest')[0]).to.exist; expect(err.get('validateTest')[0]).to.exist;
expect(err.get('validateTest')[0].message).to.equal('Validation isInt on validateTest failed'); expect(err.get('validateTest')[0].message).to.equal('Validation isInt on validateTest failed');
}); }
}); });
it('should fail a validation upon creating with hooks false', function() { it('should fail a validation upon creating with hooks false', async function() {
return this.User.create({ aNumber: 0, validateTest: 'hello' }, { hooks: false }).catch(err => { try {
await this.User.create({ aNumber: 0, validateTest: 'hello' }, { hooks: false });
} catch (err) {
expect(err).to.exist; expect(err).to.exist;
expect(err).to.be.instanceof(Object); expect(err).to.be.instanceof(Object);
expect(err.get('validateTest')).to.be.instanceof(Array); expect(err.get('validateTest')).to.be.instanceof(Array);
expect(err.get('validateTest')[0]).to.exist; expect(err.get('validateTest')[0]).to.exist;
expect(err.get('validateTest')[0].message).to.equal('Validation isInt on validateTest failed'); expect(err.get('validateTest')[0].message).to.equal('Validation isInt on validateTest failed');
}); }
}); });
it('should fail a validation upon building', function() { it('should fail a validation upon building', async function() {
return this.User.build({ aNumber: 0, validateCustom: 'aaaaaaaaaaaaaaaaaaaaaaaaaa' }).save() try {
.catch(err => { await this.User.build({ aNumber: 0, validateCustom: 'aaaaaaaaaaaaaaaaaaaaaaaaaa' }).save();
expect(err).to.exist; } catch (err) {
expect(err).to.be.instanceof(Object); expect(err).to.exist;
expect(err.get('validateCustom')).to.exist; expect(err).to.be.instanceof(Object);
expect(err.get('validateCustom')).to.be.instanceof(Array); expect(err.get('validateCustom')).to.exist;
expect(err.get('validateCustom')[0]).to.exist; expect(err.get('validateCustom')).to.be.instanceof(Array);
expect(err.get('validateCustom')[0].message).to.equal('Length failed.'); expect(err.get('validateCustom')[0]).to.exist;
}); expect(err.get('validateCustom')[0].message).to.equal('Length failed.');
}
}); });
it('should fail a validation when updating', function() { it('should fail a validation when updating', async function() {
return this.User.create({ aNumber: 0 }).then(user => { const user = await this.User.create({ aNumber: 0 });
return user.update({ validateTest: 'hello' }).catch(err => {
expect(err).to.exist; try {
expect(err).to.be.instanceof(Object); await user.update({ validateTest: 'hello' });
expect(err.get('validateTest')).to.exist; } catch (err) {
expect(err.get('validateTest')).to.be.instanceof(Array); expect(err).to.exist;
expect(err.get('validateTest')[0]).to.exist; expect(err).to.be.instanceof(Object);
expect(err.get('validateTest')[0].message).to.equal('Validation isInt on validateTest failed'); expect(err.get('validateTest')).to.exist;
}); expect(err.get('validateTest')).to.be.instanceof(Array);
}); expect(err.get('validateTest')[0]).to.exist;
expect(err.get('validateTest')[0].message).to.equal('Validation isInt on validateTest failed');
}
}); });
it('takes zero into account', function() { it('takes zero into account', async function() {
return this.User.build({ aNumber: 0 }).save({ const user = await this.User.build({ aNumber: 0 }).save({
fields: ['aNumber'] fields: ['aNumber']
}).then(user => {
expect(user.aNumber).to.equal(0);
}); });
expect(user.aNumber).to.equal(0);
}); });
it('saves a record with no primary key', function() { it('saves a record with no primary key', async function() {
const HistoryLog = this.sequelize.define('HistoryLog', { const HistoryLog = this.sequelize.define('HistoryLog', {
someText: { type: DataTypes.STRING }, someText: { type: DataTypes.STRING },
aNumber: { type: DataTypes.INTEGER }, aNumber: { type: DataTypes.INTEGER },
aRandomId: { type: DataTypes.INTEGER } aRandomId: { type: DataTypes.INTEGER }
}); });
return HistoryLog.sync().then(() => { await HistoryLog.sync();
return HistoryLog.create({ someText: 'Some random text', aNumber: 3, aRandomId: 5 }).then(log => { const log = await HistoryLog.create({ someText: 'Some random text', aNumber: 3, aRandomId: 5 });
return log.update({ aNumber: 5 }).then(newLog => { const newLog = await log.update({ aNumber: 5 });
expect(newLog.aNumber).to.equal(5); expect(newLog.aNumber).to.equal(5);
});
});
});
}); });
describe('eagerly loaded objects', () => { describe('eagerly loaded objects', () => {
beforeEach(function() { beforeEach(async function() {
this.UserEager = this.sequelize.define('UserEagerLoadingSaves', { this.UserEager = this.sequelize.define('UserEagerLoadingSaves', {
username: DataTypes.STRING, username: DataTypes.STRING,
age: DataTypes.INTEGER age: DataTypes.INTEGER
...@@ -593,113 +552,88 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -593,113 +552,88 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
this.UserEager.hasMany(this.ProjectEager, { as: 'Projects', foreignKey: 'PoobahId' }); this.UserEager.hasMany(this.ProjectEager, { as: 'Projects', foreignKey: 'PoobahId' });
this.ProjectEager.belongsTo(this.UserEager, { as: 'Poobah', foreignKey: 'PoobahId' }); this.ProjectEager.belongsTo(this.UserEager, { as: 'Poobah', foreignKey: 'PoobahId' });
return this.UserEager.sync({ force: true }).then(() => { await this.UserEager.sync({ force: true });
return this.ProjectEager.sync({ force: true });
}); await this.ProjectEager.sync({ force: true });
}); });
it('saves one object that has a collection of eagerly loaded objects', function() { it('saves one object that has a collection of eagerly loaded objects', async function() {
return this.UserEager.create({ username: 'joe', age: 1 }).then(user => { const user = await this.UserEager.create({ username: 'joe', age: 1 });
return this.ProjectEager.create({ title: 'project-joe1', overdue_days: 0 }).then(project1 => { const project1 = await this.ProjectEager.create({ title: 'project-joe1', overdue_days: 0 });
return this.ProjectEager.create({ title: 'project-joe2', overdue_days: 0 }).then(project2 => { const project2 = await this.ProjectEager.create({ title: 'project-joe2', overdue_days: 0 });
return user.setProjects([project1, project2]).then(() => { await user.setProjects([project1, project2]);
return this.UserEager.findOne({ where: { age: 1 }, include: [{ model: this.ProjectEager, as: 'Projects' }] }).then(user => { const user1 = await this.UserEager.findOne({ where: { age: 1 }, include: [{ model: this.ProjectEager, as: 'Projects' }] });
expect(user.username).to.equal('joe'); expect(user1.username).to.equal('joe');
expect(user.age).to.equal(1); expect(user1.age).to.equal(1);
expect(user.Projects).to.exist; expect(user1.Projects).to.exist;
expect(user.Projects.length).to.equal(2); expect(user1.Projects.length).to.equal(2);
user.age = user.age + 1; // happy birthday joe user1.age = user1.age + 1; // happy birthday joe
return user.save().then(user => { const user0 = await user1.save();
expect(user.username).to.equal('joe'); expect(user0.username).to.equal('joe');
expect(user.age).to.equal(2); expect(user0.age).to.equal(2);
expect(user.Projects).to.exist; expect(user0.Projects).to.exist;
expect(user.Projects.length).to.equal(2); expect(user0.Projects.length).to.equal(2);
});
});
});
});
});
});
}); });
it('saves many objects that each a have collection of eagerly loaded objects', function() { it('saves many objects that each a have collection of eagerly loaded objects', async function() {
return this.UserEager.create({ username: 'bart', age: 20 }).then(bart => { const bart = await this.UserEager.create({ username: 'bart', age: 20 });
return this.UserEager.create({ username: 'lisa', age: 20 }).then(lisa => { const lisa = await this.UserEager.create({ username: 'lisa', age: 20 });
return this.ProjectEager.create({ title: 'detention1', overdue_days: 0 }).then(detention1 => { const detention1 = await this.ProjectEager.create({ title: 'detention1', overdue_days: 0 });
return this.ProjectEager.create({ title: 'detention2', overdue_days: 0 }).then(detention2 => { const detention2 = await this.ProjectEager.create({ title: 'detention2', overdue_days: 0 });
return this.ProjectEager.create({ title: 'exam1', overdue_days: 0 }).then(exam1 => { const exam1 = await this.ProjectEager.create({ title: 'exam1', overdue_days: 0 });
return this.ProjectEager.create({ title: 'exam2', overdue_days: 0 }).then(exam2 => { const exam2 = await this.ProjectEager.create({ title: 'exam2', overdue_days: 0 });
return bart.setProjects([detention1, detention2]).then(() => { await bart.setProjects([detention1, detention2]);
return lisa.setProjects([exam1, exam2]).then(() => { await lisa.setProjects([exam1, exam2]);
return this.UserEager.findAll({ where: { age: 20 }, order: [['username', 'ASC']], include: [{ model: this.ProjectEager, as: 'Projects' }] }).then(simpsons => { const simpsons = await this.UserEager.findAll({ where: { age: 20 }, order: [['username', 'ASC']], include: [{ model: this.ProjectEager, as: 'Projects' }] });
expect(simpsons.length).to.equal(2); expect(simpsons.length).to.equal(2);
const _bart = simpsons[0]; const _bart = simpsons[0];
const _lisa = simpsons[1]; const _lisa = simpsons[1];
expect(_bart.Projects).to.exist; expect(_bart.Projects).to.exist;
expect(_lisa.Projects).to.exist; expect(_lisa.Projects).to.exist;
expect(_bart.Projects.length).to.equal(2); expect(_bart.Projects.length).to.equal(2);
expect(_lisa.Projects.length).to.equal(2); expect(_lisa.Projects.length).to.equal(2);
_bart.age = _bart.age + 1; // happy birthday bart - off to Moe's _bart.age = _bart.age + 1; // happy birthday bart - off to Moe's
return _bart.save().then(savedbart => { const savedbart = await _bart.save();
expect(savedbart.username).to.equal('bart'); expect(savedbart.username).to.equal('bart');
expect(savedbart.age).to.equal(21); expect(savedbart.age).to.equal(21);
_lisa.username = 'lsimpson'; _lisa.username = 'lsimpson';
return _lisa.save().then(savedlisa => { const savedlisa = await _lisa.save();
expect(savedlisa.username).to.equal('lsimpson'); expect(savedlisa.username).to.equal('lsimpson');
expect(savedlisa.age).to.equal(20); expect(savedlisa.age).to.equal(20);
});
});
});
});
});
});
});
});
});
});
});
}); });
it('saves many objects that each has one eagerly loaded object (to which they belong)', function() { it('saves many objects that each has one eagerly loaded object (to which they belong)', async function() {
return this.UserEager.create({ username: 'poobah', age: 18 }).then(user => { const user = await this.UserEager.create({ username: 'poobah', age: 18 });
return this.ProjectEager.create({ title: 'homework', overdue_days: 10 }).then(homework => { const homework = await this.ProjectEager.create({ title: 'homework', overdue_days: 10 });
return this.ProjectEager.create({ title: 'party', overdue_days: 2 }).then(party => { const party = await this.ProjectEager.create({ title: 'party', overdue_days: 2 });
return user.setProjects([homework, party]).then(() => { await user.setProjects([homework, party]);
return this.ProjectEager.findAll({ include: [{ model: this.UserEager, as: 'Poobah' }] }).then(projects => { const projects = await this.ProjectEager.findAll({ include: [{ model: this.UserEager, as: 'Poobah' }] });
expect(projects.length).to.equal(2); expect(projects.length).to.equal(2);
expect(projects[0].Poobah).to.exist; expect(projects[0].Poobah).to.exist;
expect(projects[1].Poobah).to.exist; expect(projects[1].Poobah).to.exist;
expect(projects[0].Poobah.username).to.equal('poobah'); expect(projects[0].Poobah.username).to.equal('poobah');
expect(projects[1].Poobah.username).to.equal('poobah'); expect(projects[1].Poobah.username).to.equal('poobah');
projects[0].title = 'partymore'; projects[0].title = 'partymore';
projects[1].title = 'partymore'; projects[1].title = 'partymore';
projects[0].overdue_days = 0; projects[0].overdue_days = 0;
projects[1].overdue_days = 0; projects[1].overdue_days = 0;
return projects[0].save().then(() => { await projects[0].save();
return projects[1].save().then(() => { await projects[1].save();
return this.ProjectEager.findAll({ where: { title: 'partymore', overdue_days: 0 }, include: [{ model: this.UserEager, as: 'Poobah' }] }).then(savedprojects => { const savedprojects = await this.ProjectEager.findAll({ where: { title: 'partymore', overdue_days: 0 }, include: [{ model: this.UserEager, as: 'Poobah' }] });
expect(savedprojects.length).to.equal(2); expect(savedprojects.length).to.equal(2);
expect(savedprojects[0].Poobah).to.exist; expect(savedprojects[0].Poobah).to.exist;
expect(savedprojects[1].Poobah).to.exist; expect(savedprojects[1].Poobah).to.exist;
expect(savedprojects[0].Poobah.username).to.equal('poobah'); expect(savedprojects[0].Poobah.username).to.equal('poobah');
expect(savedprojects[1].Poobah.username).to.equal('poobah'); expect(savedprojects[1].Poobah.username).to.equal('poobah');
});
});
});
});
});
});
});
});
}); });
}); });
}); });
......
...@@ -7,7 +7,7 @@ const chai = require('chai'), ...@@ -7,7 +7,7 @@ const chai = require('chai'),
describe(Support.getTestDialectTeaser('Instance'), () => { describe(Support.getTestDialectTeaser('Instance'), () => {
describe('toJSON', () => { describe('toJSON', () => {
beforeEach(function() { beforeEach(async function() {
this.User = this.sequelize.define('User', { this.User = this.sequelize.define('User', {
username: { type: DataTypes.STRING }, username: { type: DataTypes.STRING },
age: DataTypes.INTEGER, age: DataTypes.INTEGER,
...@@ -26,45 +26,41 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -26,45 +26,41 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
this.User.hasMany(this.Project, { as: 'Projects', foreignKey: 'lovelyUserId' }); this.User.hasMany(this.Project, { as: 'Projects', foreignKey: 'lovelyUserId' });
this.Project.belongsTo(this.User, { as: 'LovelyUser', foreignKey: 'lovelyUserId' }); this.Project.belongsTo(this.User, { as: 'LovelyUser', foreignKey: 'lovelyUserId' });
return this.User.sync({ force: true }).then(() => { await this.User.sync({ force: true });
return this.Project.sync({ force: true });
}); await this.Project.sync({ force: true });
}); });
it("doesn't return instance that isn't defined", function() { it("doesn't return instance that isn't defined", async function() {
return this.Project.create({ lovelyUserId: null }) const project0 = await this.Project.create({ lovelyUserId: null });
.then(project => {
return this.Project.findOne({ const project = await this.Project.findOne({
where: { where: {
id: project.id id: project0.id
}, },
include: [ include: [
{ model: this.User, as: 'LovelyUser' } { model: this.User, as: 'LovelyUser' }
] ]
}); });
})
.then(project => { const json = project.toJSON();
const json = project.toJSON(); expect(json.LovelyUser).to.be.equal(null);
expect(json.LovelyUser).to.be.equal(null);
});
}); });
it("doesn't return instances that aren't defined", function() { it("doesn't return instances that aren't defined", async function() {
return this.User.create({ username: 'cuss' }) const user0 = await this.User.create({ username: 'cuss' });
.then(user => {
return this.User.findOne({ const user = await this.User.findOne({
where: { where: {
id: user.id id: user0.id
}, },
include: [ include: [
{ model: this.Project, as: 'Projects' } { model: this.Project, as: 'Projects' }
] ]
}); });
})
.then(user => { expect(user.Projects).to.be.instanceof(Array);
expect(user.Projects).to.be.instanceof(Array); expect(user.Projects).to.be.length(0);
expect(user.Projects).to.be.length(0);
});
}); });
describe('build', () => { describe('build', () => {
...@@ -104,125 +100,123 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -104,125 +100,123 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
}); });
describe('create', () => { describe('create', () => {
it('returns an object containing all values', function() { it('returns an object containing all values', async function() {
return this.User.create({ const user = await this.User.create({
username: 'Adam', username: 'Adam',
age: 22, age: 22,
level: -1, level: -1,
isUser: false, isUser: false,
isAdmin: true isAdmin: true
}).then(user => { });
expect(user.toJSON()).to.deep.equal({
id: user.get('id'), expect(user.toJSON()).to.deep.equal({
username: 'Adam', id: user.get('id'),
age: 22, username: 'Adam',
isUser: false, age: 22,
isAdmin: true, isUser: false,
level: -1 isAdmin: true,
}); level: -1
}); });
}); });
it('returns a response that can be stringified', function() { it('returns a response that can be stringified', async function() {
return this.User.create({ const user = await this.User.create({
username: 'test.user', username: 'test.user',
age: 99, age: 99,
isAdmin: true, isAdmin: true,
isUser: false, isUser: false,
level: null level: null
}).then(user => {
expect(JSON.stringify(user)).to.deep.equal(`{"id":${user.get('id')},"username":"test.user","age":99,"isAdmin":true,"isUser":false,"level":null}`);
}); });
expect(JSON.stringify(user)).to.deep.equal(`{"id":${user.get('id')},"username":"test.user","age":99,"isAdmin":true,"isUser":false,"level":null}`);
}); });
it('returns a response that can be stringified and then parsed', function() { it('returns a response that can be stringified and then parsed', async function() {
return this.User.create({ const user = await this.User.create({
username: 'test.user', username: 'test.user',
age: 99, age: 99,
isAdmin: true, isAdmin: true,
level: null level: null
}).then(user => { });
expect(JSON.parse(JSON.stringify(user))).to.deep.equal({
age: 99, expect(JSON.parse(JSON.stringify(user))).to.deep.equal({
id: user.get('id'), age: 99,
isAdmin: true, id: user.get('id'),
isUser: false, isAdmin: true,
level: null, isUser: false,
username: 'test.user' level: null,
}); username: 'test.user'
}); });
}); });
}); });
describe('find', () => { describe('find', () => {
it('returns an object containing all values', function() { it('returns an object containing all values', async function() {
return this.User.create({ const user0 = await this.User.create({
username: 'Adam',
age: 22,
level: -1,
isUser: false,
isAdmin: true
});
const user = await this.User.findByPk(user0.get('id'));
expect(user.toJSON()).to.deep.equal({
id: user.get('id'),
username: 'Adam', username: 'Adam',
age: 22, age: 22,
level: -1, level: -1,
isUser: false, isUser: false,
isAdmin: true isAdmin: true
}).then(user => this.User.findByPk(user.get('id'))).then(user => {
expect(user.toJSON()).to.deep.equal({
id: user.get('id'),
username: 'Adam',
age: 22,
level: -1,
isUser: false,
isAdmin: true
});
}); });
}); });
it('returns a response that can be stringified', function() { it('returns a response that can be stringified', async function() {
return this.User.create({ const user0 = await this.User.create({
username: 'test.user', username: 'test.user',
age: 99, age: 99,
isAdmin: true, isAdmin: true,
isUser: false isUser: false
}).then(user => this.User.findByPk(user.get('id'))).then(user => {
expect(JSON.stringify(user)).to.deep.equal(`{"id":${user.get('id')},"username":"test.user","age":99,"level":null,"isUser":false,"isAdmin":true}`);
}); });
const user = await this.User.findByPk(user0.get('id'));
expect(JSON.stringify(user)).to.deep.equal(`{"id":${user.get('id')},"username":"test.user","age":99,"level":null,"isUser":false,"isAdmin":true}`);
}); });
it('returns a response that can be stringified and then parsed', function() { it('returns a response that can be stringified and then parsed', async function() {
return this.User.create({ const user0 = await this.User.create({
username: 'test.user', username: 'test.user',
age: 99, age: 99,
isAdmin: true isAdmin: true
}).then(user => this.User.findByPk(user.get('id'))).then(user => { });
expect(JSON.parse(JSON.stringify(user))).to.deep.equal({
id: user.get('id'), const user = await this.User.findByPk(user0.get('id'));
username: 'test.user', expect(JSON.parse(JSON.stringify(user))).to.deep.equal({
age: 99, id: user.get('id'),
isAdmin: true, username: 'test.user',
isUser: false, age: 99,
level: null isAdmin: true,
}); isUser: false,
level: null
}); });
}); });
}); });
it('includes the eagerly loaded associations', function() { it('includes the eagerly loaded associations', async function() {
return this.User.create({ username: 'fnord', age: 1, isAdmin: true }).then(user => { const user = await this.User.create({ username: 'fnord', age: 1, isAdmin: true });
return this.Project.create({ title: 'fnord' }).then(project => { const project = await this.Project.create({ title: 'fnord' });
return user.setProjects([project]).then(() => { await user.setProjects([project]);
return this.User.findAll({ include: [{ model: this.Project, as: 'Projects' }] }).then(users => { const users = await this.User.findAll({ include: [{ model: this.Project, as: 'Projects' }] });
const _user = users[0]; const _user = users[0];
expect(_user.Projects).to.exist; expect(_user.Projects).to.exist;
expect(JSON.parse(JSON.stringify(_user)).Projects).to.exist; expect(JSON.parse(JSON.stringify(_user)).Projects).to.exist;
return this.Project.findAll({ include: [{ model: this.User, as: 'LovelyUser' }] }).then(projects => { const projects = await this.Project.findAll({ include: [{ model: this.User, as: 'LovelyUser' }] });
const _project = projects[0]; const _project = projects[0];
expect(_project.LovelyUser).to.exist; expect(_project.LovelyUser).to.exist;
expect(JSON.parse(JSON.stringify(_project)).LovelyUser).to.exist; expect(JSON.parse(JSON.stringify(_project)).LovelyUser).to.exist;
});
});
});
});
});
}); });
}); });
}); });
...@@ -18,7 +18,7 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -18,7 +18,7 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
}); });
describe('update', () => { describe('update', () => {
beforeEach(function() { beforeEach(async function() {
this.User = this.sequelize.define('User', { this.User = this.sequelize.define('User', {
username: { type: DataTypes.STRING }, username: { type: DataTypes.STRING },
uuidv1: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV1 }, uuidv1: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV1 },
...@@ -58,59 +58,50 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -58,59 +58,50 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
allowNull: true allowNull: true
} }
}); });
return this.User.sync({ force: true }); await this.User.sync({ force: true });
}); });
if (current.dialect.supports.transactions) { if (current.dialect.supports.transactions) {
it('supports transactions', function() { it('supports transactions', async function() {
return Support.prepareTransactionTest(this.sequelize).then(sequelize => { const sequelize = await Support.prepareTransactionTest(this.sequelize);
const User = sequelize.define('User', { username: Support.Sequelize.STRING }); const User = sequelize.define('User', { username: Support.Sequelize.STRING });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({ username: 'foo' }).then(user => { const user = await User.create({ username: 'foo' });
return sequelize.transaction().then(t => { const t = await sequelize.transaction();
return user.update({ username: 'bar' }, { transaction: t }).then(() => { await user.update({ username: 'bar' }, { transaction: t });
return User.findAll().then(users1 => { const users1 = await User.findAll();
return User.findAll({ transaction: t }).then(users2 => { const users2 = await User.findAll({ transaction: t });
expect(users1[0].username).to.equal('foo'); expect(users1[0].username).to.equal('foo');
expect(users2[0].username).to.equal('bar'); expect(users2[0].username).to.equal('bar');
return t.rollback(); await t.rollback();
});
});
});
});
});
});
});
}); });
} }
it('should update fields that are not specified on create', function() { it('should update fields that are not specified on create', async function() {
const User = this.sequelize.define(`User${ config.rand()}`, { const User = this.sequelize.define(`User${ config.rand()}`, {
name: DataTypes.STRING, name: DataTypes.STRING,
bio: DataTypes.TEXT, bio: DataTypes.TEXT,
email: DataTypes.STRING email: DataTypes.STRING
}); });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({
name: 'snafu', const user1 = await User.create({
email: 'email' name: 'snafu',
}, { email: 'email'
fields: ['name', 'email'] }, {
}).then(user => { fields: ['name', 'email']
return user.update({ bio: 'swag' });
}).then(user => {
return user.reload();
}).then(user => {
expect(user.get('name')).to.equal('snafu');
expect(user.get('email')).to.equal('email');
expect(user.get('bio')).to.equal('swag');
});
}); });
const user0 = await user1.update({ bio: 'swag' });
const user = await user0.reload();
expect(user.get('name')).to.equal('snafu');
expect(user.get('email')).to.equal('email');
expect(user.get('bio')).to.equal('swag');
}); });
it('should succeed in updating when values are unchanged (without timestamps)', function() { it('should succeed in updating when values are unchanged (without timestamps)', async function() {
const User = this.sequelize.define(`User${ config.rand()}`, { const User = this.sequelize.define(`User${ config.rand()}`, {
name: DataTypes.STRING, name: DataTypes.STRING,
bio: DataTypes.TEXT, bio: DataTypes.TEXT,
...@@ -119,27 +110,26 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -119,27 +110,26 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
timestamps: false timestamps: false
}); });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({
name: 'snafu', const user1 = await User.create({
email: 'email' name: 'snafu',
}, { email: 'email'
fields: ['name', 'email'] }, {
}).then(user => { fields: ['name', 'email']
return user.update({
name: 'snafu',
email: 'email'
});
}).then(user => {
return user.reload();
}).then(user => {
expect(user.get('name')).to.equal('snafu');
expect(user.get('email')).to.equal('email');
});
}); });
const user0 = await user1.update({
name: 'snafu',
email: 'email'
});
const user = await user0.reload();
expect(user.get('name')).to.equal('snafu');
expect(user.get('email')).to.equal('email');
}); });
it('should update timestamps with milliseconds', function() { it('should update timestamps with milliseconds', async function() {
const User = this.sequelize.define(`User${ config.rand()}`, { const User = this.sequelize.define(`User${ config.rand()}`, {
name: DataTypes.STRING, name: DataTypes.STRING,
bio: DataTypes.TEXT, bio: DataTypes.TEXT,
...@@ -152,54 +142,48 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -152,54 +142,48 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
this.clock.tick(2100); //move the clock forward 2100 ms. this.clock.tick(2100); //move the clock forward 2100 ms.
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({
name: 'snafu', const user0 = await User.create({
email: 'email' name: 'snafu',
}).then(user => { email: 'email'
return user.reload();
}).then(user => {
expect(user.get('name')).to.equal('snafu');
expect(user.get('email')).to.equal('email');
const testDate = new Date();
testDate.setTime(2100);
expect(user.get('createdAt')).to.equalTime(testDate);
});
}); });
const user = await user0.reload();
expect(user.get('name')).to.equal('snafu');
expect(user.get('email')).to.equal('email');
const testDate = new Date();
testDate.setTime(2100);
expect(user.get('createdAt')).to.equalTime(testDate);
}); });
it('should only save passed attributes', function() { it('should only save passed attributes', async function() {
const user = this.User.build(); const user = this.User.build();
return user.save().then(() => { await user.save();
user.set('validateTest', 5); user.set('validateTest', 5);
expect(user.changed('validateTest')).to.be.ok; expect(user.changed('validateTest')).to.be.ok;
return user.update({
validateCustom: '1' await user.update({
}); validateCustom: '1'
}).then(() => {
expect(user.changed('validateTest')).to.be.ok;
expect(user.validateTest).to.be.equal(5);
}).then(() => {
return user.reload();
}).then(() => {
expect(user.validateTest).to.not.be.equal(5);
}); });
expect(user.changed('validateTest')).to.be.ok;
expect(user.validateTest).to.be.equal(5);
await user.reload();
expect(user.validateTest).to.not.be.equal(5);
}); });
it('should save attributes affected by setters', function() { it('should save attributes affected by setters', async function() {
const user = this.User.build(); const user = this.User.build();
return user.update({ validateSideEffect: 5 }).then(() => { await user.update({ validateSideEffect: 5 });
expect(user.validateSideEffect).to.be.equal(5); expect(user.validateSideEffect).to.be.equal(5);
}).then(() => { await user.reload();
return user.reload(); expect(user.validateSideAffected).to.be.equal(10);
}).then(() => { expect(user.validateSideEffect).not.to.be.ok;
expect(user.validateSideAffected).to.be.equal(10);
expect(user.validateSideEffect).not.to.be.ok;
});
}); });
describe('hooks', () => { describe('hooks', () => {
it('should update attributes added in hooks when default fields are used', function() { it('should update attributes added in hooks when default fields are used', async function() {
const User = this.sequelize.define(`User${ config.rand()}`, { const User = this.sequelize.define(`User${ config.rand()}`, {
name: DataTypes.STRING, name: DataTypes.STRING,
bio: DataTypes.TEXT, bio: DataTypes.TEXT,
...@@ -210,27 +194,26 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -210,27 +194,26 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
instance.set('email', 'B'); instance.set('email', 'B');
}); });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({
name: 'A', const user0 = await User.create({
bio: 'A', name: 'A',
email: 'A' bio: 'A',
}).then(user => { email: 'A'
return user.update({ });
name: 'B',
bio: 'B' await user0.update({
}); name: 'B',
}).then(() => { bio: 'B'
return User.findOne({});
}).then(user => {
expect(user.get('name')).to.equal('B');
expect(user.get('bio')).to.equal('B');
expect(user.get('email')).to.equal('B');
});
}); });
const user = await User.findOne({});
expect(user.get('name')).to.equal('B');
expect(user.get('bio')).to.equal('B');
expect(user.get('email')).to.equal('B');
}); });
it('should update attributes changed in hooks when default fields are used', function() { it('should update attributes changed in hooks when default fields are used', async function() {
const User = this.sequelize.define(`User${ config.rand()}`, { const User = this.sequelize.define(`User${ config.rand()}`, {
name: DataTypes.STRING, name: DataTypes.STRING,
bio: DataTypes.TEXT, bio: DataTypes.TEXT,
...@@ -241,28 +224,27 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -241,28 +224,27 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
instance.set('email', 'C'); instance.set('email', 'C');
}); });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({
name: 'A', const user0 = await User.create({
bio: 'A', name: 'A',
email: 'A' bio: 'A',
}).then(user => { email: 'A'
return user.update({ });
name: 'B',
bio: 'B', await user0.update({
email: 'B' name: 'B',
}); bio: 'B',
}).then(() => { email: 'B'
return User.findOne({});
}).then(user => {
expect(user.get('name')).to.equal('B');
expect(user.get('bio')).to.equal('B');
expect(user.get('email')).to.equal('C');
});
}); });
const user = await User.findOne({});
expect(user.get('name')).to.equal('B');
expect(user.get('bio')).to.equal('B');
expect(user.get('email')).to.equal('C');
}); });
it('should validate attributes added in hooks when default fields are used', function() { it('should validate attributes added in hooks when default fields are used', async function() {
const User = this.sequelize.define(`User${ config.rand()}`, { const User = this.sequelize.define(`User${ config.rand()}`, {
name: DataTypes.STRING, name: DataTypes.STRING,
bio: DataTypes.TEXT, bio: DataTypes.TEXT,
...@@ -278,24 +260,23 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -278,24 +260,23 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
instance.set('email', 'B'); instance.set('email', 'B');
}); });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({
name: 'A', const user0 = await User.create({
bio: 'A', name: 'A',
email: 'valid.email@gmail.com' bio: 'A',
}).then(user => { email: 'valid.email@gmail.com'
return expect(user.update({
name: 'B'
})).to.be.rejectedWith(Sequelize.ValidationError);
}).then(() => {
return User.findOne({}).then(user => {
expect(user.get('email')).to.equal('valid.email@gmail.com');
});
});
}); });
await expect(user0.update({
name: 'B'
})).to.be.rejectedWith(Sequelize.ValidationError);
const user = await User.findOne({});
expect(user.get('email')).to.equal('valid.email@gmail.com');
}); });
it('should validate attributes changed in hooks when default fields are used', function() { it('should validate attributes changed in hooks when default fields are used', async function() {
const User = this.sequelize.define(`User${ config.rand()}`, { const User = this.sequelize.define(`User${ config.rand()}`, {
name: DataTypes.STRING, name: DataTypes.STRING,
bio: DataTypes.TEXT, bio: DataTypes.TEXT,
...@@ -311,153 +292,144 @@ describe(Support.getTestDialectTeaser('Instance'), () => { ...@@ -311,153 +292,144 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
instance.set('email', 'B'); instance.set('email', 'B');
}); });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({
name: 'A', const user0 = await User.create({
bio: 'A', name: 'A',
email: 'valid.email@gmail.com' bio: 'A',
}).then(user => { email: 'valid.email@gmail.com'
return expect(user.update({
name: 'B',
email: 'still.valid.email@gmail.com'
})).to.be.rejectedWith(Sequelize.ValidationError);
}).then(() => {
return User.findOne({}).then(user => {
expect(user.get('email')).to.equal('valid.email@gmail.com');
});
});
}); });
await expect(user0.update({
name: 'B',
email: 'still.valid.email@gmail.com'
})).to.be.rejectedWith(Sequelize.ValidationError);
const user = await User.findOne({});
expect(user.get('email')).to.equal('valid.email@gmail.com');
}); });
}); });
it('should not set attributes that are not specified by fields', function() { it('should not set attributes that are not specified by fields', async function() {
const User = this.sequelize.define(`User${ config.rand()}`, { const User = this.sequelize.define(`User${ config.rand()}`, {
name: DataTypes.STRING, name: DataTypes.STRING,
bio: DataTypes.TEXT, bio: DataTypes.TEXT,
email: DataTypes.STRING email: DataTypes.STRING
}); });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({
name: 'snafu', const user0 = await User.create({
email: 'email' name: 'snafu',
}).then(user => { email: 'email'
return user.update({
bio: 'heyo',
email: 'heho'
}, {
fields: ['bio']
});
}).then(user => {
expect(user.get('name')).to.equal('snafu');
expect(user.get('email')).to.equal('email');
expect(user.get('bio')).to.equal('heyo');
});
}); });
});
it('updates attributes in the database', function() { const user = await user0.update({
return this.User.create({ username: 'user' }).then(user => { bio: 'heyo',
expect(user.username).to.equal('user'); email: 'heho'
return user.update({ username: 'person' }).then(user => { }, {
expect(user.username).to.equal('person'); fields: ['bio']
});
}); });
expect(user.get('name')).to.equal('snafu');
expect(user.get('email')).to.equal('email');
expect(user.get('bio')).to.equal('heyo');
}); });
it('ignores unknown attributes', function() { it('updates attributes in the database', async function() {
return this.User.create({ username: 'user' }).then(user => { const user = await this.User.create({ username: 'user' });
return user.update({ username: 'person', foo: 'bar' }).then(user => { expect(user.username).to.equal('user');
expect(user.username).to.equal('person'); const user0 = await user.update({ username: 'person' });
expect(user.foo).not.to.exist; expect(user0.username).to.equal('person');
});
});
}); });
it('ignores undefined attributes', function() { it('ignores unknown attributes', async function() {
return this.User.sync({ force: true }).then(() => { const user = await this.User.create({ username: 'user' });
return this.User.create({ username: 'user' }).then(user => { const user0 = await user.update({ username: 'person', foo: 'bar' });
return user.update({ username: undefined }).then(user => { expect(user0.username).to.equal('person');
expect(user.username).to.equal('user'); expect(user0.foo).not.to.exist;
}); });
});
}); it('ignores undefined attributes', async function() {
await this.User.sync({ force: true });
const user = await this.User.create({ username: 'user' });
const user0 = await user.update({ username: undefined });
expect(user0.username).to.equal('user');
}); });
it('doesn\'t update primary keys or timestamps', function() { it('doesn\'t update primary keys or timestamps', async function() {
const User = this.sequelize.define(`User${ config.rand()}`, { const User = this.sequelize.define(`User${ config.rand()}`, {
name: DataTypes.STRING, name: DataTypes.STRING,
bio: DataTypes.TEXT, bio: DataTypes.TEXT,
identifier: { type: DataTypes.STRING, primaryKey: true } identifier: { type: DataTypes.STRING, primaryKey: true }
}); });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({
name: 'snafu', const user = await User.create({
identifier: 'identifier' name: 'snafu',
}); identifier: 'identifier'
}).then(user => { });
const oldCreatedAt = user.createdAt,
oldUpdatedAt = user.updatedAt, const oldCreatedAt = user.createdAt,
oldIdentifier = user.identifier; oldUpdatedAt = user.updatedAt,
oldIdentifier = user.identifier;
this.clock.tick(1000);
return user.update({ this.clock.tick(1000);
name: 'foobar',
createdAt: new Date(2000, 1, 1), const user0 = await user.update({
identifier: 'another identifier' name: 'foobar',
}).then(user => { createdAt: new Date(2000, 1, 1),
expect(new Date(user.createdAt)).to.equalDate(new Date(oldCreatedAt)); identifier: 'another identifier'
expect(new Date(user.updatedAt)).to.not.equalTime(new Date(oldUpdatedAt));
expect(user.identifier).to.equal(oldIdentifier);
});
}); });
expect(new Date(user0.createdAt)).to.equalDate(new Date(oldCreatedAt));
expect(new Date(user0.updatedAt)).to.not.equalTime(new Date(oldUpdatedAt));
expect(user0.identifier).to.equal(oldIdentifier);
}); });
it('stores and restores null values', function() { it('stores and restores null values', async function() {
const Download = this.sequelize.define('download', { const Download = this.sequelize.define('download', {
startedAt: DataTypes.DATE, startedAt: DataTypes.DATE,
canceledAt: DataTypes.DATE, canceledAt: DataTypes.DATE,
finishedAt: DataTypes.DATE finishedAt: DataTypes.DATE
}); });
return Download.sync().then(() => { await Download.sync();
return Download.create({
startedAt: new Date() const download = await Download.create({
}).then(download => { startedAt: new Date()
expect(download.startedAt instanceof Date).to.be.true; });
expect(download.canceledAt).to.not.be.ok;
expect(download.finishedAt).to.not.be.ok; expect(download.startedAt instanceof Date).to.be.true;
expect(download.canceledAt).to.not.be.ok;
return download.update({ expect(download.finishedAt).to.not.be.ok;
canceledAt: new Date()
}).then(download => { const download0 = await download.update({
expect(download.startedAt instanceof Date).to.be.true; canceledAt: new Date()
expect(download.canceledAt instanceof Date).to.be.true; });
expect(download.finishedAt).to.not.be.ok;
expect(download0.startedAt instanceof Date).to.be.true;
return Download.findAll({ expect(download0.canceledAt instanceof Date).to.be.true;
where: { finishedAt: null } expect(download0.finishedAt).to.not.be.ok;
}).then(downloads => {
downloads.forEach(download => { const downloads = await Download.findAll({
expect(download.startedAt instanceof Date).to.be.true; where: { finishedAt: null }
expect(download.canceledAt instanceof Date).to.be.true; });
expect(download.finishedAt).to.not.be.ok;
}); downloads.forEach(download => {
}); expect(download.startedAt instanceof Date).to.be.true;
}); expect(download.canceledAt instanceof Date).to.be.true;
}); expect(download.finishedAt).to.not.be.ok;
}); });
}); });
it('should support logging', function() { it('should support logging', async function() {
const spy = sinon.spy(); const spy = sinon.spy();
return this.User.create({}).then(user => { const user = await this.User.create({});
return user.update({ username: 'yolo' }, { logging: spy }).then(() => { await user.update({ username: 'yolo' }, { logging: spy });
expect(spy.called).to.be.ok; expect(spy.called).to.be.ok;
});
});
}); });
}); });
}); });
...@@ -105,7 +105,7 @@ describe(Support.getTestDialectTeaser('DAO'), () => { ...@@ -105,7 +105,7 @@ describe(Support.getTestDialectTeaser('DAO'), () => {
expect(user.dataValues.email).not.to.be.ok; expect(user.dataValues.email).not.to.be.ok;
}); });
it('allows use of sequelize.fn and sequelize.col in date and bool fields', function() { it('allows use of sequelize.fn and sequelize.col in date and bool fields', async function() {
const User = this.sequelize.define('User', { const User = this.sequelize.define('User', {
d: DataTypes.DATE, d: DataTypes.DATE,
b: DataTypes.BOOLEAN, b: DataTypes.BOOLEAN,
...@@ -115,30 +115,26 @@ describe(Support.getTestDialectTeaser('DAO'), () => { ...@@ -115,30 +115,26 @@ describe(Support.getTestDialectTeaser('DAO'), () => {
} }
}, { timestamps: false }); }, { timestamps: false });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({}).then(user => { const user = await User.create({});
// Create the user first to set the proper default values. PG does not support column references in insert, // Create the user first to set the proper default values. PG does not support column references in insert,
// so we must create a record with the right value for always_false, then reference it in an update // so we must create a record with the right value for always_false, then reference it in an update
let now = dialect === 'sqlite' ? this.sequelize.fn('', this.sequelize.fn('datetime', 'now')) : this.sequelize.fn('NOW'); let now = dialect === 'sqlite' ? this.sequelize.fn('', this.sequelize.fn('datetime', 'now')) : this.sequelize.fn('NOW');
if (dialect === 'mssql') { if (dialect === 'mssql') {
now = this.sequelize.fn('', this.sequelize.fn('getdate')); now = this.sequelize.fn('', this.sequelize.fn('getdate'));
} }
user.set({ user.set({
d: now, d: now,
b: this.sequelize.col('always_false') b: this.sequelize.col('always_false')
});
expect(user.get('d')).to.be.instanceof(Sequelize.Utils.Fn);
expect(user.get('b')).to.be.instanceof(Sequelize.Utils.Col);
return user.save().then(() => {
return user.reload().then(() => {
expect(user.d).to.equalDate(new Date());
expect(user.b).to.equal(false);
});
});
});
}); });
expect(user.get('d')).to.be.instanceof(Sequelize.Utils.Fn);
expect(user.get('b')).to.be.instanceof(Sequelize.Utils.Col);
await user.save();
await user.reload();
expect(user.d).to.equalDate(new Date());
expect(user.b).to.equal(false);
}); });
describe('includes', () => { describe('includes', () => {
...@@ -288,7 +284,7 @@ describe(Support.getTestDialectTeaser('DAO'), () => { ...@@ -288,7 +284,7 @@ describe(Support.getTestDialectTeaser('DAO'), () => {
expect(product.toJSON()).to.deep.equal({ withTaxes: 1250, price: 1000, id: null }); expect(product.toJSON()).to.deep.equal({ withTaxes: 1250, price: 1000, id: null });
}); });
it('should work with save', function() { it('should work with save', async function() {
const Contact = this.sequelize.define('Contact', { const Contact = this.sequelize.define('Contact', {
first: { type: Sequelize.STRING }, first: { type: Sequelize.STRING },
last: { type: Sequelize.STRING }, last: { type: Sequelize.STRING },
...@@ -304,18 +300,16 @@ describe(Support.getTestDialectTeaser('DAO'), () => { ...@@ -304,18 +300,16 @@ describe(Support.getTestDialectTeaser('DAO'), () => {
} }
}); });
return this.sequelize.sync().then(() => { await this.sequelize.sync();
const contact = Contact.build({ const contact = Contact.build({
first: 'My', first: 'My',
last: 'Name', last: 'Name',
tags: ['yes', 'no'] tags: ['yes', 'no']
});
expect(contact.get('tags')).to.deep.equal(['yes', 'no']);
return contact.save().then(me => {
expect(me.get('tags')).to.deep.equal(['yes', 'no']);
});
}); });
expect(contact.get('tags')).to.deep.equal(['yes', 'no']);
const me = await contact.save();
expect(me.get('tags')).to.deep.equal(['yes', 'no']);
}); });
describe('plain', () => { describe('plain', () => {
...@@ -432,22 +426,18 @@ describe(Support.getTestDialectTeaser('DAO'), () => { ...@@ -432,22 +426,18 @@ describe(Support.getTestDialectTeaser('DAO'), () => {
}); });
describe('changed', () => { describe('changed', () => {
it('should return false if object was built from database', function() { it('should return false if object was built from database', async function() {
const User = this.sequelize.define('User', { const User = this.sequelize.define('User', {
name: { type: DataTypes.STRING } name: { type: DataTypes.STRING }
}); });
return User.sync().then(() => { await User.sync();
return User.create({ name: 'Jan Meier' }).then(user => { const user0 = await User.create({ name: 'Jan Meier' });
expect(user.changed('name')).to.be.false; expect(user0.changed('name')).to.be.false;
expect(user.changed()).not.to.be.ok; expect(user0.changed()).not.to.be.ok;
}); const [user] = await User.bulkCreate([{ name: 'Jan Meier' }]);
}).then(() => { expect(user.changed('name')).to.be.false;
return User.bulkCreate([{ name: 'Jan Meier' }]).then(([user]) => { expect(user.changed()).not.to.be.ok;
expect(user.changed('name')).to.be.false;
expect(user.changed()).not.to.be.ok;
});
});
}); });
it('should return true if previous value is different', function() { it('should return true if previous value is different', function() {
...@@ -463,27 +453,25 @@ describe(Support.getTestDialectTeaser('DAO'), () => { ...@@ -463,27 +453,25 @@ describe(Support.getTestDialectTeaser('DAO'), () => {
expect(user.changed()).to.be.ok; expect(user.changed()).to.be.ok;
}); });
it('should return false immediately after saving', function() { it('should return false immediately after saving', async function() {
const User = this.sequelize.define('User', { const User = this.sequelize.define('User', {
name: { type: DataTypes.STRING } name: { type: DataTypes.STRING }
}); });
return User.sync().then(() => { await User.sync();
const user = User.build({ const user = User.build({
name: 'Jan Meier' name: 'Jan Meier'
});
user.set('name', 'Mick Hansen');
expect(user.changed('name')).to.be.true;
expect(user.changed()).to.be.ok;
return user.save().then(() => {
expect(user.changed('name')).to.be.false;
expect(user.changed()).not.to.be.ok;
});
}); });
user.set('name', 'Mick Hansen');
expect(user.changed('name')).to.be.true;
expect(user.changed()).to.be.ok;
await user.save();
expect(user.changed('name')).to.be.false;
expect(user.changed()).not.to.be.ok;
}); });
it('should be available to a afterUpdate hook', function() { it('should be available to a afterUpdate hook', async function() {
const User = this.sequelize.define('User', { const User = this.sequelize.define('User', {
name: { type: DataTypes.STRING } name: { type: DataTypes.STRING }
}); });
...@@ -494,20 +482,20 @@ describe(Support.getTestDialectTeaser('DAO'), () => { ...@@ -494,20 +482,20 @@ describe(Support.getTestDialectTeaser('DAO'), () => {
return; return;
}); });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return User.create({
name: 'Ford Prefect' const user0 = await User.create({
}); name: 'Ford Prefect'
}).then(user => {
return user.update({
name: 'Arthur Dent'
});
}).then(user => {
expect(changed).to.be.ok;
expect(changed.length).to.be.ok;
expect(changed).to.include('name');
expect(user.changed()).not.to.be.ok;
}); });
const user = await user0.update({
name: 'Arthur Dent'
});
expect(changed).to.be.ok;
expect(changed.length).to.be.ok;
expect(changed).to.include('name');
expect(user.changed()).not.to.be.ok;
}); });
}); });
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!