My situation: I'm writing some tests for an object that updates its members when you call a function, and notifies the caller when it's done by using a callback. I want to test that a particular sequence of member updates happen after a certain number of function calls. This was my first attempt (I'm writing Node.js tests in TypeScript using Mocha, I've omitted the mocking I use to make the updates work but you should get the gist of it):
import assert = module("assert")
describe('Obj', function() {
describe('#updateFunction()', function () {
it('should work', function (done) {
var obj = new Object();
var expected1: { ... };
var expected2: { ... };
var expected3: { ... };
// mock etc
obj.updateFunction(() => {
assert.deepEqual(expected1, obj.member);
obj.updateNowPlaying(() => {
assert.deepEqual(expected2, obj.member);
obj.updateNowPlaying(() => {
assert.deepEqual(expected3, obj.member);
done();
});
});
});
});
});
});
Not great. Especially when I wanted to test a longer sequence of expectations.
Then I remembered a little thing called recursion and felt stupid for not thinking of it earlier:
import assert = module("assert")
describe('Obj', function() {
describe('#updateFunction()', function () {
var chainTestUpdateFunction = (obj: Object, expected: any[], done: () => void) => {
if (expected.length == 0) {
done();
}
else {
obj.updateFunction(() => {
var curExpectation = expected.shift();
assert.deepEqual(curExpectation, obj.member);
chainTestUpdateFunction (station, expected, done);
});
}
};
it('should work', function (done) {
var obj = new Object();
var expected1: { ... };
var expected2: { ... };
var expected3: { ... };
// mock etc
var expected = [expected1, expected2, expected3];
chainTestNowPlaying(obj, expected, done);
});
});
});
So, another pretty obvious solution that probably isn't even really worth blogging about. But, this is the internet after all.