== Why is this an issue?

The ``++done++`` callback is used to inform Mocha when an asynchronous test ends. Exceptions thrown after ``++done++`` (with or without parameters) is called are not handled in a consistent manner. Sometimes they will be correctly handled, but they might as well be assigned to a different test, no test at all, or even be completely ignored. Even when it works as expected this will be a source of confusion for other developers. Thus no code should be executed after ``++done++`` is called.


This rule raises an issue when some code is executed after a call to ``++done++``.


=== Noncompliant code example

[source,javascript]
----
const expect = require("chai").expect;
const fs = require("fs");

describe("Code is executed after Done", function() {
    it("Has asserts after done()", function(done) {
        try {
            expect(1).toEqual(2);
        } catch (err) {
            done();
            // This assertion will be ignored and the test will pass.
            expect(err).to.be.an.instanceof(RangeError);  // Noncompliant
        }
    });

    it("Throws an error some time after done()", function(done) {
        fs.readFile("/etc/bashrc", 'utf8', function(err, data) {
            done();
            setTimeout(() => {  // Noncompliant
                // This assertion error will not be assigned to any test.
                // Developers will have to guess which test failed.
                expect(data).to.match(/some expected string/); 
            }, 3000);
        });
    });

    it("Has code after done(err)", function(done) {
        try {
            throw Error("An error");
        } catch (err) {
            done(err);
        }
        fs.readFile("/etc/bashrc", 'utf8', function(err, data) {  // Noncompliant
            // This assertion error will be assigned to "Other test".
            expect(data).to.match(/some expected string/);
        });
    });

    it("Other test", function(done) {
        done()
    });
});
----


=== Compliant solution

[source,javascript]
----
const expect = require("chai").expect;
const fs = require("fs");

describe("Code is executed after Done", function() {
    it("Has asserts after done()", function(done) {
        try {
            expect(1).toEqual(2);
        } catch (err) {
            expect(err).to.be.an.instanceof(RangeError);
            done();
        }
    });

    it("Throws an error some time after done()", function(done) {
        fs.readFile("/etc/bashrc", 'utf8', function(err, data) {
            setTimeout(() => {
                expect(data).to.match(/some expected string/);
                done();
            }, 3000);
        });
    });

    it("Has code after done(err)", function(done) {
        try {
            throw Error("An error");
        } catch (err) {
            return done(err);
        }
        fs.readFile("/etc/bashrc", 'utf8', function(err, data) {
            // This assertion error will be assigned to "Other test".
            expect(data).to.match(/some expected string/);
            done();
        });
    });

    it("Other test", function(done) {
        done()
    });
});
----

ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

include::message.adoc[]

include::highlighting.adoc[]

endif::env-github,rspecator-view[]
