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

Commit e34efd47 by Andy Edwards Committed by GitHub

test: asyncify integration/*.js (#12286)

1 parent 35af6838
...@@ -29,8 +29,8 @@ if (current.dialect.supports.transactions) { ...@@ -29,8 +29,8 @@ if (current.dialect.supports.transactions) {
}); });
describe('context', () => { describe('context', () => {
it('does not use continuation storage on manually managed transactions', function() { it('does not use continuation storage on manually managed transactions', async function() {
return Sequelize._clsRun(async () => { await Sequelize._clsRun(async () => {
const transaction = await this.sequelize.transaction(); const transaction = await this.sequelize.transaction();
expect(this.ns.get('transaction')).not.to.be.ok; expect(this.ns.get('transaction')).not.to.be.ok;
await transaction.rollback(); await transaction.rollback();
...@@ -52,16 +52,15 @@ if (current.dialect.supports.transactions) { ...@@ -52,16 +52,15 @@ if (current.dialect.supports.transactions) {
expect(t1id).not.to.equal(t2id); expect(t1id).not.to.equal(t2id);
}); });
it('supports nested promise chains', function() { it('supports nested promise chains', async function() {
return this.sequelize.transaction(() => { await this.sequelize.transaction(async () => {
const tid = this.ns.get('transaction').id; const tid = this.ns.get('transaction').id;
return this.User.findAll().then(() => { await this.User.findAll();
expect(this.ns.get('transaction').id).to.be.ok; expect(this.ns.get('transaction').id).to.be.ok;
expect(this.ns.get('transaction').id).to.equal(tid); expect(this.ns.get('transaction').id).to.equal(tid);
}); });
}); });
});
it('does not leak variables to the outer scope', async function() { it('does not leak variables to the outer scope', async function() {
// This is a little tricky. We want to check the values in the outer scope, when the transaction has been successfully set up, but before it has been comitted. // This is a little tricky. We want to check the values in the outer scope, when the transaction has been successfully set up, but before it has been comitted.
...@@ -100,8 +99,8 @@ if (current.dialect.supports.transactions) { ...@@ -100,8 +99,8 @@ if (current.dialect.supports.transactions) {
expect(this.ns.get('transaction')).not.to.be.ok; expect(this.ns.get('transaction')).not.to.be.ok;
}); });
it('does not leak outside findOrCreate', function() { it('does not leak outside findOrCreate', async function() {
return this.User.findOrCreate({ await this.User.findOrCreate({
where: { where: {
name: 'Kafka' name: 'Kafka'
}, },
...@@ -110,26 +109,25 @@ if (current.dialect.supports.transactions) { ...@@ -110,26 +109,25 @@ if (current.dialect.supports.transactions) {
throw new Error('The transaction was not properly assigned'); throw new Error('The transaction was not properly assigned');
} }
} }
}).then(() => {
return this.User.findAll();
}); });
await this.User.findAll();
}); });
}); });
describe('sequelize.query integration', () => { describe('sequelize.query integration', () => {
it('automagically uses the transaction in all calls', function() { it('automagically uses the transaction in all calls', async function() {
return this.sequelize.transaction(() => { await this.sequelize.transaction(async () => {
return this.User.create({ name: 'bob' }).then(() => { await this.User.create({ name: 'bob' });
return Promise.all([ return Promise.all([
expect(this.User.findAll({ transaction: null })).to.eventually.have.length(0), expect(this.User.findAll({ transaction: null })).to.eventually.have.length(0),
expect(this.User.findAll({})).to.eventually.have.length(1) expect(this.User.findAll({})).to.eventually.have.length(1)
]); ]);
}); });
}); });
});
it('automagically uses the transaction in all calls with async/await', function() { it('automagically uses the transaction in all calls with async/await', async function() {
return this.sequelize.transaction(async () => { await this.sequelize.transaction(async () => {
await this.User.create({ name: 'bob' }); await this.User.create({ name: 'bob' });
expect(await this.User.findAll({ transaction: null })).to.have.length(0); expect(await this.User.findAll({ transaction: null })).to.have.length(0);
expect(await this.User.findAll({})).to.have.length(1); expect(await this.User.findAll({})).to.have.length(1);
...@@ -141,10 +139,11 @@ if (current.dialect.supports.transactions) { ...@@ -141,10 +139,11 @@ if (current.dialect.supports.transactions) {
expect(Sequelize._cls).to.equal(this.ns); expect(Sequelize._cls).to.equal(this.ns);
}); });
it('promises returned by sequelize.query are correctly patched', function() { it('promises returned by sequelize.query are correctly patched', async function() {
return this.sequelize.transaction(t => await this.sequelize.transaction(async t => {
this.sequelize.query('select 1', { type: Sequelize.QueryTypes.SELECT }) await this.sequelize.query('select 1', { type: Sequelize.QueryTypes.SELECT });
.then(() => expect(this.ns.get('transaction')).to.equal(t)) return expect(this.ns.get('transaction')).to.equal(t);
}
); );
}); });
}); });
......
...@@ -17,7 +17,7 @@ if (dialect === 'sqlite') { ...@@ -17,7 +17,7 @@ if (dialect === 'sqlite') {
describe(Support.getTestDialectTeaser('Configuration'), () => { describe(Support.getTestDialectTeaser('Configuration'), () => {
describe('Connections problems should fail with a nice message', () => { describe('Connections problems should fail with a nice message', () => {
it('when we don\'t have the correct server details', () => { it('when we don\'t have the correct server details', async () => {
const options = { const options = {
logging: false, logging: false,
host: '0.0.0.1', host: '0.0.0.1',
...@@ -42,10 +42,10 @@ describe(Support.getTestDialectTeaser('Configuration'), () => { ...@@ -42,10 +42,10 @@ describe(Support.getTestDialectTeaser('Configuration'), () => {
} }
const seq = new Sequelize(...constructorArgs); const seq = new Sequelize(...constructorArgs);
return expect(seq.query('select 1 as hello')).to.eventually.be.rejectedWith(...willBeRejectedWithArgs); await expect(seq.query('select 1 as hello')).to.eventually.be.rejectedWith(...willBeRejectedWithArgs);
}); });
it('when we don\'t have the correct login information', () => { it('when we don\'t have the correct login information', async () => {
if (dialect === 'mssql') { if (dialect === 'mssql') {
// NOTE: Travis seems to be having trouble with this test against the // NOTE: Travis seems to be having trouble with this test against the
// AWS instance. Works perfectly fine on a local setup. // AWS instance. Works perfectly fine on a local setup.
...@@ -56,9 +56,10 @@ describe(Support.getTestDialectTeaser('Configuration'), () => { ...@@ -56,9 +56,10 @@ describe(Support.getTestDialectTeaser('Configuration'), () => {
const seq = new Sequelize(config[dialect].database, config[dialect].username, 'fakepass123', { logging: false, host: config[dialect].host, port: 1, dialect }); const seq = new Sequelize(config[dialect].database, config[dialect].username, 'fakepass123', { logging: false, host: config[dialect].host, port: 1, dialect });
if (dialect === 'sqlite') { if (dialect === 'sqlite') {
// SQLite doesn't require authentication and `select 1 as hello` is a valid query, so this should be fulfilled not rejected for it. // SQLite doesn't require authentication and `select 1 as hello` is a valid query, so this should be fulfilled not rejected for it.
return expect(seq.query('select 1 as hello')).to.eventually.be.fulfilled; await expect(seq.query('select 1 as hello')).to.eventually.be.fulfilled;
} else {
await expect(seq.query('select 1 as hello')).to.eventually.be.rejectedWith(Sequelize.ConnectionRefusedError, 'connect ECONNREFUSED');
} }
return expect(seq.query('select 1 as hello')).to.eventually.be.rejectedWith(Sequelize.ConnectionRefusedError, 'connect ECONNREFUSED');
}); });
it('when we don\'t have a valid dialect.', () => { it('when we don\'t have a valid dialect.', () => {
...@@ -70,7 +71,7 @@ describe(Support.getTestDialectTeaser('Configuration'), () => { ...@@ -70,7 +71,7 @@ describe(Support.getTestDialectTeaser('Configuration'), () => {
describe('Instantiation with arguments', () => { describe('Instantiation with arguments', () => {
if (dialect === 'sqlite') { if (dialect === 'sqlite') {
it('should respect READONLY / READWRITE connection modes', () => { it('should respect READONLY / READWRITE connection modes', async () => {
const p = path.join(__dirname, '../tmp', 'foo.sqlite'); const p = path.join(__dirname, '../tmp', 'foo.sqlite');
const createTableFoo = 'CREATE TABLE foo (faz TEXT);'; const createTableFoo = 'CREATE TABLE foo (faz TEXT);';
const createTableBar = 'CREATE TABLE bar (baz TEXT);'; const createTableBar = 'CREATE TABLE bar (baz TEXT);';
...@@ -79,43 +80,41 @@ describe(Support.getTestDialectTeaser('Configuration'), () => { ...@@ -79,43 +80,41 @@ describe(Support.getTestDialectTeaser('Configuration'), () => {
return promisify(fs.access)(p, fs.R_OK | fs.W_OK); return promisify(fs.access)(p, fs.R_OK | fs.W_OK);
}; };
return promisify(fs.unlink)(p) try {
.catch(err => { try {
await promisify(fs.unlink)(p);
} catch (err) {
expect(err.code).to.equal('ENOENT'); expect(err.code).to.equal('ENOENT');
}) }
.then(() => {
const sequelizeReadOnly = new Sequelize('sqlite://foo', { const sequelizeReadOnly0 = new Sequelize('sqlite://foo', {
storage: p, storage: p,
dialectOptions: { dialectOptions: {
mode: sqlite3.OPEN_READONLY mode: sqlite3.OPEN_READONLY
} }
}); });
const sequelizeReadWrite = new Sequelize('sqlite://foo', { const sequelizeReadWrite0 = new Sequelize('sqlite://foo', {
storage: p, storage: p,
dialectOptions: { dialectOptions: {
mode: sqlite3.OPEN_READWRITE mode: sqlite3.OPEN_READWRITE
} }
}); });
expect(sequelizeReadOnly.config.dialectOptions.mode).to.equal(sqlite3.OPEN_READONLY); expect(sequelizeReadOnly0.config.dialectOptions.mode).to.equal(sqlite3.OPEN_READONLY);
expect(sequelizeReadWrite.config.dialectOptions.mode).to.equal(sqlite3.OPEN_READWRITE); expect(sequelizeReadWrite0.config.dialectOptions.mode).to.equal(sqlite3.OPEN_READWRITE);
return Promise.all([ await Promise.all([
sequelizeReadOnly.query(createTableFoo) sequelizeReadOnly0.query(createTableFoo)
.should.be.rejectedWith(Error, 'SQLITE_CANTOPEN: unable to open database file'), .should.be.rejectedWith(Error, 'SQLITE_CANTOPEN: unable to open database file'),
sequelizeReadWrite.query(createTableFoo) sequelizeReadWrite0.query(createTableFoo)
.should.be.rejectedWith(Error, 'SQLITE_CANTOPEN: unable to open database file') .should.be.rejectedWith(Error, 'SQLITE_CANTOPEN: unable to open database file')
]); ]);
})
.then(() => {
// By default, sqlite creates a connection that's READWRITE | CREATE // By default, sqlite creates a connection that's READWRITE | CREATE
const sequelize = new Sequelize('sqlite://foo', { const sequelize = new Sequelize('sqlite://foo', {
storage: p storage: p
}); });
return sequelize.query(createTableFoo); await testAccess(await sequelize.query(createTableFoo));
})
.then(testAccess)
.then(() => {
const sequelizeReadOnly = new Sequelize('sqlite://foo', { const sequelizeReadOnly = new Sequelize('sqlite://foo', {
storage: p, storage: p,
dialectOptions: { dialectOptions: {
...@@ -129,15 +128,14 @@ describe(Support.getTestDialectTeaser('Configuration'), () => { ...@@ -129,15 +128,14 @@ describe(Support.getTestDialectTeaser('Configuration'), () => {
} }
}); });
return Promise.all([ await Promise.all([
sequelizeReadOnly.query(createTableBar) sequelizeReadOnly.query(createTableBar)
.should.be.rejectedWith(Error, 'SQLITE_READONLY: attempt to write a readonly database'), .should.be.rejectedWith(Error, 'SQLITE_READONLY: attempt to write a readonly database'),
sequelizeReadWrite.query(createTableBar) sequelizeReadWrite.query(createTableBar)
]); ]);
}) } finally {
.finally(() => { await promisify(fs.unlink)(p);
return promisify(fs.unlink)(p); }
});
}); });
} }
}); });
......
...@@ -255,7 +255,7 @@ describe(Support.getTestDialectTeaser('Sequelize Errors'), () => { ...@@ -255,7 +255,7 @@ describe(Support.getTestDialectTeaser('Sequelize Errors'), () => {
}); });
describe('OptimisticLockError', () => { describe('OptimisticLockError', () => {
it('got correct error type and message', function() { it('got correct error type and message', async function() {
const Account = this.sequelize.define('Account', { const Account = this.sequelize.define('Account', {
number: { number: {
type: Sequelize.INTEGER type: Sequelize.INTEGER
...@@ -264,24 +264,23 @@ describe(Support.getTestDialectTeaser('Sequelize Errors'), () => { ...@@ -264,24 +264,23 @@ describe(Support.getTestDialectTeaser('Sequelize Errors'), () => {
version: true version: true
}); });
return Account.sync({ force: true }).then(() => { await Account.sync({ force: true });
const result = Account.create({ number: 1 }).then(accountA => { const result = (async () => {
return Account.findByPk(accountA.id).then(accountB => { const accountA = await Account.create({ number: 1 });
const accountB0 = await Account.findByPk(accountA.id);
accountA.number += 1; accountA.number += 1;
return accountA.save().then(() => { return accountB; }); await accountA.save();
}); const accountB = await accountB0;
}).then(accountB => {
accountB.number += 1; accountB.number += 1;
return accountB.save(); return await accountB.save();
}); })();
return Promise.all([ await Promise.all([
expect(result).to.eventually.be.rejectedWith(Support.Sequelize.OptimisticLockError), expect(result).to.eventually.be.rejectedWith(Support.Sequelize.OptimisticLockError),
expect(result).to.eventually.be.rejectedWith('Attempting to update a stale model instance: Account') expect(result).to.eventually.be.rejectedWith('Attempting to update a stale model instance: Account')
]); ]);
}); });
}); });
});
describe('ConstraintError', () => { describe('ConstraintError', () => {
[ [
...@@ -295,7 +294,7 @@ describe(Support.getTestDialectTeaser('Sequelize Errors'), () => { ...@@ -295,7 +294,7 @@ describe(Support.getTestDialectTeaser('Sequelize Errors'), () => {
} }
].forEach(constraintTest => { ].forEach(constraintTest => {
it(`Can be intercepted as ${constraintTest.type} using .catch`, function() { it(`Can be intercepted as ${constraintTest.type} using .catch`, async function() {
const spy = sinon.spy(), const spy = sinon.spy(),
User = this.sequelize.define('user', { User = this.sequelize.define('user', {
first_name: { first_name: {
...@@ -309,21 +308,22 @@ describe(Support.getTestDialectTeaser('Sequelize Errors'), () => { ...@@ -309,21 +308,22 @@ describe(Support.getTestDialectTeaser('Sequelize Errors'), () => {
}); });
const record = { first_name: 'jan', last_name: 'meier' }; const record = { first_name: 'jan', last_name: 'meier' };
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return User.create(record); await User.create(record);
}).then(() => {
return User.create(record).catch(err => { try {
await User.create(record);
} catch (err) {
if (!(err instanceof constraintTest.exception)) throw err; if (!(err instanceof constraintTest.exception)) throw err;
return spy(err); await spy(err);
}); }
}).then(() => {
expect(spy).to.have.been.calledOnce; expect(spy).to.have.been.calledOnce;
}); });
});
}); });
it('Supports newlines in keys', function() { it('Supports newlines in keys', async function() {
const spy = sinon.spy(), const spy = sinon.spy(),
User = this.sequelize.define('user', { User = this.sequelize.define('user', {
name: { name: {
...@@ -332,20 +332,20 @@ describe(Support.getTestDialectTeaser('Sequelize Errors'), () => { ...@@ -332,20 +332,20 @@ describe(Support.getTestDialectTeaser('Sequelize Errors'), () => {
} }
}); });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return User.create({ name: 'jan' }); await User.create({ name: 'jan' });
}).then(() => {
// If the error was successfully parsed, we can catch it! try {
return User.create({ name: 'jan' }).catch(err => { await User.create({ name: 'jan' });
} catch (err) {
if (!(err instanceof Sequelize.UniqueConstraintError)) throw err; if (!(err instanceof Sequelize.UniqueConstraintError)) throw err;
return spy(err); await spy(err);
}); }
}).then(() => {
expect(spy).to.have.been.calledOnce; expect(spy).to.have.been.calledOnce;
}); });
});
it('Works when unique keys are not defined in sequelize', function() { it('Works when unique keys are not defined in sequelize', async function() {
let User = this.sequelize.define('user', { let User = this.sequelize.define('user', {
name: { name: {
type: Sequelize.STRING, type: Sequelize.STRING,
...@@ -353,23 +353,21 @@ describe(Support.getTestDialectTeaser('Sequelize Errors'), () => { ...@@ -353,23 +353,21 @@ describe(Support.getTestDialectTeaser('Sequelize Errors'), () => {
} }
}, { timestamps: false }); }, { timestamps: false });
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
// Now let's pretend the index was created by someone else, and sequelize doesn't know about it // Now let's pretend the index was created by someone else, and sequelize doesn't know about it
User = this.sequelize.define('user', { User = this.sequelize.define('user', {
name: Sequelize.STRING name: Sequelize.STRING
}, { timestamps: false }); }, { timestamps: false });
return User.create({ name: 'jan' }); await User.create({ name: 'jan' });
}).then(() => {
// It should work even though the unique key is not defined in the model // It should work even though the unique key is not defined in the model
return expect(User.create({ name: 'jan' })).to.be.rejectedWith(Sequelize.UniqueConstraintError); await expect(User.create({ name: 'jan' })).to.be.rejectedWith(Sequelize.UniqueConstraintError);
}).then(() => {
// And when the model is not passed at all // And when the model is not passed at all
return expect(this.sequelize.query('INSERT INTO users (name) VALUES (\'jan\')')).to.be.rejectedWith(Sequelize.UniqueConstraintError); await expect(this.sequelize.query('INSERT INTO users (name) VALUES (\'jan\')')).to.be.rejectedWith(Sequelize.UniqueConstraintError);
});
}); });
it('adds parent and sql properties', function() { it('adds parent and sql properties', async function() {
const User = this.sequelize.define('user', { const User = this.sequelize.define('user', {
name: { name: {
type: Sequelize.STRING, type: Sequelize.STRING,
...@@ -377,28 +375,22 @@ describe(Support.getTestDialectTeaser('Sequelize Errors'), () => { ...@@ -377,28 +375,22 @@ describe(Support.getTestDialectTeaser('Sequelize Errors'), () => {
} }
}, { timestamps: false }); }, { timestamps: false });
return this.sequelize.sync({ force: true }) await this.sequelize.sync({ force: true });
.then(() => { await User.create({ name: 'jan' });
return User.create({ name: 'jan' });
}).then(() => {
// Unique key // Unique key
return expect(User.create({ name: 'jan' })).to.be.rejected; const error0 = await expect(User.create({ name: 'jan' })).to.be.rejected;
}).then(error => { expect(error0).to.be.instanceOf(Sequelize.UniqueConstraintError);
expect(error).to.be.instanceOf(Sequelize.UniqueConstraintError); expect(error0).to.have.property('parent');
expect(error).to.have.property('parent'); expect(error0).to.have.property('original');
expect(error).to.have.property('original'); expect(error0).to.have.property('sql');
expect(error).to.have.property('sql');
return User.create({ id: 2, name: 'jon' }); await User.create({ id: 2, name: 'jon' });
}).then(() => {
// Primary key // Primary key
return expect(User.create({ id: 2, name: 'jon' })).to.be.rejected; const error = await expect(User.create({ id: 2, name: 'jon' })).to.be.rejected;
}).then(error => {
expect(error).to.be.instanceOf(Sequelize.UniqueConstraintError); expect(error).to.be.instanceOf(Sequelize.UniqueConstraintError);
expect(error).to.have.property('parent'); expect(error).to.have.property('parent');
expect(error).to.have.property('original'); expect(error).to.have.property('original');
expect(error).to.have.property('sql'); expect(error).to.have.property('sql');
}); });
}); });
});
}); });
...@@ -13,7 +13,7 @@ describe(Support.getTestDialectTeaser('Replication'), () => { ...@@ -13,7 +13,7 @@ describe(Support.getTestDialectTeaser('Replication'), () => {
let sandbox; let sandbox;
let readSpy, writeSpy; let readSpy, writeSpy;
beforeEach(function() { beforeEach(async function() {
sandbox = sinon.createSandbox(); sandbox = sinon.createSandbox();
this.sequelize = Support.getSequelizeInstance(null, null, null, { this.sequelize = Support.getSequelizeInstance(null, null, null, {
...@@ -33,12 +33,10 @@ describe(Support.getTestDialectTeaser('Replication'), () => { ...@@ -33,12 +33,10 @@ describe(Support.getTestDialectTeaser('Replication'), () => {
} }
}); });
return this.User.sync({ force: true }) await this.User.sync({ force: true });
.then(() => {
readSpy = sandbox.spy(this.sequelize.connectionManager.pool.read, 'acquire'); readSpy = sandbox.spy(this.sequelize.connectionManager.pool.read, 'acquire');
writeSpy = sandbox.spy(this.sequelize.connectionManager.pool.write, 'acquire'); writeSpy = sandbox.spy(this.sequelize.connectionManager.pool.write, 'acquire');
}); });
});
afterEach(() => { afterEach(() => {
sandbox.restore(); sandbox.restore();
...@@ -54,25 +52,25 @@ describe(Support.getTestDialectTeaser('Replication'), () => { ...@@ -54,25 +52,25 @@ describe(Support.getTestDialectTeaser('Replication'), () => {
chai.expect(readSpy.notCalled).eql(true); chai.expect(readSpy.notCalled).eql(true);
} }
it('should be able to make a write', function() { it('should be able to make a write', async function() {
return this.User.create({ await expectWriteCalls(await this.User.create({
firstName: Math.random().toString() firstName: Math.random().toString()
}).then(expectWriteCalls); }));
}); });
it('should be able to make a read', function() { it('should be able to make a read', async function() {
return this.User.findAll().then(expectReadCalls); await expectReadCalls(await this.User.findAll());
}); });
it('should run read-only transactions on the replica', function() { it('should run read-only transactions on the replica', async function() {
return this.sequelize.transaction({ readOnly: true }, transaction => { await expectReadCalls(await this.sequelize.transaction({ readOnly: true }, transaction => {
return this.User.findAll({ transaction }); return this.User.findAll({ transaction });
}).then(expectReadCalls); }));
}); });
it('should run non-read-only transactions on the primary', function() { it('should run non-read-only transactions on the primary', async function() {
return this.sequelize.transaction(transaction => { await expectWriteCalls(await this.sequelize.transaction(transaction => {
return this.User.findAll({ transaction }); return this.User.findAll({ transaction });
}).then(expectWriteCalls); }));
}); });
}); });
...@@ -6,43 +6,37 @@ const chai = require('chai'), ...@@ -6,43 +6,37 @@ const chai = require('chai'),
DataTypes = require('../../lib/data-types'); DataTypes = require('../../lib/data-types');
describe(Support.getTestDialectTeaser('Schema'), () => { describe(Support.getTestDialectTeaser('Schema'), () => {
beforeEach(function() { beforeEach(async function() {
return this.sequelize.createSchema('testschema'); await this.sequelize.createSchema('testschema');
}); });
afterEach(function() { afterEach(async function() {
return this.sequelize.dropSchema('testschema'); await this.sequelize.dropSchema('testschema');
}); });
beforeEach(function() { beforeEach(async function() {
this.User = this.sequelize.define('User', { this.User = this.sequelize.define('User', {
aNumber: { type: DataTypes.INTEGER } aNumber: { type: DataTypes.INTEGER }
}, { }, {
schema: 'testschema' schema: 'testschema'
}); });
return this.User.sync({ force: true }); await this.User.sync({ force: true });
}); });
it('supports increment', function() { it('supports increment', async function() {
return this.User.create({ aNumber: 1 }).then(user => { const user0 = await this.User.create({ aNumber: 1 });
return user.increment('aNumber', { by: 3 }); const result = await user0.increment('aNumber', { by: 3 });
}).then(result => { const user = await result.reload();
return result.reload();
}).then(user => {
expect(user).to.be.ok; expect(user).to.be.ok;
expect(user.aNumber).to.be.equal(4); expect(user.aNumber).to.be.equal(4);
}); });
});
it('supports decrement', function() { it('supports decrement', async function() {
return this.User.create({ aNumber: 10 }).then(user => { const user0 = await this.User.create({ aNumber: 10 });
return user.decrement('aNumber', { by: 3 }); const result = await user0.decrement('aNumber', { by: 3 });
}).then(result => { const user = await result.reload();
return result.reload();
}).then(user => {
expect(user).to.be.ok; expect(user).to.be.ok;
expect(user.aNumber).to.be.equal(7); expect(user.aNumber).to.be.equal(7);
}); });
});
}); });
...@@ -12,47 +12,41 @@ if (current.dialect.supports.transactions) { ...@@ -12,47 +12,41 @@ if (current.dialect.supports.transactions) {
describe(Support.getTestDialectTeaser('Sequelize#transaction'), () => { describe(Support.getTestDialectTeaser('Sequelize#transaction'), () => {
describe('then', () => { describe('then', () => {
it('gets triggered once a transaction has been successfully committed', function() { it('gets triggered once a transaction has been successfully committed', async function() {
let called = false; let called = false;
return this
const t = await this
.sequelize .sequelize
.transaction().then(t => { .transaction();
return t.commit().then(() => {
await t.commit();
called = 1; called = 1;
});
})
.then(() => {
expect(called).to.be.ok; expect(called).to.be.ok;
}); });
});
it('gets triggered once a transaction has been successfully rolled back', function() { it('gets triggered once a transaction has been successfully rolled back', async function() {
let called = false; let called = false;
return this
const t = await this
.sequelize .sequelize
.transaction().then(t => { .transaction();
return t.rollback().then(() => {
await t.rollback();
called = 1; called = 1;
});
})
.then(() => {
expect(called).to.be.ok; expect(called).to.be.ok;
}); });
});
if (Support.getTestDialect() !== 'sqlite') { if (Support.getTestDialect() !== 'sqlite') {
it('works for long running transactions', function() { it('works for long running transactions', async function() {
return Support.prepareTransactionTest(this.sequelize).then(sequelize => { const sequelize = await Support.prepareTransactionTest(this.sequelize);
this.sequelize = sequelize; this.sequelize = sequelize;
this.User = sequelize.define('User', { this.User = sequelize.define('User', {
name: Support.Sequelize.STRING name: Support.Sequelize.STRING
}, { timestamps: false }); }, { timestamps: false });
return sequelize.sync({ force: true }); await sequelize.sync({ force: true });
}).then(() => { const t = await this.sequelize.transaction();
return this.sequelize.transaction();
}).then(t => {
let query = 'select sleep(2);'; let query = 'select sleep(2);';
switch (Support.getTestDialect()) { switch (Support.getTestDialect()) {
...@@ -69,57 +63,46 @@ if (current.dialect.supports.transactions) { ...@@ -69,57 +63,46 @@ if (current.dialect.supports.transactions) {
break; break;
} }
return this.sequelize.query(query, { transaction: t }).then(() => { await this.sequelize.query(query, { transaction: t });
return this.User.create({ name: 'foo' }); await this.User.create({ name: 'foo' });
}).then(() => { await this.sequelize.query(query, { transaction: t });
return this.sequelize.query(query, { transaction: t }); await t.commit();
}).then(() => { const users = await this.User.findAll();
return t.commit();
});
}).then(() => {
return this.User.findAll();
}).then(users => {
expect(users.length).to.equal(1); expect(users.length).to.equal(1);
expect(users[0].name).to.equal('foo'); expect(users[0].name).to.equal('foo');
}); });
});
} }
}); });
describe('complex long running example', () => { describe('complex long running example', () => {
it('works with promise syntax', function() { it('works with promise syntax', async function() {
return Support.prepareTransactionTest(this.sequelize).then(sequelize => { const sequelize = await Support.prepareTransactionTest(this.sequelize);
const Test = sequelize.define('Test', { const Test = sequelize.define('Test', {
id: { type: Support.Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, id: { type: Support.Sequelize.INTEGER, primaryKey: true, autoIncrement: true },
name: { type: Support.Sequelize.STRING } name: { type: Support.Sequelize.STRING }
}); });
return sequelize.sync({ force: true }).then(() => { await sequelize.sync({ force: true });
return sequelize.transaction().then(transaction => { const transaction = await sequelize.transaction();
expect(transaction).to.be.instanceOf(Transaction); expect(transaction).to.be.instanceOf(Transaction);
return Test await Test
.create({ name: 'Peter' }, { transaction }) .create({ name: 'Peter' }, { transaction });
.then(() => {
return delay(1000).then(() => { await delay(1000);
return transaction
.commit() await transaction
.then(() => { return Test.count(); }) .commit();
.then(count => {
const count = await Test.count();
expect(count).to.equal(1); expect(count).to.equal(1);
}); });
}); });
});
});
});
});
});
});
describe('concurrency', () => { describe('concurrency', () => {
describe('having tables with uniqueness constraints', () => { describe('having tables with uniqueness constraints', () => {
beforeEach(function() { beforeEach(async function() {
return Support.prepareTransactionTest(this.sequelize).then(sequelize => { const sequelize = await Support.prepareTransactionTest(this.sequelize);
this.sequelize = sequelize; this.sequelize = sequelize;
this.Model = sequelize.define('Model', { this.Model = sequelize.define('Model', {
...@@ -128,19 +111,23 @@ if (current.dialect.supports.transactions) { ...@@ -128,19 +111,23 @@ if (current.dialect.supports.transactions) {
timestamps: false timestamps: false
}); });
return this.Model.sync({ force: true }); await this.Model.sync({ force: true });
});
}); });
it('triggers the error event for the second transactions', function() { it('triggers the error event for the second transactions', async function() {
return this.sequelize.transaction().then(t1 => { const t1 = await this.sequelize.transaction();
return this.sequelize.transaction().then(t2 => { const t2 = await this.sequelize.transaction();
return this.Model.create({ name: 'omnom' }, { transaction: t1 }).then(() => { await this.Model.create({ name: 'omnom' }, { transaction: t1 });
return Promise.all([
this.Model.create({ name: 'omnom' }, { transaction: t2 }).catch(err => { await Promise.all([
(async () => {
try {
return await this.Model.create({ name: 'omnom' }, { transaction: t2 });
} catch (err) {
expect(err).to.be.ok; expect(err).to.be.ok;
return t2.rollback(); return t2.rollback();
}), }
})(),
delay(100).then(() => { delay(100).then(() => {
return t1.commit(); return t1.commit();
}) })
...@@ -149,8 +136,5 @@ if (current.dialect.supports.transactions) { ...@@ -149,8 +136,5 @@ if (current.dialect.supports.transactions) {
}); });
}); });
}); });
});
});
});
} }
...@@ -13,8 +13,8 @@ before(function() { ...@@ -13,8 +13,8 @@ before(function() {
}); });
}); });
beforeEach(function() { beforeEach(async function() {
return Support.clearDatabase(this.sequelize); await Support.clearDatabase(this.sequelize);
}); });
afterEach(function() { afterEach(function() {
......
...@@ -18,7 +18,7 @@ if (dialect !== 'sqlite') { ...@@ -18,7 +18,7 @@ if (dialect !== 'sqlite') {
}); });
}); });
it('returns the same value for current timestamp', function() { it('returns the same value for current timestamp', async function() {
let now = 'now()'; let now = 'now()';
const startQueryTime = Date.now(); const startQueryTime = Date.now();
...@@ -27,49 +27,46 @@ if (dialect !== 'sqlite') { ...@@ -27,49 +27,46 @@ if (dialect !== 'sqlite') {
} }
const query = `SELECT ${now} as now`; const query = `SELECT ${now} as now`;
return Promise.all([
const [now1, now2] = await Promise.all([
this.sequelize.query(query, { type: this.sequelize.QueryTypes.SELECT }), this.sequelize.query(query, { type: this.sequelize.QueryTypes.SELECT }),
this.sequelizeWithTimezone.query(query, { type: this.sequelize.QueryTypes.SELECT }) this.sequelizeWithTimezone.query(query, { type: this.sequelize.QueryTypes.SELECT })
]).then(([now1, now2]) => { ]);
const elapsedQueryTime = Date.now() - startQueryTime + 1001; const elapsedQueryTime = Date.now() - startQueryTime + 1001;
expect(now1[0].now.getTime()).to.be.closeTo(now2[0].now.getTime(), elapsedQueryTime); expect(now1[0].now.getTime()).to.be.closeTo(now2[0].now.getTime(), elapsedQueryTime);
}); });
});
if (dialect === 'mysql' || dialect === 'mariadb') { if (dialect === 'mysql' || dialect === 'mariadb') {
it('handles existing timestamps', function() { it('handles existing timestamps', async function() {
const NormalUser = this.sequelize.define('user', {}), const NormalUser = this.sequelize.define('user', {}),
TimezonedUser = this.sequelizeWithTimezone.define('user', {}); TimezonedUser = this.sequelizeWithTimezone.define('user', {});
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return NormalUser.create({}); const normalUser = await NormalUser.create({});
}).then(normalUser => {
this.normalUser = normalUser; this.normalUser = normalUser;
return TimezonedUser.findByPk(normalUser.id); const timezonedUser = await TimezonedUser.findByPk(normalUser.id);
}).then(timezonedUser => {
// Expect 7 hours difference, in milliseconds. // Expect 7 hours difference, in milliseconds.
// This difference is expected since two instances, configured for each their timezone is trying to read the same timestamp // This difference is expected since two instances, configured for each their timezone is trying to read the same timestamp
// this test does not apply to PG, since it stores the timezone along with the timestamp. // this test does not apply to PG, since it stores the timezone along with the timestamp.
expect(this.normalUser.createdAt.getTime() - timezonedUser.createdAt.getTime()).to.be.closeTo(60 * 60 * 7 * 1000, 1000); expect(this.normalUser.createdAt.getTime() - timezonedUser.createdAt.getTime()).to.be.closeTo(60 * 60 * 7 * 1000, 1000);
}); });
});
it('handles named timezones', function() { it('handles named timezones', async function() {
const NormalUser = this.sequelize.define('user', {}), const NormalUser = this.sequelize.define('user', {}),
TimezonedUser = this.sequelizeWithNamedTimezone.define('user', {}); TimezonedUser = this.sequelizeWithNamedTimezone.define('user', {});
return this.sequelize.sync({ force: true }).then(() => { await this.sequelize.sync({ force: true });
return TimezonedUser.create({}); const timezonedUser0 = await TimezonedUser.create({});
}).then(timezonedUser => {
return Promise.all([ const [normalUser, timezonedUser] = await Promise.all([
NormalUser.findByPk(timezonedUser.id), NormalUser.findByPk(timezonedUser0.id),
TimezonedUser.findByPk(timezonedUser.id) TimezonedUser.findByPk(timezonedUser0.id)
]); ]);
}).then(([normalUser, timezonedUser]) => {
// Expect 5 hours difference, in milliseconds, +/- 1 hour for DST // Expect 5 hours difference, in milliseconds, +/- 1 hour for DST
expect(normalUser.createdAt.getTime() - timezonedUser.createdAt.getTime()).to.be.closeTo(60 * 60 * 4 * 1000 * -1, 60 * 60 * 1000); expect(normalUser.createdAt.getTime() - timezonedUser.createdAt.getTime()).to.be.closeTo(60 * 60 * 4 * 1000 * -1, 60 * 60 * 1000);
}); });
});
} }
}); });
} }
...@@ -22,7 +22,7 @@ if (current.dialect.supports.tmpTableTrigger) { ...@@ -22,7 +22,7 @@ if (current.dialect.supports.tmpTableTrigger) {
'select * from deleted\n' + 'select * from deleted\n' +
'end\n'; 'end\n';
beforeEach(function() { beforeEach(async function() {
User = this.sequelize.define('user', { User = this.sequelize.define('user', {
username: { username: {
type: Sequelize.STRING, type: Sequelize.STRING,
...@@ -32,56 +32,52 @@ if (current.dialect.supports.tmpTableTrigger) { ...@@ -32,56 +32,52 @@ if (current.dialect.supports.tmpTableTrigger) {
hasTrigger: true hasTrigger: true
}); });
return User.sync({ force: true }).then(() => { await User.sync({ force: true });
return this.sequelize.query(triggerQuery, { type: this.sequelize.QueryTypes.RAW });
}); await this.sequelize.query(triggerQuery, { type: this.sequelize.QueryTypes.RAW });
}); });
it('should return output rows after insert', () => { it('should return output rows after insert', async () => {
return User.create({ await User.create({
username: 'triggertest' username: 'triggertest'
}).then(() => {
return expect(User.findOne({ username: 'triggertest' })).to.eventually.have.property('username').which.equals('triggertest');
}); });
await expect(User.findOne({ username: 'triggertest' })).to.eventually.have.property('username').which.equals('triggertest');
}); });
it('should return output rows after instance update', () => { it('should return output rows after instance update', async () => {
return User.create({ const user = await User.create({
username: 'triggertest' username: 'triggertest'
}).then(user => {
user.username = 'usernamechanged';
return user.save();
})
.then(() => {
return expect(User.findOne({ username: 'usernamechanged' })).to.eventually.have.property('username').which.equals('usernamechanged');
}); });
user.username = 'usernamechanged';
await user.save();
await expect(User.findOne({ username: 'usernamechanged' })).to.eventually.have.property('username').which.equals('usernamechanged');
}); });
it('should return output rows after Model update', () => { it('should return output rows after Model update', async () => {
return User.create({ const user = await User.create({
username: 'triggertest' username: 'triggertest'
}).then(user => { });
return User.update({
await User.update({
username: 'usernamechanged' username: 'usernamechanged'
}, { }, {
where: { where: {
id: user.get('id') id: user.get('id')
} }
}); });
})
.then(() => { await expect(User.findOne({ username: 'usernamechanged' })).to.eventually.have.property('username').which.equals('usernamechanged');
return expect(User.findOne({ username: 'usernamechanged' })).to.eventually.have.property('username').which.equals('usernamechanged');
});
}); });
it('should successfully delete with a trigger on the table', () => { it('should successfully delete with a trigger on the table', async () => {
return User.create({ const user = await User.create({
username: 'triggertest' username: 'triggertest'
}).then(user => {
return user.destroy();
}).then(() => {
return expect(User.findOne({ username: 'triggertest' })).to.eventually.be.null;
}); });
await user.destroy();
await expect(User.findOne({ username: 'triggertest' })).to.eventually.be.null;
}); });
}); });
}); });
......
...@@ -138,14 +138,15 @@ describe(Support.getTestDialectTeaser('Utils'), () => { ...@@ -138,14 +138,15 @@ describe(Support.getTestDialectTeaser('Utils'), () => {
describe('Sequelize.fn', () => { describe('Sequelize.fn', () => {
let Airplane; let Airplane;
beforeEach(function() { beforeEach(async function() {
Airplane = this.sequelize.define('Airplane', { Airplane = this.sequelize.define('Airplane', {
wings: DataTypes.INTEGER, wings: DataTypes.INTEGER,
engines: DataTypes.INTEGER engines: DataTypes.INTEGER
}); });
return Airplane.sync({ force: true }).then(() => { await Airplane.sync({ force: true });
return Airplane.bulkCreate([
await Airplane.bulkCreate([
{ {
wings: 2, wings: 2,
engines: 0 engines: 0
...@@ -158,13 +159,12 @@ describe(Support.getTestDialectTeaser('Utils'), () => { ...@@ -158,13 +159,12 @@ describe(Support.getTestDialectTeaser('Utils'), () => {
} }
]); ]);
}); });
});
if (Support.getTestDialect() !== 'mssql') { if (Support.getTestDialect() !== 'mssql') {
it('accepts condition object (with cast)', function() { it('accepts condition object (with cast)', async function() {
const type = Support.getTestDialect() === 'mysql' ? 'unsigned' : 'int'; const type = Support.getTestDialect() === 'mysql' ? 'unsigned' : 'int';
return Airplane.findAll({ const [airplane] = await Airplane.findAll({
attributes: [ attributes: [
[this.sequelize.fn('COUNT', '*'), 'count'], [this.sequelize.fn('COUNT', '*'), 'count'],
[Sequelize.fn('SUM', Sequelize.cast({ [Sequelize.fn('SUM', Sequelize.cast({
...@@ -179,18 +179,18 @@ describe(Support.getTestDialectTeaser('Utils'), () => { ...@@ -179,18 +179,18 @@ describe(Support.getTestDialectTeaser('Utils'), () => {
} }
}, type)), 'count-engines-wings'] }, type)), 'count-engines-wings']
] ]
}).then(([airplane]) => { });
// TODO: `parseInt` should not be needed, see #10533 // TODO: `parseInt` should not be needed, see #10533
expect(parseInt(airplane.get('count'), 10)).to.equal(3); expect(parseInt(airplane.get('count'), 10)).to.equal(3);
expect(parseInt(airplane.get('count-engines'), 10)).to.equal(1); expect(parseInt(airplane.get('count-engines'), 10)).to.equal(1);
expect(parseInt(airplane.get('count-engines-wings'), 10)).to.equal(2); expect(parseInt(airplane.get('count-engines-wings'), 10)).to.equal(2);
}); });
});
} }
if (Support.getTestDialect() !== 'mssql' && Support.getTestDialect() !== 'postgres') { if (Support.getTestDialect() !== 'mssql' && Support.getTestDialect() !== 'postgres') {
it('accepts condition object (auto casting)', function() { it('accepts condition object (auto casting)', async function() {
return Airplane.findAll({ const [airplane] = await Airplane.findAll({
attributes: [ attributes: [
[this.sequelize.fn('COUNT', '*'), 'count'], [this.sequelize.fn('COUNT', '*'), 'count'],
[Sequelize.fn('SUM', { [Sequelize.fn('SUM', {
...@@ -205,13 +205,13 @@ describe(Support.getTestDialectTeaser('Utils'), () => { ...@@ -205,13 +205,13 @@ describe(Support.getTestDialectTeaser('Utils'), () => {
} }
}), 'count-engines-wings'] }), 'count-engines-wings']
] ]
}).then(([airplane]) => { });
// TODO: `parseInt` should not be needed, see #10533 // TODO: `parseInt` should not be needed, see #10533
expect(airplane.get('count')).to.equal(3); expect(airplane.get('count')).to.equal(3);
expect(parseInt(airplane.get('count-engines'), 10)).to.equal(1); expect(parseInt(airplane.get('count-engines'), 10)).to.equal(1);
expect(parseInt(airplane.get('count-engines-wings'), 10)).to.equal(2); expect(parseInt(airplane.get('count-engines-wings'), 10)).to.equal(2);
}); });
});
} }
}); });
......
...@@ -8,22 +8,21 @@ const chai = require('chai'), ...@@ -8,22 +8,21 @@ const chai = require('chai'),
chai.should(); chai.should();
describe(Support.getTestDialectTeaser('Vectors'), () => { describe(Support.getTestDialectTeaser('Vectors'), () => {
it('should not allow insert backslash', function() { it('should not allow insert backslash', async function() {
const Student = this.sequelize.define('student', { const Student = this.sequelize.define('student', {
name: Sequelize.STRING name: Sequelize.STRING
}, { }, {
tableName: 'student' tableName: 'student'
}); });
return Student.sync({ force: true }).then(() => { await Student.sync({ force: true });
return Student.create({
const result0 = await Student.create({
name: 'Robert\\\'); DROP TABLE "students"; --' name: 'Robert\\\'); DROP TABLE "students"; --'
}).then(result => {
expect(result.get('name')).to.equal('Robert\\\'); DROP TABLE "students"; --');
return Student.findAll();
}).then(result => {
expect(result[0].name).to.equal('Robert\\\'); DROP TABLE "students"; --');
});
}); });
expect(result0.get('name')).to.equal('Robert\\\'); DROP TABLE "students"; --');
const result = await Student.findAll();
expect(result[0].name).to.equal('Robert\\\'); DROP TABLE "students"; --');
}); });
}); });
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!