My production code has this chunk of logic, compiled from CoffeeScript:
results = [];
results.push(slowOpA());
results.push(slowOpB());
results.push(slowOpC());
results = _.flatten(results);
$.when.apply($, results).then(onComplete).fail(onError).always(function() {
$(document).trigger('stop')
});
I would expect this to first call all the slowOp* methods in sequence, then call either onComplete
or onError
exactly once, and finally call always
exactly once. So that's what I test for with Jasmine:
@stopSpy = jasmine.createSpy '<stopSpy>'
$(document).bind 'stop', @stopSpy
...
@lastPromise = new $.Deferred()
spyOn('slowOpA').andReturn new $.Deferred().resolve()
spyOn('slowOpB').andReturn new $.Deferred().resolve()
spyOn('slowOpC').andReturn @lastPromise
...
@lastPromise.resolve()
expect(@stopSpy).toHaveBeenCalledOnce()
And 99 out of 100 times that works, but every now and then it gets 2 or 3 calls instead:
Expected spy on <stopSpy> to have been called once, but was called '2' times
Am I missing something? Or is this some obscure race condition in jQuery/Jasmine?