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

Commit 5e794684 by Jan Aagaard Meier

Slight rewrite of cls tests

1 parent 7e06e0c9
Showing with 89 additions and 73 deletions
...@@ -7,26 +7,29 @@ var chai = require('chai') ...@@ -7,26 +7,29 @@ var chai = require('chai')
, Support = require(__dirname + '/support') , Support = require(__dirname + '/support')
, Sequelize = Support.Sequelize , Sequelize = Support.Sequelize
, Promise = Sequelize.Promise , Promise = Sequelize.Promise
, cls = require('continuation-local-storage'); , cls = require('continuation-local-storage')
, current = Support.sequelize;
chai.config.includeStack = true; chai.config.includeStack = true;
describe(Support.getTestDialectTeaser("Continuation local storage"), function () { describe(Support.getTestDialectTeaser("Continuation local storage"), function () {
before(function () { before(function () {
return Support.prepareTransactionTest(Support.createSequelizeInstance({ this.sequelize = Support.createSequelizeInstance({
namespace: cls.createNamespace('sequelize') namespace: cls.createNamespace('sequelize')
})).bind(this).then(function (sequelize) {
this.sequelize = sequelize;
}); });
}); });
beforeEach(function () { beforeEach(function () {
this.ns = cls.getNamespace('sequelize'); return Support.prepareTransactionTest(this.sequelize).bind(this).then(function (sequelize) {
this.sequelize = sequelize;
this.ns = cls.getNamespace('sequelize');
this.User = this.sequelize.define('user', { this.User = this.sequelize.define('user', {
name: Sequelize.STRING name: Sequelize.STRING
});
return this.sequelize.sync({ force: true });
}); });
return this.sequelize.sync({ force: true });
}); });
var autoCallback = function autoCallback(sequelize, cb) { var autoCallback = function autoCallback(sequelize, cb) {
...@@ -40,90 +43,103 @@ describe(Support.getTestDialectTeaser("Continuation local storage"), function () ...@@ -40,90 +43,103 @@ describe(Support.getTestDialectTeaser("Continuation local storage"), function ()
}); });
}; };
[autoCallback, thenCallback].forEach(function (cb) { if (current.dialect.supports.transactions) {
describe(cb.name, function () { [autoCallback, thenCallback].forEach(function (cb) {
describe('context', function () { describe(cb.name, function () {
it('supports several concurrent transactions', function () { describe('context', function () {
var t1id, t2id, self = this; it('supports several concurrent transactions', function () {
var t1id, t2id, self = this;
return Promise.join(
cb(this.sequelize, function () { return Promise.join(
t1id = self.ns.get('transaction').id; cb(this.sequelize, function () {
t1id = self.ns.get('transaction').id;
return Promise.resolve();
}), return Promise.resolve();
cb(this.sequelize, function () { }),
t2id = self.ns.get('transaction').id; cb(this.sequelize, function () {
t2id = self.ns.get('transaction').id;
return Promise.resolve();
}), return Promise.resolve();
function () { }),
expect(t1id).not.to.equal(t2id); function () {
} expect(t1id).to.be.ok;
); expect(t2id).to.be.ok;
}); expect(t1id).not.to.equal(t2id);
}
);
});
it('supports nested promise chains', function () { it('supports nested promise chains', function () {
var self = this; var self = this;
return cb(this.sequelize, function () { return cb(this.sequelize, function () {
var tid = self.ns.get('transaction').id; var tid = self.ns.get('transaction').id;
return self.User.findAll().then(function () { return self.User.findAll().then(function () {
expect(self.ns.get('transaction').id).to.be.ok; expect(self.ns.get('transaction').id).to.be.ok;
expect(self.ns.get('transaction').id).to.equal(tid); expect(self.ns.get('transaction').id).to.equal(tid);
});
}); });
}); });
});
it('does not leak variables to the outer scope', function () { it('does not leak variables to the outer scope', 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.
// We can't just call another function from inside that transaction, since that would transfer the context to that function - exactly what we are trying to prevent; // We can't just call another function from inside that transaction, since that would transfer the context to that function - exactly what we are trying to prevent;
var self = this var self = this
, transactionSetup = false , transactionSetup = false
, transactionEnded = false; , transactionEnded = false;
cb(this.sequelize, function () { cb(this.sequelize, function () {
transactionSetup = true; transactionSetup = true;
return Promise.delay(500).then(function () { return Promise.delay(500).then(function () {
expect(self.ns.get('transaction')).to.be.ok; expect(self.ns.get('transaction')).to.be.ok;
transactionEnded = true; transactionEnded = true;
});
}); });
});
// Wait for 400 ms - should be enough time to get everything set up
return Promise.delay(400).bind(this).then(function () {
expect(transactionSetup).to.be.ok;
expect(transactionEnded).not.to.be.ok;
expect(this.ns.get('transaction')).not.to.be.ok; return new Promise(function (resolve) {
// Wait for the transaction to be setup
var interval = setInterval(function () {
if (transactionSetup) {
clearInterval(interval);
resolve();
}
}, 200);
}).bind(this).then(function () {
expect(transactionEnded).not.to.be.ok;
expect(this.ns.get('transaction')).not.to.be.ok;
// Just to make sure it didn't change between our last check and the assertion
expect(transactionEnded).not.to.be.ok;
});
}); });
});
it('does not leak variables to the following promise chain', function () { it('does not leak variables to the following promise chain', function () {
return cb(this.sequelize, function () { return cb(this.sequelize, function () {
return Promise.resolve(); return Promise.resolve();
}).bind(this).then(function () { }).bind(this).then(function () {
expect(this.ns.get('transaction')).not.to.be.ok; expect(this.ns.get('transaction')).not.to.be.ok;
});
}); });
}); });
});
describe('sequelize.query integration', function () { describe('sequelize.query integration', function () {
it('automagically uses the transaction in all calls', function () { it('automagically uses the transaction in all calls', function () {
var self = this; var self = this;
return cb(this.sequelize, function () { return cb(this.sequelize, function () {
return self.User.create({ name: 'bob' }).then(function () { return self.User.create({ name: 'bob' }).then(function () {
return Promise.all([ return Promise.all([
expect(self.User.findAll({}, { transaction: null })).to.eventually.have.length(0), expect(self.User.findAll({}, { transaction: null })).to.eventually.have.length(0),
expect(self.User.findAll({})).to.eventually.have.length(1) expect(self.User.findAll({})).to.eventually.have.length(1)
]); ]);
});
}); });
}); });
}); });
}); });
}); });
}); }
}); });
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!