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

Commit 796b6b7d by Andy Edwards Committed by GitHub

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

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