"use strict";

var runMocha = require("../helpers.cjs").runMocha;

describe("--exit", function () {
  var behaviors = {
    enabled: "--exit",
    disabled: "--no-exit",
  };

  // subprocess
  var mocha;

  function killSubprocess() {
    mocha.kill("SIGKILL");
  }

  // these two handlers deal with a ctrl-c on command-line
  before(function () {
    process.on("SIGINT", killSubprocess);
  });

  after(function () {
    process.removeListener("SIGINT", killSubprocess);
  });

  /**
   * Returns a test that executes Mocha in a subprocess with either
   * `--exit`, `--no-exit`, or default behavior.
   *
   * @param {boolean} shouldExit - Expected result; `true` if Mocha should
   *   have force-killed the process.
   * @param {"enabled"|"disabled"} [behavior] - 'enabled' or 'disabled'; omit for default
   * @returns {Function} async function implementing the test
   */
  var runExit = function (shouldExit, behavior) {
    return function (done) {
      var timeout = this.timeout();
      this.timeout(0);
      this.slow(Infinity);

      var didExit = true;
      var timeoutObj;
      var fixture = "exit.fixture.cjs";
      var args = behaviors[behavior] ? [behaviors[behavior]] : [];
      mocha = runMocha(fixture, args, function postmortem(err) {
        clearTimeout(timeoutObj);
        if (err) {
          return done(err);
        }
        expect(didExit, "to be", shouldExit);
        done();
      });

      // If this callback happens, then Mocha didn't automatically exit.
      timeoutObj = setTimeout(function () {
        didExit = false;
        killSubprocess();
      }, timeout - 500);
    };
  };

  describe("default behavior", function () {
    it("should not force exit after root suite completion", runExit(false));
  });

  describe("when enabled", function () {
    it(
      "should force exit after root suite completion",
      runExit(true, "enabled"),
    );
  });

  describe("when disabled", function () {
    it(
      "should not force exit after root suite completion",
      runExit(false, "disabled"),
    );
  });
});
