Search code examples
javascriptjasmine

How does Jasmine know if it should wait for done()?


I've been working with Jasmine tests and specifically async tests for a while now and I can't figure out how it detects whether it should wait and possibly time out if you're using done() in your test. It works perfectly fine, I'm just really curious how they did that.

Let's take this simple test. These two obviously work (BTW, even if there's no beforeEach()):

it('Sample test', function () {
    expect(true).toBe(true);
});

it('Sample test with done', function (done) {
    expect(true).toBe(true);
    done();
});

However, if I don't call done() in the second test, it will time-out.

In JS, how do they check if the function you're passing to it() declares any params?


Solution

  • Every function has a .length property that returns the number of formal parameters it has:

    console.log(function (a, b, c) { }.length);  // 3
    console.log(function () { }.length);         // 0

    It appears that this is the relevant location in the jasmine source:

    for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
       var queueableFn = queueableFns[iterativeIndex];
       if (queueableFn.fn.length > 0) {
         attemptAsync(queueableFn);
         return;
       } else {
         attemptSync(queueableFn);
       }
     }
    

    It calls each test as asynchronous if the .length property is nonzero, and synchronous if it is zero.