[
  {
    "path": ".browserslistrc",
    "content": "node >= 14\nlast 2 Chrome versions\nlast 2 Edge versions\nlast 2 Firefox versions\nlast 2 Safari versions\nlast 2 Opera versions\nunreleased Chrome versions\nunreleased Edge versions\nunreleased Firefox versions\nunreleased Safari versions\nunreleased Opera versions\n"
  },
  {
    "path": ".editorconfig",
    "content": "# This file is for unifying the coding style for different editors and IDEs\n# editorconfig.org\n\nroot = true\n\n[*]\nend_of_line = lf\ncharset = utf-8\ninsert_final_newline = true\ntrim_trailing_whitespace = true\nindent_style = space\nindent_size = 2\n"
  },
  {
    "path": ".gitattributes",
    "content": "* text=auto eol=lf\n"
  },
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "content": "# Mocha Code of Conduct\n\n## Be friendly and patient\n\nWe understand that everyone has different levels of experience or knowledge in many diverse fields, be it technical or\nnon-technical in nature.\nWe also have areas of knowledge we are eager to expand; we want to be a community where people can not only contribute, but feel comfortable to ask questions as well and learn along the way.\nIf someone says something wrong, or says something accidentally offensive, respond with patience and try to keep it polite and civil.\nRemember that we all were newbies at one point.\n\n## Be welcoming\n\nWe strive to be a community that welcomes and supports people of all backgrounds and identities.\nThis includes, but is not limited to, members of any race, ethnicity, culture, national origin, color, immigration status, social and economic class, educational level, sex, sexual orientation, gender identity and expression, age, size, family status, political belief, religion, and mental and physical ability.\n\n## Be considerate\n\nYour work will be used by other people, and you in turn will depend on the work of others.\nAny decision you make will affect users and colleagues, and you should take those consequences into account when making decisions.\nRemember that we’re a world-wide community, so you might not be communicating in someone else’s primary language.\n\n## Be respectful\n\nNot all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners.\nWe might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack.\nIt’s important to remember that a community where people feel uncomfortable or threatened is not a productive one.\nMembers of the OpenJS Foundation community should be respectful when dealing with other members as well as with people outside the OpenJS Foundation community.\n\n## Be careful in the words that you choose\n\nWe are a community of professionals, and we conduct ourselves professionally.\nBe kind to others.\nDo not insult or put down other participants.\nHarassment and other exclusionary behavior aren’t acceptable.\nThis includes, but is not limited to:\n\n- Violent threats or language directed against another person.\n- Discriminatory jokes and language.\n- Posting sexually explicit or violent material.\n- Posting (or threatening to post) other people’s personally identifying information (“doxing”).\n- Personal insults, especially those using racist or sexist terms.\n- Unwelcome sexual attention.\n- Advocating for, or encouraging, any of the above behavior.\n- Repeated harassment of others.\n  In general, if someone asks you to stop, then stop.\n\n## When we disagree, try to understand why\n\nDisagreements, both social and technical, happen all the time and OpenJS Foundation projects are no exception.\nIt is important that we resolve disagreements and differing views constructively.\nRemember that we’re different.\nThe strength of the OpenJS Foundation comes from its varied community, people from a wide range of backgrounds.\nDifferent people have different perspectives on issues.\nBeing unable to understand why someone holds a viewpoint doesn’t mean that they’re wrong.\nDon’t forget that it is human to err and blaming each other doesn’t get us anywhere.\nInstead, focus on helping to resolve issues and learning from mistakes.\n\nOriginal text courtesy of the Speak Up! project and Django Project.\n\n## QUESTIONS?\n\nIf you have questions, please see the FAQ.\nIf that doesn’t answer your questions, feel free to email <report@lists.openjsf.org>.\n\n# OpenJS Foundation Code of Conduct\n\nThe OpenJS Foundation and its member projects use the Contributor Covenant v1.4.1 as its Code of Conduct.\nRefer to the following for the full text:\n\n- [Contributor Covenant v1.4.1 in english](https://www.contributor-covenant.org/version/1/4/code-of-conduct)\n- [Contributor Covenant v1.4.1 translations](https://www.contributor-covenant.org/translations)\n\nRefer to the section on reporting and escalation in this document for the specific emails that can be used to report and escalate issues.\n\n## Reporting\n\n### Project Spaces\n\nFor reporting issues in spaces related to a member project please use the email provided by the project for reporting.\nProjects handle CoC issues related to the spaces that they maintain.\nProjects maintainers commit to:\n\n- maintain the confidentiality with regard to the reporter of an incident\n- to participate in the path for escalation as outlined in\n  the section on Escalation when required.\n\n### Foundation Spaces\n\nFor reporting issues in spaces managed by the OpenJS Foundation, for example, repositories within the OpenJS organization, use the email `report@lists.openjsf.org`.\nThe Cross Project Council (CPC) is responsible for managing these reports and commits to:\n\n- maintain the confidentiality with regard to the reporter of an incident\n- to participate in the path for escalation as outlined in\n  the section on Escalation when required.\n\n## Escalation\n\nThe OpenJS Foundation maintains a Code of Conduct Panel (CoCP).\nThis is a foundation-wide team established to manage escalation when a reporter believes that a report to a member project or the CPC has not been properly handled.\nIn order to escalate to the CoCP send an email to `\"coc-escalation@lists.openjsf.org`.\n\nFor more information, refer to the full\n[Code of Conduct governance document](https://github.com/openjs-foundation/cross-project-council/tree/main/proposals/approved/CODE_OF_CONDUCT).\n"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "# Contributing to Mocha\n\n> Please read these guidelines before submitting an issue, filing a feature request, or contributing code.\n\n## ❓ Got a Question?\n\nIf you have a question about using Mocha, please use [StackOverflow](https://stackoverflow.com) or ask the friendly people in [our Discord](https://discord.gg/KeDn2uXhER).\n\n## ✏️ Filing Issues\n\nBefore adding anything to the issue tracker, **please [search issues](https://github.com/mochajs/mocha/issues) to see if it's already been reported**.\nMake sure to check closed and/or older issues as well.\n\nWith the exception of minor documentation typos, all changes to Mocha should be discussed in the issue tracker first.\nThis includes bugs, feature requests, and improvements to documentation.\n\n### 🐛 I Found a Bug\n\nSorry!\nIt happens to the best of us.\n\nPlease [file an issue using the bug report template](https://github.com/mochajs/mocha/issues/new?assignees=&labels=type%3A+bug&projects=&template=01-bug.yml&title=%F0%9F%90%9B+Bug%3A+%3Cshort+description+of+the+bug%3E) with _as much detail as possible_ to help us reproduce and diagnose the bug.\nMost importantly:\n\n- Let us know _how_ you're running Mocha (options, flags, environment, browser or Node.js, etc.).\n- Include your test code or file(s).\n  If large, please provide a link to a repository or [gist](https://gist.github.com).\n\nIf we need more information from you, we'll let you know.\nIf you don't within a few weeks, your issue will be closed for inactivity.\n\n### ❗️ Propose a Change\n\nPlease [file an issue using the feature request template](https://github.com/mochajs/mocha/issues/new?assignees=&labels=type%3A+feature&projects=&template=03-feature-request.yml&title=%F0%9F%9A%80+Feature%3A+%3Cshort+description+of+the+feature%3E).\nMost importantly:\n\n- Let us know _what_ the proposed change is, in as much detail as you can\n- Explain _why_ you want the change\n- Include your test code or file(s).\n  If large, please provide a link to a repository or [gist](https://gist.github.com).\n\nWe'll discuss your proposed changes and how they relate to the overarching goals of Mocha, detailed below in [⚽️ About Project Goals](#%EF%B8%8F-about-project-goals).\n\n## ⚽️ About Project Goals\n\nMocha is a test framework.\nDevelopers use it against anything from legacy spaghetti in barely-supported browsers to stage-0 TC39 features in Electron.\nMocha is committed to providing support for maintained (LTS) versions of Node.js and popular browsers.\n\nMocha adheres strictly to [semantic versioning](https://semver.org).\nWe are _extremely cautious_ with changes that have the potential to break; given the size of Mocha's user base, it's _highly unlikely_ a breaking change will slide by.\n\nMocha's usage far outweighs its resources.\nIf a proposed feature would incur a maintenance penalty, it could be a hard sell.\n\nWe ask you please keep these goals in mind when making or proposing changes.\n\n## 😇 I Just Want To Help\n\n_Excellent._ Here's how:\n\n- **Handy with JavaScript?** Please check out the issues labeled [`status: accepting prs`](https://github.com/mochajs/mocha/issues?q=is%3Aissue+is%3Aopen+label%3A%22status%3A+accepting+prs%22) or [`good first issue`](https://github.com/mochajs/mocha/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22+).\n  Try `npx good-first-issue mocha`!\n- **Can you write ~~good~~ well?** The [documentation](https://mochajs.org) almost always needs some love.\n  See the [doc-related issues](https://github.com/mochajs/mocha/issues?q=is%3Aopen+is%3Aissue+label%3A%22area%3A+documentation%22).\n- **Design your thing?** [Our site](https://mochajs.org) needs your magic touch.\n- **Familiar with Mocha's codebase?** We could use your help triaging issues and/or reviewing pull requests.\n  Please contact an [org member](https://github.com/orgs/mochajs/people), and we'll chat.\n- **Want to build our community?** Mocha has a _lot_ of users.\n  We could use your help bringing everyone together in peace and harmony.\n  Please contact an [org member](https://github.com/orgs/mochajs/people).\n- **Do you write unit tests for _fun_?** A PR which increases coverage is unlikely to be turned down.\n- **Are you experienced?** 🎸 If you're a seasoned Mocha user, why not help answer some questions in [our Discord's `#help` channel](https://discord.gg/KeDn2uXhER)?\n\n## 🙋 Frequently Asked Questions\n\n### Can I work on this issue?\n\nAnyone can work on any issue marked `status: accepting prs` 🙂 Please check if there is already a PR for this issue, and if it's still being worked on. If it hasn't been updated for over a week, you're welcome to open your own PR and we'll review it when we can!\n\n## 👞 Contributing Code: Step-by-Step\n\nFirst follow the steps in [DEVELOPMENT.md](./DEVELOPMENT.md) to get Mocha's repository installed locally.\nThen:\n\n### 🎋 Initial Creation\n\n1. Make sure the issue is labeled with [`status: accepting prs`](https://github.com/mochajs/mocha/issues?q=is%3Aissue+is%3Aopen+label%3A%22status%3A+accepting+prs%22)\n1. Create a new branch in your working copy.\n1. Make your changes and add them via `git add`.\n   - Your changes will likely be somewhere in `lib/`, `bin/`, or (if your changes are browser-specific) `browser-entry.js`.\n   - Unit and/or integration **tests are required** for any code change.\n     These live in `test/`.\n   - **Do not modify** the root `mocha.js` file directly; it is automatically generated.\n   - Keep your PR focused.\n     Don't fix two things at once; don't upgrade dependencies unless necessary.\n1. Before committing, run `npm test`.\n   - This will run both Node.js-based and browser-based tests.\n   - Ultimately, your pull request will be built on our continuous integration servers ([GitHub Actions](https://github.com/mochajs/mocha/actions?query=workflow%3A%22Tests%22)).\n     The first step to ensuring these checks pass is to test on your own machine.\n   - When tests are run in CI, a coverage check is sent to [Codecov](https://app.codecov.io/gh/mochajs/mocha). You'll need to [add the Codecov GitHub app](https://app.codecov.io/login) to upload these results from your fork. This is recommended but not necessary to open a PR.\n     **A drop in code coverage % is considered a failed check**.\n1. Commit your changes.\n   - Use a brief message on the first line, referencing a relevant issue (e.g. `closes #12345`).\n   - Add detail in subsequent lines.\n   - A pre-commit hook will run which automatically formats your staged changes (and fixes any problems it can) with ESLint and Prettier.\n     If ESLint fails to fix an issue, your commit will fail and you will need to manually correct the problem.\n1. <a name=\"up-to-date\"/> (Optional) Ensure you are up-to-date with Mocha's `main` branch:\n   - You can add an \"upstream\" remote repo using `git remote add upstream https://github.com/mochajs/mocha.git && git fetch upstream`.\n   - Navigate to your `main` branch using `git checkout main`.\n   - Pull changes from `upstream` using `git pull upstream main`.\n   - If any changes were pulled in, update your branch from `main` by switching back to your branch (`git checkout <your-branch>`) then merging using `git merge main`.\n1. Push your changes to your fork; `git push origin`.\n1. In your browser, navigate to [mochajs/mocha](https://github.com/mochajs/mocha).\n   You should see a notification about your recent changes in your fork's branch, with a (green?) button to create a pull request.\n   Click it.\n1. Describe your changes in detail here, following the template.\n   Once you're satisfied, submit the form.\n\nAt that point, hooray! 🎉\nYou should see a pull request on github.com/mochajs/mocha/pulls.\n\n### 🤖 AI-Generated Code\n\nWe recognize that AI tools like GitHub Copilot, Claude, and others can be valuable aids in software development.\nHowever, **all code contributions, whether written by humans or generated by AI, must meet the same quality standards**.\n\nIf you use AI to help generate code for a pull request:\n\n- **All automated tests must pass**: Your code must pass linting, unit tests, integration tests, and any other automated checks.\n- **Manual review is required**: AI-generated code must undergo the same thorough manual inspection as any other contribution. This includes checking for correctness, security vulnerabilities, adherence to project conventions, and overall code quality.\n- **You are responsible**: As the submitter of the pull request, you are fully responsible for understanding and maintaining the code, regardless of how it was generated.\n\nThese requirements apply to all contributions and are not unique to AI-generated code—they simply reinforce our existing standards.\n\n### 🏭 PR Process\n\nNow that the pull request exists, some tasks will be run on it:\n\n1. If you have not signed our [Contributor License Agreement](docs.linuxfoundation.org/lfx/easycla/v2-current/contributors), a friendly robot will prompt you to do so.\n   A [CLA](https://cla.js.foundation/mochajs/mocha) (electronic) signature is **required** for all contributions of code to Mocha.\n1. Continuous integration checks will run against your changes.\n   The result of these checks will be displayed on your PR.\n   - If the checks fail, you must address those before the PR is accepted.\n1. Be patient while your PR is reviewed.\n   This can take a while.\n   We may request changes, but don't be afraid to question them.\n1. Your PR might become conflicted with the code in `main`.\n   If this is the case, you will need to [update your PR](#up-to-date) and resolve your conflicts.\n1. You don't need to make a new PR to any needed changes.\n   Instead, commit on top of your changes, and push these to your fork's branch.\n   The PR will be updated, and CI will re-run.\n1. Once you've addressed all the feedback you can, [re-request review on GitHub](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/about-pull-request-reviews#re-requesting-a-review).\n\nJoin us in [our Discord](https://discord.gg/KeDn2uXhER)!\n\n## 🌐 External Services\n\nMocha uses several external services for project infrastructure:\n\n- **[Codecov](https://app.codecov.io/gh/mochajs/mocha)**: Code coverage tracking. PRs must not decrease coverage. Contributors should add the Codecov GitHub app to upload coverage from forks.\n\n- **[Discord](https://discord.gg/KeDn2uXhER)**: Official community chat for support, discussions, and connecting with maintainers and users.\n\n- **[EasyCLA](https://cla.js.foundation/mochajs/mocha)**: Contributor License Agreement system via Linux Foundation. All code contributions require a signed CLA. A bot prompts contributors on their first PR.\n\n- **Netlify**: Hosts the documentation website at mochajs.org. Provides automatic deploy previews for documentation PRs and nightly scheduled deploys to update supporter information.\n\n- **[npm registry](https://www.npmjs.com/package/mocha)**: Package distribution. Mocha is also available via GitHub Releases.\n\n- **[Open Collective](https://opencollective.com/mochajs)**: Transparent donations to Mocha and expenses from maintainers.\n\n- **[OpenJS Foundation](https://openjsf.org)**: Mocha is part of the OpenJS Foundation which provides governance and infrastructure support. See [PROJECT_CHARTER.md](../PROJECT_CHARTER.md) for governance details.\n"
  },
  {
    "path": ".github/DEVELOPMENT.md",
    "content": "# Development\n\nFollow these steps to get going in local development.\nIf you are having trouble, don't be afraid to [ask for help](./CONTRIBUTING.md#❓-got-a-question).\n\n## Prerequisites\n\n- [Install Node.js 14 LTS or newer with npm@7+](https://nodejs.org/en/download).\n  - If you're new to installing Node, a tool like [nvm](https://github.com/nvm-sh/nvm#install-script) can help you manage multiple version installations.\n- You will need [Google Chrome](https://www.google.com/chrome) to run browser-based tests locally.\n\n## Setup\n\n1. Follow [Github's documentation](https://help.github.com/articles/fork-a-repo) on setting up Git, forking, and cloning.\n1. Execute `npm install` to install the development dependencies.\n   - Do not use `yarn install` or `pnpm install`.\n   - Some optional dependencies may fail; you can safely ignore these unless you are trying to build the documentation.\n   - If you're sick of seeing the failures, run `npm install --ignore-scripts`.\n\n## Developing Mocha\n\nWhen you contribute to Mocha, you will probably want to try to run your changes on the test suite of another project. You can (and should) run the test suite of Mocha itself before committing, but also confirming that your changes give the expected result on another project.\n\nFor example, [WebSocket.io](https://github.com/LearnBoost/websocket.io/):\n\n    $ git clone https://github.com/LearnBoost/websocket.io.git\n\nRetrieve websocket.io's dependencies, which will include the stable version of Mocha:\n\n    $ cd websocket.io/\n    $ npm install\n\nReplace the Mocha dependency by the current git repository:\n\n    $ cd node_modules/\n    $ mv mocha/ mocha.save\n    $ git clone https://github.com/mochajs/mocha.git\n\nInstall Mocha's dependencies for the development version:\n\n    $ cd mocha\n    $ npm install\n\nRun websocket.io's test suite using the development version you just installed:\n\n    $ cd ../..\n    $ ./node_modules/.bin/mocha\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "open_collective: mochajs\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/01-bug.yml",
    "content": "body:\n  - attributes:\n      description: If any of these required steps are not taken, we may not be able to review your issue. Help us to help you!\n      label: Bug Report Checklist\n      options:\n        - label: This is NOT a [security, `npm audit`, or GitHub Advisory issue](https://mochajs.org/explainers/security-vulnerability-reports).\n          required: true\n        - label: I have read and agree to Mocha's [Code of Conduct](https://github.com/mochajs/mocha/blob/main/.github/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/mochajs/mocha/blob/main/.github/CONTRIBUTING.md)\n          required: true\n        - label: I have searched for [related issues](https://github.com/mochajs/mocha/issues?q=is%3Aissue) and [issues with the `faq` label](https://github.com/mochajs/mocha/issues?utf8=%E2%9C%93&q=is%3Aissue%20label%3Afaq%20), but none matched my issue.\n          required: true\n        - label: I have 'smoke tested' the code to be tested by running it outside the real test suite to get a better sense of whether the problem is in the code under test, my usage of Mocha, or Mocha itself.\n          required: true\n        - label: I want to provide a PR to resolve this\n    type: checkboxes\n  - attributes:\n      description: What did you expect to happen?\n      label: Expected\n    type: textarea\n    validations:\n      required: true\n  - attributes:\n      description: What happened instead?\n      label: Actual\n    type: textarea\n    validations:\n      required: true\n  - attributes:\n      description: Detail the steps necessary to reproduce the problem. To get the fastest support, create an [MCVE](https://stackoverflow.com/help/mcve) and upload it to GitHub.\n      label: Minimal, Complete and Verifiable Example\n    type: textarea\n    validations:\n      required: true\n  - attributes:\n      description: What do `mocha --version`, `node_modules/.bin/mocha --version`, and `node --version` output? What name and version of browser/environment, shell, and any other related modules such as transpilers are you using?\n      label: Versions\n    type: textarea\n    validations:\n      required: true\n  - attributes:\n      description: Any additional info you'd like to provide.\n      label: Additional Info\n    type: textarea\ndescription: Report a bug trying to use Mocha\nlabels:\n  - \"status: in triage\"\n  - \"type: bug\"\nname: 🐛 Bug\ntitle: \"🐛 Bug: <short description of the bug>\"\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/02-documentation.yml",
    "content": "body:\n  - attributes:\n      description: If any of these required steps are not taken, we may not be able to review your issue. Help us to help you!\n      label: Documentation Request Checklist\n      options:\n        - label: I have read and agree to Mocha's [Code of Conduct](https://github.com/mochajs/mocha/blob/main/.github/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/mochajs/mocha/blob/main/.github/CONTRIBUTING.md)\n          required: true\n        - label: I have searched for [related issues](https://github.com/mochajs/mocha/issues?q=is%3Aissue) and [issues with the `faq` label](https://github.com/mochajs/mocha/issues?utf8=%E2%9C%93&q=is%3Aissue%20label%3Afaq%20), but none matched my issue.\n          required: true\n        - label: I want to provide a PR to resolve this\n    type: checkboxes\n  - attributes:\n      description: What would you like to report?\n      label: Overview\n    type: textarea\n    validations:\n      required: true\n  - attributes:\n      description: Any additional info you'd like to provide.\n      label: Additional Info\n    type: textarea\ndescription: Report a typo or missing area of documentation\nlabels:\n  - \"area: documentation\"\n  - \"status: in triage\"\nname: 📝 Docs\ntitle: \"📝 Docs: <short description of the request>\"\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/03-feature-request.yml",
    "content": "body:\n  - attributes:\n      description: If any of these required steps are not taken, we may not be able to review your issue. Help us to help you!\n      label: Feature Request Checklist\n      options:\n        - label: I have read and agree to Mocha's [Code of Conduct](https://github.com/mochajs/mocha/blob/main/.github/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/mochajs/mocha/blob/main/.github/CONTRIBUTING.md)\n          required: true\n        - label: I have searched for [related issues](https://github.com/mochajs/mocha/issues?q=is%3Aissue) and [issues with the `faq` label](https://github.com/mochajs/mocha/issues?utf8=%E2%9C%93&q=is%3Aissue%20label%3Afaq%20), but none matched my issue.\n          required: true\n        - label: I want to provide a PR to resolve this\n    type: checkboxes\n  - attributes:\n      description: What is the feature gap or problem you'd like to address?\n      label: Overview\n    type: textarea\n    validations:\n      required: true\n  - attributes:\n      description: How would you like to solve this need?\n      label: Suggested Solution\n    type: textarea\n    validations:\n      required: true\n  - attributes:\n      description: What other features or solutions have you also considered?\n      label: Alternatives\n    type: textarea\n    validations:\n      required: true\n  - attributes:\n      description: Any additional info you'd like to provide.\n      label: Additional Info\n    type: textarea\ndescription: Request that a new feature be added or an existing feature improved\nlabels:\n  - \"status: in triage\"\n  - \"type: feature\"\nname: 🚀 Feature\ntitle: \"🚀 Feature: <short description of the feature>\"\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/04-performance.yml",
    "content": "body:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking the time to suggest a performance improvement to Mocha! Please note that Mocha is a widely used library with many millions of weekly downloads, many thousands of dependents, and many years of longstanding behavior. Every change to it is inherently risky and may break user edge cases that we have no way to learn of otherwise.\n\n        So, to accept a performance improvement, we'd need to see _measurable, non-negligible improvement_ in Mocha's real-world usage. That requires providing at least:\n\n        - Exhaustive comparison with other alternatives that proves this is the winning approach\n          - Disclosure of any personal affiliation with the proposed solution and alternatives\n        - For runtime performance: some kind of reproducible benchmark to demonstrate exactly what's different\n        - For dependency cleanups:\n          - The specific change to the dependency tree of a project with Mocha and no other dependencies\n          - The specific change to the dependency tree of a project with Mocha and other common dependencies, such as `chai`, `express`, and `sinon`\n\n        You can always suggest a performance improvement without those validations, but we are unlikely to accept it without them.\n        For more information, see [mochajs/mocha#5377 🛠️ Repo: Add issue template for performance improvements](https://github.com/mochajs/mocha/issues/5377).\n  - attributes:\n      description: If any of these required steps are not taken, we may not be able to review your issue. Help us to help you!\n      label: Performance Suggestion Checklist\n      options:\n        - label: I am using the latest version of Mocha.\n          required: true\n        - label: I have read and understood the nuances around performance reports.\n          required: true\n        - label: I have read and agree to Mocha's [Code of Conduct](https://github.com/mochajs/mocha/blob/main/.github/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/mochajs/mocha/blob/main/.github/CONTRIBUTING.md)\n          required: true\n        - label: I have searched for [related issues](https://github.com/mochajs/mocha/issues?q=is%3Aissue) and [issues with the `faq` label](https://github.com/mochajs/mocha/issues?utf8=%E2%9C%93&q=is%3Aissue%20label%3Afaq%20), but none matched my issue.\n          required: true\n        - label: I want to provide a PR to resolve this\n    type: checkboxes\n  - attributes:\n      description: What is your suggestion?\n      label: Overview\n    type: textarea\n    validations:\n      required: true\n  - attributes:\n      description: If you have a suggested implementation, please explain why you believe it's the best one here.\n      label: Validations\n    type: textarea\n  - attributes:\n      description: Any additional info you'd like to provide.\n      label: Additional Info\n    type: textarea\ndescription: Suggest a way to make Mocha faster, more memory- and/or space-efficient, or otherwise improve performance\nlabels:\n  - \"area: performance\"\n  - \"status: in triage\"\nname: ⚡️ Performance\ntitle: \"⚡️ Performance: <short description of the change>\"\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/05-repository-tooling.yml",
    "content": "body:\n  - attributes:\n      description: If any of these required steps are not taken, we may not be able to review your issue. Help us to help you!\n      label: Tooling Suggestion Checklist\n      options:\n        - label: I have tried restarting my IDE and the issue persists.\n          required: true\n        - label: I have pulled the latest `main` branch of the repository.\n          required: true\n        - label: I have read and agree to Mocha's [Code of Conduct](https://github.com/mochajs/mocha/blob/main/.github/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/mochajs/mocha/blob/main/.github/CONTRIBUTING.md)\n          required: true\n        - label: I have searched for [related issues](https://github.com/mochajs/mocha/issues?q=is%3Aissue) and [issues with the `faq` label](https://github.com/mochajs/mocha/issues?utf8=%E2%9C%93&q=is%3Aissue%20label%3Afaq%20), but none matched my issue.\n          required: true\n        - label: I want to provide a PR to resolve this\n    type: checkboxes\n  - attributes:\n      description: What changes would you like, and how do they help contributors?\n      label: Overview\n    type: textarea\n    validations:\n      required: true\n  - attributes:\n      description: Any additional info you'd like to provide.\n      label: Additional Info\n    type: textarea\ndescription: Report a bug or request an enhancement in the Mocha repository's internal tooling\nlabels:\n  - \"area: repository tooling\"\n  - \"status: in triage\"\nname: 🛠️ Repository Tooling\ntitle: \"🛠️ Repo: <short description of the change>\"\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: true\ncontact_links:\n  - name: Documentation Website\n    about: Please read our documentation website before filing new issues.\n    url: https://mochajs.org\n  - name: Documentation Website > APIs\n    about: If you're using Mocha's API, see also the website's API docs.\n    url: https://mochajs.org/api\n  - name: Discord\n    about: Our Discord is the right place for quick informal questions.\n    url: https://discord.gg/KeDn2uXhER\n  - name: StackOverflow\n    about: For more questions, see the `mocha` tag on StackOverflow.\n    url: https://stackoverflow.com/questions/tagged/mocha\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "<!-- 👋 Hi, thanks for sending a PR to mocha! 💖.\nPlease fill out all fields below and make sure each item is true and [x] checked.\nOtherwise we may not be able to review your PR. -->\n\n## PR Checklist\n\n- [ ] Addresses an existing open issue: fixes #000\n- [ ] That issue was marked as [`status: accepting prs`](https://github.com/mochajs/mocha/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22)\n- [ ] Steps in [CONTRIBUTING.md](https://github.com/mochajs/mocha/blob/main/.github/CONTRIBUTING.md) were taken\n\n## Overview\n\n<!-- Description of what is changed and how the code change does that. -->\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n    groups:\n      github-actions:\n        patterns:\n          - \"*\"\n"
  },
  {
    "path": ".github/release-please/config.json",
    "content": "{\n  \"$schema\": \"https://raw.githubusercontent.com/googleapis/release-please/v17.1.3/schemas/config.json\",\n  \"release-type\": \"node\",\n  \"include-component-in-tag\": false,\n\n  \"prerelease\": true,\n  \"versioning\": \"prerelease\",\n\n  \"changelog-sections\": [\n    { \"type\": \"feat\", \"section\": \"🌟 Features\", \"hidden\": false },\n    { \"type\": \"fix\", \"section\": \"🩹 Fixes\", \"hidden\": false },\n    { \"type\": \"docs\", \"section\": \"📚 Documentation\", \"hidden\": false },\n\n    { \"type\": \"chore\", \"section\": \"🧹 Chores\", \"hidden\": false },\n    { \"type\": \"perf\", \"section\": \"🧹 Chores\", \"hidden\": false },\n    { \"type\": \"refactor\", \"section\": \"🧹 Chores\", \"hidden\": false },\n    { \"type\": \"test\", \"section\": \"🧹 Chores\", \"hidden\": false },\n\n    { \"type\": \"build\", \"section\": \"🤖 Automation\", \"hidden\": false },\n    { \"type\": \"ci\", \"section\": \"🤖 Automation\", \"hidden\": true }\n  ],\n  \"packages\": {\n    \".\": {}\n  }\n}\n"
  },
  {
    "path": ".github/release-please/manifest.json",
    "content": "{\".\":\"12.0.0-beta.10\"}\n"
  },
  {
    "path": ".github/workflows/mocha.yml",
    "content": "name: Tests\n\non:\n  push:\n    branches:\n      - main\n    paths-ignore:\n      [\"*.md\", \"docs/**\", \".github/**\", \".prettierignore\", \"AUTHORS\", \"LICENSE\"]\n  pull_request:\n    branches:\n      - main\n    paths-ignore:\n      [\"*.md\", \"docs/**\", \".github/**\", \".prettierignore\", \"AUTHORS\", \"LICENSE\"]\n    types: [opened, synchronize, reopened, edited]\n  workflow_dispatch:\n\npermissions:\n  contents: read\n  id-token: write # for Codecov OIDC\n\njobs:\n  format:\n    uses: ./.github/workflows/npm-script.yml\n    with:\n      npm-script: format:check\n\n  lint:\n    uses: ./.github/workflows/npm-script.yml\n    with:\n      npm-script: lint\n\n  smoke:\n    uses: ./.github/workflows/npm-script.yml\n    with:\n      node-versions: \"20,22,24\"\n      npm-script: test-smoke\n\n  test-node-lts:\n    # TODO: Restore \"mocha-github-actions-reporter\" style reporting without relying on third party module\n    # https://github.com/mochajs/mocha/issues/5183\n    uses: ./.github/workflows/npm-script.yml\n    needs: smoke\n    strategy:\n      fail-fast: false\n      matrix:\n        test-part:\n          - interfaces\n          - unit\n          - integration\n          - jsapi\n          - requires\n          - reporters\n          - only\n    with:\n      npm-script: test-node:${{ matrix.test-part }}\n\n  test-node-all:\n    name: Test ${{ matrix.test-part }} in all environments\n    permissions:\n      id-token: write # for Codecov OIDC\n      contents: read # for Codecov OIDC\n    # TODO: Restore \"mocha-github-actions-reporter\" style reporting without relying on third party module\n    # https://github.com/mochajs/mocha/issues/5183\n    uses: ./.github/workflows/npm-script.yml\n    needs: test-node-lts\n    strategy:\n      fail-fast: false\n      matrix:\n        coverage: [true]\n        test-part:\n          - interfaces\n          - unit\n          - integration\n          - requires\n          - reporters\n          - only\n        include:\n          - test-part: jsapi\n            coverage: false\n    with:\n      os: \"ubuntu-latest,windows-latest\"\n      # We pin exact versions here per https://github.com/mochajs/mocha/issues/5052\n      # Ref https://nodejs.org/en/about/previous-releases\n      node-versions: \"20.19.4,22.18.0,24.6.0\"\n      npm-script: test-node:${{ matrix.test-part }}\n      coverage: ${{ matrix.coverage }}\n\n  test-browser-local:\n    uses: ./.github/workflows/npm-script.yml\n    with:\n      browsers: ChromeHeadless\n      npm-script: test-browser\n\n  tsc:\n    uses: ./.github/workflows/npm-script.yml\n    with:\n      npm-script: tsc\n"
  },
  {
    "path": ".github/workflows/nightly-site-deploy.yml",
    "content": "# Deploy `mochajs.org` branch nightly by hitting a netlify build URL.\n# This updates the list of supporters\n# It uses commands from netlify.toml at root of repo\n\nname: Nightly mochajs.org Deploy\n\non:\n  schedule:\n    - cron: \"0 0 * * *\"\n  workflow_dispatch:\n\npermissions:\n  contents: read\n\njobs:\n  deploy:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Webhook Action\n        uses: joelwmale/webhook-action@6cebc9d7dc8435b684e1e1945c0013d9023b76a4\n        env:\n          data: \"\"\n          WEBHOOK_URL: ${{ secrets.NETLIFY_NIGHTLY_DEPLOY_URL }}\n"
  },
  {
    "path": ".github/workflows/npm-script.yml",
    "content": "name: Reusable npm script runner\n\non:\n  workflow_call:\n    inputs:\n      npm-script:\n        description: \"npm script\"\n        required: true\n        type: string\n      browsers:\n        description: \"A comma separated list of browser names to test with.\"\n        required: false\n        type: string\n      node-versions:\n        description: \"A comma separated list of Node versions to test with.\"\n        required: false\n        type: string\n      os:\n        description: \"A comma separated list of operating systems to test on.\"\n        required: false\n        type: string\n      coverage:\n        description: \"Whether to set up coverage reporting or not\"\n        required: false\n        type: boolean\n\npermissions:\n  contents: read\n  id-token: write\n\njobs:\n  resolve-inputs:\n    runs-on: ubuntu-latest\n    outputs:\n      browsers: ${{ steps.split-browsers.outputs.splitted }}\n      nodeVersions: ${{ steps.split-node-versions.outputs.splitted }}\n      os: ${{ steps.split-os.outputs.splitted }}\n    steps:\n      - id: split-browsers\n        if: inputs.browsers\n        run: echo \"splitted=$(echo '${{ inputs.browsers }}' | jq -R -c 'split(\",\")')\" >> $GITHUB_OUTPUT\n      - id: split-node-versions\n        if: inputs.node-versions\n        run: echo \"splitted=$(echo '${{ inputs.node-versions }}' | jq -R -c 'split(\",\")')\" >> $GITHUB_OUTPUT\n      - id: split-os\n        if: inputs.os\n        run: echo \"splitted=$(echo '${{ inputs.os }}' | jq -R -c 'split(\",\")')\" >> $GITHUB_OUTPUT\n\n  script:\n    name: ${{ inputs.npm-script }}${{ needs.resolve-inputs.outputs.browsers && format('[{0}]', matrix.browser) }}${{ needs.resolve-inputs.outputs.nodeVersions && format(' with node.js {0}', matrix.node_version) }}${{ needs.resolve-inputs.outputs.os && format(' on {0}', matrix.os) }}\n    runs-on: ${{ matrix.os }}\n    timeout-minutes: 20\n    needs:\n      - resolve-inputs\n    strategy:\n      fail-fast: false\n      matrix:\n        node_version: ${{ fromJson(needs.resolve-inputs.outputs.nodeVersions || '[\"22\"]') }}\n        os: ${{ fromJson(needs.resolve-inputs.outputs.os || '[\"ubuntu-latest\"]') }}\n        browser: ${{ fromJson(needs.resolve-inputs.outputs.browsers || '[\"\"]') }}\n    steps:\n      - uses: actions/checkout@v6\n        with:\n          persist-credentials: false\n      - uses: actions/setup-node@v6\n        with:\n          node-version: ${{ matrix.node_version }}\n          cache: \"npm\"\n      - run: npm ci --ignore-scripts\n      - run: npm run ${{ inputs.npm-script }}\n        env:\n          BROWSER: ${{ matrix.browser }}\n          COVERAGE: ${{ inputs.coverage && '1'}}\n          NODE_OPTIONS: \"--trace-warnings\"\n      # Generate and upload coverage, even if tests fail\n      - name: Generate coverage report\n        if: always() && inputs.coverage\n        run: npm run test-coverage-generate\n      # https://github.com/marketplace/actions/codecov\n      # https://app.codecov.io/gh/mochajs/mocha\n      - name: Upload coverage reports\n        if: always() && inputs.coverage\n        uses: codecov/codecov-action@v5\n        with:\n          fail_ci_if_error: true\n          use_oidc: true\n"
  },
  {
    "path": ".github/workflows/octoguide.yml",
    "content": "jobs:\n  octoguide:\n    if: ${{ !endsWith(github.actor, '[bot]') }}\n    runs-on: ubuntu-latest\n    steps:\n      - uses: OctoGuide/bot@0.21.10\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n\nname: OctoGuide\n\non:\n  discussion:\n    types: [created, edited]\n  discussion_comment:\n    types: [created, deleted, edited]\n  issue_comment:\n    types: [created, deleted, edited]\n  issues:\n    types: [edited, opened]\n  pull_request_review_comment:\n    types: [created, deleted, edited]\n  pull_request_target:\n    types: [edited, opened]\n\npermissions:\n  discussions: write\n  issues: write\n  pull-requests: write\n"
  },
  {
    "path": ".github/workflows/release-please.yml",
    "content": "name: Release Please\n\non:\n  push:\n    branches:\n      - main\n  workflow_dispatch:\n\npermissions:\n  contents: read\n  id-token: write\n\njobs:\n  release_please:\n    name: release-please\n    runs-on: ubuntu-latest\n    outputs:\n      releaseCreated: ${{ steps.release.outputs.release_created }}\n    permissions:\n      contents: write\n      pull-requests: write\n    steps:\n      - uses: googleapis/release-please-action@v4\n        id: release\n        with:\n          config-file: .github/release-please/config.json\n          manifest-file: .github/release-please/manifest.json\n\n  npm_publish:\n    name: Publish to npm\n    runs-on: ubuntu-latest\n    environment: npm\n    needs: release_please\n    if: needs.release_please.outputs.releaseCreated\n    steps:\n      - uses: actions/checkout@v6\n        with:\n          show-progress: false\n      - uses: actions/setup-node@v6\n        with:\n          node-version: \"22\"\n          registry-url: \"https://registry.npmjs.org\"\n\n      - name: Upgrade npm for OIDC support\n        run: npm install -g npm@latest\n\n      - name: Install dependencies\n        run: npm ci --ignore-scripts --force --no-fund --no-audit\n\n      - run: npm publish --provenance --access public --tag=next\n        env:\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "# Mocha-specific\ndocs/images/supporters\nmocha.js\nmocha.js.map\n.karma/\n!bin/mocha.js\n!lib/mocha.js\n\n# Bundle debugging\nstats.html\n\n#########################################\n# NON-MOCHA STUFF GOES BELOW THIS THING #\n#########################################\n\n# Git mergetool\n# Use `git config mergetool.keepBackup false` to stop generating these files\n*.orig\n\n# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# nyc/istanbul\ncoverage\n.nyc_output\n\n# Dependencies\nnode_modules/\n\n# npm\n.npm\n*.tgz\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# dotenv environment variables file\n.env\n.env.test\n\n# Yarn\nyarn.lock\n.yarn-integrity\n\n# Various temporary files\n*~\n\n# Emacs\n\\#*\\#\n/.emacs.desktop\n/.emacs.desktop.lock\n*.elc\nauto-save-list\ntramp\n.\\#*\n\n# Vim\n[._]*.s[a-v][a-z]\n[._]*.sw[a-p]\n[._]s[a-rt-v][a-z]\n[._]ss[a-gi-z]\n[._]sw[a-p]\nSession.vim\n[._]*.un~\n\n# Diff\n*.patch\n*.diff\n\n# VSCode\n.vscode/\n\n# JetBrains' IDEs\n.idea/\n*.iws\nout/\n.idea_modules/\natlassian-ide-plugin.xml\n\n# SourceTree\n*_BACKUP_*\n*_BASE_*\n*_LOCAL_*\n*_REMOTE_*\n\n# SublimeText\n*.tmlanguage.cache\n*.tmPreferences.cache\n*.stTheme.cache\n*.sublime-workspace\n*.sublime-project\nsftp-config.json\nPackage Control.last-run\nPackage Control.ca-list\nPackage Control.ca-bundle\nPackage Control.system-ca-bundle\nPackage Control.cache/\nPackage Control.ca-certs/\nPackage Control.merged-ca-bundle\nPackage Control.user-ca-bundle\noscrypto-ca-bundle.crt\nbh_unicode_properties.cache\nGitHub.sublime-settings\n\n# direnv\n.envrc\n\n# Linux\n.fuse_hidden*\n.directory\n.Trash-*\n.nfs*\n\n# Windows\nThumbs.db\nehthumbs.db\nehthumbs_vista.db\n*.stackdump\n[Dd]esktop.ini\n$RECYCLE.BIN/\n*.cab\n*.msi\n*.msix\n*.msm\n*.msp\n*.lnk\n\n# macOS\n.DS_Store\n.AppleDouble\n.LSOverride\n._*\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n\n# Local Netlify folder\n.netlify\n"
  },
  {
    "path": ".knip.jsonc",
    "content": "{\n  \"$schema\": \"https://unpkg.com/knip@5/schema-jsonc.json\",\n  \"entry\": [\n    \"bin/mocha.js!\",\n    \"bin/_mocha!\",\n    \"browser-entry.js!\",\n    \"docs/_data/supporters.cjs\",\n    \"index.js!\",\n    \"lib/cli/index.js!\",\n  ],\n  \"project\": [\"{bin,lib,scripts,test}/**/*.{js,ts,mjs,cjs}\"],\n  \"ignore\": [\n    \"test/integration/fixtures/esm/type-module/test-that-imports-non-existing-module.fixture.js\",\n    \"test/integration/fixtures/options/watch/test-with-dependency.fixture.js\",\n  ],\n  \"ignoreDependencies\": [\n    \"@test/esm-only-loader\",\n    \"coffeescript\",\n    \"fake\",\n    \"non-existent-package\",\n  ],\n  \"mocha\": {\n    \"entry\": [\"test/**/*.{js,ts,mjs,cjs}\"],\n  },\n  \"webpack\": {\n    \"config\": \"test/browser-specific/fixtures/webpack/webpack.config.js\",\n  },\n  \"rules\": {\n    \"exports\": \"off\",\n  },\n}\n"
  },
  {
    "path": ".lintstagedrc.json",
    "content": "{\n  \"@(**/*.js|bin/*)\": [\"eslint --fix\"],\n  \"!(package*).json\": [\"prettier --write\"],\n  \"*.{yml,md,html}\": [\"prettier --write\"]\n}\n"
  },
  {
    "path": ".mailmap",
    "content": "# see https://www.git-scm.com/docs/git-check-mailmap for formatting info\nTJ Holowaychuk <tj@vision-media.ca>\nTravis Jeffery <tj@travisjeffery.com> <travisjeffery@gmail.com>\nTravis Jeffery <tj@travisjeffery.com> Dr. Travis Jeffery <tj@travisjeffery.com>\nChristopher Hiller <boneskull@boneskull.com> <chiller@badwing.com>\nDavid da Silva Contín <dasilvacontin@gmail.com> David da Silva <daviddasilvacontin@me.com>\nDavid da Silva Contín <dasilvacontin@gmail.com> David da Silva <dasilvacontin@gmail.com>\nDavid da Silva Contín <dasilvacontin@gmail.com> <daviddasilvacontin@gmail.com>\nAriel Mashraki <ariel@mashraki.co.il> <ariel@codeoasis.com>\nAriel Mashraki <ariel@mashraki.co.il> <ariel.mashraki@ironsrc.com>\nForbes Lindesay <forbes@lindesay.co.uk> <fpfl2@cam.ac.uk>\nBen Bradley <ben@bradleyit.com> <[ben.bradley@cigna.com|mailto:ben.bradley@cigna.com]>\nGlen Mailer <glenjamin@gmail.com> <glen.mailer@bskyb.com>\n38elements <mh19820223@gmail.com> <38elements@users.noreply.github.com>\nAndreas Lind Petersen <andreas@one.com> Andreas Lind <andreas@one.com>\nBen Harris <benhdev@gmail.com> <bdharris08@gmail.com>\nCan Oztokmak <can@zeplin.io> <coztokmak@gmail.com>\nWill Langstroth <will@langstroth.com> <william.langstroth@gmail.com>\nSulabh Bista <sul4bh@gmail.com> <sulabh.bista@makethunder.com>\nRustem Mustafin <mustafin.rustem@gmail.com> <mustafin@kt-labs.com>\nRico Sta. Cruz <rstacruz@users.noreply.github.com> <hi@ricostacruz.com>\nPete Hawkins <pete@petes-imac.frontinternal.net> <pete@phawk.co.uk>\nRaynos <raynos2@gmail.com> <=>\nRaynos <raynos2@gmail.com> Raynos (Jake Verbaten) <raynos2@gmail.com>\nMarkus Tacker <m@coderbyheart.com> <markus@resourceful-humans.com>\nLong Ho <longlho@users.noreply.github.com> <longho@yahoo-inc.com>\nLászló Bácsi <lackac@lackac.hu> Laszlo Bacsi <lackac@lackac.hu>\nEli Skeggs <skeggse@users.noreply.github.com> <skeggse@gmail.com>\nDomenic Denicola <domenic@domenicdenicola.com> domenic <domenic@domenicdenicola.com>\nMichael Schoonmaker <michael.r.schoonmaker@gmail.com> <michael.schoonmaker@redrobotlabs.com>\n"
  },
  {
    "path": ".mocharc.yml",
    "content": "require: \"test/setup\"\nui: \"bdd\"\nglobal:\n  - \"okGlobalA,okGlobalB\"\n  - \"okGlobalC\"\n  - \"callback*\"\ntimeout: 1000\nwatch-ignore:\n  - \".*\"\n  - \"docs/_site/**\"\n  - \"node_modules\"\n  - \"coverage\"\n  - \"cache\"\n"
  },
  {
    "path": ".npmrc",
    "content": "  message=Release v%s"
  },
  {
    "path": ".nycrc",
    "content": "{\n  \"reporter\": [\"json\", \"text-summary\"],\n  \"all\": true,\n  \"exclude\": [\n    \"coverage/**\",\n    \"docs/**\",\n    \"packages/*/test{,s}/**\",\n    \"**/*.d.ts\",\n    \"test{,s}/**\",\n    \"test{,-*}.{js,cjs,mjs,ts}\",\n    \"**/*{.,-}test.{js,cjs,mjs,ts}\",\n    \"**/__tests__/**\",\n    \"**/{karma,rollup,webpack}.config.js\",\n    \"**/{babel.config,.eslintrc,.mocharc}.{js,cjs}\",\n    \"lib/browser/**\",\n    \"package-scripts.js\",\n    \"package-lock.json\",\n    \"**/package-lock.json\",\n    \"node_modules/**\",\n    \"scripts/**\"\n  ]\n}\n"
  },
  {
    "path": ".prettierignore",
    "content": "/.karma/\n/.nyc_output\n/CHANGELOG.md\n/coverage\n/pnpm-lock.yaml\n/test/*/fixtures/**\n\n# release-please generate a compact manifest.json by default\n/.github/release-please/manifest.json\n"
  },
  {
    "path": ".wallaby.js",
    "content": "\"use strict\";\n\nmodule.exports = () => {\n  return {\n    files: [\n      \"index.js\",\n      \"lib/**/*.{js,json}\",\n      \"test/setup.js\",\n      \"test/assertions.js\",\n      {\n        pattern: \"test/node-unit/**/*.fixture.js\",\n        instrument: false,\n      },\n      {\n        pattern: \"test/unit/**/*.fixture.js\",\n        instrument: false,\n      },\n      \"package.json\",\n      \"mocharc.yml\",\n      \"!lib/browser/growl.js\",\n    ],\n    filesWithNoCoverageCalculated: [\n      \"test/**/*.fixture.js\",\n      \"test/setup.js\",\n      \"test/assertions.js\",\n      \"lib/browser/**/*.js\",\n    ],\n    tests: [\"test/unit/**/*.spec.js\", \"test/node-unit/**/*.spec.js\"],\n    env: {\n      type: \"node\",\n      runner: \"node\",\n    },\n    workers: { recycle: true },\n    testFramework: { type: \"mocha\", path: __dirname },\n    setup(wallaby) {\n      // running mocha instance is not the same as mocha under test,\n      // running mocha is the project's source code mocha, mocha under test is instrumented version of the source code\n      const runningMocha = wallaby.testFramework;\n      runningMocha.timeout(1000);\n      // to expose it/describe etc. on the mocha under test\n      const MochaUnderTest = require(\"./\");\n      const mochaUnderTest = new MochaUnderTest();\n      mochaUnderTest.suite.emit(\n        MochaUnderTest.Suite.constants.EVENT_FILE_PRE_REQUIRE,\n        global,\n        \"\",\n        mochaUnderTest,\n      );\n      require(\"./test/setup\");\n    },\n    debug: true,\n    runMode: \"onsave\",\n  };\n};\n"
  },
  {
    "path": "AUTHORS",
    "content": "# Authors ordered by first contribution.\n\nTJ Holowaychuk <tj@vision-media.ca>\nJames Carr <james.r.carr@gmail.com>\nFredrik Lindin <fredriklindin@gmail.com>\nKonstantin Käfer <github@kkaefer.com>\nDavid Henderson <david.henderson@triggeredmessaging.com>\nHarry Brundage <harry.brundage@gmail.com>\nQuang Van <quangvvv@gmail.com>\nhokaccha <k.hokamura@gmail.com>\nGuillermo Rauch <rauchg@gmail.com>\nFARKAS Máté <mate.farkas@virtual-call-center.eu>\nBen Lindsey <ben.lindsey@vungle.com>\nSteve Mason <stevem@brandwatch.com>\nRyunosuke SATO <tricknotes.rs@gmail.com>\nNathan Rajlich <nathan@tootallnate.net>\nRaynos <raynos2@gmail.com>\nYuest Wang <yuestwang@gmail.com>\nMaciej Małecki <maciej.malecki@notimplemented.org>\nJoshua Krall <joshuakrall@pobox.com>\nFedor Indutny <fedor.indutny@gmail.com>\nWill Langstroth <will@langstroth.com>\nAttila Domokos <adomokos@gmail.com>\nJussi Virtanen <jussi.k.virtanen@gmail.com>\nPhil Sung <psung@dnanexus.com>\nvlad <iamvlad@gmail.com>\nPaul Miller <paul@paulmillr.com>\nBjørge Næss <bjoerge@origo.no>\nJeff Kunkle <jeff.kunkle@nearinfinity.com>\nFabio M. Costa <fabiomcosta@gmail.com>\nMichael Riley <michael.riley@autodesk.com>\nIan Young <ian.greenleaf@gmail.com>\nJakub Nešetřil <jakub@apiary.io>\nTyson Tate <tyson@tysontate.com>\nJo Liss <joliss42@gmail.com>\nArian Stolwijk <arian@aryweb.nl>\nBrendan Nee <brendan.nee@gmail.com>\nXavier Antoviaque <xavier@antoviaque.org>\nDomenic Denicola <domenic@domenicdenicola.com>\nBrian Beck <exogen@gmail.com>\nDave McKenna <davemckenna01@gmail.com>\nRichard Dingwall <rdingwall@gmail.com>\nCory Thomas <cory.thomas@bazaarvoice.com>\nR56 <rviskus@gmail.com>\nIan Storm Taylor <ian@ianstormtaylor.com>\nAndreas Brekken <andreas@opuno.com>\nabrkn <a@abrkn.com>\nNathan Bowser <nathan.bowser@spiderstrategies.com>\nLászló Bácsi <lackac@lackac.hu>\nAtsuya Takagi <asoftonight@gmail.com>\nGavin Mogan <GavinM@airg.com>\nfengmk2 <fengmk2@gmail.com>\nSeiya Konno <nulltask@gmail.com>\nJan Lehnardt <jan@apache.org>\nMatt Robenolt <matt@ydekproductions.com>\nJonas Westerlund <jonas.westerlund@me.com>\nKoen Punt <koen@koenpunt.nl>\nJason Barry <jay@jcbarry.com>\nAustin Birch <mraustinbirch@gmail.com>\nAdam Crabtree <adam.crabtree@redrobotlabs.com>\nCasey Foster <casey@caseywebdev.com>\nJonathan Creamer <matrixhasyou2k4@gmail.com>\nBrian Moore <guardbionic-github@yahoo.com>\ntraleig1 <darkphoenix739@gmail.com>\nJohn Firebaugh <john.firebaugh@gmail.com>\nairportyh <airportyh@gmail.com>\nAaron Heckmann <aaron.heckmann+github@gmail.com>\nRuss Bradberry <devdazed@me.com>\nIvan <ivan@kinvey.com>\nCorey Butler <corey@coreybutler.com>\nPaul Armstrong <paul@paularmstrongdesigns.com>\nHerman Junge <herman@geekli.st>\nMichael Schoonmaker <michael.r.schoonmaker@gmail.com>\nWil Moore III <wil.moore@wilmoore.com>\nPete Hawkins <pete@petes-imac.frontinternal.net>\ntgautier@yahoo.com <tgautier@gmail.com>\nyuitest <yuitest@cjhat.net>\nMatt Smith <matthewgarysmith@gmail.com>\nKatie Gengler <katiegengler@gmail.com>\nBryan Donovan <bdondo@gmail.com>\nNathan Alderson <nathan.alderson@adtran.com>\nShawn Krisman <telaviv@github>\nMerrick Christensen <merrick.christensen@gmail.com>\nTimo Tijhof <krinklemail@gmail.com>\nSimon Gaeremynck <gaeremyncks@gmail.com>\nJaakko Salonen <jaakko.salonen@iki.fi>\nJonathan Rajavuori <jrajav@gmail.com>\nForbes Lindesay <forbes@lindesay.co.uk>\nStanda Opichal <opichals@gmail.com>\nMatthew Shanley <matthewshanley@littlesecretsrecords.com>\nJames Lal <james@lightsofapollo.com>\nGreg Perkins <gregperkins@alum.mit.edu>\nGareth Murphy <gareth.cpm@gmail.com>\nJuzer Ali <er.juzerali@gmail.com>\nSasha Koss <koss@nocorp.me>\nJustin DuJardin <justin.dujardin@sococo.com>\nFrederico Silva <frederico.silva@gmail.com>\nJesse Dailey <jesse.dailey@gmail.com>\nYanis Wang <yanis.wang@gmail.com>\nfcrisci <fabio.crisci@amadeus.com>\nJavier Aranda <javierav@javierav.com>\nFlorian Margaine <florian@margaine.com>\nfool2fish <fool2fish@gmail.com>\nJames Bowes <jbowes@repl.ca>\nValentin Agachi <github-com@agachi.name>\nMathieu Desvé <mathieudesve@MacBook-Pro-de-Mathieu.local>\nGlen Huang <curvedmark@gmail.com>\nSimon Goumaz <simon@attentif.ch>\nAlexander Early <alexander.early@gmail.com>\nJimmy Cuadra <jimmy@jimmycuadra.com>\nRussell Munson <rmunson@github.com>\nlodr <salva@unoyunodiez.com>\nLiam Newman <bitwiseman@gmail.com>\nDmitry Shirokov <deadrunk@gmail.com>\nFredrik Enestad <fredrik@devloop.se>\nKirill Korolyov <kirill.korolyov@gmail.com>\ngrasGendarme <me@grasgendar.me>\nMike Pennisi <mike@mikepennisi.com>\nVictor Costan <costan@gmail.com>\nTim Ehat <timehat@gmail.com>\nJeremy Martin <jmar777@gmail.com>\nMal Graty <mal.graty@googlemail.com>\nDi Wu <dwu@palantir.com>\nbadunk <baduncaduncan@gmail.com>\nMarc Kuo <kuomarc2@gmail.com>\nSindre Sorhus <sindresorhus@gmail.com>\nSalehen Shovon Rahman <salehen.rahman@gmail.com>\neiji.ienaga <eiji.ienaga@gmail.com>\nOscar Godson <oscargodson@outlook.com>\nDaniel Stockman <daniel.stockman@gmail.com>\nStephen Mathieson <smath23@gmail.com>\nTravis Jeffery <tj@travisjeffery.com>\nAndreas Lind Petersen <andreas@one.com>\nRomain Prieto <romain.prieto@gmail.com>\nJP Bochi <jpbochi@gmail.com>\nTeddy Zeenny <teddyzeenny@gmail.com>\nRoman Neuhauser <rneuhauser@suse.cz>\nXhmikosR <xhmikosr@users.sourceforge.net>\nBrian Lalor <blalor@bravo5.org>\nRefael Ackermann <refael@empeeric.com>\nChrisWren <cthewren@gmail.com>\nAndrew Nesbitt <andrewnez@gmail.com>\nberni <berni@extensa.pl>\nAndrey Popp <8mayday@gmail.com>\nBrian M. Carlson <brian.m.carlson@gmail.com>\nMichael Olson <mwolson@member.fsf.org>\nArnaud Brousseau <arnaud.brousseau@gmail.com>\nPeter Rust <peter@cornerstonenw.com>\nVadim Nikitin <vnikiti@ncsu.edu>\nRoman Shtylman <shtylman@gmail.com>\nTapiwa Kelvin <tapiwa@munzwa.tk>\nRustem Mustafin <mustafin.rustem@gmail.com>\nGlen Mailer <glenjamin@gmail.com>\nNathan Black <nathan@nathanblack.org>\nsebv <seb.vincent@gmail.com>\nandy matthews <andy@commadelimited.com>\nBenjie Gillam <benjie@jemjie.com>\nNoshir Patel <nosh@blackpiano.com>\nBen Noordhuis <info@bnoordhuis.nl>\nJacob Wejendorp <jacob@wejendorp.dk>\nclaudyus <claudyus@HEX.(none)>\nDenis Bardadym <bardadymchik@gmail.com>\nConnor Dunn <connorhd@gmail.com>\nJonathan Ong <jonathanrichardong@gmail.com>\nHarish <hyeluri@gmail.com>\nMichal Charemza <michalcharemza@gmail.com>\nstartswithaj <jake.mc@icloud.com>\nGareth Aye <gaye@mozilla.com>\nNick Fitzgerald <fitzgen@gmail.com>\nJan Kopriva <jan.kopriva@gooddata.com>\nkavun <kevin.a.reed@gmail.com>\nChristoffer Hallas <christoffer.hallas@gmail.com>\nJonathan Park <jpark@daptiv.com>\nDevin Weaver <suki@tritarget.org>\nJohn Doty <jrhdoty@gmail.com>\nShaine Hatch <shaine@squidtree.com>\nBen Bradley <ben@bradleyit.com>\nqiuzuhui <qiuzuhui@users.noreply.github.com>\nJean Ponchon <gelule@gmail.com>\nLinus Unnebäck <linus@folkdatorn.se>\nMattias Tidlund <mattias.tidlund@learningwell.se>\nMatija Marohnić <matija.marohnic@gmail.com>\nMichael Jackson <mjijackson@gmail.com>\nJoel Kemp <mrjoelkemp@gmail.com>\nZsolt Takács <zsolt@takacs.cc>\njsdevel <js.developer.undefined@gmail.com>\nlakmeer <lakmeerkravid@gmail.com>\nJoshua Appelman <jappelman@xebia.com>\nChristopher Hiller <boneskull@boneskull.com>\nMichael Demmer <demmer@jut.io>\nGiovanni Bassi <giggio@giggio.net>\nPanu Horsmalahti <panu.horsmalahti@iki.fi>\nnishigori <Takuya_Nishigori@voyagegroup.com>\nNicolo Taddei <taddei.uk@gmail.com>\nDiogo Monteiro <diogo.gmt@gmail.com>\nmrShturman <mrshturman@gmail.com>\nPoppinL <poppinlp@gmail.com>\nsamuel goldszmidt <samuel.goldszmidt@gmail.com>\nRob Wu <rob@robwu.nl>\nKent C. Dodds <kent+github@doddsfamily.us>\nKevin Conway <kevinjacobconway@gmail.com>\nDominique Quatravaux <dominique@quatravaux.org>\nzhiyelee <zhiyelee@gmail.com>\nQuanlong He <kyan.ql.he@gmail.com>\nomardelarosa <thedelarosa@gmail.com>\nAriel Mashraki <ariel@mashraki.co.il>\nSean Lang <slang800@gmail.com>\nDavid da Silva Contín <dasilvacontin@gmail.com>\nC. Scott Ananian <cscott@cscott.net>\nDouglas Christopher Wilson <doug@somethingdoug.com>\nRichard Knop <RichardKnop@users.noreply.github.com>\nBuck Doyle <b@chromatin.ca>\nJonas Dohse <jonas@mbr-targeting.com>\noveddan <stangogh@gmail.com>\nmonowerker <monowerker@gmail.com>\nMarcello Bastea-Forte <marcello@cellosoft.com>\nBenoît Zugmeyer <bzugmeyer@gmail.com>\nVlad Magdalin <vlad@webflow.com>\nMoshe Kolodny <mkolodny@integralads.com>\nTom Coquereau <tom@thau.me>\nTimothy Gu <timothygu99@gmail.com>\nIan Zamojc <ian@thesecretlocation.net>\nMartin Marko <marcus@gratex.com>\nChris Buckley <chris@cmbuckley.co.uk>\nJake Craige <james.craige@gmail.com>\nFede Ramirez <i@2fd.me>\nParker Moore <parkrmoore@gmail.com>\nTodd Agulnick <tagulnick@onjack.com>\nDaniel St. Jules <danielst.jules@gmail.com>\nRico Sta. Cruz <rstacruz@users.noreply.github.com>\nAnis Safine <anis.safine.ext@francetv.fr>\nAdam Gruber <talknmime@gmail.com>\nSam Mussell <smussell@gmail.com>\nklaemo <klaemo@fastmail.fm>\nStewart Taylor <stewart.taylor1@gmail.com>\nJordan Sexton <jordan@jordansexton.com>\nKeith Cirkel <github@keithcirkel.co.uk>\nAndrii Shumada <eagleeyes91@gmail.com>\nDominic Barnes <dominic@dbarnes.info>\nMaximilian Antoni <mail@maxantoni.de>\nSune Simonsen <sune@we-knowhow.dk>\nKyle Mitchell <kyle@kemitchell.com>\nJames Nylen <jnylen@gmail.com>\nJonathan Delgado <jdelgado@rewip.com>\nJake Marsh <jakemmarsh@gmail.com>\nslyg <syl.faucherand@gmail.com>\nTomer Eskenazi <tomer.eskenazi@ironsrc.com>\nJeff Schilling <jeff.schilling@q2ebanking.com>\nRyan Hubbard <ryanmhubbard@gmail.com>\namsul <reach@amsul.ca>\nKevin Kirsche <Kev.Kirsche+GitHub@gmail.com>\nGabriel Silk <gabesilk@gmail.com>\nJohnathon Sanders <outdooricon@gmail.com>\nMax Goodman <c@chromakode.com>\nNathan Houle <nathan@nathanhoule.com>\nBen Vinegar <ben@benv.ca>\nDuncan Beevers <duncan@dweebd.com>\nTingan Ho <tingan87@gmail.com>\nGuy Arye <arye.guy@gmail.com>\nNik Nyby <nnyby@columbia.edu>\nArtem Govorov <artem.govorov@gmail.com>\nAjay Kodali <ajay.kodali@citrix.com>\nRyan Tablada <ryan.tablada@gmail.com>\nPavel Zubkou <pavel.zubkou@gmail.com>\ngigadude <gigadude@users.noreply.github.com>\nOutsider <outsideris@gmail.com>\nJason Lai <jason@getpebble.com>\nAaron Krause <aaronjkrause@gmail.com>\nwsw <wsw0108@gmail.com>\nKevin Burke <kev@inburke.com>\nBerker Peksag <berker.peksag@gmail.com>\nnexdrew <andrew.goode@nextraq.com>\nHugo Giraudel <hugo.giraudel@gmail.com>\nRich Trott <rtrott@gmail.com>\nMatt Giles <matt.giles@cerner.com>\nJoey Cozza <joey@grow.com>\nKris Rasmussen <kristopher.rasmussen@gmail.com>\nJames G. Kim <jgkim@jayg.org>\nSorin Iclanzan <sorin@iclanzan.com>\nRob Raux <rraux@peachworks.com>\nSergey Simonchik <sergey.simonchik@jetbrains.com>\nIan W. Remmel <design@ianwremmel.com>\ntmont <tommy.mont@gmail.com>\nJohn Reeves <github@jonnyreeves.co.uk>\nFagner Brack <github3@fagnermartins.com>\nMark Banner <standard8@mozilla.com>\nMichiel de Jong <michiel@unhosted.org>\nBenoit Larroque <zeta.ben@gmail.com>\nCharles Lowell <cowboyd@frontside.io>\nJoao Moreno <mail@joaomoreno.com>\nLong Ho <longlho@users.noreply.github.com>\nRobert Rossmann <rr.rossmann@me.com>\nAaron Hamid <aaron.hamid@gmail.com>\nStone <baoshi.li@adleida.com>\nTom Hughes <tom@compton.nu>\nSoel <shachar.soel@sap.com>\nMislav Marohnić <mislav.marohnic@gmail.com>\nPrayag Verma <prayag.verma@gmail.com>\nFrank Leon Rose <frankleonrose@gmail.com>\nRyan Shaw <ryan.shaw@min.vc>\nThedark1337 <thedark1337@thedark1337.com>\nGyandeep Singh <gyandeeps@gmail.com>\nryym <ryym.64@gmail.com>\nJosh Lory <josh.lory@code.org>\nJonathan Kim <jkimbo@gmail.com>\nAl Scott <al.scott@atomicobject.com>\nTobias Bieniek <tobias.bieniek@gmail.com>\nBenjamin Eidelman <beneidel@gmail.com>\nJulien Wajsberg <felash@gmail.com>\nsarehag <joakim.sarehag@gmail.com>\nAlexander Shepelin <Brightcor@gmail.com>\nOlegTsyba <oleg.tsyba.ua@gmail.com>\nXavier Damman <xdamman@gmail.com>\nMick Brooks <mick.brooks@sinking.in>\nErik Eng <mail@ptz0n.se>\nKelong Wang <buaawkl@gmail.com>\nJérémie Astori <jeremie@astori.fr>\nScottFreeCode <ScottFreeCode@users.noreply.github.com>\nSergio Santoro <santoro.srg@gmail.com>\nAdrian Ludwig <me@adrianludwig.pl>\nAnders Olsen Sandvik <Andersos@users.noreply.github.com>\nThomas Grainger <tagrain@gmail.com>\njimenglish81 <jimenglish81@gmail.com>\nAvi Vahl <avi.vahl@wix.com>\nJason Leyba <jmleyba@gmail.com>\nsilentcloud <rjmuqiang@gmail.com>\nDmitriy Simushev <simushevds@gmail.com>\nsimov <simeonvelichkov@gmail.com>\nRoss Warren <rosswarren4@gmail.com>\nBenson Trent <bensontrent@gmail.com>\nrmacklin <richard.github@nrm.com>\nRob Loach <robloach@gmail.com>\nShinnosuke Watanabe <snnskwtnb@gmail.com>\nCallum Macrae <callum@macr.ae>\nELLIOTTCABLE <me@ell.io>\nAnton <anton.redfox@gmail.com>\nPeter Müller <munter@fumle.dk>\nAPerson <danielhglus@gmail.com>\nnot-an-aardvark <not-an-aardvark@users.noreply.github.com>\nAlhadis <gardnerjohng@gmail.com>\nSlobodan Mišković <slobodan@miskovic.ca>\nPhilip M. White <philip@mailworks.org>\nChristian <me@rndm.de>\nanton <anton.valickij@gmail.com>\nDmitry Sorin <info@staypositive.ru>\nVivek Ganesan <caliberoviv@gmail.com>\nJosh Eversmann <josh.eversmann@gmail.com>\ninxorable <inxorable@codewren.ch>\nBen Harris <benhdev@gmail.com>\nAaron Petcoff <hello@aaronpetcoff.me>\nMatt Bierner <mattbierner@gmail.com>\nVille Saukkonen <villesau@users.noreply.github.com>\nBen Hutchison <ben@aldaviva.com>\nVolker Buzek <volker.buzek@sap.com>\nScott Kao <Scottkao85@users.noreply.github.com>\nSulabh Bista <sul4bh@gmail.com>\nrotemdan <rotemdan@gmail.com>\nFumiaki MATSUSHIMA <mtsmfm@gmail.com>\nMarkus Tacker <m@coderbyheart.com>\nChristoph Neuroth <christoph.neuroth@gmail.com>\nEnric Pallerols <enric@pallerols.cat>\nCraig Taub <craigtaub@gmail.com>\nYoshiya Hinosawa <hinosawa@waku-2.com>\nSebastian Van Sande <sebastian@vansande.org>\nChris Lamb <chris@chris-lamb.co.uk>\nIgwe Kalu <igwe.kalu@live.com>\nKevin Wang <kevin@fossa.io>\nLaurence Rowe <lrowe@netflix.com>\nJakob Krigovsky <jakob@krigovsky.com>\nChris <chrisleck@users.noreply.github.com>\nKunal Nagpal <kunagpal@users.noreply.github.com>\nelergy <elergy@yandex-team.ru>\nJupp Müller <jupp0r@gmail.com>\nPoprádi Árpád <popradi.arpad11@gmail.com>\nCharlie Rudolph <charles.w.rudolph@gmail.com>\nAngelica Valenta <angelicavalenta@gmail.com>\nJan Krems <jan.krems@groupon.com>\nJosh Soref <jsoref@users.noreply.github.com>\nsolodynamo <bittuf3@gmail.com>\nEli Skeggs <skeggse@users.noreply.github.com>\nNikolaos Georgiou <Nikolaos.Georgiou@gmail.com>\nolsonpm <olsonpm@users.noreply.github.com>\nDavid Neubauer <davidneub@gmail.com>\nDarryl Pogue <dvpdiner2@gmail.com>\n38elements <mh19820223@gmail.com>\nGuangcong Luo <guangcongluo@gmail.com>\nDavid M. Lee <leedm777@yahoo.com>\ntripu <t@tripu.info>\nPat Finnigan <patrick.k.finnigan@gmail.com>\nEugene Tiutiunnyk <eugene.tiutiunnyk@lookout.com>\nAaron Brady <aaron@mori.com>\nCharles Merriam <charles.merriam@gmail.com>\nKevin Partington <platinum.azure@kernelpanicstudios.com>\nLane Kelly <lanekelly16@gmail.com>\nCube <maty21@gmail.com>\nyehiyam <yehiyam@users.noreply.github.com>\nJon Surrell <jon.surrell@automattic.com>\n现充 <qixiang.cqx@alibaba-inc.com>\nAhmad Bamieh <ahmadbamieh@gmail.com>\nCapacitor Set <CapacitorSet@users.noreply.github.com>\nAnthony <keppi@o2.pl>\nCan Oztokmak <can@zeplin.io>\nImgBot <31427850+ImgBotApp@users.noreply.github.com>\nThomas Broadley <buriedunderbooks@hotmail.com>\nFND <FND@users.noreply.github.com>\nDina Berry <dfberry@users.noreply.github.com>\nMarais Rossouw <me@maraisr.com>\nAndrew Krawchyk <903716+akrawchyk@users.noreply.github.com>\nTed Yavuzkurt <hello@TedY.io>\nDaniel Ruf <daniel@daniel-ruf.de>\nHarry Wolff <hswolff@users.noreply.github.com>\nValeri Karpov <val@karpov.io>\nSilvio Massari <silvio.massari@auth0.com>\nJoseph Lin <josephlin55555@gmail.com>\nHonza Javorek <mail@honzajavorek.cz>\nHarry Sarson <harry.sarson@hotmail.co.uk>\nAnish Karandikar <anishkny@gmail.com>\nVictor <victor@turo.com>\nEmanuele <my.burning@gmail.com>\nThomas Vantuycom <thomasvantuycom@protonmail.com>\nAlex Bainter <metalex9@users.noreply.github.com>\nJerry Muzsik <jerrymuzsik@icloud.com>\nNicolas Girault <nic.girault@gmail.com>\ndfberry <dinaberry@outlook.com>\nDavNej <davnej.dev@gmail.com>\nPaul Roebuck <plroebuck@users.noreply.github.com>\nTim Harshman <goteamtim+git@gmail.com>\nCharles Samborski <demurgos@demurgos.net>\nTobias Mollstam <tobias@mollstam.com>\nBen Glassman <benglass@users.noreply.github.com>\nMark Owsiak <mark.owsiak@gmail.com>\nfargies <fargies@users.noreply.github.com>\nMarc Udoff <mlucool@gmail.com>\ngizemkeser <44727928+gizemkeser@users.noreply.github.com>\nFin Chen <finfin@gmail.com>\nBrittany Moore <moore.brittanyann@gmail.com>\nFábio Santos <fabiosantosart@gmail.com>\nJayasankar <jayasankar.m@gmail.com>\nJuerg B <44573692+juergba@users.noreply.github.com>\nSvetlana <39729453+Lana-Light@users.noreply.github.com>\nMartijn Cuppens <martijn.cuppens@intracto.com>\nAnna Henningsen <github@addaleax.net>\nAndreas Lind <andreaslindpetersen@gmail.com>\nChen Yangjian <252317+cyjake@users.noreply.github.com>\nCorey Farrell <git@cfware.com>\nWanseob Lim <email@wanseob.com>\nSzauka <33459309+Szauka@users.noreply.github.com>\nBrian Tomlin <tendonstrength@gmail.com>\nSylvain <sstephant+github@gmail.com>\nAdam Ginzberg <aginzberg@gmail.com>\nXhmikosR <xhmikosr@gmail.com>\nGastón I. Silva <givanse@gmail.com>\nAndrew Bradley <cspotcode@gmail.com>\nAndrew Bradley <abradley@brightcove.com>\nDavidLi119 <han.david.li@gmail.com>\nJames D. Rogers <jd2rogers2@gmail.com>\nCarl-Erik Kopseng <carlerik@gmail.com>\njuergba <filodron@gmail.com>\nSylvester Keil <sylvester@keil.or.at>\nBjorn Stromberg <bjorn@bjornstar.com>\nStephen Hess <trescube@users.noreply.github.com>\ntoyjhlee <toyjhlee@gmail.com>\nPiotr Kuczynski <piotr.kuczynski@gmail.com>\nThomas Scholtes <thomas-scholtes@gmx.de>\nBrian Lagerman <49239617+brian-lagerman@users.noreply.github.com>\nPascal <pascal@pascal.com>\nGabe Gorelick <gabegorelick@gmail.com>\nDaniel Ruf <827205+DanielRuf@users.noreply.github.com>\nMario Díaz Ceñera <46492068+MarioDiaz98@users.noreply.github.com>\nOliver Salzburg <oliver.salzburg@gmail.com>\nSona Lee <mojosoeun@gmail.com>\nPark Seong-beom <parkgds@gmail.com>\nEunChan Park <pec9399@naver.com>\nMia <miajeongdev@gmail.com>\nLindsay-Needs-Sleep <51773923+Lindsay-Needs-Sleep@users.noreply.github.com>\nSoobin Bak <qls014738@gmail.com>\nPeter Schmidt <peter@peterjs.com>\nSheetJSDev <dev@sheetjs.com>\nHyunSangHan <gustkd3@gmail.com>\nJan-Philip Gehrcke <jgehrcke@googlemail.com>\nRobert Kieffer <robert@broofa.com>\nSaerom Bang <saerombang11@gmail.com>\nKyle Fuller <kyle@fuller.li>\nRens Groothuijsen <l.groothuijsen@alumni.maastrichtuniversity.nl>\nHugo Kim <k7120792@gmail.com>\nKyoungWan <kyngwan@gmail.com>\nZirak <zirakertan@gmail.com>\nChristian Holm <christian@peakon.com>\nKai Cataldo <kai@kaicataldo.com>\nGil Tayar <gil.tayar@applitools.com>\nUlises Gascón <UlisesGascon@users.noreply.github.com>\nkundol <jhc9639@naver.com>\nArvid Ottenberg <arvid.ottenberg@gmx.de>\nDaniel0113 <Daniel.febles97@gmail.com>\nNico Jansen <jansennico@gmail.com>\nJacobLey <37151850+JacobLey@users.noreply.github.com>\nGil Tayar <gil@tayar.org>\nMartin Oppitz <github@martinoppitz.com>\nBenjamin E. Coe <bencoe@google.com>\nMichael Brade <brade@kde.org>\nGopishankar Haridas <gopi.shanky@gmail.com>\ndevjeel <jeelhp02@gmail.com>\nMartin Oppitz <martinoppitz@users.noreply.github.com>\nindieisaconcept <me@indieisaconcept.com>\nSri Harsha <sri_harsha509@hotmail.com>\nirrationnelle <drakkarverenis@gmail.com>\nDonghoon Song <32301380+Donghoon759@users.noreply.github.com>\nSujin Park <psujin831@gmail.com>\nKIM HYO RIN <wwhurin0515@gmail.com>\nChuf <42591821+GChuf@users.noreply.github.com>\nDonghoon Song <thdehdgns@gmail.com>\nEvaline Ju <evalineju@gmail.com>\nPark Juhyung <jh@majecty.com>\nFrançois Hodierne <francois@hodierne.net>\nEvaline Ju <69598118+evaline-ju@users.noreply.github.com>\nValeria <valeria.viana.gusmao@gmail.com>\nJordan Stephens <jordan@stephens.io>\nAdam Keating <1427265+akeating@users.noreply.github.com>\nHazem <devhazemhassanin@gmail.com>\nJosé Jesús Sinohui Fernández <josejesinohui@gmail.com>\nMaxwell Gerber <mgerber@berkeley.edu>\nSebastian Noack <sebastian.noack@gmail.com>\nChristian Bromann <github@christian-bromann.com>\nAlexander Fenster <github@fenster.name>\nMoonSupport <jiwon3346@naver.com>\nDayzen <syeuty@naver.com>\nAlexander Fenster <fenster@google.com>\nkirill-golovan <57108967+kirill-golovan@users.noreply.github.com>\nMichal Dorner <dorner.michal@gmail.com>\nCurtis Man <curtism@microsoft.com>\n华 <1395348685z@gmail.com>\nAndrei Rusu <beatfactor@users.noreply.github.com>\nQuentin Barbe <forty@everteam.org>\nMattias Norlander <mattias.norlander@gmail.com>\nCommanderRoot <CommanderRoot@users.noreply.github.com>\nElihu Cruz <elihuacruz@gmail.com>\nSukka <isukkaw@gmail.com>\nDarius Dzien <ddzien2@gmail.com>\nYeting Li <liyt@ios.ac.cn>\nGreggman <github@greggman.com>\nJosh Goldberg <git@joshuakgoldberg.com>\nKleis Auke Wolthuizen <github@kleisauke.nl>\nPaulo Gonçalves <github@paulog.dev>\nAnton Usmansky <anton.usmansky@gmail.com>\njb2311 <32516995+jb2311@users.noreply.github.com>\nAras Abbasi <aras.abbasi@googlemail.com>\nSpencer <16455389+Spencer-Doak@users.noreply.github.com>\nFeng Yu <F3n67u@outlook.com>\nPelle Wessman <pelle@kodfabrik.se>\nOrgad Shaneh <orgads@gmail.com>\nLucas Lopes <lucasaferrlopes@gmail.com>\nBryan Mishkin <698306+bmish@users.noreply.github.com>\nVille Lahdenvuo <tuhoojabotti@gmail.com>\nNathan Phillip Brink <ohnobinki@ohnopublishing.net>\nStåle Tomten <stale.tomten@finn.no>\ndependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>\nSleepy Flower <wuhao64@gmail.com>\nStevenMia <166844090+StevenMia@users.noreply.github.com>\nSimon Hanna <33220646+simhnna@users.noreply.github.com>\nIlia Choly <ilia.choly@gmail.com>\nMarjorie Saito <marjorieysaito@gmail.com>\nKhoa Huynh <58313491+khoaHyh@users.noreply.github.com>\nSam Adams <107990625+sam-super@users.noreply.github.com>\nMarc Durdin <marc@durdin.net>\nIlya Goncharov <ilgonmic@gmail.com>\ngithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>\nMark Wiemer <7833360+mark-wiemer@users.noreply.github.com>\nDanny Lin <danny0838@gmail.com>\nKristján Oddsson <hi@koddsson.com>\nDavid Huggins-Daines <dhd@ecolingui.ca>\nJoy Dey <joydey@gmail.com>\nJulian Grinblat <julian@dotcore.co.il>\nLinda_pp <rhysd@users.noreply.github.com>\nEric Cornelissen <ericornelissen@gmail.com>\nKelechi Ebiri <56020538+TG199@users.noreply.github.com>\nDinika <dinika@greyllama.cc>\nKevin Locke <kevin@kevinlocke.name>\nPhillip Barta <barta.phillip@gmail.com>\nGrzegorz Godlewski <gg@gitgis.com>\nDarren DeRidder <73rhodes@users.noreply.github.com>\nChengzhong Wu <legendecas@gmail.com>\nMarcelo Shima <marceloshima@gmail.com>\nChengzhong Wu <cwu631@bloomberg.net>\nSamuel Henrique <samosaara@gmail.com>\nMark Wiemer <markwiemer@outlook.com>\nMartin Slota <46676886+martinslota@users.noreply.github.com>\n\n# Generated by scripts/update-authors.js\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\n## [12.0.0-beta-10](https://github.com/mochajs/mocha/compare/v12.0.0-beta-9...v12.0.0-beta-10) (2026-02-21)\n\n\n### 🌟 Features\n\n* remove Sauce Labs ([#5700](https://github.com/mochajs/mocha/issues/5700)) ([625c34e](https://github.com/mochajs/mocha/commit/625c34e8469562dbde8440c2b4d64e820f7019fa))\n\n\n### 🩹 Fixes\n\n* change Pending to properly extend Error ([#5679](https://github.com/mochajs/mocha/issues/5679)) ([158effd](https://github.com/mochajs/mocha/commit/158effd7de677c21b3a4ccd79ce0879fe0f97f8b))\n* **deps:** update dependency chokidar to v5 ([#5734](https://github.com/mochajs/mocha/issues/5734)) ([ff2f17f](https://github.com/mochajs/mocha/commit/ff2f17fb25e5001420d48035f81f5b19a5f0974f))\n* **deps:** update dependency minimatch to v10 ([#5743](https://github.com/mochajs/mocha/issues/5743)) ([3f3e449](https://github.com/mochajs/mocha/commit/3f3e449f889cb2ddcf950e7bf2268091000b9f7c))\n* **deps:** update dependency starlight-package-managers to ^0.12.0 ([#5717](https://github.com/mochajs/mocha/issues/5717)) ([aa4ba48](https://github.com/mochajs/mocha/commit/aa4ba483a4a25f5dfc36334439caf2b8935874d2))\n\n\n### 📚 Documentation\n\n* fix client redirects ([#5697](https://github.com/mochajs/mocha/issues/5697)) ([dd9145d](https://github.com/mochajs/mocha/commit/dd9145dd9c5a684aa918ca5ed10155293df2bb91)), closes [#5696](https://github.com/mochajs/mocha/issues/5696)\n\n\n### 🧹 Chores\n\n* Configure Renovate ([#5678](https://github.com/mochajs/mocha/issues/5678)) ([a9c9b90](https://github.com/mochajs/mocha/commit/a9c9b90098a831d82e69d82bfc7ce8c7aa749911))\n* **deps:** update dependency @rollup/plugin-alias to v6 ([#5718](https://github.com/mochajs/mocha/issues/5718)) ([267d751](https://github.com/mochajs/mocha/commit/267d751dd05270de4e18e0348584fbb12d90ce04))\n* **deps:** update dependency @rollup/plugin-commonjs to v29 ([#5719](https://github.com/mochajs/mocha/issues/5719)) ([9ed4ee5](https://github.com/mochajs/mocha/commit/9ed4ee55d975281ea54f237d23666d7b0307a596))\n* **deps:** update dependency astro to v5.17.1 ([#5703](https://github.com/mochajs/mocha/issues/5703)) ([ec3d1fa](https://github.com/mochajs/mocha/commit/ec3d1fa02e285a4430942942c11c376e63d395ca))\n* **deps:** update dependency chai to v4.5.0 ([#5705](https://github.com/mochajs/mocha/issues/5705)) ([870f9f8](https://github.com/mochajs/mocha/commit/870f9f8df7d1f9cace40bfc29a9b5b79a26ccb4e))\n* **deps:** update dependency cross-env to v10 ([#5721](https://github.com/mochajs/mocha/issues/5721)) ([20b7476](https://github.com/mochajs/mocha/commit/20b7476904592b356a48c3f89817e930c78f15cb))\n* **deps:** update dependency knip to v5.83.1 ([#5708](https://github.com/mochajs/mocha/issues/5708)) ([d833413](https://github.com/mochajs/mocha/commit/d833413622807c91cc2dea243c2be3518e2fe10b))\n* **deps:** update dependency npm-run-all2 to v8 ([#5727](https://github.com/mochajs/mocha/issues/5727)) ([e38e0ec](https://github.com/mochajs/mocha/commit/e38e0ec3dd91be11b2b999959e6245ec721168e3))\n* **deps:** update dependency prettier to v3.8.1 ([#5709](https://github.com/mochajs/mocha/issues/5709)) ([2f98cfd](https://github.com/mochajs/mocha/commit/2f98cfd1e3e9fce8a3c1a645f99a6b4b3b69ea6c))\n* **deps:** update dependency rimraf to v6 ([#5728](https://github.com/mochajs/mocha/issues/5728)) ([ba124e9](https://github.com/mochajs/mocha/commit/ba124e9161e5efd052df77dda50925c5666ccd6d))\n* **deps:** update dependency rollup to v4.57.1 ([#5710](https://github.com/mochajs/mocha/issues/5710)) ([178749d](https://github.com/mochajs/mocha/commit/178749da1bee978b5ef109a253337ae88206365c))\n* **deps:** update dependency unexpected-map to v3 ([#5736](https://github.com/mochajs/mocha/issues/5736)) ([c1f3379](https://github.com/mochajs/mocha/commit/c1f33798ab925c76c5f9a69dcb8c1ce71da2fbc9))\n* **deps:** update dependency unist-util-visit to v5.1.0 ([#5711](https://github.com/mochajs/mocha/issues/5711)) ([7ede894](https://github.com/mochajs/mocha/commit/7ede8943ff8f7925b51d4e4a226ee76b0a77619d))\n* **deps:** update dependency webdriverio to v9 ([#5739](https://github.com/mochajs/mocha/issues/5739)) ([ff334df](https://github.com/mochajs/mocha/commit/ff334df744c93f27c7cce08ced320833ee69cb2f))\n* **deps:** update dependency webpack-cli to v6 ([#5741](https://github.com/mochajs/mocha/issues/5741)) ([95c9d75](https://github.com/mochajs/mocha/commit/95c9d75120078e4c1fbb87d23f4fd7ec1f8a5405))\n* **deps:** update dependency workerpool to v9.3.4 ([#5715](https://github.com/mochajs/mocha/issues/5715)) ([c030a3b](https://github.com/mochajs/mocha/commit/c030a3bd4774db679ac8dc7d56e705975f1a1b6e))\n* **deps:** update remark ([#5745](https://github.com/mochajs/mocha/issues/5745)) ([37a25f1](https://github.com/mochajs/mocha/commit/37a25f174e6f3f16cae34923b86ab7d2504985ce))\n* fix timeout issue with some XUnit tests ([53cc467](https://github.com/mochajs/mocha/commit/53cc46755571ed53e32254fb7d896f599a1a7d1f))\n* switch Suite from util.inherits to ES2015 classes ([#5179](https://github.com/mochajs/mocha/issues/5179)) ([1ce690e](https://github.com/mochajs/mocha/commit/1ce690e590ca7bff7f47b108d3a5cc61dde6aa1b))\n\n\n### 🤖 Automation\n\n* **deps:** bump OctoGuide/bot in the github-actions group ([#5724](https://github.com/mochajs/mocha/issues/5724)) ([87224d8](https://github.com/mochajs/mocha/commit/87224d8400fa3b074f77a8ba1baadf7e0b99d864))\n* run `npm audit fix` ([#5695](https://github.com/mochajs/mocha/issues/5695)) ([c7b00b0](https://github.com/mochajs/mocha/commit/c7b00b0e4f03583c4dcc407f28a5453df436f32b))\n\n## [12.0.0-beta-9](https://github.com/mochajs/mocha/compare/v12.0.0-beta-8...v12.0.0-beta-9) (2026-02-13)\n\n\n### 🌟 Features\n\n* remove `log-symbols` dependency ([#5469](https://github.com/mochajs/mocha/issues/5469)) ([b92168f](https://github.com/mochajs/mocha/commit/b92168f5625be7343fb94d458d8a055cca8ff0a4))\n\n## [12.0.0-beta-8](https://github.com/mochajs/mocha/compare/v12.0.0-beta-7...v12.0.0-beta-8) (2026-02-06)\n\n\n### 🧹 Chores\n\n* use OIDC to publish to npm ([#5681](https://github.com/mochajs/mocha/issues/5681)) ([5567aed](https://github.com/mochajs/mocha/commit/5567aed50a00b63074d5c7703c6d8196dee92088))\n\n## [12.0.0-beta-7](https://github.com/mochajs/mocha/compare/v12.0.0-beta-6...v12.0.0-beta-7) (2026-02-03)\n\n\n### 🩹 Fixes\n\n* bump diff dependency to ^8.0.3 ([#5674](https://github.com/mochajs/mocha/issues/5674)) ([15fb31a](https://github.com/mochajs/mocha/commit/15fb31a8b25a4d03242e5c5f901ff3800889263e))\n* print helpful message when internal CLI error happens ([#5344](https://github.com/mochajs/mocha/issues/5344)) ([1e11836](https://github.com/mochajs/mocha/commit/1e118367dbb27f558edb7389985cca97d6d7da4b))\n\n\n### 📚 Documentation\n\n* update sponsor image to be larger ([#5659](https://github.com/mochajs/mocha/issues/5659)) ([bbe2bdb](https://github.com/mochajs/mocha/commit/bbe2bdbb69f7aa560645a5ab2cbd596dd0b43448))\n\n\n### 🧹 Chores\n\n* move nyc config changes from package.json into .nycrc ([#5668](https://github.com/mochajs/mocha/issues/5668)) ([e923e40](https://github.com/mochajs/mocha/commit/e923e4063f6a24dcaf7c6d7c7a3c8be998cb7980))\n* remove extra newline ([bbe2bdb](https://github.com/mochajs/mocha/commit/bbe2bdbb69f7aa560645a5ab2cbd596dd0b43448))\n\n## [12.0.0-beta-6](https://github.com/mochajs/mocha/compare/v12.0.0-beta-5...v12.0.0-beta-6) (2026-01-23)\n\n\n### 🩹 Fixes\n\n* allow chain call timeout to override nested items timeout ([#5612](https://github.com/mochajs/mocha/issues/5612)) ([5525da6](https://github.com/mochajs/mocha/commit/5525da60cf8d2596e14ff5441ea518d47bd732da))\n* import() fallback prevention ([#5647](https://github.com/mochajs/mocha/issues/5647)) ([6a78fa3](https://github.com/mochajs/mocha/commit/6a78fa39576ffb42700811661a94c9ac996707f2))\n\n\n### 🤖 Automation\n\n* **deps:** bump OctoGuide/bot in the github-actions group ([#5653](https://github.com/mochajs/mocha/issues/5653)) ([e06cce7](https://github.com/mochajs/mocha/commit/e06cce7a49b79a163e33db166e9b078b0d7b4001))\n\n## [12.0.0-beta-5](https://github.com/mochajs/mocha/compare/v12.0.0-beta-4...v12.0.0-beta-5) (2026-01-16)\n\n\n### 🌟 Features\n\n* add --fail-hook-affected-tests option to report skipped tests as failed ([#5519](https://github.com/mochajs/mocha/issues/5519)) ([0ed524a](https://github.com/mochajs/mocha/commit/0ed524af347b59200e03b972c2450d36f6818a45))\n\n\n### 📚 Documentation\n\n* add missing /next/* redirects ([#5627](https://github.com/mochajs/mocha/issues/5627)) ([8fa183d](https://github.com/mochajs/mocha/commit/8fa183d592b29346901b55e2fa479c8f598a1ec3))\n\n\n### 🧹 Chores\n\n* cleanup issue templates ([#5624](https://github.com/mochajs/mocha/issues/5624)) ([1972dd7](https://github.com/mochajs/mocha/commit/1972dd76ec66e8e11532bb6aca9157c4f8892d3c))\n* remove unused assets folder ([#5638](https://github.com/mochajs/mocha/issues/5638)) ([ddf8644](https://github.com/mochajs/mocha/commit/ddf864482ff66b1ca46ef7f08e63ca923222e717))\n* update spam filter ([#5645](https://github.com/mochajs/mocha/issues/5645)) ([cf945fb](https://github.com/mochajs/mocha/commit/cf945fb73b7c5a74f0856cabca5b5b1c8a6ff1c8))\n* update tagline ([#5635](https://github.com/mochajs/mocha/issues/5635)) ([8ff0209](https://github.com/mochajs/mocha/commit/8ff0209db575c8231eea77e6ab23e6fe95620c92))\n\n\n### 🤖 Automation\n\n* **deps:** bump OctoGuide/bot in the github-actions group ([#5648](https://github.com/mochajs/mocha/issues/5648)) ([fed6bbd](https://github.com/mochajs/mocha/commit/fed6bbdb891c518e61e8ef4bbf07ed46b469f860))\n* **docs/dev-deps:** use JS-native `fetch` to get supporters data instead of external `needle` ([#5643](https://github.com/mochajs/mocha/issues/5643)) ([e37e56f](https://github.com/mochajs/mocha/commit/e37e56fbe6a1072f1784ef87278d46f7ac48cdb8))\n* initial file implementation for ocotoguide ([#5608](https://github.com/mochajs/mocha/issues/5608)) ([a5f5c64](https://github.com/mochajs/mocha/commit/a5f5c6442505069573a17798a515f267c24a38f3))\n\n## [12.0.0-beta-4](https://github.com/mochajs/mocha/compare/v12.0.0-beta-3...v12.0.0-beta-4) (2026-01-04)\n\n\n### 🌟 Features\n\n* ESM configuration file ([#5397](https://github.com/mochajs/mocha/issues/5397)) ([dff9d78](https://github.com/mochajs/mocha/commit/dff9d7873f2d47a799e0adef338a7d6045ba0731))\n* migrate Markdown lint to `@eslint/markdown` ([#5593](https://github.com/mochajs/mocha/issues/5593)) ([d9e1f0a](https://github.com/mochajs/mocha/commit/d9e1f0aa7e39caa11edb81581c14cd02b3f40b3f))\n\n\n### 🩹 Fixes\n\n* remove `run` and use globalThis `setup` ([#5592](https://github.com/mochajs/mocha/issues/5592)) ([1544c39](https://github.com/mochajs/mocha/commit/1544c39dcd76916cca23a111c88eee8cbb781c24))\n\n\n### 📚 Documentation\n\n* fix v3_older changelog duplicate headings ([#5602](https://github.com/mochajs/mocha/issues/5602)) ([a750518](https://github.com/mochajs/mocha/commit/a7505180b64541ac71639ec3d1193f26e73527d9))\n\n\n### 🧹 Chores\n\n* **ci:** use OIDC token for trusted publishing to `npm` ([#5610](https://github.com/mochajs/mocha/issues/5610)) ([dc0fdb7](https://github.com/mochajs/mocha/commit/dc0fdb767fe46b885f7a0ccfb67acfb453156a3b))\n* create exclusions for nyc ([#5609](https://github.com/mochajs/mocha/issues/5609)) ([702473a](https://github.com/mochajs/mocha/commit/702473a54d9348948a63b4600171afa6956ccb0b))\n* **main:** release 12.0.0-beta-4 ([#5598](https://github.com/mochajs/mocha/issues/5598)) ([424516e](https://github.com/mochajs/mocha/commit/424516ed3c34c6716afbf554425cf5df439cd86c))\n* prevent unwanted Prettier rewrites ([#5591](https://github.com/mochajs/mocha/issues/5591)) ([3ea1578](https://github.com/mochajs/mocha/commit/3ea15789ddb4b77c591d9da36d2476ac359de00d))\n* remove broken browser-test.yml ([#5615](https://github.com/mochajs/mocha/issues/5615)) ([33ce345](https://github.com/mochajs/mocha/commit/33ce345f9ab4f47573a4994c5c01de6eda2af45d))\n* remove legacy `docs/` ([#5583](https://github.com/mochajs/mocha/issues/5583)) ([d8c310e](https://github.com/mochajs/mocha/commit/d8c310e3eddd235be55ad1891cde84c3be6f56f3))\n* revert \"chore(main): release 12.0.0-beta-4 ([#5598](https://github.com/mochajs/mocha/issues/5598))\" ([#5619](https://github.com/mochajs/mocha/issues/5619)) ([dba8091](https://github.com/mochajs/mocha/commit/dba809196541df415fac2681822f5cd35cf20442))\n\n\n### 🤖 Automation\n\n* **dep:** update `diff` from v7 to v8 ([#5605](https://github.com/mochajs/mocha/issues/5605)) ([8ca311c](https://github.com/mochajs/mocha/commit/8ca311c6c9b0d353b1c9d65b5751296d9baddd83))\n* update npm command for format ([#5603](https://github.com/mochajs/mocha/issues/5603)) ([c6a29cc](https://github.com/mochajs/mocha/commit/c6a29ccb38f81d65100cb2a0e6d73ad4303f58fb))\n\n## [12.0.0-beta-3](https://github.com/mochajs/mocha/compare/v12.0.0-beta-2...v12.0.0-beta-3) (2026-01-01)\n\n\n### 🌟 Features\n\n* add mocha.mjs export ([#5527](https://github.com/mochajs/mocha/issues/5527)) ([e1cf23c](https://github.com/mochajs/mocha/commit/e1cf23cbc2049a375ab9980337dbf2486450f7cb))\n* bump serialize-javascript from 6.0.2 to 7.0.2 ([#5589](https://github.com/mochajs/mocha/issues/5589)) ([24fb1b6](https://github.com/mochajs/mocha/commit/24fb1b6f8a45b4ca93b4577838bc1d9a47c74ec1))\n* bump strip-json-comments from 3 to 5 ([#5484](https://github.com/mochajs/mocha/issues/5484)) ([9b0db24](https://github.com/mochajs/mocha/commit/9b0db24740c65717dcd1838dcafccbfc1c538d3b))\n\n\n### 🩹 Fixes\n\n* allow importing ESM interface and reporters ([#5563](https://github.com/mochajs/mocha/issues/5563)) ([bc9fc84](https://github.com/mochajs/mocha/commit/bc9fc842213d00cf7ac4a4b0de898bf29e38bdad))\n* **docs-next:** backer's logo is consistent regardless of size ([#5594](https://github.com/mochajs/mocha/issues/5594)) ([1a53a10](https://github.com/mochajs/mocha/commit/1a53a100a4f3b83a725ccf3c166dcbefebca8602))\n* surface ts-node compile errors ([#5572](https://github.com/mochajs/mocha/issues/5572)) ([add4cf8](https://github.com/mochajs/mocha/commit/add4cf8166b330c9af4342def643c606459331d7))\n\n\n### 📚 Documentation\n\n* bumped docs-next Astro to ^5.16.6 ([#5574](https://github.com/mochajs/mocha/issues/5574)) ([806222b](https://github.com/mochajs/mocha/commit/806222b0998ffb4d09399090f4ec638e90974427))\n* fix light mode Astro accent text color ([#5585](https://github.com/mochajs/mocha/issues/5585)) ([9cc3ada](https://github.com/mochajs/mocha/commit/9cc3ada85b4ab4a4f2a8c7dc1b9d9ff8f101ffc1))\n* update Contributor License Agreement link in CONTRIBUTING.md ([#5567](https://github.com/mochajs/mocha/issues/5567)) ([410ce0d](https://github.com/mochajs/mocha/commit/410ce0d2a0f799aaca2c0bc627294d70c62dd3f4))\n\n\n### 🧹 Chores\n\n* normalized ESLint config to v9's recommended structure ([#5575](https://github.com/mochajs/mocha/issues/5575)) ([7f9ed1f](https://github.com/mochajs/mocha/commit/7f9ed1fb3480e0658c2c7d84c60a1b505c941ce5))\n* update Rollup to v4 ([#5510](https://github.com/mochajs/mocha/issues/5510)) ([cafa782](https://github.com/mochajs/mocha/commit/cafa782f010021e7055f8482ede2c02c6503f0a0))\n\n\n### 🤖 Automation\n\n* **dev-deps:** upgrade `eslint` from v8 to v9 ([#5559](https://github.com/mochajs/mocha/issues/5559)) ([bb24ca8](https://github.com/mochajs/mocha/commit/bb24ca8fde15471ff68d5b01b74c2d7e6047d966))\n* **dev-deps:** upgrade `markdownlint-cli` to latest v0.46.0  ([#5560](https://github.com/mochajs/mocha/issues/5560)) ([a124f1d](https://github.com/mochajs/mocha/commit/a124f1d3b7d0f8277962cae295cd43878294e183))\n* **dev-deps:** upgrade `nyc` from 15 to 17 ([#5556](https://github.com/mochajs/mocha/issues/5556)) ([599ab01](https://github.com/mochajs/mocha/commit/599ab013f526e78b3888a092a928ea4bc67138c0))\n\n## [12.0.0-beta-2](https://github.com/mochajs/mocha/compare/v12.0.0-beta-1...v12.0.0-beta-2) (2025-11-25)\n\n\n### 🧹 Chores\n\n* bump glob to version 13 ([#5546](https://github.com/mochajs/mocha/issues/5546)) ([f4d4ad2](https://github.com/mochajs/mocha/commit/f4d4ad23e9e994668c7d95c5a9bf59f581dccebf))\n\n## [12.0.0-beta-1](https://github.com/mochajs/mocha/compare/v11.7.4...v12.0.0-beta-1) (2025-11-25)\n\n\n### ⚠ BREAKING CHANGES\n\n* cleanup references of --compilers ([#5403](https://github.com/mochajs/mocha/issues/5403))\n* change the default of --forbid-only to check for process.env.CI ([#5496](https://github.com/mochajs/mocha/issues/5496))\n* bump minimum Node.js version from 18.18.0 to 20.19.0 ([#5477](https://github.com/mochajs/mocha/issues/5477))\n\n### 🌟 Features\n\n* allow FIFOs as test files ([#5512](https://github.com/mochajs/mocha/issues/5512)) ([ca4af43](https://github.com/mochajs/mocha/commit/ca4af439d5766fdfb2b5a7d7e06db0280b1abb6e))\n* bump minimum Node.js version from 18.18.0 to 20.19.0 ([#5477](https://github.com/mochajs/mocha/issues/5477)) ([1c34eef](https://github.com/mochajs/mocha/commit/1c34eef426f29e5e46ec348272ccaa869ae43922))\n* change the default of --forbid-only to check for process.env.CI ([#5496](https://github.com/mochajs/mocha/issues/5496)) ([3d94dde](https://github.com/mochajs/mocha/commit/3d94ddea2f45d18473bf00e71db2b9766ab227fe))\n* cleanup references of --compilers ([#5403](https://github.com/mochajs/mocha/issues/5403)) ([f75d150](https://github.com/mochajs/mocha/commit/f75d150cf6115334e7f14b8ee1fbbda04eb87087))\n\n\n### 🩹 Fixes\n\n* correct assertion import syntax in getting-started guide ([#5526](https://github.com/mochajs/mocha/issues/5526)) ([fb0215b](https://github.com/mochajs/mocha/commit/fb0215bd4fba44fde0cc7b8f9b91a4f07020a13b))\n* handle empty null-prototyped objects ([#5506](https://github.com/mochajs/mocha/issues/5506)) ([2a0bce0](https://github.com/mochajs/mocha/commit/2a0bce02f6f696c74fb8fdcd9f72089e82935903))\n\n\n### 📚 Documentation\n\n* add maintainer expectations to MAINTAINERS.md ([#5514](https://github.com/mochajs/mocha/issues/5514)) ([76f95a1](https://github.com/mochajs/mocha/commit/76f95a1113ea0472800ff6b1781f2750836a6db7))\n* migrate how-to wiki pages to main documentation ([#5463](https://github.com/mochajs/mocha/issues/5463)) ([b85aec6](https://github.com/mochajs/mocha/commit/b85aec6e4307903f31b2b8039dd749efc44ffcf5))\n* migrate programmatic usage to docs, development content to DEVELOPMENT.md ([#5464](https://github.com/mochajs/mocha/issues/5464)) ([cb47925](https://github.com/mochajs/mocha/commit/cb47925f99b39bd66bdd09218395bf5e0a54802d))\n* test/integration/README: remove ref to non-existent dir ([#5516](https://github.com/mochajs/mocha/issues/5516)) ([d2c2d40](https://github.com/mochajs/mocha/commit/d2c2d4026d0f6a09b96344f034e9cba9ee6277af))\n\n\n### 🧹 Chores\n\n* applied formatting to all files ([#5493](https://github.com/mochajs/mocha/issues/5493)) ([76d7194](https://github.com/mochajs/mocha/commit/76d719495d09dc4afb37d1179ede8911c52a011e))\n* fix broken link in .github/CONTRIBUTING.md ([681e843](https://github.com/mochajs/mocha/commit/681e843800051a9d3ab66c1bfb7ad71428e34315))\n* remove Node.js 18 from test-smoke in CI too ([d643105](https://github.com/mochajs/mocha/commit/d643105aa6f3fbac9d13e8a44f4c4c7302512193))\n* switch from Coveralls to Codecov ([#5447](https://github.com/mochajs/mocha/issues/5447)) ([f4e7e54](https://github.com/mochajs/mocha/commit/f4e7e54eb285765d7c50bce9c501db2e1b1e22be))\n* unpin node-version in release-please ([#5550](https://github.com/mochajs/mocha/issues/5550)) ([62c90cd](https://github.com/mochajs/mocha/commit/62c90cd2aea4c719d2014e7134b2a1d7c189fd7a))\n* use `ps-list` instead of `pidtree` to remove wmic ([#5479](https://github.com/mochajs/mocha/issues/5479)) ([b2985b3](https://github.com/mochajs/mocha/commit/b2985b3428b4b88ca220a14a26e9eb7139e8d445))\n\n\n### 🤖 Automation\n\n* **deps:** bump actions/checkout in the github-actions group ([#5547](https://github.com/mochajs/mocha/issues/5547)) ([561eb03](https://github.com/mochajs/mocha/commit/561eb039f7cfc36563a9583b17c7d4cb7ec30652))\n* **deps:** bump actions/setup-node in the github-actions group ([#5503](https://github.com/mochajs/mocha/issues/5503)) ([9a70533](https://github.com/mochajs/mocha/commit/9a7053349589344236b20301de965030eaabfea9))\n\n## [11.7.4](https://github.com/mochajs/mocha/compare/v11.7.3...v11.7.4) (2025-10-01)\n\n\n### 🩹 Fixes\n\n* watch mode using chokidar v4 ([#5379](https://github.com/mochajs/mocha/issues/5379)) ([c2667c3](https://github.com/mochajs/mocha/commit/c2667c3b3fca33c21306f59a1cca55bb7e1dac1f))\n\n\n### 📚 Documentation\n\n* migrate remaining legacy wiki pages to main documentation ([#5465](https://github.com/mochajs/mocha/issues/5465)) ([bff9166](https://github.com/mochajs/mocha/commit/bff91660733b71b124aad939538dee7747cfbeb8))\n\n\n### 🧹 Chores\n\n* remove trailing spaces ([#5475](https://github.com/mochajs/mocha/issues/5475)) ([7f68e5c](https://github.com/mochajs/mocha/commit/7f68e5c1565606bcebeb715b8591c52973d00dff))\n\n## [11.7.3](https://github.com/mochajs/mocha/compare/v11.7.2...v11.7.3) (2025-09-30)\n\n\n### 🩹 Fixes\n\n* use original require() error for TS files if ERR_UNKNOWN_FILE_EXTENSION ([#5408](https://github.com/mochajs/mocha/issues/5408)) ([ebdbc48](https://github.com/mochajs/mocha/commit/ebdbc487693254498de62068c59e3e43d078eff1))\n\n\n### 📚 Documentation\n\n* add security escalation policy ([#5466](https://github.com/mochajs/mocha/issues/5466)) ([4122c7d](https://github.com/mochajs/mocha/commit/4122c7d13d0941be451365397fbf43e1f3103027))\n* fix duplicate global leak documentation ([#5461](https://github.com/mochajs/mocha/issues/5461)) ([1164b9d](https://github.com/mochajs/mocha/commit/1164b9da895e56cf745acda2792e634080018ff6))\n* migrate third party UIs wiki page to docs ([#5434](https://github.com/mochajs/mocha/issues/5434)) ([6654704](https://github.com/mochajs/mocha/commit/66547045cb9bd2fa8209b34c36da2a5ef49d23fc))\n* update maintainer release notes for release-please ([#5453](https://github.com/mochajs/mocha/issues/5453)) ([185ae1e](https://github.com/mochajs/mocha/commit/185ae1eabe5c1e92c758bdfb398f7f47b6ef9483))\n\n\n### 🤖 Automation\n\n* **deps:** bump actions/setup-node in the github-actions group ([#5459](https://github.com/mochajs/mocha/issues/5459)) ([48c6f40](https://github.com/mochajs/mocha/commit/48c6f4068b5d22ebc49220900f0b53f8ecdc2b74))\n\n## [11.7.2](https://github.com/mochajs/mocha/compare/v11.7.1...v11.7.2) (2025-09-01)\n\n\n### 🩹 Fixes\n\n* fail with an informative error message on a file with a broken default import ([#5413](https://github.com/mochajs/mocha/issues/5413)) ([b0e6135](https://github.com/mochajs/mocha/commit/b0e61350594f2a044bf34ea153d1fab1e82e80cc))\n* load mjs files correctly ([#5429](https://github.com/mochajs/mocha/issues/5429)) ([a947b9b](https://github.com/mochajs/mocha/commit/a947b9b95501a35efa73c18aa57a74dad555c03a))\n\n\n### 📚 Documentation\n\n* add banner from old site to new site, link from new to old ([#5414](https://github.com/mochajs/mocha/issues/5414)) ([dedef11](https://github.com/mochajs/mocha/commit/dedef110a2af2f8632fb6c1b864fa0a46ad6ca9c))\n* add info on spies to legacy docs ([#5421](https://github.com/mochajs/mocha/issues/5421)) ([21f5544](https://github.com/mochajs/mocha/commit/21f554459c75f5a75b22556b6e2ac70d6ac0e9fc))\n* explain node import swallowing error ([#5401](https://github.com/mochajs/mocha/issues/5401)) ([09f5b2c](https://github.com/mochajs/mocha/commit/09f5b2c9de67ef40d5bd1775c3fca3bdb138f371))\n* fix links in new site ([#5416](https://github.com/mochajs/mocha/issues/5416)) ([b2bc769](https://github.com/mochajs/mocha/commit/b2bc769c6c8d87311ba0bdc9df8b9b588494eba5))\n* migrate assertion libraries wiki link to main docs ([#5442](https://github.com/mochajs/mocha/issues/5442)) ([95f3ca8](https://github.com/mochajs/mocha/commit/95f3ca8bc3a6c6af2932f7fd59a404768c0c6693))\n* migrate count assertions wiki page to docs ([#5438](https://github.com/mochajs/mocha/issues/5438)) ([02a306c](https://github.com/mochajs/mocha/commit/02a306c6cbf31f4eef7d4c9bf5e06c917d3efc11))\n* migrate shared behaviours to docs-next ([#5432](https://github.com/mochajs/mocha/issues/5432)) ([1dc4aa9](https://github.com/mochajs/mocha/commit/1dc4aa98eb3793865fa2a4da3373534dafc1c9a7))\n* migrate Spies wiki page to explainers ([#5420](https://github.com/mochajs/mocha/issues/5420)) ([cbcf007](https://github.com/mochajs/mocha/commit/cbcf007c5ae25f203863aac0b43eca1e8aefe093))\n* Migrate tagging wiki page to docs ([#5435](https://github.com/mochajs/mocha/issues/5435)) ([876247a](https://github.com/mochajs/mocha/commit/876247a8a636cc7bb1c3bf31390e7771182a090a))\n* migrate third party reporters wiki page to docs ([#5433](https://github.com/mochajs/mocha/issues/5433)) ([f70764c](https://github.com/mochajs/mocha/commit/f70764c9a56fcf12e316d5539788c7be0693b6a9))\n* migrate to global leak wiki page to docs ([#5437](https://github.com/mochajs/mocha/issues/5437)) ([8a6fdca](https://github.com/mochajs/mocha/commit/8a6fdcafccd94c888fae5e8be47dd29a604241b6))\n* update /next bug report link to be docs issue template ([#5424](https://github.com/mochajs/mocha/issues/5424)) ([668cb66](https://github.com/mochajs/mocha/commit/668cb66e1288051369ab144ccb50c840ebe34267))\n\n\n### 🧹 Chores\n\n* add issue form for ⚡️ Performance ([#5406](https://github.com/mochajs/mocha/issues/5406)) ([a908b3b](https://github.com/mochajs/mocha/commit/a908b3b86604d41d5751cccfaff505d7092c114f))\n* add test for `-R import-only-loader` ([#5391](https://github.com/mochajs/mocha/issues/5391)) ([6ee5b48](https://github.com/mochajs/mocha/commit/6ee5b483b8c29e0593c7765ad7a5c7b7f7764fc3))\n* also test Node.js 24 in CI ([#5405](https://github.com/mochajs/mocha/issues/5405)) ([15f5980](https://github.com/mochajs/mocha/commit/15f59805287f4c84ab8d057735a391a795be23f1))\n* bump CI to use 20.19.4, 22.18.0, 24.6.0 ([#5430](https://github.com/mochajs/mocha/issues/5430)) ([ace5eb4](https://github.com/mochajs/mocha/commit/ace5eb47a7926fe9d56ebcd95fd659c557a5be4d))\n* bump Knip to 5.61.2 ([#5394](https://github.com/mochajs/mocha/issues/5394)) ([f3d7430](https://github.com/mochajs/mocha/commit/f3d743061d6523f7077b21749089e6fb2f9c32e3))\n* cleanup references of --opts ([#5402](https://github.com/mochajs/mocha/issues/5402)) ([1096b37](https://github.com/mochajs/mocha/commit/1096b376c3c3bb9d4256c643ad35a459ed750928))\n* enabled ESLint's no-unused-vars ([#5399](https://github.com/mochajs/mocha/issues/5399)) ([d4168ae](https://github.com/mochajs/mocha/commit/d4168aef4c21f8fd119385da1cf1794a1ec5c2e1))\n* move callback and object typedefs to a new types.d.ts ([#5351](https://github.com/mochajs/mocha/issues/5351)) ([3300d21](https://github.com/mochajs/mocha/commit/3300d2155a1b06059fbe89c98a1d8bf979539019))\n* rewrite base path instead of copy-pasting ([#5431](https://github.com/mochajs/mocha/issues/5431)) ([c6c6740](https://github.com/mochajs/mocha/commit/c6c6740fb45da43510f86c1d22ea46ce9ee6a7ae))\n* unify caught errors as err ([#5439](https://github.com/mochajs/mocha/issues/5439)) ([d4912e7](https://github.com/mochajs/mocha/commit/d4912e705cf9ae1c3aa274b6449a6a0ff6d408c5))\n* Update experimental module detection test and pin exact Node versions ([#5417](https://github.com/mochajs/mocha/issues/5417)) ([2489090](https://github.com/mochajs/mocha/commit/2489090223f2629e4a380abe4cc6d46858ada922))\n\n\n### 🤖 Automation\n\n* **deps:** bump actions/checkout in the github-actions group ([#5419](https://github.com/mochajs/mocha/issues/5419)) ([03ac2d0](https://github.com/mochajs/mocha/commit/03ac2d0e6e75e95b3dc7fb08f2e1a1117d9718ca))\n\n## [11.7.1](https://github.com/mochajs/mocha/compare/v11.7.0...v11.7.1) (2025-06-24)\n\n\n### 🩹 Fixes\n\n* always fallback to import() if require() fails ([#5384](https://github.com/mochajs/mocha/issues/5384)) ([295c168](https://github.com/mochajs/mocha/commit/295c168628c2583245fb67d371b640309ba243ba))\n\n\n### 🧹 Chores\n\n* add esm loader test ([#5383](https://github.com/mochajs/mocha/issues/5383)) ([f58e49f](https://github.com/mochajs/mocha/commit/f58e49f08df2066e27f87f93ad7ee9cd6f91d225))\n\n## [11.7.0](https://github.com/mochajs/mocha/compare/v11.6.0...v11.7.0) (2025-06-18)\n\n\n### 🌟 Features\n\n* use require to load esm ([#5366](https://github.com/mochajs/mocha/issues/5366)) ([41e24a2](https://github.com/mochajs/mocha/commit/41e24a242944da0cfc9d4d6989dede85f648cb40))\n\n## [11.6.0](https://github.com/mochajs/mocha/compare/v11.5.0...v11.6.0) (2025-06-09)\n\n\n### 🌟 Features\n\n* bump workerpool from ^6.5.1 to ^9.2.0 ([#5350](https://github.com/mochajs/mocha/issues/5350)) ([581a3c5](https://github.com/mochajs/mocha/commit/581a3c554489855ac02860689d3f4ae772c2ea79))\n\n## [11.5.0](https://github.com/mochajs/mocha/compare/v11.4.0...v11.5.0) (2025-05-22)\n\n\n### 🌟 Features\n\n* bump mimimatch from ^5.1.6 to ^9.0.5 ([#5349](https://github.com/mochajs/mocha/issues/5349)) ([a3dea85](https://github.com/mochajs/mocha/commit/a3dea85b316e229ea95f51c715ad61708e9ab9a3))\n\n## [11.4.0](https://github.com/mochajs/mocha/compare/v11.3.0...v11.4.0) (2025-05-19)\n\n\n### 🌟 Features\n\n* bump diff from ^5.2.0 to ^7.0.0 ([#5348](https://github.com/mochajs/mocha/issues/5348)) ([554d6bb](https://github.com/mochajs/mocha/commit/554d6bbec92c3c938af0a533109749b6f3b7bd2c))\n\n\n### 📚 Documentation\n\n* added CHANGELOG.md note around 11.1 yargs-parser update ([#5362](https://github.com/mochajs/mocha/issues/5362)) ([618415d](https://github.com/mochajs/mocha/commit/618415d9c6fa3ef4e959207c8dd404f4703de7a7))\n\n## [11.3.0](https://github.com/mochajs/mocha/compare/v11.2.2...v11.3.0) (2025-05-16)\n\n\n### 🌟 Features\n\n* add option to use posix exit code upon fatal signal ([#4989](https://github.com/mochajs/mocha/issues/4989)) ([91bbf85](https://github.com/mochajs/mocha/commit/91bbf855012ee9b83700d3c563b517483de0831c))\n\n\n### 📚 Documentation\n\n* Deploy new site alongside old one ([#5360](https://github.com/mochajs/mocha/issues/5360)) ([6c96545](https://github.com/mochajs/mocha/commit/6c96545aee03efeee78c55feedcf70664426514c))\n* mention explicit browser support range ([#5354](https://github.com/mochajs/mocha/issues/5354)) ([c514c0b](https://github.com/mochajs/mocha/commit/c514c0bfad044f8450a63b2f9c6c781b9ce6f164))\n* update Node.js version requirements for 11.x ([#5329](https://github.com/mochajs/mocha/issues/5329)) ([abf3dd9](https://github.com/mochajs/mocha/commit/abf3dd921544b45c4c09eef8f7c9c3c4481a3d66))\n\n\n### 🧹 Chores\n\n* remove prerelease setting in release-please config ([#5363](https://github.com/mochajs/mocha/issues/5363)) ([8878f22](https://github.com/mochajs/mocha/commit/8878f222c418a0bf4fe170c17573c30b5ea2d567))\n\n## [11.2.2](https://github.com/mochajs/mocha/compare/v11.2.1...v11.2.2) (2025-04-10)\n\n\n### 🩹 Fixes\n\n* **deps:** update chokidar to v4 ([#5256](https://github.com/mochajs/mocha/issues/5256)) ([8af0f1a](https://github.com/mochajs/mocha/commit/8af0f1a9005a948fbefeb19be618a64dd910d39f))\n\n\n### 📚 Documentation\n\n* add ClientRedirects.astro ([#5324](https://github.com/mochajs/mocha/issues/5324)) ([b88d441](https://github.com/mochajs/mocha/commit/b88d441cc7616253892572778150998627d746ec))\n* add example/tests.html to docs-next ([#5325](https://github.com/mochajs/mocha/issues/5325)) ([6ec5762](https://github.com/mochajs/mocha/commit/6ec5762edd419578e9d3ce2fcc2b8dedcb0caf06))\n\n## [11.2.1](https://github.com/mochajs/mocha/compare/v11.2.0...v11.2.1) (2025-04-10)\n\n\n### 🩹 Fixes\n\n* switch from ansi-colors to picocolors ([#5323](https://github.com/mochajs/mocha/issues/5323)) ([7c08d09](https://github.com/mochajs/mocha/commit/7c08d0944d2255084bc4415238430b13c90f0df5))\n\n\n### 📚 Documentation\n\n* fix new website typos, improve readability ([#5312](https://github.com/mochajs/mocha/issues/5312)) ([fbceb19](https://github.com/mochajs/mocha/commit/fbceb19bbdad121f0100ec3434258775bd87aeaf))\n\n\n### 🧹 Chores\n\n* \"force\" Netlify to use npm to build new site ([#5319](https://github.com/mochajs/mocha/issues/5319)) ([3a46855](https://github.com/mochajs/mocha/commit/3a46855294f82e58a5a414aed3525e394b82aced))\n* Fix tests ([#5320](https://github.com/mochajs/mocha/issues/5320)) ([18699a0](https://github.com/mochajs/mocha/commit/18699a0d668ed2654dd15433f03b74348baf9559))\n\n## [11.2.0](https://github.com/mochajs/mocha/compare/v11.1.0...v11.2.0) (2025-03-17)\n\n\n### 🌟 Features\n\n* enable reporters to show relative paths of tests ([#5292](https://github.com/mochajs/mocha/issues/5292)) ([81ea666](https://github.com/mochajs/mocha/commit/81ea6667e9286c55ffa67977448b776a23c6da2d))\n\n\n### 📚 Documentation\n\n* add instructions for API docs ([#5287](https://github.com/mochajs/mocha/issues/5287)) ([b720ec1](https://github.com/mochajs/mocha/commit/b720ec1b3ca630a90f80311da391b2a0cdfead4e))\n* add new website using Astro Starlight ([#5246](https://github.com/mochajs/mocha/issues/5246)) ([b1f1cb7](https://github.com/mochajs/mocha/commit/b1f1cb78b655191b7a43dc962b513bf1b076890c))\n* improve third-party reporter docs ([#5285](https://github.com/mochajs/mocha/issues/5285)) ([c5a0ef5](https://github.com/mochajs/mocha/commit/c5a0ef523d52d8cab50e4a9b226af3790f54e75f))\n\n\n### 🧹 Chores\n\n* enabled eslint-plugin-n ([#5280](https://github.com/mochajs/mocha/issues/5280)) ([945d6e3](https://github.com/mochajs/mocha/commit/945d6e3bf5a9de19c3aa26fbdac966a721006b58))\n* pin node-lts tests to 22.11.0 ([#5279](https://github.com/mochajs/mocha/issues/5279)) ([664e1f4](https://github.com/mochajs/mocha/commit/664e1f49f7ae214a9666c90f388407e9fa100309))\n* replace `fs-extra` with newer `fs` built-ins ([#5284](https://github.com/mochajs/mocha/issues/5284)) ([75dcf8c](https://github.com/mochajs/mocha/commit/75dcf8c6c40ed1ce134ae5e174b6f4c4ca4d8c42))\n\n## [11.1.0](https://github.com/mochajs/mocha/compare/v11.0.2...v11.1.0) (2025-01-02)\n\n\n### 🌟 Features\n\n* bump yargs to 17 ([#5165](https://github.com/mochajs/mocha/issues/5165)) ([8f1c8d8](https://github.com/mochajs/mocha/commit/8f1c8d888b0104afcd95ca55a517320399755749))\n  * Note that this also included a version bump of [`yargs-parser`](http://npmjs.com/package/yargs-parser) from `^20.2.9` to `^21.1.`, which fixed a bug that caused extra quotes in file paths to be removed.\n    See [#5341](https://github.com/mochajs/mocha/issues/5341) for more information.\n* replace `strip-ansi` with `util.stripVTControlCharacters` ([#5267](https://github.com/mochajs/mocha/issues/5267)) ([3c191c0](https://github.com/mochajs/mocha/commit/3c191c05d9db1e99aec9b600edac2ce10a6b6d71)), closes [#5265](https://github.com/mochajs/mocha/issues/5265)\n\n## [11.0.2](https://github.com/mochajs/mocha/compare/v11.0.1...v11.0.2) (2024-12-09)\n\n\n### 🩹 Fixes\n\n* catch exceptions setting Error.stackTraceLimit ([#5254](https://github.com/mochajs/mocha/issues/5254)) ([259f8f8](https://github.com/mochajs/mocha/commit/259f8f8ba5709b5d84fa66e17cd10560a11f45c9))\n* error handling for unexpected numeric arguments passed to cli ([#5263](https://github.com/mochajs/mocha/issues/5263)) ([210d658](https://github.com/mochajs/mocha/commit/210d658678a2ec3b6f85c59d4b300b4722671099))\n\n\n### 📚 Documentation\n\n* correct outdated `status: accepting prs` link ([#5268](https://github.com/mochajs/mocha/issues/5268)) ([f729cd0](https://github.com/mochajs/mocha/commit/f729cd09b61bb598409f19b3c76b9e9536812237))\n* replace \"New in\" with \"Since\" in version annotations ([#5262](https://github.com/mochajs/mocha/issues/5262)) ([6f10d12](https://github.com/mochajs/mocha/commit/6f10d12c6c6dfa4df7d5221a3ce688f687aaf320))\n\n## [11.0.1](https://github.com/mochajs/mocha/compare/v11.0.0...v11.0.1) (2024-12-02)\n\n\n### 🌟 Features\n\n* bumped glob dependency from 8 to 10 ([#5250](https://github.com/mochajs/mocha/issues/5250)) ([43c3157](https://github.com/mochajs/mocha/commit/43c3157c6ef4f2d4bfecf3ad3a42479fd64187b8))\n\n\n### 📚 Documentation\n\n* fix examples for `linkPartialObjects` methods ([#5255](https://github.com/mochajs/mocha/issues/5255)) ([34e0e52](https://github.com/mochajs/mocha/commit/34e0e52e047a9119aeae9cb5b660a8438656a1e0))\n\n## [11.0.0](https://github.com/mochajs/mocha/compare/v10.8.2...v11.0.0) (2024-11-11)\n\n### ⚠ BREAKING CHANGES\n\n- adapt new engine range for Mocha 11 ([#5216](https://github.com/mochajs/mocha/issues/5216))\n\n### 🌟 Features\n\n- allow calling hook methods ([#5231](https://github.com/mochajs/mocha/issues/5231)) ([e3da641](https://github.com/mochajs/mocha/commit/e3da641b08bed20f12df524fc64cb9579f980c1e))\n\n### 🩹 Fixes\n\n- adapt new engine range for Mocha 11 ([#5216](https://github.com/mochajs/mocha/issues/5216)) ([80da25a](https://github.com/mochajs/mocha/commit/80da25a4132ca50d3ad35087cb62c9b0f8fc946a))\n\n### 📚 Documentation\n\n- downgrade example/tests chai to 4.5.0 ([#5245](https://github.com/mochajs/mocha/issues/5245)) ([eac87e1](https://github.com/mochajs/mocha/commit/eac87e10f49207a9b388f87d77d198583c6f889a))\n\n## [10.8.2](https://github.com/mochajs/mocha/compare/v10.8.1...v10.8.2) (2024-10-30)\n\n### 🩹 Fixes\n\n- support errors with circular dependencies in object values with --parallel ([#5212](https://github.com/mochajs/mocha/issues/5212)) ([ba0fefe](https://github.com/mochajs/mocha/commit/ba0fefe10b08a689cf49edc3818026938aa3a240))\n- test link in html reporter ([#5224](https://github.com/mochajs/mocha/issues/5224)) ([f054acc](https://github.com/mochajs/mocha/commit/f054acc1f60714bbe00ad1ab270fb4977836d045))\n\n### 📚 Documentation\n\n- indicate 'exports' interface does not work in browsers ([#5181](https://github.com/mochajs/mocha/issues/5181)) ([14e640e](https://github.com/mochajs/mocha/commit/14e640ee49718d587779a9594b18f3796c42cf2a))\n\n### 🧹 Chores\n\n- fix docs builds by re-adding eleventy and ignoring gitignore again ([#5240](https://github.com/mochajs/mocha/issues/5240)) ([881e3b0](https://github.com/mochajs/mocha/commit/881e3b0ca2e24284aab2a04f63639a0aa9e0ad1b))\n\n### 🤖 Automation\n\n- **deps:** bump the github-actions group with 1 update ([#5132](https://github.com/mochajs/mocha/issues/5132)) ([e536ab2](https://github.com/mochajs/mocha/commit/e536ab25b308774e3103006c044cb996a2e17c87))\n\n## [10.8.1](https://github.com/mochajs/mocha/compare/v10.8.0...v10.8.1) (2024-10-29)\n\n### 🩹 Fixes\n\n- handle case of invalid package.json with no explicit config ([#5198](https://github.com/mochajs/mocha/issues/5198)) ([f72bc17](https://github.com/mochajs/mocha/commit/f72bc17cb44164bcfff7abc83d0d37d99a061104))\n- Typos on mochajs.org ([#5237](https://github.com/mochajs/mocha/issues/5237)) ([d8ca270](https://github.com/mochajs/mocha/commit/d8ca270a960554c9d5c5fbf264e89d668d01ff0d))\n- use accurate test links in HTML reporter ([#5228](https://github.com/mochajs/mocha/issues/5228)) ([68803b6](https://github.com/mochajs/mocha/commit/68803b685d55dcccc51fa6ccfd27701cda4e26ed))\n\n## [10.8.0](https://github.com/mochajs/mocha/compare/v10.7.3...v10.8.0) (2024-10-29)\n\n### 🌟 Features\n\n- highlight browser failures ([#5222](https://github.com/mochajs/mocha/issues/5222)) ([8ff4845](https://github.com/mochajs/mocha/commit/8ff48453a8b12d9cacf56b0c0c544c8256af64c7))\n\n### 🩹 Fixes\n\n- remove `:is()` from `mocha.css` to support older browsers ([#5225](https://github.com/mochajs/mocha/issues/5225)) ([#5227](https://github.com/mochajs/mocha/issues/5227)) ([0a24b58](https://github.com/mochajs/mocha/commit/0a24b58477ea8ad146afc798930800b02c08790a))\n\n### 📚 Documentation\n\n- add `SECURITY.md` pointing to Tidelift ([#5210](https://github.com/mochajs/mocha/issues/5210)) ([bd7e63a](https://github.com/mochajs/mocha/commit/bd7e63a1f6d98535ce1ed1ecdb57b3e4db8a33c5))\n- adopt Collective Funds Guidelines 0.1 ([#5199](https://github.com/mochajs/mocha/issues/5199)) ([2b03d86](https://github.com/mochajs/mocha/commit/2b03d865eec63d627ff229e07d777f25061260d4))\n- update README, LICENSE and fix outdated ([#5197](https://github.com/mochajs/mocha/issues/5197)) ([1203e0e](https://github.com/mochajs/mocha/commit/1203e0ed739bbbf12166078738357fdb29a8c000))\n\n### 🧹 Chores\n\n- fix npm scripts on windows ([#5219](https://github.com/mochajs/mocha/issues/5219)) ([1173da0](https://github.com/mochajs/mocha/commit/1173da0bf614e8d2a826687802ee8cbe8671ccf1))\n- remove trailing whitespace in SECURITY.md ([7563e59](https://github.com/mochajs/mocha/commit/7563e59ae3c78ada305d26eadb86998ab54342da))\n\n## [10.7.3](https://github.com/mochajs/mocha/compare/v10.7.2...v10.7.3) (2024-08-09)\n\n### 🩹 Fixes\n\n- make release-please build work ([#5194](https://github.com/mochajs/mocha/issues/5194)) ([afd66ef](https://github.com/mochajs/mocha/commit/afd66ef3df20fab51ce38b97216c09108e5c2bfd))\n\n## [10.7.2](https://github.com/mochajs/mocha/compare/v10.7.1...v10.7.2) (2024-08-06)\n\n### 📚 Documentation\n\n- improve filtering ([#5191](https://github.com/mochajs/mocha/issues/5191)) ([1ac5b55](https://github.com/mochajs/mocha/commit/1ac5b552e3f32694d349023cb7f6196ba92b180e))\n\n### 🧹 Chores\n\n- fix failing markdown linting ([#5193](https://github.com/mochajs/mocha/issues/5193)) ([7e7a2ec](https://github.com/mochajs/mocha/commit/7e7a2ecb9bf8daba7e885a880bd8314b7b6fe07d))\n\n## [10.7.1](https://github.com/mochajs/mocha/compare/v10.7.0...v10.7.1) (2024-08-06)\n\n### 🩹 Fixes\n\n- crash with --parallel and --retries both enabled ([#5173](https://github.com/mochajs/mocha/issues/5173)) ([d7013dd](https://github.com/mochajs/mocha/commit/d7013ddb1099cfafe66a1af9640370998290e62c))\n\n### 🧹 Chores\n\n- add knip to validate included dependencies ([5c2989f](https://github.com/mochajs/mocha/commit/5c2989fcc7ae17618d9db16d7c99e23dfb1d38ee))\n- more fully remove assetgraph-builder and canvas ([#5175](https://github.com/mochajs/mocha/issues/5175)) ([1883c41](https://github.com/mochajs/mocha/commit/1883c41a49fad009bd407efc1bece3a5c75fd10a))\n- replace `nps` with npm scripts ([#5128](https://github.com/mochajs/mocha/issues/5128)) ([c44653a](https://github.com/mochajs/mocha/commit/c44653a3a04b8418ec24a942fa7513a4673f3667)), closes [#5126](https://github.com/mochajs/mocha/issues/5126)\n\n## 10.7.0 / 2024-07-20\n\n### :tada: Enhancements\n\n- [#4771](https://github.com/mochajs/mocha/pull/4771) feat: add option to not fail on failing test suite ([**@ilgonmic**](https://github.com/ilgonmic))\n\n## 10.6.1 / 2024-07-20\n\n### :bug: Fixes\n\n- [#3825](https://github.com/mochajs/mocha/pull/3825) fix: do not exit when only unref'd timer is present in test code ([**@boneskull**](https://github.com/boneskull))\n- [#5040](https://github.com/mochajs/mocha/pull/5040) fix: support canonical module ([**@JacobLey**](https://github.com/JacobLey))\n\n## 10.6.0 / 2024-07-02\n\n### :tada: Enhancements\n\n- [#5150](https://github.com/mochajs/mocha/pull/5150) feat: allow ^ versions for character encoding packages ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5151](https://github.com/mochajs/mocha/pull/5151) feat: allow ^ versions for file matching packages ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5152](https://github.com/mochajs/mocha/pull/5152) feat: allow ^ versions for yargs packages ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5153](https://github.com/mochajs/mocha/pull/5153) feat: allow ^ versions for data serialization packages ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5154](https://github.com/mochajs/mocha/pull/5154) feat: allow ^ versions for miscellaneous packages ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n\n## 10.5.2 / 2024-06-25\n\n### :bug: Fixes\n\n- [#5032](https://github.com/mochajs/mocha/pull/5032) fix: better tracking of seen objects in error serialization ([**@sam-super**](https://github.com/sam-super))\n\n## 10.5.1 / 2024-06-24\n\n### :bug: Fixes\n\n- [#5086](https://github.com/mochajs/mocha/pull/5086) fix: Add error handling for nonexistent file case with --file option ([**@khoaHyh**](https://github.com/khoaHyh))\n\n## 10.5.0 / 2024-06-24\n\n### :tada: Enhancements\n\n- [#5015](https://github.com/mochajs/mocha/pull/5015) feat: use \\<progress> and \\<svg> for browser progress indicator instead of \\<canvas> ([**@yourWaifu**](https://github.com/yourWaifu))\n- [#5143](https://github.com/mochajs/mocha/pull/5143) feat: allow using any 3.x chokidar dependencies ([**@simhnna**](https://github.com/simhnna))\n- [#4835](https://github.com/mochajs/mocha/pull/4835) feat: add MOCHA\\_OPTIONS env variable ([**@icholy**](https://github.com/icholy))\n\n### :bug: Fixes\n\n- [#5107](https://github.com/mochajs/mocha/pull/5107) fix: include stack in browser uncaught error reporting ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n\n### :nut\\_and\\_bolt: Other\n\n- [#5110](https://github.com/mochajs/mocha/pull/5110) chore: switch two-column list styles to be opt-in ([**@marjys**](https://github.com/marjys))\n- [#5135](https://github.com/mochajs/mocha/pull/5135) chore: fix some typos in comments ([**@StevenMia**](https://github.com/StevenMia))\n- [#5130](https://github.com/mochajs/mocha/pull/5130) chore: rename 'master' to 'main' in docs and tooling ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n\n## 10.4.0 / 2024-03-26\n\n### :tada: Enhancements\n\n- [#4829](https://github.com/mochajs/mocha/pull/4829) feat: include `.cause` stacks in the error stack traces ([**@voxpelli**](https://github.com/voxpelli))\n- [#4985](https://github.com/mochajs/mocha/pull/4985) feat: add file path to xunit reporter ([**@bmish**](https://github.com/bmish))\n\n### :bug: Fixes\n\n- [#5074](https://github.com/mochajs/mocha/pull/5074) fix: harden error handling in `lib/cli/run.js` ([**@stalet**](https://github.com/stalet))\n\n### :nut\\_and\\_bolt: Other\n\n- [#5077](https://github.com/mochajs/mocha/pull/5077) chore: add mtfoley/pr-compliance-action ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5060](https://github.com/mochajs/mocha/pull/5060) chore: migrate ESLint config to flat config ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5095](https://github.com/mochajs/mocha/pull/5095) chore: revert [#5069](https://github.com/mochajs/mocha/pull/5069) to restore Netlify builds ([**@voxpelli**](https://github.com/voxpelli))\n- [#5097](https://github.com/mochajs/mocha/pull/5097) docs: add sponsored to sponsorship link rels ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5093](https://github.com/mochajs/mocha/pull/5093) chore: add 'status: in triage' label to issue templates and docs ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5083](https://github.com/mochajs/mocha/pull/5083) docs: fix CHANGELOG.md headings to start with a root-level h1 ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5100](https://github.com/mochajs/mocha/pull/5100) chore: fix header generation and production build crashes  ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5104](https://github.com/mochajs/mocha/pull/5104) chore: bump ESLint ecmaVersion to 2020 ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5116](https://github.com/mochajs/mocha/pull/5116) fix: eleventy template builds crash with 'unexpected token at \": string, msg...\"' ([**@LcsK**](https://github.com/LcsK))\n- [#4869](https://github.com/mochajs/mocha/pull/4869) docs: fix documentation concerning glob expansion on UNIX ([**@binki**](https://github.com/binki))\n- [#5122](https://github.com/mochajs/mocha/pull/5122) test: fix xunit integration test ([**@voxpelli**](https://github.com/voxpelli))\n- [#5123](https://github.com/mochajs/mocha/pull/5123) chore: activate dependabot for workflows ([**@voxpelli**](https://github.com/voxpelli))\n- [#5125](https://github.com/mochajs/mocha/pull/5125) build(deps): bump the github-actions group with 2 updates ([**@dependabot**](https://github.com/dependabot))\n\n## 10.3.0 / 2024-02-08\n\nThis is a stable release equivalent to [10.30.0-prerelease](#1030-prerelease--2024-01-18).\n\n## 10.3.0-prerelease / 2024-01-18\n\nThis is a prerelease version to test our ability to release.\nOther than removing or updating dependencies, it contains no intended user-facing changes.\n\n### :nut\\_and\\_bolt: Other\n\n- [#5069](https://github.com/mochajs/mocha/pull/5069): chore: remove unnecessary canvas dependency ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5068](https://github.com/mochajs/mocha/pull/5068): fix: add alt text to Built with Netlify badge ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5056](https://github.com/mochajs/mocha/pull/5056): chore: inline nyan reporter's write function ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5050](https://github.com/mochajs/mocha/pull/5050): docs: touchups to labels and a template title post-revamp ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5038](https://github.com/mochajs/mocha/pull/5038): docs: overhaul contributing and maintenance docs for end-of-year 2023 ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5029](https://github.com/mochajs/mocha/pull/5029): chore: remove stale workflow ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#5024](https://github.com/mochajs/mocha/pull/5024): chore: remove nanoid as dependency ([**@Uzlopak**](https://github.com/Uzlopak))\n- [#5023](https://github.com/mochajs/mocha/pull/5023): chore: remove touch as dev dependency ([**@Uzlopak**](https://github.com/Uzlopak))\n- [#5022](https://github.com/mochajs/mocha/pull/5022): chore: remove uuid dev dependency ([**@Uzlopak**](https://github.com/Uzlopak))\n- [#5021](https://github.com/mochajs/mocha/pull/5021): update can-i-use ([**@Uzlopak**](https://github.com/Uzlopak))\n- [#5020](https://github.com/mochajs/mocha/pull/5020): chore: fix the ci ([**@Uzlopak**](https://github.com/Uzlopak))\n- [#4974](https://github.com/mochajs/mocha/pull/4974): Add Node v19 to test matrix ([**@juergba**](https://github.com/juergba))\n- [#4970](https://github.com/mochajs/mocha/pull/4970): fix [#4837](https://github.com/mochajs/mocha/issues/4837) Update glob due to vulnerability in dep ([**@jb2311**](https://github.com/jb2311))\n- [#4962](https://github.com/mochajs/mocha/pull/4962): Fix deprecated warn gh actions ([**@outsideris**](https://github.com/outsideris))\n- [#4927](https://github.com/mochajs/mocha/pull/4927): docs: use mocha.js instead of mocha in the example run ([**@nikolas**](https://github.com/nikolas))\n- [#4918](https://github.com/mochajs/mocha/pull/4918): docs: fix fragment ID for yargs' \"extends\" documentation ([**@Spencer-Doak**](https://github.com/Spencer-Doak))\n- [#4886](https://github.com/mochajs/mocha/pull/4886): docs: fix jsdoc return type of titlePath method ([**@F3n67u**](https://github.com/F3n67u))\n\n## 10.2.0 / 2022-12-11\n\n### :tada: Enhancements\n\n- [#4945](https://github.com/mochajs/mocha/issues/4945): API: add possibility to decorate ESM name before import ([**@j0tunn**](https://github.com/j0tunn))\n\n### :bug: Fixes\n\n- [#4946](https://github.com/mochajs/mocha/issues/4946): Browser: color of failed test icon ([**@kleisauke**](https://github.com/kleisauke))\n\n### :book: Documentation\n\n- [#4944](https://github.com/mochajs/mocha/issues/4944): Remove duplicated header ([**@PauloGoncalvesBH**](https://github.com/PauloGoncalvesBH))\n\n## 10.1.0 / 2022-10-16\n\n### :tada: Enhancements\n\n- [#4896](https://github.com/mochajs/mocha/issues/4896): Browser: add support for `prefers-color-scheme: dark` ([**@greggman**](https://github.com/greggman))\n\n### :nut\\_and\\_bolt: Other\n\n- [#4912](https://github.com/mochajs/mocha/issues/4912): Browser: increase contrast for replay buttons ([**@JoshuaKGoldberg**](https://github.com/JoshuaKGoldberg))\n- [#4905](https://github.com/mochajs/mocha/issues/4905): Use standard `Promise.allSettled` instead of polyfill ([**@outsideris**](https://github.com/outsideris))\n- [#4899](https://github.com/mochajs/mocha/issues/4899): Upgrade official GitHub actions to latest ([**@ddzz**](https://github.com/ddzz))\n- [#4770](https://github.com/mochajs/mocha/issues/4770): Fix regex in function `clean`([**@yetingli**](https://github.com/yetingli))\n\n## 10.0.0 / 2022-05-01\n\n### :boom: Breaking Changes\n\n- [#4845](https://github.com/mochajs/mocha/issues/4845): **Drop Node.js v12.x support** ([**@juergba**](https://github.com/juergba))\n\n- [#4848](https://github.com/mochajs/mocha/issues/4848): Drop Internet-Explorer-11 support ([**@juergba**](https://github.com/juergba))\n\n- [#4857](https://github.com/mochajs/mocha/issues/4857): Drop AMD/RequireJS support ([**@juergba**](https://github.com/juergba))\n\n- [#4866](https://github.com/mochajs/mocha/issues/4866): Drop Growl notification support ([**@juergba**](https://github.com/juergba))\n\n- [#4863](https://github.com/mochajs/mocha/issues/4863): Rename executable `bin/mocha` to `bin/mocha.js` ([**@juergba**](https://github.com/juergba))\n\n- [#4865](https://github.com/mochajs/mocha/issues/4865): `--ignore` option in Windows: upgrade Minimatch ([**@juergba**](https://github.com/juergba))\n\n- [#4861](https://github.com/mochajs/mocha/issues/4861): Remove deprecated `Runner` signature ([**@juergba**](https://github.com/juergba))\n\n### :nut\\_and\\_bolt: Other\n\n- [#4878](https://github.com/mochajs/mocha/issues/4878): Update production dependencies ([**@juergba**](https://github.com/juergba))\n\n- [#4876](https://github.com/mochajs/mocha/issues/4876): Add Node.js v18 to CI test matrix ([**@outsideris**](https://github.com/outsideris))\n\n- [#4852](https://github.com/mochajs/mocha/issues/4852): Replace deprecated `String.prototype.substr()` ([**@CommanderRoot**](https://github.com/CommanderRoot))\n\nAlso thanks to [**@ea2305**](https://github.com/ea2305) and [**@SukkaW**](https://github.com/SukkaW) for improvements to our documentation.\n\n## 9.2.2 / 2022-03-11\n\n### :bug: Fixes\n\n- [#4842](https://github.com/mochajs/mocha/issues/4842): Loading of reporter throws wrong error ([**@juergba**](https://github.com/juergba))\n\n- [#4839](https://github.com/mochajs/mocha/issues/4839): `dry-run`: prevent potential call-stack crash ([**@juergba**](https://github.com/juergba))\n\n### :nut\\_and\\_bolt: Other\n\n- [#4843](https://github.com/mochajs/mocha/issues/4843): Update production dependencies ([**@juergba**](https://github.com/juergba))\n\n## 9.2.1 / 2022-02-19\n\n### :bug: Fixes\n\n- [#4832](https://github.com/mochajs/mocha/issues/4832): Loading of config files throws wrong error ([**@juergba**](https://github.com/juergba))\n\n- [#4799](https://github.com/mochajs/mocha/issues/4799): Reporter: configurable `maxDiffSize` reporter-option ([**@norla**](https://github.com/norla))\n\n## 9.2.0 / 2022-01-24\n\n### :tada: Enhancements\n\n- [#4813](https://github.com/mochajs/mocha/issues/4813): Parallel: assign each worker a worker-id ([**@forty**](https://github.com/forty))\n\n### :nut\\_and\\_bolt: Other\n\n- [#4818](https://github.com/mochajs/mocha/issues/4818): Update production dependencies ([**@juergba**](https://github.com/juergba))\n\n## 9.1.4 / 2022-01-14\n\n### :bug: Fixes\n\n- [#4807](https://github.com/mochajs/mocha/issues/4807): `import` throws wrong error if loader is used ([**@giltayar**](https://github.com/giltayar))\n\n### :nut\\_and\\_bolt: Other\n\n- [#4777](https://github.com/mochajs/mocha/issues/4777): Add Node v17 to CI test matrix ([**@outsideris**](https://github.com/outsideris))\n\n## 9.1.3 / 2021-10-15\n\n### :bug: Fixes\n\n- [#4769](https://github.com/mochajs/mocha/issues/4769): Browser: re-enable `bdd` ES6 style import ([**@juergba**](https://github.com/juergba))\n\n### :nut\\_and\\_bolt: Other\n\n- [#4764](https://github.com/mochajs/mocha/issues/4764): Revert deprecation of `EVENT_SUITE_ADD_*` events ([**@beatfactor**](https://github.com/beatfactor))\n\n## 9.1.2 / 2021-09-25\n\n### :bug: Fixes\n\n- [#4746](https://github.com/mochajs/mocha/issues/4746): Browser: stop using all global vars in `browser-entry.js` ([**@PaperStrike**](https://github.com/PaperStrike))\n\n### :nut\\_and\\_bolt: Other\n\n- [#4754](https://github.com/mochajs/mocha/issues/4754): Remove dependency wide-align ([**@juergba**](https://github.com/juergba))\n- [#4736](https://github.com/mochajs/mocha/issues/4736): ESM: remove code for Node versions <10 ([**@juergba**](https://github.com/juergba))\n\n## 9.1.1 / 2021-08-28\n\n### :bug: Fixes\n\n- [#4623](https://github.com/mochajs/mocha/issues/4623): `XUNIT` and `JSON` reporter crash in `parallel` mode ([**@curtisman**](https://github.com/curtisman))\n\n## 9.1.0 / 2021-08-20\n\n### :tada: Enhancements\n\n- [#4716](https://github.com/mochajs/mocha/issues/4716): Add new option `--fail-zero` ([**@juergba**](https://github.com/juergba))\n- [#4691](https://github.com/mochajs/mocha/issues/4691): Add new option `--node-option` ([**@juergba**](https://github.com/juergba))\n- [#4607](https://github.com/mochajs/mocha/issues/4607): Add output option to `JSON` reporter ([**@dorny**](https://github.com/dorny))\n\n## 9.0.3 / 2021-07-25\n\n### :bug: Fixes\n\n- [#4702](https://github.com/mochajs/mocha/issues/4702): Error rethrow from cwd-relative path while loading `.mocharc.js` ([**@kirill-golovan**](https://github.com/kirill-golovan))\n\n- [#4688](https://github.com/mochajs/mocha/issues/4688): Usage of custom interface in parallel mode ([**@juergba**](https://github.com/juergba))\n\n- [#4687](https://github.com/mochajs/mocha/issues/4687): ESM: don't swallow `MODULE_NOT_FOUND` errors in case of `type:module` ([**@giltayar**](https://github.com/giltayar))\n\n## 9.0.2 / 2021-07-03\n\n### :bug: Fixes\n\n- [#4668](https://github.com/mochajs/mocha/issues/4668): ESM: make `--require <dir>` work with new `import`-first loading ([**@giltayar**](https://github.com/giltayar))\n\n### :nut\\_and\\_bolt: Other\n\n- [#4674](https://github.com/mochajs/mocha/issues/4674): Update production dependencies ([**@juergba**](https://github.com/juergba))\n\n## 9.0.1 / 2021-06-18\n\n### :nut\\_and\\_bolt: Other\n\n- [#4657](https://github.com/mochajs/mocha/issues/4657): Browser: add separate bundle for modern browsers ([**@juergba**](https://github.com/juergba))\n\nWe added a separate browser bundle `mocha-es2018.js` in javascript ES2018, as we skipped the transpilation down to ES5. This is an **experimental step towards freezing Mocha's support of IE11**.\n\n- [#4653](https://github.com/mochajs/mocha/issues/4653): ESM: proper version check in `hasStableEsmImplementation` ([**@alexander-fenster**](https://github.com/alexander-fenster))\n\n## 9.0.0 / 2021-06-07\n\n### :boom: Breaking Changes\n\n- [#4633](https://github.com/mochajs/mocha/issues/4633): **Drop Node.js v10.x support** ([**@juergba**](https://github.com/juergba))\n\n- [#4635](https://github.com/mochajs/mocha/issues/4635): `import`-first loading of test files ([**@giltayar**](https://github.com/giltayar))\n\n**Mocha is going ESM-first!** This means that it will now use ESM `import(test_file)` to load the test files, instead of the CommonJS `require(test_file)`. This is not a problem, as `import` can also load most files that `require` does. In the rare cases where this fails, it will fallback to `require(...)`. This ESM-first approach is the next step in Mocha's ESM migration, and allows ESM loaders to load and transform the test file.\n\n- [#4636](https://github.com/mochajs/mocha/issues/4636): Remove deprecated `utils.lookupFiles()` ([**@juergba**](https://github.com/juergba))\n\n- [#4638](https://github.com/mochajs/mocha/issues/4638): Limit the size of `actual`/`expected` for `diff` generation ([**@juergba**](https://github.com/juergba))\n\n- [#4389](https://github.com/mochajs/mocha/issues/4389): Refactoring: Consuming log-symbols alternate to code for win32 in reporters/base ([**@MoonSupport**](https://github.com/MoonSupport))\n\n### :tada: Enhancements\n\n- [#4640](https://github.com/mochajs/mocha/issues/4640): Add new option `--dry-run` ([**@juergba**](https://github.com/juergba))\n\n### :bug: Fixes\n\n- [#4128](https://github.com/mochajs/mocha/issues/4128): Fix: control stringification of error message ([**@syeutyu**](https://github.com/syeutyu))\n\n### :nut\\_and\\_bolt: Other\n\n- [#4646](https://github.com/mochajs/mocha/issues/4646): Deprecate `Runner(suite: Suite, delay: boolean)` signature ([**@juergba**](https://github.com/juergba))\n- [#4643](https://github.com/mochajs/mocha/issues/4643): Update production dependencies ([**@juergba**](https://github.com/juergba))\n\n## 8.4.0 / 2021-05-07\n\n### :tada: Enhancements\n\n- [#4502](https://github.com/mochajs/mocha/issues/4502): CLI file parsing errors now have error codes ([**@evaline-ju**](https://github.com/evaline-ju))\n\n### :bug: Fixes\n\n- [#4614](https://github.com/mochajs/mocha/issues/4614): Watch: fix crash when reloading files ([**@outsideris**](https://github.com/outsideris))\n\n### :book: Documentation\n\n- [#4630](https://github.com/mochajs/mocha/issues/4630): Add `options.require` to Mocha constructor for `root hook` plugins on parallel runs ([**@juergba**](https://github.com/juergba))\n- [#4617](https://github.com/mochajs/mocha/issues/4617): Dynamically generating tests with `top-level await` and ESM test files ([**@juergba**](https://github.com/juergba))\n- [#4608](https://github.com/mochajs/mocha/issues/4608): Update default file extensions ([**@outsideris**](https://github.com/outsideris))\n\nAlso thanks to [**@outsideris**](https://github.com/outsideris) for various improvements on our GH actions workflows.\n\n## 8.3.2 / 2021-03-12\n\n### :bug: Fixes\n\n- [#4599](https://github.com/mochajs/mocha/issues/4599): Fix regression in `require` interface ([**@alexander-fenster**](https://github.com/alexander-fenster))\n\n### :book: Documentation\n\n- [#4601](https://github.com/mochajs/mocha/issues/4601): Add build to GH actions run ([**@christian-bromann**](https://github.com/christian-bromann))\n- [#4596](https://github.com/mochajs/mocha/issues/4596): Filter active sponsors/backers ([**@juergba**](https://github.com/juergba))\n- [#4225](https://github.com/mochajs/mocha/issues/4225): Update config file examples ([**@pkuczynski**](https://github.com/pkuczynski))\n\n## 8.3.1 / 2021-03-06\n\n### :bug: Fixes\n\n- [#4577](https://github.com/mochajs/mocha/issues/4577): Browser: fix `EvalError` caused by regenerator-runtime ([**@snoack**](https://github.com/snoack))\n- [#4574](https://github.com/mochajs/mocha/issues/4574): ESM: allow `import` from mocha in parallel mode ([**@nicojs**](https://github.com/nicojs))\n\n## 8.3.0 / 2021-02-11\n\n### :tada: Enhancements\n\n- [#4506](https://github.com/mochajs/mocha/issues/4506): Add error code for test timeout errors ([**@boneskull**](https://github.com/boneskull))\n- [#4112](https://github.com/mochajs/mocha/issues/4112): Add BigInt support to stringify util function ([**@JosejeSinohui**](https://github.com/JosejeSinohui))\n\n### :bug: Fixes\n\n- [#4557](https://github.com/mochajs/mocha/issues/4557): Add file location when SyntaxError happens in ESM ([**@giltayar**](https://github.com/giltayar))\n- [#4521](https://github.com/mochajs/mocha/issues/4521): Fix `require` error when bundling Mocha with Webpack ([**@devhazem**](https://github.com/devhazem))\n\n### :book: Documentation\n\n- [#4507](https://github.com/mochajs/mocha/issues/4507): Add support for typescript-style docstrings ([**@boneskull**](https://github.com/boneskull))\n- [#4503](https://github.com/mochajs/mocha/issues/4503): Add GH Actions workflow status badge ([**@outsideris**](https://github.com/outsideris))\n- [#4494](https://github.com/mochajs/mocha/issues/4494): Add example of generating tests dynamically with a closure ([**@maxwellgerber**](https://github.com/maxwellgerber))\n\n### :nut\\_and\\_bolt: Other\n\n- [#4556](https://github.com/mochajs/mocha/issues/4556): Upgrade all dependencies to latest stable ([**@AviVahl**](https://github.com/AviVahl))\n- [#4543](https://github.com/mochajs/mocha/issues/4543): Update dependencies yargs and yargs-parser ([**@juergba**](https://github.com/juergba))\n\nAlso thanks to [**@outsideris**](https://github.com/outsideris) and [**@HyunSangHan**](https://github.com/HyunSangHan) for various fixes to our website and documentation.\n\n## 8.2.1 / 2020-11-02\n\nFixed stuff.\n\n### :bug: Fixes\n\n- [#4489](https://github.com/mochajs/mocha/issues/4489): Fix problematic handling of otherwise-unhandled `Promise` rejections and erroneous \"`done()` called twice\" errors ([**@boneskull**](https://github.com/boneskull))\n- [#4496](https://github.com/mochajs/mocha/issues/4496): Avoid `MaxListenersExceededWarning` in watch mode ([**@boneskull**](https://github.com/boneskull))\n\nAlso thanks to [**@akeating**](https://github.com/akeating) for a documentation fix!\n\n## 8.2.0 / 2020-10-16\n\nThe major feature added in v8.2.0 is addition of support for [*global fixtures*](https://mochajs.org/#global-fixtures).\n\nWhile Mocha has always had the ability to run setup and teardown via a hook (e.g., a `before()` at the top level of a test file) when running tests in serial, Mocha v8.0.0 added support for parallel runs. Parallel runs are *incompatible* with this strategy; e.g., a top-level `before()` would only run for the file in which it was defined.\n\nWith [global fixtures](https://mochajs.org/#global-fixtures), Mocha can now perform user-defined setup and teardown *regardless* of mode, and these fixtures are guaranteed to run *once and only once*. This holds for parallel mode, serial mode, and even \"watch\" mode (the teardown will run once you hit Ctrl-C, just before Mocha finally exits). Tasks such as starting and stopping servers are well-suited to global fixtures, but not sharing resources--global fixtures do *not* share context with your test files (but they do share context with each other).\n\nHere's a short example of usage:\n\n```js\n// fixtures.js\n\n// can be async or not\nexports.mochaGlobalSetup = async function () {\n  this.server = await startSomeServer({port: process.env.TEST_PORT});\n  console.log(`server running on port ${this.server.port}`);\n};\n\nexports.mochaGlobalTeardown = async function () {\n  // the context (`this`) is shared, but not with the test files\n  await this.server.stop();\n  console.log(`server on port ${this.server.port} stopped`);\n};\n\n// this file can contain root hook plugins as well!\n// exports.mochaHooks = { ... }\n```\n\nFixtures are loaded with `--require`, e.g., `mocha --require fixtures.js`.\n\nFor detailed information, please see the [documentation](https://mochajs.org/#global-fixtures) and this handy-dandy [flowchart](https://mochajs.org/#test-fixture-decision-tree-wizard-thing) to help understand the differences between hooks, root hook plugins, and global fixtures (and when you should use each).\n\n### :tada: Enhancements\n\n- [#4308](https://github.com/mochajs/mocha/issues/4308): Support run-once [global setup & teardown fixtures](https://mochajs.org/#global-fixtures) ([**@boneskull**](https://github.com/boneskull))\n- [#4442](https://github.com/mochajs/mocha/issues/4442): Multi-part extensions (e.g., `test.js`) now usable with `--extension` option ([**@jordanstephens**](https://github.com/jordanstephens))\n- [#4472](https://github.com/mochajs/mocha/issues/4472): Leading dots (e.g., `.js`, `.test.js`) now usable with `--extension` option ([**@boneskull**](https://github.com/boneskull))\n- [#4434](https://github.com/mochajs/mocha/issues/4434): Output of `json` reporter now contains `speed` (\"fast\"/\"medium\"/\"slow\") property ([**@wwhurin**](https://github.com/wwhurin))\n- [#4464](https://github.com/mochajs/mocha/issues/4464): Errors thrown by serializer in parallel mode now have error codes ([**@evaline-ju**](https://github.com/evaline-ju))\n\n*For implementors of custom reporters:*\n\n- [#4409](https://github.com/mochajs/mocha/issues/4409): Parallel mode and custom reporter improvements ([**@boneskull**](https://github.com/boneskull)):\n  - Support custom worker-process-only reporters (`Runner.prototype.workerReporter()`); reporters should subclass `ParallelBufferedReporter` in `mocha/lib/nodejs/reporters/parallel-buffered`\n  - Allow opt-in of object reference matching for \"sufficiently advanced\" custom reporters (`Runner.prototype.linkPartialObjects()`); use if strict object equality is needed when consuming `Runner` event data\n  - Enable detection of parallel mode (`Runner.prototype.isParallelMode()`)\n\n### :bug: Fixes\n\n- [#4476](https://github.com/mochajs/mocha/issues/4476): Workaround for profoundly bizarre issue affecting `npm` v6.x causing some of Mocha's deps to be installed when `mocha` is present in a package's `devDependencies` and `npm install --production` is run the package's working copy ([**@boneskull**](https://github.com/boneskull))\n- [#4465](https://github.com/mochajs/mocha/issues/4465): Worker processes guaranteed (as opposed to \"very likely\") to exit before Mocha does; fixes a problem when using `nyc` with Mocha in parallel mode ([**@boneskull**](https://github.com/boneskull))\n- [#4419](https://github.com/mochajs/mocha/issues/4419): Restore `lookupFiles()` in `mocha/lib/utils`, which was broken/missing in Mocha v8.1.0; it now prints a deprecation warning (use `const {lookupFiles} = require('mocha/lib/cli')` instead) ([**@boneskull**](https://github.com/boneskull))\n\nThanks to [**@AviVahl**](https://github.com/AviVahl), [**@donghoon-song**](https://github.com/donghoon-song), [**@ValeriaVG**](https://github.com/ValeriaVG), [**@znarf**](https://github.com/znarf), [**@sujin-park**](https://github.com/sujin-park), and [**@majecty**](https://github.com/majecty) for other helpful contributions!\n\n## 8.1.3 / 2020-08-28\n\n### :bug: Fixes\n\n- [#4425](https://github.com/mochajs/mocha/issues/4425): Restore `Mocha.utils.lookupFiles()` and Webpack compatibility (both broken since v8.1.0); `Mocha.utils.lookupFiles()` is now **deprecated** and will be removed in the next major revision of Mocha; use `require('mocha/lib/cli').lookupFiles` instead ([**@boneskull**](https://github.com/boneskull))\n\n## 8.1.2 / 2020-08-25\n\n### :bug: Fixes\n\n- [#4418](https://github.com/mochajs/mocha/issues/4418): Fix command-line flag incompatibility in forthcoming Node.js v14.9.0 ([**@boneskull**](https://github.com/boneskull))\n- [#4401](https://github.com/mochajs/mocha/issues/4401): Fix missing global variable in browser ([**@irrationnelle**](https://github.com/irrationnelle))\n\n### :lock: Security Fixes\n\n- [#4396](https://github.com/mochajs/mocha/issues/4396): Update many dependencies ([**@GChuf**](https://github.com/GChuf))\n\n### :book: Documentation\n\n- Various fixes by [**@sujin-park**](https://github.com/sujin-park), [**@wwhurin**](https://github.com/wwhurin) & [**@Donghoon759**](https://github.com/Donghoon759)\n\n## 8.1.1 / 2020-08-04\n\n### :bug: Fixes\n\n- [#4394](https://github.com/mochajs/mocha/issues/4394): Fix regression wherein certain reporters did not correctly detect terminal width ([**@boneskull**](https://github.com/boneskull))\n\n## 8.1.0 / 2020-07-30\n\nIn this release, Mocha now builds its browser bundle with Rollup and Babel, which will provide the project's codebase more flexibility and consistency.\n\nWhile we've been diligent about backwards compatibility, it's *possible* consumers of the browser bundle will encounter differences (other than an increase in the bundle size). If you *do* encounter an issue with the build, please [report it here](https://github.com/mochajs/mocha/issues/new?labels=unconfirmed-bug\\&template=bug_report.md\\&title=).\n\nThis release **does not** drop support for IE11.\n\nOther community contributions came from [**@Devjeel**](https://github.com/Devjeel), [**@Harsha509**](https://github.com/Harsha509) and [**@sharath2106**](https://github.com/sharath2106). *Thank you* to everyone who contributed to this release!\n\n> Do you read Korean? See [this guide to running parallel tests in Mocha](https://blog.outsider.ne.kr/1489), translated by our maintainer, [**@outsideris**](https://github.com/outsideris).\n\n### :tada: Enhancements\n\n- [#4287](https://github.com/mochajs/mocha/issues/4287): Use background colors with inline diffs for better visual distinction ([**@michael-brade**](https://github.com/michael-brade))\n\n### :bug: Fixes\n\n- [#4328](https://github.com/mochajs/mocha/issues/4328): Fix \"watch\" mode when Mocha run in parallel ([**@boneskull**](https://github.com/boneskull))\n- [#4382](https://github.com/mochajs/mocha/issues/4382): Fix root hook execution in \"watch\" mode ([**@indieisaconcept**](https://github.com/indieisaconcept))\n- [#4383](https://github.com/mochajs/mocha/issues/4383): Consistent auto-generated hook titles ([**@cspotcode**](https://github.com/cspotcode))\n- [#4359](https://github.com/mochajs/mocha/issues/4359): Better errors when running `mocha init` ([**@boneskull**](https://github.com/boneskull))\n- [#4341](https://github.com/mochajs/mocha/issues/4341): Fix weirdness when using `delay` option in browser ([**@craigtaub**](https://github.com/craigtaub))\n\n### :lock: Security Fixes\n\n- [#4378](https://github.com/mochajs/mocha/issues/4378), [#4333](https://github.com/mochajs/mocha/issues/4333): Update [javascript-serialize](https://npm.im/javascript-serialize) ([**@martinoppitz**](https://github.com/martinoppitz), [**@wnghdcjfe**](https://github.com/wnghdcjfe))\n- [#4354](https://github.com/mochajs/mocha/issues/4354): Update [yargs-unparser](https://npm.im/yargs-unparser) ([**@martinoppitz**](https://github.com/martinoppitz))\n\n### :book: Documentation & Website\n\n- [#4173](https://github.com/mochajs/mocha/issues/4173): Document how to use `--enable-source-maps` with Mocha ([**@bcoe**](https://github.com/bcoe))\n- [#4343](https://github.com/mochajs/mocha/issues/4343): Clean up some API docs ([**@craigtaub**](https://github.com/craigtaub))\n- [#4318](https://github.com/mochajs/mocha/issues/4318): Sponsor images are now self-hosted ([**@Munter**](https://github.com/Munter))\n\n### :nut\\_and\\_bolt: Other\n\n- [#4293](https://github.com/mochajs/mocha/issues/4293): Use Rollup and Babel in build pipeline; add source map to published files ([**@Munter**](https://github.com/Munter))\n\n## 8.0.1 / 2020-06-10\n\nThe obligatory patch after a major.\n\n### :bug: Fixes\n\n- [#4328](https://github.com/mochajs/mocha/issues/4328): Fix `--parallel` when combined with `--watch` ([**@boneskull**](https://github.com/boneskull))\n\n## 8.0.0 / 2020-06-10\n\nIn this major release, Mocha adds the ability to *run tests in parallel*. Better late than never! Please note the **breaking changes** detailed below.\n\nLet's welcome [**@giltayar**](https://github.com/giltayar) and [**@nicojs**](https://github.com/nicojs) to the maintenance team!\n\n### :boom: Breaking Changes\n\n- [#4164](https://github.com/mochajs/mocha/issues/4164): **Mocha v8.0.0 now requires Node.js v10.12.0 or newer.** Mocha no longer supports the Node.js v8.x line (\"Carbon\"), which entered End-of-Life at the end of 2019 ([**@UlisesGascon**](https://github.com/UlisesGascon))\n\n- [#4175](https://github.com/mochajs/mocha/issues/4175): Having been deprecated with a warning since v7.0.0, **`mocha.opts` is no longer supported** ([**@juergba**](https://github.com/juergba))\n\n  :sparkles: **WORKAROUND:** Replace `mocha.opts` with a [configuration file](https://mochajs.org/#configuring-mocha-nodejs).\n\n- [#4260](https://github.com/mochajs/mocha/issues/4260): Remove `enableTimeout()` (`this.enableTimeout()`) from the context object ([**@craigtaub**](https://github.com/craigtaub))\n\n  :sparkles: **WORKAROUND:** Replace usage of `this.enableTimeout(false)` in your tests with `this.timeout(0)`.\n\n- [#4315](https://github.com/mochajs/mocha/issues/4315): The `spec` option no longer supports a comma-delimited list of files ([**@juergba**](https://github.com/juergba))\n\n  :sparkles: **WORKAROUND**: Use an array instead (e.g., `\"spec\": \"foo.js,bar.js\"` becomes `\"spec\": [\"foo.js\", \"bar.js\"]`).\n\n- [#4309](https://github.com/mochajs/mocha/issues/4309): Drop support for Node.js v13.x line, which is now End-of-Life ([**@juergba**](https://github.com/juergba))\n\n- [#4282](https://github.com/mochajs/mocha/issues/4282): `--forbid-only` will throw an error even if exclusive tests are avoided via `--grep` or other means ([**@arvidOtt**](https://github.com/arvidOtt))\n\n- [#4223](https://github.com/mochajs/mocha/issues/4223): The context object's `skip()` (`this.skip()`) in a \"before all\" (`before()`) hook will no longer execute subsequent sibling hooks, in addition to hooks in child suites ([**@juergba**](https://github.com/juergba))\n\n- [#4178](https://github.com/mochajs/mocha/issues/4178): Remove previously soft-deprecated APIs ([**@wnghdcjfe**](https://github.com/wnghdcjfe)):\n\n  - `Mocha.prototype.ignoreLeaks()`\n  - `Mocha.prototype.useColors()`\n  - `Mocha.prototype.useInlineDiffs()`\n  - `Mocha.prototype.hideDiff()`\n\n### :tada: Enhancements\n\n- [#4245](https://github.com/mochajs/mocha/issues/4245): Add ability to run tests in parallel for Node.js (see [docs](https://mochajs.org/#parallel-tests)) ([**@boneskull**](https://github.com/boneskull))\n\n  :exclamation: See also [#4244](https://github.com/mochajs/mocha/issues/4244); [Root Hook Plugins (docs)](https://mochajs.org/#root-hook-plugins) -- *root hooks must be defined via Root Hook Plugins to work in parallel mode*\n\n- [#4304](https://github.com/mochajs/mocha/issues/4304): `--require` now works with ES modules ([**@JacobLey**](https://github.com/JacobLey))\n\n- [#4299](https://github.com/mochajs/mocha/issues/4299): In some circumstances, Mocha can run ES modules under Node.js v10 -- *use at your own risk!* ([**@giltayar**](https://github.com/giltayar))\n\n### :book: Documentation\n\n- [#4246](https://github.com/mochajs/mocha/issues/4246): Add documentation for parallel mode and Root Hook plugins ([**@boneskull**](https://github.com/boneskull))\n\n### :nut\\_and\\_bolt: Other\n\n- [#4200](https://github.com/mochajs/mocha/issues/4200): Drop mkdirp and replace it with fs.mkdirSync ([**@HyunSangHan**](https://github.com/HyunSangHan))\n\n### :bug: Fixes\n\n(All bug fixes in Mocha v8.0.0 are also breaking changes, and are listed above)\n\n## 7.2.0 / 2020-05-22\n\n### :tada: Enhancements\n\n- [#4234](https://github.com/mochajs/mocha/issues/4234): Add ability to run tests in a mocha instance multiple times ([**@nicojs**](https://github.com/nicojs))\n- [#4219](https://github.com/mochajs/mocha/issues/4219): Exposing filename in JSON, doc, and json-stream reporters ([**@Daniel0113**](https://github.com/Daniel0113))\n- [#4244](https://github.com/mochajs/mocha/issues/4244): Add Root Hook Plugins ([**@boneskull**](https://github.com/boneskull))\n\n### :bug: Fixes\n\n- [#4258](https://github.com/mochajs/mocha/issues/4258): Fix missing dot in name of configuration file ([**@sonicdoe**](https://github.com/sonicdoe))\n- [#4194](https://github.com/mochajs/mocha/issues/4194): Check if module.paths really exists ([**@ematipico**](https://github.com/ematipico))\n- [#4256](https://github.com/mochajs/mocha/issues/4256): `--forbid-only` does not recognize `it.only` when `before` crashes ([**@arvidOtt**](https://github.com/arvidOtt))\n- [#4152](https://github.com/mochajs/mocha/issues/4152): Bug with multiple async done() calls ([**@boneskull**](https://github.com/boneskull))\n- [#4275](https://github.com/mochajs/mocha/issues/4275): Improper warnings for invalid reporters ([**@boneskull**](https://github.com/boneskull))\n- [#4288](https://github.com/mochajs/mocha/issues/4288): Broken hook.spec.js test for IE11 ([**@boneskull**](https://github.com/boneskull))\n\n### :book: Documentation\n\n- [#4081](https://github.com/mochajs/mocha/issues/4081): Insufficient white space for API docs in view on mobile ([**@HyunSangHan**](https://github.com/HyunSangHan))\n- [#4255](https://github.com/mochajs/mocha/issues/4255): Update mocha-docdash for UI fixes on API docs ([**@craigtaub**](https://github.com/craigtaub))\n- [#4235](https://github.com/mochajs/mocha/issues/4235): Enable emoji on website; enable normal ul elements ([**@boneskull**](https://github.com/boneskull))\n- [#4272](https://github.com/mochajs/mocha/issues/4272): Fetch sponsors at build time, show ALL non-skeevy sponsors ([**@boneskull**](https://github.com/boneskull))\n\n### :nut\\_and\\_bolt: Other\n\n- [#4249](https://github.com/mochajs/mocha/issues/4249): Refactoring improving encapsulation ([**@arvidOtt**](https://github.com/arvidOtt))\n- [#4242](https://github.com/mochajs/mocha/issues/4242): CI add job names, add Node.js v14 to matrix ([**@boneskull**](https://github.com/boneskull))\n- [#4237](https://github.com/mochajs/mocha/issues/4237): Refactor validatePlugins to throw coded errors ([**@boneskull**](https://github.com/boneskull))\n- [#4236](https://github.com/mochajs/mocha/issues/4236): Better debug output ([**@boneskull**](https://github.com/boneskull))\n\n## 7.1.2 / 2020-04-26\n\n### :nut\\_and\\_bolt: Other\n\n- [#4251](https://github.com/mochajs/mocha/issues/4251): Prevent karma-mocha from stalling ([**@juergba**](https://github.com/juergba))\n- [#4222](https://github.com/mochajs/mocha/issues/4222): Update dependency mkdirp to v0.5.5 ([**@outsideris**](https://github.com/outsideris))\n\n### :book: Documentation\n\n- [#4208](https://github.com/mochajs/mocha/issues/4208): Add Wallaby logo to site ([**@boneskull**](https://github.com/boneskull))\n\n## 7.1.1 / 2020-03-18\n\n### :lock: Security Fixes\n\n- [#4204](https://github.com/mochajs/mocha/issues/4204): Update dependencies mkdirp, yargs-parser and yargs ([**@juergba**](https://github.com/juergba))\n\n### :bug: Fixes\n\n- [#3660](https://github.com/mochajs/mocha/issues/3660): Fix `runner` listening to `start` and `end` events ([**@juergba**](https://github.com/juergba))\n\n### :book: Documentation\n\n- [#4190](https://github.com/mochajs/mocha/issues/4190): Show Netlify badge on footer ([**@outsideris**](https://github.com/outsideris))\n\n## 7.1.0 / 2020-02-26\n\n### :tada: Enhancements\n\n[#4038](https://github.com/mochajs/mocha/issues/4038): Add Node.js native ESM support ([**@giltayar**](https://github.com/giltayar))\n\nMocha supports writing your test files as ES modules:\n\n- Node.js only v12.11.0 and above\n- Node.js below v13.2.0, you must set `--experimental-modules` option\n- current limitations: please check our [documentation](https://mochajs.org/#nodejs-native-esm-support)\n- for programmatic usage: see [API: loadFilesAsync()](https://mochajs.org/api/mocha#loadFilesAsync)\n\n**Note:** Node.JS native [ECMAScript Modules](https://nodejs.org/api/esm.html) implementation has status: **Stability: 1 - Experimental**\n\n### :bug: Fixes\n\n- [#4181](https://github.com/mochajs/mocha/issues/4181): Programmatic API cannot access retried test objects ([**@juergba**](https://github.com/juergba))\n- [#4174](https://github.com/mochajs/mocha/issues/4174): Browser: fix `allowUncaught` option ([**@juergba**](https://github.com/juergba))\n\n### :book: Documentation\n\n- [#4058](https://github.com/mochajs/mocha/issues/4058): Manage author list in AUTHORS instead of `package.json` ([**@outsideris**](https://github.com/outsideris))\n\n### :nut\\_and\\_bolt: Other\n\n- [#4138](https://github.com/mochajs/mocha/issues/4138): Upgrade ESLint v6.8 ([**@kaicataldo**](https://github.com/kaicataldo))\n\n## 7.0.1 / 2020-01-25\n\n### :bug: Fixes\n\n- [#4165](https://github.com/mochajs/mocha/issues/4165): Fix exception when skipping tests programmatically ([**@juergba**](https://github.com/juergba))\n- [#4153](https://github.com/mochajs/mocha/issues/4153): Restore backwards compatibility for `reporterOptions` ([**@holm**](https://github.com/holm))\n- [#4150](https://github.com/mochajs/mocha/issues/4150): Fix recovery of an open test upon uncaught exception ([**@juergba**](https://github.com/juergba))\n- [#4147](https://github.com/mochajs/mocha/issues/4147): Fix regression of leaking uncaught exception handler ([**@juergba**](https://github.com/juergba))\n\n### :book: Documentation\n\n- [#4146](https://github.com/mochajs/mocha/issues/4146): Update copyright & trademark notices per OJSF ([**@boneskull**](https://github.com/boneskull))\n- [#4140](https://github.com/mochajs/mocha/issues/4140): Fix broken links ([**@KyoungWan**](https://github.com/KyoungWan))\n\n### :nut\\_and\\_bolt: Other\n\n- [#4133](https://github.com/mochajs/mocha/issues/4133): Print more descriptive error message ([**@Zirak**](https://github.com/Zirak))\n\n## 7.0.0 / 2020-01-05\n\n### :boom: Breaking Changes\n\n- [#3885](https://github.com/mochajs/mocha/issues/3885): **Drop Node.js v6.x support** ([**@mojosoeun**](https://github.com/mojosoeun))\n- [#3890](https://github.com/mochajs/mocha/issues/3890): Remove Node.js debug-related flags `--debug`/`--debug-brk` and deprecate `debug` argument ([**@juergba**](https://github.com/juergba))\n- [#3962](https://github.com/mochajs/mocha/issues/3962): Changes to command-line options ([**@ParkSB**](https://github.com/ParkSB)):\n  - `--list-interfaces` replaces `--interfaces`\n  - `--list-reporters` replaces `--reporters`\n- Hook pattern of `this.skip()` ([**@juergba**](https://github.com/juergba)):\n  - [#3859](https://github.com/mochajs/mocha/issues/3859): When conditionally skipping in a `it` test, related `afterEach` hooks are now executed\n  - [#3741](https://github.com/mochajs/mocha/issues/3741): When conditionally skipping in a `beforeEach` hook, subsequent inner `beforeEach` hooks are now skipped and related `afterEach` hooks are executed\n  - [#4136](https://github.com/mochajs/mocha/issues/4136): Disallow `this.skip()` within `after` hooks\n- [#3967](https://github.com/mochajs/mocha/issues/3967): Remove deprecated `getOptions()` and `lib/cli/options.js` ([**@juergba**](https://github.com/juergba))\n- [#4083](https://github.com/mochajs/mocha/issues/4083): Uncaught exception in `pending` test: don't swallow, but retrospectively fail the test for correct exit code ([**@juergba**](https://github.com/juergba))\n- [#4004](https://github.com/mochajs/mocha/issues/4004): Align `Mocha` constructor's option names with command-line options ([**@juergba**](https://github.com/juergba))\n\n### :tada: Enhancements\n\n- [#3980](https://github.com/mochajs/mocha/issues/3980): Refactor and improve `--watch` mode with chokidar ([**@geigerzaehler**](https://github.com/geigerzaehler)):\n  - adds command-line options `--watch-files` and `--watch-ignore`\n  - removes `--watch-extensions`\n- [#3979](https://github.com/mochajs/mocha/issues/3979): Type \"rs\\n\" to restart tests ([**@broofa**](https://github.com/broofa))\n\n### :fax: Deprecations\n\nThese are *soft*-deprecated, and will emit a warning upon use. Support will be removed in (likely) the next major version of Mocha:\n\n- [#3968](https://github.com/mochajs/mocha/issues/3968): Deprecate legacy configuration via `mocha.opts` ([**@juergba**](https://github.com/juergba))\n\n### :bug: Fixes\n\n- [#4125](https://github.com/mochajs/mocha/issues/4125): Fix timeout handling with `--inspect-brk`/`--inspect` ([**@juergba**](https://github.com/juergba))\n- [#4070](https://github.com/mochajs/mocha/issues/4070): `Mocha` constructor: improve browser setup ([**@juergba**](https://github.com/juergba))\n- [#4068](https://github.com/mochajs/mocha/issues/4068): XUnit reporter should handle exceptions during diff generation ([**@rgroothuijsen**](https://github.com/rgroothuijsen))\n- [#4030](https://github.com/mochajs/mocha/issues/4030): Fix `--allow-uncaught` with `this.skip()` ([**@juergba**](https://github.com/juergba))\n\n### :mag: Coverage\n\n- [#4109](https://github.com/mochajs/mocha/issues/4109): Add Node.js v13.x to CI test matrix ([**@juergba**](https://github.com/juergba))\n\n### :book: Documentation\n\n- [#4129](https://github.com/mochajs/mocha/issues/4129): Fix broken links ([**@SaeromB**](https://github.com/SaeromB))\n- [#4127](https://github.com/mochajs/mocha/issues/4127): Add reporter alias names to docs ([**@khg0712**](https://github.com/khg0712))\n- [#4101](https://github.com/mochajs/mocha/issues/4101): Clarify invalid usage of `done()` ([**@jgehrcke**](https://github.com/jgehrcke))\n- [#4092](https://github.com/mochajs/mocha/issues/4092): Replace `:coffee:` with emoji ☕️ ([**@pzrq**](https://github.com/pzrq))\n- [#4088](https://github.com/mochajs/mocha/issues/4088): Initial draft of project charter ([**@boneskull**](https://github.com/boneskull))\n- [#4066](https://github.com/mochajs/mocha/issues/4066): Change `sh` to `bash` for code block in docs/index.md ([**@HyunSangHan**](https://github.com/HyunSangHan))\n- [#4045](https://github.com/mochajs/mocha/issues/4045): Update README.md concerning GraphicsMagick installation ([**@HyunSangHan**](https://github.com/HyunSangHan))\n- [#3988](https://github.com/mochajs/mocha/issues/3988): Fix sponsors background color for readability ([**@outsideris**](https://github.com/outsideris))\n\n### :nut\\_and\\_bolt: Other\n\n- [#4118](https://github.com/mochajs/mocha/issues/4118): Update node-environment-flags to 1.0.6 ([**@kylef**](https://github.com/kylef))\n- [#4097](https://github.com/mochajs/mocha/issues/4097): Add GH Funding Metadata ([**@SheetJSDev**](https://github.com/SheetJSDev))\n- [#4089](https://github.com/mochajs/mocha/issues/4089): Add funding information to `package.json` ([**@Munter**](https://github.com/Munter))\n- [#4077](https://github.com/mochajs/mocha/issues/4077): Improve integration tests ([**@soobing**](https://github.com/soobing))\n\n## 6.2.3 / 2020-03-25\n\n### :lock: Security Fixes\n\n- [848d6fb8](https://github.com/mochajs/mocha/commit/848d6fb8feef659564b296db457312d38176910d): Update dependencies mkdirp, yargs-parser and yargs ([**@juergba**](https://github.com/juergba))\n\n## 6.2.2 / 2019-10-18\n\n### :bug: Fixes\n\n- [#4025](https://github.com/mochajs/mocha/issues/4025): Fix duplicate `EVENT_RUN_END` events upon uncaught exception ([**@juergba**](https://github.com/juergba))\n- [#4051](https://github.com/mochajs/mocha/issues/4051): Fix \"unhide\" function in `html` reporter (browser) ([**@pec9399**](https://github.com/pec9399))\n- [#4063](https://github.com/mochajs/mocha/issues/4063): Fix use of [esm](https://npm.im/esm) in Node.js v8.x ([**@boneskull**](https://github.com/boneskull))\n- [#4033](https://github.com/mochajs/mocha/issues/4033): Fix output when multiple async exceptions are thrown ([**@juergba**](https://github.com/juergba))\n\n### :book: Documentation\n\n- [#4046](https://github.com/mochajs/mocha/issues/4046): Site accessibility fixes ([**@Mia-jeong**](https://github.com/Mia-jeong))\n- [#4026](https://github.com/mochajs/mocha/issues/4026): Update docs for custom reporters in browser ([**@Lindsay-Needs-Sleep**](https://github.com/Lindsay-Needs-Sleep))\n- [#3971](https://github.com/mochajs/mocha/issues/3971): Adopt new OpenJS Foundation Code of Conduct ([**@craigtaub**](https://github.com/craigtaub))\n\n## 6.2.1 / 2019-09-29\n\n### :bug: Fixes\n\n- [#3955](https://github.com/mochajs/mocha/issues/3955): tty.getWindowSize is not a function inside a \"worker\\_threads\" worker ([**@1999**](https://github.com/1999))\n- [#3970](https://github.com/mochajs/mocha/issues/3970): remove extraGlobals() ([**@juergba**](https://github.com/juergba))\n- [#3984](https://github.com/mochajs/mocha/issues/3984): Update yargs-unparser to v1.6.0 ([**@juergba**](https://github.com/juergba))\n- [#3983](https://github.com/mochajs/mocha/issues/3983): Package 'esm': spawn child-process for correct loading ([**@juergba**](https://github.com/juergba))\n- [#3986](https://github.com/mochajs/mocha/issues/3986): Update yargs to v13.3.0 and yargs-parser to v13.1.1 ([**@juergba**](https://github.com/juergba))\n\n### :book: Documentation\n\n- [#3886](https://github.com/mochajs/mocha/issues/3886): fix styles on mochajs.org ([**@outsideris**](https://github.com/outsideris))\n- [#3966](https://github.com/mochajs/mocha/issues/3966): Remove jsdoc index.html placeholder from eleventy file structure and fix broken link in jsdoc tutorial ([**@Munter**](https://github.com/Munter))\n- [#3765](https://github.com/mochajs/mocha/issues/3765): Add Matomo to website ([**@MarioDiaz98**](https://github.com/MarioDiaz98))\n- [#3947](https://github.com/mochajs/mocha/issues/3947): Clarify effect of .skip() ([**@oliversalzburg**](https://github.com/oliversalzburg))\n\n## 6.2.0 / 2019-07-18\n\n### :tada: Enhancements\n\n- [#3827](https://github.com/mochajs/mocha/issues/3827): Do not fork child-process if no Node flags are present ([**@boneskull**](https://github.com/boneskull))\n- [#3725](https://github.com/mochajs/mocha/issues/3725): Base reporter store ref to console.log, see [mocha/wiki](https://github.com/mochajs/mocha/wiki/HOW-TO:-Correctly-stub-stdout) ([**@craigtaub**](https://github.com/craigtaub))\n\n### :bug: Fixes\n\n- [#3942](https://github.com/mochajs/mocha/issues/3942): Fix \"No test files found\" Error when file is passed via `--file` ([**@gabegorelick**](https://github.com/gabegorelick))\n- [#3914](https://github.com/mochajs/mocha/issues/3914): Modify Mocha constructor to accept options `global` or `globals` ([**@pascalpp**](https://github.com/pascalpp))\n- [#3894](https://github.com/mochajs/mocha/issues/3894): Fix parsing of config files with `_mocha` binary ([**@juergba**](https://github.com/juergba))\n- [#3834](https://github.com/mochajs/mocha/issues/3834): Fix CLI parsing with default values ([**@boneskull**](https://github.com/boneskull), [**@juergba**](https://github.com/juergba))\n- [#3831](https://github.com/mochajs/mocha/issues/3831): Fix `--timeout`/`--slow` string values and duplicate arguments ([**@boneskull**](https://github.com/boneskull), [**@juergba**](https://github.com/juergba))\n\n### :book: Documentation\n\n- [#3906](https://github.com/mochajs/mocha/issues/3906): Document option to define custom report name for XUnit reporter ([**@pkuczynski**](https://github.com/pkuczynski))\n- [#3889](https://github.com/mochajs/mocha/issues/3889): Adds doc links for mocha-examples ([**@craigtaub**](https://github.com/craigtaub))\n- [#3887](https://github.com/mochajs/mocha/issues/3887): Fix broken links ([**@toyjhlee**](https://github.com/toyjhlee))\n- [#3841](https://github.com/mochajs/mocha/issues/3841): Fix anchors to configuration section ([**@trescube**](https://github.com/trescube))\n\n### :mag: Coverage\n\n- [#3915](https://github.com/mochajs/mocha/issues/3915), [#3929](https://github.com/mochajs/mocha/issues/3929): Increase tests coverage for `--watch` options ([**@geigerzaehler**](https://github.com/geigerzaehler))\n\n### :nut\\_and\\_bolt: Other\n\n- [#3953](https://github.com/mochajs/mocha/issues/3953): Collect test files later, prepares improvements to the `--watch` mode behavior ([**@geigerzaehler**](https://github.com/geigerzaehler))\n- [#3939](https://github.com/mochajs/mocha/issues/3939): Upgrade for npm audit ([**@boneskull**](https://github.com/boneskull))\n- [#3930](https://github.com/mochajs/mocha/issues/3930): Extract `runWatch` into separate module ([**@geigerzaehler**](https://github.com/geigerzaehler))\n- [#3922](https://github.com/mochajs/mocha/issues/3922): Add `mocha.min.js` file to stacktrace filter ([**@brian-lagerman**](https://github.com/brian-lagerman))\n- [#3919](https://github.com/mochajs/mocha/issues/3919): Update CI config files to use Node-12.x ([**@plroebuck**](https://github.com/plroebuck))\n- [#3892](https://github.com/mochajs/mocha/issues/3892): Rework reporter tests ([**@plroebuck**](https://github.com/plroebuck))\n- [#3872](https://github.com/mochajs/mocha/issues/3872): Rename `--exclude` to `--ignore` and create alias ([**@boneskull**](https://github.com/boneskull))\n- [#3963](https://github.com/mochajs/mocha/issues/3963): Hide stacktrace when cli args are missing ([**@outsideris**](https://github.com/outsideris))\n- [#3956](https://github.com/mochajs/mocha/issues/3956): Do not redeclare variable in docs array example ([**@DanielRuf**](https://github.com/DanielRuf))\n- [#3957](https://github.com/mochajs/mocha/issues/3957): Remove duplicate line-height property in `mocha.css` ([**@DanielRuf**](https://github.com/DanielRuf))\n- [#3960](https://github.com/mochajs/mocha/issues/3960): Don't re-initialize grep option on watch re-run ([**@geigerzaehler**](https://github.com/geigerzaehler))\n\n## 6.1.4 / 2019-04-18\n\n### :lock: Security Fixes\n\n- [#3877](https://github.com/mochajs/mocha/issues/3877): Upgrade [js-yaml](https://npm.im/js-yaml), addressing [code injection vulnerability](https://www.npmjs.com/advisories/813) ([**@bjornstar**](https://github.com/bjornstar))\n\n## 6.1.3 / 2019-04-11\n\n### :bug: Fixes\n\n- [#3863](https://github.com/mochajs/mocha/issues/3863): Fix `yargs`-related global scope pollution ([**@inukshuk**](https://github.com/inukshuk))\n- [#3869](https://github.com/mochajs/mocha/issues/3869): Fix failure when installed w/ `pnpm` ([**@boneskull**](https://github.com/boneskull))\n\n## 6.1.2 / 2019-04-08\n\n### :bug: Fixes\n\n- [#3867](https://github.com/mochajs/mocha/issues/3867): Re-publish v6.1.1 from POSIX OS to avoid dropped executable flags ([**@boneskull**](https://github.com/boneskull))\n\n## 6.1.1 / 2019-04-07\n\n### :bug: Fixes\n\n- [#3866](https://github.com/mochajs/mocha/issues/3866): Fix Windows End-of-Line publishing issue ([**@juergba**](https://github.com/juergba) & [**@cspotcode**](https://github.com/cspotcode))\n\n## 6.1.0 / 2019-04-07\n\n### :lock: Security Fixes\n\n- [#3845](https://github.com/mochajs/mocha/issues/3845): Update dependency \"js-yaml\" to v3.13.0 per npm security advisory ([**@plroebuck**](https://github.com/plroebuck))\n\n### :tada: Enhancements\n\n- [#3766](https://github.com/mochajs/mocha/issues/3766): Make reporter constructor support optional `options` parameter ([**@plroebuck**](https://github.com/plroebuck))\n- [#3760](https://github.com/mochajs/mocha/issues/3760): Add support for config files with `.jsonc` extension ([**@sstephant**](https://github.com/sstephant))\n\n### :fax: Deprecations\n\nThese are *soft*-deprecated, and will emit a warning upon use. Support will be removed in (likely) the next major version of Mocha:\n\n- [#3719](https://github.com/mochajs/mocha/issues/3719): Deprecate `this.skip()` for \"after all\" hooks ([**@juergba**](https://github.com/juergba))\n\n### :bug: Fixes\n\n- [#3829](https://github.com/mochajs/mocha/issues/3829): Use cwd-relative pathname to load config file ([**@plroebuck**](https://github.com/plroebuck))\n- [#3745](https://github.com/mochajs/mocha/issues/3745): Fix async calls of `this.skip()` in \"before each\" hooks ([**@juergba**](https://github.com/juergba))\n- [#3669](https://github.com/mochajs/mocha/issues/3669): Enable `--allow-uncaught` for uncaught exceptions thrown inside hooks ([**@givanse**](https://github.com/givanse))\n\nand some regressions:\n\n- [#3848](https://github.com/mochajs/mocha/issues/3848): Fix `Suite` cloning by copying `root` property ([**@fatso83**](https://github.com/fatso83))\n- [#3816](https://github.com/mochajs/mocha/issues/3816): Guard against undefined timeout option ([**@boneskull**](https://github.com/boneskull))\n- [#3814](https://github.com/mochajs/mocha/issues/3814): Update \"yargs\" in order to avoid deprecation message ([**@boneskull**](https://github.com/boneskull))\n- [#3788](https://github.com/mochajs/mocha/issues/3788): Fix support for multiple node flags ([**@aginzberg**](https://github.com/aginzberg))\n\n### :book: Documentation\n\n- [mochajs/mocha-examples](https://github.com/mochajs/mocha-examples): New repository of working examples of common configurations using mocha ([**@craigtaub**](https://github.com/craigtaub))\n- [#3850](https://github.com/mochajs/mocha/issues/3850): Remove pound icon showing on header hover on docs ([**@jd2rogers2**](https://github.com/jd2rogers2))\n- [#3812](https://github.com/mochajs/mocha/issues/3812): Add autoprefixer to documentation page CSS ([**@Munter**](https://github.com/Munter))\n- [#3811](https://github.com/mochajs/mocha/issues/3811): Update doc examples \"tests.html\" ([**@DavidLi119**](https://github.com/DavidLi119))\n- [#3807](https://github.com/mochajs/mocha/issues/3807): Mocha website HTML tweaks ([**@plroebuck**](https://github.com/plroebuck))\n- [#3793](https://github.com/mochajs/mocha/issues/3793): Update config file example \".mocharc.yml\" ([**@cspotcode**](https://github.com/cspotcode))\n\n### :nut\\_and\\_bolt: Other\n\n- [#3830](https://github.com/mochajs/mocha/issues/3830): Replace dependency \"findup-sync\" with \"find-up\" for faster startup ([**@cspotcode**](https://github.com/cspotcode))\n- [#3799](https://github.com/mochajs/mocha/issues/3799): Update devDependencies to fix many npm vulnerabilities ([**@XhmikosR**](https://github.com/XhmikosR))\n\n## 6.0.2 / 2019-02-25\n\n### :bug: Fixes\n\nTwo more regressions fixed:\n\n- [#3768](https://github.com/mochajs/mocha/issues/3768): Test file paths no longer dropped from `mocha.opts` ([**@boneskull**](https://github.com/boneskull))\n- [#3767](https://github.com/mochajs/mocha/issues/3767): `--require` does not break on module names that look like certain `node` flags ([**@boneskull**](https://github.com/boneskull))\n\n## 6.0.1 / 2019-02-21\n\nThe obligatory round of post-major-release bugfixes.\n\n### :bug: Fixes\n\nThese issues were regressions.\n\n- [#3754](https://github.com/mochajs/mocha/issues/3754): Mocha again finds `test.js` when run without arguments ([**@plroebuck**](https://github.com/plroebuck))\n- [#3756](https://github.com/mochajs/mocha/issues/3756): Mocha again supports third-party interfaces via `--ui` ([**@boneskull**](https://github.com/boneskull))\n- [#3755](https://github.com/mochajs/mocha/issues/3755): Fix broken `--watch` ([**@boneskull**](https://github.com/boneskull))\n- [#3759](https://github.com/mochajs/mocha/issues/3759): Fix unwelcome deprecation notice when Mocha run against languages (CoffeeScript) with implicit return statements; *returning a non-`undefined` value from a `describe` callback is no longer considered deprecated* ([**@boneskull**](https://github.com/boneskull))\n\n### :book: Documentation\n\n- [#3738](https://github.com/mochajs/mocha/issues/3738): Upgrade to `@mocha/docdash@2` ([**@tendonstrength**](https://github.com/tendonstrength))\n- [#3751](https://github.com/mochajs/mocha/issues/3751): Use preferred names for example config files ([**@Szauka**](https://github.com/Szauka))\n\n## 6.0.0 / 2019-02-18\n\n### :tada: Enhancements\n\n- [#3726](https://github.com/mochajs/mocha/issues/3726): Add ability to unload files from `require` cache ([**@plroebuck**](https://github.com/plroebuck))\n\n### :bug: Fixes\n\n- [#3737](https://github.com/mochajs/mocha/issues/3737): Fix falsy values from options globals ([**@plroebuck**](https://github.com/plroebuck))\n- [#3707](https://github.com/mochajs/mocha/issues/3707): Fix encapsulation issues for `Suite#_onlyTests` and `Suite#_onlySuites` ([**@vkarpov15**](https://github.com/vkarpov15))\n- [#3711](https://github.com/mochajs/mocha/issues/3711): Fix diagnostic messages dealing with plurality and markup of output ([**@plroebuck**](https://github.com/plroebuck))\n- [#3723](https://github.com/mochajs/mocha/issues/3723): Fix \"reporter-option\" to allow comma-separated options ([**@boneskull**](https://github.com/boneskull))\n- [#3722](https://github.com/mochajs/mocha/issues/3722): Fix code quality and performance of `lookupFiles` and `files` ([**@plroebuck**](https://github.com/plroebuck))\n- [#3650](https://github.com/mochajs/mocha/issues/3650), [#3654](https://github.com/mochajs/mocha/issues/3654): Fix noisy error message when no files found ([**@craigtaub**](https://github.com/craigtaub))\n- [#3632](https://github.com/mochajs/mocha/issues/3632): Tests having an empty title are no longer confused with the \"root\" suite ([**@juergba**](https://github.com/juergba))\n- [#3666](https://github.com/mochajs/mocha/issues/3666): Fix missing error codes ([**@vkarpov15**](https://github.com/vkarpov15))\n- [#3684](https://github.com/mochajs/mocha/issues/3684): Fix exiting problem in Node.js v11.7.0+ ([**@addaleax**](https://github.com/addaleax))\n- [#3691](https://github.com/mochajs/mocha/issues/3691): Fix `--delay` (and other boolean options) not working in all cases ([**@boneskull**](https://github.com/boneskull))\n- [#3692](https://github.com/mochajs/mocha/issues/3692): Fix invalid command-line argument usage not causing actual errors ([**@boneskull**](https://github.com/boneskull))\n- [#3698](https://github.com/mochajs/mocha/issues/3698), [#3699](https://github.com/mochajs/mocha/issues/3699): Fix debug-related Node.js options not working in all cases ([**@boneskull**](https://github.com/boneskull))\n- [#3700](https://github.com/mochajs/mocha/issues/3700): Growl notifications now show the correct number of tests run ([**@outsideris**](https://github.com/outsideris))\n- [#3686](https://github.com/mochajs/mocha/issues/3686): Avoid potential ReDoS when diffing large objects ([**@cyjake**](https://github.com/cyjake))\n- [#3715](https://github.com/mochajs/mocha/issues/3715): Fix incorrect order of emitted events when used programmatically ([**@boneskull**](https://github.com/boneskull))\n- [#3706](https://github.com/mochajs/mocha/issues/3706): Fix regression wherein `--reporter-option`/`--reporter-options` did not support comma-separated key/value pairs ([**@boneskull**](https://github.com/boneskull))\n\n### :book: Documentation\n\n- [#3652](https://github.com/mochajs/mocha/issues/3652): Switch from Jekyll to Eleventy ([**@Munter**](https://github.com/Munter))\n\n### :nut\\_and\\_bolt: Other\n\n- [#3677](https://github.com/mochajs/mocha/issues/3677): Add error objects for createUnsupportedError and createInvalidExceptionError ([**@boneskull**](https://github.com/boneskull))\n- [#3733](https://github.com/mochajs/mocha/issues/3733): Removed unnecessary processing in post-processing hook ([**@wanseob**](https://github.com/wanseob))\n- [#3730](https://github.com/mochajs/mocha/issues/3730): Update nyc to latest version ([**@coreyfarrell**](https://github.com/coreyfarrell))\n- [#3648](https://github.com/mochajs/mocha/issues/3648), [#3680](https://github.com/mochajs/mocha/issues/3680): Fixes to support latest versions of [unexpected](https://npm.im/unexpected) and [unexpected-sinon](https://npm.im/unexpected-sinon) ([**@sunesimonsen**](https://github.com/sunesimonsen))\n- [#3638](https://github.com/mochajs/mocha/issues/3638): Add meta tag to site ([**@MartijnCuppens**](https://github.com/MartijnCuppens))\n- [#3653](https://github.com/mochajs/mocha/issues/3653): Fix parts of test suite failing to run on Windows ([**@boneskull**](https://github.com/boneskull))\n\n## 6.0.0-1 / 2019-01-02\n\n### :bug: Fixes\n\n- Fix missing `mocharc.json` in published package ([**@boneskull**](https://github.com/boneskull))\n\n## 6.0.0-0 / 2019-01-01\n\n**Documentation for this release can be found at [next.mochajs.org](https://next.mochajs.org)**!\n\nWelcome [**@plroebuck**](https://github.com/plroebuck), [**@craigtaub**](https://github.com/craigtaub), & [**@markowsiak**](https://github.com/markowsiak) to the team!\n\n### :boom: Breaking Changes\n\n- [#3149](https://github.com/mochajs/mocha/issues/3149): **Drop Node.js v4.x support** ([**@outsideris**](https://github.com/outsideris))\n- [#3556](https://github.com/mochajs/mocha/issues/3556): Changes to command-line options ([**@boneskull**](https://github.com/boneskull)):\n  - `--grep` and `--fgrep` are now mutually exclusive; attempting to use both will cause Mocha to fail instead of simply ignoring `--grep`\n  - `--compilers` is no longer supported; attempting to use will cause Mocha to fail with a link to more information\n  - `-d` is no longer an alias for `--debug`; `-d` is currently ignored\n  - [#3275](https://github.com/mochajs/mocha/issues/3275): `--watch-extensions` no longer implies `js`; it must be explicitly added ([**@TheDancingCode**](https://github.com/TheDancingCode))\n- [#2908](https://github.com/mochajs/mocha/issues/2908): `tap` reporter emits error messages ([**@chrmod**](https://github.com/chrmod))\n- [#2819](https://github.com/mochajs/mocha/issues/2819): When conditionally skipping in a `before` hook, subsequent `before` hooks *and* tests in nested suites are now skipped ([**@bannmoore**](https://github.com/bannmoore))\n- [#627](https://github.com/mochajs/mocha/issues/627): Emit filepath in \"timeout exceeded\" exceptions where applicable ([**@boneskull**](https://github.com/boneskull))\n- [#3556](https://github.com/mochajs/mocha/issues/3556): `lib/template.html` has moved to `lib/browser/template.html` ([**@boneskull**](https://github.com/boneskull))\n- [#2576](https://github.com/mochajs/mocha/issues/2576): An exception is now thrown if Mocha fails to parse or find a `mocha.opts` at a user-specified path ([**@plroebuck**](https://github.com/plroebuck))\n- [#3458](https://github.com/mochajs/mocha/issues/3458): Instantiating a `Base`-extending reporter without a `Runner` parameter will throw an exception ([**@craigtaub**](https://github.com/craigtaub))\n- [#3125](https://github.com/mochajs/mocha/issues/3125): For consumers of Mocha's programmatic API, all exceptions thrown from Mocha now have a `code` property (and some will have additional metadata). Some `Error` messages have changed. **Please use the `code` property to check `Error` types instead of the `message` property**; these descriptions will be localized in the future. ([**@craigtaub**](https://github.com/craigtaub))\n\n### :fax: Deprecations\n\nThese are *soft*-deprecated, and will emit a warning upon use. Support will be removed in (likely) the next major version of Mocha:\n\n- `-gc` users should use `--gc-global` instead\n- Consumers of the function exported by `bin/options` should now use the `loadMochaOpts` or `loadOptions` (preferred) functions exported by the `lib/cli/options` module\n\nRegarding the `Mocha` class constructor (from `lib/mocha`):\n\n- Use property `color: false` instead of `useColors: false`\n- Use property `timeout: false` instead of `enableTimeouts: false`\n\nAll of the above deprecations were introduced by [#3556](https://github.com/mochajs/mocha/issues/3556).\n\n`mocha.opts` is now considered \"legacy\"; please prefer RC file or `package.json` over `mocha.opts`.\n\n### :tada: Enhancements\n\nEnhancements introduced in [#3556](https://github.com/mochajs/mocha/issues/3556):\n\n- Mocha now supports \"RC\" files in JS, JSON, YAML, or `package.json`-based (using `mocha` property) format\n\n  - `.mocharc.js`, `.mocharc.json`, `.mocharc.yaml` or `.mocharc.yml` are valid \"rc\" file names and will be automatically loaded\n  - Use `--config /path/to/rc/file` to specify an explicit path\n  - Use `--package /path/to/package.json` to specify an explicit `package.json` to read the `mocha` prop from\n  - Use `--no-config` or `--no-package` to completely disable loading of configuration via RC file and `package.json`, respectively\n  - Configurations are merged as applicable using the priority list:\n    1. Command-line arguments\n    1. RC file\n    1. `package.json`\n    1. `mocha.opts`\n    1. Mocha's own defaults\n  - Check out these [example config files](https://github.com/mochajs/mocha/tree/master/example/config)\n\n- Node/V8 flag support in `mocha` executable:\n\n  - Support all allowed `node` flags as supported by the running version of `node` (also thanks to [**@demurgos**](https://github.com/demurgos))\n  - Support any V8 flag by prepending `--v8-` to the flag name\n  - All flags are also supported via config files, `package.json` properties, or `mocha.opts`\n  - Debug-related flags (e.g., `--inspect`) now *imply* `--no-timeouts`\n  - Use of e.g., `--debug` will automatically invoke `--inspect` if supported by running version of `node`\n\n- Support negation of any Mocha-specific command-line flag by prepending `--no-` to the flag name\n\n- Interfaces now have descriptions when listed using `--interfaces` flag\n\n- `Mocha` constructor supports all options\n\n- `--extension` is now an alias for `--watch-extensions` and affects *non-watch-mode* test runs as well. For example, to run *only* `test/*.coffee` (not `test/*.js`), you can do `mocha --require coffee-script/register --extensions coffee`.\n\n- [#3552](https://github.com/mochajs/mocha/issues/3552): `tap` reporter is now TAP13-capable ([**@plroebuck**](https://github.com/plroebuck) & [**@mollstam**](https://github.com/mollstam))\n\n- [#3535](https://github.com/mochajs/mocha/issues/3535): Mocha's version can now be queried programmatically via public property `Mocha.prototype.version` ([**@plroebuck**](https://github.com/plroebuck))\n\n- [#3428](https://github.com/mochajs/mocha/issues/3428): `xunit` reporter shows diffs ([**@mlucool**](https://github.com/mlucool))\n\n- [#2529](https://github.com/mochajs/mocha/issues/2529): `Runner` now emits a `retry` event when tests are retried (reporters can listen for this) ([**@catdad**](https://github.com/catdad))\n\n- [#2962](https://github.com/mochajs/mocha/issues/2962), [#3111](https://github.com/mochajs/mocha/issues/3111): In-browser notification support; warn about missing prereqs when `--growl` supplied ([**@plroebuck**](https://github.com/plroebuck))\n\n### :bug: Fixes\n\n- [#3356](https://github.com/mochajs/mocha/issues/3356): `--no-timeouts` and `--timeout 0` now does what you'd expect ([**@boneskull**](https://github.com/boneskull))\n- [#3475](https://github.com/mochajs/mocha/issues/3475): Restore `--no-exit` option ([**@boneskull**](https://github.com/boneskull))\n- [#3570](https://github.com/mochajs/mocha/issues/3570): Long-running tests now respect `SIGINT` ([**@boneskull**](https://github.com/boneskull))\n- [#2944](https://github.com/mochajs/mocha/issues/2944): `--forbid-only` and `--forbid-pending` now \"fail fast\" when encountered on a suite ([**@outsideris**](https://github.com/outsideris))\n- [#1652](https://github.com/mochajs/mocha/issues/1652), [#2951](https://github.com/mochajs/mocha/issues/2951): Fix broken clamping of timeout values ([**@plroebuck**](https://github.com/plroebuck))\n- [#2095](https://github.com/mochajs/mocha/issues/2095), [#3521](https://github.com/mochajs/mocha/issues/3521): Do not log `stdout:` prefix in browser console ([**@Bamieh**](https://github.com/Bamieh))\n- [#3595](https://github.com/mochajs/mocha/issues/3595): Fix mochajs.org deployment problems ([**@papandreou**](https://github.com/papandreou))\n- [#3518](https://github.com/mochajs/mocha/issues/3518): Improve `utils.isPromise()` ([**@fabiosantoscode**](https://github.com/fabiosantoscode))\n- [#3320](https://github.com/mochajs/mocha/issues/3320): Fail gracefully when non-extensible objects are thrown in async tests ([**@fargies**](https://github.com/fargies))\n- [#2475](https://github.com/mochajs/mocha/issues/2475): XUnit does not duplicate test result numbers in \"errors\" and \"failures\"; \"failures\" will **always** be zero ([**@mlucool**](https://github.com/mlucool))\n- [#3398](https://github.com/mochajs/mocha/issues/3398), [#3598](https://github.com/mochajs/mocha/issues/3598), [#3457](https://github.com/mochajs/mocha/issues/3457), [#3617](https://github.com/mochajs/mocha/issues/3617): Fix regression wherein `--bail` would not execute \"after\" nor \"after each\" hooks ([**@juergba**](https://github.com/juergba))\n- [#3580](https://github.com/mochajs/mocha/issues/3580): Fix potential exception when using XUnit reporter programmatically ([**@Lana-Light**](https://github.com/Lana-Light))\n- [#1304](https://github.com/mochajs/mocha/issues/1304): Do not output color to `TERM=dumb` ([**@plroebuck**](https://github.com/plroebuck))\n\n### :book: Documentation\n\n- [#3525](https://github.com/mochajs/mocha/issues/3525): Improvements to `.github/CONTRIBUTING.md` ([**@markowsiak**](https://github.com/markowsiak))\n- [#3466](https://github.com/mochajs/mocha/issues/3466): Update description of `slow` option ([**@finfin**](https://github.com/finfin))\n- [#3405](https://github.com/mochajs/mocha/issues/3405): Remove references to bower installations ([**@goteamtim**](https://github.com/goteamtim))\n- [#3361](https://github.com/mochajs/mocha/issues/3361): Improvements to `--watch` docs ([**@benglass**](https://github.com/benglass))\n- [#3136](https://github.com/mochajs/mocha/issues/3136): Improve docs around globbing and shell expansion ([**@akrawchyk**](https://github.com/akrawchyk))\n- [#2819](https://github.com/mochajs/mocha/issues/2819): Update docs around skips and hooks ([**@bannmoore**](https://github.com/bannmoore))\n- Many improvements by [**@outsideris**](https://github.com/outsideris)\n\n### :nut\\_and\\_bolt: Other\n\n- [#3557](https://github.com/mochajs/mocha/issues/3557): Use `ms` userland module instead of hand-rolled solution ([**@gizemkeser**](https://github.com/gizemkeser))\n- Many CI fixes and other refactors by [**@plroebuck**](https://github.com/plroebuck)\n- Test refactors by [**@outsideris**](https://github.com/outsideris)\n\n## 5.2.0 / 2018-05-18\n\n### :tada: Enhancements\n\n- [#3375](https://github.com/mochajs/mocha/pull/3375): Add support for comments in `mocha.opts` ([@plroebuck](https://github.com/plroebuck))\n\n### :bug: Fixes\n\n- [#3346](https://github.com/mochajs/mocha/pull/3346): Exit correctly from `before` hooks when using `--bail` ([@outsideris](https://github.com/outsideris))\n\n### :book: Documentation\n\n- [#3328](https://github.com/mochajs/mocha/pull/3328): Mocha-flavored [API docs](https://mochajs.org/api/)! ([@Munter](https://github.com/munter))\n\n### :nut\\_and\\_bolt: Other\n\n- [#3330](https://github.com/mochajs/mocha/pull/3330): Use `Buffer.from()` ([@harrysarson](https://github.com/harrysarson))\n- [#3295](https://github.com/mochajs/mocha/pull/3295): Remove redundant folder ([@DavNej](https://github.com/DajNev))\n- [#3356](https://github.com/mochajs/mocha/pull/3356): Refactoring ([@plroebuck](https://github.com/plroebuck))\n\n## 5.1.1 / 2018-04-18\n\n### :bug: Fixes\n\n- [#3325](https://github.com/mochajs/mocha/issues/3325): Revert change which broke `--watch` ([@boneskull](https://github.com/boneskull))\n\n## 5.1.0 / 2018-04-12\n\n### :tada: Enhancements\n\n- [#3210](https://github.com/mochajs/mocha/pull/3210): Add `--exclude` option ([@metalex9](https://github.com/metalex9))\n\n### :bug: Fixes\n\n- [#3318](https://github.com/mochajs/mocha/pull/3318): Fix failures in circular objects in JSON reporter ([@jeversmann](https://github.com/jeversmann), [@boneskull](https://github.com/boneskull))\n\n### :book: Documentation\n\n- [#3323](https://github.com/mochajs/mocha/pull/3323): Publish actual [API documentation](https://mochajs.org/api/)! ([@dfberry](https://github.com/dfberry), [@Munter](https://github.com/munter))\n- [#3299](https://github.com/mochajs/mocha/pull/3299): Improve docs around exclusive tests ([@nicgirault](https://github.com/nicgirault))\n\n### :nut\\_and\\_bolt: Other\n\n- [#3302](https://github.com/mochajs/mocha/pull/3302), [#3308](https://github.com/mochajs/mocha/pull/3308), [#3310](https://github.com/mochajs/mocha/pull/3310), [#3315](https://github.com/mochajs/mocha/pull/3315), [#3316](https://github.com/mochajs/mocha/pull/3316): Build matrix improvements ([more info](https://boneskull.com/mocha-and-travis-ci-build-stages/)) ([@outsideris](https://github.com/outsideris), [@boneskull](https://github.com/boneskull))\n- [#3272](https://github.com/mochajs/mocha/pull/3272): Refactor reporter tests ([@jMuzsik](https://github.com/jMuzsik))\n\n## 5.0.5 / 2018-03-22\n\nWelcome [@outsideris](https://github.com/outsideris) to the team!\n\n### :bug: Fixes\n\n- [#3096](https://github.com/mochajs/mocha/issues/3096): Fix `--bail` failing to bail within hooks ([@outsideris](https://github.com/outsideris))\n- [#3184](https://github.com/mochajs/mocha/issues/3184): Don't skip too many suites (using `describe.skip()`) ([@outsideris](https://github.com/outsideris))\n\n### :book: Documentation\n\n- [#3133](https://github.com/mochajs/mocha/issues/3133): Improve docs regarding \"pending\" behavior ([@ematicipo](https://github.com/ematicipo))\n- [#3276](https://github.com/mochajs/mocha/pull/3276), [#3274](https://github.com/mochajs/mocha/pull/3274): Fix broken stuff in `CHANGELOG.md` ([@tagoro9](https://github.com/tagoro9), [@honzajavorek](https://github.com/honzajavorek))\n\n### :nut\\_and\\_bolt: Other\n\n- [#3208](https://github.com/mochajs/mocha/issues/3208): Improve test coverage for AMD users ([@outsideris](https://github.com/outsideris))\n- [#3267](https://github.com/mochajs/mocha/pull/3267): Remove vestiges of PhantomJS from CI ([@anishkny](https://github.com/anishkny))\n- [#2952](https://github.com/mochajs/mocha/issues/2952): Fix a debug message ([@boneskull](https://github.com/boneskull))\n\n## 5.0.4 / 2018-03-07\n\n### :bug: Fixes\n\n- [#3265](https://github.com/mochajs/mocha/issues/3265): Fixes regression in \"watch\" functionality introduced in v5.0.2 ([@outsideris](https://github.com/outsideris))\n\n## 5.0.3 / 2018-03-06\n\nThis patch features a fix to address a potential \"low severity\" [ReDoS vulnerability](https://snyk.io/vuln/npm:diff:20180305) in the [diff](https://npm.im/diff) package (a dependency of Mocha).\n\n### :lock: Security Fixes\n\n- [#3266](https://github.com/mochajs/mocha/pull/3266): Bump `diff` to v3.5.0 ([@anishkny](https://github.com/anishkny))\n\n### :nut\\_and\\_bolt: Other\n\n- [#3011](https://github.com/mochajs/mocha/issues/3011): Expose `generateDiff()` in `Base` reporter ([@harrysarson](https://github.com/harrysarson))\n\n## 5.0.2 / 2018-03-05\n\nThis release fixes a class of tests which report as *false positives*. **Certain tests will now break**, though they would have previously been reported as passing. Details below. Sorry for the inconvenience!\n\n### :bug: Fixes\n\n- [#3226](https://github.com/mochajs/mocha/issues/3226): Do not swallow errors that are thrown asynchronously from passing tests ([@boneskull](https://github.com/boneskull)). Example:\n\n  \\`\\`\\`js\n  it('should actually fail, sorry!', function (done) {\n  // passing assertion\n  assert(true === true);\n\n  // test complete & is marked as passing\n  done();\n\n  // ...but something evil lurks within\n  setTimeout(() => {\n  throw new Error('chaos!');\n  }, 100);\n  });\n  \\`\\`\\`\n\n  Previously to this version, Mocha would have *silently swallowed* the `chaos!` exception, and you wouldn't know. Well, *now you know*. Mocha cannot recover from this gracefully, so it will exit with a nonzero code.\n\n  **Maintainers of external reporters**: *If* a test of this class is encountered, the `Runner` instance will emit the `end` event *twice*; you *may* need to change your reporter to use `runner.once('end')` intead of `runner.on('end')`.\n\n- [#3093](https://github.com/mochajs/mocha/issues/3093): Fix stack trace reformatting problem ([@outsideris](https://github.com/outsideris))\n\n### :nut\\_and\\_bolt: Other\n\n- [#3248](https://github.com/mochajs/mocha/issues/3248): Update `browser-stdout` to v1.3.1 ([@honzajavorek](https://github.com/honzajavorek))\n\n## 5.0.1 / 2018-02-07\n\n...your garden-variety patch release.\n\nSpecial thanks to [Wallaby.js](https://wallabyjs.com) for their continued support! :heart:\n\n### :bug: Fixes\n\n- [#1838](https://github.com/mochajs/mocha/issues/1838): `--delay` now works with `.only()` ([@silviom](https://github.com/silviom))\n- [#3119](https://github.com/mochajs/mocha/issues/3119): Plug memory leak present in v8 ([@boneskull](https://github.com/boneskull))\n\n### :book: Documentation\n\n- [#3132](https://github.com/mochajs/mocha/issues/3132), [#3098](https://github.com/mochajs/mocha/issues/3098): Update `--glob` docs ([@outsideris](https://github.com/outsideris))\n- [#3212](https://github.com/mochajs/mocha/pull/3212): Update [Wallaby.js](https://wallabyjs.com)-related docs ([@ArtemGovorov](https://github.com/ArtemGovorov))\n- [#3205](https://github.com/mochajs/mocha/pull/3205): Remove outdated cruft ([@boneskull](https://github.com/boneskull))\n\n### :nut\\_and\\_bolt: Other\n\n- [#3224](https://github.com/mochajs/mocha/pull/3224): Add proper Wallaby.js config ([@ArtemGovorov](https://github.com/ArtemGovorov))\n- [#3230](https://github.com/mochajs/mocha/pull/3230): Update copyright year ([@josephlin55555](https://github.com/josephlin55555))\n\n## 5.0.0 / 2018-01-17\n\nMocha starts off 2018 right by again dropping support for *unmaintained rubbish*.\n\nWelcome [@vkarpov15](https://github.com/vkarpov15) to the team!\n\n### :boom: Breaking Changes\n\n- **[#3148](https://github.com/mochajs/mocha/issues/3148): Drop support for IE9 and IE10** ([@Bamieh](https://github.com/Bamieh))\n  Practically speaking, only code which consumes (through bundling or otherwise) the userland [buffer](https://npm.im/buffer) module should be affected. However, Mocha will no longer test against these browsers, nor apply fixes for them.\n\n### :tada: Enhancements\n\n- [#3181](https://github.com/mochajs/mocha/issues/3181): Add useful new `--file` command line argument ([documentation](https://mochajs.org/#--file-file)) ([@hswolff](https://github.com/hswolff))\n\n### :bug: Fixes\n\n- [#3187](https://github.com/mochajs/mocha/issues/3187): Fix inaccurate test duration reporting ([@FND](https://github.com/FND))\n- [#3202](https://github.com/mochajs/mocha/pull/3202): Fix bad markup in HTML reporter ([@DanielRuf](https://github.com/DanielRuf))\n\n### :sunglasses: Developer Experience\n\n- [#2352](https://github.com/mochajs/mocha/issues/2352): Ditch GNU Make for [nps](https://npm.im/nps) to manage scripts ([@TedYav](https://github.com/TedYav))\n\n### :book: Documentation\n\n- [#3137](https://github.com/mochajs/mocha/issues/3137): Add missing `--no-timeouts` docs ([@dfberry](https://github.com/dfberry))\n- [#3134](https://github.com/mochajs/mocha/issues/3134): Improve `done()` callback docs ([@maraisr](https://github.com/maraisr))\n- [#3135](https://github.com/mochajs/mocha/issues/3135): Fix cross-references ([@vkarpov15](https://github.com/vkarpov15))\n- [#3163](https://github.com/mochajs/mocha/pull/3163): Fix tpyos ([@tbroadley](https://github.com/tbroadley))\n- [#3177](https://github.com/mochajs/mocha/pull/3177): Tweak `README.md` organization ([@xxczaki](https://github.com/xxczaki))\n- Misc updates ([@boneskull](https://github.com/boneskull))\n\n### :nut\\_and\\_bolt: Other\n\n- [#3118](https://github.com/mochajs/mocha/issues/3118): Move TextMate Integration to [its own repo](https://github.com/mochajs/mocha.tmbundle) ([@Bamieh](https://github.com/Bamieh))\n- [#3185](https://github.com/mochajs/mocha/issues/3185): Add Node.js v9 to build matrix; remove v7 ([@xxczaki](https://github.com/xxczaki))\n- [#3172](https://github.com/mochajs/mocha/issues/3172): Markdown linting ([@boneskull](https://github.com/boneskull))\n- Test & Netlify updates ([@Munter](https://github.com/munter), [@boneskull](https://github.com/boneskull))\n"
  },
  {
    "path": "FUNDING.md",
    "content": "# Fund Usage Guidelines\n\nThis project follows [Collective Funds Guidelines 0.1](https://github.com/collective-funds/guidelines) with the below customizations.\n\n## Rates\n\n- TSC Members: $75.00 USD/hour\n- Project Contributors: $50.00 USD/hour\n\n## Additional notes\n\nThe project funds are collected in the [Mocha collective](https://opencollective.com/mochajs) on [Open Collective](https://opencollective.com/) which is hosted by the [Open Source Collective](https://oscollective.org/).\n\nIn additions to the [Collective Funds Guidelines](https://github.com/collective-funds/guidelines) this project abides by the [Open Source Collective](https://oscollective.org/)'s [Terms of Fiscal Sponsorship](https://docs.oscollective.org/getting-started/terms-of-fiscal-sponsorship).\n\nWhen/if the two are in conflict, the Terms of Fiscal Sponsorship is the one that will be followed.\n"
  },
  {
    "path": "LICENSE",
    "content": "(The MIT License)\n\nCopyright (c) 2011-2024 OpenJS Foundation and contributors, https://openjsf.org\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "MAINTAINERS.md",
    "content": "# Mocha Maintainer's Handbook\n\n## Introduction\n\nHi stranger! We've written this document for:\n\n1. Active maintainers of Mocha\n1. Prospective maintainers of Mocha\n1. Anyone curious about how Mocha's maintainers maintain Mocha\n\nThe purpose of this document is to _describe our processes_.\nWe want to avoid conflicts and confusion around \"unwritten rules\".\nIn our opinion, the most straightforward way to address this is to _write them down_.\nThis _also_ happens to be the most straightforward way to change them!\n\nTo assist in eliminating ambiguity, we will define some terms.\n\n## Terminology\n\nAnyone involved with Mocha will fall into one of these buckets: **user**, **contributor**, and **maintainer**.\n\n### User\n\nA \"user\" for the purpose of this document is any _individual developer_ who consumes Mocha to write and/or execute tests.\nA user interacts with contributors.\nA user interacts with the software, web site, documentation, etc., which these contributors provide.\n\nAs a user, you're expected to follow the [code of conduct](https://github.com/mochajs/mocha/blob/main/.github/CODE_OF_CONDUCT.md) when interacting in Mocha's \"official\" social spaces.\nThis includes:\n\n- Any channel under the `mochajs` Discord\n- Any project under the `mochajs` organization on GitHub\n- Any future social, in-person, or online events which Mocha might organize\n\n### Contributor\n\nThis is the most important thing:\n\n**You don't have to write code to be a contributor!**\n\nA \"contributor\" is any individual who has _given back_ in some way to the project and its community.\nContributions include (but are not limited to):\n\n1. Reporting bugs which follow the reporting guidelines\n1. Suggesting and debating enhancements that have wide applicability\n1. Helping others with Mocha-related questions on [our Discord](https://discord.gg/KeDn2uXhER), [StackOverflow](https://stackoverflow.com), or other sites\n1. Sending pull requests which fix bugs, improve documentation, improve developer experience, improve code quality, and/or implement requested enhancements\n1. Reviewing code on pull requests\n1. Providing design assets\n1. Posting a tutorial on a personal blog or blogging site\n1. Suggesting usages for project funds\n1. Organizing a \"Mocha-branded\" event or workshop\n1. Recruiting more contributors! Don't spam.\n1. Researching the user base, getting feedback, etc. Don't spam.\n\nA contributor is _usually_ a user as well, but this isn't a hard-and-fast rule.\nA contributor is also expected to adhere to the [code of conduct](https://github.com/mochajs/mocha/blob/main/.github/CODE_OF_CONDUCT.md) as a user would.\n\nAs you can see, it's wide open! Think of it another way: if you are _adding value to Mocha_, then you are a contributor.\n\n> Due to the nature of GitHub, it's a challenge to recognize those who've made contributions _elsewhere_ on the web, or even contributions of the \"non-code\" variety.\n> If you know of any great contributions which have gone unnoticed, please bring them to the maintainers' attention!\n\n#### A Note About Donations\n\nA [donation](https://opencollective.com/mochajs) is also a great way to help Mocha if you want to help sustain OSS, but can't find time to contribute in other ways, or just want to say \"thanks!\"\n\nWe love our backers and sponsors! 💕\n\n### Maintainer\n\nA maintainer has certain \"rights\" (or \"permissions\") to the Mocha project and other projects under the `mochajs` organization.\nThere's no way to dance around this: with these rights come increased responsibilities.\n\nHowever, **there is no expectation of a standard of technical ability** to be a maintainer of Mocha.\nThis doesn't imply a lack of technical oversight--every pull request will eventually be reviewed.\n\n**If you think you aren't experienced enough to maintain a project like Mocha, you are incorrect.** The only requirements are the above responsibilities and a desire to help the project.\nIt bears repeating:\n\n**You don't have to write code to be a maintainer!**\n\n> Maintainer is synonymous with \"Collaborator\" and/or \"Owner\" in GitHub parlance.\n\n#### The Responsibilities of a Maintainer\n\nAs a maintainer, you are expected to _not just_ \"follow\" the code of conduct, but embody its values.\nYour public behavior, whether in the physical or virtual world, reflects upon the project and other maintainers.\n\n> If you don't understand the code of conduct, or why it exists, it is _your responsibility_ to educate yourself.\n> This does not imply the CoC is immutable.\n\nFurthermore, a maintainer is a contributor who **contributes regularly**. That can be daily, weekly, or even just a few times a month -- as long as it's regular.\nWe are all people with Real Lives, and for many of us, contributing to OSS is just an occasional hobby!\n\nFinally, a maintainer must help define what makes Mocha \"Mocha\".\nAt minimum, a maintainer must _understand_ the current definition (if a maintainer is not interested in decision-making).\nSome of these questions include:\n\n- What's the scope of Mocha?\n- Where should we focus efforts?\n- What's urgent, what can wait?\n- What can we break? What's off-limits?\n- What user feedback is valuable? What isn't?\n\nAs maintainers, _we work together_ to learn about the nature of these questions. If we try hard enough, we even come to some answers!\n\nA maintainer _must_ also have 2FA enabled on their GitHub account.\n\n> If you think that you aren't familiar with mocha's internals enough to contribute, please watch [this walkthrough video](https://youtu.be/zLayCLcIno0)!\n\n#### The Rights of a Maintainer\n\nYou may choose to do zero or more of these _at their discretion_:\n\n- Merge pull requests\n- Modify issues (closing, adding labels, assigning them other maintainers, etc.)\n- Modify GitHub [Projects](https://github.com/mochajs/mocha/projects)\n- Cancel builds, restart jobs, or otherwise interact with our CI server(s)\n- CRUD operations on GitHub integrations\n- Participate in the decision-making process\n- Add new maintainers to the team\n- Tag releases and publish Mocha to npm\n\n> While maintainers have the ability to commit directly to the `main` branch, _this is to be avoided_ if any other maintainer could reasonably take issue with the change, or the change affects Mocha's API or output.\n> For example, a spelling correction in `CHANGELOG.md` may not require a pull request.\n> A change to a reporter's output most certainly would! Maintainers are trusted to use their best judgement; if unsure, err on the side of caution.\n\n#### Expected Activity Levels\n\nWe generally expect maintainers to average at least:\n\n- Multiple contributions of any kind in a week\n- One meaningful, non-trivial contribution per month\n\nThese are rough averages, not strict minimums!\nIt's totally fine to skip a week or two here and there, as long as you do a little more before or after.\nMeaningful, non-trivial contributions can be a well-thought-out comment, sending a non-straightforward pull request, or anything else that adds real value to the project.\n\nIf you have to step away longer than a couple of weeks, that's totally fine too.\nJust let the other maintainers know ahead of time.\n\n- If you need to step away for up to a month or two, don't sweat it.\n- If we don't hear from you for a month without prior notice, we'll check in with you to see if you want to remain a maintainer.\n- After three months of inactivity, or two without prior notice, we'll likely remove you as a maintainer.\n\nAgain, don't stress about this if you can't always be available.\nYour boss doesn't work here; contribute as often as you reasonably can.\nEven if you step down or are removed, if you can come back and be regularly active we'll happily reinstate you.\n\n#### About \"Owners\"\n\nSome maintainers will have full admin rights to the [mochajs GitHub org](https://github.com/mochajs) and/or will have access to publish to npm.\n\n- Those with publish access must use npm's 2FA.\n- This level of access will be granted by the current owners to those maintainers who have earned the project's trust.\n\n## Mocha's Decision-Making Process\n\nMocha follows a [consensus-seeking decision-making](https://en.wikipedia.org/wiki/Consensus-seeking_decision-making) process.\nIn other words, all maintainers attempt to come to agreement.\nIf that fails, we decide by a simple vote.\n\nActive maintainers will make an effort to solicit feedback from others before making important or potentially controversial decisions.\nGiven the varying geographical distribution and availability of the maintenance team, we resolve to do the best we can to solicit feedback.\nWe will wait at least two weeks for consensus votes in most cases, and a month for especially important decisions.\n\nIn other words, to have your opinion heard, participate regularly.\nThe rest of the team won't wait on feedback that isn't necessarily forthcoming!\n\n## Communication\n\nMaintainers will mainly gather in the [Mocha Discord](https://discord.gg/KeDn2uXhER).\nThis is a _public_ Discord, and _anyone_ can join.\nVideoconference (or audio) calls may happen on a regular or irregular basis, as schedules allow.\nThis is mainly because we have Real Lives and time zones suck.\n\n## Working with Issues & Pull Requests\n\nAll new issues will need to be triaged, and pull requests must be examined.\nMaintainers must understand [Semantic Versioning](http://semver.org) (\"SemVer\"), as Mocha follows it strictly.\n\n> If you see an issue or PR that could use some labels, please add them!\n\n### Semantic Versioning\n\nThe TL;DR of Semantic Versioning is:\n\n- MAJOR version when you make incompatible API changes,\n- MINOR version when you add functionality in a backwards-compatible manner, and\n- PATCH version when you make backwards-compatible bug fixes.\n\nPull requests _must_ have one of these three (3) labels:\n\n- `semver-patch` for backwards-compatible bug fixes, documentation, or anything which does not affect a \"production\" (`npm install mocha`) installation of Mocha\n- `semver-minor` for backwards-compatible new features or usability/interface enhancements\n- `semver-major` for backwards-incompatible (\"breaking\") changes to the API\n\nA PR which introduces a breaking change is considered to be `semver-major`, _regardless_ of whether it's a bug fix, feature, or whatever.\n\nFor the purposes of the above definitions, Mocha has some unique considerations, and includes the following in its definition of \"API\":\n\n1. Mocha's _documented_, programmatic interface which _is not explicitly tagged with `@private`_\n1. Mocha's machine-readable reporter output\n1. Mocha's default settings\n1. Mocha's command-line options\n1. The environments which Mocha supports; this includes:\n   1. Browser versions\n   1. Node.js versions\n   1. Compatibility with popular module loaders (e.g., AMD)\n\n**Err on the side of the user; breaking changes to private APIs will be `semver-major`, if and only if they are known to be consumed by actively developed project(s).**\n\nExamples of a breaking changes might be:\n\n- Throwing an `Error` where one wasn't thrown before\n- Removing a command-line option or alias\n- Removing an environment from the CI configuration\n- Changing the default reporter!\n- Changing defaults in a way which would cause tests which were previously successful to start failing, or a failing test to start passing\n  - The exception is fixing likely false-positives\n  - A good example would be changing the default `timeout` value\n\n## Issue Triage\n\nIssues should be filed according to one of our [GitHub Issue forms](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-issue-forms).\nIf any required information is missing, add the `status: waiting for author` label and politely ask for the missing information.\n\n### Issue Meta\n\nFor all issues, apply the following labels based on which area(s) the issue pertains to:\n\n- `area: async`: Issues around Mocha's asynchronous usage\n- `area: browser`: Issues unique to a browser environment\n- `area: parallel`: Issues around Mocha's parallel mode\n- `area: reporter`: Usually concerning Mocha's output\n- `area: repository tooling`: Issues around Mocha's CI, own test suite, or other internal tooling\n- `area: security`: Involving vulnerabilities, actual or potential\n- `area: windows`: Windows-specific issues, particularly around path discrepancies\n\nAdditionally:\n\n- `good first issue`: If the implementation is likely doable by someone who's never contributed to Mocha (or potentially any other open source project) before\n- `status: duplicate`: If an equivalent issue was already filed, add this label, close as not planned, and comment with something like `duplicate of #<other-issue-number>`\n- `status: in discussion`: Add this whenever the issue is blocked on community input and/or deeper discussions\n- `status: in triage`: Added on new issues; re-add this whenever the issue is awaiting maintainer attention\n- `status: waiting for author`: Add this whenever the issue is blocked on something from the author\n\n### 🐛 Bugs\n\nBug reports should include a way to reproduce the issue that someone who is not deeply familiar with Mocha can work with locally.\n\nDepending on that reproduction, remove `status: in triage` and add the following label(s) in addition to the auto-added `type: bug`:\n\n- If the bug is valid and reproduction works: add `status: accepting prs`\n- If the bug might be valid but the reproduction isn't workable:\n  - Add `status: waiting for author`\n  - Politely comment explaining why the reproduction isn't workable\n- If the bug might be valid but it's not clear whether it's worth it:\n  - Add `status: in discussion`\n  - Explain that it _might_ be worth it and that more community input is needed\n- If the bug is clearly not worth it or valid, explain why, close the issue as not planned, and:\n  - If it isn't a bug at all: add the `invalid` label\n  - If it is roughly a bug but isn't something that can or should be fixed: add the `status: wontfix` label\n\n### 📝 Documentation\n\nDocumentation reports should clearly indicate a gap or problem that should be addressed in documentation.\nTriage documentation issues similar to bugs and/or feature requests - documentation is its own form of product area.\nRemove `status: in triage` and keep the auto-added `area: documentation` label.\n\n### 🚀 Features\n\nFeature requests should include a compelling reason why we should spend the maintenance time on the feature.\nGiven that Mocha is prioritizing stability over growth, this can be a high bar.\n\nDepending on the reasoning, remove `status: in triage` and add the following label(s) in addition to the auto-added `type: feature`:\n\n- If the reasoning is valid and seems worth the maintenance cost: add `status: accepting prs`\n- If the reasoning is unclear:\n  - Add `status: waiting for author`\n  - Politely comment explaining what's missing\n- If the feature might be valid but it's not clear whether it's worth it:\n  - Add `status: in discussion`\n  - Explain that it _might_ be worth it and that more community input is needed\n- If the feature is not valid, explain why, close the issue as not planned, and:\n  - If it isn't a feature request at all: add the `invalid` label\n  - If it is roughly a feature request but isn't something that can or should be implemented: add the `status: wontfix` label\n\n### 🛠 Tooling\n\nIssues filed about improvements to Mocha's internal development processes.\nThese can be more informally discussed by maintainers.\nRemove `status: in triage` and keep the auto-added `area: repository tooling`.\n\n### ❓ Questions\n\nOur issue tracker is not the right place to ask questions.\nIf an issue is filed that seems like it's more of a question, remove `status: in triage`, add the `type: question` label, politely direct the user to the [❓ Got a Question?](./.github/CONTRIBUTING.md#❓-got-a-question) section, and close the issue as not planned.\n\nIf it's _not_ a Mocha problem (people tend not to believe this), you may want to show a counter-example.\nIt's often helpful to direct the issue author to the responsible project, if you can determine what that is.\n\nIf this issue seems to be _repeatedly_ asked, add the `faq` label.\nThis may also apply to questions which receive a lot of 👍 reactions.\n\n### Closing Issues\n\nWrite \"closes #000\" (where 000 is the issue number) or \"resolves #000\" in a commit or PR to have the original issue closed automatically once the PR is merged.\n\nFor any issue which is a duplicate, write \"duplicate of #000\" in a new comment, and close the issue.\n[Read more about marking issues as duplicates](https://help.github.com/articles/about-duplicate-issues-and-pull-requests/).\n\nIf the issue is a support question, and you believe it has been answered, close the issue.\n\nIf the issue is not Mocha-related, and/or a bug cannot be confirmed, label it `invalid` and close.\n\n## Commenting on Issues and Reviewing Pull Requests\n\n**All maintainers should be courteous and kind.** Thank the external contributor for the pull request, even if it is not merged.\nIf the pull request has been opened (and subsequently closed) without discussion in a corresponding issue, let them know that by creating an issue first, they could have saved wasted effort.\n_Clearly and objectively_ explain the reasoning for rejecting any PR.\n\nIf you need more information in an issue, nicely ask the user to provide it.\nRemind them to use the issue/PR templates if they have not.\n\n### Reviewing Code\n\nUse GitHub's code review features.\nRequesting a review from another maintainer _may or may not_ actually result in a review; don't wait on it.\nIf the PR cannot move forward without input from a certain maintainer, _assign them to the PR_.\n\n### The Part About Jerks\n\nThere will be jerks.\n\n#### Rude or Entitled People\n\nThese are users who feel the Mocha project and its maintainers _owe them_ time or support.\nThis is incorrect.\n\nHowever, this behavior is often indicative of someone who is \"new\" to open source.\nMany just don't know better.\nIt is not your _responsibility_ to educate them (again, you owe them nothing).\n\nHere are some suggestions:\n\n1. If u mad, wait 20 minutes before writing a comment.\n1. \"Kill them with kindness\".\n   Explain how they are presenting themselves; maybe link to a good article or two about it.\n1. Don't make it about \"users vs.\n   maintainers\".\n   Treat them like a potential future maintainer.\n1. Avoid adding to the drama.\n   You could try to reach out privately; email may be in their GitHub profile.\n   You will likely never hear from that individual again (problem solved)\n1. If an issue is getting out of control, lock it.\n1. If someone is _repeatedly_ rude and does not correct their mistakes, you may ban them from participating in the `mochajs` org.\n   If you do not have permission to do so, contact one which does (an \"owner\").\n\n#### Code of Conduct Violations\n\n**This section is theoretical, as it's yet to happen**.\n\n1. Inform the individual of the violation; link to the CoC\n1. Follow up with OpenJS Foundation for further guidance\n1. Repeated violators will be banned inasmuch as that is technically possible\n1. No maintainer nor contributor is exempt from the CoC\n\n## Branches\n\n`main` is the only maintained branch in `mochajs/mocha` or any of the other repos.\n**`main` is the only branch to which force-pushing is disallowed.**\n\nMaintainers may push new branches to a repo, as long as they remove them when finished (merging a PR will prompt to do so).\n\nPlease _please_ **_please_** delete old or unused branches.\n\n## Merging PRs\n\nWe prefer to [squash merge](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-commits) PRs.\nRequiring users to keep clean histories for rebasing would be a large ask that we don't feel justifies the benefits.\n\n**Upon acceptance of a PR, you must assign it a milestone.**\n\n### Using Milestones\n\nIf you know that the PR is breaking, assign it to a new or existing milestone correlating with the next major release.\nFor example, if Mocha's current version is v6.5.2, then this milestone would be named `v7.0.0`.\n\nLikewise, if the PR is `semver-minor`, create or use a new milestone correlating to the next _minor_ release, e.g., `v6.6.0`.\n\nIf it's unclear what the next milestone will be, use or create a milestone named `next`.\nThis milestone will be renamed to the new version at release time.\n\nBy using milestones, we can cherry-pick non-breaking changes into minor or patch releases, and keep `main` as the latest version.\n\n**This is subject to change, hopefully.**\n\n## Mocha's Release Process\n\nReleases are managed by [Release Please](https://github.com/googleapis/release-please) and require manual approval after tests pass.\nTo create a new release after merging changes, merge the _`chore(main): release...`_ pull request that its automation has created.\nDoing so will:\n\n1. Create a new GitHub release\n2. Cause a CI job to run on `main` that will publish the package to npm\n\nYou'll then need to go to the `chore(main): release ...` commit _Publish to npm_ job run logs and click the _Review pending deployments_ link.\n\n### Major releases\n\nFor major releases, we follow an even-odd pattern:\n\n- Even versions only update dependencies and avoid breaking functional changes\n- Odd versions can update dependencies and add breaking functional changes\n\nThis results in even versions being quite small but easy to migrate to, and odd versions can usually focus on the functional changes.\n\nFor large releases, we recommend betas, then release candidates (RCs), then a full release.\nBetas are when most features are available, but more will likely be added before full release.\nRCs are almost ready for release, but would benefit from user testing before a full release.\n\nTo start a new major version beta, add `Release-As: 12.0.0-beta.1` to the additional details of your PR commit message.\nThis must be part the last line of the commit message, not the PR description.\nRelease Please respects this property and will update accordingly.\nYou can also set Release Please to prelease mode to increment the beta number.\n\n> **Important:** Always use a dot (`.`) as the separator between the pre-release label and the number (e.g. `beta.1`, not `beta-1`).\n> The `semver` library (used by npm) treats dot-separated numeric identifiers numerically, so `beta.10 > beta.9`.\n> With a dash separator, `beta-10` is a single string identifier and sorts before `beta-9` alphabetically.\n\nTo transition to an RC, add `Release-As: 12.0.0-rc.1` at the end of the PR commit message.\n\nTo transition from betas or RCs to a full release, just change Release Please back to `prerelease: false`.\n\n## About The OpenJS Foundation\n\nThe [OpenJS Foundation](https://js.foundation) retains copyright of all projects underneath the [mochajs org](https://github.com/mochajs).\nThe Foundation does not influence technical decisions nor the project roadmap.\nIt is, however, charged with ensuring the continued vitality and sustainability of projects under its banner.\n\nAs a maintainer, you have access to the resources the OpenJS Foundation provides.\n\n## About OpenCollective\n\nMocha collects donations [via OpenCollective](https://opencollective.com/mochajs). As a maintainer, you may help decide how the funds are used. These decisions are made via a consensus-seeking process, much like any other decision.\n\nExpense transparency is built in to OpenCollective.\n\n---\n\nQuestions? Ask in the [Mocha Discord](https://discord.gg/KeDn2uXhER)!\n"
  },
  {
    "path": "PROJECT_CHARTER.md",
    "content": "# Mocha Charter\n\nThis project charter serves as a statement of scope and objectives for the **Mocha** project.\n\n## §1: Guiding Principles\n\nThe **Mocha** project is part of the [OpenJS Foundation], which operates transparently, openly, collaboratively, and ethically. Project proposals, timelines, and status must not merely be open, but also easily visible to outsiders.\n\n## §2: Scope\n\n**Mocha** is a unopinionated, _general-purpose testing framework_ for the JavaScript community. **Mocha** favors flexibility over rigidity, stability over disruption, and deliberation over agility. **Mocha** aims to do one thing, and do it well. **Mocha** will strive to evolve with the needs of the community, but will make every effort not to abandon its current users in doing so.\n\n### §2.1: In-Scope\n\n- APIs (\"interfaces\") to write and organize tests written in JavaScript or compile-to-JavaScript languages\n- Command-line executable to run tests in a Node.js-based terminal environment\n- API to run tests in a browser environment\n- Output test results and errors (provide \"reporters\") to:\n  - Terminal\n  - File\n  - Browser\n  - Memory\n- APIs to extend functionality\n- File-based and code-based configuration\n- Internal test coverage for all of the above\n- Documentation including (but not limited to):\n  - Website ([https://mochajs.org](https://mochajs.org)) contents and design\n  - Test-writing and test-organizing APIs\n  - Reporters\n  - [Extensible APIs](https://mochajs.org/api)\n  - Tutorials and [code samples](https://github.com/mochajs/mocha-examples)\n  - Command-line execution and options\n  - Browser-based execution and options\n  - [Project administration](https://github.com/mochajs/admin)\n  - [Contribution guide](https://github.com/mochajs/mocha/blob/main/.github/CONTRIBUTING.md)\n- General support for multiple levels of tests, including (but not limited to):\n  - Unit tests\n  - Integration tests\n  - Functional/end-to-end tests\n  - Operational readiness tests\n- Tool configuration for project tests, build, documentation or website deployment\n- Bespoke tools, if needed\n- LTS (long-term support) policies, processes, and release cadence\n- Third-party service integrations (e.g., bots, CI servers, SCM)\n- Project-endorsed spaces for collaboration (chat rooms, mailing lists, forums, etc.)\n- Project-maintained social media, if any\n\n### §2.2: Out-of-Scope\n\n- [Test assertions](https://wikipedia.org/wiki/Test_assertion) and [mocks](https://en.wikipedia.org/wiki/Mock_object) or related\n- Compatibility with other 3rd-party libraries not hosted under GitHub's [mochajs organization](https://github.com/mochajs) unless explicitly stated in [§2: Scope](#2-scope)\n  - Note: _existence of \"official\" code samples does not imply explicit support_\n  - Efforts must be made to retain compatibility with popular libraries, frameworks and tools, but not at the expense of Mocha itself\n- Use within _unmaintained_ versions of Node.js\n- Use within browsers not meeting a threshold decided upon by maintainers\n- Use within non-Node.js or non-browser environments, unless otherwise explicitly stated in [§2: Scope](#2-scope)\n- \"Unofficial\" collaboration or Q&A spaces (including Stack Overflow and Quora)\n- Certain classes of contributions:\n  - Bug fixes or enhancements without associated test coverage\n  - Features having limited general-purpose use (as determined by maintainers)\n  - Bug fixes which \"break\" more users than are affected by the bug itself, _regardless_ of \"correctness\"\n  - Breaking changes to API without demonstrated need, especially those which would cause correct, currently-passing tests to fail\n  - Changes that significantly negatively impact performance without demonstrated need\n  - Code reviews, issue comments or pull requests which are dogmatic, demanding, or excessively critical as to discourage contributions by others\n  - Those which violate Mocha's [Code of Conduct]\n\n## §3: Relationship with OpenJS Foundation CPC\n\nTechnical leadership for the projects within the [OpenJS Foundation] is delegated to the projects through their project charters by the [OpenJS Foundation Cross-Project Council](https://openjsf.org/about/governance/) (CPC). In the case of the Mocha project, it is delegated exclusively to the maintainers of Mocha. The OpenJS Foundation's business leadership is the Board of Directors.\n\nChanges to the following **cannot** unilaterally be applied by project leadership, and must be ratified by the CPC:\n\n- Mocha's Project Charter (this document)\n- Mocha's [Code of Conduct]\n- Mocha's licenses: [MIT](https://github.com/mochajs/mocha/blob/main/LICENSE) (for code) and [CC-BY-4.0](https://github.com/mochajs/mocha/blob/main/docs/LICENSE-CC-BY-4.0) (for documentation/website)\n\n### §3.1: Other Formal Project Relationships\n\nSection Intentionally Left Blank\n\n## §4: Mocha's Governing Body\n\nMocha is governed by its maintainers. See [MAINTAINERS.md] for more information.\n\n## §5: Roles & Responsibilities\n\nThe roles and responsibilities of Mocha's maintainers are described in [MAINTAINERS.md].\n\n### §5.1: Project Operations & Management\n\nProject operations and processes are described in [MAINTAINERS.md].\n\n### §5.2: Decision-making, Voting, and/or Elections\n\nMocha uses a loose consensus-seeking process, described in [MAINTAINERS.md].\n\n### §5.3: Other Project Roles\n\nSection Intentionally Left Blank\n\n## §6: Definitions\n\nSection Intentionally Left Blank\n\n[openjs foundation]: https://openjsf.org\n[maintainers.md]: https://github.com/mochajs/mocha/blob/main/MAINTAINERS.md\n[code of conduct]: https://github.com/mochajs/mocha/blob/main/.github/CODE_OF_CONDUCT.md\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\">\n  <img src=\"docs/src/components/mocha-logo.svg\" alt=\"Mocha test framework logo\"/>\n</p>\n\n<p align=\"center\">☕️ Classic, reliable, trusted test framework for Node.js and the browser ☕️</p>\n\n<div align=\"center\">\n\n<a href=\"https://www.npmjs.com/package/mocha\"><img src=\"https://img.shields.io/npm/v/mocha.svg\" alt=\"NPM Version\"></a>\n<a href=\"https://github.com/mochajs/mocha\"><img src=\"https://img.shields.io/node/v/mocha.svg\" alt=\"Node Version\"></a>\n[![GitHub Actions Build Status](https://github.com/mochajs/mocha/actions/workflows/mocha.yml/badge.svg)](https://github.com/mochajs/mocha/actions/workflows/mocha.yml)\n<a href=\"https://codecov.io/gh/mochajs/mocha\"><img src=\"https://codecov.io/gh/mochajs/mocha/branch/main/graph/badge.svg\" alt=\"Codecov Coverage Status\"></a>\n\n</div>\n\n<div align=\"center\">\n\n<a href=\"https://discord.gg/KeDn2uXhER\"><img alt=\"Chat - Discord\" src=\"https://img.shields.io/badge/Chat-Discord-5765F2.svg\" /></a>\n<a href=\"https://github.com/mochajs/mocha#sponsors\"><img src=\"https://opencollective.com/mochajs/tiers/sponsors/badge.svg\" alt=\"OpenCollective Sponsors\"></a>\n<a href=\"https://github.com/mochajs/mocha#backers\"><img src=\"https://opencollective.com/mochajs/tiers/backers/badge.svg\" alt=\"OpenCollective Backers\"></a>\n[![Collective Funds Guidelines v0.1](https://img.shields.io/badge/collective_funds_guidelines-v0.1-D8E8D4?style=flat&labelColor=3A6457)](https://github.com/collective-funds/guidelines)\n\n</div>\n\n## Links\n\n- **[Documentation](https://mochajs.org)**\n- **[Release Notes / History / Changes](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md)**\n- [Code of Conduct](https://github.com/mochajs/mocha/blob/main/.github/CODE_OF_CONDUCT.md)\n- [Contributing](https://github.com/mochajs/mocha/blob/main/.github/CONTRIBUTING.md)\n- [Development](https://github.com/mochajs/mocha/blob/main/.github/DEVELOPMENT.md)\n- [Discord](https://discord.gg/KeDn2uXhER) (ask questions here!)\n- [Issue Tracker](https://github.com/mochajs/mocha/issues)\n\n## Backers\n\n[Become a backer](https://opencollective.com/mochajs) and show your support to our open source project on [our site](https://mochajs.org/#backers).\n\n<a href=\"https://opencollective.com/mochajs\"><img alt=\"Mocha's backers on Open Collective\" src=\"https://opencollective.com/mochajs/tiers/backers.svg?limit=30&button=false&avatarHeight=46&width=750\"></a>\n\n## Sponsors\n\nDoes your company use Mocha? Ask your manager or marketing team if your company would be interested in supporting our project.\nSupport will allow the maintainers to dedicate more time for maintenance and new features for everyone.\nAlso, your company's logo will show [on GitHub](https://github.com/mochajs/mocha#readme) and on [our site](https://mochajs.org#sponsors) - who doesn't want a little extra exposure?\n[Here's the info](https://opencollective.com/mochajs).\n\n[![MochaJS Sponsor](https://opencollective.com/mochajs/tiers/sponsors/0/avatar)](https://opencollective.com/mochajs/tiers/sponsors/0/website)\n[![MochaJS Sponsor](https://opencollective.com/mochajs/tiers/sponsors/1/avatar)](https://opencollective.com/mochajs/tiers/sponsors/1/website)\n[![MochaJS Sponsor](https://opencollective.com/mochajs/tiers/sponsors/2/avatar)](https://opencollective.com/mochajs/tiers/sponsors/2/website)\n[![MochaJS Sponsor](https://opencollective.com/mochajs/tiers/sponsors/3/avatar)](https://opencollective.com/mochajs/tiers/sponsors/3/website)\n\n## Development\n\nYou might want to know that:\n\n- Mocha is one of the _most-depended-upon_ modules on npm (source: [libraries.io](https://libraries.io/search?order=desc&platforms=NPM&sort=dependents_count)), and\n- Mocha is an _independent_ open-source project, maintained exclusively by volunteers.\n\nYou might want to help:\n\n- New to contributing to Mocha? Check out this list of [good first issues](https://github.com/mochajs/mocha/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n- Mocha could use a hand with [these issues](https://github.com/mochajs/mocha/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22)\n- The [maintainer's handbook](https://github.com/mochajs/mocha/blob/main/MAINTAINERS.md) explains how things get done\n\nFinally, come [chat with the maintainers on Discord](https://discord.gg/KeDn2uXhER) if you want to help with:\n\n- Triaging issues, answering questions\n- Review, merging, and closing pull requests\n- Other project-maintenance-y things\n\n## License\n\nCopyright 2011-2024 OpenJS Foundation and contributors. Licensed [MIT](https://github.com/mochajs/mocha/blob/main/LICENSE).\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Security contact information\n\nTo report a security vulnerability, please use the\n[Tidelift security contact](https://tidelift.com/security).\nTidelift will coordinate the fix and disclosure.\n\n## Escalation\n\nIf you do not receive an acknowledgement of your report\nwithin 6 business days, or if you cannot find a private\nsecurity contact for the project, you may escalate to the\nOpenJS Foundation CNA at `security@lists.openjsf.org`.\n\nIf the project acknowledges your report but does not\nprovide any further response or engagement within 14 days,\nescalation is also appropriate.\n"
  },
  {
    "path": "bin/_mocha",
    "content": "#!/usr/bin/env node\n\"use strict\";\n\n/**\n * This file remains for backwards compatibility only.\n * Don't put stuff in this file.\n * @see module:lib/cli\n */\n\nrequire(\"../lib/cli\").main();\n"
  },
  {
    "path": "bin/mocha.js",
    "content": "#!/usr/bin/env node\n\n\"use strict\";\n\n/**\n * This wrapper executable checks for known node flags and appends them when found,\n * before invoking the \"real\" executable (`lib/cli/cli.js`)\n *\n * @module bin/mocha\n * @private\n */\n\nconst os = require(\"node:os\");\nconst { loadOptions } = require(\"../lib/cli/options\");\nconst {\n  unparseNodeFlags,\n  isNodeFlag,\n  impliesNoTimeouts,\n} = require(\"../lib/cli/node-flags\");\nconst unparse = require(\"yargs-unparser\");\nconst debug = require(\"debug\")(\"mocha:cli:mocha\");\nconst { aliases } = require(\"../lib/cli/run-option-metadata\");\n\nconst mochaArgs = {};\nconst nodeArgs = {};\nconst SIGNAL_OFFSET = 128;\nlet hasInspect = false;\n\nconst opts = loadOptions(process.argv.slice(2));\ndebug(\"loaded opts\", opts);\n\n/**\n * Given option/command `value`, disable timeouts if applicable\n * @param {string} [value] - Value to check\n * @ignore\n */\nconst disableTimeouts = (value) => {\n  if (impliesNoTimeouts(value)) {\n    debug(\"option %s disabled timeouts\", value);\n    mochaArgs.timeout = 0;\n  }\n};\n\n/**\n * If `value` begins with `v8-` and is not explicitly `v8-options`, remove prefix\n * @param {string} [value] - Value to check\n * @returns {string} `value` with prefix (maybe) removed\n * @ignore\n */\nconst trimV8Option = (value) =>\n  value !== \"v8-options\" && /^v8-/.test(value) ? value.slice(3) : value;\n\n// sort options into \"node\" and \"mocha\" buckets\nObject.keys(opts).forEach((opt) => {\n  if (isNodeFlag(opt)) {\n    nodeArgs[trimV8Option(opt)] = opts[opt];\n  } else {\n    mochaArgs[opt] = opts[opt];\n  }\n});\n\n// disable 'timeout' for debugFlags\nObject.keys(nodeArgs).forEach((opt) => disableTimeouts(opt));\nmochaArgs[\"node-option\"] &&\n  mochaArgs[\"node-option\"].forEach((opt) => disableTimeouts(opt));\n\n// Native debugger handling\n// see https://nodejs.org/api/debugger.html#debugger_debugger\n// look for 'inspect' that would launch this debugger,\n// remove it from Mocha's opts and prepend it to Node's opts.\n// A deprecation warning will be printed by node, if applicable.\n// (mochaArgs._ are \"positional\" arguments, not prefixed with - or --)\nif (mochaArgs._) {\n  const i = mochaArgs._.findIndex((val) => val === \"inspect\");\n  if (i > -1) {\n    mochaArgs._.splice(i, 1);\n    disableTimeouts(\"inspect\");\n    hasInspect = true;\n  }\n}\n\nif (mochaArgs[\"node-option\"] || Object.keys(nodeArgs).length || hasInspect) {\n  const { spawn } = require(\"node:child_process\");\n  const mochaPath = require.resolve(\"../lib/cli/cli.js\");\n\n  const nodeArgv =\n    (mochaArgs[\"node-option\"] &&\n      mochaArgs[\"node-option\"].map((v) => \"--\" + v)) ||\n    unparseNodeFlags(nodeArgs);\n\n  if (hasInspect) nodeArgv.unshift(\"inspect\");\n  delete mochaArgs[\"node-option\"];\n\n  debug(\"final node argv\", nodeArgv);\n\n  const args = [].concat(\n    nodeArgv,\n    mochaPath,\n    unparse(mochaArgs, { alias: aliases }),\n  );\n\n  debug(\n    \"forking child process via command: %s %s\",\n    process.execPath,\n    args.join(\" \"),\n  );\n\n  const proc = spawn(process.execPath, args, {\n    stdio: \"inherit\",\n  });\n\n  proc.on(\"exit\", (code, signal) => {\n    process.on(\"exit\", () => {\n      if (signal) {\n        signal =\n          typeof signal === \"string\" ? os.constants.signals[signal] : signal;\n        if (mochaArgs[\"posix-exit-codes\"] === true) {\n          process.exitCode = SIGNAL_OFFSET + signal;\n        }\n        process.kill(process.pid, signal);\n      } else {\n        process.exit(Math.min(code, mochaArgs[\"posix-exit-codes\"] ? 1 : 255));\n      }\n    });\n  });\n\n  // terminate children.\n  process.on(\"SIGINT\", () => {\n    // XXX: a previous comment said this would abort the runner, but I can't see that it does\n    // anything with the default runner.\n    debug(\"main process caught SIGINT\");\n    proc.kill(\"SIGINT\");\n    // if running in parallel mode, we will have a proper SIGINT handler, so the below won't\n    // be needed.\n    if (!args.parallel || args.jobs < 2) {\n      // win32 does not support SIGTERM, so use next best thing.\n      if (os.platform() === \"win32\") {\n        proc.kill(\"SIGKILL\");\n      } else {\n        // using SIGKILL won't cleanly close the output streams, which can result\n        // in cut-off text or a befouled terminal.\n        debug(\"sending SIGTERM to child process\");\n        proc.kill(\"SIGTERM\");\n      }\n    }\n  });\n} else {\n  debug(\"running Mocha in-process\");\n  require(\"../lib/cli/cli\").main([], mochaArgs);\n}\n"
  },
  {
    "path": "browser-entry.js",
    "content": "\"use strict\";\n\n/* eslint no-unused-vars: off */\n\n/**\n * Shim process.stdout.\n */\n\nprocess.stdout = require(\"browser-stdout\")({ label: false });\n\nvar parseQuery = require(\"./lib/browser/parse-query\");\nvar highlightTags = require(\"./lib/browser/highlight-tags\");\nvar Mocha = require(\"./lib/mocha\");\n\n/**\n * Create a Mocha instance.\n *\n * @return {undefined}\n */\n\nvar mocha = new Mocha({ reporter: \"html\" });\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar setInterval = global.setInterval;\nvar clearTimeout = global.clearTimeout;\nvar clearInterval = global.clearInterval;\n\nvar uncaughtExceptionHandlers = [];\n\nvar originalOnerrorHandler = global.onerror;\n\n/**\n * Remove uncaughtException listener.\n * Revert to original onerror handler if previously defined.\n */\n\nprocess.removeListener = function (e, fn) {\n  if (e === \"uncaughtException\") {\n    if (originalOnerrorHandler) {\n      global.onerror = originalOnerrorHandler;\n    } else {\n      global.onerror = function () {};\n    }\n    var i = uncaughtExceptionHandlers.indexOf(fn);\n    if (i !== -1) {\n      uncaughtExceptionHandlers.splice(i, 1);\n    }\n  }\n};\n\n/**\n * Implements listenerCount for 'uncaughtException'.\n */\n\nprocess.listenerCount = function (name) {\n  if (name === \"uncaughtException\") {\n    return uncaughtExceptionHandlers.length;\n  }\n  return 0;\n};\n\n/**\n * Implements uncaughtException listener.\n */\n\nprocess.on = function (e, fn) {\n  if (e === \"uncaughtException\") {\n    global.onerror = function (msg, url, line, col, err) {\n      fn(err || new Error(msg + \" (\" + url + \":\" + line + \":\" + col + \")\"));\n      return !mocha.options.allowUncaught;\n    };\n    uncaughtExceptionHandlers.push(fn);\n  }\n};\n\nprocess.listeners = function (err) {\n  if (err === \"uncaughtException\") {\n    return uncaughtExceptionHandlers;\n  }\n  return [];\n};\n\n// The BDD UI is registered by default, but no UI will be functional in the\n// browser without an explicit call to the overridden `mocha.ui` (see below).\n// Ensure that this default UI does not expose its methods to the global scope.\nmocha.suite.removeAllListeners(\"pre-require\");\n\nvar immediateQueue = [];\nvar immediateTimeout;\n\nfunction timeslice() {\n  var immediateStart = new Date().getTime();\n  while (immediateQueue.length && new Date().getTime() - immediateStart < 100) {\n    immediateQueue.shift()();\n  }\n  if (immediateQueue.length) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  } else {\n    immediateTimeout = null;\n  }\n}\n\n/**\n * High-performance override of Runner.immediately.\n */\n\nMocha.Runner.immediately = function (callback) {\n  immediateQueue.push(callback);\n  if (!immediateTimeout) {\n    immediateTimeout = setTimeout(timeslice, 0);\n  }\n};\n\n/**\n * Function to allow assertion libraries to throw errors directly into mocha.\n * This is useful when running tests in a browser because window.onerror will\n * only receive the 'message' attribute of the Error.\n */\nmocha.throwError = function (err) {\n  uncaughtExceptionHandlers.forEach(function (fn) {\n    fn(err);\n  });\n  throw err;\n};\n\n/**\n * Override ui to ensure that the ui functions are initialized.\n * Normally this would happen in Mocha.prototype.loadFiles.\n */\n\nmocha.ui = function (ui) {\n  Mocha.prototype.ui.call(this, ui);\n  this.suite.emit(\"pre-require\", global, null, this);\n  return this;\n};\n\n/**\n * Setup mocha with the given setting options.\n */\n\nmocha.setup = function (opts) {\n  if (typeof opts === \"string\") {\n    opts = { ui: opts };\n  }\n  if (opts.delay === true) {\n    this.delay();\n  }\n  var self = this;\n  Object.keys(opts)\n    .filter(function (opt) {\n      return opt !== \"delay\";\n    })\n    .forEach(function (opt) {\n      if (Object.prototype.hasOwnProperty.call(opts, opt)) {\n        self[opt](opts[opt]);\n      }\n    });\n  return this;\n};\n\n/**\n * Run mocha, returning the Runner.\n */\n\nmocha.run = function (fn) {\n  var options = mocha.options;\n  mocha.globals(\"location\");\n\n  var query = parseQuery(global.location.search || \"\");\n  if (query.grep) {\n    mocha.grep(query.grep);\n  }\n  if (query.fgrep) {\n    mocha.fgrep(query.fgrep);\n  }\n  if (query.invert) {\n    mocha.invert();\n  }\n\n  return Mocha.prototype.run.call(mocha, function (err) {\n    // The DOM Document is not available in Web Workers.\n    var document = global.document;\n    if (\n      document &&\n      document.getElementById(\"mocha\") &&\n      options.noHighlighting !== true\n    ) {\n      highlightTags(\"code\");\n    }\n    if (fn) {\n      fn(err);\n    }\n  });\n};\n\n/**\n * Expose the process shim.\n * https://github.com/mochajs/mocha/pull/916\n */\n\nMocha.process = process;\n\n/**\n * Expose mocha.\n */\nglobal.Mocha = Mocha;\nglobal.mocha = mocha;\n\n// for bundlers: enable `import {describe, it} from 'mocha'`\n// `bdd` interface only\n// prettier-ignore\n[ \n  'describe', 'context', 'it', 'specify',\n  'xdescribe', 'xcontext', 'xit', 'xspecify',\n  'before', 'beforeEach', 'afterEach', 'after'\n].forEach(function(key) {\n  mocha[key] = global[key];\n});\n\nmodule.exports = mocha;\n"
  },
  {
    "path": "docs/.gitignore",
    "content": ".astro/\ndist/\nnode_modules/\nsrc/content/data/supporters.json\n"
  },
  {
    "path": "docs/.knip.jsonc",
    "content": "{\n  \"$schema\": \"https://unpkg.com/knip@5/schema-jsonc.json\",\n  // Entry points marked with ! are analyzed but not reported as unused\n  \"entry\": [\"src/content/**/*.mdx!\"],\n  \"project\": [\"src/**/*.{ts,js,mjs,cjs,astro}\"],\n  \"astro\": {\n    \"config\": \"astro.config.ts\",\n  },\n  \"rules\": {\n    \"exports\": \"off\",\n  },\n}\n"
  },
  {
    "path": "docs/.prettierrc.json",
    "content": "{\n  \"bracketSpacing\": true\n}\n"
  },
  {
    "path": "docs/README.md",
    "content": "# Mocha Docs: Built on Astro Starlight\n\nThis is the current Mocha documentation website, hosted at [mochajs.org](https://mochajs.org) and built with [Astro Starlight](https://starlight.astro.build).\n\n> For details on the legacy site, see [https://github.com/mochajs/docs-legacy](mochajs/docs-legacy).\n\n## Preview the new site\n\nTo run this site:\n\n```shell\ncd docs\nnpm i\nnpm run generate\nnpm run dev\n```\n"
  },
  {
    "path": "docs/_data/blocklist.json",
    "content": "[\n  \"cheap-writing-service\",\n  \"coin-master-free-spins\",\n  \"cyberflix-tv\",\n  \"device-tricks1\",\n  \"domywriting\",\n  \"emailmarketingservices-io\",\n  \"hurtiglaan-nu\",\n  \"igor-noskov\",\n  \"mochajs\",\n  \"my-true-media\",\n  \"open-apk-file\",\n  \"thetoy\",\n  \"trust-my-paper\",\n  \"writemypaper4me\",\n  \"writerseperhour\",\n  \"yiannakis-ttafounas-ttafounas\"\n]\n"
  },
  {
    "path": "docs/_data/supporters.cjs",
    "content": "/**\n * This script gathers metadata for active supporters of Mocha from OpenCollective's\n * API by aggregating order (\"donation\") information.\n *\n * It's intended to be used with 11ty, but can be run directly. Running directly\n * enables debug output.\n *\n * - gathers logo/avatar images (they are always pngs)\n * - gathers links\n * - sorts by tier and total contributions\n * - validates images\n * - writes images to a temp dir\n * @see https://docs.opencollective.com/help/contributing/development/api\n */\n\n\"use strict\";\n\nconst { writeFile, mkdir, rm } = require(\"node:fs\").promises;\nconst { resolve } = require(\"node:path\");\nconst debug = require(\"debug\")(\"mocha:docs:data:supporters\");\nconst blocklist = new Set(require(\"./blocklist.json\"));\n\n/**\n * In addition to the blocklist, any account slug matching this regex will not\n * be displayed on the website.\n */\nconst BLOCKED_STRINGS =\n  /(?:[ck]a[sz]ino|seo|slot|gambl(?:e|ing)|crypto|follow|buy|cheap|instagram|hacks|tiktok|likes|youtube|subscriber|boost|deposit|mushroom|bingo|broker|promotion|bathroom|landscaping|lawn care|groundskeeping|remediation|esports|links|coupon|review|refer|promocode|rabattkod|jämför|betting|reddit|hire|fortune|equity|download|marketing|comment|rank|scrapcar|lawyer|celeb|concrete|firestick|playground|betking)/i;\n\n/**\n * Add a few Categories exposed by Open Collective to help moderation\n */\nconst BLOCKED_CATEGORIES = [\n  \"adult\",\n  \"casino\",\n  \"credit\",\n  \"gambling\",\n  \"seo\",\n  \"writer\",\n  \"review\",\n];\n\n/**\n * The OC API endpoint\n\n */\nconst API_ENDPOINT = \"https://api.opencollective.com/graphql/v2\";\n\nconst SPONSOR_TIER = \"sponsors\";\nconst BACKER_TIER = \"backers\";\n\n// if this percent of fetches completes, the build will pass\nconst PRODUCTION_SUCCESS_THRESHOLD = 0.9;\n\nconst SUPPORTER_IMAGE_PATH = resolve(__dirname, \"../images/supporters\");\n\nconst SUPPORTER_QUERY = `query account($limit: Int, $offset: Int, $slug: String) {\n  account(slug: $slug) {\n    orders(limit: $limit, offset: $offset, status: ACTIVE, filter: INCOMING) {\n      limit\n      offset\n      totalCount\n      nodes {\n        fromAccount {\n          id\n          name\n          slug\n          website\n          imgUrlMed: imageUrl(height:64)\n          imgUrlSmall: imageUrl(height:32)\n          type\n          categories\n        }\n        tier { slug }\n        totalDonations { value }\n        createdAt\n      }\n    }\n  }\n}`;\n\nconst GRAPHQL_PAGE_SIZE = 1000;\n\nconst invalidSupporters = [];\n\nconst nodeToSupporter = (node) => ({\n  id: node.fromAccount.id,\n  name: node.fromAccount.name,\n  slug: node.fromAccount.slug,\n  website: node.fromAccount.website,\n  imgUrlMed: node.fromAccount.imgUrlMed,\n  imgUrlSmall: node.fromAccount.imgUrlSmall,\n  type: node.fromAccount.type,\n  categories: node.fromAccount.categories,\n  tier: (node.tier && node.tier.slug) || BACKER_TIER,\n  totalDonations: node.totalDonations.value * 100,\n  firstDonation: node.createdAt,\n});\n\nconst fetchImage = process.env.MOCHA_DOCS_SKIP_IMAGE_DOWNLOAD\n  ? async (supporter) => {\n      invalidSupporters.push(supporter);\n    }\n  : async (supporter) => {\n      try {\n        const { avatar: url } = supporter;\n        const response = await fetch(url, {\n          signal: AbortSignal.timeout(30000),\n        });\n        if (response.headers.get(\"content-type\")?.startsWith(\"text/html\")) {\n          throw new TypeError(\n            \"received html and expected a png; outage likely\",\n          );\n        }\n        const imageBuf = Buffer.from(await response.arrayBuffer());\n        debug(\"fetched %s\", url);\n        const filePath = resolve(SUPPORTER_IMAGE_PATH, supporter.id + \".png\");\n        await writeFile(filePath, imageBuf);\n        debug(\"wrote %s\", filePath);\n      } catch (err) {\n        console.error(\n          `failed to load ${supporter.avatar}; will discard ${supporter.tier} \"${supporter.name} (${supporter.slug}). reason:\\n`,\n          err,\n        );\n        invalidSupporters.push(supporter);\n      }\n    };\n\n/**\n * Retrieves donation data from OC\n *\n * Handles pagination\n * @param {string} slug - Collective slug to get donation data from\n * @returns {Promise<Object[]>} Array of raw donation data\n */\nconst getAllOrders = async (slug = \"mochajs\") => {\n  let allOrders = [];\n  const variables = { limit: GRAPHQL_PAGE_SIZE, offset: 0, slug };\n\n  // Handling pagination if necessary (2 pages for ~1400 results in May 2019)\n  while (true) {\n    const response = await fetch(API_ENDPOINT, {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application/json\" },\n      body: JSON.stringify({\n        query: SUPPORTER_QUERY,\n        variables: variables,\n      }),\n    });\n    const result = await response.json();\n    const orders = result.data.account.orders.nodes;\n    allOrders = [...allOrders, ...orders];\n    variables.offset += GRAPHQL_PAGE_SIZE;\n    if (orders.length < GRAPHQL_PAGE_SIZE) {\n      debug(\"retrieved %d orders\", allOrders.length);\n      return allOrders;\n    } else {\n      debug(\n        \"loading page %d of orders...\",\n        Math.floor(variables.offset / GRAPHQL_PAGE_SIZE),\n      );\n    }\n  }\n};\n\nconst isAllowed = ({ name, slug, website, categories }) => {\n  const allowed =\n    !blocklist.has(slug) &&\n    !BLOCKED_STRINGS.test(name) &&\n    !BLOCKED_STRINGS.test(slug) &&\n    !BLOCKED_STRINGS.test(website) &&\n    !categories.some((category) => BLOCKED_CATEGORIES.includes(category));\n\n  if (!allowed) {\n    debug(\"filtering %o\", { categories, name, slug, website });\n  } else {\n    // debug('keeping %o', {categories, name, slug, website}, BLOCKED_STRINGS.test(website));\n  }\n\n  return allowed;\n};\n\nconst getSupporters = async () => {\n  const orders = await getAllOrders();\n  // Deduplicating supporters with multiple orders\n  const uniqueSupporters = new Map();\n\n  const supporters = orders\n    // turn raw query result into a better data structure\n    .map(nodeToSupporter)\n    // aggregate total $ donated by unique supporter (using slug)\n    .reduce((supporters, supporter) => {\n      if (uniqueSupporters.has(supporter.slug)) {\n        uniqueSupporters.get(supporter.slug).totalDonations +=\n          supporter.totalDonations;\n        return supporters;\n      }\n      uniqueSupporters.set(supporter.slug, supporter);\n      return [...supporters, supporter];\n    }, [])\n    // discard spammy supporters\n    .filter(isAllowed)\n    // sort by total $ donated, descending\n    .sort((a, b) => b.totalDonations - a.totalDonations)\n    // determine which url to use depending on tier\n    .reduce(\n      (supporters, supporter) => {\n        if (supporter.tier === BACKER_TIER) {\n          if (supporter.name !== \"anonymous\") {\n            supporters[BACKER_TIER] = [\n              ...supporters[BACKER_TIER],\n              {\n                ...supporter,\n                avatar: encodeURI(supporter.imgUrlSmall),\n              },\n            ];\n          }\n        } else {\n          supporters[SPONSOR_TIER] = [\n            ...supporters[SPONSOR_TIER],\n            {\n              ...supporter,\n              avatar: encodeURI(supporter.imgUrlMed),\n            },\n          ];\n        }\n        return supporters;\n      },\n      {\n        [SPONSOR_TIER]: [],\n        [BACKER_TIER]: [],\n      },\n    );\n\n  await rm(SUPPORTER_IMAGE_PATH, { recursive: true, force: true });\n  debug(\"blasted %s\", SUPPORTER_IMAGE_PATH);\n  await mkdir(SUPPORTER_IMAGE_PATH, { recursive: true });\n  debug(\"created %s\", SUPPORTER_IMAGE_PATH);\n\n  // Fetch images for sponsors and save their image dimensions\n  await Promise.all([\n    ...supporters[SPONSOR_TIER].map(fetchImage),\n    ...supporters[BACKER_TIER].map(fetchImage),\n  ]);\n  debug(\"fetched images\");\n\n  invalidSupporters.forEach((supporter) => {\n    supporters[supporter.tier].splice(\n      supporters[supporter.tier].indexOf(supporter),\n      1,\n    );\n  });\n  debug(\"tossed out invalid supporters\");\n\n  const backerCount = supporters[BACKER_TIER].length;\n  const sponsorCount = supporters[SPONSOR_TIER].length;\n  const totalSupportersCount = backerCount + sponsorCount;\n  const successRate = 1 - invalidSupporters.length / totalSupportersCount;\n\n  debug(\n    \"found %d valid backers and %d valid sponsors (%d total; %d invalid; %d blocked)\",\n    backerCount,\n    sponsorCount,\n    totalSupportersCount,\n    invalidSupporters.length,\n    uniqueSupporters.size - totalSupportersCount,\n  );\n\n  if (successRate < PRODUCTION_SUCCESS_THRESHOLD) {\n    if (process.env.NETLIFY && process.env.CONTEXT !== \"deploy-preview\") {\n      throw new Error(\n        `Failed to meet success threshold ${\n          PRODUCTION_SUCCESS_THRESHOLD * 100\n        }% (was ${\n          successRate * 100\n        }%) for a production deployment; refusing to deploy`,\n      );\n    } else {\n      console.warn(\n        `WARNING: Success rate of ${\n          successRate * 100\n        }% fails to meet production threshold of ${\n          PRODUCTION_SUCCESS_THRESHOLD * 100\n        }%; would fail a production deployment!`,\n      );\n    }\n  }\n  debug(\"supporter image pull completed\");\n\n  // TODO: we'll sunset the classic docs and only have docs.\n  // At that point we'll have supporters.js only used for writing files.\n  if (process.argv.includes(\"--write-supporters-json\")) {\n    await mkdir(\"src/content/data\", { recursive: true });\n    await writeFile(\n      \"src/content/data/supporters.json\",\n      JSON.stringify(supporters, null, 4),\n    );\n  }\n  return supporters;\n};\n\nmodule.exports = getSupporters;\n\nif (require.main === module) {\n  require(\"debug\").enable(\"mocha:docs:data:supporters\");\n  process.on(\"unhandledRejection\", (err) => {\n    throw err;\n  });\n  getSupporters();\n}\n"
  },
  {
    "path": "docs/_redirects",
    "content": "/api/* https://legacy.mochajs.org/api/:splat 301\n/next/* https://mochajs.org/:splat 301\n"
  },
  {
    "path": "docs/astro.config.ts",
    "content": "import { defineConfig } from \"astro/config\";\nimport starlight from \"@astrojs/starlight\";\n\nexport default defineConfig({\n  integrations: [\n    starlight({\n      components: {\n        Footer: \"./src/components/Footer.astro\",\n        Head: \"./src/components/Head.astro\",\n        PageTitle: \"./src/components/PageTitle.astro\",\n      },\n      customCss: [\"./src/style/custom.css\"],\n      logo: {\n        dark: \"./src/components/icon-dark.svg\",\n        light: \"./src/components/icon-light.svg\",\n      },\n      sidebar: [\n        { label: \"Getting Started\", slug: \"getting-started\" },\n        {\n          items: [\n            { label: \"Browsers\", slug: \"running/browsers\" },\n            { label: \"CLI\", slug: \"running/cli\" },\n            { label: \"Configuring\", slug: \"running/configuring\" },\n            { label: \"Editor plugins\", slug: \"running/editor-plugins\" },\n            { label: \"Test globs\", slug: \"running/test-globs\" },\n          ],\n          label: \"Running Mocha\",\n        },\n        {\n          items: [\n            { label: \"Dynamic tests\", slug: \"declaring/dynamic-tests\" },\n            { label: \"Exclusive tests\", slug: \"declaring/exclusive-tests\" },\n            { label: \"Inclusive tests\", slug: \"declaring/inclusive-tests\" },\n            { label: \"Pending tests\", slug: \"declaring/pending-tests\" },\n            { label: \"Retrying tests\", slug: \"declaring/retrying-tests\" },\n          ],\n          label: \"Declaring Tests\",\n        },\n        {\n          items: [\n            { label: \"Arrow functions\", slug: \"features/arrow-functions\" },\n            { label: \"Assertions\", slug: \"features/assertions\" },\n            { label: \"Asynchronous code\", slug: \"features/asynchronous-code\" },\n            { label: \"Diffs\", slug: \"features/diffs\" },\n            { label: \"Error codes\", slug: \"features/error-codes\" },\n            { label: \"Global fixtures\", slug: \"features/global-fixtures\" },\n            { label: \"Hooks\", slug: \"features/hooks\" },\n            { label: \"Parallel mode\", slug: \"features/parallel-mode\" },\n            { label: \"Root hook plugins\", slug: \"features/root-hook-plugins\" },\n            { label: \"Timeouts\", slug: \"features/timeouts\" },\n          ],\n          label: \"Features\",\n        },\n        {\n          collapsed: true,\n          items: [\n            { label: \"About\", slug: \"interfaces/about\" },\n            { label: \"BDD (default)\", slug: \"interfaces/bdd\" },\n            { label: \"Exports\", slug: \"interfaces/exports\" },\n            { label: \"QUnit\", slug: \"interfaces/qunit\" },\n            { label: \"Require\", slug: \"interfaces/require\" },\n            { label: \"TDD\", slug: \"interfaces/tdd\" },\n            { label: \"Third-Party\", slug: \"interfaces/third-party\" },\n          ],\n          label: \"Interfaces\",\n        },\n        {\n          collapsed: true,\n          items: [\n            { label: \"About\", slug: \"reporters/about\" },\n            { label: \"Doc\", slug: \"reporters/doc\" },\n            { label: \"Dot\", slug: \"reporters/dot\" },\n            { label: \"HTML\", slug: \"reporters/html\" },\n            { label: \"JSON Stream\", slug: \"reporters/json-stream\" },\n            { label: \"JSON\", slug: \"reporters/json\" },\n            { label: \"Landing\", slug: \"reporters/landing\" },\n            { label: \"List\", slug: \"reporters/list\" },\n            { label: \"Markdown\", slug: \"reporters/markdown\" },\n            { label: \"Min\", slug: \"reporters/min\" },\n            { label: \"Nyan\", slug: \"reporters/nyan\" },\n            { label: \"Progress\", slug: \"reporters/progress\" },\n            { label: \"Spec (default)\", slug: \"reporters/spec\" },\n            { label: \"Tap\", slug: \"reporters/tap\" },\n            { label: \"Third-Party\", slug: \"reporters/third-party\" },\n            { label: \"XUnit\", slug: \"reporters/xunit\" },\n          ],\n          label: \"Reporters\",\n        },\n        {\n          collapsed: true,\n          items: [\n            {\n              label: \"Compilers deprecation\",\n              slug: \"explainers/compilers-deprecation\",\n            },\n            {\n              label: \"Counting assertions\",\n              slug: \"explainers/count-assertions\",\n            },\n            {\n              label: \"Detecting multiple calls to done()\",\n              slug: \"explainers/detecting-multiple-calls-to-done\",\n            },\n            {\n              label: \"Environment variables\",\n              slug: \"explainers/environment-variables\",\n            },\n            {\n              label: \"Find global leaks\",\n              slug: \"explainers/find-global-leaks\",\n            },\n            {\n              label: \"Global variables\",\n              slug: \"explainers/global-variables\",\n            },\n            {\n              label: \"Node.js native ESM support\",\n              slug: \"explainers/nodejs-native-esm-support\",\n            },\n            {\n              label: \"Programmatic usage\",\n              slug: \"explainers/programmatic-usage\",\n            },\n            {\n              label: \"Related tools\",\n              slug: \"explainers/related-tools\",\n            },\n            {\n              label: \"Run cycle overview\",\n              slug: \"explainers/run-cycle-overview\",\n            },\n            {\n              label: \"Security vulnerability reports\",\n              slug: \"explainers/security-vulnerability-reports\",\n            },\n            {\n              label: \"Shared behaviours\",\n              slug: \"explainers/shared-behaviours\",\n            },\n            {\n              label: \"Spies\",\n              slug: \"explainers/spies\",\n            },\n            {\n              label: \"Stub stdout\",\n              slug: \"explainers/stub-stdout\",\n            },\n            {\n              label: \"Tagging with --grep\",\n              slug: \"explainers/tagging\",\n            },\n            { label: \"Test duration\", slug: \"explainers/test-duration\" },\n            {\n              label: \"Test fixture decision tree\",\n              slug: \"explainers/test-fixture-decision-tree\",\n            },\n            {\n              label: \"Third party reporters\",\n              slug: \"explainers/third-party-reporters\",\n            },\n            {\n              label: \"Third party UIs\",\n              slug: \"explainers/third-party-uis\",\n            },\n          ],\n          label: \"Explainers\",\n        },\n        {\n          label: \"API\",\n          link: \"https://mochajs.org/api\",\n        },\n      ],\n      social: [\n        {\n          icon: \"discord\",\n          label: \"Discord\",\n          href: \"https://discord.gg/KeDn2uXhER\",\n        },\n        {\n          icon: \"github\",\n          label: \"GitHub\",\n          href: \"https://github.com/mochajs/mocha\",\n        },\n      ],\n      title: \"Mocha\",\n    }),\n  ],\n});\n"
  },
  {
    "path": "docs/netlify.toml",
    "content": "[build]\n  command = \"npm run docs\"\n  publish = \"docs/dist/\"\n\n[build.environment]\n  DEBUG = \"mocha:docs*\"\n  NODE_VERSION = \"24\"\n\n[context.deploy-preview]\n  command = \"npm run docs\"\n  publish = \"docs/dist/\"\n"
  },
  {
    "path": "docs/package.json",
    "content": "{\n  \"name\": \"docs\",\n  \"type\": \"module\",\n  \"version\": \"0.0.1\",\n  \"scripts\": {\n    \"astro\": \"astro\",\n    \"build\": \"astro check && astro build\",\n    \"dev\": \"astro dev\",\n    \"docs\": \"cd .. && npm i && cd docs && npm i && npm run generate && npm run build && cp _redirects dist/_redirects\",\n    \"generate\": \"node _data/supporters.cjs --write-supporters-json\",\n    \"prelint:knip\": \"npm install\",\n    \"lint:knip\": \"knip --cache\",\n    \"preview\": \"astro preview\",\n    \"start\": \"astro dev\"\n  },\n  \"dependencies\": {\n    \"@astrojs/check\": \"^0.9.6\",\n    \"@astrojs/starlight\": \"^0.37.1\",\n    \"astro\": \"^5.16.6\",\n    \"starlight-package-managers\": \"^0.12.0\",\n    \"typescript\": \"^5.9.3\"\n  },\n  \"devDependencies\": {\n    \"debug\": \"^4.4.3\",\n    \"knip\": \"^5.83.1\"\n  }\n}\n"
  },
  {
    "path": "docs/public/example/Array.js",
    "content": "\"use strict\";\n\ndescribe(\"Array\", function () {\n  describe(\".push()\", function () {\n    it(\"should append a value\", function () {\n      var arr = [];\n      arr.push(\"foo\");\n      arr.push(\"bar\");\n      expect(arr[0]).to.equal(\"foo\");\n      expect(arr[1]).to.equal(\"bar\");\n    });\n\n    it(\"should return the length\", function () {\n      var arr = [];\n      var n = arr.push(\"foo\");\n      expect(n).to.equal(1);\n      n = arr.push(\"bar\");\n      expect(n).to.equal(2);\n    });\n\n    describe(\"with many arguments\", function () {\n      it(\"should add the values\", function () {\n        var arr = [];\n        arr.push(\"foo\", \"bar\");\n        expect(arr[0]).to.equal(\"foo\");\n        expect(arr[1]).to.equal(\"bar\");\n      });\n    });\n  });\n\n  describe(\".unshift()\", function () {\n    it(\"should prepend a value\", function () {\n      var arr = [1, 2, 3];\n      arr.unshift(\"foo\");\n      expect(arr[0]).to.equal(\"foo\");\n      expect(arr[1]).to.equal(1);\n    });\n\n    it(\"should return the length\", function () {\n      var arr = [];\n      var n = arr.unshift(\"foo\");\n      expect(n).to.equal(1);\n      n = arr.unshift(\"bar\");\n      expect(n).to.equal(2);\n    });\n\n    describe(\"with many arguments\", function () {\n      it(\"should add the values\", function () {\n        var arr = [];\n        arr.unshift(\"foo\", \"bar\");\n        expect(arr[0]).to.equal(\"foo\");\n        expect(arr[1]).to.equal(\"bar\");\n      });\n    });\n  });\n\n  describe(\".pop()\", function () {\n    it(\"should remove and return the last value\", function () {\n      var arr = [1, 2, 3];\n      expect(arr.pop()).to.equal(3);\n      expect(arr.pop()).to.equal(2);\n      expect(arr).to.have.length(1);\n    });\n  });\n\n  describe(\".shift()\", function () {\n    it(\"should remove and return the first value\", function () {\n      var arr = [1, 2, 3];\n      expect(arr.shift()).to.equal(1);\n      expect(arr.shift()).to.equal(2);\n      expect(arr).to.have.length(1);\n    });\n  });\n});\n"
  },
  {
    "path": "docs/public/example/tests.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>Mocha</title>\n    <link rel=\"stylesheet\" href=\"https://unpkg.com/mocha/mocha.css\" />\n    <link rel=\"shortcut icon\" href=\"../favicon.svg\" />\n  </head>\n  <body>\n    <div id=\"mocha\"></div>\n    <script src=\"https://unpkg.com/mocha/mocha.js\"></script>\n    <script src=\"https://unpkg.com/chai@4.5.0/chai.js\"></script>\n    <script>\n      mocha.setup(\"bdd\");\n    </script>\n    <script>\n      expect = chai.expect;\n    </script>\n    <script src=\"Array.js\"></script>\n    <script>\n      mocha.run();\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "docs/src/components/Badges.astro",
    "content": "---\nimport { Image } from \"astro:assets\";\nimport Discord from \"./discord.svg\";\n\nconst badges = [\n  {\n    href: \"http://npmjs.com/package/mocha\",\n    alt: \"npm version\",\n    src: \"https://img.shields.io/npm/v/mocha\",\n  },\n  {\n    href: \"https://discord.gg/KeDn2uXhER\",\n    alt: \"Chat - Discord\",\n    src: Discord,\n  },\n  {\n    href: \"#sponsors\",\n    alt: \"OpenCollective sponsors\",\n    src: \"https://opencollective.com/mochajs/tiers/sponsors/badge.svg\",\n  },\n  {\n    href: \"#backers\",\n    alt: \"OpenCollective backers\",\n    src: \"https://opencollective.com/mochajs/tiers/backers/badge.svg\",\n  },\n];\n---\n\n<div class=\"badges\">\n  {\n    badges.map((badge) => (\n      <a href={badge.href}>\n        {typeof badge.src === \"string\" ? (\n          <img alt={badge.alt} src={badge.src} />\n        ) : (\n          <Image alt={badge.alt} src={badge.src} height=\"20\" width=\"84\" />\n        )}\n      </a>\n    ))\n  }\n</div>\n\n<style>\n  .badges {\n    display: flex;\n    gap: 0.4rem;\n  }\n\n  .badges img {\n    width: 84px;\n    height: 20px;\n  }\n</style>\n"
  },
  {
    "path": "docs/src/components/ClientRedirects.astro",
    "content": "<script>\n  const knownHashes = {\n    \"-allow-uncaught\": \"./running/cli/#--allow-uncaught\",\n    \"-async-only-a\": \"./running/cli/#--async-only--a\",\n    \"-bail-b\": \"./running/cli/#--bail--b\",\n    \"-check-leaks\": \"./running/cli/#--check-leaks\",\n    \"-color-c-colors\": \"./running/cli/#--color--c---colors\",\n    \"-compilers\": \"./running/cli/#--compilers\",\n    \"-config-path\": \"./running/cli/#--config-path\",\n    \"-diff\": \"./running/cli/#--diff\",\n    \"-dry-run\": \"./running/cli/#--dry-run\",\n    \"-enable-source-maps\": \"./running/cli/#--enable-source-maps\",\n    \"-exit\": \"./running/cli/#--exit\",\n    \"-extension-ext\": \"./running/cli/#--extension-ext\",\n    \"-fail-zero\": \"./running/cli/#--fail-zero\",\n    \"-fgrep-string-f-string\": \"./running/cli/#--fgrep-string--f-string\",\n    \"-file-file\": \"./running/cli/#--file-file\",\n    \"-forbid-only\": \"./running/cli/#--forbid-only\",\n    \"-forbid-pending\": \"./running/cli/#--forbid-pending\",\n    \"-full-trace\": \"./running/cli/#--full-trace\",\n    \"-global-variable-name\": \"./running/cli/#--global-variable-name\",\n    \"-grep-regexp-g-regexp\": \"./running/cli/#--grep-regexp--g-regexp\",\n    \"-ignore-filedirectoryglob-exclude-filedirectoryglob\":\n      \"./running/cli/#--ignore-filedirectoryglob---exclude-filedirectoryglob\",\n    \"-inline-diffs\": \"./running/cli/#--inline-diffs\",\n    \"-inspect-inspect-brk-inspect\":\n      \"./running/cli/#--inspect---inspect-brk-inspect\",\n    \"-invert\": \"./running/cli/#--invert\",\n    \"-jobs-count-j-count\": \"./running/cli/#--jobs-count--j-count\",\n    \"-node-option-name-n-name\": \"./running/cli/#--node-option-name--n-name\",\n    \"-opts-path\": \"./running/cli/#--opts-path\",\n    \"-package-path\": \"./running/cli/#--package-path\",\n    \"-parallel-p\": \"./running/cli/#--parallel--p\",\n    \"-pass-on-failing-test-suite\": \"./running/cli/#--pass-on-failing-test-suite\",\n    \"-recursive\": \"./running/cli/#--recursive\",\n    \"-reporter-name-r-name\": \"./running/cli/#--reporter-name--r-name\",\n    \"-reporter-option-option-o-option-reporter-options-option\":\n      \"./running/cli/#--reporter-option-option--o-option---reporter-options-option\",\n    \"-require-module-r-module\": \"./running/cli/#--require-module--r-module\",\n    \"-retries-n\": \"./running/cli/#--retries-n\",\n    \"-slow-ms-s-ms\": \"./#--slow-ms--s-ms\",\n    \"-sort-s\": \"./running/cli/#--sort--s\",\n    \"-timeout-ms-t-ms\": \"./running/cli/#--timeout-ms--t-ms\",\n    \"-ui-name-u-name\": \"./running/cli/#--ui-name--u-name\",\n    \"-watch-files-filedirectoryglob\":\n      \"./running/cli/#--watch-files-filedirectoryglob\",\n    \"-watch-ignore-filedirectoryglob\":\n      \"./running/cli/#--watch-ignore-filedirectoryglob\",\n    \"-watch-w\": \"./running/cli/#--watch--w\",\n    \"about-node-flags\": \"./running/cli/#about-node-flags\",\n    \"about-option-types\": \"./running/cli/#about-option-types\",\n    \"about-v8-flags\": \"./running/cli/#about-v8-flags\",\n    \"arrow-functions\": \"./features/arrow-functions\",\n    assertions: \"./features/assertions\",\n    \"asynchronous-code\": \"./features/asynchronous-code\",\n    \"asynchronous-hooks\": \"./features/hooks/#asynchronous-hooks\",\n    \"available-root-hooks\": \"./features/root-hook-plugins/#available-root-hooks\",\n    backers: \"#backers\",\n    \"bail-is-best-effort\": \"./features/parallel-mode/#bail-is-best-effort\",\n    bdd: \"./interfaces/bdd\",\n    \"browser-configuration\": \"./running/browsers/#browser-configuration\",\n    \"browser-specific-options\": \"./running/browsers/#browser-specific-options\",\n    \"caveats-about-testing-in-parallel\":\n      \"./features/parallel-mode/#caveats-about-testing-in-parallel\",\n    \"command-line-usage\": \"./running/cli\",\n    \"configuration-format\": \"./running/configuring/#configuration-format\",\n    \"configuring-mocha-nodejs\": \"./running/configuring\",\n    \"current-limitations\":\n      \"./explainers/nodejs-native-esm-support#current-limitations\",\n    \"custom-locations\": \"./running/configuring/#custom-locations\",\n    \"defining-a-root-hook-plugin\":\n      \"./features/root-hook-plugins#defining-a-root-hook-plugin\",\n    \"delayed-root-suite\": \"./features/hooks/#root-level-hooks\",\n    \"describing-hooks\": \"./features/hooks/#describing-hooks\",\n    \"detects-multiple-calls-to-done\":\n      \"./explainers/detecting-multiple-calls-to-done\",\n    diffs: \"./features/diffs\",\n    doc: \"./reporters/doc\",\n    \"dot-matrix\": \"./reporters/dot-matrix\",\n    \"dynamically-generating-tests\": \"./declaring/dynamic-tests\",\n    \"editor-plugins\": \"./running/editor-plugins\",\n    emacs: \"./running/editor-plugins/#emacs\",\n    \"environment-variables\": \"./running/configuring/#environment-variables\",\n    \"error-codes\": \"./features/error-codes\",\n    examples: \"./getting-started#next-steps\",\n    \"exclusive-tests\": \"./declaring/exclusive-tests\",\n    \"exclusive-tests-are-disallowed\":\n      \"./features/parallel-mode/#exclusive-tests-are-disallowed\",\n    exports: \"./interfaces/exports\",\n    \"extending-configuration\": \"./running/configuring/#extending-configuration\",\n    \"file-order-is-non-deterministic\":\n      \"./features/parallel-mode/#file-order-is-non-deterministic\",\n    \"getting-started\": \"./getting-started\",\n    \"global-fixtures\": \"./features/global-fixtures\",\n    \"global-setup-fixtures\": \"./features/global-fixtures/#global-setup-fixtures\",\n    \"global-teardown-fixtures\":\n      \"./features/global-fixtures/#global-teardown-fixtures\",\n    grep: \"./running/browsers/#grep\",\n    \"hook-level\": \"./features/timeouts#hook-level\",\n    hooks: \"./features/hooks\",\n    \"html-reporter\": \"./reporters/html\",\n    \"ignoring-config-files\": \"./running/configuring/#ignoring-config-files\",\n    \"inclusive-tests\": \"./declaring/inclusive-tests\",\n    installation: \"./getting-started#1-installation\",\n    interfaces: \"./interfaces/about\",\n    jetbrains: \"./running/editor-plugins/#jetbrains\",\n    json: \"./reporters/json\",\n    \"json-stream\": \"./reporters/json-stream\",\n    \"landing-strip\": \"./reporters/landing\",\n    \"limitations-of-asynchronous-callbacks\":\n      \"./features/asynchronous-code/#limitations-of-asynchronous-callbacks\",\n    \"limited-reporter-api-for-third-party-reporters\":\n      \"./features/parallel-mode/#limited-reporter-api-for-third-party-reporters\",\n    list: \"./reporters/list\",\n    markdown: \"./reporters/markdown\",\n    merging: \"./running/configuring/#merging\",\n    \"migrating-a-library-to-use-root-hook-plugins\":\n      \"./features/root-hook-plugins#migrating-a-library-to-use-root-hook-plugins\",\n    \"migrating-tests-to-use-root-hook-plugins\":\n      \"./features/root-hook-plugins#migrating-tests-to-use-root-hook-plugins\",\n    min: \"./reporters/min\",\n    \"mocha-fixture-wizard\": \"./explainers/test-fixture-decision-tree\",\n    \"mocha-fixture-wizard-diagram\": \"./explainers/test-fixture-decision-tree\",\n    \"mocha-sidebar-vs-code\": \"./running/editor-plugins/#mocha-sidebar-vs-code\",\n    \"more-information\": \"./#more-information\",\n    \"multiple-root-hook-plugins\":\n      \"./features/root-hook-plugins#multiple-root-hook-plugins\",\n    \"multiple-root-hooks-in-a-single-plugin\":\n      \"./features/root-hook-plugins#multiple-root-hooks-in-a-single-plugin\",\n    \"no-browser-support\": \"./features/parallel-mode/#no-browser-support\",\n    \"nodejs-native-esm-support\": \"./explainers/nodejs-native-esm-support\",\n    nyan: \"./reporters/nyan\",\n    \"options-that-differ-slightly-from-cli-options\":\n      \"./running/browsers/#options-that-differ-slightly-from-cli-options\",\n    \"options-that-only-function-in-browser-context\":\n      \"./running/browsers/#options-that-only-function-in-browser-context\",\n    \"parallel-mode\": \"./explainers/run-cycle-overview#parallel-mode\",\n    \"parallel-mode-worker-ids\":\n      \"./features/parallel-mode/#parallel-mode-worker-ids\",\n    \"parallel-tests\": \"./features/parallel-mode\",\n    \"pending-tests\": \"./declaring/pending-tests\",\n    priorities: \"./running/configuring/#priorities\",\n    progress: \"./reporters/progress\",\n    qunit: \"./interfaces/qunit\",\n    \"reporter-limitations\": \"./features/parallel-mode/#reporter-limitations\",\n    reporters: \"./reporters/about\",\n    reporting: \"./running/browsers/#reporting\",\n    require: \"./interfaces/require\",\n    \"retry-tests\": \"./declaring/retrying-tests\",\n    \"root-hook-plugins\": \"./features/root-hook-plugins\",\n    \"root-hook-plugins-can-export-a-function\":\n      \"./features/root-hook-plugins#root-hook-plugins-can-export-a-function\",\n    \"root-hooks-are-not-global\":\n      \"./features/parallel-mode/#root-hooks-are-not-global\",\n    \"root-level-hooks\": \"./features/hooks/#root-level-hooks\",\n    \"run-cycle-overview\": \"./explainers/run-cycle-overview\",\n    \"running-mocha-in-the-browser\": \"./running/browsers\",\n    \"serial-mode\": \"./explainers/run-cycle-overview#serial-mode\",\n    spec: \"./reporters/spec\",\n    sponsors: \"#sponsors\",\n    \"suite-level\": \"./features/timeouts#suite-level\",\n    \"synchronous-code\": \"./features/asynchronous-code/#synchronous-code\",\n    tap: \"./reporters/tap\",\n    tdd: \"./interfaces/tdd\",\n    \"test-duration\": \"./explainers/test-duration\",\n    \"test-duration-variability\":\n      \"./features/parallel-mode/#test-duration-variability\",\n    \"test-fixture-decision-tree-wizard-thing\":\n      \"./explainers/test-fixture-decision-tree\",\n    \"test-level\": \"./features/timeouts#test-level\",\n    textmate: \"./running/editor-plugins/#textmate\",\n    \"the-test-directory\": \"./running/test-globs\",\n    \"third-party-reporters\": \"./reporters/third-party\",\n    timeouts: \"./features/timeouts\",\n    \"troubleshooting-parallel-mode\":\n      \"./features/parallel-mode/#no-browser-support\",\n    \"using-async-await\": \"./features/asynchronous-code/#using-async--await\",\n    wallabyjs: \"./running/editor-plugins/#wallabyjs\",\n    \"when-not-to-use-global-fixtures\":\n      \"./features/global-fixtures/#when-not-to-use-global-fixtures\",\n    \"when-to-use-global-fixtures\":\n      \"./features/global-fixtures/#when-to-use-global-fixtures\",\n    \"with-commonjs\": \"./features/root-hook-plugins#with-commonjs\",\n    \"with-es-modules\": \"./features/root-hook-plugins#with-es-modules\",\n    \"working-with-promises\":\n      \"./features/asynchronous-code/#working-with-promises\",\n    xunit: \"./reporters/xunit\",\n  };\n\n  const hash = window.location.hash.slice(1);\n\n  if (Object.hasOwn(knownHashes, hash)) {\n    window.location.href = [\n      window.location.pathname,\n      knownHashes[hash as keyof typeof knownHashes],\n    ].join(\"./\");\n  }\n</script>\n"
  },
  {
    "path": "docs/src/components/FixtureWizard.astro",
    "content": "<div>\n  <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 854 665\" version=\"1.1\">\n    <title>Mocha Fixture Wizard</title>\n    <g stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\">\n      <g transform=\"translate(2.000000, 3.000000)\">\n        <rect\n          stroke=\"var(--sl-color-mocha-light)\"\n          stroke-width=\"5\"\n          fill=\"var(--sl-color-black)\"\n          fill-rule=\"nonzero\"\n          x=\"360\"\n          y=\"0\"\n          width=\"120\"\n          height=\"60\"\n          rx=\"9\"></rect>\n        <text\n          fill=\"var(--sl-color-white)\"\n          fill-rule=\"nonzero\"\n          font-family=\"HelveticaNeue, Helvetica Neue\"\n          font-size=\"16\"\n          font-weight=\"normal\"\n        >\n          <tspan x=\"388.972\" y=\"27\"> My tests </tspan>\n          <tspan x=\"377.412\" y=\"45\"> need setup! </tspan>\n        </text>\n        <polygon\n          fill=\"var(--sl-color-black)\"\n          stroke=\"#CCCCCC\"\n          stroke-width=\"4\"\n          transform=\"translate(420.000000, 200.000000) rotate(-90.000000) translate(-420.000000, -200.000000) \"\n          points=\"420 100 520 200 420 300 320 200\"></polygon>\n        <text\n          fill=\"var(--sl-color-white)\"\n          fill-rule=\"nonzero\"\n          font-family=\"HelveticaNeue, Helvetica Neue\"\n          font-size=\"16\"\n          font-weight=\"normal\"\n        >\n          <tspan x=\"360.28\" y=\"196.5\"> Setup MUST run </tspan>\n          <tspan x=\"349.76\" y=\"214.5\"> once and only once </tspan>\n        </text>\n        <line\n          x1=\"420\"\n          y1=\"60\"\n          x2=\"420\"\n          y2=\"89.76\"\n          stroke=\"var(--sl-color-gray-4)\"\n          stroke-width=\"2\"></line>\n        <polygon\n          stroke=\"var(--sl-color-gray-4)\"\n          stroke-width=\"2\"\n          fill=\"var(--sl-color-gray-4)\"\n          fill-rule=\"nonzero\"\n          points=\"420 97.76 416 89.76 424 89.76\"></polygon>\n        <polygon\n          fill=\"var(--sl-color-black)\"\n          stroke=\"#CCCCCC\"\n          stroke-width=\"4\"\n          points=\"200 285 300 385 200 485 100 385\"></polygon>\n        <text\n          fill=\"var(--sl-color-white)\"\n          fill-rule=\"nonzero\"\n          font-family=\"HelveticaNeue, Helvetica Neue\"\n          font-size=\"16\"\n          font-weight=\"normal\"\n        >\n          <tspan x=\"132.28\" y=\"381\"> Setup MUST share </tspan>\n          <tspan x=\"145.776\" y=\"399\"> state with tests </tspan>\n        </text>\n        <line\n          x1=\"370\"\n          y1=\"250\"\n          x2=\"256.72\"\n          y2=\"330.24\"\n          stroke=\"var(--sl-color-gray-4)\"\n          stroke-width=\"2\"></line>\n        <g transform=\"translate(280.000000, 274.000000)\">\n          <rect fill=\"var(--sl-color-black)\" x=\"0\" y=\"0\" width=\"58\" height=\"36\"\n          ></rect>\n          <text\n            fill-rule=\"nonzero\"\n            font-family=\"HelveticaNeue, Helvetica Neue\"\n            font-size=\"16\"\n            font-weight=\"normal\"\n            fill=\"var(--sl-color-white)\"\n          >\n            <tspan x=\"14.244\" y=\"23.5\"> YES </tspan>\n          </text>\n        </g>\n        <polygon\n          stroke=\"var(--sl-color-gray-4)\"\n          stroke-width=\"2\"\n          fill=\"var(--sl-color-gray-4)\"\n          fill-rule=\"nonzero\"\n          points=\"251.82 333.71 256.04 325.82 256.72\n      330.24 260.66 332.35\"\n        ></polygon>\n        <a href=\"#root-hook-plugins\">\n          <g transform=\"translate(0.000000, 580.000000)\">\n            <rect\n              fill=\"var(--sl-color-black)\"\n              stroke=\"var(--sl-color-mocha-light)\"\n              stroke-width=\"4\"\n              x=\"0\"\n              y=\"0\"\n              width=\"180\"\n              height=\"80\"\n              rx=\"12\"></rect>\n            <text\n              fill=\"var(--sl-color-white)\"\n              fill-rule=\"nonzero\"\n              font-family=\"HelveticaNeue-Bold, Helvetica Neue\"\n              font-size=\"16\"\n              font-weight=\"bold\"\n            >\n              <tspan x=\"11.828\" y=\"37\"> Use Root Hooks and </tspan>\n              <tspan x=\"14.676\" y=\"56\"> Avoid Parallel Mode </tspan>\n            </text>\n          </g>\n        </a>\n        <line\n          x1=\"150\"\n          y1=\"435\"\n          x2=\"93.15\"\n          y2=\"572.39\"\n          stroke=\"var(--sl-color-gray-4)\"\n          stroke-width=\"2\"></line>\n        <polygon\n          stroke=\"var(--sl-color-gray-4)\"\n          stroke-width=\"2\"\n          fill=\"var(--sl-color-gray-4)\"\n          fill-rule=\"nonzero\"\n          points=\"90.85 577.93 90.22 569.01 93.15 572.39 97.61 572.07\"\n        ></polygon>\n        <line\n          x1=\"250\"\n          y1=\"435\"\n          x2=\"306.85\"\n          y2=\"572.39\"\n          stroke=\"var(--sl-color-gray-4)\"\n          stroke-width=\"2\"></line>\n        <polygon\n          stroke=\"var(--sl-color-gray-4)\"\n          stroke-width=\"2\"\n          fill=\"var(--sl-color-gray-4)\"\n          fill-rule=\"nonzero\"\n          points=\"309.15 577.93 302.39 572.07 306.85 572.39 309.78 569.01\"\n        ></polygon>\n        <a href=\"#global-fixtures\">\n          <g transform=\"translate(220.000000, 580.000000)\">\n            <rect\n              fill=\"var(--sl-color-black)\"\n              stroke=\"var(--sl-color-mocha-light)\"\n              stroke-width=\"4\"\n              x=\"0\"\n              y=\"0\"\n              width=\"180\"\n              height=\"80\"\n              rx=\"12\"></rect>\n            <text\n              fill=\"var(--sl-color-white)\"\n              fill-rule=\"nonzero\"\n              font-family=\"HelveticaNeue-Bold, Helvetica Neue\"\n              font-size=\"16\"\n              font-weight=\"bold\"\n            >\n              <tspan x=\"15.648\" y=\"45\"> Use Global Fixtures </tspan>\n            </text>\n          </g>\n        </a>\n        <polygon\n          fill=\"var(--sl-color-black)\"\n          stroke=\"#CCCCCC\"\n          stroke-width=\"4\"\n          points=\"650 285 750 385 650 485 550 385\"></polygon>\n        <text\n          fill=\"var(--sl-color-white)\"\n          fill-rule=\"nonzero\"\n          font-family=\"HelveticaNeue, Helvetica Neue\"\n          font-size=\"16\"\n          font-weight=\"normal\"\n        >\n          <tspan x=\"580.352\" y=\"381\"> Should setup affect </tspan>\n          <tspan x=\"569.544\" y=\"399\"> tests across ALL files? </tspan>\n        </text>\n        <line\n          x1=\"470\"\n          y1=\"250\"\n          x2=\"593.11\"\n          y2=\"330.49\"\n          stroke=\"var(--sl-color-gray-4)\"\n          stroke-width=\"2\"></line>\n        <polygon\n          stroke=\"var(--sl-color-gray-4)\"\n          stroke-width=\"2\"\n          fill=\"var(--sl-color-gray-4)\"\n          fill-rule=\"nonzero\"\n          points=\"598.13 333.78 589.24 332.75 593.11 330.49 593.62 326.05\"\n        ></polygon>\n        <a href=\"#root-hook-plugins\">\n          <g transform=\"translate(444.000000, 580.000000)\">\n            <rect\n              fill=\"var(--sl-color-black)\"\n              stroke=\"var(--sl-color-mocha-light)\"\n              stroke-width=\"4\"\n              x=\"0\"\n              y=\"0\"\n              width=\"180\"\n              height=\"80\"\n              rx=\"12\"></rect>\n            <text\n              fill=\"var(--sl-color-white)\"\n              fill-rule=\"nonzero\"\n              font-family=\"HelveticaNeue-Bold, Helvetica Neue\"\n              font-size=\"16\"\n              font-weight=\"bold\"\n            >\n              <tspan x=\"26.776\" y=\"45\"> Use Root Hooks </tspan>\n            </text>\n          </g>\n        </a>\n        <a href=\"#hooks\">\n          <g transform=\"translate(670.000000, 580.000000)\">\n            <rect\n              fill=\"var(--sl-color-black)\"\n              stroke=\"var(--sl-color-mocha-light)\"\n              stroke-width=\"4\"\n              x=\"0\"\n              y=\"0\"\n              width=\"180\"\n              height=\"80\"\n              rx=\"12\"></rect>\n            <text\n              fill=\"var(--sl-color-white)\"\n              fill-rule=\"nonzero\"\n              font-family=\"HelveticaNeue-Bold, Helvetica Neue\"\n              font-size=\"16\"\n              font-weight=\"bold\"\n            >\n              <tspan x=\"27.344\" y=\"45\"> Use Plain Hooks </tspan>\n            </text>\n          </g>\n        </a>\n        <line\n          x1=\"600\"\n          y1=\"435\"\n          x2=\"537.41\"\n          y2=\"572.5\"\n          stroke=\"var(--sl-color-gray-4)\"\n          stroke-width=\"2\"></line>\n        <g transform=\"translate(91.000000, 486.000000)\">\n          <rect fill=\"var(--sl-color-black)\" x=\"0\" y=\"0\" width=\"58\" height=\"36\"\n          ></rect>\n          <text\n            fill-rule=\"nonzero\"\n            font-family=\"HelveticaNeue, Helvetica Neue\"\n            font-size=\"16\"\n            font-weight=\"normal\"\n            fill=\"var(--sl-color-white)\"\n          >\n            <tspan x=\"14.244\" y=\"23.5\"> YES </tspan>\n          </text>\n        </g>\n        <g transform=\"translate(506.000000, 272.000000)\">\n          <rect fill=\"var(--sl-color-black)\" x=\"0\" y=\"0\" width=\"58\" height=\"36\"\n          ></rect>\n          <text\n            fill-rule=\"nonzero\"\n            font-family=\"HelveticaNeue, Helvetica Neue\"\n            font-size=\"16\"\n            font-weight=\"normal\"\n            fill=\"var(--sl-color-white)\"\n          >\n            <tspan x=\"17.144\" y=\"24\"> NO </tspan>\n          </text>\n        </g>\n        <g transform=\"translate(252.000000, 485.000000)\">\n          <rect fill=\"var(--sl-color-black)\" x=\"0\" y=\"0\" width=\"58\" height=\"36\"\n          ></rect>\n          <text\n            fill-rule=\"nonzero\"\n            font-family=\"HelveticaNeue, Helvetica Neue\"\n            font-size=\"16\"\n            font-weight=\"normal\"\n            fill=\"var(--sl-color-white)\"\n          >\n            <tspan x=\"17.144\" y=\"24\"> NO </tspan>\n          </text>\n        </g>\n        <polygon\n          stroke=\"var(--sl-color-gray-4)\"\n          stroke-width=\"2\"\n          fill=\"var(--sl-color-gray-4)\"\n          fill-rule=\"nonzero\"\n          points=\"534.93 577.96 534.6 569.03 537.41 572.5 541.88 572.34\"\n        ></polygon>\n        <line\n          x1=\"700\"\n          y1=\"435\"\n          x2=\"756.85\"\n          y2=\"572.39\"\n          stroke=\"var(--sl-color-gray-4)\"\n          stroke-width=\"2\"></line>\n        <polygon\n          stroke=\"var(--sl-color-gray-4)\"\n          stroke-width=\"2\"\n          fill=\"var(--sl-color-gray-4)\"\n          fill-rule=\"nonzero\"\n          points=\"759.15 577.93 752.39 572.07 756.85 572.39 759.78 569.01\"\n        ></polygon>\n        <g transform=\"translate(540.000000, 485.000000)\">\n          <rect fill=\"var(--sl-color-black)\" x=\"0\" y=\"0\" width=\"58\" height=\"36\"\n          ></rect>\n          <text\n            fill-rule=\"nonzero\"\n            font-family=\"HelveticaNeue, Helvetica Neue\"\n            font-size=\"16\"\n            font-weight=\"normal\"\n            fill=\"var(--sl-color-white)\"\n          >\n            <tspan x=\"14.244\" y=\"23.5\"> YES </tspan>\n          </text>\n        </g>\n        <g transform=\"translate(699.000000, 489.000000)\">\n          <rect fill=\"var(--sl-color-black)\" x=\"0\" y=\"0\" width=\"58\" height=\"36\"\n          ></rect>\n          <text\n            fill-rule=\"nonzero\"\n            font-family=\"HelveticaNeue, Helvetica Neue\"\n            font-size=\"16\"\n            font-weight=\"normal\"\n            fill=\"var(--sl-color-white)\"\n          >\n            <tspan x=\"17.144\" y=\"24\"> NO </tspan>\n          </text>\n        </g>\n      </g>\n    </g>\n  </svg>\n</div>\n"
  },
  {
    "path": "docs/src/components/Footer.astro",
    "content": "---\nimport { Image } from \"astro:assets\";\n\nimport openJsfLogo from \"./openjsf-logo.svg\";\n---\n\n<footer>\n  <div id=\"copyright-notice\">\n    <p>\n      <a rel=\"home\" href=\"https://mochajs.org/\">mochajs.org</a> is licensed under\n      a\n      <a\n        href=\"https://creativecommons.org/licenses/by/4.0/\"\n        rel=\"license external noopener\"\n      >\n        Creative Commons Attribution 4.0 International License</a\n      >.\n    </p>\n\n    <p>\n      Copyright\n      <a href=\"https://openjsf.org\" rel=\"external noopener\">\n        OpenJS Foundation</a\n      >\n      and Mocha contributors. All rights reserved. The\n      <a href=\"https://openjsf.org\" rel=\"external noopener\">\n        OpenJS Foundation</a\n      >\n      has registered trademarks and uses trademarks. For a list of trademarks of\n      the\n      <a href=\"https://openjsf.org\" rel=\"external noopener\">\n        OpenJS Foundation</a\n      >, please see our\n      <a href=\"https://trademark-policy.openjsf.org/\" rel=\"external noopener\">\n        Trademark Policy</a\n      >\n      and\n      <a href=\"https://trademark-list.openjsf.org/\" rel=\"external noopener\">\n        Trademark List</a\n      >. Trademarks and logos not indicated on the\n      <a href=\"https://trademark-list.openjsf.org\" rel=\"external noopener\">\n        list of OpenJS Foundation trademarks</a\n      >\n      are trademarks™ or registered® trademarks of their respective holders. Use\n      of them does not imply any affiliation with or endorsement by them.\n    </p>\n  </div>\n\n  <div class=\"footer-bottom\">\n    <div id=\"external-links\">\n      <div class=\"openjsf-logo\">\n        <a\n          title=\"Mocha is an OpenJS Foundation Project\"\n          href=\"https://openjsf.org\"\n          rel=\"external noopener\"\n        >\n          <Image\n            alt=\"OpenJS Foundation Logo\"\n            loading=\"lazy\"\n            src={openJsfLogo}\n            width=\"120\"\n          />\n        </a>\n      </div>\n\n      <ul id=\"openjsf-links\">\n        <li>\n          <a href=\"https://openjsf.org/\" rel=\"external noopener\"\n            >The OpenJS Foundation</a\n          >\n        </li>\n        <li>\n          <a href=\"https://terms-of-use.openjsf.org/\" rel=\"external noopener\"\n            >Terms of Use</a\n          >\n        </li>\n        <li>\n          <a href=\"https://privacy-policy.openjsf.org/\" rel=\"external noopener\"\n            >Privacy Policy</a\n          >\n        </li>\n        <li>\n          <a href=\"https://bylaws.openjsf.org/\" rel=\"external noopener\"\n            >OpenJS Foundation Bylaws</a\n          >\n        </li>\n        <li>\n          <a\n            href=\"https://trademark-policy.openjsf.org/\"\n            rel=\"external noopener\">Trademark Policy</a\n          >\n        </li>\n        <li>\n          <a href=\"https://trademark-list.openjsf.org/\" rel=\"external noopener\"\n            >Trademark List</a\n          >\n        </li>\n        <li>\n          <a\n            href=\"https://www.linuxfoundation.org/cookies/\"\n            rel=\"external noopener\">Cookie Policy</a\n          >\n        </li>\n      </ul>\n    </div>\n\n    <div class=\"build-credits\">\n      <div id=\"netlify-badge\">\n        <a href=\"https://www.netlify.com\">\n          <img\n            alt=\"Built with Netlify (Netlify logo)\"\n            loading=\"lazy\"\n            src=\"https://www.netlify.com/img/global/badges/netlify-color-accent.svg\"\n          />\n        </a>\n      </div>\n\n      <dl id=\"last-modified\" class=\"dl-inline\">\n        <dt>Last updated</dt>\n        <dd>\n          <time\n            itemprop=\"lastModified\"\n            datetime=\"{{ 'now' | date: '%Y-%m-%dT%H:%M:%SZ' }}\"\n          >\n            {new Date().toUTCString()}\n          </time>\n        </dd>\n      </dl>\n    </div>\n  </div>\n</footer>\n\n<style>\n  footer {\n    color: var(--sl-color-gray-3);\n    font-size: 0.8em;\n    display: flex;\n    gap: 1rem;\n    flex-direction: column;\n  }\n\n  footer a {\n    color: var(--sl-color-accent-text);\n  }\n\n  footer p {\n    margin-bottom: 1rem;\n  }\n\n  #copyright-notice {\n    border-top: 1px solid var(--sl-color-accent-low);\n    padding-top: 2.5rem;\n    margin-top: 1.5rem;\n  }\n\n  #external-links {\n    gap: 1rem;\n    width: 100%;\n  }\n\n  .openjsf-logo {\n    margin-bottom: 0.5rem;\n  }\n\n  #openjsf-links {\n    column-count: 2;\n    column-gap: 2rem;\n    column-rule: 1px solid var(--sl-color-accent-low);\n    font-size: 0.9em;\n    list-style: none;\n    max-width: 35rem;\n    padding-left: 0;\n  }\n\n  #openjsf-links li {\n    display: inline-block;\n    padding: 0.15rem 0.5rem 0.15rem 0;\n  }\n\n  .build-credits {\n    display: flex;\n    flex-direction: column;\n    margin: 2rem 0 1rem;\n  }\n\n  .dl-inline dt,\n  .dl-inline dd {\n    display: inline;\n    margin: 0;\n  }\n\n  .dl-inline dt:after {\n    content: \": \";\n  }\n\n  .dl-inline dd + dt:before {\n    content: \"\";\n    display: block;\n  }\n\n  #last-modified {\n    font-style: italic;\n    font-size: 0.8em;\n    white-space: nowrap;\n  }\n\n  @media (width >= 819px) {\n    .footer-bottom {\n      align-items: end;\n      display: flex;\n    }\n\n    .build-credits {\n      margin: 0;\n      text-align: right;\n    }\n  }\n</style>\n"
  },
  {
    "path": "docs/src/components/Head.astro",
    "content": "---\nimport type { Props } from '@astrojs/starlight/props'\nimport Default from '@astrojs/starlight/components/Head.astro'\n\nimport thumbnail from \"./mocha-thumbnail.svg\";\n---\n\n<Default {...Astro.props}><slot /></Default>\n\n<meta property=\"og:image\" content={thumbnail.src} />\n<meta name=\"twitter:image\" content={thumbnail.src} />\n"
  },
  {
    "path": "docs/src/components/HomepagePageTitle.astro",
    "content": "---\nimport { Image } from \"astro:assets\";\n\nimport logo from \"./mocha-logo.svg\";\n---\n\n<h1 class=\"page-title\">\n  <Image alt=\"Mocha\" class=\"mocha-logo\"  src={logo} />\n  <span class=\"tags\">classic, reliable, trusted</span>\n</h1>\n\n<style>\n  @keyframes fadein {\n    from {\n      opacity: 0;\n    }\n\n    to {\n      opacity: 1;\n    }\n  }\n\n  @keyframes slideright {\n    from {\n      transform: translateY(-2rem);\n    }\n\n    to {\n      transform: translateY(0);\n    }\n  }\n\n  .page-title {\n    --logoSize: 12rem;\n    align-items: center;\n    display: flex;\n    flex-direction: column;\n  }\n\n  .mocha-logo {\n    height: var(--logoSize);\n    width: var(--logoSize);\n    z-index: 1;\n  }\n\n\n  .tags {\n    animation:\n      fadein 1s forwards,\n      slideright 1s forwards;\n    color: var(--sl-color-accent-text);\n    display: block;\n    font-size: 2rem;\n    font-weight: 200;\n    letter-spacing: 2px;\n    margin-bottom: 0.5rem;\n  }\n\n  @media (width >= 819px) {\n    @keyframes slideright {\n      from {\n        transform: translateX(-3rem);\n      }\n\n      to {\n        transform: translateX(0);\n      }\n    }\n\n    .page-title {\n      flex-direction: row;\n      --logoSize: 16rem;\n    }\n  }\n</style>\n"
  },
  {
    "path": "docs/src/components/PageTitle.astro",
    "content": "---\nimport Default from \"@astrojs/starlight/components/PageTitle.astro\";\nimport type { ComponentProps } from \"astro/types\";\n\nimport HomepagePageTitle from \"./HomepagePageTitle.astro\";\n\ntype Props = ComponentProps<typeof Default>;\n\nconst isHomepage = Astro.props.slug === \"\";\n---\n\n{isHomepage ? <HomepagePageTitle /> : <Default {...Astro.props} />}\n"
  },
  {
    "path": "docs/src/components/Supporters.astro",
    "content": "---\ninterface Supporter {\n  imgUrlMed: string;\n  imgUrlSmall: string;\n  name: string;\n  website: string;\n}\n\ninterface Props {\n  data: Supporter[];\n  size: \"small\" | \"medium\";\n}\n\nconst { size, data } = Astro.props;\n---\n\n<div class:list={[\"supporters\", `supporters-${size}`]}>\n  {\n    data.map((supporter) => (\n      <a class=\"supporter\" href={supporter.website}>\n        <img\n          alt={supporter.name}\n          class=\"supporter-image\"\n          src={\n            size === \"small\"\n              ? supporter.imgUrlSmall\n              : supporter.imgUrlMed\n          }\n        />\n      </a>\n    ))\n  }\n</div>\n\n<style>\n  .supporters {\n    display: flex;\n    gap: var(--supporterSpacing);\n    padding: var(--supporterSpacing) 0;\n  }\n\n  .supporters-small {\n    --supporterSpacing: 0.25rem;\n    flex-wrap: wrap;\n    justify-content: center;\n  }\n\n  .supporters-medium {\n    display: flex;\n    --supporterSpacing: 1rem;\n    align-items: center;\n    flex-direction: column;\n  }\n\n  .supporter {\n    background: var(--mocha-color-backdrop);\n    padding: var(--supporterSpacing);\n    user-select: none;\n  }\n\n  .supporters-small img.supporter-image {\n    height: 2rem;\n    width: 2rem;\n    object-fit: contain;\n  }\n\n  .supporters-medium img.supporter-image {\n    height: 6rem;\n    width: 20rem;\n    object-fit: contain;\n  }\n</style>\n"
  },
  {
    "path": "docs/src/content/config.ts",
    "content": "import { defineCollection } from \"astro:content\";\nimport { docsSchema } from \"@astrojs/starlight/schema\";\n\nexport const collections = {\n  docs: defineCollection({ schema: docsSchema() }),\n};\n"
  },
  {
    "path": "docs/src/content/data/sponsors.json",
    "content": "[\n  {\n    \"href\": \"https://localizejs.com\",\n    \"image\": \"https://images.opencollective.com/localize/bb2cd4d/logo/256.png\",\n    \"title\": \"Localize\"\n  },\n  {\n    \"href\": \"https://route4me.com\",\n    \"image\": \"https://images.opencollective.com/route4me/71fb6fa/avatar/256.png\",\n    \"title\": \"Route4Me Route Planner\"\n  }\n]\n"
  },
  {
    "path": "docs/src/content/docs/declaring/dynamic-tests.mdx",
    "content": "---\ndescription: Describing tests cases based on dynamic data.\ntitle: Dynamic Tests\n---\n\nGiven Mocha's use of function expressions to define suites and test cases, it's straightforward to generate your tests dynamically.\nNo special syntax is required--plain old JavaScript can be used to achieve functionality similar to \"parameterized\" tests, which you may have seen in other frameworks.\n\nTake the following example:\n\n```js\nconst assert = require(\"assert\");\n\nfunction add(args) {\n  return args.reduce((prev, curr) => prev + curr, 0);\n}\n\ndescribe(\"add()\", function () {\n  const tests = [\n    { args: [1, 2], expected: 3 },\n    { args: [1, 2, 3], expected: 6 },\n    { args: [1, 2, 3, 4], expected: 10 },\n  ];\n\n  tests.forEach(({ args, expected }) => {\n    it(`correctly adds ${args.length} args`, function () {\n      const res = add(args);\n      assert.strictEqual(res, expected);\n    });\n  });\n});\n```\n\nThe above code will produce a suite with three specs:\n\n```bash\n$ mocha\n\n  add()\n    ✓ correctly adds 2 args\n    ✓ correctly adds 3 args\n    ✓ correctly adds 4 args\n```\n\nTests added inside a `.forEach` handler often don't play well with editor plugins, especially with \"right-click run\" features.\nAnother way to parameterize tests is to generate them with a closure.\nThis following example is equivalent to the one above:\n\n```js\ndescribe(\"add()\", function () {\n  const testAdd = ({ args, expected }) =>\n    function () {\n      const res = add(args);\n      assert.strictEqual(res, expected);\n    };\n\n  it(\"correctly adds 2 args\", testAdd({ args: [1, 2], expected: 3 }));\n  it(\"correctly adds 3 args\", testAdd({ args: [1, 2, 3], expected: 6 }));\n  it(\"correctly adds 4 args\", testAdd({ args: [1, 2, 3, 4], expected: 10 }));\n});\n```\n\nWith `top-level await` you can collect your test data in a dynamic and asynchronous way while the test file is being loaded.\n\nSee also [`--delay`](/features/hooks#delayed-root-suite) for CommonJS modules without `top-level await`.\n\n```js\n// testfile.mjs\nimport assert from \"assert\";\n\n// top-level await: Node >= v14.8.0 with ESM test file\nconst tests = await new Promise((resolve) => {\n  setTimeout(resolve, 5000, [\n    { args: [1, 2], expected: 3 },\n    { args: [1, 2, 3], expected: 6 },\n    { args: [1, 2, 3, 4], expected: 10 },\n  ]);\n});\n\n// in suites, async callbacks are **not** supported\ndescribe(\"add()\", function () {\n  tests.forEach(({ args, expected }) => {\n    it(`correctly adds ${args.length} args`, function () {\n      const res = args.reduce((sum, curr) => sum + curr, 0);\n      assert.strictEqual(res, expected);\n    });\n  });\n});\n```\n"
  },
  {
    "path": "docs/src/content/docs/declaring/exclusive-tests.mdx",
    "content": "---\ndescription: Describing test cases that should be run to the exclusion of other tests.\ntitle: Exclusive Tests\n---\n\n:::caution\nExclusive tests are incompatible with [parallel mode](/features/parallel-mode).\n:::\n\nThe exclusivity feature allows you to run _only_ the specified suite or test-case\nby appending `.only()` to the function.\nHere's an example of executing only a particular suite:\n\n```js\ndescribe(\"Array\", function () {\n  describe.only(\"#indexOf()\", function () {\n    // ...\n  });\n});\n```\n\n_Note_: All nested suites will still be executed.\n\nHere's an example of executing an individual test case:\n\n```js\ndescribe(\"Array\", function () {\n  describe(\"#indexOf()\", function () {\n    it.only(\"should return -1 unless present\", function () {\n      // ...\n    });\n\n    it(\"should return the index when present\", function () {\n      // ...\n    });\n  });\n});\n```\n\nPrevious to v3.0.0, `.only()` used string matching to decide which tests to execute; this is no longer the case.\nIn v3.0.0 or newer, `.only()` can be used multiple times to define a subset of tests to run:\n\n```js\ndescribe(\"Array\", function () {\n  describe(\"#indexOf()\", function () {\n    it.only(\"should return -1 unless present\", function () {\n      // this test will be run\n    });\n\n    it.only(\"should return the index when present\", function () {\n      // this test will also be run\n    });\n\n    it(\"should return -1 if called with a non-Array context\", function () {\n      // this test will not be run\n    });\n  });\n});\n```\n\nYou may also choose multiple suites:\n\n```js\ndescribe(\"Array\", function () {\n  describe.only(\"#indexOf()\", function () {\n    it(\"should return -1 unless present\", function () {\n      // this test will be run\n    });\n\n    it(\"should return the index when present\", function () {\n      // this test will also be run\n    });\n  });\n\n  describe.only(\"#concat()\", function () {\n    it(\"should return a new Array\", function () {\n      // this test will also be run\n    });\n  });\n\n  describe(\"#slice()\", function () {\n    it(\"should return a new Array\", function () {\n      // this test will not be run\n    });\n  });\n});\n```\n\nBut _tests will have precedence_:\n\n```js\ndescribe(\"Array\", function () {\n  describe.only(\"#indexOf()\", function () {\n    it.only(\"should return -1 unless present\", function () {\n      // this test will be run\n    });\n\n    it(\"should return the index when present\", function () {\n      // this test will not be run\n    });\n  });\n});\n```\n\n:::note\nHooks, if present, will still be executed.\n:::\n\n:::tip\nBe mindful not to commit usages of `.only()` to version control, unless you really mean it!\nTo do so one can run mocha with the option `--forbid-only` in the continuous integration test command (or in a git precommit hook).\n:::\n"
  },
  {
    "path": "docs/src/content/docs/declaring/inclusive-tests.mdx",
    "content": "---\ndescription: Describing test cases that should not be run yet.\ntitle: Inclusive Tests\n---\n\nThis feature is the inverse of `.only()`.\nBy appending `.skip()`, you may tell Mocha to ignore test case(s).\nAnything skipped will be marked as [pending](/declaring/pending-tests) and reported as such.\nHere's an example of skipping an individual test:\n\n```js\ndescribe(\"Array\", function () {\n  describe(\"#indexOf()\", function () {\n    it.skip(\"should return -1 unless present\", function () {\n      // this test will not be run\n    });\n\n    it(\"should return the index when present\", function () {\n      // this test will be run\n    });\n  });\n});\n```\n\nYou can also put `.skip()` on an entire suite.\nThis is equivalent to appending `.skip()` onto all tests in the suite.\nHooks in the suite are also skipped.\n\n```js\ndescribe(\"Array\", function () {\n  describe.skip(\"#indexOf()\", function () {\n    it(\"should return -1 unless present\", function () {\n      // this test will not be run\n    });\n  });\n});\n```\n\n_Note_: Code in skipped suites that is placed outside of hooks or tests is still executed, as Mocha will still invoke the suite function to build up the suite structure for visualization.\n\n:::tip[Best practice]\nUse `.skip()` instead of commenting tests out.\n:::\n\nYou may also skip _at runtime_ using `this.skip()`.\nIf a test needs an environment or configuration which cannot be detected beforehand, a runtime skip is appropriate.\nFor example:\n\n```js\nit('should only test in the correct environment', function() {\n  if (/* check test environment */) {\n    // make assertions\n  } else {\n    this.skip();\n  }\n});\n```\n\nThe above test will be reported as [pending](/declaring/pending-tests).\nIt's also important to note that calling `this.skip()` will effectively _abort_ the test.\n\n:::tip[Best practice]\nTo avoid confusion, do not execute further instructions in a test or hook after calling `this.skip()`.\n:::\n\nContrast the above test with the following code:\n\n```js\nit('should only test in the correct environment', function() {\n  if (/* check test environment */) {\n    // make assertions\n  } else {\n    // do nothing\n  }\n});\n```\n\nBecause this test _does nothing_, it will be reported as _passing_.\n\n:::tip[Best practice]\nDon't do nothing!\nA test should make an assertion or use `this.skip()`.\n:::\n\nTo skip _multiple_ tests in this manner, use `this.skip()` in a \"before all\" hook:\n\n```js\nbefore(function() {\n  if (/* check test environment */) {\n    // setup code\n  } else {\n    this.skip();\n  }\n});\n```\n\nThis will skip all `it`, `beforeEach/afterEach`, and `describe` blocks within the suite.\n`before/after` hooks are skipped unless they are defined at the same level as the hook containing `this.skip()`.\n\n```js\ndescribe(\"outer\", function () {\n  before(function () {\n    this.skip();\n  });\n\n  after(function () {\n    // will be executed\n  });\n\n  describe(\"inner\", function () {\n    before(function () {\n      // will be skipped\n    });\n\n    after(function () {\n      // will be skipped\n    });\n  });\n});\n```\n\n:::note[Updated in v7.0.0]\nSkipping a test within an \"after all\" hook is disallowed and will throw an exception.\nUse a return statement or other means to abort hook execution.\n:::\n\nBefore Mocha v3.0.0, `this.skip()` was not supported in asynchronous tests and hooks.\n"
  },
  {
    "path": "docs/src/content/docs/declaring/pending-tests.mdx",
    "content": "---\ndescription: Describing test cases with names that don't yet have a callback.\ntitle: Pending Tests\n---\n\n\"Pending\" — as in \"someone should write these test cases eventually\" — test-cases are those _without_ a callback:\n\n```js\ndescribe(\"Array\", function () {\n  describe(\"#indexOf()\", function () {\n    // pending test below\n    it(\"should return -1 when the value is not present\");\n  });\n});\n```\n\nPending tests will be included in the test results and marked as pending.\nA pending test is not considered a failed test.\n\nRead the [inclusive tests section](/declaring/inclusive-tests) for an example of conditionally marking a test as pending via `this.skip()`.\n"
  },
  {
    "path": "docs/src/content/docs/declaring/retrying-tests.mdx",
    "content": "---\ndescription: Describing test cases that should retry on failure.\ntitle: Retry Tests\n---\n\nYou can choose to retry failed tests up to a certain number of times.\nThis feature is designed to handle end-to-end tests (functional tests/Selenium...) where resources cannot be easily mocked/stubbed.\n**It's not recommended to use this feature for unit tests**.\n\nThis feature does re-run a failed test and its corresponding `beforeEach/afterEach` hooks, but not `before/after` hooks.\n`this.retries()` has no effect on failing hooks.\n\n:::note\nThe example below was written using Selenium webdriver (which [overwrites global Mocha hooks](https://github.com/SeleniumHQ/selenium/blob/c10e8a955883f004452cdde18096d70738397788/javascript/node/selenium-webdriver/testing/index.js) for `Promise` chain).\n:::\n\n```js\ndescribe(\"retries\", function () {\n  // Retry all tests in this suite up to 4 times\n  this.retries(4);\n\n  beforeEach(function () {\n    browser.get(\"http://www.yahoo.com\");\n  });\n\n  it(\"should succeed by the 3rd try\", function () {\n    // Specify this test to only retry up to 2 times\n    this.retries(2);\n    expect($(\".foo\").isDisplayed()).to.eventually.be.true;\n  });\n});\n```\n"
  },
  {
    "path": "docs/src/content/docs/explainers/compilers-deprecation.mdx",
    "content": "---\ndescription: Compilers deprecation notice.\ntitle: Compilers deprecation\n---\n\nIf you're here, you probably hit the deprecation notice. Sorry about that!\n\n## Will it break?\n\nThis is a _soft_ deprecation, which means you get nagged about it, but it won't break (yet).\n\n## Make it go away\n\nTo suppress this warning, execute `mocha` with the `--no-deprecation` flag (though you won't get notice of any _other_ deprecations you may encounter either).\n\n## ... but why?\n\n`--compilers` is redundant; we've yet to encounter a real-world situation in which the solution couldn't be expressed using `--require`.\n\n## What should I use instead then?\n\nLet's say you want to compile using CoffeeScript. Ensure that you have the coffeescript package installed as a dev dependency:\n\n`npm install coffeescript --save-dev`\n\nThen update your package.json with the relevant require statement: `--require coffeescript/register`.\n\nHere's a list of popular compilers/transpilers:\n\n- CoffeeScript: `--compilers coffee:coffee-script/register` becomes `--require coffeescript/register`\n- Babel 6: `--compilers js:babel-core/register` becomes `--require babel-core/register`\n- Babel 7: `--require babel-core/register` used if you are using Babel v6 becomes `--require @babel/register` with Babel v7.\n- TypeScript: `--compilers ts:ts-node/register` becomes `--require ts-node/register`\n- LiveScript: `--compilers ls:livescript` becomes `--require livescript`\n- (feel free to add more examples!)\n\nYou'll have to handle file extensions as well. Mocha, by default, only loads `.js` files when given a directory (and the default directory is `test`). Therefore, to use a _different_ file extension (such as `.coffee` or `.ts`), you will need to supply a _glob_ instead of simply a directory. If this was how you ran Mocha pre-v4:\n\n```bash\n$ mocha --compilers coffee:coffee-script/register --recursive ./test\n```\n\nThen this is how you'd accomplish the same thing (`**` roughly means \"recursive\") in v4:\n\n```bash\n$ mocha --require coffeescript/register \"test/**/*.js\"\n```\n\nWhen you wrap a glob in quotes, file discovery is handed to the [glob](https://npm.im/glob) package.\nIt's _recommended_ to wrap in double-quotes, because the result should be the same regardless of your shell or environment (Windows/Linux/macOS, etc.).\n\n[glob](https://npm.im/glob) is powerful. For instance, if your `test` dir has tests written in _both_ JS _and_ CoffeeScript, you could do this:\n\n```bash\n$ mocha --require coffeescript/register \"test/**/*.{js,coffee}\"\n```\n\n## How do I use this with `--watch`?\n\nWhen using `--watch`, you will also need to specify the extension(s) to watch via `--watch-extensions`, e.g.:\n\n```js\n$ mocha --require coffeescript/register --watch --watch-extensions js,coffee \"test/**/*.{js,coffee}\"\n```\n"
  },
  {
    "path": "docs/src/content/docs/explainers/count-assertions.mdx",
    "content": "---\ndescription: How to count assertions.\ntitle: Counting assertions\n---\n\nWhile Mocha itself does not provide an assertion layer and cannot provide assertion counting, it's relatively easy to integrate this behavior using hooks. The following is a simplified version of an assertion counter:\n\n```js\nvar expected = 0;\nvar actual = 0;\n\nfunction assert(expr, msg) {\n  if (!expr) throw new Error(msg || \"assertion failed\");\n  actual++;\n}\n\nfunction expect(n) {\n  expected = n;\n}\n\nfunction reset() {\n  expected = 0;\n  actual = 0;\n}\n\nfunction check() {\n  if (!expected || expected == actual) return;\n  var err = new Error(\"expected \" + expected + \" assertions, got \" + actual);\n  this.currentTest.emit(\"error\", err);\n}\n\nbeforeEach(reset);\nafterEach(check);\n\ndescribe(\"something\", function () {\n  it(\"should work\", function (done) {\n    expect(2);\n\n    setTimeout(function () {\n      assert(\"wahoo\");\n    }, 50);\n\n    setTimeout(function () {\n      assert(\"hey\");\n    }, 50);\n\n    setTimeout(function () {\n      done();\n    }, 100);\n  });\n});\n```\n"
  },
  {
    "path": "docs/src/content/docs/explainers/detecting-multiple-calls-to-done.mdx",
    "content": "---\ndescription: Why Mocha determines if the done() callback in a test was called multiple times.\ntitle: Detecting Multiple Calls to done()\n---\n\nIf you use callback-based async tests, Mocha will throw an error if `done()` is called multiple times.\nThis is handy for catching accidental double callbacks.\n\n```javascript\nit(\"double done\", function (done) {\n  // Calling `done()` twice is an error\n  setImmediate(done);\n  setImmediate(done);\n});\n```\n\nRunning the above test will give you the below error message:\n\n```bash\n$ ./node_modules/.bin/mocha mocha.test.js\n\n\n  ✓ double done\n  1) double done\n\n  1 passing (6ms)\n  1 failing\n\n  1) double done:\n     Error: done() called multiple times\n      at Object.<anonymous> (mocha.test.js:1:63)\n      at require (internal/module.js:11:18)\n      at Array.forEach (<anonymous>)\n      at startup (bootstrap_node.js:187:16)\n      at bootstrap_node.js:608:3\n```\n"
  },
  {
    "path": "docs/src/content/docs/explainers/environment-variables.mdx",
    "content": "---\ndescription: Learn how to use environment variables in Mocha tests\ntitle: \"Environment variables\"\n---\n\nSometimes you might want your test to make use of variables set on an environment level. Common reasons for this include:\n\n- Flagging a run as CI\n- Setting the domain of an application\n- Pointing to a test database\n- Setting a key which you want to remain secure\n\nThe best way to do this is to use NodeJS's native environment variables.\n\n## Example\n\nIn your `package.json` or directly in a terminal set your variable name and value.\n\n```bash\nenv CI=STAGE mocha\n```\n\nThen in your test or code reference it via `process.env.CI`. e.g.\n\n```javascript\nif (process.env.CI === \"STAGE\") // do something\n```\n\nThe value is available from anywhere in a spec file allowing you to set values from it before the tests run. e.g.\n\n```javascript\nimport { equal } from \"assert\";\nimport { loadPage } from \"your-code\";\nconst URL = `${process.env.APP_HOST}/${process.env.APP_URI}`;\ndescribe('Test the page loads', () {\n  it('goes to URL', () => {\n    const page = loadPage(URL);\n    equal(page.url, URL);\n  });\n});\n```\n"
  },
  {
    "path": "docs/src/content/docs/explainers/find-global-leaks.mdx",
    "content": "---\ndescription: How to find a global leak.\ntitle: Find global leaks\n---\n\nDetecting which module is causing a global leak can be tedious. Add these lines at the very beginning of your tests, or in a file which is included via `--require`:\n\n```javascript\nObject.defineProperty(global, \"name_of_leaking_property\", {\n  set: function (value) {\n    throw new Error(\"Found the leak!\");\n  },\n});\n```\n\nThis will print a stacktrace that shows which module caused the leak. And if it's not yours--go open a pull request! :)\n"
  },
  {
    "path": "docs/src/content/docs/explainers/global-variables.mdx",
    "content": "---\ndescription: How to work with global variables in Mocha tests\ntitle: \"Global variables\"\n---\n\nRelated issue [#1582](https://github.com/mochajs/mocha/issues/1582)\n\nIf your test manipulates global variables, a reasonable expectation is that you will clean up after yourself. This includes commonly called methods such as `process.stdout.write()` or `console.log()`.\n\n```js\nvar expect = require(\"chai\").expect;\n\ndescribe(\"my nice test\", function () {\n  var write,\n    log,\n    output = \"\";\n\n  // restore process.stdout.write() and console.log() to their previous glory\n  var cleanup = function () {\n    process.stdout.write = write;\n    console.log = log;\n    output = \"\";\n  };\n\n  beforeEach(function () {\n    // store these functions to restore later because we are messing with them\n    write = process.stdout.write;\n    log = console.log;\n\n    // our stub will concatenate any output to a string\n    process.stdout.write = console.log = function (s) {\n      output += s;\n    };\n  });\n\n  // restore after each test\n  afterEach(cleanup);\n\n  it(\"should suppress all output if a non-AssertionError was thrown\", function () {\n    process.stdout.write(\"foo\");\n    console.log(\"bar\");\n    // uncomment below line to suppress output, which is bad\n    // expect(output).to.equal(foobar);\n    expect(output).to.equal(\"foobar\");\n  });\n\n  it(\"should not suppress any output\", function () {\n    try {\n      process.stdout.write(\"foo\");\n      console.log(\"bar\");\n      // uncomment below line to just throw an AssertionError\n      // expect(output).to.equal('barfoo');\n      expect(output).to.equal(foobar); // ReferenceError\n    } catch (e) {\n      cleanup();\n      throw e;\n    }\n  });\n});\n```\n"
  },
  {
    "path": "docs/src/content/docs/explainers/nodejs-native-esm-support.mdx",
    "content": "---\ndescription: A mid-level outline of Mocha's \"flow of execution\".\ntitle: Node.js Native ESM Support\n---\n\n:::note[New in v7.1.0]\n:::\n\nMocha supports writing your tests as ES modules, and not just using CommonJS.\nFor example:\n\n```js\n// test.mjs\nimport { add } from \"./add.mjs\";\nimport assert from \"assert\";\n\nit(\"should add to numbers from an es module\", () => {\n  assert.equal(add(3, 5), 8);\n});\n```\n\nTo enable this you don't need to do anything special.\nWrite your test file as an ES module.\nIn Node.js this means either ending the file with a `.mjs` extension, or, if you want to use the regular `.js` extension, by adding `\"type\": \"module\"` to your `package.json`.\nMore information can be found in the [Node.js documentation](https://nodejs.org/api/esm.html).\n\n### Current Limitations\n\n- [Watch mode](/running/cli#--watch--w) does not support ES Module test files\n- [Custom reporters](/reporters/third-party) and [custom interfaces](/interfaces/third-party) can only be CommonJS files\n- [Configuration file](/running/configuring) can only be a CommonJS file (`.mocharc.js` or `.mocharc.cjs`)\n- Mocha in Node.js version 24.4.0 or older [silently ignored top level errors in ESM files](https://github.com/mochajs/mocha/issues/5396).\n  If you cannot upgrade to a newer Node.js version, you can add `--no-experimental-require-module` to the `NODE_OPTIONS` environment variable.\n- When using module-level mocks via libs like `proxyquire`, `rewiremock` or `rewire`, hold off on using ES modules for your test files.\n  You can switch to using `testdouble`, which does support ESM.\n"
  },
  {
    "path": "docs/src/content/docs/explainers/programmatic-usage.mdx",
    "content": "---\ndescription: Using Mocha programmatically\ntitle: Programmatic usage\n---\n\nThere are a lot of reasons why you might want to automate running the tests using Mocha. Using the command-line can run into some problems if you want to load specific files, for example.\n\nHere is an example of using Mocha programmatically:\n\n```javascript\nvar Mocha = require(\"mocha\"),\n  fs = require(\"fs\"),\n  path = require(\"path\");\n\n// Instantiate a Mocha instance.\nvar mocha = new Mocha();\n\nvar testDir = \"some/dir/test\";\n\n// Add each .js file to the mocha instance\nfs.readdirSync(testDir)\n  .filter(function (file) {\n    // Only keep the .js files\n    return file.substr(-3) === \".js\";\n  })\n  .forEach(function (file) {\n    mocha.addFile(path.join(testDir, file));\n  });\n\n// Run the tests.\nmocha.run(function (failures) {\n  process.exitCode = failures ? 1 : 0; // exit with non-zero status if there were failures\n});\n```\n\n`mocha.run()` returns a `Runner` instance which emits many [events](https://github.com/mochajs/mocha/blob/9a7053349589344236b20301de965030eaabfea9/lib/runner.js#L52) of interest.\n\nNote that `run` (via `loadFiles`, which it calls) relies on Node's `require` to execute the test interface functions. Thus, files loaded by Mocha will be stored in Node's `require` cache and therefore tests in these files will not be re-run if `mocha.run()` is called again. If you want to run tests multiple times, you may need to clear Node's `require` cache before subsequent calls in whichever manner best suits your needs. The upcoming Mocha-6.0 release will provide `Mocha#unloadFiles`, which will remove all files loaded by `Mocha#loadFiles`.\n\nUnfortunately, event listeners in multiple places are not yet configured for restartability; for now, we recommend recreating the `mocha` instance before rerunning to _ensure_ everything gets reset properly.\n\nFind a fully [working example here](https://github.com/mochajs/mocha-examples/tree/main/packages/programmatic-usage).\n\n## Set options\n\nThere are two ways to set the options to run the tests.\n\nFirstly, you can set these options in the constructor object:\n\n```javascript\nvar mocha = new Mocha({\n  ui: \"tdd\",\n  reporter: \"list\",\n});\n```\n\nPlease check our [API documentation](https://mochajs.org/api/mocha) for a complete list of these options.\n\nSecondly, on the `mocha` object, there are some chainable methods allowing you to change some more options.\n\nHere is an example:\n\n```javascript\n// Change the reporter to \"list\" before running the tests\nmocha.reporter(\"list\").run();\n\n// Change the UI to \"tdd\" before running the tests\nmocha.ui(\"tdd\").run();\n\n// Or do both changes before running the tests\nmocha.reporter(\"list\").ui(\"tdd\").run();\n```\n\nPlease check our [API documentation](https://mochajs.org/api/mocha) for more information.\n"
  },
  {
    "path": "docs/src/content/docs/explainers/related-tools.mdx",
    "content": "---\ndescription: External tools and libraries that work well with Mocha\ntitle: Related tools\n---\n\n# Related Tools\n\n## Assertion Libraries\n\n- [chai](http://chaijs.com/) (recommended): expect(), assert(), and should style assertions\n- [earl](https://earl.fun/): ergonomic, modern and type-safe assertion library for TypeScript\n- [unexpected](https://unexpectedjs.github.io/): extensible BDD assertion toolkit\n\n## Mocks, Stubs & Spies\n\n- [sinon.js](https://sinonjs.org/): Test spies, stubs and mocks for JavaScript.\n- [nock](https://github.com/nock/nock): HTTP mocking and expectations library.\n"
  },
  {
    "path": "docs/src/content/docs/explainers/run-cycle-overview.mdx",
    "content": "---\ndescription: A mid-level outline of Mocha's \"flow of execution\".\ntitle: Run Cycle Overview\n---\n\nThe following is a mid-level outline of Mocha’s \"flow of execution\" when run in Node.js; the \"less important\" details have been omitted.\n\nIn a browser, test files are loaded by `<script>` tags, and calling `mocha.run()` begins at step 9 [below](#serial-mode).\n\n## Serial Mode\n\n1. User (that's you) executes `mocha`\n2. Loads options from config files, if present\n3. Mocha processes any command-line options provided (see section on [configuration merging](/running/configuring#merging) for details)\n4. If known flags for the `node` executable are found:\n   1. Mocha will spawn `node` in a child process, executing itself with these flags\n   2. Otherwise, Mocha does not spawn a child process\n5. Mocha loads modules specified by `--require`\n   1. If a file loaded this way contains known Mocha-specific exports (e.g., [root hook plugins](/features/root-hook-plugins)), Mocha \"registers\" these\n   2. If not, Mocha ignores any exports of a `--require`'d module\n6. Mocha validates any custom reporters or interfaces which were loaded via `--require` or otherwise\n7. Mocha _discovers_ test files; when given no files or directories, it finds files with extensions `.js`, `.mjs` or `.cjs` in the `test` directory (but not its children), relative to the current working directory\n8. The (default) [bdd interface](/interfaces/bdd) loads the test files _in no particular order_, which are given an interface-specific `global` context (this is how, e.g., `describe()` ends up as a global in a test file)\n   1. When a test file is loaded, Mocha executes all of its suites and finds--_but does not execute_--any hooks and tests therein.\n   2. Top-level hooks, tests and suites are all made members of an \"invisible\" _root suite_; there is only _one_ root suite for the entire process\n9. Mocha runs [global setup fixtures](/features/global-fixtures#global-setup-fixtures), if any\n10. Starting with the \"root\" suite, Mocha executes:\n11. Any \"before all\" hooks (for the _root_ suite, this only happens once; see [root hook plugins](/features/root-hook-plugins))\n12. For each test, Mocha executes:\n    1. Any \"before each\" hooks\n    2. The test (and reports the result)\n    3. Any \"after each\" hooks\n13. If the current suite has a child suite, repeat the steps in 10. for each child suite; each child suite _inherits_ any \"before each\" and \"after each\" hooks defined in its parent\n14. Any \"after all\" hooks (for the _root_ suite, this only happens once; see [root hook plugins](/features/root-hook-plugins))\n15. Mocha prints a final summary/epilog, if applicable\n16. Mocha runs [global teardown fixtures](/features/global-fixtures#global-teardown-fixtures), if any\n\n## Parallel Mode\n\n1. Repeat steps 1 through 6 from [Serial Mode](#serial-mode) above, skipping reporter validation\n2. All test files found are put into a queue (they are _not_ loaded by the main process)\n3. Mocha runs [global setup fixtures](/features/global-fixtures#global-setup-fixtures), if any\n4. Mocha creates a pool of subprocesses (\"workers\")\n5. _Immediately before_ a worker runs the first test it receives, the worker \"bootstraps\" itself by:\n   1. Loading all `--require`'d modules\n   2. Registering any root hook plugins\n   3. _Ignoring_ global fixtures and custom reporters\n   4. Asserting the built-in or custom interface is valid\n6. When a worker receives a test file to run, the worker creates a new Mocha instance _for the single test file_, and:\n7. The worker repeats step 8 from [above](#serial-mode)\n8. The worker repeats step 10 from [above](#serial-mode), with the caveat that the worker _does not_ report test results directly; it holds them in a memory buffer\n9. When the worker completes the test file, buffered results are returned to the main process, which then gives them to the user-specified reporter (`spec` by default)\n10. The worker makes itself available to the pool; the pool gives the worker another test file to run, if any remain\n11. Mocha prints a final summary/epilog, if applicable\n12. Mocha runs [global teardown fixtures](/features/global-fixtures#global-teardown-fixtures), if any\n"
  },
  {
    "path": "docs/src/content/docs/explainers/security-vulnerability-reports.mdx",
    "content": "---\ndescription: Information about security vulnerability reports in Mocha's dependencies\ntitle: Security Vulnerability Reports\n---\n\n{/* Use `ldquo` (left double quote) HTML because Astro wrongly makes it right quote otherwise */}\n{/* Use `rdquo` for consistency (in case we change settings later and don't notice this) */}\n\n## &ldquo;`npm audit` or GitHub Advisories reported a vulnerability in a package Mocha depends on!&rdquo;\n\nWe probably know already 🙂\n\nFirst and foremost, please check [Mocha issue 5781: Security Dashboard](https://github.com/mochajs/mocha/issues/5781), which tracks all reported potential security issues.\n\nSecond, please read the vulnerability to see if it actually applies to Mocha in your configuration (or any reasonable configuration you can imagine/test). As a test framework, Mocha is very unlikely to be affected by security vulnerabilities, as it only runs code that you as a developer provide to it.\n\nFinally, consider reading [Josh Goldberg's March 2025 blog on npm security reports](https://www.joshuakgoldberg.com/blog/please-stop-sending-me-nested-dependency-security-reports/). He's a Mocha maintainer and the core of the post remains true today.\n\nWe appreciate your concern, but we don't want to overreact or stress ourselves out unless there is a real reason to believe Mocha itself is actually affected.\n\n## Why is Mocha less likely to be affected?\n\nAs a test framework, Mocha:\n\n- Runs in a development environment, not production\n- Only executes code that you, as a developer, write and provide\n- Doesn't process untrusted user input in typical usage\n- Is not exposed to external networks in normal test scenarios\n\nMost security vulnerabilities in dependencies are relevant for production applications that handle user input, make network requests, or process untrusted data. These scenarios rarely apply to Mocha's use case as a testing tool.\n\n## What if there's a real security issue?\n\nIf you believe you've found a genuine security vulnerability that affects Mocha itself (not just a transitive dependency), please report it responsibly through our [security policy](https://github.com/mochajs/mocha/blob/main/SECURITY.md).\n\n## My build is failing, how do I workaround this?\n\nWe encourage you to find or add manual workarounds for any system that blocks PRs on `npm audit` or similar warnings. Any system that automatically blocks a process should have a manual override for known false positives.\n\nIf you can't make workaround your system, you're welcome to clone Mocha, update dependencies, rebuild from source, and use that instead of the publicly-available version. And if you have a fix for us, we're happy to review PRs!\n"
  },
  {
    "path": "docs/src/content/docs/explainers/shared-behaviours.mdx",
    "content": "---\ndescription: Reuse tests across contexts with `this`\ntitle: Shared Behaviours\n---\n\nMocha currently has no concept of a \"shared behaviour\" however the \"contexts\" facilitate this feature. For example suppose you have an `Admin` which inherits from `User`, you most likely will not want to duplicate the `User` tests for `Admin`. The \"context\" (`this`) is the same object within the \"before each\", \"after each\" hooks, and the test-case itself, allowing you to utilize this instead of closures to store data. The following is an example of how you can achieve this sort of functionality:\n\nshared.js:\n\n```js\nexports.shouldBehaveLikeAUser = function () {\n  it(\"should have .name.first\", function () {\n    this.user.name.first.should.equal(\"tobi\");\n  });\n\n  it(\"should have .name.last\", function () {\n    this.user.name.last.should.equal(\"holowaychuk\");\n  });\n\n  describe(\".fullname()\", function () {\n    it(\"should return the full name\", function () {\n      this.user.fullname().should.equal(\"tobi holowaychuk\");\n    });\n  });\n};\n```\n\ntest.js:\n\n```js\nvar User = require(\"./user\").User,\n  Admin = require(\"./user\").Admin,\n  shared = require(\"./shared\");\n\ndescribe(\"User\", function () {\n  beforeEach(function () {\n    this.user = new User(\"tobi\", \"holowaychuk\");\n  });\n\n  shared.shouldBehaveLikeAUser();\n});\n\ndescribe(\"Admin\", function () {\n  beforeEach(function () {\n    this.user = new Admin(\"tobi\", \"holowaychuk\");\n  });\n\n  shared.shouldBehaveLikeAUser();\n\n  it(\"should be an .admin\", function () {\n    this.user.admin.should.be.true;\n  });\n});\n```\n\nuser.js:\n\n```js\nexports.User = User;\nexports.Admin = Admin;\n\nfunction User(first, last) {\n  this.name = {\n    first: first,\n    last: last,\n  };\n}\n\nUser.prototype.fullname = function () {\n  return this.name.first + \" \" + this.name.last;\n};\n\nfunction Admin(first, last) {\n  User.call(this, first, last);\n  this.admin = true;\n}\n\nAdmin.prototype.__proto__ = User.prototype;\n```\n"
  },
  {
    "path": "docs/src/content/docs/explainers/spies.mdx",
    "content": "---\ndescription: How to use spies with Mocha for testing callbacks and function calls\ntitle: Spies\n---\n\nMocha does not come equipped with spies, though libraries like [Sinon](https://github.com/sinonjs/sinon) provide this behaviour if desired. The following is an example of Mocha utilizing Sinon and [Should.js](https://github.com/shouldjs/should.js) to test an EventEmitter:\n\n```javascript\nvar sinon = require(\"sinon\"),\n  EventEmitter = require(\"events\").EventEmitter;\n\ndescribe(\"EventEmitter\", function () {\n  describe(\"#emit()\", function () {\n    it(\"should invoke the callback\", function () {\n      var spy = sinon.spy(),\n        emitter = new EventEmitter();\n\n      emitter.on(\"foo\", spy);\n      emitter.emit(\"foo\");\n      spy.called.should.equal.true;\n    });\n\n    it(\"should pass arguments to the callbacks\", function () {\n      var spy = sinon.spy(),\n        emitter = new EventEmitter();\n\n      emitter.on(\"foo\", spy);\n      emitter.emit(\"foo\", \"bar\", \"baz\");\n      sinon.assert.calledOnce(spy);\n      sinon.assert.calledWith(spy, \"bar\", \"baz\");\n    });\n  });\n});\n```\n\nThe following is the same test, performed without any special spy library, utilizing the Mocha `done([err])` callback as a means to assert that the callback has occurred, otherwise resulting in a timeout. Note that Mocha only allows `done()` to be invoked once, and will otherwise error.\n\n```javascript\ndescribe(\"EventEmitter\", function () {\n  describe(\"#emit()\", function () {\n    it(\"should invoke the callback\", function (done) {\n      var emitter = new EventEmitter();\n\n      emitter.on(\"foo\", done);\n      emitter.emit(\"foo\");\n    });\n\n    it(\"should pass arguments to the callbacks\", function (done) {\n      var emitter = new EventEmitter();\n\n      emitter.on(\"foo\", function (a, b) {\n        a.should.equal(\"bar\");\n        b.should.equal(\"baz\");\n        done();\n      });\n      emitter.emit(\"foo\", \"bar\", \"baz\");\n    });\n  });\n});\n```\n"
  },
  {
    "path": "docs/src/content/docs/explainers/stub-stdout.mdx",
    "content": "---\ndescription: Learn how to properly stub stdout for testing console output\ntitle: \"Stubbing stdout\"\n---\n\nIf you want to stub `stdout` inside your own code (via `process.stdout.write` or `console.log`) there is a potential to hinder Mocha's reporter output. This is because they rely on the same mechanisms to print results of the tests.\n\ni.e.\n\n```javascript\nit('should do, but it do not', function() {\n  // user wants to hide output generated by console.log calls in fn 'foo'\n  console.log = function() {};\n  foo();\n\n  expect(...)\n});\n```\n\nThis will result in a faulty reporter output.\n\nThe correct way to handle this is to stub before and restore after the function call.\n\n```javascript\nit('will do', function() {\n  var consoleLogStub = sinon.stub(console, 'log');\n  foo();\n  consoleLogStub.restore();\n\n  expect(...)\n});\n```\n\nNow the reporters can run and print the assertion without any interference, while stubbing `stdout` inside your function.\n"
  },
  {
    "path": "docs/src/content/docs/explainers/tagging.mdx",
    "content": "---\ndescription: Use Mocha's --grep to tag and selectively run tests.\ntitle: Tagging with --grep\n---\n\nMocha's `--grep` feature may be used both on the client (via `?grep=`) and server-side. Recent releases of Mocha allow you to also click on the suite or test-case names in the browser to automatically grep them. The concept of **tagging** utilizes regular grepping, however may be a useful way to keep related tests in the same spot, while still conditionally executing them.\n\nA good example of this is if you wanted to run slow tests only before releasing, or periodically. You could use any sequence of characters you like, perhaps `#slow`, `@slow` to tag them as shown here:\n\n```js\ndescribe(\"app\", function () {\n  describe(\"GET /login\", function () {\n    it(\"should respond with the login form @fast\", function () {\n      // ...\n    });\n  });\n\n  describe(\"GET /download/:file\", function () {\n    it(\"should respond with the file @slow\", function () {\n      // ...\n    });\n  });\n});\n```\n\nTo execute fast tests only then you may do `--grep @fast`. Another alternative is to only tag `@slow`, and utilize `--grep @slow --invert` to invert the grep expression.\n"
  },
  {
    "path": "docs/src/content/docs/explainers/test-duration.mdx",
    "content": "---\ndescription: A mid-level outline of Mocha's \"flow of execution\".\ntitle: Test Duration\n---\n\nMany reporters will display test duration and flag tests that are slow (default: 75ms), as shown here with the SPEC reporter:\n\n![test duration](./reporter-spec-duration.png)\n\nThere are three levels of test duration (depicted in the following image):\n\n1. FAST: Tests that run within half of the \"slow\" threshold will show the duration in green (if at all).\n2. NORMAL: Tests that run exceeding half of the threshold (but still within it) will show the duration in yellow.\n3. SLOW: Tests that run exceeding the threshold will show the duration in red.\n\n![test duration range](./test-duration-range.png)\n\nTo tweak what's considered \"slow\", you can use the `slow()` method:\n\n```js\ndescribe(\"something slow\", function () {\n  this.slow(300000); // five minutes\n\n  it(\"should take long enough for me to go make a sandwich\", function () {\n    // ...\n  });\n});\n```\n"
  },
  {
    "path": "docs/src/content/docs/explainers/test-fixture-decision-tree.mdx",
    "content": "---\ndescription: Helping you decide which API(s) to use for your test fixtures.\ntitle: Test Fixture Decision Tree\n---\n\nThis flowchart will help you decide when to use [hooks](/features/hooks), [root hook plugins](/features/root-hook-plugins) or [global fixtures](/features/global-fixtures).\n\nimport FixtureWizard from \"../../../components/FixtureWizard.astro\";\n\n<FixtureWizard />\n"
  },
  {
    "path": "docs/src/content/docs/explainers/third-party-reporters.mdx",
    "content": "---\ndescription: Create custom reporters.\ntitle: Third party reporters\n---\n\nMocha 1.3.0 allows you to define custom third-party reporters within your own test suite, or by using npm modules. For example if \"lcov-reporter\" was published to npm, you would simply add it to your package.json in `devDependencies` and use `--reporter lcov-reporter`.\n\nHere is a minimalistic sample reporter, which you can use by executing: `mocha --reporter my-reporter.js`\n\n```js\n// my-reporter.js\nvar mocha = require(\"mocha\");\nmodule.exports = MyReporter;\n\nfunction MyReporter(runner) {\n  mocha.reporters.Base.call(this, runner);\n  var passes = 0;\n  var failures = 0;\n\n  runner.on(\"pass\", function (test) {\n    passes++;\n    console.log(\"pass: %s\", test.fullTitle());\n  });\n\n  runner.on(\"fail\", function (test, err) {\n    failures++;\n    console.log(\"fail: %s -- error: %s\", test.fullTitle(), err.message);\n  });\n\n  runner.on(\"end\", function () {\n    console.log(\"end: %d/%d\", passes, passes + failures);\n  });\n}\n\n// To have this reporter \"extend\" a built-in reporter uncomment the following line:\n// mocha.utils.inherits(MyReporter, mocha.reporters.Spec);\n```\n\nFor details look at the implementations in [lib/reporters/\\*](https://github.com/mochajs/mocha/tree/main/lib/reporters).\n\nAnother sample implementation can be found at [mocha-examples: third-party-reporter (GitHub)](https://github.com/mochajs/mocha-examples/tree/main/packages/third-party-reporter).\n\nMocha provides the following events:\n\n- **start**: Execution started\n- **waiting**: Execution of root `Suite` delayed\n- **ready**: Execution of root `Suite` started\n- **end**: Execution complete\n- **suite**: Test suite execution started\n- **suite end**: All tests (and sub-suites) have finished\n- **test**: Test execution started\n- **test end**: Test completed\n- **hook**: Hook execution started\n- **hook end**: Hook complete\n- **pass**: Test passed\n- **fail**: Test failed\n- **pending**: Test pending\n- **retry**: Test failed and retries\n"
  },
  {
    "path": "docs/src/content/docs/explainers/third-party-uis.mdx",
    "content": "---\ndescription: Create custom Mocha UIs.\ntitle: Third party UIs\n---\n\nMocha allows you to define custom UIs with the same power as those readily available. When defining UIs locally, you need to `--require` the file in question, along with specifying the `--ui`. However, when published as an npm module, you can use the ui flag as you would any other interface, such as bdd, tdd, etc.\n\nCreating a Third Party UI involves listening for the `pre-require` event emitted by the root suite. It passes a Mocha context object on which you can install the various functions necessary for the UI. Your UI will need to manage the organization and nesting of suites and tests itself, along with marking suites as skipped/pending if this is behavior you chose to expose.\n\nIn this first brief example, we'll create an interface with only a single function: `test`\n\n```javascript\nimport Mocha from \"mocha\";\nimport MochaInterface from \"mocha/lib/interfaces/common.js\";\n\nconst Test = Mocha.Test;\n/**\n * A simple UI that only exposes a single function: test\n */\nfunction SimpleUI(suite) {\n  suite.on(\"pre-require\", function (context, file, mocha) {\n    const common = MochaInterface([suite], context);\n\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n\n    /**\n     * Describes a specification or test-case with the given `title`\n     * and callback `fn` acting as a thunk.\n     */\n    context.test = function (title, fn) {\n      const test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n\n      return test;\n    };\n  });\n}\n\nMocha.interfaces[\"simple-ui\"] = SimpleUI;\n\nexport default SimpleUI;\n```\n\n```javascript\ntest(\"pass\", function () {\n  // pass\n});\n\ntest(\"fail\", function () {\n  throw new Error(\"oops!\");\n});\n```\n\n```\n$ # Install dependencies\n$ npm install mocha\n$ mocha --require ./simple-ui.js --ui simple-ui test.js\n\n\n  ✓ pass\n  1) fail\n\n  1 passing (4ms)\n  1 failing\n\n  1)  fail:\n     Error: oops!\n      at Context.<anonymous> (/Users/danielstjules/Desktop/example/test.js:6:9)\n  ...\n```\n\nIn this next example, we'll be extending the [TDD interface](https://github.com/mochajs/mocha/blob/master/lib/interfaces/tdd.js) with a comment function that simply prints the passed text. That is, `comment('This is a comment');` would print the string.\n\n```javascript\nimport Mocha from \"mocha\";\nimport MochaInterface from \"mocha/lib/interfaces/common.js\";\nimport escapeStringRegexp from \"escape-string-regexp\";\n\nconst Test = Mocha.Test;\nconst Suite = Mocha.Suite;\n\n/**\n * This example is identical to the TDD interface, but with the addition of a\n * \"comment\" function:\n * https://github.com/mochajs/mocha/blob/master/lib/interfaces/tdd.js\n */\nfunction ExampleUI(suite) {\n  var suites = [suite];\n\n  suite.on(\"pre-require\", function (context, file, mocha) {\n    var common = MochaInterface([suite], context);\n\n    /**\n     * Use all existing hook logic common to UIs. Common logic can be found in\n     * https://github.com/mochajs/mocha/blob/master/lib/interfaces/common.js\n     */\n    context.setup = common.beforeEach;\n    context.teardown = common.afterEach;\n    context.suiteSetup = common.before;\n    context.suiteTeardown = common.after;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n\n    /**\n     * Our addition. A comment function that creates a pending test and\n     * adds an isComment attribute to the test for identification by a\n     * third party, custom reporter. The comment will be printed just like\n     * a pending test. But any custom reporter could check for the isComment\n     * attribute on a test to modify its presentation.\n     */\n    context.comment = function (title) {\n      var suite, comment;\n\n      suite = suites[0];\n      comment = new Test(title, null);\n\n      comment.pending = true;\n      comment.isComment = true;\n      comment.file = file;\n      suite.addTest(comment);\n\n      return comment;\n    };\n\n    // Remaining logic is from the tdd interface, but is necessary for a\n    // complete example\n    // https://github.com/mochajs/mocha/blob/master/lib/interfaces/tdd.js\n\n    /**\n     * The default TDD suite functionality. Describes a suite with the\n     * given title and callback, fn`, which may contain nested suites\n     * and/or tests.\n     */\n    context.suite = function (title, fn) {\n      var suite = Suite.create(suites[0], title);\n\n      suite.file = file;\n      suites.unshift(suite);\n      fn.call(suite);\n      suites.shift();\n\n      return suite;\n    };\n\n    /**\n     * The default TDD pending suite functionality.\n     */\n    context.suite.skip = function (title, fn) {\n      var suite = Suite.create(suites[0], title);\n\n      suite.pending = true;\n      suites.unshift(suite);\n      fn.call(suite);\n      suites.shift();\n    };\n\n    /**\n     * Default TDD exclusive test-case logic.\n     */\n    context.suite.only = function (title, fn) {\n      var suite = context.suite(title, fn);\n      mocha.grep(suite.fullTitle());\n    };\n\n    /**\n     * Default TDD test-case logic. Describes a specification or test-case\n     * with the given `title` and callback `fn` acting as a thunk.\n     */\n    context.test = function (title, fn) {\n      var suite, test;\n\n      suite = suites[0];\n      if (suite.pending) fn = null;\n      test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n    context.test.only = function (title, fn) {\n      var test, reString;\n\n      test = context.test(title, fn);\n      reString = \"^\" + escapeStringRegexp(test.fullTitle()) + \"$\";\n      mocha.grep(new RegExp(reString));\n    };\n\n    /**\n     * Defines the skip behavior for a test.\n     */\n    context.test.skip = common.test.skip;\n  });\n}\n\nMocha.interfaces[\"example-ui\"] = ExampleUI;\n\nexport default ExampleUI;\n```\n\n```javascript\nsuite(\"Example\", function () {\n  comment(\"Here's the addition we made to the UI\");\n\n  test(\"passing test\", function () {\n    // Pass\n  });\n\n  test(\"failing test\", function () {\n    throw new Error(\"it failed!\");\n  });\n});\n```\n\n```\n$ # install both dependencies\n$ npm install mocha escape-string-regexp\n$ # Run our example\n$ mocha --require ./example-ui.js --ui example-ui test.js\n\n\n  Example\n    - Here's the addition we made to the UI\n    ✓ passing test\n    1) failing test\n\n\n  1 passing (5ms)\n  1 pending\n  1 failing\n\n  1) Example failing test:\n     Error: it failed!\n      at Context.<anonymous> (/Users/danielstjules/Desktop/example/test.js:11:11)\n      at callFn (/Users/danielstjules/Desktop/example/node_modules/mocha/lib/runnable.js:266:21)\n      at Test.Runnable.run\n....\n```\n"
  },
  {
    "path": "docs/src/content/docs/features/arrow-functions.mdx",
    "content": "---\ndescription: Working with arrow functions, aka \"lambdas\".\ntitle: Arrow Functions\n---\n\nPassing [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) (aka \"lambdas\") to Mocha is discouraged.\nLambdas lexically bind `this` and cannot access the Mocha context.\nFor example, the following code will fail:\n\n```js\ndescribe(\"my suite\", () => {\n  it(\"my test\", () => {\n    // should set the timeout of this test to 1000 ms; instead will fail\n    this.timeout(1000);\n    assert.ok(true);\n  });\n});\n```\n\n_If you do not need to use_ Mocha's context, lambdas should work.\nBe aware that using lambdas will be more painful to refactor if the need eventually arises!\n\nAlternatively, you can override certain context variables, such as test timeouts, by chain-calling methods of the created tests and/or hooks:\n\n```js\ndescribe(\"my suite\", () => {\n  beforeEach(() => {}).timeout(1000);\n  it(\"my test\", () => {\n    assert.ok(true);\n  }).timeout(1000);\n}).timeout(1000);\n```\n"
  },
  {
    "path": "docs/src/content/docs/features/assertions.mdx",
    "content": "---\ndescription: Using assertion libraries with Mocha\ntitle: Assertions\n---\n\nMocha allows you to use any assertion library you wish.\nIn many of this site's examples, we're using Node.js' built-in [assert](https://nodejs.org/api/assert.html) module--but generally, if it throws an `Error`, it will work!\nThis means you can use libraries such as:\n\n- [better-assert](https://github.com/visionmedia/better-assert) - C-style self-documenting `assert()`\n- [chai](https://www.chaijs.com) - `expect()`, `assert()` and `should`-style assertions\n- [expect.js](https://github.com/LearnBoost/expect.js) - `expect()` style assertions\n- [should.js](https://github.com/shouldjs/should.js) - BDD style shown throughout these docs\n- [unexpected](https://unexpected.js.org) - \"the extensible BDD assertion toolkit\"\n"
  },
  {
    "path": "docs/src/content/docs/features/asynchronous-code.mdx",
    "content": "---\ndescription: Testing asynchronous code with Mocha\ntitle: Asynchronous Code\n---\n\nBy adding an argument (usually named `done`) to a test callback, Mocha will know that it should wait for this function to be called to complete the test.\nThis callback accepts both an `Error` instance _or_ a falsy value; anything else is invalid usage and throws an error (usually causing a failed test).\n\n```js\ndescribe(\"User\", function () {\n  describe(\"#save()\", function () {\n    it(\"should save without error\", function (done) {\n      var user = new User(\"Luna\");\n      user.save(function (err) {\n        if (err) done(err);\n        else done();\n      });\n    });\n  });\n});\n```\n\nAlternatively, use the `done()` callback directly (which will handle an error argument, if it exists):\n\n```js\ndescribe(\"User\", function () {\n  describe(\"#save()\", function () {\n    it(\"should save without error\", function (done) {\n      var user = new User(\"Luna\");\n      user.save(done);\n    });\n  });\n});\n```\n\n## Working with Promises\n\nAlternately, instead of using the `done()` callback, you may return a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).\nThis is useful if the APIs you are testing return promises instead of taking callbacks:\n\n```js\nbeforeEach(function () {\n  return db.clear().then(function () {\n    return db.save([tobi, loki, jane]);\n  });\n});\n\ndescribe(\"#find()\", function () {\n  it(\"respond with matching records\", function () {\n    return db.find({ type: \"User\" }).should.eventually.have.length(3);\n  });\n});\n```\n\n:::note\nThe latter example uses [Chai as Promised](https://www.npmjs.com/package/chai-as-promised) for fluent promise assertions.\n:::\n\nIn Mocha v3.0.0 and newer, returning a `Promise` _and_ calling `done()` will result in an exception, as this is generally a mistake:\n\n```js\nconst assert = require(\"assert\");\n\n// antipattern\nit(\"should complete this test\", function (done) {\n  return new Promise(function (resolve) {\n    assert.ok(true);\n    resolve();\n  }).then(done);\n});\n```\n\nThe above test will fail with `Error: Resolution method is overspecified.\nSpecify a callback *or* return a Promise; not both.\nIn versions older than v3.0.0, the call to `done()` is effectively ignored.\n\n## Using async / await\n\nIf your JS environment supports [async / await](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/async_function), you can also write asynchronous tests like this:\n\n```js\nbeforeEach(async function () {\n  await db.clear();\n  await db.save([tobi, loki, jane]);\n});\n\ndescribe(\"#find()\", function () {\n  it(\"responds with matching records\", async function () {\n    const users = await db.find({ type: \"User\" });\n    users.should.have.length(3);\n  });\n});\n```\n\n## Limitations of asynchronous callbacks\n\nYou can use all asynchronous callbacks (`done`, `Promise`, and `async`/`await`) in callbacks for `it()`, `before()`, `after()`, `beforeEach()`, `afterEach()`) but not `describe()` -- it must be synchronous.\nSee [#5046](https://github.com/mochajs/mocha/pull/5046) for more information.\n\n## Synchronous Code\n\nWhen testing synchronous code, omit the callback and Mocha will automatically continue on to the next test.\n\n```js\ndescribe(\"Array\", function () {\n  describe(\"#indexOf()\", function () {\n    it(\"should return -1 when the value is not present\", function () {\n      [1, 2, 3].indexOf(5).should.equal(-1);\n      [1, 2, 3].indexOf(0).should.equal(-1);\n    });\n  });\n});\n```\n"
  },
  {
    "path": "docs/src/content/docs/features/diffs.mdx",
    "content": "---\ndescription: Displaying actual vs. expected data in test failures.\ntitle: Diffs\n---\n\nMocha supports the `err.expected` and `err.actual` properties of any thrown `AssertionError`s from an assertion library.\nMocha will attempt to display the difference between what was expected and what the assertion actually saw.\nHere's an example of a \"string\" diff using `--inline-diffs`:\n\n![string diffs](./reporter-string-diffs.png)\n"
  },
  {
    "path": "docs/src/content/docs/features/error-codes.mdx",
    "content": "---\ndescription: Status codes reported when Mocha throws an exception.\ntitle: Error Codes\n---\n\n:::note[New in v6.0.0]\n:::\n\nWhen Mocha itself throws exception, the associated `Error` will have a `code` property.\nWhere applicable, consumers should check the `code` property instead of string-matching against the `message` property.\nThe following table describes these error codes:\n\n| Code                               | Description                                                  |\n| ---------------------------------- | ------------------------------------------------------------ |\n| `ERR_MOCHA_INVALID_ARG_TYPE`       | wrong type was passed for a given argument                   |\n| `ERR_MOCHA_INVALID_ARG_VALUE`      | invalid or unsupported value was passed for a given argument |\n| `ERR_MOCHA_INVALID_EXCEPTION`      | a falsy or otherwise underspecified exception was thrown     |\n| `ERR_MOCHA_INVALID_INTERFACE`      | interface specified in options not found                     |\n| `ERR_MOCHA_INVALID_REPORTER`       | reporter specified in options not found                      |\n| `ERR_MOCHA_NO_FILES_MATCH_PATTERN` | test file(s) could not be found                              |\n| `ERR_MOCHA_UNSUPPORTED`            | requested behavior, option, or parameter is unsupported      |\n"
  },
  {
    "path": "docs/src/content/docs/features/global-fixtures.mdx",
    "content": "---\ndescription: Adding code to be run before and/or after every tests.\ntitle: Global Fixtures\n---\n\n:::note[New in v8.2.0]\n:::\n\nAt first glance, _global fixtures_ seem similar to [root hook plugins](/features/root-hook-plugins).\nHowever, unlike root hooks, global fixtures:\n\n1. Are _guaranteed_ to execute _once and only once_\n1. Work identically parallel mode, watch mode, and serial mode\n1. Do not share a context with tests, suites, or other hooks\n\nThere are two types of global fixtures: [global setup fixtures](#global-setup-fixtures) and [global teardown fixtures](#global-teardown-fixtures).\n\n## Global Setup Fixtures\n\nTo create a global setup fixture, export `mochaGlobalSetup` from a script, e.g.,:\n\n```js\n// fixtures.cjs\n\n// can be async or not\nexports.mochaGlobalSetup = async function () {\n  this.server = await startSomeServer({ port: process.env.TEST_PORT });\n  console.log(`server running on port ${this.server.port}`);\n};\n```\n\n...or an ES module:\n\n```js\n// fixtures.mjs\n\n// can be async or not\nexport async function mochaGlobalSetup() {\n  this.server = await startSomeServer({ port: process.env.TEST_PORT });\n  console.log(`server running on port ${this.server.port}`);\n}\n```\n\nTo use it, load this file when running Mocha via `mocha --require fixtures.cjs` (or whatever you have named the file).\n\n:::tip\nRemember: you can define \"requires\" in a [configuration file](/running/configuring).\n:::\n\nNow, before Mocha loads and runs your tests, it will execute the above global setup fixture, starting a server for testing.\nThis won't shut _down_ the server when Mocha is done, however!\nTo do that, use a _[global teardown fixture](#global-teardown-fixtures)_.\n\n## Global Teardown Fixtures\n\nJust like a [global setup fixture](#global-setup-fixtures), a _global teardown fixture_ can be created by exporting from a \"required\" script (we can put both types of fixtures in a single file):\n\n```js\n// fixtures.cjs, cont'd\n\n// can be async or not\nexports.mochaGlobalTeardown = async function () {\n  await this.server.stop();\n  console.log(\"server stopped!\");\n};\n```\n\n...or an ES module:\n\n```js\n// fixtures.mjs, cont'd\n\n// can be async or not\nexport async function mochaGlobalTeardown() {\n  await this.server.stop();\n  console.log(\"server stopped!\");\n}\n```\n\nYou'll note that we used `this` in the fixture examples.\nGlobal setup fixtures and global teardown fixtures _share a context_, which means we can add properties to the context object (`this`) in the setup fixture, and reference them later in the teardown fixture.\nThis is more useful when the fixtures are in separate files, since you can just use JS' variable scoping rules instead ([example below](#when-not-to-use-global-fixtures)).\n\nAs explained [above](#_top)--and [below](#when-not-to-use-global-fixtures)--test files _do not_ have access to this context object.\n\n## When To Use Global Fixtures\n\nGlobal fixtures are good for spinning up a server, opening a socket, or otherwise creating a resource that your tests will repeatedly access via I/O.\n\n## When Not To Use Global Fixtures\n\nIf you need to access an in-memory value (such as a file handle or database connection), _don't_ use global fixtures to do this, because your tests will not have access to the value.\n\n:::note\nYou could be clever and try to get around this restriction by assigning something to the `global` object, but this will _not_ work in parallel mode.\nIt's probably best to play by the rules!\n:::\n\nInstead, use the global fixture to _start_ the database, and use [root hook plugins](/features/root-hook-plugins) or plain old [hooks](/features/hooks) to create a connection.\n\nHere's an example of using global fixtures and \"before all\" hooks to get the job done.\nNote that we do not reference the `server` object anywhere in our tests!\n\nFirst, use a global fixture to start and stop a test server:\n\n```js\n// fixtures.mjs\n\nlet server;\n\nexport const mochaGlobalSetup = async () => {\n  server = await startSomeServer({ port: process.env.TEST_PORT });\n  console.log(`server running on port ${server.port}`);\n};\n\nexport const mochaGlobalTeardown = async () => {\n  await server.stop();\n  console.log(\"server stopped!\");\n};\n```\n\nThen, connect to the server in your tests:\n\n```js\n// test.spec.mjs\n\nimport { connect } from \"my-server-connector-thingy\";\n\ndescribe(\"my API\", function () {\n  let connection;\n\n  before(async function () {\n    connection = await connect({ port: process.env.TEST_PORT });\n  });\n\n  it(\"should be a nice API\", function () {\n    // assertions here\n  });\n\n  after(async function () {\n    return connection.close();\n  });\n});\n```\n\nFinally, use this command to bring it together: `mocha --require fixtures.mjs test.spec.mjs`.\n"
  },
  {
    "path": "docs/src/content/docs/features/hooks.mdx",
    "content": "---\ndescription: Extensibility hooks for the Mocha BDD interface.\ntitle: Hooks\n---\n\nWith its default \"BDD\"-style interface, Mocha provides the hooks `before()`, `after()`, `beforeEach()`, and `afterEach()`.\nThese should be used to set up preconditions and clean up after your tests.\n\n```js\ndescribe(\"hooks\", function () {\n  before(function () {\n    // runs once before the first test in this block\n  });\n\n  after(function () {\n    // runs once after the last test in this block\n  });\n\n  beforeEach(function () {\n    // runs before each test in this block\n  });\n\n  afterEach(function () {\n    // runs after each test in this block\n  });\n\n  // test cases\n});\n```\n\n:::note\nTests can appear before, after, or interspersed with your hooks.\nHooks will run in the order they are defined, as appropriate: all `before()` hooks run (once), then any `beforeEach()` hooks, tests, any `afterEach()` hooks, and finally `after()` hooks (once).\n:::\n\n## Describing Hooks\n\nAny hook can be invoked with an optional description, making it easier to pinpoint errors in your tests.\nIf a hook is given a named function, that name will be used if no description is supplied.\n\n```js\nbeforeEach(function () {\n  // beforeEach hook\n});\n\nbeforeEach(function namedFun() {\n  // beforeEach:namedFun\n});\n\nbeforeEach(\"some description\", function () {\n  // beforeEach:some description\n});\n```\n\n## Asynchronous Hooks\n\nAll hooks (`before()`, `after()`, `beforeEach()`, `afterEach()`) may be sync or async as well, behaving much like a regular test-case.\nFor example, you may wish to populate database with dummy content before each test:\n\n```js\ndescribe(\"Connection\", function () {\n  var db = new Connection(),\n    tobi = new User(\"tobi\"),\n    loki = new User(\"loki\"),\n    jane = new User(\"jane\");\n\n  beforeEach(function (done) {\n    db.clear(function (err) {\n      if (err) return done(err);\n      db.save([tobi, loki, jane], done);\n    });\n  });\n\n  describe(\"#find()\", function () {\n    it(\"respond with matching records\", function (done) {\n      db.find({ type: \"User\" }, function (err, res) {\n        if (err) return done(err);\n        res.should.have.length(3);\n        done();\n      });\n    });\n  });\n});\n```\n\n## Root-Level Hooks\n\nA hook defined at the top scope of a test file (outside of a suite) is a _root hook_.\n\nAs of v8.0.0, [Root Hook Plugins](/features/root-hook-plugins) are the preferred mechanism for setting root hooks.\n\n## Delayed Root Suite\n\n:::caution\nDelayed root suites are incompatible with [parallel mode](/features/parallel-mode).\n:::\n\nIf you need to perform asynchronous operations before any of your suites are run (e.g. for dynamically generating tests), you may delay the root suite.\nRun `mocha` with the `--delay` flag.\nThis will attach a special callback function, `run()`, to the global context:\n\n```js\nconst assert = require(\"assert\");\n\nconst fn = async (x) => {\n  return new Promise((resolve) => {\n    setTimeout(resolve, 3000, 2 * x);\n  });\n};\n\n// instead of an IIFE, you can use 'setImmediate' or 'nextTick' or 'setTimeout'\n(async function () {\n  const z = await fn(3);\n\n  describe(\"my suite\", function () {\n    it(`expected value ${z}`, function () {\n      assert.strictEqual(z, 6);\n    });\n  });\n\n  run();\n})();\n```\n"
  },
  {
    "path": "docs/src/content/docs/features/parallel-mode.mdx",
    "content": "---\ndescription: Running test simultaneously across different cores.\ntitle: Parallel Mode\n---\n\n:::note[New in v8.0.0]\n:::\n\nDepending on the number and nature of your tests, you may find a significant performance benefit when running tests in parallel (using the [`--parallel`](/running/cli#--parallel--p) flag).\n\nParallel tests should work out-of-the box for many use cases.\nHowever, you must be aware of some important implications of the behavior.\n\n:::note\nAuthors of third-party libraries built on Mocha should read this!\n:::\n\n## Reporter Limitations\n\nDue to the nature of the following reporters, they cannot work when running tests in parallel:\n\n- [`json-stream`](/reporters/json-stream)\n- [`markdown`](/reporters/markdown)\n- [`progress`](/reporters/progress)\n\nThese reporters expect Mocha to know _how many tests it plans to run_ before execution.\nThis information is unavailable in parallel mode, as test files are loaded only when they are about to be run.\n\nIn serial mode, tests results will \"stream\" as they occur.\nIn parallel mode, reporter output is _buffered_; reporting will occur after each file is completed.\nIn practice, the reporter output will appear in \"chunks\" (but will otherwise be identical).\nIf a test file is particularly slow, there may be a significant pause while it's running.\n\n## Exclusive Tests are Disallowed\n\n**You cannot use `it.only`, `describe.only`, `this.only()`, etc., in parallel mode.**\nThis is for the same reason as the incompatible reporters noted above: in parallel mode, Mocha does not load all files and suites into memory before running tests.\n\nSuggested workarounds:\n\n1. Use [`--grep`](/running/cli#--grep-regexp--g-regexp) or [`--fgrep`](/running/cli#--fgrep-string--f-string) instead; it's not particularly efficient, but it will work.\n1. Don't use parallel mode.\n   Likely, you won't be running very many exclusive tests, so you won't see a great benefit from parallel mode anyhow.\n\n:::tip\nIf parallel mode is defined in your config file, you can temporarily disable it on the command-line by using either the `--no-parallel` flag or reducing the job count, e.g., `--jobs=0`.\n:::\n\n## File Order is Non-Deterministic\n\nIn parallel mode, Mocha does not guarantee the order in which test files will run, nor which worker process runs them.\n\nBecause of this, the following options, which depend on order, _cannot be used_ in parallel mode:\n\n- [`--file`](/running/cli#--file-file)\n- [`--sort`](/running/cli#--sort--s)\n- [`--delay`](/running/cli#--delay)\n\n## Test Duration Variability\n\nRunning tests in parallel mode will naturally use more system resources.\nThe OS may take extra time to schedule and complete some operations, depending on system load.\nFor this reason, the timeouts of _individual tests_ may need to be increased either [globally](/running/cli#--timeout-ms--t-ms) or [otherwise](/features/timeouts).\n\n## \"Bail\" is \"Best Effort\"\n\nWhen used with `--bail` (or `this.bail()`) to exit after the first failure, it's likely other tests will be running at the same time.\nMocha must shut down its worker processes before exiting.\n\nLikewise, subprocesses may throw uncaught exceptions.\nWhen used with `--allow-uncaught`, Mocha will \"bubble\" this exception to the main process, but still must shut down its processes.\n\nEither way, Mocha will abort the test run \"very soon.\"\n\n## Root Hooks Are Not Global\n\n:::note\nThis only applies when running in parallel mode.\n:::\n\nA _root hook_ is a hook in a test file which is _not defined_ within a suite.\nAn example using the `bdd` interface:\n\n```js\n// test/setup.js\n\n// root hook to run before every test (even in other files)\nbeforeEach(function () {\n  doMySetup();\n});\n\n// root hook to run after every test (even in other files)\nafterEach(function () {\n  doMyTeardown();\n});\n```\n\nWhen run (in the default \"serial\" mode) via this command:\n\n```bash\nmocha --file \"./test/setup.js\" \"./test/**/*.spec.js\"\n```\n\n`setup.js` will be executed _first_, and install the two hooks shown above for every test found in `./test/**/*.spec.js`.\n\n**The above example does not work in parallel mode.**\n\nWhen Mocha runs in parallel mode, **test files do not share the same process,** nor do they share the same instance of Mocha.\nConsequently, a hypothetical root hook defined in test file _A_ **will not be present** in test file _B_.\n\nHere are a couple suggested workarounds:\n\n1. `require('./setup.js')` or `import './setup.js'` at the top of every test file.\n   Best avoided for those averse to boilerplate.\n1. _Recommended_: Define root hooks in a \"required\" file, using the [Root Hook Plugin](/features/root-hook-plugins) system.\n\nIf you need to run some code _once and only once_, use a [global fixture](/features/global-fixtures) instead.\n\n## No Browser Support\n\nParallel mode is only available in Node.js, for now.\n\n## Limited Reporter API for Third-Party Reporters\n\nThird-party reporters may encounter issues when attempting to access non-existent properties within `Test`, `Suite`, and `Hook` objects.\nIf a third-party reporter does not work in parallel mode (but otherwise works in serial mode), please [file an issue](https://github.com/mochajs/mocha/issues/new).\n\n## Troubleshooting Parallel Mode\n\nIf you find your tests don't work properly when run with [`--parallel`](/running/cli#--parallel--p), either shrug and move on, or use this handy-dandy checklist to get things working:\n\n- ✅ Ensure you are using a [supported reporter](#reporter-limitations).\n- ✅ Ensure you are not using [other unsupported flags](#file-order-is-non-deterministic).\n- ✅ Double-check your [config file](/running/configuring); options set in config files will be merged with any command-line option.\n- ✅ Look for [root hooks](#root-hooks-are-not-global) in your tests.\n  Move them into a [Root Hook Plugin](/features/root-hook-plugins).\n- ✅ Do any assertion, mock, or other test libraries you're consuming use root hooks? They may need to be [migrated](#migrating-a-library-to-use-root-hook-plugins) for compatibility with parallel mode.\n- ✅ If tests are unexpectedly timing out, you may need to increase the default test timeout (via [`--timeout`](/running/cli#--timeout-ms--t-ms))\n- ✅ Ensure your tests do not depend on being run in a specific order.\n- ✅ Ensure your tests clean up after themselves; remove temp files, handles, sockets, etc.\n  Don't try to share state or resources between test files.\n\n## Caveats About Testing in Parallel\n\nSome types of tests are _not_ so well-suited to run in parallel.\nFor example, extremely timing-sensitive tests, or tests which make I/O requests to a limited pool of resources (such as opening ports, or automating browser windows, hitting a test DB, or remote server, etc.).\n\nFree-tier cloud CI services may not provide a suitable multi-core container or VM for their build agents.\nRegarding expected performance gains in CI: your mileage may vary.\nIt may help to use a conditional in a `.mocharc.js` to check for `process.env.CI`, and adjust the job count as appropriate.\n\nIt's unlikely (but not impossible) to see a performance gain from a [job count](/running/cli#--jobs-count--j-count) _greater than_ the number of available CPU cores.\nThat said, _play around with the job count_--there's no one-size-fits all, and the unique characteristics of your tests will determine the optimal number of jobs; it may even be that fewer is faster!\n\n## Parallel Mode Worker IDs\n\n:::note[New in v9.2.0]\n:::\n\nEach process launched by parallel mode is assigned a unique id, from 0 for the first process to be launched, to N-1 for the Nth process.\nThis worker id may be accessed in tests via the environment variable `MOCHA_WORKER_ID`.\nIt can be used for example to assign a different database, service port, etc for each test process.\n"
  },
  {
    "path": "docs/src/content/docs/features/root-hook-plugins.mdx",
    "content": "---\ndescription: Adding code to be run before and/or after every test in every file.\ntitle: Root Hook Plugins\n---\n\n:::note[New in v8.0.0]\n:::\n\nIn some cases, you may want a [hook](/features/hooks) before (or after) every test in every file.\nThese are called _root hooks_.\nPrevious to v8.0.0, the way to accomplish this was to use `--file` combined with root hooks (see _[Root Hooks Are Not Global](/features/parallel-mode#root-hooks-are-not-global)_).\nThis still works in v8.0.0, but _not_ when running tests in parallel mode!\nFor that reason, running root hooks using this method is _strongly discouraged_, and may be deprecated in the future.\n\nA _Root Hook Plugin_ is a JavaScript file loaded via [`--require`](/running/cli#--require-module--r-module) which \"registers\" one or more root hooks to be used across all test files.\n\nIn browsers you can set root hooks directly via a `rootHooks` object: `mocha.setup({ rootHooks: { beforeEach() {...} } })`, see [`mocha.setup()`](/running/browsers)\n\n## Defining a Root Hook Plugin\n\nA Root Hook Plugin file is a script which exports (via `module.exports`) a `mochaHooks` property.\nIt is loaded via `--require <file>`.\n\nHere's a simple example which defines a root hook, written using CJS and ESM syntax.\n\n### With CommonJS\n\n```js\n// test/hooks.js\n\nexports.mochaHooks = {\n  beforeEach(done) {\n    // do something before every test\n    done();\n  },\n};\n```\n\n### With ES Modules\n\nWe're using the `.mjs` extension in these examples.\n\n:::tip\nIf you're having trouble getting ES modules to work, refer to [the Node.js documentation](https://nodejs.org/api/esm.html).\n:::\n\n```js\n// test/hooks.mjs\n\nexport const mochaHooks = {\n  beforeEach(done) {\n    // do something before every test\n    done();\n  },\n};\n```\n\n:::note\nFurther examples will use ESM syntax.\n:::\n\n## Available Root Hooks\n\nRoot hooks work with any interface, but _the property names do not change_.\nIn other words, if you are using the `tdd` interface, `suiteSetup` maps to `beforeAll`, and `setup` maps to `beforeEach`.\n\nAvailable root hooks and their behavior:\n\n- `beforeAll`:\n  - In **serial** mode (Mocha's default), _before all tests begin, once only_\n  - In **parallel** mode, run _before all tests begin, for each file_\n- `beforeEach`:\n  - In **both** modes, run _before each test_\n- `afterAll`:\n  - In **serial** mode, run _after all tests end, once only_\n  - In **parallel** mode, run _after all tests end, for each file_\n- `afterEach`:\n  - In **both** modes, run _after every test_\n\n:::tip\nIf you need to ensure code runs once and only once in any mode, use [global fixtures](/features/global-fixtures).\n:::\n\nAs with other hooks, `this` refers to the current context object:\n\n```js\n// test/hooks.mjs\n\nexport const mochaHooks = {\n  beforeAll() {\n    // skip all tests for bob\n    if (require(\"os\").userInfo().username === \"bob\") {\n      return this.skip();\n    }\n  },\n};\n```\n\n## Multiple Root Hooks in a Single Plugin\n\nMultiple root hooks can be defined in a single plugin, for organizational purposes.\nFor example:\n\n```js\n// test/hooks.mjs\n\nexport const mochaHooks = {\n  beforeEach: [\n    function (done) {\n      // do something before every test,\n      // then run the next hook in this array\n    },\n    async function () {\n      // async or Promise-returning functions allowed\n    },\n  ],\n};\n```\n\n## Root Hook Plugins Can Export a Function\n\nIf you need to perform some logic--such as choosing a root hook conditionally, based on the environment--`mochaHooks` can be a _function_ which returns the expected object.\n\n```js\n// test/hooks.mjs\n\nexport const mochaHooks = () => {\n  if (process.env.CI) {\n    // root hooks object\n    return {\n      beforeEach: [\n        function () {\n          // CI-specific beforeEach\n        },\n        function () {\n          // some other CI-specific beforeEach\n        },\n      ],\n    };\n  }\n  // root hooks object\n  return {\n    beforeEach() {\n      // regular beforeEach\n    },\n  };\n};\n```\n\nIf you need to perform an async operation, `mochaHooks` can be `Promise`-returning:\n\n```js\n// test/hooks.mjs\n\nexport const mochaHooks = async () => {\n  const result = await checkSomething();\n  // only use a root hook if `result` is truthy\n  if (result) {\n    // root hooks object\n    return {\n      beforeEach() {\n        // something\n      },\n    };\n  }\n};\n```\n\n## Multiple Root Hook Plugins\n\nMultiple root hook plugins can be registered by using `--require` multiple times.\nFor example, to register the root hooks in `hooks-a.js` and `hooks-b.js`, use `--require hooks-a.js --require hooks-b.js`.\nThese will be registered (and run) _in order_.\n\n## Migrating Tests to use Root Hook Plugins\n\nTo migrate your tests using root hooks to a root hook plugin:\n\n1. Find your root hooks (hooks defined _outside_ of a suite--usually `describe()` callback).\n1. Create a new file, e.g., `test/hooks.js`.\n1. _Move_ your root hooks into `test/hooks.js`.\n1. In `test/hooks.js`, make your hooks a member of an exported `mochaHooks` property.\n1. Use `--require test/hooks.js` (even better: use a [config file](/running/configuring) with `{\"require\": \"test/hooks.js\"}`) when running your tests.\n\nFor example, given the following file, `test/test.spec.js`, containing root hooks:\n\n```js\n// test/test.spec.js\n\nbeforeEach(function () {\n  // global setup for all tests\n});\n\nafter(function () {\n  // one-time final cleanup\n});\n\ndescribe(\"my test suite\", function () {\n  it(\"should have run my global setup\", function () {\n    // make assertion\n  });\n});\n```\n\nYour `test/hooks.js` (for this example, a CJS module) should contain:\n\n```js\n// test/hooks.js\n\nexports.mochaHooks = {\n  beforeAll: function () {\n    // global setup for all tests\n  },\n  afterAll: function () {\n    // one-time final cleanup\n  },\n};\n```\n\n:::note\nCareful!\n`after` becomes `afterAll` and `before` becomes `beforeAll`.\n:::\n\nYour original `test/test.spec.js` should now contain:\n\n```js\n// test/test.spec.js\n\ndescribe(\"my test suite\", function () {\n  it(\"should have run my global setup\", function () {\n    // make assertion\n  });\n});\n```\n\nRunning `mocha --require test/hooks.js test/test.spec.js` will run as before (and is now ready to be used with [`--parallel`](/running/cli#--parallel--p)).\n\n## Migrating a Library to use Root Hook PLugins\n\nIf you're a library maintainer, and your library uses root hooks, you can migrate by refactoring your entry point:\n\n- Your library should _always_ export a [`mochaHooks` object](#defining-a-root-hook-plugin).\n- To maintain backwards compatibility, run your root hooks _if and only if_ `global.beforeEach` (or other relevant hook) exists.\n- Instruct your users to `--require <your-package>` when running `mocha`.\n"
  },
  {
    "path": "docs/src/content/docs/features/timeouts.mdx",
    "content": "---\ndescription: Managing timing for non-synchronous tests.\ntitle: Timeouts\n---\n\n## Suite-level\n\nSuite-level timeouts may be applied to entire test \"suites\", or disabled via `this.timeout(0)`.\nThis will be inherited by all nested suites and test-cases that do not override the value.\n\n```js\ndescribe(\"a suite of tests\", function () {\n  this.timeout(500);\n\n  it(\"should take less than 500ms\", function (done) {\n    setTimeout(done, 300);\n  });\n\n  it(\"should take less than 500ms as well\", function (done) {\n    setTimeout(done, 250);\n  });\n});\n```\n\n## Test-level\n\nTest-specific timeouts may also be applied, or the use of `this.timeout(0)` to disable timeouts all together:\n\n```js\nit(\"should take less than 500ms\", function (done) {\n  this.timeout(500);\n  setTimeout(done, 300);\n});\n```\n\n## Hook-level\n\nHook-level timeouts may also be applied:\n\n```js\ndescribe(\"a suite of tests\", function () {\n  beforeEach(function (done) {\n    this.timeout(3000); // A very long environment setup.\n    setTimeout(done, 2500);\n  });\n});\n```\n\nAgain, use `this.timeout(0)` to disable the timeout for a hook.\n\n:::note\nIn v3.0.0 or newer, a parameter passed to `this.timeout()` greater than the [maximum delay value](https://developer.mozilla.org/docs/Web/API/WindowTimers/setTimeout#Maximum_delay_value) will cause the timeout to be disabled.\n:::\n:::note\nIn v8.0.0 or newer, `this.enableTimeouts()` has been removed.\n:::\n\n:::caution\nWith async tests if you disable timeouts via `this.timeout(0)` and then do not call `done()`, your test will exit silently.\n:::\n"
  },
  {
    "path": "docs/src/content/docs/getting-started.mdx",
    "content": "---\ntitle: Getting Started\ndescription: Set up Mocha and start testing your code.\n---\n\nimport { PackageManagers } from \"starlight-package-managers\";\n\n## 1. Installation\n\nFirst, install the [`mocha` package](https://www.npmjs.com/package/mocha) as a devDependency using your favorite package manager:\n\n<PackageManagers dev type=\"add\" pkg=\"mocha\" />\n\n:::note\nAs of v12.0.0, Mocha requires [Node.js](https://nodejs.org) `^20.19.0 || >=22.12.0`.\n:::\n\n## 2. Test File\n\nCreate the following `example.test.js` file under a `test/` directory:\n\n```js\n// test/example.test.js\nimport assert from \"node:assert\";\n\ndescribe(\"Array\", function () {\n  describe(\"#indexOf()\", function () {\n    it(\"should return -1 when the value is not present\", function () {\n      assert.equal([1, 2, 3].indexOf(4), -1);\n    });\n  });\n});\n```\n\n## 3. Running Mocha\n\nNow, run `npx mocha` to execute the Mocha package on the newly created test file:\n\n```shell\nnpx mocha\n```\n\nYou should see passing output like:\n\n```plaintext\n  Array\n    #indexOf()\n      ✓ should return -1 when the value is not present\n\n  1 passing (9ms)\n```\n\n### Optional: `test` script\n\nMost projects include a [`package.json` `\"test\"` script](https://docs.npmjs.com/cli/commands/npm-test):\n\n```json\n// package.json\n{\n  \"scripts\": {\n    \"test\": \"mocha\"\n  }\n}\n```\n\nYou can then run that script with your favorite package manager:\n\n<PackageManagers type=\"run\" pkg=\"test\" />\n\n## Next Steps\n\nSee:\n\n- [CLI](/running/cli) for the commands you can pass to `mocha`\n- [Configuring](/running/configuring) for creating a persistent test configuration file\n- [Editor Plugins](/running/editor-plugins) for improving the Mocha experience in your editor\n\nYou can see real live example code in our example repositories:\n\n- [Mocha examples](https://github.com/mochajs/mocha-examples)\n- [Express](https://github.com/visionmedia/express/tree/master/test)\n- [Connect](https://github.com/senchalabs/connect/tree/master/test)\n- [SuperAgent](https://github.com/visionmedia/superagent/tree/master/test/node)\n- [WebSocket.io](https://github.com/LearnBoost/websocket.io/tree/master/test)\n- [Mocha tests](https://github.com/mochajs/mocha/tree/main/test)\n"
  },
  {
    "path": "docs/src/content/docs/index.mdx",
    "content": "---\ndescription: The classic, reliable, trusted JavaScript test framework for Node.js & the Browser. ☕\nhead:\n  - content: Mocha | Classic, reliable, trusted. ☕\n    tag: title\ntitle: Mocha\n---\n\nimport { LinkButton } from \"@astrojs/starlight/components\";\nimport { Image } from \"astro:assets\";\n\nimport supporters from \"../data/supporters.json\";\nimport Badges from \"../../components/Badges.astro\";\nimport ClientRedirects from \"../../components/ClientRedirects.astro\";\nimport Supporters from \"../../components/Supporters.astro\";\n\n:::note[New Documentation Site]\nHello!\nWelcome to the newly revamped mochajs.org!\n\nIf you see any bugs or typos, please [file a docs issue on mochajs/mocha](https://github.com/mochajs/mocha/issues/new?template=02-documentation.yml).\nThanks!\n🤎\n\n_For the old docs website, see: [legacy.mochajs.org](https://legacy.mochajs.org)_.\n:::\n\n<Badges />\n\nMocha is a feature-rich JavaScript test framework running on [Node.js](https://nodejs.org) and in the browser, making asynchronous testing _straightforward_ and _fun_.\nMocha tests run serially, allowing for flexible and accurate reporting, while mapping uncaught exceptions to the correct test cases.\n\n<LinkButton href=\"/getting-started\">Get Started</LinkButton>\n<LinkButton href=\"/running/configuring\" variant=\"secondary\">\n  Configuration Reference\n</LinkButton>\n\n## Sponsors\n\nUse Mocha at work?\nAsk your manager or marketing team if they'd help [support](https://opencollective.com/mochajs#support) our project.\nYour company's logo will also be displayed on [npmjs.com](http://npmjs.com/package/mocha) and our [GitHub repository](https://github.com/mochajs/mocha#sponsors).\n\n<Supporters size=\"medium\" data={supporters.sponsors} />\n\n## Backers\n\nFind Mocha helpful?\nBecome a [backer](https://opencollective.com/mochajs#support) and support Mocha with a monthly donation.\n\n<Supporters size=\"small\" data={supporters.backers} />\n\n## More Information\n\nIn addition to chatting with us on [our Discord](https://discord.gg/KeDn2uXhER), for additional information such as using\nspies, mocking, and shared behaviours be sure to check out the [Mocha Wiki](https://github.com/mochajs/mocha/wiki) on GitHub.\nFor a running example of Mocha, view [example/tests.html](example/tests.html).\n\nFor the JavaScript API, view the [API documentation](/api) or the [source](https://github.com/mochajs/mocha/blob/main/lib/mocha.js).\n\n<ClientRedirects />\n"
  },
  {
    "path": "docs/src/content/docs/interfaces/about.mdx",
    "content": "---\ndescription: Mocha's available DSLs for writing tests.\ntitle: About Interfaces\n---\n\nInterfaces are how developers write tests to be executed by Mocha.\nMocha's \"interface\" system allows developers to choose their style of DSL (domain-specific language).\n"
  },
  {
    "path": "docs/src/content/docs/interfaces/bdd.mdx",
    "content": "---\ndescription: The BDD (Behavior-Driven-Design) test interface for Mocha.\ntitle: BDD\n---\n\nThe **BDD** interface provides `describe()`, `context()`, `it()`, `specify()`, `before()`, `after()`, `beforeEach()`, and `afterEach()`.\n\n`context()` is just an alias for `describe()`, and behaves the same way; it provides a way to keep tests easier to read and organized.\nSimilarly, `specify()` is an alias for `it()`.\n\n```js\ndescribe(\"Array\", function () {\n  before(function () {\n    // ...\n  });\n\n  describe(\"#indexOf()\", function () {\n    context(\"when not present\", function () {\n      it(\"should not throw an error\", function () {\n        (function () {\n          [1, 2, 3].indexOf(4);\n        }).should.not.throw();\n      });\n      it(\"should return -1\", function () {\n        [1, 2, 3].indexOf(4).should.equal(-1);\n      });\n    });\n\n    context(\"when present\", function () {\n      it(\"should return the index where the element first appears in the array\", function () {\n        [1, 2, 3].indexOf(3).should.equal(2);\n      });\n    });\n  });\n});\n```\n"
  },
  {
    "path": "docs/src/content/docs/interfaces/exports.mdx",
    "content": "---\ndescription: The Exports test interface for Mocha.\ntitle: Exports\n---\n\nThe **Exports** interface allows for organizing tests in a modular fashion.\nIt is particularly useful in larger projects where test suites can be segmented into different files.\n\n:::note\nThe Exports interface is not supported in browser environments.\nThis limitation arises because browsers handle module exports differently from Node.js.\nIf you intend to run tests in a browser, consider using the BDD or TDD interfaces, which are fully supported.\n:::\n\nThe Exports interface is much like Mocha's predecessor [expresso](https://github.com/tj/expresso).\nThe keys `before`, `after`, `beforeEach`, and `afterEach` are special-cased, object values are suites, and function values are test-cases:\n\n```js\nmodule.exports = {\n  before: function () {\n    // ...\n  },\n\n  Array: {\n    \"#indexOf()\": {\n      \"should return -1 when not present\": function () {\n        [1, 2, 3].indexOf(4).should.equal(-1);\n      },\n    },\n  },\n};\n```\n"
  },
  {
    "path": "docs/src/content/docs/interfaces/qunit.mdx",
    "content": "---\ndescription: The QUnit test interface for Mocha.\ntitle: QUnit\n---\n\nThe [QUnit](https://qunitjs.com)-inspired interface matches the \"flat\" look of QUnit, where the test suite title is defined _before_ the test-cases.\nLike TDD, it uses `suite()` and `test()`, but resembling BDD, it also contains `before()`, `after()`, `beforeEach()`, and `afterEach()`.\n\n```js\nfunction ok(expr, msg) {\n  if (!expr) throw new Error(msg);\n}\n\nsuite(\"Array\");\n\ntest(\"#length\", function () {\n  var arr = [1, 2, 3];\n  ok(arr.length == 3);\n});\n\ntest(\"#indexOf()\", function () {\n  var arr = [1, 2, 3];\n  ok(arr.indexOf(1) == 0);\n  ok(arr.indexOf(2) == 1);\n  ok(arr.indexOf(3) == 2);\n});\n\nsuite(\"String\");\n\ntest(\"#length\", function () {\n  ok(\"foo\".length == 3);\n});\n```\n"
  },
  {
    "path": "docs/src/content/docs/interfaces/require.mdx",
    "content": "---\ndescription: The require interface for Mocha.\ntitle: Require\n---\n\nThe `require` interface allows you to require the `describe` and friend words directly using `require` and call them whatever you want.\nThis interface is also useful if you want to avoid global variables in your tests.\n\n:::note\nThe `require` interface cannot be run via the `node` executable, and must be run via `mocha`.\n:::\n\n```js\nvar testCase = require(\"mocha\").describe;\nvar pre = require(\"mocha\").before;\nvar assertions = require(\"mocha\").it;\nvar assert = require(\"chai\").assert;\n\ntestCase(\"Array\", function () {\n  pre(function () {\n    // ...\n  });\n\n  testCase(\"#indexOf()\", function () {\n    assertions(\"should return -1 when not present\", function () {\n      assert.equal([1, 2, 3].indexOf(4), -1);\n    });\n  });\n});\n```\n"
  },
  {
    "path": "docs/src/content/docs/interfaces/tdd.mdx",
    "content": "---\ndescription: The TDD (Test-Driven-Design) test interface for Mocha.\ntitle: TDD\n---\n\nThe **TDD** interface provides `suite()`, `test()`, `suiteSetup()`, `suiteTeardown()`, `setup()`, and `teardown()`:\n\n```js\nsuite(\"Array\", function () {\n  setup(function () {\n    // ...\n  });\n\n  suite(\"#indexOf()\", function () {\n    test(\"should return -1 when not present\", function () {\n      assert.equal(-1, [1, 2, 3].indexOf(4));\n    });\n  });\n});\n```\n"
  },
  {
    "path": "docs/src/content/docs/interfaces/third-party.mdx",
    "content": "---\ndescription: Third-party test interfaces for Mocha.\ntitle: Third-Party Interfaces\n---\n\nMocha allows you to define custom interfaces, or UIs.\nFor more information see [Third party UIs on the wiki](https://github.com/mochajs/mocha/wiki/Third-party-UIs).\n"
  },
  {
    "path": "docs/src/content/docs/reporters/about.mdx",
    "content": "---\ndescription: How Mocha.js displays tests results as they execute and/or as a results summary.\ntitle: About Reporters\n---\n\nMocha reporters adjust to the terminal window, and always disable ANSI-escape coloring when the stdio streams are not associated with a TTY.\n"
  },
  {
    "path": "docs/src/content/docs/reporters/doc.mdx",
    "content": "---\ndescription: The Doc test reporter for Mocha.\ntitle: Doc\n---\n\nAlias: `Doc`, `doc`\n\nThe Doc reporter outputs a hierarchical HTML body representation of your tests.\nWrap it with a header, footer, and some styling, then you have some fantastic documentation!\n\n![doc reporter](./reporter-doc.png)\n\nFor example, suppose you have the following JavaScript:\n\n```js\ndescribe(\"Array\", function () {\n  describe(\"#indexOf()\", function () {\n    it(\"should return -1 when the value is not present\", function () {\n      [1, 2, 3].indexOf(5).should.equal(-1);\n      [1, 2, 3].indexOf(0).should.equal(-1);\n    });\n  });\n});\n```\n\nThe command `mocha --reporter doc array` would yield:\n\n```html\n<section class=\"suite\">\n  <h1>Array</h1>\n  <dl>\n    <section class=\"suite\">\n      <h1>#indexOf()</h1>\n      <dl>\n        <dt>should return -1 when the value is not present</dt>\n        <dd>\n          <pre><code>[1,2,3].indexOf(5).should.equal(-1);\n[1,2,3].indexOf(0).should.equal(-1);</code></pre>\n        </dd>\n      </dl>\n    </section>\n  </dl>\n</section>\n```\n\nThe SuperAgent request library [test documentation](https://ladjs.github.io/superagent/docs/test.html) was generated with Mocha's doc reporter using this Bash command:\n\n```bash\n$ mocha --reporter=doc | cat docs/head.html - docs/tail.html > docs/test.html\n```\n\nView SuperAgent's [Makefile](https://github.com/visionmedia/superagent/blob/master/Makefile) for reference.\n"
  },
  {
    "path": "docs/src/content/docs/reporters/dot.mdx",
    "content": "---\ndescription: The Dot Matrix test reporter for Mocha.\ntitle: Dot\n---\n\nAlias: `Dot`, `dot`\n\nThe Dot Matrix reporter is a series of characters which represent test cases.\nFailures highlight in red exclamation marks (`!`), pending tests with a blue comma (`,`), and slow tests as yellow.\nGood if you prefer minimal output.\n\n![dot matrix reporter](./reporter-dot.png)\n"
  },
  {
    "path": "docs/src/content/docs/reporters/html.mdx",
    "content": "---\ndescription: The HTML test reporter for Mocha.\ntitle: HTML\n---\n\nAlias: `HTML`, `html`\n\n**The HTML reporter is not intended for use on the command-line.**\n"
  },
  {
    "path": "docs/src/content/docs/reporters/json-stream.mdx",
    "content": "---\ndescription: The JSON Stream test reporter for Mocha.\ntitle: JSON Stream\n---\n\nAlias: `JSONStream`, `json-stream`\n\nThe JSON Stream reporter outputs newline-delimited JSON \"events\" as they occur, beginning with a \"start\" event, followed by test passes or failures, and then the final \"end\" event.\n\n![json stream reporter](./reporter-json-stream.png)\n"
  },
  {
    "path": "docs/src/content/docs/reporters/json.mdx",
    "content": "---\ndescription: The JSON test reporter for Mocha.\ntitle: JSON\n---\n\nAlias: `JSON`, `json`\n\nThe JSON reporter outputs a single large JSON object when the tests have completed (failures or not).\n\nBy default, it will output to the console.\nTo write directly to a file, use `--reporter-option output=filename.json`.\n\n![json reporter](./reporter-json.png)\n"
  },
  {
    "path": "docs/src/content/docs/reporters/landing.mdx",
    "content": "---\ndescription: The Landing strip test reporter for Mocha.\ntitle: Landing Strip\n---\n\nAlias: `Landing`, `landing`\n\nThe Landing Strip reporter is a gimmicky test reporter simulating a plane landing :) unicode ftw\n\n![landing strip plane reporter](./reporter-landing.png)\n![landing strip with failure](./reporter-landing-fail.png)\n"
  },
  {
    "path": "docs/src/content/docs/reporters/list.mdx",
    "content": "---\ndescription: The List test reporter for Mocha.\ntitle: List\n---\n\nAlias: `List`, `list`\n\nThe List reporter outputs a simple specifications list as test cases pass or fail, outputting the failure details at the bottom of the output.\n\n![list reporter](./reporter-list.png)\n"
  },
  {
    "path": "docs/src/content/docs/reporters/markdown.mdx",
    "content": "---\ndescription: The Markdown test reporter for Mocha.\ntitle: Markdown\n---\n\nAlias: `Markdown`, `markdown`\n\nThe Markdown reporter generates a markdown TOC and body for your test suite.\nThis is great if you want to use the tests as documentation within a GitHub wiki page, or a markdown file in the repository that GitHub can render.\nFor example, here is the Connect [test output](https://github.com/senchalabs/connect/blob/90a725343c2945aaee637e799b1cd11e065b2bff/tests.md).\n"
  },
  {
    "path": "docs/src/content/docs/reporters/min.mdx",
    "content": "---\ndescription: The Min test reporter for Mocha.\ntitle: Min\n---\n\nAlias: `Min`, `min`\n\nThe Min reporter displays the summary only, while still outputting errors on failure.\nThis reporter works great with `--watch` as it clears the terminal in order to keep your test summary at the top.\n\n![min reporter](./reporter-min.png)\n"
  },
  {
    "path": "docs/src/content/docs/reporters/nyan.mdx",
    "content": "---\ndescription: The Nyan test reporter for Mocha.\ntitle: Nyan\n---\n\nAlias: `Nyan`, `nyan`\n\nThe Nyan reporter is exactly what you might expect:\n\n![js nyan cat reporter](./reporter-nyan.png)\n"
  },
  {
    "path": "docs/src/content/docs/reporters/progress.mdx",
    "content": "---\ndescription: The Progress test reporter for Mocha.\ntitle: Progress\n---\n\nAlias: `Progress`, `progress`\n\nThe Progress reporter implements a simple progress-bar:\n\n![progress bar](./reporter-progress.png)\n"
  },
  {
    "path": "docs/src/content/docs/reporters/spec.mdx",
    "content": "---\ndescription: The Spec test reporter for Mocha.\ntitle: Spec\n---\n\nAlias: `Spec`, `spec`\n\nThis is the default reporter.\nThe Spec reporter outputs a hierarchical view nested just as the test cases are.\n\n![spec reporter](./reporter-spec.png)\n![spec reporter with failure](./reporter-spec-fail.png)\n"
  },
  {
    "path": "docs/src/content/docs/reporters/tap.mdx",
    "content": "---\ndescription: The TAP test reporter for Mocha.\ntitle: TAP\n---\n\nAlias: `TAP`, `tap`\n\nThe TAP reporter emits lines for a [Test-Anything-Protocol](https://en.wikipedia.org/wiki/Test_Anything_Protocol) consumer.\n\n![test anything protocol](./reporter-tap.png)\n"
  },
  {
    "path": "docs/src/content/docs/reporters/third-party.mdx",
    "content": "---\ndescription: Third party test reporters for Mocha.\ntitle: Third-Party Reporters\n---\n\nMocha allows you to define custom reporters.\nFor more information see the [wiki](https://github.com/mochajs/mocha/wiki/Third-party-reporters).\n\nExamples:\n\n- the [TeamCity reporter](https://github.com/travisjeffery/mocha-teamcity-reporter)\n- our [working example](https://github.com/mochajs/mocha-examples/tree/main/packages/third-party-reporter)\n"
  },
  {
    "path": "docs/src/content/docs/reporters/xunit.mdx",
    "content": "---\ndescription: The XUnit test reporter for Mocha.\ntitle: XUnit\n---\n\nAlias: `XUnit`, `xunit`\n\nThe XUnit reporter outputs an XUnit-compatible XML document, often applicable in CI servers.\n\nBy default, it will output to the console.\nTo write directly to a file, use `--reporter-option output=filename.xml`.\n\nTo specify custom report title, use `--reporter-option suiteName=\"Custom name\"`.\n\nThe reporter shows absolute file paths by default.\nTo show relative paths instead, use `--reporter-option showRelativePaths`.\n"
  },
  {
    "path": "docs/src/content/docs/running/browsers.mdx",
    "content": "---\ndescription: Running Mocha in Browsers\ntitle: Browsers\n---\n\nMocha can run in the browser.\nEvery release of Mocha will have new builds of `./mocha.js` and `./mocha.css` for use in the browser.\n\nA typical setup might look something like the following, where we call `mocha.setup('bdd')` to use the **BDD** interface before loading the test scripts, running them `onload` with `mocha.run()`.\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>Mocha Tests</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <link rel=\"stylesheet\" href=\"https://unpkg.com/mocha/mocha.css\" />\n  </head>\n  <body>\n    <div id=\"mocha\"></div>\n\n    <script src=\"https://unpkg.com/chai@4/chai.js\"></script>\n    <script src=\"https://unpkg.com/mocha/mocha.js\"></script>\n\n    <script class=\"mocha-init\">\n      mocha.setup(\"bdd\");\n      mocha.checkLeaks();\n    </script>\n    <script src=\"test.array.js\"></script>\n    <script src=\"test.object.js\"></script>\n    <script src=\"test.xhr.js\"></script>\n    <script class=\"mocha-exec\">\n      mocha.run();\n    </script>\n  </body>\n</html>\n```\n\nMocha supports the latest major versions of evergreen browsers available when Mocha's oldest supported Node.js major version was released.\nAs of Mocha v12.0.0, that includes the following browser versions that were stable as of [Node.js 20.0.0](https://nodejs.org/en/blog/release/v20.0.0)'s release on April 18, 2023:\n\n- [Chrome 112](https://developer.chrome.com/blog/new-in-chrome-112)\n- [Edge 112](https://learn.microsoft.com/en-us/deployedge/microsoft-edge-relnote-archive-stable-channel#version-1120172248-april-14-2023)\n- [Firefox 112](https://www.mozilla.org/en-US/firefox/112.0/releasenotes)\n- [Safari 16.4](https://developer.apple.com/documentation/safari-release-notes/safari-16_4-release-notes)\n\n## Grep\n\nThe browser may use the `--grep` as functionality.\nAppend a query-string to your URL: `?grep=api`.\n\n## Browser Configuration\n\nMocha options can be set via `mocha.setup()`.\nExamples:\n\n```js\n// Use \"tdd\" interface.  This is a shortcut to setting the interface;\n// any other options must be passed via an object.\nmocha.setup('tdd');\n\n// This is equivalent to the above.\nmocha.setup({\n  ui: 'tdd'\n});\n\n// Examples of options:\nmocha.setup({\n  allowUncaught: true,\n  asyncOnly: true,\n  bail: true,\n  checkLeaks: true,\n  dryRun: true,\n  failZero: true,\n  forbidOnly: true,\n  forbidPending: true,\n  global: ['MyLib'],\n  retries: 3,\n  rootHooks: { beforeEach(done) { ... done();} },\n  slow: '100',\n  timeout: '2000',\n  ui: 'bdd'\n});\n```\n\n## Browser-Specific Options\n\nBrowser Mocha supports many, but not all [CLI options](/running/configuring).\nTo use a CLI option that contains a \"-\", please convert the option to camelCase, (eg. `check-leaks` to `checkLeaks`).\n\n### Options That Differ Slightly From [CLI Options](/running/configuring)\n\n> `reporter` _`string|constructor`_\n\nYou can pass a reporter's name or a custom reporter's constructor.\nYou can find **recommended** reporters for the browser [here](#reporting).\n\nIt is possible to use [built-in reporters](/reporters/spec) as well.\nTheir employment in browsers is neither recommended nor supported, open the console to see the test results.\n\n### Options That _Only_ Function In Browser Context\n\n> `noHighlighting` _`boolean`_\n\nIf set to `true`, do not attempt to use syntax highlighting on output test code.\n\n## Reporting\n\nThe HTML reporter is the default reporter when running Mocha in the browser.\nIt looks like this:\n\n![HTML test reporter](./reporter-html.png)\n\n[Mochawesome](https://npm.im/mochawesome) is a great alternative to the default HTML reporter.\n"
  },
  {
    "path": "docs/src/content/docs/running/cli.mdx",
    "content": "---\ntitle: Command-Line Usage\ndescription: Running Mocha in your terminal.\n---\n\nRunning `npx mocha --help` will show the full list of available commands:\n\n{/* This output is defined in lib/cli/run.js */}\n\n```plaintext\nmocha [spec..]\n\nRun tests with Mocha\n\nCommands\n  mocha inspect [spec..]  Run tests with Mocha                         [default]\n  mocha init <path>       create a client-side Mocha setup at <path>\n\nRules & Behavior\n      --allow-uncaught              Allow uncaught errors to propagate [boolean]\n  -A, --async-only                  Require all tests to use a callback (async)\n                                    or return a Promise                [boolean]\n  -b, --bail                        Abort (\"bail\") after first test failure\n                                                                       [boolean]\n      --check-leaks                 Check for global variable leaks    [boolean]\n      --delay                       Delay initial execution of root suite\n                                                                       [boolean]\n      --dry-run                     Report tests without executing them[boolean]\n      --exit                        Force Mocha to quit after tests complete\n                                                                       [boolean]\n      --pass-on-failing-test-suite  Not fail test run if tests were failed\n                                                      [boolean] [default: false]\n      --fail-zero                   Fail test run if no test(s) encountered\n                                                                       [boolean]\n      --forbid-only                 Fail if exclusive test(s) encountered\n                                                                       [boolean]\n      --forbid-pending              Fail if pending test(s) encountered[boolean]\n      --global, --globals           List of allowed global variables     [array]\n  -j, --jobs                        Number of concurrent jobs for --parallel;\n                                    use 1 to run in serial\n                                   [number] [default: (number of CPU cores - 1)]\n  -p, --parallel                    Run tests in parallel              [boolean]\n      --retries                     Retry failed tests this many times  [number]\n  -s, --slow                        Specify \"slow\" test threshold (in\n                                    milliseconds)         [string] [default: 75]\n  -t, --timeout, --timeouts         Specify test timeout threshold (in\n                                    milliseconds)       [string] [default: 2000]\n  -u, --ui                          Specify user interface\n                                                       [string] [default: \"bdd\"]\n\nReporting & Output\n  -c, --color, --colors                     Force-enable color output  [boolean]\n      --diff                                Show diff on failure\n                                                       [boolean] [default: true]\n      --full-trace                          Display full stack traces  [boolean]\n      --inline-diffs                        Display actual/expected differences\n                                            inline within each string  [boolean]\n  -R, --reporter                            Specify reporter to use\n                                                      [string] [default: \"spec\"]\n  -O, --reporter-option,                    Reporter-specific options\n  --reporter-options                        (<k=v,[k1=v1,..]>)           [array]\n\nConfiguration\n      --config       Path to config file   [string] [default: (nearest rc file)]\n  -n, --node-option  Node or V8 option (no leading \"--\")                 [array]\n      --package      Path to package.json for config                    [string]\n\nFile Handling\n      --extension          File extension(s) to load\n                                           [array] [default: [\"js\",\"cjs\",\"mjs\"]]\n      --file               Specify file(s) to be loaded prior to root suite\n                           execution                   [array] [default: (none)]\n      --ignore, --exclude  Ignore file(s) or glob pattern(s)\n                                                       [array] [default: (none)]\n      --recursive          Look for tests in subdirectories            [boolean]\n  -r, --require            Require module              [array] [default: (none)]\n  -S, --sort               Sort test files                             [boolean]\n  -w, --watch              Watch files in the current working directory for\n                           changes                                     [boolean]\n      --watch-files        List of paths or globs to watch               [array]\n      --watch-ignore       List of paths or globs to exclude from watching\n                                      [array] [default: [\"node_modules\",\".git\"]]\n\nTest Filters\n  -f, --fgrep   Only run tests containing this string                   [string]\n  -g, --grep    Only run tests matching this string or regexp           [string]\n  -i, --invert  Inverts --grep and --fgrep matches                     [boolean]\n\nPositional Arguments\n  spec  One or more files, directories, or globs to test\n                                                     [array] [default: [\"test\"]]\n\nOther Options\n  -h, --help             Show usage information & exit                 [boolean]\n  -V, --version          Show version number & exit                    [boolean]\n      --list-interfaces  List built-in user interfaces & exit          [boolean]\n      --list-reporters   List built-in reporters & exit                [boolean]\n\nMocha Resources\n    Chat: https://discord.gg/KeDn2uXhER\n  GitHub: https://github.com/mochajs/mocha.git\n    Docs: https://mochajs.org/\n```\n\n## Rules & Behavior\n\n### `--allow-uncaught`\n\nBy default, Mocha will attempt to trap uncaught exceptions thrown from running tests and report these as test failures.\nUse `--allow-uncaught` to disable this behavior and allow uncaught exceptions to propagate.\nWill typically cause the process to crash.\n\nThis flag is useful when debugging particularly difficult-to-track exceptions.\n\n### `--async-only, -A`\n\nEnforce a rule that tests must be written in \"async\" style, meaning each test provides a `done` callback or returns a `Promise`.\nNon-compliant tests will be marked as failures.\n\n### `--bail, -b`\n\nCauses Mocha to stop running tests after the first test failure it encounters.\nCorresponding \"after each\" and \"after all\" hooks are executed for potential cleanup.\n\n`--bail` does _not_ imply `--exit`.\n\n### `--check-leaks`\n\nUse this option to have Mocha check for global variables that are leaked while running tests.\nSpecify globals that are acceptable via the `--global` option (for example: `--check-leaks --global jQuery --global MyLib`).\n\n### `--compilers`\n\n:::note\n`--compilers` was removed in v6.0.0.\nSee [further explanation and workarounds](https://github.com/mochajs/mocha/wiki/compilers-deprecation).\n:::\n\n### `--delay`\n\nDelay initial execution of root suite.\n\nSee [Delayed Root Suite](/features/hooks#delayed-root-suite).\n\n### `--dry-run`\n\n:::note[New in v9.0.0]\n:::\n\nReport tests without executing any of them, neither tests nor hooks.\n\n### `--exit`\n\n:::note[Updated in v4.0.0]\nTL;DR: If your tests hang after an upgrade to Mocha v4.0.0 or newer, use `--exit` for a quick (though not necessarily recommended) fix.\n:::\n\n_Prior to_ version v4.0.0, _by default_, Mocha would force its own process to exit once it was finished executing all tests.\nThis behavior enables a set of potential problems: it's indicative of tests (or fixtures, harnesses, code under test, etc.) which don't clean up after themselves properly.\nUltimately, \"dirty\" tests can (but not always) lead to _false positive_ or _false negative_ results.\n\n\"Hanging\" most often manifests itself if a server is still listening on a port, or a socket is still open, etc.\nIt can also be something like a runaway `setInterval()`, or even an errant `Promise` that never fulfilled.\n\nThe _default behavior_ in v4.0.0 (and newer) is `--no-exit`, where previously it was `--exit`.\n\n**The easiest way to \"fix\" the issue is to pass `--exit` to the Mocha process.**\nIt _can_ be time-consuming to debug--because it's not always obvious where the problem is--but it _is_ recommended to do so.\n\nTo ensure your tests aren't leaving messes around, here are some ideas to get started:\n\n- See the [Node.js guide to debugging](https://nodejs.org/en/docs/inspector)\n- Use the new [`async_hooks`](https://github.com/nodejs/node/blob/master/doc/api/async_hooks.md) API ([example](https://gist.github.com/boneskull/7fe75b63d613fa940db7ec990a5f5843))\n- Try something like [wtfnode](https://npm.im/wtfnode)\n- Use [`.only`](/declaring/exclusive-tests) until you find the test that causes Mocha to hang\n\n### `--pass-on-failing-test-suite`\n\n:::note[New in v10.7.0]\n:::\n\nIf set to `true`, Mocha returns exit code `0` even if there are failed tests during the run.\n\n### `--fail-zero`\n\n:::note[New in v9.1.0]\n:::\n\nFail test run with `exit-code: 1` if no tests are encountered.\n\n### `--forbid-only`\n\nEnforce a rule that tests may not be exclusive (use of e.g., `describe.only()` or `it.only()` is disallowed).\n\n`--forbid-only` causes Mocha to fail when an exclusive (\"only'd\") test or suite is encountered, and it will abort further test execution.\n\n### `--forbid-pending`\n\nEnforce a rule that tests may not be skipped (use of e.g., `describe.skip()`, `it.skip()`, or `this.skip()` anywhere is disallowed).\n\n`--forbid-pending` causes Mocha to fail when a skipped (\"pending\") test or suite is encountered, and it will abort further test execution.\n\n### `--global <variable-name>`\n\n:::note[Updated in v6.0.0]\nThe option is `--global` and `--globals` is now an alias.\n:::\n\nDefine a global variable name.\nFor example, suppose your app deliberately exposes a global named `app` and `YUI`, you may want to add `--global app --global YUI`.\n\n`--global` accepts wildcards.\nYou could do `--global '*bar'` and it would match `foobar`, `barbar`, etc.\nYou can also pass in `'*'` to ignore all globals.\n\n`--global` can accept a comma-delimited list; `--global app,YUI` is equivalent to `--global app --global YUI`.\n\nBy using this option in conjunction with `--check-leaks`, you can specify an allowlist of known global variables that you _expect_ to leak into global scope.\n\n### `--jobs <count>, -j <count>`\n\n:::note[New in v8.0.0]\n:::\n\nUse `--jobs <count>` to specify the _maximum_ number of processes in the worker pool.\n\nThe default value is the _number of CPU cores_ less 1.\n\n:::tip\nUse `--jobs 0` or `--jobs 1` to temporarily disable `--parallel`.\n:::\n\nHas no effect unless used with [`--parallel`](#--parallel--p).\n\n### `--parallel, -p`\n\n:::note[New in v8.0.0]\n:::\n\nUse the `--parallel` flag to run tests in a worker pool.\n\nEach test file will be put into a queue and executed as workers become available.\n\n:::caution\n`--parallel` has certain implications for Mocha's behavior which you must be aware of.\nRead more about [running tests in parallel](/features/parallel-mode).\n:::\n\n### `--retries <n>`\n\nRetries failed tests `n` times.\n\nMocha does not retry test failures by default.\n\n### `--slow <ms>, -s <ms>`\n\nSpecify the \"slow\" test threshold in milliseconds.\nMocha uses this to highlight test cases that are taking too long.\n\"Slow\" tests are not considered failures.\n\n:::note\nA test that executes for _half_ of the \"slow\" time will be highlighted _in yellow_ with the default `spec` reporter; a test that executes for entire \"slow\" time will be highlighted _in red_.\n:::\n\n### `--timeout <ms>, -t <ms>`\n\n:::note[Updated in v6.0.0]\n`--timeout 0` is implied when invoking Mocha using inspect flags.\n`--timeout 99999999` is no longer needed.\n:::\n\nSpecifies the test case timeout, defaulting to two (2) seconds (2000 milliseconds).\nTests taking longer than this amount of time will be marked as failed.\n\nTo override you may pass the timeout in milliseconds, or a value with the `s` suffix, e.g., `--timeout 2s` and `--timeout 2000` are equivalent.\n\nTo disable timeouts, use `--timeout 0`.\n\n:::note\nSynchronous (blocking) tests are also bound by the timeout, but they will not complete until the code stops blocking.\nInfinite loops will still be infinite loops!\n:::\n\n### `--ui <name>, -u <name>`\n\nThe `--ui` option lets you specify the interface to use, defaulting to `bdd`.\n\n## Reporting & Output\n\n### `--color, -c, --colors`\n\n:::note[Updated in v6.0.0]\n`--colors` is now an alias for `--color`.\n:::\n\n\"Force\" color output to be enabled, or alternatively force it to be disabled via `--no-color`.\nBy default, Mocha uses the [supports-color](https://npm.im/supports-color) module to decide.\n\nIn some cases, color output will be explicitly suppressed by certain reporters outputting in a machine-readable format.\n\n### `--diff`\n\nWhen possible, show the difference between expected and actual values when an assertion failure is encountered.\n\nThis flag is unusual in that it **defaults to `true`**; use `--no-diff` to suppress Mocha's own diff output.\n\nSome assertion libraries will supply their own diffs, in which case Mocha's will not be used, regardless of the default value.\n\nMocha's own diff output does not conform to any known standards, and is designed to be human-readable.\n\n:::note[New in v9.2.1]\n:::\n\nBy default strings are truncated to 8192 characters before generating a diff.\nThis is to prevent performance problems with large strings.\n\nIt can however make the output harder to interpret when comparing large strings.\nTherefore it is possible to configure this value using `--reporter-option maxDiffSize=[number]`.\n\nA value of 0 indicates no limit, default is 8192 characters.\n\n### `--full-trace`\n\nEnable \"full\" stack traces.\nBy default, Mocha attempts to distill stack traces into less noisy (though still useful) output.\n\nThis flag is helpful when debugging a suspected issue within Mocha or Node.js itself.\n\n### `--inline-diffs`\n\nEnable \"inline\" diffs, an alternative output for diffing strings.\n\nUseful when working with large strings.\n\nDoes nothing if an assertion library supplies its own diff output.\n\n### `--reporter <name>, -R <name>`\n\nSpecify the reporter that will be used, defaulting to `spec`.\n\nAllows use of third-party reporters.\nFor example, [mocha-lcov-reporter](https://npm.im/mocha-lcov-reporter) may be used with `--reporter mocha-lcov-reporter` after it has been installed.\n\n### `--reporter-option <option>, -O <option>, --reporter-options <option>`\n\n:::note[Updated in v6.0.0]\nCan be specified multiple times.\n`--reporter-options` is now an alias for `--reporter-option`.\n:::\n\nProvide options specific to a reporter in `<key>=<value>` format, e.g., `--reporter tap --reporter-option tapVersion=13`.\n\nNot all reporters accept options.\n\nCan be specified as a comma-delimited list.\n\n## Configuration\n\n### `--config <path>`\n\n:::note[New in v6.0.0]\n:::\n\nSpecify an explicit path to a [configuration file](/running/configuring).\n\nBy default, Mocha will search for a config file if `--config` is not specified; use `--no-config` to suppress this behavior.\n\n### `--node-option <name>, -n <name>`\n\n:::note[New in v9.1.0]\n:::\n\nFor Node.js and V8 options.\nMocha forwards these options to Node.js by spawning a new child-process.\n\nThe options are set without leading dashes `--`, e.g. `-n require=foo -n unhandled-rejections=strict`\n\nCan also be specified as a comma-delimited list: `-n require=foo,unhandled-rejections=strict`\n\n### `--opts <path>`\n\n:::note[Removed in v8.0.0]\nPlease use [configuration file](/running/configuring) instead.\n:::\n\n### `--package <path>`\n\n:::note[New in v6.0.0]\n:::\n\nSpecify an explicit path to a [`package.json` file](/running/configuring) (ostensibly containing configuration in a `mocha` property).\n\nBy default, Mocha looks for a `package.json` in the current working directory or nearest ancestor, and will use the first file found (regardless of whether it contains a `mocha` property); to suppress `package.json` lookup, use `--no-package`.\n\n## File Handling\n\n### `--extension <ext>`\n\nFiles having this extension will be considered test files.\nDefaults to `js`.\n\nSpecifying `--extension` will _remove_ `.js` as a test file extension; use `--extension js` to re-add it.\nFor example, to load `.mjs` and `.js` test files, you must supply `--extension mjs --extension js`.\n\nThe option can be given multiple times.\nThe option accepts a comma-delimited list: `--extension a,b` is equivalent to `--extension a --extension b`.\n\n:::note[New in v8.2.0]\n:::\n\n`--extension` now supports multipart extensions (e.g., `spec.js`), leading dots (`.js`) and combinations thereof (`.spec.js`);\n\n### `--file <file>`\n\n:::caution\n`--file` is incompatible with [parallel mode](/features/parallel-mode).\n:::\n\nExplicitly _include_ a test file to be loaded before other test files.\nMultiple uses of `--file` are allowed, and will be loaded in order given.\n\nUseful if you want to declare, for example, hooks to be run before every test across all other test files.\n\nFiles specified this way are not affected by `--sort` or `--recursive`.\n\nFiles specified in this way should contain one or more suites, tests or hooks.\nIf this is not the case, consider `--require` instead.\n\n### `--ignore <file|directory|glob>, --exclude <file|directory|glob>,`\n\nExplicitly ignore one or more test files, directories or globs (e.g., `some/**/files*`) that would otherwise be loaded.\n\nCan be specified multiple times.\n\n:::note[New in v10.0.0]\nIn Windows always use forward-slashes `/` as path separator.\n:::\n\nFiles specified using `--file` _are not affected_ by this option.\n\n### `--recursive`\n\nWhen looking for test files, recurse into subdirectories.\n\nSee `--extension` for defining which files are considered test files.\n\n### `--require <module>, -r <module>`\n\nRequire a module before loading the user interface or test files.\nThis is useful for:\n\n- Test harnesses\n- Assertion libraries that augment built-ins or global scope (such as [should.js](https://npm.im/should))\n- Compilers such as Babel via [@babel/register](https://npm.im/@babel/register) or TypeScript via [ts-node](https://npm.im/ts-node) (using `--require ts-node/register`).\n  See [Babel](https://github.com/mochajs/mocha-examples/tree/main/packages/babel) or [TypeScript](https://github.com/mochajs/mocha-examples/tree/main/packages/typescript) working examples.\n\nModules required in this manner are expected to do work synchronously; Mocha won't wait for async tasks in a required module to finish.\n\n:::caution\n**You cannot use `--require` to set hooks**.\nIf you want to set hooks to run, e.g., before each test, use a [Root Hook Plugin](/features/root-hook-plugins).\n:::\n\n:::note\nAs of v8.0.0, Mocha supports `--require` for [NodeJS native ESM](/explainers/nodejs-native-esm-support).\nThere is no separate `--import` flag.\n:::\n\n### `--sort, -S`\n\n:::caution\n`--sort` is incompatible with [parallel mode](/features/parallel-mode).\n:::\n\nSort test files (by absolute path) using [Array.prototype.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort).\n\n### `--watch, -w`\n\nRerun tests on file changes.\n\nThe `--watch-files` and `--watch-ignore` options can be used to control which files are watched for changes.\n\nTests may be rerun manually by typing `rs` and pressing enter (same shortcut as `nodemon`).\n\n### `--watch-files <file|directory|glob>`\n\n:::note[New in v7.0.0]\n:::\n\nList of paths or globs to watch when `--watch` is set.\nIf a file matching the given glob changes or is added or removed mocha will rerun all tests.\n\nIf the path is a directory all files and subdirectories will be watched.\n\nBy default all files in the current directory having one of the extensions provided by `--extension` and not contained in the `node_modules` or `.git` folders are watched.\n\nThe option can be given multiple times.\nThe option accepts a comma-delimited list: `--watch-files a,b` is equivalent to `--watch-files a --watch-files b`.\n\n### `--watch-ignore <file|directory|glob>`\n\n:::note[New in v7.0.0]\n:::\n\nList of paths or globs to exclude from watching.\nDefaults to `node_modules` and `.git`.\n\nTo exclude all files in a directory it is preferable to use `foo/bar` instead of `foo/bar/**/*`.\nThe latter will still watch the directory `foo/bar` but will ignore all changes to the content of that directory.\n\nThe option can be given multiple times.\nThe option accepts a comma-delimited list: `--watch-ignore a,b` is equivalent to `--watch-ignore a --watch-ignore b`.\n\n## Test Filters\n\n### `--fgrep <string>, -f <string>`\n\n:::caution[Breaking change in v6.0.0]\nNow mutually exclusive with `--grep`.\n:::\n\nCause Mocha to only run tests having titles containing the given `string`.\n\nMutually exclusive with `--grep`.\n\n### `--grep <regexp>, -g <regexp>`\n\n:::caution[Breaking change in v6.0.0]\nNow mutually exclusive with `--fgrep`.\n:::\n\nCause Mocha to only run tests matching the given `regexp`, which is internally compiled to a [RegExp](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Regexp).\n\nSuppose, for example, you have \"api\" related tests, as well as \"app\" related tests, as shown in the following snippet; One could use `--grep api` or `--grep app` to run one or the other.\nThe same goes for any other part of a suite or test-case title, `--grep users` would be valid as well, or even `--grep GET`.\n\nAnd another option with double quotes: `--grep \"groupA|groupB\"`.\n\nAnd for more complex criteria: `--grep \"/get/i\"`.\nSome shells (e.g. Git Bash for Windows) may require: `--grep \"'/get/i'\"`.\nUsing flags other than the `ignoreCase /i` (especially `/g` and `/y`) may lead to unpredictable results.\n\n```js\ndescribe(\"api\", function () {\n  describe(\"GET /api/users groupA\", function () {\n    it(\"respond with an array of users\", function () {\n      // ...\n    });\n  });\n});\n\ndescribe(\"app\", function () {\n  describe(\"GET /users groupB\", function () {\n    it(\"respond with an array of users\", function () {\n      // ...\n    });\n  });\n});\n```\n\nMutually exclusive with `--fgrep`.\n\n### `--invert`\n\nUse the _inverse_ of the match specified by `--grep` or `fgrep`.\n\nRequires either `--grep` or `--fgrep` (but not both).\n\n## Other Options\n\n### `--inspect, --inspect-brk, inspect`\n\nEnables Node.js' inspector.\n\nUse `--inspect` / `--inspect-brk` to launch the V8 inspector for use with Chrome Dev Tools.\n\nUse `inspect` to launch Node.js' internal debugger.\n\nAll of these options are mutually exclusive.\n\nImplies `--timeout 0`.\n\n## About Option Types\n\n:::note[Updated in v6.0.0]\n:::\n\nEach flag annotated of type `[boolean]` in Mocha's `--help` output can be _negated_ by prepending `--no-` to the flag name.\nFor example, `--no-color` will disable Mocha's color output, which is enabled by default.\n\nUnless otherwise noted, _all_ boolean flags default to `false`.\n\n## About `node` Flags\n\nThe `mocha` executable supports all applicable flags which the `node` executable supports.\n\nThese flags vary depending on your version of Node.js.\n\n`node` flags can be defined in Mocha's [configuration](/running/configuring).\n\n:::note[New in v9.1.0]\nYou can also pass `node` flags to Node.js using [`--node-option`](#--node-option-name--n-name).\n:::\n\n### `--enable-source-maps`\n\n:::note[New in Node.js v12.12.0]\n:::\n\nIf the [`--enable-source-maps`](https://nodejs.org/dist/latest-v12.x/docs/api/cli.html#cli_enable_source_maps) flag\nis passed to Mocha, source maps will be collected and used to provide accurate stack traces for transpiled code:\n\n```bash\nError: cool\n    at Object.<anonymous> (/Users/fake-user/bigco/nodejs-tasks/build/src/index.js:27:7)\n        -> /Users/fake-user/bigco/nodejs-tasks/src/index.ts:24:7\n```\n\n## About V8 Flags\n\nPrepend `--v8-` to any flag listed in the output of `node --v8-options` (excluding `--v8-options` itself) to use it.\n\n[V8](https://v8.dev/) flags can be defined in Mocha's [configuration](/running/configuring).\n\n:::note[New in v9.1.0]\nYou can also pass V8 flags (without `--v8-`) to Node.js using [`--node-option`](#--node-option-name--n-name).\n:::\n"
  },
  {
    "path": "docs/src/content/docs/running/configuring.mdx",
    "content": "---\ndescription: Configuration options and files across several formats.\ntitle: Configuring Mocha (Node.js)\n---\n\n:::note[New in v6.0.0]\n:::\n\nMocha supports configuration files, typical of modern command-line tools, in several formats:\n\n- **JavaScript**: Create a `.mocharc.js` (or `.mocharc.cjs` when using [`\"type\"=\"module\"`](/explainers/nodejs-native-esm-support) in your `package.json`)\n  in your project's root directory, and export an object (`module.exports = {/* ... */}`) containing your configuration. For native ESM and using `type=\"module\"`\n  or using `.mjs`, use a default export (`export default  {/* ... */}`).\n- **YAML**: Create a `.mocharc.yaml` (or `.mocharc.yml`) in your project's root directory.\n- **JSON**: Create a `.mocharc.json` (or `.mocharc.jsonc`) in your project's root directory.\n  Comments--while not valid JSON--are allowed in this file, and will be ignored by Mocha.\n- **package.json**: Create a `mocha` property in your project's `package.json`.\n\n## Custom Locations\n\nYou can specify a custom location for your configuration file with the `--config <path>` option.\nMocha will use the file's extension to determine how to parse the file, and will assume JSON if unknown.\n\nYou can specify a custom `package.json` location as well, using the `--package <path>` option.\n\n## Ignoring Config Files\n\nTo skip looking for config files, use `--no-config`.\nLikewise, use `--no-package` to stop Mocha from looking for configuration in a `package.json`.\n\n## Priorities\n\nIf no custom path was given, and if there are multiple configuration files in the same directory, Mocha will search for--and use--only one.\nThe priority is:\n\n1. `.mocharc.js`\n1. `.mocharc.yaml`\n1. `.mocharc.yml`\n1. `.mocharc.jsonc`\n1. `.mocharc.json`\n\n## Environment Variables\n\nThe `MOCHA_OPTIONS` environment variable may be used to specify command line arguments.\nThese arguments take priority over those found in configuration files.\n\nFor example, setting the `bail` and `retries` options:\n\n```bash\n$ MOCHA_OPTIONS=\"--bail --retries 3\" mocha\n```\n\n## Merging\n\nMocha will also _merge_ any options found in `package.json` into its run-time configuration.\nIn case of conflict, the priority is:\n\n1. Arguments specified on command-line\n1. Arguments specified in `MOCHA_OPTIONS` environment variable.\n1. Configuration file (`.mocharc.js`, `.mocharc.yml`, etc.)\n1. `mocha` property of `package.json`\n\nOptions which can safely be repeated (e.g., `--require`) will be _concatenated_, with higher-priority configuration sources appearing earlier in the list.\nFor example, a `.mocharc.json` containing `\"require\": \"bar\"`, coupled with execution of `mocha --require foo`, would cause Mocha to require `foo`, then `bar`, in that order.\n\nThis also includes `spec`. For example, a `.mocharc.json` containing `\"spec\": [\"**/*.test.js\"]` coupled with execution of `mocha bar.spec.js` would be the same as runninng `mocha bar.spec.js **/*.test.js`, and it would still run all `.test.js` files. To workaround this, you can comment out the `spec` property or use a different config file via `--config`.\n\n## Extending Configuration\n\nConfigurations can inherit from other modules using the `extends` keyword.\nSee [yargs API reference](http://yargs.js.org/docs/#api-reference-configobject-extends-keyword) for more information.\n\n## Configuration Format\n\n- Any \"boolean\" flag (which doesn't require a parameter, such as `--bail`), can be specified using a boolean value, e.g.: `\"bail\": true`.\n- Any \"array\"-type option (see `mocha --help` for a list) can be a single string value.\n- For options containing a dash (`-`), the option name can be specified using camelCase.\n- Aliases are valid names, e.g., `R` instead of `reporter`.\n- Test files can be specified using `spec`, e.g., `\"spec\": \"test/**/*.spec.js\"`.\n- Flags to `node` are _also_ supported in configuration files.\n  Use caution, as these can vary between versions of Node.js!\n\n**For more configuration examples, see the [`example/config`](https://github.com/mochajs/mocha/tree/main/example/config) directory on GitHub.**\n"
  },
  {
    "path": "docs/src/content/docs/running/editor-plugins.mdx",
    "content": "---\ndescription: Configuring Mocha in an editor\ntitle: Editor Plugins\n---\n\nThe following editor-related packages are available:\n\n### TextMate\n\nThe [Mocha TextMate bundle](https://github.com/mochajs/mocha.tmbundle) includes snippets to make writing tests quicker and more enjoyable.\n\n### JetBrains\n\n[JetBrains](https://www.jetbrains.com) provides a [NodeJS plugin](https://plugins.jetbrains.com/plugin/6098-node-js) for its suite of IDEs (IntelliJ IDEA, WebStorm, etc.), which contains a Mocha test runner, among other things.\n\n![JetBrains Mocha Runner Plugin in Action](./jetbrains-plugin.png)\n\nThe plugin is titled **NodeJS**, and can be installed via **Preferences** > **Plugins**, assuming your license allows it.\n\n### Wallaby.js\n\n[Wallaby.js](https://wallabyjs.com) is a continuous testing tool that enables real-time code coverage for Mocha with any assertion library in VS Code, Atom, JetBrains IDEs (IntelliJ IDEA, WebStorm, etc.), Sublime Text and Visual Studio for both browser and node.js projects.\n\n![Wallaby.js in Action](./wallaby.png)\n\n### Emacs\n\n[Emacs](https://www.gnu.org/software/emacs) support for running Mocha tests is available via a 3rd party package [mocha.el](https://github.com/scottaj/mocha.el).\nThe package is available on MELPA, and can be installed via `M-x package-install mocha`.\n\n![Emacs Mocha Runner in Action](./emacs.png)\n\n### Mocha Sidebar (VS Code)\n\n[Mocha sidebar](https://marketplace.visualstudio.com/items?itemName=maty.vscode-mocha-sidebar) is the most complete mocha extension for vs code.\n\n#### Features\n\n- see all tests in VS Code sidebar menu\n- run & debug tests for each level hierarchy from all tests to a single test (and each suite)\n- auto run tests on file save\n- see tests results directly in the code editor\n\n![mocha side bar in Action](./mocha_side_bar.png)\n"
  },
  {
    "path": "docs/src/content/docs/running/test-globs.mdx",
    "content": "---\ndescription: Configuring how Mocha finds test files.\ntitle: Test Globs\n---\n\nBy default, `mocha` looks for the glob `\"./test/*.{js,cjs,mjs}\"`, so you may want to put your tests in `test/` folder.\nIf you want to include subdirectories, pass the `--recursive` option.\n\nTo configure where `mocha` looks for tests, you may pass your own glob:\n\n```bash\n$ mocha --recursive \"./spec/*.js\"\n```\n\nSome shells support recursive matching by using the globstar (`**`) wildcard.\nBash >= 4.3 supports this with the [`globstar` option](https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html) which [must be enabled](https://github.com/mochajs/mocha/pull/3348#issuecomment-383937247) to get the same results as passing the `--recursive` option ([ZSH](http://zsh.sourceforge.net/Doc/Release/Expansion.html#Recursive-Globbing) and [Fish](https://fishshell.com/docs/current/#expand-wildcard) support this by default).\nWith recursive matching enabled, the following is the same as passing `--recursive`:\n\n```bash\n$ mocha \"./spec/**/*.js\"\n```\n\nYou should _always_ quote your globs in npm scripts.\nIf you use quotes, the [`glob`](https://www.npmjs.com/package/glob) module will handle its expansion.\nFor maximum compatibility, surround the entire expression with double quotes and refrain from `$`, `\"`, `^`, and `\\` within your expression.\n\nSee this [tutorial on using globs](https://gist.github.com/reggi/475793ea1846affbcfe8).\n\n_Note_: Double quotes around the glob are recommended for portability.\n"
  },
  {
    "path": "docs/src/env.d.ts",
    "content": "/// <reference path=\"../.astro/types.d.ts\" />\n/// <reference types=\"astro/client\" />\n"
  },
  {
    "path": "docs/src/style/custom.css",
    "content": ":root {\n  /* Fonts */\n  --sl-font: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n\n  /* Color bases */\n  --sl-color-mocha-vibrant: #c6b4a5;\n  --sl-color-mocha-light: #8d6748;\n  --sl-color-mocha-dark: #6a4728;\n\n  /* Dark mode colors. */\n  --sl-color-accent-low: #534134;\n  --sl-color-accent-high: #d4c6bb;\n  --sl-color-accent-text: var(--sl-color-mocha-vibrant);\n  --sl-color-accent: var(--sl-color-mocha-light);\n  --sl-color-white: #f3ede7;\n  --sl-color-gray-1: #f1eadf;\n  --sl-color-gray-2: #cfc6c4;\n  --sl-color-gray-3: #b0a09d;\n  --sl-color-gray-4: #635451;\n  --sl-color-gray-5: #423432;\n  --sl-color-gray-6: #302321;\n  --sl-color-gray-7: #201210;\n  --sl-color-gray-8: #100100;\n  --sl-color-black: #1d1715;\n\n  --mocha-color-backdrop: var(--sl-color-gray-1);\n}\n\n/* Light mode colors. */\n:root[data-theme=\"light\"] {\n  --sl-color-accent-low: #dfd5cc;\n  --sl-color-accent-high: #3f2e21;\n  --sl-color-accent-text: var(--sl-color-accent-high);\n  --sl-color-accent: var(--sl-color-mocha-dark);\n  --sl-color-white: #1d1715;\n  --sl-color-gray-1: #302321;\n  --sl-color-gray-2: #423432;\n  --sl-color-gray-3: #635451;\n  --sl-color-gray-4: #978784;\n  --sl-color-gray-5: #c8c0be;\n  --sl-color-gray-6: #f3ecea;\n  --sl-color-gray-7: #f9f5f5;\n  --sl-color-gray-8: #fcfafa;\n  --sl-color-black: #ffffff;\n\n  --mocha-color-backdrop: var(--sl-color-black);\n}\n\n/* Override the default blue with our brown grays */\n.starlight-aside--note {\n  --sl-color-asides-text-accent: var(--sl-color-gray-high);\n  --sl-color-asides-border: var(--sl-color-gray);\n  background-color: var(--sl-color-gray-8);\n  border: 1px solid var(--sl-color-gray-6);\n}\n\n/* Fix (todo: file issue) */\n.starlight-aside__title + .starlight-aside__content:empty {\n  margin-top: 0;\n}\n"
  },
  {
    "path": "docs/tsconfig.json",
    "content": "{\n  \"extends\": \"astro/tsconfigs/strict\"\n}\n"
  },
  {
    "path": "eslint.config.js",
    "content": "\"use strict\";\n\nconst js = require(\"@eslint/js\");\nconst { defineConfig, globalIgnores } = require(\"eslint/config\");\nconst n = require(\"eslint-plugin-n\");\nconst globals = require(\"globals\");\nconst { default: markdown } = require(\"@eslint/markdown\");\n\nconst messages = {\n  gh237: \"See https://github.com/mochajs/mocha/issues/237\",\n  gh3604: \"See https://github.com/mochajs/mocha/issues/3604\",\n};\n\nmodule.exports = defineConfig(\n  {\n    files: [\"**/*.{cjs,js,mjs}\"],\n    extends: [n.configs[\"flat/recommended-script\"], js.configs.recommended],\n    languageOptions: {\n      ecmaVersion: 2022,\n      globals: {\n        ...globals.browser,\n        ...globals.node,\n      },\n    },\n    rules: {\n      \"no-redeclare\": \"off\",\n      \"no-undef\": \"off\",\n      \"n/no-process-exit\": \"off\",\n      \"n/no-unpublished-require\": \"off\",\n      \"n/no-unsupported-features/node-builtins\": \"off\",\n      strict: [\"error\", \"global\"],\n    },\n  },\n  {\n    files: [\n      \".wallaby.js\",\n      \"package-scripts.js\",\n      \"karma.conf.js\",\n      \"bin/*\",\n      \"lib/cli/**/*.js\",\n      \"lib/nodejs/**/*.js\",\n      \"scripts/**/*.{js,mjs}\",\n      \"test/**/*.{js,mjs}\",\n    ],\n    languageOptions: {\n      globals: globals.node,\n    },\n  },\n  {\n    files: [\n      \"**/*.mjs\",\n      \"lib/nodejs/esm-utils.js\",\n      \"scripts/pick-from-package-json.js\",\n      \"test/compiler-cjs/test.js\",\n      \"test/compiler-esm/*.js\",\n    ],\n    languageOptions: {\n      sourceType: \"module\",\n    },\n  },\n  {\n    files: [\"test/**/*.{js,mjs}\"],\n    languageOptions: {\n      globals: {\n        ...globals.browser,\n        ...globals.mocha,\n        ...globals.node,\n        expect: \"readonly\",\n      },\n    },\n  },\n  {\n    files: [\"bin/*\", \"lib/**/*.js\"],\n    rules: {\n      \"no-restricted-globals\": [\n        \"error\",\n        {\n          message: messages.gh237,\n          name: \"setTimeout\",\n        },\n        {\n          message: messages.gh237,\n          name: \"clearTimeout\",\n        },\n        {\n          message: messages.gh237,\n          name: \"setInterval\",\n        },\n        {\n          message: messages.gh237,\n          name: \"clearInterval\",\n        },\n        {\n          message: messages.gh237,\n          name: \"setImmediate\",\n        },\n        {\n          message: messages.gh237,\n          name: \"clearImmediate\",\n        },\n        {\n          message: messages.gh237,\n          name: \"Date\",\n        },\n      ],\n      \"no-restricted-modules\": [\"error\", \"timers\"],\n      \"no-restricted-syntax\": [\n        \"error\",\n        // disallow `global.setTimeout()`, `global.setInterval()`, etc.\n        {\n          message: messages.gh237,\n          selector:\n            \"CallExpression[callee.object.name=global][callee.property.name=/(set|clear)(Timeout|Immediate|Interval)/]\",\n        },\n        // disallow `new global.Date()`\n        {\n          message: messages.gh237,\n          selector:\n            \"NewExpression[callee.object.name=global][callee.property.name=Date]\",\n        },\n        // disallow property access of `global.<timer>.*`\n        {\n          message: messages.gh237,\n          selector:\n            \"*[object.object.name=global][object.property.name=/(Date|(set|clear)(Timeout|Immediate|Interval))/]:expression\",\n        },\n      ],\n    },\n  },\n  {\n    files: [\"lib/reporters/*.js\"],\n    rules: {\n      \"no-restricted-syntax\": [\n        \"error\",\n        // disallow Reporters using `console.log()`\n        {\n          message: messages.gh3604,\n          selector:\n            \"CallExpression[callee.object.name=console][callee.property.name=log]\",\n        },\n      ],\n    },\n  },\n  {\n    files: [\"**/*.md\"],\n    plugins: {\n      markdown,\n    },\n    extends: [\"markdown/recommended\"],\n    language: \"markdown/gfm\",\n    rules: {\n      \"markdown/no-multiple-h1\": \"off\",\n      \"markdown/fenced-code-language\": \"off\",\n      \"markdown/no-missing-label-refs\": \"off\",\n      \"markdown/no-duplicate-headings\": [\"error\", { checkSiblingsOnly: true }],\n    },\n  },\n  globalIgnores([\n    \".karma/**\",\n    \"**/*.{fixture,min}.{js,mjs}\",\n    \"coverage/**\",\n    \"docs/{.astro,dist}/**\",\n    \"mocha.js\",\n    \"out/**\",\n    \"test/integration/fixtures/**\",\n    // TODO: ESLint's parser can't parse import attributes\n    \"rollup.config.mjs\",\n    \"scripts/pick-from-package-json.mjs\",\n  ]),\n);\n"
  },
  {
    "path": "example/config/.mocharc.js",
    "content": "\"use strict\";\n\n// This is a JavaScript-based config file containing every Mocha option plus others.\n// If you need conditional logic, you might want to use this type of config,\n// e.g. set options via environment variables 'process.env'.\n// Otherwise, JSON or YAML is recommended.\n\nmodule.exports = {\n  \"allow-uncaught\": false,\n  \"async-only\": false,\n  bail: false,\n  \"check-leaks\": false,\n  color: true,\n  delay: false,\n  diff: true,\n  exit: false, // could be expressed as \"'no-exit': true\"\n  extension: [\"js\", \"cjs\", \"mjs\"],\n  \"fail-zero\": true,\n  fgrep: \"something\", // fgrep and grep are mutually exclusive\n  file: [\"/path/to/some/file\", \"/path/to/some/other/file\"],\n  \"forbid-only\": false,\n  \"forbid-pending\": false,\n  \"full-trace\": false,\n  global: [\"jQuery\", \"$\"],\n  grep: /something/i, // also 'something', fgrep and grep are mutually exclusive\n  growl: false,\n  ignore: [\"/path/to/some/ignored/file\"],\n  \"inline-diffs\": false,\n  // invert: false, // needs to be used with grep or fgrep\n  jobs: 1,\n  \"node-option\": [\"unhandled-rejections=strict\"], // without leading \"--\", also V8 flags\n  package: \"./package.json\",\n  parallel: false,\n  recursive: false,\n  reporter: \"spec\",\n  \"reporter-option\": [\"foo=bar\", \"baz=quux\"], // array, not object\n  require: \"@babel/register\",\n  retries: 1,\n  slow: \"75\",\n  sort: false,\n  spec: [\"test/**/*.spec.js\"], // the positional arguments!\n  timeout: \"2000\", // same as \"timeout: '2s'\"\n  // timeout: false, // same as \"timeout: 0\"\n  \"trace-warnings\": true, // node flags ok\n  ui: \"bdd\",\n  \"v8-stack-trace-limit\": 100, // V8 flags are prepended with \"v8-\"\n  watch: false,\n  \"watch-files\": [\"lib/**/*.js\", \"test/**/*.js\"],\n  \"watch-ignore\": [\"lib/vendor\"],\n};\n"
  },
  {
    "path": "example/config/.mocharc.json",
    "content": "// This config file contains Mocha's defaults.\n// This same configuration could be provided in the `mocha` property of your\n// project's `package.json`.\n{\n  \"diff\": true,\n  \"extension\": [\"js\", \"cjs\", \"mjs\"],\n  \"package\": \"./package.json\",\n  \"reporter\": \"spec\",\n  \"slow\": \"75\",\n  \"timeout\": \"2000\",\n  \"ui\": \"bdd\",\n  \"watch-files\": [\"lib/**/*.js\", \"test/**/*.js\"],\n  \"watch-ignore\": [\"lib/vendor\"]\n}\n"
  },
  {
    "path": "example/config/.mocharc.jsonc",
    "content": "// This config file contains Mocha's defaults.\n// As you can see, comments are allowed.\n// This same configuration could be provided in the `mocha` property of your\n// project's `package.json`.\n{\n  \"diff\": true,\n  \"extension\": [\"js\", \"cjs\", \"mjs\"],\n  \"package\": /* 📦 */ \"./package.json\",\n  \"reporter\": /* 📋 */ \"spec\",\n  \"slow\": \"75\",\n  \"timeout\": \"2000\",\n  \"ui\": \"bdd\",\n  \"watch-files\": [\"lib/**/*.js\", \"test/**/*.js\"],\n  \"watch-ignore\": [\"lib/vendor\"],\n}\n"
  },
  {
    "path": "example/config/.mocharc.yml",
    "content": "# This is an example Mocha config containing every Mocha option plus others.\nallow-uncaught: false\nasync-only: false\nbail: false\ncheck-leaks: false\ncolor: true\ndelay: false\ndiff: true\nexit: false # could be expressed as \"no-exit: true\"\nextension: [\"js\", \"cjs\", \"mjs\"]\nfail-zero: true\n# fgrep and grep are mutually exclusive\nfgrep: \"something\"\nfile:\n  - \"/path/to/some/file\"\n  - \"/path/to/some/other/file\"\nforbid-only: false\nforbid-pending: false\nfull-trace: false\nglobal:\n  - \"jQuery\"\n  - \"$\"\n# fgrep and grep are mutually exclusive\ngrep: \"/something/i\" # also 'something'\ngrowl: false\nignore:\n  - \"/path/to/some/ignored/file\"\ninline-diffs: false\n# needs to be used with grep or fgrep\n# invert: false\njobs: 1\nnode-option:\n  - \"unhandled-rejections=strict\" # without leading \"--\", also V8 flags\npackage: \"./package.json\"\nparallel: false\nrecursive: false\nreporter: \"spec\"\nreporter-option: # array, not object\n  - \"foo=bar\"\n  - \"baz=quux\"\nrequire: \"@babel/register\"\nretries: 1\nslow: \"75\"\nsort: false\nspec:\n  - \"test/**/*.spec.js\" # the positional arguments!\ntimeout: \"2000\" # same as \"timeout: '2s'\"\n# timeout: false # same as \"timeout: 0\"\ntrace-warnings: true # node flags ok\nui: \"bdd\"\nv8-stack-trace-limit: 100 # V8 flags are prepended with \"v8-\"\nwatch: false\nwatch-files:\n  - \"lib/**/*.js\"\n  - \"test/**/*.js\"\nwatch-ignore:\n  - \"lib/vendor\"\n"
  },
  {
    "path": "example/config/README.md",
    "content": "# Mocha Configuration Examples\n\nIn this directory, you'll find example Mocha configurations for Node.js.\n\nAs of this writing, **these examples are intended to illustrate the available options; they are not intended to serve as boilerplates.**\n\n[Read more about configuration here](https://mochajs.org/#configuring-mocha-nodejs).\n"
  },
  {
    "path": "index.js",
    "content": "\"use strict\";\n\nmodule.exports = require(\"./lib/mocha\");\n"
  },
  {
    "path": "karma.conf.js",
    "content": "/**\n * Mocha's Karma config.\n *\n * IMPORTANT:\n * - Karma must _always_ be run with `NODE_PATH=.` where `.` is the project\n *   root; this allows `karma-mocha` to use our built version of Mocha\n * - You must build Mocha's browser bundle before running Karma. This is\n *   typically done automatically in `package-scripts.js`.\n *\n * There are actually several different configurations here depending on the\n * values of various environment variables (e.g., `MOCHA_TEST`, `CI`, etc.),\n * which is why it's so hairy.\n *\n * This code avoids mutating the configuration object (the `cfg` variable)\n * directly; instead, we create new objects/arrays. This makes it a little more\n * obvious what's happening, even though it's verbose.\n *\n * The main export is a function which Karma calls with a config object; the\n * final line of this function should be `config.set(cfg)` which registers the\n * configuration we've built.\n */\n\n\"use strict\";\nconst fs = require(\"node:fs\");\nconst path = require(\"node:path\");\nconst os = require(\"node:os\");\nconst rollupPlugin = require(\"./scripts/karma-rollup-plugin\");\nconst BASE_BUNDLE_DIR_PATH = path.join(__dirname, \".karma\");\nconst env = process.env;\nconst hostname = os.hostname();\nconst BROWSER = env.BROWSER;\n\n/**\n * @type KarmaConfig\n */\nconst baseConfig = {\n  frameworks: [\"rollup\", \"mocha\"],\n  files: [\n    // we use the BDD interface for all of the tests that\n    // aren't interface-specific.\n    \"test/unit/*.spec.js\",\n  ],\n  plugins: [\n    \"karma-mocha\",\n    \"karma-mocha-reporter\",\n    \"karma-chrome-launcher\",\n    rollupPlugin,\n  ],\n  rollup: {\n    configFile: \"rollup.config.mjs\",\n    include: [\"test/**\"],\n  },\n  reporters: [\"mocha\"],\n  colors: true,\n  browsers: [\"ChromeHeadless\"],\n  client: {\n    mocha: {\n      // this helps debug\n      reporter: \"html\",\n    },\n  },\n  mochaReporter: {\n    showDiff: true,\n  },\n  customLaunchers: {\n    ChromeDebug: {\n      base: \"Chrome\",\n      flags: [\"--remote-debugging-port=9333\"],\n    },\n  },\n};\n\n/**\n *\n * @param {KarmaConfig} config\n */\nmodule.exports = (config) => {\n  let bundleDirPath = path.join(BASE_BUNDLE_DIR_PATH, hostname);\n  let cfg = { ...baseConfig };\n\n  // configuration for CI mode\n  if (env.CI) {\n    console.error(\"CI mode enabled\");\n    if (env.GITHUB_RUN_ID) {\n      console.error(\"Github Actions detected\");\n      const buildId = `github-${env.GITHUB_RUN_ID}_${env.GITHUB_RUN_NUMBER}`;\n      bundleDirPath = path.join(BASE_BUNDLE_DIR_PATH, buildId);\n    } else {\n      console.error(`Local environment (${hostname}) detected`);\n      console.error(`CI + local environment is not supported`);\n      console.error(`https://github.com/mochajs/mocha/issues/5616`);\n    }\n  }\n\n  cfg = createBundleDir(cfg, bundleDirPath);\n  cfg = chooseTestSuite(cfg, env.MOCHA_TEST);\n\n  // include sourcemap\n  cfg = {\n    ...cfg,\n    files: [...cfg.files, { pattern: \"./mocha.js.map\", included: false }],\n  };\n\n  if (BROWSER) {\n    cfg = {\n      ...cfg,\n      browsers: [BROWSER],\n    };\n  }\n\n  config.set(cfg);\n};\n\n/**\n * Creates dir `bundleDirPath` if it does not exist; returns new Karma config\n * containing `bundleDirPath` for rollup plugin.\n *\n * If this fails, the rollup plugin will use a temp dir.\n * @param {KarmaConfig} cfg\n * @param {string} [bundleDirPath] Path where the output bundle should live\n * @returns {KarmaConfig} New Karma config\n */\nconst createBundleDir = (cfg, bundleDirPath) => {\n  if (bundleDirPath) {\n    try {\n      fs.mkdirSync(bundleDirPath, { recursive: true });\n      cfg = {\n        ...cfg,\n        rollup: {\n          ...cfg.rollup,\n          bundleDirPath,\n        },\n      };\n    } catch {\n      console.error(\n        `Failed to create ${bundleDirPath}; using temp directory instead`,\n      );\n    }\n  }\n  return { ...cfg };\n};\n\n/**\n * Returns a new Karma config containing standard dependencies for our tests.\n *\n * Most suites use this.\n * @param {KarmaConfig} cfg\n * @returns {KarmaConfig} New Karma config\n */\nconst addStandardDependencies = (cfg) => ({\n  ...cfg,\n  files: [\n    require.resolve(\"sinon/pkg/sinon.js\"),\n    require.resolve(\"unexpected/unexpected\"),\n    {\n      pattern: require.resolve(\"unexpected/unexpected.js.map\"),\n      included: false,\n    },\n    require.resolve(\"unexpected-sinon\"),\n    require.resolve(\"unexpected-eventemitter/dist/unexpected-eventemitter.js\"),\n    require.resolve(\"./test/browser-specific/setup\"),\n    ...cfg.files,\n  ],\n  rollup: {\n    ...cfg.rollup,\n    external: [\n      \"sinon\",\n      \"unexpected\",\n      \"unexpected-eventemitter\",\n      \"unexpected-sinon\",\n    ],\n    globals: {\n      sinon: \"sinon\",\n      unexpected: \"weknowhow.expect\",\n      \"unexpected-sinon\": \"weknowhow.unexpectedSinon\",\n      \"unexpected-eventemitter\": \"unexpectedEventEmitter\",\n    },\n  },\n});\n\n/**\n * Returns a new Karma config to run with specific configuration (which cannot\n * be run with other configurations) as specified by `value`. Known values:\n *\n * - `bdd` - `bdd`-specific tests\n * - `tdd` - `tdd`-specific tests\n * - `qunit` - `qunit`-specific tests\n * - `esm` - ESM-specific tests\n *\n * Since we can't change Mocha's interface on-the-fly, tests for specific interfaces\n * must be run in isolation.\n * @param {KarmaConfig} cfg\n * @param {string} [value] Configuration identifier, if any\n * @returns {KarmaConfig} New Karma config\n */\nconst chooseTestSuite = (cfg, value) => {\n  switch (value) {\n    case \"bdd\":\n    case \"tdd\":\n    case \"qunit\":\n      return addStandardDependencies({\n        ...cfg,\n        files: [`test/interfaces/${value}.spec.js`],\n        client: {\n          ...cfg.client,\n          mocha: {\n            ...cfg.client.mocha,\n            ui: value,\n          },\n        },\n      });\n    case \"esm\":\n      return addStandardDependencies({\n        ...cfg,\n        files: [\n          {\n            pattern: \"test/browser-specific/fixtures/esm.fixture.mjs\",\n            type: \"module\",\n          },\n          {\n            pattern: \"test/browser-specific/esm.spec.mjs\",\n            type: \"module\",\n          },\n        ],\n      });\n    default:\n      return addStandardDependencies({ ...cfg });\n  }\n};\n\n/**\n * @typedef {object} KarmaConfig\n * @property {string[]} files\n */\n"
  },
  {
    "path": "lib/browser/highlight-tags.js",
    "content": "\"use strict\";\n\n/**\n * Highlight the given string of `js`.\n *\n * @private\n * @param {string} js\n * @return {string}\n */\nfunction highlight(js) {\n  return js\n    .replace(/</g, \"&lt;\")\n    .replace(/>/g, \"&gt;\")\n    .replace(/\\/\\/(.*)/gm, '<span class=\"comment\">//$1</span>')\n    .replace(/('.*?')/gm, '<span class=\"string\">$1</span>')\n    .replace(/(\\d+\\.\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(/(\\d+)/gm, '<span class=\"number\">$1</span>')\n    .replace(\n      /\\bnew[ \\t]+(\\w+)/gm,\n      '<span class=\"keyword\">new</span> <span class=\"init\">$1</span>',\n    )\n    .replace(\n      /\\b(function|new|throw|return|var|if|else)\\b/gm,\n      '<span class=\"keyword\">$1</span>',\n    );\n}\n\n/**\n * Highlight the contents of tag `name`.\n *\n * @private\n * @param {string} name\n */\nmodule.exports = function highlightTags(name) {\n  var code = document.getElementById(\"mocha\").getElementsByTagName(name);\n  for (var i = 0, len = code.length; i < len; ++i) {\n    code[i].innerHTML = highlight(code[i].innerHTML);\n  }\n};\n"
  },
  {
    "path": "lib/browser/parse-query.js",
    "content": "\"use strict\";\n\n/**\n * Parse the given `qs`.\n *\n * @private\n * @param {string} qs\n * @return {Object<string, string>}\n */\nmodule.exports = function parseQuery(qs) {\n  return qs\n    .replace(\"?\", \"\")\n    .split(\"&\")\n    .reduce(function (obj, pair) {\n      var i = pair.indexOf(\"=\");\n      var key = pair.slice(0, i);\n      var val = pair.slice(i + 1);\n\n      // Due to how the URLSearchParams API treats spaces\n      obj[key] = decodeURIComponent(val.replace(/\\+/g, \"%20\"));\n\n      return obj;\n    }, {});\n};\n"
  },
  {
    "path": "lib/browser/template.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>Mocha</title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <link rel=\"stylesheet\" href=\"mocha.css\" />\n  </head>\n  <body>\n    <div id=\"mocha\"></div>\n    <script src=\"mocha.js\"></script>\n    <script>\n      mocha.setup(\"bdd\");\n    </script>\n    <script src=\"tests.spec.js\"></script>\n    <script>\n      mocha.run();\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "lib/cli/cli.js",
    "content": "\"use strict\";\n\n/**\n * Contains CLI entry point and public API for programmatic usage in Node.js.\n * - Option parsing is handled by {@link https://npm.im/yargs yargs}.\n * - If executed via `node`, this module will run {@linkcode module:lib/cli.main main()}.\n * @public\n * @module lib/cli\n */\n\nconst debug = require(\"debug\")(\"mocha:cli:cli\");\nconst yargs = require(\"yargs\");\nconst path = require(\"node:path\");\nconst {\n  loadRc,\n  loadPkgRc,\n  loadOptions,\n  YARGS_PARSER_CONFIG,\n} = require(\"./options\");\nconst lookupFiles = require(\"./lookup-files\");\nconst commands = require(\"./commands\");\nconst pc = require(\"picocolors\");\nconst {\n  repository,\n  homepage,\n  version,\n  discord,\n} = require(\"../../package.json\");\nconst { cwd, logSymbols } = require(\"../utils\");\n\n/**\n * - Accepts an `Array` of arguments\n * - Modifies {@link https://nodejs.org/api/modules.html#modules_module_paths Node.js' search path} for easy loading of consumer modules\n * - Sets {@linkcode https://nodejs.org/api/errors.html#errors_error_stacktracelimit Error.stackTraceLimit} to `Infinity`\n * @public\n * @summary Mocha's main command-line entry-point.\n * @param {string[]} argv - Array of arguments to parse, or by default the lovely `process.argv.slice(2)`\n * @param {object} [mochaArgs] - Object of already parsed Mocha arguments (by bin/mocha)\n */\nexports.main = (argv = process.argv.slice(2), mochaArgs) => {\n  debug(\"entered main with raw args\", argv);\n  // ensure we can require() from current working directory\n  if (typeof module.paths !== \"undefined\") {\n    module.paths.push(cwd(), path.resolve(\"node_modules\"));\n  }\n\n  try {\n    Error.stackTraceLimit = Infinity; // configurable via --stack-trace-limit?\n  } catch (err) {\n    debug(\"unable to set Error.stackTraceLimit = Infinity\", err);\n  }\n\n  var args = mochaArgs || loadOptions(argv);\n\n  yargs()\n    .scriptName(\"mocha\")\n    .command(commands.run)\n    .command(commands.init)\n    .updateStrings({\n      \"Positionals:\": \"Positional Arguments\",\n      \"Options:\": \"Other Options\",\n      \"Commands:\": \"Commands\",\n    })\n    .fail((msg, err, yargs) => {\n      debug(\"caught error sometime before command handler: %O\", err);\n      yargs.showHelp();\n      console.error(`\\n${logSymbols.error} ${pc.red(\"ERROR:\")} ${msg}`);\n      if (!msg) {\n        // Log raw error and stack when an unexpected error is encountered, to\n        // make debugging easier (instead of an inactionable \"ERROR: null\").\n        console.error(err);\n      }\n      process.exit(1);\n    })\n    .help(\"help\", \"Show usage information & exit\")\n    .alias(\"help\", \"h\")\n    .version(\"version\", \"Show version number & exit\", version)\n    .alias(\"version\", \"V\")\n    .wrap(process.stdout.columns ? Math.min(process.stdout.columns, 80) : 80)\n    .epilog(\n      `${pc.reset(\"Mocha Resources\")}\n    Chat: ${pc.magenta(discord)}\n  GitHub: ${pc.blue(repository.url)}\n    Docs: ${pc.yellow(homepage)}\n      `,\n    )\n    .parserConfiguration(YARGS_PARSER_CONFIG)\n    .config(args)\n    .parse(args._);\n};\n\nexports.lookupFiles = lookupFiles;\nexports.loadOptions = loadOptions;\nexports.loadPkgRc = loadPkgRc;\nexports.loadRc = loadRc;\n\n// allow direct execution\nif (require.main === module) {\n  exports.main();\n}\n"
  },
  {
    "path": "lib/cli/collect-files.js",
    "content": "\"use strict\";\n\nconst path = require(\"node:path\");\nconst pc = require(\"picocolors\");\nconst debug = require(\"debug\")(\"mocha:cli:run:helpers\");\nconst { minimatch } = require(\"minimatch\");\nconst { NO_FILES_MATCH_PATTERN } = require(\"../error-constants\").constants;\nconst lookupFiles = require(\"./lookup-files\");\nconst { castArray } = require(\"../utils\");\n\n/**\n * Exports a function that collects test files from CLI parameters.\n * @see module:lib/cli/run-helpers\n * @see module:lib/cli/watch-run\n * @module\n * @private\n */\n\n/**\n * @typedef {import('../types.d.ts').FileCollectionOptions} FileCollectionOptions\n * @typedef {import('../types.d.ts').FileCollectionResponse} FileCollectionResponse\n */\n\n/**\n * Smash together an array of test files in the correct order\n * @param {FileCollectionOptions} [opts] - Options\n * @returns {FileCollectionResponse} An object containing a list of files to test and unmatched files.\n * @private\n */\nmodule.exports = ({\n  ignore,\n  extension,\n  file: fileArgs,\n  recursive,\n  sort,\n  spec,\n} = {}) => {\n  const unmatchedSpecFiles = [];\n  const specFiles = spec.reduce((specFiles, arg) => {\n    try {\n      const moreSpecFiles = castArray(lookupFiles(arg, extension, recursive))\n        .filter((filename) =>\n          ignore.every(\n            (pattern) =>\n              !minimatch(filename, pattern, { windowsPathsNoEscape: true }),\n          ),\n        )\n        .map((filename) => path.resolve(filename));\n      return [...specFiles, ...moreSpecFiles];\n    } catch (err) {\n      if (err.code === NO_FILES_MATCH_PATTERN) {\n        unmatchedSpecFiles.push({ message: err.message, pattern: err.pattern });\n        return specFiles;\n      }\n\n      throw err;\n    }\n  }, []);\n\n  // check that each file passed in to --file exists\n\n  const unmatchedFiles = [];\n  fileArgs.forEach((file) => {\n    const fileAbsolutePath = path.resolve(file);\n    try {\n      // Used instead of fs.existsSync to ensure that file-ending less files are still resolved correctly\n      require.resolve(fileAbsolutePath);\n    } catch (err) {\n      if (err.code === \"MODULE_NOT_FOUND\") {\n        unmatchedFiles.push({\n          pattern: file,\n          absolutePath: fileAbsolutePath,\n        });\n        return;\n      }\n\n      throw err;\n    }\n  });\n\n  // ensure we don't sort the stuff from fileArgs; order is important!\n  if (sort) {\n    specFiles.sort();\n  }\n\n  // add files given through --file to be ran first\n  const files = [\n    ...fileArgs.map((filepath) => path.resolve(filepath)),\n    ...specFiles,\n  ];\n  debug(\"test files (in order): \", files);\n\n  if (!files.length) {\n    // give full message details when only 1 file is missing\n    const noneFoundMsg =\n      unmatchedSpecFiles.length === 1\n        ? `Error: No test files found: ${JSON.stringify(\n            unmatchedSpecFiles[0].pattern,\n          )}` // stringify to print escaped characters raw\n        : \"Error: No test files found\";\n    console.error(pc.red(noneFoundMsg));\n    process.exit(1);\n  } else {\n    // print messages as a warning\n    unmatchedSpecFiles.forEach((warning) => {\n      console.warn(pc.yellow(`Warning: ${warning.message}`));\n    });\n  }\n\n  return {\n    files,\n    unmatchedFiles,\n  };\n};\n"
  },
  {
    "path": "lib/cli/commands.js",
    "content": "\"use strict\";\n\n/**\n * Exports Yargs commands\n * @see https://github.com/yargs/yargs/blob/main/docs/advanced.md\n * @private\n * @module\n */\n\nmodule.exports = {\n  init: require(\"./init\"),\n  // default command\n  run: require(\"./run\"),\n};\n"
  },
  {
    "path": "lib/cli/config.js",
    "content": "\"use strict\";\n\n/**\n * Responsible for loading / finding Mocha's \"rc\" files.\n *\n * @private\n * @module\n */\n\nconst fs = require(\"node:fs\");\nconst path = require(\"node:path\");\nconst debug = require(\"debug\")(\"mocha:cli:config\");\nconst findUp = require(\"find-up\");\nconst { createUnparsableFileError } = require(\"../errors\");\nconst utils = require(\"../utils\");\n\n/**\n * These are the valid config files, in order of precedence;\n * e.g., if `.mocharc.js` is present, then `.mocharc.yaml` and the rest\n * will be ignored.\n * The user should still be able to explicitly specify a file.\n * @private\n */\nexports.CONFIG_FILES = [\n  \".mocharc.cjs\",\n  \".mocharc.js\",\n  \".mocharc.mjs\",\n  \".mocharc.yaml\",\n  \".mocharc.yml\",\n  \".mocharc.jsonc\",\n  \".mocharc.json\",\n];\n\n/**\n * Parsers for various config filetypes. Each accepts a filepath and\n * returns an object (but could throw)\n */\nconst parsers = (exports.parsers = {\n  yaml: (filepath) =>\n    require(\"js-yaml\").load(fs.readFileSync(filepath, \"utf8\")),\n  js: (filepath) => {\n    let cwdFilepath;\n    try {\n      debug('parsers: load cwd-relative path: \"%s\"', path.resolve(filepath));\n      cwdFilepath = require.resolve(path.resolve(filepath)); // evtl. throws\n      return require(cwdFilepath);\n    } catch (err) {\n      if (cwdFilepath) throw err;\n\n      debug('parsers: retry load as module-relative path: \"%s\"', filepath);\n      return require(filepath);\n    }\n  },\n  json: (filepath) =>\n    JSON.parse(\n      require(\"strip-json-comments\").default(fs.readFileSync(filepath, \"utf8\")),\n    ),\n});\n\n/**\n * Loads and parses, based on file extension, a config file.\n * \"JSON\" files may have comments.\n *\n * @private\n * @param {string} filepath - Config file path to load\n * @returns {Object} Parsed config object\n */\nexports.loadConfig = (filepath) => {\n  let config;\n  debug(\"loadConfig: trying to parse config at %s\", filepath);\n\n  const ext = path.extname(filepath);\n  try {\n    if (ext === \".yml\" || ext === \".yaml\") {\n      config = parsers.yaml(filepath);\n    } else if (ext === \".js\" || ext === \".cjs\" || ext === \".mjs\") {\n      const parsedConfig = parsers.js(filepath);\n      config = parsedConfig.default ?? parsedConfig;\n    } else {\n      config = parsers.json(filepath);\n    }\n  } catch (err) {\n    throw createUnparsableFileError(\n      `Unable to read/parse ${filepath}: ${err}`,\n      filepath,\n    );\n  }\n  return config;\n};\n\n/**\n * Find (\"find up\") config file starting at `cwd`\n *\n * @param {string} [cwd] - Current working directory\n * @returns {string|null} Filepath to config, if found\n */\nexports.findConfig = (cwd = utils.cwd()) => {\n  const filepath = findUp.sync(exports.CONFIG_FILES, { cwd });\n  if (filepath) {\n    debug(\"findConfig: found config file %s\", filepath);\n  }\n  return filepath;\n};\n"
  },
  {
    "path": "lib/cli/index.js",
    "content": "\"use strict\";\n\nmodule.exports = require(\"./cli\");\n"
  },
  {
    "path": "lib/cli/init.js",
    "content": "\"use strict\";\n\n/**\n * Command module for \"init\" command\n *\n * @private\n * @module\n */\n\nconst fs = require(\"node:fs\");\nconst path = require(\"node:path\");\n\nexports.command = \"init <path>\";\n\nexports.description = \"create a client-side Mocha setup at <path>\";\n\nexports.builder = (yargs) =>\n  yargs.positional(\"path\", {\n    type: \"string\",\n    normalize: true,\n  });\n\nexports.handler = (argv) => {\n  const destdir = argv.path;\n  const srcdir = path.join(__dirname, \"..\", \"..\");\n  fs.mkdirSync(destdir, { recursive: true });\n  const css = fs.readFileSync(path.join(srcdir, \"mocha.css\"));\n  const js = fs.readFileSync(path.join(srcdir, \"mocha.js\"));\n  const tmpl = fs.readFileSync(\n    path.join(srcdir, \"lib\", \"browser\", \"template.html\"),\n  );\n  fs.writeFileSync(path.join(destdir, \"mocha.css\"), css);\n  fs.writeFileSync(path.join(destdir, \"mocha.js\"), js);\n  fs.writeFileSync(path.join(destdir, \"tests.spec.js\"), \"\");\n  fs.writeFileSync(path.join(destdir, \"index.html\"), tmpl);\n};\n"
  },
  {
    "path": "lib/cli/lookup-files.js",
    "content": "\"use strict\";\n/**\n * Contains `lookupFiles`, which takes some globs/dirs/options and returns a list of files.\n * @module\n * @private\n */\n\nvar fs = require(\"node:fs\");\nvar path = require(\"node:path\");\nvar glob = require(\"glob\");\nvar errors = require(\"../errors\");\nvar createNoFilesMatchPatternError = errors.createNoFilesMatchPatternError;\nvar createMissingArgumentError = errors.createMissingArgumentError;\nconst debug = require(\"debug\")(\"mocha:cli:lookup-files\");\n\n/**\n * Determines if pathname would be a \"hidden\" file (or directory) on UN*X.\n *\n * @description\n * On UN*X, pathnames beginning with a full stop (aka dot) are hidden during\n * typical usage. Dotfiles, plain-text configuration files, are prime examples.\n *\n * @see {@link http://xahlee.info/UnixResource_dir/writ/unix_origin_of_dot_filename.html|Origin of Dot File Names}\n *\n * @private\n * @param {string} pathname - Pathname to check for match.\n * @return {boolean} whether pathname would be considered a hidden file.\n * @example\n * isHiddenOnUnix('.profile'); // => true\n */\nconst isHiddenOnUnix = (pathname) => path.basename(pathname).startsWith(\".\");\n\n/**\n * Determines if pathname has a matching file extension.\n *\n * Supports multi-part extensions.\n *\n * @private\n * @param {string} pathname - Pathname to check for match.\n * @param {string[]} exts - List of file extensions, w/-or-w/o leading period\n * @return {boolean} `true` if file extension matches.\n * @example\n * hasMatchingExtname('foo.html', ['js', 'css']); // false\n * hasMatchingExtname('foo.js', ['.js']); // true\n * hasMatchingExtname('foo.js', ['js']); // ture\n */\nconst hasMatchingExtname = (pathname, exts = []) =>\n  exts\n    .map((ext) => (ext.startsWith(\".\") ? ext : `.${ext}`))\n    .some((ext) => pathname.endsWith(ext));\n\n/**\n * Lookup file names at the given `path`.\n *\n * @description\n * Filenames are returned in _traversal_ order by the OS/filesystem.\n * **Make no assumption that the names will be sorted in any fashion.**\n *\n * @public\n * @alias module:lib/cli.lookupFiles\n * @param {string} filepath - Base path to start searching from.\n * @param {string[]} [extensions=[]] - File extensions to look for.\n * @param {boolean} [recursive=false] - Whether to recurse into subdirectories.\n * @return {string[]} An array of paths.\n * @throws {Error} if no files match pattern.\n * @throws {TypeError} if `filepath` is directory and `extensions` not provided.\n */\nmodule.exports = function lookupFiles(\n  filepath,\n  extensions = [],\n  recursive = false,\n) {\n  const files = [];\n  let stat;\n\n  if (!fs.existsSync(filepath)) {\n    let pattern;\n    if (glob.hasMagic(filepath, { windowsPathsNoEscape: true })) {\n      // Handle glob as is without extensions\n      pattern = filepath;\n    } else {\n      // glob pattern e.g. 'filepath+(.js|.ts)'\n      const strExtensions = extensions\n        .map((ext) => (ext.startsWith(\".\") ? ext : `.${ext}`))\n        .join(\"|\");\n      pattern = `${filepath}+(${strExtensions})`;\n      debug(\"looking for files using glob pattern: %s\", pattern);\n    }\n    files.push(\n      ...glob\n        .sync(pattern, {\n          nodir: true,\n          windowsPathsNoEscape: true,\n        })\n        // glob@8 and earlier sorted results in en; glob@9 depends on OS sorting.\n        // This preserves the older glob behavior.\n        // https://github.com/mochajs/mocha/pull/5250/files#r1840469747\n        .sort((a, b) => a.localeCompare(b, \"en\")),\n    );\n    if (!files.length) {\n      throw createNoFilesMatchPatternError(\n        `Cannot find any files matching pattern \"${filepath}\"`,\n        filepath,\n      );\n    }\n    return files;\n  }\n\n  // Handle file\n  try {\n    stat = fs.statSync(filepath);\n    if (stat.isFile() || stat.isFIFO()) {\n      return filepath;\n    }\n  } catch {\n    // ignore error\n    return;\n  }\n\n  // Handle directory\n  fs.readdirSync(filepath).forEach((dirent) => {\n    const pathname = path.join(filepath, dirent);\n    let stat;\n\n    try {\n      stat = fs.statSync(pathname);\n      if (stat.isDirectory()) {\n        if (recursive) {\n          files.push(...lookupFiles(pathname, extensions, recursive));\n        }\n        return;\n      }\n    } catch {\n      return;\n    }\n    if (!extensions.length) {\n      throw createMissingArgumentError(\n        `Argument '${extensions}' required when argument '${filepath}' is a directory`,\n        \"extensions\",\n        \"array\",\n      );\n    }\n\n    if (\n      !stat.isFile() ||\n      !hasMatchingExtname(pathname, extensions) ||\n      isHiddenOnUnix(pathname)\n    ) {\n      return;\n    }\n    files.push(pathname);\n  });\n\n  return files;\n};\n"
  },
  {
    "path": "lib/cli/node-flags.js",
    "content": "\"use strict\";\n\n/**\n * Some settings and code related to Mocha's handling of Node.js/V8 flags.\n * @private\n * @module\n */\n\nconst nodeFlags = process.allowedNodeEnvironmentFlags;\nconst { isMochaFlag } = require(\"./run-option-metadata\");\nconst unparse = require(\"yargs-unparser\");\n\n/**\n * These flags are considered \"debug\" flags.\n * @see {@link impliesNoTimeouts}\n * @private\n */\nconst debugFlags = new Set([\"inspect\", \"inspect-brk\"]);\n\n/**\n * Mocha has historical support for various `node` and V8 flags which might not\n * appear in `process.allowedNodeEnvironmentFlags`.\n * These include:\n *   - `--preserve-symlinks`\n *   - `--harmony-*`\n *   - `--gc-global`\n *   - `--trace-*`\n *   - `--es-staging`\n *   - `--use-strict`\n *   - `--v8-*` (but *not* `--v8-options`)\n * @summary Whether or not to pass a flag along to the `node` executable.\n * @param {string} flag - Flag to test\n * @param {boolean} [bareword=true] - If `false`, we expect `flag` to have one or two leading dashes.\n * @returns {boolean} If the flag is considered a \"Node\" flag.\n * @private\n */\nexports.isNodeFlag = (flag, bareword = true) => {\n  if (!bareword) {\n    // check if the flag begins with dashes; if not, not a node flag.\n    if (!/^--?/.test(flag)) {\n      return false;\n    }\n    // strip the leading dashes to match against subsequent checks\n    flag = flag.replace(/^--?/, \"\");\n  }\n  return (\n    // check actual node flags from `process.allowedNodeEnvironmentFlags`,\n    // then historical support for various V8 and non-`NODE_OPTIONS` flags\n    // and also any V8 flags with `--v8-` prefix\n    (!isMochaFlag(flag) && nodeFlags && nodeFlags.has(flag)) ||\n    debugFlags.has(flag) ||\n    /(?:preserve-symlinks(?:-main)?|harmony(?:[_-]|$)|(?:trace[_-].+$)|gc[_-]global$|es[_-]staging$|use[_-]strict$|v8[_-](?!options).+?$)/.test(\n      flag,\n    )\n  );\n};\n\n/**\n * Returns `true` if the flag is a \"debug-like\" flag.  These require timeouts\n * to be suppressed, or pausing the debugger on breakpoints will cause test failures.\n * @param {string} flag - Flag to test\n * @returns {boolean}\n * @private\n */\nexports.impliesNoTimeouts = (flag) => debugFlags.has(flag);\n\n/**\n * All non-strictly-boolean arguments to node--those with values--must specify those values using `=`, e.g., `--inspect=0.0.0.0`.\n * Unparse these arguments using `yargs-unparser` (which would result in `--inspect 0.0.0.0`), then supply `=` where we have values.\n * There's probably an easier or more robust way to do this; fixes welcome\n * @param {Object} opts - Arguments object\n * @returns {string[]} Unparsed arguments using `=` to specify values\n * @private\n */\nexports.unparseNodeFlags = (opts) => {\n  var args = unparse(opts);\n  return args.length\n    ? args\n        .join(\" \")\n        .split(/\\b/)\n        .map((arg) => (arg === \" \" ? \"=\" : arg))\n        .join(\"\")\n        .split(\" \")\n    : [];\n};\n"
  },
  {
    "path": "lib/cli/one-and-dones.js",
    "content": "\"use strict\";\n\n/**\n * Contains \"command\" code for \"one-and-dones\"--options passed\n * to Mocha which cause it to just dump some info and exit.\n * See {@link module:lib/cli/one-and-dones.ONE_AND_DONE_ARGS ONE_AND_DONE_ARGS} for more info.\n * @module\n * @private\n */\n\nconst Mocha = require(\"../mocha\");\n\n/**\n * Dumps a sorted list of the enumerable, lower-case keys of some object\n * to `STDOUT`.\n * @param {Object} obj - Object, ostensibly having some enumerable keys\n * @ignore\n * @private\n */\nconst showKeys = (obj) => {\n  console.log();\n  const keys = Object.keys(obj);\n  const maxKeyLength = keys.reduce((max, key) => Math.max(max, key.length), 0);\n  keys\n    .filter(\n      (key) =>\n        /^[a-z]/.test(key) && !obj[key].browserOnly && !obj[key].abstract,\n    )\n    .sort()\n    .forEach((key) => {\n      const description = obj[key].description;\n      console.log(\n        `    ${key.padEnd(maxKeyLength + 1)}${\n          description ? `- ${description}` : \"\"\n        }`,\n      );\n    });\n  console.log();\n};\n\n/**\n * Handlers for one-and-done options\n * @namespace\n * @private\n */\nexports.ONE_AND_DONES = {\n  /**\n   * Dump list of built-in interfaces\n   * @private\n   */\n  \"list-interfaces\": () => {\n    showKeys(Mocha.interfaces);\n  },\n  /**\n   * Dump list of built-in reporters\n   * @private\n   */\n  \"list-reporters\": () => {\n    showKeys(Mocha.reporters);\n  },\n};\n\n/**\n * A Set of all one-and-done options\n * @type Set<string>\n * @private\n */\nexports.ONE_AND_DONE_ARGS = new Set(\n  [\"help\", \"h\", \"version\", \"V\"].concat(Object.keys(exports.ONE_AND_DONES)),\n);\n"
  },
  {
    "path": "lib/cli/options.js",
    "content": "\"use strict\";\n\n/**\n * Main entry point for handling filesystem-based configuration,\n * whether that's a config file or `package.json` or whatever.\n * @module lib/cli/options\n * @private\n */\n\nconst fs = require(\"node:fs\");\nconst pc = require(\"picocolors\");\nconst yargsParser = require(\"yargs-parser\");\nconst {\n  types,\n  aliases,\n  isMochaFlag,\n  expectedTypeForFlag,\n} = require(\"./run-option-metadata\");\nconst { ONE_AND_DONE_ARGS } = require(\"./one-and-dones\");\nconst mocharc = require(\"../mocharc.json\");\nconst { list } = require(\"./run-helpers\");\nconst { loadConfig, findConfig } = require(\"./config\");\nconst findUp = require(\"find-up\");\nconst debug = require(\"debug\")(\"mocha:cli:options\");\nconst { isNodeFlag } = require(\"./node-flags\");\nconst {\n  createUnparsableFileError,\n  createInvalidArgumentTypeError,\n  createUnsupportedError,\n} = require(\"../errors\");\nconst { isNumeric } = require(\"../utils\");\n\n/**\n * The `yargs-parser` namespace\n * @external yargsParser\n * @see {@link https://npm.im/yargs-parser}\n */\n\n/**\n * An object returned by a configured `yargs-parser` representing arguments\n * @memberof external:yargsParser\n * @interface Arguments\n */\n\n/**\n * Base yargs parser configuration\n * @private\n */\nconst YARGS_PARSER_CONFIG = {\n  \"combine-arrays\": true,\n  \"short-option-groups\": false,\n  \"dot-notation\": false,\n  \"strip-aliased\": true,\n};\n\n/**\n * This is the config pulled from the `yargs` property of Mocha's\n * `package.json`, but it also disables camel case expansion as to\n * avoid outputting non-canonical keynames, as we need to do some\n * lookups.\n * @private\n * @ignore\n */\nconst configuration = Object.assign({}, YARGS_PARSER_CONFIG, {\n  \"camel-case-expansion\": false,\n});\n\n/**\n * This is a really fancy way to:\n * - `array`-type options: ensure unique values and evtl. split comma-delimited lists\n * - `boolean`/`number`/`string`- options: use last element when given multiple times\n * This is passed as the `coerce` option to `yargs-parser`\n * @private\n * @ignore\n */\nconst globOptions = [\"spec\", \"ignore\"];\nconst coerceOpts = Object.assign(\n  types.array.reduce(\n    (acc, arg) =>\n      Object.assign(acc, {\n        [arg]: (v) =>\n          Array.from(new Set(globOptions.includes(arg) ? v : list(v))),\n      }),\n    {},\n  ),\n  types.boolean\n    .concat(types.string, types.number)\n    .reduce(\n      (acc, arg) =>\n        Object.assign(acc, { [arg]: (v) => (Array.isArray(v) ? v.pop() : v) }),\n      {},\n    ),\n);\n\n/**\n * We do not have a case when multiple arguments are ever allowed after a flag\n * (e.g., `--foo bar baz quux`), so we fix the number of arguments to 1 across\n * the board of non-boolean options.\n * This is passed as the `narg` option to `yargs-parser`\n * @private\n * @ignore\n */\nconst nargOpts = types.array\n  .concat(types.string, types.number)\n  .reduce((acc, arg) => Object.assign(acc, { [arg]: 1 }), {});\n\n/**\n * Throws either \"UNSUPPORTED\" error or \"INVALID_ARG_TYPE\" error for numeric positional arguments.\n * @param {string[]} allArgs - Stringified args passed to mocha cli\n * @param {number} numericArg - Numeric positional arg for which error must be thrown\n * @param {Object} parsedResult - Result from `yargs-parser`\n * @private\n * @ignore\n */\nconst createErrorForNumericPositionalArg = (\n  numericArg,\n  allArgs,\n  parsedResult,\n) => {\n  // A flag for `numericArg` exists if:\n  // 1. A mocha flag immediately preceeded the numericArg in `allArgs` array and\n  // 2. `numericArg` value could not be assigned to this flag by `yargs-parser` because of incompatible datatype.\n  const flag = allArgs.find((arg, index) => {\n    const normalizedArg = arg.replace(/^--?/, \"\");\n    return (\n      isMochaFlag(arg) &&\n      allArgs[index + 1] === String(numericArg) &&\n      parsedResult[normalizedArg] !== String(numericArg)\n    );\n  });\n\n  if (flag) {\n    throw createInvalidArgumentTypeError(\n      `Mocha flag '${flag}' given invalid option: '${numericArg}'`,\n      numericArg,\n      expectedTypeForFlag(flag),\n    );\n  } else {\n    throw createUnsupportedError(\n      `Option ${numericArg} is unsupported by the mocha cli`,\n    );\n  }\n};\n\n/**\n * Wrapper around `yargs-parser` which applies our settings\n * @param {string|string[]} args - Arguments to parse\n * @param {Object} defaultValues - Default values of mocharc.json\n * @param  {...Object} configObjects - `configObjects` for yargs-parser\n * @private\n * @ignore\n */\nconst parse = (args = [], defaultValues = {}, ...configObjects) => {\n  // save node-specific args for special handling.\n  // 1. when these args have a \"=\" they should be considered to have values\n  // 2. if they don't, they are just boolean flags\n  // 3. to avoid explicitly defining the set of them, we tell yargs-parser they\n  //    are ALL boolean flags.\n  // 4. we can then reapply the values after yargs-parser is done.\n  const allArgs = Array.isArray(args) ? args : args.split(\" \");\n  const nodeArgs = allArgs.reduce((acc, arg) => {\n    const pair = arg.split(\"=\");\n    let flag = pair[0];\n    if (isNodeFlag(flag, false)) {\n      flag = flag.replace(/^--?/, \"\");\n      return acc.concat([[flag, arg.includes(\"=\") ? pair[1] : true]]);\n    }\n    return acc;\n  }, []);\n\n  const result = yargsParser.detailed(args, {\n    configuration,\n    configObjects,\n    default: defaultValues,\n    coerce: coerceOpts,\n    narg: nargOpts,\n    alias: aliases,\n    string: types.string,\n    array: types.array,\n    number: types.number,\n    boolean: types.boolean.concat(nodeArgs.map((pair) => pair[0])),\n  });\n  if (result.error) {\n    console.error(pc.red(`Error: ${result.error.message}`));\n    process.exit(1);\n  }\n\n  const numericPositionalArg = result.argv._.find((arg) => isNumeric(arg));\n  if (numericPositionalArg) {\n    createErrorForNumericPositionalArg(\n      numericPositionalArg,\n      allArgs,\n      result.argv,\n    );\n  }\n\n  // reapply \"=\" arg values from above\n  nodeArgs.forEach(([key, value]) => {\n    result.argv[key] = value;\n  });\n\n  return result.argv;\n};\n\n/**\n * Given path to config file in `args.config`, attempt to load & parse config file.\n * @param {Object} [args] - Arguments object\n * @param {string|boolean} [args.config] - Path to config file or `false` to skip\n * @public\n * @alias module:lib/cli.loadRc\n * @returns {external:yargsParser.Arguments|void} Parsed config, or nothing if `args.config` is `false`\n */\nconst loadRc = (args = {}) => {\n  if (args.config !== false) {\n    const config = args.config || findConfig();\n    return config ? loadConfig(config) : {};\n  }\n};\n\nmodule.exports.loadRc = loadRc;\n\n/**\n * Given path to `package.json` in `args.package`, attempt to load config from `mocha` prop.\n * @param {Object} [args] - Arguments object\n * @param {string|boolean} [args.config] - Path to `package.json` or `false` to skip\n * @public\n * @alias module:lib/cli.loadPkgRc\n * @returns {external:yargsParser.Arguments|void} Parsed config, or nothing if `args.package` is `false`\n */\nconst loadPkgRc = (args = {}) => {\n  let result;\n  if (args.package === false) {\n    return result;\n  }\n  result = {};\n  const filepath = args.package || findUp.sync(mocharc.package);\n  if (filepath) {\n    let configData;\n    try {\n      configData = fs.readFileSync(filepath, \"utf8\");\n    } catch (err) {\n      // If `args.package` was explicitly specified, throw an error\n      if (filepath == args.package) {\n        throw createUnparsableFileError(\n          `Unable to read ${filepath}: ${err}`,\n          filepath,\n        );\n      } else {\n        debug(\"failed to read default package.json at %s; ignoring\", filepath);\n        return result;\n      }\n    }\n    try {\n      const pkg = JSON.parse(configData);\n      if (pkg.mocha) {\n        debug(\"`mocha` prop of package.json parsed: %O\", pkg.mocha);\n        result = pkg.mocha;\n      } else {\n        debug(\"no config found in %s\", filepath);\n      }\n    } catch (err) {\n      // If JSON failed to parse, throw an error.\n      throw createUnparsableFileError(\n        `Unable to parse ${filepath}: ${err}`,\n        filepath,\n      );\n    }\n  }\n  return result;\n};\n\nmodule.exports.loadPkgRc = loadPkgRc;\n\n/**\n * Priority list:\n *\n * 1. Command-line args\n * 2. `MOCHA_OPTIONS` environment variable.\n * 3. RC file (`.mocharc.c?js`, `.mocharc.ya?ml`, `mocharc.json`)\n * 4. `mocha` prop of `package.json`\n * 5. default configuration (`lib/mocharc.json`)\n *\n * If a {@link module:lib/cli/one-and-dones.ONE_AND_DONE_ARGS \"one-and-done\" option} is present in the `argv` array, no external config files will be read.\n * @summary Parses options read from `.mocharc.*` and `package.json`.\n * @param {string|string[]} [argv] - Arguments to parse\n * @public\n * @alias module:lib/cli.loadOptions\n * @returns {external:yargsParser.Arguments} Parsed args from everything\n */\nconst loadOptions = (argv = []) => {\n  let args = parse(argv);\n  // short-circuit: look for a flag that would abort loading of options\n  if (\n    Array.from(ONE_AND_DONE_ARGS).reduce(\n      (acc, arg) => acc || arg in args,\n      false,\n    )\n  ) {\n    return args;\n  }\n\n  const envConfig = parse(process.env.MOCHA_OPTIONS || \"\");\n  const rcConfig = loadRc(args);\n  const pkgConfig = loadPkgRc(args);\n\n  if (rcConfig) {\n    args.config = false;\n    args._ = args._.concat(rcConfig._ || []);\n  }\n  if (pkgConfig) {\n    args.package = false;\n    args._ = args._.concat(pkgConfig._ || []);\n  }\n\n  args = parse(\n    args._,\n    mocharc,\n    args,\n    envConfig,\n    rcConfig || {},\n    pkgConfig || {},\n  );\n\n  // recombine positional arguments and \"spec\"\n  if (args.spec) {\n    args._ = args._.concat(args.spec);\n    delete args.spec;\n  }\n\n  // make unique\n  args._ = Array.from(new Set(args._));\n\n  return args;\n};\n\nmodule.exports.loadOptions = loadOptions;\nmodule.exports.YARGS_PARSER_CONFIG = YARGS_PARSER_CONFIG;\n"
  },
  {
    "path": "lib/cli/run-helpers.js",
    "content": "\"use strict\";\n\n/**\n * Helper scripts for the `run` command\n * @see module:lib/cli/run\n * @module\n * @private\n */\n\n/**\n * @typedef {import('../mocha.js')} Mocha\n * @typedef {import('../types.d.ts').MochaOptions} MochaOptions\n * @typedef {import('../types.d.ts').UnmatchedFile} UnmatchedFile\n * @typedef {import('../runner.js')} Runner\n */\n\nconst fs = require(\"node:fs\");\nconst path = require(\"node:path\");\nconst pc = require(\"picocolors\");\nconst debug = require(\"debug\")(\"mocha:cli:run:helpers\");\nconst { watchRun, watchParallelRun } = require(\"./watch-run\");\nconst collectFiles = require(\"./collect-files\");\nconst { format } = require(\"node:util\");\nconst { createInvalidLegacyPluginError } = require(\"../errors\");\nconst { requireOrImport } = require(\"../nodejs/esm-utils\");\nconst PluginLoader = require(\"../plugin-loader\");\n\n/**\n * Exits Mocha when tests + code under test has finished execution (default)\n * @param {number} clampedCode - Exit code; typically # of failures\n * @ignore\n * @private\n */\nconst exitMochaLater = (clampedCode) => {\n  process.on(\"exit\", () => {\n    process.exitCode = Math.min(\n      clampedCode,\n      process.argv.includes(\"--posix-exit-codes\") ? 1 : 255,\n    );\n  });\n};\n\n/**\n * Exits Mocha when Mocha itself has finished execution, regardless of\n * what the tests or code under test is doing.\n * @param {number} clampedCode - Exit code; typically # of failures\n * @ignore\n * @private\n */\nconst exitMocha = (clampedCode) => {\n  const usePosixExitCodes = process.argv.includes(\"--posix-exit-codes\");\n  clampedCode = Math.min(clampedCode, usePosixExitCodes ? 1 : 255);\n  let draining = 0;\n\n  // Eagerly set the process's exit code in case stream.write doesn't\n  // execute its callback before the process terminates.\n  process.exitCode = clampedCode;\n\n  // flush output for Node.js Windows pipe bug\n  // https://github.com/joyent/node/issues/6247 is just one bug example\n  // https://github.com/visionmedia/mocha/issues/333 has a good discussion\n  const done = () => {\n    if (!draining--) {\n      process.exit(clampedCode);\n    }\n  };\n\n  const streams = [process.stdout, process.stderr];\n\n  streams.forEach((stream) => {\n    // submit empty write request and wait for completion\n    draining += 1;\n    stream.write(\"\", done);\n  });\n\n  done();\n};\n\n/**\n * Coerce a comma-delimited string (or array thereof) into a flattened array of\n * strings\n * @param {string|string[]} str - Value to coerce\n * @returns {string[]} Array of strings\n * @private\n */\nexports.list = (str) =>\n  Array.isArray(str) ? exports.list(str.join(\",\")) : str.split(/ *, */);\n\n/**\n * `require()` the modules as required by `--require <require>`.\n *\n * Returns array of `mochaHooks` exports, if any.\n * @param {string[]} requires - Modules to require\n * @returns {Promise<object>} Plugin implementations\n * @private\n */\nexports.handleRequires = async (\n  requires = [],\n  { ignoredPlugins = [] } = {},\n) => {\n  const pluginLoader = PluginLoader.create({ ignore: ignoredPlugins });\n  for await (const mod of requires) {\n    let modpath = mod;\n    // this is relative to cwd\n    if (fs.existsSync(mod) || fs.existsSync(`${mod}.js`)) {\n      modpath = path.resolve(mod);\n      debug(\"resolved required file %s to %s\", mod, modpath);\n    }\n    const requiredModule = await requireOrImport(modpath);\n    if (requiredModule && typeof requiredModule === \"object\") {\n      if (pluginLoader.load(requiredModule)) {\n        debug(\"found one or more plugin implementations in %s\", modpath);\n      }\n    }\n    debug('loaded required module \"%s\"', mod);\n  }\n  const plugins = await pluginLoader.finalize();\n  if (Object.keys(plugins).length) {\n    debug(\"finalized plugin implementations: %O\", plugins);\n  }\n  return plugins;\n};\n\n/**\n * Logs errors and exits the app if unmatched files exist\n * @param {Mocha} mocha - Mocha instance\n * @param {UnmatchedFile} unmatchedFiles - object containing unmatched file paths\n * @returns {Promise<Runner>}\n * @private\n */\nconst handleUnmatchedFiles = (mocha, unmatchedFiles) => {\n  if (unmatchedFiles.length === 0) {\n    return;\n  }\n\n  unmatchedFiles.forEach(({ pattern, absolutePath }) => {\n    console.error(\n      pc.yellow(\n        `Warning: Cannot find any files matching pattern \"${pattern}\" at the absolute path \"${absolutePath}\"`,\n      ),\n    );\n  });\n  console.log(\n    \"No test file(s) found with the given pattern, exiting with code 1\",\n  );\n\n  return mocha.run(exitMocha(1));\n};\n\n/**\n * Collect and load test files, then run mocha instance.\n * @param {Mocha} mocha - Mocha instance\n * @param {MochaOptions} [opts] - Command line options\n * @param {Object} fileCollectParams - Parameters that control test\n *   file collection. See `lib/cli/collect-files.js`.\n * @returns {Promise<Runner>}\n * @private\n */\nconst singleRun = async (\n  mocha,\n  { exit, passOnFailingTestSuite },\n  fileCollectParams,\n) => {\n  const fileCollectionObj = collectFiles(fileCollectParams);\n\n  if (fileCollectionObj.unmatchedFiles.length > 0) {\n    return handleUnmatchedFiles(mocha, fileCollectionObj.unmatchedFiles);\n  }\n\n  debug(\"single run with %d file(s)\", fileCollectionObj.files.length);\n  mocha.files = fileCollectionObj.files;\n\n  // handles ESM modules\n  await mocha.loadFilesAsync();\n  return mocha.run(createExitHandler({ exit, passOnFailingTestSuite }));\n};\n\n/**\n * Collect files and run tests (using `Runner`).\n *\n * This is `async` for consistency.\n *\n * @param {Mocha} mocha - Mocha instance\n * @param {MochaOptions} options - Command line options\n * @param {Object} fileCollectParams - Parameters that control test\n *   file collection. See `lib/cli/collect-files.js`.\n * @returns {Promise<Runner>}\n * @ignore\n * @private\n */\nconst parallelRun = async (mocha, options, fileCollectParams) => {\n  const fileCollectionObj = collectFiles(fileCollectParams);\n\n  if (fileCollectionObj.unmatchedFiles.length > 0) {\n    return handleUnmatchedFiles(mocha, fileCollectionObj.unmatchedFiles);\n  }\n\n  debug(\n    \"executing %d test file(s) in parallel mode\",\n    fileCollectionObj.files.length,\n  );\n  mocha.files = fileCollectionObj.files;\n\n  // note that we DO NOT load any files here; this is handled by the worker\n  return mocha.run(createExitHandler(options));\n};\n\n/**\n * Actually run tests.  Delegates to one of four different functions:\n * - `singleRun`: run tests in serial & exit\n * - `watchRun`: run tests in serial, rerunning as files change\n * - `parallelRun`: run tests in parallel & exit\n * - `watchParallelRun`: run tests in parallel, rerunning as files change\n * @param {Mocha} mocha - Mocha instance\n * @param {MochaOptions} options - Command line options\n * @private\n * @returns {Promise<Runner>}\n */\nexports.runMocha = async (mocha, options) => {\n  const {\n    watch = false,\n    extension = [],\n    ignore = [],\n    file = [],\n    parallel = false,\n    recursive = false,\n    sort = false,\n    spec = [],\n  } = options;\n\n  const fileCollectParams = {\n    ignore,\n    extension,\n    file,\n    recursive,\n    sort,\n    spec,\n  };\n\n  let run;\n  if (watch) {\n    run = parallel ? watchParallelRun : watchRun;\n  } else {\n    run = parallel ? parallelRun : singleRun;\n  }\n\n  return run(mocha, options, fileCollectParams);\n};\n\n/**\n * Used for `--reporter` and `--ui`.  Ensures there's only one, and asserts that\n * it actually exists. This must be run _after_ requires are processed (see\n * {@link handleRequires}), as it'll prevent interfaces from loading otherwise.\n * @param {Object} opts - Options object\n * @param {\"reporter\"|\"ui\"} pluginType - Type of plugin.\n * @param {Object} [map] - Used as a cache of sorts;\n * `Mocha.reporters` where each key corresponds to a reporter name,\n * `Mocha.interfaces` where each key corresponds to an interface name.\n * @private\n */\nexports.validateLegacyPlugin = (opts, pluginType, map = {}) => {\n  /**\n   * This should be a unique identifier; either a string (present in `map`),\n   * or a resolvable (via `require.resolve`) module ID/path.\n   * @type {string}\n   */\n  const pluginId = opts[pluginType];\n\n  if (Array.isArray(pluginId)) {\n    throw createInvalidLegacyPluginError(\n      `\"--${pluginType}\" can only be specified once`,\n      pluginType,\n    );\n  }\n\n  const createUnknownError = (err) =>\n    createInvalidLegacyPluginError(\n      format('Could not load %s \"%s\":\\n\\n %O', pluginType, pluginId, err),\n      pluginType,\n      pluginId,\n    );\n\n  // if this exists, then it's already loaded, so nothing more to do.\n  if (!map[pluginId]) {\n    let foundId;\n    try {\n      foundId = require.resolve(pluginId);\n      map[pluginId] = require(foundId);\n    } catch (err) {\n      if (foundId) throw createUnknownError(err);\n\n      // Try to load reporters from a cwd-relative path\n      try {\n        map[pluginId] = require(path.resolve(pluginId));\n      } catch (err) {\n        throw createUnknownError(err);\n      }\n    }\n  }\n};\n\nconst createExitHandler = ({ exit, passOnFailingTestSuite }) => {\n  return (code) => {\n    const clampedCode = passOnFailingTestSuite ? 0 : Math.min(code, 255);\n\n    return exit ? exitMocha(clampedCode) : exitMochaLater(clampedCode);\n  };\n};\n"
  },
  {
    "path": "lib/cli/run-option-metadata.js",
    "content": "\"use strict\";\n\n/**\n * Metadata about various options of the `run` command\n * @see module:lib/cli/run\n * @module\n * @private\n */\n\n/**\n * Dictionary of yargs option types to list of options having said type\n * @type {Record<string, string[]>}\n * @private\n */\nconst TYPES = (exports.types = {\n  array: [\n    \"extension\",\n    \"file\",\n    \"global\",\n    \"ignore\",\n    \"node-option\",\n    \"reporter-option\",\n    \"require\",\n    \"spec\",\n    \"watch-files\",\n    \"watch-ignore\",\n  ],\n  boolean: [\n    \"allow-uncaught\",\n    \"async-only\",\n    \"bail\",\n    \"check-leaks\",\n    \"color\",\n    \"delay\",\n    \"diff\",\n    \"dry-run\",\n    \"exit\",\n    \"fail-hook-affected-tests\",\n    \"pass-on-failing-test-suite\",\n    \"fail-zero\",\n    \"forbid-only\",\n    \"forbid-pending\",\n    \"full-trace\",\n    \"inline-diffs\",\n    \"invert\",\n    \"list-interfaces\",\n    \"list-reporters\",\n    \"no-colors\",\n    \"parallel\",\n    \"posix-exit-codes\",\n    \"recursive\",\n    \"sort\",\n    \"watch\",\n  ],\n  number: [\"retries\", \"jobs\"],\n  string: [\n    \"config\",\n    \"fgrep\",\n    \"grep\",\n    \"package\",\n    \"reporter\",\n    \"ui\",\n    \"slow\",\n    \"timeout\",\n  ],\n});\n\n/**\n * Option aliases keyed by canonical option name.\n * Arrays used to reduce\n * @type {Record<string, string[]>}\n * @private\n */\nexports.aliases = {\n  \"async-only\": [\"A\"],\n  bail: [\"b\"],\n  color: [\"c\", \"colors\"],\n  fgrep: [\"f\"],\n  global: [\"globals\"],\n  grep: [\"g\"],\n  ignore: [\"exclude\"],\n  invert: [\"i\"],\n  jobs: [\"j\"],\n  \"no-colors\": [\"C\"],\n  \"node-option\": [\"n\"],\n  parallel: [\"p\"],\n  reporter: [\"R\"],\n  \"reporter-option\": [\"reporter-options\", \"O\"],\n  require: [\"r\"],\n  slow: [\"s\"],\n  sort: [\"S\"],\n  timeout: [\"t\", \"timeouts\"],\n  ui: [\"u\"],\n  watch: [\"w\"],\n};\n\nconst ALL_MOCHA_FLAGS = Object.keys(TYPES).reduce((acc, key) => {\n  // gets all flags from each of the fields in `types`, adds those,\n  // then adds aliases of each flag (if any)\n  TYPES[key].forEach((flag) => {\n    acc.add(flag);\n    const aliases = exports.aliases[flag] || [];\n    aliases.forEach((alias) => {\n      acc.add(alias);\n    });\n  });\n  return acc;\n}, new Set());\n\n/**\n * Returns `true` if the provided `flag` is known to Mocha.\n * @param {string} flag - Flag to check\n * @returns {boolean} If `true`, this is a Mocha flag\n * @private\n */\nexports.isMochaFlag = (flag) => {\n  return ALL_MOCHA_FLAGS.has(flag.replace(/^--?/, \"\"));\n};\n\n/**\n * Returns expected yarg option type for a given mocha flag.\n * @param {string} flag - Flag to check (can be with or without leading dashes \"--\"\")\n * @returns {string | undefined} - If flag is a valid mocha flag, the expected type of argument for this flag is returned, otherwise undefined is returned.\n * @private\n */\nexports.expectedTypeForFlag = (flag) => {\n  const normalizedName = flag.replace(/^--?/, \"\");\n\n  // If flag is an alias, get it's full name.\n  const aliases = exports.aliases;\n  const fullFlagName =\n    Object.keys(aliases).find((flagName) =>\n      aliases[flagName].includes(normalizedName),\n    ) || normalizedName;\n\n  return Object.keys(TYPES).find((flagType) =>\n    TYPES[flagType].includes(fullFlagName),\n  );\n};\n"
  },
  {
    "path": "lib/cli/run.js",
    "content": "\"use strict\";\n\n/**\n * Definition for Mocha's default (\"run tests\") command\n *\n * @module\n * @private\n */\n\nconst pc = require(\"picocolors\");\nconst Mocha = require(\"../mocha\");\nconst {\n  createUnsupportedError,\n  createInvalidArgumentValueError,\n  createMissingArgumentError,\n} = require(\"../errors\");\n\nconst {\n  list,\n  handleRequires,\n  validateLegacyPlugin,\n  runMocha,\n} = require(\"./run-helpers\");\nconst { ONE_AND_DONES, ONE_AND_DONE_ARGS } = require(\"./one-and-dones\");\nconst debug = require(\"debug\")(\"mocha:cli:run\");\nconst defaults = require(\"../mocharc.json\");\nconst { types, aliases } = require(\"./run-option-metadata\");\nconst { isCI, logSymbols } = require(\"../utils\");\n\n/**\n * Logical option groups\n * @constant\n */\nconst GROUPS = {\n  FILES: \"File Handling\",\n  FILTERS: \"Test Filters\",\n  NODEJS: \"Node.js & V8\",\n  OUTPUT: \"Reporting & Output\",\n  RULES: \"Rules & Behavior\",\n  CONFIG: \"Configuration\",\n};\n\nexports.command = [\"$0 [spec..]\", \"inspect\"];\n\nexports.describe = \"Run tests with Mocha\";\n\nexports.builder = (yargs) =>\n  yargs\n    .options({\n      \"allow-uncaught\": {\n        description: \"Allow uncaught errors to propagate\",\n        group: GROUPS.RULES,\n      },\n      \"async-only\": {\n        description:\n          \"Require all tests to use a callback (async) or return a Promise\",\n        group: GROUPS.RULES,\n      },\n      bail: {\n        description: 'Abort (\"bail\") after first test failure',\n        group: GROUPS.RULES,\n      },\n      \"check-leaks\": {\n        description: \"Check for global variable leaks\",\n        group: GROUPS.RULES,\n      },\n      color: {\n        description: \"Force-enable color output\",\n        group: GROUPS.OUTPUT,\n      },\n      config: {\n        config: true,\n        defaultDescription: \"(nearest rc file)\",\n        description: \"Path to config file\",\n        group: GROUPS.CONFIG,\n      },\n      delay: {\n        description: \"Delay initial execution of root suite\",\n        group: GROUPS.RULES,\n      },\n      diff: {\n        default: true,\n        description: \"Show diff on failure\",\n        group: GROUPS.OUTPUT,\n      },\n      \"dry-run\": {\n        description: \"Report tests without executing them\",\n        group: GROUPS.RULES,\n      },\n      exit: {\n        description: \"Force Mocha to quit after tests complete\",\n        group: GROUPS.RULES,\n      },\n      extension: {\n        default: defaults.extension,\n        description: \"File extension(s) to load\",\n        group: GROUPS.FILES,\n        requiresArg: true,\n        coerce: list,\n      },\n      \"pass-on-failing-test-suite\": {\n        default: false,\n        description: \"Not fail test run if tests were failed\",\n        group: GROUPS.RULES,\n      },\n      \"fail-hook-affected-tests\": {\n        description:\n          \"Report tests as failed when affected by hook failures (before/beforeEach)\",\n        group: GROUPS.RULES,\n      },\n      \"fail-zero\": {\n        description: \"Fail test run if no test(s) encountered\",\n        group: GROUPS.RULES,\n      },\n      fgrep: {\n        conflicts: \"grep\",\n        description: \"Only run tests containing this string\",\n        group: GROUPS.FILTERS,\n        requiresArg: true,\n      },\n      file: {\n        defaultDescription: \"(none)\",\n        description:\n          \"Specify file(s) to be loaded prior to root suite execution\",\n        group: GROUPS.FILES,\n        normalize: true,\n        requiresArg: true,\n      },\n      \"forbid-only\": {\n        description: \"Fail if exclusive test(s) encountered\",\n        group: GROUPS.RULES,\n        default: isCI(),\n      },\n      \"forbid-pending\": {\n        description: \"Fail if pending test(s) encountered\",\n        group: GROUPS.RULES,\n      },\n      \"full-trace\": {\n        description: \"Display full stack traces\",\n        group: GROUPS.OUTPUT,\n      },\n      global: {\n        coerce: list,\n        description: \"List of allowed global variables\",\n        group: GROUPS.RULES,\n        requiresArg: true,\n      },\n      grep: {\n        coerce: (value) => (!value ? null : value),\n        conflicts: \"fgrep\",\n        description: \"Only run tests matching this string or regexp\",\n        group: GROUPS.FILTERS,\n        requiresArg: true,\n      },\n      ignore: {\n        defaultDescription: \"(none)\",\n        description: \"Ignore file(s) or glob pattern(s)\",\n        group: GROUPS.FILES,\n        requiresArg: true,\n      },\n      \"inline-diffs\": {\n        description:\n          \"Display actual/expected differences inline within each string\",\n        group: GROUPS.OUTPUT,\n      },\n      invert: {\n        description: \"Inverts --grep and --fgrep matches\",\n        group: GROUPS.FILTERS,\n      },\n      jobs: {\n        description:\n          \"Number of concurrent jobs for --parallel; use 1 to run in serial\",\n        defaultDescription: \"(number of CPU cores - 1)\",\n        requiresArg: true,\n        group: GROUPS.RULES,\n      },\n      \"list-interfaces\": {\n        conflicts: Array.from(ONE_AND_DONE_ARGS).filter(\n          (arg) => arg !== \"list-interfaces\",\n        ),\n        description: \"List built-in user interfaces & exit\",\n      },\n      \"list-reporters\": {\n        conflicts: Array.from(ONE_AND_DONE_ARGS).filter(\n          (arg) => arg !== \"list-reporters\",\n        ),\n        description: \"List built-in reporters & exit\",\n      },\n      \"no-colors\": {\n        description: \"Force-disable color output\",\n        group: GROUPS.OUTPUT,\n        hidden: true,\n      },\n      \"node-option\": {\n        description: 'Node or V8 option (no leading \"--\")',\n        group: GROUPS.CONFIG,\n      },\n      package: {\n        description: \"Path to package.json for config\",\n        group: GROUPS.CONFIG,\n        normalize: true,\n        requiresArg: true,\n      },\n      parallel: {\n        description: \"Run tests in parallel\",\n        group: GROUPS.RULES,\n      },\n      \"posix-exit-codes\": {\n        description:\n          \"Use POSIX and UNIX shell exit codes as Mocha's return value\",\n        group: GROUPS.RULES,\n      },\n      recursive: {\n        description: \"Look for tests in subdirectories\",\n        group: GROUPS.FILES,\n      },\n      reporter: {\n        default: defaults.reporter,\n        description: \"Specify reporter to use\",\n        group: GROUPS.OUTPUT,\n        requiresArg: true,\n      },\n      \"reporter-option\": {\n        coerce: (opts) =>\n          list(opts).reduce((acc, opt) => {\n            const pair = opt.split(\"=\");\n\n            if (pair.length > 2 || !pair.length) {\n              throw createInvalidArgumentValueError(\n                `invalid reporter option '${opt}'`,\n                \"--reporter-option\",\n                opt,\n                'expected \"key=value\" format',\n              );\n            }\n\n            acc[pair[0]] = pair.length === 2 ? pair[1] : true;\n            return acc;\n          }, {}),\n        description: \"Reporter-specific options (<k=v,[k1=v1,..]>)\",\n        group: GROUPS.OUTPUT,\n        requiresArg: true,\n      },\n      require: {\n        defaultDescription: \"(none)\",\n        description: \"Require module\",\n        group: GROUPS.FILES,\n        requiresArg: true,\n      },\n      retries: {\n        description: \"Retry failed tests this many times\",\n        group: GROUPS.RULES,\n      },\n      slow: {\n        default: defaults.slow,\n        description: 'Specify \"slow\" test threshold (in milliseconds)',\n        group: GROUPS.RULES,\n      },\n      sort: {\n        description: \"Sort test files\",\n        group: GROUPS.FILES,\n      },\n      timeout: {\n        default: defaults.timeout,\n        description: \"Specify test timeout threshold (in milliseconds)\",\n        group: GROUPS.RULES,\n      },\n      ui: {\n        default: defaults.ui,\n        description: \"Specify user interface\",\n        group: GROUPS.RULES,\n        requiresArg: true,\n      },\n      watch: {\n        description: \"Watch files in the current working directory for changes\",\n        group: GROUPS.FILES,\n      },\n      \"watch-files\": {\n        description: \"List of paths or globs to watch\",\n        group: GROUPS.FILES,\n        requiresArg: true,\n        coerce: list,\n      },\n      \"watch-ignore\": {\n        description: \"List of paths or globs to exclude from watching\",\n        group: GROUPS.FILES,\n        requiresArg: true,\n        coerce: list,\n        default: defaults[\"watch-ignore\"],\n      },\n    })\n    .positional(\"spec\", {\n      default: [\"test\"],\n      description: \"One or more files, directories, or globs to test\",\n      type: \"array\",\n    })\n    .check((argv) => {\n      // \"one-and-dones\"; let yargs handle help and version\n      Object.keys(ONE_AND_DONES).forEach((opt) => {\n        if (argv[opt]) {\n          ONE_AND_DONES[opt].call(null, yargs);\n          process.exit();\n        }\n      });\n\n      // yargs.implies() isn't flexible enough to handle this\n      if (argv.invert && !(\"fgrep\" in argv || \"grep\" in argv)) {\n        throw createMissingArgumentError(\n          '\"--invert\" requires one of \"--fgrep <str>\" or \"--grep <regexp>\"',\n          \"--fgrep|--grep\",\n          \"string|regexp\",\n        );\n      }\n\n      if (argv.parallel) {\n        // yargs.conflicts() can't deal with `--file foo.js --no-parallel`, either\n        if (argv.file) {\n          throw createUnsupportedError(\n            \"--parallel runs test files in a non-deterministic order, and is mutually exclusive with --file\",\n          );\n        }\n\n        // or this\n        if (argv.sort) {\n          throw createUnsupportedError(\n            \"--parallel runs test files in a non-deterministic order, and is mutually exclusive with --sort\",\n          );\n        }\n\n        if (argv.reporter === \"progress\") {\n          throw createUnsupportedError(\n            \"--reporter=progress is mutually exclusive with --parallel\",\n          );\n        }\n\n        if (argv.reporter === \"markdown\") {\n          throw createUnsupportedError(\n            \"--reporter=markdown is mutually exclusive with --parallel\",\n          );\n        }\n\n        if (argv.reporter === \"json-stream\") {\n          throw createUnsupportedError(\n            \"--reporter=json-stream is mutually exclusive with --parallel\",\n          );\n        }\n      }\n\n      return true;\n    })\n    .middleware(async (argv, yargs) => {\n      // currently a failing middleware does not work nicely with yargs' `fail()`.\n      try {\n        // load requires first, because it can impact \"plugin\" validation\n        const plugins = await handleRequires(argv.require);\n        validateLegacyPlugin(argv, \"reporter\", Mocha.reporters);\n        validateLegacyPlugin(argv, \"ui\", Mocha.interfaces);\n        Object.assign(argv, plugins);\n      } catch (err) {\n        // this could be a bad --require, bad reporter, ui, etc.\n        console.error(`\\n${logSymbols.error} ${pc.red(\"ERROR:\")}`, err);\n        yargs.exit(1);\n      }\n    })\n    .array(types.array)\n    .boolean(types.boolean)\n    .string(types.string)\n    .number(types.number)\n    .alias(aliases);\n\nexports.handler = async function (argv) {\n  debug(\"post-yargs config\", argv);\n  const mocha = new Mocha(argv);\n\n  try {\n    await runMocha(mocha, argv);\n  } catch (err) {\n    console.error(\"\\n Exception during run:\", err);\n    process.exit(1);\n  }\n};\n"
  },
  {
    "path": "lib/cli/watch-run.js",
    "content": "\"use strict\";\n\nconst debug = require(\"debug\")(\"mocha:cli:watch\");\nconst path = require(\"node:path\");\nconst chokidar = require(\"chokidar\");\nconst glob = require(\"glob\");\nconst isPathInside = require(\"is-path-inside\");\nconst { minimatch } = require(\"minimatch\");\nconst Context = require(\"../context\");\nconst collectFiles = require(\"./collect-files\");\nconst { logSymbols } = require(\"../utils\");\n\n/**\n * @typedef {import('chokidar').FSWatcher} FSWatcher\n * @typedef {import('glob').Glob['patterns'][number]} Pattern\n * The `Pattern` class is not exported by the `glob` package.\n * Ref [link](../../node_modules/glob/dist/commonjs/pattern.d.ts).\n * @typedef {import('../mocha.js')} Mocha\n * @typedef {import('../types.d.ts').BeforeWatchRun} BeforeWatchRun\n * @typedef {import('../types.d.ts').FileCollectionOptions} FileCollectionOptions\n * @typedef {import('../types.d.ts').Rerunner} Rerunner\n * @typedef {import('../types.d.ts').PathPattern} PathPattern\n * @typedef {import('../types.d.ts').PathFilter} PathFilter\n * @typedef {import('../types.d.ts').PathMatcher} PathMatcher\n */\n\n/**\n * Exports the `watchRun` function that runs mocha in \"watch\" mode.\n * @see module:lib/cli/run-helpers\n * @module\n * @private\n */\n\n/**\n * Run Mocha in parallel \"watch\" mode\n * @param {Mocha} mocha - Mocha instance\n * @param {Object} opts - Options\n * @param {string[]} [opts.watchFiles] - List of paths and patterns to\n *   watch. If not provided all files with an extension included in\n *   `fileCollectionParams.extension` are watched. See first argument of\n *   `chokidar.watch`.\n * @param {string[]} opts.watchIgnore - List of paths and patterns to\n *   exclude from watching. See `ignored` option of `chokidar`.\n * @param {FileCollectionOptions} fileCollectParams - Parameters that control test\n * @private\n */\nexports.watchParallelRun = (\n  mocha,\n  { watchFiles, watchIgnore },\n  fileCollectParams,\n) => {\n  debug(\"creating parallel watcher\");\n\n  return createWatcher(mocha, {\n    watchFiles,\n    watchIgnore,\n    beforeRun({ mocha }) {\n      // I don't know why we're cloning the root suite.\n      const rootSuite = mocha.suite.clone();\n\n      // ensure we aren't leaking event listeners\n      mocha.dispose();\n\n      // this `require` is needed because the require cache has been cleared.  the dynamic\n      // exports set via the below call to `mocha.ui()` won't work properly if a\n      // test depends on this module.\n      const Mocha = require(\"../mocha\");\n\n      // ... and now that we've gotten a new module, we need to use it again due\n      // to `mocha.ui()` call\n      const newMocha = new Mocha(mocha.options);\n      // don't know why this is needed\n      newMocha.suite = rootSuite;\n      // nor this\n      newMocha.suite.ctx = new Context();\n\n      // reset the list of files\n      newMocha.files = collectFiles(fileCollectParams).files;\n\n      // because we've swapped out the root suite (see the `run` inner function\n      // in `createRerunner`), we need to call `mocha.ui()` again to set up the context/globals.\n      newMocha.ui(newMocha.options.ui);\n\n      // we need to call `newMocha.rootHooks` to set up rootHooks for the new\n      // suite\n      newMocha.rootHooks(newMocha.options.rootHooks);\n\n      // in parallel mode, the main Mocha process doesn't actually load the\n      // files. this flag prevents `mocha.run()` from autoloading.\n      newMocha.lazyLoadFiles(true);\n      return newMocha;\n    },\n    fileCollectParams,\n  });\n};\n\n/**\n * Run Mocha in \"watch\" mode\n * @param {Mocha} mocha - Mocha instance\n * @param {Object} opts - Options\n * @param {string[]} [opts.watchFiles] - List of paths and patterns to\n *   watch. If not provided all files with an extension included in\n *   `fileCollectionParams.extension` are watched. See first argument of\n *   `chokidar.watch`.\n * @param {string[]} opts.watchIgnore - List of paths and patterns to\n *   exclude from watching. See `ignored` option of `chokidar`.\n * @param {FileCollectionOptions} fileCollectParams - Parameters that control test\n *   file collection. See `lib/cli/collect-files.js`.\n * @private\n */\nexports.watchRun = (mocha, { watchFiles, watchIgnore }, fileCollectParams) => {\n  debug(\"creating serial watcher\");\n\n  return createWatcher(mocha, {\n    watchFiles,\n    watchIgnore,\n    beforeRun({ mocha }) {\n      mocha.unloadFiles();\n\n      // I don't know why we're cloning the root suite.\n      const rootSuite = mocha.suite.clone();\n\n      // ensure we aren't leaking event listeners\n      mocha.dispose();\n\n      // this `require` is needed because the require cache has been cleared.  the dynamic\n      // exports set via the below call to `mocha.ui()` won't work properly if a\n      // test depends on this module.\n      const Mocha = require(\"../mocha\");\n\n      // ... and now that we've gotten a new module, we need to use it again due\n      // to `mocha.ui()` call\n      const newMocha = new Mocha(mocha.options);\n      // don't know why this is needed\n      newMocha.suite = rootSuite;\n      // nor this\n      newMocha.suite.ctx = new Context();\n\n      // reset the list of files\n      newMocha.files = collectFiles(fileCollectParams).files;\n\n      // because we've swapped out the root suite (see the `run` inner function\n      // in `createRerunner`), we need to call `mocha.ui()` again to set up the context/globals.\n      newMocha.ui(newMocha.options.ui);\n\n      // we need to call `newMocha.rootHooks` to set up rootHooks for the new\n      // suite\n      newMocha.rootHooks(newMocha.options.rootHooks);\n\n      return newMocha;\n    },\n    fileCollectParams,\n  });\n};\n\n/**\n * Extracts out paths without the glob part, the directory paths,\n * and the paths for matching from the provided glob paths.\n * @param {string[]} globPaths The list of glob paths to create a filter for.\n * @param {string} basePath The path where mocha is run (e.g., current working directory).\n * @returns {PathFilter} Object to filter paths.\n * @ignore\n * @private\n */\nfunction createPathFilter(globPaths, basePath) {\n  debug(\"creating path filter from glob paths: %s\", globPaths);\n\n  /**\n   * The resulting object to filter paths.\n   * @type {PathFilter}\n   */\n  const res = {\n    dir: { paths: new Set(), globs: new Set() },\n    match: { paths: new Set(), globs: new Set() },\n  };\n\n  // for checking if a path ends with `/**/*`\n  const globEnd = path.join(path.sep, \"**\", \"*\");\n\n  /**\n   * The current glob pattern to check.\n   * @type {Pattern[]}\n   */\n  const patterns = globPaths.flatMap((globPath) => {\n    return new glob.Glob(globPath, {\n      dot: true,\n      magicalBraces: true,\n      windowsPathsNoEscape: true,\n    }).patterns;\n  }, []);\n\n  // each pattern will have its own path because of the `magicalBraces` option\n  for (const pattern of patterns) {\n    debug(\"processing glob pattern: %s\", pattern.globString());\n\n    /**\n     * Path segments before the glob pattern.\n     * @type {string[]}\n     */\n    const segments = [];\n\n    /**\n     * The current glob pattern to check.\n     * @type {Pattern | null}\n     */\n    let currentPattern = pattern;\n    let isGlob = false;\n\n    do {\n      // save string patterns until a non-string (glob or regexp) is matched\n      const entry = currentPattern.pattern();\n      const isString = typeof entry === \"string\";\n      debug(\n        \"found %s pattern: %s\",\n        isString ? \"string\" : \"glob or regexp\",\n        entry,\n      );\n      if (!isString) {\n        // if the entry is a glob\n        isGlob = true;\n        break;\n      }\n\n      segments.push(entry);\n\n      // go to next pattern\n    } while ((currentPattern = currentPattern.rest()));\n    if (!isGlob) {\n      debug(\"all subpatterns of %j processed\", pattern.globString());\n    }\n\n    // match `cleanPath` (path without the glob part) and its subdirectories\n    const cleanPath = path.resolve(basePath, ...segments);\n    debug(\"clean path: %s\", cleanPath);\n    res.dir.paths.add(cleanPath);\n    res.dir.globs.add(path.resolve(cleanPath, \"**\", \"*\"));\n\n    // match `absPath` and all of its contents\n    const absPath = path.resolve(basePath, pattern.globString());\n    debug(\"absolute path: %s\", absPath);\n    (isGlob ? res.match.globs : res.match.paths).add(absPath);\n\n    // always include `/**/*` to the full pattern for matching\n    // since it's possible for the last path segment to be a directory\n    if (!absPath.endsWith(globEnd)) {\n      res.match.globs.add(path.resolve(absPath, \"**\", \"*\"));\n    }\n  }\n\n  debug(\"returning path filter: %o\", res);\n  return res;\n}\n\n/**\n * Checks if the provided path matches with the path pattern.\n * @param {string} filePath The path to match.\n * @param {PathPattern} pattern The path pattern for matching.\n * @param {boolean} [matchParent] Treats the provided path as a match if it's a valid parent directory from the list of paths.\n * @returns {boolean} Determines if the provided path matches the pattern.\n * @ignore\n * @private\n */\nfunction matchPattern(filePath, pattern, matchParent) {\n  if (pattern.paths.has(filePath)) {\n    return true;\n  }\n\n  if (matchParent) {\n    for (const childPath of pattern.paths) {\n      if (isPathInside(childPath, filePath)) {\n        return true;\n      }\n    }\n  }\n\n  // loop through the set of glob paths instead of converting it into an array\n  for (const globPath of pattern.globs) {\n    if (\n      minimatch(filePath, globPath, { dot: true, windowsPathsNoEscape: true })\n    ) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\n/**\n * Creates an object for matching allowed or ignored file paths.\n * @param {PathFilter} allowed The filter for allowed paths.\n * @param {PathFilter} ignored The filter for ignored paths.\n * @param {string} basePath The path where mocha is run (e.g., current working directory).\n * @returns {PathMatcher} The object for matching paths.\n * @ignore\n * @private\n */\nfunction createPathMatcher(allowed, ignored, basePath) {\n  debug(\n    \"creating path matcher from allowed: %o, ignored: %o\",\n    allowed,\n    ignored,\n  );\n\n  /**\n   * Cache of known file paths processed by `matcher.allow()`.\n   * @type {Map<string, boolean>}\n   */\n  const allowCache = new Map();\n\n  /**\n   * Cache of known file paths processed by `matcher.ignore()`.\n   * @type {Map<string, boolean>}\n   */\n  const ignoreCache = new Map();\n\n  const MAX_CACHE_SIZE = 10000;\n\n  /**\n   * Performs a `map.set()` but will delete the first key\n   * for new key-value pairs whenever the limit is reached.\n   * @param {Map<string, boolean>} map The map to use.\n   * @param {string} key The key to use.\n   * @param {boolean} value The value to set.\n   */\n  function cache(map, key, value) {\n    // only delete the first key if the key doesn't exist in the map\n    if (map.size >= MAX_CACHE_SIZE && !map.has(key)) {\n      map.delete(map.keys().next().value);\n    }\n    map.set(key, value);\n  }\n\n  /**\n   * @type {PathMatcher}\n   */\n  const matcher = {\n    allow(filePath) {\n      let allow = allowCache.get(filePath);\n      if (allow !== undefined) {\n        return allow;\n      }\n\n      allow = matchPattern(filePath, allowed.match);\n      cache(allowCache, filePath, allow);\n      return allow;\n    },\n\n    ignore(filePath, stats) {\n      // Chokidar calls the ignore match function twice:\n      // once without `stats` and again with `stats`\n      // see `ignored` under https://github.com/paulmillr/chokidar?tab=readme-ov-file#path-filtering\n      // note that the second call can also have no `stats` if the `filePath` does not exist\n      // in which case, allow the nonexistent path since it may be created later\n      if (!stats) {\n        return false;\n      }\n\n      // resolve to ensure correct absolute path since, for some reason,\n      // Chokidar paths for the ignore match function use slashes `/` even for Windows\n      filePath = path.resolve(basePath, filePath);\n\n      let ignore = ignoreCache.get(filePath);\n      if (ignore !== undefined) {\n        return ignore;\n      }\n\n      // `filePath` ignore conditions:\n      // - check if it's ignored from the `ignored` path patterns\n      // - otherwise, check if it's not ignored via `matcher.allow()` to also cache the result\n      // - if no match was found and `filePath` is a directory,\n      // check from the allowed directory paths if it's a valid\n      // parent directory or if it matches any of the allowed patterns\n      // since ignoring directories will have Chokidar ignore their contents\n      // which we may need to watch changes for\n      ignore =\n        matchPattern(filePath, ignored.match) ||\n        (!matcher.allow(filePath) &&\n          (!stats.isDirectory() || !matchPattern(filePath, allowed.dir, true)));\n\n      cache(ignoreCache, filePath, ignore);\n      return ignore;\n    },\n  };\n\n  return matcher;\n}\n\n/**\n * Bootstraps a Chokidar watcher. Handles keyboard input & signals\n * @param {Mocha} mocha - Mocha instance\n * @param {Object} opts\n * @param {BeforeWatchRun} [opts.beforeRun] - Function to call before\n * `mocha.run()`\n * @param {string[]} [opts.watchFiles] - List of paths and patterns to watch. If\n *   not provided all files with an extension included in\n *   `fileCollectionParams.extension` are watched. See first argument of\n *   `chokidar.watch`.\n * @param {string[]} [opts.watchIgnore] - List of paths and patterns to exclude\n *   from watching. See `ignored` option of `chokidar`.\n * @param {FileCollectionOptions} opts.fileCollectParams - List of extensions to watch if `opts.watchFiles` is not given.\n * @returns {FSWatcher}\n * @ignore\n * @private\n */\nconst createWatcher = (\n  mocha,\n  { watchFiles, watchIgnore, beforeRun, fileCollectParams },\n) => {\n  if (!watchFiles) {\n    watchFiles = fileCollectParams.extension.map((ext) => `**/*.${ext}`);\n  }\n\n  debug(\"watching files: %s\", watchFiles);\n  debug(\"ignoring files matching: %s\", watchIgnore);\n  let globalFixtureContext;\n\n  // we handle global fixtures manually\n  mocha.enableGlobalSetup(false).enableGlobalTeardown(false);\n\n  // glob file paths are no longer supported by Chokidar since v4\n  // first, strip the glob paths from `watchFiles` for Chokidar to watch\n  // then, create path patterns from `watchFiles` and `watchIgnore`\n  // to determine if the files should be allowed or ignored\n  // by the Chokidar `ignored` match function\n\n  const basePath = process.cwd();\n  const allowed = createPathFilter(watchFiles, basePath);\n  const ignored = createPathFilter(watchIgnore, basePath);\n  const matcher = createPathMatcher(allowed, ignored, basePath);\n\n  // Chokidar has to watch the directory paths in case new files are created\n  const watcher = chokidar.watch(Array.from(allowed.dir.paths), {\n    ignoreInitial: true,\n    ignored: matcher.ignore,\n  });\n\n  const rerunner = createRerunner(mocha, watcher, {\n    beforeRun,\n  });\n\n  watcher.on(\"ready\", async () => {\n    debug(\"watcher ready\");\n    if (!globalFixtureContext) {\n      debug(\"triggering global setup\");\n      globalFixtureContext = await mocha.runGlobalSetup();\n    }\n    rerunner.run();\n  });\n\n  watcher.on(\"all\", (_event, filePath) => {\n    // only allow file paths that match the allowed patterns\n    if (matcher.allow(filePath)) {\n      rerunner.scheduleRun();\n    }\n  });\n\n  hideCursor();\n  process.on(\"exit\", () => {\n    showCursor();\n  });\n\n  // this is for testing.\n  // win32 cannot gracefully shutdown via a signal from a parent\n  // process; a `SIGINT` from a parent will cause the process\n  // to immediately exit.  during normal course of operation, a user\n  // will type Ctrl-C and the listener will be invoked, but this\n  // is not possible in automated testing.\n  // there may be another way to solve this, but it too will be a hack.\n  // for our watch tests on win32 we must _fork_ mocha with an IPC channel\n  if (process.connected) {\n    process.on(\"message\", (msg) => {\n      if (msg === \"SIGINT\") {\n        process.emit(\"SIGINT\");\n      }\n    });\n  }\n\n  let exiting = false;\n  process.on(\"SIGINT\", async () => {\n    showCursor();\n    console.error(`${logSymbols.warning} [mocha] cleaning up, please wait...`);\n    if (!exiting) {\n      exiting = true;\n      if (mocha.hasGlobalTeardownFixtures()) {\n        debug(\"running global teardown\");\n        try {\n          await mocha.runGlobalTeardown(globalFixtureContext);\n        } catch (err) {\n          console.error(err);\n        }\n      }\n      process.exit(130);\n    }\n  });\n\n  // Keyboard shortcut for restarting when \"rs\\n\" is typed (ala Nodemon)\n  process.stdin.resume();\n  process.stdin.setEncoding(\"utf8\");\n  process.stdin.on(\"data\", (data) => {\n    const str = data.toString().trim().toLowerCase();\n    if (str === \"rs\") rerunner.scheduleRun();\n  });\n\n  return watcher;\n};\n\n/**\n * Create an object that allows you to rerun tests on the mocha instance.\n *\n * @param {Mocha} mocha - Mocha instance\n * @param {FSWatcher} watcher - Chokidar `FSWatcher` instance\n * @param {Object} [opts] - Options!\n * @param {BeforeWatchRun} [opts.beforeRun] - Function to call before `mocha.run()`\n * @returns {Rerunner}\n * @ignore\n * @private\n */\nconst createRerunner = (mocha, watcher, { beforeRun } = {}) => {\n  // Set to a `Runner` when mocha is running. Set to `null` when mocha is not\n  // running.\n  let runner = null;\n\n  // true if a file has changed during a test run\n  let rerunScheduled = false;\n\n  const run = () => {\n    try {\n      mocha = beforeRun ? beforeRun({ mocha, watcher }) || mocha : mocha;\n      runner = mocha.run(() => {\n        debug(\"finished watch run\");\n        runner = null;\n        blastCache(watcher);\n        if (rerunScheduled) {\n          rerun();\n        } else {\n          console.error(`${logSymbols.info} [mocha] waiting for changes...`);\n        }\n      });\n    } catch (err) {\n      console.error(err.stack);\n    }\n  };\n\n  const scheduleRun = () => {\n    if (rerunScheduled) {\n      return;\n    }\n\n    rerunScheduled = true;\n    if (runner) {\n      runner.abort();\n    } else {\n      rerun();\n    }\n  };\n\n  const rerun = () => {\n    rerunScheduled = false;\n    eraseLine();\n    run();\n  };\n\n  return {\n    scheduleRun,\n    run,\n  };\n};\n\n/**\n * Return the list of absolute paths watched by a Chokidar watcher.\n *\n * @param watcher - Instance of a Chokidar watcher\n * @return {string[]} - List of absolute paths\n * @ignore\n * @private\n */\nconst getWatchedFiles = (watcher) => {\n  const watchedDirs = watcher.getWatched();\n  return Object.keys(watchedDirs).reduce(\n    (acc, dir) => [\n      ...acc,\n      ...watchedDirs[dir].map((file) => path.join(dir, file)),\n    ],\n    [],\n  );\n};\n\n/**\n * Hide the cursor.\n * @ignore\n * @private\n */\nconst hideCursor = () => {\n  process.stdout.write(\"\\u001b[?25l\");\n};\n\n/**\n * Show the cursor.\n * @ignore\n * @private\n */\nconst showCursor = () => {\n  process.stdout.write(\"\\u001b[?25h\");\n};\n\n/**\n * Erases the line on stdout\n * @private\n */\nconst eraseLine = () => {\n  process.stdout.write(\"\\u001b[2K\");\n};\n\n/**\n * Blast all of the watched files out of `require.cache`\n * @param {FSWatcher} watcher - Chokidar FSWatcher\n * @ignore\n * @private\n */\nconst blastCache = (watcher) => {\n  const files = getWatchedFiles(watcher);\n  files.forEach((file) => {\n    delete require.cache[file];\n  });\n  debug(\"deleted %d file(s) from the require cache\", files.length);\n};\n"
  },
  {
    "path": "lib/context.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('./runnable.js')} Runnable\n */\n\n/**\n * @module Context\n */\n/**\n * Expose `Context`.\n */\n\nmodule.exports = Context;\n\n/**\n * Initialize a new `Context`.\n *\n * @private\n */\nfunction Context() {}\n\n/**\n * Set or get the context `Runnable` to `runnable`.\n *\n * @private\n * @param {Runnable} runnable\n * @return {Context} context\n */\nContext.prototype.runnable = function (runnable) {\n  if (!arguments.length) {\n    return this._runnable;\n  }\n  this.test = this._runnable = runnable;\n  return this;\n};\n\n/**\n * Set or get test timeout `ms`.\n *\n * @private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.timeout = function (ms) {\n  if (!arguments.length) {\n    return this.runnable().timeout();\n  }\n  this.runnable().timeout(ms);\n  return this;\n};\n\n/**\n * Set or get test slowness threshold `ms`.\n *\n * @private\n * @param {number} ms\n * @return {Context} self\n */\nContext.prototype.slow = function (ms) {\n  if (!arguments.length) {\n    return this.runnable().slow();\n  }\n  this.runnable().slow(ms);\n  return this;\n};\n\n/**\n * Mark a test as skipped.\n *\n * @private\n * @throws PendingError\n */\nContext.prototype.skip = function () {\n  this.runnable().skip();\n};\n\n/**\n * Set or get a number of allowed retries on failed tests\n *\n * @private\n * @param {number} n\n * @return {Context} self\n */\nContext.prototype.retries = function (n) {\n  if (!arguments.length) {\n    return this.runnable().retries();\n  }\n  this.runnable().retries(n);\n  return this;\n};\n"
  },
  {
    "path": "lib/error-constants.js",
    "content": "\"use strict\";\n\n/**\n * When Mocha throws exceptions (or rejects `Promise`s), it attempts to assign a `code` property to the `Error` object, for easier handling. These are the potential values of `code`.\n * @public\n * @namespace\n * @memberof module:lib/errors\n */\nvar constants = {\n  /**\n   * An unrecoverable error.\n   * @constant\n   * @default\n   */\n  FATAL: \"ERR_MOCHA_FATAL\",\n\n  /**\n   * The type of an argument to a function call is invalid\n   * @constant\n   * @default\n   */\n  INVALID_ARG_TYPE: \"ERR_MOCHA_INVALID_ARG_TYPE\",\n\n  /**\n   * The value of an argument to a function call is invalid\n   * @constant\n   * @default\n   */\n  INVALID_ARG_VALUE: \"ERR_MOCHA_INVALID_ARG_VALUE\",\n\n  /**\n   * Something was thrown, but it wasn't an `Error`\n   * @constant\n   * @default\n   */\n  INVALID_EXCEPTION: \"ERR_MOCHA_INVALID_EXCEPTION\",\n\n  /**\n   * An interface (e.g., `Mocha.interfaces`) is unknown or invalid\n   * @constant\n   * @default\n   */\n  INVALID_INTERFACE: \"ERR_MOCHA_INVALID_INTERFACE\",\n\n  /**\n   * A reporter (.e.g, `Mocha.reporters`) is unknown or invalid\n   * @constant\n   * @default\n   */\n  INVALID_REPORTER: \"ERR_MOCHA_INVALID_REPORTER\",\n\n  /**\n   * `done()` was called twice in a `Test` or `Hook` callback\n   * @constant\n   * @default\n   */\n  MULTIPLE_DONE: \"ERR_MOCHA_MULTIPLE_DONE\",\n\n  /**\n   * No files matched the pattern provided by the user\n   * @constant\n   * @default\n   */\n  NO_FILES_MATCH_PATTERN: \"ERR_MOCHA_NO_FILES_MATCH_PATTERN\",\n\n  /**\n   * Known, but unsupported behavior of some kind\n   * @constant\n   * @default\n   */\n  UNSUPPORTED: \"ERR_MOCHA_UNSUPPORTED\",\n\n  /**\n   * Invalid state transition occurring in `Mocha` instance\n   * @constant\n   * @default\n   */\n  INSTANCE_ALREADY_RUNNING: \"ERR_MOCHA_INSTANCE_ALREADY_RUNNING\",\n\n  /**\n   * Invalid state transition occurring in `Mocha` instance\n   * @constant\n   * @default\n   */\n  INSTANCE_ALREADY_DISPOSED: \"ERR_MOCHA_INSTANCE_ALREADY_DISPOSED\",\n\n  /**\n   * Use of `only()` w/ `--forbid-only` results in this error.\n   * @constant\n   * @default\n   */\n  FORBIDDEN_EXCLUSIVITY: \"ERR_MOCHA_FORBIDDEN_EXCLUSIVITY\",\n\n  /**\n   * To be thrown when a user-defined plugin implementation (e.g., `mochaHooks`) is invalid\n   * @constant\n   * @default\n   */\n  INVALID_PLUGIN_IMPLEMENTATION: \"ERR_MOCHA_INVALID_PLUGIN_IMPLEMENTATION\",\n\n  /**\n   * To be thrown when a builtin or third-party plugin definition (the _definition_ of `mochaHooks`) is invalid\n   * @constant\n   * @default\n   */\n  INVALID_PLUGIN_DEFINITION: \"ERR_MOCHA_INVALID_PLUGIN_DEFINITION\",\n\n  /**\n   * When a runnable exceeds its allowed run time.\n   * @constant\n   * @default\n   */\n  TIMEOUT: \"ERR_MOCHA_TIMEOUT\",\n\n  /**\n   * Input file is not able to be parsed\n   * @constant\n   * @default\n   */\n  UNPARSABLE_FILE: \"ERR_MOCHA_UNPARSABLE_FILE\",\n};\n\nmodule.exports = { constants };\n"
  },
  {
    "path": "lib/errors.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('./mocha.js')} Mocha\n * @typedef {import('./runnable.js')} Runnable\n * @typedef {import('./types.d.ts').MochaTimeoutError} MochaTimeoutError\n * @typedef {import('./types.d.ts').PluginDefinition} PluginDefinition\n */\n\nconst { format } = require(\"node:util\");\nconst { constants } = require(\"./error-constants.js\");\nconst { isCI } = require(\"./utils\");\n\n/**\n * Contains error codes, factory functions to create throwable error objects,\n * and warning/deprecation functions.\n * @module\n */\n\n/**\n * process.emitWarning or a polyfill\n * @see https://nodejs.org/api/process.html#process_process_emitwarning_warning_options\n * @ignore\n */\nconst emitWarning = (msg, type) => {\n  if (process.emitWarning) {\n    process.emitWarning(msg, type);\n  } else {\n    /* istanbul ignore next */\n    process.nextTick(function () {\n      console.warn(type + \": \" + msg);\n    });\n  }\n};\n\n/**\n * Show a deprecation warning. Each distinct message is only displayed once.\n * Ignores empty messages.\n *\n * @param {string} [msg] - Warning to print\n * @private\n */\nconst deprecate = (msg) => {\n  msg = String(msg);\n  if (msg && !deprecate.cache[msg]) {\n    deprecate.cache[msg] = true;\n    emitWarning(msg, \"DeprecationWarning\");\n  }\n};\ndeprecate.cache = {};\n\n/**\n * Show a generic warning.\n * Ignores empty messages.\n *\n * @param {string} [msg] - Warning to print\n * @private\n */\nconst warn = (msg) => {\n  if (msg) {\n    emitWarning(msg);\n  }\n};\n\n/**\n * A set containing all string values of all Mocha error constants, for use by {@link isMochaError}.\n * @private\n */\nconst MOCHA_ERRORS = new Set(Object.values(constants));\n\n/**\n * Creates an error object to be thrown when no files to be tested could be found using specified pattern.\n *\n * @public\n * @static\n * @param {string} message - Error message to be displayed.\n * @param {string} pattern - User-specified argument value.\n * @returns {Error} instance detailing the error condition\n */\nfunction createNoFilesMatchPatternError(message, pattern) {\n  var err = new Error(message);\n  err.code = constants.NO_FILES_MATCH_PATTERN;\n  err.pattern = pattern;\n  return err;\n}\n\n/**\n * Creates an error object to be thrown when the reporter specified in the options was not found.\n *\n * @public\n * @param {string} message - Error message to be displayed.\n * @param {string} reporter - User-specified reporter value.\n * @returns {Error} instance detailing the error condition\n */\nfunction createInvalidReporterError(message, reporter) {\n  var err = new TypeError(message);\n  err.code = constants.INVALID_REPORTER;\n  err.reporter = reporter;\n  return err;\n}\n\n/**\n * Creates an error object to be thrown when the interface specified in the options was not found.\n *\n * @public\n * @static\n * @param {string} message - Error message to be displayed.\n * @param {string} ui - User-specified interface value.\n * @returns {Error} instance detailing the error condition\n */\nfunction createInvalidInterfaceError(message, ui) {\n  var err = new Error(message);\n  err.code = constants.INVALID_INTERFACE;\n  err.interface = ui;\n  return err;\n}\n\n/**\n * Creates an error object to be thrown when a behavior, option, or parameter is unsupported.\n *\n * @public\n * @static\n * @param {string} message - Error message to be displayed.\n * @returns {Error} instance detailing the error condition\n */\nfunction createUnsupportedError(message) {\n  var err = new Error(message);\n  err.code = constants.UNSUPPORTED;\n  return err;\n}\n\n/**\n * Creates an error object to be thrown when an argument is missing.\n *\n * @public\n * @static\n * @param {string} message - Error message to be displayed.\n * @param {string} argument - Argument name.\n * @param {string} expected - Expected argument datatype.\n * @returns {Error} instance detailing the error condition\n */\nfunction createMissingArgumentError(message, argument, expected) {\n  return createInvalidArgumentTypeError(message, argument, expected);\n}\n\n/**\n * Creates an error object to be thrown when an argument did not use the supported type\n *\n * @public\n * @static\n * @param {string} message - Error message to be displayed.\n * @param {string} argument - Argument name.\n * @param {string} expected - Expected argument datatype.\n * @returns {Error} instance detailing the error condition\n */\nfunction createInvalidArgumentTypeError(message, argument, expected) {\n  var err = new TypeError(message);\n  err.code = constants.INVALID_ARG_TYPE;\n  err.argument = argument;\n  err.expected = expected;\n  err.actual = typeof argument;\n  return err;\n}\n\n/**\n * Creates an error object to be thrown when an argument did not use the supported value\n *\n * @public\n * @static\n * @param {string} message - Error message to be displayed.\n * @param {string} argument - Argument name.\n * @param {string} value - Argument value.\n * @param {string} [reason] - Why value is invalid.\n * @returns {Error} instance detailing the error condition\n */\nfunction createInvalidArgumentValueError(message, argument, value, reason) {\n  var err = new TypeError(message);\n  err.code = constants.INVALID_ARG_VALUE;\n  err.argument = argument;\n  err.value = value;\n  err.reason = typeof reason !== \"undefined\" ? reason : \"is invalid\";\n  return err;\n}\n\n/**\n * Creates an error object to be thrown when an exception was caught, but the `Error` is falsy or undefined.\n *\n * @public\n * @static\n * @param {string} message - Error message to be displayed.\n * @returns {Error} instance detailing the error condition\n */\nfunction createInvalidExceptionError(message, value) {\n  var err = new Error(message);\n  err.code = constants.INVALID_EXCEPTION;\n  err.valueType = typeof value;\n  err.value = value;\n  return err;\n}\n\n/**\n * Creates an error object to be thrown when an unrecoverable error occurs.\n *\n * @public\n * @static\n * @param {string} message - Error message to be displayed.\n * @returns {Error} instance detailing the error condition\n */\nfunction createFatalError(message, value) {\n  var err = new Error(message);\n  err.code = constants.FATAL;\n  err.valueType = typeof value;\n  err.value = value;\n  return err;\n}\n\n/**\n * Dynamically creates a plugin-type-specific error based on plugin type\n * @param {string} message - Error message\n * @param {\"reporter\"|\"ui\"} pluginType - Plugin type. Future: expand as needed\n * @param {string} [pluginId] - Name/path of plugin, if any\n * @throws When `pluginType` is not known\n * @public\n * @static\n * @returns {Error}\n */\nfunction createInvalidLegacyPluginError(message, pluginType, pluginId) {\n  switch (pluginType) {\n    case \"reporter\":\n      return createInvalidReporterError(message, pluginId);\n    case \"ui\":\n      return createInvalidInterfaceError(message, pluginId);\n    default:\n      throw new Error('unknown pluginType \"' + pluginType + '\"');\n  }\n}\n\n/**\n * **DEPRECATED**.  Use {@link createInvalidLegacyPluginError} instead  Dynamically creates a plugin-type-specific error based on plugin type\n * @deprecated\n * @param {string} message - Error message\n * @param {\"reporter\"|\"interface\"} pluginType - Plugin type. Future: expand as needed\n * @param {string} [pluginId] - Name/path of plugin, if any\n * @throws When `pluginType` is not known\n * @public\n * @static\n * @returns {Error}\n */\nfunction createInvalidPluginError(...args) {\n  deprecate(\"Use createInvalidLegacyPluginError() instead\");\n  return createInvalidLegacyPluginError(...args);\n}\n\n/**\n * Creates an error object to be thrown when a mocha object's `run` method is executed while it is already disposed.\n * @param {string} message The error message to be displayed.\n * @param {boolean} cleanReferencesAfterRun the value of `cleanReferencesAfterRun`\n * @param {Mocha} instance the mocha instance that throw this error\n * @static\n */\nfunction createMochaInstanceAlreadyDisposedError(\n  message,\n  cleanReferencesAfterRun,\n  instance,\n) {\n  var err = new Error(message);\n  err.code = constants.INSTANCE_ALREADY_DISPOSED;\n  err.cleanReferencesAfterRun = cleanReferencesAfterRun;\n  err.instance = instance;\n  return err;\n}\n\n/**\n * Creates an error object to be thrown when a mocha object's `run` method is called while a test run is in progress.\n * @param {string} message The error message to be displayed.\n * @static\n * @public\n */\nfunction createMochaInstanceAlreadyRunningError(message, instance) {\n  var err = new Error(message);\n  err.code = constants.INSTANCE_ALREADY_RUNNING;\n  err.instance = instance;\n  return err;\n}\n\n/**\n * Creates an error object to be thrown when done() is called multiple times in a test\n *\n * @public\n * @param {Runnable} runnable - Original runnable\n * @param {Error} [originalErr] - Original error, if any\n * @returns {Error} instance detailing the error condition\n * @static\n */\nfunction createMultipleDoneError(runnable, originalErr) {\n  var title;\n  try {\n    title = format(\"<%s>\", runnable.fullTitle());\n    if (runnable.parent.root) {\n      title += \" (of root suite)\";\n    }\n  } catch {\n    title = format(\"<%s> (of unknown suite)\", runnable.title);\n  }\n  var message = format(\n    \"done() called multiple times in %s %s\",\n    runnable.type ? runnable.type : \"unknown runnable\",\n    title,\n  );\n  if (runnable.file) {\n    message += format(\" of file %s\", runnable.file);\n  }\n  if (originalErr) {\n    message += format(\"; in addition, done() received error: %s\", originalErr);\n  }\n\n  var err = new Error(message);\n  err.code = constants.MULTIPLE_DONE;\n  err.valueType = typeof originalErr;\n  err.value = originalErr;\n  return err;\n}\n\n/**\n * Creates an error object to be thrown when `.only()` is used with\n * `--forbid-only`.\n * @static\n * @public\n * @param {Mocha} mocha - Mocha instance\n * @returns {Error} Error with code {@link constants.FORBIDDEN_EXCLUSIVITY}\n */\nfunction createForbiddenExclusivityError(mocha) {\n  var message;\n  if (mocha.isWorker) {\n    message = \"`.only` is not supported in parallel mode\";\n  } else {\n    message = \"`.only` forbidden by --forbid-only\";\n    if (isCI()) {\n      message += \" (default in CI, add `--no-forbid-only` to allow `.only`)\";\n    }\n  }\n\n  var err = new Error(message);\n  err.code = constants.FORBIDDEN_EXCLUSIVITY;\n  return err;\n}\n\n/**\n * Creates an error object to be thrown when a plugin definition is invalid\n * @static\n * @param {string} msg - Error message\n * @param {PluginDefinition} [pluginDef] - Problematic plugin definition\n * @public\n * @returns {Error} Error with code {@link constants.INVALID_PLUGIN_DEFINITION}\n */\nfunction createInvalidPluginDefinitionError(msg, pluginDef) {\n  const err = new Error(msg);\n  err.code = constants.INVALID_PLUGIN_DEFINITION;\n  err.pluginDef = pluginDef;\n  return err;\n}\n\n/**\n * Creates an error object to be thrown when a plugin implementation (user code) is invalid\n * @static\n * @param {string} msg - Error message\n * @param {Object} [opts] - Plugin definition and user-supplied implementation\n * @param {PluginDefinition} [opts.pluginDef] - Plugin Definition\n * @param {*} [opts.pluginImpl] - Plugin Implementation (user-supplied)\n * @public\n * @returns {Error} Error with code {@link constants.INVALID_PLUGIN_DEFINITION}\n */\nfunction createInvalidPluginImplementationError(\n  msg,\n  { pluginDef, pluginImpl } = {},\n) {\n  const err = new Error(msg);\n  err.code = constants.INVALID_PLUGIN_IMPLEMENTATION;\n  err.pluginDef = pluginDef;\n  err.pluginImpl = pluginImpl;\n  return err;\n}\n\n/**\n * Creates an error object to be thrown when a runnable exceeds its allowed run time.\n * @static\n * @param {string} msg - Error message\n * @param {number} [timeout] - Timeout in ms\n * @param {string} [file] - File, if given\n * @returns {MochaTimeoutError}\n */\nfunction createTimeoutError(msg, timeout, file) {\n  const err = new Error(msg);\n  err.code = constants.TIMEOUT;\n  err.timeout = timeout;\n  err.file = file;\n  return err;\n}\n\n/**\n * Creates an error object to be thrown when file is unparsable\n * @public\n * @static\n * @param {string} message - Error message to be displayed.\n * @returns {Error} Error with code {@link constants.UNPARSABLE_FILE}\n */\nfunction createUnparsableFileError(message) {\n  var err = new Error(message);\n  err.code = constants.UNPARSABLE_FILE;\n  return err;\n}\n\n/**\n * Returns `true` if an error came out of Mocha.\n * _Can suffer from false negatives, but not false positives._\n * @static\n * @public\n * @param {*} err - Error, or anything\n * @returns {boolean}\n */\nconst isMochaError = (err) =>\n  Boolean(err && typeof err === \"object\" && MOCHA_ERRORS.has(err.code));\n\nmodule.exports = {\n  createFatalError,\n  createForbiddenExclusivityError,\n  createInvalidArgumentTypeError,\n  createInvalidArgumentValueError,\n  createInvalidExceptionError,\n  createInvalidInterfaceError,\n  createInvalidLegacyPluginError,\n  createInvalidPluginDefinitionError,\n  createInvalidPluginError,\n  createInvalidPluginImplementationError,\n  createInvalidReporterError,\n  createMissingArgumentError,\n  createMochaInstanceAlreadyDisposedError,\n  createMochaInstanceAlreadyRunningError,\n  createMultipleDoneError,\n  createNoFilesMatchPatternError,\n  createTimeoutError,\n  createUnparsableFileError,\n  createUnsupportedError,\n  deprecate,\n  isMochaError,\n  warn,\n};\n"
  },
  {
    "path": "lib/hook.js",
    "content": "\"use strict\";\n\nvar Runnable = require(\"./runnable\");\nconst { constants } = require(\"./utils\");\nconst { MOCHA_ID_PROP_NAME } = constants;\n\nclass Hook extends Runnable {\n  /**\n   * Initialize a new `Hook` with the given `title` and callback `fn`\n   *\n   * @extends Runnable\n   * @param {String} title\n   * @param {Function} fn\n   */\n  constructor(title, fn) {\n    super(title, fn);\n    this.type = \"hook\";\n  }\n\n  /**\n   * Resets the state for a next run.\n   */\n  reset() {\n    super.reset(this);\n    delete this._error;\n  }\n\n  /**\n   * Get or set the test `err`.\n   *\n   * @memberof Hook\n   * @public\n   * @param {Error} err\n   * @return {Error}\n   */\n  error(err) {\n    if (!arguments.length) {\n      err = this._error;\n      this._error = null;\n      return err;\n    }\n\n    this._error = err;\n  }\n\n  /**\n   * Returns an object suitable for IPC.\n   * Functions are represented by keys beginning with `$$`.\n   * @private\n   * @returns {Object}\n   */\n  serialize() {\n    return {\n      $$currentRetry: this.currentRetry(),\n      $$fullTitle: this.fullTitle(),\n      $$isPending: Boolean(this.isPending()),\n      $$titlePath: this.titlePath(),\n      ctx:\n        this.ctx && this.ctx.currentTest\n          ? {\n              currentTest: {\n                title: this.ctx.currentTest.title,\n                [MOCHA_ID_PROP_NAME]: this.ctx.currentTest.id,\n              },\n            }\n          : {},\n      duration: this.duration,\n      file: this.file,\n      parent: {\n        $$fullTitle: this.parent.fullTitle(),\n        [MOCHA_ID_PROP_NAME]: this.parent.id,\n      },\n      state: this.state,\n      title: this.title,\n      type: this.type,\n      [MOCHA_ID_PROP_NAME]: this.id,\n    };\n  }\n}\n\nmodule.exports = Hook;\n"
  },
  {
    "path": "lib/interfaces/bdd.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../suite.js')} Suite\n */\n\nvar Test = require(\"../test\");\nvar EVENT_FILE_PRE_REQUIRE =\n  require(\"../suite\").constants.EVENT_FILE_PRE_REQUIRE;\n\n/**\n * BDD-style interface:\n *\n *      describe('Array', function() {\n *        describe('#indexOf()', function() {\n *          it('should return -1 when not present', function() {\n *            // ...\n *          });\n *\n *          it('should return the index when present', function() {\n *            // ...\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function bddInterface(suite) {\n  var suites = [suite];\n\n  suite.on(EVENT_FILE_PRE_REQUIRE, function (context, file, mocha) {\n    var common = require(\"./common\")(suites, context, mocha);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`\n     * and callback `fn` containing nested suites\n     * and/or tests.\n     */\n\n    context.describe = context.context = function (title, fn) {\n      return common.suite.create({\n        title,\n        file,\n        fn,\n      });\n    };\n\n    /**\n     * Pending describe.\n     */\n\n    context.xdescribe =\n      context.xcontext =\n      context.describe.skip =\n        function (title, fn) {\n          return common.suite.skip({\n            title,\n            file,\n            fn,\n          });\n        };\n\n    /**\n     * Exclusive suite.\n     */\n\n    context.describe.only = function (title, fn) {\n      return common.suite.only({\n        title,\n        file,\n        fn,\n      });\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.it = context.specify = function (title, fn) {\n      var suite = suites[0];\n      if (suite.isPending()) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.it.only = function (title, fn) {\n      return common.test.only(mocha, context.it(title, fn));\n    };\n\n    /**\n     * Pending test case.\n     */\n\n    context.xit =\n      context.xspecify =\n      context.it.skip =\n        function (title) {\n          return context.it(title);\n        };\n  });\n};\n\nmodule.exports.description = \"BDD or RSpec style [default]\";\n"
  },
  {
    "path": "lib/interfaces/common.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../context.js')} Context\n * @typedef {import('../mocha.js')} Mocha\n */\n\n/**\n @module interfaces/common\n*/\n\nvar Suite = require(\"../suite\");\nvar errors = require(\"../errors\");\nvar createMissingArgumentError = errors.createMissingArgumentError;\nvar createUnsupportedError = errors.createUnsupportedError;\nvar createForbiddenExclusivityError = errors.createForbiddenExclusivityError;\n\n/**\n * Functions common to more than one interface.\n *\n * @private\n * @param {Suite[]} suites\n * @param {Context} context\n * @param {Mocha} mocha\n * @return {Object} An object containing common functions.\n */\nmodule.exports = function (suites, context, mocha) {\n  /**\n   * Check if the suite should be tested.\n   *\n   * @private\n   * @param {Suite} suite - suite to check\n   * @returns {boolean}\n   */\n  function shouldBeTested(suite) {\n    return (\n      !mocha.options.grep ||\n      (mocha.options.grep &&\n        mocha.options.grep.test(suite.fullTitle()) &&\n        !mocha.options.invert)\n    );\n  }\n\n  return {\n    /**\n     * This is only present if flag --delay is passed into Mocha. It triggers\n     * root suite execution.\n     *\n     * @param {Suite} suite The root suite.\n     * @return {Function} A function which runs the root suite\n     */\n    runWithSuite: function runWithSuite(suite) {\n      return function run() {\n        suite.run();\n      };\n    },\n\n    /**\n     * Execute before running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    before: function (name, fn) {\n      return suites[0].beforeAll(name, fn);\n    },\n\n    /**\n     * Execute after running tests.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    after: function (name, fn) {\n      return suites[0].afterAll(name, fn);\n    },\n\n    /**\n     * Execute before each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    beforeEach: function (name, fn) {\n      return suites[0].beforeEach(name, fn);\n    },\n\n    /**\n     * Execute after each test case.\n     *\n     * @param {string} name\n     * @param {Function} fn\n     */\n    afterEach: function (name, fn) {\n      return suites[0].afterEach(name, fn);\n    },\n\n    suite: {\n      /**\n       * Create an exclusive Suite; convenience function\n       * See docstring for create() below.\n       *\n       * @param {Object} opts\n       * @returns {Suite}\n       */\n      only: function only(opts) {\n        if (mocha.options.forbidOnly) {\n          throw createForbiddenExclusivityError(mocha);\n        }\n        opts.isOnly = true;\n        return this.create(opts);\n      },\n\n      /**\n       * Create a Suite, but skip it; convenience function\n       * See docstring for create() below.\n       *\n       * @param {Object} opts\n       * @returns {Suite}\n       */\n      skip: function skip(opts) {\n        opts.pending = true;\n        return this.create(opts);\n      },\n\n      /**\n       * Creates a suite.\n       *\n       * @param {Object} opts Options\n       * @param {string} opts.title Title of Suite\n       * @param {Function} [opts.fn] Suite Function (not always applicable)\n       * @param {boolean} [opts.pending] Is Suite pending?\n       * @param {string} [opts.file] Filepath where this Suite resides\n       * @param {boolean} [opts.isOnly] Is Suite exclusive?\n       * @returns {Suite}\n       */\n      create: function create(opts) {\n        var suite = Suite.create(suites[0], opts.title);\n        suite.pending = Boolean(opts.pending);\n        suite.file = opts.file;\n        suites.unshift(suite);\n        if (opts.isOnly) {\n          suite.markOnly();\n        }\n        if (\n          suite.pending &&\n          mocha.options.forbidPending &&\n          shouldBeTested(suite)\n        ) {\n          throw createUnsupportedError(\"Pending test forbidden\");\n        }\n        if (typeof opts.fn === \"function\") {\n          opts.fn.call(suite);\n          suites.shift();\n        } else if (typeof opts.fn === \"undefined\" && !suite.pending) {\n          throw createMissingArgumentError(\n            'Suite \"' +\n              suite.fullTitle() +\n              '\" was defined but no callback was supplied. ' +\n              \"Supply a callback or explicitly skip the suite.\",\n            \"callback\",\n            \"function\",\n          );\n        } else if (!opts.fn && suite.pending) {\n          suites.shift();\n        }\n\n        return suite;\n      },\n    },\n\n    test: {\n      /**\n       * Exclusive test-case.\n       *\n       * @param {Object} mocha\n       * @param {Function} test\n       * @returns {*}\n       */\n      only: function (mocha, test) {\n        if (mocha.options.forbidOnly) {\n          throw createForbiddenExclusivityError(mocha);\n        }\n        test.markOnly();\n        return test;\n      },\n\n      /**\n       * Pending test case.\n       *\n       * @param {string} title\n       */\n      skip: function (title) {\n        context.test(title);\n      },\n    },\n  };\n};\n"
  },
  {
    "path": "lib/interfaces/exports.js",
    "content": "\"use strict\";\nvar Suite = require(\"../suite\");\nvar Test = require(\"../test\");\n\n/**\n * Exports-style (as Node.js module) interface:\n *\n *     exports.Array = {\n *       '#indexOf()': {\n *         'should return -1 when the value is not present': function() {\n *\n *         },\n *\n *         'should return the correct index when the value is present': function() {\n *\n *         }\n *       }\n *     };\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function (suite) {\n  var suites = [suite];\n\n  suite.on(Suite.constants.EVENT_FILE_REQUIRE, visit);\n\n  function visit(obj, file) {\n    var suite;\n    for (var key in obj) {\n      if (typeof obj[key] === \"function\") {\n        var fn = obj[key];\n        switch (key) {\n          case \"before\":\n            suites[0].beforeAll(fn);\n            break;\n          case \"after\":\n            suites[0].afterAll(fn);\n            break;\n          case \"beforeEach\":\n            suites[0].beforeEach(fn);\n            break;\n          case \"afterEach\":\n            suites[0].afterEach(fn);\n            break;\n          default:\n            var test = new Test(key, fn);\n            test.file = file;\n            suites[0].addTest(test);\n        }\n      } else {\n        suite = Suite.create(suites[0], key);\n        suites.unshift(suite);\n        visit(obj[key], file);\n        suites.shift();\n      }\n    }\n  }\n};\n\nmodule.exports.description = 'Node.js module (\"exports\") style';\n"
  },
  {
    "path": "lib/interfaces/index.js",
    "content": "\"use strict\";\n\nexports.bdd = require(\"./bdd\");\nexports.tdd = require(\"./tdd\");\nexports.qunit = require(\"./qunit\");\nexports.exports = require(\"./exports\");\n"
  },
  {
    "path": "lib/interfaces/qunit.js",
    "content": "\"use strict\";\n/**\n * @typedef {import('../suite.js')} Suite\n */\n\nvar Test = require(\"../test\");\nvar EVENT_FILE_PRE_REQUIRE =\n  require(\"../suite\").constants.EVENT_FILE_PRE_REQUIRE;\n\n/**\n * QUnit-style interface:\n *\n *     suite('Array');\n *\n *     test('#length', function() {\n *       var arr = [1,2,3];\n *       ok(arr.length == 3);\n *     });\n *\n *     test('#indexOf()', function() {\n *       var arr = [1,2,3];\n *       ok(arr.indexOf(1) == 0);\n *       ok(arr.indexOf(2) == 1);\n *       ok(arr.indexOf(3) == 2);\n *     });\n *\n *     suite('String');\n *\n *     test('#length', function() {\n *       ok('foo'.length == 3);\n *     });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function qUnitInterface(suite) {\n  var suites = [suite];\n\n  suite.on(EVENT_FILE_PRE_REQUIRE, function (context, file, mocha) {\n    var common = require(\"./common\")(suites, context, mocha);\n\n    context.before = common.before;\n    context.after = common.after;\n    context.beforeEach = common.beforeEach;\n    context.afterEach = common.afterEach;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n    /**\n     * Describe a \"suite\" with the given `title`.\n     */\n\n    context.suite = function (title) {\n      if (suites.length > 1) {\n        suites.shift();\n      }\n      return common.suite.create({\n        title,\n        file,\n        fn: false,\n      });\n    };\n\n    /**\n     * Exclusive Suite.\n     */\n\n    context.suite.only = function (title) {\n      if (suites.length > 1) {\n        suites.shift();\n      }\n      return common.suite.only({\n        title,\n        file,\n        fn: false,\n      });\n    };\n\n    /**\n     * Describe a specification or test-case\n     * with the given `title` and callback `fn`\n     * acting as a thunk.\n     */\n\n    context.test = function (title, fn) {\n      var test = new Test(title, fn);\n      test.file = file;\n      suites[0].addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function (title, fn) {\n      return common.test.only(mocha, context.test(title, fn));\n    };\n\n    context.test.skip = common.test.skip;\n  });\n};\n\nmodule.exports.description = \"QUnit style\";\n"
  },
  {
    "path": "lib/interfaces/tdd.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../suite.js')} Suite\n */\n\nvar Test = require(\"../test\");\nvar EVENT_FILE_PRE_REQUIRE =\n  require(\"../suite\").constants.EVENT_FILE_PRE_REQUIRE;\n\n/**\n * TDD-style interface:\n *\n *      suite('Array', function() {\n *        suite('#indexOf()', function() {\n *          suiteSetup(function() {\n *\n *          });\n *\n *          test('should return -1 when not present', function() {\n *\n *          });\n *\n *          test('should return the index when present', function() {\n *\n *          });\n *\n *          suiteTeardown(function() {\n *\n *          });\n *        });\n *      });\n *\n * @param {Suite} suite Root suite.\n */\nmodule.exports = function (suite) {\n  var suites = [suite];\n\n  suite.on(EVENT_FILE_PRE_REQUIRE, function (context, file, mocha) {\n    var common = require(\"./common\")(suites, context, mocha);\n\n    context.setup = common.beforeEach;\n    context.teardown = common.afterEach;\n    context.suiteSetup = common.before;\n    context.suiteTeardown = common.after;\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n\n    /**\n     * Describe a \"suite\" with the given `title` and callback `fn` containing\n     * nested suites and/or tests.\n     */\n    context.suite = function (title, fn) {\n      return common.suite.create({\n        title,\n        file,\n        fn,\n      });\n    };\n\n    /**\n     * Pending suite.\n     */\n    context.suite.skip = function (title, fn) {\n      return common.suite.skip({\n        title,\n        file,\n        fn,\n      });\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n    context.suite.only = function (title, fn) {\n      return common.suite.only({\n        title,\n        file,\n        fn,\n      });\n    };\n\n    /**\n     * Describe a specification or test-case with the given `title` and\n     * callback `fn` acting as a thunk.\n     */\n    context.test = function (title, fn) {\n      var suite = suites[0];\n      if (suite.isPending()) {\n        fn = null;\n      }\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n      return test;\n    };\n\n    /**\n     * Exclusive test-case.\n     */\n\n    context.test.only = function (title, fn) {\n      return common.test.only(mocha, context.test(title, fn));\n    };\n\n    context.test.skip = common.test.skip;\n  });\n};\n\nmodule.exports.description =\n  'traditional \"suite\"/\"test\" instead of BDD\\'s \"describe\"/\"it\"';\n"
  },
  {
    "path": "lib/mocha.js",
    "content": "\"use strict\";\n\n/*!\n * mocha\n * Copyright(c) 2011 TJ Holowaychuk <tj@vision-media.ca>\n * MIT Licensed\n */\n\nvar escapeRe = require(\"escape-string-regexp\");\nvar path = require(\"node:path\");\nvar builtinReporters = require(\"./reporters\");\nvar utils = require(\"./utils\");\nvar mocharc = require(\"./mocharc.json\");\nvar Suite = require(\"./suite\");\nvar esmUtils = require(\"./nodejs/esm-utils\");\nvar createStatsCollector = require(\"./stats-collector\");\nconst {\n  createInvalidReporterError,\n  createInvalidInterfaceError,\n  createMochaInstanceAlreadyDisposedError,\n  createMochaInstanceAlreadyRunningError,\n  createUnsupportedError,\n} = require(\"./errors\");\nconst { EVENT_FILE_PRE_REQUIRE, EVENT_FILE_POST_REQUIRE, EVENT_FILE_REQUIRE } =\n  Suite.constants;\nvar debug = require(\"debug\")(\"mocha:mocha\");\n\n/**\n * @typedef {import('./types.d.ts').DoneCB} DoneCB\n * @typedef {import('./types.d.ts').MochaGlobalFixture} MochaGlobalFixture\n * @typedef {import('./types.d.ts').MochaOptions} MochaOptions\n * @typedef {import('./types.d.ts').MochaRootHookObject} MochaRootHookObject\n * @typedef {import('./types.d.ts').Reporter} Reporter\n */\n\nexports = module.exports = Mocha;\n\n/**\n * A Mocha instance is a finite state machine.\n * These are the states it can be in.\n * @private\n */\nvar mochaStates = utils.defineConstants({\n  /**\n   * Initial state of the mocha instance\n   * @private\n   */\n  INIT: \"init\",\n  /**\n   * Mocha instance is running tests\n   * @private\n   */\n  RUNNING: \"running\",\n  /**\n   * Mocha instance is done running tests and references to test functions and hooks are cleaned.\n   * You can reset this state by unloading the test files.\n   * @private\n   */\n  REFERENCES_CLEANED: \"referencesCleaned\",\n  /**\n   * Mocha instance is disposed and can no longer be used.\n   * @private\n   */\n  DISPOSED: \"disposed\",\n});\n\n/**\n * To require local UIs and reporters when running in node.\n */\n\nif (!utils.isBrowser() && typeof module.paths !== \"undefined\") {\n  var cwd = utils.cwd();\n  module.paths.push(cwd, path.join(cwd, \"node_modules\"));\n}\n\n/**\n * Expose internals.\n * @private\n */\n\nexports.utils = utils;\nexports.interfaces = require(\"./interfaces\");\n/**\n * @public\n * @memberof Mocha\n */\nexports.reporters = builtinReporters;\nexports.Runnable = require(\"./runnable\");\nexports.Context = require(\"./context\");\n/**\n *\n * @memberof Mocha\n */\nexports.Runner = require(\"./runner\");\nexports.Suite = Suite;\nexports.Hook = require(\"./hook\");\nexports.Test = require(\"./test\");\n\nlet currentContext;\nexports.afterEach = function (...args) {\n  return (currentContext.afterEach || currentContext.teardown).apply(\n    this,\n    args,\n  );\n};\nexports.after = function (...args) {\n  return (currentContext.after || currentContext.suiteTeardown).apply(\n    this,\n    args,\n  );\n};\nexports.beforeEach = function (...args) {\n  return (currentContext.beforeEach || currentContext.setup).apply(this, args);\n};\nexports.before = function (...args) {\n  return (currentContext.before || currentContext.suiteSetup).apply(this, args);\n};\nexports.describe = function (...args) {\n  return (currentContext.describe || currentContext.suite).apply(this, args);\n};\nexports.describe.only = function (...args) {\n  return (currentContext.describe || currentContext.suite).only.apply(\n    this,\n    args,\n  );\n};\nexports.describe.skip = function (...args) {\n  return (currentContext.describe || currentContext.suite).skip.apply(\n    this,\n    args,\n  );\n};\nexports.it = function (...args) {\n  return (currentContext.it || currentContext.test).apply(this, args);\n};\nexports.it.only = function (...args) {\n  return (currentContext.it || currentContext.test).only.apply(this, args);\n};\nexports.it.skip = function (...args) {\n  return (currentContext.it || currentContext.test).skip.apply(this, args);\n};\nexports.xdescribe = exports.describe.skip;\nexports.xit = exports.it.skip;\nexports.setup = exports.beforeEach;\nexports.suiteSetup = exports.before;\nexports.suiteTeardown = exports.after;\nexports.suite = exports.describe;\nexports.teardown = exports.afterEach;\nexports.test = exports.it;\nexports.run = function (...args) {\n  return currentContext.run.apply(this, args);\n};\n\n/**\n * Constructs a new Mocha instance with `options`.\n *\n * @public\n * @class Mocha\n * @param {MochaOptions} [options] - Settings object.\n */\nfunction Mocha(options = {}) {\n  options = { ...mocharc, ...options };\n  this.files = [];\n  this.options = options;\n  // root suite\n  this.suite = new exports.Suite(\"\", new exports.Context(), true);\n  this._cleanReferencesAfterRun = true;\n  this._state = mochaStates.INIT;\n\n  this.grep(options.grep)\n    .fgrep(options.fgrep)\n    .ui(options.ui)\n    .reporter(\n      options.reporter,\n      options[\"reporter-option\"] ||\n        options.reporterOption ||\n        options.reporterOptions, // for backwards compatibility\n    )\n    .slow(options.slow)\n    .global(options.global);\n\n  // this guard exists because Suite#timeout does not consider `undefined` to be valid input\n  if (typeof options.timeout !== \"undefined\") {\n    this.timeout(options.timeout === false ? 0 : options.timeout);\n  }\n\n  if (\"retries\" in options) {\n    this.retries(options.retries);\n  }\n\n  [\n    \"allowUncaught\",\n    \"asyncOnly\",\n    \"bail\",\n    \"checkLeaks\",\n    \"color\",\n    \"delay\",\n    \"diff\",\n    \"dryRun\",\n    \"passOnFailingTestSuite\",\n    \"failZero\",\n    \"forbidOnly\",\n    \"forbidPending\",\n    \"fullTrace\",\n    \"inlineDiffs\",\n    \"invert\",\n  ].forEach(function (opt) {\n    if (options[opt]) {\n      this[opt]();\n    }\n  }, this);\n\n  if (options.rootHooks) {\n    this.rootHooks(options.rootHooks);\n  }\n\n  /**\n   * The class which we'll instantiate in {@link Mocha#run}.  Defaults to\n   * {@link Runner} in serial mode; changes in parallel mode.\n   * @memberof Mocha\n   * @private\n   */\n  this._runnerClass = exports.Runner;\n\n  /**\n   * Whether or not to call {@link Mocha#loadFiles} implicitly when calling\n   * {@link Mocha#run}.  If this is `true`, then it's up to the consumer to call\n   * {@link Mocha#loadFiles} _or_ {@link Mocha#loadFilesAsync}.\n   * @private\n   * @memberof Mocha\n   */\n  this._lazyLoadFiles = false;\n\n  /**\n   * It's useful for a Mocha instance to know if it's running in a worker process.\n   * We could derive this via other means, but it's helpful to have a flag to refer to.\n   * @memberof Mocha\n   * @private\n   */\n  this.isWorker = Boolean(options.isWorker);\n\n  this.globalSetup(options.globalSetup)\n    .globalTeardown(options.globalTeardown)\n    .enableGlobalSetup(options.enableGlobalSetup)\n    .enableGlobalTeardown(options.enableGlobalTeardown);\n\n  if (\n    options.parallel &&\n    (typeof options.jobs === \"undefined\" || options.jobs > 1)\n  ) {\n    debug(\"attempting to enable parallel mode\");\n    this.parallelMode(true);\n  }\n}\n\n/**\n * Enables or disables bailing on the first failure.\n *\n * @public\n * @see [CLI option](../#-bail-b)\n * @param {boolean} [bail=true] - Whether to bail on first error.\n * @returns {Mocha} this\n * @chainable\n */\nMocha.prototype.bail = function (bail) {\n  this.suite.bail(bail !== false);\n  return this;\n};\n\n/**\n * @summary\n * Adds `file` to be loaded for execution.\n *\n * @description\n * Useful for generic setup code that must be included within test suite.\n *\n * @public\n * @see [CLI option](../#-file-filedirectoryglob)\n * @param {string} file - Pathname of file to be loaded.\n * @returns {Mocha} this\n * @chainable\n */\nMocha.prototype.addFile = function (file) {\n  this.files.push(file);\n  return this;\n};\n\n/**\n * Sets reporter to `reporter`, defaults to \"spec\".\n *\n * @public\n * @see [CLI option](../#-reporter-name-r-name)\n * @see [Reporters](../#reporters)\n * @param {String|Reporter} reporterName - Reporter name or constructor.\n * @param {Object} [reporterOptions] - Options used to configure the reporter.\n * @returns {Mocha} this\n * @chainable\n * @throws {Error} if requested reporter cannot be loaded\n * @example\n *\n * // Use XUnit reporter and direct its output to file\n * mocha.reporter('xunit', { output: '/path/to/testspec.xunit.xml' });\n */\nMocha.prototype.reporter = function (reporterName, reporterOptions) {\n  if (typeof reporterName === \"function\") {\n    this._reporter = reporterName;\n  } else {\n    reporterName = reporterName || \"spec\";\n    var reporter;\n    // Try to load a built-in reporter.\n    if (builtinReporters[reporterName]) {\n      reporter = builtinReporters[reporterName];\n    }\n    // Try to load reporters from process.cwd() and node_modules\n    if (!reporter) {\n      let foundReporter;\n      try {\n        foundReporter = require.resolve(reporterName);\n        reporter = require(foundReporter);\n      } catch (err) {\n        if (foundReporter) {\n          throw createInvalidReporterError(err.message, foundReporter);\n        }\n        // Try to load reporters from a cwd-relative path\n        try {\n          reporter = require(path.resolve(reporterName));\n        } catch (err) {\n          throw createInvalidReporterError(err.message, reporterName);\n        }\n      }\n    }\n    if (reporter.default) {\n      reporter = reporter.default;\n    }\n\n    this._reporter = reporter;\n  }\n  this.options.reporterOption = reporterOptions;\n  // alias option name is used in built-in reporters xunit/tap/progress\n  this.options.reporterOptions = reporterOptions;\n  return this;\n};\n\n/**\n * Sets test UI `name`, defaults to \"bdd\".\n *\n * @public\n * @see [CLI option](../#-ui-name-u-name)\n * @see [Interface DSLs](../#interfaces)\n * @param {string|Function} [ui=bdd] - Interface name or class.\n * @returns {Mocha} this\n * @chainable\n * @throws {Error} if requested interface cannot be loaded\n */\nMocha.prototype.ui = function (ui) {\n  var bindInterface;\n  if (typeof ui === \"function\") {\n    bindInterface = ui;\n  } else {\n    ui = ui || \"bdd\";\n    bindInterface = exports.interfaces[ui];\n    if (!bindInterface) {\n      try {\n        bindInterface = require(ui);\n      } catch {\n        throw createInvalidInterfaceError(`invalid interface '${ui}'`, ui);\n      }\n    }\n  }\n  if (bindInterface.default) {\n    bindInterface = bindInterface.default;\n  }\n\n  bindInterface(this.suite);\n\n  this.suite.on(EVENT_FILE_PRE_REQUIRE, function (context) {\n    currentContext = context;\n  });\n\n  return this;\n};\n\n/**\n * Loads `files` prior to execution. Does not support ES Modules.\n *\n * @description\n * The implementation relies on Node's `require` to execute\n * the test interface functions and will be subject to its cache.\n * Supports only CommonJS modules. To load ES modules, use Mocha#loadFilesAsync.\n *\n * @private\n * @see {@link Mocha#addFile}\n * @see {@link Mocha#run}\n * @see {@link Mocha#unloadFiles}\n * @see {@link Mocha#loadFilesAsync}\n * @param {Function} [fn] - Callback invoked upon completion.\n */\nMocha.prototype.loadFiles = function (fn) {\n  var self = this;\n  var suite = this.suite;\n  this.files.forEach(function (file) {\n    file = path.resolve(file);\n    suite.emit(EVENT_FILE_PRE_REQUIRE, global, file, self);\n    suite.emit(EVENT_FILE_REQUIRE, require(file), file, self);\n    suite.emit(EVENT_FILE_POST_REQUIRE, global, file, self);\n  });\n  fn && fn();\n};\n\n/**\n * Loads `files` prior to execution. Supports Node ES Modules.\n *\n * @description\n * The implementation relies on Node's `require` and `import` to execute\n * the test interface functions and will be subject to its cache.\n * Supports both CJS and ESM modules.\n *\n * @public\n * @see {@link Mocha#addFile}\n * @see {@link Mocha#run}\n * @see {@link Mocha#unloadFiles}\n * @param {Object} [options] - Settings object.\n * @param {Function} [options.esmDecorator] - Function invoked on esm module name right before importing it. By default will passthrough as is.\n * @returns {Promise}\n * @example\n *\n * // loads ESM (and CJS) test files asynchronously, then runs root suite\n * mocha.loadFilesAsync()\n *   .then(() => mocha.run(failures => process.exitCode = failures ? 1 : 0))\n *   .catch(() => process.exitCode = 1);\n */\nMocha.prototype.loadFilesAsync = function ({ esmDecorator } = {}) {\n  var self = this;\n  var suite = this.suite;\n  this.lazyLoadFiles(true);\n\n  return esmUtils.loadFilesAsync(\n    this.files,\n    function (file) {\n      suite.emit(EVENT_FILE_PRE_REQUIRE, global, file, self);\n    },\n    function (file, resultModule) {\n      suite.emit(EVENT_FILE_REQUIRE, resultModule, file, self);\n      suite.emit(EVENT_FILE_POST_REQUIRE, global, file, self);\n    },\n    esmDecorator,\n  );\n};\n\n/**\n * Removes a previously loaded file from Node's `require` cache.\n *\n * @private\n * @static\n * @see {@link Mocha#unloadFiles}\n * @param {string} file - Pathname of file to be unloaded.\n */\nMocha.unloadFile = function (file) {\n  if (utils.isBrowser()) {\n    throw createUnsupportedError(\n      \"unloadFile() is only supported in a Node.js environment\",\n    );\n  }\n  return require(\"./nodejs/file-unloader\").unloadFile(file);\n};\n\n/**\n * Unloads `files` from Node's `require` cache.\n *\n * @description\n * This allows required files to be \"freshly\" reloaded, providing the ability\n * to reuse a Mocha instance programmatically.\n * Note: does not clear ESM module files from the cache\n *\n * <strong>Intended for consumers &mdash; not used internally</strong>\n *\n * @public\n * @see {@link Mocha#run}\n * @returns {Mocha} this\n * @chainable\n */\nMocha.prototype.unloadFiles = function () {\n  if (this._state === mochaStates.DISPOSED) {\n    throw createMochaInstanceAlreadyDisposedError(\n      \"Mocha instance is already disposed, it cannot be used again.\",\n      this._cleanReferencesAfterRun,\n      this,\n    );\n  }\n\n  this.files.forEach(function (file) {\n    Mocha.unloadFile(file);\n  });\n  this._state = mochaStates.INIT;\n  return this;\n};\n\n/**\n * Sets `grep` filter after escaping RegExp special characters.\n *\n * @public\n * @see {@link Mocha#grep}\n * @param {string} str - Value to be converted to a regexp.\n * @returns {Mocha} this\n * @chainable\n * @example\n *\n * // Select tests whose full title begins with `\"foo\"` followed by a period\n * mocha.fgrep('foo.');\n */\nMocha.prototype.fgrep = function (str) {\n  if (!str) {\n    return this;\n  }\n  return this.grep(new RegExp(escapeRe(str)));\n};\n\n/**\n * @summary\n * Sets `grep` filter used to select specific tests for execution.\n *\n * @description\n * If `re` is a regexp-like string, it will be converted to regexp.\n * The regexp is tested against the full title of each test (i.e., the\n * name of the test preceded by titles of each its ancestral suites).\n * As such, using an <em>exact-match</em> fixed pattern against the\n * test name itself will not yield any matches.\n * <br>\n * <strong>Previous filter value will be overwritten on each call!</strong>\n *\n * @public\n * @see [CLI option](../#-grep-regexp-g-regexp)\n * @see {@link Mocha#fgrep}\n * @see {@link Mocha#invert}\n * @param {RegExp|String} re - Regular expression used to select tests.\n * @return {Mocha} this\n * @chainable\n * @example\n *\n * // Select tests whose full title contains `\"match\"`, ignoring case\n * mocha.grep(/match/i);\n * @example\n *\n * // Same as above but with regexp-like string argument\n * mocha.grep('/match/i');\n * @example\n *\n * // ## Anti-example\n * // Given embedded test `it('only-this-test')`...\n * mocha.grep('/^only-this-test$/');    // NO! Use `.only()` to do this!\n */\nMocha.prototype.grep = function (re) {\n  if (utils.isString(re)) {\n    // extract args if it's regex-like, i.e: [string, pattern, flag]\n    var arg = re.match(/^\\/(.*)\\/([gimy]{0,4})$|.*/);\n    this.options.grep = new RegExp(arg[1] || arg[0], arg[2]);\n  } else {\n    this.options.grep = re;\n  }\n  return this;\n};\n\n/**\n * Inverts `grep` matches.\n *\n * @public\n * @see {@link Mocha#grep}\n * @return {Mocha} this\n * @chainable\n * @example\n *\n * // Select tests whose full title does *not* contain `\"match\"`, ignoring case\n * mocha.grep(/match/i).invert();\n */\nMocha.prototype.invert = function () {\n  this.options.invert = true;\n  return this;\n};\n\n/**\n * Enables or disables checking for global variables leaked while running tests.\n *\n * @public\n * @see [CLI option](../#-check-leaks)\n * @param {boolean} [checkLeaks=true] - Whether to check for global variable leaks.\n * @return {Mocha} this\n * @chainable\n */\nMocha.prototype.checkLeaks = function (checkLeaks) {\n  this.options.checkLeaks = checkLeaks !== false;\n  return this;\n};\n\n/**\n * Enables or disables whether or not to dispose after each test run.\n * Disable this to ensure you can run the test suite multiple times.\n * If disabled, be sure to dispose mocha when you're done to prevent memory leaks.\n * @public\n * @see {@link Mocha#dispose}\n * @param {boolean} cleanReferencesAfterRun\n * @return {Mocha} this\n * @chainable\n */\nMocha.prototype.cleanReferencesAfterRun = function (cleanReferencesAfterRun) {\n  this._cleanReferencesAfterRun = cleanReferencesAfterRun !== false;\n  return this;\n};\n\n/**\n * Manually dispose this mocha instance. Mark this instance as `disposed` and unable to run more tests.\n * It also removes function references to tests functions and hooks, so variables trapped in closures can be cleaned by the garbage collector.\n * @public\n */\nMocha.prototype.dispose = function () {\n  if (this._state === mochaStates.RUNNING) {\n    throw createMochaInstanceAlreadyRunningError(\n      \"Cannot dispose while the mocha instance is still running tests.\",\n    );\n  }\n  this.unloadFiles();\n  this._previousRunner && this._previousRunner.dispose();\n  this.suite.dispose();\n  this._state = mochaStates.DISPOSED;\n};\n\n/**\n * Displays full stack trace upon test failure.\n *\n * @public\n * @see [CLI option](../#-full-trace)\n * @param {boolean} [fullTrace=true] - Whether to print full stacktrace upon failure.\n * @return {Mocha} this\n * @chainable\n */\nMocha.prototype.fullTrace = function (fullTrace) {\n  this.options.fullTrace = fullTrace !== false;\n  return this;\n};\n\n/**\n * Specifies whitelist of variable names to be expected in global scope.\n *\n * @public\n * @see [CLI option](../#-global-variable-name)\n * @see {@link Mocha#checkLeaks}\n * @param {String[]|String} global - Accepted global variable name(s).\n * @return {Mocha} this\n * @chainable\n * @example\n *\n * // Specify variables to be expected in global scope\n * mocha.global(['jQuery', 'MyLib']);\n */\nMocha.prototype.global = function (global) {\n  this.options.global = (this.options.global || [])\n    .concat(global)\n    .filter(Boolean)\n    .filter(function (elt, idx, arr) {\n      return arr.indexOf(elt) === idx;\n    });\n  return this;\n};\n// for backwards compatibility, 'globals' is an alias of 'global'\nMocha.prototype.globals = Mocha.prototype.global;\n\n/**\n * Enables or disables TTY color output by screen-oriented reporters.\n *\n * @public\n * @see [CLI option](../#-color-c-colors)\n * @param {boolean} [color=true] - Whether to enable color output.\n * @return {Mocha} this\n * @chainable\n */\nMocha.prototype.color = function (color) {\n  this.options.color = color !== false;\n  return this;\n};\n\n/**\n * Enables or disables reporter to use inline diffs (rather than +/-)\n * in test failure output.\n *\n * @public\n * @see [CLI option](../#-inline-diffs)\n * @param {boolean} [inlineDiffs=true] - Whether to use inline diffs.\n * @return {Mocha} this\n * @chainable\n */\nMocha.prototype.inlineDiffs = function (inlineDiffs) {\n  this.options.inlineDiffs = inlineDiffs !== false;\n  return this;\n};\n\n/**\n * Enables or disables reporter to include diff in test failure output.\n *\n * @public\n * @see [CLI option](../#-diff)\n * @param {boolean} [diff=true] - Whether to show diff on failure.\n * @return {Mocha} this\n * @chainable\n */\nMocha.prototype.diff = function (diff) {\n  this.options.diff = diff !== false;\n  return this;\n};\n\n/**\n * @summary\n * Sets timeout threshold value.\n *\n * @description\n * A string argument can use shorthand (such as \"2s\") and will be converted.\n * If the value is `0`, timeouts will be disabled.\n *\n * @public\n * @see [CLI option](../#-timeout-ms-t-ms)\n * @see [Timeouts](../#timeouts)\n * @param {number|string} msecs - Timeout threshold value.\n * @return {Mocha} this\n * @chainable\n * @example\n *\n * // Sets timeout to one second\n * mocha.timeout(1000);\n * @example\n *\n * // Same as above but using string argument\n * mocha.timeout('1s');\n */\nMocha.prototype.timeout = function (msecs) {\n  this.suite.timeout(msecs);\n  return this;\n};\n\n/**\n * Sets the number of times to retry failed tests.\n *\n * @public\n * @see [CLI option](../#-retries-n)\n * @see [Retry Tests](../#retry-tests)\n * @param {number} retry - Number of times to retry failed tests.\n * @return {Mocha} this\n * @chainable\n * @example\n *\n * // Allow any failed test to retry one more time\n * mocha.retries(1);\n */\nMocha.prototype.retries = function (retry) {\n  this.suite.retries(retry);\n  return this;\n};\n\n/**\n * Sets slowness threshold value.\n *\n * @public\n * @see [CLI option](../#-slow-ms-s-ms)\n * @param {number} msecs - Slowness threshold value.\n * @return {Mocha} this\n * @chainable\n * @example\n *\n * // Sets \"slow\" threshold to half a second\n * mocha.slow(500);\n * @example\n *\n * // Same as above but using string argument\n * mocha.slow('0.5s');\n */\nMocha.prototype.slow = function (msecs) {\n  this.suite.slow(msecs);\n  return this;\n};\n\n/**\n * Forces all tests to either accept a `done` callback or return a promise.\n *\n * @public\n * @see [CLI option](../#-async-only-a)\n * @param {boolean} [asyncOnly=true] - Whether to force `done` callback or promise.\n * @return {Mocha} this\n * @chainable\n */\nMocha.prototype.asyncOnly = function (asyncOnly) {\n  this.options.asyncOnly = asyncOnly !== false;\n  return this;\n};\n\n/**\n * Disables syntax highlighting (in browser).\n *\n * @public\n * @return {Mocha} this\n * @chainable\n */\nMocha.prototype.noHighlighting = function () {\n  this.options.noHighlighting = true;\n  return this;\n};\n\n/**\n * Enables or disables uncaught errors to propagate.\n *\n * @public\n * @see [CLI option](../#-allow-uncaught)\n * @param {boolean} [allowUncaught=true] - Whether to propagate uncaught errors.\n * @return {Mocha} this\n * @chainable\n */\nMocha.prototype.allowUncaught = function (allowUncaught) {\n  this.options.allowUncaught = allowUncaught !== false;\n  return this;\n};\n\n/**\n * @summary\n * Delays root suite execution.\n *\n * @description\n * Used to perform async operations before any suites are run.\n *\n * @public\n * @see [delayed root suite](../#delayed-root-suite)\n * @returns {Mocha} this\n * @chainable\n */\nMocha.prototype.delay = function delay() {\n  this.options.delay = true;\n  return this;\n};\n\n/**\n * Enables or disables running tests in dry-run mode.\n *\n * @public\n * @see [CLI option](../#-dry-run)\n * @param {boolean} [dryRun=true] - Whether to activate dry-run mode.\n * @return {Mocha} this\n * @chainable\n */\nMocha.prototype.dryRun = function (dryRun) {\n  this.options.dryRun = dryRun !== false;\n  return this;\n};\n\n/**\n * Reports tests as failed when they are skipped due to a hook failure.\n *\n * @public\n * @see [CLI option](../#-fail-hook-affected-tests)\n * @param {boolean} [failHookAffectedTests=true] - Whether to fail tests affected by hook failures.\n * @return {Mocha} this\n * @chainable\n */\nMocha.prototype.failHookAffectedTests = function (failHookAffectedTests) {\n  this.options.failHookAffectedTests = failHookAffectedTests !== false;\n  return this;\n};\n\n/**\n * Fails test run if no tests encountered with exit-code 1.\n *\n * @public\n * @see [CLI option](../#-fail-zero)\n * @param {boolean} [failZero=true] - Whether to fail test run.\n * @return {Mocha} this\n * @chainable\n */\nMocha.prototype.failZero = function (failZero) {\n  this.options.failZero = failZero !== false;\n  return this;\n};\n\n/**\n * Fail test run if tests were failed.\n *\n * @public\n * @see [CLI option](../#-pass-on-failing-test-suite)\n * @param {boolean} [passOnFailingTestSuite=false] - Whether to fail test run.\n * @return {Mocha} this\n * @chainable\n */\nMocha.prototype.passOnFailingTestSuite = function (passOnFailingTestSuite) {\n  this.options.passOnFailingTestSuite = passOnFailingTestSuite === true;\n  return this;\n};\n\n/**\n * Causes tests marked `only` to fail the suite.\n *\n * @public\n * @see [CLI option](../#-forbid-only)\n * @param {boolean} [forbidOnly=true] - Whether tests marked `only` fail the suite.\n * @returns {Mocha} this\n * @chainable\n */\nMocha.prototype.forbidOnly = function (forbidOnly) {\n  this.options.forbidOnly = forbidOnly !== false;\n  return this;\n};\n\n/**\n * Causes pending tests and tests marked `skip` to fail the suite.\n *\n * @public\n * @see [CLI option](../#-forbid-pending)\n * @param {boolean} [forbidPending=true] - Whether pending tests fail the suite.\n * @returns {Mocha} this\n * @chainable\n */\nMocha.prototype.forbidPending = function (forbidPending) {\n  this.options.forbidPending = forbidPending !== false;\n  return this;\n};\n\n/**\n * Throws an error if mocha is in the wrong state to be able to transition to a \"running\" state.\n * @private\n */\nMocha.prototype._guardRunningStateTransition = function () {\n  if (this._state === mochaStates.RUNNING) {\n    throw createMochaInstanceAlreadyRunningError(\n      \"Mocha instance is currently running tests, cannot start a next test run until this one is done\",\n      this,\n    );\n  }\n  if (\n    this._state === mochaStates.DISPOSED ||\n    this._state === mochaStates.REFERENCES_CLEANED\n  ) {\n    throw createMochaInstanceAlreadyDisposedError(\n      \"Mocha instance is already disposed, cannot start a new test run. Please create a new mocha instance. Be sure to set disable `cleanReferencesAfterRun` when you want to reuse the same mocha instance for multiple test runs.\",\n      this._cleanReferencesAfterRun,\n      this,\n    );\n  }\n};\n\n/**\n * Mocha version as specified by \"package.json\".\n *\n * @name Mocha#version\n * @type string\n * @readonly\n */\nObject.defineProperty(Mocha.prototype, \"version\", {\n  value: require(\"../package.json\").version,\n  configurable: false,\n  enumerable: true,\n  writable: false,\n});\n\n/**\n * Runs root suite and invokes `fn()` when complete.\n *\n * @description\n * To run tests multiple times (or to run tests in files that are\n * already in the `require` cache), make sure to clear them from\n * the cache first!\n *\n * @public\n * @see {@link Mocha#unloadFiles}\n * @see {@link Runner#run}\n * @param {DoneCB} [fn] - Callback invoked when test execution completed.\n * @returns {import(\"./runner.js\")} runner instance\n * @example\n *\n * // exit with non-zero status if there were test failures\n * mocha.run(failures => process.exitCode = failures ? 1 : 0);\n */\nMocha.prototype.run = function (fn) {\n  this._guardRunningStateTransition();\n  this._state = mochaStates.RUNNING;\n  if (this._previousRunner) {\n    this._previousRunner.dispose();\n    this.suite.reset();\n  }\n  if (this.files.length && !this._lazyLoadFiles) {\n    this.loadFiles();\n  }\n  var suite = this.suite;\n  var options = this.options;\n  options.files = this.files;\n  const runner = new this._runnerClass(suite, {\n    cleanReferencesAfterRun: this._cleanReferencesAfterRun,\n    delay: options.delay,\n    dryRun: options.dryRun,\n    failHookAffectedTests: options.failHookAffectedTests,\n    failZero: options.failZero,\n  });\n  createStatsCollector(runner);\n  var reporter = new this._reporter(runner, options);\n  runner.checkLeaks = options.checkLeaks === true;\n  runner.fullStackTrace = options.fullTrace;\n  runner.asyncOnly = options.asyncOnly;\n  runner.allowUncaught = options.allowUncaught;\n  runner.forbidOnly = options.forbidOnly;\n  runner.forbidPending = options.forbidPending;\n  if (options.grep) {\n    runner.grep(options.grep, options.invert);\n  }\n  if (options.global) {\n    runner.globals(options.global);\n  }\n  if (options.color !== undefined) {\n    exports.reporters.Base.useColors = options.color;\n  }\n  exports.reporters.Base.inlineDiffs = options.inlineDiffs;\n  exports.reporters.Base.hideDiff = !options.diff;\n\n  const done = (failures) => {\n    this._previousRunner = runner;\n    this._state = this._cleanReferencesAfterRun\n      ? mochaStates.REFERENCES_CLEANED\n      : mochaStates.INIT;\n    fn = fn || utils.noop;\n    if (typeof reporter.done === \"function\") {\n      reporter.done(failures, fn);\n    } else {\n      fn(failures);\n    }\n  };\n\n  const runAsync = async (runner) => {\n    const context =\n      this.options.enableGlobalSetup && this.hasGlobalSetupFixtures()\n        ? await this.runGlobalSetup(runner)\n        : {};\n    const failureCount = await runner.runAsync({\n      files: this.files,\n      options,\n    });\n    if (this.options.enableGlobalTeardown && this.hasGlobalTeardownFixtures()) {\n      await this.runGlobalTeardown(runner, { context });\n    }\n    return failureCount;\n  };\n\n  // no \"catch\" here is intentional. errors coming out of\n  // Runner#run are considered uncaught/unhandled and caught\n  // by the `process` event listeners.\n  // also: returning anything other than `runner` would be a breaking\n  // change\n  runAsync(runner).then(done);\n\n  return runner;\n};\n\n/**\n * Assigns hooks to the root suite\n * @param {MochaRootHookObject} [hooks] - Hooks to assign to root suite\n * @chainable\n */\nMocha.prototype.rootHooks = function rootHooks({\n  beforeAll = [],\n  beforeEach = [],\n  afterAll = [],\n  afterEach = [],\n} = {}) {\n  beforeAll = utils.castArray(beforeAll);\n  beforeEach = utils.castArray(beforeEach);\n  afterAll = utils.castArray(afterAll);\n  afterEach = utils.castArray(afterEach);\n  beforeAll.forEach((hook) => {\n    this.suite.beforeAll(hook);\n  });\n  beforeEach.forEach((hook) => {\n    this.suite.beforeEach(hook);\n  });\n  afterAll.forEach((hook) => {\n    this.suite.afterAll(hook);\n  });\n  afterEach.forEach((hook) => {\n    this.suite.afterEach(hook);\n  });\n  return this;\n};\n\n/**\n * Toggles parallel mode.\n *\n * Must be run before calling {@link Mocha#run}. Changes the `Runner` class to\n * use; also enables lazy file loading if not already done so.\n *\n * Warning: when passed `false` and lazy loading has been enabled _via any means_ (including calling `parallelMode(true)`), this method will _not_ disable lazy loading. Lazy loading is a prerequisite for parallel\n * mode, but parallel mode is _not_ a prerequisite for lazy loading!\n * @param {boolean} [enable] - If `true`, enable; otherwise disable.\n * @throws If run in browser\n * @throws If Mocha not in `INIT` state\n * @returns {Mocha}\n * @chainable\n * @public\n */\nMocha.prototype.parallelMode = function parallelMode(enable = true) {\n  if (utils.isBrowser()) {\n    throw createUnsupportedError(\"parallel mode is only supported in Node.js\");\n  }\n  const parallel = Boolean(enable);\n  if (\n    parallel === this.options.parallel &&\n    this._lazyLoadFiles &&\n    this._runnerClass !== exports.Runner\n  ) {\n    return this;\n  }\n  if (this._state !== mochaStates.INIT) {\n    throw createUnsupportedError(\n      \"cannot change parallel mode after having called run()\",\n    );\n  }\n  this.options.parallel = parallel;\n\n  // swap Runner class\n  this._runnerClass = parallel\n    ? require(\"./nodejs/parallel-buffered-runner\")\n    : exports.Runner;\n\n  // lazyLoadFiles may have been set `true` otherwise (for ESM loading),\n  // so keep `true` if so.\n  return this.lazyLoadFiles(this._lazyLoadFiles || parallel);\n};\n\n/**\n * Disables implicit call to {@link Mocha#loadFiles} in {@link Mocha#run}. This\n * setting is used by watch mode, parallel mode, and for loading ESM files.\n * @todo This should throw if we've already loaded files; such behavior\n * necessitates adding a new state.\n * @param {boolean} [enable] - If `true`, disable eager loading of files in\n * {@link Mocha#run}\n * @chainable\n * @public\n */\nMocha.prototype.lazyLoadFiles = function lazyLoadFiles(enable) {\n  this._lazyLoadFiles = enable === true;\n  debug(\"set lazy load to %s\", enable);\n  return this;\n};\n\n/**\n * Configures one or more global setup fixtures.\n *\n * If given no parameters, _unsets_ any previously-set fixtures.\n * @chainable\n * @public\n * @param {MochaGlobalFixture|MochaGlobalFixture[]} [setupFns] - Global setup fixture(s)\n * @returns {Mocha}\n */\nMocha.prototype.globalSetup = function globalSetup(setupFns = []) {\n  setupFns = utils.castArray(setupFns);\n  this.options.globalSetup = setupFns;\n  debug(\"configured %d global setup functions\", setupFns.length);\n  return this;\n};\n\n/**\n * Configures one or more global teardown fixtures.\n *\n * If given no parameters, _unsets_ any previously-set fixtures.\n * @chainable\n * @public\n * @param {MochaGlobalFixture|MochaGlobalFixture[]} [teardownFns] - Global teardown fixture(s)\n * @returns {Mocha}\n */\nMocha.prototype.globalTeardown = function globalTeardown(teardownFns = []) {\n  teardownFns = utils.castArray(teardownFns);\n  this.options.globalTeardown = teardownFns;\n  debug(\"configured %d global teardown functions\", teardownFns.length);\n  return this;\n};\n\n/**\n * Run any global setup fixtures sequentially, if any.\n *\n * This is _automatically called_ by {@link Mocha#run} _unless_ the `runGlobalSetup` option is `false`; see {@link Mocha#enableGlobalSetup}.\n *\n * The context object this function resolves with should be consumed by {@link Mocha#runGlobalTeardown}.\n * @param {object} [context] - Context object if already have one\n * @public\n * @returns {Promise<object>} Context object\n */\nMocha.prototype.runGlobalSetup = async function runGlobalSetup(context = {}) {\n  const { globalSetup } = this.options;\n  if (globalSetup && globalSetup.length) {\n    debug(\"run(): global setup starting\");\n    await this._runGlobalFixtures(globalSetup, context);\n    debug(\"run(): global setup complete\");\n  }\n  return context;\n};\n\n/**\n * Run any global teardown fixtures sequentially, if any.\n *\n * This is _automatically called_ by {@link Mocha#run} _unless_ the `runGlobalTeardown` option is `false`; see {@link Mocha#enableGlobalTeardown}.\n *\n * Should be called with context object returned by {@link Mocha#runGlobalSetup}, if applicable.\n * @param {object} [context] - Context object if already have one\n * @public\n * @returns {Promise<object>} Context object\n */\nMocha.prototype.runGlobalTeardown = async function runGlobalTeardown(\n  context = {},\n) {\n  const { globalTeardown } = this.options;\n  if (globalTeardown && globalTeardown.length) {\n    debug(\"run(): global teardown starting\");\n    await this._runGlobalFixtures(globalTeardown, context);\n  }\n  debug(\"run(): global teardown complete\");\n  return context;\n};\n\n/**\n * Run global fixtures sequentially with context `context`\n * @private\n * @param {MochaGlobalFixture[]} [fixtureFns] - Fixtures to run\n * @param {object} [context] - context object\n * @returns {Promise<object>} context object\n */\nMocha.prototype._runGlobalFixtures = async function _runGlobalFixtures(\n  fixtureFns = [],\n  context = {},\n) {\n  for await (const fixtureFn of fixtureFns) {\n    await fixtureFn.call(context);\n  }\n  return context;\n};\n\n/**\n * Toggle execution of any global setup fixture(s)\n *\n * @chainable\n * @public\n * @param {boolean } [enabled=true] - If `false`, do not run global setup fixture\n * @returns {Mocha}\n */\nMocha.prototype.enableGlobalSetup = function enableGlobalSetup(enabled = true) {\n  this.options.enableGlobalSetup = Boolean(enabled);\n  return this;\n};\n\n/**\n * Toggle execution of any global teardown fixture(s)\n *\n * @chainable\n * @public\n * @param {boolean } [enabled=true] - If `false`, do not run global teardown fixture\n * @returns {Mocha}\n */\nMocha.prototype.enableGlobalTeardown = function enableGlobalTeardown(\n  enabled = true,\n) {\n  this.options.enableGlobalTeardown = Boolean(enabled);\n  return this;\n};\n\n/**\n * Returns `true` if one or more global setup fixtures have been supplied.\n * @public\n * @returns {boolean}\n */\nMocha.prototype.hasGlobalSetupFixtures = function hasGlobalSetupFixtures() {\n  return Boolean(this.options.globalSetup.length);\n};\n\n/**\n * Returns `true` if one or more global teardown fixtures have been supplied.\n * @public\n * @returns {boolean}\n */\nMocha.prototype.hasGlobalTeardownFixtures =\n  function hasGlobalTeardownFixtures() {\n    return Boolean(this.options.globalTeardown.length);\n  };\n"
  },
  {
    "path": "lib/mocharc.json",
    "content": "{\n  \"diff\": true,\n  \"extension\": [\"js\", \"cjs\", \"mjs\"],\n  \"package\": \"./package.json\",\n  \"reporter\": \"spec\",\n  \"slow\": 75,\n  \"timeout\": 2000,\n  \"ui\": \"bdd\",\n  \"watch-ignore\": [\"node_modules\", \".git\"]\n}\n"
  },
  {
    "path": "lib/nodejs/buffered-worker-pool.js",
    "content": "/**\n * A wrapper around a third-party child process worker pool implementation.\n * Used by {@link module:buffered-runner}.\n * @private\n * @module buffered-worker-pool\n */\n\n\"use strict\";\n\n/**\n * @typedef {import('workerpool').WorkerPoolOptions} WorkerPoolOptions\n * @typedef {import('../types.d.ts').MochaOptions} MochaOptions\n * @typedef {import('../types.d.ts').SerializedWorkerResult} SerializedWorkerResult\n */\n\nconst serializeJavascript = require(\"serialize-javascript\");\nconst workerpool = require(\"workerpool\");\nconst { deserialize } = require(\"./serializer\");\nconst debug = require(\"debug\")(\"mocha:parallel:buffered-worker-pool\");\nconst { createInvalidArgumentTypeError } = require(\"../errors\");\n\nconst WORKER_PATH = require.resolve(\"./worker.js\");\n\n/**\n * A mapping of Mocha `Options` objects to serialized values.\n *\n * This is helpful because we tend to same the same options over and over\n * over IPC.\n * @type {WeakMap<MochaOptions,string>}\n */\nlet optionsCache = new WeakMap();\n\n/**\n * These options are passed into the [workerpool](https://npm.im/workerpool) module.\n * @type {Partial<WorkerPoolOptions>}\n */\nconst WORKER_POOL_DEFAULT_OPTS = {\n  // use child processes, not worker threads!\n  workerType: \"process\",\n  // ensure the same flags sent to `node` for this `mocha` invocation are passed\n  // along to children\n  forkOpts: { execArgv: process.execArgv },\n  maxWorkers: workerpool.cpus - 1,\n};\n\n/**\n * A wrapper around a third-party worker pool implementation.\n * @private\n */\nclass BufferedWorkerPool {\n  /**\n   * Creates an underlying worker pool instance; determines max worker count\n   * @param {Partial<WorkerPoolOptions>} [opts] - Options\n   */\n  constructor(opts = {}) {\n    const maxWorkers = Math.max(\n      1,\n      typeof opts.maxWorkers === \"undefined\"\n        ? WORKER_POOL_DEFAULT_OPTS.maxWorkers\n        : opts.maxWorkers,\n    );\n\n    /* istanbul ignore next */\n    if (workerpool.cpus < 2) {\n      // TODO: decide whether we should warn\n      debug(\n        \"not enough CPU cores available to run multiple jobs; avoid --parallel on this machine\",\n      );\n    } else if (maxWorkers >= workerpool.cpus) {\n      // TODO: decide whether we should warn\n      debug(\n        \"%d concurrent job(s) requested, but only %d core(s) available\",\n        maxWorkers,\n        workerpool.cpus,\n      );\n    }\n    /* istanbul ignore next */\n    debug(\n      \"run(): starting worker pool of max size %d, using node args: %s\",\n      maxWorkers,\n      process.execArgv.join(\" \"),\n    );\n\n    let counter = 0;\n    const onCreateWorker = ({ forkOpts }) => {\n      return {\n        forkOpts: {\n          ...forkOpts,\n          // adds an incremental id to all workers, which can be useful to allocate resources for each process\n          env: { ...process.env, MOCHA_WORKER_ID: counter++ },\n        },\n      };\n    };\n\n    this.options = {\n      ...WORKER_POOL_DEFAULT_OPTS,\n      ...opts,\n      maxWorkers,\n      onCreateWorker,\n    };\n    this._pool = workerpool.pool(WORKER_PATH, this.options);\n  }\n\n  /**\n   * Terminates all workers in the pool.\n   * @param {boolean} [force] - Whether to force-kill workers. By default, lets workers finish their current task before termination.\n   * @private\n   * @returns {Promise<void>}\n   */\n  async terminate(force = false) {\n    /* istanbul ignore next */\n    debug(\"terminate(): terminating with force = %s\", force);\n    return this._pool.terminate(force);\n  }\n\n  /**\n   * Adds a test file run to the worker pool queue for execution by a worker process.\n   *\n   * Handles serialization/deserialization.\n   *\n   * @param {string} filepath - Filepath of test\n   * @param {MochaOptions} [options] - Options for Mocha instance\n   * @private\n   * @returns {Promise<SerializedWorkerResult>}\n   */\n  async run(filepath, options = {}) {\n    if (!filepath || typeof filepath !== \"string\") {\n      throw createInvalidArgumentTypeError(\n        \"Expected a non-empty filepath\",\n        \"filepath\",\n        \"string\",\n      );\n    }\n    const serializedOptions = BufferedWorkerPool.serializeOptions(options);\n    const result = await this._pool.exec(\"run\", [filepath, serializedOptions]);\n    return deserialize(result);\n  }\n\n  /**\n   * Returns stats about the state of the worker processes in the pool.\n   *\n   * Used for debugging.\n   *\n   * @private\n   */\n  stats() {\n    return this._pool.stats();\n  }\n\n  /**\n   * Instantiates a {@link WorkerPool}.\n   * @private\n   */\n  static create(...args) {\n    return new BufferedWorkerPool(...args);\n  }\n\n  /**\n   * Given Mocha options object `opts`, serialize into a format suitable for\n   * transmission over IPC.\n   *\n   * @param {MochaOptions} [opts] - Mocha options\n   * @private\n   * @returns {string} Serialized options\n   */\n  static serializeOptions(opts = {}) {\n    if (!optionsCache.has(opts)) {\n      const serialized = serializeJavascript(opts, {\n        unsafe: true, // this means we don't care about XSS\n        ignoreFunction: true, // do not serialize functions\n      });\n      optionsCache.set(opts, serialized);\n      /* istanbul ignore next */\n      debug(\n        \"serializeOptions(): serialized options %O to: %s\",\n        opts,\n        serialized,\n      );\n    }\n    return optionsCache.get(opts);\n  }\n\n  /**\n   * Resets internal cache of serialized options objects.\n   *\n   * For testing/debugging\n   * @private\n   */\n  static resetOptionsCache() {\n    optionsCache = new WeakMap();\n  }\n}\n\nexports.BufferedWorkerPool = BufferedWorkerPool;\n"
  },
  {
    "path": "lib/nodejs/esm-utils.js",
    "content": "const path = require(\"node:path\");\nconst url = require(\"node:url\");\nconst debug = require(\"debug\")(\"mocha:esm-utils\");\nconst { isMochaError } = require(\"../errors\");\n\nconst forward = (x) => x;\n\nconst formattedImport = async (file, esmDecorator = forward) => {\n  if (path.isAbsolute(file)) {\n    try {\n      return await exports.doImport(esmDecorator(url.pathToFileURL(file)));\n    } catch (err) {\n      // This is a hack created because ESM in Node.js (at least in Node v15.5.1) does not emit\n      // the location of the syntax error in the error thrown.\n      // This is problematic because the user can't see what file has the problem,\n      // so we add the file location to the error.\n      // TODO: remove once Node.js fixes the problem.\n      if (\n        err instanceof SyntaxError &&\n        err.message &&\n        err.stack &&\n        !err.stack.includes(file)\n      ) {\n        const newErrorWithFilename = new SyntaxError(err.message);\n        newErrorWithFilename.stack = err.stack.replace(\n          /^SyntaxError/,\n          `SyntaxError[ @${file} ]`,\n        );\n        throw newErrorWithFilename;\n      }\n      throw err;\n    }\n  }\n  return exports.doImport(esmDecorator(file));\n};\n\nexports.doImport = async (file) => import(file);\n\n// When require(esm) is not available, we need to use `import()` to load ESM modules.\n// In this case, CJS modules are loaded using `import()` as well. When Node.js' builtin\n// TypeScript support is enabled, `.ts` files are also loaded using `import()`, and\n// compilers based on `require.extensions` are omitted.\nconst tryImportAndRequire = async (file, esmDecorator) => {\n  if (path.extname(file) === \".mjs\") {\n    return formattedImport(file, esmDecorator);\n  }\n  try {\n    return dealWithExports(await formattedImport(file, esmDecorator));\n  } catch (err) {\n    if (\n      err.code === \"ERR_MODULE_NOT_FOUND\" ||\n      err.code === \"ERR_UNKNOWN_FILE_EXTENSION\" ||\n      err.code === \"ERR_UNSUPPORTED_DIR_IMPORT\"\n    ) {\n      try {\n        // Importing a file usually works, but the resolution of `import` is the ESM\n        // resolution algorithm, and not the CJS resolution algorithm. We may have\n        // failed because we tried the ESM resolution, so we try to `require` it.\n        return require(file);\n      } catch (requireErr) {\n        if (\n          requireErr.code === \"ERR_REQUIRE_ESM\" ||\n          (requireErr instanceof SyntaxError &&\n            requireErr\n              .toString()\n              .includes(\"Cannot use import statement outside a module\"))\n        ) {\n          // ERR_REQUIRE_ESM happens when the test file is a JS file, but via type:module is actually ESM,\n          // AND has an import to a file that doesn't exist.\n          // This throws an `ERR_MODULE_NOT_FOUND` error above,\n          // and when we try to `require` it here, it throws an `ERR_REQUIRE_ESM`.\n          // What we want to do is throw the original error (the `ERR_MODULE_NOT_FOUND`),\n          // and not the `ERR_REQUIRE_ESM` error, which is a red herring.\n          //\n          // SyntaxError happens when in an edge case: when we're using an ESM loader that loads\n          // a `test.ts` file (i.e. unrecognized extension), and that file includes an unknown\n          // import (which throws an ERR_MODULE_NOT_FOUND). `require`-ing it will throw the\n          // syntax error, because we cannot require a file that has `import`-s.\n          throw err;\n        } else {\n          throw requireErr;\n        }\n      }\n    } else {\n      throw err;\n    }\n  }\n};\n\n// Utilize Node.js' require(esm) feature to load ESM modules\n// and CJS modules. This keeps the require() features like `require.extensions`\n// and `require.cache` effective, while allowing us to load ESM modules\n// and CJS modules in the same way.\nconst requireModule = async (file, esmDecorator) => {\n  if (path.extname(file) === \".mjs\") {\n    return formattedImport(file, esmDecorator);\n  }\n  try {\n    return require(file);\n  } catch (requireErr) {\n    debug(\"requireModule caught err: %O\", requireErr.message);\n    if (requireErr.name === \"TSError\" || isMochaError(requireErr)) {\n      throw requireErr;\n    }\n    try {\n      return dealWithExports(await formattedImport(file, esmDecorator));\n    } catch (importErr) {\n      // If a --require module throws in a Node.js version that doesn't yet support .ts files,\n      // the fallback import() will throw an uninformative error about the file extension.\n      // What we actually care about is the original require() error.\n      // See: https://github.com/mochajs/mocha/issues/5393\n      if (\n        /\\.(cts|mts|ts)$/.test(file) ||\n        importErr.code === \"ERR_UNKNOWN_FILE_EXTENSION\"\n      ) {\n        throw requireErr;\n      }\n\n      // Similarly, for an exports/imports mismatch such as a missing 'default',\n      // the require() error will be more informative for users.\n      // See: https://github.com/mochajs/mocha/issues/5411\n      if (importErr.code === \"ERR_INTERNAL_ASSERTION\") {\n        throw requireErr;\n      }\n\n      throw importErr;\n    }\n  }\n};\n\n// We only assign this `requireOrImport` function once based on Node version\n// We check for file extensions in `requireModule` and `tryImportAndRequire`\ndebug(\n  \"assigning requireOrImport, require_module === %O\",\n  process.features.require_module,\n);\nif (process.features.require_module) {\n  exports.requireOrImport = requireModule;\n} else {\n  exports.requireOrImport = tryImportAndRequire;\n}\n\nfunction dealWithExports(module) {\n  if (module.default) {\n    return module.default;\n  } else {\n    return { ...module, default: undefined };\n  }\n}\n\nexports.loadFilesAsync = async (\n  files,\n  preLoadFunc,\n  postLoadFunc,\n  esmDecorator,\n) => {\n  for (const file of files) {\n    preLoadFunc(file);\n    const result = await exports.requireOrImport(\n      path.resolve(file),\n      esmDecorator,\n    );\n    postLoadFunc(file, result);\n  }\n};\n"
  },
  {
    "path": "lib/nodejs/file-unloader.js",
    "content": "\"use strict\";\n\n/**\n * This module should not be in the browser bundle, so it's here.\n * @private\n * @module\n */\n\n/**\n * Deletes a file from the `require` cache.\n * @param {string} file - File\n */\nexports.unloadFile = (file) => {\n  delete require.cache[require.resolve(file)];\n};\n"
  },
  {
    "path": "lib/nodejs/parallel-buffered-runner.js",
    "content": "/**\n * A test Runner that uses a {@link module:buffered-worker-pool}.\n * @module parallel-buffered-runner\n * @private\n */\n\n\"use strict\";\n\n/**\n * @typedef {import('../types.d.ts').FileRunner} FileRunner\n * @typedef {import('../types.d.ts').RunnerOptions} RunnerOptions\n * @typedef {import('../types.d.ts').SerializedWorkerResult} SerializedWorkerResult\n * @typedef {import('../types.d.ts').SigIntListener} SigIntListener\n */\n\nconst Runner = require(\"../runner\");\nconst { EVENT_RUN_BEGIN, EVENT_RUN_END } = Runner.constants;\nconst debug = require(\"debug\")(\"mocha:parallel:parallel-buffered-runner\");\nconst { BufferedWorkerPool } = require(\"./buffered-worker-pool\");\nconst { setInterval, clearInterval } = global;\nconst { createMap, constants } = require(\"../utils\");\nconst { MOCHA_ID_PROP_NAME } = constants;\nconst { createFatalError } = require(\"../errors\");\n\nconst DEFAULT_WORKER_REPORTER =\n  require.resolve(\"./reporters/parallel-buffered\");\n\n/**\n * List of options to _not_ serialize for transmission to workers\n */\nconst DENY_OPTIONS = [\n  \"globalSetup\",\n  \"globalTeardown\",\n  \"parallel\",\n  \"p\",\n  \"jobs\",\n  \"j\",\n];\n\n/**\n * Outputs a debug statement with worker stats\n * @param {BufferedWorkerPool} pool - Worker pool\n */\n/* istanbul ignore next */\nconst debugStats = (pool) => {\n  const { totalWorkers, busyWorkers, idleWorkers, pendingTasks } = pool.stats();\n  debug(\n    \"%d/%d busy workers; %d idle; %d tasks queued\",\n    busyWorkers,\n    totalWorkers,\n    idleWorkers,\n    pendingTasks,\n  );\n};\n\n/**\n * The interval at which we will display stats for worker processes in debug mode\n */\nconst DEBUG_STATS_INTERVAL = 5000;\n\nconst ABORTED = \"ABORTED\";\nconst IDLE = \"IDLE\";\nconst ABORTING = \"ABORTING\";\nconst RUNNING = \"RUNNING\";\nconst BAILING = \"BAILING\";\nconst BAILED = \"BAILED\";\nconst COMPLETE = \"COMPLETE\";\n\nconst states = createMap({\n  [IDLE]: new Set([RUNNING, ABORTING]),\n  [RUNNING]: new Set([COMPLETE, BAILING, ABORTING]),\n  [COMPLETE]: new Set(),\n  [ABORTED]: new Set(),\n  [ABORTING]: new Set([ABORTED]),\n  [BAILING]: new Set([BAILED, ABORTING]),\n  [BAILED]: new Set([COMPLETE, ABORTING]),\n});\n\n/**\n * This `Runner` delegates tests runs to worker threads.  Does not execute any\n * {@link Runnable}s by itself!\n * @public\n */\nclass ParallelBufferedRunner extends Runner {\n  constructor(...args) {\n    super(...args);\n\n    let state = IDLE;\n    Object.defineProperty(this, \"_state\", {\n      get() {\n        return state;\n      },\n      set(newState) {\n        if (states[state].has(newState)) {\n          state = newState;\n        } else {\n          throw new Error(`invalid state transition: ${state} => ${newState}`);\n        }\n      },\n    });\n\n    this._workerReporter = DEFAULT_WORKER_REPORTER;\n    this._linkPartialObjects = false;\n    this._linkedObjectMap = new Map();\n\n    this.once(Runner.constants.EVENT_RUN_END, () => {\n      this._state = COMPLETE;\n    });\n  }\n\n  /**\n   * Returns a mapping function to enqueue a file in the worker pool and return results of its execution.\n   * @param {BufferedWorkerPool} pool - Worker pool\n   * @param {RunnerOptions} options - Mocha options\n   * @returns {FileRunner} Mapping function\n   * @private\n   */\n  _createFileRunner(pool, options) {\n    /**\n     * Emits event and sets `BAILING` state, if necessary.\n     * @param {Object} event - Event having `eventName`, maybe `data` and maybe `error`\n     * @param {number} failureCount - Failure count\n     */\n    const emitEvent = (event, failureCount) => {\n      this.emit(event.eventName, event.data, event.error);\n      if (\n        this._state !== BAILING &&\n        event.data &&\n        event.data._bail &&\n        (failureCount || event.error)\n      ) {\n        debug(\"run(): nonzero failure count & found bail flag\");\n        // we need to let the events complete for this file, as the worker\n        // should run any cleanup hooks\n        this._state = BAILING;\n      }\n    };\n\n    /**\n     * Given an event, recursively find any objects in its data that have ID's, and create object references to already-seen objects.\n     * @param {Object} event - Event having `eventName`, maybe `data` and maybe `error`\n     */\n    const linkEvent = (event) => {\n      const stack = [{ parent: event, prop: \"data\" }];\n      while (stack.length) {\n        const { parent, prop } = stack.pop();\n        const obj = parent[prop];\n        let newObj;\n        if (obj && typeof obj === \"object\") {\n          if (obj[MOCHA_ID_PROP_NAME]) {\n            const id = obj[MOCHA_ID_PROP_NAME];\n            newObj = this._linkedObjectMap.has(id)\n              ? Object.assign(this._linkedObjectMap.get(id), obj)\n              : obj;\n            this._linkedObjectMap.set(id, newObj);\n            parent[prop] = newObj;\n          } else {\n            throw createFatalError(\n              \"Object missing ID received in event data\",\n              obj,\n            );\n          }\n        }\n        Object.keys(newObj).forEach((key) => {\n          const value = obj[key];\n          if (value && typeof value === \"object\" && value[MOCHA_ID_PROP_NAME]) {\n            stack.push({ obj: value, parent: newObj, prop: key });\n          }\n        });\n      }\n    };\n\n    return async (file) => {\n      debug(\"run(): enqueueing test file %s\", file);\n      try {\n        const { failureCount, events } = await pool.run(file, options);\n\n        if (this._state === BAILED) {\n          // short-circuit after a graceful bail. if this happens,\n          // some other worker has bailed.\n          // TODO: determine if this is the desired behavior, or if we\n          // should report the events of this run anyway.\n          return;\n        }\n        debug(\n          \"run(): completed run of file %s; %d failures / %d events\",\n          file,\n          failureCount,\n          events.length,\n        );\n        this.failures += failureCount; // can this ever be non-numeric?\n        let event = events.shift();\n\n        if (this._linkPartialObjects) {\n          while (event) {\n            linkEvent(event);\n            emitEvent(event, failureCount);\n            event = events.shift();\n          }\n        } else {\n          while (event) {\n            emitEvent(event, failureCount);\n            event = events.shift();\n          }\n        }\n        if (this._state === BAILING) {\n          debug('run(): terminating pool due to \"bail\" flag');\n          this._state = BAILED;\n          await pool.terminate();\n        }\n      } catch (err) {\n        if (this._state === BAILED || this._state === ABORTING) {\n          debug(\n            \"run(): worker pool terminated with intent; skipping file %s\",\n            file,\n          );\n        } else {\n          // this is an uncaught exception\n          debug(\"run(): encountered uncaught exception: %O\", err);\n          if (this.allowUncaught) {\n            // still have to clean up\n            this._state = ABORTING;\n            await pool.terminate(true);\n          }\n          throw err;\n        }\n      } finally {\n        debug(\"run(): done running file %s\", file);\n      }\n    };\n  }\n\n  /**\n   * Listen on `Process.SIGINT`; terminate pool if caught.\n   * Returns the listener for later call to `process.removeListener()`.\n   * @param {BufferedWorkerPool} pool - Worker pool\n   * @returns {SigIntListener} Listener\n   * @private\n   */\n  _bindSigIntListener(pool) {\n    const sigIntListener = async () => {\n      debug(\"run(): caught a SIGINT\");\n      this._state = ABORTING;\n\n      try {\n        debug(\"run(): force-terminating worker pool\");\n        await pool.terminate(true);\n      } catch (err) {\n        console.error(\n          `Error while attempting to force-terminate worker pool: ${err}`,\n        );\n        process.exitCode = 1;\n      } finally {\n        process.nextTick(() => {\n          debug(\"run(): imminent death\");\n          this._state = ABORTED;\n          process.kill(process.pid, \"SIGINT\");\n        });\n      }\n    };\n\n    process.once(\"SIGINT\", sigIntListener);\n\n    return sigIntListener;\n  }\n\n  /**\n   * Runs Mocha tests by creating a thread pool, then delegating work to the\n   * worker threads.\n   *\n   * Each worker receives one file, and as workers become available, they take a\n   * file from the queue and run it. The worker thread execution is treated like\n   * an RPC--it returns a `Promise` containing serialized information about the\n   * run.  The information is processed as it's received, and emitted to a\n   * {@link Reporter}, which is likely listening for these events.\n   *\n   * @param {Function} callback - Called with an exit code corresponding to\n   * number of test failures.\n   * @param {RunnerOptions} [opts] - options\n   */\n  run(callback, { files, options = {} } = {}) {\n    /**\n     * Listener on `Process.SIGINT` which tries to cleanly terminate the worker pool.\n     */\n    let sigIntListener;\n\n    // assign the reporter the worker will use, which will be different than the\n    // main process' reporter\n    options = { ...options, reporter: this._workerReporter };\n\n    // This function should _not_ return a `Promise`; its parent (`Runner#run`)\n    // returns this instance, so this should do the same. However, we want to make\n    // use of `async`/`await`, so we use this IIFE.\n    (async () => {\n      /**\n       * This is an interval that outputs stats about the worker pool every so often\n       */\n      let debugInterval;\n\n      /**\n       * @type {BufferedWorkerPool}\n       */\n      let pool;\n\n      try {\n        pool = BufferedWorkerPool.create({ maxWorkers: options.jobs });\n\n        sigIntListener = this._bindSigIntListener(pool);\n\n        /* istanbul ignore next */\n        debugInterval = setInterval(\n          () => debugStats(pool),\n          DEBUG_STATS_INTERVAL,\n        ).unref();\n\n        // this is set for uncaught exception handling in `Runner#uncaught`\n        // TODO: `Runner` should be using a state machine instead.\n        this.started = true;\n        this._state = RUNNING;\n\n        this.emit(EVENT_RUN_BEGIN);\n\n        options = { ...options };\n        DENY_OPTIONS.forEach((opt) => {\n          delete options[opt];\n        });\n\n        const results = await Promise.allSettled(\n          files.map(this._createFileRunner(pool, options)),\n        );\n\n        // note that pool may already be terminated due to --bail\n        await pool.terminate();\n\n        results\n          .filter(({ status }) => status === \"rejected\")\n          .forEach(({ reason }) => {\n            if (this.allowUncaught) {\n              // yep, just the first one.\n              throw reason;\n            }\n            // \"rejected\" will correspond to uncaught exceptions.\n            // unlike the serial runner, the parallel runner can always recover.\n            this.uncaught(reason);\n          });\n\n        if (this._state === ABORTING) {\n          return;\n        }\n\n        this.emit(EVENT_RUN_END);\n        debug(\"run(): completing with failure count %d\", this.failures);\n        callback(this.failures);\n      } catch (err) {\n        // this `nextTick` takes us out of the `Promise` scope, so the\n        // exception will not be caught and returned as a rejected `Promise`,\n        // which would lead to an `unhandledRejection` event.\n        process.nextTick(() => {\n          debug(\"run(): re-throwing uncaught exception\");\n          throw err;\n        });\n      } finally {\n        clearInterval(debugInterval);\n        process.removeListener(\"SIGINT\", sigIntListener);\n      }\n    })();\n    return this;\n  }\n\n  /**\n   * Toggle partial object linking behavior; used for building object references from\n   * unique ID's.\n   * @param {boolean} [value] - If `true`, enable partial object linking, otherwise disable\n   * @returns {Runner}\n   * @chainable\n   * @public\n   * @example\n   * // this reporter needs proper object references when run in parallel mode\n   * class MyReporter() {\n   *   constructor(runner) {\n   *     runner.linkPartialObjects(true)\n   *       .on(EVENT_SUITE_BEGIN, suite => {\n   *         // this Suite may be the same object...\n   *       })\n   *       .on(EVENT_TEST_BEGIN, test => {\n   *         // ...as the `test.parent` property\n   *       });\n   *   }\n   * }\n   */\n  linkPartialObjects(value) {\n    this._linkPartialObjects = Boolean(value);\n    return super.linkPartialObjects(value);\n  }\n\n  /**\n   * If this class is the `Runner` in use, then this is going to return `true`.\n   *\n   * For use by reporters.\n   * @returns {true}\n   * @public\n   */\n  isParallelMode() {\n    return true;\n  }\n\n  /**\n   * Configures an alternate reporter for worker processes to use. Subclasses\n   * using worker processes should implement this.\n   * @public\n   * @param {string} path - Absolute path to alternate reporter for worker processes to use\n   * @returns {Runner}\n   * @throws When in serial mode\n   * @chainable\n   */\n  workerReporter(reporter) {\n    this._workerReporter = reporter;\n    return this;\n  }\n}\n\nmodule.exports = ParallelBufferedRunner;\n"
  },
  {
    "path": "lib/nodejs/reporters/parallel-buffered.js",
    "content": "/**\n * \"Buffered\" reporter used internally by a worker process when running in parallel mode.\n * @module nodejs/reporters/parallel-buffered\n * @public\n */\n\n\"use strict\";\n\n/**\n * @typedef {import('../../types.d.ts').BufferedEvent} BufferedEvent\n * @typedef {import('../../runner.js')} Runner\n */\n\n/**\n * Module dependencies.\n */\n\nconst {\n  EVENT_SUITE_BEGIN,\n  EVENT_SUITE_END,\n  EVENT_TEST_FAIL,\n  EVENT_TEST_PASS,\n  EVENT_TEST_PENDING,\n  EVENT_TEST_BEGIN,\n  EVENT_TEST_END,\n  EVENT_TEST_RETRY,\n  EVENT_DELAY_BEGIN,\n  EVENT_DELAY_END,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_RUN_END,\n} = require(\"../../runner\").constants;\nconst {\n  SerializableEvent,\n  SerializableWorkerResult,\n} = require(\"../serializer\");\nconst debug = require(\"debug\")(\"mocha:reporters:buffered\");\nconst Base = require(\"../../reporters/base\");\n\n/**\n * List of events to listen to; these will be buffered and sent\n * when `Mocha#run` is complete (via {@link ParallelBuffered#done}).\n */\nconst EVENT_NAMES = [\n  EVENT_SUITE_BEGIN,\n  EVENT_SUITE_END,\n  EVENT_TEST_BEGIN,\n  EVENT_TEST_PENDING,\n  EVENT_TEST_FAIL,\n  EVENT_TEST_PASS,\n  EVENT_TEST_RETRY,\n  EVENT_TEST_END,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n];\n\n/**\n * Like {@link EVENT_NAMES}, except we expect these events to only be emitted\n * by the `Runner` once.\n */\nconst ONCE_EVENT_NAMES = [EVENT_DELAY_BEGIN, EVENT_DELAY_END];\n\n/**\n * The `ParallelBuffered` reporter is used by each worker process in \"parallel\"\n * mode, by default.  Instead of reporting to `STDOUT`, etc., it retains a\n * list of events it receives and hands these off to the callback passed into\n * {@link Mocha#run}. That callback will then return the data to the main\n * process.\n * @public\n */\nclass ParallelBuffered extends Base {\n  /**\n   * Calls {@link ParallelBuffered#createListeners}\n   * @param {Runner} runner\n   */\n  constructor(runner, opts) {\n    super(runner, opts);\n\n    /**\n     * Retained list of events emitted from the {@link Runner} instance.\n     * @type {BufferedEvent[]}\n     * @public\n     */\n    this.events = [];\n\n    /**\n     * Map of `Runner` event names to listeners (for later teardown)\n     * @public\n     * @type {Map<string,EventListener>}\n     */\n    this.listeners = new Map();\n\n    this.createListeners(runner);\n  }\n\n  /**\n   * Returns a new listener which saves event data in memory to\n   * {@link ParallelBuffered#events}. Listeners are indexed by `eventName` and stored\n   * in {@link ParallelBuffered#listeners}. This is a defensive measure, so that we\n   * don't a) leak memory or b) remove _other_ listeners that may not be\n   * associated with this reporter.\n   *\n   * Subclasses could override this behavior.\n   *\n   * @public\n   * @param {string} eventName - Name of event to create listener for\n   * @returns {EventListener}\n   */\n  createListener(eventName) {\n    const listener = (runnable, err) => {\n      this.events.push(SerializableEvent.create(eventName, runnable, err));\n    };\n    return this.listeners.set(eventName, listener).get(eventName);\n  }\n\n  /**\n   * Creates event listeners (using {@link ParallelBuffered#createListener}) for each\n   * reporter-relevant event emitted by a {@link Runner}. This array is drained when\n   * {@link ParallelBuffered#done} is called by {@link Runner#run}.\n   *\n   * Subclasses could override this behavior.\n   * @public\n   * @param {Runner} runner - Runner instance\n   * @returns {ParallelBuffered}\n   * @chainable\n   */\n  createListeners(runner) {\n    EVENT_NAMES.forEach((evt) => {\n      runner.on(evt, this.createListener(evt));\n    });\n    ONCE_EVENT_NAMES.forEach((evt) => {\n      runner.once(evt, this.createListener(evt));\n    });\n\n    runner.once(EVENT_RUN_END, () => {\n      debug(\"received EVENT_RUN_END\");\n      this.listeners.forEach((listener, evt) => {\n        runner.removeListener(evt, listener);\n        this.listeners.delete(evt);\n      });\n    });\n\n    return this;\n  }\n\n  /**\n   * Calls the {@link Mocha#run} callback (`callback`) with the test failure\n   * count and the array of {@link BufferedEvent} objects. Resets the array.\n   *\n   * This is called directly by `Runner#run` and should not be called by any other consumer.\n   *\n   * Subclasses could override this.\n   *\n   * @param {number} failures - Number of failed tests\n   * @param {Function} callback - The callback passed to {@link Mocha#run}.\n   * @public\n   */\n  done(failures, callback) {\n    callback(SerializableWorkerResult.create(this.events, failures));\n    this.events = []; // defensive\n  }\n}\n\nmodule.exports = ParallelBuffered;\n"
  },
  {
    "path": "lib/nodejs/serializer.js",
    "content": "/**\n * Serialization/deserialization classes and functions for communication between a main Mocha process and worker processes.\n * @module serializer\n * @private\n */\n\n\"use strict\";\n\n/**\n * @typedef {import('../types.d.ts').SerializedEvent} SerializedEvent\n * @typedef {import('../types.d.ts').SerializedWorkerResult} SerializedWorkerResult\n */\n\nconst { type, breakCircularDeps } = require(\"../utils\");\nconst { createInvalidArgumentTypeError } = require(\"../errors\");\n// this is not named `mocha:parallel:serializer` because it's noisy and it's\n// helpful to be able to write `DEBUG=mocha:parallel*` and get everything else.\nconst debug = require(\"debug\")(\"mocha:serializer\");\n\nconst SERIALIZABLE_RESULT_NAME = \"SerializableWorkerResult\";\nconst SERIALIZABLE_TYPES = new Set([\"object\", \"array\", \"function\", \"error\"]);\n\n/**\n * The serializable result of a test file run from a worker.\n * @private\n */\nclass SerializableWorkerResult {\n  /**\n   * Creates instance props; of note, the `__type` prop.\n   *\n   * Note that the failure count is _redundant_ and could be derived from the\n   * list of events; but since we're already doing the work, might as well use\n   * it.\n   * @param {SerializableEvent[]} [events=[]] - Events to eventually serialize\n   * @param {number} [failureCount=0] - Failure count\n   */\n  constructor(events = [], failureCount = 0) {\n    /**\n     * The number of failures in this run\n     * @type {number}\n     */\n    this.failureCount = failureCount;\n    /**\n     * All relevant events emitted from the {@link Runner}.\n     * @type {SerializableEvent[]}\n     */\n    this.events = events;\n\n    /**\n     * Symbol-like value needed to distinguish when attempting to deserialize\n     * this object (once it's been received over IPC).\n     * @type {Readonly<\"SerializableWorkerResult\">}\n     */\n    Object.defineProperty(this, \"__type\", {\n      value: SERIALIZABLE_RESULT_NAME,\n      enumerable: true,\n      writable: false,\n    });\n  }\n\n  /**\n   * Instantiates a new {@link SerializableWorkerResult}.\n   * @param {...any} args - Args to constructor\n   * @returns {SerializableWorkerResult}\n   */\n  static create(...args) {\n    return new SerializableWorkerResult(...args);\n  }\n\n  /**\n   * Serializes each {@link SerializableEvent} in our `events` prop;\n   * makes this object read-only.\n   * @returns {Readonly<SerializableWorkerResult>}\n   */\n  serialize() {\n    this.events.forEach((event) => {\n      event.serialize();\n    });\n    return Object.freeze(this);\n  }\n\n  /**\n   * Deserializes a {@link SerializedWorkerResult} into something reporters can\n   * use; calls {@link SerializableEvent.deserialize} on each item in its\n   * `events` prop.\n   * @param {SerializedWorkerResult} obj\n   * @returns {SerializedWorkerResult}\n   */\n  static deserialize(obj) {\n    obj.events.forEach((event) => {\n      SerializableEvent.deserialize(event);\n    });\n    return obj;\n  }\n\n  /**\n   * Returns `true` if this is a {@link SerializedWorkerResult} or a\n   * {@link SerializableWorkerResult}.\n   * @param {*} value - A value to check\n   * @returns {boolean} If true, it's deserializable\n   */\n  static isSerializedWorkerResult(value) {\n    return (\n      value instanceof SerializableWorkerResult ||\n      (type(value) === \"object\" && value.__type === SERIALIZABLE_RESULT_NAME)\n    );\n  }\n}\n\n/**\n * Represents an event, emitted by a {@link Runner}, which is to be transmitted\n * over IPC.\n *\n * Due to the contents of the event data, it's not possible to send them\n * verbatim. When received by the main process--and handled by reporters--these\n * objects are expected to contain {@link Runnable} instances.  This class\n * provides facilities to perform the translation via serialization and\n * deserialization.\n * @private\n */\nclass SerializableEvent {\n  /**\n   * Constructs a `SerializableEvent`, throwing if we receive unexpected data.\n   *\n   * Practically, events emitted from `Runner` have a minimum of zero (0)\n   * arguments-- (for example, {@link Runnable.constants.EVENT_RUN_BEGIN}) and a\n   * maximum of two (2) (for example,\n   * {@link Runnable.constants.EVENT_TEST_FAIL}, where the second argument is an\n   * `Error`).  The first argument, if present, is a {@link Runnable}. This\n   * constructor's arguments adhere to this convention.\n   * @param {string} eventName - A non-empty event name.\n   * @param {any} [originalValue] - Some data. Corresponds to extra arguments\n   * passed to `EventEmitter#emit`.\n   * @param {Error} [originalError] - An error, if there's an error.\n   * @throws If `eventName` is empty, or `originalValue` is a non-object.\n   */\n  constructor(eventName, originalValue, originalError) {\n    if (!eventName) {\n      throw createInvalidArgumentTypeError(\n        \"Empty `eventName` string argument\",\n        \"eventName\",\n        \"string\",\n      );\n    }\n    /**\n     * The event name.\n     * @memberof SerializableEvent\n     */\n    this.eventName = eventName;\n    const originalValueType = type(originalValue);\n    if (originalValueType !== \"object\" && originalValueType !== \"undefined\") {\n      throw createInvalidArgumentTypeError(\n        `Expected object but received ${originalValueType}`,\n        \"originalValue\",\n        \"object\",\n      );\n    }\n    /**\n     * An error, if present.\n     * @memberof SerializableEvent\n     */\n    Object.defineProperty(this, \"originalError\", {\n      value: originalError,\n      enumerable: false,\n    });\n\n    /**\n     * The raw value.\n     *\n     * We don't want this value sent via IPC; making it non-enumerable will do that.\n     *\n     * @memberof SerializableEvent\n     */\n    Object.defineProperty(this, \"originalValue\", {\n      value: originalValue,\n      enumerable: false,\n    });\n  }\n\n  /**\n   * In case you hated using `new` (I do).\n   *\n   * @param  {...any} args - Args for {@link SerializableEvent#constructor}.\n   * @returns {SerializableEvent} A new `SerializableEvent`\n   */\n  static create(...args) {\n    return new SerializableEvent(...args);\n  }\n\n  /**\n   * Used internally by {@link SerializableEvent#serialize}.\n   * @ignore\n   * @param {Array<object|string>} pairs - List of parent/key tuples to process; modified in-place. This JSDoc type is an approximation\n   * @param {object} parent - Some parent object\n   * @param {string} key - Key to inspect\n   */\n  static _serialize(pairs, parent, key) {\n    let value = parent[key];\n    let _type = type(value);\n    if (_type === \"error\") {\n      // we need to reference the stack prop b/c it's lazily-loaded.\n      // `__type` is necessary for deserialization to create an `Error` later.\n      // `message` is apparently not enumerable, so we must handle it specifically.\n      value = Object.assign(Object.create(null), value, {\n        stack: value.stack,\n        message: value.message,\n        __type: \"Error\",\n      });\n      parent[key] = value;\n      // after this, set the result of type(value) to be `object`, and we'll throw\n      // whatever other junk is in the original error into the new `value`.\n      _type = \"object\";\n    }\n    switch (_type) {\n      case \"object\":\n        if (type(value.serialize) === \"function\") {\n          parent[key] = value.serialize();\n        } else {\n          // by adding props to the `pairs` array, we will process it further\n          pairs.push(\n            ...Object.keys(value)\n              .filter((key) => SERIALIZABLE_TYPES.has(type(value[key])))\n              .map((key) => [value, key]),\n          );\n        }\n        break;\n      case \"function\":\n        // we _may_ want to dig in to functions for some assertion libraries\n        // that might put a usable property on a function.\n        // for now, just zap it.\n        delete parent[key];\n        break;\n      case \"array\":\n        pairs.push(\n          ...value\n            .filter((value) => SERIALIZABLE_TYPES.has(type(value)))\n            .map((value, index) => [value, index]),\n        );\n        break;\n    }\n  }\n\n  /**\n   * Modifies this object *in place* (for theoretical memory consumption &\n   * performance reasons); serializes `SerializableEvent#originalValue` (placing\n   * the result in `SerializableEvent#data`) and `SerializableEvent#error`.\n   * Freezes this object. The result is an object that can be transmitted over\n   * IPC.\n   * If this quickly becomes unmaintainable, we will want to move towards immutable\n   * objects post-haste.\n   */\n  serialize() {\n    // given a parent object and a key, inspect the value and decide whether\n    // to replace it, remove it, or add it to our `pairs` array to further process.\n    // this is recursion in loop form.\n    const originalValue = this.originalValue;\n    const result = Object.assign(Object.create(null), {\n      data:\n        type(originalValue) === \"object\" &&\n        type(originalValue.serialize) === \"function\"\n          ? originalValue.serialize()\n          : originalValue,\n      error: this.originalError,\n    });\n\n    // mutates the object\n    breakCircularDeps(result.error);\n\n    const pairs = Object.keys(result).map((key) => [result, key]);\n    const seenPairs = new Set();\n    let pair;\n\n    while ((pair = pairs.shift())) {\n      if (seenPairs.has(pair[1])) {\n        continue;\n      }\n\n      seenPairs.add(pair[1]);\n      SerializableEvent._serialize(pairs, ...pair);\n    }\n\n    this.data = result.data;\n    this.error = result.error;\n\n    return Object.freeze(this);\n  }\n\n  /**\n   * Used internally by {@link SerializableEvent.deserialize}; creates an `Error`\n   * from an `Error`-like (serialized) object\n   * @ignore\n   * @param {Object} value - An Error-like value\n   * @returns {Error} Real error\n   */\n  static _deserializeError(value) {\n    const error = new Error(value.message);\n    error.stack = value.stack;\n    Object.assign(error, value);\n    delete error.__type;\n    return error;\n  }\n\n  /**\n   * Used internally by {@link SerializableEvent.deserialize}; recursively\n   * deserializes an object in-place.\n   * @param {object|Array} parent - Some object or array\n   * @param {string|number} key - Some prop name or array index within `parent`\n   */\n  static _deserializeObject(parent, key) {\n    if (key === \"__proto__\") {\n      delete parent[key];\n      return;\n    }\n    const value = parent[key];\n    // keys beginning with `$$` are converted into functions returning the value\n    // and renamed, stripping the `$$` prefix.\n    // functions defined this way cannot be array members!\n    if (type(key) === \"string\" && key.startsWith(\"$$\")) {\n      const newKey = key.slice(2);\n      parent[newKey] = () => value;\n      delete parent[key];\n      key = newKey;\n    }\n    if (type(value) === \"array\") {\n      value.forEach((_, idx) => {\n        SerializableEvent._deserializeObject(value, idx);\n      });\n    } else if (type(value) === \"object\") {\n      if (value.__type === \"Error\") {\n        parent[key] = SerializableEvent._deserializeError(value);\n      } else {\n        Object.keys(value).forEach((key) => {\n          SerializableEvent._deserializeObject(value, key);\n        });\n      }\n    }\n  }\n\n  /**\n   * Deserialize value returned from a worker into something more useful.\n   * Does not return the same object.\n   * @todo do this in a loop instead of with recursion (if necessary)\n   * @param {SerializedEvent} obj - Object returned from worker\n   * @returns {SerializedEvent} Deserialized result\n   */\n  static deserialize(obj) {\n    if (!obj) {\n      throw createInvalidArgumentTypeError(\"Expected value\", obj);\n    }\n\n    obj = Object.assign(Object.create(null), obj);\n\n    if (obj.data) {\n      Object.keys(obj.data).forEach((key) => {\n        SerializableEvent._deserializeObject(obj.data, key);\n      });\n    }\n\n    if (obj.error) {\n      obj.error = SerializableEvent._deserializeError(obj.error);\n    }\n\n    return obj;\n  }\n}\n\n/**\n * \"Serializes\" a value for transmission over IPC as a message.\n *\n * If value is an object and has a `serialize()` method, call that method; otherwise return the object and hope for the best.\n *\n * @param {*} [value] - A value to serialize\n */\nexports.serialize = function serialize(value) {\n  const result =\n    type(value) === \"object\" && type(value.serialize) === \"function\"\n      ? value.serialize()\n      : value;\n  debug(\"serialized: %O\", result);\n  return result;\n};\n\n/**\n * \"Deserializes\" a \"message\" received over IPC.\n *\n * This could be expanded with other objects that need deserialization,\n * but at present time we only care about {@link SerializableWorkerResult} objects.\n *\n * @param {*} [value] - A \"message\" to deserialize\n */\nexports.deserialize = function deserialize(value) {\n  const result = SerializableWorkerResult.isSerializedWorkerResult(value)\n    ? SerializableWorkerResult.deserialize(value)\n    : value;\n  debug(\"deserialized: %O\", result);\n  return result;\n};\n\nexports.SerializableEvent = SerializableEvent;\nexports.SerializableWorkerResult = SerializableWorkerResult;\n"
  },
  {
    "path": "lib/nodejs/worker.js",
    "content": "/**\n * A worker process.  Consumes {@link module:reporters/parallel-buffered} reporter.\n * @module worker\n * @private\n */\n\n\"use strict\";\n\n/**\n * @typedef {import('../types.d.ts').BufferedEvent} BufferedEvent\n * @typedef {import('../types.d.ts').MochaOptions} MochaOptions\n */\n\nconst {\n  createInvalidArgumentTypeError,\n  createInvalidArgumentValueError,\n} = require(\"../errors\");\nconst workerpool = require(\"workerpool\");\nconst Mocha = require(\"../mocha\");\nconst { handleRequires, validateLegacyPlugin } = require(\"../cli/run-helpers\");\nconst d = require(\"debug\");\nconst debug = d.debug(`mocha:parallel:worker:${process.pid}`);\nconst isDebugEnabled = d.enabled(`mocha:parallel:worker:${process.pid}`);\nconst { serialize } = require(\"./serializer\");\nconst { setInterval, clearInterval } = global;\n\nlet rootHooks;\n\nif (workerpool.isMainThread) {\n  throw new Error(\n    \"This script is intended to be run as a worker (by the `workerpool` package).\",\n  );\n}\n\n/**\n * Initializes some stuff on the first call to {@link run}.\n *\n * Handles `--require` and `--ui`.  Does _not_ handle `--reporter`,\n * as only the `Buffered` reporter is used.\n *\n * **This function only runs once per worker**; it overwrites itself with a no-op\n * before returning.\n *\n * @param {MochaOptions} argv - Command-line options\n */\nlet bootstrap = async (argv) => {\n  // globalSetup and globalTeardown do not run in workers\n  const plugins = await handleRequires(argv.require, {\n    ignoredPlugins: [\"mochaGlobalSetup\", \"mochaGlobalTeardown\"],\n  });\n  validateLegacyPlugin(argv, \"ui\", Mocha.interfaces);\n\n  rootHooks = plugins.rootHooks;\n  bootstrap = () => {};\n  debug(\"bootstrap(): finished with args: %O\", argv);\n};\n\n/**\n * Runs a single test file in a worker thread.\n * @param {string} filepath - Filepath of test file\n * @param {string} [serializedOptions] - **Serialized** options. This string will be eval'd!\n * @see https://npm.im/serialize-javascript\n * @returns {Promise<{failures: number, events: BufferedEvent[]}>} - Test\n * failure count and list of events.\n */\nasync function run(filepath, serializedOptions = \"{}\") {\n  if (!filepath) {\n    throw createInvalidArgumentTypeError(\n      'Expected a non-empty \"filepath\" argument',\n      \"file\",\n      \"string\",\n    );\n  }\n\n  debug(\"run(): running test file %s\", filepath);\n\n  if (typeof serializedOptions !== \"string\") {\n    throw createInvalidArgumentTypeError(\n      \"run() expects second parameter to be a string which was serialized by the `serialize-javascript` module\",\n      \"serializedOptions\",\n      \"string\",\n    );\n  }\n  let argv;\n  try {\n    argv = eval(\"(\" + serializedOptions + \")\");\n  } catch {\n    throw createInvalidArgumentValueError(\n      \"run() was unable to deserialize the options\",\n      \"serializedOptions\",\n      serializedOptions,\n    );\n  }\n\n  const opts = Object.assign({ ui: \"bdd\" }, argv, {\n    // if this was true, it would cause infinite recursion.\n    parallel: false,\n    // this doesn't work in parallel mode\n    forbidOnly: true,\n    // it's useful for a Mocha instance to know if it's running in a worker process.\n    isWorker: true,\n  });\n\n  await bootstrap(opts);\n\n  opts.rootHooks = rootHooks;\n\n  const mocha = new Mocha(opts).addFile(filepath);\n\n  try {\n    await mocha.loadFilesAsync();\n  } catch (err) {\n    debug(\"run(): could not load file %s: %s\", filepath, err);\n    throw err;\n  }\n\n  return new Promise((resolve, reject) => {\n    let debugInterval;\n    /* istanbul ignore next */\n    if (isDebugEnabled) {\n      debugInterval = setInterval(() => {\n        debug(\"run(): still running %s...\", filepath);\n      }, 5000).unref();\n    }\n    mocha.run((result) => {\n      // Runner adds these; if we don't remove them, we'll get a leak.\n      process.removeAllListeners(\"uncaughtException\");\n      process.removeAllListeners(\"unhandledRejection\");\n\n      try {\n        const serialized = serialize(result);\n        debug(\n          \"run(): completed run with %d test failures; returning to main process\",\n          typeof result.failures === \"number\" ? result.failures : 0,\n        );\n        resolve(serialized);\n      } catch (err) {\n        // TODO: figure out exactly what the sad path looks like here.\n        // rejection should only happen if an error is \"unrecoverable\"\n        debug(\"run(): serialization failed; rejecting: %O\", err);\n        reject(err);\n      } finally {\n        clearInterval(debugInterval);\n      }\n    });\n  });\n}\n\n// this registers the `run` function.\nworkerpool.worker({ run });\n\ndebug(\"started worker process\");\n\n// for testing\nexports.run = run;\n"
  },
  {
    "path": "lib/pending.js",
    "content": "\"use strict\";\n\n/**\n @module Pending\n*/\n\n/**\n * Initialize a new `PendingError` error with the given message.\n *\n * @param {string} message\n */\nclass PendingError extends Error {\n  constructor(message) {\n    super(message);\n    this.name = \"PendingError\";\n  }\n}\n\nmodule.exports = PendingError;\n"
  },
  {
    "path": "lib/plugin-loader.js",
    "content": "/**\n * @typedef {import('./types.d.ts').PluginDefinition} PluginDefinition\n */\n\n/**\n * Provides a way to load \"plugins\" as provided by the user.\n *\n * Currently supports:\n *\n * - Root hooks\n * - Global fixtures (setup/teardown)\n * @private\n * @module plugin\n */\n\n\"use strict\";\n\nconst debug = require(\"debug\")(\"mocha:plugin-loader\");\nconst {\n  createInvalidPluginDefinitionError,\n  createInvalidPluginImplementationError,\n} = require(\"./errors\");\nconst { castArray } = require(\"./utils\");\n\n/**\n * @typedef {import('./types.d.ts').PluginLoaderOptions} PluginLoaderOptions\n */\n\n/**\n * Built-in plugin definitions.\n */\nconst MochaPlugins = [\n  /**\n   * Root hook plugin definition\n   * @type {PluginDefinition}\n   */\n  {\n    exportName: \"mochaHooks\",\n    optionName: \"rootHooks\",\n    validate(value) {\n      if (\n        Array.isArray(value) ||\n        (typeof value !== \"function\" && typeof value !== \"object\")\n      ) {\n        throw createInvalidPluginImplementationError(\n          `mochaHooks must be an object or a function returning (or fulfilling with) an object`,\n        );\n      }\n    },\n    async finalize(rootHooks) {\n      if (rootHooks.length) {\n        const rootHookObjects = await Promise.all(\n          rootHooks.map(async (hook) =>\n            typeof hook === \"function\" ? hook() : hook,\n          ),\n        );\n\n        return rootHookObjects.reduce(\n          (acc, hook) => {\n            hook = {\n              beforeAll: [],\n              beforeEach: [],\n              afterAll: [],\n              afterEach: [],\n              ...hook,\n            };\n            return {\n              beforeAll: [...acc.beforeAll, ...castArray(hook.beforeAll)],\n              beforeEach: [...acc.beforeEach, ...castArray(hook.beforeEach)],\n              afterAll: [...acc.afterAll, ...castArray(hook.afterAll)],\n              afterEach: [...acc.afterEach, ...castArray(hook.afterEach)],\n            };\n          },\n          { beforeAll: [], beforeEach: [], afterAll: [], afterEach: [] },\n        );\n      }\n    },\n  },\n  /**\n   * Global setup fixture plugin definition\n   * @type {PluginDefinition}\n   */\n  {\n    exportName: \"mochaGlobalSetup\",\n    optionName: \"globalSetup\",\n    validate(value) {\n      let isValid = true;\n      if (Array.isArray(value)) {\n        if (value.some((item) => typeof item !== \"function\")) {\n          isValid = false;\n        }\n      } else if (typeof value !== \"function\") {\n        isValid = false;\n      }\n      if (!isValid) {\n        throw createInvalidPluginImplementationError(\n          `mochaGlobalSetup must be a function or an array of functions`,\n          { pluginDef: this, pluginImpl: value },\n        );\n      }\n    },\n  },\n  /**\n   * Global teardown fixture plugin definition\n   * @type {PluginDefinition}\n   */\n  {\n    exportName: \"mochaGlobalTeardown\",\n    optionName: \"globalTeardown\",\n    validate(value) {\n      let isValid = true;\n      if (Array.isArray(value)) {\n        if (value.some((item) => typeof item !== \"function\")) {\n          isValid = false;\n        }\n      } else if (typeof value !== \"function\") {\n        isValid = false;\n      }\n      if (!isValid) {\n        throw createInvalidPluginImplementationError(\n          `mochaGlobalTeardown must be a function or an array of functions`,\n          { pluginDef: this, pluginImpl: value },\n        );\n      }\n    },\n  },\n];\n\n/**\n * Contains a registry of [plugin definitions]{@link PluginDefinition} and discovers plugin implementations in user-supplied code.\n *\n * - [load()]{@link #load} should be called for all required modules\n * - The result of [finalize()]{@link #finalize} should be merged into the options for the [Mocha]{@link Mocha} constructor.\n * @private\n */\nclass PluginLoader {\n  /**\n   * Initializes plugin names, plugin map, etc.\n   * @param {PluginLoaderOptions} [opts] - Options\n   */\n  constructor({ pluginDefs = MochaPlugins, ignore = [] } = {}) {\n    /**\n     * Map of registered plugin defs\n     * @type {Map<string,PluginDefinition>}\n     */\n    this.registered = new Map();\n\n    /**\n     * Cache of known `optionName` values for checking conflicts\n     * @type {Set<string>}\n     */\n    this.knownOptionNames = new Set();\n\n    /**\n     * Cache of known `exportName` values for checking conflicts\n     * @type {Set<string>}\n     */\n    this.knownExportNames = new Set();\n\n    /**\n     * Map of user-supplied plugin implementations\n     * @type {Map<string,Array<*>>}\n     */\n    this.loaded = new Map();\n\n    /**\n     * Set of ignored plugins by export name\n     * @type {Set<string>}\n     */\n    this.ignoredExportNames = new Set(castArray(ignore));\n\n    castArray(pluginDefs).forEach((pluginDef) => {\n      this.register(pluginDef);\n    });\n\n    debug(\n      \"registered %d plugin defs (%d ignored)\",\n      this.registered.size,\n      this.ignoredExportNames.size,\n    );\n  }\n\n  /**\n   * Register a plugin\n   * @param {PluginDefinition} pluginDef - Plugin definition\n   */\n  register(pluginDef) {\n    if (!pluginDef || typeof pluginDef !== \"object\") {\n      throw createInvalidPluginDefinitionError(\n        \"pluginDef is non-object or falsy\",\n        pluginDef,\n      );\n    }\n    if (!pluginDef.exportName) {\n      throw createInvalidPluginDefinitionError(\n        `exportName is expected to be a non-empty string`,\n        pluginDef,\n      );\n    }\n    let { exportName } = pluginDef;\n    if (this.ignoredExportNames.has(exportName)) {\n      debug(\n        'refusing to register ignored plugin with export name \"%s\"',\n        exportName,\n      );\n      return;\n    }\n    exportName = String(exportName);\n    pluginDef.optionName = String(pluginDef.optionName || exportName);\n    if (this.knownExportNames.has(exportName)) {\n      throw createInvalidPluginDefinitionError(\n        `Plugin definition conflict: ${exportName}; exportName must be unique`,\n        pluginDef,\n      );\n    }\n    this.loaded.set(exportName, []);\n    this.registered.set(exportName, pluginDef);\n    this.knownExportNames.add(exportName);\n    this.knownOptionNames.add(pluginDef.optionName);\n    debug('registered plugin def \"%s\"', exportName);\n  }\n\n  /**\n   * Inspects a module's exports for known plugins and keeps them in memory.\n   *\n   * @param {*} requiredModule - The exports of a module loaded via `--require`\n   * @returns {boolean} If one or more plugins was found, return `true`.\n   */\n  load(requiredModule) {\n    // we should explicitly NOT fail if other stuff is exported.\n    // we only care about the plugins we know about.\n    if (requiredModule && typeof requiredModule === \"object\") {\n      return Array.from(this.knownExportNames).reduce(\n        (pluginImplFound, pluginName) => {\n          const pluginImpl = requiredModule[pluginName];\n          if (pluginImpl) {\n            const plugin = this.registered.get(pluginName);\n            if (typeof plugin.validate === \"function\") {\n              plugin.validate(pluginImpl);\n            }\n            this.loaded.set(pluginName, [\n              ...this.loaded.get(pluginName),\n              ...castArray(pluginImpl),\n            ]);\n            return true;\n          }\n          return pluginImplFound;\n        },\n        false,\n      );\n    }\n    return false;\n  }\n\n  /**\n   * Call the `finalize()` function of each known plugin definition on the plugins found by [load()]{@link PluginLoader#load}.\n   *\n   * Output suitable for passing as input into {@link Mocha} constructor.\n   * @returns {Promise<object>} Object having keys corresponding to registered plugin definitions' `optionName` prop (or `exportName`, if none), and the values are the implementations as provided by a user.\n   */\n  async finalize() {\n    const finalizedPlugins = Object.create(null);\n\n    for await (const [exportName, pluginImpls] of this.loaded.entries()) {\n      if (pluginImpls.length) {\n        const plugin = this.registered.get(exportName);\n        finalizedPlugins[plugin.optionName] =\n          typeof plugin.finalize === \"function\"\n            ? await plugin.finalize(pluginImpls)\n            : pluginImpls;\n      }\n    }\n\n    debug(\"finalized plugins: %O\", finalizedPlugins);\n    return finalizedPlugins;\n  }\n\n  /**\n   * Constructs a {@link PluginLoader}\n   * @param {PluginLoaderOptions} [opts] - Plugin loader options\n   */\n  static create({ pluginDefs = MochaPlugins, ignore = [] } = {}) {\n    return new PluginLoader({ pluginDefs, ignore });\n  }\n}\n\nmodule.exports = PluginLoader;\n"
  },
  {
    "path": "lib/reporters/base.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../runner.js')} Runner\n * @typedef {import('../test.js')} Test\n * @typedef {import('../types.d.ts').FullErrorStack} FullErrorStack\n */\n\n/**\n * @module Base\n */\n/**\n * Module dependencies.\n */\n\nvar diff = require(\"diff\");\nvar milliseconds = require(\"ms\");\nvar utils = require(\"../utils\");\nvar supportsColor = require(\"supports-color\");\nvar constants = require(\"../runner\").constants;\nvar EVENT_TEST_PASS = constants.EVENT_TEST_PASS;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\n\nconst isBrowser = utils.isBrowser();\n\nfunction getBrowserWindowSize() {\n  if (\"innerHeight\" in global) {\n    return [global.innerHeight, global.innerWidth];\n  }\n  // In a Web Worker, the DOM Window is not available.\n  return [640, 480];\n}\n\n/**\n * Check if both stdio streams are associated with a tty.\n */\n\nvar isatty = isBrowser || (process.stdout.isTTY && process.stderr.isTTY);\n\n/**\n * Save log references to avoid tests interfering (see GH-3604).\n */\nvar consoleLog = console.log;\n\n/**\n * @abstract\n * @description\n * All other reporters generally inherit from this reporter.\n */\nclass Base {\n  /**\n   * Constructs a new `Base` reporter instance.\n   *\n   * @public\n   * @memberof Mocha.reporters\n   * @param {Runner} runner - Instance triggers reporter actions.\n   * @param {Object} [options] - runner options\n   */\n  constructor(runner, options) {\n    var failures = (this.failures = []);\n\n    if (!runner) {\n      throw new TypeError(\"Missing runner argument\");\n    }\n    this.options = options || {};\n    this.runner = runner;\n    this.stats = runner.stats; // assigned so Reporters keep a closer reference\n\n    var maxDiffSizeOpt =\n      this.options.reporterOption && this.options.reporterOption.maxDiffSize;\n    if (maxDiffSizeOpt !== undefined && !isNaN(Number(maxDiffSizeOpt))) {\n      exports.maxDiffSize = Number(maxDiffSizeOpt);\n    }\n\n    runner.on(EVENT_TEST_PASS, function (test) {\n      if (test.duration > test.slow()) {\n        test.speed = \"slow\";\n      } else if (test.duration > test.slow() / 2) {\n        test.speed = \"medium\";\n      } else {\n        test.speed = \"fast\";\n      }\n    });\n\n    runner.on(EVENT_TEST_FAIL, function (test, err) {\n      if (showDiff(err)) {\n        stringifyDiffObjs(err);\n      }\n      // more than one error per test\n      if (test.err && err instanceof Error) {\n        test.err.multiple = (test.err.multiple || []).concat(err);\n      } else {\n        test.err = err;\n      }\n      failures.push(test);\n    });\n  }\n\n  /**\n   * Outputs common epilogue used by many of the bundled reporters.\n   *\n   * @public\n   * @memberof Mocha.reporters\n   */\n  epilogue() {\n    var stats = this.stats;\n    var fmt;\n\n    Base.consoleLog();\n\n    // passes\n    fmt =\n      color(\"bright pass\", \" \") +\n      color(\"green\", \" %d passing\") +\n      color(\"light\", \" (%s)\");\n\n    Base.consoleLog(fmt, stats.passes || 0, milliseconds(stats.duration));\n\n    // pending\n    if (stats.pending) {\n      fmt = color(\"pending\", \" \") + color(\"pending\", \" %d pending\");\n\n      Base.consoleLog(fmt, stats.pending);\n    }\n\n    // failures\n    if (stats.failures) {\n      fmt = color(\"fail\", \"  %d failing\");\n\n      Base.consoleLog(fmt, stats.failures);\n\n      Base.list(this.failures);\n      Base.consoleLog();\n    }\n\n    Base.consoleLog();\n  }\n}\n\nBase.consoleLog = consoleLog;\n\nBase.abstract = true;\n\nexports = module.exports = Base;\n\n/**\n * Enable coloring by default, except in the browser interface.\n */\nexports.useColors =\n  !isBrowser &&\n  (supportsColor.stdout || process.env.MOCHA_COLORS !== undefined);\n\n/**\n * Inline diffs instead of +/-\n */\n\nexports.inlineDiffs = false;\n\n/**\n * Truncate diffs longer than this value to avoid slow performance\n */\nexports.maxDiffSize = 8192;\n\n/**\n * Default color map.\n */\n\nexports.colors = {\n  pass: 90,\n  fail: 31,\n  \"bright pass\": 92,\n  \"bright fail\": 91,\n  \"bright yellow\": 93,\n  pending: 36,\n  suite: 0,\n  \"error title\": 0,\n  \"error message\": 31,\n  \"error stack\": 90,\n  checkmark: 32,\n  fast: 90,\n  medium: 33,\n  slow: 31,\n  green: 32,\n  light: 90,\n  \"diff gutter\": 90,\n  \"diff added\": 32,\n  \"diff removed\": 31,\n  \"diff added inline\": \"30;42\",\n  \"diff removed inline\": \"30;41\",\n};\n\n/**\n * Default symbol map.\n */\n\nexports.symbols = {\n  ok: utils.logSymbols.success,\n  err: utils.logSymbols.error,\n  dot: \".\",\n  comma: \",\",\n  bang: \"!\",\n};\n\n/**\n * Color `str` with the given `type`,\n * allowing colors to be disabled,\n * as well as user-defined color\n * schemes.\n *\n * @private\n * @param {string} type\n * @param {string} str\n * @return {string}\n */\nvar color = (exports.color = function (type, str) {\n  if (!exports.useColors) {\n    return String(str);\n  }\n  return \"\\u001b[\" + exports.colors[type] + \"m\" + str + \"\\u001b[0m\";\n});\n\n/**\n * Expose term window size, with some defaults for when stderr is not a tty.\n */\n\nexports.window = {\n  width: 75,\n};\n\nif (isatty) {\n  if (isBrowser) {\n    exports.window.width = getBrowserWindowSize()[1];\n  } else {\n    exports.window.width = process.stdout.getWindowSize(1)[0];\n  }\n}\n\n/**\n * Expose some basic cursor interactions that are common among reporters.\n */\n\nexports.cursor = {\n  hide: function () {\n    isatty && process.stdout.write(\"\\u001b[?25l\");\n  },\n\n  show: function () {\n    isatty && process.stdout.write(\"\\u001b[?25h\");\n  },\n\n  deleteLine: function () {\n    isatty && process.stdout.write(\"\\u001b[2K\");\n  },\n\n  beginningOfLine: function () {\n    isatty && process.stdout.write(\"\\u001b[0G\");\n  },\n\n  CR: function () {\n    if (isatty) {\n      exports.cursor.deleteLine();\n      exports.cursor.beginningOfLine();\n    } else {\n      process.stdout.write(\"\\r\");\n    }\n  },\n};\n\nvar showDiff = (exports.showDiff = function (err) {\n  return (\n    err &&\n    err.showDiff !== false &&\n    sameType(err.actual, err.expected) &&\n    err.expected !== undefined\n  );\n});\n\nfunction stringifyDiffObjs(err) {\n  if (!utils.isString(err.actual) || !utils.isString(err.expected)) {\n    err.actual = utils.stringify(err.actual);\n    err.expected = utils.stringify(err.expected);\n  }\n}\n\n/**\n * Returns a diff between 2 strings with coloured ANSI output.\n *\n * @description\n * The diff will be either inline or unified dependent on the value\n * of `Base.inlineDiff`.\n *\n * @param {string} actual\n * @param {string} expected\n * @return {string} Diff\n */\n\nvar generateDiff = (exports.generateDiff = function (actual, expected) {\n  try {\n    var maxLen = exports.maxDiffSize;\n    var skipped = 0;\n    if (maxLen > 0) {\n      skipped = Math.max(actual.length - maxLen, expected.length - maxLen);\n      actual = actual.slice(0, maxLen);\n      expected = expected.slice(0, maxLen);\n    }\n    let result = exports.inlineDiffs\n      ? inlineDiff(actual, expected)\n      : unifiedDiff(actual, expected);\n    if (skipped > 0) {\n      result = `${result}\\n      [mocha] output truncated to ${maxLen} characters, see \"maxDiffSize\" reporter-option\\n`;\n    }\n    return result;\n  } catch {\n    var msg =\n      \"\\n      \" +\n      color(\"diff added\", \"+ expected\") +\n      \" \" +\n      color(\"diff removed\", \"- actual:  failed to generate Mocha diff\") +\n      \"\\n\";\n    return msg;\n  }\n});\n\n/**\n * Traverses err.cause and returns all stack traces\n *\n * @private\n * @param {Error} err\n * @param {Set<Error>} [seen]\n * @return {FullErrorStack}\n */\nvar getFullErrorStack = function (err, seen) {\n  if (seen && seen.has(err)) {\n    return { message: \"\", msg: \"<circular>\", stack: \"\" };\n  }\n\n  var message;\n\n  if (typeof err.inspect === \"function\") {\n    message = err.inspect() + \"\";\n  } else if (err.message && typeof err.message.toString === \"function\") {\n    message = err.message + \"\";\n  } else {\n    message = \"\";\n  }\n\n  var msg;\n  var stack = err.stack || message;\n  var index = message ? stack.indexOf(message) : -1;\n\n  if (index === -1) {\n    msg = message;\n  } else {\n    index += message.length;\n    msg = stack.slice(0, index);\n    // remove msg from stack\n    stack = stack.slice(index + 1);\n\n    if (err.cause) {\n      seen = seen || new Set();\n      seen.add(err);\n      const causeStack = getFullErrorStack(err.cause, seen);\n      stack +=\n        \"\\n   Caused by: \" +\n        causeStack.msg +\n        (causeStack.stack ? \"\\n\" + causeStack.stack : \"\");\n    }\n  }\n\n  return {\n    message,\n    msg,\n    stack,\n  };\n};\n\n/**\n * Outputs the given `failures` as a list.\n *\n * @public\n * @memberof Mocha.reporters.Base\n * @variation 1\n * @param {Object[]} failures - Each is Test instance with corresponding\n *     Error property\n */\nexports.list = function (failures) {\n  var multipleErr, multipleTest;\n  Base.consoleLog();\n  failures.forEach(function (test, i) {\n    // format\n    var fmt =\n      color(\"error title\", \"  %s) %s:\\n\") +\n      color(\"error message\", \"     %s\") +\n      color(\"error stack\", \"\\n%s\\n\");\n\n    // msg\n    var err;\n    if (test.err && test.err.multiple) {\n      if (multipleTest !== test) {\n        multipleTest = test;\n        multipleErr = [test.err].concat(test.err.multiple);\n      }\n      err = multipleErr.shift();\n    } else {\n      err = test.err;\n    }\n\n    var { message, msg, stack } = getFullErrorStack(err);\n\n    // uncaught\n    if (err.uncaught) {\n      msg = \"Uncaught \" + msg;\n    }\n    // explicitly show diff\n    if (!exports.hideDiff && showDiff(err)) {\n      stringifyDiffObjs(err);\n      fmt =\n        color(\"error title\", \"  %s) %s:\\n%s\") + color(\"error stack\", \"\\n%s\\n\");\n      var match = message.match(/^([^:]+): expected/);\n      msg = \"\\n      \" + color(\"error message\", match ? match[1] : msg);\n\n      msg += generateDiff(err.actual, err.expected);\n    }\n\n    // indent stack trace\n    stack = stack.replace(/^/gm, \"  \");\n\n    // indented test title\n    var testTitle = \"\";\n    test.titlePath().forEach(function (str, index) {\n      if (index !== 0) {\n        testTitle += \"\\n     \";\n      }\n      for (var i = 0; i < index; i++) {\n        testTitle += \"  \";\n      }\n      testTitle += str;\n    });\n\n    Base.consoleLog(fmt, i + 1, testTitle, msg, stack);\n  });\n};\n\n/**\n * Pads the given `str` to `len`.\n *\n * @private\n * @param {string} str\n * @param {string} len\n * @return {string}\n */\nfunction pad(str, len) {\n  str = String(str);\n  return Array(len - str.length + 1).join(\" \") + str;\n}\n\n/**\n * Returns inline diff between 2 strings with coloured ANSI output.\n *\n * @private\n * @param {String} actual\n * @param {String} expected\n * @return {string} Diff\n */\nfunction inlineDiff(actual, expected) {\n  var msg = errorDiff(actual, expected);\n\n  // linenos\n  var lines = msg.split(\"\\n\");\n  if (lines.length > 4) {\n    var width = String(lines.length).length;\n    msg = lines\n      .map(function (str, i) {\n        return pad(i + 1, width) + \" |\" + \" \" + str;\n      })\n      .join(\"\\n\");\n  }\n\n  // legend\n  msg =\n    \"\\n\" +\n    color(\"diff removed inline\", \"actual\") +\n    \" \" +\n    color(\"diff added inline\", \"expected\") +\n    \"\\n\\n\" +\n    msg +\n    \"\\n\";\n\n  // indent\n  msg = msg.replace(/^/gm, \"      \");\n  return msg;\n}\n\n/**\n * Returns unified diff between two strings with coloured ANSI output.\n *\n * @private\n * @param {String} actual\n * @param {String} expected\n * @return {string} The diff.\n */\nfunction unifiedDiff(actual, expected) {\n  var indent = \"      \";\n  function cleanUp(line) {\n    if (line[0] === \"+\") {\n      return indent + colorLines(\"diff added\", line);\n    }\n    if (line[0] === \"-\") {\n      return indent + colorLines(\"diff removed\", line);\n    }\n    if (line.match(/@@/)) {\n      return \"--\";\n    }\n    if (line.match(/\\\\ No newline/)) {\n      return null;\n    }\n    return indent + line;\n  }\n  function notBlank(line) {\n    return typeof line !== \"undefined\" && line !== null;\n  }\n  var msg = diff.createPatch(\"string\", actual, expected);\n  var lines = msg.split(\"\\n\").splice(5);\n  return (\n    \"\\n      \" +\n    colorLines(\"diff added\", \"+ expected\") +\n    \" \" +\n    colorLines(\"diff removed\", \"- actual\") +\n    \"\\n\\n\" +\n    lines.map(cleanUp).filter(notBlank).join(\"\\n\")\n  );\n}\n\n/**\n * Returns character diff for `err`.\n *\n * @private\n * @param {String} actual\n * @param {String} expected\n * @return {string} the diff\n */\nfunction errorDiff(actual, expected) {\n  return diff\n    .diffWordsWithSpace(actual, expected)\n    .map(function (str) {\n      if (str.added) {\n        return colorLines(\"diff added inline\", str.value);\n      }\n      if (str.removed) {\n        return colorLines(\"diff removed inline\", str.value);\n      }\n      return str.value;\n    })\n    .join(\"\");\n}\n\n/**\n * Colors lines for `str`, using the color `name`.\n *\n * @private\n * @param {string} name\n * @param {string} str\n * @return {string}\n */\nfunction colorLines(name, str) {\n  return str\n    .split(\"\\n\")\n    .map(function (str) {\n      return color(name, str);\n    })\n    .join(\"\\n\");\n}\n\n/**\n * Object#toString reference.\n */\nvar objToString = Object.prototype.toString;\n\n/**\n * Checks that a / b have the same type.\n *\n * @private\n * @param {Object} a\n * @param {Object} b\n * @return {boolean}\n */\nfunction sameType(a, b) {\n  return objToString.call(a) === objToString.call(b);\n}\n"
  },
  {
    "path": "lib/reporters/doc.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../runner.js')} Runner\n */\n\n/**\n * @module Doc\n */\n/**\n * Module dependencies.\n */\n\nvar Base = require(\"./base\");\nvar utils = require(\"../utils\");\nvar constants = require(\"../runner\").constants;\nvar EVENT_TEST_PASS = constants.EVENT_TEST_PASS;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\nvar EVENT_SUITE_BEGIN = constants.EVENT_SUITE_BEGIN;\nvar EVENT_SUITE_END = constants.EVENT_SUITE_END;\n\nclass Doc extends Base {\n  static description = \"HTML documentation\";\n\n  /**\n   * Constructs a new `Doc` reporter instance.\n   *\n   * @public\n   * @memberof Mocha.reporters\n   * @extends Mocha.reporters.Base\n   * @param {Runner} runner - Instance triggers reporter actions.\n   * @param {Object} [options] - runner options\n   */\n  constructor(runner, options) {\n    super(runner, options);\n\n    var indents = 2;\n\n    function indent() {\n      return Array(indents).join(\"  \");\n    }\n\n    runner.on(EVENT_SUITE_BEGIN, function (suite) {\n      if (suite.root) {\n        return;\n      }\n      ++indents;\n      Base.consoleLog('%s<section class=\"suite\">', indent());\n      ++indents;\n      Base.consoleLog(\"%s<h1>%s</h1>\", indent(), utils.escape(suite.title));\n      Base.consoleLog(\"%s<dl>\", indent());\n    });\n\n    runner.on(EVENT_SUITE_END, function (suite) {\n      if (suite.root) {\n        return;\n      }\n      Base.consoleLog(\"%s</dl>\", indent());\n      --indents;\n      Base.consoleLog(\"%s</section>\", indent());\n      --indents;\n    });\n\n    runner.on(EVENT_TEST_PASS, function (test) {\n      Base.consoleLog(\"%s  <dt>%s</dt>\", indent(), utils.escape(test.title));\n      Base.consoleLog(\"%s  <dt>%s</dt>\", indent(), utils.escape(test.file));\n      var code = utils.escape(utils.clean(test.body));\n      Base.consoleLog(\n        \"%s  <dd><pre><code>%s</code></pre></dd>\",\n        indent(),\n        code,\n      );\n    });\n\n    runner.on(EVENT_TEST_FAIL, function (test, err) {\n      Base.consoleLog(\n        '%s  <dt class=\"error\">%s</dt>',\n        indent(),\n        utils.escape(test.title),\n      );\n      Base.consoleLog(\n        '%s  <dt class=\"error\">%s</dt>',\n        indent(),\n        utils.escape(test.file),\n      );\n      var code = utils.escape(utils.clean(test.body));\n      Base.consoleLog(\n        '%s  <dd class=\"error\"><pre><code>%s</code></pre></dd>',\n        indent(),\n        code,\n      );\n      Base.consoleLog(\n        '%s  <dd class=\"error\">%s</dd>',\n        indent(),\n        utils.escape(err),\n      );\n    });\n  }\n}\n\nexports = module.exports = Doc;\n"
  },
  {
    "path": "lib/reporters/dot.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../runner.js')} Runner\n */\n\n/**\n * @module Dot\n */\n/**\n * Module dependencies.\n */\n\nvar Base = require(\"./base\");\nvar constants = require(\"../runner\").constants;\nvar EVENT_TEST_PASS = constants.EVENT_TEST_PASS;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\nvar EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN;\nvar EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\n\nclass Dot extends Base {\n  static description = \"dot matrix representation\";\n\n  /**\n   * Constructs a new `Dot` reporter instance.\n   *\n   * @public\n   * @memberof Mocha.reporters\n   * @extends Mocha.reporters.Base\n   * @param {Runner} runner - Instance triggers reporter actions.\n   * @param {Object} [options] - runner options\n   */\n  constructor(runner, options) {\n    super(runner, options);\n\n    var self = this;\n    var width = (Base.window.width * 0.75) | 0;\n    var n = -1;\n\n    runner.on(EVENT_RUN_BEGIN, function () {\n      process.stdout.write(\"\\n\");\n    });\n\n    runner.on(EVENT_TEST_PENDING, function () {\n      if (++n % width === 0) {\n        process.stdout.write(\"\\n  \");\n      }\n      process.stdout.write(Base.color(\"pending\", Base.symbols.comma));\n    });\n\n    runner.on(EVENT_TEST_PASS, function (test) {\n      if (++n % width === 0) {\n        process.stdout.write(\"\\n  \");\n      }\n      if (test.speed === \"slow\") {\n        process.stdout.write(Base.color(\"bright yellow\", Base.symbols.dot));\n      } else {\n        process.stdout.write(Base.color(test.speed, Base.symbols.dot));\n      }\n    });\n\n    runner.on(EVENT_TEST_FAIL, function () {\n      if (++n % width === 0) {\n        process.stdout.write(\"\\n  \");\n      }\n      process.stdout.write(Base.color(\"fail\", Base.symbols.bang));\n    });\n\n    runner.once(EVENT_RUN_END, function () {\n      process.stdout.write(\"\\n\");\n      self.epilogue();\n    });\n  }\n}\n\nexports = module.exports = Dot;\n"
  },
  {
    "path": "lib/reporters/html.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../runner.js')} Runner\n */\n\n/**\n * @module HTML\n */\n/**\n * Module dependencies.\n */\n\nvar Base = require(\"./base\");\nvar utils = require(\"../utils\");\nvar escapeRe = require(\"escape-string-regexp\");\nvar constants = require(\"../runner\").constants;\nvar EVENT_TEST_PASS = constants.EVENT_TEST_PASS;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\nvar EVENT_SUITE_BEGIN = constants.EVENT_SUITE_BEGIN;\nvar EVENT_SUITE_END = constants.EVENT_SUITE_END;\nvar EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING;\nvar escape = utils.escape;\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\n\nvar Date = global.Date;\n\n/**\n * Stats template: Result, progress, passes, failures, and duration.\n */\n\nvar statsTemplate =\n  '<ul id=\"mocha-stats\">' +\n  '<li class=\"result\"></li>' +\n  '<li class=\"progress-contain\"><progress class=\"progress-element\" max=\"100\" value=\"0\"></progress><svg class=\"progress-ring\"><circle class=\"ring-flatlight\" stroke-dasharray=\"100%,0%\"/><circle class=\"ring-highlight\" stroke-dasharray=\"0%,100%\"/></svg><div class=\"progress-text\">0%</div></li>' +\n  '<li class=\"passes\"><a href=\"javascript:void(0);\">passes:</a> <em>0</em></li>' +\n  '<li class=\"failures\"><a href=\"javascript:void(0);\">failures:</a> <em>0</em></li>' +\n  '<li class=\"duration\">duration: <em>0</em>s</li>' +\n  \"</ul>\";\n\nvar playIcon = \"&#x2023;\";\n\nclass HTML extends Base {\n  static browserOnly = true;\n\n  /**\n   * Constructs a new `HTML` reporter instance.\n   *\n   * @public\n   * @memberof Mocha.reporters\n   * @extends Mocha.reporters.Base\n   * @param {Runner} runner - Instance triggers reporter actions.\n   * @param {Object} [options] - runner options\n   */\n  constructor(runner, options) {\n    super(runner, options);\n\n    var self = this;\n    var stats = this.stats;\n    var stat = fragment(statsTemplate);\n    var items = stat.getElementsByTagName(\"li\");\n    const resultIndex = 0;\n    const progressIndex = 1;\n    const passesIndex = 2;\n    const failuresIndex = 3;\n    const durationIndex = 4;\n    /** Stat item containing the root suite pass or fail indicator (hasFailures ? '✖' : '✓') */\n    var resultIndicator = items[resultIndex];\n    /** Passes text and count */\n    const passesStat = items[passesIndex];\n    /** Stat item containing the pass count (not the word, just the number) */\n    const passesCount = passesStat.getElementsByTagName(\"em\")[0];\n    /** Stat item linking to filter to show only passing tests */\n    const passesLink = passesStat.getElementsByTagName(\"a\")[0];\n    /** Failures text and count */\n    const failuresStat = items[failuresIndex];\n    /** Stat item containing the failure count (not the word, just the number) */\n    const failuresCount = failuresStat.getElementsByTagName(\"em\")[0];\n    /** Stat item linking to filter to show only failing tests */\n    const failuresLink = failuresStat.getElementsByTagName(\"a\")[0];\n    /** Stat item linking to the duration time (not the word or unit, just the number) */\n    var duration = items[durationIndex].getElementsByTagName(\"em\")[0];\n    var report = fragment('<ul id=\"mocha-report\"></ul>');\n    var stack = [report];\n    var progressText = items[progressIndex].getElementsByTagName(\"div\")[0];\n    var progressBar = items[progressIndex].getElementsByTagName(\"progress\")[0];\n    var progressRing = [\n      items[progressIndex].getElementsByClassName(\"ring-flatlight\")[0],\n      items[progressIndex].getElementsByClassName(\"ring-highlight\")[0],\n    ];\n    var root = document.getElementById(\"mocha\");\n\n    if (!root) {\n      return error(\"#mocha div missing, add it to your document\");\n    }\n\n    // pass toggle\n    on(passesLink, \"click\", function (evt) {\n      evt.preventDefault();\n      unhide();\n      var name = /pass/.test(report.className) ? \"\" : \" pass\";\n      report.className = report.className.replace(/fail|pass/g, \"\") + name;\n      if (report.className.trim()) {\n        hideSuitesWithout(\"test pass\");\n      }\n    });\n\n    // failure toggle\n    on(failuresLink, \"click\", function (evt) {\n      evt.preventDefault();\n      unhide();\n      var name = /fail/.test(report.className) ? \"\" : \" fail\";\n      report.className = report.className.replace(/fail|pass/g, \"\") + name;\n      if (report.className.trim()) {\n        hideSuitesWithout(\"test fail\");\n      }\n    });\n\n    root.appendChild(stat);\n    root.appendChild(report);\n\n    runner.on(EVENT_SUITE_BEGIN, function (suite) {\n      if (suite.root) {\n        return;\n      }\n\n      // suite\n      var url = self.suiteURL(suite);\n      var el = fragment(\n        '<li class=\"suite\"><h1><a href=\"%s\">%s</a></h1></li>',\n        url,\n        escape(suite.title),\n      );\n\n      // container\n      stack[0].appendChild(el);\n      stack.unshift(document.createElement(\"ul\"));\n      el.appendChild(stack[0]);\n    });\n\n    runner.on(EVENT_SUITE_END, function (suite) {\n      if (suite.root) {\n        if (stats.failures === 0) {\n          text(resultIndicator, \"✓\");\n          stat.className += \" pass\";\n        }\n        updateStats();\n        return;\n      }\n      stack.shift();\n    });\n\n    runner.on(EVENT_TEST_PASS, function (test) {\n      var url = self.testURL(test);\n      var markup =\n        '<li class=\"test pass %e\"><h2>%e<span class=\"duration\">%ems</span> ' +\n        '<a href=\"%s\" class=\"replay\">' +\n        playIcon +\n        \"</a></h2></li>\";\n      var el = fragment(markup, test.speed, test.title, test.duration, url);\n      self.addCodeToggle(el, test.body);\n      appendToStack(el);\n      updateStats();\n    });\n\n    runner.on(EVENT_TEST_FAIL, function (test) {\n      // Update stat items\n      text(resultIndicator, \"✖\");\n      stat.className += \" fail\";\n\n      var el = fragment(\n        '<li class=\"test fail\"><h2>%e <a href=\"%e\" class=\"replay\">' +\n          playIcon +\n          \"</a></h2></li>\",\n        test.title,\n        self.testURL(test),\n      );\n      var stackString; // Note: Includes leading newline\n      var message = test.err.toString();\n\n      // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we\n      // check for the result of the stringifying.\n      if (message === \"[object Error]\") {\n        message = test.err.message;\n      }\n\n      if (test.err.stack) {\n        var indexOfMessage = test.err.stack.indexOf(test.err.message);\n        if (indexOfMessage === -1) {\n          stackString = test.err.stack;\n        } else {\n          stackString = test.err.stack.slice(\n            test.err.message.length + indexOfMessage,\n          );\n        }\n      } else if (test.err.sourceURL && test.err.line !== undefined) {\n        // Safari doesn't give you a stack. Let's at least provide a source line.\n        stackString = \"\\n(\" + test.err.sourceURL + \":\" + test.err.line + \")\";\n      }\n\n      stackString = stackString || \"\";\n\n      if (test.err.htmlMessage && stackString) {\n        el.appendChild(\n          fragment(\n            '<div class=\"html-error\">%s\\n<pre class=\"error\">%e</pre></div>',\n            test.err.htmlMessage,\n            stackString,\n          ),\n        );\n      } else if (test.err.htmlMessage) {\n        el.appendChild(\n          fragment('<div class=\"html-error\">%s</div>', test.err.htmlMessage),\n        );\n      } else {\n        el.appendChild(\n          fragment('<pre class=\"error\">%e%e</pre>', message, stackString),\n        );\n      }\n\n      self.addCodeToggle(el, test.body);\n      appendToStack(el);\n      updateStats();\n    });\n\n    runner.on(EVENT_TEST_PENDING, function (test) {\n      var el = fragment(\n        '<li class=\"test pass pending\"><h2>%e</h2></li>',\n        test.title,\n      );\n      appendToStack(el);\n      updateStats();\n    });\n\n    function appendToStack(el) {\n      // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack.\n      if (stack[0]) {\n        stack[0].appendChild(el);\n      }\n    }\n\n    function updateStats() {\n      var percent = ((stats.tests / runner.total) * 100) | 0;\n      progressBar.value = percent;\n      if (progressText) {\n        // setting a toFixed that is too low, makes small changes to progress not shown\n        // setting it too high, makes the progress text longer then it needs to\n        // to address this, calculate the toFixed based on the magnitude of total\n        var decimalPlaces = Math.ceil(Math.log10(runner.total / 100));\n        text(\n          progressText,\n          percent.toFixed(Math.min(Math.max(decimalPlaces, 0), 100)) + \"%\",\n        );\n      }\n      if (progressRing) {\n        var radius = parseFloat(\n          getComputedStyle(progressRing[0]).getPropertyValue(\"r\"),\n        );\n        var wholeArc = Math.PI * 2 * radius;\n        var highlightArc = percent * (wholeArc / 100);\n        // The progress ring is in 2 parts, the flatlight color and highlight color.\n        // Rendering both on top of the other, seems to make a 3rd color on the edges.\n        // To create 1 whole ring with 2 colors, both parts are inverse of the other.\n        progressRing[0].style[\"stroke-dasharray\"] =\n          `0,${highlightArc}px,${wholeArc}px`;\n        progressRing[1].style[\"stroke-dasharray\"] =\n          `${highlightArc}px,${wholeArc}px`;\n      }\n\n      // update stats\n      var ms = new Date() - stats.start;\n      text(passesCount, stats.passes);\n      text(failuresCount, stats.failures);\n      text(duration, (ms / 1000).toFixed(2));\n    }\n  }\n\n  /**\n   * Provide suite URL.\n   *\n   * @param {Object} [suite]\n   */\n  suiteURL(suite) {\n    return makeUrl(\"^\" + escapeRe(suite.fullTitle()) + \" \");\n  }\n\n  /**\n   * Provide test URL.\n   *\n   * @param {Object} [test]\n   */\n  testURL(test) {\n    return makeUrl(\"^\" + escapeRe(test.fullTitle()) + \"$\");\n  }\n\n  /**\n   * Adds code toggle functionality for the provided test's list element.\n   *\n   * @param {HTMLLIElement} el\n   * @param {string} contents\n   */\n  addCodeToggle(el, contents) {\n    var h2 = el.getElementsByTagName(\"h2\")[0];\n\n    on(h2, \"click\", function () {\n      pre.style.display = pre.style.display === \"none\" ? \"block\" : \"none\";\n    });\n\n    var pre = fragment(\"<pre><code>%e</code></pre>\", utils.clean(contents));\n    el.appendChild(pre);\n    pre.style.display = \"none\";\n  }\n}\n\n/**\n * Makes a URL, preserving querystring (\"search\") parameters.\n *\n * @param {string} s\n * @return {string} A new URL.\n */\nfunction makeUrl(s) {\n  var search = window.location.search;\n\n  // Remove previous {grep, fgrep, invert} query parameters if present\n  if (search) {\n    search = search\n      .replace(/[?&](?:f?grep|invert)=[^&\\s]*/g, \"\")\n      .replace(/^&/, \"?\");\n  }\n\n  return (\n    window.location.pathname +\n    (search ? search + \"&\" : \"?\") +\n    \"grep=\" +\n    encodeURIComponent(s)\n  );\n}\n\n/**\n * Display error `msg`.\n *\n * @param {string} msg\n */\nfunction error(msg) {\n  document.body.appendChild(fragment('<div id=\"mocha-error\">%s</div>', msg));\n}\n\n/**\n * Return a DOM fragment from `html`.\n *\n * @param {string} html\n */\nfunction fragment(html) {\n  var args = arguments;\n  var div = document.createElement(\"div\");\n  var i = 1;\n\n  div.innerHTML = html.replace(/%([se])/g, function (_, type) {\n    switch (type) {\n      case \"s\":\n        return String(args[i++]);\n      case \"e\":\n        return escape(args[i++]);\n      // no default\n    }\n  });\n\n  return div.firstChild;\n}\n\n/**\n * Check for suites that do not have elements\n * with `classname`, and hide them.\n *\n * @param {text} classname\n */\nfunction hideSuitesWithout(classname) {\n  var suites = document.getElementsByClassName(\"suite\");\n  for (var i = 0; i < suites.length; i++) {\n    var els = suites[i].getElementsByClassName(classname);\n    if (!els.length) {\n      suites[i].className += \" hidden\";\n    }\n  }\n}\n\n/**\n * Unhide .hidden suites.\n */\nfunction unhide() {\n  var els = document.getElementsByClassName(\"suite hidden\");\n  while (els.length > 0) {\n    els[0].className = els[0].className.replace(\"suite hidden\", \"suite\");\n  }\n}\n\n/**\n * Set an element's text contents.\n *\n * @param {HTMLElement} el\n * @param {string} contents\n */\nfunction text(el, contents) {\n  if (el.textContent) {\n    el.textContent = contents;\n  } else {\n    el.innerText = contents;\n  }\n}\n\n/**\n * Listen on `event` with callback `fn`.\n */\nfunction on(el, event, fn) {\n  if (el.addEventListener) {\n    el.addEventListener(event, fn, false);\n  } else {\n    el.attachEvent(\"on\" + event, fn);\n  }\n}\n\nexports = module.exports = HTML;\n"
  },
  {
    "path": "lib/reporters/index.js",
    "content": "\"use strict\";\n\n// Alias exports to a their normalized format Mocha#reporter to prevent a need\n// for dynamic (try/catch) requires, which Browserify doesn't handle.\nexports.Base = exports.base = require(\"./base\");\nexports.Dot = exports.dot = require(\"./dot\");\nexports.Doc = exports.doc = require(\"./doc\");\nexports.TAP = exports.tap = require(\"./tap\");\nexports.JSON = exports.json = require(\"./json\");\nexports.HTML = exports.html = require(\"./html\");\nexports.List = exports.list = require(\"./list\");\nexports.Min = exports.min = require(\"./min\");\nexports.Spec = exports.spec = require(\"./spec\");\nexports.Nyan = exports.nyan = require(\"./nyan\");\nexports.XUnit = exports.xunit = require(\"./xunit\");\nexports.Markdown = exports.markdown = require(\"./markdown\");\nexports.Progress = exports.progress = require(\"./progress\");\nexports.Landing = exports.landing = require(\"./landing\");\nexports.JSONStream = exports[\"json-stream\"] = require(\"./json-stream\");\n"
  },
  {
    "path": "lib/reporters/json-stream.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../runner.js')} Runner\n * @typedef {import('../test.js')} Test\n */\n\n/**\n * @module JSONStream\n */\n/**\n * Module dependencies.\n */\n\nvar Base = require(\"./base\");\nvar constants = require(\"../runner\").constants;\nvar EVENT_TEST_PASS = constants.EVENT_TEST_PASS;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\nvar EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\n\nclass JSONStream extends Base {\n  static description = \"newline delimited JSON events\";\n\n  /**\n   * Constructs a new `JSONStream` reporter instance.\n   *\n   * @public\n   * @memberof Mocha.reporters\n   * @extends Mocha.reporters.Base\n   * @param {Runner} runner - Instance triggers reporter actions.\n   * @param {Object} [options] - runner options\n   */\n  constructor(runner, options) {\n    super(runner, options);\n\n    var self = this;\n    var total = runner.total;\n\n    runner.once(EVENT_RUN_BEGIN, function () {\n      writeEvent([\"start\", { total }]);\n    });\n\n    runner.on(EVENT_TEST_PASS, function (test) {\n      writeEvent([\"pass\", clean(test)]);\n    });\n\n    runner.on(EVENT_TEST_FAIL, function (test, err) {\n      test = clean(test);\n      test.err = err.message;\n      test.stack = err.stack || null;\n      writeEvent([\"fail\", test]);\n    });\n\n    runner.once(EVENT_RUN_END, function () {\n      writeEvent([\"end\", self.stats]);\n    });\n  }\n}\n\n/**\n * Writes Mocha event to reporter output stream.\n *\n * @private\n * @param {unknown[]} event - Mocha event to be output.\n */\nfunction writeEvent(event) {\n  process.stdout.write(JSON.stringify(event) + \"\\n\");\n}\n\n/**\n * Returns an object literal representation of `test`\n * free of cyclic properties, etc.\n *\n * @private\n * @param {Test} test - Instance used as data source.\n * @return {Object} object containing pared-down test instance data\n */\nfunction clean(test) {\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    file: test.file,\n    duration: test.duration,\n    currentRetry: test.currentRetry(),\n    speed: test.speed,\n  };\n}\n\nexports = module.exports = JSONStream;\n"
  },
  {
    "path": "lib/reporters/json.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../runner.js')} Runner\n */\n\n/**\n * @module JSON\n */\n/**\n * Module dependencies.\n */\n\nvar Base = require(\"./base\");\nvar fs = require(\"node:fs\");\nvar path = require(\"node:path\");\nconst createUnsupportedError = require(\"../errors\").createUnsupportedError;\nconst utils = require(\"../utils\");\nvar constants = require(\"../runner\").constants;\nvar EVENT_TEST_PASS = constants.EVENT_TEST_PASS;\nvar EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\nvar EVENT_TEST_END = constants.EVENT_TEST_END;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\n\nclass JSONReporter extends Base {\n  static description = \"single JSON object\";\n\n  /**\n   * Constructs a new `JSON` reporter instance.\n   *\n   * @public\n   * @memberof Mocha.reporters\n   * @extends Mocha.reporters.Base\n   * @param {Runner} runner - Instance triggers reporter actions.\n   * @param {Object} [options] - runner options\n   */\n  constructor(runner, options = {}) {\n    super(runner, options);\n\n    var self = this;\n    var tests = [];\n    var pending = [];\n    var failures = [];\n    var passes = [];\n    var output;\n\n    if (options.reporterOption && options.reporterOption.output) {\n      if (utils.isBrowser()) {\n        throw createUnsupportedError(\"file output not supported in browser\");\n      }\n      output = options.reporterOption.output;\n    }\n\n    runner.on(EVENT_TEST_END, function (test) {\n      tests.push(test);\n    });\n\n    runner.on(EVENT_TEST_PASS, function (test) {\n      passes.push(test);\n    });\n\n    runner.on(EVENT_TEST_FAIL, function (test) {\n      failures.push(test);\n    });\n\n    runner.on(EVENT_TEST_PENDING, function (test) {\n      pending.push(test);\n    });\n\n    runner.once(EVENT_RUN_END, function () {\n      var obj = {\n        stats: self.stats,\n        tests: tests.map(clean),\n        pending: pending.map(clean),\n        failures: failures.map(clean),\n        passes: passes.map(clean),\n      };\n\n      runner.testResults = obj;\n\n      var json = JSON.stringify(obj, null, 2);\n      if (output) {\n        try {\n          fs.mkdirSync(path.dirname(output), { recursive: true });\n          fs.writeFileSync(output, json);\n        } catch (err) {\n          console.error(\n            `${Base.symbols.err} [mocha] writing output to \"${output}\" failed: ${err.message}\\n`,\n          );\n          process.stdout.write(json);\n        }\n      } else {\n        process.stdout.write(json);\n      }\n    });\n  }\n}\n\n/**\n * Return a plain-object representation of `test`\n * free of cyclic properties etc.\n *\n * @private\n * @param {Object} test\n * @return {Object}\n */\nfunction clean(test) {\n  var err = test.err || {};\n  if (err instanceof Error) {\n    err = errorJSON(err);\n  }\n\n  return {\n    title: test.title,\n    fullTitle: test.fullTitle(),\n    file: test.file,\n    duration: test.duration,\n    currentRetry: test.currentRetry(),\n    speed: test.speed,\n    err: cleanCycles(err),\n  };\n}\n\n/**\n * Replaces any circular references inside `obj` with '[object Object]'\n *\n * @private\n * @param {Object} obj\n * @return {Object}\n */\nfunction cleanCycles(obj) {\n  var cache = [];\n  return JSON.parse(\n    JSON.stringify(obj, function (key, value) {\n      if (typeof value === \"object\" && value !== null) {\n        if (cache.indexOf(value) !== -1) {\n          // Instead of going in a circle, we'll print [object Object]\n          return \"\" + value;\n        }\n        cache.push(value);\n      }\n\n      return value;\n    }),\n  );\n}\n\n/**\n * Transform an Error object into a JSON object.\n *\n * @private\n * @param {Error} err\n * @return {Object}\n */\nfunction errorJSON(err) {\n  var res = {};\n  Object.getOwnPropertyNames(err).forEach(function (key) {\n    res[key] = err[key];\n  }, err);\n  return res;\n}\n\nexports = module.exports = JSONReporter;\n"
  },
  {
    "path": "lib/reporters/landing.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../runner.js')} Runner\n */\n\n/**\n * @module Landing\n */\n/**\n * Module dependencies.\n */\n\nvar Base = require(\"./base\");\nvar constants = require(\"../runner\").constants;\nvar EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\nvar EVENT_TEST_END = constants.EVENT_TEST_END;\nvar STATE_FAILED = require(\"../runnable\").constants.STATE_FAILED;\n\nvar cursor = Base.cursor;\nvar color = Base.color;\n\n/**\n * Airplane color.\n */\n\nBase.colors.plane = 0;\n\n/**\n * Airplane crash color.\n */\n\nBase.colors[\"plane crash\"] = 31;\n\n/**\n * Runway color.\n */\n\nBase.colors.runway = 90;\n\nclass Landing extends Base {\n  static description = \"Unicode landing strip\";\n\n  /**\n   * Constructs a new `Landing` reporter instance.\n   *\n   * @public\n   * @memberof Mocha.reporters\n   * @extends Mocha.reporters.Base\n   * @param {Runner} runner - Instance triggers reporter actions.\n   * @param {Object} [options] - runner options\n   */\n  constructor(runner, options) {\n    super(runner, options);\n\n    var self = this;\n    var width = (Base.window.width * 0.75) | 0;\n    var stream = process.stdout;\n\n    var plane = color(\"plane\", \"✈\");\n    var crashed = -1;\n    var n = 0;\n    var total = 0;\n\n    function runway() {\n      var buf = Array(width).join(\"-\");\n      return \"  \" + color(\"runway\", buf);\n    }\n\n    runner.on(EVENT_RUN_BEGIN, function () {\n      stream.write(\"\\n\\n\\n  \");\n      cursor.hide();\n    });\n\n    runner.on(EVENT_TEST_END, function (test) {\n      // check if the plane crashed\n      var col = crashed === -1 ? ((width * ++n) / ++total) | 0 : crashed;\n      // show the crash\n      if (test.state === STATE_FAILED) {\n        plane = color(\"plane crash\", \"✈\");\n        crashed = col;\n      }\n\n      // render landing strip\n      stream.write(\"\\u001b[\" + (width + 1) + \"D\\u001b[2A\");\n      stream.write(runway());\n      stream.write(\"\\n  \");\n      stream.write(color(\"runway\", Array(col).join(\"⋅\")));\n      stream.write(plane);\n      stream.write(color(\"runway\", Array(width - col).join(\"⋅\") + \"\\n\"));\n      stream.write(runway());\n      stream.write(\"\\u001b[0m\");\n    });\n\n    runner.once(EVENT_RUN_END, function () {\n      cursor.show();\n      process.stdout.write(\"\\n\");\n      self.epilogue();\n    });\n\n    // if cursor is hidden when we ctrl-C, then it will remain hidden unless...\n    process.once(\"SIGINT\", function () {\n      cursor.show();\n      process.nextTick(function () {\n        process.kill(process.pid, \"SIGINT\");\n      });\n    });\n  }\n}\n\nexports = module.exports = Landing;\n"
  },
  {
    "path": "lib/reporters/list.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../runner.js')} Runner\n */\n\n/**\n * @module List\n */\n/**\n * Module dependencies.\n */\n\nvar Base = require(\"./base\");\nvar constants = require(\"../runner\").constants;\nvar EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\nvar EVENT_TEST_BEGIN = constants.EVENT_TEST_BEGIN;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\nvar EVENT_TEST_PASS = constants.EVENT_TEST_PASS;\nvar EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\nclass List extends Base {\n  static description = 'like \"spec\" reporter but flat';\n\n  /**\n   * Constructs a new `List` reporter instance.\n   *\n   * @public\n   * @memberof Mocha.reporters\n   * @extends Mocha.reporters.Base\n   * @param {Runner} runner - Instance triggers reporter actions.\n   * @param {Object} [options] - runner options\n   */\n  constructor(runner, options) {\n    super(runner, options);\n\n    var n = 0;\n\n    runner.on(EVENT_RUN_BEGIN, function () {\n      Base.consoleLog();\n    });\n\n    runner.on(EVENT_TEST_BEGIN, function (test) {\n      process.stdout.write(color(\"pass\", \"    \" + test.fullTitle() + \": \"));\n    });\n\n    runner.on(EVENT_TEST_PENDING, function (test) {\n      var fmt = color(\"checkmark\", \"  -\") + color(\"pending\", \" %s\");\n      Base.consoleLog(fmt, test.fullTitle());\n    });\n\n    runner.on(EVENT_TEST_PASS, function (test) {\n      var fmt =\n        color(\"checkmark\", \"  \" + Base.symbols.ok) +\n        color(\"pass\", \" %s: \") +\n        color(test.speed, \"%dms\");\n      cursor.CR();\n      Base.consoleLog(fmt, test.fullTitle(), test.duration);\n    });\n\n    runner.on(EVENT_TEST_FAIL, function (test) {\n      cursor.CR();\n      Base.consoleLog(color(\"fail\", \"  %d) %s\"), ++n, test.fullTitle());\n    });\n\n    runner.once(EVENT_RUN_END, (...args) => this.epilogue(...args));\n  }\n}\n\nexports = module.exports = List;\n"
  },
  {
    "path": "lib/reporters/markdown.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../runner.js')} Runner\n */\n\n/**\n * @module Markdown\n */\n/**\n * Module dependencies.\n */\n\nvar Base = require(\"./base\");\nvar utils = require(\"../utils\");\nvar constants = require(\"../runner\").constants;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\nvar EVENT_SUITE_BEGIN = constants.EVENT_SUITE_BEGIN;\nvar EVENT_SUITE_END = constants.EVENT_SUITE_END;\nvar EVENT_TEST_PASS = constants.EVENT_TEST_PASS;\n\n/**\n * Constants\n */\n\nvar SUITE_PREFIX = \"$\";\n\nclass Markdown extends Base {\n  static description = \"GitHub Flavored Markdown\";\n\n  /**\n   * Constructs a new `Markdown` reporter instance.\n   *\n   * @public\n   * @memberof Mocha.reporters\n   * @extends Mocha.reporters.Base\n   * @param {Runner} runner - Instance triggers reporter actions.\n   * @param {Object} [options] - runner options\n   */\n  constructor(runner, options) {\n    super(runner, options);\n\n    var level = 0;\n    var buf = \"\";\n\n    function title(str) {\n      return Array(level).join(\"#\") + \" \" + str;\n    }\n\n    function mapTOC(suite, obj) {\n      var ret = obj;\n      var key = SUITE_PREFIX + suite.title;\n\n      obj = obj[key] = obj[key] || { suite };\n      suite.suites.forEach(function (suite) {\n        mapTOC(suite, obj);\n      });\n\n      return ret;\n    }\n\n    function stringifyTOC(obj, level) {\n      ++level;\n      var buf = \"\";\n      var link;\n      for (var key in obj) {\n        if (key === \"suite\") {\n          continue;\n        }\n        if (key !== SUITE_PREFIX) {\n          link = \" - [\" + key.substring(1) + \"]\";\n          link += \"(#\" + utils.slug(obj[key].suite.fullTitle()) + \")\\n\";\n          buf += Array(level).join(\"  \") + link;\n        }\n        buf += stringifyTOC(obj[key], level);\n      }\n      return buf;\n    }\n\n    function generateTOC(suite) {\n      var obj = mapTOC(suite, {});\n      return stringifyTOC(obj, 0);\n    }\n\n    generateTOC(runner.suite);\n\n    runner.on(EVENT_SUITE_BEGIN, function (suite) {\n      ++level;\n      var slug = utils.slug(suite.fullTitle());\n      buf += '<a name=\"' + slug + '\"></a>' + \"\\n\";\n      buf += title(suite.title) + \"\\n\";\n    });\n\n    runner.on(EVENT_SUITE_END, function () {\n      --level;\n    });\n\n    runner.on(EVENT_TEST_PASS, function (test) {\n      var code = utils.clean(test.body);\n      buf += test.title + \".\\n\";\n      buf += \"\\n```js\\n\";\n      buf += code + \"\\n\";\n      buf += \"```\\n\\n\";\n    });\n\n    runner.once(EVENT_RUN_END, function () {\n      process.stdout.write(\"# TOC\\n\");\n      process.stdout.write(generateTOC(runner.suite));\n      process.stdout.write(buf);\n    });\n  }\n}\n\nexports = module.exports = Markdown;\n"
  },
  {
    "path": "lib/reporters/min.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../runner.js')} Runner\n */\n\n/**\n * @module Min\n */\n/**\n * Module dependencies.\n */\n\nvar Base = require(\"./base\");\nvar constants = require(\"../runner\").constants;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\nvar EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN;\n\nclass Min extends Base {\n  static description = \"essentially just a summary\";\n\n  /**\n   * Constructs a new `Min` reporter instance.\n   *\n   * @description\n   * This minimal test reporter is best used with '--watch'.\n   *\n   * @public\n   * @memberof Mocha.reporters\n   * @extends Mocha.reporters.Base\n   * @param {Runner} runner - Instance triggers reporter actions.\n   * @param {Object} [options] - runner options\n   */\n  constructor(runner, options) {\n    super(runner, options);\n\n    runner.on(EVENT_RUN_BEGIN, function () {\n      // clear screen\n      process.stdout.write(\"\\u001b[2J\");\n      // set cursor position\n      process.stdout.write(\"\\u001b[1;3H\");\n    });\n\n    runner.once(EVENT_RUN_END, (...args) => this.epilogue(...args));\n  }\n}\n\nexports = module.exports = Min;\n"
  },
  {
    "path": "lib/reporters/nyan.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../runner.js')} Runner\n */\n\n/**\n * @module Nyan\n */\n/**\n * Module dependencies.\n */\n\nvar Base = require(\"./base\");\nvar constants = require(\"../runner\").constants;\nvar EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN;\nvar EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING;\nvar EVENT_TEST_PASS = constants.EVENT_TEST_PASS;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\n\nclass NyanCat extends Base {\n  static description = '\"nyan cat\"';\n\n  /**\n   * Constructs a new `Nyan` reporter instance.\n   *\n   * @public\n   * @memberof Mocha.reporters\n   * @extends Mocha.reporters.Base\n   * @param {Runner} runner - Instance triggers reporter actions.\n   * @param {Object} [options] - runner options\n   */\n  constructor(runner, options) {\n    super(runner, options);\n\n    var self = this;\n    var width = (Base.window.width * 0.75) | 0;\n    var nyanCatWidth = (this.nyanCatWidth = 11);\n\n    this.colorIndex = 0;\n    this.numberOfLines = 4;\n    this.rainbowColors = self.generateColors();\n    this.scoreboardWidth = 5;\n    this.tick = 0;\n    this.trajectories = [[], [], [], []];\n    this.trajectoryWidthMax = width - nyanCatWidth;\n\n    runner.on(EVENT_RUN_BEGIN, function () {\n      Base.cursor.hide();\n      self.draw();\n    });\n\n    runner.on(EVENT_TEST_PENDING, function () {\n      self.draw();\n    });\n\n    runner.on(EVENT_TEST_PASS, function () {\n      self.draw();\n    });\n\n    runner.on(EVENT_TEST_FAIL, function () {\n      self.draw();\n    });\n\n    runner.once(EVENT_RUN_END, function () {\n      Base.cursor.show();\n      for (var i = 0; i < self.numberOfLines; i++) {\n        process.stdout.write(\"\\n\");\n      }\n      self.epilogue();\n    });\n  }\n\n  /**\n   * Draw the nyan cat\n   *\n   * @private\n   */\n\n  draw() {\n    this.appendRainbow();\n    this.drawScoreboard();\n    this.drawRainbow();\n    this.drawNyanCat();\n    this.tick = !this.tick;\n  }\n\n  /**\n   * Draw the \"scoreboard\" showing the number\n   * of passes, failures and pending tests.\n   *\n   * @private\n   */\n\n  drawScoreboard() {\n    var stats = this.stats;\n\n    function draw(type, n) {\n      process.stdout.write(\" \");\n      process.stdout.write(Base.color(type, n));\n      process.stdout.write(\"\\n\");\n    }\n\n    draw(\"green\", stats.passes);\n    draw(\"fail\", stats.failures);\n    draw(\"pending\", stats.pending);\n    process.stdout.write(\"\\n\");\n\n    this.cursorUp(this.numberOfLines);\n  }\n\n  /**\n   * Append the rainbow.\n   *\n   * @private\n   */\n\n  appendRainbow() {\n    var segment = this.tick ? \"_\" : \"-\";\n    var rainbowified = this.rainbowify(segment);\n\n    for (var index = 0; index < this.numberOfLines; index++) {\n      var trajectory = this.trajectories[index];\n      if (trajectory.length >= this.trajectoryWidthMax) {\n        trajectory.shift();\n      }\n      trajectory.push(rainbowified);\n    }\n  }\n\n  /**\n   * Draw the rainbow.\n   *\n   * @private\n   */\n\n  drawRainbow() {\n    var self = this;\n\n    this.trajectories.forEach(function (line) {\n      process.stdout.write(\"\\u001b[\" + self.scoreboardWidth + \"C\");\n      process.stdout.write(line.join(\"\"));\n      process.stdout.write(\"\\n\");\n    });\n\n    this.cursorUp(this.numberOfLines);\n  }\n\n  /**\n   * Draw the nyan cat\n   *\n   * @private\n   */\n  drawNyanCat() {\n    var self = this;\n    var startWidth = this.scoreboardWidth + this.trajectories[0].length;\n    var dist = \"\\u001b[\" + startWidth + \"C\";\n    var padding;\n\n    process.stdout.write(dist);\n    process.stdout.write(\"_,------,\");\n    process.stdout.write(\"\\n\");\n\n    process.stdout.write(dist);\n    padding = self.tick ? \"  \" : \"   \";\n    process.stdout.write(\"_|\" + padding + \"/\\\\_/\\\\ \");\n    process.stdout.write(\"\\n\");\n\n    process.stdout.write(dist);\n    padding = self.tick ? \"_\" : \"__\";\n    var tail = self.tick ? \"~\" : \"^\";\n    process.stdout.write(tail + \"|\" + padding + this.face() + \" \");\n    process.stdout.write(\"\\n\");\n\n    process.stdout.write(dist);\n    padding = self.tick ? \" \" : \"  \";\n    process.stdout.write(padding + '\"\"  \"\" ');\n    process.stdout.write(\"\\n\");\n\n    this.cursorUp(this.numberOfLines);\n  }\n\n  /**\n   * Draw nyan cat face.\n   *\n   * @private\n   * @return {string}\n   */\n\n  face() {\n    var stats = this.stats;\n    if (stats.failures) {\n      return \"( x .x)\";\n    } else if (stats.pending) {\n      return \"( o .o)\";\n    } else if (stats.passes) {\n      return \"( ^ .^)\";\n    }\n    return \"( - .-)\";\n  }\n\n  /**\n   * Move cursor up `n`.\n   *\n   * @private\n   * @param {number} n\n   */\n\n  cursorUp(n) {\n    process.stdout.write(\"\\u001b[\" + n + \"A\");\n  }\n\n  /**\n   * Move cursor down `n`.\n   *\n   * @private\n   * @param {number} n\n   */\n\n  cursorDown(n) {\n    process.stdout.write(\"\\u001b[\" + n + \"B\");\n  }\n\n  /**\n   * Generate rainbow colors.\n   *\n   * @private\n   * @return {Array}\n   */\n  generateColors() {\n    var colors = [];\n\n    for (var i = 0; i < 6 * 7; i++) {\n      var pi3 = Math.floor(Math.PI / 3);\n      var n = i * (1.0 / 6);\n      var r = Math.floor(3 * Math.sin(n) + 3);\n      var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3);\n      var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3);\n      colors.push(36 * r + 6 * g + b + 16);\n    }\n\n    return colors;\n  }\n\n  /**\n   * Apply rainbow to the given `str`.\n   *\n   * @private\n   * @param {string} str\n   * @return {string}\n   */\n  rainbowify(str) {\n    if (!Base.useColors) {\n      return str;\n    }\n    var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length];\n    this.colorIndex += 1;\n    return \"\\u001b[38;5;\" + color + \"m\" + str + \"\\u001b[0m\";\n  }\n}\n\nexports = module.exports = NyanCat;\n"
  },
  {
    "path": "lib/reporters/progress.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../runner.js')} Runner\n */\n\n/**\n * @module Progress\n */\n/**\n * Module dependencies.\n */\n\nvar Base = require(\"./base\");\nvar constants = require(\"../runner\").constants;\nvar EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN;\nvar EVENT_TEST_END = constants.EVENT_TEST_END;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\nvar color = Base.color;\nvar cursor = Base.cursor;\n\n/**\n * General progress bar color.\n */\n\nBase.colors.progress = 90;\n\nclass Progress extends Base {\n  static description = \"a progress bar\";\n\n  /**\n   * Constructs a new `Progress` reporter instance.\n   *\n   * @public\n   * @memberof Mocha.reporters\n   * @extends Mocha.reporters.Base\n   * @param {Runner} runner - Instance triggers reporter actions.\n   * @param {Object} [options] - runner options\n   */\n  constructor(runner, options) {\n    super(runner, options);\n\n    var self = this;\n    var width = (Base.window.width * 0.5) | 0;\n    var total = runner.total;\n    var complete = 0;\n    var lastN = -1;\n\n    // default chars\n    options = options || {};\n    var reporterOptions = options.reporterOptions || {};\n\n    options.open = reporterOptions.open || \"[\";\n    options.complete = reporterOptions.complete || \"▬\";\n    options.incomplete = reporterOptions.incomplete || Base.symbols.dot;\n    options.close = reporterOptions.close || \"]\";\n    options.verbose = reporterOptions.verbose || false;\n\n    // tests started\n    runner.on(EVENT_RUN_BEGIN, function () {\n      process.stdout.write(\"\\n\");\n      cursor.hide();\n    });\n\n    // tests complete\n    runner.on(EVENT_TEST_END, function () {\n      complete++;\n\n      var percent = complete / total;\n      var n = (width * percent) | 0;\n      var i = width - n;\n\n      if (n === lastN && !options.verbose) {\n        // Don't re-render the line if it hasn't changed\n        return;\n      }\n      lastN = n;\n\n      cursor.CR();\n      process.stdout.write(\"\\u001b[J\");\n      process.stdout.write(color(\"progress\", \"  \" + options.open));\n      process.stdout.write(Array(n).join(options.complete));\n      process.stdout.write(Array(i).join(options.incomplete));\n      process.stdout.write(color(\"progress\", options.close));\n      if (options.verbose) {\n        process.stdout.write(\n          color(\"progress\", \" \" + complete + \" of \" + total),\n        );\n      }\n    });\n\n    // tests are complete, output some stats\n    // and the failures if any\n    runner.once(EVENT_RUN_END, function () {\n      cursor.show();\n      process.stdout.write(\"\\n\");\n      self.epilogue();\n    });\n  }\n}\n\nexports = module.exports = Progress;\n"
  },
  {
    "path": "lib/reporters/spec.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../runner.js')} Runner\n * @typedef {import('../test.js')} Test\n */\n\n/**\n * @module Spec\n */\n/**\n * Module dependencies.\n */\n\nvar Base = require(\"./base\");\nvar constants = require(\"../runner\").constants;\nvar EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\nvar EVENT_SUITE_BEGIN = constants.EVENT_SUITE_BEGIN;\nvar EVENT_SUITE_END = constants.EVENT_SUITE_END;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\nvar EVENT_TEST_PASS = constants.EVENT_TEST_PASS;\nvar EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING;\nvar color = Base.color;\n\nclass Spec extends Base {\n  static description = \"hierarchical & verbose [default]\";\n\n  /**\n   * Constructs a new `Spec` reporter instance.\n   *\n   * @public\n   * @memberof Mocha.reporters\n   * @extends Mocha.reporters.Base\n   * @param {Runner} runner - Instance triggers reporter actions.\n   * @param {Object} [options] - runner options\n   */\n  constructor(runner, options) {\n    super(runner, options);\n\n    var indents = 0;\n    var n = 0;\n\n    function indent() {\n      return Array(indents).join(\"  \");\n    }\n\n    runner.on(EVENT_RUN_BEGIN, function () {\n      Base.consoleLog();\n    });\n\n    runner.on(EVENT_SUITE_BEGIN, function (suite) {\n      ++indents;\n      Base.consoleLog(color(\"suite\", \"%s%s\"), indent(), suite.title);\n    });\n\n    runner.on(EVENT_SUITE_END, function () {\n      --indents;\n      if (indents === 1) {\n        Base.consoleLog();\n      }\n    });\n\n    runner.on(EVENT_TEST_PENDING, function (test) {\n      var fmt = indent() + color(\"pending\", \"  - %s\");\n      Base.consoleLog(fmt, test.title);\n    });\n\n    runner.on(EVENT_TEST_PASS, function (test) {\n      var fmt;\n      if (test.speed === \"fast\") {\n        fmt =\n          indent() +\n          color(\"checkmark\", \"  \" + Base.symbols.ok) +\n          color(\"pass\", \" %s\");\n        Base.consoleLog(fmt, test.title);\n      } else {\n        fmt =\n          indent() +\n          color(\"checkmark\", \"  \" + Base.symbols.ok) +\n          color(\"pass\", \" %s\") +\n          color(test.speed, \" (%dms)\");\n        Base.consoleLog(fmt, test.title, test.duration);\n      }\n    });\n\n    runner.on(EVENT_TEST_FAIL, function (test) {\n      Base.consoleLog(indent() + color(\"fail\", \"  %d) %s\"), ++n, test.title);\n    });\n\n    runner.once(EVENT_RUN_END, (...args) => this.epilogue(...args));\n  }\n}\n\nexports = module.exports = Spec;\n"
  },
  {
    "path": "lib/reporters/tap.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../runner.js')} Runner\n * @typedef {import('../test.js')} Test\n */\n\n/**\n * @module TAP\n */\n/**\n * Module dependencies.\n */\n\nvar util = require(\"node:util\");\nvar Base = require(\"./base\");\nvar constants = require(\"../runner\").constants;\nvar EVENT_TEST_PASS = constants.EVENT_TEST_PASS;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\nvar EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\nvar EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING;\nvar EVENT_TEST_END = constants.EVENT_TEST_END;\nvar sprintf = util.format;\n\nclass TAP extends Base {\n  static description = \"TAP-compatible output\";\n\n  /**\n   * Constructs a new `TAP` reporter instance.\n   *\n   * @public\n   * @memberof Mocha.reporters\n   * @extends Mocha.reporters.Base\n   * @param {Runner} runner - Instance triggers reporter actions.\n   * @param {Object} [options] - runner options\n   */\n  constructor(runner, options) {\n    super(runner, options);\n\n    var self = this;\n    var n = 1;\n\n    var tapVersion = \"12\";\n    if (options && options.reporterOptions) {\n      if (options.reporterOptions.tapVersion) {\n        tapVersion = options.reporterOptions.tapVersion.toString();\n      }\n    }\n\n    this._producer = createProducer(tapVersion);\n\n    runner.once(EVENT_RUN_BEGIN, function () {\n      self._producer.writeVersion();\n    });\n\n    runner.on(EVENT_TEST_END, function () {\n      ++n;\n    });\n\n    runner.on(EVENT_TEST_PENDING, function (test) {\n      self._producer.writePending(n, test);\n    });\n\n    runner.on(EVENT_TEST_PASS, function (test) {\n      self._producer.writePass(n, test);\n    });\n\n    runner.on(EVENT_TEST_FAIL, function (test, err) {\n      self._producer.writeFail(n, test, err);\n    });\n\n    runner.once(EVENT_RUN_END, function () {\n      self._producer.writeEpilogue(runner.stats);\n    });\n  }\n}\n\n/**\n * Returns a TAP-safe title of `test`.\n *\n * @private\n * @param {Test} test - Test instance.\n * @return {String} title with any hash character removed\n */\nfunction title(test) {\n  return test.fullTitle().replace(/#/g, \"\");\n}\n\n/**\n * Writes newline-terminated formatted string to reporter output stream.\n *\n * @private\n * @param {string} format - `printf`-like format string\n * @param {...*} [varArgs] - Format string arguments\n */\nfunction println() {\n  var vargs = Array.from(arguments);\n  vargs[0] += \"\\n\";\n  process.stdout.write(sprintf.apply(null, vargs));\n}\n\n/**\n * Returns a `tapVersion`-appropriate TAP producer instance, if possible.\n *\n * @private\n * @param {string} tapVersion - Version of TAP specification to produce.\n * @returns {TAPProducer} specification-appropriate instance\n * @throws {Error} if specification version has no associated producer.\n */\nfunction createProducer(tapVersion) {\n  var producers = {\n    12: new TAP12Producer(),\n    13: new TAP13Producer(),\n  };\n  var producer = producers[tapVersion];\n\n  if (!producer) {\n    throw new Error(\n      \"invalid or unsupported TAP version: \" + JSON.stringify(tapVersion),\n    );\n  }\n\n  return producer;\n}\n\n/**\n * @summary\n * Constructs a new TAPProducer.\n *\n * @description\n * <em>Only</em> to be used as an abstract base class.\n *\n * @private\n * @constructor\n */\nclass TAPProducer {\n  /**\n   * Writes the TAP version to reporter output stream.\n   *\n   * @abstract\n   */\n  writeVersion() {}\n\n  /**\n   * Writes the plan to reporter output stream.\n   *\n   * @abstract\n   * @param {number} ntests - Number of tests that are planned to run.\n   */\n  writePlan(ntests) {\n    println(\"%d..%d\", 1, ntests);\n  }\n\n  /**\n   * Writes that test passed to reporter output stream.\n   *\n   * @abstract\n   * @param {number} n - Index of test that passed.\n   * @param {Test} test - Instance containing test information.\n   */\n  writePass(n, test) {\n    println(\"ok %d %s\", n, title(test));\n  }\n\n  /**\n   * Writes that test was skipped to reporter output stream.\n   *\n   * @abstract\n   * @param {number} n - Index of test that was skipped.\n   * @param {Test} test - Instance containing test information.\n   */\n  writePending(n, test) {\n    println(\"ok %d %s # SKIP -\", n, title(test));\n  }\n\n  /**\n   * Writes that test failed to reporter output stream.\n   *\n   * @abstract\n   * @param {number} n - Index of test that failed.\n   * @param {Test} test - Instance containing test information.\n   */\n  writeFail(n, test) {\n    println(\"not ok %d %s\", n, title(test));\n  }\n\n  /**\n   * Writes the summary epilogue to reporter output stream.\n   *\n   * @abstract\n   * @param {Object} stats - Object containing run statistics.\n   */\n  writeEpilogue(stats) {\n    // :TBD: Why is this not counting pending tests?\n    println(\"# tests \" + (stats.passes + stats.failures));\n    println(\"# pass \" + stats.passes);\n    // :TBD: Why are we not showing pending results?\n    println(\"# fail \" + stats.failures);\n    this.writePlan(stats.passes + stats.failures + stats.pending);\n  }\n}\n\n/**\n * @description\n * Produces output conforming to the TAP12 specification.\n *\n * @private\n * @constructor\n * @extends TAPProducer\n * @see {@link https://testanything.org/tap-specification.html|Specification}\n */\nclass TAP12Producer extends TAPProducer {\n  /**\n   * Writes that test failed to reporter output stream, with error formatting.\n   * @override\n   */\n  writeFail(n, test, err) {\n    super.writeFail(n, test, err);\n    if (err.message) {\n      println(err.message.replace(/^/gm, \"  \"));\n    }\n    if (err.stack) {\n      println(err.stack.replace(/^/gm, \"  \"));\n    }\n  }\n}\n\n/**\n * @summary\n * Constructs a new TAP13Producer.\n *\n * @description\n * Produces output conforming to the TAP13 specification.\n *\n * @private\n * @constructor\n * @extends TAPProducer\n * @see {@link https://testanything.org/tap-version-13-specification.html|Specification}\n */\nclass TAP13Producer extends TAPProducer {\n  /**\n   * Writes the TAP version to reporter output stream.\n   * @override\n   */\n  writeVersion() {\n    println(\"TAP version 13\");\n  }\n\n  /**\n   * Writes that test failed to reporter output stream, with error formatting.\n   * @override\n   */\n  writeFail(n, test, err) {\n    super.writeFail(n, test, err);\n    var emitYamlBlock = err.message != null || err.stack != null;\n    if (emitYamlBlock) {\n      println(indent(1) + \"---\");\n      if (err.message) {\n        println(indent(2) + \"message: |-\");\n        println(err.message.replace(/^/gm, indent(3)));\n      }\n      if (err.stack) {\n        println(indent(2) + \"stack: |-\");\n        println(err.stack.replace(/^/gm, indent(3)));\n      }\n      println(indent(1) + \"...\");\n    }\n  }\n}\n\nfunction indent(level) {\n  return Array(level + 1).join(\"  \");\n}\n\nexports = module.exports = TAP;\n"
  },
  {
    "path": "lib/reporters/xunit.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('../runner.js')} Runner\n * @typedef {import('../test.js')} Test\n */\n\n/**\n * @module XUnit\n */\n/**\n * Module dependencies.\n */\n\nvar Base = require(\"./base\");\nvar utils = require(\"../utils\");\nvar fs = require(\"node:fs\");\nvar path = require(\"node:path\");\nvar errors = require(\"../errors\");\nvar createUnsupportedError = errors.createUnsupportedError;\nvar constants = require(\"../runner\").constants;\nvar EVENT_TEST_PASS = constants.EVENT_TEST_PASS;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\nvar EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING;\nvar STATE_FAILED = require(\"../runnable\").constants.STATE_FAILED;\nvar escape = utils.escape;\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n */\nvar Date = global.Date;\n\nclass XUnit extends Base {\n  static description = \"XUnit-compatible XML output\";\n\n  /**\n   * Constructs a new `XUnit` reporter instance.\n   *\n   * @public\n   * @memberof Mocha.reporters\n   * @extends Mocha.reporters.Base\n   * @param {Runner} runner - Instance triggers reporter actions.\n   * @param {Object} [options] - runner options\n   */\n  constructor(runner, options) {\n    super(runner, options);\n\n    var stats = this.stats;\n    var tests = [];\n    var self = this;\n\n    // the name of the test suite, as it will appear in the resulting XML file\n    var suiteName;\n\n    // the default name of the test suite if none is provided\n    var DEFAULT_SUITE_NAME = \"Mocha Tests\";\n\n    if (options && options.reporterOptions) {\n      if (options.reporterOptions.output) {\n        if (!fs.createWriteStream) {\n          throw createUnsupportedError(\"file output not supported in browser\");\n        }\n\n        fs.mkdirSync(path.dirname(options.reporterOptions.output), {\n          recursive: true,\n        });\n        self.fileStream = fs.createWriteStream(options.reporterOptions.output);\n      }\n\n      // get the suite name from the reporter options (if provided)\n      suiteName = options.reporterOptions.suiteName;\n    }\n\n    // fall back to the default suite name\n    suiteName = suiteName || DEFAULT_SUITE_NAME;\n\n    runner.on(EVENT_TEST_PENDING, function (test) {\n      tests.push(test);\n    });\n\n    runner.on(EVENT_TEST_PASS, function (test) {\n      tests.push(test);\n    });\n\n    runner.on(EVENT_TEST_FAIL, function (test) {\n      tests.push(test);\n    });\n\n    runner.once(EVENT_RUN_END, function () {\n      self.write(\n        tag(\n          \"testsuite\",\n          {\n            name: suiteName,\n            tests: stats.tests,\n            failures: 0,\n            errors: stats.failures,\n            skipped: stats.tests - stats.failures - stats.passes,\n            timestamp: new Date().toUTCString(),\n            time: stats.duration / 1000 || 0,\n          },\n          false,\n        ),\n      );\n\n      tests.forEach(function (t) {\n        self.test(t, options);\n      });\n\n      self.write(\"</testsuite>\");\n    });\n  }\n\n  /**\n   * Override done to close the stream (if it's a file).\n   *\n   * @param failures\n   * @param {Function} fn\n   */\n  done(failures, fn) {\n    if (this.fileStream) {\n      this.fileStream.end(function () {\n        fn(failures);\n      });\n    } else {\n      fn(failures);\n    }\n  }\n\n  /**\n   * Write out the given line.\n   *\n   * @param {string} line\n   */\n  write(line) {\n    if (this.fileStream) {\n      this.fileStream.write(line + \"\\n\");\n    } else if (typeof process === \"object\" && process.stdout) {\n      process.stdout.write(line + \"\\n\");\n    } else {\n      Base.consoleLog(line);\n    }\n  }\n\n  /**\n   * Output tag for the given `test.`\n   *\n   * @param {Test} test\n   */\n  test(test, options) {\n    Base.useColors = false;\n\n    var attrs = {\n      classname: test.parent.fullTitle(),\n      name: test.title,\n      file: testFilePath(test.file, options),\n      time: test.duration / 1000 || 0,\n    };\n\n    if (test.state === STATE_FAILED) {\n      var err = test.err;\n      var diff =\n        !Base.hideDiff && Base.showDiff(err)\n          ? \"\\n\" + Base.generateDiff(err.actual, err.expected)\n          : \"\";\n      this.write(\n        tag(\n          \"testcase\",\n          attrs,\n          false,\n          tag(\n            \"failure\",\n            {},\n            false,\n            escape(err.message) + escape(diff) + \"\\n\" + escape(err.stack),\n          ),\n        ),\n      );\n    } else if (test.isPending()) {\n      this.write(tag(\"testcase\", attrs, false, tag(\"skipped\", {}, true)));\n    } else {\n      this.write(tag(\"testcase\", attrs, true));\n    }\n  }\n}\n\n/**\n * HTML tag helper.\n *\n * @param name\n * @param attrs\n * @param close\n * @param content\n * @return {string}\n */\nfunction tag(name, attrs, close, content) {\n  var end = close ? \"/>\" : \">\";\n  var pairs = [];\n  var tag;\n\n  for (var key in attrs) {\n    if (Object.prototype.hasOwnProperty.call(attrs, key)) {\n      pairs.push(key + '=\"' + escape(attrs[key]) + '\"');\n    }\n  }\n\n  tag = \"<\" + name + (pairs.length ? \" \" + pairs.join(\" \") : \"\") + end;\n  if (content) {\n    tag += content + \"</\" + name + end;\n  }\n  return tag;\n}\n\nfunction testFilePath(filepath, options) {\n  if (\n    options &&\n    options.reporterOptions &&\n    options.reporterOptions.showRelativePaths\n  ) {\n    return path.relative(process.cwd(), filepath);\n  }\n\n  return filepath;\n}\n\nexports = module.exports = XUnit;\n"
  },
  {
    "path": "lib/runnable.js",
    "content": "\"use strict\";\n\nvar EventEmitter = require(\"node:events\").EventEmitter;\nvar PendingError = require(\"./pending\");\nvar debug = require(\"debug\")(\"mocha:runnable\");\nvar milliseconds = require(\"ms\");\nvar utils = require(\"./utils\");\nconst {\n  createInvalidExceptionError,\n  createMultipleDoneError,\n  createTimeoutError,\n} = require(\"./errors\");\n\n/**\n * Save timer references to avoid Sinon interfering (see GH-237).\n * @private\n */\nvar Date = global.Date;\nvar setTimeout = global.setTimeout;\nvar clearTimeout = global.clearTimeout;\nvar toString = Object.prototype.toString;\n\nvar MAX_TIMEOUT = Math.pow(2, 31) - 1;\n\nclass Runnable extends EventEmitter {\n  // \"Additional properties\" doc comment added for hosted docs (mochajs.org/api)\n  /**\n   * Initialize a new `Runnable` with the given `title` and callback `fn`.\n   * Additional properties, like `getFullTitle()` and `slow()`, can be viewed in the `Runnable` source.\n   *\n   * @extends external:EventEmitter\n   * @public\n   * @param {String} title\n   * @param {Function} fn\n   */\n  constructor(title, fn) {\n    super(title, fn);\n    this.title = title;\n    this.fn = fn;\n    this.body = (fn || \"\").toString();\n    this.async = fn && fn.length;\n    this.sync = !this.async;\n    this._timeout = 2000;\n    this._slow = 75;\n    this._retries = -1;\n    utils.assignNewMochaID(this);\n    Object.defineProperty(this, \"id\", {\n      get() {\n        return utils.getMochaID(this);\n      },\n    });\n    this.reset();\n  }\n\n  /**\n   * Resets the state initially or for a next run.\n   */\n  reset() {\n    this.timedOut = false;\n    this._currentRetry = 0;\n    this.pending = false;\n    delete this.state;\n    delete this.err;\n  }\n\n  /**\n   * Get current timeout value in msecs.\n   *\n   * @private\n   * @returns {number} current timeout threshold value\n   */\n  /**\n   * @summary\n   * Set timeout threshold value (msecs).\n   *\n   * @description\n   * A string argument can use shorthand (e.g., \"2s\") and will be converted.\n   * The value will be clamped to range [<code>0</code>, <code>2^<sup>31</sup>-1</code>].\n   * If clamped value matches either range endpoint, timeouts will be disabled.\n   *\n   * @private\n   * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout#Maximum_delay_value}\n   * @param {number|string} ms - Timeout threshold value.\n   * @returns {Runnable} this\n   * @chainable\n   */\n  timeout(ms) {\n    if (!arguments.length) {\n      return this._timeout;\n    }\n    if (typeof ms === \"string\") {\n      ms = milliseconds(ms);\n    }\n\n    // Clamp to range\n    var range = [0, MAX_TIMEOUT];\n    ms = utils.clamp(ms, range);\n\n    // see #1652 for reasoning\n    if (ms === range[0] || ms === range[1]) {\n      this._timeout = 0;\n    } else {\n      this._timeout = ms;\n    }\n    debug(\"timeout %d\", this._timeout);\n\n    if (this.timer) {\n      this.resetTimeout();\n    }\n    return this;\n  }\n\n  /**\n   * Set or get slow `ms`.\n   *\n   * @private\n   * @param {number|string} ms\n   * @return {Runnable|number} ms or Runnable instance.\n   */\n  slow(ms) {\n    if (!arguments.length || typeof ms === \"undefined\") {\n      return this._slow;\n    }\n    if (typeof ms === \"string\") {\n      ms = milliseconds(ms);\n    }\n    debug(\"slow %d\", ms);\n    this._slow = ms;\n    return this;\n  }\n\n  /**\n   * Halt and mark as pending.\n   *\n   * @memberof Mocha.Runnable\n   * @public\n   */\n  skip() {\n    this.pending = true;\n    throw new PendingError(\"sync skip; aborting execution\");\n  }\n\n  /**\n   * Check if this runnable or its parent suite is marked as pending.\n   *\n   * @private\n   */\n  isPending() {\n    return this.pending || (this.parent && this.parent.isPending());\n  }\n\n  /**\n   * Return `true` if this Runnable has failed.\n   * @return {boolean}\n   * @private\n   */\n  isFailed() {\n    return !this.isPending() && this.state === Runnable.constants.STATE_FAILED;\n  }\n\n  /**\n   * Return `true` if this Runnable has passed.\n   * @return {boolean}\n   * @private\n   */\n  isPassed() {\n    return !this.isPending() && this.state === Runnable.constants.STATE_PASSED;\n  }\n\n  /**\n   * Set or get number of retries.\n   *\n   * @private\n   */\n  retries(n) {\n    if (!arguments.length) {\n      return this._retries;\n    }\n    this._retries = n;\n  }\n\n  /**\n   * Set or get current retry\n   *\n   * @private\n   */\n  currentRetry(n) {\n    if (!arguments.length) {\n      return this._currentRetry;\n    }\n    this._currentRetry = n;\n  }\n\n  /**\n   * Return the full title generated by recursively concatenating the parent's\n   * full title.\n   *\n   * @memberof Mocha.Runnable\n   * @public\n   * @return {string}\n   */\n  fullTitle() {\n    return this.titlePath().join(\" \");\n  }\n\n  /**\n   * Return the title path generated by concatenating the parent's title path with the title.\n   *\n   * @memberof Mocha.Runnable\n   * @public\n   * @return {string[]}\n   */\n  titlePath() {\n    return this.parent.titlePath().concat([this.title]);\n  }\n\n  /**\n   * Clear the timeout.\n   *\n   * @private\n   */\n  clearTimeout() {\n    clearTimeout(this.timer);\n  }\n\n  /**\n   * Reset the timeout.\n   *\n   * @private\n   */\n  resetTimeout() {\n    var self = this;\n    var ms = this.timeout() || MAX_TIMEOUT;\n\n    this.clearTimeout();\n    this.timer = setTimeout(function () {\n      if (self.timeout() === 0) {\n        return;\n      }\n      self.callback(self._timeoutError(ms));\n      self.timedOut = true;\n    }, ms);\n  }\n\n  /**\n   * Set or get a list of whitelisted globals for this test run.\n   *\n   * @private\n   * @param {string[]} globals\n   */\n  globals(globals) {\n    if (!arguments.length) {\n      return this._allowedGlobals;\n    }\n    this._allowedGlobals = globals;\n  }\n\n  /**\n   * Run the test and invoke `fn(err)`.\n   *\n   * @param {Function} fn\n   * @private\n   */\n  run(fn) {\n    var self = this;\n    var start = new Date();\n    var ctx = this.ctx;\n    var finished;\n    var errorWasHandled = false;\n\n    if (this.isPending()) return fn();\n\n    // Sometimes the ctx exists, but it is not runnable\n    if (ctx && ctx.runnable) {\n      ctx.runnable(this);\n    }\n\n    // called multiple times\n    function multiple(err) {\n      if (errorWasHandled) {\n        return;\n      }\n      errorWasHandled = true;\n      self.emit(\"error\", createMultipleDoneError(self, err));\n    }\n\n    // finished\n    function done(err) {\n      var ms = self.timeout();\n      if (self.timedOut) {\n        return;\n      }\n\n      if (finished) {\n        return multiple(err);\n      }\n\n      self.clearTimeout();\n      self.duration = new Date() - start;\n      finished = true;\n      if (!err && self.duration > ms && ms > 0) {\n        err = self._timeoutError(ms);\n      }\n      fn(err);\n    }\n\n    // for .resetTimeout() and Runner#uncaught()\n    this.callback = done;\n\n    if (this.fn && typeof this.fn.call !== \"function\") {\n      done(\n        new TypeError(\n          \"A runnable must be passed a function as its second argument.\",\n        ),\n      );\n      return;\n    }\n\n    // explicit async with `done` argument\n    if (this.async) {\n      this.resetTimeout();\n\n      // allows skip() to be used in an explicit async context\n      this.skip = function asyncSkip() {\n        this.pending = true;\n        done();\n        // halt execution, the uncaught handler will ignore the failure.\n        throw new PendingError(\"async skip; aborting execution\");\n      };\n\n      try {\n        callFnAsync(this.fn);\n      } catch (err) {\n        // handles async runnables which actually run synchronously\n        errorWasHandled = true;\n        if (err instanceof PendingError) {\n          return; // done() is already called in this.skip()\n        } else if (this.allowUncaught) {\n          throw err;\n        }\n        done(Runnable.toValueOrError(err));\n      }\n      return;\n    }\n\n    // sync or promise-returning\n    try {\n      callFn(this.fn);\n    } catch (err) {\n      errorWasHandled = true;\n      if (err instanceof PendingError) {\n        return done();\n      } else if (this.allowUncaught) {\n        throw err;\n      }\n      done(Runnable.toValueOrError(err));\n    }\n\n    function callFn(fn) {\n      var result = fn.call(ctx);\n      if (result && typeof result.then === \"function\") {\n        self.resetTimeout();\n        result.then(\n          function () {\n            done();\n            // Return null so libraries like bluebird do not warn about\n            // subsequently constructed Promises.\n            return null;\n          },\n          function (reason) {\n            done(\n              reason || new Error(\"Promise rejected with no or falsy reason\"),\n            );\n          },\n        );\n      } else {\n        if (self.asyncOnly) {\n          return done(\n            new Error(\n              \"--async-only option in use without declaring `done()` or returning a promise\",\n            ),\n          );\n        }\n\n        done();\n      }\n    }\n\n    function callFnAsync(fn) {\n      var result = fn.call(ctx, function (err) {\n        if (err instanceof Error || toString.call(err) === \"[object Error]\") {\n          return done(err);\n        }\n        if (err) {\n          if (Object.prototype.toString.call(err) === \"[object Object]\") {\n            return done(\n              new Error(\n                \"done() invoked with non-Error: \" + JSON.stringify(err),\n              ),\n            );\n          }\n          return done(new Error(\"done() invoked with non-Error: \" + err));\n        }\n        if (result && utils.isPromise(result)) {\n          return done(\n            new Error(\n              \"Resolution method is overspecified. Specify a callback *or* return a Promise; not both.\",\n            ),\n          );\n        }\n\n        done();\n      });\n    }\n  }\n\n  /**\n   * Instantiates a \"timeout\" error\n   *\n   * @param {number} ms - Timeout (in milliseconds)\n   * @returns {Error} a \"timeout\" error\n   * @private\n   */\n  _timeoutError(ms) {\n    let msg = `Timeout of ${ms}ms exceeded. For async tests and hooks, ensure \"done()\" is called; if returning a Promise, ensure it resolves.`;\n    if (this.file) {\n      msg += \" (\" + this.file + \")\";\n    }\n    return createTimeoutError(msg, ms, this.file);\n  }\n\n  static constants = utils.defineConstants(\n    /**\n     * {@link Runnable}-related Runnable.constants.\n     * @public\n     * @memberof Runnable\n     * @readonly\n     * @static\n     * @alias constants\n     * @enum {string}\n     */\n    {\n      /**\n       * Value of `state` prop when a `Runnable` has failed\n       */\n      STATE_FAILED: \"failed\",\n      /**\n       * Value of `state` prop when a `Runnable` has passed\n       */\n      STATE_PASSED: \"passed\",\n      /**\n       * Value of `state` prop when a `Runnable` has been skipped by user\n       */\n      STATE_PENDING: \"pending\",\n    },\n  );\n\n  /**\n   * Given `value`, return identity if truthy, otherwise create an \"invalid exception\" error and return that.\n   * @param {*} [value] - Value to return, if present\n   * @returns {*|Error} `value`, otherwise an `Error`\n   * @private\n   */\n  static toValueOrError(value) {\n    return (\n      value ||\n      createInvalidExceptionError(\n        \"Runnable failed with falsy or undefined exception. Please throw an Error instead.\",\n        value,\n      )\n    );\n  }\n}\n\nmodule.exports = Runnable;\n"
  },
  {
    "path": "lib/runner.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('./types.d.ts').RunnerOptions} RunnerOptions\n */\n\n/**\n * Module dependencies.\n * @private\n */\nvar EventEmitter = require(\"node:events\").EventEmitter;\nvar PendingError = require(\"./pending\");\nvar utils = require(\"./utils\");\nvar debug = require(\"debug\")(\"mocha:runner\");\nvar Runnable = require(\"./runnable\");\nvar Suite = require(\"./suite\");\nvar HOOK_TYPE_BEFORE_EACH = Suite.constants.HOOK_TYPE_BEFORE_EACH;\nvar HOOK_TYPE_AFTER_EACH = Suite.constants.HOOK_TYPE_AFTER_EACH;\nvar HOOK_TYPE_AFTER_ALL = Suite.constants.HOOK_TYPE_AFTER_ALL;\nvar HOOK_TYPE_BEFORE_ALL = Suite.constants.HOOK_TYPE_BEFORE_ALL;\nvar EVENT_ROOT_SUITE_RUN = Suite.constants.EVENT_ROOT_SUITE_RUN;\nvar STATE_FAILED = Runnable.constants.STATE_FAILED;\nvar STATE_PASSED = Runnable.constants.STATE_PASSED;\nvar STATE_PENDING = Runnable.constants.STATE_PENDING;\nvar stackFilter = utils.stackTraceFilter();\nvar stringify = utils.stringify;\n\nconst {\n  createInvalidExceptionError,\n  createUnsupportedError,\n  createFatalError,\n  isMochaError,\n} = require(\"./errors\");\nconst { constants: errorConstants } = require(\"./error-constants\");\n\n/**\n * Non-enumerable globals.\n * @private\n * @readonly\n */\nvar globals = [\n  \"setTimeout\",\n  \"clearTimeout\",\n  \"setInterval\",\n  \"clearInterval\",\n  \"XMLHttpRequest\",\n  \"Date\",\n  \"setImmediate\",\n  \"clearImmediate\",\n];\n\nvar constants = utils.defineConstants(\n  /**\n   * {@link Runner}-related constants. Used by reporters. Each event emits the corresponding object, unless otherwise indicated.\n   * @example\n   * const Mocha = require('mocha');\n   * const Base = Mocha.reporters.Base;\n   * const {\n   *   EVENT_HOOK_BEGIN,\n   *   EVENT_TEST_PASS,\n   *   EVENT_TEST_FAIL,\n   *   EVENT_TEST_END\n   * } = Mocha.Runner.constants\n   *\n   * function MyReporter(runner, options) {\n   *   Base.call(this, runner, options);\n   *\n   *   runner.on(EVENT_HOOK_BEGIN, function(hook) {\n   *     console.log('hook called: ', hook.title);\n   *   });\n   *\n   *   runner.on(EVENT_TEST_PASS, function(test) {\n   *     console.log('pass: %s', test.fullTitle());\n   *   });\n   *\n   *   runner.on(EVENT_TEST_FAIL, function(test, err) {\n   *     console.log('fail: %s -- error: %s', test.fullTitle(), err.message);\n   *   });\n   *\n   *   runner.on(EVENT_TEST_END, function() {\n   *     console.log('end: %d/%d', runner.stats.passes, runner.stats.tests);\n   *   });\n   * }\n   *\n   * module.exports = MyReporter;\n   *\n   * @public\n   * @memberof Runner\n   * @readonly\n   * @alias constants\n   * @static\n   * @enum {string}\n   */\n  {\n    /**\n     * Emitted when {@link Hook} execution begins\n     */\n    EVENT_HOOK_BEGIN: \"hook\",\n    /**\n     * Emitted when {@link Hook} execution ends\n     */\n    EVENT_HOOK_END: \"hook end\",\n    /**\n     * Emitted when Root {@link Suite} execution begins (all files have been parsed and hooks/tests are ready for execution)\n     */\n    EVENT_RUN_BEGIN: \"start\",\n    /**\n     * Emitted when Root {@link Suite} execution has been delayed via `delay` option\n     */\n    EVENT_DELAY_BEGIN: \"waiting\",\n    /**\n     * Emitted when delayed Root {@link Suite} execution is triggered by user via `global.run()`\n     */\n    EVENT_DELAY_END: \"ready\",\n    /**\n     * Emitted when Root {@link Suite} execution ends\n     */\n    EVENT_RUN_END: \"end\",\n    /**\n     * Emitted when {@link Suite} execution begins\n     */\n    EVENT_SUITE_BEGIN: \"suite\",\n    /**\n     * Emitted when {@link Suite} execution ends\n     */\n    EVENT_SUITE_END: \"suite end\",\n    /**\n     * Emitted when {@link Test} execution begins\n     */\n    EVENT_TEST_BEGIN: \"test\",\n    /**\n     * Emitted when {@link Test} execution ends\n     */\n    EVENT_TEST_END: \"test end\",\n    /**\n     * Emitted when {@link Test} execution fails. Includes an `err` object of type `Error`.\n     * @example\n     * runner.on(EVENT_TEST_FAIL, function(test, err) {\n     *   console.log('fail: %s -- error: %s', test.fullTitle(), err.message);\n     * });\n     *\n     *\n     */\n    EVENT_TEST_FAIL: \"fail\",\n    /**\n     * Emitted when {@link Test} execution succeeds\n     */\n    EVENT_TEST_PASS: \"pass\",\n    /**\n     * Emitted when {@link Test} becomes pending\n     */\n    EVENT_TEST_PENDING: \"pending\",\n    /**\n     * Emitted when {@link Test} execution has failed, but will retry\n     */\n    EVENT_TEST_RETRY: \"retry\",\n    /**\n     * Initial state of Runner\n     */\n    STATE_IDLE: \"idle\",\n    /**\n     * State set to this value when the Runner has started running\n     */\n    STATE_RUNNING: \"running\",\n    /**\n     * State set to this value when the Runner has stopped\n     */\n    STATE_STOPPED: \"stopped\",\n  },\n);\n\nclass Runner extends EventEmitter {\n  /**\n   * Initialize a `Runner` at the Root {@link Suite}, which represents a hierarchy of {@link Suite|Suites} and {@link Test|Tests}.\n   *\n   * @extends external:EventEmitter\n   * @public\n   * @class\n   * @param {Suite} suite - Root suite\n   * @param {Object} [opts] - Settings object\n   * @param {boolean} [opts.cleanReferencesAfterRun] - Whether to clean references to test fns and hooks when a suite is done.\n   * @param {boolean} [opts.delay] - Whether to delay execution of root suite until ready.\n   * @param {boolean} [opts.dryRun] - Whether to report tests without running them.\n   * @param {boolean} [opts.failZero] - Whether to fail test run if zero tests encountered.\n   * @param {boolean} [opts.failHookAffectedTests] - Whether to fail all tests affected by hook failures.\n   */\n  constructor(suite, opts = {}) {\n    super();\n\n    var self = this;\n    this._globals = [];\n    this._abort = false;\n    this.suite = suite;\n    this._opts = opts;\n    this.state = constants.STATE_IDLE;\n    this.total = suite.total();\n    this.failures = 0;\n    /**\n     * @type {Map<EventEmitter,Map<string,Set<EventListener>>>}\n     */\n    this._eventListeners = new Map();\n    this.on(constants.EVENT_TEST_END, function (test) {\n      if (test.type === \"test\" && test.retriedTest() && test.parent) {\n        var idx =\n          test.parent.tests && test.parent.tests.indexOf(test.retriedTest());\n        if (idx > -1) test.parent.tests[idx] = test;\n      }\n      self.checkGlobals(test);\n    });\n    this.on(constants.EVENT_HOOK_END, function (hook) {\n      self.checkGlobals(hook);\n    });\n    this._defaultGrep = /.*/;\n    this.grep(this._defaultGrep);\n    this.globals(this.globalProps());\n\n    this.uncaught = this._uncaught.bind(this);\n    this.unhandled = (reason, promise) => {\n      if (isMochaError(reason)) {\n        debug(\n          \"trapped unhandled rejection coming out of Mocha; forwarding to uncaught handler:\",\n          reason,\n        );\n        this.uncaught(reason);\n      } else {\n        debug(\n          \"trapped unhandled rejection from (probably) user code; re-emitting on process\",\n        );\n        this._removeEventListener(\n          process,\n          \"unhandledRejection\",\n          this.unhandled,\n        );\n        try {\n          process.emit(\"unhandledRejection\", reason, promise);\n        } finally {\n          this._addEventListener(process, \"unhandledRejection\", this.unhandled);\n        }\n      }\n    };\n  }\n}\n\n/**\n * Wrapper for setImmediate, process.nextTick, or browser polyfill.\n *\n * @param {Function} fn\n * @private\n */\nRunner.immediately = global.setImmediate || process.nextTick;\n\n/**\n * Replacement for `target.on(eventName, listener)` that does bookkeeping to remove them when this runner instance is disposed.\n * @param {EventEmitter} target - The `EventEmitter`\n * @param {string} eventName - The event name\n * @param {string} fn - Listener function\n * @private\n */\nRunner.prototype._addEventListener = function (target, eventName, listener) {\n  debug(\n    \"_addEventListener(): adding for event %s; %d current listeners\",\n    eventName,\n    target.listenerCount(eventName),\n  );\n  /* istanbul ignore next */\n  if (\n    this._eventListeners.has(target) &&\n    this._eventListeners.get(target).has(eventName) &&\n    this._eventListeners.get(target).get(eventName).has(listener)\n  ) {\n    debug(\n      \"warning: tried to attach duplicate event listener for %s\",\n      eventName,\n    );\n    return;\n  }\n  target.on(eventName, listener);\n  const targetListeners = this._eventListeners.has(target)\n    ? this._eventListeners.get(target)\n    : new Map();\n  const targetEventListeners = targetListeners.has(eventName)\n    ? targetListeners.get(eventName)\n    : new Set();\n  targetEventListeners.add(listener);\n  targetListeners.set(eventName, targetEventListeners);\n  this._eventListeners.set(target, targetListeners);\n};\n\n/**\n * Replacement for `target.removeListener(eventName, listener)` that also updates the bookkeeping.\n * @param {EventEmitter} target - The `EventEmitter`\n * @param {string} eventName - The event name\n * @param {function} listener - Listener function\n * @private\n */\nRunner.prototype._removeEventListener = function (target, eventName, listener) {\n  target.removeListener(eventName, listener);\n\n  if (this._eventListeners.has(target)) {\n    const targetListeners = this._eventListeners.get(target);\n    if (targetListeners.has(eventName)) {\n      const targetEventListeners = targetListeners.get(eventName);\n      targetEventListeners.delete(listener);\n      if (!targetEventListeners.size) {\n        targetListeners.delete(eventName);\n      }\n    }\n    if (!targetListeners.size) {\n      this._eventListeners.delete(target);\n    }\n  } else {\n    debug(\"trying to remove listener for untracked object %s\", target);\n  }\n};\n\n/**\n * Removes all event handlers set during a run on this instance.\n * Remark: this does _not_ clean/dispose the tests or suites themselves.\n */\nRunner.prototype.dispose = function () {\n  this.removeAllListeners();\n  this._eventListeners.forEach((targetListeners, target) => {\n    targetListeners.forEach((targetEventListeners, eventName) => {\n      targetEventListeners.forEach((listener) => {\n        target.removeListener(eventName, listener);\n      });\n    });\n  });\n  this._eventListeners.clear();\n};\n\n/**\n * Run tests with full titles matching `re`. Updates runner.total\n * with number of tests matched.\n *\n * @public\n * @memberof Runner\n * @param {RegExp} re\n * @param {boolean} invert\n * @return {Runner} Runner instance.\n */\nRunner.prototype.grep = function (re, invert) {\n  debug(\"grep(): setting to %s\", re);\n  this._grep = re;\n  this._invert = invert;\n  this.total = this.grepTotal(this.suite);\n  return this;\n};\n\n/**\n * Returns the number of tests matching the grep search for the\n * given suite.\n *\n * @memberof Runner\n * @public\n * @param {Suite} suite\n * @return {number}\n */\nRunner.prototype.grepTotal = function (suite) {\n  var self = this;\n  var total = 0;\n\n  suite.eachTest(function (test) {\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (match) {\n      total++;\n    }\n  });\n\n  return total;\n};\n\n/**\n * Return a list of global properties.\n *\n * @return {Array}\n * @private\n */\nRunner.prototype.globalProps = function () {\n  var props = Object.keys(global);\n\n  // non-enumerables\n  for (var i = 0; i < globals.length; ++i) {\n    if (~props.indexOf(globals[i])) {\n      continue;\n    }\n    props.push(globals[i]);\n  }\n\n  return props;\n};\n\n/**\n * Allow the given `arr` of globals.\n *\n * @public\n * @memberof Runner\n * @param {Array} arr\n * @return {Runner} Runner instance.\n */\nRunner.prototype.globals = function (arr) {\n  if (!arguments.length) {\n    return this._globals;\n  }\n  debug(\"globals(): setting to %O\", arr);\n  this._globals = this._globals.concat(arr);\n  return this;\n};\n\n/**\n * Check for global variable leaks.\n *\n * @private\n */\nRunner.prototype.checkGlobals = function (test) {\n  if (!this.checkLeaks) {\n    return;\n  }\n  var ok = this._globals;\n\n  var globals = this.globalProps();\n  var leaks;\n\n  if (test) {\n    ok = ok.concat(test._allowedGlobals || []);\n  }\n\n  if (this.prevGlobalsLength === globals.length) {\n    return;\n  }\n  this.prevGlobalsLength = globals.length;\n\n  leaks = filterLeaks(ok, globals);\n  this._globals = this._globals.concat(leaks);\n\n  if (leaks.length) {\n    var msg = `global leak(s) detected: ${leaks.map((e) => `'${e}'`).join(\", \")}`;\n    this.fail(test, new Error(msg));\n  }\n};\n\n/**\n * Create an error object for a test that was skipped due to a hook failure.\n *\n * @private\n * @param {string} hookTitle - The title of the failed hook\n * @param {*} hookError - The error from the failed hook (may not be an Error object)\n * @returns {Error} The error object for the skipped test\n */\nfunction createHookSkipError(hookTitle, hookError) {\n  // Handle falsy or undefined exceptions\n  if (!hookError) {\n    hookError = createInvalidExceptionError(\n      'Hook \"' + hookTitle + '\" failed with exception: ' + hookError,\n      hookError,\n    );\n  }\n  // Convert non-Error objects to Error\n  else if (!isError(hookError)) {\n    hookError = thrown2Error(hookError);\n  }\n\n  var errorMessage =\n    'Test skipped due to failure in hook \"' +\n    hookTitle +\n    '\": ' +\n    hookError.message;\n  var testError = new Error(errorMessage);\n  testError.stack = hookError.stack;\n  return testError;\n}\n\n/**\n * Fail all tests that are affected by a hook failure.\n * This is used when the `failHookAffectedTests` option is enabled.\n *\n * @private\n * @param {Suite} suite - The suite containing the affected tests\n * @param {Error} hookError - The error from the failed hook\n * @param {string} hookTitle - The title of the failed hook\n */\nRunner.prototype.failAffectedTests = function (suite, hookError, hookTitle) {\n  if (!this._opts.failHookAffectedTests) {\n    return;\n  }\n\n  var self = this;\n  var testError = createHookSkipError(hookTitle, hookError);\n\n  // Recursively fail all tests in this suite and its child suites\n  function failTestsInSuite(s) {\n    s.tests.forEach(function (test) {\n      // Only fail tests that haven't been executed yet\n      if (!test.state) {\n        test.state = STATE_FAILED;\n        self.failures++;\n        self.emit(constants.EVENT_TEST_BEGIN, test);\n        self.emit(constants.EVENT_TEST_FAIL, test, testError);\n        self.emit(constants.EVENT_TEST_END, test);\n      }\n    });\n\n    s.suites.forEach(failTestsInSuite);\n  }\n\n  failTestsInSuite(suite);\n};\n\n/**\n * Fail the given `test`.\n *\n * If `test` is a hook, failures work in the following pattern:\n * - If bail, run corresponding `after each` and `after` hooks,\n *   then exit\n * - Failed `before` hook skips all tests in a suite and subsuites,\n *   but jumps to corresponding `after` hook\n * - Failed `before each` hook skips remaining tests in a\n *   suite and jumps to corresponding `after each` hook,\n *   which is run only once\n * - Failed `after` hook does not alter execution order\n * - Failed `after each` hook skips remaining tests in a\n *   suite and subsuites, but executes other `after each`\n *   hooks\n *\n * @private\n * @param {Runnable} test\n * @param {Error} err\n * @param {boolean} [force=false] - Whether to fail a pending test.\n */\nRunner.prototype.fail = function (test, err, force) {\n  force = force === true;\n  if (test.isPending() && !force) {\n    return;\n  }\n  if (this.state === constants.STATE_STOPPED) {\n    if (err.code === errorConstants.MULTIPLE_DONE) {\n      throw err;\n    }\n    throw createFatalError(\n      \"Test failed after root suite execution completed!\",\n      err,\n    );\n  }\n\n  ++this.failures;\n  debug(\"total number of failures: %d\", this.failures);\n  test.state = STATE_FAILED;\n\n  if (!isError(err)) {\n    err = thrown2Error(err);\n  }\n\n  // Filter the stack traces\n  if (!this.fullStackTrace) {\n    const alreadyFiltered = new Set();\n    let currentErr = err;\n\n    while (currentErr && currentErr.stack && !alreadyFiltered.has(currentErr)) {\n      alreadyFiltered.add(currentErr);\n\n      try {\n        currentErr.stack = stackFilter(currentErr.stack);\n      } catch {\n        // Ignore error as some environments do not take kindly to monkeying with the stack\n      }\n\n      currentErr = currentErr.cause;\n    }\n  }\n\n  this.emit(constants.EVENT_TEST_FAIL, test, err);\n};\n\n/**\n * Run hook `name` callbacks and then invoke `fn()`.\n *\n * @private\n * @param {string} name\n * @param {Function} fn\n */\n\nRunner.prototype.hook = function (name, fn) {\n  if (this._opts.dryRun) return fn();\n\n  var suite = this.suite;\n  var hooks = suite.getHooks(name);\n  var self = this;\n\n  function next(i) {\n    var hook = hooks[i];\n    if (!hook) {\n      return fn();\n    }\n    self.currentRunnable = hook;\n\n    if (name === HOOK_TYPE_BEFORE_ALL) {\n      hook.ctx.currentTest = hook.parent.tests[0];\n    } else if (name === HOOK_TYPE_AFTER_ALL) {\n      hook.ctx.currentTest = hook.parent.tests[hook.parent.tests.length - 1];\n    } else {\n      hook.ctx.currentTest = self.test;\n    }\n\n    setHookTitle(hook);\n\n    hook.allowUncaught = self.allowUncaught;\n\n    self.emit(constants.EVENT_HOOK_BEGIN, hook);\n\n    if (!hook.listeners(\"error\").length) {\n      self._addEventListener(hook, \"error\", function (err) {\n        self.fail(hook, err);\n      });\n    }\n\n    hook.run(function cbHookRun(err) {\n      var testError = hook.error();\n      if (testError) {\n        self.fail(self.test, testError);\n      }\n      // conditional skip\n      if (hook.pending) {\n        if (name === HOOK_TYPE_AFTER_EACH) {\n          // TODO define and implement use case\n          if (self.test) {\n            self.test.pending = true;\n          }\n        } else if (name === HOOK_TYPE_BEFORE_EACH) {\n          if (self.test) {\n            self.test.pending = true;\n          }\n          self.emit(constants.EVENT_HOOK_END, hook);\n          hook.pending = false; // activates hook for next test\n          return fn(new Error(\"abort hookDown\"));\n        } else if (name === HOOK_TYPE_BEFORE_ALL) {\n          suite.tests.forEach(function (test) {\n            test.pending = true;\n          });\n          suite.suites.forEach(function (suite) {\n            suite.pending = true;\n          });\n          hooks = [];\n        } else {\n          hook.pending = false;\n          var errForbid = createUnsupportedError(\"`this.skip` forbidden\");\n          self.fail(hook, errForbid);\n          return fn(errForbid);\n        }\n      } else if (err) {\n        self.fail(hook, err);\n        // If failHookAffectedTests is enabled, mark affected tests as failed\n        if (self._opts.failHookAffectedTests) {\n          if (name === HOOK_TYPE_BEFORE_ALL) {\n            self.failAffectedTests(self.suite, err, hook.title);\n          } else if (name === HOOK_TYPE_BEFORE_EACH) {\n            // Fail the current test\n            if (self.test && !self.test.state) {\n              var testError = createHookSkipError(hook.title, err);\n\n              self.test.state = STATE_FAILED;\n              self.failures++;\n              self.emit(constants.EVENT_TEST_BEGIN, self.test);\n              self.emit(constants.EVENT_TEST_FAIL, self.test, testError);\n              self.emit(constants.EVENT_TEST_END, self.test);\n            }\n            // Store the hook error info for remaining tests\n            self._failedBeforeEachHook = {\n              error: err,\n              title: hook.title,\n            };\n          }\n        }\n        // stop executing hooks, notify callee of hook err\n        return fn(err);\n      }\n      self.emit(constants.EVENT_HOOK_END, hook);\n      delete hook.ctx.currentTest;\n      setHookTitle(hook);\n      next(++i);\n    });\n\n    function setHookTitle(hook) {\n      hook.originalTitle = hook.originalTitle || hook.title;\n      if (hook.ctx && hook.ctx.currentTest) {\n        hook.title = `${hook.originalTitle} for \"${hook.ctx.currentTest.title}\"`;\n      } else {\n        var parentTitle;\n        if (hook.parent.title) {\n          parentTitle = hook.parent.title;\n        } else {\n          parentTitle = hook.parent.root ? \"{root}\" : \"\";\n        }\n        hook.title = `${hook.originalTitle} in \"${parentTitle}\"`;\n      }\n    }\n  }\n\n  Runner.immediately(function () {\n    next(0);\n  });\n};\n\n/**\n * Run hook `name` for the given array of `suites`\n * in order, and callback `fn(err, errSuite)`.\n *\n * @private\n * @param {string} name\n * @param {Array} suites\n * @param {Function} fn\n */\nRunner.prototype.hooks = function (name, suites, fn) {\n  var self = this;\n  var orig = this.suite;\n\n  function next(suite) {\n    self.suite = suite;\n\n    if (!suite) {\n      self.suite = orig;\n      return fn();\n    }\n\n    self.hook(name, function (err) {\n      if (err) {\n        var errSuite = self.suite;\n        self.suite = orig;\n        return fn(err, errSuite);\n      }\n\n      next(suites.pop());\n    });\n  }\n\n  next(suites.pop());\n};\n\n/**\n * Run 'afterEach' hooks from bottom up.\n *\n * @param {String} name\n * @param {Function} fn\n * @private\n */\nRunner.prototype.hookUp = function (name, fn) {\n  var suites = [this.suite].concat(this.parents()).reverse();\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Run 'beforeEach' hooks from top level down.\n *\n * @param {String} name\n * @param {Function} fn\n * @private\n */\nRunner.prototype.hookDown = function (name, fn) {\n  var suites = [this.suite].concat(this.parents());\n  this.hooks(name, suites, fn);\n};\n\n/**\n * Return an array of parent Suites from\n * closest to furthest.\n *\n * @return {Array}\n * @private\n */\nRunner.prototype.parents = function () {\n  var suite = this.suite;\n  var suites = [];\n  while (suite.parent) {\n    suite = suite.parent;\n    suites.push(suite);\n  }\n  return suites;\n};\n\n/**\n * Run the current test and callback `fn(err)`.\n *\n * @param {Function} fn\n * @private\n */\nRunner.prototype.runTest = function (fn) {\n  if (this._opts.dryRun) return Runner.immediately(fn);\n\n  var self = this;\n  var test = this.test;\n\n  if (!test) {\n    return;\n  }\n\n  if (this.asyncOnly) {\n    test.asyncOnly = true;\n  }\n  this._addEventListener(test, \"error\", function (err) {\n    self.fail(test, err);\n  });\n  if (this.allowUncaught) {\n    test.allowUncaught = true;\n    return test.run(fn);\n  }\n  try {\n    test.run(fn);\n  } catch (err) {\n    fn(err);\n  }\n};\n\n/**\n * Run tests in the given `suite` and invoke the callback `fn()` when complete.\n *\n * @private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runTests = function (suite, fn) {\n  var self = this;\n  var tests = suite.tests.slice();\n  var test;\n\n  function hookErr(err, errSuite, after) {\n    // before/after Each hook for errSuite failed:\n    var orig = self.suite;\n\n    // If failHookAffectedTests is enabled and this is a beforeEach failure,\n    // mark remaining tests as failed\n    if (\n      self._opts.failHookAffectedTests &&\n      !after &&\n      self._failedBeforeEachHook\n    ) {\n      // Fail all remaining tests in the suite\n      var remainingTests = tests.slice();\n      remainingTests.forEach(function (t) {\n        if (!t.state) {\n          var testError = createHookSkipError(\n            self._failedBeforeEachHook.title,\n            self._failedBeforeEachHook.error,\n          );\n\n          t.state = STATE_FAILED;\n          self.failures++;\n          self.emit(constants.EVENT_TEST_BEGIN, t);\n          self.emit(constants.EVENT_TEST_FAIL, t, testError);\n          self.emit(constants.EVENT_TEST_END, t);\n        }\n      });\n      // Clear the stored hook info\n      delete self._failedBeforeEachHook;\n    }\n\n    // for failed 'after each' hook start from errSuite parent,\n    // otherwise start from errSuite itself\n    self.suite = after ? errSuite.parent : errSuite;\n\n    if (self.suite) {\n      self.hookUp(HOOK_TYPE_AFTER_EACH, function (err2, errSuite2) {\n        self.suite = orig;\n        // some hooks may fail even now\n        if (err2) {\n          return hookErr(err2, errSuite2, true);\n        }\n        // report error suite\n        fn(errSuite);\n      });\n    } else {\n      // there is no need calling other 'after each' hooks\n      self.suite = orig;\n      fn(errSuite);\n    }\n  }\n\n  function next(err, errSuite) {\n    // if we bail after first err\n    if (self.failures && suite._bail) {\n      tests = [];\n    }\n\n    if (self._abort) {\n      return fn();\n    }\n\n    if (err) {\n      return hookErr(err, errSuite, true);\n    }\n\n    // next test\n    test = tests.shift();\n\n    // all done\n    if (!test) {\n      return fn();\n    }\n\n    // grep\n    var match = self._grep.test(test.fullTitle());\n    if (self._invert) {\n      match = !match;\n    }\n    if (!match) {\n      // Run immediately only if we have defined a grep. When we\n      // define a grep — It can cause maximum callstack error if\n      // the grep is doing a large recursive loop by neglecting\n      // all tests. The run immediately function also comes with\n      // a performance cost. So we don't want to run immediately\n      // if we run the whole test suite, because running the whole\n      // test suite don't do any immediate recursive loops. Thus,\n      // allowing a JS runtime to breathe.\n      if (self._grep !== self._defaultGrep) {\n        Runner.immediately(next);\n      } else {\n        next();\n      }\n      return;\n    }\n\n    // static skip, no hooks are executed\n    if (test.isPending()) {\n      if (self.forbidPending) {\n        self.fail(test, new Error(\"Pending test forbidden\"), true);\n      } else {\n        test.state = STATE_PENDING;\n        self.emit(constants.EVENT_TEST_PENDING, test);\n      }\n      self.emit(constants.EVENT_TEST_END, test);\n      return next();\n    }\n\n    // execute test and hook(s)\n    self.emit(constants.EVENT_TEST_BEGIN, (self.test = test));\n    self.hookDown(HOOK_TYPE_BEFORE_EACH, function (err, errSuite) {\n      // conditional skip within beforeEach\n      if (test.isPending()) {\n        if (self.forbidPending) {\n          self.fail(test, new Error(\"Pending test forbidden\"), true);\n        } else {\n          test.state = STATE_PENDING;\n          self.emit(constants.EVENT_TEST_PENDING, test);\n        }\n        self.emit(constants.EVENT_TEST_END, test);\n        // skip inner afterEach hooks below errSuite level\n        var origSuite = self.suite;\n        self.suite = errSuite || self.suite;\n        return self.hookUp(HOOK_TYPE_AFTER_EACH, function (e, eSuite) {\n          self.suite = origSuite;\n          next(e, eSuite);\n        });\n      }\n      if (err) {\n        return hookErr(err, errSuite, false);\n      }\n      self.currentRunnable = self.test;\n      self.runTest(function (err) {\n        test = self.test;\n        // conditional skip within it\n        if (test.pending) {\n          if (self.forbidPending) {\n            self.fail(test, new Error(\"Pending test forbidden\"), true);\n          } else {\n            test.state = STATE_PENDING;\n            self.emit(constants.EVENT_TEST_PENDING, test);\n          }\n          self.emit(constants.EVENT_TEST_END, test);\n          return self.hookUp(HOOK_TYPE_AFTER_EACH, next);\n        } else if (err) {\n          var retry = test.currentRetry();\n          if (retry < test.retries()) {\n            var clonedTest = test.clone();\n            clonedTest.currentRetry(retry + 1);\n            tests.unshift(clonedTest);\n\n            self.emit(constants.EVENT_TEST_RETRY, test, err);\n\n            // Early return + hook trigger so that it doesn't\n            // increment the count wrong\n            return self.hookUp(HOOK_TYPE_AFTER_EACH, next);\n          } else {\n            self.fail(test, err);\n          }\n          self.emit(constants.EVENT_TEST_END, test);\n          return self.hookUp(HOOK_TYPE_AFTER_EACH, next);\n        }\n\n        test.state = STATE_PASSED;\n        self.emit(constants.EVENT_TEST_PASS, test);\n        self.emit(constants.EVENT_TEST_END, test);\n        self.hookUp(HOOK_TYPE_AFTER_EACH, next);\n      });\n    });\n  }\n\n  this.next = next;\n  this.hookErr = hookErr;\n  next();\n};\n\n/**\n * Run the given `suite` and invoke the callback `fn()` when complete.\n *\n * @private\n * @param {Suite} suite\n * @param {Function} fn\n */\nRunner.prototype.runSuite = function (suite, fn) {\n  var i = 0;\n  var self = this;\n  var total = this.grepTotal(suite);\n\n  debug(\"runSuite(): running %s\", suite.fullTitle());\n\n  if (!total || (self.failures && suite._bail)) {\n    debug(\"runSuite(): bailing\");\n    return fn();\n  }\n\n  this.emit(constants.EVENT_SUITE_BEGIN, (this.suite = suite));\n\n  function next(errSuite) {\n    if (errSuite) {\n      // current suite failed on a hook from errSuite\n      if (errSuite === suite) {\n        // if errSuite is current suite\n        // continue to the next sibling suite\n        return done();\n      }\n      // errSuite is among the parents of current suite\n      // stop execution of errSuite and all sub-suites\n      return done(errSuite);\n    }\n\n    if (self._abort) {\n      return done();\n    }\n\n    var curr = suite.suites[i++];\n    if (!curr) {\n      return done();\n    }\n\n    // Avoid grep neglecting large number of tests causing a\n    // huge recursive loop and thus a maximum call stack error.\n    // See comment in `this.runTests()` for more information.\n    if (self._grep !== self._defaultGrep) {\n      Runner.immediately(function () {\n        self.runSuite(curr, next);\n      });\n    } else {\n      self.runSuite(curr, next);\n    }\n  }\n\n  function done(errSuite) {\n    self.suite = suite;\n    self.nextSuite = next;\n\n    // remove reference to test\n    delete self.test;\n\n    self.hook(HOOK_TYPE_AFTER_ALL, function () {\n      self.emit(constants.EVENT_SUITE_END, suite);\n      fn(errSuite);\n    });\n  }\n\n  this.nextSuite = next;\n\n  this.hook(HOOK_TYPE_BEFORE_ALL, function (err) {\n    if (err) {\n      return done();\n    }\n    self.runTests(suite, next);\n  });\n};\n\n/**\n * Handle uncaught exceptions within runner.\n *\n * This function is bound to the instance as `Runner#uncaught` at instantiation\n * time. It's intended to be listening on the `Process.uncaughtException` event.\n * In order to not leak EE listeners, we need to ensure no more than a single\n * `uncaughtException` listener exists per `Runner`.  The only way to do\n * this--because this function needs the context (and we don't have lambdas)--is\n * to use `Function.prototype.bind`. We need strict equality to unregister and\n * _only_ unregister the _one_ listener we set from the\n * `Process.uncaughtException` event; would be poor form to just remove\n * everything. See {@link Runner#run} for where the event listener is registered\n * and unregistered.\n * @param {Error} err - Some uncaught error\n * @private\n */\nRunner.prototype._uncaught = function (err) {\n  // this is defensive to prevent future developers from mis-calling this function.\n  // it's more likely that it'd be called with the incorrect context--say, the global\n  // `process` object--than it would to be called with a context that is not a \"subclass\"\n  // of `Runner`.\n  if (!(this instanceof Runner)) {\n    throw createFatalError(\n      \"Runner#uncaught() called with invalid context\",\n      this,\n    );\n  }\n  if (err instanceof PendingError) {\n    debug(\"uncaught(): caught a PendingError\");\n    return;\n  }\n  // browser does not exit script when throwing in global.onerror()\n  if (this.allowUncaught && !utils.isBrowser()) {\n    debug(\"uncaught(): bubbling exception due to --allow-uncaught\");\n    throw err;\n  }\n\n  if (this.state === constants.STATE_STOPPED) {\n    debug(\"uncaught(): throwing after run has completed!\");\n    throw err;\n  }\n\n  if (err) {\n    debug(\"uncaught(): got truthy exception %O\", err);\n  } else {\n    debug(\"uncaught(): undefined/falsy exception\");\n    err = createInvalidExceptionError(\n      \"Caught falsy/undefined exception which would otherwise be uncaught. No stack trace found; try a debugger\",\n      err,\n    );\n  }\n\n  if (!isError(err)) {\n    err = thrown2Error(err);\n    debug('uncaught(): converted \"error\" %o to Error', err);\n  }\n  err.uncaught = true;\n\n  var runnable = this.currentRunnable;\n\n  if (!runnable) {\n    runnable = new Runnable(\"Uncaught error outside test suite\");\n    debug(\"uncaught(): no current Runnable; created a phony one\");\n    runnable.parent = this.suite;\n\n    if (this.state === constants.STATE_RUNNING) {\n      debug(\"uncaught(): failing gracefully\");\n      this.fail(runnable, err);\n    } else {\n      // Can't recover from this failure\n      debug(\"uncaught(): test run has not yet started; unrecoverable\");\n      this.emit(constants.EVENT_RUN_BEGIN);\n      this.fail(runnable, err);\n      this.emit(constants.EVENT_RUN_END);\n    }\n\n    return;\n  }\n\n  runnable.clearTimeout();\n\n  if (runnable.isFailed()) {\n    debug(\"uncaught(): Runnable has already failed\");\n    // Ignore error if already failed\n    return;\n  } else if (runnable.isPending()) {\n    debug(\"uncaught(): pending Runnable wound up failing!\");\n    // report 'pending test' retrospectively as failed\n    this.fail(runnable, err, true);\n    return;\n  }\n\n  // we cannot recover gracefully if a Runnable has already passed\n  // then fails asynchronously\n  if (runnable.isPassed()) {\n    debug(\"uncaught(): Runnable has already passed; bailing gracefully\");\n    this.fail(runnable, err);\n    this.abort();\n  } else {\n    debug(\"uncaught(): forcing Runnable to complete with Error\");\n    return runnable.callback(err);\n  }\n};\n\n/**\n * Run the root suite and invoke `fn(failures)`\n * on completion.\n *\n * @public\n * @memberof Runner\n * @param {Function} fn - Callback when finished\n * @param {RunnerOptions} [opts] - For subclasses\n * @returns {Runner} Runner instance.\n */\nRunner.prototype.run = function (fn, opts = {}) {\n  var rootSuite = this.suite;\n  var options = opts.options || {};\n\n  debug(\"run(): got options: %O\", options);\n  fn = fn || function () {};\n\n  const end = () => {\n    if (!this.total && this._opts.failZero) this.failures = 1;\n\n    debug(\"run(): root suite completed; emitting %s\", constants.EVENT_RUN_END);\n    this.emit(constants.EVENT_RUN_END);\n  };\n\n  const begin = () => {\n    debug(\"run(): emitting %s\", constants.EVENT_RUN_BEGIN);\n    this.emit(constants.EVENT_RUN_BEGIN);\n    debug(\"run(): emitted %s\", constants.EVENT_RUN_BEGIN);\n\n    this.runSuite(rootSuite, end);\n  };\n\n  const prepare = () => {\n    debug(\"run(): starting\");\n    // If there is an `only` filter\n    if (rootSuite.hasOnly()) {\n      rootSuite.filterOnly();\n      debug(\"run(): filtered exclusive Runnables\");\n    }\n    this.state = constants.STATE_RUNNING;\n    if (this._opts.delay) {\n      this.emit(constants.EVENT_DELAY_END);\n      debug('run(): \"delay\" ended');\n    }\n\n    return begin();\n  };\n\n  // references cleanup to avoid memory leaks\n  if (this._opts.cleanReferencesAfterRun) {\n    this.on(constants.EVENT_SUITE_END, (suite) => {\n      suite.cleanReferences();\n    });\n  }\n\n  // callback\n  this.on(constants.EVENT_RUN_END, function () {\n    this.state = constants.STATE_STOPPED;\n    debug(\"run(): emitted %s\", constants.EVENT_RUN_END);\n    fn(this.failures);\n  });\n\n  this._removeEventListener(process, \"uncaughtException\", this.uncaught);\n  this._removeEventListener(process, \"unhandledRejection\", this.unhandled);\n  this._addEventListener(process, \"uncaughtException\", this.uncaught);\n  this._addEventListener(process, \"unhandledRejection\", this.unhandled);\n\n  if (this._opts.delay) {\n    // for reporters, I guess.\n    // might be nice to debounce some dots while we wait.\n    this.emit(constants.EVENT_DELAY_BEGIN, rootSuite);\n    rootSuite.once(EVENT_ROOT_SUITE_RUN, prepare);\n    debug(\"run(): waiting for green light due to --delay\");\n  } else {\n    Runner.immediately(prepare);\n  }\n\n  return this;\n};\n\n/**\n * Toggle partial object linking behavior; used for building object references from\n * unique ID's. Does nothing in serial mode, because the object references already exist.\n * Subclasses can implement this (e.g., `ParallelBufferedRunner`)\n * @abstract\n * @param {boolean} [value] - If `true`, enable partial object linking, otherwise disable\n * @returns {Runner}\n * @chainable\n * @public\n * @example\n * // this reporter needs proper object references when run in parallel mode\n * class MyReporter {\n *   constructor(runner) {\n *     runner.linkPartialObjects(true)\n *       .on(EVENT_SUITE_BEGIN, suite => {\n *         // this Suite may be the same object...\n *       })\n *       .on(EVENT_TEST_BEGIN, test => {\n *         // ...as the `test.parent` property\n *       });\n *   }\n * }\n */\nRunner.prototype.linkPartialObjects = function () {\n  return this;\n};\n\n/*\n * Like {@link Runner#run}, but does not accept a callback and returns a `Promise` instead of a `Runner`.\n * This function cannot reject; an `unhandledRejection` event will bubble up to the `process` object instead.\n * @public\n * @memberof Runner\n * @param {Object} [opts] - Options for {@link Runner#run}\n * @returns {Promise<number>} Failure count\n */\nRunner.prototype.runAsync = async function runAsync(opts = {}) {\n  return new Promise((resolve) => {\n    this.run(resolve, opts);\n  });\n};\n\n/**\n * Cleanly abort execution.\n *\n * @memberof Runner\n * @public\n * @return {Runner} Runner instance.\n */\nRunner.prototype.abort = function () {\n  debug(\"abort(): aborting\");\n  this._abort = true;\n\n  return this;\n};\n\n/**\n * Returns `true` if Mocha is running in parallel mode.  For reporters.\n *\n * Subclasses should return an appropriate value.\n * @public\n * @returns {false}\n */\nRunner.prototype.isParallelMode = function isParallelMode() {\n  return false;\n};\n\n/**\n * Configures an alternate reporter for worker processes to use. Subclasses\n * using worker processes should implement this.\n * @public\n * @param {string} path - Absolute path to alternate reporter for worker processes to use\n * @returns {Runner}\n * @throws When in serial mode\n * @chainable\n * @abstract\n */\nRunner.prototype.workerReporter = function () {\n  throw createUnsupportedError(\"workerReporter() not supported in serial mode\");\n};\n\n/**\n * Filter leaks with the given globals flagged as `ok`.\n *\n * @private\n * @param {Array} ok\n * @param {Array} globals\n * @return {Array}\n */\nfunction filterLeaks(ok, globals) {\n  return globals.filter(function (key) {\n    // Firefox and Chrome exposes iframes as index inside the window object\n    if (/^\\d+/.test(key)) {\n      return false;\n    }\n\n    // in firefox\n    // if runner runs in an iframe, this iframe's window.getInterface method\n    // not init at first it is assigned in some seconds\n    if (global.navigator && /^getInterface/.test(key)) {\n      return false;\n    }\n\n    // an iframe could be approached by window[iframeIndex]\n    // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak\n    if (global.navigator && /^\\d+/.test(key)) {\n      return false;\n    }\n\n    // Opera and IE expose global variables for HTML element IDs (issue #243)\n    if (/^mocha-/.test(key)) {\n      return false;\n    }\n\n    var matched = ok.filter(function (ok) {\n      if (~ok.indexOf(\"*\")) {\n        return key.indexOf(ok.split(\"*\")[0]) === 0;\n      }\n      return key === ok;\n    });\n    return !matched.length && (!global.navigator || key !== \"onerror\");\n  });\n}\n\n/**\n * Check if argument is an instance of Error object or a duck-typed equivalent.\n *\n * @private\n * @param {Object} err - object to check\n * @param {string} err.message - error message\n * @returns {boolean}\n */\nfunction isError(err) {\n  return err instanceof Error || (err && typeof err.message === \"string\");\n}\n\n/**\n *\n * Converts thrown non-extensible type into proper Error.\n *\n * @private\n * @param {*} thrown - Non-extensible type thrown by code\n * @return {Error}\n */\nfunction thrown2Error(err) {\n  return new Error(\n    `the ${utils.canonicalType(err)} ${stringify(\n      err,\n    )} was thrown, throw an Error :)`,\n  );\n}\n\nRunner.constants = constants;\n\n/**\n * Node.js' `EventEmitter`\n * @external EventEmitter\n * @see {@link https://nodejs.org/api/events.html#events_class_eventemitter}\n */\n\nmodule.exports = Runner;\n"
  },
  {
    "path": "lib/stats-collector.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('./types.d.ts').StatsCollector} StatsCollector\n * @typedef {import('./runner.js')} Runner\n */\n\n/**\n * Provides a factory function for a {@link StatsCollector} object.\n * @module\n */\n\nvar constants = require(\"./runner\").constants;\nvar EVENT_TEST_PASS = constants.EVENT_TEST_PASS;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\nvar EVENT_SUITE_BEGIN = constants.EVENT_SUITE_BEGIN;\nvar EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN;\nvar EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\nvar EVENT_TEST_END = constants.EVENT_TEST_END;\n\nvar Date = global.Date;\n\n/**\n * Provides stats such as test duration, number of tests passed / failed etc., by listening for events emitted by `runner`.\n *\n * @private\n * @param {Runner} runner - Runner instance\n * @throws {TypeError} If falsy `runner`\n */\nfunction createStatsCollector(runner) {\n  /**\n   * @type {StatsCollector}\n   */\n  var stats = {\n    suites: 0,\n    tests: 0,\n    passes: 0,\n    pending: 0,\n    failures: 0,\n  };\n\n  if (!runner) {\n    throw new TypeError(\"Missing runner argument\");\n  }\n\n  runner.stats = stats;\n\n  runner.once(EVENT_RUN_BEGIN, function () {\n    stats.start = new Date();\n  });\n  runner.on(EVENT_SUITE_BEGIN, function (suite) {\n    suite.root || stats.suites++;\n  });\n  runner.on(EVENT_TEST_PASS, function () {\n    stats.passes++;\n  });\n  runner.on(EVENT_TEST_FAIL, function () {\n    stats.failures++;\n  });\n  runner.on(EVENT_TEST_PENDING, function () {\n    stats.pending++;\n  });\n  runner.on(EVENT_TEST_END, function () {\n    stats.tests++;\n  });\n  runner.once(EVENT_RUN_END, function () {\n    stats.end = new Date();\n    stats.duration = stats.end - stats.start;\n  });\n}\n\nmodule.exports = createStatsCollector;\n"
  },
  {
    "path": "lib/suite.js",
    "content": "\"use strict\";\n\n/**\n * @typedef {import('./test.js')} Test\n */\n\n/**\n * Module dependencies.\n * @private\n */\nconst { EventEmitter } = require(\"node:events\");\nconst Hook = require(\"./hook\");\nvar {\n  assignNewMochaID,\n  clamp,\n  constants: utilsConstants,\n  defineConstants,\n  getMochaID,\n  isString,\n} = require(\"./utils\");\nconst debug = require(\"debug\")(\"mocha:suite\");\nconst milliseconds = require(\"ms\");\nconst errors = require(\"./errors\");\n\nconst { MOCHA_ID_PROP_NAME } = utilsConstants;\n\nclass Suite extends EventEmitter {\n  static constants = defineConstants(\n    /**\n     * {@link Suite}-related constants.\n     * @public\n     * @memberof Suite\n     * @alias constants\n     * @readonly\n     * @static\n     * @enum {string}\n     */\n    {\n      /**\n       * Event emitted after a test file has been loaded. Not emitted in browser.\n       */\n      EVENT_FILE_POST_REQUIRE: \"post-require\",\n      /**\n       * Event emitted before a test file has been loaded. In browser, this is emitted once an interface has been selected.\n       */\n      EVENT_FILE_PRE_REQUIRE: \"pre-require\",\n      /**\n       * Event emitted immediately after a test file has been loaded. Not emitted in browser.\n       */\n      EVENT_FILE_REQUIRE: \"require\",\n      /**\n       * Event emitted when `global.run()` is called (use with `delay` option).\n       */\n      EVENT_ROOT_SUITE_RUN: \"run\",\n\n      /**\n       * Namespace for collection of a `Suite`'s \"after all\" hooks.\n       */\n      HOOK_TYPE_AFTER_ALL: \"afterAll\",\n      /**\n       * Namespace for collection of a `Suite`'s \"after each\" hooks.\n       */\n      HOOK_TYPE_AFTER_EACH: \"afterEach\",\n      /**\n       * Namespace for collection of a `Suite`'s \"before all\" hooks.\n       */\n      HOOK_TYPE_BEFORE_ALL: \"beforeAll\",\n      /**\n       * Namespace for collection of a `Suite`'s \"before each\" hooks.\n       */\n      HOOK_TYPE_BEFORE_EACH: \"beforeEach\",\n\n      /**\n       * Emitted after a child `Suite` has been added to a `Suite`.\n       */\n      EVENT_SUITE_ADD_SUITE: \"suite\",\n      /**\n       * Emitted after an \"after all\" `Hook` has been added to a `Suite`.\n       */\n      EVENT_SUITE_ADD_HOOK_AFTER_ALL: \"afterAll\",\n      /**\n       * Emitted after an \"after each\" `Hook` has been added to a `Suite`.\n       */\n      EVENT_SUITE_ADD_HOOK_AFTER_EACH: \"afterEach\",\n      /**\n       * Emitted after an \"before all\" `Hook` has been added to a `Suite`.\n       */\n      EVENT_SUITE_ADD_HOOK_BEFORE_ALL: \"beforeAll\",\n      /**\n       * Emitted after an \"before each\" `Hook` has been added to a `Suite`.\n       */\n      EVENT_SUITE_ADD_HOOK_BEFORE_EACH: \"beforeEach\",\n      /**\n       * Emitted after a `Test` has been added to a `Suite`.\n       */\n      EVENT_SUITE_ADD_TEST: \"test\",\n    },\n  );\n\n  /**\n   * Create a new `Suite` with the given `title` and parent `Suite`.\n   *\n   * @public\n   * @param {Suite} parent - Parent suite (required!)\n   * @param {string} title - Title\n   * @return {Suite}\n   */\n  static create(parent, title) {\n    var suite = new Suite(title, parent.ctx);\n    suite.parent = parent;\n    parent.addSuite(suite);\n    return suite;\n  }\n\n  /**\n   * Constructs a new `Suite` instance with the given `title`, `ctx`, and `isRoot`.\n   *\n   * @public\n   * @extends EventEmitter\n   * @see {@link https://nodejs.org/api/events.html#events_class_eventemitter|EventEmitter}\n   * @param {string} title - Suite title.\n   * @param {Context} parentContext - Parent context instance.\n   * @param {boolean} [isRoot=false] - Whether this is the root suite.\n   */\n  constructor(title, parentContext, isRoot) {\n    if (!isString(title)) {\n      throw errors.createInvalidArgumentTypeError(\n        'Suite argument \"title\" must be a string. Received type \"' +\n          typeof title +\n          '\"',\n        \"title\",\n        \"string\",\n      );\n    }\n    super();\n    this.title = title;\n    function Context() {}\n    Context.prototype = parentContext;\n    this.ctx = new Context();\n    this.suites = [];\n    this.tests = [];\n    this.root = isRoot === true;\n    this.pending = false;\n    this._retries = -1;\n    this._beforeEach = [];\n    this._beforeAll = [];\n    this._afterEach = [];\n    this._afterAll = [];\n    this._timeout = 2000;\n    this._slow = 75;\n    this._bail = false;\n    this._onlyTests = [];\n    this._onlySuites = [];\n    assignNewMochaID(this);\n\n    Object.defineProperty(this, \"id\", {\n      get() {\n        return getMochaID(this);\n      },\n    });\n\n    this.reset();\n  }\n\n  /**\n   * Resets the state initially or for a next run.\n   */\n  reset() {\n    this.delayed = false;\n    function doReset(thingToReset) {\n      thingToReset.reset();\n    }\n    this.suites.forEach(doReset);\n    this.tests.forEach(doReset);\n    this._beforeEach.forEach(doReset);\n    this._afterEach.forEach(doReset);\n    this._beforeAll.forEach(doReset);\n    this._afterAll.forEach(doReset);\n  }\n\n  /**\n   * Return a clone of this `Suite`.\n   *\n   * @private\n   * @return {Suite}\n   */\n  clone() {\n    var suite = new Suite(this.title);\n    debug(\"clone\");\n    suite.ctx = this.ctx;\n    suite.root = this.root;\n    suite.timeout(this.timeout());\n    suite.retries(this.retries());\n    suite.slow(this.slow());\n    suite.bail(this.bail());\n    return suite;\n  }\n\n  /**\n   * Set or get timeout `ms` or short-hand such as \"2s\".\n   *\n   * @private\n   * @todo Do not attempt to set value if `ms` is undefined\n   * @param {number|string} ms\n   * @return {Suite|number} for chaining\n   */\n  timeout(ms) {\n    if (!arguments.length) {\n      return this._timeout;\n    }\n    if (typeof ms === \"string\") {\n      ms = milliseconds(ms);\n    }\n\n    // Clamp to range\n    var INT_MAX = Math.pow(2, 31) - 1;\n    var range = [0, INT_MAX];\n    ms = clamp(ms, range);\n\n    debug(\"timeout %d\", ms);\n    this._timeout = parseInt(ms, 10);\n\n    // Allow overriding inner/nested suites\n    // See and test-cases with chain-called timeout argument.\n    // https://github.com/mochajs/mocha/issues/5422\n    for (const t of this.tests) {\n      t.timeout(this._timeout);\n    }\n    for (const s of this.suites) {\n      s.timeout(this._timeout);\n    }\n    return this;\n  }\n\n  /**\n   * Set or get number of times to retry a failed test.\n   *\n   * @private\n   * @param {number|string} n\n   * @return {Suite|number} for chaining\n   */\n  retries(n) {\n    if (!arguments.length) {\n      return this._retries;\n    }\n    debug(\"retries %d\", n);\n    this._retries = parseInt(n, 10) || 0;\n    return this;\n  }\n\n  /**\n   * Set or get slow `ms` or short-hand such as \"2s\".\n   *\n   * @private\n   * @param {number|string} ms\n   * @return {Suite|number} for chaining\n   */\n  slow(ms) {\n    if (!arguments.length) {\n      return this._slow;\n    }\n    if (typeof ms === \"string\") {\n      ms = milliseconds(ms);\n    }\n    debug(\"slow %d\", ms);\n    this._slow = ms;\n    return this;\n  }\n\n  /**\n   * Set or get whether to bail after first error.\n   *\n   * @private\n   * @param {boolean} bail\n   * @return {Suite|number} for chaining\n   */\n  bail(bail) {\n    if (!arguments.length) {\n      return this._bail;\n    }\n    debug(\"bail %s\", bail);\n    this._bail = bail;\n    return this;\n  }\n\n  /**\n   * Check if this suite or its parent suite is marked as pending.\n   *\n   * @private\n   */\n  isPending() {\n    return this.pending || (this.parent && this.parent.isPending());\n  }\n\n  /**\n   * Generic hook-creator.\n   * @private\n   * @param {string} title - Title of hook\n   * @param {Function} fn - Hook callback\n   * @returns {Hook} A new hook\n   */\n  _createHook(title, fn) {\n    var hook = new Hook(title, fn);\n    hook.parent = this;\n    hook.timeout(this.timeout());\n    hook.retries(this.retries());\n    hook.slow(this.slow());\n    hook.ctx = this.ctx;\n    hook.file = this.file;\n    return hook;\n  }\n\n  /**\n   * Run `fn(test[, done])` before running tests.\n   *\n   * @private\n   * @param {string} title\n   * @param {Function} fn\n   * @return {Suite} for chaining\n   */\n  beforeAll(title, fn) {\n    if (this.isPending()) {\n      return this;\n    }\n    if (typeof title === \"function\") {\n      fn = title;\n      title = fn.name;\n    }\n    title = '\"before all\" hook' + (title ? \": \" + title : \"\");\n\n    var hook = this._createHook(title, fn);\n    this._beforeAll.push(hook);\n    this.emit(Suite.constants.EVENT_SUITE_ADD_HOOK_BEFORE_ALL, hook);\n    return hook;\n  }\n\n  /**\n   * Run `fn(test[, done])` after running tests.\n   *\n   * @private\n   * @param {string} title\n   * @param {Function} fn\n   * @return {Suite} for chaining\n   */\n  afterAll(title, fn) {\n    if (this.isPending()) {\n      return this;\n    }\n    if (typeof title === \"function\") {\n      fn = title;\n      title = fn.name;\n    }\n    title = '\"after all\" hook' + (title ? \": \" + title : \"\");\n\n    var hook = this._createHook(title, fn);\n    this._afterAll.push(hook);\n    this.emit(Suite.constants.EVENT_SUITE_ADD_HOOK_AFTER_ALL, hook);\n    return hook;\n  }\n\n  /**\n   * Run `fn(test[, done])` before each test case.\n   *\n   * @private\n   * @param {string} title\n   * @param {Function} fn\n   * @return {Suite} for chaining\n   */\n  beforeEach(title, fn) {\n    if (this.isPending()) {\n      return this;\n    }\n    if (typeof title === \"function\") {\n      fn = title;\n      title = fn.name;\n    }\n    title = '\"before each\" hook' + (title ? \": \" + title : \"\");\n\n    var hook = this._createHook(title, fn);\n    this._beforeEach.push(hook);\n    this.emit(Suite.constants.EVENT_SUITE_ADD_HOOK_BEFORE_EACH, hook);\n    return hook;\n  }\n\n  /**\n   * Run `fn(test[, done])` after each test case.\n   *\n   * @private\n   * @param {string} title\n   * @param {Function} fn\n   * @return {Suite} for chaining\n   */\n  afterEach(title, fn) {\n    if (this.isPending()) {\n      return this;\n    }\n    if (typeof title === \"function\") {\n      fn = title;\n      title = fn.name;\n    }\n    title = '\"after each\" hook' + (title ? \": \" + title : \"\");\n\n    var hook = this._createHook(title, fn);\n    this._afterEach.push(hook);\n    this.emit(Suite.constants.EVENT_SUITE_ADD_HOOK_AFTER_EACH, hook);\n    return hook;\n  }\n\n  /**\n   * Add a test `suite`.\n   *\n   * @private\n   * @param {Suite} suite\n   * @return {Suite} for chaining\n   */\n  addSuite(suite) {\n    suite.parent = this;\n    suite.root = false;\n    suite.timeout(this.timeout());\n    suite.retries(this.retries());\n    suite.slow(this.slow());\n    suite.bail(this.bail());\n    this.suites.push(suite);\n    this.emit(Suite.constants.EVENT_SUITE_ADD_SUITE, suite);\n    return this;\n  }\n\n  /**\n   * Add a `test` to this suite.\n   *\n   * @private\n   * @param {Test} test\n   * @return {Suite} for chaining\n   */\n  addTest(test) {\n    test.parent = this;\n    test.timeout(this.timeout());\n    test.retries(this.retries());\n    test.slow(this.slow());\n    test.ctx = this.ctx;\n    this.tests.push(test);\n    this.emit(Suite.constants.EVENT_SUITE_ADD_TEST, test);\n    return this;\n  }\n\n  /**\n   * Return the full title generated by recursively concatenating the parent's\n   * full title.\n   *\n   * @memberof Suite\n   * @public\n   * @return {string}\n   */\n  fullTitle() {\n    return this.titlePath().join(\" \");\n  }\n\n  /**\n   * Return the title path generated by recursively concatenating the parent's\n   * title path.\n   *\n   * @memberof Suite\n   * @public\n   * @return {string[]}\n   */\n  titlePath() {\n    var result = [];\n    if (this.parent) {\n      result = result.concat(this.parent.titlePath());\n    }\n    if (!this.root) {\n      result.push(this.title);\n    }\n    return result;\n  }\n\n  /**\n   * Return the total number of tests.\n   *\n   * @memberof Suite\n   * @public\n   * @return {number}\n   */\n  total() {\n    return (\n      this.suites.reduce(function (sum, suite) {\n        return sum + suite.total();\n      }, 0) + this.tests.length\n    );\n  }\n\n  /**\n   * Iterates through each suite recursively to find all tests. Applies a\n   * function in the format `fn(test)`.\n   *\n   * @private\n   * @param {Function} fn\n   * @return {Suite}\n   */\n  eachTest(fn) {\n    this.tests.forEach(fn);\n    this.suites.forEach(function (suite) {\n      suite.eachTest(fn);\n    });\n    return this;\n  }\n\n  /**\n   * This will run the root suite if we happen to be running in delayed mode.\n   * @private\n   */\n  run() {\n    if (this.root) {\n      this.emit(Suite.constants.EVENT_ROOT_SUITE_RUN);\n    }\n  }\n\n  /**\n   * Determines whether a suite has an `only` test or suite as a descendant.\n   *\n   * @private\n   * @returns {Boolean}\n   */\n  hasOnly() {\n    return (\n      this._onlyTests.length > 0 ||\n      this._onlySuites.length > 0 ||\n      this.suites.some(function (suite) {\n        return suite.hasOnly();\n      })\n    );\n  }\n\n  /**\n   * Filter suites based on `isOnly` logic.\n   *\n   * @private\n   * @returns {Boolean}\n   */\n  filterOnly() {\n    if (this._onlyTests.length) {\n      // If the suite contains `only` tests, run those and ignore any nested suites.\n      this.tests = this._onlyTests;\n      this.suites = [];\n    } else {\n      // Otherwise, do not run any of the tests in this suite.\n      this.tests = [];\n      this._onlySuites.forEach(function (onlySuite) {\n        // If there are other `only` tests/suites nested in the current `only` suite, then filter that `only` suite.\n        // Otherwise, all of the tests on this `only` suite should be run, so don't filter it.\n        if (onlySuite.hasOnly()) {\n          onlySuite.filterOnly();\n        }\n      });\n      // Run the `only` suites, as well as any other suites that have `only` tests/suites as descendants.\n      var onlySuites = this._onlySuites;\n      this.suites = this.suites.filter(function (childSuite) {\n        return onlySuites.indexOf(childSuite) !== -1 || childSuite.filterOnly();\n      });\n    }\n    // Keep the suite only if there is something to run\n    return this.tests.length > 0 || this.suites.length > 0;\n  }\n\n  /**\n   * Adds a suite to the list of subsuites marked `only`.\n   *\n   * @private\n   * @param {Suite} suite\n   */\n  appendOnlySuite(suite) {\n    this._onlySuites.push(suite);\n  }\n\n  /**\n   * Marks a suite to be `only`.\n   *\n   * @private\n   */\n  markOnly() {\n    this.parent && this.parent.appendOnlySuite(this);\n  }\n\n  /**\n   * Adds a test to the list of tests marked `only`.\n   *\n   * @private\n   * @param {Test} test\n   */\n  appendOnlyTest(test) {\n    this._onlyTests.push(test);\n  }\n\n  /**\n   * Returns the array of hooks by hook name; see `HOOK_TYPE_*` constants.\n   * @private\n   */\n  getHooks(name) {\n    return this[\"_\" + name];\n  }\n\n  /**\n   * cleans all references from this suite and all child suites.\n   */\n  dispose() {\n    this.suites.forEach(function (suite) {\n      suite.dispose();\n    });\n    this.cleanReferences();\n  }\n\n  /**\n   * Cleans up the references to all the deferred functions\n   * (before/after/beforeEach/afterEach) and tests of a Suite.\n   * These must be deleted otherwise a memory leak can happen,\n   * as those functions may reference variables from closures,\n   * thus those variables can never be garbage collected as long\n   * as the deferred functions exist.\n   *\n   * @private\n   */\n  cleanReferences() {\n    function cleanArrReferences(arr) {\n      for (var i = 0; i < arr.length; i++) {\n        delete arr[i].fn;\n      }\n    }\n\n    if (Array.isArray(this._beforeAll)) {\n      cleanArrReferences(this._beforeAll);\n    }\n\n    if (Array.isArray(this._beforeEach)) {\n      cleanArrReferences(this._beforeEach);\n    }\n\n    if (Array.isArray(this._afterAll)) {\n      cleanArrReferences(this._afterAll);\n    }\n\n    if (Array.isArray(this._afterEach)) {\n      cleanArrReferences(this._afterEach);\n    }\n\n    for (var i = 0; i < this.tests.length; i++) {\n      delete this.tests[i].fn;\n    }\n  }\n\n  /**\n   * Returns an object suitable for IPC.\n   * Functions are represented by keys beginning with `$$`.\n   * @private\n   * @returns {Object}\n   */\n  serialize() {\n    return {\n      _bail: this._bail,\n      $$fullTitle: this.fullTitle(),\n      $$isPending: Boolean(this.isPending()),\n      root: this.root,\n      title: this.title,\n      [MOCHA_ID_PROP_NAME]: this.id,\n      parent: this.parent ? { [MOCHA_ID_PROP_NAME]: this.parent.id } : null,\n    };\n  }\n}\n\nexports = module.exports = Suite;\n"
  },
  {
    "path": "lib/test.js",
    "content": "\"use strict\";\nvar Runnable = require(\"./runnable\");\nvar utils = require(\"./utils\");\nvar errors = require(\"./errors\");\nvar createInvalidArgumentTypeError = errors.createInvalidArgumentTypeError;\nvar isString = utils.isString;\n\nconst { MOCHA_ID_PROP_NAME } = utils.constants;\n\nclass Test extends Runnable {\n  /**\n   * Initialize a new `Test` with the given `title` and callback `fn`.\n   *\n   * @public\n   * @extends Runnable\n   * @param {String} title - Test title (required)\n   * @param {Function} [fn] - Test callback.  If omitted, the Test is considered \"pending\"\n   */\n  constructor(title, fn) {\n    if (!isString(title)) {\n      throw createInvalidArgumentTypeError(\n        'Test argument \"title\" should be a string. Received type \"' +\n          typeof title +\n          '\"',\n        \"title\",\n        \"string\",\n      );\n    }\n    super(title, fn);\n    this.type = \"test\";\n    this.reset();\n  }\n\n  /**\n   * Resets the state initially or for a next run.\n   */\n  reset() {\n    super.reset();\n    this.pending = !this.fn;\n    delete this.state;\n  }\n\n  /**\n   * Set or get retried test\n   *\n   * @private\n   */\n  retriedTest(n) {\n    if (!arguments.length) {\n      return this._retriedTest;\n    }\n    this._retriedTest = n;\n  }\n\n  /**\n   * Add test to the list of tests marked `only`.\n   *\n   * @private\n   */\n  markOnly() {\n    this.parent.appendOnlyTest(this);\n  }\n\n  clone() {\n    var test = new Test(this.title, this.fn);\n    test.timeout(this.timeout());\n    test.slow(this.slow());\n    test.retries(this.retries());\n    test.currentRetry(this.currentRetry());\n    test.retriedTest(this.retriedTest() || this);\n    test.globals(this.globals());\n    test.parent = this.parent;\n    test.file = this.file;\n    test.ctx = this.ctx;\n    return test;\n  }\n\n  /**\n   * Returns an minimal object suitable for transmission over IPC.\n   * Functions are represented by keys beginning with `$$`.\n   * @private\n   * @returns {Object}\n   */\n  serialize() {\n    return {\n      $$currentRetry: this._currentRetry,\n      $$fullTitle: this.fullTitle(),\n      $$isPending: Boolean(this.pending),\n      $$retriedTest: this._retriedTest || null,\n      $$slow: this._slow,\n      $$titlePath: this.titlePath(),\n      body: this.body,\n      duration: this.duration,\n      err: this.err,\n      parent: {\n        $$fullTitle: this.parent.fullTitle(),\n        [MOCHA_ID_PROP_NAME]: this.parent.id,\n      },\n      speed: this.speed,\n      state: this.state,\n      title: this.title,\n      type: this.type,\n      file: this.file,\n      [MOCHA_ID_PROP_NAME]: this.id,\n    };\n  }\n}\n\nmodule.exports = Test;\n"
  },
  {
    "path": "lib/types.d.ts",
    "content": "/**\n * These types are a preliminary step towards moving Mocha's TypeScript types into Mocha.\n * They are not yet complete and are not yet fully used in the codebase.\n * For now, if you're an external user, you should use the types from @types/mocha.\n */\n\nimport type { FSWatcher, MatchFunction } from \"chokidar\" with {\n  \"resolution-mode\": \"import\",\n};\n\nimport type { constants } from \"./error-constants.js\";\nimport type Mocha from \"./mocha.js\";\nimport Runner from \"./runner.js\";\n\n/**\n * Command-line options\n */\nexport interface MochaOptions {\n  /** Propagate uncaught errors? */\n  allowUncaught?: boolean;\n\n  /** Force `done` callback or promise? */\n  asyncOnly?: boolean;\n\n  /** Bail after first test failure? */\n  bail?: boolean;\n\n  /** Check for global variable leaks? */\n  checkLeaks?: boolean;\n\n  /** Color TTY output from reporter? */\n  color?: boolean;\n\n  /** Delay root suite execution? */\n  delay?: boolean;\n\n  /** Show diff on failure? */\n  diff?: boolean;\n\n  /** Report tests without running them? */\n  dryRun?: boolean;\n\n  /** Fail test run if tests were failed? */\n  passOnFailingTestSuite?: boolean;\n\n  /** Fail test run if zero tests? */\n  failZero?: boolean;\n\n  /** Test filter given string. */\n  fgrep?: string;\n\n  /** Tests marked `only` fail the suite? */\n  forbidOnly?: boolean;\n\n  /** Pending tests fail the suite? */\n  forbidPending?: boolean;\n\n  /** Full stacktrace upon failure? */\n  fullTrace?: boolean;\n\n  /** Variables expected in global scope. */\n  global?: string[];\n\n  /** Test filter given regular expression. */\n  grep?: RegExp;\n\n  /** Display inline diffs? */\n  inlineDiffs?: boolean;\n\n  /** Invert test filter matches? */\n  invert?: boolean;\n\n  /** Disable syntax highlighting? */\n  noHighlighting?: boolean;\n\n  /** Reporter name or constructor. */\n  reporter?: string | Reporter;\n\n  /** Reporter settings object. */\n  reporterOption?: Object;\n\n  /** Number of times to retry failed tests. */\n  retries?: number;\n\n  /** Slow threshold value, in milliseconds. */\n  slow?: number;\n\n  /** Timeout threshold value, in milliseconds. */\n  timeout?: number | string;\n\n  /** Interface name. */\n  ui?: string;\n\n  /** Run jobs in parallel. */\n  parallel?: boolean;\n\n  /** Max number of worker processes for parallel runs. */\n  jobs?: number;\n\n  /** Hooks to bootstrap the root suite with. */\n  rootHooks?: MochaRootHookObject;\n\n  /** Pathname of `rootHooks` plugin for parallel runs. */\n  require?: string[];\n\n  /** Should be `true` if `Mocha` process is running in a worker process. */\n  isWorker?: boolean;\n\n  watch?: boolean;\n  extension?: string[];\n  recursive?: boolean;\n  sort?: boolean;\n  file?: string[];\n  spec?: string[];\n  ignore?: string[];\n}\n\n/**\n * Callback to be invoked when test execution is complete.\n *\n * @private\n * @param failures - Number of failures that occurred.\n */\nexport type DoneCB = (failures?: number) => void;\n\nexport interface RunnerOptions {\n  /** Files to run */\n  files?: string[];\n  /** Command-line options */\n  options?: object;\n}\n\n/**\n * An alternative way to define root hooks that works with parallel runs.\n */\nexport interface MochaRootHookObject {\n  /** \"Before all\" hook(s) */\n  beforeAll?: Function | Function[];\n  /** \"Before each\" hook(s) */\n  beforeEach?: Function | Function[];\n  /** \"After all\" hook(s) */\n  afterAll?: Function | Function[];\n  /** \"After each\" hook(s)} */\n  afterEach?: Function | Function[];\n}\n\n/**\n * A function that's invoked _once_ which is either sync or async.\n * Can be a \"teardown\" or \"setup\".  These will all share the same context.\n */\nexport type MochaGlobalFixture = () => void | Promise<void>;\n\n/**\n * An object making up all necessary parts of a plugin loader and aggregator\n */\nexport interface PluginDefinition {\n  /**\n   * Named export to use\n   */\n  exportName: string;\n  /**\n   * Option name for Mocha constructor (use `exportName` if omitted)\n   */\n  optionName?: string;\n  /**\n   * Validator function\n   */\n  validate?: PluginValidator;\n  /**\n   * Finalizer/aggregator function\n   */\n  finalize?: PluginFinalizer;\n}\n\n/**\n * A (sync) function to assert a user-supplied plugin implementation is valid.\n *\n * Defined in a {@link PluginDefinition}.\n\n * @param value Value to check\n * @this {PluginDefinition}\n */\nexport type PluginValidator = (this: PluginDefinition, value: unknown) => void;\n\n/**\n * A function to finalize plugins implementations of a particular ilk\n * @param implementations User-supplied implementations\n */\nexport type PluginFinalizer = (\n  implementations: unknown[],\n) => Promise<unknown> | unknown;\n\n/**\n * An object to configure how Mocha gathers test files\n */\nexport interface FileCollectionOptions {\n  /** File extensions to use */\n  extension?: string[];\n  /** Files, dirs, globs to run */\n  spec?: string[];\n  /** Files, dirs, globs to ignore */\n  ignore?: string[];\n  /** List of additional files to include */\n  file?: string[];\n  /** Find files recursively */\n  recursive?: boolean;\n  /** Sort test files */\n  sort?: boolean;\n}\n\n/**\n * Diagnostic object containing unmatched files\n */\nexport interface UnmatchedFile {\n  /** The absolute path to the file */\n  absolutePath: string;\n  /** A list of unmatched files derived from the file arguments passed in */\n  pattern: string;\n}\n\n/**\n * Response object containing a list of files to test and unmatched files.\n */\nexport interface FileCollectionResponse {\n  /** A list of files to test */\n  files: string[];\n  /** A list of unmatched files derived from the file arguments passed in */\n  unmatchedFiles: UnmatchedFile[];\n}\n\n/**\n * @private\n */\nexport interface BeforeWatchRunOptions {\n  mocha: Mocha;\n  watcher: FSWatcher;\n}\n\n/**\n * Callback to be run before `mocha.run()` is called.\n * Optionally, it can return a new `Mocha` instance.\n * @private\n */\nexport type BeforeWatchRun = (options: BeforeWatchRunOptions) => Mocha;\n\n/**\n * Object containing run control methods\n * @private\n */\nexport interface Rerunner {\n  /** Calls `mocha.run()` */\n  run: Function;\n  /** Schedules another call to `run */\n  scheduleRun: Function;\n}\n\n/**\n * Object containing paths (without globs) and glob paths for matching.\n * @private\n */\nexport interface PathPattern {\n  /** Set of absolute paths without globs. */\n  paths: Set<string>;\n  /** Set of absolute glob paths. */\n  globs: Set<string>;\n}\n\n/**\n * Object containing path patterns for filtering from the provided glob paths.\n * @private\n */\nexport interface PathFilter {\n  /** Path patterns for directories. */\n  dir: PathPattern;\n  /** Path patterns for matching. */\n  match: PathPattern;\n}\n\n/**\n * Checks if the file path matches the allowed patterns.\n * @private\n * @param filePath The file path to check.\n * @returns Determines if there was a match.\n */\nexport type AllowMatchFunction = (filePath: string) => boolean;\n\n/**\n * Object for matching paths to either allow or ignore them.\n * @private\n */\nexport interface PathMatcher {\n  /** Checks if the file path matches the allowed patterns. */\n  allow: AllowMatchFunction;\n  /** The Chokidar `ignored` match function. */\n  ignore: MatchFunction;\n}\n\nexport interface StatsCollector {\n  /** integer count of suites run */\n  suites: number;\n\n  /** integer count of tests run */\n  tests: number;\n\n  /** integer count of passing tests */\n  passes: number;\n\n  /** integer count of pending tests */\n  pending: number;\n\n  /** integer count of failed tests */\n  failures: number;\n\n  /** time when testing began */\n  start: Date;\n\n  /** time when testing concluded */\n  end: Date;\n\n  /** number of msecs that testing took */\n  duration: number;\n}\n\nexport interface PluginLoaderOptions {\n  /**\n   * Plugin definitions\n   */\n  pluginDefs?: PluginDefinition;\n\n  /**\n   * A list of plugins to ignore when loading\n   */\n  ignore?: string[];\n}\n\n/**\n * @memberof module:lib/errors\n */\nexport interface MochaTimeoutError extends Error {\n  code: typeof constants.TIMEOUT;\n\n  /**\n   * Timeout in ms\n   */\n  timeout?: number;\n\n  /**\n   * Filepath, if given\n   */\n  file?: string;\n}\n\n/**\n * The result of calling `SerializableEvent.serialize`, as received\n * by the deserializer.\n * @private\n */\nexport interface SerializedEvent {\n  /** Optional serialized data */\n  data?: object;\n\n  /** Optional serialized `Error` */\n  error?: Error;\n}\n\n/**\n * The result of calling `SerializableWorkerResult.serialize` as received\n * by the deserializer.\n * @private\n */\nexport interface SerializedWorkerResult {\n  /** Number of failures */\n  failureCount: number;\n\n  /** Serialized events */\n  events: SerializedEvent[];\n\n  /** Symbol-like to denote the type of object this is */\n  __type: \"SerializedWorkerResult\";\n}\n\n/**\n * Listener function intended to be bound to `Process.SIGINT` event\n * @private\n */\nexport type SigIntListener = () => Promise<void>;\n\n/**\n * A function accepting a test file path and returning the results of a test run\n * @private\n * @param filename - File to run\n */\nexport type FileRunner = (filename: string) => Promise<SerializedWorkerResult>;\n\n/**\n * Serializable event data from a `Runner`.  Keys of the `data` property\n * beginning with `__` will be converted into a function which returns the value\n * upon deserialization.\n */\nexport interface BufferedEvent {\n  /** Event name */\n  name: string;\n\n  /** Event parameters */\n  data: object;\n}\n\n/**\n * An object with all stack traces recursively mounted from each err.cause\n * @memberof module:lib/reporters/base\n */\nexport interface FullErrorStack {\n  message: string;\n  msg: string;\n  stack: string;\n}\n\nexport interface Reporter {\n  new (runner: Runner, options: MochaOptions): Reporter;\n  done?: (failures: number, callback: () => void) => void;\n}\n"
  },
  {
    "path": "lib/utils.js",
    "content": "\"use strict\";\n\n/**\n * Various utility functions used throughout Mocha's codebase.\n * @module utils\n */\n\n/**\n * Module dependencies.\n */\nvar path = require(\"node:path\");\nvar he = require(\"he\");\nvar pc = require(\"picocolors\");\nvar isUnicodeSupported = require(\"is-unicode-supported\")();\n\nconst MOCHA_ID_PROP_NAME = \"__mocha_id__\";\n\n/**\n * Escape special characters in the given string of html.\n *\n * @private\n * @param  {string} html\n * @return {string}\n */\nexports.escape = function (html) {\n  return he.encode(String(html), { useNamedReferences: false });\n};\n\n/**\n * Test if the given obj is type of string.\n *\n * @private\n * @param {Object} obj\n * @return {boolean}\n */\nexports.isString = function (obj) {\n  return typeof obj === \"string\";\n};\n\n/**\n * Compute a slug from the given `str`.\n *\n * @private\n * @param {string} str\n * @return {string}\n */\nexports.slug = function (str) {\n  return str\n    .toLowerCase()\n    .replace(/\\s+/g, \"-\")\n    .replace(/[^-\\w]/g, \"\")\n    .replace(/-{2,}/g, \"-\");\n};\n\n/**\n * Strip the function definition from `str`, and re-indent for pre whitespace.\n *\n * @param {string} str\n * @return {string}\n */\nexports.clean = function (str) {\n  str = str\n    .replace(/\\r\\n?|[\\n\\u2028\\u2029]/g, \"\\n\")\n    .replace(/^\\uFEFF/, \"\")\n    // (traditional)->  space/name     parameters    body     (lambda)-> parameters       body   multi-statement/single          keep body content\n    .replace(\n      /^function(?:\\s*|\\s[^(]*)\\([^)]*\\)\\s*\\{((?:.|\\n)*?)\\}$|^\\([^)]*\\)\\s*=>\\s*(?:\\{((?:.|\\n)*?)\\}|((?:.|\\n)*))$/,\n      \"$1$2$3\",\n    );\n\n  var spaces = str.match(/^\\n?( *)/)[1].length;\n  var tabs = str.match(/^\\n?(\\t*)/)[1].length;\n  var re = new RegExp(\n    \"^\\n?\" + (tabs ? \"\\t\" : \" \") + \"{\" + (tabs || spaces) + \"}\",\n    \"gm\",\n  );\n\n  str = str.replace(re, \"\");\n\n  return str.trim();\n};\n\n/**\n * If a value could have properties, and has none, this function is called,\n * which returns a string representation of the empty value.\n *\n * Functions w/ no properties return `'[Function]'`\n * Arrays w/ length === 0 return `'[]'`\n * Objects w/ no properties return `'{}'`\n * All else: return result of `value.toString()`\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {string} typeHint The type of the value\n * @returns {string}\n */\nfunction emptyRepresentation(value, typeHint) {\n  switch (typeHint) {\n    case \"function\":\n      return \"[Function]\";\n    case \"null-prototype\":\n    case \"object\":\n      return \"{}\";\n    case \"array\":\n      return \"[]\";\n    default:\n      return value.toString();\n  }\n}\n\n/**\n * Takes some variable and asks `Object.prototype.toString()` what it thinks it\n * is.\n *\n * @private\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString\n * @param {*} value The value to test.\n * @returns {string} Computed type\n * @example\n * canonicalType({}) // 'object'\n * canonicalType([]) // 'array'\n * canonicalType(1) // 'number'\n * canonicalType(false) // 'boolean'\n * canonicalType(Infinity) // 'number'\n * canonicalType(null) // 'null'\n * canonicalType(new Date()) // 'date'\n * canonicalType(/foo/) // 'regexp'\n * canonicalType('type') // 'string'\n * canonicalType(global) // 'global'\n * canonicalType(new String('foo') // 'object'\n * canonicalType(async function() {}) // 'asyncfunction'\n * canonicalType(Object.create(null)) // 'null-prototype'\n */\nvar canonicalType = (exports.canonicalType = function canonicalType(value) {\n  if (value === undefined) {\n    return \"undefined\";\n  } else if (value === null) {\n    return \"null\";\n  } else if (Buffer.isBuffer(value)) {\n    return \"buffer\";\n  } else if (Object.getPrototypeOf(value) === null) {\n    return \"null-prototype\";\n  }\n\n  return Object.prototype.toString\n    .call(value)\n    .replace(/^\\[.+\\s(.+?)]$/, \"$1\")\n    .toLowerCase();\n});\n\n/**\n *\n * Returns a general type or data structure of a variable\n * @private\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures\n * @param {*} value The value to test.\n * @returns {string} One of undefined, boolean, number, string, bigint, symbol, object\n * @example\n * type({}) // 'object'\n * type([]) // 'array'\n * type(1) // 'number'\n * type(false) // 'boolean'\n * type(Infinity) // 'number'\n * type(null) // 'null'\n * type(new Date()) // 'object'\n * type(/foo/) // 'object'\n * type('type') // 'string'\n * type(global) // 'object'\n * type(new String('foo') // 'string'\n */\nexports.type = function type(value) {\n  // Null is special\n  if (value === null) return \"null\";\n  const primitives = new Set([\n    \"undefined\",\n    \"boolean\",\n    \"number\",\n    \"string\",\n    \"bigint\",\n    \"symbol\",\n  ]);\n  const _type = typeof value;\n  if (_type === \"function\") return _type;\n  if (primitives.has(_type)) return _type;\n  if (value instanceof String) return \"string\";\n  if (value instanceof Error) return \"error\";\n  if (Array.isArray(value)) return \"array\";\n\n  return _type;\n};\n\n/**\n * Stringify `value`. Different behavior depending on type of value:\n *\n * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively.\n * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes.\n * - If `value` is an *empty* object, function, or array, return result of function\n *   {@link emptyRepresentation}.\n * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of\n *   JSON.stringify().\n *\n * @private\n * @see exports.type\n * @param {*} value\n * @return {string}\n */\nexports.stringify = function (value) {\n  var typeHint = canonicalType(value);\n\n  if (!~[\"object\", \"array\", \"function\", \"null-prototype\"].indexOf(typeHint)) {\n    if (typeHint === \"buffer\") {\n      var json = Buffer.prototype.toJSON.call(value);\n      // Based on the toJSON result\n      return jsonStringify(\n        json.data && json.type ? json.data : json,\n        2,\n      ).replace(/,(\\n|$)/g, \"$1\");\n    }\n\n    // IE7/IE8 has a bizarre String constructor; needs to be coerced\n    // into an array and back to obj.\n    if (typeHint === \"string\" && typeof value === \"object\") {\n      value = value.split(\"\").reduce(function (acc, char, idx) {\n        acc[idx] = char;\n        return acc;\n      }, {});\n      typeHint = \"object\";\n    } else {\n      return jsonStringify(value);\n    }\n  }\n\n  for (var prop in value) {\n    if (Object.prototype.hasOwnProperty.call(value, prop)) {\n      return jsonStringify(\n        exports.canonicalize(value, null, typeHint),\n        2,\n      ).replace(/,(\\n|$)/g, \"$1\");\n    }\n  }\n\n  return emptyRepresentation(value, typeHint);\n};\n\n/**\n * like JSON.stringify but more sense.\n *\n * @private\n * @param {Object}  object\n * @param {number=} spaces\n * @param {number=} depth\n * @returns {*}\n */\nfunction jsonStringify(object, spaces, depth) {\n  if (typeof spaces === \"undefined\") {\n    // primitive types\n    return _stringify(object);\n  }\n\n  depth = depth || 1;\n  var space = spaces * depth;\n  var str = Array.isArray(object) ? \"[\" : \"{\";\n  var end = Array.isArray(object) ? \"]\" : \"}\";\n  var length =\n    typeof object.length === \"number\"\n      ? object.length\n      : Object.keys(object).length;\n  // `.repeat()` polyfill\n  function repeat(s, n) {\n    return new Array(n).join(s);\n  }\n\n  function _stringify(val) {\n    switch (canonicalType(val)) {\n      case \"null\":\n      case \"undefined\":\n        val = \"[\" + val + \"]\";\n        break;\n      case \"array\":\n      case \"object\":\n        val = jsonStringify(val, spaces, depth + 1);\n        break;\n      case \"boolean\":\n      case \"regexp\":\n      case \"symbol\":\n      case \"number\":\n        val =\n          val === 0 && 1 / val === -Infinity // `-0`\n            ? \"-0\"\n            : val.toString();\n        break;\n      case \"bigint\":\n        val = val.toString() + \"n\";\n        break;\n      case \"date\":\n        var sDate = isNaN(val.getTime()) ? val.toString() : val.toISOString();\n        val = \"[Date: \" + sDate + \"]\";\n        break;\n      case \"buffer\":\n        var json = val.toJSON();\n        // Based on the toJSON result\n        json = json.data && json.type ? json.data : json;\n        val = \"[Buffer: \" + jsonStringify(json, 2, depth + 1) + \"]\";\n        break;\n      default:\n        val =\n          val === \"[Function]\" || val === \"[Circular]\"\n            ? val\n            : JSON.stringify(val); // string\n    }\n    return val;\n  }\n\n  for (var i in object) {\n    if (!Object.prototype.hasOwnProperty.call(object, i)) {\n      continue; // not my business\n    }\n    --length;\n    str +=\n      \"\\n \" +\n      repeat(\" \", space) +\n      (Array.isArray(object) ? \"\" : '\"' + i + '\": ') + // key\n      _stringify(object[i]) + // value\n      (length ? \",\" : \"\"); // comma\n  }\n\n  return (\n    str +\n    // [], {}\n    (str.length !== 1 ? \"\\n\" + repeat(\" \", space - 1) + end : end)\n  );\n}\n\n/**\n * Return a new Thing that has the keys in sorted order. Recursive.\n *\n * If the Thing...\n * - has already been seen, return string `'[Circular]'`\n * - is `undefined`, return string `'[undefined]'`\n * - is `null`, return value `null`\n * - is some other primitive, return the value\n * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method\n * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again.\n * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()`\n *\n * @private\n * @see {@link exports.stringify}\n * @param {*} value Thing to inspect.  May or may not have properties.\n * @param {Array} [stack=[]] Stack of seen values\n * @param {string} [typeHint] Type hint\n * @return {(Object|Array|Function|string|undefined)}\n */\nexports.canonicalize = function canonicalize(value, stack, typeHint) {\n  var canonicalizedObj;\n\n  var prop;\n\n  typeHint = typeHint || canonicalType(value);\n  function withStack(value, fn) {\n    stack.push(value);\n    fn();\n    stack.pop();\n  }\n\n  stack = stack || [];\n\n  if (stack.indexOf(value) !== -1) {\n    return \"[Circular]\";\n  }\n\n  switch (typeHint) {\n    case \"undefined\":\n    case \"buffer\":\n    case \"null\":\n      canonicalizedObj = value;\n      break;\n    case \"array\":\n      withStack(value, function () {\n        canonicalizedObj = value.map(function (item) {\n          return exports.canonicalize(item, stack);\n        });\n      });\n      break;\n    case \"function\":\n      /* eslint-disable-next-line no-unused-vars */\n      for (prop in value) {\n        canonicalizedObj = {};\n        break;\n      }\n\n      if (!canonicalizedObj) {\n        canonicalizedObj = emptyRepresentation(value, typeHint);\n        break;\n      }\n    /* falls through */\n    case \"null-prototype\":\n    case \"object\":\n      canonicalizedObj = canonicalizedObj || {};\n      if (typeHint === \"null-prototype\" && Symbol.toStringTag in value) {\n        canonicalizedObj[\"[Symbol.toStringTag]\"] = value[Symbol.toStringTag];\n      }\n      withStack(value, function () {\n        Object.keys(value)\n          .sort()\n          .forEach(function (key) {\n            canonicalizedObj[key] = exports.canonicalize(value[key], stack);\n          });\n      });\n      break;\n    case \"date\":\n    case \"number\":\n    case \"regexp\":\n    case \"boolean\":\n    case \"symbol\":\n      canonicalizedObj = value;\n      break;\n    default:\n      canonicalizedObj = value + \"\";\n  }\n\n  return canonicalizedObj;\n};\n\n/**\n * @summary\n * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`)\n * @description\n * When invoking this function you get a filter function that get the Error.stack as an input,\n * and return a prettify output.\n * (i.e: strip Mocha and internal node functions from stack trace).\n * @returns {Function}\n */\nexports.stackTraceFilter = function () {\n  // TODO: Replace with `process.browser`\n  var is = typeof document === \"undefined\" ? { node: true } : { browser: true };\n  var slash = path.sep;\n  var cwd;\n  if (is.node) {\n    cwd = exports.cwd() + slash;\n  } else {\n    cwd = (\n      typeof location === \"undefined\" ? window.location : location\n    ).href.replace(/\\/[^/]*$/, \"/\");\n    slash = \"/\";\n  }\n\n  function isMochaInternal(line) {\n    return (\n      ~line.indexOf(\"node_modules\" + slash + \"mocha\" + slash) ||\n      ~line.indexOf(slash + \"mocha.js\") ||\n      ~line.indexOf(slash + \"mocha.min.js\")\n    );\n  }\n\n  function isNodeInternal(line) {\n    return (\n      ~line.indexOf(\"(timers.js:\") ||\n      ~line.indexOf(\"(events.js:\") ||\n      ~line.indexOf(\"(node.js:\") ||\n      ~line.indexOf(\"(module.js:\") ||\n      ~line.indexOf(\"GeneratorFunctionPrototype.next (native)\") ||\n      false\n    );\n  }\n\n  return function (stack) {\n    stack = stack.split(\"\\n\");\n\n    stack = stack.reduce(function (list, line) {\n      if (isMochaInternal(line)) {\n        return list;\n      }\n\n      if (is.node && isNodeInternal(line)) {\n        return list;\n      }\n\n      // Clean up cwd(absolute)\n      if (/:\\d+:\\d+\\)?$/.test(line)) {\n        line = line.replace(\"(\" + cwd, \"(\");\n      }\n\n      list.push(line);\n      return list;\n    }, []);\n\n    return stack.join(\"\\n\");\n  };\n};\n\n/**\n * Crude, but effective.\n * @public\n * @param {*} value\n * @returns {boolean} Whether or not `value` is a Promise\n */\nexports.isPromise = function isPromise(value) {\n  return (\n    typeof value === \"object\" &&\n    value !== null &&\n    typeof value.then === \"function\"\n  );\n};\n\n/**\n * Clamps a numeric value to an inclusive range.\n *\n * @param {number} value - Value to be clamped.\n * @param {number[]} range - Two element array specifying [min, max] range.\n * @returns {number} clamped value\n */\nexports.clamp = function clamp(value, range) {\n  return Math.min(Math.max(value, range[0]), range[1]);\n};\n\n/**\n * It's a noop.\n * @public\n */\nexports.noop = function () {};\n\n/**\n * Creates a map-like object.\n *\n * @description\n * A \"map\" is an object with no prototype, for our purposes. In some cases\n * this would be more appropriate than a `Map`, especially if your environment\n * doesn't support it. Recommended for use in Mocha's public APIs.\n *\n * @public\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Custom_and_Null_objects|MDN:Map}\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Custom_and_Null_objects|MDN:Object.create - Custom objects}\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Custom_and_Null_objects|MDN:Object.assign}\n * @param {...*} [obj] - Arguments to `Object.assign()`.\n * @returns {Object} An object with no prototype, having `...obj` properties\n */\nexports.createMap = function () {\n  return Object.assign.apply(\n    null,\n    [Object.create(null)].concat(Array.prototype.slice.call(arguments)),\n  );\n};\n\n/**\n * Creates a read-only map-like object.\n *\n * @description\n * This differs from {@link module:utils.createMap createMap} only in that\n * the argument must be non-empty, because the result is frozen.\n *\n * @see {@link module:utils.createMap createMap}\n * @param {...*} [obj] - Arguments to `Object.assign()`.\n * @returns {Object} A frozen object with no prototype, having `...obj` properties\n * @throws {TypeError} if argument is not a non-empty object.\n */\nexports.defineConstants = function (obj) {\n  if (canonicalType(obj) !== \"object\" || !Object.keys(obj).length) {\n    throw new TypeError(\"Invalid argument; expected a non-empty object\");\n  }\n  return Object.freeze(exports.createMap(obj));\n};\n\n/**\n * Returns current working directory\n *\n * Wrapper around `process.cwd()` for isolation\n * @private\n */\nexports.cwd = function cwd() {\n  return process.cwd();\n};\n\n/**\n * Returns `true` if Mocha is running in a browser.\n * Checks for `process.browser`.\n * @returns {boolean}\n * @private\n */\nexports.isBrowser = function isBrowser() {\n  return Boolean(process.browser);\n};\n\n/*\n * Casts `value` to an array; useful for optionally accepting array parameters\n *\n * It follows these rules, depending on `value`.  If `value` is...\n * 1. `undefined`: return an empty Array\n * 2. `null`: return an array with a single `null` element\n * 3. Any other object: return the value of `Array.from()` _if_ the object is iterable\n * 4. otherwise: return an array with a single element, `value`\n * @param {*} value - Something to cast to an Array\n * @returns {Array<*>}\n */\nexports.castArray = function castArray(value) {\n  if (value === undefined) {\n    return [];\n  }\n  if (value === null) {\n    return [null];\n  }\n  if (\n    typeof value === \"object\" &&\n    (typeof value[Symbol.iterator] === \"function\" || value.length !== undefined)\n  ) {\n    return Array.from(value);\n  }\n  return [value];\n};\n\nexports.constants = exports.defineConstants({\n  MOCHA_ID_PROP_NAME,\n});\n\nconst uniqueIDBase =\n  \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_\";\n\n/**\n * Creates a new unique identifier\n * Does not create cryptographically safe ids.\n * Trivial copy of nanoid/non-secure\n * @returns {string} Unique identifier\n */\nexports.uniqueID = () => {\n  let id = \"\";\n  for (let i = 0; i < 21; i++) {\n    id += uniqueIDBase[(Math.random() * 64) | 0];\n  }\n  return id;\n};\n\nexports.assignNewMochaID = (obj) => {\n  const id = exports.uniqueID();\n  Object.defineProperty(obj, MOCHA_ID_PROP_NAME, {\n    get() {\n      return id;\n    },\n  });\n  return obj;\n};\n\n/**\n * Retrieves a Mocha ID from an object, if present.\n * @param {*} [obj] - Object\n * @returns {string|void}\n */\nexports.getMochaID = (obj) =>\n  obj && typeof obj === \"object\" ? obj[MOCHA_ID_PROP_NAME] : undefined;\n\n/**\n * Replaces any detected circular dependency with the string '[Circular]'\n * Mutates original object\n * @param inputObj {*}\n * @returns {*}\n */\nexports.breakCircularDeps = (inputObj) => {\n  const seen = new Set();\n\n  function _breakCircularDeps(obj) {\n    if (obj && typeof obj !== \"object\") {\n      return obj;\n    }\n\n    if (seen.has(obj)) {\n      return \"[Circular]\";\n    }\n\n    seen.add(obj);\n    for (const k in obj) {\n      const descriptor = Object.getOwnPropertyDescriptor(obj, k);\n\n      if (descriptor && descriptor.writable) {\n        obj[k] = _breakCircularDeps(obj[k], k);\n      }\n    }\n\n    // deleting means only a seen object that is its own child will be detected\n    seen.delete(obj);\n    return obj;\n  }\n\n  return _breakCircularDeps(inputObj);\n};\n\n/**\n * Checks if provided input can be parsed as a JavaScript Number.\n */\nexports.isNumeric = (input) => {\n  return !isNaN(parseFloat(input));\n};\n\n/**\n * Checks if being ran in a CI environment.\n *\n * This uses the CI env variable, which is set by most popular CI providers. Some\n * examples include:\n * Github:     https://docs.github.com/en/actions/reference/workflows-and-actions/variables\n * Gitlab:     https://docs.gitlab.com/ci/variables/predefined_variables/\n * CircleCI:   https://circleci.com/docs/reference/variables/#built-in-environment-variables\n * Bitbucket:  https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/\n */\nexports.isCI = () => {\n  return !!process.env.CI;\n};\n\nexports.logSymbols = {\n  info: pc.blue(isUnicodeSupported ? \"ℹ\" : \"i\"),\n  success: pc.green(isUnicodeSupported ? \"✔\" : \"√\"),\n  warning: pc.yellow(isUnicodeSupported ? \"⚠\" : \"‼\"),\n  error: pc.red(isUnicodeSupported ? \"✖\" : \"×\"),\n};\n"
  },
  {
    "path": "mocha.css",
    "content": "@charset \"utf-8\";\n\n:root {\n  --mocha-color: #000;\n  --mocha-bg-color: #fff;\n  --mocha-test-pass-color: #007f6a;\n  --mocha-test-pass-duration-color: #fff;\n  --mocha-test-pass-shadow-color: rgba(0, 0, 0, 0.2);\n  --mocha-test-pass-mediump-color: #c09853;\n  --mocha-test-pass-slow-color: #b94a48;\n  --mocha-test-pending-color: #0b97c4;\n  --mocha-test-pending-icon-color: #0b97c4;\n  --mocha-test-fail-color: #c00;\n  --mocha-test-fail-icon-color: #c00;\n  --mocha-test-fail-pre-color: #000;\n  --mocha-test-fail-pre-error-color: #c00;\n  --mocha-test-html-error-color: #000;\n  --mocha-box-shadow-color: #eee;\n  --mocha-box-bottom-color: #ddd;\n  --mocha-test-replay-color: #000;\n  --mocha-test-replay-bg-color: #eee;\n  --mocha-stats-color: #888;\n  --mocha-stats-em-color: #000;\n  --mocha-stats-hover-color: #eee;\n  --mocha-progress-ring-color: #eee;\n  --mocha-progress-ring-highlight-color: #9f9f9f;\n  --mocha-progress-text-color: #000;\n  --mocha-error-color: #c00;\n\n  --mocha-code-comment: #ddd;\n  --mocha-code-init: #2f6fad;\n  --mocha-code-string: #5890ad;\n  --mocha-code-keyword: #8a6343;\n  --mocha-code-number: #2f6fad;\n}\n\n@media (prefers-color-scheme: dark) {\n  :root {\n    --mocha-color: #fff;\n    --mocha-bg-color: #222;\n    --mocha-test-pass-color: #00d6b2;\n    --mocha-test-pass-duration-color: #222;\n    --mocha-test-pass-shadow-color: rgba(255, 255, 255, 0.2);\n    --mocha-test-pass-mediump-color: #f1be67;\n    --mocha-test-pass-slow-color: #f49896;\n    --mocha-test-pending-color: #0b97c4;\n    --mocha-test-pending-icon-color: #0b97c4;\n    --mocha-test-fail-color: #f44;\n    --mocha-test-fail-icon-color: #f44;\n    --mocha-test-fail-pre-color: #fff;\n    --mocha-test-fail-pre-error-color: #f44;\n    --mocha-test-html-error-color: #fff;\n    --mocha-box-shadow-color: #444;\n    --mocha-box-bottom-color: #555;\n    --mocha-test-replay-color: #fff;\n    --mocha-test-replay-bg-color: #444;\n    --mocha-stats-color: #aaa;\n    --mocha-stats-em-color: #fff;\n    --mocha-stats-hover-color: #444;\n    --mocha-progress-ring-color: #444;\n    --mocha-progress-ring-highlight-color: #888;\n    --mocha-progress-text-color: #fff;\n    --mocha-error-color: #f44;\n\n    --mocha-code-comment: #ddd;\n    --mocha-code-init: #9cc7f1;\n    --mocha-code-string: #80d4ff;\n    --mocha-code-keyword: #e3a470;\n    --mocha-code-number: #4ca7ff;\n  }\n}\n\nbody {\n  margin: 0;\n  background-color: var(--mocha-bg-color);\n  color: var(--mocha-color);\n}\n\n#mocha {\n  font:\n    20px/1.5 \"Helvetica Neue\",\n    Helvetica,\n    Arial,\n    sans-serif;\n  margin: 60px 50px;\n}\n\n#mocha ul,\n#mocha li {\n  margin: 0;\n  padding: 0;\n}\n\n#mocha ul {\n  list-style: none;\n}\n\n#mocha h1,\n#mocha h2 {\n  margin: 0;\n}\n\n#mocha h1 {\n  margin-top: 15px;\n  font-size: 1em;\n  font-weight: 200;\n}\n\n#mocha h1 a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha h1 a:hover {\n  text-decoration: underline;\n}\n\n#mocha .suite .suite h1 {\n  margin-top: 0;\n  font-size: 0.8em;\n}\n\n#mocha .hidden {\n  display: none;\n}\n\n#mocha h2 {\n  font-size: 12px;\n  font-weight: normal;\n  cursor: pointer;\n}\n\n#mocha .suite {\n  margin-left: 15px;\n}\n\n#mocha .test {\n  margin-left: 15px;\n  overflow: hidden;\n}\n\n#mocha .test.pending:hover h2::after {\n  content: \"(pending)\";\n  font-family: arial, sans-serif;\n}\n\n#mocha .test.pass.medium .duration {\n  background: var(--mocha-test-pass-mediump-color);\n}\n\n#mocha .test.pass.slow .duration {\n  background: var(--mocha-test-pass-slow-color);\n}\n\n#mocha .test.pass::before {\n  content: \"✓\";\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: var(--mocha-test-pass-color);\n}\n\n#mocha .test.pass .duration {\n  font-size: 9px;\n  margin-left: 5px;\n  padding: 2px 5px;\n  color: var(--mocha-test-pass-duration-color);\n  -webkit-box-shadow: inset 0 1px 1px var(--mocha-test-pass-shadow-color);\n  -moz-box-shadow: inset 0 1px 1px var(--mocha-test-pass-shadow-color);\n  box-shadow: inset 0 1px 1px var(--mocha-test-pass-shadow-color);\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  -ms-border-radius: 5px;\n  -o-border-radius: 5px;\n  border-radius: 5px;\n}\n\n#mocha .test.pass.fast .duration {\n  display: none;\n}\n\n#mocha .test.pending {\n  color: var(--mocha-test-pending-color);\n}\n\n#mocha .test.pending::before {\n  content: \"◦\";\n  color: var(--mocha-test-pending-icon-color);\n}\n\n#mocha .test.fail {\n  color: var(--mocha-test-fail-color);\n}\n\n#mocha .test.fail pre {\n  color: var(--mocha-test-fail-pre-color);\n}\n\n#mocha .test.fail::before {\n  content: \"✖\";\n  font-size: 12px;\n  display: block;\n  float: left;\n  margin-right: 5px;\n  color: var(--mocha-test-fail-icon-color);\n}\n\n#mocha .test pre.error {\n  color: var(--mocha-test-fail-pre-error-color);\n  max-height: 300px;\n  overflow: auto;\n}\n\n#mocha .test .html-error {\n  overflow: auto;\n  color: var(--mocha-test-html-error-color);\n  display: block;\n  float: left;\n  clear: left;\n  font:\n    12px/1.5 monaco,\n    monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid var(--mocha-box-shadow-color);\n  max-width: 85%; /*(1)*/\n  max-width: -webkit-calc(100% - 42px);\n  max-width: -moz-calc(100% - 42px);\n  max-width: calc(100% - 42px); /*(2)*/\n  max-height: 300px;\n  word-wrap: break-word;\n  border-bottom-color: var(--mocha-box-bottom-color);\n  -webkit-box-shadow: 0 1px 3px var(--mocha-box-shadow-color);\n  -moz-box-shadow: 0 1px 3px var(--mocha-box-shadow-color);\n  box-shadow: 0 1px 3px var(--mocha-box-shadow-color);\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n\n#mocha .test .html-error pre.error {\n  border: none;\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n  -webkit-box-shadow: 0;\n  -moz-box-shadow: 0;\n  box-shadow: 0;\n  padding: 0;\n  margin: 0;\n  margin-top: 18px;\n  max-height: none;\n}\n\n/**\n * (1): approximate for browsers not supporting calc\n * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)\n *      ^^ seriously\n */\n#mocha .test pre {\n  display: block;\n  float: left;\n  clear: left;\n  font:\n    12px/1.5 monaco,\n    monospace;\n  margin: 5px;\n  padding: 15px;\n  border: 1px solid var(--mocha-box-shadow-color);\n  max-width: 85%; /*(1)*/\n  max-width: -webkit-calc(100% - 42px);\n  max-width: -moz-calc(100% - 42px);\n  max-width: calc(100% - 42px); /*(2)*/\n  word-wrap: break-word;\n  border-bottom-color: var(--mocha-box-bottom-color);\n  -webkit-box-shadow: 0 1px 3px var(--mocha-box-shadow-color);\n  -moz-box-shadow: 0 1px 3px var(--mocha-box-shadow-color);\n  box-shadow: 0 1px 3px var(--mocha-box-shadow-color);\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  border-radius: 3px;\n}\n\n#mocha .test h2 {\n  position: relative;\n}\n\n#mocha .test a.replay {\n  position: absolute;\n  top: 3px;\n  right: 0;\n  text-decoration: none;\n  vertical-align: middle;\n  display: block;\n  width: 15px;\n  height: 15px;\n  line-height: 15px;\n  text-align: center;\n  background: var(--mocha-test-replay-bg-color);\n  font-size: 15px;\n  -webkit-border-radius: 15px;\n  -moz-border-radius: 15px;\n  border-radius: 15px;\n  -webkit-transition: opacity 200ms;\n  -moz-transition: opacity 200ms;\n  -o-transition: opacity 200ms;\n  transition: opacity 200ms;\n  opacity: 0.7;\n  color: var(--mocha-test-replay-color);\n}\n\n#mocha .test:hover a.replay {\n  box-shadow: 0 0 1px inset var(--mocha-test-replay-color);\n  opacity: 1;\n}\n\n#mocha-report.pass .test.fail {\n  display: none;\n}\n\n#mocha-report.fail .test.pass {\n  display: none;\n}\n\n#mocha-report.pending .test.pass,\n#mocha-report.pending .test.fail {\n  display: none;\n}\n#mocha-report.pending .test.pass.pending {\n  display: block;\n}\n\n#mocha-error {\n  color: var(--mocha-error-color);\n  font-size: 1.5em;\n  font-weight: 100;\n  letter-spacing: 1px;\n}\n\n#mocha-stats {\n  --ring-container-size: 40px;\n  --ring-size: 39px;\n  --ring-radius: calc(var(--ring-size) / 2);\n\n  position: fixed;\n  top: 15px;\n  right: 10px;\n  font-size: 12px;\n  margin: 0;\n  color: var(--mocha-stats-color);\n  z-index: 1;\n}\n\n#mocha-stats.fail li.result {\n  color: var(--mocha-test-fail-color);\n}\n\n#mocha-stats.fail li.failures {\n  color: var(--mocha-test-fail-color);\n}\n\n#mocha-stats.fail li.failures em {\n  color: var(--mocha-test-fail-color);\n}\n\n#mocha-stats.pass li.result {\n  color: var(--mocha-test-pass-color);\n}\n\n#mocha-stats.pass li.passes {\n  color: var(--mocha-test-pass-color);\n}\n\n#mocha-stats.pass li.passes em {\n  color: var(--mocha-test-pass-color);\n}\n\n#mocha-stats .progress-contain {\n  float: right;\n  padding: 0;\n}\n\n#mocha-stats .progress-element,\n#mocha-stats .progress-text {\n  width: var(--ring-container-size);\n  display: block;\n  top: 12px;\n  position: absolute;\n}\n\n#mocha-stats .progress-element {\n  visibility: hidden;\n  height: calc(var(--ring-container-size) / 2);\n}\n\n#mocha-stats .progress-text {\n  text-align: center;\n  text-overflow: clip;\n  overflow: hidden;\n  color: var(--mocha-stats-em-color);\n  font-size: 11px;\n}\n\n#mocha-stats .progress-ring {\n  width: var(--ring-container-size);\n  height: var(--ring-container-size);\n}\n\n#mocha-stats .ring-flatlight,\n#mocha-stats .ring-highlight {\n  --stroke-thickness: 1.65px;\n  --center: calc(var(--ring-container-size) / 2);\n  cx: var(--center);\n  cy: var(--center);\n  r: calc(var(--ring-radius) - calc(var(--stroke-thickness) / 2));\n  fill: hsla(0, 0%, 0%, 0);\n  stroke-width: var(--stroke-thickness);\n}\n\n#mocha-stats .ring-flatlight {\n  stroke: var(--mocha-progress-ring-color);\n}\n\n#mocha-stats .ring-highlight {\n  stroke: var(--mocha-progress-ring-highlight-color);\n}\n\n#mocha-stats em {\n  color: var(--mocha-stats-em-color);\n}\n\n#mocha-stats a {\n  text-decoration: none;\n  color: inherit;\n}\n\n#mocha-stats a:hover {\n  border-bottom: 1px solid var(--mocha-stats-hover-color);\n}\n\n#mocha-stats li {\n  display: inline-block;\n  margin: 0 5px;\n  list-style: none;\n  padding-top: 11px;\n}\n\n#mocha code .comment {\n  color: var(--mocha-code-comment);\n}\n#mocha code .init {\n  color: var(--mocha-code-init);\n}\n#mocha code .string {\n  color: var(--mocha-code-string);\n}\n#mocha code .keyword {\n  color: var(--mocha-code-keyword);\n}\n#mocha code .number {\n  color: var(--mocha-code-number);\n}\n\n@media screen and (max-device-width: 480px) {\n  #mocha {\n    margin: 60px 0px;\n  }\n\n  #mocha #stats {\n    position: absolute;\n  }\n}\n"
  },
  {
    "path": "mocha.mjs",
    "content": "// this built file is not committed to the repo\n// @copilot do not remove, this is used in a way you don't understand\n/* eslint-disable-next-line n/no-missing-import */\nimport \"./mocha.js\";\n\nconst { mocha, Mocha } = globalThis;\n\nconst mochaExports = {\n  after: (...args) => globalThis.after?.(...args),\n  afterEach: (...args) => globalThis.afterEach?.(...args),\n  before: (...args) => globalThis.before?.(...args),\n  beforeEach: (...args) => globalThis.beforeEach?.(...args),\n  context: (...args) => globalThis.context?.(...args),\n  describe: (...args) => globalThis.describe?.(...args),\n  it: (...args) => globalThis.it?.(...args),\n  setup: (...args) => globalThis.setup?.(...args),\n  suite: (...args) => globalThis.suite?.(...args),\n  suiteSetup: (...args) => globalThis.suiteSetup?.(...args),\n  suiteTeardown: (...args) => globalThis.suiteTeardown?.(...args),\n  teardown: (...args) => globalThis.teardown?.(...args),\n  test: (...args) => globalThis.test?.(...args),\n  specify: (...args) => globalThis.specify?.(...args),\n  xcontext: (...args) => globalThis.xcontext?.(...args),\n  xdescribe: (...args) => globalThis.xdescribe?.(...args),\n  xit: (...args) => globalThis.xit?.(...args),\n  xspecify: (...args) => globalThis.xspecify?.(...args),\n};\n\nexport default Mocha;\n\n// Export the mocha instance (in browser, this has setup/run methods)\nexport { mocha };\n\n// Re-export class/utility exports from the Mocha module\nexport const {\n  utils,\n  interfaces,\n  reporters,\n  Runnable,\n  Context,\n  Runner,\n  Suite,\n  Hook,\n  Test,\n} = Mocha;\n\n// Re-export test interface functions\nexport const {\n  after,\n  afterEach,\n  before,\n  beforeEach,\n  context,\n  describe,\n  it,\n  run,\n  setup,\n  suite,\n  suiteSetup,\n  suiteTeardown,\n  teardown,\n  test,\n  specify,\n  xcontext,\n  xdescribe,\n  xit,\n  xspecify,\n} = mochaExports;\n"
  },
  {
    "path": "netlify.toml",
    "content": "[build]\n  command = \"npm run docs\"\n  publish = \"docs/dist/\"\n\n[build.environment]\n  DEBUG = \"mocha:docs*\"\n  NODE_VERSION = \"24\"\n\n[context.deploy-preview]\n  command = \"npm run docs\"\n  publish = \"docs/dist/\"\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"mocha\",\n  \"version\": \"12.0.0-beta.10\",\n  \"type\": \"commonjs\",\n  \"description\": \"Classic, reliable, trusted test framework for Node.js and the browser\",\n  \"keywords\": [\n    \"mocha\",\n    \"test\",\n    \"bdd\",\n    \"tdd\",\n    \"tap\",\n    \"testing\",\n    \"chai\",\n    \"assertion\",\n    \"ava\",\n    \"jest\",\n    \"tape\",\n    \"jasmine\",\n    \"karma\"\n  ],\n  \"author\": \"TJ Holowaychuk <tj@vision-media.ca>\",\n  \"license\": \"MIT\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/mochajs/mocha.git\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/mochajs/mocha/issues/\"\n  },\n  \"discord\": \"https://discord.gg/KeDn2uXhER\",\n  \"homepage\": \"https://mochajs.org/\",\n  \"logo\": \"https://cldup.com/S9uQ-cOLYz.svg\",\n  \"notifyLogo\": \"https://ibin.co/4QuRuGjXvl36.png\",\n  \"bin\": {\n    \"mocha\": \"./bin/mocha.js\",\n    \"_mocha\": \"./bin/_mocha\"\n  },\n  \"directories\": {\n    \"lib\": \"./lib\",\n    \"test\": \"./test\"\n  },\n  \"engines\": {\n    \"node\": \"^20.19.0 || >=22.12.0\"\n  },\n  \"scripts\": {\n    \"build\": \"rollup -c ./rollup.config.mjs\",\n    \"clean\": \"rimraf mocha.js mocha.js.map\",\n    \"docs\": \"cd docs; npm run docs\",\n    \"format:check\": \"prettier --check .\",\n    \"format:fix\": \"prettier --write .\",\n    \"lint:installed-check\": \"installed-check --engine-check --ignore-dev\",\n    \"lint:knip\": \"knip --cache\",\n    \"lint:knip-docs\": \"cd docs && npm run lint:knip\",\n    \"lint:code\": \"eslint . --max-warnings 0\",\n    \"lint\": \"run-p lint:*\",\n    \"prepublishOnly\": \"run-s clean build version\",\n    \"test-browser-run\": \"cross-env NODE_PATH=. karma start ./karma.conf.js --single-run\",\n    \"test-browser:reporters:bdd\": \"cross-env MOCHA_TEST=bdd npm run -s test-browser-run\",\n    \"test-browser:reporters:esm\": \"cross-env MOCHA_TEST=esm npm run -s test-browser-run\",\n    \"test-browser:reporters:qunit\": \"cross-env MOCHA_TEST=qunit npm run -s test-browser-run\",\n    \"test-browser:reporters:tdd\": \"cross-env MOCHA_TEST=tdd npm run -s test-browser-run\",\n    \"test-browser:reporters\": \"run-s test-browser:reporters:*\",\n    \"test-browser:webpack-compat\": \"webpack --mode development --config ./test/browser-specific/fixtures/webpack/webpack.config.js\",\n    \"test-browser\": \"run-s clean build test-browser:*\",\n    \"test-coverage-clean\": \"rimraf .nyc_output coverage\",\n    \"test-coverage-generate\": \"nyc report --reporter=lcov --reporter=text\",\n    \"test-node-run-only\": \"nyc --no-clean --reporter=json node bin/mocha.js --no-forbid-only\",\n    \"test-node-run\": \"nyc --no-clean --reporter=json node bin/mocha.js --forbid-only\",\n    \"test-node:integration\": \"run-s clean build && npm run -s test-node-run -- --parallel --timeout 10000 --slow 3750 \\\"test/integration/**/*.spec.js\\\"\",\n    \"test-node:integration:watch\": \"run-s clean build && npm run -s test-node-run -- --parallel --timeout 10000 --slow 3750 \\\"test/integration/options/watch.spec.js\\\"\",\n    \"test-node:interfaces:bdd\": \"npm run -s test-node-run -- --ui bdd test/interfaces/bdd.spec\",\n    \"test-node:interfaces:exports\": \"npm run -s test-node-run -- --ui exports test/interfaces/exports.spec\",\n    \"test-node:interfaces:qunit\": \"npm run -s test-node-run -- --ui qunit test/interfaces/qunit.spec\",\n    \"test-node:interfaces:tdd\": \"npm run -s test-node-run -- --ui tdd test/interfaces/tdd.spec\",\n    \"test-node:interfaces\": \"run-p test-node:interfaces:*\",\n    \"test-node:jsapi\": \"node test/jsapi/index.js\",\n    \"test-node:only:bddRequire\": \"npm run -s test-node-run-only -- --ui qunit test/only/bdd-require.spec --no-parallel\",\n    \"test-node:only:globalBdd\": \"npm run -s test-node-run-only -- --ui bdd test/only/global/bdd.spec --no-parallel\",\n    \"test-node:only:globalQunit\": \"npm run -s test-node-run-only -- --ui qunit test/only/global/qunit.spec --no-parallel\",\n    \"test-node:only:globalTdd\": \"npm run -s test-node-run-only -- --ui tdd test/only/global/tdd.spec --no-parallel\",\n    \"test-node:only\": \"run-p test-node:only:*\",\n    \"test-node:reporters\": \"npm run -s test-node-run -- \\\"test/reporters/*.spec.js\\\"\",\n    \"test-node:requires\": \"npm run -s test-node-run -- --require coffeescript/register --require test/require/a.js --require test/require/b.coffee --require test/require/c.js --require test/require/d.coffee test/require/require.spec.js\",\n    \"test-node:unit\": \"npm run -s test-node-run -- \\\"test/unit/*.spec.js\\\" \\\"test/node-unit/**/*.spec.js\\\"\",\n    \"test-node\": \"run-s test-coverage-clean test-node:* test-coverage-generate\",\n    \"test-smoke\": \"node ./bin/mocha --no-config test/smoke/smoke.spec.js\",\n    \"test\": \"run-s lint test-node test-browser\",\n    \"tsc\": \"tsc\",\n    \"version:linkify-changelog\": \"node scripts/linkify-changelog.mjs\",\n    \"version:update-authors\": \"node scripts/update-authors.js\",\n    \"version\": \"run-p version:* && git add -A ./AUTHORS ./CHANGELOG.md\"\n  },\n  \"dependencies\": {\n    \"browser-stdout\": \"^1.3.1\",\n    \"chokidar\": \"^5.0.0\",\n    \"debug\": \"^4.3.5\",\n    \"diff\": \"^8.0.3\",\n    \"escape-string-regexp\": \"^4.0.0\",\n    \"find-up\": \"^5.0.0\",\n    \"glob\": \"^13.0.0\",\n    \"he\": \"^1.2.0\",\n    \"is-path-inside\": \"^3.0.3\",\n    \"is-unicode-supported\": \"^0.1.0\",\n    \"js-yaml\": \"^4.1.0\",\n    \"minimatch\": \"^10.2.2\",\n    \"ms\": \"^2.1.3\",\n    \"picocolors\": \"^1.1.1\",\n    \"serialize-javascript\": \"^7.0.2\",\n    \"strip-json-comments\": \"^5.0.3\",\n    \"supports-color\": \"^8.1.1\",\n    \"workerpool\": \"^10.0.0\",\n    \"yargs\": \"^17.7.2\",\n    \"yargs-parser\": \"^21.1.1\",\n    \"yargs-unparser\": \"^2.0.0\"\n  },\n  \"devDependencies\": {\n    \"@eslint/js\": \"^10.0.0\",\n    \"@eslint/markdown\": \"^7.5.1\",\n    \"@rollup/plugin-alias\": \"^6.0.0\",\n    \"@rollup/plugin-commonjs\": \"^29.0.0\",\n    \"@rollup/plugin-json\": \"^6.1.0\",\n    \"@rollup/plugin-multi-entry\": \"^7.1.0\",\n    \"@rollup/plugin-node-resolve\": \"^16.0.3\",\n    \"@test/esm-only-loader\": \"./test/compiler-fixtures/esm-only-loader\",\n    \"@types/node\": \"^22.15.3\",\n    \"@types/yargs\": \"^17.0.33\",\n    \"chai\": \"^6.0.0\",\n    \"coffeescript\": \"^2.6.1\",\n    \"cross-env\": \"^10.0.0\",\n    \"eslint\": \"^10.0.0\",\n    \"eslint-plugin-n\": \"^17.23.1\",\n    \"fail-on-errors-webpack-plugin\": \"^3.0.0\",\n    \"globals\": \"^16.5.0\",\n    \"installed-check\": \"^10.0.0\",\n    \"karma\": \"^6.4.2\",\n    \"karma-chrome-launcher\": \"^3.2.0\",\n    \"karma-mocha\": \"^2.0.1\",\n    \"karma-mocha-reporter\": \"^2.2.5\",\n    \"knip\": \"^5.61.3\",\n    \"npm-run-all2\": \"^8.0.0\",\n    \"nyc\": \"^17.1.0\",\n    \"prettier\": \"3.8.1\",\n    \"ps-list\": \"^9.0.0\",\n    \"remark\": \"^15.0.0\",\n    \"remark-github\": \"^12.0.0\",\n    \"remark-inline-links\": \"^7.0.0\",\n    \"rewiremock\": \"^3.14.3\",\n    \"rimraf\": \"^6.0.0\",\n    \"rollup\": \"^4.52.3\",\n    \"rollup-plugin-polyfill-node\": \"^0.13.0\",\n    \"rollup-plugin-visualizer\": \"^6.0.5\",\n    \"semver\": \"^7.7.2\",\n    \"sinon\": \"^9.0.3\",\n    \"typescript\": \"^5.8.3\",\n    \"unexpected\": \"^11.14.0\",\n    \"unexpected-eventemitter\": \"^2.2.0\",\n    \"unexpected-map\": \"^3.0.0\",\n    \"unexpected-set\": \"^3.0.0\",\n    \"unexpected-sinon\": \"^10.11.2\",\n    \"webpack\": \"^5.67.0\",\n    \"webpack-cli\": \"^6.0.0\"\n  },\n  \"files\": [\n    \"bin/*mocha*\",\n    \"lib/**/*.{js,html,json}\",\n    \"index.js\",\n    \"mocha.css\",\n    \"mocha.js\",\n    \"mocha.js.map\",\n    \"mocha.mjs\",\n    \"browser-entry.js\"\n  ],\n  \"browser\": {\n    \"./index.js\": \"./browser-entry.js\",\n    \"fs\": false,\n    \"path\": false,\n    \"supports-color\": false,\n    \"./lib/nodejs/buffered-worker-pool.js\": false,\n    \"./lib/nodejs/esm-utils.js\": false,\n    \"./lib/nodejs/file-unloader.js\": false,\n    \"./lib/nodejs/parallel-buffered-runner.js\": false,\n    \"./lib/nodejs/serializer.js\": false,\n    \"./lib/nodejs/worker.js\": false,\n    \"./lib/nodejs/reporters/parallel-buffered.js\": false,\n    \"./lib/cli/index.js\": false\n  },\n  \"overrides\": {\n    \"@types/eslint\": \"^9.6.1\",\n    \"@types/estree\": \"^1.0.7\",\n    \"webdriverio\": \"^9.0.0\"\n  }\n}\n"
  },
  {
    "path": "renovate.json",
    "content": "{\n  \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n  \"extends\": [\"config:recommended\"],\n  \"minimumReleaseAge\": \"7 days\",\n  \"patch\": {\n    \"enabled\": false\n  }\n}\n"
  },
  {
    "path": "rollup.config.mjs",
    "content": "import alias from \"@rollup/plugin-alias\";\nimport commonjs from \"@rollup/plugin-commonjs\";\nimport nodeResolve from \"@rollup/plugin-node-resolve\";\nimport json from \"@rollup/plugin-json\";\nimport nodePolyfills from \"rollup-plugin-polyfill-node\";\n\n// Debugging tools\nimport { visualizer } from \"rollup-plugin-visualizer\";\n\nimport pickFromPackageJson from \"./scripts/pick-from-package-json.mjs\";\nimport packageJson from \"./package.json\" with { type: \"json\" };\n\nconst config = {\n  input: \"./browser-entry.js\",\n  strictDeprecations: true,\n  output: {\n    file: \"./mocha.js\",\n    format: \"umd\",\n    sourcemap: true,\n    name: \"mocha\",\n    banner: `// mocha@${packageJson.version} in javascript ES2018`,\n  },\n  plugins: [\n    // https://github.com/FredKSchott/rollup-plugin-polyfill-node/issues/84\n    alias({\n      entries: [{ find: /^node:(.*)/, replacement: \"$1\" }],\n    }),\n    json(),\n    pickFromPackageJson({\n      keys: [\"name\", \"version\", \"homepage\", \"notifyLogo\"],\n    }),\n    commonjs(),\n    nodePolyfills({\n      // Polyfill all files, including all files including any source files.\n      include: null,\n    }),\n    nodeResolve({\n      browser: true,\n    }),\n  ],\n  onwarn: (warning, warn) => {\n    if (warning.code === \"CIRCULAR_DEPENDENCY\") return;\n\n    // Use default for everything else\n    warn(warning);\n  },\n};\n\nif (!process.env.CI) {\n  config.plugins.push(visualizer());\n}\n\nexport default config;\n"
  },
  {
    "path": "scripts/karma-rollup-plugin.js",
    "content": "\"use strict\";\n\n/**\n * This Karma plugin bundles all test files into a single file for browser\n * testing.\n *\n * The plugin reads the file configuration from your Karma config and replaces\n * them with a single bundle file instead. This is done by creating a rollup\n * bundle file at a new path, then replacing all input file glob patterns with\n * the bundle file. Then a bundle processor transform is added to handle that\n * specific new file. The bundle preprocessor is the one actually calling\n * rollup with a modified config that allows for multiple entry points for a\n * single output bundle.\n *\n * This is an implementation that specifically solves Mocha's use case. It\n * does not support watch mode. It possibly could be made reusable with\n * more work and actual testing.\n *\n * We do not use karma-rollup-preprocessor because at the time of\n * implementation it had a behavior where each individual file gets bundled\n * separately with no deduplication of dependencies across bundles. This makes\n * the operation slow to a point where it is actively blocking a responsive\n * feedback loop in development.\n * See issue at https://github.com/jlmakes/karma-rollup-preprocessor/issues/49\n *\n * This plugin was based on the architecture of\n * https://www.npmjs.com/package/karma-browserify in order to achieve the\n * behavior where all input files get bundled into a single file. The code has\n * been modified heavily to simplify and support rollup instead of browserify.\n */\n\nconst os = require(\"node:os\");\nconst fs = require(\"node:fs\");\nconst path = require(\"node:path\");\nconst { randomUUID } = require(\"node:crypto\");\nconst rollup = require(\"rollup\");\nconst { minimatch } = require(\"minimatch\");\nconst { loadConfigFile } = require(\"rollup/dist/loadConfigFile.js\");\nconst multiEntry = require(\"@rollup/plugin-multi-entry\");\n\nconst fileMap = new Map();\n\n/**\n * The rollup framework that creates the initial logger and bundle file\n * as well as prepends the bundle file to the karma file configuration.\n */\nfunction framework(fileConfigs, pluginConfig, basePath, preprocessors) {\n  const includePatterns = pluginConfig.include.map((pattern) =>\n    path.resolve(basePath, pattern),\n  );\n\n  const bundlePatterns = fileConfigs\n    .map((fileConfig) => fileConfig.pattern)\n    .filter((filePath) =>\n      includePatterns.some((includePattern) =>\n        minimatch(filePath, includePattern.replace(/\\\\/g, \"/\")),\n      ),\n    );\n\n  const bundleFilename = `${randomUUID()}.rollup.js`;\n  let bundleLocation = path.resolve(\n    pluginConfig.bundleDirPath ? pluginConfig.bundleDirPath : os.tmpdir(),\n    bundleFilename,\n  );\n  if (process.platform === \"win32\") {\n    bundleLocation = bundleLocation.replace(/\\\\/g, \"/\");\n  }\n\n  fs.closeSync(fs.openSync(bundleLocation, \"w\"));\n  preprocessors[bundleLocation] = [\"rollup\"];\n\n  // Save file mapping for later\n  fileMap.set(bundleLocation, bundlePatterns);\n\n  // Remove all file match patterns that were included in bundle\n  // And inject the bundle in their place.\n  // Need to use array mutation, otherwise Karma ignores us\n  let bundleInjected = false;\n  for (const bundlePattern of bundlePatterns) {\n    const idx = fileConfigs.findIndex(\n      ({ pattern }) => pattern === bundlePattern,\n    );\n\n    if (idx > -1) {\n      if (bundleInjected) {\n        fileConfigs.splice(idx, 1);\n      } else {\n        fileConfigs.splice(idx, 1, {\n          pattern: bundleLocation,\n          served: true,\n          included: true,\n          watched: true,\n        });\n        bundleInjected = true;\n      }\n    }\n  }\n}\n\nframework.$inject = [\n  \"config.files\",\n  \"config.rollup\",\n  \"config.basePath\",\n  \"config.preprocessors\",\n];\n\n/**\n * A special preprocessor that builds the main rollup bundle once and\n * passes the bundle contents through on all later preprocessing request.\n */\nfunction bundlePreprocessor(config) {\n  const {\n    basePath,\n    rollup: { configFile, globals = {}, external = [] },\n  } = config;\n\n  return async function (content, file, done) {\n    const configPromise = await loadConfigFile(\n      path.resolve(basePath, configFile),\n    );\n    const { options, warnings } = await configPromise;\n    const config = options[0];\n    // plugins is always an array\n    const pluginConfig = [\n      ...(config.plugins || []),\n      multiEntry({ exports: false }),\n    ];\n    // XXX: output is always an array, but we only have one output config.\n    // if we have multiple, this code needs changing.\n    const outputConfig = {\n      ...((config.output || [])[0] || {}),\n      file: file.path,\n      globals,\n      sourcemap: \"inline\",\n    };\n\n    warnings.flush();\n\n    const bundle = await rollup.rollup({\n      input: fileMap.get(file.path),\n      plugins: pluginConfig,\n      external,\n      onwarn: config.onwarn,\n    });\n\n    await bundle.write(outputConfig);\n    console.error(`wrote bundle to ${file.path}`);\n    const code = fs.readFileSync(outputConfig.file, \"utf8\");\n\n    done(null, code);\n  };\n}\n\nbundlePreprocessor.$inject = [\"config\"];\n\nmodule.exports = {\n  \"framework:rollup\": [\"factory\", framework],\n  \"preprocessor:rollup\": [\"factory\", bundlePreprocessor],\n};\n"
  },
  {
    "path": "scripts/linkify-changelog.mjs",
    "content": "/**\n * Linkify CHANGELOG.md\n */\n\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { remark } from \"remark\";\nimport remarkGithub from \"remark-github\";\nimport remarkInlineLinks from \"remark-inline-links\";\n\nconst filepath = new URL(\"../CHANGELOG.md\", import.meta.url);\n\nwriteFileSync(\n  filepath,\n  remark()\n    .data(\"settings\", {\n      bullet: \"-\",\n      incrementListMarker: false,\n      listItemIndent: \"one\",\n    })\n    .use([remarkGithub, remarkInlineLinks])\n    .processSync(readFileSync(filepath))\n    .toString(),\n);\n"
  },
  {
    "path": "scripts/pick-from-package-json.mjs",
    "content": "/**\n * This rollup plugin lets you pick specific fields you want to export\n * for the specific case of importing a modules `package.json`.\n *\n * This helps reduce the file size of the resulting bundle.\n *\n * @param {object} options\n * @param {string[]} options.keys List of keys to export from package.json\n */\nexport default function pickFromPackageJson({ keys }) {\n  return {\n    name: \"pick-from-package-json\",\n    load: async (id) => {\n      if (id.endsWith(\"mocha/package.json\")) {\n        const manifest = await import(id, { with: { type: \"json\" } });\n\n        const result = {};\n\n        for (const key of keys) {\n          result[key] = manifest[key];\n        }\n\n        return { code: JSON.stringify(result) };\n      }\n      return null;\n    },\n  };\n}\n"
  },
  {
    "path": "scripts/update-authors.js",
    "content": "// original comes from https://github.com/nodejs/node/blob/master/tools/update-authors.js\n\n// Usage: tools/update-author.js [--dry]\n// Passing --dry will redirect output to stdout rather than write to 'AUTHORS'.\n\"use strict\";\nconst { spawn } = require(\"node:child_process\");\nconst fs = require(\"node:fs\");\nconst readline = require(\"node:readline\");\n\nconst log = spawn(\n  \"git\",\n  // Inspect author name/email and body.\n  [\"log\", \"--reverse\", \"--format=Author: %aN <%aE>\\n%b\"],\n  {\n    stdio: [\"inherit\", \"pipe\", \"inherit\"],\n  },\n);\nconst rl = readline.createInterface({ input: log.stdout });\n\nlet output;\nif (process.argv.includes(\"--dry\")) {\n  output = process.stdout;\n} else {\n  output = fs.createWriteStream(\"AUTHORS\");\n}\n\noutput.write(\"# Authors ordered by first contribution.\\n\\n\");\n\nconst seen = new Set();\n\nconst excludeEmails = [\n  \"<support@greenkeeper.io>\",\n  \"<greenkeeper[bot]@users.noreply.github.com>\",\n];\n\n// Support regular git author metadata, as well as `Author:` and\n// `Co-authored-by:` in the message body. Both have been used in the past\n// to indicate multiple authors per commit, with the latter standardized\n// by GitHub now.\nconst authorRe =\n  /(^Author:|^Co-authored-by:)\\s+(?<author>[^<]+)\\s+(?<email><[^>]+>)/i;\n\nrl.on(\"line\", (line) => {\n  const match = line.match(authorRe);\n  if (!match) return;\n\n  const { author, email } = match.groups;\n\n  if (seen.has(email) || excludeEmails.includes(email)) {\n    return;\n  }\n\n  seen.add(email);\n  output.write(`${author} ${email}\\n`);\n});\n\nrl.on(\"close\", () => {\n  output.end(\"\\n# Generated by scripts/update-authors.js\\n\");\n});\n"
  },
  {
    "path": "test/README.md",
    "content": "# About Mocha's Tests\n\n- **All assertions should be made using [unexpected](http://unexpected.js.org)**, unless there's a good reason not to. Exceptions include:\n  - Testing diff output. Mocha generates diff output unless the assertion library decides to do this itself. Since `unexpected` generates its _own_ diff output, we need to use an assertion library that does not; we use the built-in `assert` module.\n  - `test/unit/runnable.spec.js` must avoid 3rd-party code; read source for more info\n  - Tests asserting interop with other specific assertion libraries.\n- All tests have extension `.spec.js`.\n- All test fixtures have extension `.fixture.js`.\n- All test fixtures are _ignored_ by ESLint.\n- `mocha.opts` will require `test/setup.js`, which is the main harness.\n- `test/assertions.js` contains Mocha-specific types and assertions for `unexpected`\n- `test/node-unit/` only runs in Node.js; `test/browser-specific/` only runs in the browser.\n  - See `../karma.conf.js` for more information on which tests run in the browser.\n- We can't run all of the Node.js tests in one `mocha` command, because we need to use different command-line options to test the various reporters and interfaces.\n  - See `../package-scripts.js` for more info about how things are split up.\n"
  },
  {
    "path": "test/assertions.js",
    "content": "\"use strict\";\n\nconst { version } = require(\"../package.json\");\nconst escapeRe = require(\"escape-string-regexp\");\n\nmodule.exports = {\n  name: \"unexpected-mocha-internal\",\n  version,\n  installInto(expect) {\n    expect\n      .addType({\n        name: \"RawResult\",\n        base: \"object\",\n        identify(v) {\n          return (\n            this.baseType.identify(v) &&\n            typeof v.output === \"string\" &&\n            \"code\" in v && // may be null\n            Array.isArray(v.args) &&\n            typeof v.command === \"string\"\n          );\n        },\n      })\n      .addType({\n        name: \"JSONResult\",\n        base: \"RawResult\",\n        identify(v) {\n          return (\n            this.baseType.identify(v) &&\n            typeof v.stats === \"object\" &&\n            Array.isArray(v.failures) &&\n            Array.isArray(v.passes) &&\n            Array.isArray(v.tests) &&\n            Array.isArray(v.pending)\n          );\n        },\n      })\n      .addType({\n        name: \"SummarizedResult\",\n        base: \"RawResult\",\n        identify(v) {\n          return (\n            this.baseType.identify(v) &&\n            typeof v.passing === \"number\" &&\n            typeof v.failing === \"number\" &&\n            typeof v.pending === \"number\"\n          );\n        },\n      })\n      .addAssertion(\n        \"<JSONResult> [not] to have (passed|succeeded)\",\n        (expect, result) => {\n          expect(result, \"to satisfy\", {\n            code: expect.it(\"[not] to be\", 0),\n            stats: {\n              failures: expect.it(\"[not] to be\", 0),\n            },\n            failures: expect.it(\"[not] to be empty\"),\n          });\n        },\n      )\n      .addAssertion(\n        \"<SummarizedResult|RawResult> [not] to have (passed|succeeded)\",\n        (expect, result) => {\n          expect(result, \"[not] to have property\", \"code\", 0);\n        },\n      )\n      .addAssertion(\n        \"<SummarizedResult|JSONResult> [not] to have completed with [exit] code <number>\",\n        (expect, result, code) => {\n          expect(result.code, \"[not] to be\", code);\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have passed (with|having) count <number>\",\n        (expect, result, count) => {\n          expect(result, \"[not] to pass\").and(\"[not] to satisfy\", {\n            stats: { passes: expect.it(\"to be\", count) },\n          });\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have failed (with|having) count <number>\",\n        (expect, result, count) => {\n          expect(result, \"[not] to have failed\").and(\"[not] to satisfy\", {\n            stats: { failures: expect.it(\"to be\", count) },\n          });\n        },\n      )\n      .addAssertion(\"<JSONResult> [not] to have failed\", (expect, result) => {\n        expect(result, \"[not] to satisfy\", {\n          code: expect.it(\"to be greater than\", 0),\n          stats: {\n            failures: expect.it(\"to be greater than\", 0),\n          },\n          failures: expect.it(\"to be non-empty\"),\n        });\n      })\n      .addAssertion(\n        \"<SummarizedResult|RawResult> [not] to have failed\",\n        (expect, result) => {\n          expect(result, \"[not] to satisfy\", {\n            code: expect.it(\"to be greater than\", 0),\n          });\n        },\n      )\n      .addAssertion(\n        \"<SummarizedResult|RawResult> [not] to have failed (with|having) output <any>\",\n        (expect, result, output) => {\n          expect(result, \"[not] to satisfy\", {\n            code: expect.it(\"to be greater than\", 0),\n            output,\n          });\n        },\n      )\n      .addAssertion(\n        \"<SummarizedResult|RawResult> [not] to have passed (with|having) output <any>\",\n        (expect, result, output) => {\n          expect(result, \"[not] to satisfy\", {\n            code: 0,\n            output,\n          });\n        },\n      )\n      .addAssertion(\n        \"<SummarizedResult> [not] to have failed [test] count <number>\",\n        (expect, result, count) => {\n          expect(result.failing, \"[not] to be\", count);\n        },\n      )\n      .addAssertion(\n        \"<SummarizedResult> [not] to have passed [test] count <number>\",\n        (expect, result, count) => {\n          expect(result.passing, \"[not] to be\", count);\n        },\n      )\n      .addAssertion(\n        \"<SummarizedResult> [not] to have pending [test] count <number>\",\n        (expect, result, count) => {\n          expect(result.pending, \"[not] to be\", count);\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have test count <number>\",\n        (expect, result, count) => {\n          expect(result.stats.tests, \"[not] to be\", count);\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have failed [test] count <number>\",\n        (expect, result, count) => {\n          expect(result.stats.failures, \"[not] to be\", count);\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have passed [test] count <number>\",\n        (expect, result, count) => {\n          expect(result.stats.passes, \"[not] to be\", count);\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have pending [test] count <number>\",\n        (expect, result, count) => {\n          expect(result.stats.pending, \"[not] to be\", count);\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have run (test|tests) <string+>\",\n        (expect, result, ...titles) => {\n          titles.forEach((title) => {\n            expect(\n              result,\n              \"[not] to have a value satisfying\",\n              expect.it(\n                \"to have an item satisfying\",\n                expect\n                  .it(\"to have property\", \"title\", title)\n                  .or(\"to have property\", \"fullTitle\", title),\n              ),\n            );\n          });\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have failed (test|tests) <string+>\",\n        (expect, result, ...titles) => {\n          titles.forEach((title) => {\n            expect(\n              result.failures,\n              \"[not] to have an item satisfying\",\n              expect\n                .it(\"to have property\", \"title\", title)\n                .or(\"to have property\", \"fullTitle\", title),\n            );\n          });\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have (error|errors) <any+>\",\n        (expect, result, ...errors) => {\n          errors.forEach((error) => {\n            expect(result, \"[not] to satisfy\", {\n              failures: expect.it(\"to have an item satisfying\", {\n                err: expect\n                  .it(\"to satisfy\", error)\n                  .or(\"to satisfy\", { message: error }),\n              }),\n            });\n          });\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have passed (test|tests) <string+>\",\n        (expect, result, ...titles) => {\n          titles.forEach((title) => {\n            expect(result.passes, \"[not] to have an item satisfying\", {\n              title,\n            });\n          });\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have test order <string> <array>\",\n        (expect, result, state, titles) => {\n          expect(\n            result[state].slice(0, titles.length),\n            \"[not] to satisfy\",\n            titles.map((title) => {\n              return typeof title === \"string\" ? { title } : title;\n            }),\n          );\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have passed test order <array>\",\n        (expect, result, titles) => {\n          expect(result, \"[not] to have test order\", \"passes\", titles);\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have passed test order <string+>\",\n        (expect, result, ...titles) => {\n          expect(result, \"[not] to have test order\", \"passes\", titles);\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have failed test order <array>\",\n        (expect, result, titles) => {\n          expect(result, \"[not] to have test order\", \"failures\", titles);\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have failed test order <string+>\",\n        (expect, result, ...titles) => {\n          expect(result, \"[not] to have test order\", \"failures\", titles);\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have pending test order <array>\",\n        (expect, result, titles) => {\n          expect(result, \"[not] to have test order\", \"pending\", titles);\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have pending test order <string+>\",\n        (expect, result, ...titles) => {\n          expect(result, \"[not] to have test order\", \"pending\", titles);\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have pending tests\",\n        (expect, result) => {\n          expect(result.stats.pending, \"[not] to be greater than\", 0);\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have passed tests\",\n        (expect, result) => {\n          expect(result.stats.passes, \"[not] to be greater than\", 0);\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have failed tests\",\n        (expect, result) => {\n          expect(result.stats.failed, \"[not] to be greater than\", 0);\n        },\n      )\n      .addAssertion(\"<JSONResult> [not] to have tests\", (expect, result) => {\n        expect(result.stats.tests, \"[not] to be greater than\", 0);\n      })\n      .addAssertion(\n        \"<JSONResult> [not] to have retried test <string>\",\n        (expect, result, title) => {\n          expect(result.tests, \"[not] to have an item satisfying\", {\n            title,\n            currentRetry: expect.it(\"to be positive\"),\n          });\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have retried test <string> <number>\",\n        (expect, result, title, count) => {\n          expect(result.tests, \"[not] to have an item satisfying\", {\n            title,\n            currentRetry: count,\n          });\n        },\n      )\n      .addAssertion(\n        \"<JSONResult> [not] to have failed with (error|errors) <any+>\",\n        function (expect, result, ...errors) {\n          errors.forEach((error) => {\n            expect(result, \"[not] to have failed\").and(\"[not] to satisfy\", {\n              failures: expect.it(\"to have an item satisfying\", {\n                err: expect\n                  .it(\"to satisfy\", error)\n                  .or(\"to satisfy\", { message: error }),\n              }),\n            });\n          });\n        },\n      )\n      .addAssertion(\n        \"<RawResult|SummarizedResult> [not] to contain [output] <any>\",\n        (expect, result, output) => {\n          expect(result.output, \"[not] to satisfy\", output);\n        },\n      )\n      .addAssertion(\n        \"<RawResult|SummarizedResult> to contain [output] once <any>\",\n        (expect, result, output) => {\n          if (typeof output === \"string\") {\n            output = escapeRe(output);\n          } else if (!(output instanceof RegExp)) {\n            throw new TypeError(\"expected a string or regexp\");\n          }\n          output = new RegExp(output, \"g\");\n          expect(result.output.match(output), \"to have length\", 1);\n        },\n      )\n      .addAssertion(\n        \"<RawResult|SummarizedResult|JSONResult> to have [exit] code <number>\",\n        (expect, result, code) => {\n          expect(result.code, \"to be\", code);\n        },\n      );\n  },\n};\n"
  },
  {
    "path": "test/browser-specific/esm.spec.mjs",
    "content": "import \"./fixtures/esm.fixture.mjs\";\n\nit(\"should register a global if it did not fail\", function () {\n  expect(window.MOCHA_IS_OK, \"to be ok\");\n});\n\nit(\"should has global Mocha\", function () {\n  expect(window.Mocha, \"not to be\", undefined);\n});\n"
  },
  {
    "path": "test/browser-specific/fixtures/esm.fixture.mjs",
    "content": "/* eslint-disable-next-line import/no-absolute-path */\nimport '/base/mocha.js';\nwindow.MOCHA_IS_OK = true;\n"
  },
  {
    "path": "test/browser-specific/fixtures/webpack/webpack.config.js",
    "content": "'use strict';\n\nconst FailOnErrorsPlugin = require('fail-on-errors-webpack-plugin');\nconst {tmpdir} = require('node:os');\nconst {join} = require('node:path');\n\nconst outputPath = join(tmpdir(), 'mocha-test-webpack');\n\nconsole.error('output dir: %s', outputPath);\n\nmodule.exports = {\n  entry: require.resolve('./webpack.fixture.mjs'),\n  target: 'browserslist:last 2 Chrome versions',\n  output: {\n    path: outputPath,\n    chunkFormat: 'commonjs'\n  },\n  plugins: [\n    new FailOnErrorsPlugin({\n      failOnErrors: true,\n      failOnWarnings: false\n    })\n  ]\n};\n"
  },
  {
    "path": "test/browser-specific/fixtures/webpack/webpack.fixture.mjs",
    "content": "/* eslint-disable-next-line no-unused-vars */\nimport mocha from '../../../../mocha.js';\n"
  },
  {
    "path": "test/browser-specific/setup.js",
    "content": "\"use strict\";\n\nprocess.stdout = require(\"browser-stdout\")();\n\nglobal.expect = require(\"unexpected\")\n  .clone()\n  .use(require(\"unexpected-set\"))\n  .use(require(\"unexpected-map\"))\n  .use(require(\"unexpected-sinon\"))\n  .use(require(\"unexpected-eventemitter\"));\n"
  },
  {
    "path": "test/compiler/test.coffee",
    "content": "\nobj = foo: 'bar'\n\ndescribe 'coffeescript', ->\n  it 'should work', ->\n    expect(obj, 'to equal', foo: 'bar')\n"
  },
  {
    "path": "test/compiler/test.foo",
    "content": "1\n"
  },
  {
    "path": "test/compiler-cjs/test.js",
    "content": "const obj = { foo: \"bar\" };\n\ndescribe(\"cjs written in esm\", () => {\n  it(\"should work\", () => {\n    expect(obj, \"to equal\", { foo: \"bar\" });\n  });\n});\n\nexport const foo = \"bar\";\n"
  },
  {
    "path": "test/compiler-cjs/test.js.compiled",
    "content": "const obj = { foo: 'bar' };\n\ndescribe('cjs written in esm', () => {\n  it('should work', () => {\n    expect(obj, 'to equal', { foo: 'bar' });\n  });\n});\n\nmodule.exports.foo = 'bar';\n"
  },
  {
    "path": "test/compiler-cjs/test.ts",
    "content": "const obj: unknown = { foo: \"bar\" };\n\ndescribe(\"cts written in esm\", () => {\n  it(\"should work\", () => {\n    expect(obj, \"to equal\", { foo: \"bar\" });\n  });\n});\n\nexport const foo = \"bar\";\n"
  },
  {
    "path": "test/compiler-cjs/test.ts.compiled",
    "content": "const obj = { foo: 'bar' };\n\ndescribe('cts written in esm', () => {\n  it('should work', () => {\n    expect(obj, 'to equal', { foo: 'bar' });\n  });\n});\n\nmodule.exports.foo = 'bar';\n"
  },
  {
    "path": "test/compiler-esm/package.json",
    "content": "{\n  \"//\": \"Setting default type for .ts files as ESM as well\",\n  \"type\": \"module\"\n}\n"
  },
  {
    "path": "test/compiler-esm/test-tla.js",
    "content": "const obj = { foo: \"bar\" };\n\ndescribe(\"esm written in esm with top-level-await\", () => {\n  it(\"should work\", () => {\n    expect(obj, \"to equal\", { foo: \"bar\" });\n  });\n});\n\nawait undefined;\n\nexport const foo = \"bar\";\n"
  },
  {
    "path": "test/compiler-esm/test-tla.js.compiled",
    "content": "const obj = { foo: 'bar' };\n\ndescribe('esm written in esm with top-level-await', () => {\n  it('should work', () => {\n    expect(obj, 'to equal', { foo: 'bar' });\n  });\n});\n\nawait undefined;\n\nexport const foo = 'bar';\n"
  },
  {
    "path": "test/compiler-esm/test-tla.mjs",
    "content": "const obj = { foo: \"bar\" };\n\ndescribe(\"esm written in esm with top-level-await\", () => {\n  it(\"should work\", () => {\n    expect(obj, \"to equal\", { foo: \"bar\" });\n  });\n});\n\nawait undefined;\n\nexport const foo = \"bar\";\n"
  },
  {
    "path": "test/compiler-esm/test-tla.mjs.compiled",
    "content": "const obj = { foo: 'bar' };\n\ndescribe('esm written in esm with top-level-await', () => {\n  it('should work', () => {\n    expect(obj, 'to equal', { foo: 'bar' });\n  });\n});\n\nawait undefined;\n\nexport const foo = 'bar';\n"
  },
  {
    "path": "test/compiler-esm/test-tla.ts",
    "content": "const obj: unknown = { foo: \"bar\" };\nenum Foo {\n  Bar = \"bar\",\n}\n\ndescribe(\"esm written in esm with top-level-await\", () => {\n  it(\"should work\", () => {\n    expect(obj, \"to equal\", { foo: Foo.Bar });\n  });\n});\n\nawait undefined;\n\nexport const foo = \"bar\";\n"
  },
  {
    "path": "test/compiler-esm/test-tla.ts.compiled",
    "content": "const obj = { foo: 'bar' };\nconst Foo = {\n  Bar: 'bar',\n};\n\ndescribe('esm written in esm with top-level-await', () => {\n  it('should work', () => {\n    expect(obj, 'to equal', { foo: Foo.Bar });\n  });\n});\n\nawait undefined;\n\nexport const foo = 'bar';\n"
  },
  {
    "path": "test/compiler-esm/test.js",
    "content": "const obj = { foo: \"bar\" };\n\ndescribe(\"esm written in esm\", () => {\n  it(\"should work\", () => {\n    expect(obj, \"to equal\", { foo: \"bar\" });\n  });\n});\n\nexport const foo = \"bar\";\n"
  },
  {
    "path": "test/compiler-esm/test.js.compiled",
    "content": "const obj = { foo: 'bar' };\n\ndescribe('esm written in esm', () => {\n  it('should work', () => {\n    expect(obj, 'to equal', { foo: 'bar' });\n  });\n});\n\nexport const foo = 'bar';\n"
  },
  {
    "path": "test/compiler-esm/test.mjs",
    "content": "const obj = { foo: \"bar\" };\n\ndescribe(\"esm written in esm\", () => {\n  it(\"should work\", () => {\n    expect(obj, \"to equal\", { foo: \"bar\" });\n  });\n});\n\nexport const foo = \"bar\";\n"
  },
  {
    "path": "test/compiler-esm/test.mjs.compiled",
    "content": "const obj = {foo: 'bar'};\n\ndescribe('esm written in esm', () => {\n  it('should work', () => {\n    expect(obj, 'to equal', {foo: 'bar'});\n  });\n});\n\nexport const foo = 'bar';\n"
  },
  {
    "path": "test/compiler-esm/test.ts",
    "content": "const obj: unknown = { foo: \"bar\" };\nenum Foo {\n  Bar = \"bar\",\n}\n\ndescribe(\"esm written in esm\", () => {\n  it(\"should work\", () => {\n    expect(obj, \"to equal\", { foo: Foo.Bar });\n  });\n});\n\nexport const foo = \"bar\";\n"
  },
  {
    "path": "test/compiler-esm/test.ts.compiled",
    "content": "const obj = { foo: 'bar' };\nconst Foo = {\n  Bar: 'bar',\n};\n\ndescribe('esm written in esm', () => {\n  it('should work', () => {\n    expect(obj, 'to equal', { foo: Foo.Bar });\n  });\n});\n\nexport const foo = 'bar';\n"
  },
  {
    "path": "test/compiler-fixtures/esm-loader.fixture.mjs",
    "content": "import fsPromises from \"node:fs/promises\";\nimport { fileURLToPath } from \"node:url\";\n\nexport async function load(url, context, nextLoad) {\n  if (!url.includes(\"compiler-esm\") && !url.includes(\"compiler-cjs\")) {\n    return nextLoad(url, context);\n  }\n  const format = url.includes(\"compiler-esm\") ? \"module\" : \"commonjs\";\n  const content = await fsPromises.readFile(\n    fileURLToPath(url + \".compiled\"),\n    \"utf8\",\n  );\n  return {\n    format,\n    source: content,\n    shortCircuit: true,\n  };\n}\n"
  },
  {
    "path": "test/compiler-fixtures/esm-only-loader/README.md",
    "content": "Test package used to cover a loader package that is only defined with `exports.imports` in the `package.json`.\n\nThis must be linked to `node_modules` and be `require`/`import`-ed with a bare specifier, as\ndefined in algorithm [`ESM_RESOLVE`][] step 5.2:\n\n```\nESM_RESOLVE(specifier, parentURL)\n  ...\n  5. Otherwise,\n    1. Note: specifier is now a bare specifier.\n    2. Set resolved the result of PACKAGE_RESOLVE(specifier, parentURL).\n```\n\n[`ESM_RESOLVE`]: https://nodejs.org/api/esm.html?fts_query=algorithm#resolution-algorithm-specification\n"
  },
  {
    "path": "test/compiler-fixtures/esm-only-loader/esm-loader.fixture.mjs",
    "content": "import fsPromises from \"node:fs/promises\";\nimport { fileURLToPath } from \"node:url\";\n\nexport async function load(url, context, nextLoad) {\n  if (!url.includes(\"compiler-esm\") && !url.includes(\"compiler-cjs\")) {\n    return nextLoad(url, context);\n  }\n  const format = url.includes(\"compiler-esm\") ? \"module\" : \"commonjs\";\n  const content = await fsPromises.readFile(\n    fileURLToPath(url + \".compiled\"),\n    \"utf8\",\n  );\n  return {\n    format,\n    source: content,\n    shortCircuit: true,\n  };\n}\n"
  },
  {
    "path": "test/compiler-fixtures/esm-only-loader/esm.fixture.js",
    "content": "import Module from \"node:module\";\n\nModule.register(new URL(\"./esm-loader.fixture.mjs\", import.meta.url));\n"
  },
  {
    "path": "test/compiler-fixtures/esm-only-loader/package.json",
    "content": "{\n  \"name\": \"@test/esm-only-loader\",\n  \"type\": \"module\",\n  \"exports\": {\n    \".\": {\n      \"import\": \"./esm.fixture.js\"\n    }\n  }\n}\n"
  },
  {
    "path": "test/compiler-fixtures/esm.fixture.js",
    "content": "const Module = require(\"node:module\");\nconst { pathToFileURL } = require(\"node:url\");\nconst path = require(\"node:path\");\n\nModule.register(\n  pathToFileURL(path.resolve(__dirname, \"esm-loader.fixture.mjs\")),\n);\n"
  },
  {
    "path": "test/compiler-fixtures/foo.fixture.js",
    "content": "\"use strict\";\n\nvar fs = require(\"fs\");\n\nrequire.extensions[\".foo\"] = function (module, filename) {\n  var content;\n  content = fs.readFileSync(filename, \"utf8\");\n  var test =\n    'describe(\"custom compiler\",function(){ it(\"should work\",function() { ' +\n    \"expect(\" +\n    content +\n    ', \"to be\", 1); }); });';\n  return module._compile(test, filename);\n};\n"
  },
  {
    "path": "test/compiler-fixtures/js.fixture.js",
    "content": "\"use strict\";\n\nconst fs = require(\"fs\");\n\nconst original = require.extensions[\".js\"];\nrequire.extensions[\".js\"] = function (module, filename) {\n  if (!filename.includes(\"compiler-cjs\")) {\n    return original(module, filename);\n  }\n  const content = fs.readFileSync(filename + \".compiled\", \"utf8\");\n  return module._compile(content, filename);\n};\n"
  },
  {
    "path": "test/compiler-fixtures/ts.fixture.js",
    "content": "\"use strict\";\n\nconst fs = require(\"fs\");\n\nrequire.extensions[\".ts\"] = function (module, filename) {\n  const content = fs.readFileSync(filename + \".compiled\", \"utf8\");\n  return module._compile(content, filename);\n};\n"
  },
  {
    "path": "test/integration/README.md",
    "content": "# Mocha Integration Tests\n\nThe tests in this directory are integration or end-to-end tests. Most of them spawn a `mocha` process and inspect the result of `STDOUT` and/or `STDERR`.\n\n## Directories\n\n- `fixtures`: Test file fixtures intended to be run via these tests. Usually have `.fixture.js` extension\n- `plugins`: Tests related to plugins (e.g., root hook plugins, global fixtures, etc.)\n- `options`: Tests for specific command-line flags\n\n## Helpers\n\nThe `helpers.js` module contains many functions to handle the common cases of spawning a Mocha process and other utilities. The important ones:\n\n- `runMocha` / `runMochaAsync`: spawns Mocha to run a fixture with the default reporter. Returns a parsed `SummarizedResult` object containing information parsed from the reporter's epilogue\n- `runMochaJSON` / `runMochaJSONAsync`: spawns Mocha to run a fixture with a `json` reporter and parses the output; good for assertions about specific numbers and types of test results. Returns a `JSONResult` object\n- `invokeMocha` / `invokeMochaAsync`: spawns Mocha with the default reporter but does not parse its output; good for testing errors of the non-test-failure variety. Does not expect a fixture file path, but one can manually be provided. Preferred to test Mocha's output to `STDERR`. Returns a `RawSummarizedResultObject` with the raw output and exit code, etc.\n- `resolveFixurePath`: a handy way to get the path to a fixture file. Required when using `invokeMocha*`\n- `runMochaWatch*`: similar to `runMocha*`, but runs Mocha in \"watch\" mode. Accepts a function which should trigger a rerun; the function should touch a file or perform some other filesystem operation. Forks instead of spawns on Windows\n- `invokeNode`: spawns `node` instead of `mocha`; good for testing programmatic usage of Mocha by running a script which does this\n\n### Return Types\n\n- `RawResult`: an object containing props `args`, `code`, `output` and `command`\n- `SummarizedResult`: a `RawResult` + props `passing`, `failing` and `pending`\n- `JSONResult`: a `RawResult` + parsed output of `json` reporter\n\n### Default Arguments\n\nBy default, all of these helpers run with the following options:\n\n- `--no-color`: it's easier to make assertions about output w/o having to deal w/ ANSI escape codes\n- `--no-bail`: overrides a configuration file w/ `bail: true`; providing `--bail` to the arguments list will suppress this (useful when testing `--bail`!)\n- `--no-parallel`: overrides a configuration file w/ `parallel: true`; providing `--parallel` to the arguments list will suppress this\n\n## Environment Variables Which Do Stuff\n\n- `DEBUG=mocha:test*`: will show debug output from tests & helpers, if any\n- `MOCHA_TEST_KEEP_TEMP_DIRS=1`: does not automatically remove any temporary directories and files created by the `createTempDir` helper. Use to manually debug problems when running fixtures in temp directories\n"
  },
  {
    "path": "test/integration/color.spec.js",
    "content": "\"use strict\";\n\nvar childProcess = require(\"node:child_process\");\nvar path = require(\"node:path\");\n\ndescribe(\"mocha binary\", function () {\n  it(\"should not output colors to pipe\", function (done) {\n    var command = [path.join(\"bin\", \"mocha\"), \"--grep\", \"missing-test\"];\n    childProcess.execFile(process.execPath, command, function (err, stdout) {\n      if (err) return done(err);\n\n      expect(stdout, \"not to contain\", \"[90m\");\n\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/common-js-require.spec.js",
    "content": "\"use strict\";\n\nconst { runMochaAsync } = require(\"./helpers\");\n\ndescribe(\"common js require\", () => {\n  it(\"should be able to run a test where all mocha exports are used\", async () => {\n    const result = await runMochaAsync(\"common-js-require.fixture.js\", [\n      \"--delay\",\n      \"--no-forbid-only\",\n    ]);\n    expect(result.output, \"to contain\", \"running before\");\n    expect(result.output, \"to contain\", \"running suiteSetup\");\n    expect(result.output, \"to contain\", \"running setup\");\n    expect(result.output, \"to contain\", \"running beforeEach\");\n    expect(result.output, \"to contain\", \"running it\");\n    expect(result.output, \"to contain\", \"running afterEach\");\n    expect(result.output, \"to contain\", \"running teardown\");\n    expect(result.output, \"to contain\", \"running suiteTeardown\");\n    expect(result.output, \"to contain\", \"running after\");\n  });\n});\n"
  },
  {
    "path": "test/integration/compiler-cjs.spec.js",
    "content": "\"use strict\";\n\nvar exec = require(\"node:child_process\").exec;\nvar path = require(\"node:path\");\n\ndescribe(\"support CJS require.extension compilers with esm syntax\", function () {\n  it(\"should support .js extension\", function (done) {\n    exec(\n      '\"' +\n        process.execPath +\n        '\" \"' +\n        path.join(\"bin\", \"mocha\") +\n        '\" -R json --require test/compiler-fixtures/js.fixture \"test/compiler-cjs/*.js\"',\n      { cwd: path.join(__dirname, \"..\", \"..\") },\n      function (error, stdout) {\n        if (error && !stdout) {\n          return done(error);\n        }\n        var results = JSON.parse(stdout);\n        expect(results, \"to have property\", \"tests\");\n        var titles = [];\n        for (var index = 0; index < results.tests.length; index += 1) {\n          expect(results.tests[index], \"to have property\", \"fullTitle\");\n          titles.push(results.tests[index].fullTitle);\n        }\n        expect(titles, \"to contain\", \"cjs written in esm should work\").and(\n          \"to have length\",\n          1,\n        );\n        done();\n      },\n    );\n  });\n\n  it(\"should support .ts extension\", function (done) {\n    exec(\n      '\"' +\n        process.execPath +\n        '\" \"' +\n        path.join(\"bin\", \"mocha\") +\n        '\" -R json --require test/compiler-fixtures/ts.fixture \"test/compiler-cjs/*.ts\"',\n      { cwd: path.join(__dirname, \"..\", \"..\") },\n      function (error, stdout) {\n        if (error && !stdout) {\n          return done(error);\n        }\n        var results = JSON.parse(stdout);\n        expect(results, \"to have property\", \"tests\");\n        var titles = [];\n        for (var index = 0; index < results.tests.length; index += 1) {\n          expect(results.tests[index], \"to have property\", \"fullTitle\");\n          titles.push(results.tests[index].fullTitle);\n        }\n        expect(titles, \"to contain\", \"cts written in esm should work\").and(\n          \"to have length\",\n          1,\n        );\n        done();\n      },\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/compiler-esm-only-loader.spec.js",
    "content": "\"use strict\";\n\nvar exec = require(\"node:child_process\").exec;\nvar path = require(\"node:path\");\n\n// Regression test for https://github.com/mochajs/mocha/issues/5380\ndescribe(\"support ESM only module loader packages\", function () {\n  /**\n   * Load the filename using an ESM-only loader and expect things to work\n   * @param {string} filename Name of the file to load\n   * @param {Function} done A Mocha done callback for when the test ends\n   */\n  function loadAndExpect(filename, done) {\n    exec(\n      '\"' +\n        process.execPath +\n        '\" \"' +\n        path.join(\"bin\", \"mocha\") +\n        `\" -R json --require \"@test/esm-only-loader\" \"${filename}\"`,\n      { cwd: path.join(__dirname, \"..\", \"..\") },\n      function (error, stdout) {\n        if (error && !stdout) {\n          return done(error);\n        }\n        var results = JSON.parse(stdout);\n        expect(results, \"to have property\", \"tests\");\n        var titles = [];\n        for (var index = 0; index < results.tests.length; index += 1) {\n          expect(results.tests[index], \"to have property\", \"fullTitle\");\n          titles.push(results.tests[index].fullTitle);\n        }\n        expect(titles, \"to contain\", \"esm written in esm should work\")\n          .and(\n            \"to contain\",\n            \"esm written in esm with top-level-await should work\",\n          )\n          .and(\"to have length\", 2);\n        done();\n      },\n    );\n  }\n\n  it(\"should support ESM .js extension\", function (done) {\n    loadAndExpect(\"test/compiler-esm/*.js\", done);\n  });\n\n  it(\"should support ESM .ts extension\", function (done) {\n    loadAndExpect(\"test/compiler-esm/*.ts\", done);\n  });\n\n  it(\"should support ESM .mjs extension\", function (done) {\n    loadAndExpect(\"test/compiler-esm/*.mjs\", done);\n  });\n});\n"
  },
  {
    "path": "test/integration/compiler-esm.spec.js",
    "content": "\"use strict\";\n\nvar exec = require(\"node:child_process\").exec;\nvar path = require(\"node:path\");\n\ndescribe(\"support ESM module loader compilers\", function () {\n  /**\n   * Runs `exec` on an ESM setup for the given file\n   * @param {string} filename Path to the file to load\n   * @param {Function} done A Mocha done callback for when the test ends\n   */\n  function loadAndExpect(filename, done) {\n    exec(\n      '\"' +\n        process.execPath +\n        '\" \"' +\n        path.join(\"bin\", \"mocha\") +\n        `\" -R json --require test/compiler-fixtures/esm.fixture \"${filename}\"`,\n      { cwd: path.join(__dirname, \"..\", \"..\") },\n      function (error, stdout) {\n        if (error && !stdout) {\n          return done(error);\n        }\n        var results = JSON.parse(stdout);\n        expect(results, \"to have property\", \"tests\");\n        var titles = [];\n        for (var index = 0; index < results.tests.length; index += 1) {\n          expect(results.tests[index], \"to have property\", \"fullTitle\");\n          titles.push(results.tests[index].fullTitle);\n        }\n        expect(titles, \"to contain\", \"esm written in esm should work\")\n          .and(\n            \"to contain\",\n            \"esm written in esm with top-level-await should work\",\n          )\n          .and(\"to have length\", 2);\n        done();\n      },\n    );\n  }\n\n  it(\"should support ESM .js extension\", function (done) {\n    loadAndExpect(\"test/compiler-esm/*.js\", done);\n  });\n\n  it(\"should support ESM .ts extension\", function (done) {\n    loadAndExpect(\"test/compiler-esm/*.ts\", done);\n  });\n\n  it(\"should support ESM .mjs extension\", function (done) {\n    loadAndExpect(\"test/compiler-esm/*.mjs\", done);\n  });\n});\n"
  },
  {
    "path": "test/integration/compiler-globbing.spec.js",
    "content": "\"use strict\";\n\nvar exec = require(\"node:child_process\").exec;\nvar path = require(\"node:path\");\n\ndescribe(\"globbing like --compilers\", function () {\n  it(\"should find a file of each type\", function (done) {\n    exec(\n      '\"' +\n        process.execPath +\n        '\" \"' +\n        path.join(\"bin\", \"mocha\") +\n        '\" -R json --require coffeescript/register --require test/compiler-fixtures/foo.fixture \"test/compiler/*.@(coffee|foo)\"',\n      { cwd: path.join(__dirname, \"..\", \"..\") },\n      function (error, stdout) {\n        if (error && !stdout) {\n          return done(error);\n        }\n        var results = JSON.parse(stdout);\n        expect(results, \"to have property\", \"tests\");\n        var titles = [];\n        for (var index = 0; index < results.tests.length; index += 1) {\n          expect(results.tests[index], \"to have property\", \"fullTitle\");\n          titles.push(results.tests[index].fullTitle);\n        }\n        expect(\n          titles,\n          \"to contain\",\n          \"coffeescript should work\",\n          \"custom compiler should work\",\n        ).and(\"to have length\", 2);\n        done();\n      },\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/config.spec.js",
    "content": "\"use strict\";\n\n// This is not a \"functional\" test; we aren't invoking the mocha executable.\n// Instead we just avoid test doubles.\n\nvar fs = require(\"node:fs\");\nvar path = require(\"node:path\");\nvar loadConfig = require(\"../../lib/cli/config\").loadConfig;\n\ndescribe(\"config\", function () {\n  it(\"should return the same values for all supported config types\", function () {\n    var configDir = path.join(__dirname, \"fixtures\", \"config\");\n    var js = loadConfig(path.join(configDir, \"mocharc.js\")); // canonical form\n    var cjs = loadConfig(path.join(configDir, \"mocharc.cjs\"));\n    var json = loadConfig(path.join(configDir, \"mocharc.json\"));\n    var mjs = loadConfig(path.join(configDir, \"mocharc.mjs\"));\n    var yaml = loadConfig(path.join(configDir, \"mocharc.yaml\"));\n    expect(cjs, \"to equal\", js);\n    expect(json, \"to equal\", js);\n    expect(mjs, \"to equal\", js);\n    expect(yaml, \"to equal\", js);\n  });\n\n  describe('when configuring Mocha via a \".js\" file', function () {\n    var projRootDir = path.join(__dirname, \"..\", \"..\");\n    var configDir = path.join(__dirname, \"fixtures\", \"config\");\n    var json = loadConfig(path.join(configDir, \"mocharc.json\"));\n\n    it(\"should load configuration given absolute path\", function () {\n      var js;\n\n      function _loadConfig() {\n        js = loadConfig(path.join(configDir, \"mocharc.js\"));\n      }\n\n      expect(_loadConfig, \"not to throw\");\n      expect(js, \"to equal\", json);\n    });\n\n    it(\"should load configuration given cwd-relative path\", function () {\n      var relConfigDir = configDir.substring(projRootDir.length + 1);\n      var js;\n\n      function _loadConfig() {\n        js = loadConfig(path.join(\".\", relConfigDir, \"mocharc.js\"));\n      }\n\n      expect(_loadConfig, \"not to throw\");\n      expect(js, \"to equal\", json);\n    });\n\n    it(\"should rethrow error from absolute path configuration\", function () {\n      function _loadConfig() {\n        loadConfig(path.join(configDir, \"mocharcWithThrowError.js\"));\n      }\n\n      expect(_loadConfig, \"to throw\", {\n        message: /Error from mocharcWithThrowError/,\n      });\n    });\n\n    it(\"should rethrow error from cwd-relative path configuration\", function () {\n      var relConfigDir = configDir.substring(projRootDir.length + 1);\n\n      function _loadConfig() {\n        loadConfig(path.join(\".\", relConfigDir, \"mocharcWithThrowError.js\"));\n      }\n\n      expect(_loadConfig, \"to throw\", {\n        message: /Error from mocharcWithThrowError/,\n      });\n    });\n\n    // In other words, path does not begin with '/', './', or '../'\n    describe(\"when path is neither absolute or relative\", function () {\n      var nodeModulesDir = path.join(projRootDir, \"node_modules\");\n      var pkgName = \"mocha-config\";\n      var installedLocally = false;\n      var symlinkedPkg = false;\n\n      before(function () {\n        try {\n          var srcPath = path.join(configDir, pkgName);\n          var targetPath = path.join(nodeModulesDir, pkgName);\n          fs.symlinkSync(srcPath, targetPath, \"dir\");\n          symlinkedPkg = true;\n          installedLocally = true;\n        } catch (err) {\n          if (err.code === \"EEXIST\") {\n            console.log(\"setup:\", 'package already exists in \"node_modules\"');\n            installedLocally = true;\n          } else {\n            console.error(\"setup failed:\", err);\n          }\n        }\n      });\n\n      it(\"should load configuration given module-relative path\", function () {\n        var js;\n\n        if (!installedLocally) {\n          return this.skip();\n        }\n\n        function _loadConfig() {\n          js = loadConfig(path.join(pkgName, \"index.js\"));\n        }\n\n        expect(_loadConfig, \"not to throw\");\n        expect(js, \"to equal\", json);\n      });\n\n      after(function () {\n        if (symlinkedPkg) {\n          try {\n            fs.unlinkSync(path.join(nodeModulesDir, pkgName));\n          } catch (err) {\n            console.error(\"teardown failed:\", err);\n          }\n        }\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/deprecate.spec.js",
    "content": "\"use strict\";\n\nvar assert = require(\"node:assert\");\nvar run = require(\"./helpers\").runMocha;\nvar args = [];\n\ndescribe(\"utils.deprecate test\", function () {\n  it(\"should print unique deprecation only once\", function (done) {\n    run(\n      \"deprecate.fixture.js\",\n      args,\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        var result = res.output.match(/deprecated thing/g) || [];\n        assert.strictEqual(result.length, 2);\n        done();\n      },\n      { stdio: \"pipe\" },\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/diffs.spec.js",
    "content": "\"use strict\";\n\nvar helpers = require(\"./helpers\");\nvar run = helpers.runMocha;\nvar fs = require(\"node:fs\");\nvar path = require(\"node:path\");\n\n/**\n * Returns an array of diffs corresponding to exceptions thrown from specs,\n * given the plaintext output (-C) of a mocha run.\n *\n * @param  {string}   output\n * returns {string[]}\n */\nfunction getDiffs(output) {\n  var diffs, i, inDiff, inStackTrace;\n\n  diffs = [];\n  output.split(\"\\n\").forEach(function (line) {\n    if (line.match(/^\\s{2}\\d+\\)/)) {\n      // New spec, e.g. \"1) spec title\"\n      diffs.push([]);\n      i = diffs.length - 1;\n      inStackTrace = false;\n      inDiff = false;\n    } else if (!diffs.length || inStackTrace) {\n      // Haven't encountered a spec yet\n      // or we're in the middle of a stack trace\n    } else if (line.indexOf(\"+ expected - actual\") !== -1) {\n      inDiff = true;\n    } else if (line.match(/at Context/)) {\n      // At the start of a stack trace\n      inStackTrace = true;\n      inDiff = false;\n    } else if (inDiff) {\n      diffs[i].push(line);\n    }\n  });\n\n  return diffs.map(function (diff) {\n    return diff\n      .filter(function (line) {\n        return line.trim().length;\n      })\n      .join(\"\\n\");\n  });\n}\n\n/**\n * Returns content of test/integration/fixtures/diffs/output,\n * post-processed for consumption by tests.\n * @returns {string[]} Array of diff lines\n */\nfunction getExpectedOutput() {\n  var output = fs\n    .readFileSync(path.join(__dirname, \"fixtures\", \"diffs\", \"output\"), \"UTF8\")\n    .replace(/\\r\\n/g, \"\\n\");\n\n  // Diffs are delimited in file by \"// DIFF\"\n  return output\n    .split(/\\s*\\/\\/ DIFF/)\n    .slice(1)\n    .map(function (diff) {\n      return diff.split(\"\\n\").filter(Boolean).join(\"\\n\");\n    });\n}\n\ndescribe(\"diffs\", function () {\n  var diffs, expected;\n\n  before(function (done) {\n    run(\"diffs/diffs.fixture.js\", [], function (err, res) {\n      if (err) {\n        done(err);\n        return;\n      }\n      expected = getExpectedOutput();\n      diffs = getDiffs(res.output.replace(/\\r\\n/g, \"\\n\"));\n      done();\n    });\n  });\n\n  [\n    \"should display a diff for small strings\",\n    \"should display a diff of canonicalized objects\",\n    \"should display a diff for medium strings\",\n    \"should display a diff for entire object dumps\",\n    \"should display a diff for multi-line strings\",\n    \"should display a diff for entire object dumps\",\n    \"should display a full-comparison with escaped special characters\",\n    \"should display a word diff for large strings\",\n    \"should work with objects\",\n    \"should show value diffs and not be affected by commas\",\n    \"should display diff by data and not like an objects\",\n  ].forEach(function (title, i) {\n    it(title, function () {\n      expect(diffs[i], \"to be\", expected[i]);\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/duplicate-arguments.spec.js",
    "content": "\"use strict\";\n\nvar runMochaJSON = require(\"./helpers\").runMochaJSON;\n\ndescribe(\"when non-array argument is provided multiple times\", function () {\n  describe(\"when the same argument name is used\", function () {\n    it(\"should prefer the last value\", function (done) {\n      runMochaJSON(\n        \"passing-sync\",\n        [\"--no-async-only\", \"--async-only\", \"--no-async-only\"],\n        function (err, result) {\n          if (err) {\n            return done(err);\n          }\n          expect(result, \"to have passed\");\n          done();\n        },\n      );\n    });\n  });\n\n  describe(\"when a different argument name is used\", function () {\n    it(\"should prefer the last value\", function (done) {\n      runMochaJSON(\n        \"passing-async\",\n        [\"--timeout\", \"100\", \"-t\", \"10\"],\n        function (err, result) {\n          if (err) {\n            return done(err);\n          }\n          expect(result, \"to have failed\");\n          done();\n        },\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/esm.spec.js",
    "content": "\"use strict\";\nvar path = require(\"node:path\");\nconst { runMochaJSON: run, runMochaAsync } = require(\"./helpers\");\nvar args = [];\n\ndescribe(\"esm\", function () {\n  it(\"should pass a passing esm test that uses esm\", function (done) {\n    var fixture = \"esm/esm-success.fixture.mjs\";\n    run(fixture, args, function (err, result) {\n      if (err) {\n        done(err);\n        return;\n      }\n\n      expect(result, \"to have passed test count\", 1);\n      done();\n    });\n  });\n\n  it(\"should fail a failing esm test that uses esm\", function (done) {\n    var fixture = \"esm/esm-failure.fixture.mjs\";\n    run(fixture, args, function (err, result) {\n      if (err) {\n        done(err);\n        return;\n      }\n\n      expect(result, \"to have failed test count\", 1).and(\n        \"to have failed test\",\n        \"should use a function from an esm, and fail\",\n      );\n      done();\n    });\n  });\n\n  it(\"should show file location when there is a syntax error in the test\", async function () {\n    var fixture = \"esm/syntax-error/esm-syntax-error.fixture.mjs\";\n    const err = await runMochaAsync(fixture, args, { stdio: \"pipe\" }).catch(\n      (err) => err,\n    );\n    expect(err.output, \"to contain\", \"SyntaxError\").and(\n      \"to contain\",\n      \"esm-syntax-error.fixture.mjs\",\n    );\n  });\n\n  it(\"should recognize esm files ending with .js due to package.json type flag\", function (done) {\n    var fixture = \"esm/js-folder/esm-in-js.fixture.js\";\n    run(fixture, args, function (err, result) {\n      if (err) {\n        done(err);\n        return;\n      }\n\n      expect(result, \"to have passed test count\", 1);\n      done();\n    });\n  });\n\n  it('should enable requiring/loading a cjs module with \"dir\" as filename', async function () {\n    var fixture = \"esm/test-that-uses-dir-cjs-require.fixture.js\";\n    const result = await runMochaAsync(\n      fixture,\n      [\"--require\", path.resolve(__dirname, \"./fixtures/esm/dir-cjs-require\")],\n      { stdio: \"pipe\" },\n    );\n\n    expect(result, \"to have passed test count\", 1);\n  });\n\n  it(\"should throw an ERR_MODULE_NOT_FOUND and not ERR_REQUIRE_ESM if file imports a non-existing module\", async function () {\n    const fixture =\n      \"esm/type-module/test-that-imports-non-existing-module.fixture.js\";\n\n    const err = await runMochaAsync(fixture, [\"--unhandled-rejections=warn\"], {\n      stdio: \"pipe\",\n    }).catch((err) => err);\n\n    expect(err.output, \"to contain\", \"ERR_MODULE_NOT_FOUND\").and(\n      \"to contain\",\n      \"test-that-imports-non-existing-module\",\n    );\n  });\n\n  it(\"should throw an ERR_MODULE_NOT_FOUND and not ERR_REQUIRE_ESM if file imports a non-existing module with a loader\", async function () {\n    const fixture =\n      \"esm/loader-with-module-not-found/test-that-imports-non-existing-module.fixture.ts\";\n\n    const err = await runMochaAsync(\n      fixture,\n      [\n        \"--unhandled-rejections=warn\",\n        \"--loader=./test/integration/fixtures/esm/loader-with-module-not-found/loader-that-recognizes-ts.mjs\",\n      ],\n      {\n        stdio: \"pipe\",\n      },\n    ).catch((err) => err);\n\n    expect(err.output, \"to contain\", \"ERR_MODULE_NOT_FOUND\").and(\n      \"to contain\",\n      \"non-existent-package\",\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/events.spec.js",
    "content": "\"use strict\";\n\nvar helpers = require(\"./helpers\");\nvar runMochaJSON = helpers.runMochaJSON;\n\ndescribe(\"event order\", function () {\n  describe(\"trivial test case\", function () {\n    it(\"should assert trivial event order\", function (done) {\n      runMochaJSON(\"runner/events-basic.fixture.js\", [], function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res, \"to have passed\")\n          .and(\"to have passed test count\", 2)\n          .and(\"to have passed test order\", \"test A\", \"test B\")\n          .and(\"to have failed test count\", 0);\n        done();\n      });\n    });\n  });\n\n  describe(\"--bail test case\", function () {\n    it(\"should assert --bail event order\", function (done) {\n      runMochaJSON(\n        \"runner/events-bail.fixture.js\",\n        [\"--bail\"],\n        function (err, res) {\n          if (err) {\n            done(err);\n            return;\n          }\n          expect(res, \"to have failed with error\", \"error test A\")\n            .and(\"to have failed test count\", 1)\n            .and(\"to have passed test count\", 0);\n          done();\n        },\n      );\n    });\n  });\n\n  describe(\"--retries test case\", function () {\n    it(\"should assert --retries event order\", function (done) {\n      runMochaJSON(\n        \"runner/events-retries.fixture.js\",\n        [\"--retries\", \"1\"],\n        function (err, res) {\n          if (err) {\n            done(err);\n            return;\n          }\n          expect(res, \"to have failed with error\", \"error test A\")\n            .and(\"to have failed test count\", 1)\n            .and(\"to have passed test count\", 0);\n          done();\n        },\n      );\n    });\n  });\n\n  describe(\"--delay test case\", function () {\n    it(\"should assert --delay event order\", function (done) {\n      runMochaJSON(\n        \"runner/events-delay.fixture.js\",\n        [\"--delay\"],\n        function (err, res) {\n          if (err) {\n            done(err);\n            return;\n          }\n          expect(res, \"to have passed\")\n            .and(\"to have passed test count\", 2)\n            .and(\"to have passed test order\", \"test A\", \"test B\")\n            .and(\"to have failed test count\", 0);\n          done();\n        },\n      );\n    });\n  });\n\n  describe(\"--retries and --bail test case\", function () {\n    it(\"should assert --retries event order\", function (done) {\n      runMochaJSON(\n        \"runner/events-bail-retries.fixture.js\",\n        [\"--retries\", \"1\", \"--bail\"],\n        function (err, res) {\n          if (err) {\n            done(err);\n            return;\n          }\n          expect(res, \"to have failed with error\", \"error test A\")\n            .and(\"to have failed test count\", 1)\n            .and(\"to have passed test count\", 0);\n          done();\n        },\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/fifo.spec.js",
    "content": "\"use strict\";\n\nconst assert = require(\"node:assert/strict\");\nconst { execSync } = require(\"node:child_process\");\nconst {\n  createReadStream,\n  createWriteStream,\n  mkdtempSync,\n  unlinkSync,\n} = require(\"node:fs\");\nconst { join } = require(\"node:path\");\nconst { tmpdir } = require(\"node:os\");\n\nconst { invokeMocha, toJSONResult } = require(\"./helpers\");\n\ndescribe(\"FIFO support\", function () {\n  it(\"should accept a test passed as a FIFO\", function (done) {\n    const dir = mkdtempSync(join(tmpdir(), \"mocha-test-fifo-\"));\n    const fifoPath = join(dir, \"fifo-1\");\n    execSync(`mkfifo ${fifoPath}`);\n\n    const writer = createWriteStream(fifoPath);\n    writer.on(\"ready\", () => {\n      writer.write(\n        `\n        describe('suite from FIFO', () => {\n          it('should pass', () => true);\n        });\n      `,\n        (err) => {\n          if (!err) writer.end();\n        },\n      );\n    });\n\n    const args = [\"--reporter\", \"json\", fifoPath];\n\n    invokeMocha(\n      args,\n      (err, res) => {\n        if (err) return done(err);\n\n        try {\n          const result = toJSONResult(res);\n          assert.equal(result.code, 0);\n          assert.equal(result.stats.suites, 1);\n          assert.equal(result.stats.tests, 1);\n          assert.equal(result.stats.passes, 1);\n          assert.equal(result.stats.pending, 0);\n          assert.equal(result.stats.failures, 0);\n\n          // Node hangs if FIFO is never unlinked.\n          unlinkSync(fifoPath);\n\n          done();\n        } catch (err) {\n          // Node hangs if FIFO is never read from.\n          createReadStream(fifoPath).close();\n\n          done(err);\n        }\n      },\n      { stdio: \"pipe\" },\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/file-utils.spec.js",
    "content": "\"use strict\";\n\nconst lookupFiles = require(\"../../lib/cli/lookup-files\");\nconst { existsSync, symlinkSync, renameSync } = require(\"node:fs\");\nconst path = require(\"node:path\");\nconst { touchFile, createTempDir } = require(\"./helpers\");\n\nconst SYMLINK_SUPPORT = process.platform !== \"win32\";\n\ndescribe(\"file utils\", function () {\n  let tmpDir;\n  let removeTempDir;\n  let tmpFile;\n\n  beforeEach(async function () {\n    const result = await createTempDir();\n    tmpDir = result.dirpath;\n    removeTempDir = result.removeTempDir;\n\n    tmpFile = (filepath) => path.join(tmpDir, filepath);\n\n    touchFile(tmpFile(\"mocha-utils.js\"));\n    if (SYMLINK_SUPPORT) {\n      symlinkSync(tmpFile(\"mocha-utils.js\"), tmpFile(\"mocha-utils-link.js\"));\n    }\n  });\n\n  afterEach(async function () {\n    return removeTempDir();\n  });\n\n  describe(\"lookupFiles()\", function () {\n    it(\"should not return broken symlink file path\", function () {\n      if (!SYMLINK_SUPPORT) {\n        return this.skip();\n      }\n\n      expect(\n        lookupFiles(tmpDir, [\"js\"], false),\n        \"to contain\",\n        tmpFile(\"mocha-utils-link.js\"),\n        tmpFile(\"mocha-utils.js\"),\n      ).and(\"to have length\", 2);\n      expect(existsSync(tmpFile(\"mocha-utils-link.js\")), \"to be\", true);\n      renameSync(tmpFile(\"mocha-utils.js\"), tmpFile(\"bob\"));\n      expect(existsSync(tmpFile(\"mocha-utils-link.js\")), \"to be\", false);\n      expect(lookupFiles(tmpDir, [\"js\"], false), \"to equal\", []);\n    });\n\n    it('should accept a glob \"path\" value', function () {\n      const res = lookupFiles(tmpFile(\"mocha-utils*\"), [\"js\"], false).map(\n        (foundFilepath) => path.normalize(foundFilepath),\n      );\n\n      let expectedLength = 0;\n      let ex = expect(res, \"to contain\", tmpFile(\"mocha-utils.js\"));\n      expectedLength++;\n\n      if (SYMLINK_SUPPORT) {\n        ex = ex.and(\"to contain\", tmpFile(\"mocha-utils-link.js\"));\n        expectedLength++;\n      }\n\n      ex.and(\"to have length\", expectedLength);\n    });\n\n    describe(\"when given `extension` option\", function () {\n      describe(\"when provided a directory for the filepath\", function () {\n        let filepath;\n\n        beforeEach(async function () {\n          filepath = tmpFile(\"mocha-utils-text.txt\");\n          touchFile(filepath);\n        });\n\n        describe(\"when `extension` option has leading dot\", function () {\n          it(\"should find the file w/ the extension\", function () {\n            expect(lookupFiles(tmpDir, [\".txt\"]), \"to equal\", [filepath]);\n          });\n        });\n\n        describe(\"when `extension` option has no leading dot\", function () {\n          it(\"should find the file w/ the extension\", function () {\n            expect(lookupFiles(tmpDir, [\"txt\"]), \"to equal\", [filepath]);\n          });\n        });\n\n        describe(\"when directory contains file without multipart extension\", function () {\n          let filepath;\n\n          beforeEach(function () {\n            filepath = tmpFile(\"mocha-utils-test.js\");\n            touchFile(filepath);\n          });\n\n          describe(\"when provided multipart `extension` option\", function () {\n            describe(\"when `extension` option has no leading dot\", function () {\n              it(\"should not match the filepath\", function () {\n                expect(\n                  lookupFiles(tmpDir, [\"test.js\"]).map((filepath) =>\n                    path.normalize(filepath),\n                  ),\n                  \"to equal\",\n                  [],\n                );\n              });\n            });\n\n            describe(\"when `extension` option has a leading dot\", function () {\n              it(\"should not match the filepath\", function () {\n                expect(\n                  lookupFiles(tmpDir, [\".test.js\"]).map((filepath) =>\n                    path.normalize(filepath),\n                  ),\n                  \"to equal\",\n                  [],\n                );\n              });\n            });\n          });\n        });\n\n        describe(\"when directory contains matching file having a multipart extension\", function () {\n          let filepath;\n\n          beforeEach(function () {\n            filepath = tmpFile(\"mocha-utils.test.js\");\n            touchFile(filepath);\n          });\n\n          describe(\"when provided multipart `extension` option\", function () {\n            describe(\"when `extension` option has no leading dot\", function () {\n              it(\"should find the matching file\", function () {\n                expect(\n                  lookupFiles(tmpDir, [\"test.js\"]).map((filepath) =>\n                    path.normalize(filepath),\n                  ),\n                  \"to equal\",\n                  [filepath],\n                );\n              });\n            });\n\n            describe(\"when `extension` option has a leading dot\", function () {\n              it(\"should find the matching file\", function () {\n                expect(\n                  lookupFiles(tmpDir, [\".test.js\"]).map((filepath) =>\n                    path.normalize(filepath),\n                  ),\n                  \"to equal\",\n                  [filepath],\n                );\n              });\n            });\n          });\n        });\n      });\n    });\n\n    describe(\"when provided a filepath with no extension\", function () {\n      let filepath;\n\n      beforeEach(async function () {\n        filepath = tmpFile(\"mocha-utils.ts\");\n        touchFile(filepath);\n      });\n\n      describe(\"when `extension` option has a leading dot\", function () {\n        describe(\"when only provided a single extension\", function () {\n          it(\"should append provided extensions and find only the matching file\", function () {\n            expect(\n              lookupFiles(tmpFile(\"mocha-utils\"), [\".js\"]).map(\n                (foundFilepath) => path.normalize(foundFilepath),\n              ),\n              \"to equal\",\n              [tmpFile(\"mocha-utils.js\")],\n            );\n          });\n        });\n\n        describe(\"when provided multiple extensions\", function () {\n          it(\"should append provided extensions and find all matching files\", function () {\n            expect(\n              lookupFiles(tmpFile(\"mocha-utils\"), [\".js\", \".ts\"]).map(\n                (foundFilepath) => path.normalize(foundFilepath),\n              ),\n              \"to contain\",\n              tmpFile(\"mocha-utils.js\"),\n              filepath,\n            ).and(\"to have length\", 2);\n          });\n        });\n      });\n\n      describe(\"when `extension` option has no leading dot\", function () {\n        describe(\"when only provided a single extension\", function () {\n          it(\"should append provided extensions and find only the matching file\", function () {\n            expect(\n              lookupFiles(tmpFile(\"mocha-utils\"), [\"js\"]).map((foundFilepath) =>\n                path.normalize(foundFilepath),\n              ),\n              \"to equal\",\n              [tmpFile(\"mocha-utils.js\")],\n            );\n          });\n        });\n\n        describe(\"when provided multiple extensions\", function () {\n          it(\"should append provided extensions and find all matching files\", function () {\n            expect(\n              lookupFiles(tmpFile(\"mocha-utils\"), [\"js\", \"ts\"]).map(\n                (foundFilepath) => path.normalize(foundFilepath),\n              ),\n              \"to contain\",\n              tmpFile(\"mocha-utils.js\"),\n              filepath,\n            ).and(\"to have length\", 2);\n          });\n        });\n      });\n\n      describe(\"when `extension` option is multipart\", function () {\n        let filepath;\n\n        beforeEach(function () {\n          filepath = tmpFile(\"mocha-utils.test.js\");\n          touchFile(filepath);\n        });\n\n        describe(\"when `extension` option has no leading dot\", function () {\n          it(\"should append provided extension and find only the matching file\", function () {\n            expect(\n              lookupFiles(tmpFile(\"mocha-utils\"), [\"test.js\"]).map(\n                (foundFilepath) => path.normalize(foundFilepath),\n              ),\n              \"to equal\",\n              [filepath],\n            );\n          });\n        });\n\n        describe(\"when `extension` option has leading dot\", function () {\n          it(\"should append provided extension and find only the matching file\", function () {\n            expect(\n              lookupFiles(tmpFile(\"mocha-utils\"), [\".test.js\"]).map(\n                (foundFilepath) => path.normalize(foundFilepath),\n              ),\n              \"to equal\",\n              [filepath],\n            );\n          });\n        });\n      });\n    });\n\n    describe(\"when no files match\", function () {\n      it(\"should throw an exception\", function () {\n        expect(() => lookupFiles(tmpFile(\"mocha-utils\")), \"to throw\", {\n          name: \"Error\",\n          code: \"ERR_MOCHA_NO_FILES_MATCH_PATTERN\",\n        });\n      });\n    });\n\n    describe(\"when looking up a directory and no extensions provided\", function () {\n      it(\"should throw\", function () {\n        expect(() => lookupFiles(tmpDir), \"to throw\", {\n          name: \"TypeError\",\n          code: \"ERR_MOCHA_INVALID_ARG_TYPE\",\n          argument: \"extensions\",\n        });\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/__default__.fixture.js",
    "content": "// this generic fixture does nothing special and will be used if no fixture is supplied\n\n'use strict';\n\ndescribe('a suite', function() {\n  it('should succeed', function(done) {\n    done();\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/cascade.fixture.js",
    "content": "'use strict';\n\ndescribe('one', function () {\n  before(function () {\n    console.log('before one');\n  });\n\n  after(function () {\n    console.log('after one');\n  });\n\n  beforeEach(function () {\n    console.log('  before each one');\n  });\n\n  afterEach(function () {\n    console.log('  after each one');\n  });\n\n  describe('two', function () {\n    before(function () {\n      console.log('  before two');\n    });\n\n    after(function () {\n      console.log('  after two');\n    });\n\n    beforeEach(function () {\n      console.log('    before each two');\n    });\n\n    afterEach(function () {\n      console.log('    after each two');\n    });\n\n    describe('three', function () {\n      before(function () {\n        console.log('    before three');\n      });\n\n      after(function () {\n        console.log('    after three');\n      });\n\n      beforeEach(function () {\n        console.log('    before each three');\n      });\n\n      afterEach(function () {\n        console.log('    after each three');\n      });\n\n      it('should three', function () {\n        console.log('      TEST three');\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/collect-files.fixture.mjs",
    "content": "var obj = {foo: 'bar'};\n\ndescribe('mjs', function () {\n  it('should work', function () {\n    expect(obj, 'to equal', {foo: 'bar'});\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/common-js-require.fixture.js",
    "content": "const { afterEach,\n  after,\n  beforeEach,\n  before,\n  describe,\n  xdescribe,\n  it,\n  xit,\n  setup,\n  suiteSetup,\n  suiteTeardown,\n  suite,\n  teardown,\n  test,\n  run } = require('../../..');\n\n\nsuite('root suite', () => {\n  setup(() => {\n    console.log('running setup');\n  })\n  before(() => {\n    console.log('running before');\n  });\n  beforeEach(() => {\n    console.log('running beforeEach');\n  });\n  afterEach(() => {\n    console.log('running afterEach');\n  });\n  after(() => {\n    console.log('running after');\n  });\n  teardown(() => {\n    console.log('running teardown');\n  });\n  suiteSetup(() => {\n    console.log('running suiteSetup');\n  });\n  suiteTeardown(() => {\n    console.log('running suiteTeardown');\n  });\n\n  describe.only('describe only', () => {\n    it('it', () => {\n      console.log('running it');\n    }).timeout(1000);\n    xit('it', () => {\n      console.log('running xit');\n    });\n    it.only('it.only', () => {\n      console.log('running it.only');\n    }).retries(2);\n    it.skip('it.skip', () => {\n      console.log('running it.skip');\n    });\n    test('test', () => {\n      console.log('running test');\n    });\n  });\n\n  describe('describe', () => {});\n\n  xdescribe('xdescribe', () => {});\n\n  describe.skip('describe.skip', () => {});\n\n  suite.only('suite only', () => {});\n\n  suite.skip('suite.skip', () => {});\n\n});\n\n// using `run` here makes it so this suite needs to be run with `--delay` mode.\n// adding it here to test that `run` is correctly exported from mocha.\nsetTimeout(run, 0);\n"
  },
  {
    "path": "test/integration/fixtures/config/mocha-config/index.js",
    "content": "'use strict';\n  \n// a comment\nmodule.exports = {\n  require: ['foo', 'bar'],\n  bail: true,\n  reporter: 'dot',\n  slow: 60\n};\n"
  },
  {
    "path": "test/integration/fixtures/config/mocha-config/package.json",
    "content": "{\n  \"name\": \"mocha-config\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Configure Mocha via package\",\n  \"main\": \"index.js\",\n  \"peerDependencies\": {\n    \"mocha\": \"^7.0.0\"\n  },\n  \"keywords\": [\n    \"mocha\",\n    \"config\"\n  ],\n  \"license\": \"CC0\"\n}\n"
  },
  {
    "path": "test/integration/fixtures/config/mocharc.cjs",
    "content": "'use strict';\n\n// a comment\nmodule.exports = {\n  require: ['foo', 'bar'],\n  bail: true,\n  reporter: 'dot',\n  slow: 60\n};\n"
  },
  {
    "path": "test/integration/fixtures/config/mocharc.js",
    "content": "'use strict';\n\n// a comment\nmodule.exports = {\n  require: ['foo', 'bar'],\n  bail: true,\n  reporter: 'dot',\n  slow: 60\n};\n"
  },
  {
    "path": "test/integration/fixtures/config/mocharc.json",
    "content": "{\n  // a comment\n  \"require\": [\"foo\", \"bar\"],\n  \"bail\": true,\n  \"reporter\": \"dot\",\n  \"slow\": 60\n}\n"
  },
  {
    "path": "test/integration/fixtures/config/mocharc.mjs",
    "content": "// a comment\nexport default {\n  require: ['foo', 'bar'],\n  bail: true,\n  reporter: 'dot',\n  slow: 60\n};\n"
  },
  {
    "path": "test/integration/fixtures/config/mocharc.yaml",
    "content": "# a comment\nrequire:\n  - foo\n  - bar\nbail: true\nreporter: dot\nslow: 60\n"
  },
  {
    "path": "test/integration/fixtures/config/mocharcWithThrowError.js",
    "content": "'use strict';\n\nthrow new Error(\"Error from mocharcWithThrowError\");\n\n// a comment\nmodule.exports = {\n  require: ['foo', 'bar'],\n  bail: true,\n  reporter: 'dot',\n  slow: 60\n};\n"
  },
  {
    "path": "test/integration/fixtures/current-test-title.fixture.js",
    "content": "'use strict';\nvar assert = require('assert');\n\nfunction getTitle(ctx) {\n  return ctx.currentTest && ctx.currentTest.title;\n};\n\nbefore(function () {\n  assert.strictEqual(getTitle(this), undefined);\n});\n\ndescribe('suite A', () => {\n\n  before(function () {\n    assert.strictEqual(getTitle(this), undefined);\n  });\n\n  describe('suite B', () => {\n\n    it('test1 B', () => {});\n\n    describe('suite C', function () {\n      var lap = 0;\n\n      before(function () {\n        assert.strictEqual(getTitle(this), 'test1 C');\n      });\n      beforeEach(function () {\n        assert.strictEqual(getTitle(this), ++lap === 1 ? 'test1 C' : 'test2 C');\n      });\n\n      it('test1 C', function () {});\n      it('test2 C', function () {});\n\n      afterEach(function () {\n        assert.strictEqual(getTitle(this), lap === 1 ? 'test1 C' : 'test2 C');\n      });\n      after(function () {\n        assert.strictEqual(getTitle(this), 'test2 C');\n      });\n    });\n  });\n});\n\nafter(function () {\n  assert.strictEqual(getTitle(this), undefined);\n});\n"
  },
  {
    "path": "test/integration/fixtures/deprecate.fixture.js",
    "content": "'use strict';\n\nvar errors = require(\"../../../lib/errors\");\n\nit('consolidates identical calls to deprecate', function() {\n  errors.deprecate(\"suite foo did a deprecated thing\");\n  errors.deprecate(\"suite foo did a deprecated thing\");\n  errors.deprecate(\"suite bar did a deprecated thing\");\n});\n"
  },
  {
    "path": "test/integration/fixtures/diffs/diffs.css.in",
    "content": "body {\n  font: \"Helvetica Neue\", Helvetica, arial, sans-serif;\n  background: black;\n  color: white;\n}\n\na {\n  color: blue\n}\n"
  },
  {
    "path": "test/integration/fixtures/diffs/diffs.css.out",
    "content": "body {\n  font: \"Helvetica Neue\", Helvetica, arial, sans-serif;\n  background: black;\n  color: #fff;\n}\n\na {\n  color: blue;\n}\n\nfoo {\n  bar: 'baz';\n}\n"
  },
  {
    "path": "test/integration/fixtures/diffs/diffs.fixture.js",
    "content": "'use strict';\n\n// assert is used because unexpected doesn't use mocha's diffs.\nvar assert = require('assert');\nvar fs = require('fs');\nvar cssin = fs.readFileSync('test/integration/fixtures/diffs/diffs.css.in', 'ascii');\nvar cssout = fs.readFileSync('test/integration/fixtures/diffs/diffs.css.out', 'ascii');\n\ndescribe('diffs', function () {\n  var actual, expected;\n\n  it('should display a diff for small strings', function () {\n    actual = 'foo rar baz';\n    expected = 'foo bar baz';\n    assert.strictEqual(actual, expected);\n  });\n\n  it('should display a diff of canonicalized objects', function () {\n    actual = { name: 'travis j', age: 23 };\n    expected = { age: 23, name: 'travis' };\n    assert.deepStrictEqual(actual, expected);\n  });\n\n  it('should display a diff for medium strings', function () {\n    actual = 'foo bar baz\\nfoo rar baz\\nfoo bar raz';\n    expected = 'foo bar baz\\nfoo bar baz\\nfoo bar baz';\n    assert.strictEqual(actual, expected);\n  });\n\n  it('should display a diff for entire object dumps', function () {\n    actual = {\n      name: 'joel',\n      age: 30,\n      address: {\n        city: 'new york',\n        country: 'usa'\n      }\n    };\n    expected = {\n      name: 'joe',\n      age: 30,\n      address: {\n        city: 'new york',\n        country: 'us'\n      }\n    };\n    assert.deepStrictEqual(actual, expected);\n  });\n\n  it('should display a diff for multi-line strings', function () {\n    actual = 'one two three\\nfour zzzz six\\nseven eight nine';\n    expected = 'one two three\\nfour five six\\nseven eight nine';\n    assert.strictEqual(actual, expected);\n  });\n\n  it('should display a diff for entire object dumps', function () {\n    actual = {\n      name: 'joel',\n      age: 30,\n      address: {\n        city: 'new york',\n        country: 'usa'\n      }\n    };\n    expected = {\n      name: 'joe',\n      age: 30,\n      address: {\n        city: 'new york',\n        country: 'us'\n      }\n    };\n    assert.deepStrictEqual(actual, expected);\n  });\n\n  it('should display a full-comparison with escaped special characters', function () {\n    actual = 'one\\ttab\\ntwo\\t\\t\\ttabs';\n    expected = 'one\\ttab\\ntwo\\t\\ttabs';\n    assert.strictEqual(actual, expected);\n  });\n\n  it('should display a word diff for large strings', function () {\n    assert.strictEqual(cssin, cssout);\n  });\n\n  it('should work with objects', function () {\n    actual = {\n      name: 'tobi',\n      species: 'ferret',\n      color: 'white',\n      age: 2\n    };\n\n    expected = {\n      name: 'loki',\n      species: 'ferret',\n      color: 'brown',\n      age: 2\n    };\n\n    assert.deepStrictEqual(actual, expected);\n  });\n\n  it('should show value diffs and not be affected by commas', function () {\n    actual = { a: 123 };\n    expected = { a: 123, b: 456 };\n    assert.deepStrictEqual(actual, expected);\n  });\n\n  it('should display diff by data and not like an objects', function () {\n    actual = Buffer.from([0x01]);\n    expected = Buffer.from([0x02]);\n    assert.deepStrictEqual(actual, expected);\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/diffs/output",
    "content": "// DIFF\n      -foo rar baz\n      +foo bar baz\n\n// DIFF\n       {\n         \"age\": 23\n      -  \"name\": \"travis j\"\n      +  \"name\": \"travis\"\n       }\n\n// DIFF\n       foo bar baz\n      -foo rar baz\n      -foo bar raz\n      +foo bar baz\n      +foo bar baz\n\n// DIFF\n       {\n         \"address\": {\n           \"city\": \"new york\"\n      -    \"country\": \"usa\"\n      +    \"country\": \"us\"\n         }\n         \"age\": 30\n      -  \"name\": \"joel\"\n      +  \"name\": \"joe\"\n       }\n\n// DIFF\n       one two three\n      -four zzzz six\n      +four five six\n       seven eight nine\n\n// DIFF\n       {\n         \"address\": {\n           \"city\": \"new york\"\n      -    \"country\": \"usa\"\n      +    \"country\": \"us\"\n         }\n         \"age\": 30\n      -  \"name\": \"joel\"\n      +  \"name\": \"joe\"\n       }\n\n// DIFF\n       one\ttab\n      -two\t\t\ttabs\n      +two\t\ttabs\n\n// DIFF\n       body {\n         font: \"Helvetica Neue\", Helvetica, arial, sans-serif;\n         background: black;\n      -  color: white;\n      +  color: #fff;\n       }\n       a {\n      -  color: blue\n      +  color: blue;\n       }\n      +\n      +foo {\n      +  bar: 'baz';\n      +}\n\n// DIFF\n       {\n         \"age\": 2\n      -  \"color\": \"white\"\n      -  \"name\": \"tobi\"\n      +  \"color\": \"brown\"\n      +  \"name\": \"loki\"\n         \"species\": \"ferret\"\n       }\n\n// DIFF\n       {\n         \"a\": 123\n      +  \"b\": 456\n       }\n\n// DIFF\n       [\n      -  1\n      +  2\n       ]\n"
  },
  {
    "path": "test/integration/fixtures/esm/add.mjs",
    "content": "export function add(a, b) {\n  return a + b;\n}\n"
  },
  {
    "path": "test/integration/fixtures/esm/dir-cjs-require/index.js",
    "content": "global.testPassesIfThisVariableIsDefined = true\n"
  },
  {
    "path": "test/integration/fixtures/esm/esm-failure.fixture.mjs",
    "content": "import {add} from './add.mjs';\n\nit('should use a function from an esm, and fail', () => {\n  expect(add(3, 5), 'to be', 9);\n});\n"
  },
  {
    "path": "test/integration/fixtures/esm/esm-success.fixture.mjs",
    "content": "import {add} from './add.mjs';\n\nit('should use a function from an esm', () => {\n  expect(add(3, 5), 'to be', 8);\n});\n"
  },
  {
    "path": "test/integration/fixtures/esm/js-folder/add.js",
    "content": "export function add(a, b) {\n  return a + b;\n}\n"
  },
  {
    "path": "test/integration/fixtures/esm/js-folder/esm-in-js.fixture.js",
    "content": "import {add} from './add.js';\n\nit('should use a function from an esm module with a js extension', () => {\n  expect(add(3, 5), 'to be', 8);\n});\n"
  },
  {
    "path": "test/integration/fixtures/esm/js-folder/package.json",
    "content": "{\n  \"type\": \"module\"\n}\n"
  },
  {
    "path": "test/integration/fixtures/esm/loader-with-module-not-found/loader-that-recognizes-ts.mjs",
    "content": "/**\n * @param {string} specifier\n * @param {{\n *   conditions: !Array<string>,\n *   parentURL: !(string | undefined),\n * }} context\n * @param {Function} defaultResolve\n * @returns {Promise<{ url: string }>}\n */\nexport async function resolve(specifier, context, defaultResolve) {\n  return await defaultResolve(\n    specifier.replace('.ts', '.mjs'),\n    context,\n    defaultResolve,\n  );\n}\n"
  },
  {
    "path": "test/integration/fixtures/esm/loader-with-module-not-found/test-that-imports-non-existing-module.fixture.mjs",
    "content": "import 'non-existent-package';\n"
  },
  {
    "path": "test/integration/fixtures/esm/loader-with-module-not-found/test-that-imports-non-existing-module.fixture.ts",
    "content": "// This file will be resolved to `test-that-imports-non-existing-module.fixture.mjs` by the loader\nimport 'non-existent-package';\n"
  },
  {
    "path": "test/integration/fixtures/esm/syntax-error/esm-syntax-error.fixture.mjs",
    "content": "// This is intentionally a syntax error\nit('should never run because of a syntax error here', => {\n});\n"
  },
  {
    "path": "test/integration/fixtures/esm/test-that-uses-dir-cjs-require.fixture.js/index.js",
    "content": "// See https://github.com/mochajs/mocha/issues/4665 for an explanation of this test\nit('should require a dir import', () => {\n  expect(global.testPassesIfThisVariableIsDefined, 'to be', true)\n})\n"
  },
  {
    "path": "test/integration/fixtures/esm/type-module/package.json",
    "content": "{\n  \"type\": \"module\"\n}\n"
  },
  {
    "path": "test/integration/fixtures/esm/type-module/test-that-imports-non-existing-module.fixture.js",
    "content": "import assert from 'assert';\nimport './this-module-does-not-exist.js';\n\nit('should not pass (or even run) because above import will fail', () => {\n  assert(true);\n});\n"
  },
  {
    "path": "test/integration/fixtures/exit.fixture.js",
    "content": "'use strict';\n\nvar net = require('net');\n\nit('should hang when --no-exit used', function (done) {\n  var server = net.createServer();\n  server.listen(55554, done);\n});\n"
  },
  {
    "path": "test/integration/fixtures/failing-sync.fixture.js",
    "content": "'use strict';\n\nvar assert = require('assert');\n\ndescribe('a suite', function() {\n  it('should succeed', function() {\n    assert(false);\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/failing.fixture.js",
    "content": "'use strict';\n\n// One passing test and three failing tests\n\nvar assert = require('assert');\n\ndescribe('suite', function () {\n  it('test1', function () {\n    assert(true);\n  });\n\n  it('test2', function () {\n    assert(false);\n  });\n\n  it('test3', function () {\n    assert(false);\n  });\n\n  it('test4', function () {\n    assert(false);\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/glob/glob.spec.js",
    "content": "'use strict';\n\ndescribe('globbing test', function() {\n  it('should find this test', function() {\n    // see test/integration/glob.spec.js for details\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/glob/nested/glob.spec.js",
    "content": "'use strict';\n\ndescribe('globbing test', function() {\n  it('should find this test', function() {\n    // see test/integration/glob.spec.js for details\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/after-each-hook-async-error.fixture.js",
    "content": "'use strict';\n\ndescribe('spec 1', function () {\n  afterEach(function (done) {\n    console.log('after');\n    process.nextTick(function () {\n      throw new Error('after each hook error');\n    });\n  });\n  it('should be called because error is in after each hook', function () {\n    console.log('test 1');\n  });\n  it('should not be called', function () {\n    console.log('test 2');\n  });\n});\ndescribe('spec 2', function () {\n  it('should be called, because hook error was in a sibling suite', function () {\n    console.log('test 3');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/after-each-hook-error.fixture.js",
    "content": "'use strict';\n\ndescribe('spec 1', function () {\n  afterEach(function () {\n    console.log('after');\n    throw new Error('after each hook error');\n  });\n  it('should be called because error is in after each hook', function () {\n    console.log('test 1');\n  });\n  it('should not be called', function () {\n    console.log('test 2');\n  });\n});\ndescribe('spec 2', function () {\n  it('should be called, because hook error was in a sibling suite', function () {\n    console.log('test 3');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/after-each-this-test-error.fixture.js",
    "content": "describe('fail the test from the \"after each\" hook', function() {\n  it('should fail', function() {\n    // but not here\n  });\n\n  afterEach(function() {\n    this.test.error(new Error('failing from after each'));\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/after-hook-async-error.fixture.js",
    "content": "'use strict';\n\ndescribe('spec 1', function () {\n  after(function (done) {\n    console.log('after');\n    process.nextTick(function () {\n      throw new Error('after hook error');\n    });\n  });\n  it('should be called because error is in after hook', function () {\n    console.log('test 1');\n  });\n  it('should be called because error is in after hook', function () {\n    console.log('test 2');\n  });\n});\ndescribe('spec 2', function () {\n  it('should be called, because hook error was in a sibling suite', function () {\n    console.log('test 3');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/after-hook-deepnested-error.fixture.js",
    "content": "'use strict';\n\ndescribe('spec 1', function () {\n  it('should pass', function () { });\n  describe('spec 2 nested - this title should be used', function () {\n    after(function() {\n      throw new Error('after hook nested error');\n    });\n    describe('spec 3 nested', function () {\n        it('it nested - this title should not be used', function () { });\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/after-hook-error.fixture.js",
    "content": "'use strict';\n\ndescribe('spec 1', function () {\n  after(function () {\n    console.log('after');\n    throw new Error('after hook error');\n  });\n  it('should be called because error is in after hook', function () {\n    console.log('test 1');\n  });\n  it('should be called because error is in after hook', function () {\n    console.log('test 2');\n  });\n});\ndescribe('spec 2', function () {\n  it('should be called, because hook error was in a sibling suite', function () {\n    console.log('test 3');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/after-hook-nested-error.fixture.js",
    "content": "'use strict';\n\ndescribe('spec 1', function () {\n  it('should pass', function () { });\n  describe('spec nested', function () {\n    after(function() {\n      throw new Error('after hook nested error');\n    });\n    it('it nested - this title should be used', function () { });\n  });\n  describe('spec 2 nested', function () {\n    it('it nested - not this title', function () { });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/before-each-hook-async-error.fixture.js",
    "content": "'use strict';\n\ndescribe('spec 1', function () {\n  beforeEach(function (done) {\n    console.log('before');\n    process.nextTick(function () {\n      throw new Error('before each hook error');\n    });\n  });\n  it('should not be called because of error in before each hook', function () {\n    console.log('test 1');\n  });\n  it('should not be called because of error in before each hook', function () {\n    console.log('test 2');\n  });\n});\ndescribe('spec 2', function () {\n  it('should be called, because hook error was in a sibling suite', function () {\n    console.log('test 3');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/before-each-hook-error-with-fail-affected.fixture.js",
    "content": "'use strict';\n\ndescribe('fails `beforeEach` hook', function () {\n  beforeEach(function () {\n    throw new Error('error in `beforeEach` hook');\n  });\n  it('test 1', function () {\n    // This should be reported as failed due to beforeEach hook failure\n  });\n  it('test 2', function () {\n    // This should be reported as failed due to beforeEach hook failure\n  });\n});\ndescribe('passes normally', function () {\n  it('test 3', function () {\n    // This should pass normally\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/before-each-hook-error.fixture.js",
    "content": "'use strict';\n\ndescribe('spec 1', function () {\n  beforeEach(function () {\n    console.log('before');\n    throw new Error('before each hook error');\n  });\n  it('should not be called because of error in before each hook', function () {\n    console.log('test 1');\n  });\n  it('should not be called because of error in before each hook', function () {\n    console.log('test 2');\n  });\n});\ndescribe('spec 2', function () {\n  it('should be called, because hook error was in a sibling suite', function () {\n    console.log('test 3');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/before-each-hook-throw-non-error.fixture.js",
    "content": "'use strict';\n\ndescribe('throws non-Error in `beforeEach` hook', function () {\n  describe('throws null', function () {\n    beforeEach(function () {\n      throw null;\n    });\n    it('test 1', function () {\n      // Should be reported as failed due to beforeEach hook failure\n    });\n  });\n\n  describe('throws undefined', function () {\n    beforeEach(function () {\n      throw undefined;\n    });\n    it('test 2', function () {\n      // Should be reported as failed due to beforeEach hook failure\n    });\n  });\n\n  describe('throws string', function () {\n    beforeEach(function () {\n      throw 'string error';\n    });\n    it('test 3', function () {\n      // Should be reported as failed due to beforeEach hook failure\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/before-hook-async-error-tip.fixture.js",
    "content": "'use strict';\n\ndescribe('spec 1', function () {\n  it('should not blame me', function () { });\n});\ndescribe('spec 2', function () {\n  before(function (done) {\n    process.nextTick(function () {\n      throw new Error('before hook error');\n    });\n  });\n  it('skipped');\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/before-hook-async-error.fixture.js",
    "content": "'use strict';\n\ndescribe('spec 1', function () {\n  before(function (done) {\n    console.log('before');\n    process.nextTick(function () {\n      throw new Error('before hook error');\n    });\n  });\n  it('should not be called because of error in before hook', function () {\n    console.log('test 1');\n  });\n  it('should not be called because of error in before hook', function () {\n    console.log('test 2');\n  });\n});\ndescribe('spec 2', function () {\n  it('should be called, because hook error was in a sibling suite', function () {\n    console.log('test 3');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/before-hook-deepnested-error.fixture.js",
    "content": "'use strict';\n\ndescribe('spec 1', function () {\n  it('should pass', function () { });\n  describe('spec 2 nested - this title should be used', function () {\n    before(function() {\n      throw new Error('before hook nested error');\n    });\n    describe('spec 3 nested', function () { \n      it('it nested - this title should not be used', function () { });\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/before-hook-error-tip.fixture.js",
    "content": "'use strict';\n\ndescribe('spec 1', function () {\n  it('should not blame me', function () { });\n});\ndescribe('spec 2', function () {\n  before(function () {\n    throw new Error('before hook error');\n  });\n  it('skipped');\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/before-hook-error-with-fail-affected.fixture.js",
    "content": "'use strict';\n\ndescribe('fails `before` hook', function () {\n  before(function () {\n    throw new Error('error in `before` hook');\n  });\n  it('test 1', function () {\n    // This should be reported as failed due to before hook failure\n  });\n  it('test 2', function () {\n    // This should be reported as failed due to before hook failure\n  });\n});\ndescribe('passes normally', function () {\n  it('test 3', function () {\n    // This should pass normally\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/before-hook-error.fixture.js",
    "content": "'use strict';\n\ndescribe('spec 1', function () {\n  before(function () {\n    console.log('before');\n    throw new Error('before hook error');\n  });\n  it('should not be called because of error in before hook', function () {\n    console.log('test 1');\n  });\n  it('should not be called because of error in before hook', function () {\n    console.log('test 2');\n  });\n});\ndescribe('spec 2', function () {\n  it('should be called, because hook error was in a sibling suite', function () {\n    console.log('test 3');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/before-hook-nested-error.fixture.js",
    "content": "'use strict';\n\ndescribe('spec 1', function () {\n  it('should pass', function () { });\n  describe('spec nested', function () {\n    before(function() {\n      throw new Error('before hook nested error');\n    });\n    it('it nested - this title should be used', function () { });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/before-hook-root-error.fixture.js",
    "content": "'use strict';\n\nbefore(function() {\n  throw new Error('before hook root error');\n});\n\ndescribe('spec 1', function () {\n  it('should not be called', function () { });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/before-hook-throw-non-error.fixture.js",
    "content": "'use strict';\n\ndescribe('throws non-Error in `before` hook', function () {\n  describe('throws null', function () {\n    before(function () {\n      throw null;\n    });\n    it('test 1', function () {\n      // Should be reported as failed due to before hook failure\n    });\n  });\n\n  describe('throws undefined', function () {\n    before(function () {\n      throw undefined;\n    });\n    it('test 2', function () {\n      // Should be reported as failed due to before hook failure\n    });\n  });\n\n  describe('throws string', function () {\n    before(function () {\n      throw 'string error';\n    });\n    it('test 3', function () {\n      // Should be reported as failed due to before hook failure\n    });\n  });\n\n  describe('throws number', function () {\n    before(function () {\n      throw 42;\n    });\n    it('test 4', function () {\n      // Should be reported as failed due to before hook failure\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/multiple-hook-async-error.fixture.js",
    "content": "'use strict';\n\nbefore(function () {\n  console.log('root before');\n});\nbeforeEach(function () {\n  console.log('root before each');\n});\ndescribe('1', function () {\n  beforeEach(function () {\n    console.log('1 before each');\n  });\n\n  describe('1-1', function () {\n    before(function () {\n      console.log('1-1 before');\n    });\n    beforeEach(function (done) {\n      console.log('1-1 before each');\n      process.nextTick(function () {\n        throw new Error('1-1 before each hook failed');\n      });\n    });\n    it('1-1 test 1', function () {\n      console.log('1-1 test 1');\n    });\n    it('1-1 test 2', function () {\n      console.log('1-1 test 2');\n    });\n    afterEach(function () {\n      console.log('1-1 after each');\n    });\n    after(function (done) {\n      console.log('1-1 after');\n      process.nextTick(function () {\n        throw new Error('1-1 after hook failed');\n      });\n    });\n  });\n\n  describe('1-2', function () {\n    before(function () {\n      console.log('1-2 before');\n    });\n    beforeEach(function () {\n      console.log('1-2 before each');\n    });\n    it('1-2 test 1', function () {\n      console.log('1-2 test 1');\n    });\n    it('1-2 test 2', function () {\n      console.log('1-2 test 2');\n    });\n    afterEach(function (done) {\n      console.log('1-2 after each');\n      process.nextTick(function () {\n        throw new Error('1-2 after each hook failed');\n      });\n    });\n    after(function () {\n      console.log('1-2 after');\n    });\n  });\n\n  afterEach(function () {\n    console.log('1 after each');\n  });\n\n  after(function () {\n    console.log('1 after');\n  });\n});\n\ndescribe('2', function () {\n  beforeEach(function (done) {\n    console.log('2 before each');\n    process.nextTick(function () {\n      throw new Error('2 before each hook failed');\n    });\n  });\n\n  describe('2-1', function () {\n    before(function () {\n      console.log('2-1 before');\n    });\n    beforeEach(function () {\n      console.log('2-1 before each');\n    });\n    it('2-1 test 1', function () {\n      console.log('2-1 test 1');\n    });\n    it('2-1 test 2', function () {\n      console.log('2-1 test 2');\n    });\n    afterEach(function () {\n      console.log('2-1 after each');\n    });\n    after(function () {\n      console.log('2-1 after');\n    });\n  });\n\n  describe('2-2', function () {\n    before(function () {\n      console.log('2-2 before');\n    });\n    beforeEach(function () {\n      console.log('2-2 before each');\n    });\n    it('2-2 test 1', function () {\n      console.log('2-2 test 1');\n    });\n    it('2-2 test 2', function () {\n      console.log('2-2 test 2');\n    });\n    afterEach(function () {\n      console.log('2-2 after each');\n    });\n    after(function () {\n      console.log('2-2 after');\n    });\n  });\n\n  afterEach(function (done) {\n    console.log('2 after each');\n    process.nextTick(function () {\n      throw new Error('2 after each hook failed');\n    });\n  });\n\n  after(function () {\n    console.log('2 after');\n  });\n});\n\nafter(function () {\n  console.log('root after');\n});\nafterEach(function () {\n  console.log('root after each');\n});\n"
  },
  {
    "path": "test/integration/fixtures/hooks/multiple-hook-error.fixture.js",
    "content": "'use strict';\n\nbefore(function () {\n  console.log('root before');\n});\nbeforeEach(function () {\n  console.log('root before each');\n});\ndescribe('1', function () {\n  beforeEach(function () {\n    console.log('1 before each');\n  });\n\n  describe('1-1', function () {\n    before(function () {\n      console.log('1-1 before');\n    });\n    beforeEach(function () {\n      console.log('1-1 before each');\n      throw new Error('1-1 before each hook failed');\n    });\n    it('1-1 test 1', function () {\n      console.log('1-1 test 1');\n    });\n    it('1-1 test 2', function () {\n      console.log('1-1 test 2');\n    });\n    afterEach(function () {\n      console.log('1-1 after each');\n    });\n    after(function () {\n      console.log('1-1 after');\n      throw new Error('1-1 after hook failed');\n    });\n  });\n\n  describe('1-2', function () {\n    before(function () {\n      console.log('1-2 before');\n    });\n    beforeEach(function () {\n      console.log('1-2 before each');\n    });\n    it('1-2 test 1', function () {\n      console.log('1-2 test 1');\n    });\n    it('1-2 test 2', function () {\n      console.log('1-2 test 2');\n    });\n    afterEach(function () {\n      console.log('1-2 after each');\n      throw new Error('1-2 after each hook failed');\n    });\n    after(function () {\n      console.log('1-2 after');\n    });\n  });\n\n  afterEach(function () {\n    console.log('1 after each');\n  });\n\n  after(function () {\n    console.log('1 after');\n  });\n});\n\ndescribe('2', function () {\n  beforeEach(function () {\n    console.log('2 before each');\n    throw new Error('2 before each hook failed');\n  });\n\n  describe('2-1', function () {\n    before(function () {\n      console.log('2-1 before');\n    });\n    beforeEach(function () {\n      console.log('2-1 before each');\n    });\n    it('2-1 test 1', function () {\n      console.log('2-1 test 1');\n    });\n    it('2-1 test 2', function () {\n      console.log('2-1 test 2');\n    });\n    afterEach(function () {\n      console.log('2-1 after each');\n    });\n    after(function () {\n      console.log('2-1 after');\n    });\n  });\n\n  describe('2-2', function () {\n    before(function () {\n      console.log('2-2 before');\n    });\n    beforeEach(function () {\n      console.log('2-2 before each');\n    });\n    it('2-2 test 1', function () {\n      console.log('2-2 test 1');\n    });\n    it('2-2 test 2', function () {\n      console.log('2-2 test 2');\n    });\n    afterEach(function () {\n      console.log('2-2 after each');\n    });\n    after(function () {\n      console.log('2-2 after');\n    });\n  });\n\n  afterEach(function () {\n    console.log('2 after each');\n    throw new Error('2 after each hook failed');\n  });\n\n  after(function () {\n    console.log('2 after');\n  });\n});\n\nafter(function () {\n  console.log('root after');\n});\nafterEach(function () {\n  console.log('root after each');\n});\n"
  },
  {
    "path": "test/integration/fixtures/multiple-done-async.fixture.js",
    "content": "'use strict';\n\n// The suite below should result in an additional error, but does\n// not. Uncomment once this bug is resolved.\n\n// describe('suite', function() {\n//   beforeEach(function(done) {\n//     done();\n//     done();\n//   });\n\n//   it('test', function() {});\n// });\n\nit('should fail in an async test case', function (done) {\n  process.nextTick(function () {\n    done();\n    setTimeout(done);\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/multiple-done-before-each.fixture.js",
    "content": "'use strict';\n\ndescribe('suite1', function () {\n  beforeEach(function (done) {\n    setTimeout(done, 10);\n    setTimeout(done, 20);\n  });\n\n  it('test1', function (done) {\n    setTimeout(done, 50);\n  });\n\n  it('test2', function (done) {\n    setTimeout(done, 50);\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/multiple-done-before.fixture.js",
    "content": "'use strict';\n\ndescribe('suite1', function () {\n  before(function (done) {\n    setTimeout(done, 10);\n    setTimeout(done, 30);\n  });\n\n  it('test1', function (done) {\n    setTimeout(done, 50);\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/multiple-done-specs.fixture.js",
    "content": "'use strict';\n\ndescribe('suite', function () {\n  it('test1', function (done) {\n    done();\n    setTimeout(done, 10);\n  });\n\n  it('test2', function (done) {\n    setTimeout(done, 20);\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/multiple-done-with-error.fixture.js",
    "content": "'use strict';\n\nit('should fail in a test-case', function (done) {\n  process.nextTick(function () {\n    done();\n    done(new Error('second error'));\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/multiple-done.fixture.js",
    "content": "'use strict';\n\n// The suite below should result in an additional error, but does\n// not. Uncomment once this bug is resolved.\n\n// describe('suite', function() {\n//   beforeEach(function(done) {\n//     done();\n//     done();\n//   });\n\n//   it('test', function() {});\n// });\n\nit('should fail in a test-case', function (done) {\n  process.nextTick(function () {\n    done();\n    done();\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/multiple-runs/clean-references.fixture.js",
    "content": "'use strict';\nconst Mocha = require('../../../../lib/mocha');\n\nconst mocha = new Mocha({ reporter: 'json' });\nmocha.cleanReferencesAfterRun(true);\nrequire('./run-thrice-helper')(mocha);\n"
  },
  {
    "path": "test/integration/fixtures/multiple-runs/dispose.fixture.js",
    "content": "'use strict';\nconst Mocha = require('../../../../lib/mocha');\n\nconst mocha = new Mocha({ reporter: 'json' });\nmocha.dispose();\nrequire('./run-thrice-helper')(mocha);\n"
  },
  {
    "path": "test/integration/fixtures/multiple-runs/multiple-runs-with-different-output-suite.fixture.js",
    "content": "describe('Multiple runs', () => {\n\n  /**\n   * Shared state! Bad practice, but nice for this test\n   */\n  let i = 0;\n\n  it('should skip, fail and pass respectively', function () {\n    switch (i++) {\n      case 0:\n        this.skip();\n      case 1:\n        throw new Error('Expected error');\n      default:\n        // this is fine ☕\n        break;\n    }\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/multiple-runs/multiple-runs-with-flaky-before-each-suite.fixture.js",
    "content": "describe('Multiple runs', () => {\n\n  /**\n   * Shared state! Bad practice, but nice for this test\n   */\n  let i = 0;\n\n  beforeEach(function () {\n    if (i++ === 0) {\n      throw new Error('Expected error for this test');\n    }\n  });\n\n\n  it('should be a dummy test', function () {\n    // this is fine ☕\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/multiple-runs/multiple-runs-with-flaky-before-each.fixture.js",
    "content": "'use strict';\nconst Mocha = require('../../../../lib/mocha');\n\nconst mocha = new Mocha({ reporter: 'json' });\nmocha.cleanReferencesAfterRun(false);\nmocha.addFile(require.resolve('./multiple-runs-with-flaky-before-each-suite.fixture.js'));\nconsole.log('[');\nmocha.run(() => {\n  console.log(',');\n  mocha.run(() => {\n    console.log(']');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/multiple-runs/run-thrice-helper.js",
    "content": "module.exports = function (mocha) {\n  mocha.addFile(require.resolve('./multiple-runs-with-different-output-suite.fixture.js'));\n  console.log('[');\n  try {\n    mocha.run(() => {\n      console.log(',');\n      try {\n        mocha.run(() => {\n          console.log(',');\n          mocha.run(() => {\n            console.log(']');\n          });\n        });\n      } catch (err) {\n        console.error(err.code);\n        throw err;\n      }\n    });\n  } catch (err) {\n    console.error(err.code);\n    throw err;\n  }\n\n}\n"
  },
  {
    "path": "test/integration/fixtures/multiple-runs/run-thrice.fixture.js",
    "content": "'use strict';\nconst Mocha = require('../../../../lib/mocha');\n\nconst mocha = new Mocha({ reporter: 'json' });\nmocha.cleanReferencesAfterRun(false);\nrequire('./run-thrice-helper')(mocha);\n"
  },
  {
    "path": "test/integration/fixtures/multiple-runs/start-second-run-if-previous-is-still-running-suite.fixture.js",
    "content": "describe('slow suite', () => {\n  it('should be slow', (done) => {\n    setTimeout(200, done);\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/multiple-runs/start-second-run-if-previous-is-still-running.fixture.js",
    "content": "'use strict';\nconst Mocha = require('../../../../lib/mocha');\n\nconst mocha = new Mocha({ reporter: 'json' });\nmocha.addFile(require.resolve('./start-second-run-if-previous-is-still-running-suite.fixture.js'));\nmocha.run();\ntry {\n  mocha.run();\n} catch (err) {\n  console.error(err.code);\n}\n\n"
  },
  {
    "path": "test/integration/fixtures/no-diff.fixture.js",
    "content": "'use strict';\nvar assert = require('assert');\n\ndescribe('Example test', function () {\n  it('should fail', function () {\n    assert.deepStrictEqual([1, 2, 3], ['foo', 'bar', 'baz']);\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/allow-uncaught/propagate.fixture.js",
    "content": "'use strict';\n\ndescribe('Uncaught exception - throw and exit', () => {\n  it('test1', () => {\n    setTimeout(() => {\n      throw new Error('Uncaught error after test1');\n    }, 1);\n  });\n  it('test2', function () { });\n  it('test3', function () { });\n  it('test4', function () { });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/allow-uncaught/this-skip-it.fixture.js",
    "content": "'use strict';\n\ndescribe('test suite', () => {\n    it('test1', function () { });\n    it('test2', function (done) {\n        var self = this;\n        setTimeout(function () {\n          self.skip();\n          throw new Error(\"should not throw\");\n        }, 10);\n    });\n    it('test3', function () {\n        this.skip();\n        throw new Error(\"should not throw\");\n    });\n    it('test4', function () { });\n    it('test5', function () {\n        this.skip();\n        throw new Error(\"should not throw\");\n    });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/async-only-async.fixture.js",
    "content": "'use strict';\n\nit('should pass', function (done) {\n  done();\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/async-only-sync.fixture.js",
    "content": "'use strict';\n\nit('throws an error', function () {});\n"
  },
  {
    "path": "test/integration/fixtures/options/bail-async.fixture.js",
    "content": "'use strict';\n\ndescribe('suite1', function () {\n  it('should display this spec', function () {});\n\n  it('should only display this error', function (done) {\n    throw new Error('this should be displayed');\n  });\n\n  it('should not display this error', function (done) {\n    throw new Error('this should not be displayed');\n  });\n});\n\ndescribe('suite2', function () {\n  before(function (done) {\n    throw new Error('this hook should not be displayed');\n  });\n\n  it('should not display this error', function (done) {\n    throw new Error('this should not be displayed');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/bail-with-after.fixture.js",
    "content": "'use strict';\nvar assert = require('assert');\n\ndescribe('suite1', function () {\n  var runOrder = [];\n  before('before suite1', function () {\n    runOrder.push('before suite1');\n  });\n  beforeEach('beforeEach suite1', function () {\n    runOrder.push('beforeEach suite1');\n  });\n  it('test suite1', function () {\n    runOrder.push('test suite1');\n  });\n\n  describe('suite1A', function () {\n    before('before suite1A', function () {\n      runOrder.push('before suite1A');\n    });\n    beforeEach('beforeEach suite1A', function () {\n      runOrder.push('beforeEach suite1A');\n    }); \n    it('test suite1A', function () {\n      runOrder.push('test suite1A');\n    });\n    afterEach('afterEach suite1A', function () {\n      runOrder.push('afterEach suite1A');\n    });\n    after('after suite1A', function () {\n      runOrder.push('after suite1A');\n      throw new Error('after suite1A error');\n    });\n  });\n\n  afterEach('afterEach suite1', function () {\n    runOrder.push('afterEach suite1');\n  });\n  after('after suite1', function () {\n    runOrder.push('after suite1');\n    assert.deepStrictEqual(runOrder, [\n      'before suite1', 'beforeEach suite1', 'test suite1',\n      'afterEach suite1', 'before suite1A', 'beforeEach suite1',\n      'beforeEach suite1A', 'test suite1A', 'afterEach suite1A',\n      'afterEach suite1', 'after suite1A', 'after suite1'\n    ]);\n  });\n});\n\ndescribe('suite2', function () {\n  before('before suite2', function () {});\n  beforeEach('beforeEach suite2', function () {});\n  it('test suite2', function () {\n    console.log('test suite2 - should not run');\n  });\n  afterEach('afterEach suite2', function () {});\n  after('after suite2', function () {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/bail-with-afterEach.fixture.js",
    "content": "'use strict';\nvar assert = require('assert');\n\ndescribe('suite1', function () {\n  var runOrder = [];\n  before('before suite1', function () {\n    runOrder.push('before suite1');\n  });\n  beforeEach('beforeEach suite1', function () {\n    runOrder.push('beforeEach suite1');\n  });\n  it('test suite1', function () {\n    runOrder.push('test suite1');\n  });\n\n  describe('suite1A', function () {\n    before('before suite1A', function () {\n      runOrder.push('before suite1A');\n    });\n    beforeEach('beforeEach suite1A', function () {\n      runOrder.push('beforeEach suite1A');\n    }); \n    it('test suite1A', function () {\n      runOrder.push('test suite1A');\n    });\n    afterEach('afterEach suite1A', function () {\n      runOrder.push('afterEach suite1A');\n      throw new Error('afterEach suite1A error');\n    });\n    after('after suite1A', function () {\n      runOrder.push('after suite1A');\n    });\n  });\n\n  afterEach('afterEach suite1', function () {\n    runOrder.push('afterEach suite1');\n  });\n  after('after suite1', function () {\n    runOrder.push('after suite1');\n    assert.deepStrictEqual(runOrder, [\n      'before suite1', 'beforeEach suite1', 'test suite1',\n      'afterEach suite1', 'before suite1A', 'beforeEach suite1',\n      'beforeEach suite1A', 'test suite1A', 'afterEach suite1A',\n      'afterEach suite1', 'after suite1A', 'after suite1'\n    ]);\n  });\n});\n\ndescribe('suite2', function () {\n  before('before suite2', function () {});\n  beforeEach('beforeEach suite2', function () {});\n  it('test suite2', function () {\n    runOrder.push('test suite2 - should not run');\n  });\n  afterEach('afterEach suite2', function () {});\n  after('after suite2', function () {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/bail-with-before.fixture.js",
    "content": "'use strict';\nvar assert = require('assert');\n\ndescribe('suite1', function () {\n  var runOrder = [];\n  before('before suite1', function () {\n    runOrder.push('before suite1');\n    throw new Error('before suite1 error');\n  });\n  beforeEach('beforeEach suite1', function () {\n    runOrder.push('beforeEach suite1 - should not run');\n  });\n  it('test suite1', function () {\n    runOrder.push('test suite1 - should not run');\n  });\n\n  describe('suite1A', function () {\n    before('before suite1A', function () {});\n    beforeEach('beforeEach suite1A', function () {}); \n    it('test suite1A', function () {\n      runOrder.push('test suite1A - should not run');\n    });\n    afterEach('afterEach suite1A', function () {});\n    after('after suite1A', function () {});\n  });\n\n  afterEach('afterEach suite1', function () {\n    runOrder.push('afterEach suite1 - should not run');\n  });\n  after('after suite1', function () {\n    runOrder.push('after suite1');\n    assert.deepStrictEqual(runOrder, ['before suite1', 'after suite1']);\n  });\n});\n\ndescribe('suite2', function () {\n  before('before suite2', function () {});\n  beforeEach('beforeEach suite2', function () {});\n  it('test suite2', function () {\n    console.log('test suite2 - should not run');\n  });\n  afterEach('afterEach suite2', function () {});\n  after('after suite2', function () {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/bail-with-beforeEach.fixture.js",
    "content": "'use strict';\nvar assert = require('assert');\n\ndescribe('suite1', function () {\n  var runOrder = [];\n  before('before suite1', function () {\n    runOrder.push('before suite1');\n  });\n  beforeEach('beforeEach suite1', function () {\n    runOrder.push('beforeEach suite1');\n    throw new Error('beforeEach suite1 error');\n  });\n  it('test suite1', function () {\n    runOrder.push('test suite1 - should not run');\n  });\n\n  describe('suite1A', function () {\n    before('before suite1A', function () {});\n    beforeEach('beforeEach suite1A', function () {}); \n    it('test suite1A', function () {\n      runOrder.push('test suite1A - should not run');\n    });\n    afterEach('afterEach suite1A', function () {});\n    after('after suite1A', function () {});\n  });\n\n  afterEach('afterEach suite1', function () {\n    runOrder.push('afterEach suite1');\n  });\n  after('after suite1', function () {\n    runOrder.push('after suite1');\n    assert.deepStrictEqual(runOrder, [\n      'before suite1', 'beforeEach suite1', 'afterEach suite1', 'after suite1'\n    ]);\n  });\n});\n\ndescribe('suite2', function () {\n  before('before suite2', function () {});\n  beforeEach('beforeEach suite2', function () {});\n  it('test suite2', function () {\n    runOrder.push('test suite2 - should not run');\n  });\n  afterEach('afterEach suite2', function () {});\n  after('after suite2', function () {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/bail-with-test.fixture.js",
    "content": "'use strict';\nvar assert = require('assert');\n\ndescribe('suite1', function () {\n  var runOrder = [];\n  before('before suite1', function () {\n    runOrder.push('before suite1');\n  });\n  beforeEach('beforeEach suite1', function () {\n    runOrder.push('beforeEach suite1');\n  });\n  it('test suite1', function () {\n    runOrder.push('test suite1');\n    throw new Error('test suite1 error');\n  });\n\n  describe('suite1A', function () {\n    before('before suite1A', function () {});\n    beforeEach('beforeEach suite1A', function () {}); \n    it('test suite1A', function () {\n      runOrder.push('test suite1A - should not run');\n    });\n    afterEach('afterEach suite1A', function () {});\n    after('after suite1A', function () {});\n  });\n\n  afterEach('afterEach suite1', function () {\n    runOrder.push('afterEach suite1');\n  });\n  after('after suite1', function () {\n    runOrder.push('after suite1');\n    assert.deepStrictEqual(runOrder, [\n      'before suite1', 'beforeEach suite1', 'test suite1',\n      'afterEach suite1', 'after suite1'\n    ]);\n  });\n});\n\ndescribe('suite2', function () {\n  before('before suite2', function () {});\n  beforeEach('beforeEach suite2', function () {});\n  it('test suite2', function () {\n    runOrder.push('test suite2 - should not run');\n  });\n  afterEach('afterEach suite2', function () {});\n  after('after suite2', function () {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/bail.fixture.js",
    "content": "'use strict';\n\ndescribe('suite1', function () {\n  it('should display this spec', function () {});\n\n  it('should only display this error', function () {\n    throw new Error('this should be displayed');\n  });\n\n  it('should not display this error', function () {\n    throw new Error('this should not be displayed');\n  });\n});\n\ndescribe('suite2', function () {\n  before(function () {\n    throw new Error('this hook should not be displayed');\n  });\n\n  it('should not display this error', function () {\n    throw new Error('this should not be displayed');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/delay-fail.fixture.js",
    "content": "'use strict';\n\nsetTimeout(function () {\n  throw new Error('oops');\n  /* eslint no-unreachable: off */\n  it('test', function () {});\n  run();\n}, 100);\n"
  },
  {
    "path": "test/integration/fixtures/options/delay-only.fixture.js",
    "content": "'use strict';\n\nvar assert = require('assert');\nvar delay = 200;\n\nsetTimeout(function () {\n  describe('delayed execution should execute exclusive tests only', function () {\n    it('should not run this test', function () {\n      (true).should.equal(false);\n    });\n\n    it.only('should run this', function () {});\n\n    it('should not run this test, neither', function () {\n      (true).should.equal(false);\n    });\n\n    it.only('should run this, too', function () {});\n  });\n\n  run();\n}, delay);\n\n\n"
  },
  {
    "path": "test/integration/fixtures/options/delay.fixture.js",
    "content": "'use strict';\n\nvar assert = require('assert');\nvar delay = 200;\n\nsetTimeout(function () {\n  describe('delayed execution', function () {\n    it('should have no effect if attempted twice in the same suite', function () {\n      assert(true);\n      run();\n      assert(true);\n    });\n  });\n\n  run();\n}, delay);\n"
  },
  {
    "path": "test/integration/fixtures/options/dry-run/dry-run.fixture.js",
    "content": "'use strict';\n\ndescribe.only('suite1', function() {\n  it.skip('test1 - report as skipped', function() { });\n\n  it('test2 - report as passed', function() { });\n\n  it('test3 - report as passed', function() {\n    throw new Error('this test should not run');\n  });\n});\n\ndescribe('suite2', function () {\n  before(function() {\n    throw new Error('this hook should not run');\n  });\n  beforeEach(function() {\n    throw new Error('this hook should not run');\n  });\n\n  it.only('test4 - report as passed', function () {\n    throw new Error('this test should not run');\n  });\n\n  it('test5 - should be ignored', function () {\n    throw new Error('this test should not run');\n  });\n\n  afterEach(function() {\n    throw new Error('this hook should not run');\n  });\n  after(function() {\n    throw new Error('this hook should not run');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/dry-run/stack-size.fixture.js",
    "content": "var assert = require('assert');\n\ndescribe('Wrapper suite', function () {\n  for(let i=0; i < 400; i++) {\n    describe(`suite ${i}`, function () {\n      it(`test ${i}`, function () {\n        assert.equal(1, 1);\n      });\n    });\n  }\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/extension/test1.fixture.js",
    "content": "var obj = {foo: 'bar'};\n\ndescribe('js', function () {\n  it('should work', function () {\n    expect(obj, 'to equal', {foo: 'bar'});\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/extension/test2.fixture.coffee",
    "content": "\nobj = foo: 'bar'\n\ndescribe 'coffeescript', ->\n  it 'should work', ->\n    expect(obj, 'to equal', foo: 'bar')\n"
  },
  {
    "path": "test/integration/fixtures/options/file-alpha.fixture.js",
    "content": "'use strict';\n\ndescribe('alpha', function () {\n  it('should be executed first', function () {\n    if (global.beta !== undefined) {\n      throw new Error('alpha was not executed first');\n    }\n\n    if (global.theta !== undefined) {\n      throw new Error('alpha was not executed first');\n    }\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/file-beta.fixture.js",
    "content": "'use strict';\n\ndescribe('beta', function () {\n  it('should be executed second', function () {\n    global.beta = 1;\n\n    if (global.theta !== undefined) {\n      throw new Error('beta was not executed second');\n    }\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/file-theta.fixture.js",
    "content": "'use strict';\n\ndescribe('theta', function () {\n  it('should be executed third', function () {\n    global.theta = 1;\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/forbid-only/only-before-each.fixture.js",
    "content": "'use strict';\n\ndescribe('test marked with only and beforeEach has skip', function() {\n  beforeEach(function() {\n    this.skip();\n  });\n  it.only('only test', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/forbid-only/only-before.fixture.js",
    "content": "'use strict';\n\ndescribe('test marked with only and before has skip', function() {\n  before(function() {\n    this.skip();\n  });\n  it.only('only test', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/forbid-only/only-empty-suite.fixture.js",
    "content": "'use strict';\n\ndescribe.only('forbid only - suite marked with only', function() {});\n"
  },
  {
    "path": "test/integration/fixtures/options/forbid-only/only-suite.fixture.js",
    "content": "'use strict';\n\ndescribe.only('forbid only - suite marked with only', function() {\n  it('test1', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/forbid-only/only.fixture.js",
    "content": "'use strict';\n\ndescribe('forbid only - test marked with only', function() {\n  it('test1', function() {});\n  it.only('test2', function() {});\n  it('test3', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/forbid-only/passed.fixture.js",
    "content": "'use strict';\n\ndescribe('forbid only - `.only` is not used', function() {\n  it('test1', function() {});\n  it('test2', function() {});\n  it('test3', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/forbid-pending/before-this-skip.fixture.js",
    "content": "'use strict';\n\ndescribe('forbid pending - before calls `skip()`', function() {\n  it('test', function() {});\n  before(function() {\n    this.skip();\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/forbid-pending/beforeEach-this-skip.fixture.js",
    "content": "'use strict';\n\ndescribe('forbid pending - beforeEach calls `skip()`', function() {\n  it('test', function() {});\n  beforeEach(function() {\n    this.skip();\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/forbid-pending/passed.fixture.js",
    "content": "'use strict';\n\ndescribe('forbid pending - all test pass', function() {\n  it('test1', function() {});\n  it('test2', function() {});\n  it('test3', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/forbid-pending/pending.fixture.js",
    "content": "'use strict';\n\ndescribe('forbid pending - test without function', function() {\n  it('test1', function() {});\n  it('test2');\n  it('test3', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/forbid-pending/skip-empty-suite.fixture.js",
    "content": "'use strict';\n\ndescribe.skip('forbid pending - suite marked with skip', function() {});\n"
  },
  {
    "path": "test/integration/fixtures/options/forbid-pending/skip-suite.fixture.js",
    "content": "'use strict';\n\ndescribe.skip('forbid pending - suite marked with skip', function() {\n  it('test1', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/forbid-pending/skip.fixture.js",
    "content": "'use strict';\n\ndescribe('forbid pending - test marked with skip', function() {\n  it('test1', function() {});\n  it.skip('test2', function() {});\n  it('test3', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/forbid-pending/this-skip.fixture.js",
    "content": "'use strict';\n\ndescribe('forbid pending - test calls `skip()`', function() {\n  it('test1', function() {});\n  it('test2', function() {\n    this.skip();\n  });\n  it('test3', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/grep.fixture.js",
    "content": "'use strict';\n\ndescribe('grep', function () {\n  describe('Match', function () {\n    it('should run', function () {});\n    it('should also run', function () {});\n  });\n\n  describe('match', function () {\n    it('should run', function () {});\n    it('should also run', function () {});\n  });\n\n  describe('fail', function () {\n    it('should not be ran', function () {\n      throw new Error('Spec should not run');\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/ignore/fail.fixture.js",
    "content": "'use strict';\n\ndescribe('ignore test fail', function () {\n  it('should not run this test', function () {\n    throw new Error('should not run');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/ignore/nested/fail.fixture.js",
    "content": "'use strict';\n\ndescribe('ignore test nested fail', function () {\n  it('should not run this test', function () {\n    throw new Error('should not run');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/ignore/nested/pass.fixture.js",
    "content": "'use strict';\n\ndescribe('ignore test nested pass', function () {\n  it('should find this test', function () {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/ignore/pass.fixture.js",
    "content": "'use strict';\n\ndescribe('ignore test pass', function () {\n  it('should find this test', function () {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/jobs/fail-in-parallel.fixture.js",
    "content": "'use strict';\n\nit('should fail if in a worker', function() {\n  if (!require('workerpool').isMainThread) {\n    throw new Error('in worker!');\n  }\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/only/bdd.fixture.js",
    "content": "'use strict';\n\ndescribe.only('should run this suite', function () {\n  it('should run this test', function () {});\n\n  it('should run this test', function () {});\n\n  it('should run this test', function () {});\n});\n\ndescribe('should not run this suite', function () {\n  it('should not run this test', function () {\n    (true).should.equal(false);\n  });\n\n  it('should not run this test', function () {\n    (true).should.equal(false);\n  });\n\n  it('should not run this test', function () {\n    (true).should.equal(false);\n  });\n});\n\ndescribe.only('should run this suite too', function () {\n  describe('should run this nested suite', function () {\n    it('should run this test', function () {});\n\n    it('should run this test', function () {});\n\n    it('should run this test', function () {});\n  });\n});\n\ndescribe.only('should run this suite, even', function () {\n  describe('should run this nested suite, even', function () {\n    describe('should run this doubly-nested suite!', function () {\n      it('should run this test', function () {});\n\n      it('should run this test', function () {});\n\n      it('should run this test', function () {});\n    });\n  });\n});\n\ndescribe('should run this suite with an exclusive test', function () {\n  it.only('should run this test', function () {});\n\n  describe('should not run this nested suite', function () {\n    describe.only('should not run this doubly-nested suite', function () {\n      it('should not run this test', function () {});\n\n      it('should not run this test', function () {});\n\n      it('should not run this test', function () {});\n    });\n  });\n});\n\ndescribe('should run this suite with an exclusive test (reverse order)', function () {\n  describe('should not run this nested suite', function () {\n    describe.only('should not run this doubly-nested suite', function () {\n      it('should not run this test', function () {});\n\n      it('should not run this test', function () {});\n\n      it('should not run this test', function () {});\n    });\n  });\n  it.only('should run this test', function () {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/only/qunit.fixture.js",
    "content": "'use strict';\n\nsuite.only('should run all tests in this suite');\n\ntest('should run this test #1', function () {});\n\ntest('should run this test #2', function () {});\n\ntest('should run this test #3', function () {});\n\ntest('should run this test #4', function () {});\n\ntest('should run this test #5', function () {});\n\nsuite('should not run any of this suite\\'s tests');\n\ntest('should not run this test', function () {\n  (false).should.equal(true);\n});\n\ntest('should not run this test', function () {\n  (false).should.equal(true);\n});\n\ntest('should not run this test', function () {\n  (false).should.equal(true);\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/only/tdd.fixture.js",
    "content": "'use strict';\n\nsuite.only('should run all tests in this tdd suite', function () {\n  test('should run this test #1', function () {});\n\n  test('should run this test #2', function () {});\n\n  test('should run this test #3', function () {});\n\n  test('should run this test #4', function () {});\n});\n\nsuite('should not run this suite', function () {\n  test('should not run this test', function () {\n    (true).should.equal(false);\n  });\n\n  test('should not run this test', function () {\n    (true).should.equal(false);\n  });\n\n  test('should not run this test', function () {\n    (true).should.equal(false);\n  });\n});\n\nsuite.only('should run this suite too', function () {\n  suite('should run this nested suite', function () {\n    test('should run this test', function () {});\n\n    test('should run this test', function () {});\n\n    test('should run this test', function () {});\n\n    test('should run this test', function () {});\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/parallel/bail.fixture.js",
    "content": "describe('some suite', function() {\n  this.bail(true);\n  \n  it('should bail', function() {\n    throw new Error();\n  });\n\n  it('will not get run', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/parallel/exclusive-test-a.fixture.js",
    "content": "describe.only('it should only run this, but it does not', function() {\n  it('should do a thing', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/parallel/exclusive-test-b.fixture.js",
    "content": "describe('it should run this anyway', function() {\n  it('should do a different thing', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/parallel/retries-a.fixture.js",
    "content": "describe('retry suite A', function() {\n  it('should pass', function() {\n\n  });\n});"
  },
  {
    "path": "test/integration/fixtures/options/parallel/retries-b.fixture.js",
    "content": "describe('retry suite B', function() {\n  let count = 0;\n  it('should retry', function() {\n    this.retries(3);\n    console.log(`count: ${++count}`);\n    throw new Error('failure');\n  });\n});"
  },
  {
    "path": "test/integration/fixtures/options/parallel/syntax-err.fixture.js",
    "content": "var foo = "
  },
  {
    "path": "test/integration/fixtures/options/parallel/test-a.fixture.js",
    "content": "describe('a', function() {\n  it('should pass', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/parallel/test-b.fixture.js",
    "content": "describe('b', function() {\n  it('should be pending');\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/parallel/test-c.fixture.js",
    "content": "describe('c', function() {\n  it('should fail', function() {\n    throw new Error('failure');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/parallel/test-d.fixture.js",
    "content": "describe('d', function() {\n  it('should pass, then fail', function() {\n    process.nextTick(function() {\n      throw new Error('uncaught!!');\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/parallel/uncaught.fixture.js",
    "content": "'use strict';\n\nit('throws an uncaught exception', function (done) {\n  process.nextTick(function () {\n    throw new Error('existential isolation!!');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/reporter-esm.fixture.mjs",
    "content": "function SimplerReporter(runner, options) {\n  console.log(JSON.stringify(options.reporterOption));\n}\n\nexport default SimplerReporter;\n"
  },
  {
    "path": "test/integration/fixtures/options/reporter-with-options.fixture.js",
    "content": "'use strict';\n\nfunction ReporterWithOptions(runner, options) {\n  console.log(JSON.stringify(options.reporterOption));\n}\n\nmodule.exports = ReporterWithOptions;\n"
  },
  {
    "path": "test/integration/fixtures/options/retries.fixture.js",
    "content": "'use strict';\n\ndescribe('retries', function () {\n  it('should fail', function () {\n    throw new Error('retry failure');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/slow-test.fixture.js",
    "content": "'use strict';\n\ndescribe('a suite', function() {\n  it('should succeed in 500ms', function(done) {\n    setTimeout(done, 500);\n  });\n\n  it('should succeed in 1.1s', function(done) {\n    setTimeout(done, 1100);\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/sort-alpha.fixture.js",
    "content": "'use strict';\n\ndescribe('alpha', function () {\n  it('should be executed first', function () {\n    if (global.beta) {\n      throw new Error('alpha was not executed first');\n    }\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/sort-beta.fixture.js",
    "content": "'use strict';\n\ndescribe('beta', function () {\n  it('should be executed second', function () {\n    global.beta = 1;\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/timeout-unref.fixture.js",
    "content": "it('unrefs a timeout', function(done) {\n  setTimeout(done, 10).unref();\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/watch/dependency.fixture.js",
    "content": "module.exports.testShouldFail = false;\n"
  },
  {
    "path": "test/integration/fixtures/options/watch/hook.fixture.js",
    "content": "module.exports = {\n  mochaHooks: {\n    [\"<hook>\"]: function() {\n      throw new Error(\"<hook> Hook Error\");\n    },\n  },\n};\n"
  },
  {
    "path": "test/integration/fixtures/options/watch/test-file-change.fixture.js",
    "content": "// This will be replaced in the tests\nconst testShouldFail = true;\n\nit('checks dependency', () => {\n  if (testShouldFail === true) {\n    throw new Error('test failed');\n  }\n});\n"
  },
  {
    "path": "test/integration/fixtures/options/watch/test-with-dependency.fixture.js",
    "content": "const dependency = require('./lib/dependency');\n\nit('checks dependency', () => {\n  if (dependency.testShouldFail === true) {\n    throw new Error('test failed');\n  }\n});\n"
  },
  {
    "path": "test/integration/fixtures/parallel/circular-error-array.mjs",
    "content": "import {describe,it} from \"../../../../index.js\";\n\ndescribe('test1', () => {\n  it('test', () => {\n    const error = new Error('Foo');\n    error.foo = { props: [] };\n    error.foo.props.push(error.foo);\n    throw error;\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/parallel/circular-error-object.mjs",
    "content": "import {describe,it} from \"../../../../index.js\";\n\ndescribe('test1', () => {\n  it('test', () => {\n    const errorA = {};\n    const objectB = {toA: errorA};\n    errorA.toB = objectB;\n\n    const error = new Error(\"Oh no!\");\n    error.error = errorA;\n    error.values = [errorA];\n\n    throw error;\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/parallel/getter-error-object.mjs",
    "content": "import {describe, it} from '../../../../index.js';\n\ndescribe('test1', () => {\n  it('test', async () => {\n    const error = new Error('Oh no!');\n\n    error.nested = {\n      get inner() {\n        return 'abc';\n      }\n    };\n\n    throw error;\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/parallel/non-circular-error.mjs",
    "content": "import {it} from '../../../../index.js';\n\nit('test', () => {\n  throw new Error('Foo');\n});\n"
  },
  {
    "path": "test/integration/fixtures/parallel/test1.mjs",
    "content": "import {describe,it} from \"../../../../index.js\";\n\ndescribe('test1', () => {\n  it('should pass', () => {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/parallel/test2.mjs",
    "content": "import {describe,it} from \"../../../../index.js\";\n\ndescribe('test2', () => {\n  it('should pass', () => {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/parallel/test3.mjs",
    "content": "import {describe,it} from \"../../../../index.js\";\n\ndescribe('test3', () => {\n  it('should fail', () => {\n    throw new Error('expecting this error to fail');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/parallel/testworkerid1.mjs",
    "content": "import assert from 'assert';\n\ndescribe('test1', () => {\n  it('should always run on worker with id 0', () => {\n    assert.ok(process.env.MOCHA_WORKER_ID === '0');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/parallel/testworkerid2.mjs",
    "content": "import assert from 'assert';\n\ndescribe('test2', () => {\n  it('should always run on worker with id 1', () => {\n    assert.ok(process.env.MOCHA_WORKER_ID === '1');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/parallel/testworkerid3.mjs",
    "content": "import assert from 'assert';\n\ndescribe('test3', () => {\n  it('should run on worker with either id 0 or 1', () => {\n    assert.ok(\n      process.env.MOCHA_WORKER_ID === '0' || process.env.MOCHA_WORKER_ID === '1'\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/passing-async.fixture.js",
    "content": "'use strict';\n\ndescribe('a suite', function() {\n  it('should succeed in 50ms', function(done) {\n    setTimeout(done, 50);\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/passing-sync.fixture.js",
    "content": "'use strict';\n\ndescribe('a suite', function() {\n  it('should succeed', function() {\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/passing.fixture.js",
    "content": "'use strict';\n\nvar assert = require('assert');\n\ndescribe('suite', function () {\n  it('test1', function () {\n    assert(true);\n  });\n\n  it('test2', function () {\n    assert(true);\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/pending/programmatic.fixture.js",
    "content": "'use strict';\nconst Mocha = require('../../../../lib/mocha');\n\nconst mocha = new Mocha({reporter: 'json'});\nmocha.addFile(\"./test/integration/fixtures/__default__.fixture.js\");\n\nconst runner = mocha.run();\nrunner.on('test', function (test) { test.pending = true; });\n"
  },
  {
    "path": "test/integration/fixtures/pending/skip-async-before-hooks.fixture.js",
    "content": "'use strict';\nvar assert = require('assert');\n\ndescribe('outer suite', function() {\n  var runOrder = [];\n  before(function() {\n    runOrder.push('outer before');\n  });\n\n  it('should run test-1', function() {\n    runOrder.push('should run test-1');\n  });\n\n  describe('inner suite', function() {\n    before(function(done) {\n      runOrder.push('inner before');\n      var self = this;\n      setTimeout(function() {\n        self.skip();   // done() is not required\n      }, 0);\n    });\n\n    before(function() {\n      runOrder.push('inner before-2 should not run');\n    });\n\n    beforeEach(function() {\n      runOrder.push('beforeEach should not run');\n    });\n\n    afterEach(function() {\n      runOrder.push('afterEach should not run');\n    });\n\n    after(function() {\n      runOrder.push('inner after');\n    });\n\n    it('should not run this test', function() {\n      throw new Error('inner suite test should not run');\n    });\n\n    describe('skipped suite', function() {\n      before(function() {\n        runOrder.push('skipped suite before should not run');\n      });\n\n      it('should not run this test', function() {\n        throw new Error('skipped suite test should not run');\n      });\n\n      after(function() {\n        runOrder.push('skipped suite after should not run');\n      });\n    });\n  });\n\n  it('should run test-2', function() {\n    runOrder.push('should run test-2');\n  });\n\n  after(function() {\n    runOrder.push('outer after');\n    assert.deepStrictEqual(runOrder, [\n      'outer before', \n      'should run test-1', 'should run test-2',\n      'inner before', 'inner after',\n      'outer after'\n    ]);\n    throw new Error('should throw this error');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/pending/skip-async-before-nested.fixture.js",
    "content": "describe('skip in before with nested describes', function () {\n  before(function (done) {\n    var self = this;\n    setTimeout(function () {\n      self.skip();   // done() is not required\n    }, 0);\n  });\n\n  it('should never run this test', function () {\n    throw new Error('never run this test');\n  });\n\n  describe('nested describe', function () {\n    before(function () {\n      throw new Error('first level before should not run');\n    });\n\n    it('should never run this test', function () {\n      throw new Error('never run this test');\n    });\n\n    after(function () {\n      throw new Error('first level after should not run');\n    });\n\n    describe('nested again', function () {\n      before(function () {\n        throw new Error('second level before should not run');\n      });\n\n      it('should never run this test', function () {\n        throw new Error('never run this test');\n      });\n\n      after(function () {\n        throw new Error('second level after should not run');\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/pending/skip-async-before.fixture.js",
    "content": "'use strict';\n\ndescribe('outer describe', function () {\n  it('should run this test', function () {});\n\n  describe('skip in before', function () {\n    before(function (done) {\n      var self = this;\n      setTimeout(function () {\n        self.skip();   // done() is not required\n      }, 0);\n    });\n\n    it('should never run this test', function () {\n      throw new Error('never run this test');\n    });\n    it('should never run this test', function () {\n      throw new Error('never run this test');\n    });\n  });\n\n  it('should run this test', function () {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/pending/skip-async-beforeEach.fixture.js",
    "content": "'use strict';\nvar assert = require('assert');\n\ndescribe('skip in beforeEach', function() {\n  var runOrder = [];\n  beforeEach(function(done) {\n    runOrder.push('beforeEach');\n    var self = this;\n    setTimeout(function() {\n      self.skip();   // done() is not required\n    }, 10);\n  });\n\n  it('should skip this test-1', function() {\n    throw new Error('never run this test');\n  });\n\n  describe('inner', function() {\n    beforeEach(function() {\n      runOrder.push('should not run');\n    });\n\n    it('should skip this test-2', function() {\n      throw new Error('never run this test');\n    });\n    it('should skip this test-3', function() {\n      throw new Error('never run this test');\n    });\n\n    afterEach(function() {\n      runOrder.push('should not run');\n    });\n  });\n\n  afterEach(function() {\n    runOrder.push('afterEach');\n  });\n  after(function() {\n    runOrder.push('after');\n    assert.deepStrictEqual(runOrder, [\n      'beforeEach', 'afterEach',\n      'beforeEach', 'afterEach',\n      'beforeEach', 'afterEach',\n      'after'\n    ]);\n    throw new Error('should throw this error');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/pending/skip-async-spec.fixture.js",
    "content": "'use strict';\nvar assert = require('assert');\n\ndescribe('skip in test', function () {\n  var runOrder = [];\n  beforeEach(function () {\n    runOrder.push('beforeEach');\n  });\n\n  it('should skip async', function (done) {\n    var self = this;\n    setTimeout(function () {\n      self.skip();   // done() is not required\n    }, 0);\n  });\n  it('should run other tests in suite', function () {});\n\n  afterEach(function() {\n    runOrder.push('afterEach');\n  });\n  after(function() {\n    runOrder.push('after');\n    assert.deepStrictEqual(runOrder, [\n      'beforeEach', 'afterEach',\n      'beforeEach', 'afterEach',\n      'after'\n    ]);\n    throw new Error('should throw this error');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/pending/skip-hierarchy.fixture.js",
    "content": "'use strict';\n\ndescribe('a suite', function(){\n  describe.skip('skipped suite 1');\n  describe.skip('skipped suite 2');\n  describe('another suite', function(){\n    it('a test', function(){})\n  })\n});\n"
  },
  {
    "path": "test/integration/fixtures/pending/skip-shorthand.fixture.js",
    "content": "'use strict';\n\ndescribe('pending shorthand', function () {\n  xit('pending spec', function () {}).timeout(0);\n  xspecify('pending spec', function () {}).timeout(0);\n  it.skip('pending spec', function () {}).timeout(0);\n});\n"
  },
  {
    "path": "test/integration/fixtures/pending/skip-sync-after.fixture.js",
    "content": "'use strict';\n\ndescribe('skip in after', function () {\n  it('should run this test-1', function () {});\n\n  after('should throw \"this.skip forbidden\"', function () {\n    this.skip();\n  });\n\n  describe('inner suite', function () {\n    it('should run this test-2', function () {});\n  });\n});\n\ndescribe('second suite', function () {\n  it('should run this test-3', function () {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/pending/skip-sync-before-hooks.fixture.js",
    "content": "'use strict';\nvar assert = require('assert');\n\ndescribe('outer suite', function() {\n  var runOrder = [];\n  before(function() {\n    runOrder.push('outer before');\n  });\n\n  it('should run test-1', function() {\n    runOrder.push('should run test-1');\n  });\n\n  describe('inner suite', function() {\n    before(function() {\n      runOrder.push('inner before');\n      this.skip();\n    });\n\n    before(function() {\n      runOrder.push('inner before-2 should not run');\n    });\n\n    beforeEach(function() {\n      runOrder.push('beforeEach should not run');\n    });\n\n    afterEach(function() {\n      runOrder.push('afterEach should not run');\n    });\n\n    after(function() {\n      runOrder.push('inner after');\n    });\n\n    it('should never run this test', function() {\n      throw new Error('inner suite test should not run');\n    });\n\n    describe('skipped suite', function() {\n      before(function() {\n        runOrder.push('skipped suite before should not run');\n      });\n\n      it('should never run this test', function() {\n        throw new Error('skipped suite test should not run');\n      });\n\n      after(function() {\n        runOrder.push('skipped suite after should not run');\n      });\n    });\n  });\n\n  it('should run test-2', function() {\n    runOrder.push('should run test-2');\n  });\n\n  after(function() {\n    runOrder.push('outer after');\n    assert.deepStrictEqual(runOrder, [\n      'outer before', \n      'should run test-1', 'should run test-2',\n      'inner before', 'inner after',\n      'outer after'\n    ]);\n    throw new Error('should throw this error');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/pending/skip-sync-before-inner.fixture.js",
    "content": "'use strict';\nvar assert = require('assert');\n\ndescribe('outer suite', function() {\n  var runOrder = [];\n  before(function() {\n    runOrder.push('outer before');\n    this.skip();\n  });\n\n  it('should never run this outer test', function() {\n    throw new Error('outer suite test should not run');\n  });\n\n  describe('inner suite', function() {\n    before(function() { runOrder.push('no inner before'); });\n    before(function(done) { runOrder.push('no inner before'); done(); });\n    before(async function() { runOrder.push('no inner before'); });\n    before(function() { return Promise.resolve(runOrder.push('no inner before')) });\n\n    after(function() { runOrder.push('no inner after'); });\n    after(function(done) { runOrder.push('no inner after'); done(); });\n    after(async function() { runOrder.push('no inner after'); });\n    after(function() { return Promise.resolve(runOrder.push('no inner after')) });\n\n    it('should never run this inner test', function() {\n      throw new Error('inner suite test should not run');\n    });\n  });\n\n  after(function() {\n    runOrder.push('outer after');\n    assert.deepStrictEqual(runOrder, [\n      'outer before', 'outer after'\n    ]);\n    throw new Error('should throw this error');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/pending/skip-sync-before-nested.fixture.js",
    "content": "'use strict';\n\ndescribe('skip in before with nested describes', function () {\n  before(function () {\n    this.skip();\n  });\n\n  it('should never run this test', function () {\n    throw new Error('never run this test');\n  });\n\n  describe('nested describe', function () {\n    before(function () {\n      throw new Error('first level before should not run');\n    });\n\n    it('should never run this test', function () {\n      throw new Error('never run this test');\n    });\n\n    after(function () {\n      throw new Error('first level after should not run');\n    });\n\n    describe('nested again', function () {\n      before(function () {\n        throw new Error('second level before should not run');\n      });\n\n      it('should never run this test', function () {\n        throw new Error('never run this test');\n      });\n\n      after(function () {\n        throw new Error('second level after should not run');\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/pending/skip-sync-before.fixture.js",
    "content": "'use strict';\n\ndescribe('outer describe', function () {\n  it('should run this test', function () {});\n\n  describe('skip in before', function () {\n    before(function () {\n      this.skip();\n    });\n\n    it('should never run this test', function () {\n      throw new Error('never run this test');\n    });\n    it('should never run this test', function () {\n      throw new Error('never run this test');\n    });\n  });\n\n  it('should run this test', function () {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/pending/skip-sync-beforeEach-cond.fixture.js",
    "content": "'use strict';\n\ndescribe('skip conditionally in beforeEach', function() {\n  var n = 1;\n  beforeEach(function() {\n    if (n !== 2) {\n        this.skip();\n    }\n  });\n\n  it('should skip this test-1', function() {\n    throw new Error('never run this test');\n  });\n  it('should run this test-2', function() {});\n\n  describe('inner suite', function() {\n    it('should skip this test-3', function() {\n      throw new Error('never run this test');\n    });\n  });\n\n  afterEach(function() { n++; });\n  after(function() {\n    if (n === 4) {\n      throw new Error('should throw this error');\n    }\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/pending/skip-sync-beforeEach.fixture.js",
    "content": "'use strict';\nvar assert = require('assert');\n\ndescribe('skip in beforeEach', function() {\n  var runOrder = [];\n  beforeEach(function() {\n    runOrder.push('beforeEach');\n    this.skip();\n  });\n\n  it('should skip this test-1', function() {\n    throw new Error('never run this test');\n  });\n\n  describe('inner', function() {\n    beforeEach(function() {\n      runOrder.push('should not run');\n    });\n\n    it('should skip this test-2', function() {\n      throw new Error('never run this test');\n    });\n    it('should skip this test-3', function() {\n      throw new Error('never run this test');\n    });\n\n    afterEach(function() {\n      runOrder.push('should not run');\n    });\n  });\n\n  afterEach(function() {\n    runOrder.push('afterEach');\n  });\n  after(function() {\n    runOrder.push('after');\n    assert.deepStrictEqual(runOrder, [\n      'beforeEach', 'afterEach',\n      'beforeEach', 'afterEach',\n      'beforeEach', 'afterEach',\n      'after'\n    ]);\n    throw new Error('should throw this error');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/pending/skip-sync-spec.fixture.js",
    "content": "'use strict';\nvar assert = require('assert');\n\ndescribe('skip in test', function () {\n  var runOrder = [];\n  beforeEach(function () {\n    runOrder.push('beforeEach');\n  });\n\n  it('should skip immediately', function () {\n    this.skip();\n    throw new Error('never run this test');\n  });\n  it('should run other tests in suite', function () {});\n\n  afterEach(function() {\n    runOrder.push('afterEach');\n  });\n  after(function() {\n    runOrder.push('after');\n    assert.deepStrictEqual(runOrder, [\n      'beforeEach', 'afterEach',\n      'beforeEach', 'afterEach',\n      'after'\n    ]);\n    throw new Error('should throw this error');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/pending/spec.fixture.js",
    "content": "'use strict';\n\ndescribe('suite', function () {\n  it('pending spec');\n});\n"
  },
  {
    "path": "test/integration/fixtures/plugins/global-fixtures/global-setup-teardown-multiple.fixture.js",
    "content": "'use strict';\n\nexports.mochaGlobalSetup = [\n  async function() {\n    this.foo = 0;\n  },\n  function() {\n    this.foo = this.foo + 1;\n  }\n];\n\nexports.mochaGlobalTeardown = [\n  async function() {\n    this.foo = this.foo + 1;\n  },\n  function() {\n    this.foo = this.foo + 1;\n    console.log(`teardown: this.foo = ${this.foo}`);\n  }\n];\n"
  },
  {
    "path": "test/integration/fixtures/plugins/global-fixtures/global-setup-teardown.fixture.js",
    "content": "'use strict';\n\nexports.mochaGlobalSetup = async function() {\n  this.foo = 'bar';\n  console.log(`setup: this.foo = ${this.foo}`);\n};\n\nexports.mochaGlobalTeardown = async function() {\n  console.log(`teardown: this.foo = ${this.foo}`);\n};\n"
  },
  {
    "path": "test/integration/fixtures/plugins/global-fixtures/global-setup.fixture.js",
    "content": "'use strict';\n\nexports.mochaGlobalSetup = async function() {\n  console.log(`setup schmetup`);\n};\n\n"
  },
  {
    "path": "test/integration/fixtures/plugins/global-fixtures/global-teardown.fixture.js",
    "content": "'use strict';\n\nexports.mochaGlobalTeardown = async function() {\n  console.log('teardown schmeardown');\n};\n"
  },
  {
    "path": "test/integration/fixtures/plugins/root-hooks/esm/package.json",
    "content": "{ \"type\": \"module\" }\n"
  },
  {
    "path": "test/integration/fixtures/plugins/root-hooks/esm/root-hook-defs-esm.fixture.js",
    "content": "export const mochaHooks = () => ({\n  beforeEach() {\n    console.log('esm beforeEach');\n  },\n  afterEach() {\n    console.log('esm afterEach');\n  },\n});\n"
  },
  {
    "path": "test/integration/fixtures/plugins/root-hooks/root-hook-defs-a.fixture.js",
    "content": "'use strict';\n\nexports.mochaHooks = {\n  beforeAll() {\n    console.log('beforeAll');\n  },\n  beforeEach() {\n    console.log('beforeEach');\n  },\n  afterAll() {\n    console.log('afterAll');\n  },\n  afterEach() {\n    console.log('afterEach');\n  }\n};\n"
  },
  {
    "path": "test/integration/fixtures/plugins/root-hooks/root-hook-defs-b.fixture.js",
    "content": "'use strict';\n\nexports.mochaHooks = {\n  beforeAll: [\n    function() {\n      console.log('beforeAll array 1');\n    },\n    function() {\n      console.log('beforeAll array 2');\n    }\n  ],\n  beforeEach: [\n    function() {\n      console.log('beforeEach array 1');\n    },\n    function() {\n      console.log('beforeEach array 2');\n    }\n  ],\n  afterAll: [\n    function() {\n      console.log('afterAll array 1');\n    },\n    function() {\n      console.log('afterAll array 2');\n    }\n  ],\n  afterEach: [\n    function() {\n      console.log('afterEach array 1');\n    },\n    function() {\n      console.log('afterEach array 2');\n    }\n  ]\n};\n"
  },
  {
    "path": "test/integration/fixtures/plugins/root-hooks/root-hook-defs-c.fixture.js",
    "content": "'use strict';\n\nexports.mochaHooks = async () => ({\n  beforeAll() {\n    console.log('beforeAll');\n  },\n  beforeEach() {\n    console.log('beforeEach');\n  },\n  afterAll() {\n    console.log('afterAll');\n  },\n  afterEach() {\n    console.log('afterEach');\n  }\n});\n"
  },
  {
    "path": "test/integration/fixtures/plugins/root-hooks/root-hook-defs-d.fixture.js",
    "content": "'use strict';\n\nexports.mochaHooks = async() => ({\n  beforeAll: [\n    function() {\n      console.log('beforeAll array 1');\n    },\n    function() {\n      console.log('beforeAll array 2');\n    }\n  ],\n  beforeEach: [\n    function() {\n      console.log('beforeEach array 1');\n    },\n    function() {\n      console.log('beforeEach array 2');\n    }\n  ],\n  afterAll: [\n    function() {\n      console.log('afterAll array 1');\n    },\n    function() {\n      console.log('afterAll array 2');\n    }\n  ],\n  afterEach: [\n    function() {\n      console.log('afterEach array 1');\n    },\n    function() {\n      console.log('afterEach array 2');\n    }\n  ]\n});\n"
  },
  {
    "path": "test/integration/fixtures/plugins/root-hooks/root-hook-defs-esm-broken.fixture.js",
    "content": "export const mochaHooks = {\n  beforeAll() {\n    console.log('mjs beforeAll');\n  },\n  afterAll() {\n    console.log('mjs afterAll');\n  },\n};\n"
  },
  {
    "path": "test/integration/fixtures/plugins/root-hooks/root-hook-defs-esm.fixture.mjs",
    "content": "export const mochaHooks = {\n  beforeAll() {\n    console.log('mjs beforeAll');\n  },\n  afterAll() {\n    console.log('mjs afterAll');\n  },\n};\n"
  },
  {
    "path": "test/integration/fixtures/plugins/root-hooks/root-hook-test-2.fixture.js",
    "content": "// run with --require root-hook-defs-a.fixture.js --require\n// root-hook-defs-b.fixture.js\n\nit('should also have some root hooks', function() {\n  // test\n});"
  },
  {
    "path": "test/integration/fixtures/plugins/root-hooks/root-hook-test.fixture.js",
    "content": "// run with --require root-hook-defs-a.fixture.js --require\n// root-hook-defs-b.fixture.js\n\nit('should have some root hooks', function() {\n  // test\n});"
  },
  {
    "path": "test/integration/fixtures/regression/issue-1991.fixture.js",
    "content": "'use strict';\n\n/* eslint no-unused-vars: off */\n\nfunction MemoryLeak () {\n  this.myArr = [];\n  for (var i = 0; i < 1000000; i++) {\n    this.myArr.push(i);\n  }\n}\n\nvar numOfTests = 300;\nfor (var i = 0; i < numOfTests; i += 1) {\n  /*\n   * This Test suite will crash V8 due to:\n   * 'FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory'\n   * if all the deferred functions references have not been cleared\n   */\n  describe('Memory Leak Suite #' + i, function () {\n    // The <closureVar> variable will be accessed by the test below.\n    // As long as those test's functions are\n    // referenced in memory, the closure variable may not be garbage collected\n    // as it is still referenced.\n    // * In a chrome heap snapshot it will appear under \"system / Context\" (a scope)\n    var closureVar;\n\n    before(function () {\n      var x = closureVar ? 1 : 2;\n    });\n\n    after(function () {\n      var x = closureVar[0];\n    });\n\n    beforeEach(function () {\n      var x = closureVar ? 1 : 2;\n    });\n\n    afterEach(function () {\n      var x = closureVar[0];\n    });\n\n    it('access a variable via a closure', function () {\n      // slow performance on older node.js versions\n      this.timeout(1000);\n      closureVar = new MemoryLeak();\n    });\n  });\n}\n"
  },
  {
    "path": "test/integration/fixtures/regression/issue-2315.fixture.js",
    "content": "'use strict';\n\ndescribe('issue-2315: cannot read property currentRetry of undefined', function () {\n  before(function () {\n    process.nextTick(function () {\n      throw new Error();\n    });\n  });\n\n  it('something', function () {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/regression/issue-2406.fixture.js",
    "content": "'use strict';\n\ndescribe('outer describe', function () {\n  it('should not run this test', function () {});\n  describe('this suite should not run', function () {\n    it('should not run this test', function () {});\n  });\n  describe.only('this .only suite should run', function () {\n    describe('this suite should run', function () {\n      it('should run this test in a nested suite', function () {});\n    });\n    it('should run this test', function () {});\n  });\n  describe('this suite should not run', function () {\n    it('should not run this test', function () {});\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/regression/issue-2417.fixture.js",
    "content": "'use strict';\n\ndescribe('outer describe', function () {\n  describe.only('outer describe.only', function () {\n    it.only('inner it.only', function () {\n      // should run and exit without error\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/reporters.fixture.js",
    "content": "'use strict';\n\n/**\n * This file generates a wide range of output to test reporter functionality.\n */\n\ndescribe('Animals', function() {\n\n  it('should consume organic material', function(done) { done(); });\n  it('should breathe oxygen', function(done) {\n    // we're a jellyfish\n    var actualBreathe = 'nothing';\n    var expectedBreathe = 'oxygen';\n    expect(actualBreathe, 'to equal', expectedBreathe);\n    done();\n  });\n  it('should be able to move', function(done) { done(); });\n  it('should reproduce sexually', function(done) { done(); });\n  it('should grow from a hollow sphere of cells', function(done) { done(); });\n\n  describe('Vertebrates', function() {\n    describe('Mammals', function() {\n      it('should give birth to live young', function(done) {\n        var expectedMammal = {\n          consumesMaterial: 'organic',\n          breathe: 'oxygen',\n          reproduction: {\n            type: 'sexually',\n            spawnType: 'live',\n          }\n        };\n        var platypus = JSON.parse(JSON.stringify(expectedMammal));\n        platypus['reproduction']['spawnType'] = 'hard-shelled egg';\n\n        expect(platypus, 'to equal', expectedMammal);\n        done();\n      });\n\n      describe('Blue Whale', function() {\n        it('should be the largest of all mammals', function(done) { done(); });\n        it('should have a body in some shade of blue', function(done) {\n          var bodyColor = 'blueish_grey';\n          var shadesOfBlue = ['cyan', 'light_blue', 'blue', 'indigo'];\n          expect(bodyColor, 'to be one of', shadesOfBlue);\n\n          done();\n        });\n      });\n    });\n    describe('Birds', function() {\n      it('should have feathers', function(done) { done(); });\n      it('should lay hard-shelled eggs', function(done) { done(); });\n    });\n  });\n\n  describe('Tardigrades', function() {\n    it('should answer to \"water bear\"', function(done) { done(); });\n    it('should be able to survive global mass extinction events', function(done) {\n      throw new Error(\"How do we even test for this without causing one?\")\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/retries/async.fixture.js",
    "content": "'use strict';\n\ndescribe('retries', function () {\n  var times = 0;\n  before(function () {\n    console.log('before');\n  });\n\n  after(function () {\n    console.log('after');\n  });\n\n  beforeEach(function () {\n    console.log('before each', times);\n  });\n\n  afterEach(function () {\n    console.log('after each', times);\n  });\n\n  it('should allow override and run appropriate hooks', function (done) {\n    this.timeout(100);\n    this.retries(2);\n    console.log('TEST', times);\n    if (++times < 3) {\n      return setTimeout(done, 300);\n    }\n    setTimeout(done, 50);\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/retries/early-pass.fixture.js",
    "content": "'use strict';\nconst assert = require('assert');\n\ndescribe('retries', function () {\n  this.retries(1);\n  var times = 0;\n  var self = this;\n\n  it('should pass after 1 retry', function () {\n    times++;\n    if (times !== 2) {\n      throw new Error('retry error ' + times);\n    }\n  });\n  \n  it('check for updated `suite.tests`', function() {\n    assert.strictEqual(self.tests[0]._currentRetry, 1);\n    assert.ok(self.tests[0]._retriedTest);\n    assert.strictEqual(self.tests[0].state, 'passed');\n  })\n});\n"
  },
  {
    "path": "test/integration/fixtures/retries/hooks.fixture.js",
    "content": "'use strict';\n\ndescribe('retries', function () {\n  var times = 0;\n  before(function () {\n    console.log('before');\n  });\n\n  after(function () {\n    console.log('after');\n  });\n\n  beforeEach(function () {\n    console.log('before each', times);\n  });\n\n  afterEach(function () {\n    console.log('after each', times);\n  });\n\n  it('should allow override and run appropriate hooks', function () {\n    this.retries(4);\n    console.log('TEST', times);\n    times++;\n    throw new Error('retry error');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/retries/nested.fixture.js",
    "content": "'use strict';\n\ndescribe('retries', function () {\n  this.retries(3);\n  describe('nested', function () {\n    it('should fail after only 1 retry', function () {\n      this.retries(1);\n      throw new Error('retry error');\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/runner/events-bail-retries.fixture.js",
    "content": "'use strict';\nvar Runner = require('../../../../lib/runner.js');\nvar assert = require('assert');\nvar constants = Runner.constants;\nvar EVENT_HOOK_BEGIN = constants.EVENT_HOOK_BEGIN;\nvar EVENT_HOOK_END = constants.EVENT_HOOK_END;\nvar EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\nvar EVENT_SUITE_BEGIN = constants.EVENT_SUITE_BEGIN;\nvar EVENT_SUITE_END = constants.EVENT_SUITE_END;\nvar EVENT_TEST_BEGIN = constants.EVENT_TEST_BEGIN;\nvar EVENT_TEST_END = constants.EVENT_TEST_END;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\nvar EVENT_TEST_RETRY = constants.EVENT_TEST_RETRY;\n\nvar emitOrder = [\n EVENT_RUN_BEGIN,\n  EVENT_SUITE_BEGIN,\n  EVENT_SUITE_BEGIN,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_BEGIN,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_RETRY,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_BEGIN,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_FAIL,\n  EVENT_TEST_END,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_SUITE_END,\n  EVENT_SUITE_END,\n  EVENT_RUN_END\n];\n\nvar realEmit = Runner.prototype.emit;\nRunner.prototype.emit = function(event, ...args) {\n  // console.log(`emit: ${event}`);\n  assert.strictEqual(event, emitOrder.shift());\n  return realEmit.call(this, event, ...args);\n};\n\ndescribe('suite A', function() {\n  before('before', function() {});\n  beforeEach('beforeEach', function() {});\n  it('test A', function() {\n    throw new Error('error test A');\n  });\n  afterEach('afterEach', function() {});\n  after('after', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/runner/events-bail.fixture.js",
    "content": "'use strict';\nvar Runner = require('../../../../lib/runner.js');\nvar assert = require('assert');\nvar constants = Runner.constants;\nvar EVENT_HOOK_BEGIN = constants.EVENT_HOOK_BEGIN;\nvar EVENT_HOOK_END = constants.EVENT_HOOK_END;\nvar EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\nvar EVENT_SUITE_BEGIN = constants.EVENT_SUITE_BEGIN;\nvar EVENT_SUITE_END = constants.EVENT_SUITE_END;\nvar EVENT_TEST_BEGIN = constants.EVENT_TEST_BEGIN;\nvar EVENT_TEST_END = constants.EVENT_TEST_END;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\n\nvar emitOrder = [\n  EVENT_RUN_BEGIN,\n  EVENT_SUITE_BEGIN,\n  EVENT_SUITE_BEGIN,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_BEGIN,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_FAIL,\n  EVENT_TEST_END,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_SUITE_END,\n  EVENT_SUITE_END,\n  EVENT_RUN_END\n];\n\nvar realEmit = Runner.prototype.emit;\nRunner.prototype.emit = function(event, ...args) {\n  assert.strictEqual(event, emitOrder.shift());\n  return realEmit.call(this, event, ...args);\n};\n\ndescribe('suite A', function() {\n  before('before', function() {});\n  beforeEach('beforeEach', function() {});\n  it('test A', function() {\n    throw new Error('error test A');\n  });\n  describe('suite B', function() {\n    it('test B', function() {});\n  });\n  afterEach('afterEach', function() {});\n  after('after', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/runner/events-basic.fixture.js",
    "content": "'use strict';\nvar Runner = require('../../../../lib/runner.js');\nvar assert = require('assert');\nvar constants = Runner.constants;\nvar EVENT_DELAY_BEGIN = constants.EVENT_DELAY_BEGIN;\nvar EVENT_DELAY_END = constants.EVENT_DELAY_END;\nvar EVENT_HOOK_BEGIN = constants.EVENT_HOOK_BEGIN;\nvar EVENT_HOOK_END = constants.EVENT_HOOK_END;\nvar EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\nvar EVENT_SUITE_BEGIN = constants.EVENT_SUITE_BEGIN;\nvar EVENT_SUITE_END = constants.EVENT_SUITE_END;\nvar EVENT_TEST_BEGIN = constants.EVENT_TEST_BEGIN;\nvar EVENT_TEST_END = constants.EVENT_TEST_END;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\nvar EVENT_TEST_PASS = constants.EVENT_TEST_PASS;\nvar EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING;\nvar EVENT_TEST_RETRY = constants.EVENT_TEST_RETRY;\n\nvar emitOrder = [\n  EVENT_RUN_BEGIN,\n  EVENT_SUITE_BEGIN,\n  EVENT_SUITE_BEGIN,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_BEGIN,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_PASS,\n  EVENT_TEST_END,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_SUITE_BEGIN,\n  EVENT_TEST_BEGIN,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_PASS,\n  EVENT_TEST_END,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_SUITE_END,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_SUITE_END,\n  EVENT_SUITE_END,\n  EVENT_RUN_END\n];\n\nvar realEmit = Runner.prototype.emit;\nRunner.prototype.emit = function(event, ...args) {\n  assert.strictEqual(event, emitOrder.shift());\n  return realEmit.call(this, event, ...args);\n};\n\ndescribe('suite A', function() {\n  before('before', function() {});\n  beforeEach('beforeEach', function() {});\n  it('test A', function() {});\n  describe('suite B', function() {\n    it('test B', function() {});\n  });\n  afterEach('afterEach', function() {});\n  after('after', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/runner/events-delay.fixture.js",
    "content": "'use strict';\nvar Runner = require('../../../../lib/runner.js');\nvar assert = require('assert');\nvar constants = Runner.constants;\nvar EVENT_DELAY_BEGIN = constants.EVENT_DELAY_BEGIN;\nvar EVENT_DELAY_END = constants.EVENT_DELAY_END;\nvar EVENT_HOOK_BEGIN = constants.EVENT_HOOK_BEGIN;\nvar EVENT_HOOK_END = constants.EVENT_HOOK_END;\nvar EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\nvar EVENT_SUITE_BEGIN = constants.EVENT_SUITE_BEGIN;\nvar EVENT_SUITE_END = constants.EVENT_SUITE_END;\nvar EVENT_TEST_BEGIN = constants.EVENT_TEST_BEGIN;\nvar EVENT_TEST_END = constants.EVENT_TEST_END;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\nvar EVENT_TEST_PASS = constants.EVENT_TEST_PASS;\nvar EVENT_TEST_PENDING = constants.EVENT_TEST_PENDING;\nvar EVENT_TEST_RETRY = constants.EVENT_TEST_RETRY;\n\nvar emitOrder = [\n  EVENT_DELAY_BEGIN,\n  EVENT_DELAY_END,\n  EVENT_RUN_BEGIN,\n  EVENT_SUITE_BEGIN,\n  EVENT_SUITE_BEGIN,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_BEGIN,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_PASS,\n  EVENT_TEST_END,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_SUITE_BEGIN,\n  EVENT_TEST_BEGIN,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_PASS,\n  EVENT_TEST_END,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_SUITE_END,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_SUITE_END,\n  EVENT_SUITE_END,\n  EVENT_RUN_END\n];\n\nvar realEmit = Runner.prototype.emit;\nRunner.prototype.emit = function(event, ...args) {\n  assert.strictEqual(event, emitOrder.shift());\n  return realEmit.call(this, event, ...args);\n};\n\nsetTimeout(function() {\n\n  describe('suite A', function() {\n    before('before', function() {});\n    beforeEach('beforeEach', function() {});\n    it('test A', function() {});\n    describe('suite B', function() {\n      it('test B', function() {});\n    });\n    afterEach('afterEach', function() {});\n    after('after', function() {});\n  });\n\n  run();\n}, 100);\n"
  },
  {
    "path": "test/integration/fixtures/runner/events-retries.fixture.js",
    "content": "'use strict';\nvar Runner = require('../../../../lib/runner.js');\nvar assert = require('assert');\nvar constants = Runner.constants;\nvar EVENT_HOOK_BEGIN = constants.EVENT_HOOK_BEGIN;\nvar EVENT_HOOK_END = constants.EVENT_HOOK_END;\nvar EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = constants.EVENT_RUN_END;\nvar EVENT_SUITE_BEGIN = constants.EVENT_SUITE_BEGIN;\nvar EVENT_SUITE_END = constants.EVENT_SUITE_END;\nvar EVENT_TEST_BEGIN = constants.EVENT_TEST_BEGIN;\nvar EVENT_TEST_END = constants.EVENT_TEST_END;\nvar EVENT_TEST_FAIL = constants.EVENT_TEST_FAIL;\nvar EVENT_TEST_RETRY = constants.EVENT_TEST_RETRY;\n\nvar emitOrder = [\n  EVENT_RUN_BEGIN,\n  EVENT_SUITE_BEGIN,\n  EVENT_SUITE_BEGIN,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_BEGIN,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_RETRY,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_BEGIN,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_FAIL,\n  EVENT_TEST_END,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_SUITE_END,\n  EVENT_SUITE_END,\n  EVENT_RUN_END\n];\n\nvar realEmit = Runner.prototype.emit;\nRunner.prototype.emit = function(event, ...args) {\n  assert.strictEqual(event, emitOrder.shift());\n  return realEmit.call(this, event, ...args);\n};\n\ndescribe('suite A', function() {\n  before('before', function() {});\n  beforeEach('beforeEach', function() {});\n  it('test A', function() {\n    throw new Error('error test A');\n  });\n  afterEach('afterEach', function() {});\n  after('after', function() {});\n});\n"
  },
  {
    "path": "test/integration/fixtures/signals-sigabrt.fixture.js",
    "content": "'use strict';\n\ndescribe('signal suite', function () {\n  it('test SIGABRT', function () {\n    process.kill(process.pid, 'SIGABRT');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/signals-sigterm-numeric.fixture.js",
    "content": "'use strict';\nconst os = require('node:os');\n\ndescribe('signal suite', function () {\n  it('test SIGTERM', function () {\n    process.kill(process.pid, os.constants.signals['SIGTERM']);\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/signals-sigterm.fixture.js",
    "content": "'use strict';\n\ndescribe('signal suite', function () {\n  it('test SIGTERM', function () {\n    process.kill(process.pid, 'SIGTERM');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/simple-reporter.js",
    "content": "'use strict';\n\nconst Mocha = require('../../..');\nconst {\n  EVENT_RUN_BEGIN,\n  EVENT_RUN_END,\n  EVENT_TEST_FAIL,\n  EVENT_TEST_PASS,\n  EVENT_SUITE_BEGIN,\n  EVENT_SUITE_END\n} = Mocha.Runner.constants;\n\n// this reporter outputs test results, indenting two spaces per suite\nclass MyReporter {\n  constructor(runner) {\n    this._indents = 0;\n    const stats = runner.stats;\n\n    runner\n      .once(EVENT_RUN_BEGIN, () => {\n        console.log('start');\n      })\n      .on(EVENT_SUITE_BEGIN, () => {\n        this.increaseIndent();\n      })\n      .on(EVENT_SUITE_END, () => {\n        this.decreaseIndent();\n      })\n      .on(EVENT_TEST_PASS, test => {\n        // Test#fullTitle() returns the suite name(s)\n        // prepended to the test title\n        console.log(`${this.indent()}pass: ${test.fullTitle()}`);\n      })\n      .on(EVENT_TEST_FAIL, (test, err) => {\n        console.log(\n          `${this.indent()}fail: ${test.fullTitle()} - error: ${err.message}`\n        );\n      })\n      .once(EVENT_RUN_END, () => {\n        console.log(`end: ${stats.passes}/${stats.passes + stats.failures} ok`);\n      });\n  }\n\n  indent() {\n    return Array(this._indents).join('  ');\n  }\n\n  increaseIndent() {\n    this._indents++;\n  }\n\n  decreaseIndent() {\n    this._indents--;\n  }\n}\n\nmodule.exports = MyReporter;\n"
  },
  {
    "path": "test/integration/fixtures/simple-ui.fixture.js",
    "content": "'use strict';\n\nvar Mocha = require('../../../lib/mocha');\nvar Test = Mocha.Test;\nvar EVENT_FILE_PRE_REQUIRE = Mocha.Suite.constants.EVENT_FILE_PRE_REQUIRE;\n\n/**\n * A simple UI that only exposes a single function: test\n */\nmodule.exports = Mocha.interfaces['simple-ui'] = function(suite) {\n  suite.on(EVENT_FILE_PRE_REQUIRE, function(\n    context,\n    file,\n    mocha\n  ) {\n    var common = require('../../../lib/interfaces/common')(\n      [suite],\n      context\n    );\n\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n\n    /**\n     * Describes a specification or test-case with the given `title`\n     * and callback `fn` acting as a thunk.\n     */\n    context.test = function(title, fn) {\n      var test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n\n      return test;\n    };\n  });\n};\n"
  },
  {
    "path": "test/integration/fixtures/simple-ui.fixture.mjs",
    "content": "import Mocha from '../../../lib/mocha.js'\nimport MochaInterface from '../../../lib/interfaces/common.js';\n\nconst Test = Mocha.Test;\nconst EVENT_FILE_PRE_REQUIRE = Mocha.Suite.constants.EVENT_FILE_PRE_REQUIRE;\n\n/**\n * A simple UI that only exposes a single function: test\n */\nfunction SimpleUI(suite) {\n  suite.on(EVENT_FILE_PRE_REQUIRE, function(\n    context,\n    file,\n    mocha\n  ) {\n    const common = MochaInterface(\n      [suite],\n      context\n    );\n\n    context.run = mocha.options.delay && common.runWithSuite(suite);\n\n    /**\n     * Describes a specification or test-case with the given `title`\n     * and callback `fn` acting as a thunk.\n     */\n    context.test = function(title, fn) {\n      const test = new Test(title, fn);\n      test.file = file;\n      suite.addTest(test);\n\n      return test;\n    };\n  });\n};\n\nMocha.interfaces['simple-ui'] = SimpleUI;\n\nexport default SimpleUI;\n"
  },
  {
    "path": "test/integration/fixtures/suite/suite-no-callback.fixture.js",
    "content": "'use strict';\n\ndescribe('a suite without a callback');\n"
  },
  {
    "path": "test/integration/fixtures/suite/suite-returning-value.fixture.js",
    "content": "'use strict';\n\ndescribe('a suite returning a value', function () {\n  return Promise.resolve();\n});\n"
  },
  {
    "path": "test/integration/fixtures/suite/suite-skipped-callback.fixture.js",
    "content": "'use strict';\n\nxdescribe('a pending suite with a callback', function () {});\n"
  },
  {
    "path": "test/integration/fixtures/suite/suite-skipped-no-callback.fixture.js",
    "content": "'use strict';\n\nxdescribe('a pending suite without a callback');\n"
  },
  {
    "path": "test/integration/fixtures/test-for-simple-ui.fixture.js",
    "content": "'use strict';\n\ntest('pass', function () {\n  // pass\n});\n"
  },
  {
    "path": "test/integration/fixtures/timeout-chained-call.fixture.js",
    "content": "'use strict';\n\ndescribe(\"should fail due to suite-level timeout lower than elapsed time of inner test\", function() {\n  it(\"inner test\", async function () {\n    await new Promise((resolve) => {\n      setTimeout(resolve, 100);\n    });\n  }).timeout(110);\n}).timeout(50);\n"
  },
  {
    "path": "test/integration/fixtures/timeout-override.fixture.js",
    "content": "'use strict';\n\ndescribe('timeout override', function() {\n  it('should fail async test due to re-enable', function(done) {\n    this.timeout(0);\n    this.timeout(1);\n    setTimeout(done, 2);\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/timeout.fixture.js",
    "content": "'use strict';\n\ndescribe('timeout', function () {\n  this.timeout(1);\n\n  it('should be honored with sync suites', function () {\n    sleep(2);\n  });\n\n  it('should be honored with async suites', function (done) {\n    sleep(2);\n    done();\n  });\n\n  function sleep (ms) {\n    var start = Date.now();\n    while (start + ms > Date.now());\n  }\n});\n"
  },
  {
    "path": "test/integration/fixtures/uncaught/after-runner.fixture.js",
    "content": "'use strict';\n\ndescribe(\"Uncaught exception after runner's end\", () => {\n  it('test', () => {\n    setTimeout(() => {\n      throw new Error('Unexpected crash');\n    }, 100);\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/uncaught/double.fixture.js",
    "content": "'use strict';\n\n/**\n * This file should only generate one failure per spec despite the fact that\n * Mocha is capable of detecting two distinct exceptions during test execution.\n */\n\nit('fails exactly once when a global error is thrown first', function (done) {\n  process.nextTick(function () {\n    throw new Error('global error');\n  });\n});\n\nit('fails exactly once when a global error is thrown second', function (done) {\n  process.nextTick(function () {\n    done(new Error('test error'));\n  });\n\n  process.nextTick(function () {\n    throw new Error('global error');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/uncaught/fatal.fixture.js",
    "content": "'use strict';\n\ndescribe('fatal uncaught exception', function () {\n  describe('first suite', function () {\n    it('should bail if a successful test asynchronously fails', function (done) {\n      done();\n      process.nextTick(function () {\n        throw new Error('global error');\n      });\n    });\n\n    it('should not actually get run', function () {\n      throw new Error('should never throw - first suite');\n    });\n  });\n  \n  describe('second suite', function () {\n    it('should not actually get run', function () {\n      throw new Error('should never throw - second suite');\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/uncaught/hook.fixture.js",
    "content": "'use strict';\n\ndescribe('uncaught', function () {\n  beforeEach(function (done) {\n    process.nextTick(function () {\n      throw new Error('oh noes');\n    });\n  });\n\n  it('test', function (done) {\n    process.nextTick(function () {\n      throw new Error(\"I'm uncaught!\");\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/uncaught/issue-1327.fixture.js",
    "content": "'use strict';\n\n// we cannot recover gracefully if a Runnable has already passed\n// then fails asynchronously\nit('test 1', function () {\n  process.nextTick(function () {\n    throw new Error('Too bad');\n  });\n});\n\nit('test 2', function () {\n  throw new Error('should not run - test 2');\n});\n\nit('test 3', function () {\n  throw new Error('should not run - test 3');\n});\n"
  },
  {
    "path": "test/integration/fixtures/uncaught/issue-1417.fixture.js",
    "content": "'use strict';\n\n/**\n * This file should generate only one failure per spec for the thrown error.\n * It should not report misleading 'multiple calls to done()'.\n */\n\nit('fails exactly once when a global error is thrown synchronously and done errors', function (done) {\n  setTimeout(function () {\n    done(new Error('test error'));\n  }, 1); // Not 0 - it will 'succeed', but won't test the breaking condition\n\n  throw new Error('sync error a');\n});\n\nit('fails exactly once when a global error is thrown synchronously and done completes', function (done) {\n  setTimeout(function () {\n    done();\n  }, 1); // Not 0 - it will 'succeed', but won't test the breaking condition\n\n  throw new Error('sync error b');\n});\n"
  },
  {
    "path": "test/integration/fixtures/uncaught/listeners.fixture.js",
    "content": "'use strict';\n\nconst assert = require('assert');\nconst mocha = require('../../../../lib/mocha');\n\n// keep this low to avoid warning\nfor (let i = 0; i < 5; i++) {\n  const r = new mocha.Runner(new mocha.Suite('' + i, undefined));\n  r.run();\n}\n\nassert.strictEqual(process.listenerCount('uncaughtException'), 1);\nassert.strictEqual(process.listeners('uncaughtException')[0].name, 'uncaught');\n"
  },
  {
    "path": "test/integration/fixtures/uncaught/pending.fixture.js",
    "content": "'use strict';\n\ndescribe('Uncaught exception within pending test', () => {\n  it('test1', function () { });\n\n  it('test2', function () {\n    process.nextTick(function () {\n      throw new Error('I am uncaught!');\n    });\n    this.skip();\n  });\n\n  it('test3 - should run', function () { });\n  it('test4 - should run', function () { });\n});\n"
  },
  {
    "path": "test/integration/fixtures/uncaught/recover.fixture.js",
    "content": "'use strict';\nconst assert = require('assert');\n\ndescribe('uncaught', function() {\n  var hookOrder = [];\n  it('throw delayed error', (done) => {\n    setTimeout(() => {\n      throw new Error('Whoops!');\n    }, 10)\n    setTimeout(done, 10);\n  });\n  it('should wait 15ms', (done) => {      \n    setTimeout(done, 15);\n  });\n  it('test 3', () => { });\n\n  afterEach(function() {\n    hookOrder.push(this.currentTest.title);\n  });\n  after(function() {\n    hookOrder.push('after');\n    assert.deepEqual(\n      hookOrder,\n      ['throw delayed error', 'should wait 15ms', 'test 3', 'after']\n    );\n    throw new Error('should get upto here and throw');\n  });\n});\n"
  },
  {
    "path": "test/integration/fixtures/uncaught/unhandled.fixture.js",
    "content": "it('should emit an unhandled rejection', async function() {\n  setTimeout(() => {\n    Promise.resolve().then(() => {\n      throw new Error('yikes');\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/glob.spec.js",
    "content": "\"use strict\";\n\nvar exec = require(\"node:child_process\").exec;\nvar path = require(\"node:path\");\n\nvar node = '\"' + process.execPath + '\"';\n\ndescribe(\"globbing\", function () {\n  describe(\"by the shell\", function () {\n    it(\"should find the first level test\", function (done) {\n      testGlob.shouldSucceed(\n        \"./*.js\",\n        function (results) {\n          expect(\n            results.stdout,\n            \"to contain\",\n            '[\"end\",{\"suites\":1,\"tests\":1,\"passes\":1,\"pending\":0,\"failures\":0,',\n          );\n        },\n        done,\n      );\n    });\n\n    it(\"should not find a non-matching pattern\", function (done) {\n      testGlob.shouldFail(\n        \"./*-none.js\",\n        function (results) {\n          expect(\n            results.stderr,\n            \"to contain\",\n            'Error: No test files found: \"./*-none.js\"',\n          );\n        },\n        done,\n      );\n    });\n\n    it(\"should handle multiple non-matching patterns\", function (done) {\n      testGlob.shouldFail(\n        \"./*-none.js ./*-none-twice.js\",\n        function (results) {\n          expect(results.stderr, \"to contain\", \"Error: No test files found\");\n          expect(results.stderr, \"not to contain\", \"*-none\");\n        },\n        done,\n      );\n    });\n\n    it(\"should handle both matching and non-matching patterns in the same command\", function (done) {\n      testGlob.shouldSucceed(\n        \"./*.js ./*-none.js\",\n        function (results) {\n          expect(\n            results.stdout,\n            \"to contain\",\n            '[\"end\",{\"suites\":1,\"tests\":1,\"passes\":1,\"pending\":0,\"failures\":0,',\n          );\n          expect(\n            results.stderr,\n            \"to contain\",\n            \"Warning: Cannot find any files matching pattern\",\n          );\n        },\n        done,\n      );\n    });\n  });\n\n  describe(\"by Mocha\", function () {\n    it(\"should find the first level test\", function (done) {\n      testGlob.shouldSucceed(\n        '\"./*.js\"',\n        function (results) {\n          expect(\n            results.stdout,\n            \"to contain\",\n            '[\"end\",{\"suites\":1,\"tests\":1,\"passes\":1,\"pending\":0,\"failures\":0,',\n          );\n        },\n        done,\n      );\n    });\n\n    it(\"should not find a non-matching pattern\", function (done) {\n      testGlob.shouldFail(\n        '\"./*-none.js\"',\n        function (results) {\n          expect(\n            results.stderr,\n            \"to contain\",\n            'Error: No test files found: \"./*-none.js\"',\n          );\n        },\n        done,\n      );\n    });\n\n    it(\"should handle multiple non-matching patterns\", function (done) {\n      testGlob.shouldFail(\n        '\"./*-none.js\" \"./*-none-twice.js\"',\n        function (results) {\n          expect(results.stderr, \"to contain\", \"Error: No test files found\");\n        },\n        done,\n      );\n    });\n\n    it(\"should handle both matching and non-matching patterns in the same command\", function (done) {\n      testGlob.shouldSucceed(\n        '\"./*.js\" \"./*-none.js\"',\n        function (results) {\n          expect(\n            results.stdout,\n            \"to contain\",\n            '[\"end\",{\"suites\":1,\"tests\":1,\"passes\":1,\"pending\":0,\"failures\":0,',\n          );\n          expect(\n            results.stderr,\n            \"to contain\",\n            \"Warning: Cannot find any files matching pattern\",\n          );\n        },\n        done,\n      );\n    });\n\n    describe(\"double-starred\", function () {\n      it(\"should find the tests on multiple levels\", function (done) {\n        testGlob.shouldSucceed(\n          '\"./**/*.js\"',\n          function (results) {\n            expect(\n              results.stdout,\n              \"to contain\",\n              '[\"end\",{\"suites\":2,\"tests\":2,\"passes\":2,\"pending\":0,\"failures\":0,',\n            );\n          },\n          done,\n        );\n      });\n\n      it(\"should not find a non-matching pattern\", function (done) {\n        testGlob.shouldFail(\n          '\"./**/*-none.js\"',\n          function (results) {\n            expect(\n              results.stderr,\n              \"to contain\",\n              'Error: No test files found: \"./**/*-none.js\"',\n            );\n          },\n          done,\n        );\n      });\n\n      it(\"should handle both matching and non-matching patterns in the same command\", function (done) {\n        testGlob.shouldSucceed(\n          '\"./**/*.js\" \"./**/*-none.js\"',\n          function (results) {\n            expect(\n              results.stdout,\n              \"to contain\",\n              '[\"end\",{\"suites\":2,\"tests\":2,\"passes\":2,\"pending\":0,\"failures\":0,',\n            );\n            expect(\n              results.stderr,\n              \"to contain\",\n              \"Warning: Cannot find any files matching pattern\",\n            );\n          },\n          done,\n        );\n      });\n    });\n  });\n});\n\nvar testGlob = {\n  shouldSucceed: execMochaWith(function shouldNotError(error) {\n    if (error) {\n      throw error;\n    }\n  }),\n\n  shouldFail: execMochaWith(function shouldFailWithStderr(error, stderr) {\n    expect(error && error.message, \"to contain\", stderr);\n  }),\n};\n\nfunction execMochaWith(validate) {\n  return function execMocha(glob, assertOn, done) {\n    exec(\n      node +\n        ' \"' +\n        path.join(\"..\", \"..\", \"..\", \"..\", \"bin\", \"mocha\") +\n        '\" -R json-stream --no-config ' +\n        glob,\n      { cwd: path.join(__dirname, \"fixtures\", \"glob\") },\n      function (error, stdout, stderr) {\n        try {\n          validate(error, stderr);\n          assertOn({ stdout, stderr });\n          done();\n        } catch (assertion) {\n          done(assertion);\n        }\n      },\n    );\n  };\n}\n"
  },
  {
    "path": "test/integration/helpers.js",
    "content": "\"use strict\";\n\nconst escapeRegExp = require(\"escape-string-regexp\");\nconst os = require(\"node:os\");\nconst fs = require(\"node:fs\");\nconst fsP = require(\"node:fs/promises\");\nconst { format } = require(\"node:util\");\nconst path = require(\"node:path\");\nconst Base = require(\"../../lib/reporters/base\");\nconst debug = require(\"debug\")(\"mocha:test:integration:helpers\");\nconst SIGNAL_OFFSET = 128;\n\n/**\n * Path to `mocha` executable\n */\nconst MOCHA_EXECUTABLE = require.resolve(\"../../bin/mocha\");\n\n/**\n * regular expression used for splitting lines based on new line / dot symbol.\n */\nconst SPLIT_DOT_REPORTER_REGEXP = new RegExp(\"[\\\\n\" + Base.symbols.dot + \"]+\");\n\n/**\n * Name of \"default\" fixture file.\n */\nconst DEFAULT_FIXTURE = \"__default__\";\n\n/**\n * Path to \"default\" fixture file\n */\nconst DEFAULT_FIXTURE_PATH = resolveFixturePath(DEFAULT_FIXTURE);\n\n/**\n * Invokes the mocha binary for the given fixture with color output disabled.\n * Accepts an array of additional command line args to pass. The callback is\n * invoked with a summary of the run, in addition to its output. The summary\n * includes the number of passing, pending, and failing tests, as well as the\n * exit code. Useful for testing different reporters.\n *\n * By default, `STDERR` is ignored. Pass `{stdio: 'pipe'}` as `opts` if you\n * want it.\n * Example response:\n * {\n *   pending: 0,\n *   passing: 0,\n *   failing: 1,\n *   code:    1,\n *   output:  '...'\n * }\n *\n * @param {string} fixturePath - Path to fixture .js file\n * @param {string[]|SummarizedResultCallback} args - Extra args to mocha executable\n * @param {SummarizedResultCallback|Object} done - Callback\n * @param {Object} [opts] - Options for `spawn()`\n * @returns {ChildProcess} Subprocess process\n */\nfunction runMocha(fixturePath, args, done, opts = {}) {\n  if (typeof args === \"function\") {\n    opts = done;\n    done = args;\n    args = [];\n  }\n\n  return invokeMocha(\n    [...args, resolveFixturePath(fixturePath)],\n    (err, res) => {\n      if (err) {\n        return done(err);\n      }\n\n      done(null, getSummary(res));\n    },\n    opts,\n  );\n}\n\n/**\n * Invokes the mocha executable for the given fixture using the `json` reporter,\n * calling callback `done` with parsed output.\n *\n * Use when you expect `mocha` _not_ to fail (test failures OK); the output from\n * the `json` reporter--and thus the entire subprocess--must be valid JSON!\n *\n * By default, `STDERR` is ignored. Pass `{stdio: 'pipe'}` as `opts` if you\n * want it.\n * @param {string} fixturePath - Path from `__dirname__`\n * @param {string[]|JSONResultCallback} args - Args to `mocha` or callback\n * @param {JSONResultCallback|Object} done - Callback or options\n * @param {Object} [opts] - Opts for `spawn()`\n * @returns {ChildProcess} Subprocess instance\n */\nfunction runMochaJSON(fixturePath, args, done, opts) {\n  if (typeof args === \"function\") {\n    opts = done;\n    done = args;\n    args = [];\n  }\n\n  return invokeMocha(\n    [...args, \"--reporter\", \"json\", resolveFixturePath(fixturePath)],\n    (err, res) => {\n      if (err) {\n        return done(err);\n      }\n\n      let result;\n      try {\n        result = toJSONResult(res);\n      } catch (err) {\n        return done(\n          new Error(\n            format(\n              \"Failed to parse JSON reporter output. Error:\\n%O\\nResult:\\n%O\",\n              err,\n              res,\n            ),\n          ),\n        );\n      }\n      done(null, result);\n    },\n    opts,\n  );\n}\n\n/**\n *\n * If you need more granular control, try {@link invokeMochaAsync} instead.\n *\n * Like {@link runMocha}, but returns a `Promise`.\n * @param {string} fixturePath - Path to (or name of, or basename of) fixture file\n * @param {Options} [args] - Command-line arguments to the `mocha` executable\n * @param {Object} [opts] - Options for `child_process.spawn`.\n * @returns {Promise<Summary>}\n */\nfunction runMochaAsync(fixturePath, args, opts) {\n  return new Promise((resolve, reject) => {\n    runMocha(\n      fixturePath,\n      args,\n      (err, result) => {\n        if (err) {\n          return reject(err);\n        }\n        resolve(result);\n      },\n      opts,\n    );\n  });\n}\n\n/**\n * Like {@link runMochaJSON}, but returns a `Promise`.\n * @param {string} fixturePath - Path to (or name of, or basename of) fixture file\n * @param {Options} [args] - Command-line args\n * @param {Object} [opts] - Options for `child_process.spawn`\n * @returns {Promise<JSONResult>}\n */\nfunction runMochaJSONAsync(fixturePath, args = [], opts = {}) {\n  return new Promise((resolve, reject) => {\n    runMochaJSON(\n      fixturePath,\n      args,\n      (err, result) => {\n        if (err) {\n          return reject(err);\n        }\n        resolve(result);\n      },\n      opts,\n    );\n  });\n}\n\n/**\n * Coerce output as returned by _spawnMochaWithListeners using JSON reporter into a JSONResult as\n * recognized by our custom unexpected assertions\n * @param {RawResult} result - Raw stdout from Mocha run using JSON reporter\n * @returns {JSONResult}\n */\nfunction toJSONResult(result) {\n  try {\n    return { ...JSON.parse(result.output), ...result };\n  } catch (err) {\n    throw new Error(\n      `Couldn't parse JSON: ${err.message}\\n\\nOriginal result output: ${result.output}`,\n      { cause: err },\n    );\n  }\n}\n\n/**\n * Creates arguments loading a default fixture if none provided\n *\n * - The `--no-color` arg is always used (color output complicates testing `STDOUT`)\n * - Unless `--bail` or `--no-bail` is set, use `--no-bail`.  This enables using\n *   `--bail` (if desired) from the command-line when running our integration\n *   test suites without stepping on the toes of subprocesses.\n * - Unless `--parallel` or `--no-parallel` is set, use `--no-parallel`.  We\n *   assume the test suite is _already_ running in parallel--and there's no point\n *   in trying to run a single test fixture in parallel.\n * - The {@link DEFAULT_FIXTURE} file is used if no arguments are provided.\n *\n * @param {string[]|*} [args] - Arguments to `spawn`\n * @returns {string[]}\n */\nfunction defaultArgs(args = [DEFAULT_FIXTURE_PATH]) {\n  const newArgs = [\n    ...(!args.length ? [DEFAULT_FIXTURE_PATH] : args),\n    \"--no-color\",\n  ];\n  if (!newArgs.some((arg) => /--(no-)?bail/.test(arg))) {\n    newArgs.push(\"--no-bail\");\n  }\n  if (!newArgs.some((arg) => /--(no-)?parallel/.test(arg))) {\n    newArgs.push(\"--no-parallel\");\n  }\n  return newArgs;\n}\n\n/**\n * Invoke `mocha` with default arguments. Calls `done` upon exit. Does _not_ accept a fixture path.\n *\n * Good for testing error conditions. This is low-level, and you likely want\n * {@link runMocha} or even {@link runMochaJSON} if you are running test fixtures.\n *\n * @param {string[]|RawResultCallback} args - Args to `mocha` or callback\n * @param {RawResultCallback|Object} done - Callback or options\n * @param {Object} [opts] - Options\n * @returns {ChildProcess}\n */\nfunction invokeMocha(args, done, opts = {}) {\n  if (typeof args === \"function\") {\n    opts = done;\n    done = args;\n    args = [];\n  }\n  return createSubprocess(\n    defaultArgs([MOCHA_EXECUTABLE].concat(args)),\n    done,\n    opts,\n  );\n}\n\n/**\n * Invokes the mocha binary with the given arguments. Returns the\n * child process and a promise for the results of running the\n * command. The promise resolves when the child process exits. The\n * result includes the **raw** string output, as well as exit code.\n *\n * By default, `STDERR` is ignored. Pass `{stdio: 'pipe'}` as `opts` if you\n * want it as part of the result output.\n *\n * @param {string[]} args - Array of args\n * @param {Object} [opts] - Opts for `spawn()`\n * @returns {[import('child_process').ChildProcess,Promise<RawResult>]} A tuple of process and result promise\n */\nfunction invokeMochaAsync(args, opts = {}) {\n  let mochaProcess;\n  const resultPromise = new Promise((resolve, reject) => {\n    mochaProcess = createSubprocess(\n      defaultArgs([MOCHA_EXECUTABLE].concat(args)),\n      (err, result) => {\n        if (err) {\n          reject(err);\n        } else {\n          resolve(result);\n        }\n      },\n      opts,\n    );\n  });\n  return [mochaProcess, resultPromise];\n}\n\n/**\n * Invokes subprocess with currently-running `node`.\n *\n * Useful for running certain fixtures as scripts.\n *\n * @param {string[]|RawResultCallback} args - Args to `mocha` or callback\n * @param {RawResultCallback|Object} done - Callback or options\n * @param {Object} [opts] - Options\n * @returns {ChildProcess}\n */\nfunction invokeNode(args, done, opts = {}) {\n  if (typeof args === \"function\") {\n    opts = done;\n    done = args;\n    args = [];\n  }\n  return createSubprocess(args, done, opts);\n}\n\n/**\n * Creates a subprocess and calls callback `done` when it has exited.\n *\n * This is the most low-level function and should _not_ be exported.\n *\n * @param {string[]} args - Path to executable and arguments\n * @param {RawResultCallback} done - Callback\n * @param {Object|string} [opts] - Options to `child_process` or 'pipe' for shortcut to `{stdio: pipe}`\n * @param {boolean} [opts.fork] - If `true`, use `child_process.fork` instead\n * @returns {import('child_process').ChildProcess}\n */\nfunction createSubprocess(args, done, opts = {}) {\n  let output = \"\";\n\n  if (opts === \"pipe\") {\n    opts = { stdio: [\"inherit\", \"pipe\", \"pipe\"] };\n  }\n\n  const env = { ...process.env };\n  // prevent DEBUG from borking STDERR when piping, unless explicitly set via `opts`\n  delete env.DEBUG;\n\n  opts = {\n    cwd: process.cwd(),\n    stdio: [\"inherit\", \"pipe\", \"inherit\"],\n    env,\n    ...opts,\n  };\n\n  /**\n   * @type {import('child_process').ChildProcess}\n   */\n  let mocha;\n  if (opts.fork) {\n    const { fork } = require(\"node:child_process\");\n    // to use ipc, we need a fourth item in `stdio` array.\n    // opts.stdio is usually an array of length 3, but it could be smaller\n    // (pad with `null`)\n    for (let i = opts.stdio.length; i < 4; i++) {\n      opts.stdio.push(i === 3 ? \"ipc\" : null);\n    }\n    debug(\"forking: %s\", args.join(\" \"));\n    mocha = fork(args[0], args.slice(1), opts);\n  } else {\n    const { spawn } = require(\"node:child_process\");\n    debug(\"spawning: %s\", [process.execPath].concat(args).join(\" \"));\n    mocha = spawn(process.execPath, args, opts);\n  }\n\n  const listener = (data) => {\n    output += data;\n  };\n\n  mocha.stdout.on(\"data\", listener);\n  if (mocha.stderr) {\n    mocha.stderr.on(\"data\", listener);\n  }\n  mocha.on(\"error\", done);\n\n  mocha.on(\"close\", (code) => {\n    done(null, {\n      output,\n      code,\n      args,\n      command: args.join(\" \"),\n    });\n  });\n\n  /**\n   * Emulate node's exit code for fatal signal. Allows tests to see the same\n   * exit code as the mocha cli.\n   */\n  mocha.on(\"exit\", (code, signal) => {\n    if (signal) {\n      mocha.exitCode =\n        SIGNAL_OFFSET +\n        (typeof signal == \"string\" ? os.constants.signals[signal] : signal);\n    }\n  });\n\n  return mocha;\n}\n\n/**\n * Given a fixture \"name\" (a relative path from `${__dirname}/fixtures`),\n * with or without extension, or an absolute path, resolve a fixture filepath\n * @param {string} fixture - Fixture name\n * @returns {string} Resolved filepath\n */\nfunction resolveFixturePath(fixture) {\n  if (\n    path.extname(fixture) !== \".js\" &&\n    path.extname(fixture) !== \".mjs\" &&\n    path.extname(fixture) !== \".ts\"\n  ) {\n    fixture += \".fixture.js\";\n  }\n  return path.isAbsolute(fixture)\n    ? fixture\n    : path.resolve(__dirname, \"fixtures\", fixture);\n}\n\n/**\n * Parses some `mocha` reporter output and returns a summary based on the \"epilogue\"\n * @param {string} res - Typically output of STDOUT from the 'spec' reporter\n * @returns {Summary}\n */\nfunction getSummary(res) {\n  return [\"passing\", \"pending\", \"failing\"].reduce((summary, type) => {\n    const pattern = new RegExp(`  (\\\\d+) ${type}\\\\s`);\n    const match = pattern.exec(res.output);\n    summary[type] = match ? parseInt(match, 10) : 0;\n\n    return summary;\n  }, res);\n}\n\n/**\n * Runs the mocha executable in watch mode calls `change` and returns the\n * raw result.\n *\n * The function starts mocha with the given arguments and `--watch` and\n * waits until the first test run has completed. Then it calls `change`\n * and waits until the second test run has been completed. Mocha is\n * killed and the result is returned.\n *\n * On Windows, this will call `child_process.fork()` instead of `spawn()`.\n *\n * **Exit code will always be 0**\n * @param {string[]} args - Array of argument strings\n * @param {object|string} opts - If a `string`, then `cwd`, otherwise options for `child_process`\n * @param {Function} change - A potentially `Promise`-returning callback to execute which will change a watched file\n * @returns {Promise<RawResult>}\n */\nasync function runMochaWatchAsync(args, opts, change) {\n  if (typeof opts === \"string\") {\n    opts = { cwd: opts };\n  }\n  opts = {\n    sleepMs: 2000,\n    stdio: [\"pipe\", \"pipe\", \"inherit\"],\n    ...opts,\n    fork: process.platform === \"win32\",\n  };\n  const [mochaProcess, resultPromise] = invokeMochaAsync(\n    [...args, \"--watch\"],\n    opts,\n  );\n  await sleep(opts.sleepMs);\n  await change(mochaProcess);\n  await sleep(opts.sleepMs);\n\n  if (\n    !(mochaProcess.connected\n      ? mochaProcess.send(\"SIGINT\")\n      : mochaProcess.kill(\"SIGINT\"))\n  ) {\n    throw new Error(\"failed to send signal to subprocess\");\n  }\n\n  const res = await resultPromise;\n\n  // we kill the process with `SIGINT`, so it will always appear as \"failed\" to our\n  // custom assertions (a non-zero exit code 130). just change it to 0.\n  res.code = 0;\n  return res;\n}\n\n/**\n * Runs the mocha executable in watch mode calls `change` and returns the\n * JSON result.\n *\n * The function starts mocha with the given arguments and `--watch` and\n * waits until the first test run has completed. Then it calls `change`\n * and waits until the second test run has been completed. Mocha is\n * killed and the result is returned.\n *\n * On Windows, this will call `child_process.fork()` instead of `spawn()`.\n *\n * **Exit code will always be 0**\n * @param {string[]} args - Array of argument strings\n * @param {object|string} opts - If a `string`, then `cwd`, otherwise options for `child_process`\n * @param {Function} change - A potentially `Promise`-returning callback to execute which will change a watched file\n * @returns {Promise<JSONResult>}\n */\nasync function runMochaWatchJSONAsync(args, opts, change) {\n  const res = await runMochaWatchAsync(\n    [...args, \"--reporter\", \"json\"],\n    opts,\n    change,\n  );\n  return (\n    res.output\n      // eslint-disable-next-line no-control-regex\n      .replace(/\\u001b\\[\\?25./g, \"\")\n      .split(\"\\u001b[2K\")\n      .filter((x) => x)\n      .map((x) => JSON.parse(x))\n  );\n}\n\nconst touchRef = new Date();\n\n/**\n * Synchronously touch a file. Creates\n * the file and all its parent directories if necessary.\n *\n * @param {string} filepath - Path to file\n */\nfunction touchFile(filepath) {\n  fs.mkdirSync(path.dirname(filepath), { recursive: true });\n  try {\n    fs.utimesSync(filepath, touchRef, touchRef);\n  } catch {\n    const fd = fs.openSync(filepath, \"a\");\n    fs.closeSync(fd);\n  }\n}\n\n/**\n * Synchronously replace all substrings matched by `pattern` with\n * `replacement` in the contents of file at `filepath`\n *\n * @param {string} filepath - Path to file\n * @param {RegExp|string} pattern - Search pattern\n * @param {string} replacement - Replacement\n */\nfunction replaceFileContents(filepath, pattern, replacement) {\n  const contents = fs.readFileSync(filepath, \"utf-8\");\n  const newContents = contents.replace(pattern, replacement);\n  fs.writeFileSync(filepath, newContents, \"utf-8\");\n}\n\n/**\n * Synchronously copy a fixture to the given destination file path.\n * Creates parent directories of the destination path if necessary.\n *\n * @param {string} fixtureName - Relative path from __dirname to fixture, or absolute path\n * @param {*} dest - Destination directory\n */\nfunction copyFixture(fixtureName, dest) {\n  const fixtureSource = resolveFixturePath(fixtureName);\n  fs.mkdirSync(path.dirname(dest), { recursive: true });\n  fs.cpSync(fixtureSource, dest);\n}\n\n/**\n * Creates a temporary directory\n * @returns {Promise<CreateTempDirResult>} Temp dir path and cleanup function\n */\nconst createTempDir = async () => {\n  const dirpath = await fsP.mkdtemp(path.join(os.tmpdir(), \"mocha-\"));\n  return {\n    dirpath,\n    removeTempDir: async () => {\n      if (!process.env.MOCHA_TEST_KEEP_TEMP_DIRS) {\n        return fs.rmSync(dirpath, { recursive: true, force: true });\n      }\n    },\n  };\n};\n\n/**\n * Waits for `time` ms.\n * @param {number} time - Time in ms\n * @returns {Promise<void>}\n */\nfunction sleep(time) {\n  return new Promise((resolve) => {\n    setTimeout(resolve, time);\n  });\n}\n\nmodule.exports = {\n  DEFAULT_FIXTURE,\n  SPLIT_DOT_REPORTER_REGEXP,\n  copyFixture,\n\n  createTempDir,\n  escapeRegExp,\n  getSummary,\n  invokeMocha,\n  invokeMochaAsync,\n  invokeNode,\n  replaceFileContents,\n  resolveFixturePath,\n  runMocha,\n  runMochaAsync,\n  runMochaJSON,\n  runMochaJSONAsync,\n  runMochaWatchAsync,\n  runMochaWatchJSONAsync,\n  sleep,\n  toJSONResult,\n  touchFile,\n};\n\n/**\n * A summary of a `mocha` run\n * @typedef {Object} Summary\n * @property {number} passing - Number of passing tests\n * @property {number} pending - Number of pending tests\n * @property {number} failing - Number of failing tests\n */\n\n/**\n * An unprocessed result from a `mocha` run\n * @typedef {Object} RawResult\n * @property {string} output - Process output; _usually_ just stdout\n * @property {number?} code - Exit code or `null` in some circumstances\n * @property {string[]} args - Array of program arguments\n * @property {string} command - Complete command executed\n */\n\n/**\n * The result of a `mocha` run using `json` reporter\n * @typedef {Object} JSONResult\n * @property {Object} stats - Statistics\n * @property {Object[]} failures - Failure information\n * @property {number?} code - Exit code or `null` in some circumstances\n * @property {string} command - Complete command executed\n */\n\n/**\n * The result of a `mocha` run using `spec` reporter (parsed)\n * @typedef {Summary} SummarizedResult\n * @property {string} output - Process output; _usually_ just stdout\n * @property {number?} code - Exit code or `null` in some circumstances\n */\n\n/**\n * Callback function run when `mocha` process execution complete\n * @callback RawResultCallback\n * @param {Error?} err - Error, if any\n * @param {RawResult} result - Result of `mocha` run\n * @returns {void}\n */\n\n/**\n * Callback function run when `mocha` process execution complete\n * @callback JSONResultCallback\n * @param {Error?} err - Error, if any\n * @param {JSONResult} result - Result of `mocha` run\n * @returns {void}\n */\n\n/**\n * Callback function run when `mocha` process execution complete\n * @callback SummarizedResultCallback\n * @param {Error?} err - Error, if any\n * @param {SummarizedResult} result - Result of `mocha` run\n * @returns {void}\n */\n\n/**\n * Return value when calling {@link createTempDir}\n *\n * @typedef {Object} CreateTempDirResult\n * @property {string} dirname - Path of new temp dir\n * @property {RemoveTempDirCallback} removeTempDir - \"Cleanup\" function to remove temp dir\n */\n\n/**\n * Cleanup function to remove temp dir\n * @callback RemoveTempDirCallback\n * @returns {void}\n */\n"
  },
  {
    "path": "test/integration/hook-err.spec.js",
    "content": "\"use strict\";\nconst {\n  runMocha,\n  runMochaJSON,\n  runMochaJSONAsync,\n  SPLIT_DOT_REPORTER_REGEXP,\n} = require(\"./helpers\");\nconst { bang } = require(\"../../lib/reporters/base\").symbols;\n\ndescribe(\"hook error handling\", function () {\n  let lines;\n\n  describe(\"before hook error\", function () {\n    before(run(\"hooks/before-hook-error.fixture.js\"));\n    it(\"should verify results\", function () {\n      expect(lines, \"to equal\", [\"before\", bang + \"test 3\"]);\n    });\n  });\n\n  describe(\"before hook error tip\", function () {\n    before(run(\"hooks/before-hook-error-tip.fixture.js\", onlyErrorTitle()));\n    it(\"should verify results\", function () {\n      expect(lines, \"to equal\", [\n        \"1) spec 2\",\n        '\"before all\" hook for \"skipped\":',\n      ]);\n    });\n  });\n\n  describe(\"before hook root error\", function () {\n    it(\"should verify results\", function (done) {\n      runMochaJSON(\"hooks/before-hook-root-error\", [], (err, res) => {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have failed with error\", \"before hook root error\")\n          .and(\"to have failed test\", '\"before all\" hook in \"{root}\"')\n          .and(\"to have passed test count\", 0);\n        done();\n      });\n    });\n  });\n\n  describe(\"before hook nested error\", function () {\n    it(\"should verify results\", function (done) {\n      runMochaJSON(\"hooks/before-hook-nested-error\", [], (err, res) => {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have failed with error\", \"before hook nested error\")\n          .and(\n            \"to have failed test\",\n            '\"before all\" hook for \"it nested - this title should be used\"',\n          )\n          .and(\"to have passed test count\", 1)\n          .and(\"to have passed test\", \"should pass\");\n        done();\n      });\n    });\n  });\n\n  describe(\"before hook deepnested error\", function () {\n    it(\"should verify results\", function (done) {\n      runMochaJSON(\"hooks/before-hook-deepnested-error\", [], (err, res) => {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have failed with error\", \"before hook nested error\")\n          .and(\n            \"to have failed test\",\n            '\"before all\" hook in \"spec 2 nested - this title should be used\"',\n          )\n          .and(\"to have passed test count\", 1)\n          .and(\"to have passed test\", \"should pass\");\n        done();\n      });\n    });\n  });\n\n  describe(\"before each hook error\", function () {\n    before(run(\"hooks/before-each-hook-error.fixture.js\"));\n    it(\"should verify results\", function () {\n      expect(lines, \"to equal\", [\"before\", bang + \"test 3\"]);\n    });\n  });\n\n  describe(\"after hook error\", function () {\n    before(run(\"hooks/after-hook-error.fixture.js\"));\n    it(\"should verify results\", function () {\n      expect(lines, \"to equal\", [\"test 1\", \"test 2\", \"after\", bang + \"test 3\"]);\n    });\n  });\n\n  describe(\"after hook nested error\", function () {\n    it(\"should verify results\", function (done) {\n      runMochaJSON(\"hooks/after-hook-nested-error\", [], (err, res) => {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have failed with error\", \"after hook nested error\")\n          .and(\n            \"to have failed test\",\n            '\"after all\" hook for \"it nested - this title should be used\"',\n          )\n          .and(\"to have passed test count\", 3)\n          .and(\n            \"to have passed test order\",\n            \"should pass\",\n            \"it nested - this title should be used\",\n            \"it nested - not this title\",\n          );\n        done();\n      });\n    });\n  });\n\n  describe(\"after hook deepnested error\", function () {\n    it(\"should verify results\", function (done) {\n      runMochaJSON(\"hooks/after-hook-deepnested-error\", [], (err, res) => {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have failed with error\", \"after hook nested error\")\n          .and(\n            \"to have failed test\",\n            '\"after all\" hook in \"spec 2 nested - this title should be used\"',\n          )\n          .and(\"to have passed test count\", 2)\n          .and(\n            \"to have passed test order\",\n            \"should pass\",\n            \"it nested - this title should not be used\",\n          );\n        done();\n      });\n    });\n  });\n\n  describe(\"after each hook error\", function () {\n    before(run(\"hooks/after-each-hook-error.fixture.js\"));\n    it(\"should verify results\", function () {\n      expect(lines, \"to equal\", [\"test 1\", \"after\", bang + \"test 3\"]);\n    });\n  });\n\n  describe(\"multiple hook errors\", function () {\n    before(run(\"hooks/multiple-hook-error.fixture.js\"));\n    it(\"should verify results\", function () {\n      expect(lines, \"to equal\", [\n        \"root before\",\n        \"1-1 before\",\n        \"root before each\",\n        \"1 before each\",\n        \"1-1 before each\",\n        bang + \"1-1 after each\",\n        \"1 after each\",\n        \"root after each\",\n        \"1-1 after\",\n        bang + \"1-2 before\",\n        \"root before each\",\n        \"1 before each\",\n        \"1-2 before each\",\n        \"1-2 test 1\",\n        \"1-2 after each\",\n        bang + \"1 after each\",\n        \"root after each\",\n        \"1-2 after\",\n        \"1 after\",\n        \"2-1 before\",\n        \"root before each\",\n        \"2 before each\",\n        bang + \"2 after each\",\n        bang + \"root after each\",\n        \"2-1 after\",\n        \"2 after\",\n        \"root after\",\n      ]);\n    });\n  });\n\n  describe(\"async - before hook error\", function () {\n    before(run(\"hooks/before-hook-async-error.fixture.js\"));\n    it(\"should verify results\", function () {\n      expect(lines, \"to equal\", [\"before\", bang + \"test 3\"]);\n    });\n  });\n\n  describe(\"async - before hook error tip\", function () {\n    before(\n      run(\"hooks/before-hook-async-error-tip.fixture.js\", onlyErrorTitle()),\n    );\n    it(\"should verify results\", function () {\n      expect(lines, \"to equal\", [\n        \"1) spec 2\",\n        '\"before all\" hook for \"skipped\":',\n      ]);\n    });\n  });\n\n  describe(\"async - before each hook error\", function () {\n    before(run(\"hooks/before-each-hook-async-error.fixture.js\"));\n    it(\"should verify results\", function () {\n      expect(lines, \"to equal\", [\"before\", bang + \"test 3\"]);\n    });\n  });\n\n  describe(\"async - after hook error\", function () {\n    before(run(\"hooks/after-hook-async-error.fixture.js\"));\n    it(\"should verify results\", function () {\n      expect(lines, \"to equal\", [\"test 1\", \"test 2\", \"after\", bang + \"test 3\"]);\n    });\n  });\n\n  describe(\"async - after each hook error\", function () {\n    before(run(\"hooks/after-each-hook-async-error.fixture.js\"));\n    it(\"should verify results\", function () {\n      expect(lines, \"to equal\", [\"test 1\", \"after\", bang + \"test 3\"]);\n    });\n  });\n\n  describe(\"async - multiple hook errors\", function () {\n    before(run(\"hooks/multiple-hook-async-error.fixture.js\"));\n    it(\"should verify results\", function () {\n      expect(lines, \"to equal\", [\n        \"root before\",\n        \"1-1 before\",\n        \"root before each\",\n        \"1 before each\",\n        \"1-1 before each\",\n        bang + \"1-1 after each\",\n        \"1 after each\",\n        \"root after each\",\n        \"1-1 after\",\n        bang + \"1-2 before\",\n        \"root before each\",\n        \"1 before each\",\n        \"1-2 before each\",\n        \"1-2 test 1\",\n        \"1-2 after each\",\n        bang + \"1 after each\",\n        \"root after each\",\n        \"1-2 after\",\n        \"1 after\",\n        \"2-1 before\",\n        \"root before each\",\n        \"2 before each\",\n        bang + \"2 after each\",\n        bang + \"root after each\",\n        \"2-1 after\",\n        \"2 after\",\n        \"root after\",\n      ]);\n    });\n  });\n\n  describe('\"this.test.error()-style failure', function () {\n    it(\"should fail the associated test\", async function () {\n      return expect(\n        runMochaJSONAsync(\"hooks/after-each-this-test-error\"),\n        \"when fulfilled\",\n        \"to have failed\",\n      ).and(\n        \"when fulfilled\",\n        \"to have failed test\",\n        'fail the test from the \"after each\" hook should fail',\n      );\n    });\n  });\n\n  describe(\"--fail-hook-affected-tests\", function () {\n    describe(\"error in `before` hook\", function () {\n      it(\"should fail all affected tests\", function (done) {\n        runMochaJSON(\n          \"hooks/before-hook-error-with-fail-affected\",\n          [\"--fail-hook-affected-tests\"],\n          (err, res) => {\n            if (err) {\n              return done(err);\n            }\n            expect(res, \"to have failed\")\n              .and(\"to have failed test count\", 3)\n              .and(\"to have failed test\", '\"before all\" hook for \"test 1\"')\n              .and(\"to have failed test\", \"test 1\")\n              .and(\"to have failed test\", \"test 2\")\n              .and(\"to have passed test count\", 1)\n              .and(\"to have passed test\", \"test 3\");\n            done();\n          },\n        );\n      });\n    });\n\n    describe(\"error in `beforeEach` hook\", function () {\n      it(\"should fail all affected tests\", function (done) {\n        runMochaJSON(\n          \"hooks/before-each-hook-error-with-fail-affected\",\n          [\"--fail-hook-affected-tests\"],\n          (err, res) => {\n            if (err) {\n              return done(err);\n            }\n            expect(res, \"to have failed\")\n              .and(\"to have failed test count\", 3)\n              .and(\"to have failed test\", '\"before each\" hook for \"test 1\"')\n              .and(\"to have failed test\", \"test 1\")\n              .and(\"to have failed test\", \"test 2\")\n              .and(\"to have passed test count\", 1)\n              .and(\"to have passed test\", \"test 3\");\n            done();\n          },\n        );\n      });\n    });\n\n    describe(\"non-Error thrown in `before` hook\", function () {\n      it(\"should handle null, undefined, and other non-Error values\", function (done) {\n        runMochaJSON(\n          \"hooks/before-hook-throw-non-error\",\n          [\"--fail-hook-affected-tests\"],\n          (err, res) => {\n            if (err) {\n              return done(err);\n            }\n            expect(res, \"to have failed\")\n              .and(\"to have failed test count\", 8) // 4 hooks + 4 affected tests\n              .and(\"to have failed test\", \"test 1\")\n              .and(\"to have failed test\", \"test 2\")\n              .and(\"to have failed test\", \"test 3\")\n              .and(\"to have failed test\", \"test 4\");\n            done();\n          },\n        );\n      });\n    });\n\n    describe(\"non-Error thrown in `beforeEach` hook\", function () {\n      it(\"should handle null, undefined, and other non-Error values\", function (done) {\n        runMochaJSON(\n          \"hooks/before-each-hook-throw-non-error\",\n          [\"--fail-hook-affected-tests\"],\n          (err, res) => {\n            if (err) {\n              return done(err);\n            }\n            expect(res, \"to have failed\")\n              .and(\"to have failed test count\", 6) // 3 hooks + 3 affected tests\n              .and(\"to have failed test\", \"test 1\")\n              .and(\"to have failed test\", \"test 2\")\n              .and(\"to have failed test\", \"test 3\");\n            done();\n          },\n        );\n      });\n    });\n  });\n\n  function run(fnPath, outputFilter) {\n    return (done) =>\n      runMocha(fnPath, [\"--reporter\", \"dot\"], (err, res) => {\n        expect(err, \"to be falsy\");\n\n        lines = res.output\n          .split(SPLIT_DOT_REPORTER_REGEXP)\n          .map((line) => line.trim())\n          .filter(outputFilter || onlyConsoleOutput());\n\n        done();\n      });\n  }\n});\n\nfunction onlyConsoleOutput() {\n  let foundSummary = false;\n  return (line) => {\n    if (!foundSummary) {\n      foundSummary = !!/\\(\\d+ms\\)/.exec(line);\n    }\n    return !foundSummary && line.length > 0;\n  };\n}\n\nfunction onlyErrorTitle() {\n  let foundErrorTitle = false;\n  let foundError = false;\n  return (line) => {\n    if (!foundErrorTitle) {\n      foundErrorTitle = !!/^1\\)/.exec(line);\n    }\n    if (!foundError) {\n      foundError = /Error:/.exec(line);\n    }\n    return foundErrorTitle && !foundError;\n  };\n}\n"
  },
  {
    "path": "test/integration/hooks.spec.js",
    "content": "\"use strict\";\n\nvar assert = require(\"node:assert\");\nvar runMocha = require(\"./helpers\").runMocha;\nvar runMochaJSON = require(\"./helpers\").runMochaJSON;\nvar SPLIT_DOT_REPORTER_REGEXP = require(\"./helpers\").SPLIT_DOT_REPORTER_REGEXP;\nvar args = [\"--reporter\", \"dot\"];\n\ndescribe(\"hooks\", function () {\n  it(\"are ran in correct order\", function (done) {\n    runMocha(\"cascade.fixture.js\", args, function (err, res) {\n      var lines, expected;\n\n      if (err) {\n        done(err);\n        return;\n      }\n\n      lines = res.output\n        .split(SPLIT_DOT_REPORTER_REGEXP)\n        .map(function (line) {\n          return line.trim();\n        })\n        .filter(function (line) {\n          return line.length;\n        })\n        .slice(0, -1);\n\n      expected = [\n        \"before one\",\n        \"before two\",\n        \"before three\",\n        \"before each one\",\n        \"before each two\",\n        \"before each three\",\n        \"TEST three\",\n        \"after each three\",\n        \"after each two\",\n        \"after each one\",\n        \"after three\",\n        \"after two\",\n        \"after one\",\n      ];\n\n      expected.forEach(function (line, i) {\n        assert.strictEqual(lines[i], line);\n      });\n\n      assert.strictEqual(res.code, 0);\n      done();\n    });\n  });\n\n  it(\"current test title of all hooks\", function (done) {\n    runMochaJSON(\"current-test-title.fixture.js\", [], function (err, res) {\n      if (err) {\n        return done(err);\n      }\n      expect(res, \"to have passed\")\n        .and(\"to have passed test count\", 3)\n        .and(\"to have passed test order\", \"test1 B\", \"test1 C\", \"test2 C\");\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/init.spec.js",
    "content": "\"use strict\";\n\nvar fs = require(\"node:fs\");\nvar rimraf = require(\"rimraf\");\nvar invokeMocha = require(\"./helpers\").invokeMocha;\nvar path = require(\"node:path\");\nvar os = require(\"node:os\");\n\ndescribe(\"init command\", function () {\n  var tmpdir;\n\n  beforeEach(function () {\n    tmpdir = path.join(os.tmpdir(), \"mocha-init\");\n    try {\n      fs.mkdirSync(tmpdir);\n    } catch {\n      /* empty */\n    }\n    expect(fs.existsSync(tmpdir), \"to be true\");\n  });\n\n  afterEach(function () {\n    try {\n      rimraf.sync(tmpdir);\n    } catch {\n      /* empty */\n    }\n  });\n\n  describe(\"when no path is supplied\", function () {\n    it(\"should fail\", function (done) {\n      invokeMocha(\n        [\"init\"],\n        function (err, result) {\n          if (err) {\n            return done(err);\n          }\n          expect(\n            result,\n            \"to have failed with output\",\n            /not enough non-option arguments/i,\n          );\n          done();\n        },\n        { stdio: \"pipe\" },\n      );\n    });\n    it(\"should not throw\", function (done) {\n      invokeMocha(\n        [\"init\"],\n        function (err, result) {\n          if (err) {\n            return done(err);\n          }\n          expect(result, \"to have failed\").and(\"not to satisfy\", {\n            output: /throw/i,\n          });\n          done();\n        },\n        { stdio: \"pipe\" },\n      );\n    });\n  });\n\n  it(\"should create some files in the dest dir\", function (done) {\n    invokeMocha(\n      [\"init\", tmpdir],\n      function (err, result) {\n        if (err) {\n          return done(err);\n        }\n        expect(result, \"to have succeeded\");\n        expect(fs.existsSync(path.join(tmpdir, \"mocha.css\")), \"to be true\");\n        expect(fs.existsSync(path.join(tmpdir, \"mocha.js\")), \"to be true\");\n        expect(fs.existsSync(path.join(tmpdir, \"tests.spec.js\")), \"to be true\");\n        expect(fs.existsSync(path.join(tmpdir, \"index.html\")), \"to be true\");\n        done();\n      },\n      { stdio: \"pipe\" },\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/invalid-arguments.spec.js",
    "content": "\"use strict\";\n\nvar invokeMocha = require(\"./helpers\").invokeMocha;\n\ndescribe(\"invalid arguments\", function () {\n  describe(\"when argument is missing required value\", function () {\n    it(\"should exit with failure\", function (done) {\n      invokeMocha(\n        [\"--ui\"],\n        function (err, result) {\n          if (err) {\n            return done(err);\n          }\n          expect(result, \"to have failed\");\n          expect(result.output, \"to match\", /not enough arguments/i);\n          done();\n        },\n        { stdio: \"pipe\" },\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/multiple-done.spec.js",
    "content": "\"use strict\";\n\nvar runMochaJSON = require(\"./helpers\").runMochaJSON;\nvar invokeMocha = require(\"./helpers\").invokeMocha;\nvar MULTIPLE_DONE = require(\"../../lib/error-constants\").constants\n  .MULTIPLE_DONE;\n\ndescribe(\"multiple calls to done()\", function () {\n  var res;\n  describe(\"from a spec\", function () {\n    before(function (done) {\n      runMochaJSON(\"multiple-done\", function (err, result) {\n        res = result;\n        done(err);\n      });\n    });\n\n    it(\"results in failure\", function () {\n      expect(res, \"to have failed test count\", 1)\n        .and(\"to have passed test count\", 1)\n        .and(\"to have pending test count\", 0)\n        .and(\"to have failed\");\n    });\n\n    it(\"throws a descriptive error\", function () {\n      expect(res, \"to have failed with error\", {\n        message:\n          /done\\(\\) called multiple times in test <should fail in a test-case> \\(of root suite\\) of file.+multiple-done\\.fixture\\.js/,\n        code: MULTIPLE_DONE,\n      });\n    });\n  });\n\n  describe(\"with error passed on second call\", function () {\n    before(function (done) {\n      runMochaJSON(\"multiple-done-with-error\", function (err, result) {\n        res = result;\n        done(err);\n      });\n    });\n\n    it(\"results in failure\", function () {\n      expect(res, \"to have failed test count\", 1)\n        .and(\"to have passed test count\", 1)\n        .and(\"to have pending test count\", 0)\n        .and(\"to have failed\");\n    });\n\n    it(\"should throw a descriptive error\", function () {\n      expect(res, \"to have failed with error\", {\n        message:\n          /done\\(\\) called multiple times in test <should fail in a test-case> \\(of root suite\\) of file.+multiple-done-with-error\\.fixture\\.js; in addition, done\\(\\) received error: Error: second error/,\n        code: MULTIPLE_DONE,\n      });\n    });\n  });\n\n  describe(\"with multiple specs\", function () {\n    before(function (done) {\n      runMochaJSON(\"multiple-done-specs\", function (err, result) {\n        res = result;\n        done(err);\n      });\n    });\n\n    it(\"results in failure\", function () {\n      expect(res, \"to have failed test count\", 1)\n        .and(\"to have passed test count\", 2)\n        .and(\"to have pending test count\", 0)\n        .and(\"to have failed\");\n    });\n\n    it(\"correctly attributes the error\", function () {\n      expect(res.failures[0], \"to satisfy\", {\n        fullTitle: \"suite test1\",\n        err: {\n          message:\n            /done\\(\\) called multiple times in test <suite test1> of file.+multiple-done-specs\\.fixture\\.js/,\n          code: MULTIPLE_DONE,\n        },\n      });\n    });\n  });\n\n  describe(\"from a before hook\", function () {\n    before(function (done) {\n      runMochaJSON(\"multiple-done-before\", function (err, result) {\n        res = result;\n        done(err);\n      });\n    });\n\n    it(\"results in failure\", function () {\n      expect(res, \"to have failed test count\", 1)\n        .and(\"to have passed test count\", 1)\n        .and(\"to have pending test count\", 0)\n        .and(\"to have failed\");\n    });\n\n    it(\"correctly attributes the error\", function () {\n      expect(res.failures[0], \"to satisfy\", {\n        fullTitle: 'suite1 \"before all\" hook in \"suite1\"',\n        err: {\n          message:\n            /done\\(\\) called multiple times in hook <suite1 \"before all\" hook in \"suite1\"> of file.+multiple-done-before\\.fixture\\.js/,\n        },\n      });\n    });\n  });\n\n  describe('from a \"before each\" hook', function () {\n    before(function (done) {\n      runMochaJSON(\"multiple-done-before-each\", function (err, result) {\n        res = result;\n        done(err);\n      });\n    });\n\n    it(\"results in a failure\", function () {\n      expect(res, \"to have failed test count\", 2)\n        .and(\"to have passed test count\", 2)\n        .and(\"to have pending test count\", 0)\n        .and(\"to have exit code\", 2);\n    });\n\n    it(\"correctly attributes the errors\", function () {\n      expect(res.failures[0], \"to equal\", res.failures[1]).and(\"to satisfy\", {\n        fullTitle: 'suite1 \"before each\" hook in \"suite1\"',\n        err: {\n          message:\n            /done\\(\\) called multiple times in hook <suite1 \"before each\" hook in \"suite1\"> of file.+multiple-done-before-each\\.fixture\\.js/,\n          multiple: [\n            {\n              code: \"ERR_MOCHA_MULTIPLE_DONE\",\n            },\n          ],\n        },\n      });\n    });\n  });\n\n  describe(\"when done() called asynchronously\", function () {\n    before(function (done) {\n      // we can't be sure that mocha won't fail with an uncaught exception here, which would cause any JSON\n      // output to be befouled; we need to run \"raw\" and capture STDERR\n      invokeMocha(\n        require.resolve(\"./fixtures/multiple-done-async.fixture.js\"),\n        function (err, result) {\n          res = result;\n          done(err);\n        },\n        \"pipe\",\n      );\n    });\n\n    it(\"results in error\", function () {\n      expect(res, \"to satisfy\", {\n        code: expect.it(\"to be greater than\", 0),\n        output:\n          /done\\(\\) called multiple times in test <should fail in an async test case> \\(of root suite\\) of file.+multiple-done-async\\.fixture\\.js/,\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/multiple-runs.spec.js",
    "content": "\"use strict\";\n\nconst { invokeNode } = require(\"./helpers\");\n\ndescribe(\"multiple runs\", function () {\n  it(\"should be allowed to run multiple times if cleanReferences is turned off\", function (done) {\n    var path =\n      require.resolve(\"./fixtures/multiple-runs/run-thrice.fixture.js\");\n    invokeNode([path], function (err, res) {\n      if (err) {\n        done(err);\n        return;\n      }\n      expect(res.code, \"to be\", 0);\n      var results = JSON.parse(res.output);\n      expect(results, \"to have length\", 3);\n      expect(results[0].pending, \"to have length\", 1);\n      expect(results[0].failures, \"to have length\", 0);\n      expect(results[0].passes, \"to have length\", 0);\n      expect(results[1].pending, \"to have length\", 0);\n      expect(results[1].failures, \"to have length\", 1);\n      expect(results[1].passes, \"to have length\", 0);\n      expect(results[2].pending, \"to have length\", 0);\n      expect(results[2].failures, \"to have length\", 0);\n      expect(results[2].passes, \"to have length\", 1);\n      done();\n    });\n  });\n\n  it(\"should not be allowed if cleanReferences is true\", function (done) {\n    var path =\n      require.resolve(\"./fixtures/multiple-runs/clean-references.fixture.js\");\n    invokeNode(\n      [path],\n      function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res, \"to have failed\").and(\n          \"to contain output\",\n          /ERR_MOCHA_INSTANCE_ALREADY_DISPOSED/,\n        );\n\n        done();\n      },\n      { stdio: [\"ignore\", \"pipe\", \"pipe\"] },\n    );\n  });\n\n  it(\"should not be allowed if the instance is disposed\", function (done) {\n    var path = require.resolve(\"./fixtures/multiple-runs/dispose.fixture.js\");\n    invokeNode(\n      [path, \"--directly-dispose\"],\n      function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res.code, \"not to be\", 0);\n        expect(res.output, \"to contain\", \"ERR_MOCHA_INSTANCE_ALREADY_DISPOSED\");\n        done();\n      },\n      { stdio: [\"ignore\", \"pipe\", \"pipe\"] },\n    );\n  });\n\n  it(\"should not be allowed to run while a previous run is in progress\", function (done) {\n    var path =\n      require.resolve(\"./fixtures/multiple-runs/start-second-run-if-previous-is-still-running.fixture\");\n    invokeNode(\n      [path],\n      function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res.output, \"to contain\", \"ERR_MOCHA_INSTANCE_ALREADY_RUNNING\");\n        done();\n      },\n      { stdio: [\"ignore\", \"pipe\", \"pipe\"] },\n    );\n  });\n\n  it(\"should reset the hooks between runs\", function (done) {\n    var path =\n      require.resolve(\"./fixtures/multiple-runs/multiple-runs-with-flaky-before-each.fixture\");\n    invokeNode([path], function (err, res) {\n      expect(err, \"to be null\");\n      expect(res.code, \"to be\", 0);\n      var results = JSON.parse(res.output);\n      expect(results, \"to have length\", 2);\n      expect(results[0].failures, \"to have length\", 1);\n      expect(results[0].passes, \"to have length\", 0);\n      expect(results[1].passes, \"to have length\", 1);\n      expect(results[1].failures, \"to have length\", 0);\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/no-diff.spec.js",
    "content": "\"use strict\";\n\nvar helpers = require(\"./helpers\");\nvar run = helpers.runMocha;\n\ndescribe(\"no-diff\", function () {\n  describe(\"when enabled\", function () {\n    it(\"should not display a diff\", function (done) {\n      run(\"no-diff.fixture.js\", [\"--no-diff\"], function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res.output, \"not to match\", /\\+ expected/);\n        expect(res.output, \"not to match\", /- actual/);\n        done();\n      });\n    });\n  });\n\n  describe(\"when disabled\", function () {\n    it(\"should display a diff\", function (done) {\n      run(\"no-diff.fixture.js\", [\"--diff\"], function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res.output, \"to match\", /\\+ expected/);\n        expect(res.output, \"to match\", /- actual/);\n        done();\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/only.spec.js",
    "content": "\"use strict\";\n\nvar run = require(\"./helpers\").runMochaJSON;\nvar assert = require(\"node:assert\");\n\ndescribe(\".only()\", function () {\n  describe(\"bdd\", function () {\n    it(\"should run only tests that marked as `only`\", function (done) {\n      run(\n        \"options/only/bdd.fixture.js\",\n        [\"--ui\", \"bdd\", \"--no-forbid-only\"],\n        function (err, res) {\n          if (err) {\n            done(err);\n            return;\n          }\n          assert.strictEqual(res.stats.pending, 0);\n          assert.strictEqual(res.stats.passes, 11);\n          assert.strictEqual(res.stats.failures, 0);\n          assert.strictEqual(res.code, 0);\n          done();\n        },\n      );\n    });\n  });\n\n  describe(\"tdd\", function () {\n    it(\"should run only tests that marked as `only`\", function (done) {\n      run(\n        \"options/only/tdd.fixture.js\",\n        [\"--ui\", \"tdd\", \"--no-forbid-only\"],\n        function (err, res) {\n          if (err) {\n            done(err);\n            return;\n          }\n          assert.strictEqual(res.stats.pending, 0);\n          assert.strictEqual(res.stats.passes, 8);\n          assert.strictEqual(res.stats.failures, 0);\n          assert.strictEqual(res.code, 0);\n          done();\n        },\n      );\n    });\n  });\n\n  describe(\"qunit\", function () {\n    it(\"should run only tests that marked as `only`\", function (done) {\n      run(\n        \"options/only/qunit.fixture.js\",\n        [\"--ui\", \"qunit\", \"--no-forbid-only\"],\n        function (err, res) {\n          if (err) {\n            done(err);\n            return;\n          }\n          assert.strictEqual(res.stats.pending, 0);\n          assert.strictEqual(res.stats.passes, 5);\n          assert.strictEqual(res.stats.failures, 0);\n          assert.strictEqual(res.code, 0);\n          done();\n        },\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/allowUncaught.spec.js",
    "content": "\"use strict\";\n\nvar path = require(\"node:path\").posix;\nvar helpers = require(\"../helpers\");\nvar runMocha = helpers.runMocha;\nvar runMochaJSON = helpers.runMochaJSON;\n\ndescribe(\"--allow-uncaught\", function () {\n  var args = [\"--allow-uncaught\"];\n\n  it(\"should throw an uncaught error and exit process\", function (done) {\n    var fixture = path.join(\"options\", \"allow-uncaught\", \"propagate\");\n    runMocha(\n      fixture,\n      args,\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n\n        expect(res.code, \"to be greater than\", 0);\n        expect(res.output, \"to contain\", \"Error: Uncaught error after test1\");\n        expect(res.passing, \"to be\", 0);\n        expect(res.failing, \"to be\", 0);\n        done();\n      },\n      { stdio: \"pipe\" },\n    );\n  });\n\n  it(\"should run with conditional `this.skip()`\", function (done) {\n    var fixture = path.join(\"options\", \"allow-uncaught\", \"this-skip-it\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have passed\")\n        .and(\"to have passed test count\", 2)\n        .and(\"to have pending test count\", 3)\n        .and(\"to have passed test\", \"test1\", \"test4\")\n        .and(\"to have pending test order\", \"test2\", \"test3\", \"test5\");\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/asyncOnly.spec.js",
    "content": "\"use strict\";\n\nvar path = require(\"node:path\").posix;\nvar helpers = require(\"../helpers\");\nvar runMochaJSON = helpers.runMochaJSON;\n\ndescribe(\"--async-only\", function () {\n  var args = [];\n\n  before(function () {\n    args = [\"--async-only\"];\n  });\n\n  it(\"should fail synchronous specs\", function (done) {\n    var fixture = path.join(\"options\", \"async-only-sync\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have failed\");\n      done();\n    });\n  });\n\n  it(\"should allow asynchronous specs\", function (done) {\n    var fixture = path.join(\"options\", \"async-only-async\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have passed\");\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/bail.spec.js",
    "content": "\"use strict\";\n\nvar path = require(\"node:path\").posix;\nvar helpers = require(\"../helpers\");\nvar runMochaJSON = helpers.runMochaJSON;\n\ndescribe(\"--bail\", function () {\n  var args = [];\n\n  before(function () {\n    args = [\"--bail\"];\n  });\n\n  it(\"should stop after the first error\", function (done) {\n    var fixture = path.join(\"options\", \"bail\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have failed\")\n        .and(\"to have passed test\", \"should display this spec\")\n        .and(\"to have failed test\", \"should only display this error\")\n        .and(\"to have passed test count\", 1)\n        .and(\"to have failed test count\", 1);\n      done();\n    });\n  });\n\n  it(\"should stop after the first error - async\", function (done) {\n    var fixture = path.join(\"options\", \"bail-async\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have failed\")\n        .and(\"to have passed test\", \"should display this spec\")\n        .and(\"to have failed test\", \"should only display this error\")\n        .and(\"to have passed test count\", 1)\n        .and(\"to have failed test count\", 1);\n      done();\n    });\n  });\n\n  it('should stop all tests after failing \"before\" hook', function (done) {\n    var fixture = path.join(\"options\", \"bail-with-before\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have failed\")\n        .and(\"to have failed test count\", 1)\n        .and(\n          \"to have failed test\",\n          '\"before all\" hook: before suite1 for \"test suite1\"',\n        )\n        .and(\"to have passed test count\", 0);\n      done();\n    });\n  });\n\n  it('should stop all tests after failing \"beforeEach\" hook', function (done) {\n    var fixture = path.join(\"options\", \"bail-with-beforeEach\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have failed\")\n        .and(\"to have failed test count\", 1)\n        .and(\n          \"to have failed test\",\n          '\"before each\" hook: beforeEach suite1 for \"test suite1\"',\n        )\n        .and(\"to have passed test count\", 0);\n      done();\n    });\n  });\n\n  it(\"should stop all tests after failing test\", function (done) {\n    var fixture = path.join(\"options\", \"bail-with-test\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have failed\")\n        .and(\"to have failed test count\", 1)\n        .and(\"to have failed test\", \"test suite1\")\n        .and(\"to have passed test count\", 0);\n      done();\n    });\n  });\n\n  it('should stop all tests after failing \"after\" hook', function (done) {\n    var fixture = path.join(\"options\", \"bail-with-after\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have failed\")\n        .and(\"to have failed test count\", 1)\n        .and(\n          \"to have failed test\",\n          '\"after all\" hook: after suite1A for \"test suite1A\"',\n        )\n        .and(\"to have passed test count\", 2)\n        .and(\"to have passed test order\", \"test suite1\", \"test suite1A\");\n      done();\n    });\n  });\n\n  it('should stop all tests after failing \"afterEach\" hook', function (done) {\n    var fixture = path.join(\"options\", \"bail-with-afterEach\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have failed\")\n        .and(\"to have failed test count\", 1)\n        .and(\n          \"to have failed test\",\n          '\"after each\" hook: afterEach suite1A for \"test suite1A\"',\n        )\n        .and(\"to have passed test count\", 2)\n        .and(\"to have passed test order\", \"test suite1\", \"test suite1A\");\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/delay.spec.js",
    "content": "\"use strict\";\n\nvar path = require(\"node:path\").posix;\nvar helpers = require(\"../helpers\");\nvar runMochaJSON = helpers.runMochaJSON;\n\ndescribe(\"--delay\", function () {\n  var args = [\"--delay\", \"--no-forbid-only\"];\n\n  it(\"should run the generated test suite\", function (done) {\n    var fixture = path.join(\"options\", \"delay\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have passed\").and(\"to have passed test count\", 1);\n      done();\n    });\n  });\n\n  it(\"should execute exclusive tests only\", function (done) {\n    var fixture = path.join(\"options\", \"delay-only\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have passed\")\n        .and(\"to have passed test count\", 2)\n        .and(\n          \"to have passed test order\",\n          \"should run this\",\n          \"should run this, too\",\n        );\n      done();\n    });\n  });\n\n  it(\"should throw an error if the test suite failed to run\", function (done) {\n    var fixture = path.join(\"options\", \"delay-fail\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have failed\").and(\n        \"to have failed test\",\n        \"Uncaught error outside test suite\",\n      );\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/dryRun.spec.js",
    "content": "\"use strict\";\n\nvar path = require(\"node:path\").posix;\nvar helpers = require(\"../helpers\");\nvar runMochaJSON = helpers.runMochaJSON;\n\ndescribe(\"--dry-run\", function () {\n  var args = [\"--dry-run\", \"--no-forbid-only\"];\n\n  it(\"should only report, but not execute any test\", function (done) {\n    var fixture = path.join(\"options/dry-run\", \"dry-run\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have passed\")\n        .and(\n          \"to have passed tests\",\n          \"test2 - report as passed\",\n          \"test3 - report as passed\",\n          \"test4 - report as passed\",\n        )\n        .and(\"to have passed test count\", 3)\n        .and(\"to have pending test count\", 1)\n        .and(\"to have failed test count\", 0);\n      done();\n    });\n  });\n\n  it('should pass without \"RangeError: maximum call stack size exceeded\"', function (done) {\n    var fixture = path.join(\"options/dry-run\", \"stack-size\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have passed test count\", 400);\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/exit.spec.js",
    "content": "\"use strict\";\n\nvar runMocha = require(\"../helpers\").runMocha;\n\ndescribe(\"--exit\", function () {\n  var behaviors = {\n    enabled: \"--exit\",\n    disabled: \"--no-exit\",\n  };\n\n  // subprocess\n  var mocha;\n\n  function killSubprocess() {\n    mocha.kill(\"SIGKILL\");\n  }\n\n  // these two handlers deal with a ctrl-c on command-line\n  before(function () {\n    process.on(\"SIGINT\", killSubprocess);\n  });\n\n  after(function () {\n    process.removeListener(\"SIGINT\", killSubprocess);\n  });\n\n  /**\n   * Returns a test that executes Mocha in a subprocess with either\n   * `--exit`, `--no-exit`, or default behavior.\n   *\n   * @param {boolean} shouldExit - Expected result; `true` if Mocha should\n   *   have force-killed the process.\n   * @param {\"enabled\"|\"disabled\"} [behavior] - 'enabled' or 'disabled'; omit for default\n   * @returns {Function} async function implementing the test\n   */\n  var runExit = function (shouldExit, behavior) {\n    return function (done) {\n      var timeout = this.timeout();\n      this.timeout(0);\n      this.slow(Infinity);\n\n      var didExit = true;\n      var timeoutObj;\n      var fixture = \"exit.fixture.js\";\n      var args = behaviors[behavior] ? [behaviors[behavior]] : [];\n      mocha = runMocha(fixture, args, function postmortem(err) {\n        clearTimeout(timeoutObj);\n        if (err) {\n          return done(err);\n        }\n        expect(didExit, \"to be\", shouldExit);\n        done();\n      });\n\n      // If this callback happens, then Mocha didn't automatically exit.\n      timeoutObj = setTimeout(function () {\n        didExit = false;\n        killSubprocess();\n      }, timeout - 500);\n    };\n  };\n\n  describe(\"default behavior\", function () {\n    it(\"should not force exit after root suite completion\", runExit(false));\n  });\n\n  describe(\"when enabled\", function () {\n    it(\n      \"should force exit after root suite completion\",\n      runExit(true, \"enabled\"),\n    );\n  });\n\n  describe(\"when disabled\", function () {\n    it(\n      \"should not force exit after root suite completion\",\n      runExit(false, \"disabled\"),\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/options/extension.spec.js",
    "content": "\"use strict\";\n\nvar helpers = require(\"../helpers\");\nvar invokeMocha = helpers.invokeMocha;\nvar toJSONResult = helpers.toJSONResult;\n\ndescribe(\"--extension\", function () {\n  it(\"should allow comma-separated variables\", function (done) {\n    var args = [\n      \"--require\",\n      \"coffeescript/register\",\n      \"--require\",\n      \"./test/setup\",\n      \"--reporter\",\n      \"json\",\n      \"--extension\",\n      \"js,coffee\",\n      \"test/integration/fixtures/options/extension\",\n    ];\n    invokeMocha(args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n      expect(toJSONResult(res), \"to have passed\").and(\n        \"to have passed test count\",\n        2,\n      );\n      done();\n    });\n  });\n\n  it(\"should allow extensions beginning with a dot\", function (done) {\n    var args = [\n      \"--require\",\n      \"coffeescript/register\",\n      \"--require\",\n      \"./test/setup\",\n      \"--reporter\",\n      \"json\",\n      \"--extension\",\n      \".js\",\n      \"test/integration/fixtures/options/extension\",\n    ];\n    invokeMocha(args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n      expect(toJSONResult(res), \"to have passed\").and(\n        \"to have passed test count\",\n        1,\n      );\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/failZero.spec.js",
    "content": "\"use strict\";\n\nvar helpers = require(\"../helpers\");\nvar runMochaJSON = helpers.runMochaJSON;\n\ndescribe(\"--fail-zero\", function () {\n  var args = [\"--fail-zero\", \"--grep\", \"yyyyyy\"];\n\n  it(\"should fail since no tests are encountered\", function (done) {\n    var fixture = \"__default__.fixture.js\";\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have passed test count\", 0)\n        .and(\"to have test count\", 0)\n        .and(\"to have exit code\", 1);\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/file.spec.js",
    "content": "\"use strict\";\n\nvar path = require(\"node:path\").posix;\nconst {\n  runMochaJSON,\n  resolveFixturePath: resolvePath,\n  runMocha,\n} = require(\"../helpers\");\n\ndescribe(\"--file\", function () {\n  var args = [];\n  var fixtures = {\n    alpha: path.join(\"options\", \"file-alpha\"),\n    beta: path.join(\"options\", \"file-beta\"),\n    theta: path.join(\"options\", \"file-theta\"),\n  };\n\n  it(\"should run tests passed via file first\", function (done) {\n    args = [\"--file\", resolvePath(fixtures.alpha)];\n\n    var fixture = fixtures.beta;\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n      expect(res, \"to have passed\")\n        .and(\"to have passed test count\", 2)\n        .and(\"to have passed test order\", \"should be executed first\");\n      done();\n    });\n  });\n\n  it(\"should run multiple tests passed via file first\", function (done) {\n    args = [\n      \"--file\",\n      resolvePath(fixtures.alpha),\n      \"--file\",\n      resolvePath(fixtures.beta),\n    ];\n\n    var fixture = fixtures.theta;\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n      expect(res, \"to have passed\")\n        .and(\"to have passed test count\", 3)\n        .and(\n          \"to have passed test order\",\n          \"should be executed first\",\n          \"should be executed second\",\n          \"should be executed third\",\n        );\n      done();\n    });\n  });\n\n  it(\"should support having no other test files\", function (done) {\n    args = [\"--file\", resolvePath(fixtures.alpha)];\n\n    runMochaJSON(\"filethatdoesnotexist.js\", args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n      expect(res, \"to have passed\").and(\"to have passed test count\", 1);\n      done();\n    });\n  });\n\n  it(\"should run esm tests passed via file\", function (done) {\n    const esmFile = \"collect-files.fixture.mjs\";\n    const testArgs = [\"--file\", resolvePath(esmFile)];\n\n    runMochaJSON(esmFile, testArgs, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n      expect(res, \"to have passed\");\n      done();\n    });\n  });\n\n  it(\"should log a warning if a nonexistent file with an unknown extension is specified\", function (done) {\n    const nonexistentTestFileArg = \"nonexistent.test.ts\";\n    runMocha(\n      nonexistentTestFileArg,\n      [\"--file\"],\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n\n        expect(\n          res.output,\n          \"to contain\",\n          `Warning: Cannot find any files matching pattern`,\n        ).and(\"to contain\", nonexistentTestFileArg);\n        done();\n      },\n      { stdio: \"pipe\" },\n    );\n  });\n\n  it(\"should provide warning for nonexistent js file extensions\", function (done) {\n    const nonexistentCjsArg = \"nonexistent.test.js\";\n\n    runMocha(\n      nonexistentCjsArg,\n      [\"--file\"],\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n\n        expect(\n          res.output,\n          \"to contain\",\n          `Warning: Cannot find any files matching pattern`,\n        ).and(\"to contain\", nonexistentCjsArg);\n        done();\n      },\n      { stdio: \"pipe\" },\n    );\n  });\n\n  it(\"should provide warning for nonexistent esm file extensions\", function (done) {\n    const nonexistentEsmArg = \"nonexistent.test.mjs\";\n\n    runMocha(\n      nonexistentEsmArg,\n      [\"--file\"],\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n\n        expect(\n          res.output,\n          \"to contain\",\n          `Warning: Cannot find any files matching pattern`,\n        ).and(\"to contain\", nonexistentEsmArg);\n        done();\n      },\n      { stdio: \"pipe\" },\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/options/forbidOnly.spec.js",
    "content": "\"use strict\";\n\nvar path = require(\"node:path\").posix;\nvar helpers = require(\"../helpers\");\nvar runMocha = helpers.runMocha;\nvar runMochaJSON = helpers.runMochaJSON;\n\ndescribe(\"--forbid-only\", function () {\n  var args = [];\n  var onlyErrorMessage = \"`.only` forbidden\";\n\n  beforeEach(function () {\n    args = [\"--forbid-only\"];\n  });\n\n  it(\"should succeed if there are only passed tests\", function (done) {\n    var fixture = path.join(\"options\", \"forbid-only\", \"passed\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n      expect(res, \"to have passed\");\n      done();\n    });\n  });\n\n  it(\"should fail if there are tests marked only\", function (done) {\n    var fixture = path.join(\"options\", \"forbid-only\", \"only\");\n    var spawnOpts = { stdio: \"pipe\" };\n    runMocha(\n      fixture,\n      args,\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have failed with output\", new RegExp(onlyErrorMessage));\n        done();\n      },\n      spawnOpts,\n    );\n  });\n\n  it(\"should fail if there are tests in suites marked only\", function (done) {\n    var fixture = path.join(\"options\", \"forbid-only\", \"only-suite\");\n    var spawnOpts = { stdio: \"pipe\" };\n    runMocha(\n      fixture,\n      args,\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have failed with output\", new RegExp(onlyErrorMessage));\n        done();\n      },\n      spawnOpts,\n    );\n  });\n\n  it(\"should fail if there is empty suite marked only\", function (done) {\n    var fixture = path.join(\"options\", \"forbid-only\", \"only-empty-suite\");\n    var spawnOpts = { stdio: \"pipe\" };\n    runMocha(\n      fixture,\n      args,\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have failed with output\", new RegExp(onlyErrorMessage));\n        done();\n      },\n      spawnOpts,\n    );\n  });\n\n  it(\"should fail if there is suite marked only which matches grep\", function (done) {\n    var fixture = path.join(\"options\", \"forbid-only\", \"only-suite\");\n    var spawnOpts = { stdio: \"pipe\" };\n    runMocha(\n      fixture,\n      args.concat(\"--fgrep\", \"suite marked with only\"),\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have failed with output\", new RegExp(onlyErrorMessage));\n        done();\n      },\n      spawnOpts,\n    );\n  });\n\n  it(\"should fail if suite marked only does not match grep\", function (done) {\n    var fixture = path.join(\"options\", \"forbid-only\", \"only-suite\");\n    var spawnOpts = { stdio: \"pipe\" };\n    runMocha(\n      fixture,\n      args.concat(\"--fgrep\", \"bumble bees\"),\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have failed with output\", new RegExp(onlyErrorMessage));\n        done();\n      },\n      spawnOpts,\n    );\n  });\n\n  it(\"should fail if suite marked only does not match inverted grep\", function (done) {\n    var fixture = path.join(\"options\", \"forbid-only\", \"only-suite\");\n    var spawnOpts = { stdio: \"pipe\" };\n    runMocha(\n      fixture,\n      args.concat(\"--fgrep\", \"suite marked with only\", \"--invert\"),\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have failed with output\", new RegExp(onlyErrorMessage));\n        done();\n      },\n      spawnOpts,\n    );\n  });\n\n  it('should fail even if before has \"skip\"', function (done) {\n    var fixture = path.join(\"options\", \"forbid-only\", \"only-before\");\n    var spawnOpts = { stdio: \"pipe\" };\n    runMocha(\n      fixture,\n      args,\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have failed with output\", new RegExp(onlyErrorMessage));\n        done();\n      },\n      spawnOpts,\n    );\n  });\n\n  it('should fail even if beforeEach has \"skip\"', function (done) {\n    var fixture = path.join(\"options\", \"forbid-only\", \"only-before-each\");\n    var spawnOpts = { stdio: \"pipe\" };\n    runMocha(\n      fixture,\n      args,\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have failed with output\", new RegExp(onlyErrorMessage));\n        done();\n      },\n      spawnOpts,\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/options/forbidPending.spec.js",
    "content": "\"use strict\";\n\nvar path = require(\"node:path\").posix;\nvar helpers = require(\"../helpers\");\nvar runMocha = helpers.runMocha;\nvar runMochaJSON = helpers.runMochaJSON;\n\ndescribe(\"--forbid-pending\", function () {\n  var args = [];\n  var pendingErrorMessage = \"Pending test forbidden\";\n\n  before(function () {\n    args = [\"--forbid-pending\"];\n  });\n\n  it(\"should succeed if there are only passed tests\", function (done) {\n    var fixture = path.join(\"options\", \"forbid-pending\", \"passed\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n      expect(res, \"to have passed\");\n      done();\n    });\n  });\n\n  it(\"should fail if there are tests in suites marked skip\", function (done) {\n    var fixture = path.join(\"options\", \"forbid-pending\", \"skip-suite\");\n    var spawnOpts = { stdio: \"pipe\" };\n    runMocha(\n      fixture,\n      args,\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to satisfy\", {\n          code: 1,\n          output: new RegExp(pendingErrorMessage),\n        });\n        done();\n      },\n      spawnOpts,\n    );\n  });\n\n  it(\"should fail if there is empty suite marked pending\", function (done) {\n    var fixture = path.join(\"options\", \"forbid-pending\", \"skip-empty-suite\");\n    var spawnOpts = { stdio: \"pipe\" };\n    runMocha(\n      fixture,\n      args,\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to satisfy\", {\n          code: 1,\n          output: new RegExp(pendingErrorMessage),\n        });\n        done();\n      },\n      spawnOpts,\n    );\n  });\n\n  var forbidPendingFailureTests = {\n    \"should fail if there are tests marked skip\": \"skip\",\n    \"should fail if there are pending tests\": \"pending\",\n    \"should fail if tests call `skip()`\": \"this-skip\",\n    \"should fail if beforeEach calls `skip()`\": \"beforeEach-this-skip\",\n    \"should fail if before calls `skip()`\": \"before-this-skip\",\n  };\n\n  Object.keys(forbidPendingFailureTests).forEach(function (title) {\n    it(title, function (done) {\n      var fixture = path.join(\n        \"options\",\n        \"forbid-pending\",\n        forbidPendingFailureTests[title],\n      );\n      runMochaJSON(fixture, args, function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have failed with error\", pendingErrorMessage);\n        done();\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/grep.spec.js",
    "content": "\"use strict\";\n\nvar helpers = require(\"../helpers\");\nvar runMocha = helpers.runMocha;\nvar runMochaJSON = helpers.runMochaJSON;\n\nvar FIXTURE = \"options/grep\";\n\ndescribe(\"--grep\", function () {\n  it(\"should run specs matching a string\", function (done) {\n    runMochaJSON(FIXTURE, [\"--grep\", \"match\"], function (err, res) {\n      if (err) {\n        return done(err);\n      }\n      expect(res, \"to have passed\")\n        .and(\"to have passed test count\", 2)\n        .and(\"not to have pending tests\");\n      done();\n    });\n  });\n\n  describe(\"should run specs matching a RegExp\", function () {\n    it(\"with RegExp-like strings (pattern followed by flag)\", function (done) {\n      runMochaJSON(FIXTURE, [\"--grep\", \"/match/i\"], function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have passed\")\n          .and(\"to have passed test count\", 4)\n          .and(\"not to have pending tests\");\n        done();\n      });\n    });\n\n    it(\"with string as pattern\", function (done) {\n      runMochaJSON(FIXTURE, [\"--grep\", \".*\"], function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have failed\")\n          .and(\"to have passed test count\", 4)\n          .and(\"to have failed test count\", 1)\n          .and(\"not to have pending tests\");\n        done();\n      });\n    });\n  });\n\n  describe(\"when used with --invert\", function () {\n    it(\"should run specs that do not match the pattern\", function (done) {\n      runMochaJSON(\n        FIXTURE,\n        [\"--grep\", \"fail\", \"--invert\"],\n        function (err, res) {\n          if (err) {\n            return done(err);\n          }\n          expect(res, \"to have passed\")\n            .and(\"to have passed test count\", 4)\n            .and(\"not to have pending tests\");\n          done();\n        },\n      );\n    });\n  });\n\n  describe(\"when both --fgrep and --grep used together\", function () {\n    it(\"should report an error\", function (done) {\n      runMocha(\n        FIXTURE,\n        [\"--fgrep\", \"first\", \"--grep\", \"second\"],\n        function (err, res) {\n          if (err) {\n            return done(err);\n          }\n          expect(res, \"to have failed with output\", /mutually exclusive/i);\n          done();\n        },\n        \"pipe\",\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/ignore.spec.js",
    "content": "\"use strict\";\n\nvar path = require(\"node:path\").posix;\nvar helpers = require(\"../helpers\");\nvar runMochaJSON = helpers.runMochaJSON;\nvar resolvePath = helpers.resolveFixturePath;\n\ndescribe(\"--ignore\", function () {\n  /*\n   * Runs mocha in {path} with the given args.\n   * Calls handleResult with the result.\n   *\n   * @param {string} fixture\n   * @param {string[]} args\n   * @param {function} handleResult\n   * @param {function} done\n   */\n  function runMochaTest(fixture, args, handleResult, done) {\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      handleResult(res);\n      done();\n    });\n  }\n\n  it(\"should ignore specific files\", function (done) {\n    var fixtures = path.join(\"options\", \"ignore\", \"*\");\n    runMochaTest(\n      fixtures,\n      [\n        \"--ignore\",\n        resolvePath(path.join(\"options\", \"ignore\", \"fail\")).replace(/\\\\/g, \"/\"),\n      ],\n      function (res) {\n        expect(res, \"to have passed\")\n          .and(\"to have run test\", \"should find this test\")\n          .and(\"not to have pending tests\");\n      },\n      done,\n    );\n  });\n\n  it(\"should ignore globbed files\", function (done) {\n    var fixtures = path.join(\"options\", \"ignore\", \"**\", \"*\");\n    runMochaTest(\n      fixtures,\n      [\"--ignore\", \"**/fail.fixture.js\"],\n      function (res) {\n        expect(res, \"to have passed\")\n          .and(\"not to have pending tests\")\n          .and(\"to have passed test count\", 2);\n      },\n      done,\n    );\n  });\n\n  it(\"should ignore multiple patterns\", function (done) {\n    var fixtures = path.join(\"options\", \"ignore\", \"**\", \"*\");\n    runMochaTest(\n      fixtures,\n      [\n        \"--ignore\",\n        resolvePath(path.join(\"options\", \"ignore\", \"fail\")).replace(/\\\\/g, \"/\"),\n        \"--ignore\",\n        resolvePath(path.join(\"options\", \"ignore\", \"nested\", \"fail\")).replace(\n          /\\\\/g,\n          \"/\",\n        ),\n      ],\n      function (res) {\n        expect(res, \"to have passed\")\n          .and(\"not to have pending tests\")\n          .and(\"to have passed test count\", 2);\n      },\n      done,\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/options/invert.spec.js",
    "content": "\"use strict\";\n\nvar runMocha = require(\"../helpers\").runMocha;\n\ndescribe(\"--invert\", function () {\n  describe(\"when used without --fgrep or --grep\", function () {\n    it(\"it should report an error\", function (done) {\n      runMocha(\n        \"options/grep\",\n        [\"--invert\"],\n        function (err, res) {\n          if (err) {\n            return done(err);\n          }\n          expect(\n            res,\n            \"to have failed with output\",\n            /--invert.*--grep <regexp>/,\n          );\n          done();\n        },\n        \"pipe\",\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/jobs.spec.js",
    "content": "\"use strict\";\n\nvar helpers = require(\"../helpers\");\nvar runMochaAsync = helpers.runMochaAsync;\n\ndescribe(\"--jobs\", function () {\n  describe(\"when set to a number less than 2\", function () {\n    it(\"should run tests in serial\", function () {\n      return expect(\n        runMochaAsync(\n          \"options/jobs/fail-in-parallel\",\n          [\"--parallel\", \"--jobs\", \"1\"],\n          \"pipe\",\n        ),\n        \"when fulfilled\",\n        \"to have passed\",\n      );\n    });\n  });\n\n  describe(\"when set to a number greater than 1\", function () {\n    it(\"should run tests in parallel\", function () {\n      return expect(\n        runMochaAsync(\n          \"options/jobs/fail-in-parallel\",\n          [\"--parallel\", \"--jobs\", \"2\"],\n          \"pipe\",\n        ),\n        \"when fulfilled\",\n        \"to have failed\",\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/listInterfaces.spec.js",
    "content": "\"use strict\";\n\nvar helpers = require(\"../helpers\");\nvar invokeMocha = helpers.invokeMocha;\nvar escapeRegExp = helpers.escapeRegExp;\nvar interfaces = require(\"../../../lib/mocha\").interfaces;\n\ndescribe(\"--list-interfaces\", function () {\n  it(\"should dump a list of all interfaces with descriptions\", function (done) {\n    var expected = Object.keys(interfaces)\n      .filter(function (name) {\n        return /^[a-z]/.test(name);\n      })\n      .map(function (name) {\n        return {\n          name: escapeRegExp(name),\n          description: escapeRegExp(interfaces[name].description),\n        };\n      });\n\n    invokeMocha([\"--list-interfaces\"], function (err, result) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(result.code, \"to be\", 0);\n      expected.forEach(function (ui) {\n        expect(\n          result.output,\n          \"to match\",\n          new RegExp(ui.name + \"\\\\s*-\\\\s*\" + ui.description),\n        );\n      });\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/listReporters.spec.js",
    "content": "\"use strict\";\n\nvar helpers = require(\"../helpers\");\nvar invokeMocha = helpers.invokeMocha;\nvar escapeRegExp = helpers.escapeRegExp;\nvar reporters = require(\"../../../lib/mocha\").reporters;\n\ndescribe(\"--list-reporters\", function () {\n  it(\"should dump a list of all reporters with descriptions\", function (done) {\n    var expected = Object.keys(reporters)\n      .filter(function (name) {\n        return (\n          /^[a-z]/.test(name) &&\n          !(reporters[name].abstract || reporters[name].browserOnly)\n        );\n      })\n      .map(function (name) {\n        return {\n          name: escapeRegExp(name),\n          description: escapeRegExp(reporters[name].description),\n        };\n      });\n\n    invokeMocha([\"--list-reporters\"], function (err, result) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(result.code, \"to be\", 0);\n      expected.forEach(function (reporter) {\n        expect(\n          result.output,\n          \"to match\",\n          new RegExp(reporter.name + \"\\\\s*-\\\\s*\" + reporter.description),\n        );\n      });\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/node-flags.spec.js",
    "content": "\"use strict\";\n\nvar invokeMocha = require(\"../helpers\").invokeMocha;\n\ndescribe(\"node flags\", function () {\n  it(\"should not consider argument values to be node flags\", function (done) {\n    invokeMocha(\n      [\"--require\", \"trace-dependency\"],\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"not to have failed with output\", /bad option/i);\n        done();\n      },\n      \"pipe\",\n    );\n  });\n});\n\ndescribe('node flags using \"--node-option\"', function () {\n  it(\"should pass fake option to node and fail with node exception\", function (done) {\n    invokeMocha(\n      [\"--node-option\", \"fake-flag\"],\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have failed with output\", /bad option: --fake-flag/i);\n        done();\n      },\n      \"pipe\",\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/options/parallel.spec.js",
    "content": "\"use strict\";\nconst Mocha = require(\"../../../lib/mocha\");\nconst {\n  runMochaAsync,\n  invokeMochaAsync,\n  getSummary,\n  resolveFixturePath,\n} = require(\"../helpers\");\nconst psList = require(\"ps-list\").default;\n\nconst REPORTER_FIXTURE_PATH = resolveFixturePath(\"options/parallel/test-a\");\n\n/**\n * Get child processes of a given PID using ps-list\n * @param {number} pid - Parent process ID\n * @param {Object} options - Options object\n * @param {boolean} options.root - Include the parent PID in results\n * @returns {Promise<number[]>} Array of child process PIDs\n */\nasync function getChildPids(pid) {\n  return (\n    (await psList())\n      // ppid = parent process ID\n      .filter((proc) => proc.ppid === pid)\n      .map((proc) => proc.pid)\n  );\n}\n\n/**\n * Check if a process exists using ps-list\n * @param {number} pid - Process ID to check\n * @param {Object} options - Options object\n * @param {boolean} options.root - Include the PID itself in results\n * @returns {Promise<boolean>} Array with the PID if exists, null otherwise\n */\nasync function checkProcessExists(pid) {\n  return (await psList()).some((proc) => proc.pid === pid);\n}\n\n/**\n * Run a test fixture with the same reporter in both parallel and serial modes,\n * returning both outputs for comparison\n * @param {string} reporter - Reporter name\n * @returns {{actual: import('../helpers').Summary, expected: import('../helpers').Summary}}\n */\nasync function compareReporters(reporter) {\n  const [actual, expected] = await Promise.all([\n    runMochaAsync(REPORTER_FIXTURE_PATH, [\n      \"--reporter\",\n      reporter,\n      \"--no-parallel\",\n    ]),\n    runMochaAsync(REPORTER_FIXTURE_PATH, [\n      \"--reporter\",\n      reporter,\n      \"--parallel\",\n    ]),\n  ]);\n\n  // the test duration is non-deterministic, so we just fudge it\n  actual.output = expected.output = expected.output.replace(/\\d+m?s/g, \"100ms\");\n\n  return { actual, expected };\n}\n\n/**\n * Many (but not all) reporters can use this assertion to compare output of serial vs. parallel\n * @param {string} reporter - Reporter name\n */\nasync function assertReporterOutputEquality(reporter) {\n  const { actual, expected } = await compareReporters(reporter);\n  return expect(actual, \"to satisfy\", {\n    passing: expected.passing,\n    failing: expected.failing,\n    pending: expected.pending,\n    code: expected.code,\n    output: expected.output,\n  });\n}\n\n/**\n * Polls a process for its list of children PIDs. Returns the first non-empty list found\n * @param {number} pid - Process PID\n * @returns {number[]} Child PIDs\n */\nasync function waitForChildPids(pid) {\n  let childPids = [];\n  while (!childPids.length) {\n    childPids = await getChildPids(pid);\n    await new Promise((resolve) => setTimeout(resolve, 100));\n  }\n  return childPids;\n}\n\ndescribe(\"--parallel\", function () {\n  describe(\"when a test has a syntax error\", function () {\n    describe(\"when there is only a single test file\", function () {\n      it(\"should fail gracefully\", async function () {\n        return expect(\n          runMochaAsync(\"options/parallel/syntax-err\", [\"--parallel\"]),\n          \"when fulfilled\",\n          \"to have failed with output\",\n          /SyntaxError/,\n        );\n      });\n    });\n\n    describe(\"when there are multiple test files\", function () {\n      it(\"should fail gracefully\", async function () {\n        return expect(\n          invokeMochaAsync(\n            [resolveFixturePath(\"options/parallel/syntax-err\"), \"--parallel\"],\n            \"pipe\",\n          )[1],\n          \"when fulfilled\",\n          \"to have failed\",\n        );\n      });\n    });\n  });\n\n  describe(\"when used with CJS tests\", function () {\n    it(\"should have the same result as with --no-parallel\", async function () {\n      const expected = await runMochaAsync(\"options/parallel/test-*\", [\n        \"--no-parallel\",\n      ]);\n      return expect(\n        runMochaAsync(\"options/parallel/test-*\", [\"--parallel\"]),\n        \"to be fulfilled with value satisfying\",\n        {\n          passing: expected.passing,\n          failing: expected.failing,\n          pending: expected.pending,\n          code: expected.code,\n        },\n      );\n    });\n  });\n\n  describe(\"when used with ESM tests\", function () {\n    it(\"should have the same result as with --no-parallel\", async function () {\n      const expected = getSummary(\n        await invokeMochaAsync([\n          \"--no-parallel\",\n          resolveFixturePath(\"esm/*.fixture.mjs\"),\n        ])[1],\n      );\n\n      const actual = getSummary(\n        await invokeMochaAsync([\n          \"--parallel\",\n          resolveFixturePath(\"esm/*.fixture.mjs\"),\n        ])[1],\n      );\n\n      return expect(actual, \"to satisfy\", {\n        pending: expected.pending,\n        passing: expected.passing,\n        failing: expected.failing,\n      });\n    });\n  });\n\n  describe(\"when used with --retries\", function () {\n    it(\"should retry tests appropriately\", async function () {\n      return expect(\n        runMochaAsync(\"options/parallel/retries-*\", [\"--parallel\"]),\n        \"when fulfilled\",\n        \"to satisfy\",\n        expect\n          .it(\"to have failed\")\n          .and(\"to have passed test count\", 1)\n          .and(\"to have pending test count\", 0)\n          .and(\"to have failed test count\", 1)\n          .and(\"to contain output\", /count: 3/),\n      );\n    });\n  });\n\n  describe(\"when used with --allow-uncaught\", function () {\n    it(\"should bubble up an exception\", async function () {\n      return expect(\n        invokeMochaAsync(\n          [\n            resolveFixturePath(\"options/parallel/uncaught\"),\n            \"--parallel\",\n            \"--allow-uncaught\",\n          ],\n          \"pipe\",\n        )[1],\n        \"when fulfilled\",\n        \"to satisfy\",\n        expect\n          .it(\"to contain output\", /Error: existential isolation/i)\n          .and(\"to have exit code\", 1),\n      );\n    });\n  });\n\n  describe(\"when used with --file\", function () {\n    it(\"should error out\", async function () {\n      return expect(\n        invokeMochaAsync(\n          [\n            \"--file\",\n            resolveFixturePath(\"options/parallel/test-a\"),\n            \"--parallel\",\n          ],\n          \"pipe\",\n        )[1],\n        \"when fulfilled\",\n        \"to contain output\",\n        /mutually exclusive with --file/,\n      );\n    });\n  });\n\n  describe(\"when used with --sort\", function () {\n    it(\"should error out\", async function () {\n      return expect(\n        invokeMochaAsync(\n          [\n            \"--sort\",\n            resolveFixturePath(\"options/parallel/test-*\"),\n            \"--parallel\",\n          ],\n          \"pipe\",\n        )[1],\n        \"when fulfilled\",\n        \"to contain output\",\n        /mutually exclusive with --sort/,\n      );\n    });\n  });\n\n  describe(\"when used with exclusive tests\", function () {\n    it(\"should error out\", async function () {\n      return expect(\n        invokeMochaAsync(\n          [\n            resolveFixturePath(\"options/parallel/exclusive-test-*\"),\n            \"--parallel\",\n          ],\n          \"pipe\",\n        )[1],\n        \"when fulfilled\",\n        \"to contain output\",\n        /`\\.only` is not supported in parallel mode/,\n      );\n    });\n  });\n\n  describe(\"when used with --bail\", function () {\n    it(\"should skip some tests\", async function () {\n      const result = await runMochaAsync(\"options/parallel/test-*\", [\n        \"--parallel\",\n        \"--bail\",\n      ]);\n      // we don't know _exactly_ how many tests will be skipped here\n      // due to the --bail, but the number of tests completed should be\n      // less than the total, which is 5.\n      return expect(\n        result.passing + result.pending + result.failing,\n        \"to be less than\",\n        5,\n      );\n    });\n\n    it(\"should fail\", async function () {\n      return expect(\n        runMochaAsync(\"options/parallel/test-*\", [\"--parallel\", \"--bail\"]),\n        \"when fulfilled\",\n        \"to have failed\",\n      );\n    });\n  });\n\n  describe('when encountering a \"bail\" in context', function () {\n    it(\"should skip some tests\", async function () {\n      const result = await runMochaAsync(\"options/parallel/bail\", [\n        \"--parallel\",\n      ]);\n      return expect(\n        result.passing + result.pending + result.failing,\n        \"to be less than\",\n        2,\n      );\n    });\n\n    it(\"should fail\", async function () {\n      return expect(\n        runMochaAsync(\"options/parallel/bail\", [\"--parallel\", \"--bail\"]),\n        \"when fulfilled\",\n        \"to have failed\",\n      );\n    });\n  });\n\n  describe('when used with \"grep\"', function () {\n    it(\"should be equivalent to running in serial\", async function () {\n      const expected = await runMochaAsync(\"options/parallel/test-*\", [\n        \"--no-parallel\",\n        '--grep=\"suite d\"',\n      ]);\n      return expect(\n        runMochaAsync(\"options/parallel/test-*\", [\n          \"--parallel\",\n          '--grep=\"suite d\"',\n        ]),\n        \"to be fulfilled with value satisfying\",\n        {\n          passing: expected.passing,\n          failing: expected.failing,\n          pending: expected.pending,\n          code: expected.code,\n        },\n      );\n    });\n  });\n\n  describe(\"reporter equivalence\", function () {\n    // each reporter name is duplicated; one is in all lower-case\n    // 'base' is abstract, 'html' is browser-only, others are incompatible\n    const DENY = [\"progress\", \"base\", \"html\", \"markdown\", \"json-stream\"];\n    Object.keys(Mocha.reporters)\n      .filter((name) => /^[a-z]/.test(name) && DENY.indexOf(name) === -1)\n      .forEach((reporter) => {\n        describe(`when multiple test files run with --reporter=${reporter}`, function () {\n          it(\"should have the same result as when run with --no-parallel\", async function () {\n            // note that the output may not be in the same order, as running file\n            // order is non-deterministic in parallel mode\n            const expected = await runMochaAsync(\"options/parallel/test-*\", [\n              \"--reporter\",\n              reporter,\n              \"--no-parallel\",\n            ]);\n            return expect(\n              runMochaAsync(\"options/parallel/test-*\", [\n                \"--reporter\",\n                reporter,\n                \"--parallel\",\n              ]),\n              \"to be fulfilled with value satisfying\",\n              {\n                passing: expected.passing,\n                failing: expected.failing,\n                pending: expected.pending,\n                code: expected.code,\n              },\n            );\n          });\n        });\n      });\n\n    describe(\"when a single test file is run with --reporter=dot\", function () {\n      it(\"should have the same output as when run with --no-parallel\", async function () {\n        return assertReporterOutputEquality.call(this, \"dot\");\n      });\n    });\n\n    describe(\"when a single test file is run with --reporter=doc\", function () {\n      it(\"should have the same output as when run with --no-parallel\", async function () {\n        return assertReporterOutputEquality.call(this, \"doc\");\n      });\n    });\n\n    describe(\"when a single test file is run with --reporter=tap\", function () {\n      it(\"should have the same output as when run with --no-parallel\", async function () {\n        return assertReporterOutputEquality.call(this, \"tap\");\n      });\n    });\n\n    describe(\"when a single test file is run with --reporter=list\", function () {\n      it(\"should have the same output as when run with --no-parallel\", async function () {\n        return assertReporterOutputEquality.call(this, \"list\");\n      });\n    });\n\n    describe(\"when a single test file is run with --reporter=min\", function () {\n      it(\"should have the same output as when run with --no-parallel\", async function () {\n        return assertReporterOutputEquality.call(this, \"min\");\n      });\n    });\n\n    describe(\"when a single test file is run with --reporter=spec\", function () {\n      it(\"should have the same output as when run with --no-parallel\", async function () {\n        return assertReporterOutputEquality.call(this, \"spec\");\n      });\n    });\n\n    describe(\"when a single test file is run with --reporter=nyan\", function () {\n      it(\"should have the same output as when run with --no-parallel\", async function () {\n        return assertReporterOutputEquality.call(this, \"nyan\");\n      });\n    });\n\n    describe(\"when a single test file is run with --reporter=landing\", function () {\n      it(\"should have the same output as when run with --no-parallel\", async function () {\n        return assertReporterOutputEquality.call(this, \"landing\");\n      });\n    });\n\n    describe(\"when a single test file is run with --reporter=progress\", function () {\n      it(\"should fail due to incompatibility\", async function () {\n        return expect(\n          invokeMochaAsync(\n            [\n              resolveFixturePath(\"options/parallel/test-a\"),\n              \"--reporter=progress\",\n              \"--parallel\",\n            ],\n            \"pipe\",\n          )[1],\n          \"when fulfilled\",\n          \"to satisfy\",\n          expect\n            .it(\"to have failed\")\n            .and(\"to contain output\", /mutually exclusive/),\n        );\n      });\n    });\n\n    describe(\"when a single test file is run with --reporter=markdown\", function () {\n      it(\"should fail due to incompatibility\", async function () {\n        return expect(\n          invokeMochaAsync(\n            [\n              resolveFixturePath(\"options/parallel/test-a\"),\n              \"--reporter=markdown\",\n              \"--parallel\",\n            ],\n            \"pipe\",\n          )[1],\n          \"when fulfilled\",\n          \"to satisfy\",\n          expect\n            .it(\"to have failed\")\n            .and(\"to contain output\", /mutually exclusive/),\n        );\n      });\n    });\n\n    describe(\"when a single test file is run with --reporter=json-stream\", function () {\n      it(\"should fail due to incompatibility\", async function () {\n        return expect(\n          invokeMochaAsync(\n            [\n              resolveFixturePath(\"options/parallel/test-a\"),\n              \"--reporter=json-stream\",\n              \"--parallel\",\n            ],\n            \"pipe\",\n          )[1],\n          \"when fulfilled\",\n          \"to satisfy\",\n          expect\n            .it(\"to have failed\")\n            .and(\"to contain output\", /mutually exclusive/),\n        );\n      });\n    });\n\n    describe(\"when a single test file is run with --reporter=json\", function () {\n      it(\"should have the same output as when run with --no-parallel\", async function () {\n        // this one has some timings/durations that we can safely ignore\n        const { expected, actual } = await compareReporters(\"json\");\n        expected.output = JSON.parse(expected.output);\n        actual.output = JSON.parse(actual.output);\n        return expect(actual, \"to satisfy\", {\n          passing: expected.passing,\n          failing: expected.failing,\n          pending: expected.pending,\n          code: expected.code,\n          output: {\n            stats: {\n              suites: expected.output.stats.suites,\n              tests: expected.output.stats.tests,\n              passes: expected.output.stats.passes,\n              pending: expected.output.stats.pending,\n              failures: expected.output.stats.failures,\n            },\n            tests: expected.tests,\n          },\n        });\n      });\n    });\n\n    describe(\"when a single test file is run with --reporter=xunit\", function () {\n      it(\"should have the same output as when run with --no-parallel\", async function () {\n        // durations need replacing\n        const { expected, actual } = await compareReporters(\"xunit\");\n        expected.output = expected.output\n          .replace(/time=\".+?\"/g, 'time=\"0.5\"')\n          .replace(/timestamp=\".+?\"/g, 'timestamp=\"some-timestamp');\n        actual.output = actual.output\n          .replace(/time=\".+?\"/g, 'time=\"0.5\"')\n          .replace(/timestamp=\".+?\"/g, 'timestamp=\"some-timestamp');\n        return expect(actual, \"to satisfy\", {\n          passing: expected.passing,\n          failing: expected.failing,\n          pending: expected.pending,\n          code: expected.code,\n          output: expected.output,\n        });\n      });\n    });\n  });\n\n  // - `waitForChildPids` polls for created children\n  // - `await promise` waits for `invokeMochaAsync` to complete, which should\n  //   kill all children\n  // - `checkProcessExists` validates that each child was killed\n  // - if any weren't killed, the test fails\n  describe(\"pool shutdown\", function () {\n    describe(\"during normal operation\", function () {\n      it(\"should not leave orphaned processes around\", async function () {\n        const [{ pid }, promise] = invokeMochaAsync([\n          resolveFixturePath(\"options/parallel/test-*\"),\n          \"--parallel\",\n        ]);\n        const childPids = await waitForChildPids(pid);\n        await promise;\n        return expect(\n          Promise.all(\n            [pid, ...childPids].map(\n              async (childPid) => await checkProcessExists(childPid),\n            ),\n          ),\n          \"when fulfilled\",\n          \"to have items satisfying\",\n          false,\n        );\n      });\n    });\n\n    describe(\"during operation with --bail\", function () {\n      it(\"should not leave orphaned processes around\", async function () {\n        const [{ pid }, promise] = invokeMochaAsync([\n          resolveFixturePath(\"options/parallel/test-*\"),\n          \"--bail\",\n          \"--parallel\",\n        ]);\n        const childPids = await waitForChildPids(pid);\n        await promise;\n        return expect(\n          Promise.all(\n            [pid, ...childPids].map(\n              async (childPid) => await checkProcessExists(childPid),\n            ),\n          ),\n          \"when fulfilled\",\n          \"to have items satisfying\",\n          false,\n        );\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/passOnFailingTestSuite.spec.js",
    "content": "\"use strict\";\n\nvar helpers = require(\"../helpers\");\nvar runMochaJSON = helpers.runMochaJSON;\n\ndescribe(\"Enabled --pass-on-failing-test-suite\", function () {\n  var args = [\"--pass-on-failing-test-suite=true\"];\n\n  it(\"Test should finish with zero code with disabled option\", function (done) {\n    var fixture = \"failing-sync.fixture.js\";\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have passed test count\", 0)\n        .and(\"to have test count\", 1)\n        .and(\"to have exit code\", 0);\n      done();\n    });\n  });\n});\n\ndescribe(\"Disabled --pass-on-failing-test-suite\", function () {\n  var args = [\"--pass-on-failing-test-suite=false\"];\n\n  it(\"Test should return non-zero code with enabled option\", function (done) {\n    var fixture = \"failing-sync.fixture.js\";\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have passed test count\", 0)\n        .and(\"to have test count\", 1)\n        .and(\"to have exit code\", 1);\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/posixExitCodes.spec.js",
    "content": "\"use strict\";\n\nvar helpers = require(\"../helpers\");\nvar runMocha = helpers.runMocha;\nvar os = require(\"node:os\");\n\nconst EXIT_FAILURE = 1;\nconst SIGNAL_OFFSET = 128;\n\ndescribe(\"--posix-exit-codes\", function () {\n  if (os.platform() !== \"win32\") {\n    describe(\"when enabled\", function () {\n      describe(\"when mocha is run as a child process\", () => {\n        // 'no-warnings' node option makes mocha run as a child process\n        const args = [\"--no-warnings\", \"--posix-exit-codes\"];\n\n        it(\"should exit with correct POSIX shell code on SIGABRT\", function (done) {\n          var fixture = \"signals-sigabrt.fixture.js\";\n          runMocha(fixture, args, function postmortem(err, res) {\n            if (err) {\n              return done(err);\n            }\n            expect(\n              res.code,\n              \"to be\",\n              SIGNAL_OFFSET + os.constants.signals.SIGABRT,\n            );\n            done();\n          });\n        });\n\n        it(\"should exit with correct POSIX shell code on SIGTERM\", function (done) {\n          // SIGTERM is not supported on Windows\n          if (os.platform() !== \"win32\") {\n            var fixture = \"signals-sigterm.fixture.js\";\n            runMocha(fixture, args, function postmortem(err, res) {\n              if (err) {\n                return done(err);\n              }\n              expect(\n                res.code,\n                \"to be\",\n                SIGNAL_OFFSET + os.constants.signals.SIGTERM,\n              );\n              done();\n            });\n          } else {\n            done();\n          }\n        });\n\n        it(\"should exit with the correct POSIX shell code on numeric fatal signal\", function (done) {\n          // not supported on Windows\n          if (os.platform() !== \"win32\") {\n            var fixture = \"signals-sigterm-numeric.fixture.js\";\n            runMocha(fixture, args, function postmortem(err, res) {\n              if (err) {\n                return done(err);\n              }\n              expect(\n                res.code,\n                \"to be\",\n                SIGNAL_OFFSET + os.constants.signals.SIGTERM,\n              );\n              done();\n            });\n          } else {\n            done();\n          }\n        });\n\n        it(\"should exit with code 1 if there are test failures\", function (done) {\n          var fixture = \"failing.fixture.js\";\n          runMocha(fixture, args, function postmortem(err, res) {\n            if (err) {\n              return done(err);\n            }\n            expect(res.code, \"to be\", EXIT_FAILURE);\n            done();\n          });\n        });\n      });\n\n      describe(\"when mocha is run in-process\", () => {\n        // Without node-specific cli options, mocha runs in-process\n        const args = [\"--posix-exit-codes\"];\n\n        it(\"should exit with the correct POSIX shell code on SIGABRT\", function (done) {\n          var fixture = \"signals-sigabrt.fixture.js\";\n          runMocha(fixture, args, function postmortem(err, res) {\n            if (err) {\n              return done(err);\n            }\n            expect(\n              res.code,\n              \"to be\",\n              SIGNAL_OFFSET + os.constants.signals.SIGABRT,\n            );\n            done();\n          });\n        });\n\n        it(\"should exit with the correct POSIX shell code on SIGTERM\", function (done) {\n          // SIGTERM is not supported on Windows\n          if (os.platform() !== \"win32\") {\n            var fixture = \"signals-sigterm.fixture.js\";\n            runMocha(fixture, args, function postmortem(err, res) {\n              if (err) {\n                return done(err);\n              }\n              expect(\n                res.code,\n                \"to be\",\n                SIGNAL_OFFSET + os.constants.signals.SIGTERM,\n              );\n              done();\n            });\n          } else {\n            done();\n          }\n        });\n\n        it(\"should exit with code 1 if there are test failures\", function (done) {\n          var fixture = \"failing.fixture.js\";\n          runMocha(fixture, args, function postmortem(err, res) {\n            if (err) {\n              return done(err);\n            }\n            expect(res.code, \"to be\", EXIT_FAILURE);\n            done();\n          });\n        });\n      });\n    });\n\n    describe(\"when not enabled\", function () {\n      describe(\"when mocha is run as a child process\", () => {\n        // any node-specific option makes mocha run as a child process\n        var args = [\"--no-warnings\"];\n\n        it(\"should exit with the number of failed tests\", function (done) {\n          var fixture = \"failing.fixture.js\";\n          var numFailures = 3;\n          runMocha(fixture, args, function postmortem(err, res) {\n            if (err) {\n              return done(err);\n            }\n            expect(res.code, \"to be\", numFailures);\n            done();\n          });\n        });\n      });\n\n      describe(\"when mocha is run in-process\", () => {\n        var args = [];\n\n        it(\"should exit with the number of failed tests\", function (done) {\n          var fixture = \"failing.fixture.js\";\n          var numFailures = 3;\n          runMocha(fixture, args, function postmortem(err, res) {\n            if (err) {\n              return done(err);\n            }\n            expect(res.code, \"to be\", numFailures);\n            done();\n          });\n        });\n      });\n    });\n  }\n});\n"
  },
  {
    "path": "test/integration/options/reporter-option.spec.js",
    "content": "\"use strict\";\n\nvar runMocha = require(\"../helpers\").runMocha;\nvar path = require(\"node:path\");\n\ndescribe(\"--reporter-option\", function () {\n  describe(\"when given options w/ invalid format\", function () {\n    it(\"should display an error\", function (done) {\n      runMocha(\n        \"passing.fixture.js\",\n        [\"--reporter-option\", \"foo=bar=baz\"],\n        function (err, res) {\n          if (err) {\n            return done(err);\n          }\n          expect(res, \"to have failed\").and(\n            \"to contain output\",\n            /invalid reporter option/i,\n          );\n          done();\n        },\n        \"pipe\",\n      );\n    });\n\n    it(\"should allow comma-separated values\", function (done) {\n      runMocha(\n        \"passing.fixture.js\",\n        [\n          \"--reporter\",\n          path.join(\n            __dirname,\n            \"..\",\n            \"fixtures\",\n            \"options\",\n            \"reporter-with-options.fixture.js\",\n          ),\n          \"--reporter-option\",\n          \"foo=bar,baz=quux\",\n        ],\n        function (err, res) {\n          if (err) {\n            return done(err);\n          }\n          expect(res, \"to have passed\").and(\n            \"to contain output\",\n            /{\"foo\":\"bar\",\"baz\":\"quux\"}/,\n          );\n          done();\n        },\n        \"pipe\",\n      );\n    });\n\n    it(\"should allow repeated options\", function (done) {\n      runMocha(\n        \"passing.fixture.js\",\n        [\n          \"--reporter\",\n          path.join(\n            __dirname,\n            \"..\",\n            \"fixtures\",\n            \"options\",\n            \"reporter-with-options.fixture.js\",\n          ),\n          \"--reporter-option\",\n          \"foo=bar\",\n          \"--reporter-option\",\n          \"baz=quux\",\n        ],\n        function (err, res) {\n          if (err) {\n            return done(err);\n          }\n          expect(res, \"to have passed\").and(\n            \"to contain output\",\n            /{\"foo\":\"bar\",\"baz\":\"quux\"}/,\n          );\n          done();\n        },\n        \"pipe\",\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/reporter.spec.js",
    "content": "\"use strict\";\n\nvar runMocha = require(\"../helpers\").runMocha;\nvar path = require(\"node:path\");\n\ndescribe(\"--reporter\", function () {\n  it(\"should work for ESM\", function (done) {\n    runMocha(\n      \"passing.fixture.js\",\n      [\n        \"--reporter\",\n        path.join(\n          __dirname,\n          \"..\",\n          \"fixtures\",\n          \"options\",\n          \"reporter-esm.fixture.mjs\",\n        ),\n      ],\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"to have passed\");\n        done();\n      },\n      \"inherit\",\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/options/retries.spec.js",
    "content": "\"use strict\";\n\nvar path = require(\"node:path\").posix;\nvar helpers = require(\"../helpers\");\nvar runMochaJSON = helpers.runMochaJSON;\n\ndescribe(\"--retries\", function () {\n  var args = [];\n\n  it(\"should retry test failures after a certain threshold\", function (done) {\n    args = [\"--retries\", \"3\"];\n    var fixture = path.join(\"options\", \"retries\");\n    runMochaJSON(fixture, args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n      expect(res, \"to have failed\")\n        .and(\"not to have pending tests\")\n        .and(\"not to have passed tests\")\n        .and(\"to have retried test\", \"should fail\", 3);\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/sort.spec.js",
    "content": "\"use strict\";\n\nvar path = require(\"node:path\").posix;\nvar helpers = require(\"../helpers\");\nvar runMochaJSON = helpers.runMochaJSON;\n\ndescribe(\"--sort\", function () {\n  var args = [];\n\n  before(function () {\n    args = [\"--sort\"];\n  });\n\n  it(\"should sort tests in alphabetical order\", function (done) {\n    var fixtures = path.join(\"options\", \"sort*\");\n    runMochaJSON(fixtures, args, function (err, res) {\n      if (err) {\n        done(err);\n        return;\n      }\n      expect(res, \"to have passed test count\", 2).and(\n        \"to have passed test order\",\n        \"should be executed first\",\n      );\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/options/timeout.spec.js",
    "content": "\"use strict\";\n\nvar helpers = require(\"../helpers\");\nvar runMochaJSON = helpers.runMochaJSON;\n\ndescribe(\"--timeout\", function () {\n  it(\"should allow human-readable string value\", function (done) {\n    runMochaJSON(\"options/slow-test\", [\"--timeout\", \"1s\"], function (err, res) {\n      if (err) {\n        done(err);\n        return;\n      }\n      expect(res, \"to have failed\")\n        .and(\"to have passed test count\", 1)\n        .and(\"to have failed test count\", 1);\n      done();\n    });\n  });\n\n  it(\"should allow numeric value\", function (done) {\n    runMochaJSON(\n      \"options/slow-test\",\n      [\"--timeout\", \"1000\"],\n      function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res, \"to have failed\")\n          .and(\"to have passed test count\", 1)\n          .and(\"to have failed test count\", 1);\n        done();\n      },\n    );\n  });\n\n  it(\"should allow multiple values\", function (done) {\n    var fixture = \"options/slow-test\";\n    runMochaJSON(\n      fixture,\n      [\"--timeout\", \"2s\", \"--timeout\", \"1000\"],\n      function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res, \"to have failed\")\n          .and(\"to have passed test count\", 1)\n          .and(\"to have failed test count\", 1);\n        done();\n      },\n    );\n  });\n\n  it('should disable timeout with \"--inspect\"', function (done) {\n    var fixture = \"options/slow-test\";\n    runMochaJSON(\n      fixture,\n      [\"--inspect\", \"--timeout\", \"200\"],\n      function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res, \"to have passed\").and(\"to have passed test count\", 2);\n        done();\n      },\n    );\n  });\n\n  it('should disable timeout with \"-n inspect\"', function (done) {\n    var fixture = \"options/slow-test\";\n    runMochaJSON(\n      fixture,\n      [\"-n\", \"inspect\", \"--timeout\", \"200\"],\n      function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res, \"to have passed\").and(\"to have passed test count\", 2);\n        done();\n      },\n    );\n  });\n\n  it(\"should complete tests having unref'd async behavior\", function (done) {\n    runMochaJSON(\n      \"options/timeout-unref\",\n      [\"--timeout\", \"0\"],\n      function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res, \"to have passed\").and(\"to have passed test count\", 1);\n        done();\n      },\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/options/ui.spec.js",
    "content": "\"use strict\";\n\nvar helpers = require(\"../helpers\");\nvar runMochaJSON = helpers.runMochaJSON;\n\ndescribe(\"--ui\", function () {\n  var simpleUiPath = require.resolve(\"../fixtures/simple-ui.fixture.js\");\n  var simpleUiESMPath = require.resolve(\"../fixtures/simple-ui.fixture.mjs\");\n\n  it(\"should load interface and run it\", function (done) {\n    runMochaJSON(\n      \"test-for-simple-ui\",\n      [\"--ui\", simpleUiPath],\n      function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res, \"to have passed\");\n        done();\n      },\n    );\n  });\n\n  it(\"should work if required and name added to Mocha's `interfaces` prop\", function (done) {\n    runMochaJSON(\n      \"test-for-simple-ui\",\n      [\"--require\", simpleUiPath, \"--ui\", \"simple-ui\"],\n      function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res, \"to have passed\");\n        done();\n      },\n    );\n  });\n\n  it(\"should work for ESM\", function (done) {\n    runMochaJSON(\n      \"test-for-simple-ui\",\n      [\"--require\", simpleUiESMPath, \"--ui\", \"simple-ui\"],\n      function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res, \"to have passed\");\n        done();\n      },\n    );\n  });\n\n  it(\"should work for ESM when imported via path\", function (done) {\n    runMochaJSON(\n      \"test-for-simple-ui\",\n      [\"--ui\", simpleUiESMPath],\n      function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res, \"to have passed\");\n        done();\n      },\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/options/watch.spec.js",
    "content": "\"use strict\";\n\nconst fs = require(\"node:fs\");\nconst path = require(\"node:path\");\nconst {\n  copyFixture,\n  runMochaWatchJSONAsync,\n  sleep,\n  runMochaWatchAsync,\n  touchFile,\n  replaceFileContents,\n  createTempDir,\n  DEFAULT_FIXTURE,\n} = require(\"../helpers\");\n\ndescribe(\"--watch\", function () {\n  describe(\"when enabled\", function () {\n    /**\n     * @type {string}\n     */\n    let tempDir;\n    /**\n     * @type {import('../helpers').RemoveTempDirCallback}\n     */\n    let cleanup;\n\n    this.slow(5000);\n\n    beforeEach(async function () {\n      const { dirpath, removeTempDir } = await createTempDir();\n      tempDir = dirpath;\n      cleanup = removeTempDir;\n    });\n\n    afterEach(function () {\n      cleanup();\n    });\n\n    it(\"reruns test when watched test file is touched\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      return runMochaWatchJSONAsync([testFile], tempDir, () => {\n        touchFile(testFile);\n      }).then((results) => {\n        expect(results, \"to have length\", 2);\n      });\n    });\n\n    it(\"reruns test when watched test file crashes\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      replaceFileContents(testFile, \"done();\", \"done((;\");\n\n      return runMochaWatchJSONAsync([testFile], tempDir, () => {\n        replaceFileContents(testFile, \"done((;\", \"done();\");\n      }).then((results) => {\n        expect(results, \"to have length\", 1);\n      });\n    });\n\n    describe(\"when in parallel mode\", function () {\n      it(\"reruns test when watched test file is touched\", function () {\n        const testFile = path.join(tempDir, \"test.js\");\n        copyFixture(DEFAULT_FIXTURE, testFile);\n\n        return runMochaWatchJSONAsync([\"--parallel\", testFile], tempDir, () => {\n          touchFile(testFile);\n        }).then((results) => {\n          expect(results, \"to have length\", 2);\n        });\n      });\n\n      it(\"reruns test when watched test file is crashed\", function () {\n        const testFile = path.join(tempDir, \"test.js\");\n        copyFixture(DEFAULT_FIXTURE, testFile);\n\n        replaceFileContents(testFile, \"done();\", \"done((;\");\n\n        return runMochaWatchJSONAsync([testFile], tempDir, () => {\n          replaceFileContents(testFile, \"done((;\", \"done();\");\n        }).then((results) => {\n          expect(results, \"to have length\", 1);\n        });\n      });\n    });\n\n    it(\"reruns test when file matching --watch-files changes\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      const watchedFile = path.join(tempDir, \"dir/file.xyz\");\n      touchFile(watchedFile);\n\n      return runMochaWatchJSONAsync(\n        [testFile, \"--watch-files\", \"dir/*.xyz\"],\n        tempDir,\n        () => {\n          touchFile(watchedFile);\n        },\n      ).then((results) => {\n        expect(results.length, \"to equal\", 2);\n      });\n    });\n\n    it(\"reruns test when file matching --watch-files is added\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      const watchedFile = path.join(tempDir, \"lib/file.xyz\");\n      return runMochaWatchJSONAsync(\n        [testFile, \"--watch-files\", \"**/*.xyz\"],\n        tempDir,\n        () => {\n          touchFile(watchedFile);\n        },\n      ).then((results) => {\n        expect(results, \"to have length\", 2);\n      });\n    });\n\n    it(\"reruns test when file and directory paths under --watch-files are added\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      // only create 'lib', 'dir', and 'file.xyz' when watching\n      const libPath = path.join(tempDir, \"lib\");\n      const dirPath = path.join(libPath, \"dir\");\n      const watchedFile = path.join(dirPath, \"file.xyz\");\n\n      return runMochaWatchJSONAsync(\n        [testFile, \"--watch-files\", \"lib\"],\n        tempDir,\n        async () => {\n          fs.mkdirSync(libPath);\n          await sleep(1000);\n\n          fs.mkdirSync(dirPath);\n          await sleep(1000);\n\n          touchFile(watchedFile);\n        },\n      ).then((results) => {\n        expect(results, \"to have length\", 4);\n      });\n    });\n\n    it(\"reruns test when file matching --watch-files is removed\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      const watchedFile = path.join(tempDir, \"lib/file.xyz\");\n      touchFile(watchedFile);\n\n      return runMochaWatchJSONAsync(\n        [testFile, \"--watch-files\", \"lib/**/*.xyz\"],\n        tempDir,\n        () => {\n          fs.rmSync(watchedFile, { recursive: true, force: true });\n        },\n      ).then((results) => {\n        expect(results, \"to have length\", 2);\n      });\n    });\n\n    it(\"reruns test when file matching exact --watch-files changes\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      const watchedFile = path.join(tempDir, \"lib/file.xyz\");\n      touchFile(watchedFile);\n\n      return runMochaWatchJSONAsync(\n        [testFile, \"--watch-files\", \"lib/file.xyz\"],\n        tempDir,\n        () => {\n          touchFile(watchedFile);\n        },\n      ).then((results) => {\n        expect(results, \"to have length\", 2);\n      });\n    });\n\n    it(\"reruns test when file under --watch-files changes\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      const watchedFile = path.join(tempDir, \"lib/dir/file.xyz\");\n      touchFile(watchedFile);\n\n      return runMochaWatchJSONAsync(\n        [testFile, \"--watch-files\", \"lib\"],\n        tempDir,\n        () => {\n          touchFile(watchedFile);\n        },\n      ).then((results) => {\n        expect(results, \"to have length\", 2);\n      });\n    });\n\n    it(\"reruns test when file matching --watch-files starting with a glob pattern changes\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      const watchedFile = path.join(tempDir, \"lib/dir/file.xyz\");\n      touchFile(watchedFile);\n\n      return runMochaWatchJSONAsync(\n        [testFile, \"--watch-files\", \"**/lib\"],\n        tempDir,\n        () => {\n          touchFile(watchedFile);\n        },\n      ).then((results) => {\n        expect(results, \"to have length\", 2);\n      });\n    });\n\n    it(\"reruns test when file matching --watch-files ending with a glob pattern changes\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      const watchedFile = path.join(tempDir, \"lib/dir/file.xyz\");\n      touchFile(watchedFile);\n\n      return runMochaWatchJSONAsync(\n        [testFile, \"--watch-files\", \"lib/**/*\"],\n        tempDir,\n        () => {\n          touchFile(watchedFile);\n        },\n      ).then((results) => {\n        expect(results, \"to have length\", 2);\n      });\n    });\n\n    it(\"reruns test when file matching --watch-files with glob pattern in between changes\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      const watchedFile = path.join(tempDir, \"lib/dir/file.xyz\");\n      touchFile(watchedFile);\n\n      return runMochaWatchJSONAsync(\n        [testFile, \"--watch-files\", \"lib/**/dir\"],\n        tempDir,\n        () => {\n          touchFile(watchedFile);\n        },\n      ).then((results) => {\n        expect(results, \"to have length\", 2);\n      });\n    });\n\n    it(\"reruns test when file matching --watch-files outside the current working directory changes\", function () {\n      // create a subdirectory to watch as the current working directory\n      const tempCwd = path.join(tempDir, \"dir\");\n      const testFile = path.join(tempCwd, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      const watchedFile = path.join(tempDir, \"lib/file.xyz\");\n      touchFile(watchedFile);\n\n      // use an absolute path for the watch file pattern,\n      // otherwise it would be read relative to the current working directory\n      const watchFilePattern = path.join(tempDir, \"lib/**/*.xyz\");\n\n      return runMochaWatchJSONAsync(\n        [testFile, \"--watch-files\", watchFilePattern],\n        tempCwd,\n        () => {\n          touchFile(watchedFile);\n        },\n      ).then((results) => {\n        expect(results, \"to have length\", 2);\n      });\n    });\n\n    it(\"does not rerun test when file not matching --watch-files is changed\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      const watchedFile = path.join(tempDir, \"dir/file.js\");\n      touchFile(watchedFile);\n\n      return runMochaWatchJSONAsync(\n        [testFile, \"--watch-files\", \"dir/*.xyz\"],\n        tempDir,\n        () => {\n          touchFile(watchedFile);\n        },\n      ).then((results) => {\n        expect(results.length, \"to equal\", 1);\n      });\n    });\n\n    it(\"picks up new test files when they are added\", function () {\n      const testFile = path.join(tempDir, \"test/a.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      return runMochaWatchJSONAsync(\n        [\"test/**/*.js\", \"--watch-files\", \"test/**/*.js\"],\n        tempDir,\n        () => {\n          const addedTestFile = path.join(tempDir, \"test/b.js\");\n          copyFixture(\"passing\", addedTestFile);\n        },\n      ).then((results) => {\n        expect(results, \"to have length\", 2);\n        expect(results[0].passes, \"to have length\", 1);\n        expect(results[1].passes, \"to have length\", 3);\n      });\n    });\n\n    it(\"reruns test when file matching --extension is changed\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      const watchedFile = path.join(tempDir, \"file.xyz\");\n      touchFile(watchedFile);\n\n      return runMochaWatchJSONAsync(\n        [testFile, \"--extension\", \"xyz,js\"],\n        tempDir,\n        () => {\n          touchFile(watchedFile);\n        },\n      ).then((results) => {\n        expect(results, \"to have length\", 2);\n      });\n    });\n\n    it('reruns when \"rs\\\\n\" typed', function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      return runMochaWatchJSONAsync([testFile], tempDir, (mochaProcess) => {\n        mochaProcess.stdin.write(\"rs\\n\");\n      }).then((results) => {\n        expect(results, \"to have length\", 2);\n      });\n    });\n\n    it(\"reruns test when file starting with . and matching --extension is changed\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      const watchedFile = path.join(tempDir, \".file.xyz\");\n      touchFile(watchedFile);\n\n      return runMochaWatchJSONAsync(\n        [testFile, \"--extension\", \"xyz,js\"],\n        tempDir,\n        () => {\n          touchFile(watchedFile);\n        },\n      ).then((results) => {\n        expect(results, \"to have length\", 2);\n      });\n    });\n\n    it('ignores files in \"node_modules\" and \".git\" by default', function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      const nodeModulesFile = path.join(tempDir, \"node_modules\", \"file.xyz\");\n      const gitFile = path.join(tempDir, \".git\", \"file.xyz\");\n\n      touchFile(gitFile);\n      touchFile(nodeModulesFile);\n\n      return runMochaWatchJSONAsync(\n        [testFile, \"--extension\", \"xyz,js\"],\n        tempDir,\n        () => {\n          touchFile(gitFile);\n          touchFile(nodeModulesFile);\n        },\n      ).then((results) => {\n        expect(results, \"to have length\", 1);\n      });\n    });\n\n    it(\"ignores files matching --watch-ignore\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      const watchedFile = path.join(tempDir, \"dir/file-to-ignore.xyz\");\n      touchFile(watchedFile);\n\n      return runMochaWatchJSONAsync(\n        [\n          testFile,\n          \"--watch-files\",\n          \"dir/*.xyz\",\n          \"--watch-ignore\",\n          \"dir/*ignore*\",\n        ],\n        tempDir,\n        () => {\n          touchFile(watchedFile);\n        },\n      ).then((results) => {\n        expect(results.length, \"to equal\", 1);\n      });\n    });\n\n    // Workaround: escape via e.g. `dir/[[]ab[]].js`\n    it(\"ignores files whose name is the watch glob\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      const watchedFile = path.join(tempDir, \"dir/[ab].js\");\n      touchFile(watchedFile);\n\n      return runMochaWatchJSONAsync(\n        [testFile, \"--watch-files\", \"dir/[ab].js\"],\n        tempDir,\n        () => {\n          touchFile(watchedFile);\n        },\n      ).then((results) => {\n        expect(results.length, \"to equal\", 1);\n      });\n    });\n\n    it(\"reloads test files when they change\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(\"options/watch/test-file-change\", testFile);\n\n      return runMochaWatchJSONAsync(\n        [testFile, \"--watch-files\", \"**/*.js\"],\n        tempDir,\n        () => {\n          replaceFileContents(\n            testFile,\n            \"testShouldFail = true\",\n            \"testShouldFail = false\",\n          );\n        },\n      ).then((results) => {\n        expect(results, \"to have length\", 2);\n        expect(results[0].passes, \"to have length\", 0);\n        expect(results[0].failures, \"to have length\", 1);\n        expect(results[1].passes, \"to have length\", 1);\n        expect(results[1].failures, \"to have length\", 0);\n      });\n    });\n\n    it(\"reloads test dependencies when they change\", function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(\"options/watch/test-with-dependency\", testFile);\n\n      const dependency = path.join(tempDir, \"lib\", \"dependency.js\");\n      copyFixture(\"options/watch/dependency\", dependency);\n\n      return runMochaWatchJSONAsync(\n        [testFile, \"--watch-files\", \"lib/**/*.js\"],\n        tempDir,\n        () => {\n          replaceFileContents(\n            dependency,\n            \"module.exports.testShouldFail = false\",\n            \"module.exports.testShouldFail = true\",\n          );\n        },\n      ).then((results) => {\n        expect(results, \"to have length\", 2);\n        expect(results[0].passes, \"to have length\", 1);\n        expect(results[0].failures, \"to have length\", 0);\n        expect(results[1].passes, \"to have length\", 0);\n        expect(results[1].failures, \"to have length\", 1);\n      });\n    });\n\n    // Regression test for https://github.com/mochajs/mocha/issues/2027\n    it(\"respects --fgrep on re-runs\", async function () {\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(\"options/grep\", testFile);\n\n      return expect(\n        runMochaWatchJSONAsync([testFile, \"--fgrep\", \"match\"], tempDir, () => {\n          touchFile(testFile);\n        }),\n        \"when fulfilled\",\n        \"to satisfy\",\n        {\n          length: 2,\n          0: { tests: expect.it(\"to have length\", 2) },\n          1: { tests: expect.it(\"to have length\", 2) },\n        },\n      );\n    });\n\n    describe(\"with required hooks\", function () {\n      /**\n       * Helper for setting up hook tests\n       *\n       * @param {string} hookName name of hook to test\n       * @return {function}\n       */\n      function setupHookTest(hookName) {\n        return function () {\n          const testFile = path.join(tempDir, \"test.js\");\n          const hookFile = path.join(tempDir, \"hook.js\");\n\n          copyFixture(\"__default__\", testFile);\n          copyFixture(\"options/watch/hook\", hookFile);\n\n          replaceFileContents(hookFile, \"<hook>\", hookName);\n\n          return runMochaWatchJSONAsync(\n            [testFile, \"--require\", hookFile],\n            tempDir,\n            () => {\n              touchFile(testFile);\n            },\n          ).then((results) => {\n            expect(results.length, \"to equal\", 2);\n            expect(results[0].failures, \"to have length\", 1);\n            expect(results[1].failures, \"to have length\", 1);\n          });\n        };\n      }\n\n      it(\"mochaHooks.beforeAll runs as expected\", setupHookTest(\"beforeAll\"));\n      it(\"mochaHooks.beforeEach runs as expected\", setupHookTest(\"beforeEach\"));\n      it(\"mochaHooks.afterAll runs as expected\", setupHookTest(\"afterAll\"));\n      it(\"mochaHooks.afterEach runs as expected\", setupHookTest(\"afterEach\"));\n    });\n\n    it(\"should not leak event listeners\", function () {\n      this.timeout(20000);\n      const testFile = path.join(tempDir, \"test.js\");\n      copyFixture(DEFAULT_FIXTURE, testFile);\n\n      return expect(\n        runMochaWatchAsync(\n          [testFile],\n          { cwd: tempDir, stdio: \"pipe\" },\n          async () => {\n            // we want to cause _n + 1_ reruns, which should cause the warning\n            // to occur if the listeners aren't properly destroyed\n            const iterations = new Array(process.getMaxListeners() + 1);\n            // eslint-disable-next-line no-unused-vars\n            for await (const _ of iterations) {\n              touchFile(testFile);\n              await sleep(1000);\n            }\n          },\n        ),\n        \"when fulfilled\",\n        \"to satisfy\",\n        {\n          output: expect.it(\"not to match\", /MaxListenersExceededWarning/),\n        },\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/parallel.spec.js",
    "content": "\"use strict\";\n\nconst assert = require(\"node:assert\");\nconst { runMochaJSONAsync } = require(\"./helpers\");\n\ndescribe(\"parallel run\", () => {\n  /**\n   * @see https://github.com/mochajs/mocha/issues/4559\n   */\n  it('should allow `import {it} from \"mocha\"` module syntax', async () => {\n    const result = await runMochaJSONAsync(\"parallel/test3.mjs\", [\n      \"--parallel\",\n      \"--jobs\",\n      \"2\",\n      require.resolve(\"./fixtures/parallel/test1.mjs\"),\n      require.resolve(\"./fixtures/parallel/test2.mjs\"),\n    ]);\n    assert.strictEqual(result.stats.failures, 1);\n    assert.strictEqual(result.stats.passes, 2);\n  });\n\n  it(\"should correctly set worker ids for each process\", async () => {\n    const result = await runMochaJSONAsync(\"parallel/testworkerid3.mjs\", [\n      \"--parallel\",\n      \"--jobs\",\n      \"2\",\n      require.resolve(\"./fixtures/parallel/testworkerid1.mjs\"),\n      require.resolve(\"./fixtures/parallel/testworkerid2.mjs\"),\n    ]);\n    assert.strictEqual(result.stats.failures, 0);\n    assert.strictEqual(result.stats.passes, 3);\n  });\n\n  it(\"should correctly handle circular array references in an exception\", async () => {\n    const result = await runMochaJSONAsync(\n      \"parallel/circular-error-array.mjs\",\n      [\n        \"--parallel\",\n        \"--jobs\",\n        \"2\",\n        require.resolve(\"./fixtures/parallel/testworkerid1.mjs\"),\n      ],\n    );\n    assert.strictEqual(result.stats.failures, 1);\n    assert.strictEqual(result.stats.passes, 1);\n    assert.strictEqual(result.failures[0].err.message, \"Foo\");\n    assert.strictEqual(result.failures[0].err.foo.props[0], \"[Circular]\");\n  });\n\n  it(\"should correctly handle an exception with retries\", async () => {\n    const result = await runMochaJSONAsync(\n      \"parallel/circular-error-array.mjs\",\n      [\n        \"--parallel\",\n        \"--jobs\",\n        \"2\",\n        \"--retries\",\n        \"1\",\n        require.resolve(\"./fixtures/parallel/testworkerid1.mjs\"),\n      ],\n    );\n    assert.strictEqual(result.stats.failures, 1);\n    assert.strictEqual(result.stats.passes, 1);\n    assert.strictEqual(result.failures[0].err.message, \"Foo\");\n    assert.strictEqual(result.failures[0].err.foo.props[0], \"[Circular]\");\n  });\n\n  it(\"should correctly handle circular object references in an exception\", async () => {\n    const result = await runMochaJSONAsync(\n      \"parallel/circular-error-object.mjs\",\n      [\n        \"--parallel\",\n        \"--jobs\",\n        \"2\",\n        require.resolve(\"./fixtures/parallel/testworkerid1.mjs\"),\n      ],\n    );\n    assert.strictEqual(result.stats.failures, 1);\n    assert.strictEqual(result.stats.passes, 1);\n    assert.strictEqual(result.failures[0].err.message, \"Oh no!\");\n    assert.deepStrictEqual(result.failures[0].err.values, [\n      { toB: { toA: \"[Circular]\" } },\n    ]);\n  });\n\n  it(\"should correctly handle a non-writable getter reference in an exception\", async () => {\n    const result = await runMochaJSONAsync(\"parallel/getter-error-object.mjs\", [\n      \"--parallel\",\n      \"--jobs\",\n      \"2\",\n      require.resolve(\"./fixtures/parallel/testworkerid1.mjs\"),\n    ]);\n    assert.strictEqual(result.stats.failures, 1);\n    assert.strictEqual(result.stats.passes, 1);\n    assert.strictEqual(result.failures[0].err.message, \"Oh no!\");\n  });\n});\n"
  },
  {
    "path": "test/integration/pending.spec.js",
    "content": "\"use strict\";\n\nvar assert = require(\"node:assert\");\nvar helpers = require(\"./helpers\");\nvar run = helpers.runMochaJSON;\nvar invokeNode = helpers.invokeNode;\nvar toJSONResult = helpers.toJSONResult;\nvar args = [];\n\ndescribe(\"pending\", function () {\n  describe(\"pending specs\", function () {\n    it(\"should be created by omitting a function\", function (done) {\n      run(\"pending/spec.fixture.js\", args, function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        assert.strictEqual(res.stats.pending, 1);\n        assert.strictEqual(res.stats.passes, 0);\n        assert.strictEqual(res.stats.failures, 0);\n        assert.strictEqual(res.code, 0);\n        done();\n      });\n    });\n    it(\"should return the test object when used via shorthand methods\", function (done) {\n      run(\"pending/skip-shorthand.fixture.js\", args, function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        assert.strictEqual(res.stats.pending, 3);\n        assert.strictEqual(res.stats.passes, 0);\n        assert.strictEqual(res.stats.failures, 0);\n        assert.strictEqual(res.code, 0);\n        done();\n      });\n    });\n    it(\"should keep hierarchies of suites\", function (done) {\n      run(\"pending/skip-hierarchy.fixture.js\", args, function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        assert.strictEqual(res.stats.suites, 2);\n        assert.strictEqual(res.stats.pending, 0);\n        assert.strictEqual(res.stats.passes, 1);\n        assert.strictEqual(res.stats.failures, 0);\n        assert.strictEqual(res.code, 0);\n        assert.strictEqual(\n          res.passes[0].fullTitle,\n          \"a suite another suite a test\",\n        );\n        done();\n      });\n    });\n  });\n\n  describe(\"synchronous skip()\", function () {\n    describe(\"in spec\", function () {\n      it(\"should immediately skip the spec and run all others\", function (done) {\n        run(\"pending/skip-sync-spec.fixture.js\", args, function (err, res) {\n          if (err) {\n            return done(err);\n          }\n          expect(res, \"to have failed with error\", \"should throw this error\")\n            .and(\"to have failed test count\", 1)\n            .and(\"to have pending test count\", 1)\n            .and(\"to have pending test order\", \"should skip immediately\")\n            .and(\"to have passed test count\", 1)\n            .and(\"to have passed tests\", \"should run other tests in suite\");\n          done();\n        });\n      });\n    });\n\n    describe(\"in after\", function () {\n      it(\"should throw, but run all tests\", function (done) {\n        run(\"pending/skip-sync-after.fixture.js\", args, function (err, res) {\n          if (err) {\n            return done(err);\n          }\n          expect(res, \"to have failed with error\", \"`this.skip` forbidden\")\n            .and(\"to have failed test count\", 1)\n            .and(\"to have pending test count\", 0)\n            .and(\"to have passed test count\", 3)\n            .and(\n              \"to have passed test order\",\n              \"should run this test-1\",\n              \"should run this test-2\",\n              \"should run this test-3\",\n            );\n          done();\n        });\n      });\n    });\n\n    describe(\"in before\", function () {\n      it(\"should skip all suite specs\", function (done) {\n        run(\"pending/skip-sync-before.fixture.js\", args, function (err, res) {\n          if (err) {\n            done(err);\n            return;\n          }\n          assert.strictEqual(res.stats.pending, 2);\n          assert.strictEqual(res.stats.passes, 2);\n          assert.strictEqual(res.stats.failures, 0);\n          assert.strictEqual(res.code, 0);\n          done();\n        });\n      });\n      it(\"should run before and after hooks\", function (done) {\n        run(\"pending/skip-sync-before-hooks.fixture.js\", function (err, res) {\n          if (err) {\n            return done(err);\n          }\n          expect(res, \"to have failed with error\", \"should throw this error\")\n            .and(\"to have failed test count\", 1)\n            .and(\"to have pending test count\", 2)\n            .and(\"to have passed test count\", 2)\n            .and(\n              \"to have passed test order\",\n              \"should run test-1\",\n              \"should run test-2\",\n            );\n          done();\n        });\n      });\n      it(\"should skip all sync/async inner before/after hooks\", function (done) {\n        run(\"pending/skip-sync-before-inner.fixture.js\", function (err, res) {\n          if (err) {\n            return done(err);\n          }\n          expect(res, \"to have failed with error\", \"should throw this error\")\n            .and(\"to have failed test count\", 1)\n            .and(\"to have pending test count\", 2)\n            .and(\"to have passed test count\", 0)\n            .and(\n              \"to have pending test order\",\n              \"should never run this outer test\",\n              \"should never run this inner test\",\n            );\n          done();\n        });\n      });\n    });\n\n    describe(\"in before with nested describe\", function () {\n      it(\"should skip all suite specs, even if nested\", function (done) {\n        run(\n          \"pending/skip-sync-before-nested.fixture.js\",\n          args,\n          function (err, res) {\n            if (err) {\n              done(err);\n              return;\n            }\n            assert.strictEqual(res.stats.pending, 3);\n            assert.strictEqual(res.stats.passes, 0);\n            assert.strictEqual(res.stats.failures, 0);\n            assert.strictEqual(res.code, 0);\n            done();\n          },\n        );\n      });\n    });\n\n    describe(\"in beforeEach\", function () {\n      it(\"should skip all suite specs\", function (done) {\n        var fixture = \"pending/skip-sync-beforeEach.fixture.js\";\n        run(fixture, args, function (err, res) {\n          if (err) {\n            return done(err);\n          }\n          expect(res, \"to have failed with error\", \"should throw this error\")\n            .and(\"to have failed test count\", 1)\n            .and(\"to have pending test count\", 3)\n            .and(\n              \"to have pending test order\",\n              \"should skip this test-1\",\n              \"should skip this test-2\",\n              \"should skip this test-3\",\n            )\n            .and(\"to have passed test count\", 0);\n          done();\n        });\n      });\n      it(\"should skip only two suite specs\", function (done) {\n        var fixture = \"pending/skip-sync-beforeEach-cond.fixture.js\";\n        run(fixture, args, function (err, res) {\n          if (err) {\n            return done(err);\n          }\n          expect(res, \"to have failed with error\", \"should throw this error\")\n            .and(\"to have failed test count\", 1)\n            .and(\"to have pending test count\", 2)\n            .and(\n              \"to have pending test order\",\n              \"should skip this test-1\",\n              \"should skip this test-3\",\n            )\n            .and(\"to have passed test count\", 1)\n            .and(\"to have passed test\", \"should run this test-2\");\n          done();\n        });\n      });\n    });\n  });\n\n  describe(\"asynchronous skip()\", function () {\n    describe(\"in spec\", function () {\n      it(\"should immediately skip the spec and run all others\", function (done) {\n        run(\"pending/skip-async-spec.fixture.js\", args, function (err, res) {\n          if (err) {\n            return done(err);\n          }\n          expect(res, \"to have failed with error\", \"should throw this error\")\n            .and(\"to have failed test count\", 1)\n            .and(\"to have pending test count\", 1)\n            .and(\"to have pending test order\", \"should skip async\")\n            .and(\"to have passed test count\", 1)\n            .and(\"to have passed tests\", \"should run other tests in suite\");\n          done();\n        });\n      });\n    });\n\n    describe(\"in before\", function () {\n      it(\"should skip all suite specs\", function (done) {\n        run(\"pending/skip-async-before.fixture.js\", args, function (err, res) {\n          if (err) {\n            done(err);\n            return;\n          }\n          assert.strictEqual(res.stats.pending, 2);\n          assert.strictEqual(res.stats.passes, 2);\n          assert.strictEqual(res.stats.failures, 0);\n          assert.strictEqual(res.code, 0);\n          done();\n        });\n      });\n      it(\"should run before and after hooks\", function (done) {\n        run(\"pending/skip-async-before-hooks.fixture.js\", function (err, res) {\n          if (err) {\n            return done(err);\n          }\n          expect(res, \"to have failed with error\", \"should throw this error\")\n            .and(\"to have failed test count\", 1)\n            .and(\"to have pending test count\", 2)\n            .and(\"to have passed test count\", 2)\n            .and(\n              \"to have passed test order\",\n              \"should run test-1\",\n              \"should run test-2\",\n            );\n          done();\n        });\n      });\n    });\n\n    describe(\"in before with nested describe\", function () {\n      it(\"should skip all suite specs, even if nested\", function (done) {\n        run(\n          \"pending/skip-async-before-nested.fixture.js\",\n          args,\n          function (err, res) {\n            if (err) {\n              done(err);\n              return;\n            }\n            assert.strictEqual(res.stats.pending, 3);\n            assert.strictEqual(res.stats.passes, 0);\n            assert.strictEqual(res.stats.failures, 0);\n            assert.strictEqual(res.code, 0);\n            done();\n          },\n        );\n      });\n    });\n\n    describe(\"in beforeEach\", function () {\n      it(\"should skip all suite specs\", function (done) {\n        var fixture = \"pending/skip-async-beforeEach.fixture.js\";\n        run(fixture, args, function (err, res) {\n          if (err) {\n            return done(err);\n          }\n          expect(res, \"to have failed with error\", \"should throw this error\")\n            .and(\"to have failed test count\", 1)\n            .and(\"to have pending test count\", 3)\n            .and(\n              \"to have pending test order\",\n              \"should skip this test-1\",\n              \"should skip this test-2\",\n              \"should skip this test-3\",\n            )\n            .and(\"to have passed test count\", 0);\n          done();\n        });\n      });\n    });\n  });\n\n  describe(\"programmatic usage\", function () {\n    it(\"should skip the test by listening to test event\", function (done) {\n      var path = require.resolve(\"./fixtures/pending/programmatic.fixture.js\");\n      invokeNode([path], function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        var result = toJSONResult(res);\n        expect(result, \"to have passed\")\n          .and(\"to have passed test count\", 0)\n          .and(\"to have pending test count\", 1)\n          .and(\"to have pending test order\", \"should succeed\");\n        done();\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/plugins/global-fixtures.spec.js",
    "content": "\"use strict\";\n\nconst path = require(\"node:path\");\nconst {\n  touchFile,\n  runMochaAsync,\n  runMochaWatchAsync,\n  copyFixture,\n  DEFAULT_FIXTURE,\n  resolveFixturePath,\n  createTempDir,\n} = require(\"../helpers\");\n\ndescribe(\"global setup/teardown\", function () {\n  describe(\"when mocha run in serial mode\", function () {\n    it(\"should execute global setup and teardown\", async function () {\n      return expect(\n        runMochaAsync(DEFAULT_FIXTURE, [\n          \"--require\",\n          resolveFixturePath(\"plugins/global-fixtures/global-setup-teardown\"),\n        ]),\n        \"when fulfilled\",\n        \"to have passed\",\n      );\n    });\n\n    describe(\"when only global teardown is supplied\", function () {\n      it(\"should run global teardown\", async function () {\n        return expect(\n          runMochaAsync(DEFAULT_FIXTURE, [\n            \"--require\",\n            resolveFixturePath(\"plugins/global-fixtures/global-teardown\"),\n          ]),\n          \"when fulfilled\",\n          \"to contain once\",\n          /teardown schmeardown/,\n        );\n      });\n    });\n\n    describe(\"when only global setup is supplied\", function () {\n      it(\"should run global setup\", async function () {\n        return expect(\n          runMochaAsync(DEFAULT_FIXTURE, [\n            \"--require\",\n            resolveFixturePath(\"plugins/global-fixtures/global-setup\"),\n          ]),\n          \"when fulfilled\",\n          \"to contain once\",\n          /setup schmetup/,\n        );\n      });\n    });\n\n    it(\"should share context\", async function () {\n      return expect(\n        runMochaAsync(DEFAULT_FIXTURE, [\n          \"--require\",\n          resolveFixturePath(\"plugins/global-fixtures/global-setup-teardown\"),\n        ]),\n        \"when fulfilled\",\n        \"to contain once\",\n        /setup: this\\.foo = bar[\\s\\S]+teardown: this\\.foo = bar/,\n      );\n    });\n\n    describe(\"when supplied multiple functions\", function () {\n      it(\"should execute them sequentially\", async function () {\n        return expect(\n          runMochaAsync(DEFAULT_FIXTURE, [\n            \"--require\",\n            resolveFixturePath(\n              \"plugins/global-fixtures/global-setup-teardown-multiple\",\n            ),\n          ]),\n          \"when fulfilled\",\n          \"to contain once\",\n          /teardown: this.foo = 3/,\n        );\n      });\n    });\n\n    describe(\"when run in watch mode\", function () {\n      let tempDir;\n      let testFile;\n      let removeTempDir;\n\n      beforeEach(async function () {\n        const tempInfo = await createTempDir();\n        tempDir = tempInfo.dirpath;\n        removeTempDir = tempInfo.removeTempDir;\n        testFile = path.join(tempDir, \"test.js\");\n        copyFixture(DEFAULT_FIXTURE, testFile);\n      });\n\n      afterEach(async function () {\n        if (removeTempDir) {\n          return removeTempDir();\n        }\n      });\n\n      it(\"should execute global setup and teardown\", async function () {\n        return expect(\n          runMochaWatchAsync(\n            [\n              \"--require\",\n              resolveFixturePath(\n                \"plugins/global-fixtures/global-setup-teardown\",\n              ),\n              testFile,\n            ],\n            tempDir,\n            () => {\n              touchFile(testFile);\n            },\n          ),\n          \"when fulfilled\",\n          \"to have passed\",\n        );\n      });\n\n      describe(\"when only global teardown is supplied\", function () {\n        it(\"should run global teardown\", async function () {\n          return expect(\n            runMochaWatchAsync(\n              [\n                \"--require\",\n                resolveFixturePath(\"plugins/global-fixtures/global-teardown\"),\n                testFile,\n              ],\n              tempDir,\n              () => {\n                touchFile(testFile);\n              },\n            ),\n            \"when fulfilled\",\n            \"to contain once\",\n            /teardown schmeardown/,\n          );\n        });\n      });\n\n      describe(\"when only global setup is supplied\", function () {\n        it(\"should run global setup\", async function () {\n          return expect(\n            runMochaWatchAsync(\n              [\n                \"--require\",\n                resolveFixturePath(\"plugins/global-fixtures/global-setup\"),\n                testFile,\n              ],\n              tempDir,\n              () => {\n                touchFile(testFile);\n              },\n            ),\n            \"when fulfilled\",\n            \"to contain once\",\n            /setup schmetup/,\n          );\n        });\n      });\n\n      it(\"should not re-execute the global fixtures\", async function () {\n        return expect(\n          runMochaWatchAsync(\n            [\n              \"--require\",\n              resolveFixturePath(\n                \"plugins/global-fixtures/global-setup-teardown-multiple\",\n              ),\n              testFile,\n            ],\n            tempDir,\n            () => {\n              touchFile(testFile);\n            },\n          ),\n          \"when fulfilled\",\n          \"to contain once\",\n          /teardown: this.foo = 3/,\n        );\n      });\n    });\n  });\n\n  describe(\"when mocha run in parallel mode\", function () {\n    it(\"should execute global setup and teardown\", async function () {\n      return expect(\n        runMochaAsync(DEFAULT_FIXTURE, [\n          \"--parallel\",\n          \"--require\",\n          resolveFixturePath(\"plugins/global-fixtures/global-setup-teardown\"),\n        ]),\n        \"when fulfilled\",\n        \"to have passed\",\n      );\n    });\n\n    it(\"should share context\", async function () {\n      return expect(\n        runMochaAsync(DEFAULT_FIXTURE, [\n          \"--parallel\",\n          \"--require\",\n          resolveFixturePath(\"plugins/global-fixtures/global-setup-teardown\"),\n        ]),\n        \"when fulfilled\",\n        \"to contain once\",\n        /setup: this.foo = bar/,\n      ).and(\"when fulfilled\", \"to contain once\", /teardown: this.foo = bar/);\n    });\n\n    describe(\"when supplied multiple functions\", function () {\n      it(\"should execute them sequentially\", async function () {\n        return expect(\n          runMochaAsync(DEFAULT_FIXTURE, [\n            \"--parallel\",\n            \"--require\",\n            resolveFixturePath(\n              \"plugins/global-fixtures/global-setup-teardown-multiple\",\n            ),\n          ]),\n          \"when fulfilled\",\n          \"to contain once\",\n          /teardown: this.foo = 3/,\n        );\n      });\n    });\n\n    describe(\"when run in watch mode\", function () {\n      let tempDir;\n      let testFile;\n      let removeTempDir;\n\n      beforeEach(async function () {\n        const tempInfo = await createTempDir();\n        tempDir = tempInfo.dirpath;\n        removeTempDir = tempInfo.removeTempDir;\n        testFile = path.join(tempDir, \"test.js\");\n        copyFixture(DEFAULT_FIXTURE, testFile);\n      });\n\n      afterEach(async function () {\n        if (removeTempDir) {\n          return removeTempDir();\n        }\n      });\n\n      it(\"should execute global setup and teardown\", async function () {\n        return expect(\n          runMochaWatchAsync(\n            [\n              \"--parallel\",\n              \"--require\",\n              resolveFixturePath(\n                \"plugins/global-fixtures/global-setup-teardown\",\n              ),\n              testFile,\n            ],\n            tempDir,\n            () => {\n              touchFile(testFile);\n            },\n          ),\n          \"when fulfilled\",\n          \"to have passed\",\n        );\n      });\n\n      it(\"should not re-execute the global fixtures\", async function () {\n        return expect(\n          runMochaWatchAsync(\n            [\n              \"--parallel\",\n              \"--require\",\n              resolveFixturePath(\n                \"plugins/global-fixtures/global-setup-teardown-multiple\",\n              ),\n              testFile,\n            ],\n            tempDir,\n            () => {\n              touchFile(testFile);\n            },\n          ),\n          \"when fulfilled\",\n          \"to contain once\",\n          /teardown: this.foo = 3/,\n        );\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/plugins/root-hooks.spec.js",
    "content": "\"use strict\";\n\nvar invokeMochaAsync = require(\"../helpers\").invokeMochaAsync;\nconst semver = require(\"semver\");\n\n/**\n * Extracts root hook log messages from run results\n * `root-hook-defs-*` fixtures are root hook plugins which call `console.log()`\n * for verification that they have been run.\n * @param {RawResult} res - result of invokeMochaAsync()\n */\nfunction extractHookOutputFromResult(res) {\n  return res.output\n    .trim()\n    .split(\"\\n\")\n    .filter(function (line) {\n      // every line that begins with whitespace (e.g., the test name) should be ignored;\n      // we just want the console.log messages\n      return /^\\S/.test(line);\n    })\n    .sort();\n}\n\n/**\n * Helper to call Mocha and pipe the result through `extractHookOutputFromResult`\n * @param {*} args - args for invokeMochaAsync\n * @param {*} opts - opts for invokeMochaAsync\n */\nfunction runMochaForHookOutput(args, opts) {\n  return invokeMochaAsync(args, opts)[1].then(extractHookOutputFromResult);\n}\n\ndescribe(\"root hooks\", function () {\n  describe(\"when mocha run in serial mode\", function () {\n    it(\"should run root hooks when provided via mochaHooks object export\", function () {\n      return expect(\n        runMochaForHookOutput([\n          \"--require=\" +\n            require.resolve(\"../fixtures/plugins/root-hooks/root-hook-defs-a.fixture.js\"),\n          \"--require=\" +\n            require.resolve(\"../fixtures/plugins/root-hooks/root-hook-defs-b.fixture.js\"),\n          require.resolve(\"../fixtures/plugins/root-hooks/root-hook-test.fixture.js\"),\n        ]),\n        \"to be fulfilled with\",\n        [\n          \"afterAll\",\n          \"afterAll array 1\",\n          \"afterAll array 2\",\n          \"afterEach\",\n          \"afterEach array 1\",\n          \"afterEach array 2\",\n          \"beforeAll\",\n          \"beforeAll array 1\",\n          \"beforeAll array 2\",\n          \"beforeEach\",\n          \"beforeEach array 1\",\n          \"beforeEach array 2\",\n        ],\n      );\n    });\n\n    it(\"should run root hooks when provided via mochaHooks function export\", function () {\n      return expect(\n        runMochaForHookOutput([\n          \"--require=\" +\n            require.resolve(\"../fixtures/plugins/root-hooks/root-hook-defs-c.fixture.js\"),\n          \"--require=\" +\n            require.resolve(\"../fixtures/plugins/root-hooks/root-hook-defs-d.fixture.js\"),\n          require.resolve(\"../fixtures/plugins/root-hooks/root-hook-test.fixture.js\"),\n        ]),\n        \"to be fulfilled with\",\n        [\n          \"afterAll\",\n          \"afterAll array 1\",\n          \"afterAll array 2\",\n          \"afterEach\",\n          \"afterEach array 1\",\n          \"afterEach array 2\",\n          \"beforeAll\",\n          \"beforeAll array 1\",\n          \"beforeAll array 2\",\n          \"beforeEach\",\n          \"beforeEach array 1\",\n          \"beforeEach array 2\",\n        ],\n      );\n    });\n\n    describe(\"support ESM when type=module or .mjs extension\", function () {\n      it(\"should run root hooks when provided via mochaHooks\", function () {\n        return expect(\n          runMochaForHookOutput([\n            \"--require=\" +\n              require.resolve(\n                // as object\n                \"../fixtures/plugins/root-hooks/root-hook-defs-esm.fixture.mjs\",\n              ),\n            \"--require=\" +\n              require.resolve(\n                // as function\n                \"../fixtures/plugins/root-hooks/esm/root-hook-defs-esm.fixture.js\",\n              ),\n            \"--require=\" +\n              require.resolve(\n                // mixed with commonjs\n                \"../fixtures/plugins/root-hooks/root-hook-defs-a.fixture.js\",\n              ),\n            require.resolve(\"../fixtures/plugins/root-hooks/root-hook-test.fixture.js\"),\n          ]),\n          \"to be fulfilled with\",\n          [\n            \"afterAll\",\n            \"afterEach\",\n            \"beforeAll\",\n            \"beforeEach\",\n            \"esm afterEach\",\n            \"esm beforeEach\",\n            \"mjs afterAll\",\n            \"mjs beforeAll\",\n          ],\n        );\n      });\n    });\n\n    describe(\"support ESM via .js extension w/o type=module\", function () {\n      // --(no-)experimental-detect-module was experimental when these tests were written\n      // https://nodejs.org/api/cli.html#--no-experimental-detect-module\n      // https://nodejs.org/api/packages.html#syntax-detection\n      // (introduced in Node 20.10.0, 21.1.0)\n      // newer versions of Node no longer fail :)\n      function isNewerVersion(vString) {\n        // Latest versions considered \"older\": 18.20.8, 20.18.3, 22.11.0\n        // (May update after writing)\n        return semver.satisfies(vString, \"^20.19.0 || ^22.12.0 || ^24.0.0\");\n      }\n\n      describe(\"on older versions, should fail due to ambiguous file type\", function () {\n        // --(no-)experimental-detect-module was experimental when these tests were written\n        // (introduced in Node 20.10.0, 21.1.0)\n        // newer versions of Node no longer fail :)\n        if (isNewerVersion(process.versions.node)) {\n          return true; // skip suite on newer Node versions\n        }\n\n        const filename =\n          \"../fixtures/plugins/root-hooks/root-hook-defs-esm-broken.fixture.js\";\n        const noDetectModuleRegex = /SyntaxError: Unexpected token/;\n        const detectModuleRegex = /Cannot require\\(\\) ES Module/;\n\n        it(\"with --no-experimental-detect-module\", function () {\n          return expect(\n            invokeMochaAsync(\n              [\n                \"--require=\" + require.resolve(filename), // as object\n                \"--no-experimental-detect-module\",\n              ],\n              \"pipe\",\n            )[1],\n            \"when fulfilled\",\n            \"to contain output\",\n            noDetectModuleRegex,\n          );\n        });\n\n        it(\"with --experimental-detect-module\", function () {\n          // --experimental-detect-module was introduced in Node 20.10.0, 21.1.0\n          // adding the flag to older versions of Node does nothing\n          const expectedRegex =\n            process.version >= \"v21.1.0\"\n              ? detectModuleRegex\n              : noDetectModuleRegex;\n          return expect(\n            invokeMochaAsync(\n              [\n                \"--require=\" + require.resolve(filename), // as object\n                \"--experimental-detect-module\",\n              ],\n              \"pipe\",\n            )[1],\n            \"when fulfilled\",\n            \"to contain output\",\n            expectedRegex,\n          );\n        });\n      });\n\n      describe(\"on newer versions, should work\", function () {\n        if (!isNewerVersion(process.versions.node)) {\n          return true; // skip suite on older Node versions\n        }\n\n        const filename =\n          \"../fixtures/plugins/root-hooks/root-hook-defs-esm-broken.fixture.js\";\n        const runSuccessRegex = /0 passing/;\n\n        it(\"with --no-experimental-detect-module\", function () {\n          return expect(\n            invokeMochaAsync(\n              [\n                \"--require=\" + require.resolve(filename), // as object\n                \"--no-experimental-detect-module\",\n              ],\n              \"pipe\",\n            )[1],\n            \"when fulfilled\",\n            \"to contain output\",\n            runSuccessRegex,\n          );\n        });\n\n        it(\"with --experimental-detect-module\", function () {\n          return expect(\n            invokeMochaAsync(\n              [\n                \"--require=\" + require.resolve(filename), // as object\n                // enabled by default in these newer versions, but clearer to use it explicitly\n                \"--experimental-detect-module\",\n              ],\n              \"pipe\",\n            )[1],\n            \"when fulfilled\",\n            \"to contain output\",\n            runSuccessRegex,\n          );\n        });\n      });\n    });\n  });\n\n  describe(\"when mocha in parallel mode\", function () {\n    it(\"should run root hooks when provided via mochaHooks object exports\", function () {\n      return expect(\n        runMochaForHookOutput([\n          \"--require=\" +\n            require.resolve(\"../fixtures/plugins/root-hooks/root-hook-defs-a.fixture.js\"),\n          \"--require=\" +\n            require.resolve(\"../fixtures/plugins/root-hooks/root-hook-defs-b.fixture.js\"),\n          \"--parallel\",\n          require.resolve(\"../fixtures/plugins/root-hooks/root-hook-test.fixture.js\"),\n        ]),\n        \"to be fulfilled with\",\n        [\n          \"afterAll\",\n          \"afterAll array 1\",\n          \"afterAll array 2\",\n          \"afterEach\",\n          \"afterEach array 1\",\n          \"afterEach array 2\",\n          \"beforeAll\",\n          \"beforeAll array 1\",\n          \"beforeAll array 2\",\n          \"beforeEach\",\n          \"beforeEach array 1\",\n          \"beforeEach array 2\",\n        ],\n      );\n    });\n\n    it(\"should run root hooks when provided via mochaHooks function export\", function () {\n      return expect(\n        runMochaForHookOutput([\n          \"--require=\" +\n            require.resolve(\"../fixtures/plugins/root-hooks/root-hook-defs-c.fixture.js\"),\n          \"--require=\" +\n            require.resolve(\"../fixtures/plugins/root-hooks/root-hook-defs-d.fixture.js\"),\n          \"--parallel\",\n          require.resolve(\"../fixtures/plugins/root-hooks/root-hook-test.fixture.js\"),\n        ]),\n        \"to be fulfilled with\",\n        [\n          \"afterAll\",\n          \"afterAll array 1\",\n          \"afterAll array 2\",\n          \"afterEach\",\n          \"afterEach array 1\",\n          \"afterEach array 2\",\n          \"beforeAll\",\n          \"beforeAll array 1\",\n          \"beforeAll array 2\",\n          \"beforeEach\",\n          \"beforeEach array 1\",\n          \"beforeEach array 2\",\n        ],\n      );\n    });\n\n    describe(\"when running multiple jobs\", function () {\n      it(\"should run root hooks when provided via mochaHooks object exports for each job\", function () {\n        return expect(\n          runMochaForHookOutput([\n            \"--require=\" +\n              require.resolve(\"../fixtures/plugins/root-hooks/root-hook-defs-a.fixture.js\"),\n            \"--require=\" +\n              require.resolve(\"../fixtures/plugins/root-hooks/root-hook-defs-b.fixture.js\"),\n            \"--parallel\",\n            require.resolve(\"../fixtures/plugins/root-hooks/root-hook-test.fixture.js\"),\n            require.resolve(\"../fixtures/plugins/root-hooks/root-hook-test-2.fixture.js\"),\n          ]),\n          \"to be fulfilled with\",\n          [\n            \"afterAll\",\n            \"afterAll\",\n            \"afterAll array 1\",\n            \"afterAll array 1\",\n            \"afterAll array 2\",\n            \"afterAll array 2\",\n            \"afterEach\",\n            \"afterEach\",\n            \"afterEach array 1\",\n            \"afterEach array 1\",\n            \"afterEach array 2\",\n            \"afterEach array 2\",\n            \"beforeAll\",\n            \"beforeAll\",\n            \"beforeAll array 1\",\n            \"beforeAll array 1\",\n            \"beforeAll array 2\",\n            \"beforeAll array 2\",\n            \"beforeEach\",\n            \"beforeEach\",\n            \"beforeEach array 1\",\n            \"beforeEach array 1\",\n            \"beforeEach array 2\",\n            \"beforeEach array 2\",\n          ],\n        );\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/regression.spec.js",
    "content": "\"use strict\";\n\nvar run = require(\"./helpers\").runMocha;\nvar runJSON = require(\"./helpers\").runMochaJSON;\n\ndescribe(\"regressions\", function () {\n  it(\"issue-1991: Declarations do not get cleaned up unless you set them to `null` - Memory Leak\", function (done) {\n    // on a modern MBP takes ±5 seconds on node 4.0, but on older laptops with node 0.12 ±40 seconds.\n    // Could easily take longer on even weaker machines (Travis-CI containers for example).\n    this.timeout(120000);\n    this.slow(12000);\n    run(\"regression/issue-1991.fixture.js\", [], function (err, res) {\n      if (err) {\n        done(err);\n        return;\n      }\n      expect(res, \"not to contain output\", \"process out of memory\").and(\n        \"to have passed\",\n      );\n      done();\n    });\n  });\n\n  describe(\"issue-2286: after doesn't execute if test was skipped in beforeEach\", function () {\n    var afterWasRun = false;\n    describe(\"suite with skipped test for meta test\", function () {\n      beforeEach(function () {\n        this.skip();\n      });\n      after(function () {\n        afterWasRun = true;\n      });\n      it(\"should be pending\", function () {});\n    });\n    after(\"meta test\", function () {\n      expect(afterWasRun, \"to be\", true);\n    });\n  });\n\n  it(\"issue-2315: cannot read property currentRetry of undefined\", function (done) {\n    runJSON(\"regression/issue-2315.fixture.js\", [], function (err, res) {\n      if (err) {\n        done(err);\n        return;\n      }\n      expect(res, \"to have failed\")\n        .and(\"not to have pending tests\")\n        .and(\"to have failed test count\", 1);\n      done();\n    });\n  });\n\n  it(\"issue-2406: should run nested describe.only suites\", function (done) {\n    runJSON(\n      \"regression/issue-2406.fixture.js\",\n      [\"--no-forbid-only\"],\n      function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res, \"to have passed\")\n          .and(\"not to have pending tests\")\n          .and(\"to have passed test count\", 2);\n        done();\n      },\n    );\n  });\n\n  it(\"issue-2417: should not recurse infinitely with .only suites nested within each other\", function (done) {\n    runJSON(\n      \"regression/issue-2417.fixture.js\",\n      [\"--no-forbid-only\"],\n      function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(res, \"to have passed\")\n          .and(\"not to have pending tests\")\n          .and(\"to have passed test count\", 1);\n        done();\n      },\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/reporters.spec.js",
    "content": "\"use strict\";\n\nvar os = require(\"node:os\");\nvar fs = require(\"node:fs\");\nvar crypto = require(\"node:crypto\");\nvar path = require(\"node:path\");\nvar run = require(\"./helpers\").runMocha;\n\ndescribe(\"reporters\", function () {\n  describe(\"markdown\", function () {\n    var res;\n\n    before(function (done) {\n      run(\n        \"passing.fixture.js\",\n        [\"--reporter\", \"markdown\"],\n        function (err, result) {\n          res = result;\n          done(err);\n        },\n      );\n    });\n\n    it(\"does not exceed maximum callstack (issue: 1875)\", function () {\n      expect(res.output, \"not to contain\", \"RangeError\");\n    });\n\n    it(\"contains spec src\", function () {\n      var src = [\"```js\", \"assert(true);\", \"```\"].join(\"\\n\");\n\n      expect(res.output, \"to contain\", src);\n    });\n  });\n\n  describe(\"xunit\", function () {\n    it(\"prints test cases with --reporter-options output (issue: 1864)\", function (done) {\n      var randomStr = crypto.randomBytes(8).toString(\"hex\");\n      var tmpDir = os.tmpdir().replace(new RegExp(path.sep + \"$\"), \"\");\n      var tmpFile = tmpDir + path.sep + \"test-issue-1864-\" + randomStr + \".xml\";\n\n      var args = [\n        \"--reporter=xunit\",\n        \"--reporter-options\",\n        \"output=\" + tmpFile,\n      ];\n      var expectedOutput = [\n        '<testcase classname=\"suite\" name=\"test1\" file=\"',\n        '<testcase classname=\"suite\" name=\"test2\" file=\"',\n        \"</testsuite>\",\n      ];\n\n      run(\"passing.fixture.js\", args, function (err) {\n        if (err) return done(err);\n\n        var xml = fs.readFileSync(tmpFile, \"utf8\");\n        fs.unlinkSync(tmpFile);\n\n        expectedOutput.forEach(function (line) {\n          expect(xml, \"to contain\", line);\n        });\n\n        done(err);\n      });\n    });\n  });\n\n  describe(\"loader\", function () {\n    it(\"loads a reporter from a path relative to the current working directory\", function (done) {\n      var reporterAtARelativePath =\n        \"test/integration/fixtures/simple-reporter.js\";\n\n      var args = [\"--reporter=\" + reporterAtARelativePath];\n\n      run(\"passing.fixture.js\", args, function (err, result) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(result, \"to have passed\");\n        done();\n      });\n    });\n\n    it(\"loads a reporter from an absolute path\", function (done) {\n      // Generates an absolute path string\n      var reporterAtAnAbsolutePath = path.join(\n        process.cwd(),\n        \"test/integration/fixtures/simple-reporter.js\",\n      );\n\n      var args = [\"--reporter=\" + reporterAtAnAbsolutePath];\n\n      run(\"passing.fixture.js\", args, function (err, result) {\n        if (err) {\n          done(err);\n          return;\n        }\n        expect(result, \"to have passed\");\n        done();\n      });\n    });\n  });\n\n  describe(\"tap\", function () {\n    var not = function (predicate) {\n      return function () {\n        return !predicate.apply(this, arguments);\n      };\n    };\n    var versionPredicate = function (line) {\n      return line.match(/^TAP version \\d+$/) != null;\n    };\n    var planPredicate = function (line) {\n      return line.match(/^1\\.\\.\\d+$/) != null;\n    };\n    var testLinePredicate = function (line) {\n      return line.match(/^not ok/) != null || line.match(/^ok/) != null;\n    };\n    var diagnosticPredicate = function (line) {\n      return line.match(/^#/) != null;\n    };\n    var bailOutPredicate = function (line) {\n      return line.match(/^Bail out!/) != null;\n    };\n    var anythingElsePredicate = function (line) {\n      return (\n        versionPredicate(line) === false &&\n        planPredicate(line) === false &&\n        testLinePredicate(line) === false &&\n        diagnosticPredicate(line) === false &&\n        bailOutPredicate(line) === false\n      );\n    };\n\n    describe(\"produces valid TAP v13 output\", function () {\n      var runFixtureAndValidateOutput = function (fixture, expected) {\n        it(\"for \" + fixture, function (done) {\n          var args = [\"--reporter=tap\", \"--reporter-option\", \"tapVersion=13\"];\n\n          run(fixture, args, function (err, res) {\n            if (err) {\n              done(err);\n              return;\n            }\n\n            var expectedVersion = 13;\n            var expectedPlan = \"1..\" + expected.numTests;\n\n            var outputLines = res.output.split(\"\\n\");\n\n            // first line must be version line\n            expect(\n              outputLines[0],\n              \"to equal\",\n              \"TAP version \" + expectedVersion,\n            );\n\n            // plan must appear once\n            expect(outputLines, \"to contain\", expectedPlan);\n            expect(\n              outputLines.filter(function (l) {\n                return l === expectedPlan;\n              }),\n              \"to have length\",\n              1,\n            );\n            // plan cannot appear in middle of the output\n            var firstTestLine = outputLines.findIndex(testLinePredicate);\n            // there must be at least one test line\n            expect(firstTestLine, \"to be greater than\", -1);\n            var lastTestLine =\n              outputLines.length -\n              1 -\n              outputLines.slice().reverse().findIndex(testLinePredicate);\n            var planLine = outputLines.findIndex(function (line) {\n              return line === expectedPlan;\n            });\n            expect(\n              planLine < firstTestLine || planLine > lastTestLine,\n              \"to equal\",\n              true,\n            );\n\n            done();\n          });\n        });\n      };\n\n      runFixtureAndValidateOutput(\"passing.fixture.js\", {\n        numTests: 2,\n      });\n      runFixtureAndValidateOutput(\"reporters.fixture.js\", {\n        numTests: 12,\n      });\n    });\n\n    it(\"should fail if given invalid `tapVersion`\", function (done) {\n      var invalidTapVersion = \"nosuch\";\n      var args = [\n        \"--reporter=tap\",\n        \"--reporter-option\",\n        \"tapVersion=\" + invalidTapVersion,\n      ];\n\n      run(\n        \"reporters.fixture.js\",\n        args,\n        function (err, res) {\n          if (err) {\n            done(err);\n            return;\n          }\n\n          var pattern = `Error: invalid or unsupported TAP version: \"${invalidTapVersion}\"`;\n          expect(res, \"to satisfy\", {\n            code: 1,\n            output: new RegExp(pattern, \"m\"),\n          });\n          done();\n        },\n        { stdio: \"pipe\" },\n      );\n    });\n\n    it(\"places exceptions correctly in YAML blocks\", function (done) {\n      var args = [\"--reporter=tap\", \"--reporter-option\", \"tapVersion=13\"];\n\n      run(\"reporters.fixture.js\", args, function (err, res) {\n        if (err) {\n          done(err);\n          return;\n        }\n\n        var outputLines = res.output.split(\"\\n\");\n\n        for (var i = 0; i + 1 < outputLines.length; i++) {\n          if (\n            testLinePredicate(outputLines[i]) &&\n            testLinePredicate(outputLines[i + 1]) === false\n          ) {\n            var blockLinesStart = i + 1;\n            var blockLinesEnd =\n              i +\n              1 +\n              outputLines.slice(i + 1).findIndex(not(anythingElsePredicate));\n            var blockLines =\n              blockLinesEnd > blockLinesStart\n                ? outputLines.slice(blockLinesStart, blockLinesEnd)\n                : outputLines.slice(blockLinesStart);\n            i += blockLines.length;\n\n            expect(blockLines[0], \"to match\", /^\\s+---/);\n            expect(blockLines[blockLines.length - 1], \"to match\", /^\\s+\\.\\.\\./);\n          }\n        }\n\n        done();\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/retries.spec.js",
    "content": "\"use strict\";\n\nvar assert = require(\"node:assert\");\nvar helpers = require(\"./helpers\");\nvar runJSON = helpers.runMochaJSON;\nvar args = [];\nvar bang = require(\"../../lib/reporters/base\").symbols.bang;\n\ndescribe(\"retries\", function () {\n  it(\"are ran in correct order\", function (done) {\n    helpers.runMocha(\n      \"retries/hooks.fixture.js\",\n      [\"--reporter\", \"dot\"],\n      function (err, res) {\n        var lines, expected;\n\n        if (err) {\n          done(err);\n          return;\n        }\n\n        lines = res.output\n          .split(helpers.SPLIT_DOT_REPORTER_REGEXP)\n          .map(function (line) {\n            return line.trim();\n          })\n          .filter(function (line) {\n            return line.length;\n          })\n          .slice(0, -1);\n\n        expected = [\n          \"before\",\n          \"before each 0\",\n          \"TEST 0\",\n          \"after each 1\",\n          \"before each 1\",\n          \"TEST 1\",\n          \"after each 2\",\n          \"before each 2\",\n          \"TEST 2\",\n          \"after each 3\",\n          \"before each 3\",\n          \"TEST 3\",\n          \"after each 4\",\n          \"before each 4\",\n          \"TEST 4\",\n          bang + \"after each 5\",\n          \"after\",\n        ];\n\n        expected.forEach(function (line, i) {\n          assert.strictEqual(lines[i], line);\n        });\n\n        assert.strictEqual(res.code, 1);\n        done();\n      },\n    );\n  });\n\n  it(\"should exit early if test passes\", function (done) {\n    runJSON(\"retries/early-pass.fixture.js\", args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have passed\")\n        .and(\"to have passed test count\", 2)\n        .and(\"to have failed test count\", 0)\n        .and(\"to have retried test\", \"should pass after 1 retry\", 1);\n\n      done();\n    });\n  });\n\n  it(\"should let test override\", function (done) {\n    runJSON(\"retries/nested.fixture.js\", args, function (err, res) {\n      if (err) {\n        done(err);\n        return;\n      }\n      assert.strictEqual(res.stats.passes, 0);\n      assert.strictEqual(res.stats.failures, 1);\n      assert.strictEqual(res.stats.tests, 1);\n      assert.strictEqual(res.tests[0].currentRetry, 1);\n      assert.strictEqual(res.code, 1);\n      done();\n    });\n  });\n\n  it(\"should not hang w/ async test\", function (done) {\n    helpers.runMocha(\n      \"retries/async.fixture.js\",\n      [\"--reporter\", \"dot\"],\n      function (err, res) {\n        var lines, expected;\n\n        if (err) {\n          done(err);\n          return;\n        }\n\n        lines = res.output\n          .split(helpers.SPLIT_DOT_REPORTER_REGEXP)\n          .map(function (line) {\n            return line.trim();\n          })\n          .filter(function (line) {\n            return line.length;\n          })\n          .slice(0, -1);\n\n        expected = [\n          \"before\",\n          \"before each 0\",\n          \"TEST 0\",\n          \"after each 1\",\n          \"before each 1\",\n          \"TEST 1\",\n          \"after each 2\",\n          \"before each 2\",\n          \"TEST 2\",\n          \"after each 3\",\n          \"after\",\n        ];\n\n        expected.forEach(function (line, i) {\n          assert.strictEqual(lines[i], line);\n        });\n\n        assert.strictEqual(res.code, 0);\n        done();\n      },\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/suite.spec.js",
    "content": "\"use strict\";\n\nvar run = require(\"./helpers\").runMocha;\nvar args = [];\n\ndescribe(\"suite w/no callback\", function () {\n  it(\"should throw a helpful error message when a callback for suite is not supplied\", function (done) {\n    run(\n      \"suite/suite-no-callback.fixture.js\",\n      args,\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(\n          res.output,\n          \"to match\",\n          /no callback was supplied. Supply a callback/,\n        );\n        done();\n      },\n      { stdio: \"pipe\" },\n    );\n  });\n});\n\ndescribe(\"skipped suite w/no callback\", function () {\n  it(\"should not throw an error when a callback for skipped suite is not supplied\", function (done) {\n    run(\n      \"suite/suite-skipped-no-callback.fixture.js\",\n      args,\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        var pattern = /TypeError/g;\n        var result = res.output.match(pattern) || [];\n        expect(result, \"to have length\", 0);\n        done();\n      },\n    );\n  });\n});\n\ndescribe(\"skipped suite w/ callback\", function () {\n  it(\"should not throw an error when a callback for skipped suite is supplied\", function (done) {\n    run(\"suite/suite-skipped-callback.fixture.js\", args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n      var pattern = /TypeError/g;\n      var result = res.output.match(pattern) || [];\n      expect(result, \"to have length\", 0);\n      done();\n    });\n  });\n});\n\ndescribe(\"suite returning a value\", function () {\n  it(\"should not give a deprecation warning for suite callback returning a value\", function (done) {\n    run(\n      \"suite/suite-returning-value.fixture.js\",\n      args,\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n        expect(res, \"not to contain output\", /Suites ignore return values/);\n        done();\n      },\n      { stdio: \"pipe\" },\n    );\n  });\n});\n"
  },
  {
    "path": "test/integration/timeout.spec.js",
    "content": "\"use strict\";\n\nvar assert = require(\"node:assert\");\nvar run = require(\"./helpers\").runMochaJSON;\nvar args = [];\n\ndescribe(\"this.timeout()\", function () {\n  it(\"is respected by sync and async suites\", function (done) {\n    run(\"timeout.fixture.js\", args, function (err, res) {\n      if (err) {\n        done(err);\n        return;\n      }\n      assert.strictEqual(res.stats.pending, 0);\n      assert.strictEqual(res.stats.passes, 0);\n      assert.strictEqual(res.stats.failures, 2);\n      assert.strictEqual(res.code, 2);\n      done();\n    });\n  });\n\n  it(\"should allow overriding if disabled per-test\", function (done) {\n    run(\"timeout-override.fixture.js\", args, function (err, res) {\n      if (err) {\n        done(err);\n        return;\n      }\n      assert.strictEqual(res.stats.failures, 1);\n      done();\n    });\n  });\n});\n\ndescribe(\"describe.timeout()\", function () {\n  it(\"should fail due to suite-level timeout lower than elapsed time of inner test\", function (done) {\n    run(\"timeout-chained-call.fixture.js\", args, function (err, res) {\n      if (err) {\n        done(err);\n        return;\n      }\n\n      assert.ok(res.failures[0].err.message.match(/Timeout of 50ms exceeded/));\n      assert.strictEqual(res.code, 1);\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/integration/uncaught.spec.js",
    "content": "\"use strict\";\n\nconst {\n  runMocha,\n  runMochaJSON: run,\n  invokeMochaAsync,\n  invokeNode,\n  resolveFixturePath,\n} = require(\"./helpers\");\nvar args = [];\n\ndescribe(\"uncaught exceptions\", function () {\n  it(\"handles uncaught exceptions from hooks\", function (done) {\n    run(\"uncaught/hook\", args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have failed with error\", \"oh noes\")\n        .and(\"to have passed test count\", 0)\n        .and(\"to have pending test count\", 0)\n        .and(\"to have failed test count\", 1)\n        .and(\"to have failed test\", '\"before each\" hook for \"test\"');\n\n      done();\n    });\n  });\n\n  it(\"handles uncaught exceptions from async specs\", function (done) {\n    run(\"uncaught/double\", args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have failed with error\", \"global error\", \"test error\")\n        .and(\"to have passed test count\", 0)\n        .and(\"to have pending test count\", 0)\n        .and(\"to have failed test count\", 2)\n        .and(\n          \"to have failed test\",\n          \"fails exactly once when a global error is thrown first\",\n          \"fails exactly once when a global error is thrown second\",\n        );\n\n      done();\n    });\n  });\n\n  it(\"handles uncaught exceptions from which Mocha cannot recover\", function (done) {\n    run(\"uncaught/fatal\", args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      var testName = \"should bail if a successful test asynchronously fails\";\n      expect(res, \"to have failed with error\", \"global error\")\n        .and(\"to have passed test count\", 1)\n        .and(\"to have failed test count\", 1)\n        .and(\"to have passed test\", testName)\n        .and(\"to have failed test\", testName);\n\n      done();\n    });\n  });\n\n  it(\"handles uncaught exceptions within pending tests\", function (done) {\n    run(\"uncaught/pending\", args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have failed with error\", \"I am uncaught!\")\n        .and(\"to have passed test count\", 3)\n        .and(\"to have pending test count\", 1)\n        .and(\"to have failed test count\", 1)\n        .and(\n          \"to have passed test\",\n          \"test1\",\n          \"test3 - should run\",\n          \"test4 - should run\",\n        )\n        .and(\"to have pending test order\", \"test2\")\n        .and(\"to have failed test\", \"test2\");\n\n      done();\n    });\n  });\n\n  it(\"handles uncaught exceptions within open tests\", function (done) {\n    run(\"uncaught/recover\", args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(\n        res,\n        \"to have failed with error\",\n        \"Whoops!\",\n        \"Whoops!\", // JSON reporter does not show the second error message\n        \"should get upto here and throw\",\n      )\n        .and(\"to have passed test count\", 2)\n        .and(\"to have failed test count\", 3)\n        .and(\"to have passed test\", \"should wait 15ms\", \"test 3\")\n        .and(\n          \"to have failed test\",\n          \"throw delayed error\",\n          \"throw delayed error\",\n          '\"after all\" hook for \"test 3\"',\n        );\n\n      done();\n    });\n  });\n\n  it(\"removes uncaught exceptions handlers correctly\", function (done) {\n    invokeNode([resolveFixturePath(\"uncaught/listeners\")], function (err, res) {\n      if (err) {\n        return done(err);\n      }\n\n      expect(res, \"to have passed\");\n      done();\n    });\n  });\n\n  it(\"handles uncaught exceptions after runner's end\", function (done) {\n    runMocha(\n      \"uncaught/after-runner\",\n      args,\n      function (err, res) {\n        if (err) {\n          return done(err);\n        }\n\n        expect(res, \"to have failed\").and(\"to satisfy\", {\n          failing: 0,\n          passing: 1,\n          pending: 0,\n          output: expect.it(\"to contain\", \"Error: Unexpected crash\"),\n        });\n\n        done();\n      },\n      \"pipe\",\n    );\n  });\n\n  it(\"issue-1327: should run the first test and then bail\", function (done) {\n    run(\"uncaught/issue-1327\", args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n      expect(res, \"to have failed with error\", \"Too bad\")\n        .and(\"to have passed test count\", 1)\n        .and(\"to have failed test count\", 1)\n        .and(\"to have passed test\", \"test 1\")\n        .and(\"to have failed test\", \"test 1\");\n      done();\n    });\n  });\n\n  it(\"issue-1417: uncaught exceptions from async specs\", function (done) {\n    run(\"uncaught/issue-1417\", args, function (err, res) {\n      if (err) {\n        return done(err);\n      }\n      expect(res, \"to have failed with errors\", \"sync error a\", \"sync error b\")\n        .and(\"to have exit code\", 2)\n        .and(\"not to have passed tests\")\n        .and(\"not to have pending tests\")\n        .and(\"to have failed test order\", [\n          \"fails exactly once when a global error is thrown synchronously and done errors\",\n          \"fails exactly once when a global error is thrown synchronously and done completes\",\n        ]);\n      done();\n    });\n  });\n\n  describe(\"issue-4481: behavior of non-Mocha-originating unhandled rejections\", function () {\n    describe('when Node is in \"warn\" mode', function () {\n      it(\"should warn\", async function () {\n        const [, promise] = invokeMochaAsync(\n          [\n            resolveFixturePath(\"uncaught/unhandled\"),\n            \"--unhandled-rejections=warn\",\n          ],\n          { stdio: \"pipe\" },\n        );\n\n        return expect(\n          promise,\n          \"when fulfilled\",\n          \"to have passed with output\",\n          /UnhandledPromiseRejectionWarning: Error: yikes/,\n        );\n      });\n    });\n\n    describe('when Node is in \"strict\" mode', function () {\n      it(\"should fail with an uncaught exception\", async function () {\n        const [, promise] = invokeMochaAsync(\n          [\n            resolveFixturePath(\"uncaught/unhandled\"),\n            \"--unhandled-rejections=strict\",\n          ],\n          { stdio: \"pipe\" },\n        );\n        return expect(\n          promise,\n          \"when fulfilled\",\n          \"to have failed with output\",\n          /Error: yikes/,\n        );\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/interfaces/bdd.spec.js",
    "content": "\"use strict\";\n\ndescribe(\"integer primitives\", function () {\n  describe(\"arithmetic\", function () {\n    it(\"should add\", function () {\n      expect(1 + 1, \"to be\", 2);\n      expect(2 + 2, \"to be\", 4);\n    });\n\n    it(\"should subtract\", function () {\n      expect(1 - 1, \"to be\", 0);\n      expect(2 - 1, \"to be\", 1);\n    });\n  });\n});\n\ndescribe(\"integer primitives\", function () {\n  describe(\"arithmetic is not\", function () {\n    it(\"should add\", function () {\n      expect(1 + 1, \"not to equal\", 3);\n      expect(2 + 2, \"not to equal\", 5);\n    });\n  });\n});\n\ncontext(\"test suite\", function () {\n  beforeEach(function () {\n    this.number = 5;\n  });\n\n  specify(\"share a property\", function () {\n    expect(this.number, \"to be\", 5);\n  });\n});\n\ndescribe(\"pending suite\", function () {\n  describe.skip(\"this is pending suite\", function () {\n    it(\"should not run\", function () {\n      expect(1 + 1, \"to be\", 3);\n    });\n  });\n});\n\ndescribe(\"pending tests\", function () {\n  it.skip(\"should not run\", function () {\n    expect(1 + 1, \"to be\", 3);\n  });\n});\n\ndescribe(\"setting timeout by appending it to test\", function () {\n  var runningTest =\n    it(\"enables users to call timeout on active tests\", function () {\n      expect(1 + 1, \"to be\", 2);\n    }).timeout(1003);\n\n  var skippedTest =\n    xit(\"enables users to call timeout on pending tests\", function () {\n      expect(1 + 1, \"to be\", 3);\n    }).timeout(1002);\n\n  it(\"sets timeout on pending tests\", function () {\n    expect(skippedTest._timeout, \"to be\", 1002);\n  });\n\n  it(\"sets timeout on running tests\", function () {\n    expect(runningTest._timeout, \"to be\", 1003);\n  });\n});\n"
  },
  {
    "path": "test/interfaces/exports.spec.js",
    "content": "\"use strict\";\n\nvar calls = [];\n\nexports.Array = {\n  before: function () {\n    calls.push(\"before\");\n  },\n\n  after: function () {\n    calls.push(\"after\");\n    expect(calls, \"to equal\", [\n      \"before\",\n      \"before each\",\n      \"one\",\n      \"after each\",\n      \"before each\",\n      \"two\",\n      \"after each\",\n      \"after\",\n    ]);\n  },\n\n  \"#indexOf()\": {\n    beforeEach: function () {\n      calls.push(\"before each\");\n    },\n\n    afterEach: function () {\n      calls.push(\"after each\");\n    },\n\n    \"should return -1 when the value is not present\": function () {\n      calls.push(\"one\");\n      expect([1, 2, 3].indexOf(5), \"to be\", -1);\n      expect([1, 2, 3].indexOf(0), \"to be\", -1);\n    },\n\n    \"should return the correct index when the value is present\": function () {\n      calls.push(\"two\");\n      expect([1, 2, 3].indexOf(1), \"to be\", 0);\n      expect([1, 2, 3].indexOf(2), \"to be\", 1);\n      expect([1, 2, 3].indexOf(3), \"to be\", 2);\n    },\n  },\n};\n"
  },
  {
    "path": "test/interfaces/qunit.spec.js",
    "content": "\"use strict\";\n\nsuite(\"integer primitives\");\n\ntest(\"should add\", function () {\n  expect(2 + 2, \"to be\", 4);\n});\n\ntest(\"should decrement\", function () {\n  var number = 3;\n  expect(--number, \"to be\", 2);\n  expect(--number, \"to be\", 1);\n  expect(number - 1, \"to be\", 0);\n});\n\nsuite(\"String\");\n\ntest(\"#length\", function () {\n  expect(\"foo\", \"to have length\", 3);\n});\n"
  },
  {
    "path": "test/interfaces/tdd.spec.js",
    "content": "\"use strict\";\n\nsuite(\"integer primitives\", function () {\n  suite(\"arithmetic\", function () {\n    var initialValue = 41;\n\n    suiteSetup(function (done) {\n      expect(initialValue, \"to be\", 41);\n      initialValue += 1;\n      done();\n    });\n\n    test(\"should add\", function () {\n      expect(initialValue, \"to be\", 42);\n      expect(1 + 1, \"to be\", 2);\n      expect(2 + 2, \"to be\", 4);\n    });\n\n    test(\"should subtract\", function () {\n      expect(initialValue, \"to be\", 42);\n      expect(1 - 1, \"to be\", 0);\n      expect(2 - 1, \"to be\", 1);\n    });\n\n    test.skip(\"should skip this test\", function () {\n      var zero = 0;\n      expect(zero, \"to be\", 1);\n    });\n\n    suite.skip(\"should skip this suite\", function () {\n      test(\"should skip this test\", function () {\n        var zero = 0;\n        expect(zero, \"to be\", 1);\n      });\n    });\n\n    suiteTeardown(function (done) {\n      expect(initialValue, \"to be\", 42);\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/jsapi/index.js",
    "content": "\"use strict\";\n\nvar Mocha = require(\"../../\");\n\nvar mocha = new Mocha({\n  ui: \"bdd\",\n  globals: [\"okGlobalA\", \"okGlobalB\", \"okGlobalC\", \"callback*\"],\n  growl: true,\n});\n\nrequire(\"../setup\");\n\nmocha.addFile(\"test/unit/suite.spec.js\");\nmocha.addFile(\"test/unit/runner.spec.js\");\nmocha.addFile(\"test/unit/runnable.spec.js\");\nmocha.addFile(\"test/unit/hook-sync.spec.js\");\nmocha.addFile(\"test/unit/hook-sync-nested.spec.js\");\nmocha.addFile(\"test/unit/hook-async.spec.js\");\nmocha.addFile(\"test/unit/duration.spec.js\");\nmocha.addFile(\"test/unit/globals.spec.js\");\nmocha.addFile(\"test/unit/timeout.spec.js\");\n\nmocha.run(function () {\n  console.log(\"done\");\n});\n"
  },
  {
    "path": "test/node-unit/buffered-worker-pool.spec.js",
    "content": "\"use strict\";\n\nconst rewiremock = require(\"rewiremock/node\");\nconst sinon = require(\"sinon\");\n\ndescribe(\"class BufferedWorkerPool\", function () {\n  let BufferedWorkerPool;\n  let pool;\n  let stats;\n  let serializeJavascript;\n  let serializer;\n  let result;\n\n  beforeEach(function () {\n    stats = {\n      totalWorkers: 10,\n      busyWorkers: 8,\n      idleWorkers: 2,\n      pendingTasks: 3,\n    };\n    result = { failures: 0, events: [] };\n    pool = {\n      terminate: sinon.stub().resolves(),\n      exec: sinon.stub().resolves(result),\n      stats: sinon.stub().returns(stats),\n    };\n    serializer = {\n      deserialize: sinon.stub(),\n    };\n\n    serializeJavascript = sinon.spy(require(\"serialize-javascript\"));\n    BufferedWorkerPool = rewiremock.proxy(\n      require.resolve(\"../../lib/nodejs/buffered-worker-pool\"),\n      {\n        workerpool: {\n          pool: sinon.stub().returns(pool),\n          cpus: 8,\n        },\n        \"../../lib/nodejs/serializer\": serializer,\n        \"serialize-javascript\": serializeJavascript,\n      },\n    ).BufferedWorkerPool;\n\n    // reset cache\n    BufferedWorkerPool.resetOptionsCache();\n  });\n\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"static method\", function () {\n    describe(\"create()\", function () {\n      it(\"should return a BufferedWorkerPool instance\", function () {\n        expect(\n          BufferedWorkerPool.create({ foo: \"bar\" }),\n          \"to be a\",\n          BufferedWorkerPool,\n        );\n      });\n\n      describe(\"when passed no arguments\", function () {\n        it(\"should not throw\", function () {\n          expect(BufferedWorkerPool.create, \"not to throw\");\n        });\n      });\n    });\n\n    describe(\"serializeOptions()\", function () {\n      describe(\"when passed no arguments\", function () {\n        it(\"should not throw\", function () {\n          expect(BufferedWorkerPool.serializeOptions, \"not to throw\");\n        });\n      });\n\n      it(\"should return a serialized string\", function () {\n        expect(\n          BufferedWorkerPool.serializeOptions({ foo: \"bar\" }),\n          \"to be a\",\n          \"string\",\n        );\n      });\n\n      describe(\"when called multiple times with the same object\", function () {\n        it(\"should not perform serialization twice\", function () {\n          const obj = { foo: \"bar\" };\n          BufferedWorkerPool.serializeOptions(obj);\n          BufferedWorkerPool.serializeOptions(obj);\n          expect(serializeJavascript, \"was called once\");\n        });\n\n        it(\"should return the same value\", function () {\n          const obj = { foo: \"bar\" };\n          expect(\n            BufferedWorkerPool.serializeOptions(obj),\n            \"to be\",\n            BufferedWorkerPool.serializeOptions(obj),\n          );\n        });\n      });\n    });\n  });\n\n  describe(\"constructor\", function () {\n    it(\"should apply defaults\", function () {\n      expect(new BufferedWorkerPool(), \"to satisfy\", {\n        options: {\n          workerType: \"process\",\n          forkOpts: { execArgv: process.execArgv },\n          maxWorkers: expect.it(\"to be greater than or equal to\", 1),\n        },\n      });\n    });\n  });\n\n  describe(\"instance method\", function () {\n    let workerPool;\n\n    beforeEach(function () {\n      workerPool = BufferedWorkerPool.create();\n    });\n\n    describe(\"stats()\", function () {\n      it(\"should return the object returned by `workerpool.Pool#stats`\", function () {\n        expect(workerPool.stats(), \"to be\", stats);\n      });\n    });\n\n    describe(\"run()\", function () {\n      describe(\"when passed no arguments\", function () {\n        it(\"should reject\", async function () {\n          return expect(workerPool.run(), \"to be rejected with\", {\n            code: \"ERR_MOCHA_INVALID_ARG_TYPE\",\n          });\n        });\n      });\n\n      describe(\"when passed a non-string filepath\", function () {\n        it(\"should reject\", async function () {\n          return expect(workerPool.run(123), \"to be rejected with\", {\n            code: \"ERR_MOCHA_INVALID_ARG_TYPE\",\n          });\n        });\n      });\n\n      it(\"should serialize the options object\", async function () {\n        await workerPool.run(\"file.js\", { foo: \"bar\" });\n\n        expect(pool.exec, \"to have a call satisfying\", [\n          \"run\",\n          [\"file.js\", '{\"foo\":\"bar\"}'],\n        ]).and(\"was called once\");\n      });\n\n      it(\"should deserialize the result\", async function () {\n        await workerPool.run(\"file.js\", { foo: \"bar\" });\n        expect(serializer.deserialize, \"to have a call satisfying\", [\n          result,\n        ]).and(\"was called once\");\n      });\n    });\n\n    describe(\"terminate()\", function () {\n      describe(\"when called with `force`\", function () {\n        beforeEach(async function () {\n          await workerPool.terminate(true);\n        });\n\n        it('should delegate to the underlying pool w/ \"force\" behavior', async function () {\n          expect(pool.terminate, \"to have a call satisfying\", [true]).and(\n            \"was called once\",\n          );\n        });\n      });\n\n      describe(\"when called without `force`\", function () {\n        beforeEach(async function () {\n          await workerPool.terminate();\n        });\n\n        it('should delegate to the underlying pool w/o \"force\" behavior', async function () {\n          expect(pool.terminate, \"to have a call satisfying\", [false]).and(\n            \"was called once\",\n          );\n        });\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/node-unit/cli/config.spec.js",
    "content": "\"use strict\";\n\nconst sinon = require(\"sinon\");\nconst rewiremock = require(\"rewiremock/node\");\nconst { parsers } = require(\"../../../lib/cli/config\");\n\ndescribe(\"cli/config\", function () {\n  const phonyConfigObject = { ok: true };\n\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"loadConfig()\", function () {\n    let parsers;\n    let loadConfig;\n\n    beforeEach(function () {\n      const config = rewiremock.proxy(\n        require.resolve(\"../../../lib/cli/config\"),\n      );\n      parsers = config.parsers;\n      loadConfig = config.loadConfig;\n    });\n\n    describe(\"when parsing succeeds\", function () {\n      beforeEach(function () {\n        sinon.stub(parsers, \"yaml\").returns(phonyConfigObject);\n        sinon.stub(parsers, \"json\").returns(phonyConfigObject);\n        sinon.stub(parsers, \"js\").returns(phonyConfigObject);\n      });\n\n      describe('when supplied a filepath with \".cjs\" extension', function () {\n        const filepath = \"foo.cjs\";\n\n        it(\"should use the JS parser\", function () {\n          loadConfig(filepath);\n          expect(parsers.js, \"to have calls satisfying\", [\n            { args: [filepath], returned: phonyConfigObject },\n          ]).and(\"was called once\");\n        });\n      });\n\n      describe('when supplied a filepath with \".js\" extension', function () {\n        const filepath = \"foo.js\";\n\n        it(\"should use the JS parser\", function () {\n          loadConfig(filepath);\n          expect(parsers.js, \"to have calls satisfying\", [\n            { args: [filepath], returned: phonyConfigObject },\n          ]).and(\"was called once\");\n        });\n      });\n\n      describe('when supplied a filepath with \".json\" extension', function () {\n        const filepath = \"foo.json\";\n\n        it(\"should use the JSON parser\", function () {\n          loadConfig(\"foo.json\");\n          expect(parsers.json, \"to have calls satisfying\", [\n            { args: [filepath], returned: phonyConfigObject },\n          ]).and(\"was called once\");\n        });\n      });\n\n      describe('when supplied a filepath with \".jsonc\" extension', function () {\n        const filepath = \"foo.jsonc\";\n\n        it(\"should use the JSON parser\", function () {\n          loadConfig(\"foo.jsonc\");\n          expect(parsers.json, \"to have calls satisfying\", [\n            { args: [filepath], returned: phonyConfigObject },\n          ]).and(\"was called once\");\n        });\n      });\n\n      describe('when supplied a filepath with \".mjs\" extension', function () {\n        const filepath = \"foo.mjs\";\n\n        it(\"should use the JS parser\", function () {\n          loadConfig(filepath);\n          expect(parsers.js, \"to have calls satisfying\", [\n            { args: [filepath], returned: phonyConfigObject },\n          ]).and(\"was called once\");\n        });\n      });\n\n      describe('when supplied a filepath with \".yaml\" extension', function () {\n        const filepath = \"foo.yaml\";\n\n        it(\"should use the YAML parser\", function () {\n          loadConfig(filepath);\n          expect(parsers.yaml, \"to have calls satisfying\", [\n            { args: [filepath], returned: phonyConfigObject },\n          ]).and(\"was called once\");\n        });\n      });\n\n      describe('when supplied a filepath with \".yml\" extension', function () {\n        const filepath = \"foo.yml\";\n\n        it(\"should use the YAML parser\", function () {\n          loadConfig(filepath);\n          expect(parsers.yaml, \"to have calls satisfying\", [\n            { args: [filepath], returned: phonyConfigObject },\n          ]).and(\"was called once\");\n        });\n      });\n    });\n\n    describe(\"when supplied a filepath with unsupported extension\", function () {\n      beforeEach(function () {\n        sinon.stub(parsers, \"json\").returns(phonyConfigObject);\n      });\n\n      it(\"should use the JSON parser\", function () {\n        loadConfig(\"foo.bar\");\n        expect(parsers.json, \"was called\");\n      });\n    });\n\n    describe(\"when config file parsing fails\", function () {\n      beforeEach(function () {\n        sinon.stub(parsers, \"yaml\").throws(\"goo.yaml is unparsable\");\n      });\n\n      it(\"should throw\", function () {\n        expect(\n          () => loadConfig(\"goo.yaml\"),\n          \"to throw\",\n          \"Unable to read/parse goo.yaml: goo.yaml is unparsable\",\n        );\n      });\n    });\n  });\n\n  describe(\"findConfig()\", function () {\n    let findup;\n    let findConfig;\n    let CONFIG_FILES;\n\n    beforeEach(function () {\n      findup = { sync: sinon.stub().returns(\"/some/path/.mocharc.js\") };\n      const config = rewiremock.proxy(\n        require.resolve(\"../../../lib/cli/config\"),\n        (r) => ({\n          \"find-up\": r.by(() => findup),\n        }),\n      );\n      findConfig = config.findConfig;\n      CONFIG_FILES = config.CONFIG_FILES;\n    });\n\n    it(\"should look for one of the config files using findup-sync\", function () {\n      findConfig();\n      expect(findup, \"to have a call satisfying\", {\n        args: [CONFIG_FILES, { cwd: process.cwd() }],\n        returned: \"/some/path/.mocharc.js\",\n      });\n    });\n\n    it(\"should support an explicit `cwd`\", function () {\n      findConfig(\"/some/path/\");\n      expect(findup, \"to have a call satisfying\", {\n        args: [CONFIG_FILES, { cwd: \"/some/path/\" }],\n        returned: \"/some/path/.mocharc.js\",\n      });\n    });\n  });\n\n  describe(\"parsers()\", function () {\n    it(\"should print error message for faulty require\", function () {\n      // Fixture exists, but fails loading.\n      // Prints correct error message without using fallback path.\n      expect(\n        () => parsers.js(require.resolve(\"./fixtures/bad-require.fixture.js\")),\n        \"to throw\",\n        { message: /Cannot find module 'fake'/, code: \"MODULE_NOT_FOUND\" },\n      );\n    });\n\n    it(\"should print error message for non-existing file\", function () {\n      expect(() => parsers.js(\"not-existing.js\"), \"to throw\", {\n        message: /Cannot find module 'not-existing.js'/,\n        code: \"MODULE_NOT_FOUND\",\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/node-unit/cli/fixtures/bad-module.fixture.js",
    "content": "throw new Error(\"this module is wonky\");\n"
  },
  {
    "path": "test/node-unit/cli/fixtures/bad-require.fixture.js",
    "content": "require(\"fake\");\n"
  },
  {
    "path": "test/node-unit/cli/mocha-flags.spec.js",
    "content": "\"use strict\";\n\nconst {\n  types,\n  expectedTypeForFlag,\n} = require(\"../../../lib/cli/run-option-metadata\");\n\ndescribe(\"mocha-flags\", function () {\n  describe(\"expectedTypeForFlag()\", function () {\n    Object.entries(types).forEach(([dataType, flags]) => {\n      flags.forEach((flag) => {\n        it(`returns expected ${flag}'s type as ${dataType}`, function () {\n          expect(expectedTypeForFlag(flag), \"to equal\", dataType);\n        });\n      });\n    });\n\n    it(\"returns undefined for node flags\", function () {\n      expect(expectedTypeForFlag(\"--throw-deprecation\"), \"to equal\", undefined);\n      expect(expectedTypeForFlag(\"throw-deprecation\"), \"to equal\", undefined);\n    });\n\n    it(\"returns undefined for unsupported flags\", function () {\n      expect(expectedTypeForFlag(\"--foo\"), \"to equal\", undefined);\n    });\n  });\n});\n"
  },
  {
    "path": "test/node-unit/cli/node-flags.spec.js",
    "content": "\"use strict\";\n\nconst nodeEnvFlags = [...process.allowedNodeEnvironmentFlags];\nconst {\n  isNodeFlag,\n  impliesNoTimeouts,\n  unparseNodeFlags,\n} = require(\"../../../lib/cli/node-flags\");\n\nconst { isMochaFlag } = require(\"../../../lib/cli/run-option-metadata\");\n\ndescribe(\"node-flags\", function () {\n  describe(\"isNodeFlag()\", function () {\n    describe(\"for all allowed node environment flags\", function () {\n      nodeEnvFlags\n        .filter((flag) => !isMochaFlag(flag))\n        .forEach((envFlag) => {\n          it(`${envFlag} should return true`, function () {\n            expect(isNodeFlag(envFlag), \"to be true\");\n          });\n        });\n    });\n\n    describe(\"for all allowed node env flags which conflict with mocha flags\", function () {\n      nodeEnvFlags\n        .filter((flag) => isMochaFlag(flag))\n        .forEach((envFlag) => {\n          it(`${envFlag} should return false`, function () {\n            expect(isNodeFlag(envFlag), \"to be false\");\n          });\n        });\n    });\n\n    describe(\"when expecting leading dashes\", function () {\n      it(\"should require leading dashes\", function () {\n        expect(isNodeFlag(\"throw-deprecation\", false), \"to be false\");\n        expect(isNodeFlag(\"--throw-deprecation\", false), \"to be true\");\n      });\n    });\n\n    describe(\"special cases\", function () {\n      it('should return true for flags starting with \"preserve-symlinks\"', function () {\n        expect(isNodeFlag(\"preserve-symlinks\"), \"to be true\");\n        expect(isNodeFlag(\"preserve-symlinks-main\"), \"to be true\");\n        expect(isNodeFlag(\"preserve_symlinks\"), \"to be true\");\n      });\n\n      it('should return true for flags starting with \"harmony-\" or \"harmony_\"', function () {\n        expect(isNodeFlag(\"harmony-literally-anything\"), \"to be true\");\n        expect(isNodeFlag(\"harmony_literally_underscores\"), \"to be true\");\n        expect(isNodeFlag(\"harmonynope\"), \"to be false\");\n      });\n\n      it('should return true for flags starting with \"trace-\" or \"trace_\"', function () {\n        expect(isNodeFlag(\"trace-literally-anything\"), \"to be true\");\n        expect(isNodeFlag(\"trace_literally_underscores\"), \"to be true\");\n        expect(isNodeFlag(\"tracenope\"), \"to be false\");\n      });\n\n      it('should return true for \"harmony\" itself', function () {\n        expect(isNodeFlag(\"harmony\"), \"to be true\");\n      });\n\n      it('should return true for \"gc-global\"', function () {\n        expect(isNodeFlag(\"gc-global\"), \"to be true\");\n        expect(isNodeFlag(\"gc_global\"), \"to be true\");\n      });\n\n      it('should return true for \"es-staging\"', function () {\n        expect(isNodeFlag(\"es-staging\"), \"to be true\");\n        expect(isNodeFlag(\"es_staging\"), \"to be true\");\n      });\n\n      it('should return true for \"use-strict\"', function () {\n        expect(isNodeFlag(\"use-strict\"), \"to be true\");\n        expect(isNodeFlag(\"use_strict\"), \"to be true\");\n      });\n\n      it('should return true for flags starting with \"--v8-\"', function () {\n        expect(isNodeFlag(\"v8-\"), \"to be false\");\n        expect(isNodeFlag(\"v8-options\"), \"to be false\");\n        expect(isNodeFlag(\"v8_options\"), \"to be false\");\n        expect(isNodeFlag(\"v8-anything-else\"), \"to be true\");\n        expect(isNodeFlag(\"v8_anything_else\"), \"to be true\");\n      });\n    });\n  });\n\n  describe(\"impliesNoTimeouts()\", function () {\n    it(\"should return true for inspect flags\", function () {\n      expect(impliesNoTimeouts(\"inspect\"), \"to be true\");\n      expect(impliesNoTimeouts(\"inspect-brk\"), \"to be true\");\n    });\n  });\n\n  describe(\"unparseNodeFlags()\", function () {\n    it(\"should handle single v8 flags\", function () {\n      expect(unparseNodeFlags({ \"v8-numeric\": 100 }), \"to equal\", [\n        \"--v8-numeric=100\",\n      ]);\n      expect(unparseNodeFlags({ \"v8-boolean\": true }), \"to equal\", [\n        \"--v8-boolean\",\n      ]);\n    });\n\n    it(\"should handle multiple v8 flags\", function () {\n      expect(\n        unparseNodeFlags({ \"v8-numeric-one\": 1, \"v8-numeric-two\": 2 }),\n        \"to equal\",\n        [\"--v8-numeric-one=1\", \"--v8-numeric-two=2\"],\n      );\n      expect(\n        unparseNodeFlags({ \"v8-boolean-one\": true, \"v8-boolean-two\": true }),\n        \"to equal\",\n        [\"--v8-boolean-one\", \"--v8-boolean-two\"],\n      );\n      expect(\n        unparseNodeFlags({\n          \"v8-boolean-one\": true,\n          \"v8-numeric-one\": 1,\n          \"v8-boolean-two\": true,\n        }),\n        \"to equal\",\n        [\"--v8-boolean-one\", \"--v8-numeric-one=1\", \"--v8-boolean-two\"],\n      );\n      expect(\n        unparseNodeFlags({\n          \"v8-numeric-one\": 1,\n          \"v8-boolean-one\": true,\n          \"v8-numeric-two\": 2,\n        }),\n        \"to equal\",\n        [\"--v8-numeric-one=1\", \"--v8-boolean-one\", \"--v8-numeric-two=2\"],\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/node-unit/cli/options.spec.js",
    "content": "\"use strict\";\n\nconst sinon = require(\"sinon\");\nconst rewiremock = require(\"rewiremock/node\");\nconst { ONE_AND_DONE_ARGS } = require(\"../../../lib/cli/one-and-dones\");\nconst { constants } = require(\"../../../lib/error-constants\");\n\nconst modulePath = require.resolve(\"../../../lib/cli/options\");\nconst mocharcPath = require.resolve(\"../../../lib/mocharc.json\");\nconst configPath = require.resolve(\"../../../lib/cli/config\");\n\nconst proxyLoadOptions = ({\n  readFileSync = {},\n  findupSync = null,\n  findConfig = {},\n  loadConfig = {},\n} = {}) =>\n  rewiremock.proxy(modulePath, (r) => ({\n    \"node:fs\": r.with({ readFileSync }).directChildOnly(),\n    [mocharcPath]: defaults,\n    \"find-up\": r\n      .by(() => (findupSync ? { sync: findupSync } : {}))\n      .directChildOnly(),\n    [configPath]: r.with({ findConfig, loadConfig }).directChildOnly(),\n  })).loadOptions;\n\nconst defaults = {\n  timeout: 1000,\n  extension: [\"js\"],\n};\n\ndescribe(\"options\", function () {\n  let readFileSync;\n  let findupSync;\n  let loadOptions;\n  let findConfig;\n  let loadConfig;\n\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  /**\n   * Order of priority:\n   * 1. Command-line args\n   * 2. `MOCHA_OPTIONS` environment variable\n   * 3. RC file (`.mocharc.js`, `.mocharc.ya?ml`, `mocharc.json`)\n   * 4. `mocha` prop of `package.json`\n   * 5. default rc\n   */\n  describe(\"loadOptions()\", function () {\n    describe(\"when no parameter provided\", function () {\n      beforeEach(function () {\n        this.timeout(1000);\n        readFileSync = sinon.stub();\n        readFileSync.onFirstCall().returns(\"{}\");\n        findConfig = sinon.stub().returns(\"/some/.mocharc.json\");\n        loadConfig = sinon.stub().returns({});\n        findupSync = sinon.stub().returns(\"/some/package.json\");\n\n        loadOptions = proxyLoadOptions({\n          readFileSync,\n          findConfig,\n          loadConfig,\n          findupSync,\n        });\n      });\n\n      it(\"should return an object containing positional args, defaults, and anti-reloading flags\", function () {\n        expect(\n          loadOptions(),\n          \"to equal\",\n          Object.assign({}, defaults, {\n            _: [],\n            config: false,\n            package: false,\n          }),\n        );\n      });\n    });\n\n    describe(\"when parameter provided\", function () {\n      describe(\"package.json\", function () {\n        describe(\"when path to package.json (`--package <path>`) is valid\", function () {\n          let result;\n\n          beforeEach(function () {\n            const filepath = \"/some/package.json\";\n            readFileSync = sinon.stub();\n            // package.json\n            readFileSync.onFirstCall().returns('{\"mocha\": {\"retries\": 3}}');\n            findConfig = sinon.stub().returns(\"/some/.mocharc.json\");\n            loadConfig = sinon.stub().returns({});\n            findupSync = sinon.stub();\n            loadOptions = proxyLoadOptions({\n              readFileSync,\n              findConfig,\n              loadConfig,\n              findupSync,\n            });\n            result = loadOptions([\"--package\", filepath]);\n          });\n\n          it(\"should return merged options incl. package.json opts\", function () {\n            expect(\n              result,\n              \"to equal\",\n              Object.assign(\n                {\n                  _: [],\n                },\n                defaults,\n                {\n                  config: false,\n                  package: false,\n                  retries: 3,\n                },\n              ),\n            );\n          });\n\n          it(\"should not try to find a package.json\", function () {\n            expect(findupSync, \"was not called\");\n          });\n\n          it(\"should set package = false\", function () {\n            expect(result, \"to have property\", \"package\", false);\n          });\n        });\n\n        describe(\"when path to package.json (`--package <path>`) is invalid\", function () {\n          beforeEach(function () {\n            readFileSync = sinon.stub();\n            // package.json\n            readFileSync.onFirstCall().throws(\"bad file message\");\n            findConfig = sinon.stub().returns(\"/some/.mocharc.json\");\n            loadConfig = sinon.stub().returns({});\n            findupSync = sinon.stub();\n            loadOptions = proxyLoadOptions({\n              readFileSync,\n              findConfig,\n              loadConfig,\n              findupSync,\n            });\n          });\n\n          it(\"should throw\", function () {\n            expect(\n              () => {\n                loadOptions(\"--package /something/wherever --require butts\");\n              },\n              \"to throw\",\n              \"Unable to read /something/wherever: bad file message\",\n            );\n          });\n        });\n\n        describe(\"when path to package.json unspecified\", function () {\n          let result;\n\n          beforeEach(function () {\n            const filepath = \"/some/package.json\";\n            readFileSync = sinon.stub();\n            // package.json\n            readFileSync\n              .onFirstCall()\n              .returns('{\"mocha\": {\"retries\": 3, \"_\": [\"foobar.spec.js\"]}}');\n            findConfig = sinon.stub().returns(\"/some/.mocharc.json\");\n            loadConfig = sinon.stub().returns({});\n            findupSync = sinon.stub().returns(filepath);\n            loadOptions = proxyLoadOptions({\n              readFileSync,\n              findConfig,\n              loadConfig,\n              findupSync,\n            });\n            result = loadOptions();\n          });\n\n          it(\"should return merged options incl. found package.json\", function () {\n            expect(\n              result,\n              \"to equal\",\n              Object.assign(\n                {\n                  _: [\"foobar.spec.js\"],\n                },\n                defaults,\n                {\n                  config: false,\n                  package: false,\n                  retries: 3,\n                },\n              ),\n            );\n          });\n\n          it(\"should set package = false\", function () {\n            expect(result, \"to have property\", \"package\", false);\n          });\n        });\n\n        describe(\"when path to package.json unspecified and package.json exists but is invalid\", function () {\n          beforeEach(function () {\n            const filepath = \"/some/package.json\";\n            readFileSync = sinon.stub();\n            // package.json\n            readFileSync.onFirstCall().returns(\"{definitely-invalid\");\n            findConfig = sinon.stub().returns(\"/some/.mocharc.json\");\n            loadConfig = sinon.stub().returns({});\n            findupSync = sinon.stub().returns(filepath);\n            loadOptions = proxyLoadOptions({\n              readFileSync,\n              findConfig,\n              loadConfig,\n              findupSync,\n            });\n          });\n\n          it(\"should throw\", function () {\n            expect(\n              () => {\n                loadOptions();\n              },\n              \"to throw\",\n              /SyntaxError/,\n            );\n          });\n        });\n\n        describe(\"when called with package = false (`--no-package`)\", function () {\n          let result;\n          beforeEach(function () {\n            readFileSync = sinon.stub();\n            readFileSync.onFirstCall().returns(\"{}\");\n            findConfig = sinon.stub().returns(\"/some/path/to/.mocharc.json\");\n            loadConfig = sinon.stub().returns({ \"check-leaks\": true });\n            findupSync = sinon.stub().returns(\"/some/package.json\");\n\n            loadOptions = proxyLoadOptions({\n              readFileSync,\n              findConfig,\n              loadConfig,\n              findupSync,\n            });\n\n            result = loadOptions(\"--no-diff --no-package\");\n          });\n\n          it(\"should return parsed args and default config\", function () {\n            expect(\n              result,\n              \"to equal\",\n              Object.assign({ _: [] }, defaults, {\n                diff: false,\n                \"check-leaks\": true,\n                config: false,\n                package: false,\n              }),\n            );\n          });\n\n          it(\"should not look for package.json\", function () {\n            expect(findupSync, \"was not called\");\n          });\n\n          it(\"should set package = false\", function () {\n            expect(result, \"to have property\", \"package\", false);\n          });\n        });\n      });\n\n      describe(\"rc file\", function () {\n        describe(\"when called with config = false (`--no-config`)\", function () {\n          let result;\n          beforeEach(function () {\n            readFileSync = sinon.stub();\n            readFileSync\n              .onFirstCall()\n              .returns(\n                '{\"mocha\": {\"check-leaks\": true, \"_\": [\"foobar.spec.js\"]}}',\n              );\n            findConfig = sinon.stub();\n            loadConfig = sinon.stub();\n            findupSync = sinon.stub().returns(\"/some/package.json\");\n\n            loadOptions = proxyLoadOptions({\n              readFileSync,\n              findConfig,\n              loadConfig,\n              findupSync,\n            });\n\n            result = loadOptions(\"--no-diff --no-config\");\n          });\n\n          it(\"should return parsed args, default config and package.json\", function () {\n            expect(\n              result,\n              \"to equal\",\n              Object.assign({ _: [\"foobar.spec.js\"] }, defaults, {\n                diff: false,\n                \"check-leaks\": true,\n                config: false,\n                package: false,\n              }),\n            );\n          });\n\n          it(\"should not attempt to load a config file\", function () {\n            expect(loadConfig, \"was not called\");\n          });\n\n          it(\"should not attempt to find a config file\", function () {\n            expect(findConfig, \"was not called\");\n          });\n\n          it(\"should set config = false\", function () {\n            expect(result, \"to have property\", \"config\", false);\n          });\n        });\n\n        describe(\"when path to config (`--config <path>`) is invalid\", function () {\n          let config;\n\n          beforeEach(function () {\n            readFileSync = sinon.stub();\n            config = \"/some/.mocharc.json\";\n            readFileSync.onFirstCall().returns(\"{}\");\n            findConfig = sinon.stub();\n            loadConfig = sinon.stub().throws(\"Error\", \"failed to parse\");\n            findupSync = sinon.stub().returns(\"/some/package.json\");\n\n            loadOptions = proxyLoadOptions({\n              readFileSync,\n              findConfig,\n              loadConfig,\n              findupSync,\n            });\n          });\n\n          it(\"should not look for a config\", function () {\n            try {\n              loadOptions(`--config ${config}`);\n            } catch {\n              /* empty */\n            }\n            expect(findConfig, \"was not called\");\n          });\n\n          it(\"should attempt to load file at path\", function () {\n            try {\n              loadOptions(`--config ${config}`);\n            } catch {\n              /* empty */\n            }\n            expect(loadConfig, \"to have a call satisfying\", [config]);\n          });\n\n          it(\"should throw to warn the user\", function () {\n            expect(\n              () => {\n                loadOptions(`--config ${config}`);\n              },\n              \"to throw\",\n              \"failed to parse\",\n            );\n          });\n        });\n\n        describe(\"when called with unspecified config\", function () {\n          describe(\"when an rc file would be found\", function () {\n            let result;\n\n            beforeEach(function () {\n              readFileSync = sinon.stub();\n              readFileSync.onFirstCall().returns(\"{}\");\n              readFileSync.onSecondCall().throws();\n              findConfig = sinon.stub().returns(\"/some/.mocharc.json\");\n              loadConfig = sinon.stub().returns({});\n              findupSync = sinon.stub().returns(\"/some/package.json\");\n\n              loadOptions = proxyLoadOptions({\n                readFileSync,\n                findConfig,\n                loadConfig,\n                findupSync,\n              });\n\n              result = loadOptions();\n            });\n\n            it(\"should look for a config\", function () {\n              expect(findConfig, \"was called\");\n            });\n\n            it(\"should attempt to load file at found path\", function () {\n              expect(loadConfig, \"to have a call satisfying\", [\n                \"/some/.mocharc.json\",\n              ]);\n            });\n\n            it(\"should set config = false\", function () {\n              expect(result, \"to have property\", \"config\", false);\n            });\n          });\n\n          describe(\"when an rc file would not be found\", function () {\n            let result;\n\n            beforeEach(function () {\n              readFileSync = sinon.stub();\n              readFileSync.onFirstCall().returns(\"{}\");\n              readFileSync.onSecondCall().throws();\n              findConfig = sinon.stub().returns(null);\n              loadConfig = sinon.stub().returns({});\n              findupSync = sinon.stub().returns(\"/some/package.json\");\n\n              loadOptions = proxyLoadOptions({\n                readFileSync,\n                findConfig,\n                loadConfig,\n                findupSync,\n              });\n\n              result = loadOptions();\n            });\n\n            it(\"should look for a config\", function () {\n              expect(findConfig, \"was called\");\n            });\n\n            it(\"should not attempt to load a config file\", function () {\n              expect(loadConfig, \"was not called\");\n            });\n\n            it(\"should set config = false\", function () {\n              expect(result, \"to have property\", \"config\", false);\n            });\n          });\n        });\n      });\n    });\n\n    describe(\"env options\", function () {\n      it(\"should parse flags from MOCHA_OPTIONS\", function () {\n        readFileSync = sinon.stub().onFirstCall().returns(\"{}\");\n        findConfig = sinon.stub().returns(\"/some/.mocharc.json\");\n        loadConfig = sinon.stub().returns({});\n        findupSync = sinon.stub().returns(\"/some/package.json\");\n        sinon\n          .stub(process, \"env\")\n          .value({ MOCHA_OPTIONS: \"--retries 42 --color\" });\n\n        loadOptions = proxyLoadOptions({\n          readFileSync,\n          findConfig,\n          loadConfig,\n          findupSync,\n        });\n\n        expect(loadOptions(), \"to satisfy\", {\n          retries: 42,\n          color: true,\n        });\n      });\n    });\n\n    describe(\"config priority\", function () {\n      it(\"should prioritize package.json over defaults\", function () {\n        readFileSync = sinon.stub();\n        readFileSync\n          .onFirstCall()\n          .returns(\n            '{\"mocha\": {\"timeout\": 700, \"require\": \"bar\", \"extension\": \"ts\"}}',\n          );\n        findConfig = sinon.stub().returns(\"/some/.mocharc.json\");\n        loadConfig = sinon.stub().returns({});\n        findupSync = sinon.stub().returns(\"/some/package.json\");\n\n        loadOptions = proxyLoadOptions({\n          readFileSync,\n          findConfig,\n          loadConfig,\n          findupSync,\n        });\n\n        expect(loadOptions(), \"to satisfy\", {\n          timeout: 700,\n          require: [\"bar\"],\n          extension: [\"ts\"],\n        });\n      });\n\n      it(\"should prioritize rc file over package.json\", function () {\n        readFileSync = sinon.stub();\n        readFileSync.onFirstCall().returns('{\"mocha\": {\"timeout\": 700}}');\n        readFileSync.onSecondCall().returns(\"--timeout 800\");\n        findConfig = sinon.stub().returns(\"/some/.mocharc.json\");\n        loadConfig = sinon.stub().returns({ timeout: 600 });\n        findupSync = sinon.stub().returns(\"/some/package.json\");\n\n        loadOptions = proxyLoadOptions({\n          readFileSync,\n          findConfig,\n          loadConfig,\n          findupSync,\n        });\n\n        expect(loadOptions(), \"to have property\", \"timeout\", 600);\n      });\n\n      it(\"should prioritize args over rc file\", function () {\n        readFileSync = sinon.stub();\n        readFileSync.onFirstCall().returns('{\"mocha\": {\"timeout\": 700}}');\n        readFileSync.onSecondCall().returns(\"--timeout 800\");\n        findConfig = sinon.stub().returns(\"/some/.mocharc.json\");\n        loadConfig = sinon.stub().returns({ timeout: 600 });\n        findupSync = sinon.stub().returns(\"/some/package.json\");\n\n        loadOptions = proxyLoadOptions({\n          readFileSync,\n          findConfig,\n          loadConfig,\n          findupSync,\n        });\n\n        expect(\n          loadOptions(\"--timeout 500\"),\n          \"to have property\",\n          \"timeout\",\n          \"500\",\n        );\n      });\n\n      it(\"should prioritize env over rc file\", function () {\n        readFileSync = sinon.stub();\n        readFileSync.onFirstCall().returns(\"{}\");\n        readFileSync.onSecondCall().returns(\"\");\n        findConfig = sinon.stub().returns(\"/some/.mocharc.json\");\n        loadConfig = sinon.stub().returns({ retries: 300 });\n        findupSync = sinon.stub().returns(\"/some/package.json\");\n        sinon\n          .stub(process, \"env\")\n          .value({ MOCHA_OPTIONS: \"--retries 800 --color\" });\n\n        loadOptions = proxyLoadOptions({\n          readFileSync,\n          findConfig,\n          loadConfig,\n          findupSync,\n        });\n\n        expect(loadOptions(), \"to have property\", \"retries\", 800);\n      });\n    });\n\n    describe(\"when called with a one-and-done arg\", function () {\n      beforeEach(function () {\n        readFileSync = sinon.stub();\n        findConfig = sinon.stub();\n        loadConfig = sinon.stub();\n        findupSync = sinon.stub();\n        loadOptions = proxyLoadOptions({\n          readFileSync,\n          findConfig,\n          loadConfig,\n          findupSync,\n        });\n      });\n\n      ONE_AND_DONE_ARGS.forEach((arg) => {\n        describe(`\"${arg}\"`, function () {\n          it(`should return basic parsed arguments and flag`, function () {\n            expect(loadOptions(`--${arg}`), \"to equal\", { _: [], [arg]: true });\n          });\n        });\n      });\n    });\n\n    describe('\"extension\" handling', function () {\n      describe('when user supplies \"extension\" option', function () {\n        let result;\n\n        beforeEach(function () {\n          readFileSync = sinon.stub();\n          readFileSync.onFirstCall().throws();\n          findConfig = sinon.stub().returns(\"/some/.mocharc.json\");\n          loadConfig = sinon.stub().returns({ extension: [\"tsx\"] });\n          findupSync = sinon.stub();\n          loadOptions = proxyLoadOptions({\n            readFileSync,\n            findConfig,\n            loadConfig,\n            findupSync,\n          });\n          result = loadOptions([\"--extension\", \"ts\"]);\n        });\n\n        it(\"should not concatenate the default value\", function () {\n          expect(result, \"to have property\", \"extension\", [\"ts\", \"tsx\"]);\n        });\n      });\n\n      describe('when user does not supply \"extension\" option', function () {\n        let result;\n\n        beforeEach(function () {\n          readFileSync = sinon.stub();\n          readFileSync.onFirstCall().throws();\n          findConfig = sinon.stub().returns(\"/some/.mocharc.json\");\n          loadConfig = sinon.stub().returns({});\n          findupSync = sinon.stub();\n          loadOptions = proxyLoadOptions({\n            readFileSync,\n            findConfig,\n            loadConfig,\n            findupSync,\n          });\n          result = loadOptions();\n        });\n\n        it(\"should retain the default\", function () {\n          expect(result, \"to have property\", \"extension\", [\"js\"]);\n        });\n      });\n    });\n\n    describe('\"spec\" handling', function () {\n      describe('when user supplies \"spec\" in config and positional arguments', function () {\n        let result;\n\n        beforeEach(function () {\n          readFileSync = sinon.stub();\n          readFileSync.onFirstCall().throws();\n          findConfig = sinon.stub().returns(\"/some/.mocharc.json\");\n          loadConfig = sinon\n            .stub()\n            .returns({ spec: \"{dirA,dirB}/**/*.spec.js\" });\n          findupSync = sinon.stub();\n          loadOptions = proxyLoadOptions({\n            readFileSync,\n            findConfig,\n            loadConfig,\n            findupSync,\n          });\n          result = loadOptions([\"*.test.js\"]);\n        });\n\n        it(\"should place both - unsplitted - into the positional arguments array\", function () {\n          expect(result, \"to have property\", \"_\", [\n            \"*.test.js\",\n            \"{dirA,dirB}/**/*.spec.js\",\n          ]);\n        });\n      });\n    });\n\n    describe('\"ignore\" handling', function () {\n      let result;\n\n      beforeEach(function () {\n        readFileSync = sinon.stub();\n        readFileSync.onFirstCall().throws();\n        findConfig = sinon.stub().returns(\"/some/.mocharc.json\");\n        loadConfig = sinon\n          .stub()\n          .returns({ ignore: \"{dirA,dirB}/**/*.spec.js\" });\n        findupSync = sinon.stub();\n        loadOptions = proxyLoadOptions({\n          readFileSync,\n          findConfig,\n          loadConfig,\n          findupSync,\n        });\n        result = loadOptions([\"--ignore\", \"*.test.js\"]);\n      });\n\n      it(\"should not split option values by comma\", function () {\n        expect(result, \"to have property\", \"ignore\", [\n          \"*.test.js\",\n          \"{dirA,dirB}/**/*.spec.js\",\n        ]);\n      });\n    });\n\n    describe('\"numeric arguments\"', function () {\n      const numericArg = 123;\n\n      const unsupportedError = (arg) => {\n        return {\n          message: `Option ${arg} is unsupported by the mocha cli`,\n          code: constants.UNSUPPORTED,\n        };\n      };\n\n      const invalidArgError = (flag, arg, expectedType = \"string\") => {\n        return {\n          message: `Mocha flag '${flag}' given invalid option: '${arg}'`,\n          code: constants.INVALID_ARG_TYPE,\n          argument: arg,\n          actual: \"number\",\n          expected: expectedType,\n        };\n      };\n\n      beforeEach(function () {\n        readFileSync = sinon.stub();\n        findConfig = sinon.stub();\n        loadConfig = sinon.stub();\n        findupSync = sinon.stub();\n        loadOptions = proxyLoadOptions({\n          readFileSync,\n          findConfig,\n          loadConfig,\n          findupSync,\n        });\n      });\n\n      it(\"throws UNSUPPORTED error when numeric option is passed to cli\", function () {\n        expect(\n          () => loadOptions(`${numericArg}`),\n          \"to throw\",\n          unsupportedError(numericArg),\n        );\n      });\n\n      it(\"throws INVALID_ARG_TYPE error when numeric argument is passed to mocha flag that does not accept numeric value\", function () {\n        const flag = \"--delay\";\n        expect(\n          () => loadOptions(`${flag} ${numericArg}`),\n          \"to throw\",\n          invalidArgError(flag, numericArg, \"boolean\"),\n        );\n      });\n\n      it('throws INVALID_ARG_TYPE error when incompatible flag does not have preceding \"--\"', function () {\n        const flag = \"delay\";\n        expect(\n          () => loadOptions(`${flag} ${numericArg}`),\n          \"to throw\",\n          invalidArgError(flag, numericArg, \"boolean\"),\n        );\n      });\n\n      it(\"shows correct flag in error when multiple mocha flags have numeric values\", function () {\n        const flag = \"--delay\";\n        expect(\n          () =>\n            loadOptions(\n              `--timeout ${numericArg} ${flag} ${numericArg} --retries ${numericArg}`,\n            ),\n          \"to throw\",\n          invalidArgError(flag, numericArg, \"boolean\"),\n        );\n      });\n\n      it(\"throws UNSUPPORTED error when numeric arg is passed to unsupported flag\", function () {\n        const invalidFlag = \"foo\";\n        expect(\n          () => loadOptions(`${invalidFlag} ${numericArg}`),\n          \"to throw\",\n          unsupportedError(numericArg),\n        );\n      });\n\n      it(\"does not throw error if numeric value is passed to a compatible mocha flag\", function () {\n        expect(() => loadOptions(`--retries ${numericArg}`), \"not to throw\");\n      });\n\n      it(\"does not throw error if numeric value is passed to a node options\", function () {\n        expect(\n          () =>\n            loadOptions(\n              `--secure-heap-min=${numericArg} --conditions=${numericArg}`,\n            ),\n          \"not to throw\",\n        );\n      });\n\n      it(\"does not throw error if numeric value is passed to string flag\", function () {\n        expect(() => loadOptions(`--grep ${numericArg}`), \"not to throw\");\n      });\n\n      it(\"does not throw error if numeric value is passed to an array flag\", function () {\n        expect(() => loadOptions(`--spec ${numericArg}`), \"not to throw\");\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/node-unit/cli/run-helpers.spec.js",
    "content": "\"use strict\";\n\nconst { validateLegacyPlugin, list } = require(\"../../../lib/cli/run-helpers\");\nconst Mocha = require(\"../../../lib/mocha\");\n\ndescribe(\"helpers\", function () {\n  describe(\"validateLegacyPlugin()\", function () {\n    describe('when used with \"reporter\" key', function () {\n      it(\"should disallow an array of names\", function () {\n        expect(\n          () => validateLegacyPlugin({ reporter: [\"bar\"] }, \"reporter\"),\n          \"to throw\",\n          {\n            code: \"ERR_MOCHA_INVALID_REPORTER\",\n            message: /can only be specified once/i,\n          },\n        );\n      });\n\n      it(\"should fail to recognize an unknown reporter\", function () {\n        expect(\n          () => validateLegacyPlugin({ reporter: \"bar\" }, \"reporter\"),\n          \"to throw\",\n          {\n            code: \"ERR_MOCHA_INVALID_REPORTER\",\n            message: /cannot find module/i,\n          },\n        );\n      });\n    });\n\n    describe('when used with an \"ui\" key', function () {\n      it(\"should disallow an array of names\", function () {\n        expect(() => validateLegacyPlugin({ ui: [\"bar\"] }, \"ui\"), \"to throw\", {\n          code: \"ERR_MOCHA_INVALID_INTERFACE\",\n          message: /can only be specified once/i,\n        });\n      });\n\n      it(\"should fail to recognize an unknown interface\", function () {\n        expect(() => validateLegacyPlugin({ ui: \"bar\" }, \"ui\"), \"to throw\", {\n          code: \"ERR_MOCHA_INVALID_INTERFACE\",\n          message: /cannot find module/i,\n        });\n      });\n    });\n\n    describe(\"when used with an unknown plugin type\", function () {\n      it(\"should fail\", function () {\n        expect(\n          () => validateLegacyPlugin({ frog: \"bar\" }, \"frog\"),\n          \"to throw\",\n          /unknown plugin/i,\n        );\n      });\n    });\n\n    describe(\"when used with a third-party interface\", function () {\n      it('should add the interface to \"Mocha.interfaces\"', function () {\n        // let's suppose that `glob` is an interface\n        const opts = { ui: \"glob\" };\n        validateLegacyPlugin(opts, \"ui\", Mocha.interfaces);\n        expect(opts.ui, \"to equal\", \"glob\");\n        expect(Mocha.interfaces, \"to satisfy\", { glob: require(\"glob\") });\n        delete Mocha.interfaces.glob;\n      });\n    });\n\n    describe(\"when a plugin throws an exception upon load\", function () {\n      it(\"should fail and report the original error\", function () {\n        expect(\n          () =>\n            validateLegacyPlugin(\n              {\n                reporter: require.resolve(\"./fixtures/bad-module.fixture.js\"),\n              },\n              \"reporter\",\n            ),\n          \"to throw\",\n          { message: /wonky/, code: \"ERR_MOCHA_INVALID_REPORTER\" },\n        );\n      });\n\n      it('should fail and report the original \"MODULE_NOT_FOUND\" error.message', function () {\n        expect(\n          () =>\n            validateLegacyPlugin(\n              {\n                reporter: require.resolve(\"./fixtures/bad-require.fixture.js\"),\n              },\n              \"reporter\",\n            ),\n          \"to throw\",\n          {\n            message: /Error: Cannot find module 'fake'/,\n            code: \"ERR_MOCHA_INVALID_REPORTER\",\n          },\n        );\n      });\n    });\n  });\n\n  describe(\"list()\", function () {\n    describe(\"when provided a flat array\", function () {\n      it(\"should return a flat array\", function () {\n        expect(list([\"foo\", \"bar\"]), \"to equal\", [\"foo\", \"bar\"]);\n      });\n    });\n    describe(\"when provided a nested array\", function () {\n      it(\"should return a flat array\", function () {\n        expect(list([[\"foo\", \"bar\"], \"baz\"]), \"to equal\", [\n          \"foo\",\n          \"bar\",\n          \"baz\",\n        ]);\n      });\n    });\n    describe(\"when given a comma-delimited string\", function () {\n      it(\"should return a flat array\", function () {\n        expect(list(\"foo,bar\"), \"to equal\", [\"foo\", \"bar\"]);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/node-unit/cli/run.spec.js",
    "content": "\"use strict\";\n\nconst { builder } = require(\"../../../lib/cli/run\");\nconst { types } = require(\"../../../lib/cli/run-option-metadata\");\n\ndescribe(\"command\", function () {\n  describe(\"run\", function () {\n    describe(\"builder\", function () {\n      const IGNORED_OPTIONS = new Set([\"help\", \"version\"]);\n      const options = builder(require(\"yargs\")()).getOptions();\n      [\"number\", \"string\", \"boolean\", \"array\"].forEach((type) => {\n        describe(`${type} type`, function () {\n          Array.from(new Set(options[type])).forEach((option) => {\n            if (!IGNORED_OPTIONS.has(option)) {\n              it(`should include option ${option}`, function () {\n                expect(types[type], \"to contain\", option);\n              });\n            }\n          });\n        });\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/node-unit/esm-utils.spec.js",
    "content": "\"use strict\";\n\nconst esmUtils = require(\"../../lib/nodejs/esm-utils\");\nconst sinon = require(\"sinon\");\nconst url = require(\"node:url\");\n\ndescribe(\"esm-utils\", function () {\n  describe(\"requireOrImport\", function () {\n    it(\"should show an informative error message for a broken default import\", async function () {\n      return expect(\n        () =>\n          esmUtils.requireOrImport(\n            \"../../test/node-unit/fixtures/broken-default-import.mjs\",\n          ),\n        \"to be rejected with error satisfying\",\n        {\n          name: \"SyntaxError\",\n          message:\n            \"The requested module './module-without-default-export.mjs' does not provide an export named 'default'\",\n        },\n      );\n    });\n\n    it(\"should show a syntax error message when importing a TypeScript file with invalid syntax\", async function () {\n      return expect(\n        () =>\n          esmUtils.requireOrImport(\n            \"../../test/node-unit/fixtures/broken-syntax.ts\",\n          ),\n        \"to be rejected with error satisfying\",\n        {\n          name: \"SyntaxError\",\n          message: /Invalid or unexpected token|Expected ident/,\n        },\n      );\n    });\n\n    it(\"should surface the ts-node TSError error rather than falling back to `import(...)`\", async function () {\n      return expect(\n        () =>\n          esmUtils.requireOrImport(\n            \"../../test/node-unit/fixtures/mock-ts-node-compile-err.ts\",\n          ),\n        \"to be rejected with error satisfying\",\n        {\n          name: \"TSError\",\n          message: /A TS compilation error/,\n        },\n      );\n    });\n\n    it(\"should surface Mocha errors rather than falling back to `import(...)`\", async function () {\n      return expect(\n        () =>\n          esmUtils.requireOrImport(\n            \"../../test/node-unit/fixtures/mock-mocha-forbidden-exclusivity-err.ts\",\n          ),\n        \"to be rejected with error satisfying\",\n        {\n          code: \"ERR_MOCHA_FORBIDDEN_EXCLUSIVITY\",\n          message: /`\\.only` is not supported in parallel mode/,\n        },\n      );\n    });\n  });\n\n  describe(\"loadFilesAsync()\", function () {\n    beforeEach(function () {\n      sinon.stub(esmUtils, \"doImport\").resolves({});\n    });\n\n    afterEach(function () {\n      sinon.restore();\n    });\n\n    it(\"should not decorate imported module if no decorator passed\", async function () {\n      await esmUtils.loadFilesAsync(\n        [\"/foo/bar.mjs\"],\n        () => {},\n        () => {},\n      );\n\n      expect(\n        esmUtils.doImport.firstCall.args[0].toString(),\n        \"to be\",\n        url.pathToFileURL(\"/foo/bar.mjs\").toString(),\n      );\n    });\n\n    it(\"should decorate imported module with passed decorator\", async function () {\n      await esmUtils.loadFilesAsync(\n        [\"/foo/bar.mjs\"],\n        () => {},\n        () => {},\n        (x) => `${x}?foo=bar`,\n      );\n\n      expect(\n        esmUtils.doImport.firstCall.args[0].toString(),\n        \"to be\",\n        `${url.pathToFileURL(\"/foo/bar.mjs\").toString()}?foo=bar`,\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/node-unit/fixtures/broken-default-import.mjs",
    "content": "import moduleWithoutDefaultExport from './module-without-default-export.mjs';\n\nmoduleWithoutDefaultExport;\n"
  },
  {
    "path": "test/node-unit/fixtures/broken-syntax.ts",
    "content": "@!\n"
  },
  {
    "path": "test/node-unit/fixtures/dumb-module.fixture.js",
    "content": ""
  },
  {
    "path": "test/node-unit/fixtures/dumber-module.fixture.js",
    "content": ""
  },
  {
    "path": "test/node-unit/fixtures/mock-mocha-forbidden-exclusivity-err.ts",
    "content": "/*\n Mock file that simulates a Mocha FORBIDDEN_EXCLUSIVITY error\n This error is thrown when .only is used in parallel mode\n */\nconst { createForbiddenExclusivityError } = require('../../../lib/errors');\n\n// Simulate a mocha instance in worker mode\nconst mockMocha = { isWorker: true };\n\nthrow createForbiddenExclusivityError(mockMocha);\n"
  },
  {
    "path": "test/node-unit/fixtures/mock-ts-node-compile-err.ts",
    "content": "/*\n Stripped down version of this error from ts-node:\n https://github.com/TypeStrong/ts-node/blob/ddb05ef23be92a90c3ecac5a0220435c65ebbd2a/src/index.ts#L435\n It's thrown when ts-node hits a compilation error.\n */\nclass TSError extends Error {\n  constructor(...args) {\n    super(...args);\n\n    this.name = 'TSError';\n  }\n}\nthrow new TSError('A TS compilation error');\n"
  },
  {
    "path": "test/node-unit/fixtures/module-without-default-export.mjs",
    "content": "export const value = 42;\n"
  },
  {
    "path": "test/node-unit/fixtures/wonky-reporter.fixture.js",
    "content": "throw new Error('bad weirdness in this one');\n"
  },
  {
    "path": "test/node-unit/mocha.spec.js",
    "content": "\"use strict\";\n\nconst path = require(\"node:path\");\nconst rewiremock = require(\"rewiremock/node\");\nconst sinon = require(\"sinon\");\nconst { EventEmitter } = require(\"node:events\");\n\nconst DUMB_FIXTURE_PATH = require.resolve(\"./fixtures/dumb-module.fixture.js\");\nconst DUMBER_FIXTURE_PATH =\n  require.resolve(\"./fixtures/dumber-module.fixture.js\");\n\ndescribe(\"Mocha\", function () {\n  let stubs;\n  let opts;\n  let Mocha;\n\n  beforeEach(function () {\n    opts = { reporter: sinon.stub() };\n\n    stubs = {};\n    stubs.errors = {\n      warn: sinon.stub(),\n      createMochaInstanceAlreadyDisposedError: sinon\n        .stub()\n        .throws({ code: \"ERR_MOCHA_INSTANCE_ALREADY_DISPOSED\" }),\n      createInvalidReporterError: sinon\n        .stub()\n        .throws({ code: \"ERR_MOCHA_INVALID_REPORTER\" }),\n      createUnsupportedError: sinon\n        .stub()\n        .throws({ code: \"ERR_MOCHA_UNSUPPORTED\" }),\n    };\n    stubs.utils = {\n      supportsEsModules: sinon.stub().returns(false),\n      isString: sinon.stub(),\n      noop: sinon.stub(),\n      cwd: sinon.stub().returns(process.cwd()),\n      isBrowser: sinon.stub().returns(false),\n    };\n    stubs.suite = Object.assign(sinon.createStubInstance(EventEmitter), {\n      slow: sinon.stub(),\n      timeout: sinon.stub(),\n      bail: sinon.stub(),\n      reset: sinon.stub(),\n      dispose: sinon.stub(),\n    });\n    stubs.Suite = sinon.stub().returns(stubs.suite);\n    stubs.Suite.constants = {};\n    stubs.ParallelBufferedRunner = sinon.stub().returns({});\n    stubs.esmUtils = {\n      loadFilesAsync: sinon.stub(),\n    };\n    const runner = Object.assign(sinon.createStubInstance(EventEmitter), {\n      runAsync: sinon.stub().resolves(0),\n      globals: sinon.stub(),\n      grep: sinon.stub(),\n      dispose: sinon.stub(),\n    });\n    stubs.Runner = sinon.stub().returns(runner);\n    // the Runner constructor is the main export, and constants is a static prop.\n    // we don't need the constants themselves, but the object cannot be undefined\n    stubs.Runner.constants = {};\n\n    Mocha = rewiremock.proxy(\n      () => require(\"../../lib/mocha\"),\n      (r) => ({\n        \"../../lib/utils.js\": r.with(stubs.utils).callThrough(),\n        \"../../lib/suite.js\": stubs.Suite,\n        \"../../lib/nodejs/parallel-buffered-runner.js\":\n          stubs.ParallelBufferedRunner,\n        \"../../lib/nodejs/esm-utils\": stubs.esmUtils,\n        \"../../lib/runner.js\": stubs.Runner,\n        \"../../lib/errors.js\": stubs.errors,\n      }),\n    );\n    delete require.cache[DUMB_FIXTURE_PATH];\n    delete require.cache[DUMBER_FIXTURE_PATH];\n  });\n\n  afterEach(function () {\n    delete require.cache[DUMB_FIXTURE_PATH];\n    delete require.cache[DUMBER_FIXTURE_PATH];\n    sinon.restore();\n  });\n\n  describe(\"instance method\", function () {\n    let mocha;\n\n    beforeEach(function () {\n      mocha = new Mocha(opts);\n    });\n\n    describe(\"parallelMode()\", function () {\n      describe(\"when `Mocha` is running in Node.js\", function () {\n        it(\"should return the Mocha instance\", function () {\n          expect(mocha.parallelMode(), \"to be\", mocha);\n        });\n\n        describe(\"when parallel mode is already enabled\", function () {\n          beforeEach(function () {\n            mocha.options.parallel = true;\n            mocha._runnerClass = stubs.ParallelBufferedRunner;\n            mocha._lazyLoadFiles = true;\n          });\n\n          it(\"should not swap the Runner, nor change lazy loading setting\", function () {\n            expect(mocha.parallelMode(true), \"to satisfy\", {\n              options: { parallel: true },\n              _runnerClass: stubs.ParallelBufferedRunner,\n              _lazyLoadFiles: true,\n            });\n          });\n        });\n\n        describe(\"when parallel mode is already disabled\", function () {\n          beforeEach(function () {\n            mocha.options.parallel = false;\n            mocha._runnerClass = Mocha.Runner;\n            mocha._lazyLoadFiles = false;\n          });\n\n          it(\"should not swap the Runner, nor change lazy loading setting\", function () {\n            expect(mocha.parallelMode(false), \"to satisfy\", {\n              options: { parallel: false },\n              _runnerClass: Mocha.Runner,\n              _lazyLoadFiles: false,\n            });\n          });\n        });\n\n        describe(\"when `Mocha` instance in serial mode\", function () {\n          beforeEach(function () {\n            mocha.options.parallel = false;\n          });\n\n          describe(\"when passed `true` value\", function () {\n            describe(\"when `Mocha` instance is in `INIT` state\", function () {\n              beforeEach(function () {\n                mocha._state = \"init\";\n              });\n\n              it(\"should enable parallel mode\", function () {\n                // FIXME: the dynamic require() call breaks the mock of\n                // `ParallelBufferedRunner` and returns the real class.\n                // don't know how to make this work or if it's even possible\n                expect(mocha.parallelMode(true), \"to satisfy\", {\n                  _runnerClass: expect.it(\"not to be\", Mocha.Runner),\n                  options: {\n                    parallel: true,\n                  },\n                  _lazyLoadFiles: true,\n                });\n              });\n            });\n\n            describe(\"when `Mocha` instance is not in `INIT` state\", function () {\n              beforeEach(function () {\n                mocha._state = \"disposed\";\n              });\n\n              it(\"should throw\", function () {\n                expect(\n                  () => {\n                    mocha.parallelMode(true);\n                  },\n                  \"to throw\",\n                  {\n                    code: \"ERR_MOCHA_UNSUPPORTED\",\n                  },\n                );\n              });\n            });\n          });\n\n          describe(\"when passed non-`true` value\", function () {\n            describe(\"when `Mocha` instance is in `INIT` state\", function () {\n              beforeEach(function () {\n                mocha._state = \"init\";\n              });\n\n              it(\"should enable serial mode\", function () {\n                expect(mocha.parallelMode(0), \"to satisfy\", {\n                  _runnerClass: Mocha.Runner,\n                  options: {\n                    parallel: false,\n                  },\n                  _lazyLoadFiles: false,\n                });\n              });\n            });\n          });\n        });\n      });\n    });\n\n    describe(\"addFile()\", function () {\n      it(\"should add the given file to the files array\", function () {\n        mocha.addFile(\"some-file.js\");\n        expect(mocha.files, \"to exhaustively satisfy\", [\"some-file.js\"]);\n      });\n\n      it(\"should be chainable\", function () {\n        expect(mocha.addFile(\"some-file.js\"), \"to be\", mocha);\n      });\n    });\n\n    describe(\"loadFiles()\", function () {\n      it(\"should load all files from the files array\", function () {\n        this.timeout(1000);\n        mocha.files = [DUMB_FIXTURE_PATH, DUMBER_FIXTURE_PATH];\n        mocha.loadFiles();\n        expect(require.cache, \"to have keys\", [\n          DUMB_FIXTURE_PATH,\n          DUMBER_FIXTURE_PATH,\n        ]);\n      });\n\n      it(\"should execute the optional callback if given\", function () {\n        expect((cb) => {\n          mocha.loadFiles(cb);\n        }, \"to call the callback\");\n      });\n    });\n\n    describe(\"loadFilesAsync()\", function () {\n      it(\"shoud pass esmDecorator to actual load function\", async function () {\n        const esmDecorator = (x) => `${x}?foo=bar`;\n\n        await mocha.loadFilesAsync({ esmDecorator });\n\n        expect(stubs.esmUtils.loadFilesAsync, \"was called once\");\n        expect(\n          stubs.esmUtils.loadFilesAsync.firstCall.args[3],\n          \"to be\",\n          esmDecorator,\n        );\n      });\n    });\n\n    describe(\"unloadFiles()\", function () {\n      it(\"should delegate Mocha.unloadFile() for each item in its list of files\", function () {\n        mocha.files = [DUMB_FIXTURE_PATH, DUMBER_FIXTURE_PATH];\n        sinon.stub(Mocha, \"unloadFile\");\n        mocha.unloadFiles();\n        expect(Mocha.unloadFile, \"to have a call exhaustively satisfying\", [\n          DUMB_FIXTURE_PATH,\n        ])\n          .and(\"to have a call exhaustively satisfying\", [DUMBER_FIXTURE_PATH])\n          .and(\"was called twice\");\n      });\n\n      it(\"should be chainable\", function () {\n        expect(mocha.unloadFiles(), \"to be\", mocha);\n      });\n    });\n\n    describe(\"reporter()\", function () {\n      describe(\"when a reporter exists relative to the cwd\", function () {\n        beforeEach(function () {\n          stubs.utils.cwd.returns(\n            path.resolve(__dirname, \"..\", \"..\", \"lib\", \"reporters\"),\n          );\n        });\n\n        it(\"should load from current working directory\", function () {\n          expect(function () {\n            mocha.reporter(\"./lib/reporters/spec.js\");\n          }, \"not to throw\");\n        });\n\n        describe(\"when the reporter throws upon load\", function () {\n          it('should throw \"invalid reporter\" exception', function () {\n            expect(\n              function () {\n                mocha.reporter(\n                  \"./test/node-unit/fixtures/wonky-reporter.fixture.js\",\n                );\n              },\n              \"to throw\",\n              {\n                code: \"ERR_MOCHA_INVALID_REPORTER\",\n              },\n            );\n          });\n        });\n      });\n\n      describe('when a reporter exists relative to the \"mocha\" module path', function () {\n        it(\"should load from module path\", function () {\n          expect(function () {\n            mocha.reporter(\"./reporters/spec\");\n          }, \"not to throw\");\n        });\n\n        describe(\"when the reporter throws upon load\", function () {\n          it('should throw \"invalid reporter\" exception', function () {\n            expect(\n              function () {\n                mocha.reporter(\n                  \"../test/node-unit/fixtures/wonky-reporter.fixture.js\",\n                );\n              },\n              \"to throw\",\n              {\n                code: \"ERR_MOCHA_INVALID_REPORTER\",\n              },\n            );\n          });\n        });\n      });\n    });\n\n    describe(\"unloadFiles()\", function () {\n      it(\"should reset referencesCleaned and allow for next run\", function (done) {\n        mocha.run(function () {\n          mocha.unloadFiles();\n          mocha.run(done);\n        });\n      });\n\n      it(\"should not be allowed when the current instance is already disposed\", function () {\n        mocha.dispose();\n        expect(\n          function () {\n            mocha.unloadFiles();\n          },\n          \"to throw\",\n          { code: \"ERR_MOCHA_INSTANCE_ALREADY_DISPOSED\" },\n        );\n      });\n    });\n\n    describe(\"lazyLoadFiles()\", function () {\n      it(\"should return the `Mocha` instance\", function () {\n        expect(mocha.lazyLoadFiles(), \"to be\", mocha);\n      });\n      describe(\"when passed a non-`true` value\", function () {\n        it(\"should enable eager loading\", function () {\n          mocha.lazyLoadFiles(0);\n          expect(mocha._lazyLoadFiles, \"to be false\");\n        });\n      });\n\n      describe(\"when passed `true`\", function () {\n        it(\"should enable lazy loading\", function () {\n          mocha.lazyLoadFiles(true);\n          expect(mocha._lazyLoadFiles, \"to be true\");\n        });\n      });\n    });\n  });\n\n  describe(\"static method\", function () {\n    describe(\"unloadFile()\", function () {\n      it(\"should unload a specific file from cache\", function () {\n        require(DUMB_FIXTURE_PATH);\n        Mocha.unloadFile(DUMB_FIXTURE_PATH);\n        expect(require.cache, \"not to have key\", DUMB_FIXTURE_PATH);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/node-unit/parallel-buffered-runner.spec.js",
    "content": "\"use strict\";\n\nconst {\n  EVENT_RUN_BEGIN,\n  EVENT_TEST_PASS,\n  EVENT_TEST_FAIL,\n  EVENT_SUITE_END,\n  EVENT_SUITE_BEGIN,\n} = require(\"../../lib/runner\").constants;\nconst rewiremock = require(\"rewiremock/node\");\nconst Suite = require(\"../../lib/suite\");\nconst Runner = require(\"../../lib/runner\");\nconst sinon = require(\"sinon\");\nconst { constants } = require(\"../../lib/utils\");\nconst { MOCHA_ID_PROP_NAME } = constants;\n\ndescribe(\"parallel-buffered-runner\", function () {\n  describe(\"ParallelBufferedRunner\", function () {\n    let run;\n    let BufferedWorkerPool;\n    let terminate;\n    let ParallelBufferedRunner;\n    let suite;\n    let warn;\n    let fatalError;\n\n    beforeEach(function () {\n      suite = new Suite(\"a root suite\", {}, true);\n      warn = sinon.stub();\n\n      fatalError = new Error();\n\n      // tests will want to further define the behavior of these.\n      run = sinon.stub();\n      terminate = sinon.stub();\n      BufferedWorkerPool = {\n        create: sinon.stub().returns({\n          run,\n          terminate,\n          stats: sinon.stub().returns({}),\n        }),\n      };\n      /**\n       * @type {ParallelBufferedRunner}\n       */\n      ParallelBufferedRunner = rewiremock.proxy(\n        () => require(\"../../lib/nodejs/parallel-buffered-runner\"),\n        (r) => ({\n          \"../../lib/nodejs/buffered-worker-pool\": {\n            BufferedWorkerPool,\n          },\n          \"../../lib/utils\": r.with({ warn }).callThrough(),\n          \"../../lib/errors\": r\n            .with({\n              createFatalError: sinon.stub().returns(fatalError),\n            })\n            .callThrough(),\n        }),\n      );\n    });\n\n    describe(\"constructor\", function () {\n      it('should start in \"IDLE\" state', function () {\n        expect(\n          new ParallelBufferedRunner(suite),\n          \"to have property\",\n          \"_state\",\n          \"IDLE\",\n        );\n      });\n    });\n\n    describe(\"instance property\", function () {\n      let runner;\n\n      beforeEach(function () {\n        runner = new ParallelBufferedRunner(suite);\n      });\n\n      describe(\"_state\", function () {\n        it(\"should disallow an invalid state transition\", function () {\n          expect(\n            () => {\n              runner._state = \"BAILED\";\n            },\n            \"to throw\",\n            /invalid state transition/,\n          );\n        });\n      });\n    });\n\n    describe(\"event\", function () {\n      let runner;\n\n      beforeEach(function () {\n        runner = new ParallelBufferedRunner(suite);\n      });\n\n      describe(\"EVENT_RUN_END\", function () {\n        it(\"should change the state to COMPLETE\", function () {\n          runner._state = \"RUNNING\";\n          runner.emit(Runner.constants.EVENT_RUN_END);\n          expect(runner._state, \"to be\", \"COMPLETE\");\n        });\n      });\n    });\n\n    describe(\"instance method\", function () {\n      describe(\"run()\", function () {\n        let runner;\n\n        beforeEach(function () {\n          runner = new ParallelBufferedRunner(suite);\n        });\n\n        // the purpose of this is to ensure that--despite using `Promise`s\n        // internally--`BufferedRunner#run` does not return a `Promise`.\n        it(\"should be chainable\", function (done) {\n          expect(runner.run(done, { files: [], options: {} }), \"to be\", runner);\n        });\n\n        it(\"should emit `EVENT_RUN_BEGIN`\", async function () {\n          return expect(\n            () =>\n              new Promise((resolve) => {\n                runner.run(resolve, { files: [], options: {} });\n              }),\n            \"to emit from\",\n            runner,\n            EVENT_RUN_BEGIN,\n          );\n        });\n\n        describe(\"when instructed to link objects\", function () {\n          beforeEach(function () {\n            runner._linkPartialObjects = true;\n          });\n\n          it(\"should create object references\", function () {\n            const options = { reporter: runner._workerReporter };\n            const someSuite = {\n              title: \"some suite\",\n              [MOCHA_ID_PROP_NAME]: \"bar\",\n            };\n\n            run.withArgs(\"some-file.js\", options).resolves({\n              failureCount: 0,\n              events: [\n                {\n                  eventName: EVENT_SUITE_END,\n                  data: someSuite,\n                },\n                {\n                  eventName: EVENT_TEST_PASS,\n                  data: {\n                    title: \"some test\",\n                    [MOCHA_ID_PROP_NAME]: \"foo\",\n                    parent: {\n                      // this stub object points to someSuite with id 'bar'\n                      [MOCHA_ID_PROP_NAME]: \"bar\",\n                    },\n                  },\n                },\n                {\n                  eventName: EVENT_SUITE_END,\n                  // ensure we are not passing the _same_ someSuite,\n                  // because we won't get the same one from the subprocess\n                  data: { ...someSuite },\n                },\n              ],\n            });\n\n            return expect(\n              () =>\n                new Promise((resolve) => {\n                  runner.run(resolve, { files: [\"some-file.js\"], options: {} });\n                }),\n              \"to emit from\",\n              runner,\n              EVENT_TEST_PASS,\n              {\n                title: \"some test\",\n                [MOCHA_ID_PROP_NAME]: \"foo\",\n                parent: expect\n                  .it(\"to be\", someSuite)\n                  .and(\"to have property\", \"title\", \"some suite\"),\n              },\n            );\n          });\n\n          describe(\"when event data object is missing an ID\", function () {\n            it(\"should result in an uncaught exception\", function (done) {\n              const options = { reporter: runner._workerReporter };\n              sinon.spy(runner, \"uncaught\");\n              const someSuite = {\n                title: \"some suite\",\n                [MOCHA_ID_PROP_NAME]: \"bar\",\n              };\n\n              run.withArgs(\"some-file.js\", options).resolves({\n                failureCount: 0,\n                events: [\n                  {\n                    eventName: EVENT_SUITE_END,\n                    data: someSuite,\n                  },\n                  {\n                    eventName: EVENT_TEST_PASS,\n                    data: {\n                      title: \"some test\",\n                      // note missing ID right here\n                      parent: {\n                        // this stub object points to someSuite with id 'bar'\n                        [MOCHA_ID_PROP_NAME]: \"bar\",\n                      },\n                    },\n                  },\n                  {\n                    eventName: EVENT_SUITE_END,\n                    // ensure we are not passing the _same_ someSuite,\n                    // because we won't get the same one from the subprocess\n                    data: { ...someSuite },\n                  },\n                ],\n              });\n\n              runner.run(\n                () => {\n                  expect(runner.uncaught, \"to have a call satisfying\", [\n                    fatalError,\n                  ]);\n                  done();\n                },\n                { files: [\"some-file.js\"], options: {} },\n              );\n            });\n          });\n        });\n\n        describe(\"when a worker fails\", function () {\n          it(\"should recover\", function (done) {\n            const options = { reporter: runner._workerReporter };\n            run.withArgs(\"some-file.js\", options).rejects(new Error(\"whoops\"));\n            run.withArgs(\"some-other-file.js\", options).resolves({\n              failureCount: 0,\n              events: [\n                {\n                  eventName: EVENT_TEST_PASS,\n                  data: {\n                    title: \"some test\",\n                  },\n                },\n                {\n                  eventName: EVENT_SUITE_END,\n                  data: {\n                    title: \"some suite\",\n                  },\n                },\n              ],\n            });\n\n            runner.run(\n              () => {\n                expect(terminate, \"to have calls satisfying\", [{ args: [] }]);\n                done();\n              },\n              {\n                files: [\"some-file.js\", \"some-other-file.js\"],\n                options,\n              },\n            );\n          });\n\n          it(\"should delegate to Runner#uncaught\", function (done) {\n            const options = { reporter: runner._workerReporter };\n            sinon.spy(runner, \"uncaught\");\n            const err = new Error(\"whoops\");\n            run.withArgs(\"some-file.js\", options).rejects(new Error(\"whoops\"));\n            run.withArgs(\"some-other-file.js\", options).resolves({\n              failureCount: 0,\n              events: [\n                {\n                  eventName: EVENT_TEST_PASS,\n                  data: {\n                    title: \"some test\",\n                  },\n                },\n                {\n                  eventName: EVENT_SUITE_END,\n                  data: {\n                    title: \"some suite\",\n                  },\n                },\n              ],\n            });\n\n            runner.run(\n              () => {\n                expect(runner.uncaught, \"to have a call satisfying\", [err]);\n                done();\n              },\n              {\n                files: [\"some-file.js\", \"some-other-file.js\"],\n                options,\n              },\n            );\n          });\n        });\n\n        describe(\"when suite should bail\", function () {\n          describe(\"when no event contains an error\", function () {\n            it(\"should not force-terminate\", function (done) {\n              run.resolves({\n                failureCount: 0,\n                events: [\n                  {\n                    eventName: EVENT_SUITE_BEGIN,\n                    data: {\n                      title: \"some suite\",\n                      _bail: true,\n                    },\n                  },\n                  {\n                    eventName: EVENT_TEST_PASS,\n                    data: {\n                      title: \"some test\",\n                    },\n                  },\n                  {\n                    eventName: EVENT_SUITE_END,\n                    data: {\n                      title: \"some suite\",\n                      _bail: true,\n                    },\n                  },\n                ],\n              });\n\n              runner.run(\n                () => {\n                  expect(terminate, \"to have a call satisfying\", {\n                    args: [],\n                  }).and(\"was called once\");\n                  done();\n                },\n                {\n                  files: [\"some-file.js\", \"some-other-file.js\"],\n                  options: {},\n                },\n              );\n            });\n          });\n\n          describe(\"when an event contains an error and has positive failures\", function () {\n            describe(\"when subsequent files have not yet been run\", function () {\n              it(\"should cleanly terminate the thread pool\", function (done) {\n                const options = { reporter: runner._workerReporter };\n                const err = {\n                  __type: \"Error\",\n                  message: \"oh no\",\n                };\n                run.withArgs(\"some-file.js\", options).resolves({\n                  failureCount: 1,\n                  events: [\n                    {\n                      eventName: EVENT_SUITE_BEGIN,\n                      data: {\n                        title: \"some suite\",\n                        _bail: true,\n                      },\n                    },\n                    {\n                      eventName: EVENT_TEST_FAIL,\n                      data: {\n                        title: \"some test\",\n                      },\n                      error: err,\n                    },\n                    {\n                      eventName: EVENT_SUITE_END,\n                      data: {\n                        title: \"some suite\",\n                        _bail: true,\n                      },\n                    },\n                  ],\n                });\n                run.withArgs(\"some-other-file.js\", options).rejects();\n\n                runner.run(\n                  () => {\n                    expect(terminate, \"to have calls satisfying\", [\n                      { args: [] }, // this is the pool force-terminating\n                      { args: [] }, // this will always be called, and will do nothing due to the previous call\n                    ]).and(\"was called twice\");\n                    done();\n                  },\n                  {\n                    files: [\"some-file.js\", \"some-other-file.js\"],\n                    options,\n                  },\n                );\n              });\n            });\n\n            describe(\"when subsequent files already started running\", function () {\n              it(\"should cleanly terminate the thread pool\", function (done) {\n                const options = { reporter: runner._workerReporter };\n                const err = {\n                  __type: \"Error\",\n                  message: \"oh no\",\n                };\n                run.withArgs(\"some-file.js\", options).resolves({\n                  failureCount: 1,\n                  events: [\n                    {\n                      eventName: EVENT_SUITE_BEGIN,\n                      data: {\n                        title: \"some suite\",\n                        _bail: true,\n                      },\n                    },\n                    {\n                      eventName: EVENT_TEST_FAIL,\n                      data: {\n                        title: \"some test\",\n                      },\n                      error: err,\n                    },\n                    {\n                      eventName: EVENT_SUITE_END,\n                      data: {\n                        title: \"some suite\",\n                        _bail: true,\n                      },\n                    },\n                  ],\n                });\n                run.withArgs(\"some-other-file.js\", options).resolves({\n                  failureCount: 0,\n                  events: [\n                    {\n                      eventName: EVENT_SUITE_BEGIN,\n                      data: {\n                        title: \"some suite\",\n                      },\n                    },\n                    {\n                      eventName: EVENT_TEST_PASS,\n                      data: {\n                        title: \"some test\",\n                      },\n                    },\n                    {\n                      eventName: EVENT_SUITE_END,\n                      data: {\n                        title: \"some suite\",\n                      },\n                    },\n                  ],\n                });\n\n                runner.run(\n                  () => {\n                    expect(terminate, \"to have calls satisfying\", [\n                      { args: [] }, // this is the pool force-terminating\n                      { args: [] }, // this will always be called, and will do nothing due to the previous call\n                    ]).and(\"was called twice\");\n                    done();\n                  },\n                  {\n                    files: [\"some-file.js\", \"some-other-file.js\"],\n                    options,\n                  },\n                );\n              });\n            });\n          });\n        });\n\n        describe(\"when a suite has a bail flag\", function () {\n          describe(\"when no event contains an error\", function () {\n            it(\"should not force-terminate\", function (done) {\n              run.resolves({\n                failureCount: 0,\n                events: [\n                  {\n                    eventName: EVENT_TEST_PASS,\n                    data: {\n                      title: \"some test\",\n                    },\n                  },\n                  {\n                    eventName: EVENT_SUITE_END,\n                    data: {\n                      title: \"some suite\",\n                      _bail: true,\n                    },\n                  },\n                ],\n              });\n\n              runner.run(\n                () => {\n                  expect(terminate, \"to have a call satisfying\", {\n                    args: [],\n                  }).and(\"was called once\");\n                  done();\n                },\n                {\n                  files: [\"some-file.js\", \"some-other-file.js\"],\n                  options: {},\n                },\n              );\n            });\n          });\n\n          describe(\"when an event contains an error and has positive failures\", function () {\n            describe(\"when subsequent files have not yet been run\", function () {\n              it(\"should cleanly terminate the thread pool\", function (done) {\n                const options = { reporter: runner._workerReporter };\n                const err = {\n                  __type: \"Error\",\n                  message: \"oh no\",\n                };\n                run.withArgs(\"some-file.js\", options).resolves({\n                  failureCount: 1,\n                  events: [\n                    {\n                      eventName: EVENT_TEST_FAIL,\n                      data: {\n                        title: \"some test\",\n                      },\n                      error: err,\n                    },\n                    {\n                      eventName: EVENT_SUITE_END,\n                      data: {\n                        title: \"some suite\",\n                        _bail: true,\n                      },\n                    },\n                  ],\n                });\n                run.withArgs(\"some-other-file.js\", options).rejects();\n\n                runner.run(\n                  () => {\n                    expect(terminate, \"to have calls satisfying\", [\n                      { args: [] }, // this is the pool force-terminating\n                      { args: [] }, // this will always be called, and will do nothing due to the previous call\n                    ]).and(\"was called twice\");\n                    done();\n                  },\n                  {\n                    files: [\"some-file.js\", \"some-other-file.js\"],\n                    options,\n                  },\n                );\n              });\n            });\n\n            describe(\"when subsequent files already started running\", function () {\n              it(\"should cleanly terminate the thread pool\", function (done) {\n                const options = { reporter: runner._workerReporter };\n                const err = {\n                  __type: \"Error\",\n                  message: \"oh no\",\n                };\n                run.withArgs(\"some-file.js\", options).resolves({\n                  failureCount: 1,\n                  events: [\n                    {\n                      eventName: EVENT_TEST_FAIL,\n                      data: {\n                        title: \"some test\",\n                      },\n                      error: err,\n                    },\n                    {\n                      eventName: EVENT_SUITE_END,\n                      data: {\n                        title: \"some suite\",\n                        _bail: true,\n                      },\n                    },\n                  ],\n                });\n                run.withArgs(\"some-other-file.js\", options).resolves({\n                  failureCount: 0,\n                  events: [\n                    {\n                      eventName: EVENT_TEST_PASS,\n                      data: {\n                        title: \"some test\",\n                      },\n                    },\n                    {\n                      eventName: EVENT_SUITE_END,\n                      data: {\n                        title: \"some suite\",\n                      },\n                    },\n                  ],\n                });\n\n                runner.run(\n                  () => {\n                    expect(terminate, \"to have calls satisfying\", [\n                      { args: [] }, // this is the pool force-terminating\n                      { args: [] }, // this will always be called, and will do nothing due to the previous call\n                    ]).and(\"was called twice\");\n                    done();\n                  },\n                  {\n                    files: [\"some-file.js\", \"some-other-file.js\"],\n                    options,\n                  },\n                );\n              });\n            });\n\n            describe(\"when subsequent files have not yet been run\", function () {\n              it(\"should cleanly terminate the thread pool\", function (done) {\n                const options = { reporter: runner._workerReporter };\n                const err = {\n                  __type: \"Error\",\n                  message: \"oh no\",\n                };\n                run.withArgs(\"some-file.js\", options).resolves({\n                  failureCount: 1,\n                  events: [\n                    {\n                      eventName: EVENT_TEST_FAIL,\n                      data: {\n                        title: \"some test\",\n                      },\n                      error: err,\n                    },\n                    {\n                      eventName: EVENT_SUITE_END,\n                      data: {\n                        title: \"some suite\",\n                        _bail: true,\n                      },\n                    },\n                  ],\n                });\n                run.withArgs(\"some-other-file.js\", options).rejects();\n\n                runner.run(\n                  () => {\n                    expect(terminate, \"to have calls satisfying\", [\n                      { args: [] }, // this is the pool force-terminating\n                      { args: [] }, // this will always be called, and will do nothing due to the previous call\n                    ]).and(\"was called twice\");\n                    done();\n                  },\n                  {\n                    files: [\"some-file.js\", \"some-other-file.js\"],\n                    options,\n                  },\n                );\n              });\n            });\n          });\n        });\n      });\n\n      describe(\"linkPartialObjects()\", function () {\n        let runner;\n\n        beforeEach(function () {\n          runner = new ParallelBufferedRunner(suite);\n        });\n\n        it(\"should return the runner\", function () {\n          expect(runner.linkPartialObjects(), \"to be\", runner);\n        });\n\n        // avoid testing implementation details; don't check _linkPartialObjects\n      });\n\n      describe(\"isParallelMode()\", function () {\n        let runner;\n\n        beforeEach(function () {\n          runner = new ParallelBufferedRunner(suite);\n        });\n\n        it(\"should return true\", function () {\n          expect(runner.isParallelMode(), \"to be true\");\n        });\n      });\n\n      describe(\"workerReporter()\", function () {\n        let runner;\n\n        beforeEach(function () {\n          runner = new ParallelBufferedRunner(suite);\n        });\n\n        it(\"should return its context\", function () {\n          expect(runner.workerReporter(), \"to be\", runner);\n        });\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/node-unit/reporters/parallel-buffered.spec.js",
    "content": "\"use strict\";\n\n// this reporter does not actually output anything to the terminal, so we\n// need to test it differently.\n\nconst {\n  EVENT_SUITE_BEGIN,\n  EVENT_SUITE_END,\n  EVENT_TEST_FAIL,\n  EVENT_TEST_PASS,\n  EVENT_TEST_PENDING,\n  EVENT_TEST_BEGIN,\n  EVENT_TEST_END,\n  EVENT_TEST_RETRY,\n  EVENT_DELAY_BEGIN,\n  EVENT_DELAY_END,\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_RUN_END,\n} = require(\"../../../lib/runner\").constants;\nconst { EventEmitter } = require(\"node:events\");\nconst sinon = require(\"sinon\");\nconst rewiremock = require(\"rewiremock/node\");\nconst semver = require(\"semver\");\n\ndescribe(\"ParallelBuffered\", function () {\n  /** @type {EventEmitter} */\n  let runner;\n  let ParallelBuffered;\n\n  beforeEach(function () {\n    runner = new EventEmitter();\n    ParallelBuffered = rewiremock.proxy(\n      () => require(\"../../../lib/nodejs/reporters/parallel-buffered\"),\n      {\n        \"../../../lib/nodejs/serializer\": {\n          SerializableEvent: {\n            create: (eventName, runnable, err) => ({\n              eventName,\n              data: runnable,\n              error: err,\n              __type: \"MockSerializableEvent\",\n            }),\n          },\n          SerializableWorkerResult: {\n            create: (events, failures) => ({\n              events,\n              failures,\n              __type: \"MockSerializableWorkerResult\",\n            }),\n          },\n        },\n        \"../../../lib/reporters/base\": class MockBase {},\n      },\n    );\n  });\n\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"constructor\", function () {\n    it(\"should listen for Runner events\", function () {\n      // EventEmitter#once calls thru to EventEmitter#on, which\n      // befouls our assertion below.\n      sinon.stub(runner, \"once\");\n      sinon.stub(runner, \"on\");\n\n      new ParallelBuffered(runner);\n      expect(runner.on, \"to have calls satisfying\", [\n        // via Buffered\n        [EVENT_SUITE_BEGIN, expect.it(\"to be a function\")],\n        [EVENT_SUITE_END, expect.it(\"to be a function\")],\n        [EVENT_TEST_BEGIN, expect.it(\"to be a function\")],\n        [EVENT_TEST_PENDING, expect.it(\"to be a function\")],\n        [EVENT_TEST_FAIL, expect.it(\"to be a function\")],\n        [EVENT_TEST_PASS, expect.it(\"to be a function\")],\n        [EVENT_TEST_RETRY, expect.it(\"to be a function\")],\n        [EVENT_TEST_END, expect.it(\"to be a function\")],\n        [EVENT_HOOK_BEGIN, expect.it(\"to be a function\")],\n        [EVENT_HOOK_END, expect.it(\"to be a function\")],\n      ]);\n    });\n\n    it(\"should listen for Runner events expecting to occur once\", function () {\n      sinon.stub(runner, \"once\");\n\n      new ParallelBuffered(runner);\n      expect(runner.once, \"to have calls satisfying\", [\n        [EVENT_DELAY_BEGIN, expect.it(\"to be a function\")],\n        [EVENT_DELAY_END, expect.it(\"to be a function\")],\n        [EVENT_RUN_END, expect.it(\"to be a function\")],\n      ]);\n    });\n  });\n\n  describe(\"event\", function () {\n    let reporter;\n\n    beforeEach(function () {\n      reporter = new ParallelBuffered(runner);\n    });\n\n    describe(\"on EVENT_RUN_END\", function () {\n      it(\"should remove all listeners\", function () {\n        runner.emit(EVENT_RUN_END);\n        // Some node versions throw instead of returning `[]` due to a bug\n        // Fix is in Node ^22.14 and ^24.0, but not yet backported to 20 as of writing\n        // Problem was introduced in 20.19.0, not present in 20.18.3\n        // https://github.com/nodejs/node/issues/56263\n        const nodeVersionThrows = semver.satisfies(\n          process.versions.node,\n          \"^20.19.0 || >=22.0.0 <22.14.0\",\n        );\n        if (nodeVersionThrows) {\n          expect(runner.listeners, \"to throw\");\n        } else {\n          expect(runner.listeners(), \"to be empty\");\n        }\n      });\n    });\n\n    describe(\"on any other event listened for\", function () {\n      it(\"should populate its `events` array with SerializableEvents\", function () {\n        const suite = {\n          title: \"some suite\",\n        };\n        const test = {\n          title: \"some test\",\n        };\n        runner.emit(EVENT_SUITE_BEGIN, suite);\n        runner.emit(EVENT_TEST_BEGIN, test);\n        runner.emit(EVENT_TEST_PASS, test);\n        runner.emit(EVENT_TEST_END, test);\n        runner.emit(EVENT_SUITE_END, suite);\n        expect(reporter.events, \"to equal\", [\n          {\n            eventName: EVENT_SUITE_BEGIN,\n            data: suite,\n            __type: \"MockSerializableEvent\",\n          },\n          {\n            eventName: EVENT_TEST_BEGIN,\n            data: test,\n            __type: \"MockSerializableEvent\",\n          },\n          {\n            eventName: EVENT_TEST_PASS,\n            data: test,\n            __type: \"MockSerializableEvent\",\n          },\n          {\n            eventName: EVENT_TEST_END,\n            data: test,\n            __type: \"MockSerializableEvent\",\n          },\n          {\n            eventName: EVENT_SUITE_END,\n            data: suite,\n            __type: \"MockSerializableEvent\",\n          },\n        ]);\n      });\n    });\n  });\n\n  describe(\"instance method\", function () {\n    let reporter;\n\n    beforeEach(function () {\n      reporter = new ParallelBuffered(runner);\n    });\n\n    describe(\"done\", function () {\n      it(\"should execute its callback with a SerializableWorkerResult\", function () {\n        const suite = {\n          title: \"some suite\",\n        };\n        const test = {\n          title: \"some test\",\n        };\n        runner.emit(EVENT_SUITE_BEGIN, suite);\n        runner.emit(EVENT_TEST_BEGIN, test);\n        runner.emit(EVENT_TEST_PASS, test);\n        runner.emit(EVENT_TEST_END, test);\n        runner.emit(EVENT_SUITE_END, suite);\n        const cb = sinon.stub();\n        reporter.done(0, cb);\n        expect(cb, \"to have a call satisfying\", [\n          {\n            events: [\n              {\n                eventName: EVENT_SUITE_BEGIN,\n                data: suite,\n                __type: \"MockSerializableEvent\",\n              },\n              {\n                eventName: EVENT_TEST_BEGIN,\n                data: test,\n                __type: \"MockSerializableEvent\",\n              },\n              {\n                eventName: EVENT_TEST_PASS,\n                data: test,\n                __type: \"MockSerializableEvent\",\n              },\n              {\n                eventName: EVENT_TEST_END,\n                data: test,\n                __type: \"MockSerializableEvent\",\n              },\n              {\n                eventName: EVENT_SUITE_END,\n                data: suite,\n                __type: \"MockSerializableEvent\",\n              },\n            ],\n            failures: 0,\n            __type: \"MockSerializableWorkerResult\",\n          },\n        ]);\n      });\n\n      it(\"should reset its `events` prop\", function () {\n        const suite = {\n          title: \"some suite\",\n        };\n        const test = {\n          title: \"some test\",\n        };\n        runner.emit(EVENT_SUITE_BEGIN, suite);\n        runner.emit(EVENT_TEST_BEGIN, test);\n        runner.emit(EVENT_TEST_PASS, test);\n        runner.emit(EVENT_TEST_END, test);\n        runner.emit(EVENT_SUITE_END, suite);\n        const cb = sinon.stub();\n        reporter.done(0, cb);\n        expect(reporter.events, \"to be empty\");\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/node-unit/serializer.spec.js",
    "content": "\"use strict\";\n\nconst sinon = require(\"sinon\");\nconst {\n  serialize,\n  deserialize,\n  SerializableEvent,\n  SerializableWorkerResult,\n} = require(\"../../lib/nodejs/serializer\");\n\ndescribe(\"serializer\", function () {\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"function\", function () {\n    describe(\"serialize\", function () {\n      describe(\"when passed a non-object value\", function () {\n        it(\"should return the value\", function () {\n          expect(serialize(\"knees & toes\"), \"to be\", \"knees & toes\");\n        });\n      });\n\n      describe(\"when passed an object value\", function () {\n        describe(\"w/o a `serialize` method\", function () {\n          it(\"should return the value\", function () {\n            const obj = {};\n            expect(serialize(obj), \"to be\", obj);\n          });\n        });\n\n        describe(\"having a `serialize` method\", function () {\n          it(\"should return the result of the `serialize` method\", function () {\n            const serializedObj = { foo: \"bar\" };\n            const obj = { serialize: sinon.stub().returns(serializedObj) };\n            expect(serialize(obj), \"to be\", serializedObj);\n          });\n        });\n      });\n\n      describe(\"when not passed anything\", function () {\n        it(\"should return `undefined`\", function () {\n          expect(serialize(), \"to be undefined\");\n        });\n      });\n    });\n\n    describe(\"deserialize\", function () {\n      describe(\"when passed nothing\", function () {\n        it(\"should return `undefined`\", function () {\n          expect(deserialize(), \"to be undefined\");\n        });\n      });\n\n      describe(\"when passed a non-object value\", function () {\n        it(\"should return the value\", function () {\n          expect(deserialize(500), \"to be\", 500);\n        });\n      });\n\n      describe(\"when passed an object value which is not a SerializedWorkerResult\", function () {\n        it(\"should return the value\", function () {\n          const obj = {};\n          expect(deserialize(obj), \"to be\", obj);\n        });\n      });\n\n      describe(\"when passed a SerializedWorkerResult object\", function () {\n        // note that SerializedWorkerResult is an interface (typedef), not a class.\n\n        it(\"should return the result of `SerializableWorkerResult.deserialize` called on the value\", function () {\n          const obj = Object.assign({}, SerializableWorkerResult.create());\n          sinon.stub(SerializableWorkerResult, \"deserialize\").returns(\"butts\");\n          deserialize(obj);\n          expect(\n            SerializableWorkerResult.deserialize,\n            \"to have a call satisfying\",\n            {\n              args: [obj],\n              returned: \"butts\",\n            },\n          );\n        });\n      });\n    });\n  });\n\n  describe(\"SerializableEvent\", function () {\n    describe(\"constructor\", function () {\n      describe(\"when called without `eventName`\", function () {\n        it('should throw \"invalid arg value\" error', function () {\n          expect(() => new SerializableEvent(), \"to throw\", {\n            code: \"ERR_MOCHA_INVALID_ARG_TYPE\",\n          });\n        });\n      });\n\n      describe(\"when called with a non-object `rawObject`\", function () {\n        it('should throw \"invalid arg type\" error', function () {\n          expect(() => new SerializableEvent(\"blub\", \"glug\"), \"to throw\", {\n            code: \"ERR_MOCHA_INVALID_ARG_TYPE\",\n          });\n        });\n      });\n    });\n\n    describe(\"instance method\", function () {\n      describe(\"serialize\", function () {\n        it(\"should mutate the instance in-place\", function () {\n          const evt = SerializableEvent.create(\"foo\");\n          expect(evt.serialize(), \"to be\", evt);\n        });\n\n        it(\"should freeze the instance\", function () {\n          expect(\n            Object.isFrozen(SerializableEvent.create(\"foo\").serialize()),\n            \"to be true\",\n          );\n        });\n\n        describe(\"when passed an object with a `serialize` method\", function () {\n          it(\"should call the `serialize` method\", function () {\n            const obj = {\n              serialize: sinon.stub(),\n            };\n            SerializableEvent.create(\"some-event\", obj).serialize();\n            expect(obj.serialize, \"was called once\");\n          });\n        });\n\n        describe(\"when passed an object containing an object with a `serialize` method\", function () {\n          it(\"should call the `serialize` method\", function () {\n            const stub = sinon.stub();\n            const obj = {\n              nested: {\n                serialize: stub,\n              },\n            };\n            SerializableEvent.create(\"some-event\", obj).serialize();\n            expect(stub, \"was called once\");\n          });\n        });\n\n        describe(\"when passed an object containing a non-`serialize` method\", function () {\n          it(\"should remove the method\", function () {\n            const obj = {\n              func: () => {},\n            };\n\n            expect(\n              SerializableEvent.create(\"some-event\", obj).serialize(),\n              \"to satisfy\",\n              {\n                data: expect.it(\"not to have property\", \"func\"),\n              },\n            );\n          });\n        });\n\n        describe(\"when passed an object containing an array\", function () {\n          it(\"should serialize the array\", function () {\n            const obj = {\n              list: [{ herp: \"derp\" }, { bing: \"bong\" }],\n            };\n            expect(\n              SerializableEvent.create(\"some-event\", obj).serialize(),\n              \"to satisfy\",\n              { data: { list: [{ herp: \"derp\" }, { bing: \"bong\" }] } },\n            );\n          });\n        });\n\n        describe(\"when passed an error\", function () {\n          it(\"should serialize the error\", function () {\n            const obj = {};\n            const err = new Error(\"monkeypants\");\n            expect(\n              SerializableEvent.create(\"some-event\", obj, err).serialize(),\n              \"to satisfy\",\n              {\n                eventName: \"some-event\",\n                error: {\n                  message: \"monkeypants\",\n                  stack: /^Error: monkeypants/,\n                  __type: \"Error\",\n                },\n                data: obj,\n              },\n            );\n          });\n\n          it(\"should retain own props\", function () {\n            const obj = {};\n            const err = new Error(\"monkeypants\");\n            err.code = \"MONKEY\";\n            expect(\n              SerializableEvent.create(\"some-event\", obj, err).serialize(),\n              \"to satisfy\",\n              {\n                eventName: \"some-event\",\n                error: {\n                  code: \"MONKEY\",\n                  message: \"monkeypants\",\n                  stack: /^Error: monkeypants/,\n                  __type: \"Error\",\n                },\n                data: obj,\n              },\n            );\n          });\n\n          it(\"should not retain not-own props\", function () {\n            const obj = {};\n            const err = new Error(\"monkeypants\");\n\n            err.__proto__.code = \"MONKEY\";\n            expect(\n              SerializableEvent.create(\"some-event\", obj, err).serialize(),\n              \"to satisfy\",\n              {\n                eventName: \"some-event\",\n                error: {\n                  message: \"monkeypants\",\n                  stack: /^Error: monkeypants/,\n                  __type: \"Error\",\n                },\n                data: obj,\n              },\n            );\n          });\n        });\n\n        describe(\"when passed an object containing a top-level prop with an Error value\", function () {\n          it(\"should serialize the Error\", function () {\n            const obj = {\n              monkeyError: new Error(\"pantsmonkey\"),\n            };\n            const evt = SerializableEvent.create(\"some-event\", obj);\n            expect(evt.serialize(), \"to satisfy\", {\n              eventName: \"some-event\",\n              data: {\n                monkeyError: {\n                  message: \"pantsmonkey\",\n                  stack: /^Error: pantsmonkey/,\n                  __type: \"Error\",\n                },\n              },\n            });\n          });\n        });\n        describe(\"when passed an object containing a nested prop with an Error value\", function () {\n          it(\"should serialize the Error\", function () {\n            const obj = {\n              nestedObj: {\n                monkeyError: new Error(\"pantsmonkey\"),\n              },\n            };\n            const evt = SerializableEvent.create(\"some-event\", obj);\n            expect(evt.serialize(), \"to satisfy\", {\n              eventName: \"some-event\",\n              data: {\n                nestedObj: {\n                  monkeyError: {\n                    message: \"pantsmonkey\",\n                    stack: /^Error: pantsmonkey/,\n                    __type: \"Error\",\n                  },\n                },\n              },\n            });\n          });\n        });\n      });\n    });\n\n    describe(\"static method\", function () {\n      describe(\"deserialize\", function () {\n        describe(\"when passed a falsy parameter\", function () {\n          it('should throw \"invalid arg type\" error', function () {\n            expect(SerializableEvent.deserialize, \"to throw\", {\n              code: \"ERR_MOCHA_INVALID_ARG_TYPE\",\n            });\n          });\n        });\n\n        it(\"should return a new object w/ null prototype\", function () {\n          const obj = { bob: \"bob\" };\n          expect(SerializableEvent.deserialize(obj), \"to satisfy\", obj)\n            .and(\"not to equal\", obj)\n            .and(\"not to have property\", \"constructor\");\n        });\n\n        describe(\"when passed value contains `data` prop\", function () {\n          it(\"should ignore __proto__\", function () {\n            const obj = {\n              data: Object.create(null),\n            };\n\n            obj.data.__proto__ = { peaches: \"prunes\" };\n\n            const expected = Object.assign(Object.create(null), {\n              data: Object.create(null),\n            });\n            expect(SerializableEvent.deserialize(obj), \"to equal\", expected);\n          });\n\n          describe(\"when `data` prop contains a nested serialized Error prop\", function () {\n            it(\"should create an Error instance from the nested serialized Error prop\", function () {\n              const message = \"problems!\";\n              const stack = \"problem instructions\";\n              const code = \"EIEIO\";\n              const expected = Object.assign(Object.create(null), {\n                data: {\n                  whoops: Object.assign(new Error(message), {\n                    stack,\n                    code,\n                  }),\n                },\n              });\n\n              expect(\n                SerializableEvent.deserialize({\n                  data: {\n                    whoops: {\n                      message,\n                      stack,\n                      code,\n                      __type: \"Error\",\n                    },\n                  },\n                }),\n                \"to equal\",\n                expected,\n              );\n            });\n          });\n        });\n\n        describe(\"when passed value contains an `error` prop\", function () {\n          it(\"should create an Error instance from the prop\", function () {\n            const message = \"problems!\";\n            const stack = \"problem instructions\";\n            const code = \"EIEIO\";\n            const expected = Object.assign(Object.create(null), {\n              error: Object.assign(new Error(message), {\n                stack,\n                code,\n              }),\n            });\n\n            expect(\n              SerializableEvent.deserialize({\n                error: {\n                  message,\n                  stack,\n                  code,\n                  __type: \"Error\",\n                },\n              }),\n              \"to equal\",\n              expected,\n            );\n          });\n        });\n\n        describe('when passed value data contains a prop beginning with \"$$\"', function () {\n          let result;\n\n          beforeEach(function () {\n            result = SerializableEvent.deserialize({ data: { $$foo: \"bar\" } });\n          });\n          it(\"should create a new prop having a function value\", function () {\n            expect(result, \"to satisfy\", {\n              data: {\n                foo: expect.it(\"to be a function\"),\n              },\n            });\n          });\n\n          it(\"should create a new prop returning the original value\", function () {\n            expect(result.data.foo(), \"to equal\", \"bar\");\n          });\n\n          it('should remove the prop with the \"$$\" prefix', function () {\n            expect(result, \"not to have property\", \"$$foo\");\n          });\n        });\n\n        describe(\"when the value data contains a prop with an array value\", function () {\n          beforeEach(function () {\n            sinon.spy(SerializableEvent, \"_deserializeObject\");\n          });\n\n          it(\"should deserialize each prop\", function () {\n            const obj = { data: { foo: [{ bar: \"baz\" }] } };\n            SerializableEvent.deserialize(obj);\n            expect(\n              SerializableEvent._deserializeObject,\n              \"to have a call satisfying\",\n              {\n                args: [obj.data.foo, 0],\n              },\n            );\n          });\n        });\n      });\n\n      describe(\"create\", function () {\n        it(\"should instantiate a SerializableEvent\", function () {\n          expect(\n            SerializableEvent.create(\"some-event\"),\n            \"to be a\",\n            SerializableEvent,\n          );\n        });\n      });\n    });\n  });\n\n  describe(\"SerializableWorkerResult\", function () {\n    describe(\"static method\", function () {\n      describe(\"create\", function () {\n        it(\"should return a new SerializableWorkerResult instance\", function () {\n          expect(\n            SerializableWorkerResult.create(),\n            \"to be a\",\n            SerializableWorkerResult,\n          );\n        });\n      });\n\n      describe(\"isSerializedWorkerResult\", function () {\n        describe(\"when passed an instance\", function () {\n          it(\"should return `true`\", function () {\n            expect(\n              SerializableWorkerResult.isSerializedWorkerResult(\n                new SerializableWorkerResult(),\n              ),\n              \"to be true\",\n            );\n          });\n        });\n\n        describe(\"when passed an object with an appropriate `__type` prop\", function () {\n          it(\"should return `true`\", function () {\n            // this is the most likely use-case, as the object is transmitted over IPC\n            // and loses its prototype\n            const original = new SerializableWorkerResult();\n            const clone = Object.assign({}, original);\n            expect(\n              SerializableWorkerResult.isSerializedWorkerResult(clone),\n              \"to be true\",\n            );\n          });\n        });\n\n        describe(\"when passed an object without an appropriate `__type` prop\", function () {\n          it(\"should return `false`\", function () {\n            expect(\n              SerializableWorkerResult.isSerializedWorkerResult({\n                mister: \"mister\",\n              }),\n              \"to be false\",\n            );\n          });\n        });\n      });\n\n      describe(\"deserialize\", function () {\n        beforeEach(function () {\n          sinon.stub(SerializableEvent, \"deserialize\");\n        });\n\n        it(\"should call SerializableEvent#deserialize on each item in its `events` prop\", function () {\n          const result = Object.assign(\n            {},\n            SerializableWorkerResult.create([\n              { eventName: \"foo\" },\n              { eventName: \"bar\" },\n            ]),\n          );\n          SerializableWorkerResult.deserialize(result);\n          expect(SerializableEvent.deserialize, \"to have calls satisfying\", [\n            { args: [{ eventName: \"foo\" }] },\n            { args: [{ eventName: \"bar\" }] },\n          ]);\n        });\n\n        it(\"should return the deserialized value\", function () {\n          const result = Object.assign(\n            {},\n            SerializableWorkerResult.create([\n              { eventName: \"foo\" },\n              { eventName: \"bar\" },\n            ]),\n          );\n          expect(\n            SerializableWorkerResult.deserialize(result),\n            \"to equal\",\n            result,\n          );\n        });\n      });\n    });\n\n    describe(\"instance method\", function () {\n      describe(\"serialize\", function () {\n        it(\"should return a read-only value\", function () {\n          expect(\n            Object.isFrozen(SerializableWorkerResult.create().serialize()),\n            \"to be true\",\n          );\n        });\n\n        it(\"should call `SerializableEvent#serialize` of each of its events\", function () {\n          sinon.spy(SerializableEvent.prototype, \"serialize\");\n          const events = [\n            SerializableEvent.create(\"foo\"),\n            SerializableEvent.create(\"bar\"),\n          ];\n          SerializableWorkerResult.create(events).serialize();\n          expect(\n            SerializableEvent.prototype.serialize,\n            \"to have calls satisfying\",\n            [{ thisValue: events[0] }, { thisValue: events[1] }],\n          );\n        });\n      });\n    });\n    describe(\"constructor\", function () {\n      // the following two tests should be combined into one, but not sure how to express\n      // as a single assertion\n\n      it(\"should add a readonly `__type` prop\", function () {\n        expect(\n          new SerializableWorkerResult(),\n          \"to have readonly property\",\n          \"__type\",\n        );\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/node-unit/stack-trace-filter.spec.js",
    "content": "\"use strict\";\n\nvar path = require(\"node:path\");\nvar utils = require(\"../../lib/utils\");\n\ndescribe(\"stackTraceFilter()\", function () {\n  describe(\"on node\", function () {\n    var filter = utils.stackTraceFilter();\n\n    describe(\"on POSIX OS\", function () {\n      before(function () {\n        if (path.sep !== \"/\") {\n          this.skip();\n        }\n      });\n\n      it(\"should get a stack-trace as a string and prettify it\", function () {\n        var stack = [\n          \"AssertionError: foo bar\",\n          \"at EventEmitter.<anonymous> (/usr/local/dev/test.js:16:12)\",\n          \"at Context.<anonymous> (/usr/local/dev/test.js:19:5)\",\n          \"Test.Runnable.run (/usr/local/lib/node_modules/mocha/lib/runnable.js:244:7)\",\n          \"Runner.runTest (/usr/local/lib/node_modules/mocha/lib/runner.js:374:10)\",\n          \"/usr/local/lib/node_modules/mocha/lib/runner.js:452:12\",\n          \"next (/usr/local/lib/node_modules/mocha/lib/runner.js:299:14)\",\n          \"/usr/local/lib/node_modules/mocha/lib/runner.js:309:7\",\n          \"next (/usr/local/lib/node_modules/mocha/lib/runner.js:248:23)\",\n          \"Immediate._onImmediate (/usr/local/lib/node_modules/mocha/lib/runner.js:276:5)\",\n          \"at processImmediate [as _immediateCallback] (timers.js:321:17)\",\n        ];\n        expect(filter(stack.join(\"\\n\")), \"to be\", stack.slice(0, 3).join(\"\\n\"));\n\n        stack = [\n          \"AssertionError: bar baz\",\n          \"at /usr/local/dev/some-test-file.js:25:8\",\n          \"at tryCatcher (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/util.js:24:31)\",\n          \"at Promise._resolveFromResolver (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/promise.js:439:31)\",\n          \"at new Promise (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/promise.js:53:37)\",\n          \"at yourFunction (/usr/local/dev/own/tmp/test1.js:24:13)\",\n          \"at Context.<anonymous> (/usr/local/dev/some-test-file:30:4)\",\n          \"Test.Runnable.run (/usr/local/lib/node_modules/mocha/lib/runnable.js:218:15)\",\n          \"next (/usr/local/lib/node_modules/mocha/lib/runner.js:248:23)\",\n          \"Immediate._onImmediate (/usr/local/lib/node_modules/mocha/lib/runner.js:276:5)\",\n          \"at processImmediate [as _immediateCallback] (timers.js:321:17)\",\n        ];\n\n        expect(filter(stack.join(\"\\n\")), \"to be\", stack.slice(0, 7).join(\"\\n\"));\n      });\n\n      it(\"does not ignore other bower_components and components\", function () {\n        var stack = [\n          \"Error: failed\",\n          \"at assert (index.html:11:26)\",\n          \"at Context.<anonymous> (test.js:17:18)\",\n          \"at bower_components/should/should.js:4827:7\",\n          \"at next (file:///.../bower_components/should/should.js:4766:23)\",\n          \"at components/should/5.0.0/should.js:4827:7\",\n          \"at next (file:///.../components/should/5.0.0/should.js:4766:23)\",\n          \"at file:///.../bower_components/mocha/mocha.js:4794:5\",\n          \"at timeslice (.../components/mocha/mocha.js:6218:27)\",\n          \"at Test.require.register.Runnable.run (file:///.../components/mochajs/mocha/2.1.0/mocha.js:4463:15)\",\n          \"at Runner.require.register.Runner.runTest (file:///.../components/mochajs/mocha/2.1.0/mocha.js:4892:10)\",\n          \"at file:///.../components/mochajs/mocha/2.1.0/mocha.js:4970:12\",\n          \"at next (file:///.../components/mochajs/mocha/2.1.0/mocha.js:4817:14)\",\n        ];\n        expect(filter(stack.join(\"\\n\")), \"to be\", stack.slice(0, 7).join(\"\\n\"));\n      });\n\n      it(\"should replace absolute with relative paths\", function () {\n        var stack = [\n          \"Error: \" + process.cwd() + \"/bla.js has a problem\",\n          \"at foo (\" + process.cwd() + \"/foo/index.js:13:226)\",\n          \"at bar (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/promise.js:11:26)\",\n        ];\n\n        var expected = [\n          \"Error: \" + process.cwd() + \"/bla.js has a problem\",\n          \"at foo (foo/index.js:13:226)\",\n          \"at bar (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/promise.js:11:26)\",\n        ];\n\n        expect(filter(stack.join(\"\\n\")), \"to be\", expected.join(\"\\n\"));\n      });\n\n      it(\"should not replace absolute path which has cwd as infix\", function () {\n        var stack = [\n          \"Error: /www\" + process.cwd() + \"/bla.js has a problem\",\n          \"at foo (/www\" + process.cwd() + \"/foo/index.js:13:226)\",\n          \"at bar (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/promise.js:11:26)\",\n        ];\n\n        var expected = [\n          \"Error: /www\" + process.cwd() + \"/bla.js has a problem\",\n          \"at foo (/www\" + process.cwd() + \"/foo/index.js:13:226)\",\n          \"at bar (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/promise.js:11:26)\",\n        ];\n\n        expect(filter(stack.join(\"\\n\")), \"to be\", expected.join(\"\\n\"));\n      });\n    });\n\n    describe(\"on Windows\", function () {\n      before(function () {\n        if (path.sep === \"/\") {\n          this.skip();\n        }\n      });\n\n      it(\"should work on Windows\", function () {\n        var stack = [\n          \"Error: failed\",\n          \"at Context.<anonymous> (C:\\\\Users\\\\ishida\\\\src\\\\test\\\\test\\\\mytest.js:5:9)\",\n          \"at callFn (C:\\\\Users\\\\ishida\\\\src\\\\test\\\\node_modules\\\\mocha\\\\lib\\\\runnable.js:326:21)\",\n          \"at Test.Runnable.run (C:\\\\Users\\\\ishida\\\\src\\\\test\\\\node_modules\\\\mocha\\\\lib\\\\runnable.js:319:7)\",\n          \"at Runner.runTest (C:\\\\Users\\\\ishida\\\\src\\\\test\\\\node_modules\\\\mocha\\\\lib\\\\runner.js:422:10)\",\n          \"at C:\\\\Users\\\\ishida\\\\src\\\\test\\\\node_modules\\\\mocha\\\\lib\\\\runner.js:528:12\",\n          \"at next (C:\\\\Users\\\\ishida\\\\src\\\\test\\\\node_modules\\\\mocha\\\\lib\\\\runner.js:342:14)\",\n          \"at C:\\\\Users\\\\ishida\\\\src\\\\test\\\\node_modules\\\\mocha\\\\lib\\\\runner.js:352:7\",\n          \"at next (C:\\\\Users\\\\ishida\\\\src\\\\test\\\\node_modules\\\\mocha\\\\lib\\\\runner.js:284:14)\",\n          \"at Immediate._onImmediate (C:\\\\Users\\\\ishida\\\\src\\\\test\\\\node_modules\\\\mocha\\\\lib\\\\runner.js:320:5)\",\n        ];\n        expect(filter(stack.join(\"\\n\")), \"to be\", stack.slice(0, 2).join(\"\\n\"));\n      });\n    });\n  });\n\n  describe(\"on browser\", function () {\n    var filter;\n    before(function () {\n      global.document = true;\n      global.location = { href: \"localhost:3000/foo/bar/index.html\" };\n      filter = utils.stackTraceFilter();\n    });\n    it(\"does not strip out other bower_components\", function () {\n      var stack = [\n        \"Error: failed\",\n        \"at assert (index.html:11:26)\",\n        \"at Context.<anonymous> (test.js:17:18)\",\n        \"at bower_components/should/should.js:4827:7\",\n        \"at next (bower_components/should/should.js:4766:23)\",\n        \"at components/should/5.0.0/should.js:4827:7\",\n        \"at next (components/should/5.0.0/should.js:4766:23)\",\n        \"at Runner.require.register.Runner.runTest (node_modules/mocha.js:4892:10)\",\n        \"at localhost:3000/foo/bar/node_modules/mocha.js:4970:12\",\n        \"at next (node_modules/mocha.js:4817:14)\",\n      ];\n      expect(filter(stack.join(\"\\n\")), \"to be\", stack.slice(0, 7).join(\"\\n\"));\n    });\n\n    after(function () {\n      delete global.document;\n      delete global.location;\n    });\n  });\n});\n"
  },
  {
    "path": "test/node-unit/utils.spec.js",
    "content": "\"use strict\";\n\nconst rewiremock = require(\"rewiremock/node\");\n\ndescribe(\"utils\", function () {\n  let utils;\n\n  beforeEach(function () {\n    // add deps to be mocked as needed to second parameter\n    utils = rewiremock.proxy(\"../../lib/utils\", {});\n  });\n\n  describe(\"function\", function () {\n    describe(\"cwd()\", function () {\n      it(\"should return the current working directory\", function () {\n        expect(utils.cwd(), \"to be\", process.cwd());\n      });\n    });\n\n    describe(\"type()\", function () {\n      it('should return \"function\" if the parameter is an async function', function () {\n        expect(\n          utils.type(async () => {}),\n          \"to be\",\n          \"function\",\n        );\n      });\n      it('should return \"error\" if the parameter is an Error', function () {\n        expect(utils.type(new Error(\"err\")), \"to be\", \"error\");\n      });\n    });\n    describe(\"canonicalType()\", function () {\n      it('should return \"buffer\" if the parameter is a Buffer', function () {\n        expect(\n          utils.canonicalType(Buffer.from(\"ff\", \"hex\")),\n          \"to be\",\n          \"buffer\",\n        );\n      });\n      it('should return \"asyncfunction\" if the parameter is an async function', function () {\n        expect(\n          utils.canonicalType(async () => {}),\n          \"to be\",\n          \"asyncfunction\",\n        );\n      });\n    });\n    describe(\"isNumeric()\", function () {\n      it(\"returns true for a number type\", function () {\n        expect(utils.isNumeric(42), \"to equal\", true);\n      });\n      it(\"returns true for a string that can be parsed as a number\", function () {\n        expect(utils.isNumeric(\"42\"), \"to equal\", true);\n      });\n      it(\"returns false for a string that cannot be parsed as a number\", function () {\n        expect(utils.isNumeric(\"foo\"), \"to equal\", false);\n      });\n      it(\"returns false for empty string\", function () {\n        expect(utils.isNumeric(\"\"), \"to equal\", false);\n      });\n      it(\"returns false for empty string with many whitespaces\", function () {\n        expect(utils.isNumeric(\"    \"), \"to equal\", false);\n      });\n      it(\"returns true for stringified zero\", function () {\n        expect(utils.isNumeric(\"0\"), \"to equal\", true);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/node-unit/worker.spec.js",
    "content": "\"use strict\";\n\nconst serializeJavascript = require(\"serialize-javascript\");\nconst rewiremock = require(\"rewiremock/node\");\nconst { SerializableWorkerResult } = require(\"../../lib/nodejs/serializer\");\nconst sinon = require(\"sinon\");\n\nconst WORKER_PATH = require.resolve(\"../../lib/nodejs/worker.js\");\n\ndescribe(\"worker\", function () {\n  let worker;\n  let stubs;\n\n  beforeEach(function () {\n    stubs = {\n      workerpool: {\n        isMainThread: false,\n        worker: sinon.stub(),\n      },\n    };\n    sinon.spy(process, \"removeAllListeners\");\n  });\n\n  describe(\"when run as main process\", function () {\n    it(\"should throw\", function () {\n      expect(() => {\n        rewiremock.proxy(WORKER_PATH, {\n          workerpool: {\n            isMainThread: true,\n            worker: stubs.workerpool.worker,\n          },\n        });\n      }, \"to throw\");\n    });\n  });\n\n  describe(\"when run as worker process\", function () {\n    let mocha;\n\n    beforeEach(function () {\n      mocha = {\n        addFile: sinon.stub().returnsThis(),\n        loadFilesAsync: sinon.stub().resolves(),\n        run: sinon.stub().callsArgAsync(0),\n        unloadFiles: sinon.stub().returnsThis(),\n      };\n      stubs.Mocha = Object.assign(sinon.stub().returns(mocha), {\n        bdd: sinon.stub(),\n        interfaces: {},\n      });\n\n      stubs.serializer = {\n        serialize: sinon.stub(),\n      };\n\n      stubs.runHelpers = {\n        handleRequires: sinon.stub().resolves({}),\n        validateLegacyPlugin: sinon.stub(),\n      };\n\n      stubs.plugin = {\n        aggregateRootHooks: sinon.stub().resolves(),\n      };\n\n      worker = rewiremock.proxy(WORKER_PATH, {\n        workerpool: stubs.workerpool,\n        \"../../lib/mocha\": stubs.Mocha,\n        \"../../lib/nodejs/serializer\": stubs.serializer,\n        \"../../lib/cli/run-helpers\": stubs.runHelpers,\n        \"../../lib/plugin-loader\": stubs.plugin,\n      });\n    });\n\n    it(\"should register itself with workerpool\", function () {\n      expect(stubs.workerpool.worker, \"to have a call satisfying\", [\n        { run: worker.run },\n      ]);\n    });\n\n    describe(\"function\", function () {\n      describe(\"run()\", function () {\n        describe(\"when called without arguments\", function () {\n          it(\"should reject\", async function () {\n            return expect(worker.run, \"to be rejected with error satisfying\", {\n              code: \"ERR_MOCHA_INVALID_ARG_TYPE\",\n            });\n          });\n        });\n\n        describe(\"when passed a non-string `options` value\", function () {\n          it(\"should reject\", async function () {\n            return expect(\n              () => worker.run(\"foo.js\", 42),\n              \"to be rejected with error satisfying\",\n              {\n                code: \"ERR_MOCHA_INVALID_ARG_TYPE\",\n              },\n            );\n          });\n        });\n\n        describe(\"when passed an invalid string `options` value\", function () {\n          it(\"should reject\", async function () {\n            return expect(\n              () => worker.run(\"foo.js\", \"tomfoolery\"),\n              \"to be rejected with error satisfying\",\n              {\n                code: \"ERR_MOCHA_INVALID_ARG_VALUE\",\n              },\n            );\n          });\n        });\n\n        describe('when called with empty \"filepath\" argument', function () {\n          it(\"should reject\", async function () {\n            return expect(\n              () => worker.run(\"\"),\n              \"to be rejected with error satisfying\",\n              {\n                code: \"ERR_MOCHA_INVALID_ARG_TYPE\",\n              },\n            );\n          });\n        });\n\n        describe('when the file at \"filepath\" argument is unloadable', function () {\n          it(\"should reject\", async function () {\n            mocha.loadFilesAsync.rejects();\n            return expect(\n              () => worker.run(\"some-non-existent-file.js\"),\n              \"to be rejected\",\n            );\n          });\n        });\n\n        describe('when the file at \"filepath\" is loadable', function () {\n          let result;\n          beforeEach(function () {\n            result = SerializableWorkerResult.create();\n\n            mocha.loadFilesAsync.resolves();\n            mocha.run.yields(result);\n          });\n\n          it('should handle \"--require\"', async function () {\n            await worker.run(\n              \"some-file.js\",\n              serializeJavascript({ require: \"foo\" }),\n            );\n            expect(\n              stubs.runHelpers.handleRequires,\n              \"to have a call satisfying\",\n              [\n                \"foo\",\n                { ignoredPlugins: [\"mochaGlobalSetup\", \"mochaGlobalTeardown\"] },\n              ],\n            ).and(\"was called once\");\n          });\n\n          it('should handle \"--ui\"', async function () {\n            const argv = { foo: \"bar\" };\n            await worker.run(\"some-file.js\", serializeJavascript(argv));\n\n            expect(\n              stubs.runHelpers.validateLegacyPlugin,\n              \"to have a call satisfying\",\n              [argv, \"ui\", stubs.Mocha.interfaces],\n            ).and(\"was called once\");\n          });\n\n          it(\"should call Mocha#run\", async function () {\n            await worker.run(\"some-file.js\");\n            expect(mocha.run, \"was called once\");\n          });\n\n          it(\"should remove all uncaughtException listeners\", async function () {\n            await worker.run(\"some-file.js\");\n            expect(process.removeAllListeners, \"to have a call satisfying\", [\n              \"uncaughtException\",\n            ]);\n          });\n\n          it(\"should remove all unhandledRejection listeners\", async function () {\n            await worker.run(\"some-file.js\");\n            expect(process.removeAllListeners, \"to have a call satisfying\", [\n              \"unhandledRejection\",\n            ]);\n          });\n\n          describe(\"when serialization succeeds\", function () {\n            beforeEach(function () {\n              stubs.serializer.serialize.returnsArg(0);\n            });\n\n            it(\"should resolve with a SerializedWorkerResult\", async function () {\n              return expect(\n                worker.run(\"some-file.js\"),\n                \"to be fulfilled with\",\n                result,\n              );\n            });\n          });\n\n          describe(\"when serialization fails\", function () {\n            beforeEach(function () {\n              stubs.serializer.serialize.throws();\n            });\n\n            it(\"should reject\", async function () {\n              return expect(worker.run(\"some-file.js\"), \"to be rejected\");\n            });\n          });\n\n          describe(\"when run twice\", function () {\n            it(\"should initialize only once\", async function () {\n              await worker.run(\"some-file.js\");\n              await worker.run(\"some-other-file.js\");\n\n              expect(stubs.runHelpers, \"to satisfy\", {\n                handleRequires: expect.it(\"was called once\"),\n                validateLegacyPlugin: expect.it(\"was called once\"),\n              });\n            });\n          });\n        });\n      });\n    });\n  });\n\n  afterEach(function () {\n    sinon.restore();\n    // this is needed due to `require.cache` getting dumped in watch mode\n    process.removeAllListeners(\"beforeExit\");\n  });\n});\n"
  },
  {
    "path": "test/only/bdd-require.spec.js",
    "content": "\"use strict\";\n\nvar mocha = require(\"../../lib/mocha\");\n\nvar beforeEach = mocha.beforeEach;\nvar it = mocha.it;\nvar describe = mocha.describe;\n\ndescribe('it.only via require(\"mocha\")', function () {\n  beforeEach(function () {\n    this.didRunBeforeEach = true;\n  });\n  describe(\"nested within a describe/context\", function () {\n    it.only(\"should run all enclosing beforeEach hooks\", function () {\n      require(\"node:assert\").strictEqual(this.didRunBeforeEach, true);\n    });\n  });\n});\n"
  },
  {
    "path": "test/only/global/bdd.spec.js",
    "content": "\"use strict\";\n\n// Root-only test cases\nit.only(\"#Root-Suite, should run this bdd test-case #1\", function () {\n  expect(true, \"to be\", true);\n});\n\nit(\"#Root-Suite, should not run this bdd test-case #2\", function () {\n  expect(false, \"to be\", true);\n});\n\nit(\"#Root-Suite, should not run this bdd test-case #3\", function () {\n  expect(false, \"to be\", true);\n});\n"
  },
  {
    "path": "test/only/global/qunit.spec.js",
    "content": "\"use strict\";\n\n// Root-only test cases\ntest.only(\"#Root-Suite, should run this qunit test-case #1\", function () {\n  expect(true, \"to be\", true);\n});\n\ntest(\"#Root-Suite, should not run this qunit test-case #2\", function () {\n  expect(false, \"to be\", true);\n});\n\ntest(\"#Root-Suite, should not run this qunit test-case #3\", function () {\n  expect(false, \"to be\", true);\n});\n"
  },
  {
    "path": "test/only/global/tdd.spec.js",
    "content": "\"use strict\";\n\n// Root-only test cases\ntest.only(\"#Root-Suite, should run this tdd test-case #1\", function () {\n  expect(true, \"to be\", true);\n});\n\ntest(\"#Root-Suite, should not run this tdd test-case #2\", function () {\n  expect(false, \"to be\", true);\n});\n\ntest(\"#Root-Suite, should not run this tdd test-case #3\", function () {\n  expect(false, \"to be\", true);\n});\n"
  },
  {
    "path": "test/reporters/base.spec.js",
    "content": "\"use strict\";\n\nvar assert = require(\"node:assert\");\nvar chai = require(\"chai\");\nvar sinon = require(\"sinon\");\nvar helpers = require(\"./helpers\");\nvar reporters = require(\"../../\").reporters;\nvar AssertionError = assert.AssertionError;\nvar Base = reporters.Base;\nvar chaiExpect = chai.expect;\nvar createElements = helpers.createElements;\nvar makeTest = helpers.makeTest;\nvar Mocha = require(\"../../\");\nvar Suite = Mocha.Suite;\nvar Runner = Mocha.Runner;\n\ndescribe(\"Base reporter\", function () {\n  var stdout;\n\n  function list(tests) {\n    try {\n      Base.list(tests);\n    } finally {\n      sinon.restore();\n    }\n  }\n\n  function generateDiff(actual, expected) {\n    var diffStr;\n\n    try {\n      diffStr = Base.generateDiff(actual, expected);\n    } finally {\n      sinon.restore();\n    }\n\n    return diffStr;\n  }\n\n  var gather = function (chunk) {\n    stdout.push(chunk);\n  };\n\n  beforeEach(function () {\n    sinon.stub(Base, \"useColors\").value(false);\n    sinon.stub(process.stdout, \"write\").callsFake(gather);\n    stdout = [];\n  });\n\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"showDiff\", function () {\n    var err;\n\n    beforeEach(function () {\n      err = new AssertionError({ actual: \"foo\", expected: \"bar\" });\n    });\n\n    it(\"should show diffs by default\", function () {\n      var test = makeTest(err);\n\n      list([test]);\n\n      var errOut = stdout.join(\"\\n\");\n      expect(errOut, \"to match\", /- actual/);\n      expect(errOut, \"to match\", /\\+ expected/);\n    });\n\n    it(\"should show diffs if 'err.showDiff' is true\", function () {\n      err.showDiff = true;\n      var test = makeTest(err);\n\n      list([test]);\n\n      var errOut = stdout.join(\"\\n\");\n      expect(errOut, \"to match\", /- actual/);\n      expect(errOut, \"to match\", /\\+ expected/);\n    });\n\n    it(\"should not show diffs if 'err.showDiff' is false\", function () {\n      err.showDiff = false;\n      var test = makeTest(err);\n\n      list([test]);\n\n      var errOut = stdout.join(\"\\n\");\n      expect(errOut, \"not to match\", /- actual/);\n      expect(errOut, \"not to match\", /\\+ expected/);\n    });\n\n    it(\"should not show diffs if 'expected' is not defined\", function () {\n      var _err = new Error(\"ouch\");\n      var test = makeTest(_err);\n\n      list([test]);\n\n      var errOut = stdout.join(\"\\n\");\n      expect(errOut, \"not to match\", /- actual/);\n      expect(errOut, \"not to match\", /\\+ expected/);\n    });\n\n    it(\"should not show diffs if 'hideDiff' is true\", function () {\n      var test = makeTest(err);\n\n      sinon.stub(Base, \"hideDiff\").value(true);\n      list([test]);\n\n      var errOut = stdout.join(\"\\n\");\n      expect(errOut, \"not to match\", /- actual/);\n      expect(errOut, \"not to match\", /\\+ expected/);\n    });\n  });\n\n  describe(\"getting two strings\", function () {\n    // Fix regression V1.2.1(see: issue #1241)\n    it(\"should show strings diff as is\", function () {\n      var err = new Error(\"test\");\n      err.actual = \"foo\\nbar\";\n      err.expected = \"foo\\nbaz\";\n      err.showDiff = true;\n      var test = makeTest(err);\n\n      list([test]);\n\n      var errOut = stdout.join(\"\\n\");\n      expect(errOut, \"not to match\", /\"foo\\\\nbar\"/);\n      expect(errOut, \"to match\", /foo/).and(\"to match\", /bar/);\n      expect(errOut, \"to match\", /test/);\n      expect(errOut, \"to match\", /actual/);\n      expect(errOut, \"to match\", /expected/);\n    });\n  });\n\n  describe(\"diff generation\", function () {\n    var inlineDiffsStub;\n\n    beforeEach(function () {\n      inlineDiffsStub = sinon.stub(Base, \"inlineDiffs\").value(false);\n    });\n\n    it(\"should generate unified diffs if 'inlineDiffs' is false\", function () {\n      var actual = \"a foo unified diff\";\n      var expected = \"a bar unified diff\";\n\n      var output = generateDiff(actual, expected);\n\n      expect(\n        output,\n        \"to be\",\n        \"\\n      + expected - actual\\n\\n      -a foo unified diff\\n      +a bar unified diff\\n      \",\n      );\n    });\n\n    it(\"should generate inline diffs if 'inlineDiffs' is true\", function () {\n      var actual = \"a foo inline diff\";\n      var expected = \"a bar inline diff\";\n\n      inlineDiffsStub.value(true);\n      var output = generateDiff(actual, expected);\n\n      expect(\n        output,\n        \"to be\",\n        \"      \\n      actual expected\\n      \\n      a foobar inline diff\\n      \",\n      );\n    });\n\n    it(\"should truncate overly long 'actual' \", function () {\n      var actual = \"\";\n      var i = 0;\n      while (i++ < 500) {\n        actual += \"a foo unified diff \";\n      }\n      var expected = \"a bar unified diff\";\n\n      var output = generateDiff(actual, expected);\n\n      expect(output, \"to match\", /output truncated/);\n    });\n\n    it(\"should truncate overly long 'expected' \", function () {\n      var actual = \"a foo unified diff\";\n      var expected = \"\";\n      var i = 0;\n      while (i++ < 500) {\n        expected += \"a bar unified diff \";\n      }\n\n      var output = generateDiff(actual, expected);\n\n      expect(output, \"to match\", /output truncated/);\n    });\n\n    it(\"should not truncate overly long 'actual' if maxDiffSize=0\", function () {\n      var actual = \"\";\n      var i = 0;\n      while (i++ < 120) {\n        actual += \"a bar unified diff \";\n      }\n      var expected = \"b foo unified diff\";\n\n      sinon.stub(Base, \"maxDiffSize\").value(0);\n      var output = generateDiff(actual, expected);\n\n      expect(output, \"not to match\", /output truncated/);\n    });\n\n    it(\"should not truncate overly long 'expected' if maxDiffSize=0\", function () {\n      var actual = \"a foo unified diff\";\n      var expected = \"\";\n      var i = 0;\n      while (i++ < 120) {\n        expected += \"a bar unified diff \";\n      }\n\n      sinon.stub(Base, \"maxDiffSize\").value(0);\n      var output = generateDiff(actual, expected);\n\n      expect(output, \"not to match\", /output truncated/);\n    });\n  });\n\n  describe(\"inline strings diff\", function () {\n    beforeEach(function () {\n      sinon.stub(Base, \"inlineDiffs\").value(true);\n    });\n\n    it(\"should show single line diff if 'inlineDiffs' is true\", function () {\n      var err = new Error(\"test\");\n      err.actual = \"a foo inline diff\";\n      err.expected = \"a bar inline diff\";\n      err.showDiff = true;\n      var test = makeTest(err);\n\n      list([test]);\n\n      var errOut = stdout.join(\"\\n\");\n      expect(errOut, \"to match\", /a foobar inline diff/);\n      expect(errOut, \"to match\", /test/);\n      expect(errOut, \"to match\", /actual/);\n      expect(errOut, \"to match\", /expected/);\n    });\n\n    it(\"should split lines if string has more than 4 line breaks\", function () {\n      var err = new Error(\"test\");\n      err.actual = \"a\\nfoo\\ninline\\ndiff\\nwith\\nmultiple lines\";\n      err.expected = \"a\\nbar\\ninline\\ndiff\\nwith\\nmultiple lines\";\n      err.showDiff = true;\n      var test = makeTest(err);\n\n      list([test]);\n\n      var errOut = stdout.join(\"\\n\");\n      expect(errOut, \"to match\", /1 \\| a/);\n      expect(errOut, \"to match\", /2 \\| foobar/);\n      expect(errOut, \"to match\", /3 \\| inline/);\n      expect(errOut, \"to match\", /4 \\| diff/);\n      expect(errOut, \"to match\", /5 \\| with/);\n      expect(errOut, \"to match\", /6 \\| multiple lines/);\n      expect(errOut, \"to match\", /test/);\n      expect(errOut, \"to match\", /actual/);\n      expect(errOut, \"to match\", /expected/);\n    });\n  });\n\n  describe(\"unified diff\", function () {\n    beforeEach(function () {\n      sinon.stub(Base, \"inlineDiffs\").value(false);\n    });\n\n    it(\"should separate diff hunks by two dashes\", function () {\n      var err = new Error(\"test\");\n      err.actual = createElements({ from: 2, to: 11 });\n      err.expected = createElements({ from: 1, to: 10 });\n      err.showDiff = true;\n      var test = makeTest(err);\n\n      list([test]);\n\n      var errOut = stdout.join(\"\\n\");\n\n      var regexesToMatch = [\n        /\\[/,\n        /\\+ {2}\"element 1\"/,\n        /\"element 2\"/,\n        /\"element 3\"/,\n        /\"element 4\"/,\n        /\"element 5\"/,\n        /--/,\n        /\"element 7\"/,\n        /\"element 8\"/,\n        /\"element 9\"/,\n        /\"element 10\"/,\n        /- {2}\"element 11\"/,\n        /]/,\n        /test/,\n        /expected/,\n        /actual/,\n      ];\n\n      regexesToMatch.forEach(function (aRegex) {\n        expect(errOut, \"to match\", aRegex);\n      });\n    });\n  });\n\n  describe(\"when 'reporterOption.maxDiffSize' is provided\", function () {\n    var origSize;\n\n    beforeEach(function () {\n      sinon.restore();\n      origSize = Base.maxDiffSize;\n    });\n\n    afterEach(function () {\n      Base.maxDiffSize = origSize;\n    });\n\n    it(\"should set 'Base.maxDiffSize' used for truncating diffs\", function () {\n      var options = {\n        reporterOption: {\n          maxDiffSize: 4,\n        },\n      };\n      var suite = new Suite(\"Dummy suite\", \"root\");\n      var runner = new Runner(suite);\n      // eslint-disable-next-line no-unused-vars\n      var base = new Base(runner, options);\n      expect(Base.maxDiffSize, \"to be\", 4);\n    });\n  });\n\n  it(\"should stringify objects\", function () {\n    var err = new Error(\"test\");\n    err.actual = { key: \"a1\" };\n    err.expected = { key: \"e1\" };\n    err.showDiff = true;\n    var test = makeTest(err);\n\n    list([test]);\n\n    var errOut = stdout.join(\"\\n\");\n    expect(errOut, \"to match\", /\"key\"/);\n    expect(errOut, \"to match\", /test/);\n    expect(errOut, \"to match\", /- actual/);\n    expect(errOut, \"to match\", /\\+ expected/);\n  });\n\n  it(\"should stringify Object.create(null)\", function () {\n    var err = new Error(\"test\");\n\n    err.actual = Object.create(null);\n    err.actual.hasOwnProperty = 1;\n    err.expected = Object.create(null);\n    err.expected.hasOwnProperty = 2;\n    err.showDiff = true;\n    var test = makeTest(err);\n\n    list([test]);\n\n    var errOut = stdout.join(\"\\n\");\n    expect(errOut, \"to match\", /\"hasOwnProperty\"/);\n    expect(errOut, \"to match\", /test/);\n    expect(errOut, \"to match\", /- actual/);\n    expect(errOut, \"to match\", /\\+ expected/);\n  });\n\n  it(\"should handle error messages that are not strings\", function () {\n    try {\n      assert(false, true);\n    } catch (err) {\n      err.actual = false;\n      err.expected = true;\n      err.showDiff = true;\n      var test = makeTest(err);\n\n      list([test]);\n\n      var errOut = stdout.join(\"\\n\");\n      expect(errOut, \"to match\", /\\+true/);\n      expect(errOut, \"to match\", /-false/);\n      expect(errOut, \"to match\", /- actual/);\n      expect(errOut, \"to match\", /\\+ expected/);\n    }\n  });\n\n  it(\"should interpret 'chai' module custom error messages\", function () {\n    var actual = 43;\n    var expected = 42;\n\n    try {\n      chaiExpect(actual, \"custom error message\").to.equal(expected);\n    } catch (err) {\n      err.actual = actual;\n      err.expected = expected;\n      err.showDiff = true;\n      var test = makeTest(err);\n\n      list([test]);\n\n      var errOut = stdout.join(\"\\n\");\n      expect(errOut, \"to match\", /custom error message\\n/)\n        .and(\"to match\", /\\+42/)\n        .and(\"to match\", /-43/)\n        .and(\"to match\", /- actual/)\n        .and(\"to match\", /\\+ expected/);\n    }\n  });\n\n  it(\"should interpret 'assert' module custom error messages\", function () {\n    var actual = 43;\n    var expected = 42;\n\n    try {\n      assert.strictEqual(actual, expected, \"custom error message\");\n      // AssertionError: custom error message: expected 43 to equal 42.\n      // assert.equal(43, 42, 'custom error message: expected 43 to equal 42.');\n    } catch (err) {\n      err.actual = actual;\n      err.expected = expected;\n      err.showDiff = true;\n      var test = makeTest(err);\n\n      list([test]);\n\n      var errOut = stdout.join(\"\\n\");\n      expect(errOut, \"to match\", /custom error message\\n/);\n      expect(errOut, \"to match\", /\\+42/);\n      expect(errOut, \"to match\", /-43/);\n      expect(errOut, \"to match\", /- actual/);\n      expect(errOut, \"to match\", /\\+ expected/);\n    }\n  });\n\n  it(\"should remove message from stack\", function () {\n    var err = {\n      message: \"Error\",\n      stack: \"Error\\nfoo\\nbar\",\n      showDiff: false,\n    };\n    var test = makeTest(err);\n\n    list([test]);\n\n    var errOut = stdout.join(\"\\n\").trim();\n    expect(errOut, \"to be\", \"1) test title:\\n     Error\\n  foo\\n  bar\");\n  });\n\n  it(\"should use 'inspect' if 'inspect' and 'message' are set\", function () {\n    var err = new Error(\"test\");\n    err.showDiff = false;\n    err.message = \"error message\";\n    err.inspect = function () {\n      return \"Inspect Error\";\n    };\n\n    var test = makeTest(err);\n\n    list([test]);\n\n    var errOut = stdout.join(\"\\n\").trim();\n\n    expect(errOut, \"to contain\", \"Inspect Error\");\n  });\n\n  it(\"should set an empty message if neither 'inspect' nor 'message' is set\", function () {\n    var err = {\n      showDiff: false,\n    };\n    var test = makeTest(err);\n\n    list([test]);\n\n    var errOut = stdout.join(\"\\n\").trim();\n    expect(errOut, \"to be\", \"1) test title:\");\n  });\n\n  it(\"should not modify stack if it does not contain message\", function () {\n    var err = {\n      message: \"Error\",\n      stack: \"foo\\nbar\",\n      showDiff: false,\n    };\n    var test = makeTest(err);\n\n    list([test]);\n\n    var errOut = stdout.join(\"\\n\").trim();\n    expect(errOut, \"to be\", \"1) test title:\\n     Error\\n  foo\\n  bar\");\n  });\n\n  describe(\"error causes\", function () {\n    it(\"should append any error cause trail to stack traces\", function () {\n      var err = {\n        message: \"Error\",\n        stack: \"Error\\nfoo\\nbar\",\n        showDiff: false,\n        cause: {\n          message: \"Cause1\",\n          stack: \"Cause1\\nbar\\nfoo\",\n          showDiff: false,\n          cause: {\n            message: \"Cause2\",\n            stack: \"Cause2\\nabc\\nxyz\",\n            showDiff: false,\n          },\n        },\n      };\n      var test = makeTest(err);\n\n      list([test]);\n\n      var errOut = stdout.join(\"\\n\").trim();\n      expect(\n        errOut,\n        \"to be\",\n        \"1) test title:\\n     Error\\n  foo\\n  bar\\n     Caused by: Cause1\\n  bar\\n  foo\\n     Caused by: Cause2\\n  abc\\n  xyz\",\n      );\n    });\n\n    it(\"should not get stuck in a hypothetical circular error cause trail\", function () {\n      var err1 = {\n        message: \"Error\",\n        stack: \"Error\\nfoo\\nbar\",\n        showDiff: false,\n      };\n      var err2 = {\n        message: \"Cause1\",\n        stack: \"Cause1\\nbar\\nfoo\",\n        showDiff: false,\n        cause: err1,\n      };\n      err1.cause = err2;\n\n      var test = makeTest(err1);\n\n      list([test]);\n\n      var errOut = stdout.join(\"\\n\").trim();\n      expect(\n        errOut,\n        \"to be\",\n        \"1) test title:\\n     Error\\n  foo\\n  bar\\n     Caused by: Cause1\\n  bar\\n  foo\\n     Caused by: <circular>\",\n      );\n    });\n\n    it(\"should set an empty cause if neither 'inspect' nor 'message' is set\", function () {\n      var err = {\n        message: \"Error\",\n        stack: \"Error\\nfoo\\nbar\",\n        showDiff: false,\n        cause: {\n          showDiff: false,\n        },\n      };\n\n      var test = makeTest(err);\n\n      list([test]);\n\n      var errOut = stdout.join(\"\\n\").trim();\n      expect(\n        errOut,\n        \"to be\",\n        \"1) test title:\\n     Error\\n  foo\\n  bar\\n     Caused by:\",\n      );\n    });\n\n    it(\"should not add cause trail if error does not contain message\", function () {\n      var err = {\n        message: \"Error\",\n        stack: \"foo\\nbar\",\n        showDiff: false,\n        cause: {\n          message: \"Cause1\",\n          stack: \"Cause1\\nbar\\nfoo\",\n          showDiff: false,\n          cause: {\n            message: \"Cause2\",\n            stack: \"Cause2\\nabc\\nxyz\",\n            showDiff: false,\n          },\n        },\n      };\n      var test = makeTest(err);\n\n      list([test]);\n\n      var errOut = stdout.join(\"\\n\").trim();\n      expect(errOut, \"to be\", \"1) test title:\\n     Error\\n  foo\\n  bar\");\n    });\n  });\n\n  it(\"should list multiple Errors per test\", function () {\n    var err = new Error(\"First Error\");\n    err.multiple = [new Error(\"Second Error - same test\")];\n    var test = makeTest(err);\n\n    list([test, test]);\n\n    var errOut = stdout.join(\"\\n\").trim();\n    expect(\n      errOut,\n      \"to contain\",\n      \"Error: First Error\",\n      \"Error: Second Error - same test\",\n    );\n  });\n\n  describe(\"when reporter output immune to user test changes\", function () {\n    var baseConsoleLog;\n\n    beforeEach(function () {\n      sinon.restore();\n      sinon.stub(console, \"log\");\n      baseConsoleLog = sinon.stub(Base, \"consoleLog\");\n    });\n\n    it(\"should let you stub out console.log without effecting reporters output\", function () {\n      Base.list([]);\n      baseConsoleLog.restore();\n\n      expect(baseConsoleLog, \"was called\");\n      expect(console.log, \"was not called\");\n    });\n  });\n});\n"
  },
  {
    "path": "test/reporters/doc.spec.js",
    "content": "\"use strict\";\n\nvar events = require(\"../../\").Runner.constants;\nvar helpers = require(\"./helpers\");\nvar reporters = require(\"../../\").reporters;\n\nvar Doc = reporters.Doc;\nvar createMockRunner = helpers.createMockRunner;\nvar createRunReporterFunction = helpers.createRunReporterFunction;\n\nvar EVENT_SUITE_BEGIN = events.EVENT_SUITE_BEGIN;\nvar EVENT_SUITE_END = events.EVENT_SUITE_END;\nvar EVENT_TEST_FAIL = events.EVENT_TEST_FAIL;\nvar EVENT_TEST_PASS = events.EVENT_TEST_PASS;\n\ndescribe(\"Doc reporter\", function () {\n  var runner;\n  var options = {};\n  var runReporter = createRunReporterFunction(Doc);\n\n  afterEach(function () {\n    runner = null;\n  });\n\n  describe(\"event handlers\", function () {\n    describe(\"on 'suite' event\", function () {\n      describe(\"when suite root does not exist\", function () {\n        var expectedTitle = \"expectedTitle\";\n        var unescapedTitle = \"<div>\" + expectedTitle + \"</div>\";\n        var suite = {\n          root: false,\n          title: expectedTitle,\n        };\n\n        it(\"should log html with indents and expected title\", async function () {\n          runner = createMockRunner(\n            \"suite\",\n            EVENT_SUITE_BEGIN,\n            null,\n            null,\n            suite,\n          );\n          var { stdout } = await runReporter({}, runner, options);\n          var expectedArray = [\n            '    <section class=\"suite\">\\n',\n            \"      <h1>\" + expectedTitle + \"</h1>\\n\",\n            \"      <dl>\\n\",\n          ];\n          expect(stdout, \"to equal\", expectedArray);\n        });\n\n        it(\"should escape title where necessary\", async function () {\n          var suite = {\n            root: false,\n            title: unescapedTitle,\n          };\n          expectedTitle =\n            \"&#x3C;div&#x3E;\" + expectedTitle + \"&#x3C;/div&#x3E;\";\n\n          runner = createMockRunner(\n            \"suite\",\n            EVENT_SUITE_BEGIN,\n            null,\n            null,\n            suite,\n          );\n          var { stdout } = await runReporter({}, runner, options);\n          var expectedArray = [\n            '    <section class=\"suite\">\\n',\n            \"      <h1>\" + expectedTitle + \"</h1>\\n\",\n            \"      <dl>\\n\",\n          ];\n          expect(stdout, \"to equal\", expectedArray);\n        });\n      });\n\n      describe(\"when suite root exists\", function () {\n        var suite = {\n          root: true,\n        };\n\n        it(\"should not log any html\", async function () {\n          runner = createMockRunner(\n            \"suite\",\n            EVENT_SUITE_BEGIN,\n            null,\n            null,\n            suite,\n          );\n          var { stdout } = await runReporter({}, runner, options);\n          expect(stdout, \"to be empty\");\n        });\n      });\n    });\n\n    describe(\"on 'suite end' event\", function () {\n      describe(\"when suite root does not exist\", function () {\n        var suite = {\n          root: false,\n        };\n\n        it(\"should log expected html with indents\", async function () {\n          runner = createMockRunner(\n            \"suite end\",\n            EVENT_SUITE_END,\n            null,\n            null,\n            suite,\n          );\n          var { stdout } = await runReporter({}, runner, options);\n          var expectedArray = [\"  </dl>\\n\", \"</section>\\n\"];\n          expect(stdout, \"to equal\", expectedArray);\n        });\n      });\n\n      describe(\"when suite root exists\", function () {\n        var suite = {\n          root: true,\n        };\n\n        it(\"should not log any html\", async function () {\n          runner = createMockRunner(\n            \"suite end\",\n            EVENT_SUITE_END,\n            null,\n            null,\n            suite,\n          );\n          var { stdout } = await runReporter({}, runner, options);\n          expect(stdout, \"to be empty\");\n        });\n      });\n    });\n\n    describe(\"on 'pass' event\", function () {\n      var expectedTitle = \"some tite\";\n      var expectedFile = \"testFile.spec.js\";\n      var expectedBody = \"some body\";\n      var test = {\n        title: expectedTitle,\n        file: expectedFile,\n        body: expectedBody,\n        slow: function () {\n          return \"\";\n        },\n      };\n\n      it(\"should log html with indents, expected title, and body\", async function () {\n        runner = createMockRunner(\"pass\", EVENT_TEST_PASS, null, null, test);\n        var { stdout } = await runReporter({}, runner, options);\n        var expectedArray = [\n          \"    <dt>\" + expectedTitle + \"</dt>\\n\",\n          \"    <dt>\" + expectedFile + \"</dt>\\n\",\n          \"    <dd><pre><code>\" + expectedBody + \"</code></pre></dd>\\n\",\n        ];\n        expect(stdout, \"to equal\", expectedArray);\n      });\n\n      it(\"should escape title and body where necessary\", async function () {\n        var unescapedTitle = \"<div>\" + expectedTitle + \"</div>\";\n        var unescapedFile = \"<div>\" + expectedFile + \"</div>\";\n        var unescapedBody = \"<div>\" + expectedBody + \"</div>\";\n        test.title = unescapedTitle;\n        test.file = unescapedFile;\n        test.body = unescapedBody;\n\n        var expectedEscapedTitle =\n          \"&#x3C;div&#x3E;\" + expectedTitle + \"&#x3C;/div&#x3E;\";\n        var expectedEscapedFile =\n          \"&#x3C;div&#x3E;\" + expectedFile + \"&#x3C;/div&#x3E;\";\n        var expectedEscapedBody =\n          \"&#x3C;div&#x3E;\" + expectedBody + \"&#x3C;/div&#x3E;\";\n        runner = createMockRunner(\"pass\", EVENT_TEST_PASS, null, null, test);\n        var { stdout } = await runReporter({}, runner, options);\n        var expectedArray = [\n          \"    <dt>\" + expectedEscapedTitle + \"</dt>\\n\",\n          \"    <dt>\" + expectedEscapedFile + \"</dt>\\n\",\n          \"    <dd><pre><code>\" + expectedEscapedBody + \"</code></pre></dd>\\n\",\n        ];\n        expect(stdout, \"to equal\", expectedArray);\n      });\n    });\n\n    describe(\"on 'fail' event\", function () {\n      var expectedTitle = \"some tite\";\n      var expectedFile = \"testFile.spec.js\";\n      var expectedBody = \"some body\";\n      var expectedError = \"some error\";\n      var test = {\n        title: expectedTitle,\n        file: expectedFile,\n        body: expectedBody,\n        slow: function () {\n          return \"\";\n        },\n      };\n\n      it(\"should log html with indents, expected title, body, and error\", async function () {\n        runner = createMockRunner(\n          \"fail two args\",\n          EVENT_TEST_FAIL,\n          null,\n          null,\n          test,\n          expectedError,\n        );\n        var { stdout } = await runReporter({}, runner, options);\n        var expectedArray = [\n          '    <dt class=\"error\">' + expectedTitle + \"</dt>\\n\",\n          '    <dt class=\"error\">' + expectedFile + \"</dt>\\n\",\n          '    <dd class=\"error\"><pre><code>' +\n            expectedBody +\n            \"</code></pre></dd>\\n\",\n          '    <dd class=\"error\">' + expectedError + \"</dd>\\n\",\n        ];\n        expect(stdout, \"to equal\", expectedArray);\n      });\n\n      it(\"should escape title, body, and error where necessary\", async function () {\n        var unescapedTitle = \"<div>\" + expectedTitle + \"</div>\";\n        var unescapedFile = \"<div>\" + expectedFile + \"</div>\";\n        var unescapedBody = \"<div>\" + expectedBody + \"</div>\";\n        var unescapedError = \"<div>\" + expectedError + \"</div>\";\n        test.title = unescapedTitle;\n        test.file = unescapedFile;\n        test.body = unescapedBody;\n\n        var expectedEscapedTitle =\n          \"&#x3C;div&#x3E;\" + expectedTitle + \"&#x3C;/div&#x3E;\";\n        var expectedEscapedFile =\n          \"&#x3C;div&#x3E;\" + expectedFile + \"&#x3C;/div&#x3E;\";\n        var expectedEscapedBody =\n          \"&#x3C;div&#x3E;\" + expectedBody + \"&#x3C;/div&#x3E;\";\n        var expectedEscapedError =\n          \"&#x3C;div&#x3E;\" + expectedError + \"&#x3C;/div&#x3E;\";\n        runner = createMockRunner(\n          \"fail two args\",\n          EVENT_TEST_FAIL,\n          null,\n          null,\n          test,\n          unescapedError,\n        );\n        var { stdout } = await runReporter({}, runner, options);\n        var expectedArray = [\n          '    <dt class=\"error\">' + expectedEscapedTitle + \"</dt>\\n\",\n          '    <dt class=\"error\">' + expectedEscapedFile + \"</dt>\\n\",\n          '    <dd class=\"error\"><pre><code>' +\n            expectedEscapedBody +\n            \"</code></pre></dd>\\n\",\n          '    <dd class=\"error\">' + expectedEscapedError + \"</dd>\\n\",\n        ];\n        expect(stdout, \"to equal\", expectedArray);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/reporters/dot.spec.js",
    "content": "\"use strict\";\n\nvar sinon = require(\"sinon\");\nvar events = require(\"../../\").Runner.constants;\nvar helpers = require(\"./helpers\");\nvar reporters = require(\"../../\").reporters;\n\nvar Base = reporters.Base;\nvar Dot = reporters.Dot;\nvar createMockRunner = helpers.createMockRunner;\nvar createRunReporterFunction = helpers.createRunReporterFunction;\n\nvar EVENT_RUN_BEGIN = events.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = events.EVENT_RUN_END;\nvar EVENT_TEST_FAIL = events.EVENT_TEST_FAIL;\nvar EVENT_TEST_PASS = events.EVENT_TEST_PASS;\nvar EVENT_TEST_PENDING = events.EVENT_TEST_PENDING;\n\ndescribe(\"Dot reporter\", function () {\n  var windowWidthStub;\n  var runReporter = createRunReporterFunction(Dot);\n  var noop = function () {};\n\n  beforeEach(function () {\n    windowWidthStub = sinon.stub(Base.window, \"width\").value(0);\n    sinon.stub(Base, \"useColors\").value(false);\n    sinon.stub(Base, \"color\").callsFake(function (type, str) {\n      return type.replace(/ /g, \"-\") + \"_\" + str;\n    });\n  });\n\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"event handlers\", function () {\n    describe(\"on 'start' event\", function () {\n      it(\"should write a newline\", async function () {\n        var runner = createMockRunner(\"start\", EVENT_RUN_BEGIN);\n        var options = {};\n        var { stdout } = await runReporter({ epilogue: noop }, runner, options);\n        sinon.restore();\n\n        var expectedArray = [\"\\n\"];\n        expect(stdout, \"to equal\", expectedArray);\n      });\n    });\n\n    describe(\"on 'pending' event\", function () {\n      describe(\"when window width is greater than 1\", function () {\n        beforeEach(function () {\n          windowWidthStub.value(2);\n        });\n\n        it(\"should write a newline followed by a comma\", async function () {\n          var runner = createMockRunner(\"pending\", EVENT_TEST_PENDING);\n          var options = {};\n          var { stdout } = await runReporter(\n            { epilogue: noop },\n            runner,\n            options,\n          );\n          sinon.restore();\n\n          var expectedArray = [\"\\n  \", \"pending_\" + Base.symbols.comma];\n          expect(stdout, \"to equal\", expectedArray);\n        });\n      });\n\n      describe(\"when window width is less than or equal to 1\", function () {\n        it(\"should write a comma\", async function () {\n          var runner = createMockRunner(\"pending\", EVENT_TEST_PENDING);\n          var options = {};\n          var { stdout } = await runReporter(\n            { epilogue: noop },\n            runner,\n            options,\n          );\n          sinon.restore();\n\n          var expectedArray = [\"pending_\" + Base.symbols.comma];\n          expect(stdout, \"to equal\", expectedArray);\n        });\n      });\n    });\n\n    describe(\"on 'pass' event\", function () {\n      var test = {\n        duration: 1,\n        slow: function () {\n          return 2;\n        },\n      };\n\n      describe(\"when window width is greater than 1\", function () {\n        beforeEach(function () {\n          windowWidthStub.value(2);\n        });\n\n        describe(\"when test speed is fast\", function () {\n          it(\"should write a newline followed by a dot\", async function () {\n            var runner = createMockRunner(\n              \"pass\",\n              EVENT_TEST_PASS,\n              null,\n              null,\n              test,\n            );\n            var options = {};\n            var { stdout } = await runReporter(\n              { epilogue: noop },\n              runner,\n              options,\n            );\n            sinon.restore();\n\n            expect(test.speed, \"to equal\", \"fast\");\n            var expectedArray = [\"\\n  \", \"fast_\" + Base.symbols.dot];\n            expect(stdout, \"to equal\", expectedArray);\n          });\n        });\n      });\n\n      describe(\"when window width is less than or equal to 1\", function () {\n        describe(\"when test speed is fast\", function () {\n          it(\"should write a grey dot\", async function () {\n            var runner = createMockRunner(\n              \"pass\",\n              EVENT_TEST_PASS,\n              null,\n              null,\n              test,\n            );\n            var options = {};\n            var { stdout } = await runReporter(\n              { epilogue: noop },\n              runner,\n              options,\n            );\n            sinon.restore();\n\n            expect(test.speed, \"to equal\", \"fast\");\n            var expectedArray = [\"fast_\" + Base.symbols.dot];\n            expect(stdout, \"to equal\", expectedArray);\n          });\n        });\n\n        describe(\"when test speed is medium\", function () {\n          it(\"should write a yellow dot\", async function () {\n            test.duration = 2;\n            var runner = createMockRunner(\n              \"pass\",\n              EVENT_TEST_PASS,\n              null,\n              null,\n              test,\n            );\n            var options = {};\n            var { stdout } = await runReporter(\n              { epilogue: noop },\n              runner,\n              options,\n            );\n            sinon.restore();\n\n            expect(test.speed, \"to equal\", \"medium\");\n            var expectedArray = [\"medium_\" + Base.symbols.dot];\n            expect(stdout, \"to equal\", expectedArray);\n          });\n        });\n\n        describe(\"when test speed is slow\", function () {\n          it(\"should write a bright yellow dot\", async function () {\n            test.duration = 3;\n            var runner = createMockRunner(\n              \"pass\",\n              EVENT_TEST_PASS,\n              null,\n              null,\n              test,\n            );\n            var options = {};\n            var { stdout } = await runReporter(\n              { epilogue: noop },\n              runner,\n              options,\n            );\n            sinon.restore();\n\n            expect(test.speed, \"to equal\", \"slow\");\n            var expectedArray = [\"bright-yellow_\" + Base.symbols.dot];\n            expect(stdout, \"to equal\", expectedArray);\n          });\n        });\n      });\n    });\n\n    describe(\"on 'fail' event\", function () {\n      var test = {\n        test: {\n          err: \"some error\",\n        },\n      };\n\n      describe(\"when window width is greater than 1\", function () {\n        beforeEach(function () {\n          windowWidthStub.value(2);\n        });\n\n        it(\"should write a newline followed by an exclamation mark\", async function () {\n          var runner = createMockRunner(\n            \"fail\",\n            EVENT_TEST_FAIL,\n            null,\n            null,\n            test,\n          );\n          var options = {};\n          var { stdout } = await runReporter(\n            { epilogue: noop },\n            runner,\n            options,\n          );\n          sinon.restore();\n\n          var expectedArray = [\"\\n  \", \"fail_\" + Base.symbols.bang];\n          expect(stdout, \"to equal\", expectedArray);\n        });\n      });\n\n      describe(\"when window width is less than or equal to 1\", function () {\n        it(\"should write an exclamation mark\", async function () {\n          var runner = createMockRunner(\n            \"fail\",\n            EVENT_TEST_FAIL,\n            null,\n            null,\n            test,\n          );\n          var options = {};\n          var { stdout } = await runReporter(\n            { epilogue: noop },\n            runner,\n            options,\n          );\n          sinon.restore();\n\n          var expectedArray = [\"fail_\" + Base.symbols.bang];\n          expect(stdout, \"to equal\", expectedArray);\n        });\n      });\n    });\n\n    describe(\"on 'end' event\", function () {\n      it(\"should call epilogue\", async function () {\n        var runner = createMockRunner(\"end\", EVENT_RUN_END);\n        var fakeThis = {\n          epilogue: sinon.stub(),\n        };\n        var options = {};\n        await runReporter(fakeThis, runner, options);\n        sinon.restore();\n\n        expect(fakeThis.epilogue.called, \"to be true\");\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/reporters/helpers.js",
    "content": "\"use strict\";\n\nvar sinon = require(\"sinon\");\nvar errors = require(\"../../lib/errors\");\nvar createStatsCollector = require(\"../../lib/stats-collector\");\n\nvar createUnsupportedError = errors.createUnsupportedError;\n\n/**\n * Creates a mock runner object.\n *\n * @param {string} runStr - argument that defines the runnerEvent\n * @param {string} ifStr1 - runner event\n * @param {(string|null)} [ifStr2] - runner event\n * @param {(string|null)} [ifStr3] - runner event\n * @param {(*|null)} [arg1] - variable to be added to event handler's scope\n * @param {(*|null)} [arg2] - variable to be added to event handler's scope\n * @return {Object} mock runner instance\n */\nfunction createMockRunner(runStr, ifStr1, ifStr2, ifStr3, arg1, arg2) {\n  var runnerFunction = createRunnerFunction(\n    runStr,\n    ifStr1,\n    ifStr2,\n    ifStr3,\n    arg1,\n    arg2,\n  );\n  var mockRunner = {\n    on: runnerFunction,\n    once: runnerFunction,\n  };\n  createStatsCollector(mockRunner);\n  return mockRunner;\n}\n\nfunction afterTick(callback) {\n  return async function (...args) {\n    // Waiting a tick allows any extensions to be assigned in the constructor\n    await Promise.resolve();\n    callback(...args);\n  };\n}\n\n/**\n * Creates an event handler function to be used by the runner.\n *\n * @description\n * Arguments 'ifStr1', 'ifStr2', and 'ifStr3' should be `Runner.constants`.\n *\n * @param {string} runStr - argument that defines the runnerEvent\n * @param {string} ifStr1 - runner event\n * @param {(string|null)} [ifStr2] - runner event\n * @param {(string|null)} [ifStr3] - runner event\n * @param {(*|null)} [arg1] - variable to be added to event handler's scope\n * @param {(*|null)} [arg2] - variable to be added to event handler's scope\n * @return {Function} event handler for the requested runner events\n */\nfunction createRunnerFunction(runStr, ifStr1, ifStr2, ifStr3, arg1, arg2) {\n  var test = null;\n  switch (runStr) {\n    case \"start\":\n    case \"pending\":\n    case \"end\":\n      return afterTick(function (event, callback) {\n        if (event === ifStr1) {\n          callback();\n        }\n      });\n    case \"pending test\":\n    case \"pass\":\n    case \"fail\":\n    case \"suite\":\n    case \"suite end\":\n    case \"test end\":\n      test = arg1;\n      return afterTick(function (event, callback) {\n        if (event === ifStr1) {\n          callback(test);\n        }\n      });\n    case \"fail two args\":\n      test = arg1;\n      var expectedError = arg2;\n      return afterTick(function (event, callback) {\n        if (event === ifStr1) {\n          callback(test, expectedError);\n        }\n      });\n    case \"start test\":\n      test = arg1;\n      return afterTick(function (event, callback) {\n        if (event === ifStr1) {\n          callback();\n        }\n        if (event === ifStr2) {\n          callback(test);\n        }\n      });\n    case \"suite suite end\":\n      var expectedSuite = arg1;\n      return afterTick(function (event, callback) {\n        if (event === ifStr1) {\n          callback(expectedSuite);\n        }\n        if (event === ifStr2) {\n          callback();\n        }\n        if (event === ifStr3) {\n          callback();\n        }\n      });\n    case \"pass end\":\n      test = arg1;\n      return afterTick(function (event, callback) {\n        if (event === ifStr1) {\n          callback(test);\n        }\n        if (event === ifStr2) {\n          callback();\n        }\n      });\n    case \"test end fail\":\n      test = arg1;\n      var error = arg2;\n      return afterTick(function (event, callback) {\n        if (event === ifStr1) {\n          callback();\n        }\n        if (event === ifStr2) {\n          callback(test, error);\n        }\n      });\n    case \"fail end pass\":\n      return afterTick(function (event, callback) {\n        test = arg1;\n        if (event === ifStr1) {\n          callback(test, {});\n        }\n        if (event === ifStr2) {\n          callback(test);\n        }\n        if (event === ifStr3) {\n          callback(test);\n        }\n      });\n    default:\n      throw createUnsupportedError(\n        \"This function does not support the runner string specified.\",\n      );\n  }\n}\n\nfunction makeTest(err) {\n  return {\n    err,\n    titlePath: function () {\n      return [\"test title\"];\n    },\n  };\n}\n\nfunction createElements(argObj) {\n  var res = [];\n  for (var i = argObj.from; i <= argObj.to; i++) {\n    res.push(\"element \" + i);\n  }\n  return res;\n}\n\nfunction makeExpectedTest(\n  expectedTitle,\n  expectedFullTitle,\n  expectedFile,\n  expectedDuration,\n  currentRetry,\n) {\n  return {\n    title: expectedTitle,\n    fullTitle: function () {\n      return expectedFullTitle;\n    },\n    file: expectedFile,\n    duration: expectedDuration,\n    currentRetry: function () {\n      return currentRetry;\n    },\n    slow: function () {},\n  };\n}\n\n/**\n * Creates closure with reference to the reporter class constructor.\n *\n * @param {Function} ReporterClass - Reporter class constructor\n * @return {createRunReporterFunction~runReporter}\n */\nfunction createRunReporterFunction(ReporterClass) {\n  /**\n   * Run reporter using stream reassignment to capture output.\n   *\n   * @param {object} extensions - Any extra properties to add to the instance.\n   * @param {Runner} runner - Mock instance\n   * @param {Object} [options] - Reporter configuration settings\n   * @param {boolean} [tee=false] - Whether to echo output to screen\n   * @return {string[]} Lines of output written to `stdout`\n   */\n  var runReporter = async function (extensions, runner, options, tee) {\n    var origStdoutWrite = process.stdout.write;\n    var stdoutWriteStub = sinon.stub(process.stdout, \"write\");\n    var stdout = [];\n\n    var gather = function (chunk) {\n      stdout.push(chunk);\n      if (tee) {\n        origStdoutWrite.call(process.stdout, chunk);\n      }\n    };\n\n    // Reassign stream in order to make a copy of all reporter output\n    stdoutWriteStub.callsFake(gather);\n\n    // The new instance will have all of `extensions` and still be a `ReporterClass`\n    var ReporterClassExtended = class extends ReporterClass {\n      constructor(...args) {\n        super(...args);\n        Object.assign(this, extensions);\n      }\n    };\n\n    var reporter;\n\n    try {\n      reporter = new ReporterClassExtended(runner, options);\n\n      // Waiting a tick allows any events to fire before this function resolves\n      await Promise.resolve();\n    } finally {\n      // Revert stream reassignment here so reporter output\n      // can't be corrupted if any test assertions throw\n      stdoutWriteStub.restore();\n    }\n\n    return { reporter, stdout };\n  };\n\n  return runReporter;\n}\n\nmodule.exports = {\n  createElements,\n  createMockRunner,\n  createRunReporterFunction,\n  makeExpectedTest,\n  makeTest,\n};\n"
  },
  {
    "path": "test/reporters/json-stream.spec.js",
    "content": "\"use strict\";\n\nvar events = require(\"../../\").Runner.constants;\nvar helpers = require(\"./helpers\");\nvar reporters = require(\"../../\").reporters;\n\nvar JSONStream = reporters.JSONStream;\nvar createMockRunner = helpers.createMockRunner;\nvar makeExpectedTest = helpers.makeExpectedTest;\nvar makeRunReporter = helpers.createRunReporterFunction;\n\nvar EVENT_RUN_BEGIN = events.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = events.EVENT_RUN_END;\nvar EVENT_TEST_FAIL = events.EVENT_TEST_FAIL;\nvar EVENT_TEST_PASS = events.EVENT_TEST_PASS;\n\ndescribe(\"JSON Stream reporter\", function () {\n  var runReporter = makeRunReporter(JSONStream);\n  var expectedTitle = \"some title\";\n  var expectedFullTitle = \"full title\";\n  var expectedFile = \"someTest.spec.js\";\n  var expectedDuration = 1000;\n  var currentRetry = 1;\n  var expectedSpeed = \"fast\";\n  var expectedTest = makeExpectedTest(\n    expectedTitle,\n    expectedFullTitle,\n    expectedFile,\n    expectedDuration,\n    currentRetry,\n    expectedSpeed,\n  );\n  var expectedErrorMessage = \"error message\";\n  var expectedErrorStack = \"error stack\";\n  var expectedError = {\n    message: expectedErrorMessage,\n  };\n\n  describe(\"event handlers\", function () {\n    describe(\"on 'start' event\", function () {\n      it(\"should write stringified start with expected total\", async function () {\n        var runner = createMockRunner(\"start\", EVENT_RUN_BEGIN);\n        var expectedTotal = 12;\n        runner.total = expectedTotal;\n        var options = {};\n        var { stdout } = await runReporter({}, runner, options);\n\n        expect(\n          stdout[0],\n          \"to equal\",\n          '[\"start\",{\"total\":' + expectedTotal + \"}]\\n\",\n        );\n      });\n    });\n\n    describe(\"on 'pass' event\", function () {\n      it(\"should write stringified test data\", async function () {\n        var runner = createMockRunner(\n          \"pass\",\n          EVENT_TEST_PASS,\n          null,\n          null,\n          expectedTest,\n        );\n        var options = {};\n        var { stdout } = await runReporter({}, runner, options);\n\n        expect(\n          stdout[0],\n          \"to equal\",\n          '[\"pass\",{\"title\":' +\n            `\"${expectedTitle}\"` +\n            ',\"fullTitle\":' +\n            `\"${expectedFullTitle}\"` +\n            ',\"file\":' +\n            `\"${expectedFile}\"` +\n            ',\"duration\":' +\n            expectedDuration +\n            ',\"currentRetry\":' +\n            currentRetry +\n            ',\"speed\":' +\n            `\"${expectedSpeed}\"` +\n            \"}]\\n\",\n        );\n      });\n    });\n\n    describe(\"on 'fail' event\", function () {\n      describe(\"when error stack exists\", function () {\n        it(\"should write stringified test data with error data\", async function () {\n          expectedError.stack = expectedErrorStack;\n          var runner = createMockRunner(\n            \"fail two args\",\n            EVENT_TEST_FAIL,\n            null,\n            null,\n            expectedTest,\n            expectedError,\n          );\n          var options = {};\n          var { stdout } = await runReporter({}, runner, options);\n\n          expect(\n            stdout[0],\n            \"to equal\",\n            '[\"fail\",{\"title\":' +\n              `\"${expectedTitle}\"` +\n              ',\"fullTitle\":' +\n              `\"${expectedFullTitle}\"` +\n              ',\"file\":' +\n              `\"${expectedFile}\"` +\n              ',\"duration\":' +\n              expectedDuration +\n              ',\"currentRetry\":' +\n              currentRetry +\n              ',\"speed\":' +\n              `\"${expectedSpeed}\"` +\n              ',\"err\":' +\n              `\"${expectedErrorMessage}\"` +\n              ',\"stack\":' +\n              `\"${expectedErrorStack}\"` +\n              \"}]\\n\",\n          );\n        });\n      });\n\n      describe(\"when error stack does not exist\", function () {\n        it(\"should write stringified test data with error data\", async function () {\n          expectedError.stack = null;\n          var runner = createMockRunner(\n            \"fail two args\",\n            EVENT_TEST_FAIL,\n            null,\n            null,\n            expectedTest,\n            expectedError,\n          );\n          var options = {};\n          var { stdout } = await runReporter(this, runner, options);\n\n          expect(\n            stdout[0],\n            \"to equal\",\n            '[\"fail\",{\"title\":' +\n              `\"${expectedTitle}\"` +\n              ',\"fullTitle\":' +\n              `\"${expectedFullTitle}\"` +\n              ',\"file\":' +\n              `\"${expectedFile}\"` +\n              ',\"duration\":' +\n              expectedDuration +\n              ',\"currentRetry\":' +\n              currentRetry +\n              ',\"speed\":' +\n              `\"${expectedSpeed}\"` +\n              ',\"err\":' +\n              `\"${expectedErrorMessage}\"` +\n              ',\"stack\":null}]\\n',\n          );\n        });\n      });\n    });\n\n    describe(\"on 'end' event\", function () {\n      it(\"should write summary statistics\", async function () {\n        var runner = createMockRunner(\"end\", EVENT_RUN_END);\n        var options = {};\n        var { stdout } = await runReporter(this, runner, options);\n        expect(stdout[0], \"to match\", /end/);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/reporters/json.spec.js",
    "content": "\"use strict\";\n\nvar fs = require(\"node:fs\");\nvar sinon = require(\"sinon\");\nvar JSONReporter = require(\"../../lib/reporters/json\");\nvar utils = require(\"../../lib/utils\");\nvar Mocha = require(\"../../\");\nvar Suite = Mocha.Suite;\nvar Runner = Mocha.Runner;\nvar Test = Mocha.Test;\n\ndescribe(\"JSON reporter\", function () {\n  var mocha;\n  var suite;\n  var runner;\n  var testTitle = \"json test 1\";\n  var testFile = \"someTest.spec.js\";\n  var noop = function () {};\n\n  beforeEach(function () {\n    mocha = new Mocha({\n      reporter: \"json\",\n    });\n    suite = new Suite(\"JSON suite\", \"root\");\n    runner = new Runner(suite);\n  });\n\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"test results\", function () {\n    beforeEach(function () {\n      var options = {};\n      /* eslint-disable-next-line no-unused-vars */\n      var mochaReporter = new mocha._reporter(runner, options);\n    });\n\n    beforeEach(function () {\n      sinon.stub(process.stdout, \"write\").callsFake(noop);\n    });\n\n    it(\"should have 1 test failure\", function (done) {\n      var error = { message: \"oh shit\" };\n\n      var test = new Test(testTitle, function (done) {\n        done(new Error(error.message));\n      });\n\n      test.file = testFile;\n      suite.addTest(test);\n\n      runner.run(function (failureCount) {\n        sinon.restore();\n        expect(runner, \"to satisfy\", {\n          testResults: {\n            failures: [\n              {\n                title: testTitle,\n                file: testFile,\n                err: {\n                  message: error.message,\n                },\n              },\n            ],\n          },\n        });\n        expect(failureCount, \"to be\", 1);\n        done();\n      });\n    });\n\n    it(\"should have 1 test pending\", function (done) {\n      var test = new Test(testTitle);\n      test.file = testFile;\n      suite.addTest(test);\n\n      runner.run(function (failureCount) {\n        sinon.restore();\n        expect(runner, \"to satisfy\", {\n          testResults: {\n            pending: [\n              {\n                title: testTitle,\n                file: testFile,\n              },\n            ],\n          },\n        });\n        expect(failureCount, \"to be\", 0);\n        done();\n      });\n    });\n\n    it(\"should have 1 test pass\", function (done) {\n      const test = new Test(testTitle, () => {});\n\n      test.file = testFile;\n      suite.addTest(test);\n\n      runner.run(function (failureCount) {\n        sinon.restore();\n        expect(runner, \"to satisfy\", {\n          testResults: {\n            passes: [\n              {\n                title: testTitle,\n                file: testFile,\n                speed: /(slow|medium|fast)/,\n              },\n            ],\n          },\n        });\n        expect(failureCount, \"to be\", 0);\n        done();\n      });\n    });\n\n    it(\"should handle circular objects in errors\", function (done) {\n      var testTitle = \"json test 1\";\n      function CircleError() {\n        this.message = \"oh shit\";\n        this.circular = this;\n      }\n      var error = new CircleError();\n\n      var test = new Test(testTitle, function () {\n        throw error;\n      });\n\n      test.file = testFile;\n      suite.addTest(test);\n\n      runner.run(function (failureCount) {\n        sinon.restore();\n        expect(runner, \"to satisfy\", {\n          testResults: {\n            failures: [\n              {\n                title: testTitle,\n                file: testFile,\n                err: {\n                  message: error.message,\n                },\n              },\n            ],\n          },\n        });\n        expect(failureCount, \"to be\", 1);\n        done();\n      });\n    });\n  });\n\n  describe('when \"reporterOption.output\" is provided', function () {\n    var expectedDirName = \"reports\";\n    var expectedFileName = \"reports/test-results.json\";\n    var options = {\n      reporterOption: {\n        output: expectedFileName,\n      },\n    };\n\n    beforeEach(function () {\n      /* eslint-disable-next-line no-unused-vars */\n      var mochaReporter = new mocha._reporter(runner, options);\n    });\n\n    beforeEach(function () {\n      // Add one test to suite to avoid assertions against empty test results\n      var test = new Test(testTitle, () => {});\n      test.file = testFile;\n      suite.addTest(test);\n    });\n\n    it(\"should write test results to file\", function (done) {\n      const fsMkdirSync = sinon.stub(fs, \"mkdirSync\");\n      const fsWriteFileSync = sinon.stub(fs, \"writeFileSync\");\n\n      fsWriteFileSync.callsFake(function (filename, content) {\n        const expectedJson = JSON.stringify(runner.testResults, null, 2);\n        expect(expectedFileName, \"to be\", filename);\n        expect(content, \"to be\", expectedJson);\n      });\n\n      runner.run(function () {\n        expect(\n          fsMkdirSync.calledWith(expectedDirName, { recursive: true }),\n          \"to be true\",\n        );\n        expect(fsWriteFileSync.calledOnce, \"to be true\");\n        done();\n      });\n    });\n\n    it(\"should warn and write test results to console\", function (done) {\n      const fsMkdirSync = sinon.stub(fs, \"mkdirSync\");\n      const fsWriteFileSync = sinon.stub(fs, \"writeFileSync\");\n\n      fsWriteFileSync.throws(\"unable to write file\");\n\n      const outLog = [];\n      const fake = (chunk) => outLog.push(chunk);\n      sinon.stub(process.stderr, \"write\").callsFake(fake);\n      sinon.stub(process.stdout, \"write\").callsFake(fake);\n\n      runner.run(function () {\n        sinon.restore();\n        expect(\n          fsMkdirSync.calledWith(expectedDirName, { recursive: true }),\n          \"to be true\",\n        );\n        expect(fsWriteFileSync.calledOnce, \"to be true\");\n        expect(\n          outLog[0],\n          \"to contain\",\n          `[mocha] writing output to \"${expectedFileName}\" failed:`,\n        );\n        expect(outLog[1], \"to match\", /\"fullTitle\": \"JSON suite json test 1\"/);\n        done();\n      });\n    });\n\n    it('should throw \"unsupported error\" in browser', function () {\n      sinon.stub(utils, \"isBrowser\").callsFake(() => true);\n      expect(\n        () => new JSONReporter(runner, options),\n        \"to throw\",\n        \"file output not supported in browser\",\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/reporters/landing.spec.js",
    "content": "\"use strict\";\n\nvar sinon = require(\"sinon\");\nvar events = require(\"../../\").Runner.constants;\nvar helpers = require(\"./helpers\");\nvar reporters = require(\"../../\").reporters;\nvar states = require(\"../../\").Runnable.constants;\n\nvar Base = reporters.Base;\nvar Landing = reporters.Landing;\nvar createMockRunner = helpers.createMockRunner;\nvar makeRunReporter = helpers.createRunReporterFunction;\n\nvar EVENT_RUN_BEGIN = events.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = events.EVENT_RUN_END;\nvar EVENT_TEST_END = events.EVENT_TEST_END;\n\nvar STATE_FAILED = states.STATE_FAILED;\nvar STATE_PASSED = states.STATE_PASSED;\n\ndescribe(\"Landing reporter\", function () {\n  var runReporter = makeRunReporter(Landing);\n  var resetCode = \"\\u001b[0m\";\n  var expectedArray = [\n    \"\\u001b[1D\\u001b[2A\",\n    \"  \",\n    \"\\n  \",\n    \"\",\n    \"✈\",\n    \"\\n\",\n    \"  \",\n    resetCode,\n  ];\n\n  beforeEach(function () {\n    sinon.stub(Base, \"useColors\").value(false);\n    sinon.stub(Base.window, \"width\").value(1);\n  });\n\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"event handlers\", function () {\n    describe(\"on 'start' event\", function () {\n      it(\"should write newlines\", async function () {\n        sinon.stub(Base.cursor, \"hide\");\n\n        var runner = createMockRunner(\"start\", EVENT_RUN_BEGIN);\n        var options = {};\n        var { stdout } = await runReporter({}, runner, options);\n        sinon.restore();\n\n        expect(stdout[0], \"to equal\", \"\\n\\n\\n  \");\n      });\n\n      it(\"should call cursor hide\", async function () {\n        var hideCursorStub = sinon.stub(Base.cursor, \"hide\");\n\n        var runner = createMockRunner(\"start\", EVENT_RUN_BEGIN);\n        var options = {};\n        await runReporter({}, runner, options);\n        sinon.restore();\n\n        expect(hideCursorStub.called, \"to be true\");\n      });\n    });\n\n    describe(\"on 'test end' event\", function () {\n      describe(\"when test passes\", function () {\n        it(\"should write expected landing strip\", async function () {\n          var test = {\n            state: STATE_PASSED,\n          };\n          var runner = createMockRunner(\n            \"test end\",\n            EVENT_TEST_END,\n            null,\n            null,\n            test,\n          );\n          var options = {};\n          var { stdout } = await runReporter({}, runner, options);\n          sinon.restore();\n\n          expect(stdout, \"to equal\", expectedArray);\n        });\n      });\n\n      describe(\"when test fails\", function () {\n        it(\"should write expected landing strip\", async function () {\n          var test = {\n            state: STATE_FAILED,\n          };\n          var runner = createMockRunner(\n            \"test end\",\n            EVENT_TEST_END,\n            null,\n            null,\n            test,\n          );\n          runner.total = 12;\n          var options = {};\n          var { stdout } = await runReporter({}, runner, options);\n          sinon.restore();\n\n          expect(stdout, \"to equal\", expectedArray);\n        });\n      });\n    });\n\n    describe(\"on 'end' event\", function () {\n      it(\"should call cursor show and epilogue\", async function () {\n        var showCursorStub = sinon.stub(Base.cursor, \"show\");\n\n        var fakeThis = {\n          epilogue: sinon.spy(),\n        };\n        var runner = createMockRunner(\"end\", EVENT_RUN_END);\n        var options = {};\n        await runReporter(fakeThis, runner, options);\n        sinon.restore();\n\n        expect(fakeThis.epilogue.calledOnce, \"to be true\");\n        expect(showCursorStub.called, \"to be true\");\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/reporters/list.spec.js",
    "content": "\"use strict\";\n\nvar sinon = require(\"sinon\");\nvar events = require(\"../../\").Runner.constants;\nvar helpers = require(\"./helpers\");\nvar reporters = require(\"../../\").reporters;\n\nvar Base = reporters.Base;\nvar List = reporters.List;\nvar createMockRunner = helpers.createMockRunner;\nvar makeRunReporter = helpers.createRunReporterFunction;\n\nvar EVENT_RUN_BEGIN = events.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = events.EVENT_RUN_END;\nvar EVENT_TEST_BEGIN = events.EVENT_TEST_BEGIN;\nvar EVENT_TEST_FAIL = events.EVENT_TEST_FAIL;\nvar EVENT_TEST_PASS = events.EVENT_TEST_PASS;\nvar EVENT_TEST_PENDING = events.EVENT_TEST_PENDING;\n\ndescribe(\"List reporter\", function () {\n  var runReporter = makeRunReporter(List);\n  var expectedTitle = \"some title\";\n  var expectedDuration = 100;\n  var noop = function () {};\n  var test = {\n    fullTitle: function () {\n      return expectedTitle;\n    },\n    duration: expectedDuration,\n    slow: noop,\n  };\n\n  beforeEach(function () {\n    sinon.stub(Base, \"useColors\").value(false);\n  });\n\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"event handlers\", function () {\n    describe(\"on 'start' and 'test' events\", function () {\n      it(\"should write expected newline and title\", async function () {\n        var runner = createMockRunner(\n          \"start test\",\n          EVENT_RUN_BEGIN,\n          EVENT_TEST_BEGIN,\n          null,\n          test,\n        );\n        var options = {};\n        var fakeThis = {\n          epilogue: noop,\n        };\n        var { stdout } = await runReporter(fakeThis, runner, options);\n        sinon.restore();\n\n        var startString = \"\\n\";\n        var testString = \"    \" + expectedTitle + \": \";\n        var expectedArray = [startString, testString];\n        expect(stdout, \"to equal\", expectedArray);\n      });\n    });\n\n    describe(\"on 'pending' event\", function () {\n      it(\"should write expected title\", async function () {\n        var runner = createMockRunner(\n          \"pending test\",\n          EVENT_TEST_PENDING,\n          null,\n          null,\n          test,\n        );\n        var options = {};\n        var fakeThis = {\n          epilogue: noop,\n        };\n        var { stdout } = await runReporter(fakeThis, runner, options);\n        sinon.restore();\n\n        expect(stdout[0], \"to equal\", \"  - \" + expectedTitle + \"\\n\");\n      });\n    });\n\n    describe(\"on 'pass' event\", function () {\n      var crStub;\n\n      beforeEach(function () {\n        crStub = sinon.stub(Base.cursor, \"CR\").callsFake(noop);\n      });\n\n      it(\"should call cursor CR\", async function () {\n        var runner = createMockRunner(\n          \"pass\",\n          EVENT_TEST_PASS,\n          null,\n          null,\n          test,\n        );\n        var options = {};\n        var fakeThis = {\n          epilogue: noop,\n        };\n        await runReporter(fakeThis, runner, options);\n        sinon.restore();\n\n        expect(crStub.called, \"to be true\");\n      });\n\n      it(\"should write expected symbol, title, and duration\", async function () {\n        var expectedOkSymbol = \"OK\";\n        sinon.stub(Base.symbols, \"ok\").value(expectedOkSymbol);\n\n        var runner = createMockRunner(\n          \"pass\",\n          EVENT_TEST_PASS,\n          null,\n          null,\n          test,\n        );\n        var options = {};\n        var fakeThis = {\n          epilogue: noop,\n        };\n        var { stdout } = await runReporter(fakeThis, runner, options);\n        sinon.restore();\n\n        expect(\n          stdout[0],\n          \"to be\",\n          \"  \" +\n            expectedOkSymbol +\n            \" \" +\n            expectedTitle +\n            \": \" +\n            expectedDuration +\n            \"ms\\n\",\n        );\n      });\n    });\n\n    describe(\"on 'fail' event\", function () {\n      var crStub;\n\n      beforeEach(function () {\n        crStub = sinon.stub(Base.cursor, \"CR\").callsFake(noop);\n      });\n\n      it(\"should call cursor CR\", async function () {\n        var runner = createMockRunner(\n          \"fail\",\n          EVENT_TEST_FAIL,\n          null,\n          null,\n          test,\n        );\n        var options = {};\n        var fakeThis = {\n          epilogue: noop,\n        };\n        await runReporter(fakeThis, runner, options);\n        sinon.restore();\n\n        expect(crStub.called, \"to be true\");\n      });\n\n      it(\"should write expected error number and title\", async function () {\n        var expectedErrorCount = 1;\n        var runner = createMockRunner(\n          \"fail\",\n          EVENT_TEST_FAIL,\n          null,\n          null,\n          test,\n        );\n        var options = {};\n        var fakeThis = {\n          epilogue: noop,\n        };\n        var { stdout } = await runReporter(fakeThis, runner, options);\n        sinon.restore();\n\n        expect(\n          stdout[0],\n          \"to be\",\n          \"  \" + expectedErrorCount + \") \" + expectedTitle + \"\\n\",\n        );\n      });\n\n      it(\"should immediately construct fail strings\", async function () {\n        var actual = { a: \"actual\" };\n        var expected = { a: \"expected\" };\n        var checked = false;\n        var err;\n        test = {};\n\n        var runner = createMockRunner(\n          \"fail\",\n          EVENT_TEST_FAIL,\n          null,\n          null,\n          test,\n        );\n        runner.on = runner.once = function (event, callback) {\n          if (\n            !checked &&\n            event === \"fail\" &&\n            callback.toString().includes(\"stringifyDiffObjs\") // target correct fail event callback\n          ) {\n            err = new Error(\"fake failure object with actual/expected\");\n            err.actual = actual;\n            err.expected = expected;\n            err.showDiff = true;\n            callback(test, err);\n            checked = true;\n          }\n        };\n        var options = {};\n        var fakeThis = {\n          epilogue: noop,\n        };\n        await runReporter(fakeThis, runner, options);\n        sinon.restore();\n\n        expect(typeof err.actual, \"to be\", \"string\");\n        expect(typeof err.expected, \"to be\", \"string\");\n      });\n    });\n\n    describe(\"on 'end' event\", function () {\n      it(\"should call epilogue\", async function () {\n        var runner = createMockRunner(\"end\", EVENT_RUN_END);\n        var options = {};\n        var fakeThis = {\n          epilogue: sinon.spy(),\n        };\n        await runReporter(fakeThis, runner, options);\n        sinon.restore();\n\n        expect(fakeThis.epilogue.calledOnce, \"to be true\");\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/reporters/markdown.spec.js",
    "content": "\"use strict\";\n\nvar events = require(\"../../\").Runner.constants;\nvar helpers = require(\"./helpers\");\nvar reporters = require(\"../../\").reporters;\n\nvar Markdown = reporters.Markdown;\nvar createMockRunner = helpers.createMockRunner;\nvar makeRunReporter = helpers.createRunReporterFunction;\n\nvar EVENT_RUN_END = events.EVENT_RUN_END;\nvar EVENT_SUITE_BEGIN = events.EVENT_SUITE_BEGIN;\nvar EVENT_SUITE_END = events.EVENT_SUITE_END;\nvar EVENT_TEST_PASS = events.EVENT_TEST_PASS;\n\ndescribe(\"Markdown reporter\", function () {\n  var runReporter = makeRunReporter(Markdown);\n  var expectedTitle = \"expected title\";\n  var expectedFullTitle = \"full title\";\n  var sluggedFullTitle = \"full-title\";\n  var noop = function () {};\n\n  describe(\"event handlers\", function () {\n    describe(\"on 'suite' event\", function () {\n      it(\"should write expected slugged titles on 'end' event\", async function () {\n        var expectedSuite = {\n          title: expectedTitle,\n          fullTitle: function () {\n            return expectedFullTitle;\n          },\n          suites: [\n            {\n              title: expectedTitle,\n              fullTitle: function () {\n                return expectedFullTitle;\n              },\n              suites: [],\n            },\n          ],\n        };\n        var runner = createMockRunner(\n          \"suite suite end\",\n          EVENT_SUITE_BEGIN,\n          EVENT_SUITE_END,\n          EVENT_RUN_END,\n          expectedSuite,\n        );\n        runner.suite = expectedSuite;\n        var options = {};\n        var { stdout } = await runReporter({}, runner, options);\n\n        var expectedArray = [\n          \"# TOC\\n\",\n          \" - [\" +\n            expectedTitle +\n            \"](#\" +\n            sluggedFullTitle +\n            \")\\n   - [\" +\n            expectedTitle +\n            \"](#\" +\n            sluggedFullTitle +\n            \")\\n\",\n          '<a name=\"' + sluggedFullTitle + '\"></a>\\n ' + expectedTitle + \"\\n\",\n        ];\n\n        expect(stdout, \"to equal\", expectedArray);\n      });\n    });\n\n    describe(\"on 'pass' event\", function () {\n      it(\"should write test code inside js code block, on 'end' event\", async function () {\n        var expectedSuite = {\n          title: expectedTitle,\n          fullTitle: function () {\n            return expectedFullTitle;\n          },\n          suites: [],\n        };\n        var expectedDuration = 1000;\n        var currentRetry = 1;\n        var expectedBody = \"some body\";\n        var expectedTest = {\n          title: expectedTitle,\n          fullTitle: function () {\n            return expectedFullTitle;\n          },\n          duration: expectedDuration,\n          currentRetry: function () {\n            return currentRetry;\n          },\n          slow: noop,\n          body: expectedBody,\n        };\n        var runner = createMockRunner(\n          \"pass end\",\n          EVENT_TEST_PASS,\n          EVENT_RUN_END,\n          null,\n          expectedTest,\n        );\n        runner.suite = expectedSuite;\n        var options = {};\n        var { stdout } = await runReporter({}, runner, options);\n\n        var expectedArray = [\n          \"# TOC\\n\",\n          \" - [\" + expectedTitle + \"](#\" + sluggedFullTitle + \")\\n\",\n          expectedTitle + \".\\n\\n```js\\n\" + expectedBody + \"\\n```\\n\\n\",\n        ];\n\n        expect(stdout, \"to equal\", expectedArray);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/reporters/min.spec.js",
    "content": "\"use strict\";\n\nvar sinon = require(\"sinon\");\nvar events = require(\"../../\").Runner.constants;\nvar helpers = require(\"./helpers\");\nvar reporters = require(\"../../\").reporters;\n\nvar Min = reporters.Min;\nvar createMockRunner = helpers.createMockRunner;\nvar makeRunReporter = helpers.createRunReporterFunction;\n\nvar EVENT_RUN_BEGIN = events.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = events.EVENT_RUN_END;\n\ndescribe(\"Min reporter\", function () {\n  var runReporter = makeRunReporter(Min);\n  var noop = function () {};\n\n  describe(\"event handlers\", function () {\n    describe(\"on 'start' event\", function () {\n      it(\"should clear screen then set cursor position\", async function () {\n        var runner = createMockRunner(\"start\", EVENT_RUN_BEGIN);\n        var options = {};\n        var fakeThis = {\n          epilogue: noop,\n        };\n        var { stdout } = await runReporter(fakeThis, runner, options);\n\n        var expectedArray = [\"\\u001b[2J\", \"\\u001b[1;3H\"];\n        expect(stdout, \"to equal\", expectedArray);\n      });\n    });\n\n    describe(\"on 'end' event\", function () {\n      it(\"should call epilogue\", async function () {\n        var fakeThis = {\n          epilogue: sinon.stub().callsFake(noop),\n        };\n        var runner = createMockRunner(\"end\", EVENT_RUN_END);\n        var options = {};\n        await runReporter(fakeThis, runner, options);\n\n        expect(fakeThis.epilogue.called, \"to be true\");\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/reporters/nyan.spec.js",
    "content": "\"use strict\";\n\nvar sinon = require(\"sinon\");\nvar events = require(\"../../\").Runner.constants;\nvar helpers = require(\"./helpers\");\nvar reporters = require(\"../../\").reporters;\n\nvar Base = reporters.Base;\nvar NyanCat = reporters.Nyan;\nvar createMockRunner = helpers.createMockRunner;\nvar makeRunReporter = helpers.createRunReporterFunction;\n\nvar EVENT_RUN_BEGIN = events.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = events.EVENT_RUN_END;\nvar EVENT_TEST_FAIL = events.EVENT_TEST_FAIL;\nvar EVENT_TEST_PASS = events.EVENT_TEST_PASS;\nvar EVENT_TEST_PENDING = events.EVENT_TEST_PENDING;\n\ndescribe(\"Nyan reporter\", function () {\n  var noop = function () {};\n\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"event handlers\", function () {\n    var runReporter = makeRunReporter(NyanCat);\n\n    describe(\"on 'start' event\", function () {\n      it(\"should call draw\", async function () {\n        var fakeThis = {\n          draw: sinon.stub().callsFake(noop),\n          generateColors: noop,\n        };\n\n        var runner = createMockRunner(\"start\", EVENT_RUN_BEGIN);\n        var options = {};\n        await runReporter(fakeThis, runner, options);\n\n        expect(fakeThis.draw.called, \"to be true\");\n      });\n    });\n\n    describe(\"on 'pending' event\", function () {\n      it(\"should call draw\", async function () {\n        var fakeThis = {\n          draw: sinon.stub().callsFake(noop),\n          generateColors: noop,\n        };\n        var runner = createMockRunner(\"pending\", EVENT_TEST_PENDING);\n        var options = {};\n        await runReporter(fakeThis, runner, options);\n\n        expect(fakeThis.draw.called, \"to be true\");\n      });\n    });\n\n    describe(\"on 'pass' event\", function () {\n      it(\"should call draw\", async function () {\n        var test = {\n          duration: \"\",\n          slow: noop,\n        };\n        var fakeThis = {\n          draw: sinon.stub().callsFake(noop),\n          generateColors: noop,\n        };\n        var runner = createMockRunner(\n          \"pass\",\n          EVENT_TEST_PASS,\n          null,\n          null,\n          test,\n        );\n        var options = {};\n        await runReporter(fakeThis, runner, options);\n\n        expect(fakeThis.draw.called, \"to be true\");\n      });\n    });\n\n    describe(\"on 'fail' event\", function () {\n      it(\"should call draw\", async function () {\n        var test = {\n          err: \"\",\n        };\n        var fakeThis = {\n          draw: sinon.stub().callsFake(noop),\n          generateColors: noop,\n        };\n        var runner = createMockRunner(\n          \"fail\",\n          EVENT_TEST_FAIL,\n          null,\n          null,\n          test,\n        );\n        var options = {};\n        await runReporter(fakeThis, runner, options);\n\n        expect(fakeThis.draw.called, \"to be true\");\n      });\n    });\n\n    describe(\"on 'end' event\", function () {\n      it(\"should call epilogue\", async function () {\n        var fakeThis = {\n          draw: noop,\n          epilogue: sinon.stub().callsFake(noop),\n          generateColors: noop,\n        };\n        var runner = createMockRunner(\"end\", EVENT_RUN_END);\n        var options = {};\n        await runReporter(fakeThis, runner, options);\n\n        expect(fakeThis.epilogue.called, \"to be true\");\n      });\n\n      it(\"should write numberOfLines amount of newlines\", async function () {\n        var expectedNumberOfLines = 4;\n        var fakeThis = {\n          draw: noop,\n          epilogue: noop,\n          generateColors: noop,\n        };\n        var runner = createMockRunner(\"end\", EVENT_RUN_END);\n        var options = {};\n        var { stdout } = await runReporter(fakeThis, runner, options);\n\n        var isBlankLine = function (value) {\n          return value === \"\\n\";\n        };\n\n        expect(\n          stdout.filter(isBlankLine),\n          \"to have length\",\n          expectedNumberOfLines,\n        );\n      });\n\n      it(\"should call Base show\", async function () {\n        var showCursorStub = sinon.stub(Base.cursor, \"show\");\n        var fakeThis = {\n          draw: noop,\n          epilogue: noop,\n          generateColors: noop,\n        };\n        var runner = createMockRunner(\"end\", EVENT_RUN_END);\n        var options = {};\n        await runReporter(fakeThis, runner, options);\n        sinon.restore();\n\n        expect(showCursorStub.called, \"to be true\");\n      });\n    });\n  });\n\n  describe(\"#draw\", function () {\n    var stdoutWriteStub;\n    var stdout;\n\n    beforeEach(function () {\n      stdoutWriteStub = sinon.stub(process.stdout, \"write\");\n      stdoutWriteStub.callsFake(function (chunk) {\n        stdout.push(chunk);\n      });\n      stdout = [];\n    });\n\n    describe(\"when 'tick' is false\", function () {\n      it(\"should draw face with expected spaces, _ and ^\", function () {\n        var runner = { on: noop, once: noop };\n        var options = {};\n        var nyanCat = new NyanCat(runner, options);\n        nyanCat.stats = { passes: 2, pending: 1, failures: 0 };\n        var fakeThis = {\n          tick: false,\n          appendRainbow: noop,\n          rainbowify: noop,\n          drawScoreboard: noop,\n          drawRainbow: noop,\n          drawNyanCat: NyanCat.prototype.drawNyanCat,\n          scoreboardWidth: 0,\n          trajectories: [[]],\n          face: noop,\n          cursorUp: noop,\n        };\n\n        try {\n          nyanCat.draw.call(fakeThis);\n        } finally {\n          sinon.restore();\n        }\n\n        var expectedArray = [\n          \"\\u001b[0C\",\n          \"_,------,\",\n          \"\\n\",\n          \"\\u001b[0C\",\n          \"_|   /\\\\_/\\\\ \",\n          \"\\n\",\n          \"\\u001b[0C\",\n          \"^|__undefined \",\n          \"\\n\",\n          \"\\u001b[0C\",\n          '  \"\"  \"\" ',\n          \"\\n\",\n        ];\n        expect(stdout, \"to equal\", expectedArray);\n      });\n    });\n\n    describe(\"when 'tick' is true\", function () {\n      it(\"should draw face with expected spaces, _ and ~\", function () {\n        var runner = { on: noop, once: noop };\n        var options = {};\n        var nyanCat = new NyanCat(runner, options);\n        nyanCat.stats = { passes: 2, pending: 1, failures: 0 };\n        var fakeThis = {\n          tick: true,\n          appendRainbow: noop,\n          rainbowify: noop,\n          drawScoreboard: noop,\n          drawRainbow: noop,\n          drawNyanCat: NyanCat.prototype.drawNyanCat,\n          scoreboardWidth: 0,\n          trajectories: [[]],\n          face: noop,\n          cursorUp: noop,\n        };\n\n        try {\n          nyanCat.draw.call(fakeThis);\n        } finally {\n          sinon.restore();\n        }\n\n        var expectedArray = [\n          \"\\u001b[0C\",\n          \"_,------,\",\n          \"\\n\",\n          \"\\u001b[0C\",\n          \"_|  /\\\\_/\\\\ \",\n          \"\\n\",\n          \"\\u001b[0C\",\n          \"~|_undefined \",\n          \"\\n\",\n          \"\\u001b[0C\",\n          ' \"\"  \"\" ',\n          \"\\n\",\n        ];\n        expect(stdout, \"to equal\", expectedArray);\n      });\n    });\n  });\n\n  describe(\"#cursorDown\", function () {\n    var stdoutWriteStub;\n    var stdout;\n\n    beforeEach(function () {\n      stdoutWriteStub = sinon.stub(process.stdout, \"write\");\n      stdoutWriteStub.callsFake(function (chunk) {\n        stdout.push(chunk);\n      });\n      stdout = [];\n    });\n\n    it(\"should write cursor down interaction with expected number\", function () {\n      var runner = { on: noop, once: noop };\n      var options = {};\n      var nyanCat = new NyanCat(runner, options);\n      var expectedNumber = 25;\n\n      try {\n        nyanCat.cursorDown(expectedNumber);\n      } finally {\n        sinon.restore();\n      }\n\n      var expectedArray = [\"\\u001b[\" + expectedNumber + \"B\"];\n      expect(stdout, \"to equal\", expectedArray);\n    });\n  });\n\n  describe(\"#cursorUp\", function () {\n    var stdoutWriteStub;\n    var stdout;\n\n    beforeEach(function () {\n      stdoutWriteStub = sinon.stub(process.stdout, \"write\");\n      stdoutWriteStub.callsFake(function (chunk) {\n        stdout.push(chunk);\n      });\n      stdout = [];\n    });\n\n    it(\"should write cursor up interaction with expected number\", function () {\n      var runner = { on: noop, once: noop };\n      var options = {};\n      var nyanCat = new NyanCat(runner, options);\n      var expectedNumber = 25;\n\n      try {\n        nyanCat.cursorUp(expectedNumber);\n      } finally {\n        sinon.restore();\n      }\n\n      var expectedArray = [\"\\u001b[\" + expectedNumber + \"A\"];\n      expect(stdout, \"to equal\", expectedArray);\n    });\n  });\n\n  describe(\"#rainbowify\", function () {\n    var useColorsStub;\n\n    beforeEach(function () {\n      useColorsStub = sinon.stub(Base, \"useColors\");\n    });\n\n    afterEach(function () {\n      sinon.restore();\n    });\n\n    describe(\"when 'useColors' is false\", function () {\n      beforeEach(function () {\n        useColorsStub.value(false);\n      });\n\n      it(\"should return argument string\", function () {\n        var runner = { on: noop, once: noop };\n        var options = {};\n        var nyanCat = new NyanCat(runner, options);\n\n        var inputString = \"hello\";\n        var outputString = nyanCat.rainbowify(inputString);\n        sinon.restore();\n\n        var expectedString = inputString;\n        expect(outputString, \"to be\", expectedString);\n      });\n    });\n\n    describe(\"when 'useColors' is true\", function () {\n      beforeEach(function () {\n        useColorsStub.value(true);\n      });\n\n      it(\"should return rainbowified string from the given string and predefined codes\", function () {\n        var runner = { on: noop, once: noop };\n        var options = {};\n        var nyanCat = new NyanCat(runner, options);\n\n        var inputString = \"hello\";\n        var colorCode = \"somecode\";\n        var fakeThis = {\n          rainbowColors: [colorCode],\n          colorIndex: 0,\n        };\n        var outputString = nyanCat.rainbowify.call(fakeThis, inputString);\n        sinon.restore();\n\n        var startCode = \"\\u001b[38;5;\";\n        var endCode = \"\\u001b[0m\";\n        var expectedString =\n          startCode + colorCode + \"m\" + inputString + endCode;\n        expect(outputString, \"to be\", expectedString);\n      });\n    });\n  });\n\n  describe(\"#appendRainbow\", function () {\n    describe(\"when 'tick' is true\", function () {\n      it(\"should set an underscore segment\", function () {\n        var runner = { on: noop, once: noop };\n        var options = {};\n        var nyanCat = new NyanCat(runner, options);\n        var expectedSegment;\n        var inputArray = [];\n        var trajectories = [inputArray, inputArray, inputArray, inputArray];\n        nyanCat.appendRainbow.call({\n          tick: true,\n          rainbowify: function (segment) {\n            expectedSegment = segment;\n          },\n          numberOfLines: 4,\n          trajectoryWidthMax: 0,\n          trajectories,\n        });\n\n        expect(expectedSegment, \"to be\", \"_\");\n      });\n\n      it(\"should shift each trajectory item if its length is greater than or equal to its max width\", function () {\n        var runner = { on: noop, once: noop };\n        var options = {};\n        var nyanCat = new NyanCat(runner, options);\n\n        var rainbowifyResult = \"rainbowify\";\n        var inputArray = [\"itemToShify\"];\n        var trajectories = [inputArray, inputArray, inputArray, inputArray];\n        var expectedArray = [rainbowifyResult];\n        var expectedTrajectories = [\n          expectedArray,\n          expectedArray,\n          expectedArray,\n          expectedArray,\n        ];\n        nyanCat.appendRainbow.call({\n          tick: true,\n          rainbowify: function () {\n            return rainbowifyResult;\n          },\n          numberOfLines: 4,\n          trajectoryWidthMax: 0,\n          trajectories,\n        });\n\n        expect(trajectories, \"to equal\", expectedTrajectories);\n      });\n    });\n\n    describe(\"when 'tick' is false\", function () {\n      it(\"should set a dash segment\", function () {\n        var runner = { on: noop, once: noop };\n        var options = {};\n        var nyanCat = new NyanCat(runner, options);\n        var expectedSegment;\n        var inputArray = [];\n        var trajectories = [inputArray, inputArray, inputArray, inputArray];\n        nyanCat.appendRainbow.call({\n          tick: false,\n          rainbowify: function (segment) {\n            expectedSegment = segment;\n          },\n          numberOfLines: 4,\n          trajectoryWidthMax: 5,\n          trajectories,\n        });\n\n        expect(expectedSegment, \"to equal\", \"-\");\n      });\n    });\n  });\n\n  describe(\"#drawScoreboard\", function () {\n    var stdout;\n\n    beforeEach(function () {\n      sinon.stub(Base, \"color\").callsFake(function (type, n) {\n        return type + n;\n      });\n      var stdoutWriteStub = sinon.stub(process.stdout, \"write\");\n      stdoutWriteStub.callsFake(function (chunk) {\n        stdout.push(chunk);\n      });\n      stdout = [];\n    });\n\n    it(\"should write scoreboard with color set with each stat\", function () {\n      var runner = { on: noop, once: noop };\n      var options = {};\n      var nyanCat = new NyanCat(runner, options);\n\n      var passes = 2;\n      var pending = 1;\n      var failures = 1;\n\n      var fakeThis = {\n        cursorUp: noop,\n        stats: { passes, pending, failures },\n        numberOfLines: 4,\n      };\n\n      try {\n        nyanCat.drawScoreboard.call(fakeThis);\n      } finally {\n        sinon.restore();\n      }\n\n      var expectedArray = [\n        \" \",\n        \"green\" + passes,\n        \"\\n\",\n        \" \",\n        \"fail\" + failures,\n        \"\\n\",\n        \" \",\n        \"pending\" + pending,\n        \"\\n\",\n        \"\\n\",\n      ];\n      expect(stdout, \"to equal\", expectedArray);\n    });\n\n    it(\"should call cursorUp with given numberOfLines\", function () {\n      var expectedNumberOfLines = 1000;\n\n      var runner = { on: noop, once: noop };\n      var options = {};\n      var nyanCat = new NyanCat(runner, options);\n      var fakeThis = {\n        cursorUp: sinon.spy(),\n        stats: { passes: 0, pending: 0, failures: 0 },\n        numberOfLines: expectedNumberOfLines,\n      };\n\n      try {\n        nyanCat.drawScoreboard.call(fakeThis);\n      } finally {\n        sinon.restore();\n      }\n\n      expect(fakeThis.cursorUp.calledWith(expectedNumberOfLines), \"to be true\");\n    });\n  });\n\n  describe(\"#drawRainbow\", function () {\n    var stdout;\n\n    beforeEach(function () {\n      var stdoutWriteStub = sinon.stub(process.stdout, \"write\");\n      stdoutWriteStub.callsFake(function (chunk) {\n        stdout.push(chunk);\n      });\n      stdout = [];\n    });\n\n    it(\"should write width, contents and newline for each trajectory\", function () {\n      var expectedWidth = 444;\n\n      var expectedContents = \"input\";\n      var inputArray = [expectedContents];\n      var trajectories = [inputArray];\n      var runner = { on: noop, once: noop };\n      var options = {};\n      var nyanCat = new NyanCat(runner, options);\n      var fakeThis = {\n        cursorUp: noop,\n        trajectories,\n        scoreboardWidth: expectedWidth,\n        numberOfLines: 1,\n      };\n\n      try {\n        nyanCat.drawRainbow.call(fakeThis);\n      } finally {\n        sinon.restore();\n      }\n\n      var expectedArray = [\n        \"\\u001b[\" + expectedWidth + \"C\",\n        expectedContents,\n        \"\\n\",\n      ];\n      expect(stdout, \"to equal\", expectedArray);\n    });\n\n    it(\"should call cursorUp with given numberOfLines\", function () {\n      var expectedCursorArgument = null;\n      var expectedNumberOfLines = 1000;\n\n      var runner = { on: noop, once: noop };\n      var options = {};\n      var nyanCat = new NyanCat(runner, options);\n      var fakeThis = {\n        cursorUp: function (lines) {\n          expectedCursorArgument = lines;\n        },\n        trajectories: [[\"input\"]],\n        scoreboardWidth: 1,\n        numberOfLines: expectedNumberOfLines,\n      };\n\n      try {\n        nyanCat.drawRainbow.call(fakeThis);\n      } finally {\n        sinon.restore();\n      }\n\n      expect(expectedCursorArgument, \"to be\", expectedNumberOfLines);\n    });\n  });\n\n  describe(\"#face\", function () {\n    it('should expect \"( x .x)\" if any failures', function () {\n      var runner = { on: noop, once: noop };\n      var options = {};\n      var nyanCat = new NyanCat(runner, options);\n      nyanCat.stats = { passes: 2, pending: 1, failures: 1 };\n\n      expect(nyanCat.face(), \"to be\", \"( x .x)\");\n    });\n\n    it('should expect \"( o .o)\" if any pending but none failing', function () {\n      var runner = { on: noop, once: noop };\n      var options = {};\n      var nyanCat = new NyanCat(runner, options);\n      nyanCat.stats = { passes: 2, pending: 1, failures: 0 };\n\n      expect(nyanCat.face(), \"to be\", \"( o .o)\");\n    });\n\n    it('should expect \"( ^ .^)\" if all passing', function () {\n      var runner = { on: noop, once: noop };\n      var options = {};\n      var nyanCat = new NyanCat(runner, options);\n      nyanCat.stats = { passes: 1, pending: 0, failures: 0 };\n\n      expect(nyanCat.face(), \"to be\", \"( ^ .^)\");\n    });\n\n    it('should expect \"( - .-)\" otherwise', function (done) {\n      var runner = { on: noop, once: noop };\n      var options = {};\n      var nyanCat = new NyanCat(runner, options);\n      nyanCat.stats = { passes: 0, pending: 0, failures: 0 };\n\n      expect(nyanCat.face(), \"to be\", \"( - .-)\");\n      done();\n    });\n  });\n});\n"
  },
  {
    "path": "test/reporters/progress.spec.js",
    "content": "\"use strict\";\n\nvar sinon = require(\"sinon\");\nvar events = require(\"../../\").Runner.constants;\nvar helpers = require(\"./helpers\");\nvar reporters = require(\"../../\").reporters;\n\nvar Base = reporters.Base;\nvar Progress = reporters.Progress;\nvar createMockRunner = helpers.createMockRunner;\nvar makeRunReporter = helpers.createRunReporterFunction;\n\nvar EVENT_RUN_BEGIN = events.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = events.EVENT_RUN_END;\nvar EVENT_TEST_END = events.EVENT_TEST_END;\n\ndescribe(\"Progress reporter\", function () {\n  var runReporter = makeRunReporter(Progress);\n  var noop = function () {};\n\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"event handlers\", function () {\n    describe(\"on 'start' event\", function () {\n      it(\"should call cursor hide\", async function () {\n        var hideCursorStub = sinon.stub(Base.cursor, \"hide\");\n\n        var runner = createMockRunner(\"start\", EVENT_RUN_BEGIN);\n        var options = {};\n        await runReporter({}, runner, options);\n        sinon.restore();\n\n        expect(hideCursorStub.called, \"to be true\");\n      });\n    });\n\n    describe(\"on 'test end' event\", function () {\n      describe(\"when line has changed\", function () {\n        it(\"should write expected progress of open and close options\", async function () {\n          var crCursorStub = sinon.stub(Base.cursor, \"CR\").callsFake(noop);\n          sinon.stub(Base, \"useColors\").value(false);\n          sinon.stub(Base.window, \"width\").value(5);\n\n          var expectedTotal = 12;\n          var expectedOpen = \"OpEn\";\n          var expectedClose = \"cLoSe\";\n          var expectedIncomplete = \"iNcOmPlEtE\";\n          var expectedOptions = {\n            open: expectedOpen,\n            complete: \"cOmPlEtE\",\n            incomplete: expectedIncomplete,\n            close: expectedClose,\n          };\n\n          var runner = createMockRunner(\"test end\", EVENT_TEST_END);\n          runner.total = expectedTotal;\n          var options = {\n            reporterOptions: expectedOptions,\n          };\n          var { stdout } = await runReporter({}, runner, options);\n          sinon.restore();\n\n          var expectedArray = [\n            \"\\u001b[J\",\n            \"  \" + expectedOpen,\n            \"\",\n            expectedIncomplete,\n            expectedClose,\n          ];\n\n          expect(crCursorStub.called, \"to be true\");\n          expect(stdout, \"to equal\", expectedArray);\n        });\n      });\n\n      describe(\"when line has not changed\", function () {\n        it(\"should not write anything\", async function () {\n          sinon.stub(Base, \"useColors\").value(false);\n          sinon.stub(Base.cursor, \"CR\").callsFake(noop);\n          sinon.stub(Base.window, \"width\").value(-3);\n\n          var expectedTotal = 1;\n          var runner = createMockRunner(\"test end\", EVENT_TEST_END);\n          runner.total = expectedTotal;\n          var options = {};\n          var { stdout } = await runReporter({}, runner, options);\n          sinon.restore();\n\n          expect(stdout, \"to equal\", []);\n        });\n      });\n    });\n\n    describe(\"on 'end' event\", function () {\n      it(\"should call cursor show and epilogue\", async function () {\n        var showCursorStub = sinon.stub(Base.cursor, \"show\");\n        var fakeThis = {\n          epilogue: sinon.spy(),\n        };\n        var runner = createMockRunner(\"end\", EVENT_RUN_END);\n        var options = {};\n        await runReporter(fakeThis, runner, options);\n        sinon.restore();\n\n        expect(fakeThis.epilogue.calledOnce, \"to be true\");\n        expect(showCursorStub.called, \"to be true\");\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/reporters/spec.spec.js",
    "content": "\"use strict\";\n\nvar sinon = require(\"sinon\");\nvar events = require(\"../../\").Runner.constants;\nvar helpers = require(\"./helpers\");\nvar reporters = require(\"../../\").reporters;\n\nvar Base = reporters.Base;\nvar Spec = reporters.Spec;\nvar createMockRunner = helpers.createMockRunner;\nvar makeRunReporter = helpers.createRunReporterFunction;\n\nvar EVENT_SUITE_BEGIN = events.EVENT_SUITE_BEGIN;\nvar EVENT_TEST_FAIL = events.EVENT_TEST_FAIL;\nvar EVENT_TEST_PASS = events.EVENT_TEST_PASS;\nvar EVENT_TEST_PENDING = events.EVENT_TEST_PENDING;\n\ndescribe(\"Spec reporter\", function () {\n  var runReporter = makeRunReporter(Spec);\n  var expectedTitle = \"expectedTitle\";\n  var noop = function () {};\n\n  beforeEach(function () {\n    sinon.stub(Base, \"useColors\").value(false);\n  });\n\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"event handlers\", function () {\n    describe(\"on 'suite' event\", function () {\n      it(\"should return title\", async function () {\n        var suite = {\n          title: expectedTitle,\n        };\n        var runner = createMockRunner(\n          \"suite\",\n          EVENT_SUITE_BEGIN,\n          null,\n          null,\n          suite,\n        );\n        var options = {};\n        var { stdout } = await runReporter({ epilogue: noop }, runner, options);\n        sinon.restore();\n\n        var expectedArray = [expectedTitle + \"\\n\"];\n        expect(stdout, \"to equal\", expectedArray);\n      });\n    });\n\n    describe(\"on 'pending' event\", function () {\n      it(\"should return title\", async function () {\n        var suite = {\n          title: expectedTitle,\n        };\n        var runner = createMockRunner(\n          \"pending test\",\n          EVENT_TEST_PENDING,\n          null,\n          null,\n          suite,\n        );\n        var options = {};\n        var { stdout } = await runReporter({ epilogue: noop }, runner, options);\n        sinon.restore();\n\n        var expectedArray = [\"  - \" + expectedTitle + \"\\n\"];\n        expect(stdout, \"to equal\", expectedArray);\n      });\n    });\n\n    describe(\"on 'pass' event\", function () {\n      describe(\"when test speed is slow\", function () {\n        it(\"should return expected tick, title, and duration\", async function () {\n          var expectedDuration = 2;\n          var test = {\n            title: expectedTitle,\n            duration: expectedDuration,\n            slow: function () {\n              return 1;\n            },\n          };\n          var runner = createMockRunner(\n            \"pass\",\n            EVENT_TEST_PASS,\n            null,\n            null,\n            test,\n          );\n          var options = {};\n          var { stdout } = await runReporter(\n            { epilogue: noop },\n            runner,\n            options,\n          );\n          sinon.restore();\n\n          var expectedString =\n            \"  \" +\n            Base.symbols.ok +\n            \" \" +\n            expectedTitle +\n            \" (\" +\n            expectedDuration +\n            \"ms)\" +\n            \"\\n\";\n          expect(stdout[0], \"to be\", expectedString);\n        });\n      });\n\n      describe(\"when test speed is fast\", function () {\n        it(\"should return expected tick, title without a duration\", async function () {\n          var expectedDuration = 1;\n          var test = {\n            title: expectedTitle,\n            duration: expectedDuration,\n            slow: function () {\n              return 2;\n            },\n          };\n          var runner = createMockRunner(\n            \"pass\",\n            EVENT_TEST_PASS,\n            null,\n            null,\n            test,\n          );\n          var options = {};\n          var { stdout } = await runReporter(\n            { epilogue: noop },\n            runner,\n            options,\n          );\n          sinon.restore();\n\n          var expectedString =\n            \"  \" + Base.symbols.ok + \" \" + expectedTitle + \"\\n\";\n          expect(stdout[0], \"to be\", expectedString);\n        });\n      });\n    });\n\n    describe(\"on 'fail' event\", function () {\n      it(\"should return title and function count\", async function () {\n        var functionCount = 1;\n        var test = {\n          title: expectedTitle,\n        };\n        var runner = createMockRunner(\n          \"fail\",\n          EVENT_TEST_FAIL,\n          null,\n          null,\n          test,\n        );\n        var options = {};\n        var { stdout } = await runReporter({ epilogue: noop }, runner, options);\n        sinon.restore();\n\n        var expectedArray = [\n          \"  \" + functionCount + \") \" + expectedTitle + \"\\n\",\n        ];\n        expect(stdout, \"to equal\", expectedArray);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/reporters/tap.spec.js",
    "content": "\"use strict\";\n\nvar events = require(\"../../\").Runner.constants;\nvar helpers = require(\"./helpers\");\nvar reporters = require(\"../../\").reporters;\n\nvar TAP = reporters.TAP;\nvar createMockRunner = helpers.createMockRunner;\nvar makeRunReporter = helpers.createRunReporterFunction;\n\nvar EVENT_RUN_BEGIN = events.EVENT_RUN_BEGIN;\nvar EVENT_RUN_END = events.EVENT_RUN_END;\nvar EVENT_TEST_END = events.EVENT_TEST_END;\nvar EVENT_TEST_FAIL = events.EVENT_TEST_FAIL;\nvar EVENT_TEST_PASS = events.EVENT_TEST_PASS;\nvar EVENT_TEST_PENDING = events.EVENT_TEST_PENDING;\n\ndescribe(\"TAP reporter\", function () {\n  var runReporter = makeRunReporter(TAP);\n  var expectedTitle = \"some title\";\n  var countAfterTestEnd = 2;\n  var noop = function () {};\n\n  function createTest() {\n    return {\n      fullTitle: function () {\n        return expectedTitle;\n      },\n      slow: noop,\n    };\n  }\n\n  describe(\"TAP12 spec\", function () {\n    var options = {\n      reporterOptions: {\n        tapVersion: \"12\",\n      },\n    };\n\n    describe(\"event handlers\", function () {\n      describe(\"on 'start' event\", function () {\n        var expectedSuite = \"some suite\";\n        var stdout = [];\n\n        before(async function () {\n          var runner = createMockRunner(\"start\", EVENT_RUN_BEGIN);\n          runner.suite = expectedSuite;\n          ({ stdout } = await runReporter({}, runner, options));\n        });\n\n        it(\"should not write a TAP specification version\", function () {\n          expect(stdout, \"not to contain\", \"TAP version\");\n        });\n      });\n\n      describe(\"on 'pending' event\", function () {\n        var stdout = [];\n\n        before(async function () {\n          var test = createTest();\n          var runner = createMockRunner(\n            \"start test\",\n            EVENT_TEST_END,\n            EVENT_TEST_PENDING,\n            null,\n            test,\n          );\n          runner.suite = \"\";\n          ({ stdout } = await runReporter({}, runner, options));\n        });\n\n        it(\"should write expected message including count and title\", function () {\n          var expectedMessage =\n            \"ok \" + countAfterTestEnd + \" \" + expectedTitle + \" # SKIP -\\n\";\n          expect(stdout[0], \"to equal\", expectedMessage);\n        });\n      });\n\n      describe(\"on 'pass' event\", function () {\n        var stdout;\n\n        before(async function () {\n          var test = createTest();\n          var runner = createMockRunner(\n            \"start test\",\n            EVENT_TEST_END,\n            EVENT_TEST_PASS,\n            null,\n            test,\n          );\n          runner.suite = \"\";\n          ({ stdout } = await runReporter({}, runner, options));\n        });\n\n        it(\"should write expected message including count and title\", function () {\n          var expectedMessage =\n            \"ok \" + countAfterTestEnd + \" \" + expectedTitle + \"\\n\";\n          expect(stdout[0], \"to equal\", expectedMessage);\n        });\n      });\n\n      describe(\"on 'fail' event\", function () {\n        var expectedErrorMessage = \"some error\";\n        var expectedStack = \"some stack\";\n\n        describe(\"when 'error' has only message\", function () {\n          var stdout;\n\n          before(async function () {\n            var test = createTest();\n            var error = {\n              message: expectedErrorMessage,\n            };\n            var runner = createMockRunner(\n              \"test end fail\",\n              EVENT_TEST_END,\n              EVENT_TEST_FAIL,\n              null,\n              test,\n              error,\n            );\n            runner.on = function (event, callback) {\n              if (event === EVENT_TEST_END) {\n                callback();\n              } else if (event === EVENT_TEST_FAIL) {\n                callback(test, error);\n              }\n            };\n            runner.suite = \"\";\n            ({ stdout } = await runReporter({}, runner, options));\n          });\n\n          it(\"should write expected message and error message\", function () {\n            var expectedArray = [\n              \"not ok \" + countAfterTestEnd + \" \" + expectedTitle + \"\\n\",\n              \"  \" + expectedErrorMessage + \"\\n\",\n            ];\n            expect(stdout, \"to equal\", expectedArray);\n          });\n        });\n\n        describe(\"when 'error' has only stack\", function () {\n          var stdout;\n\n          before(async function () {\n            var test = createTest();\n            var error = {\n              stack: expectedStack,\n            };\n            var runner = createMockRunner(\n              \"test end fail\",\n              EVENT_TEST_END,\n              EVENT_TEST_FAIL,\n              null,\n              test,\n              error,\n            );\n            runner.suite = \"\";\n            ({ stdout } = await runReporter({}, runner, options));\n          });\n\n          it(\"should write expected message and stack\", function () {\n            var expectedArray = [\n              \"not ok \" + countAfterTestEnd + \" \" + expectedTitle + \"\\n\",\n              \"  \" + expectedStack + \"\\n\",\n            ];\n            expect(stdout, \"to equal\", expectedArray);\n          });\n        });\n\n        describe(\"when 'error' has both message and stack\", function () {\n          var stdout;\n\n          before(async function () {\n            var test = createTest();\n            var error = {\n              stack: expectedStack,\n              message: expectedErrorMessage,\n            };\n            var runner = createMockRunner(\n              \"test end fail\",\n              EVENT_TEST_END,\n              EVENT_TEST_FAIL,\n              null,\n              test,\n              error,\n            );\n            runner.on = function (event, callback) {\n              if (event === EVENT_TEST_END) {\n                callback();\n              } else if (event === EVENT_TEST_FAIL) {\n                callback(test, error);\n              }\n            };\n            runner.suite = \"\";\n            ({ stdout } = await runReporter({}, runner, options));\n          });\n\n          it(\"should write expected message, error message, and stack\", function () {\n            var expectedArray = [\n              \"not ok \" + countAfterTestEnd + \" \" + expectedTitle + \"\\n\",\n              \"  \" + expectedErrorMessage + \"\\n\",\n              \"  \" + expectedStack + \"\\n\",\n            ];\n            expect(stdout, \"to equal\", expectedArray);\n          });\n        });\n\n        describe(\"when 'error' has neither message nor stack\", function () {\n          var stdout;\n\n          before(async function () {\n            var test = createTest();\n            var error = {};\n            var runner = createMockRunner(\n              \"test end fail\",\n              EVENT_TEST_END,\n              EVENT_TEST_FAIL,\n              null,\n              test,\n              error,\n            );\n            runner.on = runner.once = function (event, callback) {\n              if (event === EVENT_TEST_END) {\n                callback();\n              } else if (event === EVENT_TEST_FAIL) {\n                callback(test, error);\n              }\n            };\n            runner.suite = \"\";\n            ({ stdout } = await runReporter({}, runner, options));\n          });\n\n          it(\"should write expected message only\", function () {\n            var expectedArray = [\n              \"not ok \" + countAfterTestEnd + \" \" + expectedTitle + \"\\n\",\n            ];\n            expect(stdout, \"to equal\", expectedArray);\n          });\n        });\n      });\n\n      describe(\"on 'end' event\", function () {\n        var stdout;\n\n        before(async function () {\n          var test = createTest();\n          var runner = createMockRunner(\n            \"fail end pass\",\n            EVENT_TEST_FAIL,\n            EVENT_RUN_END,\n            EVENT_TEST_PASS,\n            test,\n          );\n          runner.suite = \"\";\n          ({ stdout } = await runReporter({}, runner, options));\n        });\n\n        it(\"should write total tests, passes, failures, & plan\", function () {\n          var numberOfPasses = 1;\n          var numberOfFails = 1;\n          var totalTests = numberOfPasses + numberOfFails;\n          var expectedArray = [\n            \"ok \" + numberOfPasses + \" \" + expectedTitle + \"\\n\",\n            \"not ok \" + numberOfFails + \" \" + expectedTitle + \"\\n\",\n            \"# tests \" + totalTests + \"\\n\",\n            \"# pass \" + numberOfPasses + \"\\n\",\n            \"# fail \" + numberOfFails + \"\\n\",\n            \"1..\" + totalTests + \"\\n\",\n          ];\n          expect(stdout, \"to equal\", expectedArray);\n        });\n      });\n    });\n  });\n\n  describe(\"TAP13 spec\", function () {\n    var options = {\n      reporterOptions: {\n        tapVersion: \"13\",\n      },\n    };\n\n    describe(\"event handlers\", function () {\n      describe(\"on 'start' event\", function () {\n        var expectedSuite = \"some suite\";\n        var stdout;\n\n        before(async function () {\n          var runner = createMockRunner(\"start\", EVENT_RUN_BEGIN);\n          runner.suite = expectedSuite;\n          ({ stdout } = await runReporter({}, runner, options));\n        });\n\n        it(\"should write the TAP specification version\", function () {\n          var tapVersion = options.reporterOptions.tapVersion;\n          var expectedFirstLine = \"TAP version \" + tapVersion + \"\\n\";\n          expect(stdout[0], \"to equal\", expectedFirstLine);\n        });\n      });\n\n      describe(\"on 'pending' event\", function () {\n        var stdout;\n\n        before(async function () {\n          var test = createTest();\n          var runner = createMockRunner(\n            \"start test\",\n            EVENT_TEST_END,\n            EVENT_TEST_PENDING,\n            null,\n            test,\n          );\n          runner.suite = \"\";\n          ({ stdout } = await runReporter({}, runner, options));\n        });\n\n        it(\"should write expected message including count and title\", function () {\n          var expectedMessage =\n            \"ok \" + countAfterTestEnd + \" \" + expectedTitle + \" # SKIP -\\n\";\n          expect(stdout[0], \"to equal\", expectedMessage);\n        });\n      });\n\n      describe(\"on 'pass' event\", function () {\n        var stdout;\n\n        before(async function () {\n          var test = createTest();\n          var runner = createMockRunner(\n            \"start test\",\n            EVENT_TEST_END,\n            EVENT_TEST_PASS,\n            null,\n            test,\n          );\n          runner.suite = \"\";\n          ({ stdout } = await runReporter({}, runner, options));\n        });\n\n        it(\"should write expected message including count and title\", function () {\n          var expectedMessage =\n            \"ok \" + countAfterTestEnd + \" \" + expectedTitle + \"\\n\";\n          expect(stdout[0], \"to equal\", expectedMessage);\n        });\n      });\n\n      describe(\"on 'fail' event\", function () {\n        var expectedErrorMessage = \"some error\";\n        var expectedStack = \"some stack\";\n\n        describe(\"when 'error' has only message\", function () {\n          var stdout;\n\n          before(async function () {\n            var test = createTest();\n            var error = {\n              message: expectedErrorMessage,\n            };\n            var runner = createMockRunner(\n              \"test end fail\",\n              EVENT_TEST_END,\n              EVENT_TEST_FAIL,\n              null,\n              test,\n              error,\n            );\n            runner.on = function (event, callback) {\n              if (event === EVENT_TEST_END) {\n                callback();\n              } else if (event === EVENT_TEST_FAIL) {\n                callback(test, error);\n              }\n            };\n            runner.suite = \"\";\n            ({ stdout } = await runReporter({}, runner, options));\n          });\n\n          it(\"should write expected message and error message\", function () {\n            var expectedArray = [\n              \"not ok \" + countAfterTestEnd + \" \" + expectedTitle + \"\\n\",\n              \"  ---\\n\",\n              \"    message: |-\\n\",\n              \"      \" + expectedErrorMessage + \"\\n\",\n              \"  ...\\n\",\n            ];\n            expect(stdout, \"to equal\", expectedArray);\n          });\n        });\n\n        describe(\"when 'error' has only stack\", function () {\n          var stdout;\n\n          before(async function () {\n            var test = createTest();\n            var error = {\n              stack: expectedStack,\n            };\n            var runner = createMockRunner(\n              \"test end fail\",\n              EVENT_TEST_END,\n              EVENT_TEST_FAIL,\n              null,\n              test,\n              error,\n            );\n            runner.suite = \"\";\n            ({ stdout } = await runReporter({}, runner, options));\n          });\n\n          it(\"should write expected message and stack\", function () {\n            var expectedArray = [\n              \"not ok \" + countAfterTestEnd + \" \" + expectedTitle + \"\\n\",\n              \"  ---\\n\",\n              \"    stack: |-\\n\",\n              \"      \" + expectedStack + \"\\n\",\n              \"  ...\\n\",\n            ];\n            expect(stdout, \"to equal\", expectedArray);\n          });\n        });\n\n        describe(\"when 'error' has both message and stack\", function () {\n          var stdout;\n\n          before(async function () {\n            var test = createTest();\n            var error = {\n              stack: expectedStack,\n              message: expectedErrorMessage,\n            };\n            var runner = createMockRunner(\n              \"test end fail\",\n              EVENT_TEST_END,\n              EVENT_TEST_FAIL,\n              null,\n              test,\n              error,\n            );\n            runner.on = function (event, callback) {\n              if (event === EVENT_TEST_END) {\n                callback();\n              } else if (event === EVENT_TEST_FAIL) {\n                callback(test, error);\n              }\n            };\n            runner.suite = \"\";\n            ({ stdout } = await runReporter({}, runner, options));\n          });\n\n          it(\"should write expected message, error message, and stack\", function () {\n            var expectedArray = [\n              \"not ok \" + countAfterTestEnd + \" \" + expectedTitle + \"\\n\",\n              \"  ---\\n\",\n              \"    message: |-\\n\",\n              \"      \" + expectedErrorMessage + \"\\n\",\n              \"    stack: |-\\n\",\n              \"      \" + expectedStack + \"\\n\",\n              \"  ...\\n\",\n            ];\n            expect(stdout, \"to equal\", expectedArray);\n          });\n        });\n\n        describe(\"when 'error' has neither message nor stack\", function () {\n          var stdout;\n\n          before(async function () {\n            var test = createTest();\n            var error = {};\n            var runner = createMockRunner(\n              \"test end fail\",\n              EVENT_TEST_END,\n              EVENT_TEST_FAIL,\n              null,\n              test,\n              error,\n            );\n            runner.on = runner.once = function (event, callback) {\n              if (event === EVENT_TEST_END) {\n                callback();\n              } else if (event === EVENT_TEST_FAIL) {\n                callback(test, error);\n              }\n            };\n            runner.suite = \"\";\n            ({ stdout } = await runReporter({}, runner, options));\n          });\n\n          it(\"should write expected message only\", function () {\n            var expectedArray = [\n              \"not ok \" + countAfterTestEnd + \" \" + expectedTitle + \"\\n\",\n            ];\n            expect(stdout, \"to equal\", expectedArray);\n          });\n        });\n      });\n\n      describe(\"on 'end' event\", function () {\n        var stdout;\n\n        before(async function () {\n          var test = createTest();\n          var runner = createMockRunner(\n            \"fail end pass\",\n            EVENT_TEST_FAIL,\n            EVENT_RUN_END,\n            EVENT_TEST_PASS,\n            test,\n          );\n          runner.suite = \"\";\n          ({ stdout } = await runReporter({}, runner, options));\n        });\n\n        it(\"should write total tests, passes, failures & plan\", function () {\n          var numberOfPasses = 1;\n          var numberOfFails = 1;\n          var totalTests = numberOfPasses + numberOfFails;\n          var expectedArray = [\n            \"ok \" + numberOfPasses + \" \" + expectedTitle + \"\\n\",\n            \"not ok \" + numberOfFails + \" \" + expectedTitle + \"\\n\",\n            \"# tests \" + totalTests + \"\\n\",\n            \"# pass \" + numberOfPasses + \"\\n\",\n            \"# fail \" + numberOfFails + \"\\n\",\n            \"1..\" + totalTests + \"\\n\",\n          ];\n          expect(stdout, \"to equal\", expectedArray);\n        });\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/reporters/xunit.spec.js",
    "content": "\"use strict\";\n\nvar EventEmitter = require(\"events\").EventEmitter;\nvar fs = require(\"fs\");\nvar path = require(\"path\");\nvar sinon = require(\"sinon\");\nvar createStatsCollector = require(\"../../lib/stats-collector\");\nvar events = require(\"../../\").Runner.constants;\nvar reporters = require(\"../../\").reporters;\nvar states = require(\"../../\").Runnable.constants;\n\nconst { createTempDir, touchFile } = require(\"../integration/helpers\");\n\nvar helpers = require(\"./helpers\");\nvar createMockRunner = helpers.createMockRunner;\nvar makeRunReporter = helpers.createRunReporterFunction;\n\nvar Base = reporters.Base;\nvar XUnit = reporters.XUnit;\n\nvar EVENT_RUN_END = events.EVENT_RUN_END;\nvar EVENT_TEST_END = events.EVENT_TEST_END;\nvar EVENT_TEST_FAIL = events.EVENT_TEST_FAIL;\nvar EVENT_TEST_PASS = events.EVENT_TEST_PASS;\nvar EVENT_TEST_PENDING = events.EVENT_TEST_PENDING;\n\nvar STATE_FAILED = states.STATE_FAILED;\nvar STATE_PASSED = states.STATE_PASSED;\n\ndescribe(\"XUnit reporter\", function () {\n  var runReporter = makeRunReporter(XUnit);\n  var runner;\n  var noop = function () {};\n\n  var expectedLine = \"some-line\";\n  var expectedClassName = \"fullTitle\";\n  var expectedTitle = \"some title\";\n  var expectedFile = \"testFile.spec.js\";\n  var expectedMessage = \"some message\";\n  var expectedDiff =\n    \"\\n      + expected - actual\\n\\n      -foo\\n      +bar\\n      \";\n  var expectedStack = \"some-stack\";\n\n  beforeEach(function () {\n    runner = { on: noop, once: noop };\n    createStatsCollector(runner);\n  });\n\n  describe(\"when 'reporterOptions.output' is provided\", function () {\n    var expectedOutput = path.join(path.sep, \"path\", \"to\", \"some-output\");\n    var options = {\n      reporterOptions: {\n        output: expectedOutput,\n      },\n    };\n\n    describe(\"when fileStream can be created\", function () {\n      var fsMkdirSync;\n      var fsCreateWriteStream;\n\n      beforeEach(function () {\n        fsMkdirSync = sinon.stub(fs, \"mkdirSync\");\n        fsCreateWriteStream = sinon.stub(fs, \"createWriteStream\");\n      });\n\n      it(\"should open given file for writing, recursively creating directories in pathname\", async function () {\n        var runner = createMockRunner(\"start\", events.EVENT_RUN_BEGIN);\n        var options = {\n          reporterOptions: {\n            output: expectedOutput,\n          },\n        };\n        new XUnit(runner, options);\n\n        var expectedDirectory = path.dirname(expectedOutput);\n        expect(\n          fsMkdirSync.calledWith(expectedDirectory, {\n            recursive: true,\n          }),\n          \"to be true\",\n        );\n\n        expect(fsCreateWriteStream.calledWith(expectedOutput), \"to be true\");\n      });\n\n      afterEach(function () {\n        sinon.restore();\n      });\n    });\n\n    describe(\"when fileStream cannot be created\", function () {\n      describe(\"when given an invalid pathname\", function () {\n        /**\n         * @type {string}\n         */\n        let tmpdir;\n\n        /**\n         * @type {import('../integration/helpers').RemoveTempDirCallback}\n         */\n        let cleanup;\n        var invalidPath;\n\n        beforeEach(async function () {\n          const { dirpath, removeTempDir } = await createTempDir();\n          tmpdir = dirpath;\n          cleanup = removeTempDir;\n\n          // Create path where file 'some-file' used as directory\n          invalidPath = path.join(\n            tmpdir,\n            \"some-file\",\n            path.basename(expectedOutput),\n          );\n          touchFile(path.dirname(invalidPath));\n        });\n\n        it(\"should throw system error\", function () {\n          var options = {\n            reporterOptions: {\n              output: invalidPath,\n            },\n          };\n          var boundXUnit = () => new XUnit(runner, options);\n          expect(\n            boundXUnit,\n            \"to throw\",\n            expect.it(\"to be an\", Error).and(\"to satisfy\", {\n              syscall: \"mkdir\",\n              code: \"EEXIST\",\n              path: path.dirname(invalidPath),\n            }),\n          );\n        });\n\n        afterEach(function () {\n          cleanup();\n        });\n      });\n\n      describe(\"when run in browser\", function () {\n        beforeEach(function () {\n          sinon.stub(fs, \"createWriteStream\").value(false);\n        });\n\n        it(\"should throw unsupported error\", function () {\n          var boundXUnit = () => new XUnit(runner, options);\n          expect(\n            boundXUnit,\n            \"to throw\",\n            \"file output not supported in browser\",\n          );\n        });\n\n        afterEach(function () {\n          sinon.restore();\n        });\n      });\n    });\n  });\n\n  describe(\"event handlers\", function () {\n    var fsCreateWriteStream;\n\n    beforeEach(function () {\n      sinon.stub(fs, \"mkdirSync\");\n      fsCreateWriteStream = sinon.stub(fs, \"createWriteStream\");\n    });\n\n    describe(\"on 'pending', 'pass' and 'fail' events\", function () {\n      it(\"should add test to tests called on 'end' event\", async function () {\n        var pendingTest = {\n          isPending: () => false,\n          parent: {\n            fullTitle: () => \"pending parent\",\n          },\n          name: \"pending\",\n          slow: noop,\n        };\n        var failTest = {\n          isPending: () => false,\n          parent: {\n            fullTitle: () => \"fail parent\",\n          },\n          name: \"fail\",\n          slow: noop,\n        };\n        var passTest = {\n          isPending: () => false,\n          parent: {\n            fullTitle: () => \"pass parent\",\n          },\n          name: \"pass\",\n          slow: noop,\n        };\n        var write = sinon.spy();\n        fsCreateWriteStream.returns({ write });\n        runner.on = runner.once = function (event, callback) {\n          if (event === EVENT_TEST_PENDING) {\n            callback(pendingTest);\n          } else if (event === EVENT_TEST_PASS) {\n            callback(passTest);\n          } else if (event === EVENT_TEST_FAIL) {\n            callback(failTest);\n          } else if (event === EVENT_RUN_END) {\n            callback();\n          }\n        };\n\n        var expectedOutput = path.join(path.sep, \"path\", \"to\", \"some-output\");\n        var options = {\n          reporterOptions: {\n            output: expectedOutput,\n          },\n        };\n        const { reporter } = await runReporter({}, runner, options);\n\n        reporter.fileStream;\n        expect(write.getCalls().length, \"to equal\", 5);\n        expect(write.getCall(1).args[0], \"to match\", /pending parent/);\n        expect(write.getCall(2).args[0], \"to match\", /pass parent/);\n        expect(write.getCall(3).args[0], \"to match\", /fail parent/);\n      });\n    });\n  });\n\n  describe(\"#done\", function () {\n    var xunit;\n    var options = {\n      reporterOptions: {},\n    };\n    var expectedNFailures = 13;\n    var callback;\n\n    beforeEach(function () {\n      callback = sinon.spy();\n    });\n\n    afterEach(function () {\n      callback = null;\n      xunit = null;\n      sinon.restore();\n    });\n\n    describe(\"when output directed to file\", function () {\n      var fakeThis;\n\n      beforeEach(function () {\n        xunit = new XUnit(runner, options);\n\n        fakeThis = {\n          fileStream: {\n            end: sinon.stub().callsFake(function (chunk, encoding, cb) {\n              if (typeof arguments[0] === \"function\") {\n                cb = arguments[0];\n              }\n              cb();\n            }),\n            write: function () {},\n          },\n        };\n      });\n\n      it(\"should run completion callback via 'fileStream.end'\", function () {\n        xunit.done.call(fakeThis, expectedNFailures, callback);\n\n        expect(fakeThis.fileStream.end.calledOnce, \"to be true\");\n        expect(callback.calledOnce, \"to be true\");\n        expect(callback.calledWith(expectedNFailures), \"to be true\");\n      });\n    });\n\n    describe(\"when output directed to stdout (or console)\", function () {\n      var fakeThis;\n\n      beforeEach(function () {\n        xunit = new XUnit(runner, options);\n        fakeThis = {};\n      });\n\n      it(\"should run completion callback\", function () {\n        xunit.done.call(fakeThis, expectedNFailures, callback);\n\n        expect(callback.calledOnce, \"to be true\");\n        expect(callback.calledWith(expectedNFailures), \"to be true\");\n      });\n    });\n  });\n\n  describe(\"#write\", function () {\n    // :TODO: Method should be named 'writeln', not 'write'\n    describe(\"when output directed to file\", function () {\n      var fileStream = {\n        write: sinon.spy(),\n      };\n\n      it(\"should call 'fileStream.write' with line and newline\", function () {\n        var xunit = new XUnit(runner);\n        var fakeThis = { fileStream };\n        xunit.write.call(fakeThis, expectedLine);\n\n        expect(fileStream.write.calledWith(expectedLine + \"\\n\"), \"to be true\");\n      });\n    });\n\n    describe(\"when output directed to stdout\", function () {\n      it(\"should call 'process.stdout.write' with line and newline\", function () {\n        var xunit = new XUnit(runner);\n        var fakeThis = { fileStream: false };\n        var stdoutWriteStub = sinon.stub(process.stdout, \"write\");\n        xunit.write.call(fakeThis, expectedLine);\n        stdoutWriteStub.restore();\n\n        expect(stdoutWriteStub.calledWith(expectedLine + \"\\n\"), \"to be true\");\n      });\n    });\n\n    describe(\"when output directed to console\", function () {\n      it(\"should call 'Base.consoleLog' with line\", function () {\n        // :TODO: XUnit needs a trivially testable means to force console.log()\n        var realProcess = process;\n        process = false; // eslint-disable-line no-global-assign\n\n        var xunit = new XUnit(runner);\n        var fakeThis = { fileStream: false };\n        var consoleLogStub = sinon.stub(Base, \"consoleLog\");\n        xunit.write.call(fakeThis, expectedLine);\n        consoleLogStub.restore();\n\n        process = realProcess; // eslint-disable-line no-global-assign\n\n        expect(consoleLogStub.calledWith(expectedLine), \"to be true\");\n      });\n    });\n  });\n\n  describe(\"#test\", function () {\n    var expectedWrite;\n    var fakeThis = {\n      write: function (str) {\n        expectedWrite = str;\n      },\n    };\n\n    beforeEach(function () {\n      sinon.stub(Base, \"useColors\").value(false);\n    });\n\n    afterEach(function () {\n      sinon.restore();\n      expectedWrite = null;\n    });\n\n    describe(\"on test failure\", function () {\n      it(\"should write expected tag with error details\", function () {\n        var xunit = new XUnit(runner);\n        var expectedTest = {\n          state: STATE_FAILED,\n          title: expectedTitle,\n          file: expectedFile,\n          parent: {\n            fullTitle: function () {\n              return expectedClassName;\n            },\n          },\n          duration: 1000,\n          err: {\n            actual: \"foo\",\n            expected: \"bar\",\n            message: expectedMessage,\n            stack: expectedStack,\n          },\n        };\n\n        xunit.test.call(fakeThis, expectedTest);\n        sinon.restore();\n\n        var expectedTag =\n          '<testcase classname=\"' +\n          expectedClassName +\n          '\" name=\"' +\n          expectedTitle +\n          '\" file=\"' +\n          expectedFile +\n          '\" time=\"1\"><failure>' +\n          expectedMessage +\n          \"\\n\" +\n          expectedDiff +\n          \"\\n\" +\n          expectedStack +\n          \"</failure></testcase>\";\n        expect(expectedWrite, \"to be\", expectedTag);\n      });\n\n      it(\"should handle non-string diff values\", function () {\n        var runner = new EventEmitter();\n        createStatsCollector(runner);\n        var xunit = new XUnit(runner);\n\n        var expectedTest = {\n          state: STATE_FAILED,\n          title: expectedTitle,\n          file: expectedFile,\n          parent: {\n            fullTitle: function () {\n              return expectedClassName;\n            },\n          },\n          duration: 1000,\n          err: {\n            actual: 1,\n            expected: 2,\n            message: expectedMessage,\n            stack: expectedStack,\n          },\n        };\n\n        sinon.stub(xunit, \"write\").callsFake(function (str) {\n          expectedWrite += str;\n        });\n\n        runner.emit(EVENT_TEST_FAIL, expectedTest, expectedTest.err);\n        runner.emit(EVENT_RUN_END);\n        sinon.restore();\n\n        var expectedDiff =\n          \"\\n      + expected - actual\\n\\n      -1\\n      +2\\n      \";\n\n        expect(expectedWrite, \"to contain\", expectedDiff);\n      });\n    });\n\n    describe(\"on test pending\", function () {\n      it(\"should write expected tag\", function () {\n        var xunit = new XUnit(runner);\n        var expectedTest = {\n          isPending: function () {\n            return true;\n          },\n          title: expectedTitle,\n          file: expectedFile,\n          parent: {\n            fullTitle: function () {\n              return expectedClassName;\n            },\n          },\n          duration: 1000,\n        };\n\n        xunit.test.call(fakeThis, expectedTest);\n        sinon.restore();\n\n        var expectedTag =\n          '<testcase classname=\"' +\n          expectedClassName +\n          '\" name=\"' +\n          expectedTitle +\n          '\" file=\"' +\n          expectedFile +\n          '\" time=\"1\"><skipped/></testcase>';\n        expect(expectedWrite, \"to be\", expectedTag);\n      });\n    });\n\n    describe(\"on test in any other state\", function () {\n      it(\"should write expected tag\", function () {\n        var xunit = new XUnit(runner);\n        var expectedTest = {\n          isPending: function () {\n            return false;\n          },\n          title: expectedTitle,\n          file: expectedFile,\n          parent: {\n            fullTitle: function () {\n              return expectedClassName;\n            },\n          },\n          duration: false,\n        };\n\n        xunit.test.call(fakeThis, expectedTest);\n        sinon.restore();\n\n        var expectedTag =\n          '<testcase classname=\"' +\n          expectedClassName +\n          '\" name=\"' +\n          expectedTitle +\n          '\" file=\"' +\n          expectedFile +\n          '\" time=\"0\"/>';\n        expect(expectedWrite, \"to be\", expectedTag);\n      });\n    });\n\n    it(\"should write expected summary statistics\", function () {\n      var numTests = 0;\n      var numPass = 0;\n      var numFail = 0;\n      var simpleError = {\n        actual: \"foo\",\n        expected: \"bar\",\n        message: expectedMessage,\n        stack: expectedStack,\n      };\n      var generateTest = function (passed) {\n        numTests++;\n        if (passed) {\n          numPass++;\n        } else {\n          numFail++;\n        }\n        return {\n          title: [expectedTitle, numTests].join(\": \"),\n          state: passed ? STATE_PASSED : STATE_FAILED,\n          isPending: function () {\n            return false;\n          },\n          slow: function () {\n            return false;\n          },\n          parent: {\n            fullTitle: function () {\n              return expectedClassName;\n            },\n          },\n          duration: 1000,\n        };\n      };\n\n      var runner = new EventEmitter();\n      createStatsCollector(runner);\n      var xunit = new XUnit(runner);\n      expectedWrite = \"\";\n      sinon.stub(xunit, \"write\").callsFake(function (str) {\n        expectedWrite += str;\n      });\n\n      // 3 tests, no failures (i.e. tests that could not run), and 2 errors\n      runner.emit(EVENT_TEST_PASS, generateTest(true));\n      runner.emit(EVENT_TEST_END);\n      runner.emit(EVENT_TEST_FAIL, generateTest(false), simpleError);\n      runner.emit(EVENT_TEST_END);\n      runner.emit(EVENT_TEST_FAIL, generateTest(false), simpleError);\n      runner.emit(EVENT_TEST_END);\n      runner.emit(EVENT_RUN_END);\n\n      sinon.restore();\n\n      var expectedNumPass = 1;\n      var expectedNumFail = 2;\n      var expectedNumTests = 3;\n\n      expect(expectedNumPass, \"to be\", numPass);\n      expect(expectedNumFail, \"to be\", numFail);\n      expect(expectedNumTests, \"to be\", numTests);\n\n      // :NOTE: Mocha test \"fail\" is an XUnit \"error\"\n      var expectedTag =\n        '<testsuite name=\"Mocha Tests\" tests=\"3\" failures=\"0\" errors=\"2\" skipped=\"0\"';\n\n      expect(expectedWrite, \"to contain\", expectedTag);\n      expect(expectedWrite, \"to contain\", \"</testsuite>\");\n    });\n  });\n\n  describe(\"suite name\", function () {\n    // Capture the events that the reporter subscribes to\n    var events = {};\n    // Capture output lines (will contain the resulting XML of XUnit reporter)\n    var lines = [];\n    // File stream into which the XUnit reporter will write\n    var fileStream;\n\n    before(function () {\n      fileStream = {\n        write: function (chunk) {\n          lines.push(chunk);\n        },\n      };\n    });\n\n    beforeEach(function () {\n      lines = [];\n      events = {};\n\n      runner.on = runner.once = function (eventName, eventHandler) {\n        // Capture the event handler\n        events[eventName] = eventHandler;\n      };\n    });\n\n    it(\"should use custom name if provided via reporter options\", function () {\n      var customSuiteName = \"Mocha Is Great!\";\n      var options = {\n        reporterOptions: {\n          suiteName: customSuiteName,\n        },\n      };\n\n      var xunit = new XUnit(runner, options);\n      xunit.fileStream = fileStream;\n\n      // Trigger end event to force XUnit reporter to write its output\n      events[EVENT_RUN_END]();\n\n      expect(lines[0], \"to contain\", customSuiteName);\n    });\n\n    it(\"should use default name otherwise\", function () {\n      var defaultSuiteName = \"Mocha Tests\";\n      var options = {\n        reporterOptions: {},\n      };\n\n      var xunit = new XUnit(runner, options);\n      xunit.fileStream = fileStream;\n\n      // Trigger end event to force XUnit reporter to write its output\n      events[EVENT_RUN_END]();\n\n      expect(lines[0], \"to contain\", defaultSuiteName);\n    });\n  });\n\n  describe(\"showRelativePaths reporter option\", function () {\n    const projectPath = path.join(\"home\", \"username\", \"demo-project\");\n    const relativeTestPath = path.join(\"tests\", \"demo-test.spec.js\");\n    const absoluteTestPath = path.join(projectPath, relativeTestPath);\n\n    var expectedWrite = \"\";\n    const fakeThis = {\n      write: function (str) {\n        expectedWrite = expectedWrite + str;\n      },\n    };\n\n    const failingTest = {\n      state: STATE_FAILED,\n      title: expectedTitle,\n      file: absoluteTestPath,\n      parent: {\n        fullTitle: function () {\n          return expectedClassName;\n        },\n      },\n      duration: 1000,\n      err: {\n        actual: \"foo\",\n        expected: \"bar\",\n        message: expectedMessage,\n        stack: expectedStack,\n      },\n    };\n\n    beforeEach(function () {\n      sinon.stub(process, \"cwd\").returns(projectPath);\n    });\n\n    afterEach(function () {\n      sinon.restore();\n      expectedWrite = \"\";\n    });\n\n    it(\"shows relative paths for tests if showRelativePaths reporter option is set\", function () {\n      const options = {\n        reporterOptions: {\n          showRelativePaths: true,\n        },\n      };\n      const xunit = new XUnit(runner, options);\n\n      xunit.test.call(fakeThis, failingTest, options);\n\n      expect(expectedWrite, \"not to contain\", absoluteTestPath);\n      expect(expectedWrite, \"to contain\", relativeTestPath);\n    });\n\n    it(\"shows absolute paths for tests by default\", function () {\n      const options = {};\n      const xunit = new XUnit(runner);\n\n      xunit.test.call(fakeThis, failingTest, options);\n\n      expect(expectedWrite, \"to contain\", absoluteTestPath);\n      // Double quote included to ensure printed paths don't start with relative path. Example printed line: <testcase classname=\"suite\" name=\"test\" file=\"some/tesfile.js\" time=\"0\"/>\n      expect(expectedWrite, \"not to contain\", `\"${relativeTestPath}`);\n    });\n  });\n});\n"
  },
  {
    "path": "test/require/a.js",
    "content": "\"use strict\";\n\nglobal.required = global.required || [];\nglobal.required.push(\"a.js\");\n"
  },
  {
    "path": "test/require/b.coffee",
    "content": "global.required ?= []\nglobal.required.push 'b.coffee'\n"
  },
  {
    "path": "test/require/c.js",
    "content": "\"use strict\";\n\nglobal.required = global.required || [];\nglobal.required.push(\"c.js\");\n"
  },
  {
    "path": "test/require/d.coffee",
    "content": "global.required ?= []\nglobal.required.push 'd.coffee'\n"
  },
  {
    "path": "test/require/require.spec.js",
    "content": "\"use strict\";\n\ndescribe(\"require test\", function () {\n  it(\"should require args in order\", function () {\n    var req = global.required;\n    expect(req.indexOf(\"a.js\"), \"to be\", 0);\n    expect(req.indexOf(\"b.coffee\"), \"to be\", 1);\n    expect(req.indexOf(\"c.js\"), \"to be\", 2);\n    expect(req.indexOf(\"d.coffee\"), \"to be\", 3);\n  });\n});\n"
  },
  {
    "path": "test/setup.js",
    "content": "\"use strict\";\n\nconst unexpected = require(\"unexpected\");\n\nglobal.expect = unexpected\n  .clone()\n  .use(require(\"unexpected-sinon\"))\n  .use(require(\"unexpected-eventemitter\"))\n  .use(require(\"unexpected-map\"))\n  .use(require(\"unexpected-set\"))\n  .use(require(\"./assertions\"));\n"
  },
  {
    "path": "test/smoke/smoke.spec.js",
    "content": "\"use strict\";\n\n// This test ensures Mocha's dependencies are properly in place,\n// and is intended to be run after an `npm install --production` in a clean\n// working copy. It helps avoid publishing Mocha with `dependencies`\n// in `devDependencies` or otherwise in the wrong place.\n// It does not ensure that all files are present in the published package!\n\nvar assert = require(\"node:assert\");\n\ndescribe(\"a production installation of Mocha\", function () {\n  it(\"should be able to execute a test\", function () {\n    assert.ok(true);\n  });\n});\n"
  },
  {
    "path": "test/unit/context.spec.js",
    "content": "\"use strict\";\n\ndescribe(\"Context\", function () {\n  beforeEach(function () {\n    this.calls = [\"before\"];\n  });\n\n  describe(\"nested\", function () {\n    beforeEach(function () {\n      this.calls.push(\"before two\");\n    });\n\n    it(\"should work\", function () {\n      expect(this.calls, \"to equal\", [\"before\", \"before two\"]);\n      this.calls.push(\"test\");\n    });\n\n    after(function () {\n      expect(this.calls, \"to equal\", [\"before\", \"before two\", \"test\"]);\n      this.calls.push(\"after two\");\n    });\n  });\n\n  after(function () {\n    expect(this.calls, \"to equal\", [\n      \"before\",\n      \"before two\",\n      \"test\",\n      \"after two\",\n    ]);\n  });\n});\n\ndescribe(\"Context Siblings\", function () {\n  beforeEach(function () {\n    this.calls = [\"before\"];\n  });\n\n  describe(\"sequestered sibling\", function () {\n    beforeEach(function () {\n      this.calls.push(\"before two\");\n      this.hiddenFromSibling = \"This should be hidden\";\n    });\n\n    it(\"should work\", function () {\n      expect(this.hiddenFromSibling, \"to equal\", \"This should be hidden\");\n    });\n  });\n\n  describe(\"sibling verifiction\", function () {\n    beforeEach(function () {\n      this.calls.push(\"before sibling\");\n    });\n\n    it(\"should not have value set within a sibling describe\", function () {\n      expect(\"This should be hidden\", \"not to equal\", this.hiddenFromSibling);\n      this.visibleFromTestSibling = \"Visible from test sibling\";\n    });\n\n    it(\"should allow test siblings to modify shared context\", function () {\n      expect(\n        \"Visible from test sibling\",\n        \"to equal\",\n        this.visibleFromTestSibling,\n      );\n    });\n\n    it(\"should have reset this.calls before describe\", function () {\n      expect(this.calls, \"to equal\", [\"before\", \"before sibling\"]);\n    });\n  });\n\n  after(function () {\n    expect(this.calls, \"to equal\", [\"before\", \"before sibling\"]);\n  });\n});\n\ndescribe(\"methods\", function () {\n  describe(\"timeout()\", function () {\n    it(\"should return the timeout\", function () {\n      // set this explicitly because browser and node use diff settings\n      this.timeout(1000);\n      expect(this.timeout(), \"to be\", 1000);\n    });\n  });\n\n  describe(\"slow()\", function () {\n    it(\"should return the slow\", function () {\n      expect(this.slow(), \"to be\", 75);\n    });\n  });\n\n  describe(\"retries\", function () {\n    it(\"should return the number of retries\", function () {\n      expect(this.retries(), \"to be\", -1);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/duration.spec.js",
    "content": "\"use strict\";\n\ndescribe(\"durations\", function () {\n  describe(\"when slow\", function () {\n    it(\"should highlight in red\", function (done) {\n      setTimeout(function () {\n        done();\n      }, 100);\n    });\n  });\n\n  describe(\"when reasonable\", function () {\n    it(\"should highlight in yellow\", function (done) {\n      setTimeout(function () {\n        done();\n      }, 50);\n    });\n  });\n\n  describe(\"when fast\", function () {\n    it(\"should not highlight\", function (done) {\n      setTimeout(function () {\n        done();\n      }, 10);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/errors.spec.js",
    "content": "\"use strict\";\n\nvar errors = require(\"../../lib/errors\");\nvar constants = require(\"../../lib/error-constants\");\nconst sinon = require(\"sinon\");\nconst { createNoFilesMatchPatternError } = require(\"../../lib/errors\");\n\ndescribe(\"Errors\", function () {\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  var message = \"some message\";\n\n  describe(\"createInvalidReporterError()\", function () {\n    it(\"should include expected code in thrown reporter errors\", function () {\n      expect(\n        errors.createInvalidReporterError(message, \"badReporter\"),\n        \"to satisfy\",\n        {\n          message,\n          code: \"ERR_MOCHA_INVALID_REPORTER\",\n          reporter: \"badReporter\",\n        },\n      );\n    });\n  });\n\n  describe(\"createInvalidInterfaceError()\", function () {\n    it(\"should include expected code in thrown interface errors\", function () {\n      expect(\n        errors.createInvalidInterfaceError(message, \"badUi\"),\n        \"to satisfy\",\n        {\n          message,\n          code: \"ERR_MOCHA_INVALID_INTERFACE\",\n          interface: \"badUi\",\n        },\n      );\n    });\n  });\n\n  describe(\"createForbiddenExclusivityError()\", function () {\n    describe(\"when Mocha instance is running in a worker process\", function () {\n      it(\"should output a message regarding incompatibility\", function () {\n        var mocha = { isWorker: true };\n        expect(\n          errors.createForbiddenExclusivityError(mocha, {}),\n          \"to satisfy\",\n          {\n            message: /parallel/,\n            code: constants.FORBIDDEN_EXCLUSIVITY,\n          },\n        );\n      });\n    });\n\n    describe(\"when Mocha instance is not running in a worker process\", function () {\n      it(\"should output a message regarding --forbid-only\", function () {\n        var mocha = {};\n        expect(\n          errors.createForbiddenExclusivityError(mocha, {}),\n          \"to satisfy\",\n          {\n            message: /--forbid-only/,\n            code: constants.FORBIDDEN_EXCLUSIVITY,\n          },\n        );\n      });\n    });\n  });\n\n  describe(\"createUnparsableFileError()\", function () {\n    it(\"should include expected code in thrown unparsable file errors\", function () {\n      expect(\n        errors.createUnparsableFileError(message, \"badFilePath\"),\n        \"to satisfy\",\n        {\n          message,\n          code: \"ERR_MOCHA_UNPARSABLE_FILE\",\n        },\n      );\n    });\n  });\n\n  describe(\"deprecate()\", function () {\n    var emitWarning;\n\n    beforeEach(function () {\n      if (process.emitWarning) {\n        emitWarning = process.emitWarning;\n        sinon.stub(process, \"emitWarning\");\n      } else {\n        process.emitWarning = sinon.spy();\n      }\n      errors.deprecate.cache = {};\n    });\n\n    afterEach(function () {\n      // if this is not set, then we created it, so we should remove it.\n      if (!emitWarning) {\n        delete process.emitWarning;\n      }\n    });\n\n    it(\"should coerce its parameter to a string\", function () {\n      errors.deprecate(1);\n      expect(process.emitWarning, \"to have a call satisfying\", [\n        \"1\",\n        \"DeprecationWarning\",\n      ]);\n    });\n\n    it(\"should cache the message\", function () {\n      errors.deprecate(\"foo\");\n      errors.deprecate(\"foo\");\n      expect(process.emitWarning, \"was called times\", 1);\n    });\n\n    it(\"should ignore falsy messages\", function () {\n      errors.deprecate(\"\");\n      expect(process.emitWarning, \"was not called\");\n    });\n  });\n\n  describe(\"warn()\", function () {\n    var emitWarning;\n\n    beforeEach(function () {\n      if (process.emitWarning) {\n        emitWarning = process.emitWarning;\n        sinon.stub(process, \"emitWarning\");\n      } else {\n        process.emitWarning = sinon.spy();\n      }\n    });\n\n    afterEach(function () {\n      // if this is not set, then we created it, so we should remove it.\n      if (!emitWarning) {\n        delete process.emitWarning;\n      }\n    });\n\n    it(\"should call process.emitWarning\", function () {\n      errors.warn(\"foo\");\n      expect(process.emitWarning, \"was called times\", 1);\n    });\n\n    it(\"should not cache messages\", function () {\n      errors.warn(\"foo\");\n      errors.warn(\"foo\");\n      expect(process.emitWarning, \"was called times\", 2);\n    });\n\n    it(\"should ignore falsy messages\", function () {\n      errors.warn(\"\");\n      expect(process.emitWarning, \"was not called\");\n    });\n  });\n\n  describe(\"isMochaError()\", function () {\n    describe(\"when provided an Error object having a known Mocha error code\", function () {\n      it(\"should return true\", function () {\n        expect(\n          errors.isMochaError(createNoFilesMatchPatternError(\"derp\")),\n          \"to be true\",\n        );\n      });\n    });\n\n    describe(\"when provided an Error object with a non-Mocha error code\", function () {\n      it(\"should return false\", function () {\n        const err = new Error();\n        err.code = \"ENOTEA\";\n        expect(errors.isMochaError(err), \"to be false\");\n      });\n    });\n\n    describe(\"when provided a non-error\", function () {\n      it(\"should return false\", function () {\n        expect(errors.isMochaError(), \"to be false\");\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/globals.spec.js",
    "content": "\"use strict\";\n\ndescribe(\"global leaks\", function () {\n  before(function () {\n    // uncomment to test\n    // foo = 'hey';\n    // bar = 'hey';\n  });\n\n  beforeEach(function () {\n    // uncomment to test\n    // foo = 'bar'\n  });\n\n  it(\"should cause tests to fail\", function () {\n    // uncomment to test\n    // foo = 'bar';\n    // bar = 'baz';\n    // baz = 'raz';\n  });\n\n  it(\"should pass when accepted\", function () {\n    global.okGlobalA = 1;\n    global.okGlobalB = 1;\n    global.okGlobalC = 1;\n  });\n\n  it(\"should pass with wildcard\", function () {\n    global.callback123 = \"foo\";\n    global.callback345 = \"bar\";\n  });\n\n  it('should pass when prefixed \"mocha-\"', function () {\n    // Opera and IE do this for HTML element IDs anyway\n    // but to sure we can assert this in any browser, simulate it.\n    global[\"mocha-example\"] = { nodeType: 1 };\n  });\n\n  afterEach(function () {\n    // uncomment to test\n    // foo = 'bar'\n  });\n});\n"
  },
  {
    "path": "test/unit/grep.spec.js",
    "content": "\"use strict\";\n\nvar Mocha = require(\"../../lib/mocha\");\n\ndescribe(\"Mocha\", function () {\n  describe('\"grep\" option', function () {\n    it(\"should add a RegExp to the mocha.options object\", function () {\n      var mocha = new Mocha({ grep: /foo.*/ });\n      expect(mocha.options.grep, \"to equal\", /foo.*/);\n    });\n\n    it(\"should convert string to a RegExp\", function () {\n      var mocha = new Mocha({ grep: \"foo.*\" });\n      expect(mocha.options.grep, \"to equal\", /foo.*/);\n    });\n  });\n\n  describe('\"fgrep\" option', function () {\n    it(\"should escape and convert string to a RegExp\", function () {\n      var mocha = new Mocha({ fgrep: \"foo.*\" });\n      expect(mocha.options.grep, \"to equal\", /foo\\.\\*/);\n    });\n  });\n\n  describe(\".grep()\", function () {\n    // Test helper\n    function testGrep(mocha) {\n      return function testGrep(grep, expected) {\n        mocha.grep(grep);\n        expect(String(mocha.options.grep), \"to be\", expected);\n      };\n    }\n\n    it(\"should add a RegExp to the mocha.options object\", function () {\n      var test = testGrep(new Mocha());\n      test(/foo/, \"/foo/\");\n    });\n\n    it(\"should convert grep string to a RegExp\", function () {\n      var test = testGrep(new Mocha());\n      test(\"foo\", \"/foo/\");\n      test(\"^foo.*bar$\", \"/^foo.*bar$/\");\n      test(\"^@.*(?=\\\\(\\\\)$)\", \"/^@.*(?=\\\\(\\\\)$)/\");\n    });\n\n    it(\"should covert grep regex-like string to a RegExp\", function () {\n      var test = testGrep(new Mocha());\n      test(\"/foo/\", \"/foo/\");\n      // Keep the flags\n      test(\"/baz/i\", \"/baz/i\");\n      test(\"/bar/g\", \"/bar/g\");\n      test(\"/^foo(.*)bar/g\", \"/^foo(.*)bar/g\");\n    });\n\n    it(\"should return its parent Mocha object for chainability\", function () {\n      var mocha = new Mocha();\n      expect(mocha.grep(), \"to be\", mocha);\n    });\n  });\n\n  describe('\"invert\" option', function () {\n    it(\"should add a Boolean to the mocha.options object\", function () {\n      var mocha = new Mocha({ invert: true });\n      expect(mocha.options.invert, \"to be\", true);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/hook-async.spec.js",
    "content": "\"use strict\";\n\ndescribe(\"async\", function () {\n  var calls = [];\n\n  before(function () {\n    calls.push(\"root before all\");\n  });\n\n  after(function () {\n    calls.push(\"root after all\");\n    expect(calls, \"to equal\", [\n      \"root before all\",\n      \"before all\",\n      \"parent before\",\n      \"before\",\n      \"before test one\",\n      \"one\",\n      \"after\",\n      \"after test one passed\",\n      \"parent after\",\n      \"parent before\",\n      \"before\",\n      \"before test two\",\n      \"two\",\n      \"after\",\n      \"after test two passed\",\n      \"parent after\",\n      \"parent before\",\n      \"before\",\n      \"before test three\",\n      \"three\",\n      \"after\",\n      \"after test three passed\",\n      \"parent after\",\n      \"after all\",\n      \"root after all\",\n    ]);\n  });\n\n  beforeEach(function () {\n    calls.push(\"parent before\");\n  });\n\n  afterEach(function () {\n    calls.push(\"parent after\");\n  });\n\n  describe(\"hooks\", function () {\n    before(function () {\n      calls.push(\"before all\");\n    });\n\n    after(function () {\n      calls.push(\"after all\");\n    });\n\n    beforeEach(function (done) {\n      var ctx = this;\n      process.nextTick(function () {\n        calls.push(\"before\");\n        if (ctx.currentTest) {\n          calls.push(\"before test \" + ctx.currentTest.title);\n        }\n        done();\n      });\n    });\n\n    it(\"one\", function (done) {\n      expect(calls, \"to equal\", [\n        \"root before all\",\n        \"before all\",\n        \"parent before\",\n        \"before\",\n        \"before test one\",\n      ]);\n      calls.push(\"one\");\n      process.nextTick(done);\n    });\n\n    it(\"two\", function () {\n      expect(calls, \"to equal\", [\n        \"root before all\",\n        \"before all\",\n        \"parent before\",\n        \"before\",\n        \"before test one\",\n        \"one\",\n        \"after\",\n        \"after test one passed\",\n        \"parent after\",\n        \"parent before\",\n        \"before\",\n        \"before test two\",\n      ]);\n      calls.push(\"two\");\n    });\n\n    it(\"three\", function () {\n      expect(calls, \"to equal\", [\n        \"root before all\",\n        \"before all\",\n        \"parent before\",\n        \"before\",\n        \"before test one\",\n        \"one\",\n        \"after\",\n        \"after test one passed\",\n        \"parent after\",\n        \"parent before\",\n        \"before\",\n        \"before test two\",\n        \"two\",\n        \"after\",\n        \"after test two passed\",\n        \"parent after\",\n        \"parent before\",\n        \"before\",\n        \"before test three\",\n      ]);\n      calls.push(\"three\");\n    });\n\n    afterEach(function (done) {\n      var ctx = this;\n      process.nextTick(function () {\n        calls.push(\"after\");\n        if (ctx.currentTest) {\n          calls.push(\n            \"after test \" + ctx.currentTest.title + \" \" + ctx.currentTest.state,\n          );\n        }\n        done();\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/hook-sync-nested.spec.js",
    "content": "\"use strict\";\n\ndescribe(\"serial\", function () {\n  describe(\"nested\", function () {\n    var calls = [];\n\n    beforeEach(function () {\n      calls.push(\"parent before\");\n      if (this.currentTest) {\n        calls.push(\"parent before test \" + this.currentTest.title);\n      }\n    });\n\n    afterEach(function () {\n      calls.push(\"parent after\");\n      if (this.currentTest) {\n        calls.push(\n          \"parent after test \" +\n            this.currentTest.title +\n            \" \" +\n            this.currentTest.state,\n        );\n      }\n    });\n\n    it(\"foo\", function () {\n      expect(calls, \"to equal\", [\"parent before\", \"parent before test foo\"]);\n      calls.push(\"foo\");\n    });\n\n    it(\"bar\", function () {\n      expect(calls, \"to equal\", [\n        \"parent before\",\n        \"parent before test foo\",\n        \"foo\",\n        \"parent after\",\n        \"parent after test foo passed\",\n        \"parent before\",\n        \"parent before test bar\",\n      ]);\n    });\n\n    describe(\"hooks\", function () {\n      beforeEach(function () {\n        calls.push(\"before\");\n        if (this.currentTest) {\n          calls.push(\"before test \" + this.currentTest.title);\n        }\n      });\n\n      it(\"one\", function () {\n        expect(calls, \"to equal\", [\n          \"parent before\",\n          \"parent before test foo\",\n          \"foo\",\n          \"parent after\",\n          \"parent after test foo passed\",\n          \"parent before\",\n          \"parent before test bar\",\n          \"parent after\",\n          \"parent after test bar passed\",\n          \"parent before\",\n          \"parent before test one\",\n          \"before\",\n          \"before test one\",\n        ]);\n        calls.push(\"one\");\n      });\n\n      it(\"two\", function () {\n        expect(calls, \"to equal\", [\n          \"parent before\",\n          \"parent before test foo\",\n          \"foo\",\n          \"parent after\",\n          \"parent after test foo passed\",\n          \"parent before\",\n          \"parent before test bar\",\n          \"parent after\",\n          \"parent after test bar passed\",\n          \"parent before\",\n          \"parent before test one\",\n          \"before\",\n          \"before test one\",\n          \"one\",\n          \"after\",\n          \"after test one passed\",\n          \"parent after\",\n          \"parent after test one passed\",\n          \"parent before\",\n          \"parent before test two\",\n          \"before\",\n          \"before test two\",\n        ]);\n        calls.push(\"two\");\n      });\n\n      afterEach(function () {\n        calls.push(\"after\");\n        if (this.currentTest) {\n          calls.push(\n            \"after test \" +\n              this.currentTest.title +\n              \" \" +\n              this.currentTest.state,\n          );\n        }\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/hook-sync.spec.js",
    "content": "\"use strict\";\n\ndescribe(\"serial\", function () {\n  var calls = [];\n\n  beforeEach(function () {\n    calls.push(\"parent before\");\n  });\n\n  afterEach(function () {\n    calls.push(\"parent after\");\n  });\n\n  describe(\"hooks\", function () {\n    beforeEach(function () {\n      calls.push(\"before\");\n      if (this.currentTest) {\n        calls.push(\"before test \" + this.currentTest.title);\n      }\n    });\n\n    it(\"one\", function () {\n      expect(calls, \"to equal\", [\"parent before\", \"before\", \"before test one\"]);\n      calls.push(\"one\");\n    });\n\n    it(\"two\", function () {\n      expect(calls, \"to equal\", [\n        \"parent before\",\n        \"before\",\n        \"before test one\",\n        \"one\",\n        \"after\",\n        \"after test one passed\",\n        \"parent after\",\n        \"parent before\",\n        \"before\",\n        \"before test two\",\n      ]);\n      calls.push(\"two\");\n    });\n\n    it(\"three\", function () {\n      expect(calls, \"to equal\", [\n        \"parent before\",\n        \"before\",\n        \"before test one\",\n        \"one\",\n        \"after\",\n        \"after test one passed\",\n        \"parent after\",\n        \"parent before\",\n        \"before\",\n        \"before test two\",\n        \"two\",\n        \"after\",\n        \"after test two passed\",\n        \"parent after\",\n        \"parent before\",\n        \"before\",\n        \"before test three\",\n      ]);\n      calls.push(\"three\");\n    });\n\n    afterEach(function () {\n      calls.push(\"after\");\n      if (this.currentTest) {\n        calls.push(\n          \"after test \" + this.currentTest.title + \" \" + this.currentTest.state,\n        );\n      }\n    });\n\n    after(function () {\n      expect(calls, \"to equal\", [\n        \"parent before\",\n        \"before\",\n        \"before test one\",\n        \"one\",\n        \"after\",\n        \"after test one passed\",\n        \"parent after\",\n        \"parent before\",\n        \"before\",\n        \"before test two\",\n        \"two\",\n        \"after\",\n        \"after test two passed\",\n        \"parent after\",\n        \"parent before\",\n        \"before\",\n        \"before test three\",\n        \"three\",\n        \"after\",\n        \"after test three passed\",\n        \"parent after\",\n      ]);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/hook-timeout.spec.js",
    "content": "\"use strict\";\n\ndescribe(\"hook timeout\", function () {\n  before(function (done) {\n    setTimeout(done, 100);\n  });\n\n  it(\"should work\", function (done) {\n    done();\n  });\n});\n"
  },
  {
    "path": "test/unit/hook.spec.js",
    "content": "\"use strict\";\nvar sinon = require(\"sinon\");\nvar Mocha = require(\"../../lib/mocha\");\nvar Hook = Mocha.Hook;\nvar Runnable = Mocha.Runnable;\n\ndescribe(\"Hook\", function () {\n  var hook;\n\n  beforeEach(function () {\n    hook = new Hook(\"Some hook\", function () {});\n  });\n\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"error\", function () {\n    it(\"should set the hook._error\", function () {\n      var expectedError = new Error(\"Expected error\");\n      hook.error(expectedError);\n      expect(hook._error, \"to be\", expectedError);\n    });\n    it(\"should get the hook._error when called without arguments\", function () {\n      var expectedError = new Error(\"Expected error\");\n      hook._error = expectedError;\n      expect(hook.error(), \"to be\", expectedError);\n    });\n  });\n\n  describe(\"reset\", function () {\n    it(\"should call Runnable.reset\", function () {\n      var runnableResetStub = sinon.stub(Runnable.prototype, \"reset\");\n      hook.reset();\n      expect(runnableResetStub, \"was called once\");\n    });\n\n    it(\"should reset the error state\", function () {\n      hook.error(new Error(\"Expected error for test\"));\n      hook.reset();\n      expect(hook.error(), \"to be undefined\");\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/mocha.spec.js",
    "content": "\"use strict\";\n\nvar sinon = require(\"sinon\");\nvar EventEmitter = require(\"node:events\").EventEmitter;\nvar Mocha = require(\"../../lib/mocha\");\nvar utils = require(\"../../lib/utils\");\nconst errors = require(\"../../lib/errors\");\n\ndescribe(\"Mocha\", function () {\n  /**\n   * Options for `Mocha` constructor\n   */\n  var opts;\n\n  /**\n   * Stub `Runner` constructor; returns a stubbed `EventEmitter`\n   */\n  var Runner;\n\n  /**\n   * Stub `Suite` constructor; returns a stubbed `EventEmitter`\n   */\n  var Suite;\n\n  /**\n   * Stub `Suite` instance (root suite in our case)\n   */\n  var suite;\n\n  /**\n   * Stub `Runner` (`EventEmitter`) instance\n   */\n  var runner;\n\n  /**\n   * Stub `Base` reporter constructor\n   */\n  var Base;\n\n  /**\n   * Instance of a hypothetical reporter\n   */\n  var reporterInstance;\n\n  beforeEach(function () {\n    reporterInstance = {};\n    opts = { reporter: sinon.stub().returns(reporterInstance) };\n\n    // NOTE: calling `stub(someObject, someFunction)` where `someFunction` has\n    // its own static properties WILL NOT blast those static properties!\n    Base = sinon.stub(Mocha.reporters, \"Base\").returns({});\n    sinon.stub(Mocha.reporters, \"base\").returns({});\n    sinon.stub(Mocha.reporters, \"spec\").returns({});\n\n    runner = {\n      ...sinon.createStubInstance(EventEmitter),\n      runAsync: sinon.stub().resolves(0),\n      globals: sinon.stub(),\n      grep: sinon.stub(),\n      dispose: sinon.stub(),\n    };\n    Runner = sinon.stub(Mocha, \"Runner\").returns(runner);\n    // the Runner constructor is the main export, and constants is a static prop.\n    // we don't need the constants themselves, but the object cannot be undefined\n    Runner.constants = {};\n    suite = {\n      ...sinon.createStubInstance(EventEmitter),\n      slow: sinon.stub(),\n      timeout: sinon.stub(),\n      bail: sinon.stub(),\n      dispose: sinon.stub(),\n      reset: sinon.stub(),\n      beforeAll: sinon.stub(),\n      beforeEach: sinon.stub(),\n      afterAll: sinon.stub(),\n      afterEach: sinon.stub(),\n    };\n    Suite = sinon.stub(Mocha, \"Suite\").returns(suite);\n    Suite.constants = {};\n\n    sinon.stub(errors, \"warn\");\n    sinon.stub(utils, \"isString\");\n    sinon.stub(utils, \"noop\");\n  });\n\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"constructor\", function () {\n    var mocha;\n\n    beforeEach(function () {\n      mocha = sinon.createStubInstance(Mocha);\n      mocha.timeout.returnsThis();\n      mocha.retries.returnsThis();\n      sinon.stub(Mocha.prototype, \"timeout\").returnsThis();\n      sinon.stub(Mocha.prototype, \"global\").returnsThis();\n      sinon.stub(Mocha.prototype, \"retries\").returnsThis();\n      sinon.stub(Mocha.prototype, \"rootHooks\").returnsThis();\n      sinon.stub(Mocha.prototype, \"parallelMode\").returnsThis();\n      sinon.stub(Mocha.prototype, \"globalSetup\").returnsThis();\n      sinon.stub(Mocha.prototype, \"globalTeardown\").returnsThis();\n      sinon.stub(Mocha.prototype, \"enableGlobalSetup\").returnsThis();\n      sinon.stub(Mocha.prototype, \"enableGlobalTeardown\").returnsThis();\n    });\n\n    it(\"should set _cleanReferencesAfterRun to true\", function () {\n      expect(new Mocha()._cleanReferencesAfterRun, \"to be\", true);\n    });\n\n    describe(\"when `timeout` option is `undefined`\", function () {\n      it(\"should not attempt to set timeout\", function () {\n        new Mocha({ timeout: undefined });\n        expect(Mocha.prototype.timeout, \"was not called\");\n      });\n    });\n\n    describe(\"when `timeout` option is `false`\", function () {\n      it(\"should attempt to set timeout\", function () {\n        new Mocha({ timeout: false });\n        expect(Mocha.prototype.timeout, \"to have a call satisfying\", [0]).and(\n          \"was called once\",\n        );\n      });\n    });\n\n    describe(\"when `global` option is an `Array`\", function () {\n      it(\"should attempt to set globals\", function () {\n        new Mocha({ global: [\"singular\"] });\n        expect(Mocha.prototype.global, \"to have a call satisfying\", [\n          [\"singular\"],\n        ]).and(\"was called once\");\n      });\n    });\n\n    describe(\"when `retries` option is present\", function () {\n      it(\"should attempt to set retries`\", function () {\n        new Mocha({ retries: 1 });\n        expect(Mocha.prototype.retries, \"to have a call satisfying\", [1]).and(\n          \"was called once\",\n        );\n      });\n    });\n\n    describe(\"when `retries` option is not present\", function () {\n      it(\"should not attempt to set retries\", function () {\n        new Mocha({});\n        expect(Mocha.prototype.retries, \"was not called\");\n      });\n    });\n\n    describe(\"when `rootHooks` option is truthy\", function () {\n      it(\"shouid attempt to set root hooks\", function () {\n        new Mocha({ rootHooks: [\"a root hook\"] });\n        expect(Mocha.prototype.rootHooks, \"to have a call satisfying\", [\n          [\"a root hook\"],\n        ]).and(\"was called once\");\n      });\n    });\n\n    describe(\"when `parallel` option is true\", function () {\n      describe(\"and `jobs` option > 1\", function () {\n        it(\"should enable parallel mode\", function () {\n          new Mocha({ parallel: true, jobs: 2 });\n          expect(Mocha.prototype.parallelMode, \"to have a call satisfying\", [\n            true,\n          ]).and(\"was called once\");\n        });\n      });\n\n      describe(\"and `jobs` option <= 1\", function () {\n        it(\"should not enable parallel mode\", function () {\n          new Mocha({ parallel: true, jobs: 1 });\n          expect(Mocha.prototype.parallelMode, \"was not called\");\n        });\n      });\n\n      describe(\"when `globalSetup` option is present\", function () {\n        it(\"should configure global setup fixtures\", function () {\n          const globalSetup = [() => {}];\n          const mocha = new Mocha({ globalSetup });\n          expect(mocha.globalSetup, \"to have a call satisfying\", [\n            globalSetup,\n          ]).and(\"was called once\");\n        });\n      });\n\n      describe(\"when `globalTeardown` option is present\", function () {\n        it(\"should configure global teardown fixtures\", function () {\n          const globalTeardown = [() => {}];\n          const mocha = new Mocha({ globalTeardown });\n          expect(mocha.globalTeardown, \"to have a call satisfying\", [\n            globalTeardown,\n          ]).and(\"was called once\");\n        });\n      });\n\n      describe(\"when `enableGlobalSetup` option is present\", function () {\n        it(\"should toggle global setup fixtures\", function () {\n          const mocha = new Mocha({ enableGlobalSetup: 1 });\n          expect(mocha.enableGlobalSetup, \"to have a call satisfying\", [1]).and(\n            \"was called once\",\n          );\n        });\n      });\n\n      describe(\"when `enableGlobalTeardown` option is present\", function () {\n        it(\"should configure global teardown fixtures\", function () {\n          const mocha = new Mocha({ enableGlobalTeardown: 1 });\n          expect(\n            mocha.enableGlobalTeardown,\n            \"to have a call satisfying\",\n            [1],\n          ).and(\"was called once\");\n        });\n      });\n    });\n  });\n\n  describe(\"instance method\", function () {\n    var mocha;\n\n    beforeEach(function () {\n      mocha = new Mocha(opts);\n    });\n\n    describe(\"allowUncaught()\", function () {\n      it(\"should set the allowUncaught option to true\", function () {\n        mocha.allowUncaught();\n        expect(mocha.options, \"to have property\", \"allowUncaught\", true);\n      });\n\n      it(\"should set the allowUncaught option to false\", function () {\n        mocha.allowUncaught(false);\n        expect(mocha.options, \"to have property\", \"allowUncaught\", false);\n      });\n\n      it(\"should be chainable\", function () {\n        expect(mocha.allowUncaught(), \"to be\", mocha);\n      });\n    });\n\n    describe(\"asyncOnly()\", function () {\n      it(\"should set the asyncOnly option to true\", function () {\n        mocha.asyncOnly();\n        expect(mocha.options, \"to have property\", \"asyncOnly\", true);\n      });\n\n      it(\"should set the asyncOnly option to false\", function () {\n        mocha.asyncOnly(false);\n        expect(mocha.options, \"to have property\", \"asyncOnly\", false);\n      });\n\n      it(\"should be chainable\", function () {\n        expect(mocha.asyncOnly(), \"to be\", mocha);\n      });\n    });\n\n    describe(\"bail()\", function () {\n      it('should set the \"bail\" flag on the root suite', function () {\n        mocha.bail();\n        expect(suite.bail, \"to have a call satisfying\", [true]).and(\n          \"was called once\",\n        );\n      });\n\n      it('should unset the \"bail\" flag on the root suite', function () {\n        mocha.bail(false);\n        expect(suite.bail, \"to have a call satisfying\", [false]).and(\n          \"was called once\",\n        );\n      });\n\n      it(\"should be chainable\", function () {\n        expect(mocha.bail(), \"to be\", mocha);\n      });\n    });\n\n    describe(\"checkLeaks()\", function () {\n      it(\"should set the checkLeaks option to true\", function () {\n        mocha.checkLeaks();\n        expect(mocha.options, \"to have property\", \"checkLeaks\", true);\n      });\n    });\n\n    describe(\"cleanReferencesAfterRun()\", function () {\n      it(\"should set the _cleanReferencesAfterRun attribute\", function () {\n        mocha.cleanReferencesAfterRun();\n        expect(mocha._cleanReferencesAfterRun, \"to be\", true);\n      });\n\n      it(\"should set the _cleanReferencesAfterRun attribute to false\", function () {\n        mocha.cleanReferencesAfterRun(false);\n        expect(mocha._cleanReferencesAfterRun, \"to be\", false);\n      });\n\n      it(\"should be chainable\", function () {\n        expect(mocha.cleanReferencesAfterRun(), \"to be\", mocha);\n      });\n    });\n\n    describe(\"color()\", function () {\n      it(\"should set the color option to true\", function () {\n        mocha.color();\n        expect(mocha.options, \"to have property\", \"color\", true);\n      });\n\n      it(\"should set the color option to false\", function () {\n        mocha.color(false);\n        expect(mocha.options, \"to have property\", \"color\", false);\n      });\n\n      it(\"should be chainable\", function () {\n        expect(mocha.color(), \"to be\", mocha);\n      });\n    });\n\n    describe(\"delay()\", function () {\n      it(\"should set the delay option to true\", function () {\n        mocha.delay();\n        expect(mocha.options, \"to have property\", \"delay\", true);\n      });\n\n      it(\"should be chainable\", function () {\n        expect(mocha.delay(), \"to be\", mocha);\n      });\n    });\n\n    describe(\"diff()\", function () {\n      it(\"should set the diff option to true\", function () {\n        mocha.diff();\n        expect(mocha.options, \"to have property\", \"diff\", true);\n      });\n\n      it(\"should set the diff option to false\", function () {\n        mocha.diff(false);\n        expect(mocha.options, \"to have property\", \"diff\", false);\n      });\n    });\n\n    describe(\"dispose()\", function () {\n      it(\"should dispose the root suite\", function () {\n        mocha.dispose();\n        expect(suite.dispose, \"was called once\");\n      });\n\n      it(\"should dispose previous test runner\", function () {\n        mocha._previousRunner = runner;\n        mocha.dispose();\n        expect(runner.dispose, \"was called once\");\n      });\n\n      it(\"should unload the files\", function () {\n        var unloadFilesStub = sinon.stub(mocha, \"unloadFiles\");\n        mocha.dispose();\n        expect(unloadFilesStub, \"was called once\");\n      });\n    });\n\n    describe(\"dryRun()\", function () {\n      it(\"should set the dryRun option to true\", function () {\n        mocha.dryRun();\n        expect(mocha.options, \"to have property\", \"dryRun\", true);\n      });\n\n      it(\"should set the dryRun option to false\", function () {\n        mocha.dryRun(false);\n        expect(mocha.options, \"to have property\", \"dryRun\", false);\n      });\n    });\n\n    describe(\"passOnFailingTestSuite()\", function () {\n      it(\"should set the passOnFailingTestSuite option to false\", function () {\n        mocha.passOnFailingTestSuite();\n        expect(\n          mocha.options,\n          \"to have property\",\n          \"passOnFailingTestSuite\",\n          false,\n        );\n      });\n\n      it(\"should set the passOnFailingTestSuite option to true\", function () {\n        mocha.passOnFailingTestSuite(true);\n        expect(\n          mocha.options,\n          \"to have property\",\n          \"passOnFailingTestSuite\",\n          true,\n        );\n      });\n    });\n\n    describe(\"failZero()\", function () {\n      it(\"should set the failZero option to true\", function () {\n        mocha.failZero();\n        expect(mocha.options, \"to have property\", \"failZero\", true);\n      });\n\n      it(\"should set the failZero option to false\", function () {\n        mocha.failZero(false);\n        expect(mocha.options, \"to have property\", \"failZero\", false);\n      });\n    });\n\n    describe(\"forbidOnly()\", function () {\n      it(\"should set the forbidOnly option to true\", function () {\n        mocha.forbidOnly();\n        expect(mocha.options, \"to have property\", \"forbidOnly\", true);\n      });\n\n      it(\"should set the forbidOnly option to false\", function () {\n        mocha.forbidOnly(false);\n        expect(mocha.options, \"to have property\", \"forbidOnly\", false);\n      });\n\n      it(\"should be chainable\", function () {\n        expect(mocha.forbidOnly(), \"to be\", mocha);\n      });\n    });\n\n    describe(\"forbidPending()\", function () {\n      it(\"should set the forbidPending option to true\", function () {\n        mocha.forbidPending();\n        expect(mocha.options, \"to have property\", \"forbidPending\", true);\n      });\n\n      it(\"should set the forbidPending option to false\", function () {\n        mocha.forbidPending(false);\n        expect(mocha.options, \"to have property\", \"forbidPending\", false);\n      });\n\n      it(\"should be chainable\", function () {\n        expect(mocha.forbidPending(), \"to be\", mocha);\n      });\n    });\n\n    describe(\"fullTrace()\", function () {\n      it(\"should set the fullTrace option to true\", function () {\n        mocha.fullTrace();\n        expect(mocha.options, \"to have property\", \"fullTrace\", true);\n      });\n\n      it(\"should set the fullTrace option to false\", function () {\n        mocha.fullTrace(false);\n        expect(mocha.options, \"to have property\", \"fullTrace\", false);\n      });\n\n      it(\"should be chainable\", function () {\n        expect(mocha.fullTrace(), \"to be\", mocha);\n      });\n    });\n\n    describe(\"global()\", function () {\n      it(\"should be an empty array initially\", function () {\n        expect(mocha.options.global, \"to be empty\");\n      });\n\n      it(\"should be chainable\", function () {\n        expect(mocha.global(), \"to be\", mocha);\n      });\n\n      describe(\"when argument is invalid\", function () {\n        it(\"should not modify the whitelist when given empty string\", function () {\n          mocha.global(\"\");\n          expect(mocha.options.global, \"to be empty\");\n        });\n\n        it(\"should not modify the whitelist when given empty array\", function () {\n          mocha.global([]);\n          expect(mocha.options.global, \"to be empty\");\n        });\n      });\n\n      describe(\"when argument is valid\", function () {\n        var elem = \"foo\";\n        var elem2 = \"bar\";\n        var elem3 = \"baz\";\n\n        it(\"should add string to the whitelist\", function () {\n          mocha.global(elem);\n          expect(mocha.options.global, \"to contain\", elem);\n          expect(mocha.options.global, \"to have length\", 1);\n        });\n\n        it(\"should add contents of string array to the whitelist\", function () {\n          var elems = [elem, elem2];\n          mocha.global(elems);\n          expect(mocha.options.global, \"to contain\", elem, elem2);\n          expect(mocha.options.global, \"to have length\", elems.length);\n        });\n\n        it(\"should not have duplicates\", function () {\n          var mocha = new Mocha({ global: [elem, elem2] });\n          var elems = [elem, elem2, elem3];\n          mocha.global(elems);\n          expect(mocha.options.global, \"to contain\", elem, elem2, elem3);\n          expect(mocha.options.global, \"to have length\", elems.length);\n        });\n      });\n    });\n\n    describe(\"inlineDiffs()\", function () {\n      it(\"should set the inlineDiffs option to true\", function () {\n        mocha.inlineDiffs();\n        expect(mocha.options, \"to have property\", \"inlineDiffs\", true);\n      });\n\n      it(\"should set the inlineDiffs option to false\", function () {\n        mocha.inlineDiffs(false);\n        expect(mocha.options, \"to have property\", \"inlineDiffs\", false);\n      });\n\n      it(\"should be chainable\", function () {\n        expect(mocha.inlineDiffs(), \"to be\", mocha);\n      });\n    });\n\n    describe(\"invert()\", function () {\n      it(\"should set the invert option to true\", function () {\n        mocha.invert();\n        expect(mocha.options, \"to have property\", \"invert\", true);\n      });\n\n      it(\"should be chainable\", function () {\n        expect(mocha.invert(), \"to be\", mocha);\n      });\n    });\n\n    describe(\"noHighlighting()\", function () {\n      // :NOTE: Browser-only option...\n      it(\"should set the noHighlighting option to true\", function () {\n        mocha.noHighlighting();\n        expect(mocha.options, \"to have property\", \"noHighlighting\", true);\n      });\n\n      it(\"should be chainable\", function () {\n        expect(mocha.noHighlighting(), \"to be\", mocha);\n      });\n    });\n\n    describe(\"reporter()\", function () {\n      it(\"should be chainable\", function () {\n        expect(mocha.reporter(), \"to be\", mocha);\n      });\n\n      it(\"should keep reporterOption on options\", function () {\n        var mocha = new Mocha({\n          reporter: \"spec\",\n          reporterOption: {\n            foo: \"bar\",\n          },\n        });\n        expect(mocha.options.reporterOption, \"to have property\", \"foo\", \"bar\");\n        // To support the legacy property name that can be used by reporters\n        expect(mocha.options.reporterOptions, \"to have property\", \"foo\", \"bar\");\n      });\n\n      it(\"should support legacy reporterOptions\", function () {\n        var mocha = new Mocha({\n          reporter: \"spec\",\n          reporterOptions: {\n            foo: \"bar\",\n          },\n        });\n        expect(mocha.options.reporterOption, \"to have property\", \"foo\", \"bar\");\n        // To support the legacy property name that can be used by reporters\n        expect(mocha.options.reporterOptions, \"to have property\", \"foo\", \"bar\");\n      });\n    });\n\n    describe(\"run()\", function () {\n      let globalFixtureContext;\n\n      beforeEach(function () {\n        globalFixtureContext = {};\n        sinon.stub(mocha, \"runGlobalSetup\").returns(globalFixtureContext);\n        sinon.stub(mocha, \"runGlobalTeardown\").returns(globalFixtureContext);\n      });\n\n      describe(\"when files have been added to the Mocha instance\", function () {\n        beforeEach(function () {\n          sinon.stub(mocha, \"loadFiles\");\n          mocha.addFile(\"some-file.js\");\n        });\n\n        describe(\"when Mocha is set to eagerly load files\", function () {\n          it(\"should eagerly load files\", function (done) {\n            mocha.run(function () {\n              expect(mocha.loadFiles, \"was called once\");\n              done();\n            });\n          });\n        });\n\n        describe(\"when Mocha is set to lazily load files\", function () {\n          beforeEach(function () {\n            mocha.lazyLoadFiles(true);\n          });\n\n          it(\"should not eagerly load files\", function (done) {\n            mocha.run(function () {\n              expect(mocha.loadFiles, \"was not called\");\n              done();\n            });\n          });\n        });\n      });\n\n      describe(\"Runner initialization\", function () {\n        it(\"should instantiate a Runner\", function (done) {\n          mocha.run(function () {\n            expect(Runner, \"to have a call satisfying\", {\n              calledWithNew: true,\n              args: [\n                mocha.suite,\n                {\n                  delay: mocha.options.delay,\n                  cleanReferencesAfterRun:\n                    mocha.options.cleanReferencesAfterRun,\n                },\n              ],\n            }).and(\"was called once\");\n            done();\n          });\n        });\n\n        describe('when \"grep\" option is present', function () {\n          beforeEach(function () {\n            mocha.options.grep = /foo/;\n            mocha.options.invert = false;\n          });\n\n          it('should configure \"grep\"', function (done) {\n            mocha.run(function () {\n              expect(runner.grep, \"to have a call satisfying\", [\n                mocha.options.grep,\n                mocha.options.invert,\n              ]).and(\"was called once\");\n              done();\n            });\n          });\n        });\n\n        describe('when \"global\" option is present', function () {\n          beforeEach(function () {\n            mocha.options.global = [\"foo\", \"bar\"];\n          });\n\n          it(\"should configure global vars\", function (done) {\n            mocha.run(function () {\n              expect(runner.globals, \"to have a call satisfying\", [\n                mocha.options.global,\n              ]).and(\"was called once\");\n              done();\n            });\n          });\n        });\n      });\n\n      describe(\"Base reporter initialization\", function () {\n        beforeEach(function () {\n          mocha.options.inlineDiffs = \"some value\";\n          mocha.options.diff = false;\n        });\n\n        describe('when \"color\" options is set', function () {\n          beforeEach(function () {\n            mocha.options.color = \"truthy\";\n          });\n\n          it(\"should configure the Base reporter\", function (done) {\n            mocha.run(function () {\n              expect(Base, \"to satisfy\", {\n                inlineDiffs: \"some value\",\n                hideDiff: true,\n                useColors: \"truthy\",\n              });\n              done();\n            });\n          });\n        });\n\n        it(\"should configure the Base reporter\", function (done) {\n          mocha.run(function () {\n            expect(Base, \"to satisfy\", {\n              inlineDiffs: \"some value\",\n              hideDiff: true,\n            });\n            done();\n          });\n        });\n      });\n\n      it(\"should instantiate a reporter\", function (done) {\n        mocha.run(function () {\n          expect(opts.reporter, \"to have a call satisfying\", {\n            calledWithNew: true,\n            args: [runner, mocha.options],\n          }).and(\"was called once\");\n          done();\n        });\n      });\n\n      // TODO: figure out how to stub the stats collector\n      it(\"should initialize the stats collector\");\n\n      describe('when a reporter instance has a \"done\" method', function () {\n        beforeEach(function () {\n          reporterInstance.done = sinon.stub().callsArgAsync(1);\n        });\n\n        it('should call the reporter \"done\" method', function (done) {\n          mocha.run(function () {\n            expect(reporterInstance.done, \"was called once\");\n            done();\n          });\n        });\n      });\n\n      it(\"should execute the callback when complete\", function (done) {\n        mocha.run(done);\n      });\n\n      describe(\"when a run is in progress\", function () {\n        it(\"should throw\", function (done) {\n          mocha.run(done); // this is async!\n          expect(\n            function () {\n              mocha.run();\n            },\n            \"to throw\",\n            {\n              code: \"ERR_MOCHA_INSTANCE_ALREADY_RUNNING\",\n              instance: mocha,\n            },\n          );\n        });\n\n        it(\"should not call `Runner#runAsync`\", function (done) {\n          mocha.run(done); // this is async!\n          try {\n            mocha.run();\n          } catch {\n            // Ignore error\n          } finally {\n            // it'll be 0 or 1, depending on timing.\n            expect(runner.runAsync.callCount, \"to be less than\", 2);\n          }\n        });\n      });\n\n      describe(\"when the `Mocha` instance is already disposed\", function () {\n        beforeEach(function () {\n          mocha.dispose();\n        });\n\n        it(\"should throw\", function () {\n          expect(\n            function () {\n              mocha.run();\n            },\n            \"to throw\",\n            {\n              code: \"ERR_MOCHA_INSTANCE_ALREADY_DISPOSED\",\n              cleanReferencesAfterRun: true,\n              instance: mocha,\n            },\n          );\n        });\n\n        it(\"should not call `Runner#runAsync`\", function () {\n          try {\n            mocha.run();\n          } catch {\n            // Ignore error\n          } finally {\n            expect(runner.runAsync, \"was not called\");\n          }\n        });\n      });\n\n      describe(\"when a run has finished and is called again\", function () {\n        beforeEach(function (done) {\n          mocha.run(function () {\n            runner.runAsync.reset();\n            done();\n          });\n        });\n\n        it(\"should throw\", function () {\n          expect(\n            function () {\n              mocha.run();\n            },\n            \"to throw\",\n            {\n              code: \"ERR_MOCHA_INSTANCE_ALREADY_DISPOSED\",\n              instance: mocha,\n            },\n          );\n        });\n\n        it(\"should not call `Runner#runAsync()`\", function () {\n          try {\n            mocha.run();\n          } catch {\n            // Ignore error\n          } finally {\n            expect(runner.runAsync, \"was not called\");\n          }\n        });\n      });\n\n      describe(\"when Mocha configured for multiple runs and multiple runs are attempted\", function () {\n        beforeEach(function () {\n          mocha.cleanReferencesAfterRun(false);\n        });\n\n        it(\"should not throw\", function (done) {\n          mocha.run(function () {\n            mocha.run(done);\n          });\n        });\n\n        it(\"should call `Runner#runAsync` for each call\", function (done) {\n          mocha.run(function () {\n            mocha.run(function () {\n              expect(runner.runAsync, \"was called twice\");\n              done();\n            });\n          });\n        });\n\n        it(\"should reset the root Suite between runs\", function (done) {\n          mocha.run(function () {\n            mocha.run(function () {\n              expect(suite.reset, \"was called once\");\n              done();\n            });\n          });\n        });\n\n        it(\"should dispose the previous runner\", function (done) {\n          mocha.run(function () {\n            mocha.run(function () {\n              expect(runner.dispose, \"was called once\");\n              done();\n            });\n          });\n        });\n      });\n\n      describe(\"when global setup fixtures enabled\", function () {\n        beforeEach(function () {\n          mocha.options.enableGlobalSetup = true;\n        });\n        describe(\"when global setup fixtures not present\", function () {\n          beforeEach(function () {\n            sinon.stub(mocha, \"hasGlobalSetupFixtures\").returns(false);\n          });\n\n          it(\"should not run global setup fixtures\", function (done) {\n            mocha.run(() => {\n              expect(mocha.runGlobalSetup, \"was not called\");\n              done();\n            });\n          });\n        });\n\n        describe(\"when global setup fixtures are present\", function () {\n          beforeEach(function () {\n            sinon.stub(mocha, \"hasGlobalSetupFixtures\").returns(true);\n          });\n\n          it(\"should run global setup fixtures\", function (done) {\n            mocha.run(() => {\n              expect(mocha.runGlobalSetup, \"to have a call satisfying\", {\n                args: [expect.it(\"to be\", runner)],\n              }).and(\"was called once\");\n              done();\n            });\n          });\n        });\n      });\n\n      describe(\"when global setup fixtures disabled\", function () {\n        beforeEach(function () {\n          mocha.options.enableGlobalSetup = false;\n        });\n        describe(\"when global setup fixtures not present\", function () {\n          beforeEach(function () {\n            sinon.stub(mocha, \"hasGlobalSetupFixtures\").returns(false);\n          });\n\n          it(\"should not run global setup fixtures\", function (done) {\n            mocha.run(() => {\n              expect(mocha.runGlobalSetup, \"was not called\");\n              done();\n            });\n          });\n        });\n\n        describe(\"when global setup fixtures are present\", function () {\n          beforeEach(function () {\n            sinon.stub(mocha, \"hasGlobalSetupFixtures\").returns(true);\n          });\n\n          it(\"should not run global setup fixtures\", function (done) {\n            mocha.run(() => {\n              expect(mocha.runGlobalSetup, \"was not called\");\n              done();\n            });\n          });\n        });\n      });\n\n      describe(\"when global teardown fixtures enabled\", function () {\n        beforeEach(function () {\n          mocha.options.enableGlobalTeardown = true;\n        });\n        describe(\"when global teardown fixtures not present\", function () {\n          beforeEach(function () {\n            sinon.stub(mocha, \"hasGlobalTeardownFixtures\").returns(false);\n          });\n\n          it(\"should not run global teardown fixtures\", function (done) {\n            mocha.run(() => {\n              expect(mocha.runGlobalTeardown, \"was not called\");\n              done();\n            });\n          });\n        });\n\n        describe(\"when global teardown fixtures are present\", function () {\n          beforeEach(function () {\n            sinon.stub(mocha, \"hasGlobalTeardownFixtures\").returns(true);\n          });\n\n          it(\"should run global teardown fixtures\", function (done) {\n            mocha.run(() => {\n              expect(mocha.runGlobalTeardown, \"to have a call satisfying\", {\n                args: [expect.it(\"to be\", runner), { context: {} }],\n              }).and(\"was called once\");\n              done();\n            });\n          });\n\n          describe(\"when global setup fixtures are present and enabled\", function () {\n            beforeEach(function () {\n              sinon.stub(mocha, \"hasGlobalSetupFixtures\").returns(true);\n              mocha.options.enableGlobalSetup = true;\n            });\n\n            it(\"should use the same context as returned by `runGlobalSetup`\", function (done) {\n              mocha.run(() => {\n                expect(mocha.runGlobalTeardown, \"to have a call satisfying\", {\n                  args: [\n                    expect.it(\"to be\", runner),\n                    { context: globalFixtureContext },\n                  ],\n                }).and(\"was called once\");\n                done();\n              });\n            });\n          });\n        });\n      });\n\n      describe(\"when global teardown fixtures disabled\", function () {\n        beforeEach(function () {\n          mocha.options.enableGlobalTeardown = false;\n        });\n        describe(\"when global teardown fixtures not present\", function () {\n          beforeEach(function () {\n            sinon.stub(mocha, \"hasGlobalTeardownFixtures\").returns(false);\n          });\n\n          it(\"should not run global teardown fixtures\", function (done) {\n            mocha.run(() => {\n              expect(mocha.runGlobalTeardown, \"was not called\");\n              done();\n            });\n          });\n        });\n\n        describe(\"when global teardown fixtures are present\", function () {\n          beforeEach(function () {\n            sinon.stub(mocha, \"hasGlobalTeardownFixtures\").returns(true);\n          });\n\n          it(\"should not run global teardown fixtures\", function (done) {\n            mocha.run(() => {\n              expect(mocha.runGlobalTeardown, \"was not called\");\n              done();\n            });\n          });\n        });\n      });\n    });\n\n    describe(\"parallelMode()\", function () {\n      describe(\"when `Mocha` is running in a browser\", function () {\n        beforeEach(function () {\n          sinon.stub(utils, \"isBrowser\").returns(true);\n        });\n\n        it(\"should throw\", function () {\n          expect(\n            function () {\n              mocha.parallelMode();\n            },\n            \"to throw\",\n            { code: \"ERR_MOCHA_UNSUPPORTED\" },\n          );\n        });\n      });\n    });\n\n    describe(\"unloadFile()\", function () {\n      describe(\"when run in a browser\", function () {\n        beforeEach(function () {\n          sinon.stub(utils, \"isBrowser\").returns(true);\n        });\n\n        it(\"should throw\", function () {\n          expect(() => Mocha.unloadFile(\"guy-fieri.js\"), \"to throw\", {\n            code: \"ERR_MOCHA_UNSUPPORTED\",\n          });\n        });\n      });\n    });\n\n    describe(\"_runGlobalFixtures()\", function () {\n      it(\"should execute multiple fixtures in order\", async function () {\n        const fixtures = [\n          sinon.stub().resolves(\"foo\"),\n          sinon.stub().returns(\"bar\"),\n        ];\n        const context = await mocha._runGlobalFixtures(fixtures);\n\n        return expect(fixtures, \"to satisfy\", [\n          expect.it(\"to have a call satisfying\", {\n            thisValue: context,\n            returnValue: expect.it(\"to be fulfilled with\", \"foo\"),\n          }),\n          expect.it(\"to have a call satisfying\", {\n            thisValue: context,\n            returnValue: \"bar\",\n          }),\n        ]);\n      });\n    });\n\n    describe(\"runGlobalSetup()\", function () {\n      let context;\n\n      beforeEach(function () {\n        sinon.stub(mocha, \"_runGlobalFixtures\").resolvesArg(1);\n        context = {};\n      });\n\n      describe(\"when fixture(s) are present\", function () {\n        beforeEach(function () {\n          mocha.options.globalSetup = [sinon.spy()];\n        });\n\n        it(\"should attempt run the fixtures\", async function () {\n          await mocha.runGlobalSetup(context);\n          expect(mocha._runGlobalFixtures, \"to have a call satisfying\", [\n            mocha.options.globalSetup,\n            context,\n          ]);\n        });\n      });\n\n      describe(\"when a fixture is not present\", function () {\n        it(\"should not attempt to run fixtures\", async function () {\n          await mocha.runGlobalSetup();\n          expect(mocha._runGlobalFixtures, \"was not called\");\n        });\n      });\n    });\n\n    describe(\"runGlobalTeardown()\", function () {\n      let context;\n\n      beforeEach(function () {\n        sinon.stub(mocha, \"_runGlobalFixtures\").resolvesArg(1);\n        context = {};\n      });\n\n      describe(\"when fixture(s) are present\", function () {\n        beforeEach(function () {\n          mocha.options.globalTeardown = [sinon.spy()];\n        });\n\n        it(\"should attempt to run the fixtures\", async function () {\n          await mocha.runGlobalTeardown();\n          expect(mocha._runGlobalFixtures, \"to have a call satisfying\", [\n            mocha.options.globalTeardown,\n            context,\n          ]);\n        });\n      });\n\n      describe(\"when a fixture is not present\", function () {\n        it(\"not attempt to run the fixtures\", async function () {\n          await mocha.runGlobalTeardown();\n          expect(mocha._runGlobalFixtures, \"was not called\");\n        });\n      });\n    });\n\n    describe(\"hasGlobalSetupFixtures()\", function () {\n      describe(\"when one or more global setup fixtures are present\", function () {\n        it(\"should return `true`\", function () {\n          mocha.options.globalSetup = [() => {}];\n          expect(mocha.hasGlobalSetupFixtures(), \"to be true\");\n        });\n      });\n\n      describe(\"when no global setup fixtures are present\", function () {\n        it(\"should return `false`\", function () {\n          mocha.options.globalSetup = [];\n          expect(mocha.hasGlobalSetupFixtures(), \"to be false\");\n        });\n      });\n    });\n\n    describe(\"hasGlobalTeardownFixtures()\", function () {\n      describe(\"when one or more global teardown fixtures are present\", function () {\n        it(\"should return `true`\", function () {\n          mocha.options.globalTeardown = [() => {}];\n          expect(mocha.hasGlobalTeardownFixtures(), \"to be true\");\n        });\n      });\n\n      describe(\"when no global teardown fixtures are present\", function () {\n        it(\"should return `false`\", function () {\n          mocha.options.globalTeardown = [];\n          expect(mocha.hasGlobalTeardownFixtures(), \"to be false\");\n        });\n      });\n    });\n\n    describe(\"rootHooks()\", function () {\n      it(\"should be chainable\", function () {\n        expect(mocha.rootHooks(), \"to be\", mocha);\n      });\n\n      describe('when provided a single \"before all\" hook', function () {\n        it(\"should attach it to the root suite\", function () {\n          const beforeAll = () => {};\n          mocha.rootHooks({ beforeAll });\n          expect(mocha.suite.beforeAll, \"to have a call satisfying\", [\n            beforeAll,\n          ]).and(\"was called once\");\n        });\n      });\n\n      describe('when provided a single \"before each\" hook', function () {\n        it(\"should attach it to the root suite\", function () {\n          const beforeEach = () => {};\n          mocha.rootHooks({ beforeEach });\n          expect(mocha.suite.beforeEach, \"to have a call satisfying\", [\n            beforeEach,\n          ]).and(\"was called once\");\n        });\n      });\n\n      describe('when provided a single \"after all\" hook', function () {\n        it(\"should attach it to the root suite\", function () {\n          const afterAll = () => {};\n          mocha.rootHooks({ afterAll });\n          expect(mocha.suite.afterAll, \"to have a call satisfying\", [\n            afterAll,\n          ]).and(\"was called once\");\n        });\n      });\n\n      describe('when provided a single \"after each\" hook', function () {\n        it(\"should attach it to the root suite\", function () {\n          const afterEach = () => {};\n          mocha.rootHooks({ afterEach });\n          expect(mocha.suite.afterEach, \"to have a call satisfying\", [\n            afterEach,\n          ]).and(\"was called once\");\n        });\n      });\n\n      describe('when provided multiple \"before all\" hooks', function () {\n        it(\"should attach each to the root suite\", function () {\n          const beforeAll = [() => {}, () => {}];\n          mocha.rootHooks({ beforeAll });\n          expect(mocha.suite.beforeAll, \"to have calls satisfying\", [\n            [beforeAll[0]],\n            [beforeAll[1]],\n          ]).and(\"was called twice\");\n        });\n      });\n\n      describe('when provided multiple \"before each\" hooks', function () {\n        it(\"should attach each to the root suite\", function () {\n          const beforeEach = [() => {}, () => {}];\n          mocha.rootHooks({ beforeEach });\n          expect(mocha.suite.beforeEach, \"to have calls satisfying\", [\n            [beforeEach[0]],\n            [beforeEach[1]],\n          ]).and(\"was called twice\");\n        });\n      });\n\n      describe('when provided multiple \"after all\" hooks', function () {\n        it(\"should attach each to the root suite\", function () {\n          const afterAll = [() => {}, () => {}];\n          mocha.rootHooks({ afterAll });\n          expect(mocha.suite.afterAll, \"to have calls satisfying\", [\n            [afterAll[0]],\n            [afterAll[1]],\n          ]).and(\"was called twice\");\n        });\n      });\n\n      describe('when provided multiple \"after each\" hooks', function () {\n        it(\"should attach each to the root suite\", function () {\n          const afterEach = [() => {}, () => {}];\n          mocha.rootHooks({ afterEach });\n          expect(mocha.suite.afterEach, \"to have calls satisfying\", [\n            [afterEach[0]],\n            [afterEach[1]],\n          ]).and(\"was called twice\");\n        });\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/overspecified-async.spec.js",
    "content": "\"use strict\";\n\ndescribe(\"overspecified asynchronous resolution method\", function () {\n  it(\"should fail when multiple methods are used\", function (done) {\n    setTimeout(done, 0);\n\n    // uncomment\n    // return { then: function() {} };\n  });\n});\n"
  },
  {
    "path": "test/unit/parse-query.spec.js",
    "content": "\"use strict\";\n\nvar parseQuery = require(\"../../lib/browser/parse-query\");\n\ndescribe(\"parseQuery()\", function () {\n  it(\"should get queryString and return key-value object\", function () {\n    expect(parseQuery(\"?foo=1&bar=2&baz=3\"), \"to equal\", {\n      foo: \"1\",\n      bar: \"2\",\n      baz: \"3\",\n    });\n\n    expect(parseQuery(\"?r1=^@(?!.*\\\\)$)&r2=m{2}&r3=^co.*\"), \"to equal\", {\n      r1: \"^@(?!.*\\\\)$)\",\n      r2: \"m{2}\",\n      r3: \"^co.*\",\n    });\n  });\n\n  it('should parse \"+\" as a space', function () {\n    expect(parseQuery(\"?grep=foo+bar\"), \"to equal\", { grep: \"foo bar\" });\n  });\n});\n"
  },
  {
    "path": "test/unit/plugin-loader.spec.js",
    "content": "\"use strict\";\n\nconst PluginLoader = require(\"../../lib/plugin-loader\");\nconst sinon = require(\"sinon\");\nconst { INVALID_PLUGIN_DEFINITION, INVALID_PLUGIN_IMPLEMENTATION } =\n  require(\"../../lib/error-constants\").constants;\n\ndescribe(\"plugin module\", function () {\n  describe(\"class PluginLoader\", function () {\n    describe(\"constructor\", function () {\n      describe(\"when passed no options\", function () {\n        it(\"should populate a registry of built-in plugins\", function () {\n          expect(new PluginLoader().registered.has(\"mochaHooks\"), \"to be true\");\n        });\n      });\n\n      describe(\"when passed custom plugins\", function () {\n        it(\"should register the custom plugins\", function () {\n          const plugin = { exportName: \"mochaBananaPhone\" };\n          expect(\n            new PluginLoader({ pluginDefs: [plugin] }).registered,\n            \"to satisfy\",\n            new Map([[\"mochaBananaPhone\", plugin]]),\n          );\n        });\n      });\n\n      describe(\"when passed ignored plugins\", function () {\n        it(\"should retain a list of ignored plugins\", function () {\n          expect(\n            new PluginLoader({\n              ignore: [\"elephantInRoom\"],\n            }).ignoredExportNames,\n            \"to contain\",\n            \"elephantInRoom\",\n          );\n        });\n      });\n    });\n\n    describe(\"static method\", function () {\n      describe(\"create()\", function () {\n        it(\"should return a PluginLoader instance\", function () {\n          expect(PluginLoader.create(), \"to be a\", PluginLoader);\n        });\n      });\n    });\n\n    describe(\"instance method\", function () {\n      let pluginLoader;\n\n      beforeEach(function () {\n        pluginLoader = PluginLoader.create({\n          ignore: [\"elephantInRoom\"],\n        });\n      });\n\n      describe(\"register()\", function () {\n        describe(\"when the plugin export name is not in use\", function () {\n          it(\"should not throw\", function () {\n            expect(\n              () => pluginLoader.register({ exportName: \"butts\" }),\n              \"not to throw\",\n            );\n          });\n        });\n\n        describe(\"when the plugin export name is already in use\", function () {\n          it(\"should throw\", function () {\n            const pluginDef = { exportName: \"butts\" };\n            pluginLoader.register(pluginDef);\n            expect(() => pluginLoader.register(pluginDef), \"to throw\", {\n              code: INVALID_PLUGIN_DEFINITION,\n              pluginDef,\n            });\n          });\n        });\n\n        describe(\"when the plugin export name is ignored\", function () {\n          let pluginDef;\n\n          beforeEach(function () {\n            pluginDef = { exportName: \"elephantInRoom\" };\n          });\n\n          it(\"should not throw\", function () {\n            expect(() => pluginLoader.register(pluginDef), \"not to throw\");\n          });\n\n          it(\"should not register the plugin\", function () {\n            pluginLoader.register(pluginDef);\n            expect(\n              pluginLoader.registered,\n              \"not to have key\",\n              \"elephantInRoom\",\n            );\n          });\n        });\n\n        describe(\"when passed a falsy parameter\", function () {\n          it(\"should throw\", function () {\n            expect(() => pluginLoader.register(), \"to throw\", {\n              code: INVALID_PLUGIN_DEFINITION,\n            });\n          });\n        });\n\n        describe(\"when passed a non-object parameter\", function () {\n          it(\"should throw\", function () {\n            expect(() => pluginLoader.register(1), \"to throw\", {\n              code: INVALID_PLUGIN_DEFINITION,\n              pluginDef: 1,\n            });\n          });\n        });\n\n        describe(\"when passed a definition w/o an exportName\", function () {\n          it(\"should throw\", function () {\n            const pluginDef = { foo: \"bar\" };\n            expect(() => pluginLoader.register(pluginDef), \"to throw\", {\n              code: INVALID_PLUGIN_DEFINITION,\n              pluginDef,\n            });\n          });\n        });\n      });\n\n      describe(\"load()\", function () {\n        let pluginLoader;\n\n        beforeEach(function () {\n          pluginLoader = PluginLoader.create();\n        });\n\n        describe(\"when called with a falsy value\", function () {\n          it(\"should return false\", function () {\n            expect(pluginLoader.load(), \"to be false\");\n          });\n        });\n\n        describe(\"when called with an object containing no recognized plugin\", function () {\n          it(\"should return false\", function () {\n            // also it should not throw\n            expect(\n              pluginLoader.load({ mochaBananaPhone: () => {} }),\n              \"to be false\",\n            );\n          });\n        });\n\n        describe(\"when called with an object containing a recognized plugin\", function () {\n          let plugin;\n          let pluginLoader;\n\n          beforeEach(function () {\n            plugin = {\n              exportName: \"mochaBananaPhone\",\n              validate: sinon.spy(),\n            };\n            pluginLoader = PluginLoader.create({ pluginDefs: [plugin] });\n          });\n\n          it(\"should return true\", function () {\n            const func = () => {};\n            expect(pluginLoader.load({ mochaBananaPhone: func }), \"to be true\");\n          });\n\n          it(\"should retain the value of any matching property in its mapping\", function () {\n            const func = () => {};\n            pluginLoader.load({ mochaBananaPhone: func });\n            expect(\n              pluginLoader.loaded,\n              \"to satisfy\",\n              new Map([[\"mochaBananaPhone\", [func]]]),\n            );\n          });\n\n          it(\"should call the associated validator, if present\", function () {\n            const func = () => {};\n            pluginLoader.load({ mochaBananaPhone: func });\n            expect(plugin.validate, \"was called once\");\n          });\n        });\n      });\n\n      describe(\"load()\", function () {\n        let pluginLoader;\n        let fooPlugin;\n        let barPlugin;\n\n        beforeEach(function () {\n          fooPlugin = {\n            exportName: \"foo\",\n            validate: sinon.stub(),\n          };\n          fooPlugin.validate.withArgs(\"ERROR\").throws();\n          barPlugin = {\n            exportName: \"bar\",\n            validate: sinon.stub(),\n          };\n          pluginLoader = PluginLoader.create({\n            pluginDefs: [fooPlugin, barPlugin],\n          });\n        });\n\n        describe(\"when passed a falsy or non-object value\", function () {\n          it(\"should return false\", function () {\n            expect(pluginLoader.load(), \"to be false\");\n          });\n\n          it(\"should not call a validator\", function () {\n            expect([fooPlugin, barPlugin], \"to have items satisfying\", {\n              validate: expect.it(\"was not called\"),\n            });\n          });\n        });\n\n        describe(\"when passed an object value\", function () {\n          describe(\"when no keys match any known named exports\", function () {\n            let retval;\n\n            beforeEach(function () {\n              retval = pluginLoader.load({ butts: () => {} });\n            });\n\n            it(\"should return false\", function () {\n              expect(retval, \"to be false\");\n            });\n          });\n\n          describe(\"when a key matches a known named export\", function () {\n            let retval;\n            let impl;\n\n            beforeEach(function () {\n              impl = sinon.stub();\n            });\n\n            it(\"should call the associated validator\", function () {\n              retval = pluginLoader.load({ foo: impl });\n\n              expect(fooPlugin.validate, \"to have a call satisfying\", [\n                impl,\n              ]).and(\"was called once\");\n            });\n\n            it(\"should not call validators whose keys were not found\", function () {\n              retval = pluginLoader.load({ foo: impl });\n              expect(barPlugin.validate, \"was not called\");\n            });\n\n            describe(\"when the value passes the associated validator\", function () {\n              beforeEach(function () {\n                retval = pluginLoader.load({ foo: impl });\n              });\n\n              it(\"should return true\", function () {\n                expect(retval, \"to be true\");\n              });\n\n              it(\"should add the implementation to the internal mapping\", function () {\n                expect(\n                  pluginLoader.loaded,\n                  \"to satisfy\",\n                  new Map([[\"foo\", expect.it(\"to have length\", 1)]]),\n                );\n              });\n\n              it(\"should not add an implementation of plugins not present\", function () {\n                expect(\n                  pluginLoader.loaded,\n                  \"to satisfy\",\n                  new Map([[\"bar\", expect.it(\"to be empty\")]]),\n                );\n              });\n            });\n\n            describe(\"when the value does not pass the associated validator\", function () {\n              it(\"should throw\", function () {\n                expect(() => pluginLoader.load({ foo: \"ERROR\" }), \"to throw\");\n              });\n            });\n          });\n        });\n      });\n\n      describe(\"finalize()\", function () {\n        let pluginLoader;\n        let fooPlugin;\n        let barPlugin;\n        let bazPlugin;\n\n        beforeEach(function () {\n          fooPlugin = {\n            exportName: \"foo\",\n            optionName: \"fooOption\",\n            validate: sinon.stub(),\n            finalize: (impls) => impls.map(() => \"FOO\"),\n          };\n          fooPlugin.validate.withArgs(\"ERROR\").throws();\n          barPlugin = {\n            exportName: \"bar\",\n            validate: sinon.stub(),\n            finalize: (impls) => impls.map(() => \"BAR\"),\n          };\n          bazPlugin = {\n            exportName: \"baz\",\n          };\n          pluginLoader = PluginLoader.create({\n            pluginDefs: [fooPlugin, barPlugin, bazPlugin],\n          });\n        });\n\n        describe(\"when no plugins have been loaded\", function () {\n          it(\"should return an empty map\", async function () {\n            return expect(pluginLoader.finalize(), \"to be fulfilled with\", {});\n          });\n        });\n\n        describe(\"when a plugin has one or more implementations\", function () {\n          beforeEach(function () {\n            pluginLoader.load({ foo: sinon.stub() });\n            pluginLoader.load({ foo: sinon.stub() });\n          });\n\n          it(\"should return an object map using `optionName` key for each registered plugin\", async function () {\n            return expect(pluginLoader.finalize(), \"to be fulfilled with\", {\n              fooOption: [\"FOO\", \"FOO\"],\n            });\n          });\n\n          it(\"should omit unused plugins\", async function () {\n            pluginLoader.load({ bar: sinon.stub() });\n            return expect(pluginLoader.finalize(), \"to be fulfilled with\", {\n              fooOption: [\"FOO\", \"FOO\"],\n              bar: [\"BAR\"],\n            });\n          });\n        });\n\n        describe('when a plugin has no \"finalize\" function', function () {\n          it(\"should return an array of raw implementations\", function () {\n            pluginLoader.load({ baz: \"polar bears\" });\n            return expect(pluginLoader.finalize(), \"to be fulfilled with\", {\n              baz: [\"polar bears\"],\n            });\n          });\n        });\n      });\n    });\n  });\n\n  describe(\"root hooks plugin 🎣\", function () {\n    let pluginLoader;\n\n    beforeEach(function () {\n      pluginLoader = PluginLoader.create();\n    });\n\n    describe(\"when impl is an array\", function () {\n      it(\"should fail validation\", function () {\n        expect(() => pluginLoader.load({ mochaHooks: [] }), \"to throw\", {\n          code: INVALID_PLUGIN_IMPLEMENTATION,\n        });\n      });\n    });\n\n    describe(\"when impl is a primitive\", function () {\n      it(\"should fail validation\", function () {\n        expect(() => pluginLoader.load({ mochaHooks: \"nuts\" }), \"to throw\", {\n          code: INVALID_PLUGIN_IMPLEMENTATION,\n        });\n      });\n    });\n\n    describe(\"when impl is a function\", function () {\n      it(\"should pass validation\", function () {\n        expect(pluginLoader.load({ mochaHooks: sinon.stub() }), \"to be true\");\n      });\n    });\n\n    describe(\"when impl is an object of functions\", function () {\n      // todo: hook name validation?\n      it(\"should pass validation\");\n    });\n\n    describe(\"when a loaded impl is finalized\", function () {\n      it(\"should flatten the implementations\", async function () {\n        function a() {}\n        function b() {}\n        function d() {}\n        function g() {}\n        async function f() {}\n        function c() {\n          return {\n            beforeAll: d,\n            beforeEach: g,\n          };\n        }\n        async function e() {\n          return {\n            afterEach: f,\n          };\n        }\n\n        [\n          {\n            beforeEach: a,\n          },\n          {\n            afterAll: b,\n          },\n          c,\n          e,\n        ].forEach((impl) => {\n          pluginLoader.load({ mochaHooks: impl });\n        });\n\n        return expect(pluginLoader.finalize(), \"to be fulfilled with\", {\n          rootHooks: {\n            beforeAll: [d],\n            beforeEach: [a, g],\n            afterAll: [b],\n            afterEach: [f],\n          },\n        });\n      });\n    });\n  });\n\n  describe(\"global fixtures plugin\", function () {\n    let pluginLoader;\n\n    beforeEach(function () {\n      pluginLoader = PluginLoader.create();\n    });\n\n    describe(\"global setup\", function () {\n      describe(\"when an implementation is a primitive\", function () {\n        it(\"should fail validation\", function () {\n          expect(\n            () => pluginLoader.load({ mochaGlobalSetup: \"nuts\" }),\n            \"to throw\",\n          );\n        });\n      });\n      describe(\"when an implementation is an array of primitives\", function () {\n        it(\"should fail validation\", function () {\n          expect(\n            () => pluginLoader.load({ mochaGlobalSetup: [\"nuts\"] }),\n            \"to throw\",\n          );\n        });\n      });\n\n      describe(\"when an implementation is a function\", function () {\n        it(\"should pass validation\", function () {\n          expect(\n            pluginLoader.load({ mochaGlobalSetup: sinon.stub() }),\n            \"to be true\",\n          );\n        });\n      });\n\n      describe(\"when an implementation is an array of functions\", function () {\n        it(\"should pass validation\", function () {\n          expect(\n            pluginLoader.load({ mochaGlobalSetup: [sinon.stub()] }),\n            \"to be true\",\n          );\n        });\n      });\n    });\n\n    describe(\"global teardown\", function () {\n      describe(\"when an implementation is a primitive\", function () {\n        it(\"should fail validation\", function () {\n          expect(\n            () => pluginLoader.load({ mochaGlobalTeardown: \"nuts\" }),\n            \"to throw\",\n          );\n        });\n      });\n      describe(\"when an implementation is an array of primitives\", function () {\n        it(\"should fail validation\", function () {\n          expect(\n            () => pluginLoader.load({ mochaGlobalTeardown: [\"nuts\"] }),\n            \"to throw\",\n          );\n        });\n      });\n\n      describe(\"when an implementation is a function\", function () {\n        it(\"should pass validation\", function () {\n          expect(\n            pluginLoader.load({ mochaGlobalTeardown: sinon.stub() }),\n            \"to be true\",\n          );\n        });\n      });\n\n      describe(\"when an implementation is an array of functions\", function () {\n        it(\"should pass validation\", function () {\n          expect(\n            pluginLoader.load({ mochaGlobalTeardown: [sinon.stub()] }),\n            \"to be true\",\n          );\n        });\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/required-tokens.spec.js",
    "content": "\"use strict\";\n\nconst assert = require(\"node:assert\");\nconst { describe, it } = require(\"../..\");\n\ndescribe('using imported \"describe\"', function () {\n  it('using imported \"it\"', function (done) {\n    assert.ok(true);\n    done();\n  });\n});\n"
  },
  {
    "path": "test/unit/root.spec.js",
    "content": "\"use strict\";\n\nvar calls = [];\n\nbefore(function () {\n  calls.push(\"before\");\n});\n\ndescribe(\"root\", function () {\n  it(\"should be a valid suite\", function () {\n    expect(calls, \"to equal\", [\"before\"]);\n  });\n});\n"
  },
  {
    "path": "test/unit/runnable.spec.js",
    "content": "\"use strict\";\n\nvar Mocha = require(\"../../lib/mocha\");\nvar Runnable = Mocha.Runnable;\nvar Suite = Mocha.Suite;\nvar sinon = require(\"sinon\");\nconst { TIMEOUT } = require(\"../../lib/error-constants\").constants;\nvar STATE_FAILED = Runnable.constants.STATE_FAILED;\n\ndescribe(\"Runnable(title, fn)\", function () {\n  describe(\"#timeout(ms)\", function () {\n    var DISABLED_TIMEOUTS = 0;\n    var MAX_TIMEOUT = 2147483647; // INT_MAX (32-bit signed integer)\n\n    describe(\"when value is less than lower bound\", function () {\n      it(\"should clamp to lower bound given numeric\", function () {\n        var run = new Runnable();\n        run.timeout(-1);\n        expect(run.timeout(), \"to be\", DISABLED_TIMEOUTS);\n      });\n      it(\"should clamp to lower bound given timestamp\", function () {\n        var run = new Runnable();\n        run.timeout(\"-1 ms\");\n        expect(run.timeout(), \"to be\", DISABLED_TIMEOUTS);\n      });\n    });\n\n    describe(\"when value is equal to lower bound\", function () {\n      var run;\n\n      beforeEach(function () {\n        run = new Runnable();\n        run.timeout(DISABLED_TIMEOUTS);\n      });\n      describe(\"given numeric value\", function () {\n        it(\"should set the timeout value to disabled\", function () {\n          expect(run.timeout(), \"to be\", DISABLED_TIMEOUTS);\n        });\n      });\n\n      describe(\"given string timestamp\", function () {\n        it(\"should set the timeout value to disabled\", function () {\n          expect(run.timeout(), \"to be\", DISABLED_TIMEOUTS);\n        });\n      });\n    });\n\n    describe(\"when value is within `setTimeout` bounds\", function () {\n      var run;\n      var timeout = 1000;\n\n      beforeEach(function () {\n        run = new Runnable();\n        run.timeout(timeout);\n      });\n\n      describe(\"given numeric value\", function () {\n        it(\"should set the timeout value\", function () {\n          expect(run.timeout(), \"to be\", timeout);\n        });\n      });\n\n      describe(\"given string timestamp\", function () {\n        it(\"should set the timeout value\", function () {\n          expect(run.timeout(), \"to be\", timeout);\n        });\n      });\n    });\n\n    describe(\"when value is equal to upper bound\", function () {\n      var run;\n\n      beforeEach(function () {\n        run = new Runnable();\n        run.timeout(MAX_TIMEOUT);\n      });\n      describe(\"given numeric value\", function () {\n        it(\"should set the disabled timeout value\", function () {\n          expect(run.timeout(), \"to be\", 0);\n        });\n      });\n    });\n\n    describe(\"when value is out-of-bounds\", function () {\n      var run;\n      var timeout = MAX_TIMEOUT + 1;\n\n      beforeEach(function () {\n        run = new Runnable();\n        run.timeout(timeout);\n      });\n\n      describe(\"given numeric value\", function () {\n        it(\"should set the disabled timeout value\", function () {\n          expect(run.timeout(), \"to be\", 0);\n        });\n      });\n    });\n  });\n\n  describe(\"#slow(ms)\", function () {\n    var run;\n\n    beforeEach(function () {\n      run = new Runnable();\n    });\n\n    it(\"should set the slow threshold\", function () {\n      run.slow(100);\n      expect(run.slow(), \"to be\", 100);\n    });\n\n    it(\"should not set the slow threshold if the parameter is not passed\", function () {\n      run.slow();\n      expect(run.slow(), \"to be\", 75);\n    });\n\n    it(\"should not set the slow threshold if the parameter is undefined\", function () {\n      run.slow(undefined);\n      expect(run.slow(), \"to be\", 75);\n    });\n\n    describe(\"when passed a time-formatted string\", function () {\n      it(\"should convert to ms\", function () {\n        run.slow(\"1s\");\n        expect(run.slow(), \"to be\", 1000);\n      });\n    });\n  });\n\n  describe(\"#reset\", function () {\n    var run;\n\n    beforeEach(function () {\n      run = new Runnable();\n    });\n\n    it(\"should reset current run state\", function () {\n      run.timedOut = true;\n      run._currentRetry = 5;\n      run.pending = true;\n      run.err = new Error();\n      run.state = \"error\";\n\n      run.reset();\n      expect(run.timedOut, \"to be false\");\n      expect(run._currentRetry, \"to be\", 0);\n      expect(run.pending, \"to be false\");\n      expect(run.err, \"to be undefined\");\n      expect(run.state, \"to be undefined\");\n    });\n  });\n\n  describe(\".title\", function () {\n    it(\"should be present\", function () {\n      expect(new Runnable(\"foo\").title, \"to be\", \"foo\");\n    });\n  });\n\n  describe(\".titlePath()\", function () {\n    it(\"returns the concatenation of the parent's title path and runnable's title\", function () {\n      var runnable = new Runnable(\"bar\");\n      runnable.parent = new Suite(\"foo\");\n      expect(\n        JSON.stringify(runnable.titlePath()),\n        \"to be\",\n        JSON.stringify([\"foo\", \"bar\"]),\n      );\n    });\n  });\n\n  describe(\"when arity >= 1\", function () {\n    var run;\n\n    beforeEach(function () {\n      // Runnable knows whether it's provided a 'done' parameter\n      // eslint-disable-next-line no-unused-vars\n      run = new Runnable(\"foo\", function (done) {});\n    });\n\n    it(\"should be .async\", function () {\n      expect(run.async, \"to be\", 1);\n    });\n\n    it(\"should not be .sync\", function () {\n      expect(run.sync, \"to be false\");\n    });\n  });\n\n  describe(\"when arity == 0\", function () {\n    var run;\n\n    beforeEach(function () {\n      run = new Runnable(\"foo\", function () {});\n    });\n\n    it(\"should not be .async\", function () {\n      expect(run.async, \"to be\", 0);\n    });\n\n    it(\"should be .sync\", function () {\n      expect(run.sync, \"to be true\");\n    });\n  });\n\n  describe(\"#globals\", function () {\n    it(\"should allow for whitelisting globals\", function () {\n      var runnable = new Runnable(\"foo\", function () {});\n      runnable.globals([\"foobar\"]);\n      expect(runnable._allowedGlobals, \"to equal\", [\"foobar\"]);\n    });\n  });\n\n  describe(\"#retries(n)\", function () {\n    it(\"should set the number of retries\", function () {\n      var run = new Runnable();\n      run.retries(1);\n      expect(run.retries(), \"to be\", 1);\n    });\n  });\n\n  describe(\".run(fn)\", function () {\n    describe(\"when .pending\", function () {\n      it(\"should not invoke the callback\", function (done) {\n        var spy = sinon.spy();\n        var runnable = new Runnable(\"foo\", spy);\n\n        runnable.pending = true;\n        runnable.run(function (err) {\n          if (err) {\n            return done(err);\n          }\n          expect(spy, \"was not called\");\n          done();\n        });\n      });\n    });\n\n    describe(\"when sync\", function () {\n      describe(\"without error\", function () {\n        it(\"should invoke the callback\", function (done) {\n          var spy = sinon.spy();\n          var runnable = new Runnable(\"foo\", spy);\n\n          runnable.run(function (err) {\n            if (err) {\n              return done(err);\n            }\n\n            expect(spy, \"was called times\", 1);\n            done();\n          });\n        });\n      });\n\n      describe(\"when an exception is thrown\", function () {\n        it(\"should invoke the callback with error\", function (done) {\n          var stub = sinon.stub().throws(\"Error\", \"fail\");\n          var runnable = new Runnable(\"foo\", stub);\n\n          runnable.run(function (err) {\n            expect(err.message, \"to be\", \"fail\");\n            expect(stub, \"was called\");\n            done();\n          });\n        });\n      });\n\n      describe(\"when an exception is thrown and is allowed to remain uncaught\", function () {\n        it(\"throws an error when it is allowed\", function () {\n          var stub = sinon.stub().throws(\"Error\", \"fail\");\n          var runnable = new Runnable(\"foo\", stub);\n          runnable.allowUncaught = true;\n\n          function fail() {\n            runnable.run(function () {});\n          }\n          expect(fail, \"to throw\", \"fail\");\n        });\n      });\n    });\n\n    describe(\"when timeouts are disabled\", function () {\n      it(\"should not error with timeout\", function (done) {\n        var runnable = new Runnable(\"foo\", function (done) {\n          setTimeout(function () {\n            setTimeout(done);\n          }, 2);\n        });\n        runnable.timeout(1);\n        runnable.timeout(0);\n        runnable.run(function (err) {\n          expect(err, \"to be falsy\");\n          done();\n        });\n      });\n    });\n\n    describe(\"when async\", function () {\n      describe(\"without error\", function () {\n        it(\"should invoke the callback\", function (done) {\n          var runnable = new Runnable(\"foo\", function (done) {\n            setTimeout(done);\n          });\n\n          runnable.run(function (err) {\n            expect(err, \"to be falsy\");\n            done();\n          });\n        });\n      });\n\n      describe(\"when the callback is invoked several times\", function () {\n        describe(\"without an error\", function () {\n          it('should emit a single \"error\" event', function (done) {\n            var callbackSpy = sinon.spy();\n            var errorSpy = sinon.spy();\n\n            var runnable = new Runnable(\"foo\", function (done) {\n              process.nextTick(done);\n              setTimeout(done);\n              setTimeout(done);\n              setTimeout(done);\n            });\n\n            // XXX too many diff assertions and very flimsy assertion that this\n            // event was only emitted once.  think of a better way.\n            runnable.on(\"error\", errorSpy).on(\"error\", function (err) {\n              process.nextTick(function () {\n                expect(errorSpy, \"was called times\", 1);\n                expect(\n                  err.message,\n                  \"to match\",\n                  /done\\(\\) called multiple times/,\n                );\n                expect(callbackSpy, \"was called times\", 1);\n                done();\n              });\n            });\n\n            runnable.run(callbackSpy);\n          });\n        });\n\n        describe(\"with an error\", function () {\n          it('should emit a single \"error\" event', function (done) {\n            var callbackSpy = sinon.spy();\n            var errorSpy = sinon.spy();\n\n            var runnable = new Runnable(\"foo\", function (done) {\n              done(new Error(\"fail\"));\n              setTimeout(done);\n              done(new Error(\"fail\"));\n              setTimeout(done);\n              setTimeout(done);\n            });\n\n            // XXX too many diff assertions and very flimsy assertion that this\n            // event was only emitted once.  think of a better way.\n            runnable.on(\"error\", errorSpy).on(\"error\", function (err) {\n              process.nextTick(function () {\n                expect(errorSpy, \"was called times\", 1);\n                expect(\n                  err.message,\n                  \"to match\",\n                  /done\\(\\) called multiple times.+received error: Error: fail/,\n                );\n                expect(callbackSpy, \"was called times\", 1);\n                done();\n              });\n            });\n\n            runnable.run(callbackSpy);\n          });\n        });\n      });\n\n      describe(\"when an exception is thrown\", function () {\n        it(\"should invoke the callback\", function (done) {\n          var runnable = new Runnable(\n            \"foo\",\n            sinon.stub().throws(\"Error\", \"fail\"),\n          );\n\n          runnable.run(function (err) {\n            expect(err.message, \"to be\", \"fail\");\n            done();\n          });\n        });\n\n        it(\"should not throw its own exception if passed a non-object\", function (done) {\n          var runnable = new Runnable(\"foo\", function () {\n            /* eslint no-throw-literal: off */\n            throw null;\n          });\n\n          runnable.run(function (err) {\n            expect(err.message, \"to be\", Runnable.toValueOrError().message);\n            done();\n          });\n        });\n      });\n\n      describe(\"when an exception is thrown and is allowed to remain uncaught\", function () {\n        it(\"throws an error when it is allowed\", function (done) {\n          var runnable = new Runnable(\"foo\", function () {\n            throw new Error(\"fail\");\n          });\n          runnable.allowUncaught = true;\n\n          function fail() {\n            runnable.run(function () {});\n          }\n          expect(fail, \"to throw\", \"fail\");\n          done();\n        });\n      });\n\n      describe(\"when an error is passed\", function () {\n        it(\"should invoke the callback\", function (done) {\n          var runnable = new Runnable(\"foo\", function (done) {\n            done(new Error(\"fail\"));\n          });\n\n          runnable.run(function (err) {\n            expect(err.message, \"to be\", \"fail\");\n            done();\n          });\n        });\n      });\n\n      describe(\"when done() is invoked with a non-Error object\", function () {\n        it(\"should invoke the callback\", function (done) {\n          var runnable = new Runnable(\"foo\", function (done) {\n            done({\n              error: \"Test error\",\n            });\n          });\n\n          runnable.run(function (err) {\n            expect(\n              err.message,\n              \"to be\",\n              'done() invoked with non-Error: {\"error\":\"Test error\"}',\n            );\n            done();\n          });\n        });\n      });\n\n      describe(\"when done() is invoked with a string\", function () {\n        it(\"should invoke the callback\", function (done) {\n          var runnable = new Runnable(\"foo\", function (done) {\n            done(\"Test error\");\n          });\n\n          runnable.run(function (err) {\n            expect(\n              err.message,\n              \"to be\",\n              \"done() invoked with non-Error: Test error\",\n            );\n            done();\n          });\n        });\n      });\n\n      it(\"should allow updating the timeout\", function (done) {\n        var spy = sinon.spy();\n        // Runnable knows whether it's provided a 'done' parameter\n        // eslint-disable-next-line no-unused-vars\n        var runnable = new Runnable(\"foo\", function (done) {\n          setTimeout(spy, 1);\n          setTimeout(spy, 100);\n        });\n        runnable.timeout(50);\n        runnable.run(function (err) {\n          expect(err, \"to be truthy\");\n          expect(spy, \"was called times\", 1);\n          done();\n        });\n      });\n\n      it(\"should allow a timeout of 0\", function (done) {\n        const runnable = new Runnable(\"foo\", () => {});\n        runnable.timeout(0);\n        runnable.run((err) => {\n          expect(err, \"to be falsy\");\n          done();\n        });\n      });\n    });\n\n    describe(\"when fn returns a promise\", function () {\n      describe(\"when the promise is fulfilled with no value\", function () {\n        var fulfilledPromise = {\n          then: function (fulfilled) {\n            setTimeout(fulfilled);\n          },\n        };\n\n        it(\"should invoke the callback\", function (done) {\n          var runnable = new Runnable(\"foo\", function () {\n            return fulfilledPromise;\n          });\n\n          runnable.run(function (err) {\n            expect(err, \"to be falsy\");\n            done();\n          });\n        });\n      });\n\n      describe(\"when the promise is fulfilled with a value\", function () {\n        var fulfilledPromise = {\n          then: function (fulfilled) {\n            setTimeout(function () {\n              fulfilled({});\n            });\n          },\n        };\n\n        it(\"should invoke the callback\", function (done) {\n          var runnable = new Runnable(\"foo\", function () {\n            return fulfilledPromise;\n          });\n\n          runnable.run(function (err) {\n            expect(err, \"to be falsy\");\n            done();\n          });\n        });\n      });\n\n      describe(\"when the promise is rejected\", function () {\n        var expectedErr = new Error(\"fail\");\n        var rejectedPromise = {\n          then: function (fulfilled, rejected) {\n            setTimeout(function () {\n              rejected(expectedErr);\n            });\n          },\n        };\n\n        it(\"should invoke the callback\", function (done) {\n          var runnable = new Runnable(\"foo\", function () {\n            return rejectedPromise;\n          });\n\n          runnable.run(function (err) {\n            expect(err, \"to be\", expectedErr);\n            done();\n          });\n        });\n      });\n\n      describe(\"when the promise is rejected without a reason\", function () {\n        var expectedErr = new Error(\"Promise rejected with no or falsy reason\");\n        var rejectedPromise = {\n          then: function (fulfilled, rejected) {\n            setTimeout(function () {\n              rejected();\n            });\n          },\n        };\n\n        it(\"should invoke the callback\", function (done) {\n          var runnable = new Runnable(\"foo\", function () {\n            return rejectedPromise;\n          });\n\n          runnable.run(function (err) {\n            expect(err.message, \"to be\", expectedErr.message);\n            done();\n          });\n        });\n      });\n\n      describe(\"when the promise takes too long to settle\", function () {\n        var foreverPendingPromise = {\n          then: function () {},\n        };\n\n        it(\"should throw the timeout error\", function (done) {\n          var runnable = new Runnable(\"foo\", function () {\n            return foreverPendingPromise;\n          });\n          runnable.file = \"/some/path\";\n\n          runnable.timeout(10);\n          runnable.run(function (err) {\n            expect(err, \"to satisfy\", { code: TIMEOUT, timeout: 10 });\n            done();\n          });\n        });\n      });\n    });\n\n    describe(\"when fn returns a non-promise\", function () {\n      it(\"should invoke the callback\", function (done) {\n        var runnable = new Runnable(\"foo\", function () {\n          return {\n            then: \"i ran my tests\",\n          };\n        });\n\n        runnable.run(done);\n      });\n    });\n\n    describe(\"if timed-out\", function () {\n      it(\"should ignore call to `done` and not execute callback again\", function (done) {\n        var runnable = new Runnable(\"foo\", function (done) {\n          setTimeout(done, 20);\n        });\n        runnable.timeout(10);\n        runnable.run(function (err) {\n          expect(err, \"to satisfy\", { code: TIMEOUT, timeout: 10 });\n          // timedOut is set *after* this callback is executed\n          process.nextTick(function () {\n            expect(runnable.timedOut, \"to be truthy\");\n            done();\n          });\n        });\n      });\n    });\n\n    describe(\"if async\", function () {\n      it(\"this.skip() should set runnable to pending\", function (done) {\n        var runnable = new Runnable(\"foo\", function () {\n          // normally \"this\" but it gets around having to muck with a context\n          runnable.skip();\n        });\n        runnable.run(function (err) {\n          expect(err, \"to be undefined\");\n          expect(runnable.pending, \"to be true\");\n          done();\n        });\n      });\n\n      it(\"this.skip() should halt synchronous execution\", function (done) {\n        var aborted = true;\n        var runnable = new Runnable(\"foo\", function () {\n          // normally \"this\" but it gets around having to muck with a context\n          runnable.skip();\n          /* istanbul ignore next */\n          aborted = false;\n        });\n        runnable.run(function () {\n          process.nextTick(function () {\n            expect(aborted, \"to be true\");\n            done();\n          });\n        });\n      });\n    });\n\n    describe(\"when fn is not a function\", function () {\n      it(\"should throw an error\", function () {\n        var runnable = new Runnable(\"foo\", 4);\n\n        runnable.run(function (err) {\n          expect(\n            err.message,\n            \"to be\",\n            \"A runnable must be passed a function as its second argument.\",\n          );\n        });\n      });\n    });\n  });\n\n  describe(\"#isFailed()\", function () {\n    it(\"should return `true` if test has not failed\", function () {\n      var runnable = new Runnable(\"foo\", function () {});\n      // runner sets the state\n      runnable.run(function () {\n        expect(runnable.isFailed(), \"to be false\");\n      });\n    });\n\n    it(\"should return `true` if test has failed\", function () {\n      var runnable = new Runnable(\"foo\", function () {});\n      // runner sets the state\n      runnable.state = STATE_FAILED;\n      runnable.run(function () {\n        expect(runnable.isFailed(), \"to be false\");\n      });\n    });\n\n    it(\"should return `false` if test is pending\", function () {\n      var runnable = new Runnable(\"foo\", function () {});\n      // runner sets the state\n      runnable.isPending = function () {\n        return true;\n      };\n      runnable.run(function () {\n        expect(runnable.isFailed(), \"to be false\");\n      });\n    });\n  });\n\n  describe(\"#resetTimeout()\", function () {\n    it(\"should not time out if timeouts disabled after reset\", function (done) {\n      var runnable = new Runnable(\"foo\", function () {});\n      runnable.timeout(10);\n      runnable.resetTimeout();\n      runnable.timeout(0);\n      runnable.run();\n      setTimeout(function () {\n        expect(runnable.timedOut, \"to be\", false);\n        done();\n      }, 20);\n    });\n  });\n\n  describe(\"static method\", function () {\n    describe(\"toValueOrError\", function () {\n      it(\"should return identity if parameter is truthy\", function () {\n        expect(Runnable.toValueOrError(\"foo\"), \"to be\", \"foo\");\n      });\n\n      it(\"should return an Error if parameter is falsy\", function () {\n        expect(Runnable.toValueOrError(null), \"to be an\", Error);\n      });\n    });\n  });\n\n  describe(\"interesting property\", function () {\n    describe(\"id\", function () {\n      it(\"should have a unique identifier\", function () {\n        expect(new Runnable(\"foo\", () => {}), \"to have property\", \"id\");\n      });\n\n      it(\"should have a permanent identifier\", function () {\n        const runnable = new Runnable(\"foo\", () => {});\n        expect(runnable.id, \"to be\", runnable.id);\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/runner.spec.js",
    "content": "\"use strict\";\n\nconst path = require(\"node:path\");\nconst sinon = require(\"sinon\");\nconst Mocha = require(\"../../lib/mocha\");\nconst PendingError = require(\"../../lib/pending\");\nconst { Suite, Runner, Test, Hook, Runnable } = Mocha;\nconst { noop } = Mocha.utils;\nconst { FATAL, MULTIPLE_DONE, UNSUPPORTED } =\n  require(\"../../lib/error-constants\").constants;\n\nconst {\n  EVENT_HOOK_BEGIN,\n  EVENT_HOOK_END,\n  EVENT_TEST_FAIL,\n  EVENT_TEST_PASS,\n  EVENT_TEST_RETRY,\n  EVENT_TEST_END,\n  EVENT_RUN_END,\n  EVENT_SUITE_END,\n  STATE_IDLE,\n  STATE_RUNNING,\n  STATE_STOPPED,\n} = Runner.constants;\nconst { STATE_FAILED } = Mocha.Runnable.constants;\n\ndescribe(\"Runner\", function () {\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"instance method\", function () {\n    let suite;\n    let runner;\n    beforeEach(function () {\n      suite = new Suite(\"Suite\", \"root\");\n      runner = new Runner(suite, { cleanReferencesAfterRun: true });\n      runner.checkLeaks = true;\n    });\n\n    describe(\"grep()\", function () {\n      it(\"should update the runner.total with number of matched tests\", function () {\n        suite.addTest(new Test(\"im a test about lions\", noop));\n        suite.addTest(new Test(\"im another test about lions\", noop));\n        suite.addTest(new Test(\"im a test about bears\", noop));\n        var newRunner = new Runner(suite);\n        newRunner.grep(/lions/);\n        expect(newRunner.total, \"to be\", 2);\n      });\n\n      it(\"should update the runner.total with number of matched tests when inverted\", function () {\n        suite.addTest(new Test(\"im a test about lions\", noop));\n        suite.addTest(new Test(\"im another test about lions\", noop));\n        suite.addTest(new Test(\"im a test about bears\", noop));\n        var newRunner = new Runner(suite);\n        newRunner.grep(/lions/, true);\n        expect(newRunner.total, \"to be\", 1);\n      });\n    });\n\n    describe(\"grepTotal()\", function () {\n      it(\"should return the total number of matched tests\", function () {\n        suite.addTest(new Test(\"im a test about lions\", noop));\n        suite.addTest(new Test(\"im another test about lions\", noop));\n        suite.addTest(new Test(\"im a test about bears\", noop));\n        runner.grep(/lions/);\n        expect(runner.grepTotal(suite), \"to be\", 2);\n      });\n\n      it(\"should return the total number of matched tests when inverted\", function () {\n        suite.addTest(new Test(\"im a test about lions\", noop));\n        suite.addTest(new Test(\"im another test about lions\", noop));\n        suite.addTest(new Test(\"im a test about bears\", noop));\n        runner.grep(/lions/, true);\n        expect(runner.grepTotal(suite), \"to be\", 1);\n      });\n    });\n    describe(\"globalProps()\", function () {\n      it(\"should include common non enumerable globals\", function () {\n        var props = runner.globalProps();\n        expect(\n          props,\n          \"to contain\",\n          \"setTimeout\",\n          \"clearTimeout\",\n          \"setInterval\",\n          \"clearInterval\",\n          \"Date\",\n          \"XMLHttpRequest\",\n        );\n      });\n    });\n\n    describe(\"globals()\", function () {\n      it(\"should default to the known globals\", function () {\n        expect(runner.globals().length, \"to be greater than\", 16);\n      });\n\n      it(\"should white-list globals\", function () {\n        runner.globals([\"foo\", \"bar\"]);\n        expect(runner.globals(), \"to contain\", \"foo\", \"bar\");\n      });\n    });\n\n    describe(\"checkGlobals(test)\", function () {\n      before(function () {\n        if (!Object.create) {\n          this.skip();\n        }\n      });\n\n      it(\"should allow variables that match a wildcard\", function (done) {\n        runner.globals([\"foo*\", \"giz*\"]);\n        global.foo = \"baz\";\n        global.gizmo = \"quux\";\n        runner.checkGlobals();\n        delete global.foo;\n        delete global.gizmo;\n        done();\n      });\n\n      it('should emit \"fail\" when a new global is introduced', function (done) {\n        var test = new Test(\"im a test\", noop);\n        runner.checkGlobals();\n        global.foo = \"bar\";\n        runner.on(EVENT_TEST_FAIL, function (_test, _err) {\n          expect(_test, \"to be\", test);\n          expect(_err, \"to have message\", \"global leak(s) detected: 'foo'\");\n          delete global.foo;\n          done();\n        });\n        runner.checkGlobals(test);\n      });\n\n      it('should emit \"fail\" when a single new disallowed global is introduced after a single extra global is allowed', function (done) {\n        var doneCalled = false;\n        runner.globals(\"good\");\n        global.bad = 1;\n        runner.on(EVENT_TEST_FAIL, function () {\n          delete global.bad;\n          done();\n          doneCalled = true;\n        });\n        runner.checkGlobals(new Test(\"yet another test\", noop));\n        if (!doneCalled) {\n          done(Error(\"Expected test failure did not occur.\"));\n        }\n      });\n\n      it(\"should not fail when a new common global is introduced\", function () {\n        if (process.browser) {\n          this.skip();\n          return;\n        }\n        // verify that the prop isn't enumerable\n        expect(\n          Object.prototype.propertyIsEnumerable.call(global, \"XMLHttpRequest\"),\n          \"to be\",\n          false,\n        );\n\n        // create a new runner and keep a reference to the test.\n        var test = new Test(\"im a test about bears\", noop);\n        suite.addTest(test);\n        var newRunner = new Runner(suite);\n\n        // make the prop enumerable again.\n        global.XMLHttpRequest = noop;\n        expect(\n          Object.prototype.propertyIsEnumerable.call(global, \"XMLHttpRequest\"),\n          \"to be\",\n          true,\n        );\n\n        // verify the test hasn't failed.\n        newRunner.checkGlobals(test);\n        expect(test, \"not to have key\", \"state\");\n\n        // clean up our global space.\n        delete global.XMLHttpRequest;\n      });\n\n      it(\"should pluralize the error message when several are introduced\", function (done) {\n        var test = new Test(\"im a test\", noop);\n        runner.checkGlobals();\n        global.foo = \"bar\";\n        global.bar = \"baz\";\n        runner.on(EVENT_TEST_FAIL, function (_test, _err) {\n          expect(_test, \"to be\", test);\n          expect(\n            _err.message,\n            \"to be\",\n            \"global leak(s) detected: 'foo', 'bar'\",\n          );\n          delete global.foo;\n          delete global.bar;\n          done();\n        });\n        runner.checkGlobals(test);\n      });\n\n      it(\"should respect per test whitelisted globals\", function () {\n        var test = new Test(\"im a test about lions\", noop);\n        test.globals([\"foo\"]);\n\n        suite.addTest(test);\n        var runner = new Runner(suite);\n\n        global.foo = \"bar\";\n\n        // verify the test hasn't failed.\n        runner.checkGlobals(test);\n        expect(test, \"not to have key\", \"state\");\n\n        delete global.foo;\n      });\n\n      it(\"should respect per test whitelisted globals but still detect other leaks\", function (done) {\n        var test = new Test(\"im a test about lions\", noop);\n        test.globals([\"foo\"]);\n\n        suite.addTest(test);\n\n        global.foo = \"whitelisted\";\n        global.bar = \"detect-me\";\n        runner.on(EVENT_TEST_FAIL, function (_test, _err) {\n          expect(_test.title, \"to be\", \"im a test about lions\");\n          expect(_err, \"to have message\", \"global leak(s) detected: 'bar'\");\n          delete global.foo;\n          delete global.bar;\n          done();\n        });\n        runner.checkGlobals(test);\n      });\n\n      it('should emit \"fail\" when a global beginning with \"d\" is introduced', function (done) {\n        global.derp = \"bar\";\n        runner.on(EVENT_TEST_FAIL, function (_test, _err) {\n          expect(_test.title, \"to be\", \"herp\");\n          expect(_err, \"to have message\", \"global leak(s) detected: 'derp'\");\n          delete global.derp;\n          done();\n        });\n        runner.checkGlobals(new Test(\"herp\", noop));\n      });\n    });\n    describe(\"hook()\", function () {\n      it(\"should execute hooks after failed test if suite bail is true\", function (done) {\n        runner.fail(new Test(\"failed test\", noop), new Error());\n        suite.bail(true);\n        suite.afterEach(function () {\n          suite.afterAll(function () {\n            done();\n          });\n        });\n        runner.hook(\"afterEach\", noop);\n        runner.hook(\"afterAll\", noop);\n      });\n\n      it(\"should augment hook title with current test title\", function (done) {\n        var expectedHookTitle;\n        function assertHookTitle() {\n          expect(hook.title, \"to be\", expectedHookTitle);\n        }\n        var failHook = false;\n        var hookError = new Error(\"failed hook\");\n        suite.beforeEach(function () {\n          assertHookTitle();\n          if (failHook) {\n            throw hookError;\n          }\n        });\n        runner.on(EVENT_HOOK_BEGIN, assertHookTitle);\n        runner.on(EVENT_HOOK_END, assertHookTitle);\n        runner.on(EVENT_TEST_FAIL, assertHookTitle);\n        runner.on(EVENT_TEST_PASS, assertHookTitle);\n        var hook = suite._beforeEach[0];\n\n        suite.addTest(new Test(\"should behave\", noop));\n        suite.addTest(new Test(\"should obey\", noop));\n        runner.suite = suite;\n\n        runner.test = suite.tests[0];\n        expectedHookTitle = '\"before each\" hook for \"should behave\"';\n        runner.hook(\"beforeEach\", function (err) {\n          if (err && err !== hookError) return done(err);\n\n          runner.test = suite.tests[1];\n          failHook = true;\n          expectedHookTitle = '\"before each\" hook for \"should obey\"';\n          runner.hook(\"beforeEach\", function (err) {\n            if (err && err !== hookError) return done(err);\n            return done();\n          });\n        });\n      });\n    });\n\n    describe(\"fail()\", function () {\n      it(\"should increment `Runner#failures`\", function () {\n        expect(runner.failures, \"to be\", 0);\n        runner.fail(new Test(\"one\", noop), {});\n        expect(runner.failures, \"to be\", 1);\n        runner.fail(new Test(\"two\", noop), new Error());\n        expect(runner.failures, \"to be\", 2);\n      });\n\n      it('should set `Test#state` to \"failed\"', function () {\n        var test = new Test(\"some test\", noop);\n        runner.fail(test, \"some error\");\n        expect(test.state, \"to be\", STATE_FAILED);\n      });\n\n      it('should emit \"fail\"', function (done) {\n        var test = new Test(\"some other test\", noop);\n        var err = {};\n        runner.on(EVENT_TEST_FAIL, function (_test, _err) {\n          expect(_test, \"to be\", test);\n          expect(_err, \"to be an\", Error);\n          expect(_err, \"not to be\", {});\n          done();\n        });\n        runner.fail(test, err);\n      });\n\n      it(\"should emit a helpful message when failed with a string\", function (done) {\n        var test = new Test(\"helpful test\", noop);\n        var err = \"string\";\n        runner.on(EVENT_TEST_FAIL, function (_test, _err) {\n          expect(_err, \"to be an\", Error);\n          expect(\n            _err,\n            \"to have message\",\n            'the string \"string\" was thrown, throw an Error :)',\n          );\n          done();\n        });\n        runner.fail(test, err);\n      });\n\n      it(\"should emit a the error when failed with an Error instance\", function (done) {\n        var test = new Test(\"a test\", noop);\n        var err = new Error(\"an error message\");\n        runner.on(EVENT_TEST_FAIL, function (_test, _err) {\n          expect(_err, \"to be an\", Error);\n          expect(_err, \"to have message\", \"an error message\");\n          done();\n        });\n        runner.fail(test, err);\n      });\n\n      it(\"should emit the error when failed with an Error-like object\", function (done) {\n        var test = new Test(\"a test\", noop);\n        var err = { message: \"an error message\" };\n        runner.on(EVENT_TEST_FAIL, function (_test, _err) {\n          expect(_err, \"not to be an\", Error);\n          expect(_err.message, \"to be\", \"an error message\");\n          done();\n        });\n        runner.fail(test, err);\n      });\n\n      it(\"should emit a helpful message when failed with an Object\", function (done) {\n        var test = new Test(\"a test\", noop);\n        var err = { x: 1 };\n        runner.on(EVENT_TEST_FAIL, function (_test, _err) {\n          expect(_err, \"to be an\", Error);\n          expect(\n            _err,\n            \"to have message\",\n            'the object {\\n  \"x\": 1\\n} was thrown, throw an Error :)',\n          );\n          done();\n        });\n        runner.fail(test, err);\n      });\n\n      it(\"should emit a helpful message when failed with an Array\", function (done) {\n        var test = new Test(\"a test\", noop);\n        var err = [1, 2];\n        runner.on(EVENT_TEST_FAIL, function (_test, _err) {\n          expect(_err, \"to be an\", Error);\n          expect(\n            _err,\n            \"to have message\",\n            \"the array [\\n  1\\n  2\\n] was thrown, throw an Error :)\",\n          );\n          done();\n        });\n        runner.fail(test, err);\n      });\n\n      it(\"should recover if the error stack is not writable\", function (done) {\n        if (!Object.create) {\n          this.skip();\n          return;\n        }\n\n        var err = new Error(\"not evil\");\n        Object.defineProperty(err, \"stack\", {\n          value: err.stack,\n        });\n        var test = new Test(\"a test\", noop);\n\n        runner.on(EVENT_TEST_FAIL, function (_test, _err) {\n          expect(_err, \"to have message\", \"not evil\");\n          done();\n        });\n\n        runner.fail(test, err);\n      });\n\n      it(\"should return and not increment failures when test is pending\", function () {\n        var test = new Test(\"a test\");\n        suite.addTest(test);\n        test.pending = true;\n        runner.fail(test, new Error());\n        expect(runner.failures, \"to be\", 0);\n      });\n\n      describe(\"when Runner has stopped\", function () {\n        beforeEach(function () {\n          runner.state = STATE_STOPPED;\n        });\n\n        describe(\"when test is not pending\", function () {\n          describe('when error is the \"multiple done\" variety', function () {\n            it('should throw the \"multiple done\" error', function () {\n              var test = new Test(\"test\", function () {});\n              suite.addTest(test);\n              var err = new Error();\n              err.code = MULTIPLE_DONE;\n              expect(\n                function () {\n                  runner.fail(test, err);\n                },\n                \"to throw\",\n                err,\n              );\n            });\n          });\n\n          describe('when error is not of the \"multiple done\" variety', function () {\n            it('should throw a \"fatal\" error', function () {\n              var test = new Test(\"test\", function () {});\n              suite.addTest(test);\n              var err = new Error();\n              expect(\n                function () {\n                  runner.fail(test, err);\n                },\n                \"to throw\",\n                {\n                  code: FATAL,\n                },\n              );\n            });\n          });\n        });\n      });\n      it(\"should increment .failures\", function () {\n        expect(runner.failures, \"to be\", 0);\n        var test1 = new Test(\"fail hook 1\", noop);\n        var test2 = new Test(\"fail hook 2\", noop);\n        suite.addTest(test1);\n        suite.addTest(test2);\n        runner.fail(test1, new Error(\"error1\"));\n        expect(runner.failures, \"to be\", 1);\n        runner.fail(test2, new Error(\"error2\"));\n        expect(runner.failures, \"to be\", 2);\n      });\n\n      it('should emit \"fail\"', function (done) {\n        var hook = new Hook();\n        hook.parent = suite;\n        var err = new Error(\"error\");\n        runner.on(EVENT_TEST_FAIL, function (_hook, _err) {\n          expect(_hook, \"to be\", hook);\n          expect(_err, \"to be\", err);\n          done();\n        });\n        runner.fail(hook, err);\n      });\n\n      it('should not emit \"end\" if suite bail is not true', function (done) {\n        var hook = new Hook();\n        hook.parent = suite;\n        var err = new Error(\"error\");\n        suite.bail(false);\n        expect(\n          function () {\n            runner.fail(hook, err);\n          },\n          \"not to emit from\",\n          hook,\n          EVENT_RUN_END,\n        );\n        done();\n      });\n    });\n\n    describe(\"run()\", function () {\n      it('should emit \"retry\" when a retryable test fails', function (done) {\n        var retries = 2;\n        var retryableFails = 0;\n        var err = new Error(\"bear error\");\n\n        var test = new Test(\"im a test about bears\", function () {\n          if (retryableFails < retries) {\n            throw err;\n          }\n        });\n\n        suite.retries(retries);\n        suite.addTest(test);\n\n        runner.on(EVENT_TEST_RETRY, function (testClone, testErr) {\n          retryableFails += 1;\n          expect(testClone.title, \"to be\", test.title);\n          expect(testErr, \"to be\", err);\n        });\n\n        runner.run(function (failures) {\n          expect(failures, \"to be\", 0);\n          expect(retryableFails, \"to be\", retries);\n\n          done();\n        });\n      });\n\n      // karma-mocha is inexplicably doing this with a Hook\n      it(\"should not throw an exception if something emits EVENT_TEST_END with a non-Test object\", function () {\n        expect(function () {\n          runner.emit(EVENT_TEST_END, {});\n        }, \"not to throw\");\n      });\n\n      it(\"should clean references after a run\", function () {\n        runner = new Runner(suite, {\n          delay: false,\n          cleanReferencesAfterRun: true,\n        });\n        var cleanReferencesStub = sinon.stub(suite, \"cleanReferences\");\n        runner.run();\n        runner.emit(EVENT_SUITE_END, suite);\n        expect(cleanReferencesStub, \"was called once\");\n      });\n\n      it(\"should not clean references after a run when `cleanReferencesAfterRun` is `false`\", function () {\n        runner = new Runner(suite, {\n          delay: false,\n          cleanReferencesAfterRun: false,\n        });\n        var cleanReferencesStub = sinon.stub(suite, \"cleanReferences\");\n        runner.run();\n        runner.emit(EVENT_SUITE_END, suite);\n        expect(cleanReferencesStub, \"was not called\");\n      });\n\n      it(\"should not leak `Process.uncaughtException` listeners\", function (done) {\n        var normalUncaughtExceptionListenerCount =\n          process.listenerCount(\"uncaughtException\");\n\n        runner.run();\n        runner.run();\n        runner.run();\n        expect(\n          process.listenerCount(\"uncaughtException\"),\n          \"to be\",\n          normalUncaughtExceptionListenerCount + 1,\n        );\n        done();\n      });\n\n      describe(\"stack traces\", function () {\n        var stack = [\n          \"AssertionError: foo bar\",\n          \"at EventEmitter.<anonymous> (/usr/local/dev/test.js:16:12)\",\n          \"at Context.<anonymous> (/usr/local/dev/test.js:19:5)\",\n          \"Test.Runnable.run (/usr/local/lib/node_modules/mocha/lib/runnable.js:244:7)\",\n          \"Runner.runTest (/usr/local/lib/node_modules/mocha/lib/runner.js:374:10)\",\n          \"/usr/local/lib/node_modules/mocha/lib/runner.js:452:12\",\n          \"next (/usr/local/lib/node_modules/mocha/lib/runner.js:299:14)\",\n          \"/usr/local/lib/node_modules/mocha/lib/runner.js:309:7\",\n          \"next (/usr/local/lib/node_modules/mocha/lib/runner.js:248:23)\",\n          \"Immediate._onImmediate (/usr/local/lib/node_modules/mocha/lib/runner.js:276:5)\",\n          \"at processImmediate [as _immediateCallback] (timers.js:321:17)\",\n        ];\n\n        before(function () {\n          // Only for Node running on Windows\n          if (process.platform === \"win32\") {\n            var addDrive = function (str) {\n              var drive = \"C:\";\n              var pos = str.indexOf(path.posix.sep);\n              return pos !== -1\n                ? str.slice(0, pos) + drive + str.slice(pos)\n                : str;\n            };\n\n            var useWinPathSep = function (str) {\n              return str.split(path.posix.sep).join(path.win32.sep);\n            };\n\n            // Fake Windows pathnames in stacktrace\n            stack = stack.map(function (line) {\n              return useWinPathSep(addDrive(line));\n            });\n          }\n        });\n\n        describe(\"short\", function () {\n          before(function () {\n            if (process.browser) {\n              this.skip();\n            }\n          });\n\n          it(\"should prettify the stack-trace\", function (done) {\n            var hook = new Hook();\n            hook.parent = suite;\n            var err = new Error();\n            // Fake stack-trace\n            err.stack = stack.join(\"\\n\");\n\n            runner.on(EVENT_TEST_FAIL, function (_hook, _err) {\n              expect(_err.stack, \"to be\", stack.slice(0, 3).join(\"\\n\"));\n              done();\n            });\n            runner.fail(hook, err);\n          });\n\n          it(\"should prettify stack-traces in error cause trail\", function (done) {\n            var hook = new Hook();\n            hook.parent = suite;\n            var causeErr = new Error();\n            // Fake stack-trace\n            causeErr.stack = stack.join(\"\\n\");\n            var err = new Error();\n            err.cause = causeErr;\n\n            runner.on(EVENT_TEST_FAIL, function (_hook, _err) {\n              expect(_err.cause.stack, \"to be\", stack.slice(0, 3).join(\"\\n\"));\n              done();\n            });\n            runner.fail(hook, err);\n          });\n        });\n\n        describe(\"long\", function () {\n          it(\"should display the full stack-trace\", function (done) {\n            var hook = new Hook();\n            hook.parent = suite;\n            var err = new Error();\n            // Fake stack-trace\n            err.stack = stack.join(\"\\n\");\n            // Add --stack-trace option\n            runner.fullStackTrace = true;\n\n            runner.on(EVENT_TEST_FAIL, function (_hook, _err) {\n              expect(_err.stack, \"to be\", stack.join(\"\\n\"));\n              done();\n            });\n            runner.fail(hook, err);\n          });\n\n          it(\"should display full stack-traces in error cause trail\", function (done) {\n            var hook = new Hook();\n            hook.parent = suite;\n            var causeErr = new Error();\n            // Fake stack-trace\n            causeErr.stack = stack.join(\"\\n\");\n            var err = new Error();\n            err.cause = causeErr;\n            // Add --stack-trace option\n            runner.fullStackTrace = true;\n\n            runner.on(EVENT_TEST_FAIL, function (_hook, _err) {\n              expect(_err.cause.stack, \"to be\", stack.join(\"\\n\"));\n              done();\n            });\n            runner.fail(hook, err);\n          });\n        });\n\n        describe(\"ginormous\", function () {\n          before(function () {\n            if (process.browser) {\n              this.skip();\n            }\n          });\n\n          // Generate 64k string\n          function genOverlongSingleLineMessage() {\n            var n = 8200;\n            var data = [];\n            data.length = n;\n            for (var i = 0; i < n; i++) {\n              data[i] = { a: 1 };\n            }\n            return JSON.stringify(data);\n          }\n\n          // Generate 64k string\n          function genOverlongMultiLineMessage() {\n            var n = 1150;\n            var data = [];\n            data.length = n;\n            var str =\n              \"Lorem ipsum dolor sit amet, consectetur adipiscing elit.\";\n            for (var i = 0; i < n; i++) {\n              data[i] = str;\n            }\n            return data.join(\"\\n\");\n          }\n\n          it(\"should not hang if overlong error message is single line\", function (done) {\n            var hook = new Hook();\n            hook.parent = suite;\n            var message = genOverlongSingleLineMessage();\n            var err = new Error();\n            // Fake stack-trace\n            err.stack = [message].concat(stack).join(\"\\n\");\n\n            runner.on(EVENT_TEST_FAIL, function (_hook, _err) {\n              var filteredErrStack = _err.stack.split(\"\\n\").slice(1);\n              expect(\n                filteredErrStack.join(\"\\n\"),\n                \"to be\",\n                stack.slice(0, 3).join(\"\\n\"),\n              );\n              done();\n            });\n            runner.fail(hook, err);\n          });\n\n          it(\"should not hang if overlong error message is multiple lines\", function (done) {\n            var hook = new Hook();\n            hook.parent = suite;\n            var message = genOverlongMultiLineMessage();\n            var err = new Error();\n            // Fake stack-trace\n            err.stack = [message].concat(stack).join(\"\\n\");\n\n            runner.on(EVENT_TEST_FAIL, function (_hook, _err) {\n              var filteredErrStack = _err.stack.split(\"\\n\").slice(-3);\n              expect(\n                filteredErrStack.join(\"\\n\"),\n                \"to be\",\n                stack.slice(0, 3).join(\"\\n\"),\n              );\n              done();\n            });\n            runner.fail(hook, err);\n          });\n        });\n      });\n    });\n\n    describe(\"runAsync()\", function () {\n      beforeEach(function () {\n        sinon.stub(runner, \"run\").callsArgWithAsync(0, 42).returnsThis();\n      });\n\n      it(\"should return a Promise with a failure count\", async function () {\n        return expect(runner.runAsync(), \"to be fulfilled with\", 42);\n      });\n\n      it(\"should pass through options to Runner#run\", async function () {\n        await runner.runAsync({ foo: \"bar\" });\n        expect(runner.run, \"to have a call satisfying\", [\n          expect.it(\"to be a function\"),\n          { foo: \"bar\" },\n        ]).and(\"was called once\");\n      });\n    });\n\n    describe(\"dispose()\", function () {\n      it(\"should remove all listeners from itself\", function () {\n        runner.on(\"disposeShouldRemoveThis\", noop);\n        runner.dispose();\n        expect(runner.listenerCount(\"disposeShouldRemoveThis\"), \"to be\", 0);\n      });\n\n      it('should remove \"error\" listeners from a test', function () {\n        var fn = sinon.stub();\n        runner.test = new Test(\"test for dispose\", fn);\n        runner.runTest(noop);\n        // sanity check\n        expect(runner.test.listenerCount(\"error\"), \"to be\", 1);\n        runner.dispose();\n        expect(runner.test.listenerCount(\"error\"), \"to be\", 0);\n      });\n\n      it('should remove \"uncaughtException\" listeners from the process', function () {\n        var normalUncaughtExceptionListenerCount =\n          process.listenerCount(\"uncaughtException\");\n        runner.run(noop);\n        // sanity check\n        expect(\n          process.listenerCount(\"uncaughtException\"),\n          \"to be\",\n          normalUncaughtExceptionListenerCount + 1,\n        );\n        runner.dispose();\n        expect(\n          process.listenerCount(\"uncaughtException\"),\n          \"to be\",\n          normalUncaughtExceptionListenerCount,\n        );\n      });\n    });\n\n    describe(\"runTest()\", function () {\n      it(\"should return when no tests to run\", function () {\n        runner.test = undefined;\n        expect(runner.runTest(noop), \"to be undefined\");\n      });\n    });\n\n    describe(\"allowUncaught()\", function () {\n      it(\"should allow unhandled errors to propagate through\", function () {\n        var newRunner = new Runner(suite);\n        newRunner.allowUncaught = true;\n        newRunner.test = new Test(\"failing test\", function () {\n          throw new Error(\"allow unhandled errors\");\n        });\n        function fail() {\n          newRunner.runTest();\n        }\n        expect(fail, \"to throw\", \"allow unhandled errors\");\n      });\n\n      it(\"should not allow unhandled errors in sync hooks to propagate through\", function (done) {\n        suite.beforeEach(function () {\n          throw new Error();\n        });\n        var runner = new Runner(suite);\n        runner.allowUncaught = false;\n\n        // We are monkey patching here with runner.once and a hook.run wrapper to effectively\n        // capture thrown errors within the event loop phase where Runner.immediately executes\n        runner.once(EVENT_HOOK_BEGIN, function (hook) {\n          var _run = hook.run;\n          hook.run = function (fn) {\n            function throwError() {\n              _run.call(hook, fn);\n            }\n            expect(throwError, \"not to throw\");\n            done();\n          };\n        });\n\n        runner.hook(\"beforeEach\", noop);\n      });\n\n      it(\"should allow unhandled errors in sync hooks to propagate through\", function (done) {\n        suite.beforeEach(function () {\n          throw new Error(\"allow unhandled errors in sync hooks\");\n        });\n        var runner = new Runner(suite);\n        runner.allowUncaught = true;\n\n        runner.once(EVENT_HOOK_BEGIN, function (hook) {\n          var _run = hook.run;\n          hook.run = function (fn) {\n            function throwError() {\n              _run.call(hook, fn);\n            }\n            var expected = \"allow unhandled errors in sync hooks\";\n            expect(throwError, \"to throw\", expected);\n            done();\n          };\n        });\n\n        runner.hook(\"beforeEach\", noop);\n      });\n\n      it(\"async - should allow unhandled errors in hooks to propagate through\", function (done) {\n        // the `done` argument, although unused, it triggers the async path\n        // see this.async in the Runnable constructor\n        suite.beforeEach(function () {\n          throw new Error(\"allow unhandled errors in async hooks\");\n        });\n        var runner = new Runner(suite);\n        runner.allowUncaught = true;\n\n        runner.once(EVENT_HOOK_BEGIN, function (hook) {\n          var _run = hook.run;\n          hook.run = function (fn) {\n            function throwError() {\n              _run.call(hook, fn);\n            }\n            var expected = \"allow unhandled errors in async hooks\";\n            expect(throwError, \"to throw\", expected);\n            done();\n          };\n        });\n\n        runner.hook(\"beforeEach\", noop);\n      });\n    });\n\n    describe(\"abort()\", function () {\n      it(\"should set _abort property to true\", function () {\n        runner.abort();\n        expect(runner._abort, \"to be true\");\n      });\n\n      it(\"should return the Runner\", function () {\n        expect(runner.abort(), \"to be\", runner);\n      });\n    });\n\n    describe(\"_uncaught()\", function () {\n      describe(\"when called with a non-Runner context\", function () {\n        it(\"should throw\", function () {\n          expect(runner._uncaught.bind({}), \"to throw\", {\n            code: FATAL,\n          });\n        });\n      });\n    });\n\n    describe(\"uncaught()\", function () {\n      beforeEach(function () {\n        sinon.stub(runner, \"fail\");\n      });\n\n      describe(\"when allow-uncaught is set to true\", function () {\n        it(\"should propagate error and throw\", function () {\n          if (process.browser) this.skip();\n\n          var err = new Error(\"should rethrow err\");\n          runner.allowUncaught = true;\n          expect(\n            function () {\n              runner.uncaught(err);\n            },\n            \"to throw\",\n            \"should rethrow err\",\n          );\n        });\n      });\n\n      describe(\"when provided an object argument\", function () {\n        describe(\"when argument is not an Error\", function () {\n          var err;\n          beforeEach(function () {\n            err = { whatever: \"yolo\" };\n          });\n\n          it(\"should fail with a transient Runnable and a new Error coerced from the object\", function () {\n            runner.uncaught(err);\n\n            expect(runner.fail, \"to have all calls satisfying\", [\n              expect.it(\"to be a\", Runnable).and(\"to satisfy\", {\n                parent: runner.suite,\n                title: /uncaught error outside test suite/i,\n              }),\n              expect.it(\"to be an\", Error).and(\"to satisfy\", {\n                message: /throw an error/i,\n                uncaught: true,\n              }),\n            ]).and(\"was called once\");\n          });\n        });\n\n        describe(\"when argument is a PendingError\", function () {\n          it(\"should ignore argument and return\", function () {\n            var err = new PendingError();\n            expect(runner.uncaught(err), \"to be undefined\");\n          });\n        });\n\n        describe(\"when argument is an Error\", function () {\n          var err;\n          beforeEach(function () {\n            err = new Error(\"sorry dave\");\n          });\n\n          it('should add the \"uncaught\" property to the Error', function () {\n            runner.uncaught(err);\n            expect(err, \"to have property\", \"uncaught\", true);\n          });\n\n          describe(\"when no Runnables are running\", function () {\n            beforeEach(function () {\n              delete runner.currentRunnable;\n            });\n\n            it(\"should fail with a transient Runnable and the error\", function () {\n              runner.uncaught(err);\n\n              expect(runner.fail, \"to have all calls satisfying\", [\n                expect.it(\"to be a\", Runnable).and(\"to satisfy\", {\n                  parent: runner.suite,\n                  title: /uncaught error outside test suite/i,\n                }),\n                err,\n              ]).and(\"was called once\");\n            });\n\n            describe(\"when Runner is RUNNING\", function () {\n              beforeEach(function () {\n                runner.state = STATE_RUNNING;\n              });\n\n              it(\"should not emit start/end events\", function () {\n                expect(\n                  function () {\n                    runner.uncaught(err);\n                  },\n                  \"not to emit from\",\n                  runner,\n                  \"start\",\n                ).and(\"not to emit from\", runner, \"end\");\n              });\n            });\n\n            describe(\"when Runner is IDLE\", function () {\n              beforeEach(function () {\n                runner.state = STATE_IDLE;\n              });\n\n              it(\"should emit start/end events for the benefit of reporters\", function () {\n                expect(\n                  function () {\n                    runner.uncaught(err);\n                  },\n                  \"to emit from\",\n                  runner,\n                  \"start\",\n                ).and(\"to emit from\", runner, \"end\");\n              });\n            });\n\n            describe(\"when Runner is STOPPED\", function () {\n              beforeEach(function () {\n                runner.state = STATE_STOPPED;\n              });\n\n              it(\"should not emit start/end events, since this presumably would have already happened\", function () {\n                expect(\n                  function () {\n                    try {\n                      runner.uncaught(err);\n                    } catch {\n                      /* empty */\n                    }\n                  },\n                  \"not to emit from\",\n                  runner,\n                  \"start\",\n                ).and(\"not to emit from\", runner, \"end\");\n              });\n\n              it(\"should throw\", function () {\n                expect(function () {\n                  runner.uncaught(err);\n                }, \"to throw\");\n              });\n            });\n          });\n\n          describe(\"when a Runnable is running or has run\", function () {\n            var runnable;\n            beforeEach(function () {\n              runnable = new Runnable();\n              runnable.parent = runner.suite;\n              sinon.stub(runnable, \"clearTimeout\");\n              runner.currentRunnable = runnable;\n            });\n\n            it(\"should clear any pending timeouts\", function () {\n              runnable.callback = sinon.fake();\n              runner.uncaught(err);\n              expect(runnable.clearTimeout, \"was called times\", 1);\n            });\n\n            describe(\"when current Runnable has already failed\", function () {\n              beforeEach(function () {\n                sinon.stub(runnable, \"isFailed\").returns(true);\n              });\n\n              it(\"should not attempt to fail again\", function () {\n                runner.uncaught(err);\n                expect(runner.fail, \"was not called\");\n              });\n            });\n\n            describe(\"when current Runnable has been marked pending\", function () {\n              beforeEach(function () {\n                sinon.stub(runnable, \"isPending\").returns(true);\n              });\n\n              it(\"should attempt to fail\", function () {\n                runner.uncaught(err);\n                expect(runner.fail, \"was called once\");\n              });\n            });\n\n            describe(\"when the current Runnable has already passed\", function () {\n              beforeEach(function () {\n                sinon.stub(runnable, \"isPassed\").returns(true);\n              });\n\n              it(\"should fail with the current Runnable and the error\", function () {\n                runner.uncaught(err);\n\n                expect(runner.fail, \"to have all calls satisfying\", [\n                  expect.it(\"to be\", runnable),\n                  err,\n                ]).and(\"was called once\");\n              });\n\n              it(\"should abort the runner without emitting end event\", function () {\n                expect(\n                  function () {\n                    runner.uncaught(err);\n                  },\n                  \"not to emit from\",\n                  runner,\n                  \"end\",\n                );\n                expect(runner._abort, \"to be\", true);\n              });\n            });\n\n            describe(\"when the current Runnable is still running\", function () {\n              describe(\"when the current Runnable is a Test\", function () {\n                beforeEach(function () {\n                  runnable = new Test(\"goomba\", noop);\n                  runnable.parent = runner.suite;\n                  runner.currentRunnable = runnable;\n                  runnable.callback = sinon.fake();\n                });\n\n                it(\"should run callback(err) to handle failing and hooks\", function () {\n                  runner.uncaught(err);\n\n                  expect(runner.fail, \"was not called\");\n                  expect(runnable.callback, \"to have all calls satisfying\", [\n                    err,\n                  ]).and(\"was called once\");\n                });\n\n                it(\"should not notify test has ended\", function () {\n                  expect(\n                    function () {\n                      runner.uncaught(err);\n                    },\n                    \"not to emit from\",\n                    runner,\n                    EVENT_TEST_END,\n                  );\n                });\n\n                it(\"should not notify run has ended\", function () {\n                  expect(\n                    function () {\n                      runner.uncaught(err);\n                    },\n                    \"not to emit from\",\n                    runner,\n                    EVENT_RUN_END,\n                  );\n                });\n              });\n\n              describe(\"when the current Runnable is a Hook\", function () {\n                beforeEach(function () {\n                  runnable = new Hook();\n                  runnable.parent = runner.suite;\n                  runner.currentRunnable = runnable;\n                  runnable.callback = sinon.fake();\n                });\n\n                it(\"should run callback(err) to handle failing hook pattern\", function () {\n                  runner.uncaught(err);\n\n                  expect(runner.fail, \"was not called\");\n                  expect(runnable.callback, \"to have all calls satisfying\", [\n                    err,\n                  ]).and(\"was called once\");\n                });\n\n                it(\"should not notify test has ended\", function () {\n                  expect(\n                    function () {\n                      runner.uncaught(err);\n                    },\n                    \"not to emit from\",\n                    runner,\n                    EVENT_TEST_END,\n                  );\n                });\n\n                it(\"should not notify run has ended\", function () {\n                  expect(\n                    function () {\n                      runner.uncaught(err);\n                    },\n                    \"not to emit from\",\n                    runner,\n                    EVENT_RUN_END,\n                  );\n                });\n              });\n            });\n          });\n        });\n      });\n    });\n\n    describe(\"linkPartialObjects()\", function () {\n      it(\"should return the Runner\", function () {\n        expect(runner.linkPartialObjects(), \"to be\", runner);\n      });\n    });\n\n    describe(\"isParallelMode()\", function () {\n      it(\"should return false\", function () {\n        expect(runner.isParallelMode(), \"to be false\");\n      });\n    });\n\n    describe(\"workerReporter()\", function () {\n      it(\"should throw\", function () {\n        expect(() => runner.workerReporter(), \"to throw\", {\n          code: UNSUPPORTED,\n        });\n      });\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/suite.spec.js",
    "content": "\"use strict\";\n\nconst Mocha = require(\"../../lib/mocha\");\nconst { Suite, Test, Context } = Mocha;\nconst sinon = require(\"sinon\");\nconst errors = require(\"../../lib/errors\");\n\nfunction supportsFunctionNames() {\n  return function foo() {}.name === \"foo\";\n}\n\ndescribe(\"Suite\", function () {\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"instance method\", function () {\n    let suite;\n\n    describe(\"clone()\", function () {\n      beforeEach(function () {\n        suite = new Suite(\"To be cloned\", {}, true);\n        suite._timeout = 3043;\n        suite._slow = 101;\n        suite._bail = true;\n        suite.suites.push(1);\n        suite.tests.push(\"hello\");\n        suite._beforeEach.push(2);\n        suite._beforeAll.push(3);\n        suite._afterEach.push(4);\n        suite._afterAll.push(5);\n      });\n\n      it(\"should clone the Suite, omitting children\", function () {\n        expect(suite.clone(), \"to satisfy\", {\n          title: \"To be cloned\",\n          _timeout: 3043,\n          _slow: 101,\n          _bail: true,\n          suites: expect.it(\"to be empty\"),\n          tests: expect.it(\"to be empty\"),\n          _beforeEach: expect.it(\"to be empty\"),\n          _beforeAll: expect.it(\"to be empty\"),\n          _afterEach: expect.it(\"to be empty\"),\n          _afterAll: expect.it(\"to be empty\"),\n          root: true,\n        }).and(\"not to be\", suite);\n      });\n    });\n\n    describe(\"reset()\", function () {\n      beforeEach(function () {\n        suite = new Suite(\"Suite to be reset\", function () {});\n      });\n\n      it(\"should reset the `delayed` state\", function () {\n        suite.delayed = true;\n        suite.reset();\n        expect(suite.delayed, \"to be\", false);\n      });\n\n      it(\"should forward reset to suites and tests\", function () {\n        const childSuite = new Suite(\"child suite\", suite.context);\n        const test = new Test(\"test\", function () {});\n        suite.addSuite(childSuite);\n        suite.addTest(test);\n        const testResetStub = sinon.stub(test, \"reset\");\n        const suiteResetStub = sinon.stub(childSuite, \"reset\");\n        suite.reset();\n        expect(testResetStub, \"was called once\");\n        expect(suiteResetStub, \"was called once\");\n      });\n\n      it(\"should forward reset to all hooks\", function () {\n        suite.beforeEach(function () {});\n        suite.afterEach(function () {});\n        suite.beforeAll(function () {});\n        suite.afterAll(function () {});\n        sinon.stub(suite.getHooks(\"beforeEach\")[0], \"reset\");\n        sinon.stub(suite.getHooks(\"afterEach\")[0], \"reset\");\n        sinon.stub(suite.getHooks(\"beforeAll\")[0], \"reset\");\n        sinon.stub(suite.getHooks(\"afterAll\")[0], \"reset\");\n\n        suite.reset();\n\n        expect(suite.getHooks(\"beforeEach\")[0].reset, \"was called once\");\n        expect(suite.getHooks(\"afterEach\")[0].reset, \"was called once\");\n        expect(suite.getHooks(\"beforeAll\")[0].reset, \"was called once\");\n        expect(suite.getHooks(\"afterAll\")[0].reset, \"was called once\");\n      });\n    });\n\n    describe(\"timeout()\", function () {\n      beforeEach(function () {\n        suite = new Suite(\"A Suite\");\n      });\n\n      describe(\"when no argument is passed\", function () {\n        it(\"should return the timeout value\", function () {\n          expect(suite.timeout(), \"to be\", 2000);\n        });\n      });\n\n      describe(\"when argument is passed\", function () {\n        it(\"should return the Suite object\", function () {\n          const newSuite = suite.timeout(5000);\n          expect(newSuite.timeout(), \"to be\", 5000);\n        });\n      });\n    });\n\n    describe(\"slow()\", function () {\n      beforeEach(function () {\n        suite = new Suite(\"A Suite\");\n      });\n\n      describe(\"when given a string\", function () {\n        it(\"should parse it\", function () {\n          suite.slow(\"5 seconds\");\n          expect(suite.slow(), \"to be\", 5000);\n        });\n      });\n\n      describe(\"when no argument is passed\", function () {\n        it(\"should return the slow value\", function () {\n          expect(suite.slow(), \"to be\", 75);\n        });\n      });\n\n      describe(\"when argument is passed\", function () {\n        it(\"should return the Suite object\", function () {\n          const newSuite = suite.slow(5000);\n          expect(newSuite.slow(), \"to be\", 5000);\n        });\n      });\n    });\n\n    describe(\"bail()\", function () {\n      beforeEach(function () {\n        suite = new Suite(\"A Suite\");\n        suite._bail = true;\n      });\n\n      describe(\"when no argument is passed\", function () {\n        it(\"should return the bail value\", function () {\n          expect(suite.bail(), \"to be\", true);\n        });\n      });\n\n      describe(\"when argument is passed\", function () {\n        it(\"should return the Suite object\", function () {\n          const newSuite = suite.bail(false);\n          expect(newSuite.bail(), \"to be\", false);\n        });\n      });\n    });\n\n    describe(\"beforeAll()\", function () {\n      beforeEach(function () {\n        suite = new Suite(\"A Suite\");\n      });\n\n      describe(\"wraps the passed in function in a Hook\", function () {\n        it(\"adds it to _beforeAll\", function () {\n          const fn = function () {};\n          suite.beforeAll(fn);\n\n          expect(suite._beforeAll, \"to have length\", 1);\n          const beforeAllItem = suite._beforeAll[0];\n          expect(beforeAllItem.title, \"to match\", /^\"before all\" hook/);\n          expect(beforeAllItem.fn, \"to be\", fn);\n        });\n\n        it(\"appends title to hook\", function () {\n          const fn = function () {};\n          suite.beforeAll(\"test\", fn);\n\n          expect(suite._beforeAll, \"to have length\", 1);\n          const beforeAllItem = suite._beforeAll[0];\n          expect(beforeAllItem.title, \"to be\", '\"before all\" hook: test');\n          expect(beforeAllItem.fn, \"to be\", fn);\n        });\n\n        it(\"uses function name if available\", function () {\n          if (!supportsFunctionNames()) {\n            this.skip();\n            return;\n          }\n          function namedFn() {}\n          suite.beforeAll(namedFn);\n          const beforeAllItem = suite._beforeAll[0];\n          expect(beforeAllItem.title, \"to be\", '\"before all\" hook: namedFn');\n          expect(beforeAllItem.fn, \"to be\", namedFn);\n        });\n      });\n    });\n\n    describe(\"afterAll()\", function () {\n      beforeEach(function () {\n        suite = new Suite(\"A Suite\");\n      });\n\n      describe(\"wraps the passed in function in a Hook\", function () {\n        it(\"adds it to _afterAll\", function () {\n          const fn = function () {};\n          suite.afterAll(fn);\n\n          expect(suite._afterAll, \"to have length\", 1);\n          const afterAllItem = suite._afterAll[0];\n          expect(afterAllItem.title, \"to match\", /^\"after all\" hook/);\n          expect(afterAllItem.fn, \"to be\", fn);\n        });\n        it(\"appends title to hook\", function () {\n          const fn = function () {};\n          suite.afterAll(\"test\", fn);\n\n          expect(suite._afterAll, \"to have length\", 1);\n          const beforeAllItem = suite._afterAll[0];\n          expect(beforeAllItem.title, \"to be\", '\"after all\" hook: test');\n          expect(beforeAllItem.fn, \"to be\", fn);\n        });\n\n        it(\"uses function name if available\", function () {\n          if (!supportsFunctionNames()) {\n            this.skip();\n            return;\n          }\n          function namedFn() {}\n          suite.afterAll(namedFn);\n          const afterAllItem = suite._afterAll[0];\n          expect(afterAllItem.title, \"to be\", '\"after all\" hook: namedFn');\n          expect(afterAllItem.fn, \"to be\", namedFn);\n        });\n      });\n    });\n\n    describe(\"beforeEach()\", function () {\n      let suite;\n\n      beforeEach(function () {\n        suite = new Suite(\"A Suite\");\n      });\n\n      describe(\"wraps the passed in function in a Hook\", function () {\n        it(\"adds it to _beforeEach\", function () {\n          const fn = function () {};\n          suite.beforeEach(fn);\n\n          expect(suite._beforeEach, \"to have length\", 1);\n          const beforeEachItem = suite._beforeEach[0];\n          expect(beforeEachItem.title, \"to match\", /^\"before each\" hook/);\n          expect(beforeEachItem.fn, \"to be\", fn);\n        });\n\n        it(\"appends title to hook\", function () {\n          const fn = function () {};\n          suite.beforeEach(\"test\", fn);\n\n          expect(suite._beforeEach, \"to have length\", 1);\n          const beforeAllItem = suite._beforeEach[0];\n          expect(beforeAllItem.title, \"to be\", '\"before each\" hook: test');\n          expect(beforeAllItem.fn, \"to be\", fn);\n        });\n\n        it(\"uses function name if available\", function () {\n          if (!supportsFunctionNames()) {\n            this.skip();\n            return;\n          }\n          function namedFn() {}\n          suite.beforeEach(namedFn);\n          const beforeEachItem = suite._beforeEach[0];\n          expect(beforeEachItem.title, \"to be\", '\"before each\" hook: namedFn');\n          expect(beforeEachItem.fn, \"to be\", namedFn);\n        });\n      });\n\n      describe(\"when the suite is pending\", function () {\n        beforeEach(function () {\n          suite.pending = true;\n        });\n\n        it(\"should not create a hook\", function () {\n          suite.beforeEach(function () {});\n          expect(suite._beforeEach, \"to be empty\");\n        });\n      });\n    });\n\n    describe(\"afterEach()\", function () {\n      beforeEach(function () {\n        suite = new Suite(\"A Suite\");\n      });\n\n      describe(\"wraps the passed in function in a Hook\", function () {\n        it(\"adds it to _afterEach\", function () {\n          const fn = function () {};\n          suite.afterEach(fn);\n\n          expect(suite._afterEach, \"to have length\", 1);\n          const afterEachItem = suite._afterEach[0];\n          expect(afterEachItem.title, \"to match\", /^\"after each\" hook/);\n          expect(afterEachItem.fn, \"to be\", fn);\n        });\n\n        it(\"appends title to hook\", function () {\n          const fn = function () {};\n          suite.afterEach(\"test\", fn);\n\n          expect(suite._afterEach, \"to have length\", 1);\n          const beforeAllItem = suite._afterEach[0];\n          expect(beforeAllItem.title, \"to be\", '\"after each\" hook: test');\n          expect(beforeAllItem.fn, \"to be\", fn);\n        });\n\n        it(\"uses function name if available\", function () {\n          if (!supportsFunctionNames()) {\n            this.skip();\n            return;\n          }\n          function namedFn() {}\n          suite.afterEach(namedFn);\n          const afterEachItem = suite._afterEach[0];\n          expect(afterEachItem.title, \"to be\", '\"after each\" hook: namedFn');\n          expect(afterEachItem.fn, \"to be\", namedFn);\n        });\n      });\n    });\n\n    describe(\"create()\", function () {\n      let first;\n      let second;\n\n      before(function () {\n        first = new Suite(\"Root suite\", {}, true);\n        second = new Suite(\"RottenRoot suite\", {}, true);\n        first.addSuite(second);\n      });\n\n      it(\"does not create a second root suite\", function () {\n        expect(second.parent, \"to be\", first);\n        expect(first.root, \"to be\", true);\n        expect(second.root, \"to be\", false);\n      });\n\n      it(\"does not denote the root suite by being titleless\", function () {\n        const emptyTitleSuite = Suite.create(second, \"\");\n        expect(emptyTitleSuite.parent, \"to be\", second);\n        expect(emptyTitleSuite.root, \"to be\", false);\n        expect(second.root, \"to be\", false);\n      });\n    });\n\n    describe(\"addSuite()\", function () {\n      let first;\n      let second;\n\n      beforeEach(function () {\n        first = new Suite(\"First suite\");\n        first.timeout(4002);\n        first.slow(200);\n        second = new Suite(\"Second suite\");\n        first.addSuite(second);\n      });\n\n      it(\"sets the parent on the added Suite\", function () {\n        expect(second.parent, \"to be\", first);\n      });\n\n      it(\"copies the timeout value\", function () {\n        expect(second.timeout(), \"to be\", 4002);\n      });\n\n      it(\"copies the slow value\", function () {\n        expect(second.slow(), \"to be\", 200);\n      });\n\n      it(\"adds the suite to the suites collection\", function () {\n        expect(first.suites, \"to have length\", 1);\n        expect(first.suites[0], \"to be\", second);\n      });\n\n      it(\"treats suite as pending if its parent is pending\", function () {\n        first.pending = true;\n        expect(second.isPending(), \"to be\", true);\n      });\n    });\n\n    describe(\"addTest()\", function () {\n      let test;\n\n      beforeEach(function () {\n        suite = new Suite(\"A Suite\", new Context());\n        suite.timeout(4002);\n        test = new Test(\"test\");\n        suite.addTest(test);\n      });\n\n      it(\"sets the parent on the added test\", function () {\n        expect(test.parent, \"to be\", suite);\n      });\n\n      it(\"copies the timeout value\", function () {\n        expect(test.timeout(), \"to be\", 4002);\n      });\n\n      it(\"adds the test to the tests collection\", function () {\n        expect(suite.tests, \"to satisfy\", [test]).and(\"to have length\", 1);\n      });\n    });\n\n    describe(\"fullTitle()\", function () {\n      beforeEach(function () {\n        suite = new Suite(\"A Suite\");\n      });\n\n      describe(\"when there is no parent\", function () {\n        it(\"returns the suite title\", function () {\n          expect(suite.fullTitle(), \"to be\", \"A Suite\");\n        });\n      });\n\n      describe(\"when there is a parent\", function () {\n        it(\"returns the combination of parent's and suite's title\", function () {\n          const parentSuite = new Suite(\"I am a parent\");\n          parentSuite.addSuite(suite);\n          expect(suite.fullTitle(), \"to be\", \"I am a parent A Suite\");\n        });\n      });\n    });\n\n    describe(\"titlePath()\", function () {\n      beforeEach(function () {\n        suite = new Suite(\"A Suite\");\n      });\n\n      describe(\"when there is no parent\", function () {\n        it(\"returns the suite title\", function () {\n          expect(suite.titlePath(), \"to equal\", [\"A Suite\"]);\n        });\n      });\n\n      describe(\"when there is a parent\", function () {\n        describe(\"the parent is the root suite\", function () {\n          it(\"returns the suite title\", function () {\n            const rootSuite = new Suite(\"\", {}, true);\n            rootSuite.addSuite(suite);\n            expect(suite.titlePath(), \"to equal\", [\"A Suite\"]);\n          });\n        });\n\n        describe(\"the parent is not the root suite\", function () {\n          it(\"returns the concatenation of parent's and suite's title\", function () {\n            const parentSuite = new Suite(\"I am a parent\");\n            parentSuite.addSuite(suite);\n            expect(suite.titlePath(), \"to equal\", [\"I am a parent\", \"A Suite\"]);\n          });\n        });\n      });\n    });\n\n    describe(\"total()\", function () {\n      beforeEach(function () {\n        suite = new Suite(\"A Suite\");\n      });\n\n      describe(\"when there are no nested suites or tests\", function () {\n        it(\"should return 0\", function () {\n          expect(suite.total(), \"to be\", 0);\n        });\n      });\n\n      describe(\"when there are several tests in the suite\", function () {\n        it(\"should return the number\", function () {\n          suite.addTest(new Test(\"a child test\"));\n          suite.addTest(new Test(\"another child test\"));\n          expect(suite.total(), \"to be\", 2);\n        });\n      });\n    });\n\n    describe(\"eachTest(fn)\", function () {\n      beforeEach(function () {\n        suite = new Suite(\"A Suite\");\n      });\n\n      describe(\"when there are no nested suites or tests\", function () {\n        it(\"should return 0\", function () {\n          let n = 0;\n          function fn() {\n            n++;\n          }\n          suite.eachTest(fn);\n          expect(n, \"to be\", 0);\n        });\n      });\n\n      describe(\"when there are several tests in the suite\", function () {\n        it(\"should return the number\", function () {\n          suite.addTest(new Test(\"a child test\"));\n          suite.addTest(new Test(\"another child test\"));\n\n          let n = 0;\n          function fn() {\n            n++;\n          }\n          suite.eachTest(fn);\n          expect(n, \"to be\", 2);\n        });\n      });\n\n      describe(\"when there are several levels of nested suites\", function () {\n        it(\"should return the number\", function () {\n          suite.addTest(new Test(\"a child test\"));\n          const childSuite = new Suite(\"a child suite\");\n          childSuite.addTest(new Test(\"a test in a child suite\"));\n          suite.addSuite(childSuite);\n\n          let n = 0;\n          function fn() {\n            n++;\n          }\n          suite.eachTest(fn);\n          expect(n, \"to be\", 2);\n        });\n      });\n    });\n\n    describe(\"constructor\", function () {\n      beforeEach(function () {\n        sinon.stub(errors, \"deprecate\");\n      });\n\n      /* eslint no-new: off */\n      it(\"should throw an error if the title isn't a string\", function () {\n        expect(function () {\n          new Suite(undefined, \"root\");\n        }, \"to throw\");\n\n        expect(function () {\n          new Suite(function () {}, \"root\");\n        }, \"to throw\");\n      });\n\n      it(\"should not throw if the title is a string\", function () {\n        expect(function () {\n          new Suite(\"Bdd suite\", \"root\");\n        }, \"not to throw\");\n      });\n    });\n\n    describe(\"timeout()\", function () {\n      it(\"should convert a string to milliseconds\", function () {\n        const suite = new Suite(\"some suite\");\n        suite.timeout(\"100\");\n        expect(suite.timeout(), \"to be\", 100);\n      });\n    });\n\n    describe(\"hasOnly()\", function () {\n      it(\"should return true if a test has `only`\", function () {\n        const suite = new Suite(\"foo\");\n        const test = new Test(\"bar\");\n\n        suite.appendOnlyTest(test);\n\n        expect(suite.hasOnly(), \"to be\", true);\n      });\n\n      it(\"should return true if a suite has `only`\", function () {\n        const suite = new Suite(\"foo\");\n        const nested = new Suite(\"bar\");\n\n        suite.appendOnlySuite(nested);\n\n        expect(suite.hasOnly(), \"to be\", true);\n      });\n\n      it(\"should return true if nested suite has `only`\", function () {\n        const suite = new Suite(\"foo\");\n        const nested = new Suite(\"bar\");\n        const test = new Test(\"baz\");\n\n        nested.appendOnlyTest(test);\n        // `nested` has a `only` test, but `suite` doesn't know about it\n        suite.suites.push(nested);\n\n        expect(suite.hasOnly(), \"to be\", true);\n      });\n\n      it(\"should return false if no suite or test is marked `only`\", function () {\n        const suite = new Suite(\"foo\");\n        const nested = new Suite(\"bar\");\n        const test = new Test(\"baz\");\n\n        suite.suites.push(nested);\n        nested.tests.push(test);\n\n        expect(suite.hasOnly(), \"to be\", false);\n      });\n    });\n\n    describe(\"filterOnly()\", function () {\n      it(\"should filter out all other tests and suites if a test has `only`\", function () {\n        const suite = new Suite(\"a\");\n        const nested = new Suite(\"b\");\n        const test = new Test(\"c\");\n        const test2 = new Test(\"d\");\n\n        suite.suites.push(nested);\n        suite.appendOnlyTest(test);\n        suite.tests.push(test2);\n\n        suite.filterOnly();\n\n        expect(suite, \"to satisfy\", {\n          suites: expect.it(\"to be empty\"),\n          tests: expect\n            .it(\"to have length\", 1)\n            .and(\"to have an item satisfying\", { title: \"c\" }),\n        });\n      });\n\n      it(\"should filter out all other tests and suites if a suite has `only`\", function () {\n        const suite = new Suite(\"a\");\n        const nested1 = new Suite(\"b\");\n        const nested2 = new Suite(\"c\");\n        const test = new Test(\"d\");\n        const nestedTest = new Test(\"e\");\n\n        nested1.appendOnlyTest(nestedTest);\n\n        suite.tests.push(test);\n        suite.suites.push(nested1);\n        suite.appendOnlySuite(nested1);\n        suite.suites.push(nested2);\n\n        suite.filterOnly();\n\n        expect(suite, \"to satisfy\", {\n          suites: expect\n            .it(\"to have length\", 1)\n            .and(\"to have an item satisfying\", { title: \"b\" }),\n          tests: expect.it(\"to be empty\"),\n        });\n      });\n    });\n\n    describe(\"markOnly()\", function () {\n      it(\"should call appendOnlySuite on parent\", function () {\n        const suite = new Suite(\"foo\");\n        const spy = sinon.spy();\n        suite.parent = {\n          appendOnlySuite: spy,\n        };\n        suite.markOnly();\n\n        expect(spy, \"to have a call exhaustively satisfying\", [suite]).and(\n          \"was called once\",\n        );\n      });\n    });\n  });\n});\n\ndescribe(\"Test\", function () {\n  describe(\"initialization\", function () {\n    it(\"should throw an error if the title isn't a string\", function () {\n      expect(function () {\n        new Test(function () {});\n      }, \"to throw\");\n\n      expect(() => {\n        new Test(undefined, function () {});\n      }, \"to throw\");\n    });\n\n    it(\"should not throw if the title is a string\", function () {\n      expect(function () {\n        new Test(\"test-case\", function () {});\n      }, \"not to throw\");\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/test.spec.js",
    "content": "\"use strict\";\n\nvar sinon = require(\"sinon\");\nvar mocha = require(\"../../lib/mocha\");\nvar Test = mocha.Test;\nvar Runnable = mocha.Runnable;\n\ndescribe(\"Test\", function () {\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\".clone()\", function () {\n    beforeEach(function () {\n      this._test = new Test(\"To be cloned\", function () {});\n      this._test._timeout = 3043;\n      this._test._slow = 101;\n      this._test._retries = 3;\n      this._test._currentRetry = 1;\n      this._test._allowedGlobals = [\"foo\"];\n      this._test.parent = \"foo\";\n      this._test.file = \"bar\";\n    });\n\n    it(\"should copy the title\", function () {\n      expect(this._test.clone().title, \"to be\", \"To be cloned\");\n    });\n\n    it(\"should copy the timeout value\", function () {\n      expect(this._test.clone().timeout(), \"to be\", 3043);\n    });\n\n    it(\"should copy the slow value\", function () {\n      expect(this._test.clone().slow(), \"to be\", 101);\n    });\n\n    it(\"should copy the retries value\", function () {\n      expect(this._test.clone().retries(), \"to be\", 3);\n    });\n\n    it(\"should copy the currentRetry value\", function () {\n      expect(this._test.clone().currentRetry(), \"to be\", 1);\n    });\n\n    it(\"should add/keep the retriedTest value\", function () {\n      var clone1 = this._test.clone();\n      expect(clone1.retriedTest(), \"to be\", this._test);\n      expect(clone1.clone().retriedTest(), \"to be\", this._test);\n    });\n\n    it(\"should copy the globals value\", function () {\n      expect(this._test.clone().globals(), \"not to be empty\");\n    });\n\n    it(\"should copy the parent value\", function () {\n      expect(this._test.clone().parent, \"to be\", \"foo\");\n    });\n\n    it(\"should copy the file value\", function () {\n      expect(this._test.clone().file, \"to be\", \"bar\");\n    });\n  });\n\n  describe(\".reset()\", function () {\n    beforeEach(function () {\n      this._test = new Test(\"Test to be reset\", function () {});\n    });\n\n    it(\"should reset the run state\", function () {\n      this._test.pending = true;\n      this._test.reset();\n      expect(this._test.pending, \"to be\", false);\n    });\n\n    it(\"should call Runnable.reset\", function () {\n      var runnableResetStub = sinon.stub(Runnable.prototype, \"reset\");\n      this._test.reset();\n      expect(runnableResetStub, \"was called once\");\n    });\n  });\n\n  describe(\".isPending()\", function () {\n    beforeEach(function () {\n      this._test = new Test(\"Is it skipped\", function () {});\n    });\n\n    it(\"should not be pending by default\", function () {\n      expect(this._test.isPending(), \"not to be\", true);\n    });\n\n    it(\"should be pending when marked as such\", function () {\n      this._test.pending = true;\n      expect(this._test.isPending(), \"to be\", true);\n    });\n\n    it(\"should be pending when its parent is pending\", function () {\n      this._test.parent = {\n        isPending: function () {\n          return true;\n        },\n      };\n      expect(this._test.isPending(), \"to be\", true);\n    });\n  });\n\n  describe(\".markOnly()\", function () {\n    afterEach(function () {\n      sinon.restore();\n    });\n\n    it(\"should call appendOnlyTest on parent\", function () {\n      var test = new Test(\"foo\");\n      var spy = sinon.spy();\n      test.parent = {\n        appendOnlyTest: spy,\n      };\n      test.markOnly();\n\n      expect(spy, \"to have a call exhaustively satisfying\", [test]).and(\n        \"was called once\",\n      );\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/throw.spec.js",
    "content": "\"use strict\";\n\n/* eslint no-throw-literal: off */\n\nvar sinon = require(\"sinon\");\nvar Mocha = require(\"../../lib/mocha\");\nvar Suite = Mocha.Suite;\nvar Test = Mocha.Test;\nvar Runnable = Mocha.Runnable;\nvar Runner = Mocha.Runner;\nvar EVENT_RUN_END = Runner.constants.EVENT_RUN_END;\nvar STATE_FAILED = Runnable.constants.STATE_FAILED;\n\ndescribe(\"a test that throws\", function () {\n  var suite;\n  var runner;\n  var uncaughtHandlers;\n\n  beforeEach(function () {\n    suite = new Suite(\"Suite\", \"root\");\n    runner = new Runner(suite);\n\n    // see https://github.com/mochajs/mocha/pull/2983#issuecomment-350428522\n    uncaughtHandlers = process.listeners(\"uncaughtException\") || [];\n    process.removeAllListeners(\"uncaughtException\");\n  });\n\n  afterEach(function () {\n    process.removeAllListeners(\"uncaughtException\");\n    uncaughtHandlers.forEach(function (listener) {\n      process.on(\"uncaughtException\", listener);\n    });\n    sinon.restore();\n  });\n\n  describe(\"non-extensible\", function () {\n    it(\"should not pass if throwing sync and test is sync\", function (done) {\n      var test = new Test(\"im sync and throw string sync\", function () {\n        throw \"non-extensible\";\n      });\n      suite.addTest(test);\n      runner = new Runner(suite);\n      runner.on(EVENT_RUN_END, function () {\n        expect(runner.failures, \"to be\", 1);\n        expect(test.state, \"to be\", STATE_FAILED);\n        done();\n      });\n      runner.run();\n    });\n\n    it(\"should not pass if throwing sync and test is async\", function (done) {\n      var test = new Test(\"im async and throw string sync\", function () {\n        throw \"non-extensible\";\n      });\n      suite.addTest(test);\n      runner = new Runner(suite);\n      runner.on(EVENT_RUN_END, function () {\n        expect(runner.failures, \"to be\", 1);\n        expect(test.state, \"to be\", STATE_FAILED);\n        done();\n      });\n      runner.run();\n    });\n\n    it(\"should not pass if throwing async and test is async\", function (done) {\n      var test = new Test(\"im async and throw string async\", function () {\n        process.nextTick(function () {\n          throw \"non-extensible\";\n        });\n      });\n      suite.addTest(test);\n      runner = new Runner(suite);\n      runner.on(EVENT_RUN_END, function () {\n        expect(runner.failures, \"to be\", 1);\n        expect(test.state, \"to be\", STATE_FAILED);\n        done();\n      });\n      runner.run();\n    });\n  });\n\n  describe(\"undefined\", function () {\n    it(\"should not pass if throwing sync and test is sync\", function (done) {\n      var test = new Test(\"im sync and throw undefined sync\", function () {\n        throw undefined;\n      });\n      suite.addTest(test);\n      runner = new Runner(suite);\n      runner.on(EVENT_RUN_END, function () {\n        expect(runner.failures, \"to be\", 1);\n        expect(test.state, \"to be\", STATE_FAILED);\n        done();\n      });\n      runner.run();\n    });\n\n    it(\"should not pass if throwing sync and test is async\", function (done) {\n      var test = new Test(\"im async and throw undefined sync\", function () {\n        throw undefined;\n      });\n      suite.addTest(test);\n      runner = new Runner(suite);\n      runner.on(EVENT_RUN_END, function () {\n        expect(runner.failures, \"to be\", 1);\n        expect(test.state, \"to be\", STATE_FAILED);\n        done();\n      });\n      runner.run();\n    });\n\n    it(\"should not pass if throwing async and test is async\", function (done) {\n      var test = new Test(\"im async and throw undefined async\", function () {\n        process.nextTick(function () {\n          throw undefined;\n        });\n      });\n      suite.addTest(test);\n      runner = new Runner(suite);\n      runner.on(EVENT_RUN_END, function () {\n        expect(runner.failures, \"to be\", 1);\n        expect(test.state, \"to be\", STATE_FAILED);\n        done();\n      });\n      runner.run();\n    });\n  });\n\n  describe(\"null\", function () {\n    it(\"should not pass if throwing sync and test is sync\", function (done) {\n      var test = new Test(\"im sync and throw null sync\", function () {\n        throw null;\n      });\n      suite.addTest(test);\n      runner = new Runner(suite);\n      runner.on(EVENT_RUN_END, function () {\n        expect(runner.failures, \"to be\", 1);\n        expect(test.state, \"to be\", STATE_FAILED);\n        done();\n      });\n      runner.run();\n    });\n\n    it(\"should not pass if throwing sync and test is async\", function (done) {\n      var test = new Test(\"im async and throw null sync\", function () {\n        throw null;\n      });\n      suite.addTest(test);\n      runner = new Runner(suite);\n      runner.on(EVENT_RUN_END, function () {\n        expect(runner.failures, \"to be\", 1);\n        expect(test.state, \"to be\", STATE_FAILED);\n        done();\n      });\n      runner.run();\n    });\n\n    it(\"should not pass if throwing async and test is async\", function (done) {\n      var test = new Test(\"im async and throw null async\", function () {\n        process.nextTick(function () {\n          throw null;\n        });\n      });\n      suite.addTest(test);\n      runner = new Runner(suite);\n      runner.on(EVENT_RUN_END, function () {\n        expect(runner.failures, \"to be\", 1);\n        expect(test.state, \"to be\", STATE_FAILED);\n        done();\n      });\n      runner.run();\n    });\n  });\n\n  describe(\"stack\", function () {\n    it(\"should include the stack when throwing async\", function (done) {\n      var test = new Test(\"im async and throw null async\", function () {\n        process.nextTick(function throwError() {\n          throw new Error(\"test error\");\n        });\n      });\n      suite.addTest(test);\n      runner = new Runner(suite);\n      sinon.stub(runner, \"fail\");\n\n      runner.on(EVENT_RUN_END, function () {\n        try {\n          expect(runner.fail, \"to have all calls satisfying\", [\n            expect.it(\"to be a\", Runnable),\n            expect.it(\"to be an\", Error).and(\"to satisfy\", {\n              message: /test error/i,\n              stack: /throwError/i,\n              uncaught: true,\n            }),\n          ]).and(\"was called once\");\n        } catch (err) {\n          return done(err);\n        }\n\n        done();\n      });\n      runner.run();\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/timeout.spec.js",
    "content": "\"use strict\";\n\ndescribe(\"timeouts\", function () {\n  beforeEach(function (done) {\n    // uncomment\n    // setTimeout(done, 3000);\n    done();\n  });\n\n  it(\"should error on timeout\", function (done) {\n    // uncomment\n    // setTimeout(done, 3000);\n    done();\n  });\n\n  it(\"should allow overriding per-test\", function (done) {\n    this.timeout(1500);\n    setTimeout(function () {\n      done();\n    }, 50);\n  });\n\n  describe(\"chaining calls\", function () {\n    describe(\"suite-level\", function () {\n      describe(\"should override for inner test cases and deeply nested suites\", function () {\n        it(\"inner test\", async function () {\n          await new Promise((resolve) => {\n            setTimeout(resolve, 1000);\n          });\n        });\n        describe(\"nested suite\", function () {\n          it(\"nested test\", async function () {\n            await new Promise((resolve) => {\n              setTimeout(resolve, 2200); // This waiting time is higher than the default timeout value, 2 seconds.\n            });\n          });\n        }).timeout(70);\n      }).timeout(2500); // This chained `timeout` config will override `timeout` for nested suites and cases\n    });\n  });\n\n  describe(\"disabling\", function () {\n    it(\"should work with timeout(0)\", function (done) {\n      this.timeout(0);\n      setTimeout(done, 1);\n    });\n\n    describe(\"using beforeEach\", function () {\n      beforeEach(function () {\n        this.timeout(0);\n      });\n\n      it(\"should work with timeout(0)\", function (done) {\n        setTimeout(done, 1);\n      });\n    });\n\n    describe(\"using before\", function () {\n      before(function () {\n        this.timeout(0);\n      });\n\n      it(\"should work with timeout(0)\", function (done) {\n        setTimeout(done, 1);\n      });\n    });\n\n    describe(\"using timeout(0)\", function () {\n      this.timeout(4);\n\n      it(\"should suppress timeout(4)\", function (done) {\n        this.slow(100);\n        // The test is in the before() call.\n        this.timeout(0);\n        setTimeout(done, 50);\n      });\n    });\n\n    describe(\"suite-level\", function () {\n      this.timeout(0);\n\n      it(\"should work with timeout(0)\", function (done) {\n        setTimeout(done, 1);\n      });\n\n      describe(\"nested suite\", function () {\n        it(\"should work with timeout(0)\", function (done) {\n          setTimeout(done, 1);\n        });\n      });\n    });\n\n    describe(\"chaining calls\", function () {\n      before(function (done) {\n        setTimeout(function () {\n          done();\n        }, 50);\n      }).timeout(1500);\n\n      it(\"should allow overriding via chaining\", function (done) {\n        setTimeout(function () {\n          done();\n        }, 50);\n      }).timeout(1500);\n\n      describe(\"suite-level\", function () {\n        it(\"should work with timeout(0)\", function (done) {\n          setTimeout(done, 1);\n        });\n\n        describe(\"nested suite\", function () {\n          it(\"should work with timeout(0)\", function (done) {\n            setTimeout(done, 1);\n          });\n        });\n      }).timeout(1000);\n    });\n  });\n});\n"
  },
  {
    "path": "test/unit/utils.spec.js",
    "content": "/* global BigInt */\n\"use strict\";\n\nvar utils = require(\"../../lib/utils\");\nvar sinon = require(\"sinon\");\n\ndescribe(\"lib/utils\", function () {\n  afterEach(function () {\n    sinon.restore();\n  });\n\n  describe(\"clean()\", function () {\n    it(\"should remove the wrapping function declaration\", function () {\n      expect(\n        utils.clean(\"function  (one, two, three)  {\\n//code\\n}\"),\n        \"to be\",\n        \"//code\",\n      );\n    });\n\n    it(\"should handle newlines in the function declaration\", function () {\n      expect(\n        utils.clean(\"function  (one, two, three)\\n  {\\n//code\\n}\"),\n        \"to be\",\n        \"//code\",\n      );\n    });\n\n    it(\"should remove space character indentation from the function body\", function () {\n      expect(\n        utils.clean(\"  //line1\\n    //line2\"),\n        \"to be\",\n        \"//line1\\n  //line2\",\n      );\n    });\n\n    it(\"should remove tab character indentation from the function body\", function () {\n      expect(\n        utils.clean(\"\\t//line1\\n\\t\\t//line2\"),\n        \"to be\",\n        \"//line1\\n\\t//line2\",\n      );\n    });\n\n    it(\"should handle functions with tabs in their declarations\", function () {\n      expect(utils.clean(\"function\\t(\\t)\\t{\\n//code\\n}\"), \"to be\", \"//code\");\n    });\n\n    it(\"should handle named functions without space after name\", function () {\n      expect(\n        utils.clean(\"function withName() {\\n//code\\n}\"),\n        \"to be\",\n        \"//code\",\n      );\n    });\n\n    it(\"should handle named functions with space after name\", function () {\n      expect(\n        utils.clean(\"function withName () {\\n//code\\n}\"),\n        \"to be\",\n        \"//code\",\n      );\n    });\n\n    it(\"should handle functions with no space between the end and the closing brace\", function () {\n      expect(utils.clean(\"function() {/*code*/}\"), \"to be\", \"/*code*/\");\n    });\n\n    it(\"should handle functions with parentheses in the same line\", function () {\n      expect(\n        utils.clean(\"function() { if (true) { /* code */ } }\"),\n        \"to be\",\n        \"if (true) { /* code */ }\",\n      );\n    });\n\n    it(\"should handle empty functions\", function () {\n      expect(utils.clean(\"function() {}\"), \"to be\", \"\");\n    });\n\n    it(\"should format a single line test function\", function () {\n      var fn = [\"function () {\", \"  var a = 1;\", \"}\"].join(\"\\n\");\n      expect(utils.clean(fn), \"to be\", \"var a = 1;\");\n    });\n\n    it(\"should format a multi line test indented with spaces\", function () {\n      // and no new lines after curly braces, shouldn't matter\n      var fn = [\n        \"function(){  var a = 1;\",\n        // this one has more spaces\n        \"    var b = 2;\",\n        \"  var c = 3;  }\",\n      ].join(\"\\n\");\n      expect(utils.clean(fn), \"to be\", \"var a = 1;\\n  var b = 2;\\nvar c = 3;\");\n    });\n\n    it(\"should format a multi line test indented with tabs\", function () {\n      var fn = [\n        \"function (arg1, arg2)   {\",\n        \"\\tif (true) {\",\n        \"\\t\\tvar a = 1;\",\n        \"\\t}\",\n        \"}\",\n      ].join(\"\\n\");\n      expect(utils.clean(fn), \"to be\", \"if (true) {\\n\\tvar a = 1;\\n}\");\n    });\n\n    it(\"should format functions saved in windows style - spaces\", function () {\n      var fn = [\n        \"function (one) {\",\n        \"   do {\",\n        '    \"nothing\";',\n        \"   } while (false);\",\n        \" }\",\n      ].join(\"\\r\\n\");\n      expect(utils.clean(fn), \"to be\", 'do {\\n \"nothing\";\\n} while (false);');\n    });\n\n    it(\"should format functions saved in windows style - tabs\", function () {\n      var fn = [\n        \"function ( )   {\",\n        \"\\tif (false) {\",\n        \"\\t\\tvar json = {\",\n        \"\\t\\t\\tone : 1\",\n        \"\\t\\t};\",\n        \"\\t}\",\n        \"}\",\n      ].join(\"\\r\\n\");\n      expect(\n        utils.clean(fn),\n        \"to be\",\n        \"if (false) {\\n\\tvar json = {\\n\\t\\tone : 1\\n\\t};\\n}\",\n      );\n    });\n\n    it(\"should format es6 arrow functions\", function () {\n      var fn = [\"() => {\", \"  var a = 1;\", \"}\"].join(\"\\n\");\n      expect(utils.clean(fn), \"to be\", \"var a = 1;\");\n    });\n\n    it(\"should format es6 arrow functions with implicit return\", function () {\n      var fn = \"() => foo()\";\n      expect(utils.clean(fn), \"to be\", \"foo()\");\n    });\n  });\n\n  describe(\"stringify()\", function () {\n    var stringify = utils.stringify;\n\n    it(\"should return an object representation of a string created with a String constructor\", function () {\n      /* eslint no-new-wrappers: off */\n      expect(\n        stringify(new String(\"foo\")),\n        \"to be\",\n        '{\\n  \"0\": \"f\"\\n  \"1\": \"o\"\\n  \"2\": \"o\"\\n}',\n      );\n    });\n\n    it(\"should return Buffer with .toJSON representation\", function () {\n      expect(stringify(Buffer.from([0x01])), \"to be\", \"[\\n  1\\n]\");\n      expect(stringify(Buffer.from([0x01, 0x02])), \"to be\", \"[\\n  1\\n  2\\n]\");\n\n      expect(\n        stringify(Buffer.from(\"ABCD\")),\n        \"to be\",\n        \"[\\n  65\\n  66\\n  67\\n  68\\n]\",\n      );\n    });\n\n    it(\"should return Date object with .toISOString() + string prefix\", function () {\n      expect(\n        stringify(new Date(0)),\n        \"to be\",\n        \"[Date: \" + new Date(0).toISOString() + \"]\",\n      );\n\n      var date = new Date(); // now\n      expect(stringify(date), \"to be\", \"[Date: \" + date.toISOString() + \"]\");\n    });\n\n    it(\"should return invalid Date object with .toString() + string prefix\", function () {\n      expect(\n        stringify(new Date(\"\")),\n        \"to be\",\n        \"[Date: \" + new Date(\"\").toString() + \"]\",\n      );\n    });\n\n    describe(\"#Number\", function () {\n      it(\"should show the handle -0 situations\", function () {\n        expect(stringify(-0), \"to be\", \"-0\");\n        expect(stringify(0), \"to be\", \"0\");\n        expect(stringify(\"-0\"), \"to be\", '\"-0\"');\n      });\n\n      it(\"should work well with `NaN` and `Infinity`\", function () {\n        expect(stringify(NaN), \"to be\", \"NaN\");\n        expect(stringify(Infinity), \"to be\", \"Infinity\");\n        expect(stringify(-Infinity), \"to be\", \"-Infinity\");\n      });\n\n      it(\"floats and ints\", function () {\n        expect(stringify(1), \"to be\", \"1\");\n        expect(stringify(1.2), \"to be\", \"1.2\");\n        expect(stringify(1e9), \"to be\", \"1000000000\");\n      });\n\n      if (typeof BigInt === \"function\") {\n        it(\"should work with bigints when possible\", function () {\n          expect(stringify(BigInt(1)), \"to be\", \"1n\");\n          expect(stringify(BigInt(2)), \"to be\", \"2n\");\n        });\n      }\n    });\n\n    describe(\"canonicalize example\", function () {\n      it(\"should represent the actual full result\", function () {\n        var expected = {\n          str: \"string\",\n          int: 90,\n          float: 9.99,\n          boolean: false,\n          nil: null,\n          undef: undefined,\n          regex: /^[a-z|A-Z]/,\n          date: new Date(0),\n          func: function () {},\n          infi: Infinity,\n          nan: NaN,\n          zero: -0,\n          buffer: Buffer.from([0x01, 0x02]),\n          array: [1, 2, 3],\n          empArr: [],\n          matrix: [[1], [2, 3, 4]],\n          object: { a: 1, b: 2 },\n          canObj: { a: { b: 1, c: 2 }, b: {} },\n          empObj: {},\n        };\n        expected.circular = expected; // Make `Circular` situation\n        var actual = [\n          \"{\",\n          '  \"array\": [',\n          \"    1\",\n          \"    2\",\n          \"    3\",\n          \"  ]\",\n          '  \"boolean\": false',\n          '  \"buffer\": [Buffer: [',\n          \"    1\",\n          \"    2\",\n          \"  ]]\",\n          '  \"canObj\": {',\n          '    \"a\": {',\n          '      \"b\": 1',\n          '      \"c\": 2',\n          \"    }\",\n          '    \"b\": {}',\n          \"  }\",\n          '  \"circular\": [Circular]',\n          '  \"date\": [Date: 1970-01-01T00:00:00.000Z]',\n          '  \"empArr\": []',\n          '  \"empObj\": {}',\n          '  \"float\": 9.99',\n          '  \"func\": [Function]',\n          '  \"infi\": Infinity',\n          '  \"int\": 90',\n          '  \"matrix\": [',\n          \"    [\",\n          \"      1\",\n          \"    ]\",\n          \"    [\",\n          \"      2\",\n          \"      3\",\n          \"      4\",\n          \"    ]\",\n          \"  ]\",\n          '  \"nan\": NaN',\n          '  \"nil\": [null]',\n          '  \"object\": {',\n          '    \"a\": 1',\n          '    \"b\": 2',\n          \"  }\",\n          '  \"regex\": /^[a-z|A-Z]/',\n          '  \"str\": \"string\"',\n          '  \"undef\": [undefined]',\n          '  \"zero\": -0',\n          \"}\",\n        ].join(\"\\n\");\n        expect(stringify(expected), \"to be\", actual);\n      });\n\n      describe(\"should represent null prototypes\", function () {\n        it(\"Without properties\", function () {\n          const foo = Object.create(null, {});\n          const expected = \"{}\";\n\n          expect(stringify(foo), \"to be\", expected);\n        });\n\n        it(\"With explicit names\", function () {\n          const foo = Object.create(null, {\n            [Symbol.toStringTag]: { value: \"Foo\" },\n            bing: { get: () => \"bong\", enumerable: true },\n          });\n          const expected = [\n            \"{\",\n            '  \"[Symbol.toStringTag]\": \"Foo\"',\n            '  \"bing\": \"bong\"',\n            \"}\",\n          ].join(\"\\n\");\n\n          expect(stringify(foo), \"to be\", expected);\n        });\n\n        it(\"Without names\", function () {\n          const unnamed = {\n            bing: \"bong\",\n            abc: 123,\n          };\n          unnamed.self = unnamed;\n          const expected = [\n            \"{\",\n            '  \"abc\": 123',\n            '  \"bing\": \"bong\"',\n            '  \"self\": [Circular]',\n            \"}\",\n          ].join(\"\\n\");\n\n          expect(\n            stringify(Object.setPrototypeOf(unnamed, null)),\n            \"to be\",\n            expected,\n          );\n        });\n      });\n    });\n\n    it(\"should canonicalize the object\", function () {\n      var travis = { name: \"travis\", age: 24 };\n      var travis2 = { age: 24, name: \"travis\" };\n\n      expect(stringify(travis), \"to be\", stringify(travis2));\n    });\n\n    it(\"should handle circular structures in objects\", function () {\n      var travis = { name: \"travis\" };\n      travis.whoami = travis;\n\n      expect(\n        stringify(travis),\n        \"to be\",\n        '{\\n  \"name\": \"travis\"\\n  \"whoami\": [Circular]\\n}',\n      );\n    });\n\n    it(\"should handle circular structures in arrays\", function () {\n      var travis = [\"travis\"];\n      travis.push(travis);\n\n      expect(stringify(travis), \"to be\", '[\\n  \"travis\"\\n  [Circular]\\n]');\n    });\n\n    it(\"should handle circular structures in functions\", function () {\n      var travis = function () {};\n      travis.fn = travis;\n\n      expect(stringify(travis), \"to be\", '{\\n  \"fn\": [Circular]\\n}');\n    });\n\n    it(\"should handle various non-undefined, non-null, non-object, non-array, non-date, and non-function values\", function () {\n      var regexp = /(?:)/;\n      var regExpObj = { regexp };\n      var regexpString = \"/(?:)/\";\n\n      expect(\n        stringify(regExpObj),\n        \"to be\",\n        '{\\n  \"regexp\": ' + regexpString + \"\\n}\",\n      );\n      expect(stringify(regexp), \"to be\", regexpString);\n\n      var number = 1;\n      var numberObj = { number };\n      var numberString = \"1\";\n\n      expect(stringify(numberObj), \"to be\", '{\\n  \"number\": ' + number + \"\\n}\");\n      expect(stringify(number), \"to be\", numberString);\n\n      var boolean = false;\n      var booleanObj = { boolean };\n      var booleanString = \"false\";\n\n      expect(\n        stringify(booleanObj),\n        \"to be\",\n        '{\\n  \"boolean\": ' + boolean + \"\\n}\",\n      );\n      expect(stringify(boolean), \"to be\", booleanString);\n\n      var string = \"sneepy\";\n      var stringObj = { string };\n\n      expect(\n        stringify(stringObj),\n        \"to be\",\n        '{\\n  \"string\": \"' + string + '\"\\n}',\n      );\n      expect(stringify(string), \"to be\", JSON.stringify(string));\n\n      var nullValue = null;\n      var nullObj = { null: null };\n      var nullString = \"[null]\";\n\n      expect(stringify(nullObj), \"to be\", '{\\n  \"null\": [null]\\n}');\n      expect(stringify(nullValue), \"to be\", nullString);\n    });\n\n    it(\"should handle arrays\", function () {\n      var array = [\"dave\", \"dave\", \"dave\", \"dave\"];\n      var arrayObj = { array };\n      var arrayString = '    \"dave\"\\n    \"dave\"\\n    \"dave\"\\n    \"dave\"';\n\n      expect(\n        stringify(arrayObj),\n        \"to be\",\n        '{\\n  \"array\": [\\n' + arrayString + \"\\n  ]\\n}\",\n      );\n      expect(\n        stringify(array),\n        \"to be\",\n        \"[\" + arrayString.replace(/\\s+/g, \"\\n  \") + \"\\n]\",\n      );\n    });\n\n    it(\"should handle functions\", function () {\n      var fn = function () {};\n      var fnObj = { fn };\n      var fnString = \"[Function]\";\n\n      expect(stringify(fnObj), \"to be\", '{\\n  \"fn\": ' + fnString + \"\\n}\");\n      expect(stringify(fn), \"to be\", \"[Function]\");\n    });\n\n    it(\"should handle empty objects\", function () {\n      expect(stringify({}), \"to be\", \"{}\");\n      expect(stringify({ foo: {} }), \"to be\", '{\\n  \"foo\": {}\\n}');\n    });\n\n    it(\"should handle empty arrays\", function () {\n      expect(stringify([]), \"to be\", \"[]\");\n      expect(stringify({ foo: [] }), \"to be\", '{\\n  \"foo\": []\\n}');\n    });\n\n    it(\"should handle non-empty arrays\", function () {\n      expect(stringify([\"a\", \"b\", \"c\"]), \"to be\", '[\\n  \"a\"\\n  \"b\"\\n  \"c\"\\n]');\n    });\n\n    it(\"should handle empty functions (with no properties)\", function () {\n      expect(\n        stringify(function () {}),\n        \"to be\",\n        \"[Function]\",\n      );\n      expect(\n        stringify({ foo: function () {} }),\n        \"to be\",\n        '{\\n  \"foo\": [Function]\\n}',\n      );\n      expect(\n        stringify({ foo: function () {}, bar: \"baz\" }),\n        \"to be\",\n        '{\\n  \"bar\": \"baz\"\\n  \"foo\": [Function]\\n}',\n      );\n    });\n\n    it(\"should handle functions w/ properties\", function () {\n      var fn = function () {};\n      fn.bar = \"baz\";\n      expect(stringify(fn), \"to be\", '{\\n  \"bar\": \"baz\"\\n}');\n      expect(\n        stringify({ foo: fn }),\n        \"to be\",\n        '{\\n  \"foo\": {\\n    \"bar\": \"baz\"\\n  }\\n}',\n      );\n    });\n\n    it(\"should handle undefined values\", function () {\n      expect(\n        stringify({ foo: undefined }),\n        \"to be\",\n        '{\\n  \"foo\": [undefined]\\n}',\n      );\n      expect(\n        stringify({ foo: \"bar\", baz: undefined }),\n        \"to be\",\n        '{\\n  \"baz\": [undefined]\\n  \"foo\": \"bar\"\\n}',\n      );\n      expect(stringify(), \"to be\", \"[undefined]\");\n    });\n\n    it(\"should recurse\", function () {\n      expect(\n        stringify({ foo: { bar: { baz: { quux: { herp: \"derp\" } } } } }),\n        \"to be\",\n        '{\\n  \"foo\": {\\n    \"bar\": {\\n      \"baz\": {\\n        \"quux\": {\\n          \"herp\": \"derp\"\\n        }\\n      }\\n    }\\n  }\\n}',\n      );\n    });\n\n    it(\"might get confusing\", function () {\n      expect(stringify(null), \"to be\", \"[null]\");\n    });\n\n    it(\"should not freak out if it sees a primitive twice\", function () {\n      expect(\n        stringify({ foo: null, bar: null }),\n        \"to be\",\n        '{\\n  \"bar\": [null]\\n  \"foo\": [null]\\n}',\n      );\n      expect(\n        stringify({ foo: 1, bar: 1 }),\n        \"to be\",\n        '{\\n  \"bar\": 1\\n  \"foo\": 1\\n}',\n      );\n    });\n\n    it(\"should stringify dates\", function () {\n      var date = new Date(0);\n      expect(stringify(date), \"to be\", \"[Date: 1970-01-01T00:00:00.000Z]\");\n      expect(\n        stringify({ date }),\n        \"to be\",\n        '{\\n  \"date\": [Date: 1970-01-01T00:00:00.000Z]\\n}',\n      );\n    });\n\n    it(\"should handle object without an Object prototype\", function () {\n      var a;\n      if (Object.create) {\n        a = Object.create(null);\n      } else {\n        a = {};\n      }\n      a.foo = 1;\n\n      expect(stringify(a), \"to be\", '{\\n  \"foo\": 1\\n}');\n    });\n\n    // In old version node.js, Symbol is not available by default.\n    if (typeof global.Symbol === \"function\") {\n      it(\"should handle Symbol\", function () {\n        var symbol = Symbol(\"value\");\n        expect(stringify(symbol), \"to match\", /^Symbol\\(value\\)/);\n        expect(stringify({ symbol }), \"to match\", /\"symbol\": Symbol\\(value\\)/);\n      });\n    }\n\n    it(\"should handle length properties that cannot be coerced to a number\", function () {\n      expect(\n        stringify({ length: { nonBuiltinProperty: 0 } }),\n        \"to be\",\n        '{\\n  \"length\": {\\n    \"nonBuiltinProperty\": 0\\n  }\\n}',\n      );\n      expect(\n        stringify({ length: \"a string where length should be\" }),\n        \"to be\",\n        '{\\n  \"length\": \"a string where length should be\"\\n}',\n      );\n    });\n  });\n\n  describe(\"type()\", function () {\n    var type = utils.type;\n    var toString = Object.prototype.toString;\n\n    beforeEach(function () {\n      // some JS engines such as PhantomJS 1.x exhibit this behavior\n      Object.prototype.toString = function () {\n        if (this === global) {\n          return \"[object DOMWindow]\";\n        }\n        return toString.call(this);\n      };\n    });\n\n    it(\"should recognize various types\", function () {\n      expect(type({}), \"to be\", \"object\");\n      expect(type([]), \"to be\", \"array\");\n      expect(type(1), \"to be\", \"number\");\n      expect(type(Infinity), \"to be\", \"number\");\n      expect(type(null), \"to be\", \"null\");\n      expect(type(undefined), \"to be\", \"undefined\");\n      expect(type(new Date()), \"to be\", \"object\");\n      expect(type(/foo/), \"to be\", \"object\");\n      expect(type(\"type\"), \"to be\", \"string\");\n      expect(type(new Error()), \"to be\", \"error\");\n      expect(type(global), \"to be\", \"object\");\n      expect(type(true), \"to be\", \"boolean\");\n      expect(type(Buffer.from(\"ff\", \"hex\")), \"to be\", \"object\");\n      expect(type(Symbol.iterator), \"to be\", \"symbol\");\n      expect(type(new Map()), \"to be\", \"object\");\n      expect(type(new WeakMap()), \"to be\", \"object\");\n      expect(type(new Set()), \"to be\", \"object\");\n      expect(type(new WeakSet()), \"to be\", \"object\");\n      expect(\n        type(async () => {}),\n        \"to be\",\n        \"function\",\n      );\n    });\n\n    describe(\"when toString on null or undefined stringifies window\", function () {\n      it(\"should recognize null and undefined\", function () {\n        expect(type(null), \"to be\", \"null\");\n        expect(type(undefined), \"to be\", \"undefined\");\n      });\n    });\n\n    afterEach(function () {\n      Object.prototype.toString = toString;\n    });\n  });\n\n  describe(\"canonicalType()\", function () {\n    var type = utils.canonicalType;\n    var toString = Object.prototype.toString;\n\n    beforeEach(function () {\n      // some JS engines such as PhantomJS 1.x exhibit this behavior\n      Object.prototype.toString = function () {\n        if (this === global) {\n          return \"[object DOMWindow]\";\n        }\n        return toString.call(this);\n      };\n    });\n\n    it(\"should recognize various types\", function () {\n      expect(type({}), \"to be\", \"object\");\n      expect(type([]), \"to be\", \"array\");\n      expect(type(1), \"to be\", \"number\");\n      expect(type(Infinity), \"to be\", \"number\");\n      expect(type(null), \"to be\", \"null\");\n      expect(type(undefined), \"to be\", \"undefined\");\n      expect(type(new Date()), \"to be\", \"date\");\n      expect(type(/foo/), \"to be\", \"regexp\");\n      expect(type(\"type\"), \"to be\", \"string\");\n      expect(type(global), \"to be\", \"domwindow\");\n      expect(type(true), \"to be\", \"boolean\");\n    });\n\n    describe(\"when toString on null or undefined stringifies window\", function () {\n      it(\"should recognize null and undefined\", function () {\n        expect(type(null), \"to be\", \"null\");\n        expect(type(undefined), \"to be\", \"undefined\");\n      });\n    });\n\n    afterEach(function () {\n      Object.prototype.toString = toString;\n    });\n  });\n\n  describe(\"isPromise()\", function () {\n    it(\"should return true if the value is Promise-ish\", function () {\n      expect(\n        utils.isPromise({\n          then: function () {},\n        }),\n        \"to be\",\n        true,\n      );\n    });\n\n    it(\"should return false if the value is not an object\", function () {\n      expect(utils.isPromise(1), \"to be\", false);\n    });\n\n    it('should return false if the value is an object w/o a \"then\" function', function () {\n      expect(utils.isPromise({}), \"to be\", false);\n    });\n\n    it(\"should return false if the object is null\", function () {\n      expect(utils.isPromise(null), \"to be\", false);\n    });\n  });\n\n  describe(\"escape()\", function () {\n    it(\"replaces the usual xml suspects\", function () {\n      expect(utils.escape(\"<a<bc<d<\"), \"to be\", \"&#x3C;a&#x3C;bc&#x3C;d&#x3C;\");\n      expect(utils.escape(\">a>bc>d>\"), \"to be\", \"&#x3E;a&#x3E;bc&#x3E;d&#x3E;\");\n      expect(utils.escape('\"a\"bc\"d\"'), \"to be\", \"&#x22;a&#x22;bc&#x22;d&#x22;\");\n      expect(utils.escape('<>\"&'), \"to be\", \"&#x3C;&#x3E;&#x22;&#x26;\");\n\n      expect(utils.escape(\"&a&bc&d&\"), \"to be\", \"&#x26;a&#x26;bc&#x26;d&#x26;\");\n      expect(utils.escape(\"&amp;&lt;\"), \"to be\", \"&#x26;amp;&#x26;lt;\");\n    });\n\n    it(\"replaces invalid xml characters\", function () {\n      expect(\n        utils.escape(\"\\x1B[32mfoo\\x1B[0m\"),\n        \"to be\",\n        \"&#x1B;[32mfoo&#x1B;[0m\",\n      );\n      // Ensure we can handle non-trivial unicode characters as well\n      expect(utils.escape(\"💩\"), \"to be\", \"&#x1F4A9;\");\n    });\n  });\n\n  describe(\"createMap()\", function () {\n    it(\"should return an object with a null prototype\", function () {\n      expect(Object.getPrototypeOf(utils.createMap()), \"to be\", null);\n    });\n\n    it(\"should add props to the object\", function () {\n      expect(utils.createMap({ foo: \"bar\" }), \"to exhaustively satisfy\", {\n        foo: \"bar\",\n      });\n    });\n\n    it(\"should add props from all object parameters to the object\", function () {\n      expect(\n        utils.createMap({ foo: \"bar\" }, { bar: \"baz\" }),\n        \"to exhaustively satisfy\",\n        { foo: \"bar\", bar: \"baz\" },\n      );\n    });\n  });\n\n  describe(\"slug()\", function () {\n    it(\"should convert the string to lowercase\", function () {\n      expect(utils.slug(\"FOO\"), \"to be\", \"foo\");\n    });\n\n    it(\"should convert whitespace to dashes\", function () {\n      expect(\n        utils.slug(\"peanut butter\\nand\\tjelly\"),\n        \"to be\",\n        \"peanut-butter-and-jelly\",\n      );\n    });\n\n    it(\"should strip non-alphanumeric and non-dash characters\", function () {\n      expect(utils.slug(\"murder-hornets!!\"), \"to be\", \"murder-hornets\");\n    });\n\n    it(\"should disallow consecutive dashes\", function () {\n      expect(utils.slug(\"poppies & fritz\"), \"to be\", \"poppies-fritz\");\n    });\n  });\n\n  describe(\"castArray()\", function () {\n    describe(\"when provided an array value\", function () {\n      it(\"should return a copy of the array\", function () {\n        const v = [\"foo\", \"bar\", \"baz\"];\n        expect(utils.castArray(v), \"to equal\", [\"foo\", \"bar\", \"baz\"]).and(\n          \"not to be\",\n          v,\n        );\n      });\n    });\n\n    describe('when provided an \"arguments\" value', function () {\n      it(\"should return an array containing the arguments\", function () {\n        (function () {\n          expect(utils.castArray(arguments), \"to equal\", [\n            \"foo\",\n            \"bar\",\n            \"baz\",\n          ]).and(\"not to be\", arguments);\n        })(\"foo\", \"bar\", \"baz\");\n      });\n    });\n\n    describe(\"when provided an object\", function () {\n      it(\"should return an array containing the object only\", function () {\n        const v = { foo: \"bar\" };\n        expect(utils.castArray(v), \"to equal\", [v]);\n      });\n    });\n\n    describe(\"when provided no parameters\", function () {\n      it(\"should return an empty array\", function () {\n        expect(utils.castArray(), \"to equal\", []);\n      });\n    });\n\n    describe(\"when provided a primitive value\", function () {\n      it(\"should return an array containing the primitive value only\", function () {\n        expect(utils.castArray(\"butts\"), \"to equal\", [\"butts\"]);\n      });\n    });\n\n    describe(\"when provided null\", function () {\n      it(\"should return an array containing a null value only\", function () {\n        expect(utils.castArray(null), \"to equal\", [null]);\n      });\n    });\n  });\n\n  describe(\"uniqueID()\", function () {\n    it(\"should return a non-empty string\", function () {\n      expect(utils.uniqueID(), \"to be a string\").and(\"not to be empty\");\n    });\n    it(\"should have length of 21\", function () {\n      expect(utils.uniqueID().length, \"to equal\", 21);\n    });\n  });\n});\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"allowJs\": true,\n    \"module\": \"Node16\",\n    \"resolveJsonModule\": true,\n    \"skipLibCheck\": true,\n    \"target\": \"ES2022\",\n    \"noEmit\": true\n  },\n  \"exclude\": [\"lib/browser\"],\n  \"include\": [\"lib\"]\n}\n"
  }
]