Q:

Mocha Tests Are Timing Out

I'm running Node.js 4.0 so it supports generators now.
I've tried gulp-mocha-co and also recently removed that as well as upgraded to Node 4.0 since it supports generators now.
Either way, as soon as I started to try to make my mocha tests generator friendly I get timeouts on all those tests after adding the * to make my mocha unit tests generators.  I noticed that it doesn't even run my test implementation code.  It gets to the *function() of my test and that's when it just sits and times out.
I am using gulp-mocha right now.
myTests.js
"use strict";

var chai = require('chai'),
    should = chai.should(),
    testUtil = require('../../../test/testUtilities'),
    carUseCase = require('../../../src/usecases/carGet'),
    gateway= require('../../../test/gateway'),
    carRequestModel = require('../../../src/models/http/request/carRequest');

describe('Get Car by Id', function() {

    it('should return no car when no cars exist', function*(done){
        var cars = [];

        inMemoryGateway.data(cars);
        carUseCase.gateway(gateway);

        var request = testUtil.createCarRequest();
        var responseModel = yield carUseCase.find(request);
        should.not.exist(responseModel.cars);

        var request = testUtil.createCarRequest(0, "", "", "");
        var responseModel = yield carUseCase.find(request);
        should.not.exist(responseModel.cars);

        done();
    });

gulp.js
var gulp = require('gulp'),
    mocha = require('gulp-mocha');

...
    gulp.task('mocha-unit', function() {
        process.env.PORT = 5001;
        return gulp.src([config.test.src.unit], { read: false })
            .pipe(mocha({
                reporter: config.test.mocha.reporter,
                ui: 'bdd'
            }))
    });

carGet.js
var car = require('../entities/car'),
    realGateway = require('../../src/gateways/carGateway'),
    carResponse = require('../../src/models/http/response/carResponse'),
    _gateway;

module.exports = {
    find: function *(carRequest){

        carResponse.http.statusCode = 200;

        var entity = yield _gateway.find(carRequest.id);

        if(!entity.cars || entity.cars.length == 0){
            entity.cars = null;
            carResponse.http.statusCode = 204;
        }

        carResponse.cars = entity.cars;

        return carResponse;
    }
};

gatewayTestDouble.js
'use strict';

var _data;

module.exports = {
    data: function(data){
        _data = data
    },
    find: function *(id) {
        var found = [];

        if(id == null && hasData(_data)){
            yield _data;
            return;
        }

        if(!id && !isPositiveNumber(id)){
            yield found;
            return;
        }

        if(isPositiveNumber(id) && hasData(_data)) {
            for (var i = 0; i < _data.length; i++) {
                if (_data[i].id === id)
                    found.push(_data[i]);
            }
        }

        yield found;
    }
};

Error
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.

A:

There's a couple things going on here.

Since you've declared done as a callback argument, Mocha waits for it to be called, which never happens because...
Mocha doesn't support generators as callbacks. All it sees is that your callback returned an iterator. Since Mocha doesn't run the iterator to completion, the done() call is never reached.

Mocha does however support functions that return promises, as a mutually-exclusive alternative to functions that declare done in their arg lists.
The co utility can wrap generators that iterate multiple promises, turning them into functions that return a single promise.
In order to work, don't declare done in the arg list, then import co and do something like this:
it('should foo', co.wrap(function*() {
  var foo = yield somethingThatReturnsAPromise();
  // do something with foo
}));

Note that you could alternatively do the below, and Mocha wouldn't be able to tell the difference:
it('should foo', co.wrap(function*() {
  return somethingThatReturnsAPromise().then(function(foo) {
    // do something with foo
  });
}));

Hope that helps!

