Lately I have been writing a dependency injection module for node.js which works with coroutines. I'll probably write more about it later since I find this topic super interesting but for now, one can look at this introduction to generators. I am using the excellent bluebird promises library for the coroutine part.
So let's try to write a mocha test with coroutines, there are a few gotcha.
Here's our basic generator:
function* generator() {
yield 'ok';
yield Promise.delay('late', 100);
}
(notice the * at the end). Here's how to use it (node >= 0.11.4 with --harmony flag):
var g = generator();
g.next(); // { value: ok, done: false }
g.next(); // { value: <promise object>, done: false }
g.next(); // { value: undefined, done: true }
A basic mocha test would be:
suite('Async with generator', function() {
test('basic generator', function() {
var g = generator();
assert.equal(g.next().value, 'ok');
assert.equal(g.next().value, 'late');
});
});
And this fails... Because the second call to g.next()
returns the promise object. A fix would be:
test('With synchronous yield', function(done) {
var g = generator();
assert.equal(g.next().value, 'ok');
g.next().value.then(function(val) {
assert.equal(val, 'late');
done();
});
});
This pass, but is not very pretty, and suddendly, we have to get back the asynchronous callback back :(
A better solution is to use a [coroutine](https://github.com/petkaantonov/bluebird/blob/master/API.md#promisecoroutinegeneratorfunction-generatorfunction