"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var mocha_exports = {};
__export(mocha_exports, {
  adaptReporter: () => adaptReporter,
  afterOne: () => afterOne,
  afterRun: () => afterRun,
  beforeOne: () => beforeOne,
  beforeRun: () => beforeRun,
  browserSetup: () => browserSetup,
  extendApi: () => extendApi,
  generalSetup: () => generalSetup,
  runMocha: () => runMocha
});
module.exports = __toCommonJS(mocha_exports);
var import_failure_detail = require("./failure-detail.js");
var import_boot = require("./mocks/boot.js");
var import_logging = require("./mocks/logging.js");
var import_time = require("./mocks/time.js");
var import_options = require("./options.js");
var import_text_diff = require("./text-diff.js");
var import_wtf = require("./util/wtf.js");
var import_web_reporter = require("./web-reporter.js");
/**
 * @license
 * Copyright 2022-2026 Matter.js Authors
 * SPDX-License-Identifier: Apache-2.0
 */
const TEST_HOOK_TIMEOUT = 6e4;
const beforeOneHook = /* @__PURE__ */ Symbol("before-hook");
const afterOneHook = /* @__PURE__ */ Symbol("after-hook");
function beforeOne(test, fn) {
  if (test[beforeOneHook]) {
    throw new Error("Only one beforeTest currently allowed");
  }
  test[beforeOneHook] = fn;
}
function afterOne(test, fn) {
  if (test[afterOneHook]) {
    throw new Error("Only one afterTest currently allowed");
  }
  test[afterOneHook] = fn;
}
function generalSetup(mocha) {
  const Base = mocha.constructor.reporters.Base;
  Base.colors["diff added inline"] = "97;42;48;5;22";
  Base.colors["diff removed inline"] = "97;41;48;5;52";
  function filterLogs(hook) {
    const actual = mocha.suite[hook];
    mocha.suite[hook] = function(fn) {
      return actual.call(this, async function(...args) {
        return await onlyLogFailure(() => fn.apply(this, args));
      });
    };
  }
  filterLogs("beforeAll");
  filterLogs("afterAll");
  filterLogs("beforeEach");
  filterLogs("afterEach");
  mocha.suite.beforeEach(function(done) {
    this.timeout(TEST_HOOK_TIMEOUT);
    return this.currentTest[beforeOneHook]?.call(this, done);
  });
  mocha.suite.afterEach(function(done) {
    this.timeout(TEST_HOOK_TIMEOUT);
    for (const hook of import_logging.LoggerHooks.afterEach) {
      hook(mocha);
    }
    return this.currentTest[afterOneHook]?.call(this, done);
  });
  import_text_diff.TextDiff.generator = Base.generateDiff.bind(Base);
}
function extendApi(Mocha2) {
  Mocha2.Runnable.prototype._timeoutError = function(timeoutMs) {
    const error = new import_time.TestTimeoutError(`Timeout of ${timeoutMs}ms exceeded`);
    error.code = "ERR_MOCHA_TIMEOUT";
    error.timeout = timeoutMs;
    if (this.file) {
      error.file = this.file;
    }
    return error;
  };
  Mocha2.reporters.Base.maxDiffSize = 65535;
  const descriptors = /* @__PURE__ */ new WeakMap();
  Object.defineProperty(Mocha2.Suite.prototype, "descriptor", {
    get() {
      const suite = this;
      let descriptor = descriptors.get(suite);
      if (descriptor) {
        return descriptor;
      }
      descriptor = {
        get name() {
          return suite.title;
        },
        get kind() {
          return "suite";
        },
        get path() {
          return suite.file;
        },
        get members() {
          const members = Array();
          for (const sub of suite.suites) {
            members.push(sub.descriptor);
          }
          for (const test of suite.tests) {
            if (test.descriptor === void 0) {
              test.descriptor = { name: test.title, kind: "js" };
            }
            members.push(test.descriptor);
          }
          return members;
        }
      };
      descriptors.set(suite, descriptor);
      return descriptor;
    }
  });
  Object.defineProperty(Mocha2.Test.prototype, "descriptor", {
    set(descriptor) {
      descriptors.set(this, descriptor);
    },
    get() {
      let descriptor = descriptors.get(this);
      if (descriptor) {
        return descriptor;
      }
      descriptor = {
        name: this.title,
        kind: "js"
      };
      descriptors.set(this, descriptor);
      return descriptor;
    }
  });
}
function instrumentSuites(mocha) {
  for (const suite of mocha.suite.suites) {
    suite.beforeAll(beforeEachFile);
    suite.beforeEach(beforeEach);
    const hooks = suite._beforeAll;
    const myHook = hooks.pop();
    hooks.unshift(myHook);
  }
}
async function runMocha(mocha, options) {
  instrumentSuites(mocha);
  if (!options?.skipBeforeHooks) {
    await onlyLogFailure(async () => {
      for (const hook of beforeRunHooks) {
        await hook();
      }
    });
  }
  await new Promise((resolve) => {
    const runner = mocha.run(() => resolve(runner));
  });
  if (!options?.skipAfterHooks) {
    await onlyLogFailure(async () => {
      for (const hook of afterRunHooks) {
        await hook();
      }
    });
  }
  import_wtf.wtf.dump();
}
function beforeEachFile() {
  import_boot.Boot.reboot();
}
function beforeEach() {
  import_boot.Boot.reset();
}
function adaptReporter(Mocha2, title, reporter, updateStats = false) {
  const RUNNER = Mocha2.Runner.constants;
  let logs = Array();
  class MochaReporter extends Mocha2.reporters.Base {
    constructor(runner) {
      super(runner);
      runner.once(RUNNER.EVENT_RUN_BEGIN, () => {
        if (!MatterHooks) {
          throw new Error("Matter hooks not loaded");
        }
        MatterHooks.loggerSink = (text) => {
          logs.push(text);
        };
        reporter.beginRun(title, this.translatedStats);
      });
      runner.on(RUNNER.EVENT_SUITE_BEGIN, (suite) => {
        reporter.beginSuite(suite.titlePath(), this.translatedStats, suite.file);
      });
      runner.on(RUNNER.EVENT_TEST_BEGIN, (test) => {
        if (updateStats && test.descriptor) {
          test.descriptor.runAt = /* @__PURE__ */ new Date();
        }
        logs = test.logs = [];
        reporter.beginTest(test.title, this.translatedStats);
      });
      runner.on(RUNNER.EVENT_TEST_PASS, (test) => {
        if (updateStats && test.descriptor) {
          test.descriptor.durationMs = test.duration;
          test.descriptor.passed = true;
        }
        reporter.passTest(test.title);
      });
      runner.on(RUNNER.EVENT_TEST_FAIL, (test, error) => {
        let diagnostics;
        if (error instanceof import_time.TestTimeoutError) {
          diagnostics = error.diagnostics;
        }
        if (updateStats && test.descriptor) {
          test.descriptor.durationMs = test.duration;
          test.descriptor.passed = false;
        }
        const logs2 = test.logs;
        reporter.failTest(
          test.title,
          (0, import_failure_detail.FailureDetail)(error, void 0, logs2, void 0, diagnostics),
          test.descriptor
        );
        import_wtf.wtf.dump();
      });
      runner.once(RUNNER.EVENT_RUN_END, () => {
        if (!MatterHooks) {
          throw new Error("Matter hooks not loaded");
        }
        MatterHooks.loggerSink = void 0;
        reporter.endRun(this.translatedStats);
      });
    }
    get translatedStats() {
      return {
        total: this.runner.total,
        complete: this.stats.tests,
        failures: this.stats.failures
      };
    }
  }
  return MochaReporter;
}
function browserSetup(mocha) {
  mocha.setup("bdd");
  globalThis.MatterTest = {
    // Starts Mocha (called by clicking link)
    start: () => {
      instrumentSuites(mocha);
      const root = document.querySelector("#mocha");
      if (root) {
        root.innerHTML = "";
      }
      return mocha.run();
    },
    // Start Mocha, proxying reporting through console to Playwright and completing once Mocha has finished
    auto: async function(options) {
      import_options.TestOptions.apply(mocha, options);
      mocha.reporter(adaptReporter(Mocha, "Web", new import_web_reporter.WebReporter()));
      return new Promise((accept) => {
        const runner = this.start();
        runner.on("end", accept);
      });
    }
  };
}
const beforeRunHooks = Array();
const afterRunHooks = Array();
function beforeRun(hook) {
  beforeRunHooks.push(hook);
}
function afterRun(hook) {
  afterRunHooks.push(hook);
}
async function onlyLogFailure(fn) {
  if (!MatterHooks) {
    throw new Error("Matter hooks not loaded");
  }
  const logs = Array();
  const existingSink = MatterHooks.loggerSink;
  try {
    MatterHooks.loggerSink = (text) => {
      logs.push(text);
    };
    return await fn();
  } catch (e) {
    process.stdout.write(logs.join("\n"));
    throw e;
  } finally {
    MatterHooks.loggerSink = existingSink;
  }
}
//# sourceMappingURL=mocha.js.map
