├── .browserslistrc ├── .editorconfig ├── .eleventy.js ├── .fossaignore ├── .gitattributes ├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── DEVELOPMENT.md ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── 01-bug.yml │ ├── 02-documentation.yml │ ├── 03-feature-request.yml │ ├── 04-repository-tooling.yml │ └── config.yml ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml ├── release-please │ ├── config.json │ └── manifest.json └── workflows │ ├── browser-test.yml │ ├── compliance.yml │ ├── mocha.yml │ ├── nightly-site-deploy.yml │ ├── npm-script.yml │ └── release-please.yml ├── .gitignore ├── .knip.jsonc ├── .lintstagedrc.json ├── .mailmap ├── .markdownlint.json ├── .mocharc.yml ├── .npmrc ├── .nycrc ├── .wallaby.js ├── AUTHORS ├── CHANGELOG.md ├── FUNDING.md ├── LICENSE ├── MAINTAINERS.md ├── PROJECT_CHARTER.md ├── README.md ├── SECURITY.md ├── assets ├── mocha-banner-192.png ├── mocha-banner.svg ├── mocha-fixture-wizard.sketch ├── mocha-logo-128.png ├── mocha-logo-192.png ├── mocha-logo-64.png ├── mocha-logo-96.png ├── mocha-logo.svg └── opencollective-header.png ├── bin ├── _mocha └── mocha.js ├── browser-entry.js ├── docs-next ├── .gitignore ├── .prettierrc.json ├── README.md ├── astro.config.ts ├── netlify.toml ├── package-lock.json ├── package.json ├── public │ ├── example │ │ ├── Array.js │ │ └── tests.html │ └── favicon.svg ├── src │ ├── components │ │ ├── Badges.astro │ │ ├── ClientRedirects.astro │ │ ├── FixtureWizard.astro │ │ ├── Footer.astro │ │ ├── Head.astro │ │ ├── HomepagePageTitle.astro │ │ ├── PageTitle.astro │ │ ├── Supporters.astro │ │ ├── discord.svg │ │ ├── icon-dark.svg │ │ ├── icon-light.svg │ │ ├── mocha-logo.svg │ │ ├── mocha-thumbnail.svg │ │ └── openjsf-logo.svg │ ├── content │ │ ├── config.ts │ │ ├── data │ │ │ └── sponsors.json │ │ └── docs │ │ │ ├── declaring │ │ │ ├── dynamic-tests.mdx │ │ │ ├── exclusive-tests.mdx │ │ │ ├── inclusive-tests.mdx │ │ │ ├── pending-tests.mdx │ │ │ └── retrying-tests.mdx │ │ │ ├── explainers │ │ │ ├── detecting-multiple-calls-to-done.mdx │ │ │ ├── nodejs-native-esm-support.mdx │ │ │ ├── reporter-spec-duration.png │ │ │ ├── run-cycle-overview.mdx │ │ │ ├── test-duration-range.png │ │ │ ├── test-duration.mdx │ │ │ └── test-fixture-decision-tree.mdx │ │ │ ├── features │ │ │ ├── arrow-functions.mdx │ │ │ ├── assertions.mdx │ │ │ ├── asynchronous-code.mdx │ │ │ ├── diffs.mdx │ │ │ ├── error-codes.mdx │ │ │ ├── global-fixtures.mdx │ │ │ ├── hooks.mdx │ │ │ ├── parallel-mode.mdx │ │ │ ├── reporter-string-diffs.png │ │ │ ├── root-hook-plugins.mdx │ │ │ └── timeouts.mdx │ │ │ ├── getting-started.mdx │ │ │ ├── index.mdx │ │ │ ├── interfaces │ │ │ ├── about.mdx │ │ │ ├── bdd.mdx │ │ │ ├── exports.mdx │ │ │ ├── qunit.mdx │ │ │ ├── require.mdx │ │ │ ├── tdd.mdx │ │ │ └── third-party.mdx │ │ │ ├── reporters │ │ │ ├── about.mdx │ │ │ ├── doc.mdx │ │ │ ├── dot.mdx │ │ │ ├── html.mdx │ │ │ ├── json-stream.mdx │ │ │ ├── json.mdx │ │ │ ├── landing.mdx │ │ │ ├── list.mdx │ │ │ ├── markdown.mdx │ │ │ ├── min.mdx │ │ │ ├── nyan.mdx │ │ │ ├── progress.mdx │ │ │ ├── reporter-doc.png │ │ │ ├── reporter-dot.png │ │ │ ├── reporter-json-stream.png │ │ │ ├── reporter-json.png │ │ │ ├── reporter-landing-fail.png │ │ │ ├── reporter-landing.png │ │ │ ├── reporter-list.png │ │ │ ├── reporter-min.png │ │ │ ├── reporter-nyan.png │ │ │ ├── reporter-progress.png │ │ │ ├── reporter-spec-fail.png │ │ │ ├── reporter-spec.png │ │ │ ├── reporter-string-diffs.png │ │ │ ├── reporter-tap.png │ │ │ ├── spec.mdx │ │ │ ├── tap.mdx │ │ │ ├── third-party.mdx │ │ │ └── xunit.mdx │ │ │ └── running │ │ │ ├── browsers.mdx │ │ │ ├── cli.mdx │ │ │ ├── configuring.mdx │ │ │ ├── editor-plugins.mdx │ │ │ ├── emacs.png │ │ │ ├── jetbrains-plugin.png │ │ │ ├── mocha_side_bar.png │ │ │ ├── reporter-html.png │ │ │ ├── test-globs.mdx │ │ │ └── wallaby.png │ ├── env.d.ts │ └── style │ │ └── custom.css └── tsconfig.json ├── docs ├── .browserslistrc ├── .eleventyignore ├── API.md ├── CNAME ├── LICENSE-CC-BY-4.0 ├── README.md ├── _data │ ├── blocklist.json │ ├── files.js │ ├── supporters.js │ ├── toc.js │ └── usage.js ├── _headers ├── _includes │ ├── default.liquid │ ├── fixture-wizard.html │ └── supporters.md ├── api-tutorials │ ├── custom-reporter.md │ └── jsdoc.tutorials.json ├── changelogs │ ├── CHANGELOG_V3_older.md │ ├── CHANGELOG_V4.md │ └── README.md ├── css │ ├── normalize.css │ ├── prism.css │ ├── style.css │ └── supporters.css ├── example │ ├── Array.js │ ├── async-dump.js │ ├── debug-hanging-mocha.js │ └── tests.html ├── favicon.ico ├── images │ ├── emacs.png │ ├── jetbrains-plugin.png │ ├── join-chat.svg │ ├── link-icon.svg │ ├── matomo-logo.png │ ├── mocha-logo.svg │ ├── mocha_side_bar.png │ ├── openjsf-logo.svg │ ├── reporter-doc.png │ ├── reporter-dot.png │ ├── reporter-html.png │ ├── reporter-json-stream.png │ ├── reporter-json.png │ ├── reporter-landing-fail.png │ ├── reporter-landing.png │ ├── reporter-list.png │ ├── reporter-min.png │ ├── reporter-nyan.png │ ├── reporter-progress.png │ ├── reporter-spec-duration.png │ ├── reporter-spec-fail.png │ ├── reporter-spec.png │ ├── reporter-string-diffs.png │ ├── reporter-tap.png │ ├── test-duration-range.png │ ├── wallaby-logo.png │ └── wallaby.png ├── index.md └── js │ └── html5shiv.min.js ├── eslint.config.js ├── example └── config │ ├── .mocharc.js │ ├── .mocharc.json │ ├── .mocharc.jsonc │ ├── .mocharc.yml │ └── README.md ├── index.js ├── jsdoc.conf.json ├── karma.conf.js ├── lib ├── browser │ ├── highlight-tags.js │ ├── parse-query.js │ └── template.html ├── cli │ ├── cli.js │ ├── collect-files.js │ ├── commands.js │ ├── config.js │ ├── index.js │ ├── init.js │ ├── lookup-files.js │ ├── node-flags.js │ ├── one-and-dones.js │ ├── options.js │ ├── run-helpers.js │ ├── run-option-metadata.js │ ├── run.js │ └── watch-run.js ├── context.js ├── errors.js ├── hook.js ├── interfaces │ ├── bdd.js │ ├── common.js │ ├── exports.js │ ├── index.js │ ├── qunit.js │ └── tdd.js ├── mocha.js ├── mocharc.json ├── nodejs │ ├── buffered-worker-pool.js │ ├── esm-utils.js │ ├── file-unloader.js │ ├── parallel-buffered-runner.js │ ├── reporters │ │ └── parallel-buffered.js │ ├── serializer.js │ └── worker.js ├── pending.js ├── plugin-loader.js ├── reporters │ ├── base.js │ ├── doc.js │ ├── dot.js │ ├── html.js │ ├── index.js │ ├── json-stream.js │ ├── json.js │ ├── landing.js │ ├── list.js │ ├── markdown.js │ ├── min.js │ ├── nyan.js │ ├── progress.js │ ├── spec.js │ ├── tap.js │ └── xunit.js ├── runnable.js ├── runner.js ├── stats-collector.js ├── suite.js ├── test.js └── utils.js ├── mocha.css ├── netlify.toml ├── package-lock.json ├── package.json ├── rollup.config.js ├── scripts ├── karma-rollup-plugin.js ├── linkify-changelog.mjs ├── pick-from-package-json.js └── update-authors.js └── test ├── README.md ├── assertions.js ├── browser-specific ├── esm.spec.mjs ├── fixtures │ ├── esm.fixture.mjs │ └── webpack │ │ ├── webpack.config.js │ │ └── webpack.fixture.mjs └── setup.js ├── compiler-fixtures └── foo.fixture.js ├── compiler ├── test.coffee └── test.foo ├── integration ├── README.md ├── color.spec.js ├── common-js-require.spec.js ├── compiler-globbing.spec.js ├── config.spec.js ├── deprecate.spec.js ├── diffs.spec.js ├── duplicate-arguments.spec.js ├── esm.spec.js ├── events.spec.js ├── file-utils.spec.js ├── fixtures │ ├── __default__.fixture.js │ ├── cascade.fixture.js │ ├── collect-files.fixture.mjs │ ├── common-js-require.fixture.js │ ├── config │ │ ├── mocha-config │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── mocharc.cjs │ │ ├── mocharc.js │ │ ├── mocharc.json │ │ ├── mocharc.yaml │ │ └── mocharcWithThrowError.js │ ├── current-test-title.fixture.js │ ├── deprecate.fixture.js │ ├── diffs │ │ ├── diffs.css.in │ │ ├── diffs.css.out │ │ ├── diffs.fixture.js │ │ └── output │ ├── esm │ │ ├── add.mjs │ │ ├── dir-cjs-require │ │ │ └── index.js │ │ ├── esm-failure.fixture.mjs │ │ ├── esm-success.fixture.mjs │ │ ├── js-folder │ │ │ ├── add.js │ │ │ ├── esm-in-js.fixture.js │ │ │ └── package.json │ │ ├── loader-with-module-not-found │ │ │ ├── loader-that-recognizes-ts.mjs │ │ │ ├── test-that-imports-non-existing-module.fixture.mjs │ │ │ └── test-that-imports-non-existing-module.fixture.ts │ │ ├── syntax-error │ │ │ └── esm-syntax-error.fixture.mjs │ │ ├── test-that-uses-dir-cjs-require.fixture.js │ │ │ └── index.js │ │ └── type-module │ │ │ ├── package.json │ │ │ └── test-that-imports-non-existing-module.fixture.js │ ├── exit.fixture.js │ ├── failing-sync.fixture.js │ ├── failing.fixture.js │ ├── glob │ │ ├── glob.spec.js │ │ └── nested │ │ │ └── glob.spec.js │ ├── hooks │ │ ├── after-each-hook-async-error.fixture.js │ │ ├── after-each-hook-error.fixture.js │ │ ├── after-each-this-test-error.fixture.js │ │ ├── after-hook-async-error.fixture.js │ │ ├── after-hook-deepnested-error.fixture.js │ │ ├── after-hook-error.fixture.js │ │ ├── after-hook-nested-error.fixture.js │ │ ├── before-each-hook-async-error.fixture.js │ │ ├── before-each-hook-error.fixture.js │ │ ├── before-hook-async-error-tip.fixture.js │ │ ├── before-hook-async-error.fixture.js │ │ ├── before-hook-deepnested-error.fixture.js │ │ ├── before-hook-error-tip.fixture.js │ │ ├── before-hook-error.fixture.js │ │ ├── before-hook-nested-error.fixture.js │ │ ├── before-hook-root-error.fixture.js │ │ ├── multiple-hook-async-error.fixture.js │ │ └── multiple-hook-error.fixture.js │ ├── multiple-done-async.fixture.js │ ├── multiple-done-before-each.fixture.js │ ├── multiple-done-before.fixture.js │ ├── multiple-done-specs.fixture.js │ ├── multiple-done-with-error.fixture.js │ ├── multiple-done.fixture.js │ ├── multiple-runs │ │ ├── clean-references.fixture.js │ │ ├── dispose.fixture.js │ │ ├── multiple-runs-with-different-output-suite.fixture.js │ │ ├── multiple-runs-with-flaky-before-each-suite.fixture.js │ │ ├── multiple-runs-with-flaky-before-each.fixture.js │ │ ├── run-thrice-helper.js │ │ ├── run-thrice.fixture.js │ │ ├── start-second-run-if-previous-is-still-running-suite.fixture.js │ │ └── start-second-run-if-previous-is-still-running.fixture.js │ ├── no-diff.fixture.js │ ├── options │ │ ├── allow-uncaught │ │ │ ├── propagate.fixture.js │ │ │ └── this-skip-it.fixture.js │ │ ├── async-only-async.fixture.js │ │ ├── async-only-sync.fixture.js │ │ ├── bail-async.fixture.js │ │ ├── bail-with-after.fixture.js │ │ ├── bail-with-afterEach.fixture.js │ │ ├── bail-with-before.fixture.js │ │ ├── bail-with-beforeEach.fixture.js │ │ ├── bail-with-test.fixture.js │ │ ├── bail.fixture.js │ │ ├── delay-fail.fixture.js │ │ ├── delay-only.fixture.js │ │ ├── delay.fixture.js │ │ ├── dry-run │ │ │ ├── dry-run.fixture.js │ │ │ └── stack-size.fixture.js │ │ ├── extension │ │ │ ├── test1.fixture.js │ │ │ └── test2.fixture.coffee │ │ ├── file-alpha.fixture.js │ │ ├── file-beta.fixture.js │ │ ├── file-theta.fixture.js │ │ ├── forbid-only │ │ │ ├── only-before-each.fixture.js │ │ │ ├── only-before.fixture.js │ │ │ ├── only-empty-suite.fixture.js │ │ │ ├── only-suite.fixture.js │ │ │ ├── only.fixture.js │ │ │ └── passed.fixture.js │ │ ├── forbid-pending │ │ │ ├── before-this-skip.fixture.js │ │ │ ├── beforeEach-this-skip.fixture.js │ │ │ ├── passed.fixture.js │ │ │ ├── pending.fixture.js │ │ │ ├── skip-empty-suite.fixture.js │ │ │ ├── skip-suite.fixture.js │ │ │ ├── skip.fixture.js │ │ │ └── this-skip.fixture.js │ │ ├── grep.fixture.js │ │ ├── ignore │ │ │ ├── fail.fixture.js │ │ │ ├── nested │ │ │ │ ├── fail.fixture.js │ │ │ │ └── pass.fixture.js │ │ │ └── pass.fixture.js │ │ ├── jobs │ │ │ └── fail-in-parallel.fixture.js │ │ ├── only │ │ │ ├── bdd.fixture.js │ │ │ ├── qunit.fixture.js │ │ │ └── tdd.fixture.js │ │ ├── parallel │ │ │ ├── bail.fixture.js │ │ │ ├── exclusive-test-a.fixture.js │ │ │ ├── exclusive-test-b.fixture.js │ │ │ ├── retries-a.fixture.js │ │ │ ├── retries-b.fixture.js │ │ │ ├── syntax-err.fixture.js │ │ │ ├── test-a.fixture.js │ │ │ ├── test-b.fixture.js │ │ │ ├── test-c.fixture.js │ │ │ ├── test-d.fixture.js │ │ │ └── uncaught.fixture.js │ │ ├── reporter-with-options.fixture.js │ │ ├── retries.fixture.js │ │ ├── slow-test.fixture.js │ │ ├── sort-alpha.fixture.js │ │ ├── sort-beta.fixture.js │ │ ├── timeout-unref.fixture.js │ │ └── watch │ │ │ ├── dependency.fixture.js │ │ │ ├── hook.fixture.js │ │ │ ├── test-file-change.fixture.js │ │ │ └── test-with-dependency.fixture.js │ ├── parallel │ │ ├── circular-error-array.mjs │ │ ├── circular-error-object.mjs │ │ ├── getter-error-object.mjs │ │ ├── non-circular-error.mjs │ │ ├── test1.mjs │ │ ├── test2.mjs │ │ ├── test3.mjs │ │ ├── testworkerid1.mjs │ │ ├── testworkerid2.mjs │ │ └── testworkerid3.mjs │ ├── passing-async.fixture.js │ ├── passing-sync.fixture.js │ ├── passing.fixture.js │ ├── pending │ │ ├── programmatic.fixture.js │ │ ├── skip-async-before-hooks.fixture.js │ │ ├── skip-async-before-nested.fixture.js │ │ ├── skip-async-before.fixture.js │ │ ├── skip-async-beforeEach.fixture.js │ │ ├── skip-async-spec.fixture.js │ │ ├── skip-hierarchy.fixture.js │ │ ├── skip-shorthand.fixture.js │ │ ├── skip-sync-after.fixture.js │ │ ├── skip-sync-before-hooks.fixture.js │ │ ├── skip-sync-before-inner.fixture.js │ │ ├── skip-sync-before-nested.fixture.js │ │ ├── skip-sync-before.fixture.js │ │ ├── skip-sync-beforeEach-cond.fixture.js │ │ ├── skip-sync-beforeEach.fixture.js │ │ ├── skip-sync-spec.fixture.js │ │ └── spec.fixture.js │ ├── plugins │ │ ├── global-fixtures │ │ │ ├── global-setup-teardown-multiple.fixture.js │ │ │ ├── global-setup-teardown.fixture.js │ │ │ ├── global-setup.fixture.js │ │ │ └── global-teardown.fixture.js │ │ └── root-hooks │ │ │ ├── esm │ │ │ ├── package.json │ │ │ └── root-hook-defs-esm.fixture.js │ │ │ ├── root-hook-defs-a.fixture.js │ │ │ ├── root-hook-defs-b.fixture.js │ │ │ ├── root-hook-defs-c.fixture.js │ │ │ ├── root-hook-defs-d.fixture.js │ │ │ ├── root-hook-defs-esm-broken.fixture.js │ │ │ ├── root-hook-defs-esm.fixture.mjs │ │ │ ├── root-hook-test-2.fixture.js │ │ │ └── root-hook-test.fixture.js │ ├── regression │ │ ├── issue-1991.fixture.js │ │ ├── issue-2315.fixture.js │ │ ├── issue-2406.fixture.js │ │ └── issue-2417.fixture.js │ ├── reporters.fixture.js │ ├── retries │ │ ├── async.fixture.js │ │ ├── early-pass.fixture.js │ │ ├── hooks.fixture.js │ │ └── nested.fixture.js │ ├── runner │ │ ├── events-bail-retries.fixture.js │ │ ├── events-bail.fixture.js │ │ ├── events-basic.fixture.js │ │ ├── events-delay.fixture.js │ │ └── events-retries.fixture.js │ ├── signals-sigabrt.fixture.js │ ├── signals-sigterm-numeric.fixture.js │ ├── signals-sigterm.fixture.js │ ├── simple-reporter.js │ ├── simple-ui.fixture.js │ ├── suite │ │ ├── suite-no-callback.fixture.js │ │ ├── suite-returning-value.fixture.js │ │ ├── suite-skipped-callback.fixture.js │ │ └── suite-skipped-no-callback.fixture.js │ ├── test-for-simple-ui.fixture.js │ ├── timeout-override.fixture.js │ ├── timeout.fixture.js │ └── uncaught │ │ ├── after-runner.fixture.js │ │ ├── double.fixture.js │ │ ├── fatal.fixture.js │ │ ├── hook.fixture.js │ │ ├── issue-1327.fixture.js │ │ ├── issue-1417.fixture.js │ │ ├── listeners.fixture.js │ │ ├── pending.fixture.js │ │ ├── recover.fixture.js │ │ └── unhandled.fixture.js ├── glob.spec.js ├── helpers.js ├── hook-err.spec.js ├── hooks.spec.js ├── init.spec.js ├── invalid-arguments.spec.js ├── multiple-done.spec.js ├── multiple-runs.spec.js ├── no-diff.spec.js ├── only.spec.js ├── options │ ├── allowUncaught.spec.js │ ├── asyncOnly.spec.js │ ├── bail.spec.js │ ├── compilers.spec.js │ ├── delay.spec.js │ ├── dryRun.spec.js │ ├── exit.spec.js │ ├── extension.spec.js │ ├── failZero.spec.js │ ├── file.spec.js │ ├── forbidOnly.spec.js │ ├── forbidPending.spec.js │ ├── grep.spec.js │ ├── ignore.spec.js │ ├── invert.spec.js │ ├── jobs.spec.js │ ├── listInterfaces.spec.js │ ├── listReporters.spec.js │ ├── node-flags.spec.js │ ├── opts.spec.js │ ├── parallel.spec.js │ ├── passOnFailingTestSuite.spec.js │ ├── posixExitCodes.spec.js │ ├── reporter-option.spec.js │ ├── retries.spec.js │ ├── sort.spec.js │ ├── timeout.spec.js │ ├── ui.spec.js │ └── watch.spec.js ├── parallel.spec.js ├── pending.spec.js ├── plugins │ ├── global-fixtures.spec.js │ └── root-hooks.spec.js ├── regression.spec.js ├── reporters.spec.js ├── retries.spec.js ├── suite.spec.js ├── timeout.spec.js └── uncaught.spec.js ├── interfaces ├── bdd.spec.js ├── exports.spec.js ├── qunit.spec.js └── tdd.spec.js ├── jsapi └── index.js ├── node-unit ├── buffered-worker-pool.spec.js ├── cli │ ├── config.spec.js │ ├── fixtures │ │ ├── bad-module.fixture.js │ │ └── bad-require.fixture.js │ ├── mocha-flags.spec.js │ ├── node-flags.spec.js │ ├── options.spec.js │ ├── run-helpers.spec.js │ └── run.spec.js ├── esm-utils.spec.js ├── fixtures │ ├── dumb-module.fixture.js │ ├── dumber-module.fixture.js │ └── wonky-reporter.fixture.js ├── mocha.spec.js ├── parallel-buffered-runner.spec.js ├── reporters │ └── parallel-buffered.spec.js ├── serializer.spec.js ├── stack-trace-filter.spec.js ├── utils.spec.js └── worker.spec.js ├── only ├── bdd-require.spec.js └── global │ ├── bdd.spec.js │ ├── qunit.spec.js │ └── tdd.spec.js ├── reporters ├── base.spec.js ├── doc.spec.js ├── dot.spec.js ├── helpers.js ├── json-stream.spec.js ├── json.spec.js ├── landing.spec.js ├── list.spec.js ├── markdown.spec.js ├── min.spec.js ├── nyan.spec.js ├── progress.spec.js ├── spec.spec.js ├── tap.spec.js └── xunit.spec.js ├── require ├── a.js ├── b.coffee ├── c.js ├── d.coffee └── require.spec.js ├── setup.js ├── smoke └── smoke.spec.js └── unit ├── context.spec.js ├── duration.spec.js ├── errors.spec.js ├── globals.spec.js ├── grep.spec.js ├── hook-async.spec.js ├── hook-sync-nested.spec.js ├── hook-sync.spec.js ├── hook-timeout.spec.js ├── hook.spec.js ├── mocha.spec.js ├── overspecified-async.spec.js ├── parse-query.spec.js ├── plugin-loader.spec.js ├── required-tokens.spec.js ├── root.spec.js ├── runnable.spec.js ├── runner.spec.js ├── suite.spec.js ├── test.spec.js ├── throw.spec.js ├── timeout.spec.js └── utils.spec.js /.browserslistrc: -------------------------------------------------------------------------------- 1 | node >= 14 2 | last 2 Chrome versions 3 | last 2 Edge versions 4 | last 2 Firefox versions 5 | last 2 Safari versions 6 | last 2 Opera versions 7 | unreleased Chrome versions 8 | unreleased Edge versions 9 | unreleased Firefox versions 10 | unreleased Safari versions 11 | unreleased Opera versions 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | end_of_line = lf 8 | charset = utf-8 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | indent_style = space 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /.fossaignore: -------------------------------------------------------------------------------- 1 | CONTRIBUTING.md 2 | MAINTAINERS.md 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /.github/DEVELOPMENT.md: -------------------------------------------------------------------------------- 1 | # Development 2 | 3 | Follow these steps to get going in local development. 4 | If you are having trouble, don't be afraid to [ask for help](./CONTRIBUTING.md#❓-got-a-question). 5 | 6 | ## Prerequisites 7 | 8 | - [Install Node.js 14 LTS or newer with npm@7+](https://nodejs.org/en/download). 9 | - 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. 10 | - You will need [Google Chrome](https://www.google.com/chrome) to run browser-based tests locally. 11 | 12 | ## Setup 13 | 14 | 1. Follow [Github's documentation](https://help.github.com/articles/fork-a-repo) on setting up Git, forking, and cloning. 15 | 1. Execute `npm install` to install the development dependencies. 16 | - Do not use `yarn install` or `pnpm install`. 17 | - Some optional dependencies may fail; you can safely ignore these unless you are trying to build the documentation. 18 | - If you're sick of seeing the failures, run `npm install --ignore-scripts`. 19 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | open_collective: mochajs 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Documentation Website 4 | about: Please read our documentation website before filing new issues. 5 | url: https://mochajs.org 6 | - name: Documentation Website > APIs 7 | about: If you're using Mocha's API, see also the website's API docs. 8 | url: https://mochajs.org/api 9 | - name: Discord 10 | about: Our Discord is the right place for quick informal questions. 11 | url: https://discord.gg/KeDn2uXhER 12 | - name: StackOverflow 13 | about: For more questions, see the `mocha` tag on StackOverflow. 14 | url: https://stackoverflow.com/questions/tagged/mocha 15 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | ## PR Checklist 6 | 7 | - [ ] Addresses an existing open issue: fixes #000 8 | - [ ] 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) 9 | - [ ] Steps in [CONTRIBUTING.md](https://github.com/mochajs/mocha/blob/main/.github/CONTRIBUTING.md) were taken 10 | 11 | ## Overview 12 | 13 | 14 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: 'github-actions' 4 | directory: '/' 5 | schedule: 6 | interval: 'weekly' 7 | groups: 8 | github-actions: 9 | patterns: 10 | - '*' 11 | -------------------------------------------------------------------------------- /.github/release-please/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/googleapis/release-please/v16.12.0/schemas/config.json", 3 | "release-type": "node", 4 | "include-component-in-tag": false, 5 | 6 | "changelog-sections": [ 7 | { "type": "feat", "section": "🌟 Features", "hidden": false }, 8 | { "type": "fix", "section": "🩹 Fixes", "hidden": false }, 9 | { "type": "docs", "section": "📚 Documentation", "hidden": false }, 10 | 11 | { "type": "chore", "section": "🧹 Chores", "hidden": false }, 12 | { "type": "perf", "section": "🧹 Chores", "hidden": false }, 13 | { "type": "refactor", "section": "🧹 Chores", "hidden": false }, 14 | { "type": "test", "section": "🧹 Chores", "hidden": false }, 15 | 16 | { "type": "build", "section": "🤖 Automation", "hidden": false }, 17 | { "type": "ci", "section": "🤖 Automation", "hidden": true } 18 | ], 19 | "packages": { 20 | ".": {} 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.github/release-please/manifest.json: -------------------------------------------------------------------------------- 1 | {".":"11.5.0"} 2 | -------------------------------------------------------------------------------- /.github/workflows/browser-test.yml: -------------------------------------------------------------------------------- 1 | name: Browser Tests for forked PRs 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - labeled 7 | 8 | permissions: 9 | contents: read 10 | pull-requests: write 11 | 12 | jobs: 13 | test-browser: 14 | name: 'Browser Tests' 15 | if: contains(github.event.pull_request.labels.*.name, 'run-browser-test') 16 | uses: ./.github/workflows/npm-script.yml 17 | secrets: inherit 18 | with: 19 | npm-script: test.browser 20 | 21 | remove-label: 22 | needs: test-browser 23 | if: always() 24 | runs-on: ubuntu-latest 25 | steps: 26 | - name: remove 'run-browser-test' label 27 | uses: buildsville/add-remove-label@ac59c9f0aeb66eb12d6366eb1d69ec1906e9ef9a 28 | with: 29 | token: ${{secrets.GITHUB_TOKEN}} 30 | label: run-browser-test 31 | type: remove 32 | -------------------------------------------------------------------------------- /.github/workflows/compliance.yml: -------------------------------------------------------------------------------- 1 | jobs: 2 | compliance: 3 | runs-on: ubuntu-latest 4 | steps: 5 | - uses: mtfoley/pr-compliance-action@11b664f0fcf2c4ce954f05ccfcaab6e52b529f86 6 | with: 7 | body-auto-close: false 8 | ignore-team-members: false 9 | 10 | name: Compliance 11 | 12 | on: 13 | pull_request: 14 | branches: 15 | - main 16 | types: 17 | - edited 18 | - opened 19 | - reopened 20 | - synchronize 21 | 22 | permissions: 23 | pull-requests: write 24 | -------------------------------------------------------------------------------- /.github/workflows/nightly-site-deploy.yml: -------------------------------------------------------------------------------- 1 | # Deploy `mochajs.org` branch nightly by hitting a netlify build URL. 2 | # This updates the list of supporters 3 | # It uses commands from netlify.toml at root of repo 4 | 5 | name: Nightly mochajs.org Deploy 6 | 7 | on: 8 | schedule: 9 | - cron: '0 0 * * *' 10 | 11 | permissions: 12 | contents: read 13 | 14 | jobs: 15 | deploy: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Webhook Action 19 | uses: joelwmale/webhook-action@cc1a66f987e1591785273fd6f9d2f7a9d8d7c9cd 20 | env: 21 | data: '' 22 | WEBHOOK_URL: ${{ secrets.NETLIFY_NIGHTLY_DEPLOY_URL }} 23 | -------------------------------------------------------------------------------- /.knip.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/knip@5/schema-jsonc.json", 3 | "entry": [ 4 | "bin/mocha.js!", 5 | "bin/_mocha!", 6 | "browser-entry.js!", 7 | "index.js!", 8 | "lib/cli/index.js!", 9 | ".eleventy.js", 10 | "karma.conf.js" 11 | ], 12 | "project": [ 13 | "{bin,lib,scripts,test}/**/*.{js,ts,mjs,cjs}" 14 | ], 15 | "ignore": [ 16 | "test/integration/fixtures/esm/type-module/test-that-imports-non-existing-module.fixture.js", 17 | "test/integration/fixtures/options/watch/test-with-dependency.fixture.js" 18 | ], 19 | "ignoreDependencies": [ 20 | "@mocha/docdash", 21 | "coffeescript", 22 | "fake", 23 | "jsdoc-ts-utils", 24 | "karma-chrome-launcher", 25 | "karma-mocha-reporter", 26 | "karma-mocha", 27 | "karma-sauce-launcher", 28 | "non-existent-package", 29 | "prettier" 30 | ], 31 | "mocha": { 32 | "entry": ["test/**/*.{js,ts,mjs,cjs}"] 33 | }, 34 | "webpack": { 35 | "config": "test/browser-specific/fixtures/webpack/webpack.config.js" 36 | }, 37 | "rules": { 38 | "exports": "off" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "@(**/*.js|bin/*)": ["eslint --fix"], 3 | "!(package*).json": ["prettier --write"], 4 | "*.{yml,md,html}": ["prettier --write"] 5 | } 6 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "no-inline-html": false, 3 | "line-length": false, 4 | "no-trailing-punctuation": false, 5 | "no-duplicate-header": false, 6 | "first-header-h1": false, 7 | "first-line-h1": false, 8 | "commands-show-output": false, 9 | "single-h1": false, 10 | "fenced-code-language": false 11 | } 12 | -------------------------------------------------------------------------------- /.mocharc.yml: -------------------------------------------------------------------------------- 1 | require: 'test/setup' 2 | ui: 'bdd' 3 | global: 4 | - 'okGlobalA,okGlobalB' 5 | - 'okGlobalC' 6 | - 'callback*' 7 | timeout: 1000 8 | watch-ignore: 9 | - '.*' 10 | - 'docs/_site/**' 11 | - 'node_modules' 12 | - 'coverage' 13 | - 'cache' 14 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | message=Release v%s -------------------------------------------------------------------------------- /.nycrc: -------------------------------------------------------------------------------- 1 | { 2 | "reporter": [ 3 | "json", 4 | "text-summary" 5 | ], 6 | "exclude": [ 7 | "coverage/**", 8 | "docs/**", 9 | "packages/*/test{,s}/**", 10 | "**/*.d.ts", 11 | "test{,s}/**", 12 | "test{,-*}.{js,cjs,mjs,ts}", 13 | "**/*{.,-}test.{js,cjs,mjs,ts}", 14 | "**/__tests__/**", 15 | "**/{karma,rollup,webpack}.config.js", 16 | "**/{babel.config,.eslintrc,.mocharc}.{js,cjs}", 17 | "lib/browser/**", 18 | "package-scripts.js", 19 | "scripts/**" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /FUNDING.md: -------------------------------------------------------------------------------- 1 | # Fund Usage Guidelines 2 | 3 | This project follows [Collective Funds Guidelines 0.1](https://github.com/collective-funds/guidelines) with the below customizations. 4 | 5 | ## Rates 6 | 7 | * TSC Members: $50.00 USD/hour 8 | * Project Contributors: $50.00 USD/hour 9 | 10 | ## Additional notes 11 | 12 | The 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/). 13 | 14 | In 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). 15 | 16 | When/if the two are in conflict, the Terms of Fiscal Sponsorship is the one that will be followed. 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2011-2024 OpenJS Foundation and contributors, https://openjsf.org 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Security contact information 4 | 5 | To report a security vulnerability, please use the 6 | [Tidelift security contact](https://tidelift.com/security). 7 | Tidelift will coordinate the fix and disclosure. 8 | -------------------------------------------------------------------------------- /assets/mocha-banner-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/assets/mocha-banner-192.png -------------------------------------------------------------------------------- /assets/mocha-fixture-wizard.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/assets/mocha-fixture-wizard.sketch -------------------------------------------------------------------------------- /assets/mocha-logo-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/assets/mocha-logo-128.png -------------------------------------------------------------------------------- /assets/mocha-logo-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/assets/mocha-logo-192.png -------------------------------------------------------------------------------- /assets/mocha-logo-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/assets/mocha-logo-64.png -------------------------------------------------------------------------------- /assets/mocha-logo-96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/assets/mocha-logo-96.png -------------------------------------------------------------------------------- /assets/opencollective-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/assets/opencollective-header.png -------------------------------------------------------------------------------- /bin/_mocha: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | /** 5 | * This file remains for backwards compatibility only. 6 | * Don't put stuff in this file. 7 | * @see module:lib/cli 8 | */ 9 | 10 | require('../lib/cli').main(); 11 | -------------------------------------------------------------------------------- /docs-next/.gitignore: -------------------------------------------------------------------------------- 1 | .astro/ 2 | dist/ 3 | node_modules/ 4 | src/content/data/supporters.json 5 | -------------------------------------------------------------------------------- /docs-next/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": true 3 | } 4 | -------------------------------------------------------------------------------- /docs-next/README.md: -------------------------------------------------------------------------------- 1 | # Mocha Docs vNext: Built on Astro Starlight 2 | 3 | After `cd`ing into this directory: 4 | 5 | ```shell 6 | npm i 7 | npm run generate 8 | npm run dev 9 | ``` 10 | 11 | To merge with the old site: 12 | 13 | ```shell 14 | npm i 15 | npm run build-with-old 16 | ``` 17 | 18 | To preview the old and new site: 19 | 20 | ```shell 21 | cd .. # back to root dir 22 | npm run docs:preview 23 | ``` 24 | 25 | The new site will be at `http://localhost:8080/next` 26 | -------------------------------------------------------------------------------- /docs-next/netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | command = "npm run docs" 3 | publish = "dist/" 4 | 5 | [build.environment] 6 | DEBUG = "mocha:docs*" 7 | NODE_VERSION = "20" 8 | 9 | [context.deploy-preview] 10 | command = "npm run docs" 11 | publish = "dist/" 12 | -------------------------------------------------------------------------------- /docs-next/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs-next", 3 | "type": "module", 4 | "version": "0.0.1", 5 | "scripts": { 6 | "generate": "node ../docs/_data/supporters.js --write-supporters-json", 7 | "dev": "astro dev", 8 | "start": "astro dev", 9 | "docs": "cd .. && npm i && cd docs-next && npm run generate && npm run build", 10 | "build": "astro check && astro build", 11 | "preview": "astro preview", 12 | "build-with-old": "npm run generate && npm run build -- --outDir ../docs/_site/next", 13 | "astro": "astro" 14 | }, 15 | "dependencies": { 16 | "@astrojs/check": "^0.9.4", 17 | "@astrojs/starlight": "^0.28.4", 18 | "astro": "^4.15.3", 19 | "astro-og-canvas": "^0.5.4", 20 | "debug": "^4.3.7", 21 | "needle": "^3.3.1", 22 | "sharp": "^0.32.5", 23 | "starlight-package-managers": "^0.7.0", 24 | "typescript": "^5.6.3" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /docs-next/public/example/tests.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mocha 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs-next/src/components/Badges.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Image } from "astro:assets"; 3 | import Discord from "./discord.svg"; 4 | 5 | const badges = [ 6 | { 7 | href: "http://npmjs.com/package/mocha", 8 | alt: "npm version", 9 | src: "https://img.shields.io/npm/v/mocha", 10 | }, 11 | { 12 | href: "https://discord.gg/KeDn2uXhER", 13 | alt: "Chat - Discord", 14 | src: Discord, 15 | }, 16 | { 17 | href: "#sponsors", 18 | alt: "OpenCollective sponsors", 19 | src: "https://opencollective.com/mochajs/tiers/sponsors/badge.svg", 20 | }, 21 | { 22 | href: "#backers", 23 | alt: "OpenCollective backers", 24 | src: "https://opencollective.com/mochajs/tiers/backers/badge.svg", 25 | }, 26 | ]; 27 | --- 28 | 29 |
30 | { 31 | badges.map((badge) => ( 32 | 33 | {typeof badge.src === "string" ? ( 34 | {badge.alt} 35 | ) : ( 36 | {badge.alt} 37 | )} 38 | 39 | )) 40 | } 41 |
42 | 43 | 54 | -------------------------------------------------------------------------------- /docs-next/src/components/Head.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { Props } from '@astrojs/starlight/props' 3 | import Default from '@astrojs/starlight/components/Head.astro' 4 | 5 | import thumbnail from "./mocha-thumbnail.svg"; 6 | --- 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs-next/src/components/PageTitle.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Default from "@astrojs/starlight/components/PageTitle.astro"; 3 | import type { ComponentProps } from "astro/types"; 4 | 5 | import HomepagePageTitle from "./HomepagePageTitle.astro"; 6 | 7 | type Props = ComponentProps; 8 | 9 | const isHomepage = Astro.props.slug === ""; 10 | --- 11 | 12 | {isHomepage ? : } 13 | -------------------------------------------------------------------------------- /docs-next/src/components/discord.svg: -------------------------------------------------------------------------------- 1 | chat: DiscordchatDiscord -------------------------------------------------------------------------------- /docs-next/src/content/config.ts: -------------------------------------------------------------------------------- 1 | import { defineCollection } from "astro:content"; 2 | import { docsSchema } from "@astrojs/starlight/schema"; 3 | 4 | export const collections = { 5 | docs: defineCollection({ schema: docsSchema() }), 6 | }; 7 | -------------------------------------------------------------------------------- /docs-next/src/content/data/sponsors.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "href": "https://localizejs.com", 4 | "image": "https://images.opencollective.com/localize/bb2cd4d/logo/256.png", 5 | "title": "Localize" 6 | }, 7 | { 8 | "href": "https://route4me.com", 9 | "image": "https://images.opencollective.com/route4me/71fb6fa/avatar/256.png", 10 | "title": "Route4Me Route Planner" 11 | } 12 | ] 13 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/declaring/pending-tests.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Describing test cases with names that don't yet have a callback. 3 | title: Pending Tests 4 | --- 5 | 6 | "Pending" — as in "someone should write these test cases eventually" — test-cases are those _without_ a callback: 7 | 8 | ```js 9 | describe("Array", function () { 10 | describe("#indexOf()", function () { 11 | // pending test below 12 | it("should return -1 when the value is not present"); 13 | }); 14 | }); 15 | ``` 16 | 17 | Pending tests will be included in the test results and marked as pending. 18 | A pending test is not considered a failed test. 19 | 20 | Read the [inclusive tests section](./inclusive-tests) for an example of conditionally marking a test as pending via `this.skip()`. 21 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/explainers/detecting-multiple-calls-to-done.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Why Mocha determines if the done() callback in a test was called multiple times. 3 | title: Detecting Multiple Calls to done() 4 | --- 5 | 6 | If you use callback-based async tests, Mocha will throw an error if `done()` is called multiple times. 7 | This is handy for catching accidental double callbacks. 8 | 9 | ```javascript 10 | it("double done", function (done) { 11 | // Calling `done()` twice is an error 12 | setImmediate(done); 13 | setImmediate(done); 14 | }); 15 | ``` 16 | 17 | Running the above test will give you the below error message: 18 | 19 | ```bash 20 | $ ./node_modules/.bin/mocha mocha.test.js 21 | 22 | 23 | ✓ double done 24 | 1) double done 25 | 26 | 1 passing (6ms) 27 | 1 failing 28 | 29 | 1) double done: 30 | Error: done() called multiple times 31 | at Object. (mocha.test.js:1:63) 32 | at require (internal/module.js:11:18) 33 | at Array.forEach () 34 | at startup (bootstrap_node.js:187:16) 35 | at bootstrap_node.js:608:3 36 | ``` 37 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/explainers/reporter-spec-duration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/explainers/reporter-spec-duration.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/explainers/test-duration-range.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/explainers/test-duration-range.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/explainers/test-duration.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: A mid-level outline of Mocha's "flow of execution". 3 | title: Test Duration 4 | --- 5 | 6 | Many reporters will display test duration and flag tests that are slow (default: 75ms), as shown here with the SPEC reporter: 7 | 8 | ![test duration](./reporter-spec-duration.png) 9 | 10 | There are three levels of test duration (depicted in the following image): 11 | 12 | 1. FAST: Tests that run within half of the "slow" threshold will show the duration in green (if at all). 13 | 2. NORMAL: Tests that run exceeding half of the threshold (but still within it) will show the duration in yellow. 14 | 3. SLOW: Tests that run exceeding the threshold will show the duration in red. 15 | 16 | ![test duration range](./test-duration-range.png) 17 | 18 | To tweak what's considered "slow", you can use the `slow()` method: 19 | 20 | ```js 21 | describe("something slow", function () { 22 | this.slow(300000); // five minutes 23 | 24 | it("should take long enough for me to go make a sandwich", function () { 25 | // ... 26 | }); 27 | }); 28 | ``` 29 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/explainers/test-fixture-decision-tree.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Helping you decide which API(s) to use for your test fixtures. 3 | title: Test Fixture Decision Tree 4 | --- 5 | 6 | This flowchart will help you decide when to use [hooks](../features/hooks), [root hook plugins](../features/root-hook-plugins) or [global fixtures](../features/global-fixtures). 7 | 8 | import FixtureWizard from "../../../components/FixtureWizard.astro"; 9 | 10 | 11 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/features/arrow-functions.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Working with arrow functions, aka "lambdas". 3 | title: Arrow Functions 4 | --- 5 | 6 | Passing [arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) (aka "lambdas") to Mocha is discouraged. 7 | Lambdas lexically bind `this` and cannot access the Mocha context. 8 | For example, the following code will fail: 9 | 10 | ```js 11 | describe("my suite", () => { 12 | it("my test", () => { 13 | // should set the timeout of this test to 1000 ms; instead will fail 14 | this.timeout(1000); 15 | assert.ok(true); 16 | }); 17 | }); 18 | ``` 19 | 20 | _If you do not need to use_ Mocha's context, lambdas should work. 21 | Be aware that using lambdas will be more painful to refactor if the need eventually arises! 22 | 23 | Alternatively, you can override certain context variables, such as test timeouts, by chain-calling methods of the created tests and/or hooks: 24 | 25 | ```js 26 | describe("my suite", () => { 27 | beforeEach(() => {}).timeout(1000); 28 | it("my test", () => { 29 | assert.ok(true); 30 | }).timeout(1000); 31 | }).timeout(1000); 32 | ``` 33 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/features/assertions.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Using assertion libraries with Mocha 3 | title: Assertions 4 | --- 5 | 6 | Mocha allows you to use any assertion library you wish. 7 | In 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! 8 | This means you can use libraries such as: 9 | 10 | - [better-assert](https://github.com/visionmedia/better-assert) - C-style self-documenting `assert()` 11 | - [chai](https://www.chaijs.com) - `expect()`, `assert()` and `should`-style assertions 12 | - [expect.js](https://github.com/LearnBoost/expect.js) - `expect()` style assertions 13 | - [should.js](https://github.com/shouldjs/should.js) - BDD style shown throughout these docs 14 | - [unexpected](https://unexpected.js.org) - "the extensible BDD assertion toolkit" 15 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/features/diffs.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Displaying actual vs. expected data in test failures. 3 | title: Diffs 4 | --- 5 | 6 | Mocha supports the `err.expected` and `err.actual` properties of any thrown `AssertionError`s from an assertion library. 7 | Mocha will attempt to display the difference between what was expected and what the assertion actually saw. 8 | Here's an example of a "string" diff using `--inline-diffs`: 9 | 10 | ![string diffs](./reporter-string-diffs.png) 11 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/features/reporter-string-diffs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/features/reporter-string-diffs.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/interfaces/about.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Mocha's available DSLs for writing tests. 3 | title: About Interfaces 4 | --- 5 | 6 | Interfaces are how developers write tests to be executed by Mocha. 7 | Mocha's "interface" system allows developers to choose their style of DSL (domain-specific language). 8 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/interfaces/bdd.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The BDD (Behavior-Driven-Design) test interface for Mocha. 3 | title: BDD 4 | --- 5 | 6 | The **BDD** interface provides `describe()`, `context()`, `it()`, `specify()`, `before()`, `after()`, `beforeEach()`, and `afterEach()`. 7 | 8 | `context()` is just an alias for `describe()`, and behaves the same way; it provides a way to keep tests easier to read and organized. 9 | Similarly, `specify()` is an alias for `it()`. 10 | 11 | ```js 12 | describe("Array", function () { 13 | before(function () { 14 | // ... 15 | }); 16 | 17 | describe("#indexOf()", function () { 18 | context("when not present", function () { 19 | it("should not throw an error", function () { 20 | (function () { 21 | [1, 2, 3].indexOf(4); 22 | }).should.not.throw(); 23 | }); 24 | it("should return -1", function () { 25 | [1, 2, 3].indexOf(4).should.equal(-1); 26 | }); 27 | }); 28 | 29 | context("when present", function () { 30 | it("should return the index where the element first appears in the array", function () { 31 | [1, 2, 3].indexOf(3).should.equal(2); 32 | }); 33 | }); 34 | }); 35 | }); 36 | ``` 37 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/interfaces/exports.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The Exports test interface for Mocha. 3 | title: Exports 4 | --- 5 | 6 | The **Exports** interface allows for organizing tests in a modular fashion. 7 | It is particularly useful in larger projects where test suites can be segmented into different files. 8 | 9 | :::note 10 | The Exports interface is not supported in browser environments. 11 | This limitation arises because browsers handle module exports differently from Node.js. 12 | If you intend to run tests in a browser, consider using the BDD or TDD interfaces, which are fully supported. 13 | ::: 14 | 15 | The Exports interface is much like Mocha's predecessor [expresso](https://github.com/tj/expresso). 16 | The keys `before`, `after`, `beforeEach`, and `afterEach` are special-cased, object values are suites, and function values are test-cases: 17 | 18 | ```js 19 | module.exports = { 20 | before: function () { 21 | // ... 22 | }, 23 | 24 | Array: { 25 | "#indexOf()": { 26 | "should return -1 when not present": function () { 27 | [1, 2, 3].indexOf(4).should.equal(-1); 28 | }, 29 | }, 30 | }, 31 | }; 32 | ``` 33 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/interfaces/qunit.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The QUnit test interface for Mocha. 3 | title: QUnit 4 | --- 5 | 6 | The [QUnit](https://qunitjs.com)-inspired interface matches the "flat" look of QUnit, where the test suite title is defined _before_ the test-cases. 7 | Like TDD, it uses `suite()` and `test()`, but resembling BDD, it also contains `before()`, `after()`, `beforeEach()`, and `afterEach()`. 8 | 9 | ```js 10 | function ok(expr, msg) { 11 | if (!expr) throw new Error(msg); 12 | } 13 | 14 | suite("Array"); 15 | 16 | test("#length", function () { 17 | var arr = [1, 2, 3]; 18 | ok(arr.length == 3); 19 | }); 20 | 21 | test("#indexOf()", function () { 22 | var arr = [1, 2, 3]; 23 | ok(arr.indexOf(1) == 0); 24 | ok(arr.indexOf(2) == 1); 25 | ok(arr.indexOf(3) == 2); 26 | }); 27 | 28 | suite("String"); 29 | 30 | test("#length", function () { 31 | ok("foo".length == 3); 32 | }); 33 | ``` 34 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/interfaces/require.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The require interface for Mocha. 3 | title: Require 4 | --- 5 | 6 | The `require` interface allows you to require the `describe` and friend words directly using `require` and call them whatever you want. 7 | This interface is also useful if you want to avoid global variables in your tests. 8 | 9 | :::note 10 | The `require` interface cannot be run via the `node` executable, and must be run via `mocha`. 11 | ::: 12 | 13 | ```js 14 | var testCase = require("mocha").describe; 15 | var pre = require("mocha").before; 16 | var assertions = require("mocha").it; 17 | var assert = require("chai").assert; 18 | 19 | testCase("Array", function () { 20 | pre(function () { 21 | // ... 22 | }); 23 | 24 | testCase("#indexOf()", function () { 25 | assertions("should return -1 when not present", function () { 26 | assert.equal([1, 2, 3].indexOf(4), -1); 27 | }); 28 | }); 29 | }); 30 | ``` 31 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/interfaces/tdd.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The TDD (Test-Driven-Design) test interface for Mocha. 3 | title: TDD 4 | --- 5 | 6 | The **TDD** interface provides `suite()`, `test()`, `suiteSetup()`, `suiteTeardown()`, `setup()`, and `teardown()`: 7 | 8 | ```js 9 | suite("Array", function () { 10 | setup(function () { 11 | // ... 12 | }); 13 | 14 | suite("#indexOf()", function () { 15 | test("should return -1 when not present", function () { 16 | assert.equal(-1, [1, 2, 3].indexOf(4)); 17 | }); 18 | }); 19 | }); 20 | ``` 21 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/interfaces/third-party.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Third-party test interfaces for Mocha. 3 | title: Third-Party Interfaces 4 | --- 5 | 6 | Mocha allows you to define custom interfaces, or UIs. 7 | For more information see [Third party UIs on the wiki](https://github.com/mochajs/mocha/wiki/Third-party-UIs). 8 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/about.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: How Mocha.js displays tests results as they execute and/or as a results summary. 3 | title: About Reporters 4 | --- 5 | 6 | Mocha reporters adjust to the terminal window, and always disable ANSI-escape coloring when the stdio streams are not associated with a TTY. 7 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/dot.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The Dot Matrix test reporter for Mocha. 3 | title: Dot 4 | --- 5 | 6 | Alias: `Dot`, `dot` 7 | 8 | The Dot Matrix reporter is a series of characters which represent test cases. 9 | Failures highlight in red exclamation marks (`!`), pending tests with a blue comma (`,`), and slow tests as yellow. 10 | Good if you prefer minimal output. 11 | 12 | ![dot matrix reporter](./reporter-dot.png) 13 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/html.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The HTML test reporter for Mocha. 3 | title: HTML 4 | --- 5 | 6 | Alias: `HTML`, `html` 7 | 8 | **The HTML reporter is not intended for use on the command-line.** 9 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/json-stream.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The JSON Stream test reporter for Mocha. 3 | title: JSON Stream 4 | --- 5 | 6 | Alias: `JSONStream`, `json-stream` 7 | 8 | The 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. 9 | 10 | ![json stream reporter](./reporter-json-stream.png) 11 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/json.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The JSON test reporter for Mocha. 3 | title: JSON 4 | --- 5 | 6 | Alias: `JSON`, `json` 7 | 8 | The JSON reporter outputs a single large JSON object when the tests have completed (failures or not). 9 | 10 | By default, it will output to the console. 11 | To write directly to a file, use `--reporter-option output=filename.json`. 12 | 13 | ![json reporter](./reporter-json.png) 14 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/landing.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The Landing strip test reporter for Mocha. 3 | title: Landing Strip 4 | --- 5 | 6 | Alias: `Landing`, `landing` 7 | 8 | The Landing Strip reporter is a gimmicky test reporter simulating a plane landing :) unicode ftw 9 | 10 | ![landing strip plane reporter](./reporter-landing.png) 11 | ![landing strip with failure](./reporter-landing-fail.png) 12 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/list.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The List test reporter for Mocha. 3 | title: List 4 | --- 5 | 6 | Alias: `List`, `list` 7 | 8 | The List reporter outputs a simple specifications list as test cases pass or fail, outputting the failure details at the bottom of the output. 9 | 10 | ![list reporter](./reporter-list.png) 11 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/markdown.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The Markdown test reporter for Mocha. 3 | title: Markdown 4 | --- 5 | 6 | Alias: `Markdown`, `markdown` 7 | 8 | The Markdown reporter generates a markdown TOC and body for your test suite. 9 | This 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. 10 | For example, here is the Connect [test output](https://github.com/senchalabs/connect/blob/90a725343c2945aaee637e799b1cd11e065b2bff/tests.md). 11 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/min.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The Min test reporter for Mocha. 3 | title: Min 4 | --- 5 | 6 | Alias: `Min`, `min` 7 | 8 | The Min reporter displays the summary only, while still outputting errors on failure. 9 | This reporter works great with `--watch` as it clears the terminal in order to keep your test summary at the top. 10 | 11 | ![min reporter](./reporter-min.png) 12 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/nyan.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The Nyan test reporter for Mocha. 3 | title: Nyan 4 | --- 5 | 6 | Alias: `Nyan`, `nyan` 7 | 8 | The Nyan reporter is exactly what you might expect: 9 | 10 | ![js nyan cat reporter](./reporter-nyan.png) 11 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/progress.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The Progress test reporter for Mocha. 3 | title: Progress 4 | --- 5 | 6 | Alias: `Progress`, `progress` 7 | 8 | The Progress reporter implements a simple progress-bar: 9 | 10 | ![progress bar](./reporter-progress.png) 11 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/reporter-doc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/reporters/reporter-doc.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/reporter-dot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/reporters/reporter-dot.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/reporter-json-stream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/reporters/reporter-json-stream.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/reporter-json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/reporters/reporter-json.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/reporter-landing-fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/reporters/reporter-landing-fail.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/reporter-landing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/reporters/reporter-landing.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/reporter-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/reporters/reporter-list.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/reporter-min.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/reporters/reporter-min.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/reporter-nyan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/reporters/reporter-nyan.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/reporter-progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/reporters/reporter-progress.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/reporter-spec-fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/reporters/reporter-spec-fail.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/reporter-spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/reporters/reporter-spec.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/reporter-string-diffs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/reporters/reporter-string-diffs.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/reporter-tap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/reporters/reporter-tap.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/spec.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The Spec test reporter for Mocha. 3 | title: Spec 4 | --- 5 | 6 | Alias: `Spec`, `spec` 7 | 8 | This is the default reporter. 9 | The Spec reporter outputs a hierarchical view nested just as the test cases are. 10 | 11 | ![spec reporter](./reporter-spec.png) 12 | ![spec reporter with failure](./reporter-spec-fail.png) 13 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/tap.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The TAP test reporter for Mocha. 3 | title: TAP 4 | --- 5 | 6 | Alias: `TAP`, `tap` 7 | 8 | The TAP reporter emits lines for a [Test-Anything-Protocol](https://en.wikipedia.org/wiki/Test_Anything_Protocol) consumer. 9 | 10 | ![test anything protocol](./reporter-tap.png) 11 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/third-party.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: Third party test reporters for Mocha. 3 | title: Third-Party Reporters 4 | --- 5 | 6 | Mocha allows you to define custom reporters. 7 | For more information see the [wiki](https://github.com/mochajs/mocha/wiki/Third-party-reporters). 8 | 9 | Examples: 10 | 11 | - the [TeamCity reporter](https://github.com/travisjeffery/mocha-teamcity-reporter) 12 | - our [working example](https://github.com/mochajs/mocha-examples/tree/main/packages/third-party-reporter) 13 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/reporters/xunit.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: The XUnit test reporter for Mocha. 3 | title: XUnit 4 | --- 5 | 6 | Alias: `XUnit`, `xunit` 7 | 8 | The XUnit reporter outputs an XUnit-compatible XML document, often applicable in CI servers. 9 | 10 | By default, it will output to the console. 11 | To write directly to a file, use `--reporter-option output=filename.xml`. 12 | 13 | To specify custom report title, use `--reporter-option suiteName="Custom name"`. 14 | 15 | The reporter shows absolute file paths by default. 16 | To show relative paths instead, use `--reporter-option showRelativePaths`. 17 | -------------------------------------------------------------------------------- /docs-next/src/content/docs/running/emacs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/running/emacs.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/running/jetbrains-plugin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/running/jetbrains-plugin.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/running/mocha_side_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/running/mocha_side_bar.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/running/reporter-html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/running/reporter-html.png -------------------------------------------------------------------------------- /docs-next/src/content/docs/running/wallaby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs-next/src/content/docs/running/wallaby.png -------------------------------------------------------------------------------- /docs-next/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /docs-next/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict" 3 | } 4 | -------------------------------------------------------------------------------- /docs/.browserslistrc: -------------------------------------------------------------------------------- 1 | ## Browsers support for autoprefixing CSS for the website 2 | last 2 major versions 3 | not dead 4 | Firefox ESR 5 | -------------------------------------------------------------------------------- /docs/.eleventyignore: -------------------------------------------------------------------------------- 1 | README.md 2 | API.md 3 | LICENSE* 4 | .* 5 | _dist/ 6 | example/ 7 | changelogs/ 8 | api-tutorials/ 9 | _site/ 10 | 11 | -------------------------------------------------------------------------------- /docs/API.md: -------------------------------------------------------------------------------- 1 | # Mocha's API Documentation 2 | 3 | --- 4 | 5 | Congratulations! You've found Mocha's API documentation. These docs are for developers who wish to: 6 | 7 | - Create an extension for Mocha, or 8 | - Develop Mocha itself, or 9 | - Do something else fancy with Mocha 10 | 11 | Otherwise, **you probably want the [main documentation](https://mochajs.org)**. 12 | 13 | ## Other Links 14 | 15 | - **[Main Documentation](https://mochajs.org)** 16 | - **[Release Notes / History / Changes](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md)** 17 | - [Code of Conduct](https://github.com/mochajs/mocha/blob/main/.github/CODE_OF_CONDUCT.md) 18 | - [Discord](https://discord.gg/KeDn2uXhER) (ask questions here!) 19 | - [Issue Tracker](https://github.com/mochajs/mocha/issues) 20 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | mochajs.org 2 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # mochajs.org 2 | 3 | _So you wanna build the site?_ 4 | 5 | [mochajs.org](https://mochajs.org) is built using [Eleventy](https://www.11ty.io/), a simple static site generator. 6 | 7 | ## Development 8 | 9 | 1. Run `npm install` / `npm ci` from working copy root to get Node.js deps. 10 | 1. To include the API documentation, run `npm run docs:api` before the either of the following commands. 11 | 1. To serve the site and rebuild as changes are made, execute `npm run docs-watch`. 12 | 1. To rebuild the site _once_, execute `npm run docs`. 13 | 14 | ### Notes 15 | 16 | - The content lives in `docs/index.md`; everything else is markup, scripts, assets, etc. 17 | - This file (`docs/README.md`) should _not_ be included in the build. 18 | - `docs/_site_` is where the deployed site lives. This directories are _not_ under version control. 19 | -------------------------------------------------------------------------------- /docs/_data/blocklist.json: -------------------------------------------------------------------------------- 1 | [ 2 | "cheap-writing-service", 3 | "coin-master-free-spins", 4 | "cyberflix-tv", 5 | "device-tricks1", 6 | "domywriting", 7 | "emailmarketingservices-io", 8 | "hurtiglaan-nu", 9 | "igor-noskov", 10 | "mochajs", 11 | "my-true-media", 12 | "open-apk-file", 13 | "thetoy", 14 | "trust-my-paper", 15 | "writemypaper4me", 16 | "writerseperhour", 17 | "yiannakis-ttafounas-ttafounas" 18 | ] 19 | -------------------------------------------------------------------------------- /docs/_data/toc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const markdownToc = require('markdown-toc'); 4 | const {readFileSync} = require('node:fs'); 5 | const {resolve} = require('node:path'); 6 | 7 | const IGNORED_HEADINGS_REGEXP = /Features|Table of Contents|Backers|Sponsors/i; 8 | const DOCUMENT_PATH = resolve(__dirname, '..', 'index.md'); 9 | 10 | module.exports = () => { 11 | const doc = readFileSync(DOCUMENT_PATH, 'utf-8'); 12 | return markdownToc(doc, { 13 | slugify: require('uslug'), 14 | firsth1: false, 15 | bullets: '-', 16 | maxdepth: 2, 17 | // if filter is supplied, maxdepth is apparently ignored, 18 | // so we have to do it ourselves. 19 | filter: (str, ele) => ele.lvl < 2 && !IGNORED_HEADINGS_REGEXP.test(str) 20 | }).content; 21 | }; 22 | -------------------------------------------------------------------------------- /docs/_data/usage.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const {stripVTControlCharacters} = require('node:util'); 4 | const {resolve} = require('node:path'); 5 | const {execSync} = require('node:child_process'); 6 | 7 | const executable = require.resolve('../../bin/mocha'); 8 | const flag = '--help'; 9 | 10 | /** 11 | * Return the output of `mocha --help` for display 12 | */ 13 | module.exports = () => { 14 | return stripVTControlCharacters( 15 | String( 16 | execSync(`"${process.execPath}" ${executable} ${flag}`, { 17 | cwd: resolve(__dirname, '..') 18 | }) 19 | ).trim() 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /docs/_headers: -------------------------------------------------------------------------------- 1 | /* 2 | X-Frame-Options: DENY 3 | X-XSS-Protection: 1; mode=block 4 | X-Content-Type-Options: nosniff 5 | Strict-Transport-Security: max-age=31536000; includeSubDomains 6 | Referrer-Policy: strict-origin-when-cross-origin 7 | 8 | ## Far future expires for hashed file names 9 | /static/* 10 | Cache-Control: max-age=31536000 11 | -------------------------------------------------------------------------------- /docs/api-tutorials/jsdoc.tutorials.json: -------------------------------------------------------------------------------- 1 | { 2 | "custom-reporter": { 3 | "title": "Create a Custom Reporter" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /docs/changelogs/README.md: -------------------------------------------------------------------------------- 1 | # Historical Changelogs 2 | 3 | These are changelogs for (very) old versions of Mocha. 4 | 5 | These changelogs are _not_ included in the website, and are here only for archival purposes. 6 | 7 | _If you're looking for the current changelog, [here is the current changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md)._ 8 | -------------------------------------------------------------------------------- /docs/css/supporters.css: -------------------------------------------------------------------------------- 1 | .image-list-wide a, 2 | .image-list-wide li { 3 | width: 100%; 4 | } 5 | 6 | .backer, 7 | .sponsor { 8 | background-position: center; 9 | background-repeat: no-repeat; 10 | background-size: contain; 11 | } 12 | 13 | .sponsor { 14 | height: 64px; 15 | width: 100%; 16 | } 17 | 18 | .backer { 19 | width: 32px; 20 | height: 32px; 21 | } 22 | -------------------------------------------------------------------------------- /docs/example/async-dump.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const {createHook} = require('async_hooks'); 4 | const {stackTraceFilter} = require('mocha/lib/utils'); 5 | const allResources = new Map(); 6 | const resourceActivity = new Set(); 7 | 8 | const filterStack = stackTraceFilter(); 9 | 10 | const hook = createHook({ 11 | init(asyncId, type, triggerAsyncId) { 12 | allResources.set(asyncId, {type, triggerAsyncId, stack: (new Error()).stack}); 13 | }, 14 | before(asyncId) { 15 | resourceActivity.add(asyncId); 16 | }, 17 | after(asyncId) { 18 | resourceActivity.delete(asyncId); 19 | }, 20 | destroy(asyncId) { 21 | allResources.delete(asyncId); 22 | } 23 | }).enable(); 24 | 25 | global.asyncDump = module.exports = () => { 26 | hook.disable(); 27 | console.error('STUFF STILL IN THE EVENT LOOP:') 28 | allResources.forEach(value=> { 29 | console.error(`Type: ${value.type}`); 30 | console.error(filterStack(value.stack)); 31 | console.error('\n'); 32 | }); 33 | }; 34 | -------------------------------------------------------------------------------- /docs/example/debug-hanging-mocha.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const net = require('net'); 4 | const assert = require('assert'); 5 | 6 | describe('how to debug Mocha when it hangs', function () { 7 | before(function (done) { 8 | const server = net.createServer(); 9 | server.listen(10101, done); 10 | }); 11 | 12 | after(function () { 13 | global.asyncDump(); 14 | }); 15 | 16 | it('should complete, but Mocha should not exit', function(done) { 17 | const sock = net.createConnection(10101, () => { 18 | assert.deepStrictEqual(sock.address().family, 'IPv4'); 19 | done(); 20 | }); 21 | }); 22 | }); -------------------------------------------------------------------------------- /docs/example/tests.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mocha 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/favicon.ico -------------------------------------------------------------------------------- /docs/images/emacs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/emacs.png -------------------------------------------------------------------------------- /docs/images/jetbrains-plugin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/jetbrains-plugin.png -------------------------------------------------------------------------------- /docs/images/join-chat.svg: -------------------------------------------------------------------------------- 1 | chatchatDiscordDiscord 2 | -------------------------------------------------------------------------------- /docs/images/link-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/images/matomo-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/matomo-logo.png -------------------------------------------------------------------------------- /docs/images/mocha_side_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/mocha_side_bar.png -------------------------------------------------------------------------------- /docs/images/reporter-doc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/reporter-doc.png -------------------------------------------------------------------------------- /docs/images/reporter-dot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/reporter-dot.png -------------------------------------------------------------------------------- /docs/images/reporter-html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/reporter-html.png -------------------------------------------------------------------------------- /docs/images/reporter-json-stream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/reporter-json-stream.png -------------------------------------------------------------------------------- /docs/images/reporter-json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/reporter-json.png -------------------------------------------------------------------------------- /docs/images/reporter-landing-fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/reporter-landing-fail.png -------------------------------------------------------------------------------- /docs/images/reporter-landing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/reporter-landing.png -------------------------------------------------------------------------------- /docs/images/reporter-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/reporter-list.png -------------------------------------------------------------------------------- /docs/images/reporter-min.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/reporter-min.png -------------------------------------------------------------------------------- /docs/images/reporter-nyan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/reporter-nyan.png -------------------------------------------------------------------------------- /docs/images/reporter-progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/reporter-progress.png -------------------------------------------------------------------------------- /docs/images/reporter-spec-duration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/reporter-spec-duration.png -------------------------------------------------------------------------------- /docs/images/reporter-spec-fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/reporter-spec-fail.png -------------------------------------------------------------------------------- /docs/images/reporter-spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/reporter-spec.png -------------------------------------------------------------------------------- /docs/images/reporter-string-diffs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/reporter-string-diffs.png -------------------------------------------------------------------------------- /docs/images/reporter-tap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/reporter-tap.png -------------------------------------------------------------------------------- /docs/images/test-duration-range.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/test-duration-range.png -------------------------------------------------------------------------------- /docs/images/wallaby-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/wallaby-logo.png -------------------------------------------------------------------------------- /docs/images/wallaby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/docs/images/wallaby.png -------------------------------------------------------------------------------- /example/config/.mocharc.json: -------------------------------------------------------------------------------- 1 | // This config file contains Mocha's defaults. 2 | // This same configuration could be provided in the `mocha` property of your 3 | // project's `package.json`. 4 | { 5 | "diff": true, 6 | "extension": ["js", "cjs", "mjs"], 7 | "package": "./package.json", 8 | "reporter": "spec", 9 | "slow": "75", 10 | "timeout": "2000", 11 | "ui": "bdd", 12 | "watch-files": ["lib/**/*.js", "test/**/*.js"], 13 | "watch-ignore": ["lib/vendor"] 14 | } 15 | -------------------------------------------------------------------------------- /example/config/.mocharc.jsonc: -------------------------------------------------------------------------------- 1 | // This config file contains Mocha's defaults. 2 | // As you can see, comments are allowed. 3 | // This same configuration could be provided in the `mocha` property of your 4 | // project's `package.json`. 5 | { 6 | "diff": true, 7 | "extension": ["js","cjs","mjs"], 8 | "package": /* 📦 */ "./package.json", 9 | "reporter": /* 📋 */ "spec", 10 | "slow": "75", 11 | "timeout": "2000", 12 | "ui": "bdd", 13 | "watch-files": ["lib/**/*.js", "test/**/*.js"], 14 | "watch-ignore": ["lib/vendor"] 15 | } 16 | -------------------------------------------------------------------------------- /example/config/README.md: -------------------------------------------------------------------------------- 1 | # Mocha Configuration Examples 2 | 3 | In this directory, you'll find example Mocha configurations for Node.js. 4 | 5 | As of this writing, **these examples are intended to illustrate the available options; they are not intended to serve as boilerplates.** 6 | 7 | [Read more about configuration here](https://mochajs.org/#configuring-mocha-nodejs). 8 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('./lib/mocha'); 4 | -------------------------------------------------------------------------------- /jsdoc.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "markdown": { 3 | "hardwrap": true, 4 | "parser": "gfm" 5 | }, 6 | "mocha-docdash": { 7 | "sort": true, 8 | "static": false 9 | }, 10 | "opts": { 11 | "destination": "docs/api", 12 | "encoding": "utf8", 13 | "recurse": true, 14 | "template": "node_modules/@mocha/docdash", 15 | "tutorials": "docs/api-tutorials", 16 | "verbose": true 17 | }, 18 | "plugins": ["./node_modules/jsdoc-ts-utils", "plugins/markdown"], 19 | "source": { 20 | "include": ["lib/", "./docs/API.md", "bin"] 21 | }, 22 | "tags": { 23 | "allowUnknownTags": true 24 | }, 25 | "templates": { 26 | "cleverLinks": false, 27 | "default": { 28 | "includeDate": false, 29 | "outputSourceFiles": true 30 | }, 31 | "monospaceLinks": false 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/browser/highlight-tags.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Highlight the given string of `js`. 5 | * 6 | * @private 7 | * @param {string} js 8 | * @return {string} 9 | */ 10 | function highlight(js) { 11 | return js 12 | .replace(//g, '>') 14 | .replace(/\/\/(.*)/gm, '//$1') 15 | .replace(/('.*?')/gm, '$1') 16 | .replace(/(\d+\.\d+)/gm, '$1') 17 | .replace(/(\d+)/gm, '$1') 18 | .replace( 19 | /\bnew[ \t]+(\w+)/gm, 20 | 'new $1' 21 | ) 22 | .replace( 23 | /\b(function|new|throw|return|var|if|else)\b/gm, 24 | '$1' 25 | ); 26 | } 27 | 28 | /** 29 | * Highlight the contents of tag `name`. 30 | * 31 | * @private 32 | * @param {string} name 33 | */ 34 | module.exports = function highlightTags(name) { 35 | var code = document.getElementById('mocha').getElementsByTagName(name); 36 | for (var i = 0, len = code.length; i < len; ++i) { 37 | code[i].innerHTML = highlight(code[i].innerHTML); 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /lib/browser/parse-query.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Parse the given `qs`. 5 | * 6 | * @private 7 | * @param {string} qs 8 | * @return {Object} 9 | */ 10 | module.exports = function parseQuery(qs) { 11 | return qs 12 | .replace('?', '') 13 | .split('&') 14 | .reduce(function (obj, pair) { 15 | var i = pair.indexOf('='); 16 | var key = pair.slice(0, i); 17 | var val = pair.slice(++i); 18 | 19 | // Due to how the URLSearchParams API treats spaces 20 | obj[key] = decodeURIComponent(val.replace(/\+/g, '%20')); 21 | 22 | return obj; 23 | }, {}); 24 | }; 25 | -------------------------------------------------------------------------------- /lib/browser/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mocha 6 | 7 | 8 | 9 | 10 |
11 | 12 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /lib/cli/commands.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Exports Yargs commands 5 | * @see https://github.com/yargs/yargs/blob/main/docs/advanced.md 6 | * @private 7 | * @module 8 | */ 9 | 10 | module.exports = { 11 | init: require('./init'), 12 | // default command 13 | run: require('./run'), 14 | } 15 | -------------------------------------------------------------------------------- /lib/cli/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('./cli'); 4 | -------------------------------------------------------------------------------- /lib/cli/init.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Command module for "init" command 5 | * 6 | * @private 7 | * @module 8 | */ 9 | 10 | const fs = require('node:fs'); 11 | const path = require('node:path'); 12 | 13 | exports.command = 'init '; 14 | 15 | exports.description = 'create a client-side Mocha setup at '; 16 | 17 | exports.builder = yargs => 18 | yargs.positional('path', { 19 | type: 'string', 20 | normalize: true 21 | }); 22 | 23 | exports.handler = argv => { 24 | const destdir = argv.path; 25 | const srcdir = path.join(__dirname, '..', '..'); 26 | fs.mkdirSync(destdir, {recursive: true}); 27 | const css = fs.readFileSync(path.join(srcdir, 'mocha.css')); 28 | const js = fs.readFileSync(path.join(srcdir, 'mocha.js')); 29 | const tmpl = fs.readFileSync( 30 | path.join(srcdir, 'lib', 'browser', 'template.html') 31 | ); 32 | fs.writeFileSync(path.join(destdir, 'mocha.css'), css); 33 | fs.writeFileSync(path.join(destdir, 'mocha.js'), js); 34 | fs.writeFileSync(path.join(destdir, 'tests.spec.js'), ''); 35 | fs.writeFileSync(path.join(destdir, 'index.html'), tmpl); 36 | }; 37 | -------------------------------------------------------------------------------- /lib/interfaces/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.bdd = require('./bdd'); 4 | exports.tdd = require('./tdd'); 5 | exports.qunit = require('./qunit'); 6 | exports.exports = require('./exports'); 7 | -------------------------------------------------------------------------------- /lib/mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | "diff": true, 3 | "extension": ["js", "cjs", "mjs"], 4 | "package": "./package.json", 5 | "reporter": "spec", 6 | "slow": 75, 7 | "timeout": 2000, 8 | "ui": "bdd", 9 | "watch-ignore": ["node_modules", ".git"] 10 | } 11 | -------------------------------------------------------------------------------- /lib/nodejs/file-unloader.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * This module should not be in the browser bundle, so it's here. 5 | * @private 6 | * @module 7 | */ 8 | 9 | /** 10 | * Deletes a file from the `require` cache. 11 | * @param {string} file - File 12 | */ 13 | exports.unloadFile = file => { 14 | delete require.cache[require.resolve(file)]; 15 | }; 16 | -------------------------------------------------------------------------------- /lib/pending.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | @module Pending 5 | */ 6 | 7 | module.exports = Pending; 8 | 9 | /** 10 | * Initialize a new `Pending` error with the given message. 11 | * 12 | * @param {string} message 13 | */ 14 | function Pending(message) { 15 | this.message = message; 16 | } 17 | -------------------------------------------------------------------------------- /lib/reporters/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Alias exports to a their normalized format Mocha#reporter to prevent a need 4 | // for dynamic (try/catch) requires, which Browserify doesn't handle. 5 | exports.Base = exports.base = require('./base'); 6 | exports.Dot = exports.dot = require('./dot'); 7 | exports.Doc = exports.doc = require('./doc'); 8 | exports.TAP = exports.tap = require('./tap'); 9 | exports.JSON = exports.json = require('./json'); 10 | exports.HTML = exports.html = require('./html'); 11 | exports.List = exports.list = require('./list'); 12 | exports.Min = exports.min = require('./min'); 13 | exports.Spec = exports.spec = require('./spec'); 14 | exports.Nyan = exports.nyan = require('./nyan'); 15 | exports.XUnit = exports.xunit = require('./xunit'); 16 | exports.Markdown = exports.markdown = require('./markdown'); 17 | exports.Progress = exports.progress = require('./progress'); 18 | exports.Landing = exports.landing = require('./landing'); 19 | exports.JSONStream = exports['json-stream'] = require('./json-stream'); 20 | -------------------------------------------------------------------------------- /lib/reporters/min.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * @module Min 4 | */ 5 | /** 6 | * Module dependencies. 7 | */ 8 | 9 | var Base = require('./base'); 10 | var inherits = require('../utils').inherits; 11 | var constants = require('../runner').constants; 12 | var EVENT_RUN_END = constants.EVENT_RUN_END; 13 | var EVENT_RUN_BEGIN = constants.EVENT_RUN_BEGIN; 14 | 15 | /** 16 | * Expose `Min`. 17 | */ 18 | 19 | exports = module.exports = Min; 20 | 21 | /** 22 | * Constructs a new `Min` reporter instance. 23 | * 24 | * @description 25 | * This minimal test reporter is best used with '--watch'. 26 | * 27 | * @public 28 | * @class 29 | * @memberof Mocha.reporters 30 | * @extends Mocha.reporters.Base 31 | * @param {Runner} runner - Instance triggers reporter actions. 32 | * @param {Object} [options] - runner options 33 | */ 34 | function Min(runner, options) { 35 | Base.call(this, runner, options); 36 | 37 | runner.on(EVENT_RUN_BEGIN, function () { 38 | // clear screen 39 | process.stdout.write('\u001b[2J'); 40 | // set cursor position 41 | process.stdout.write('\u001b[1;3H'); 42 | }); 43 | 44 | runner.once(EVENT_RUN_END, this.epilogue.bind(this)); 45 | } 46 | 47 | /** 48 | * Inherit from `Base.prototype`. 49 | */ 50 | inherits(Min, Base); 51 | 52 | Min.description = 'essentially just a summary'; 53 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | # Netlify deploy configuration 2 | # See https://www.netlify.com/docs/continuous-deployment/#deploy-contexts 3 | 4 | # Global settings applied to the whole site. 5 | # 6 | # “publish” is the directory to publish (relative to root of your repo), 7 | # “command” is your build command, 8 | # “base” is directory to change to before starting build. if you set base: 9 | # that is where we will look for package.json/.nvmrc/etc not repo root! 10 | 11 | [build] 12 | command = "npm run docs" 13 | publish = "docs/_site/" 14 | 15 | [build.environment] 16 | DEBUG = "mocha:docs*" 17 | NODE_VERSION = "20" # LTS until 2026-04-30 18 | 19 | [context.deploy-preview] 20 | command = "npm run docs" 21 | publish = "docs/_site/" 22 | -------------------------------------------------------------------------------- /scripts/linkify-changelog.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * Linkify CHANGELOG.md 3 | */ 4 | 5 | import {readFileSync, writeFileSync} from 'node:fs'; 6 | import {remark} from 'remark'; 7 | import remarkGithub from 'remark-github'; 8 | import remarkInlineLinks from 'remark-inline-links'; 9 | 10 | const filepath = new URL('../CHANGELOG.md', import.meta.url); 11 | 12 | writeFileSync( 13 | filepath, 14 | remark() 15 | .data('settings', { 16 | bullet: '-', 17 | incrementListMarker: false, 18 | listItemIndent: 'one' 19 | }) 20 | .use([remarkGithub, remarkInlineLinks]) 21 | .processSync(readFileSync(filepath)) 22 | .toString() 23 | ); 24 | -------------------------------------------------------------------------------- /scripts/pick-from-package-json.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This rollup plugin lets you pick specific fields you want to export 3 | * for the specific case of importing a modules `package.json`. 4 | * 5 | * This helps reduce the file size of the resulting bundle. 6 | * 7 | * @param {object} options 8 | * @param {string[]} options.keys List of keys to export from package.json 9 | */ 10 | export default function pickFromPackageJson({keys}) { 11 | return { 12 | name: 'pick-from-package-json', 13 | load: id => { 14 | if (id.endsWith('mocha/package.json')) { 15 | const manifest = require(id); 16 | 17 | const result = {}; 18 | 19 | for (const key of keys) { 20 | result[key] = manifest[key]; 21 | } 22 | 23 | return {code: JSON.stringify(result)}; 24 | } 25 | return null; 26 | } 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | # About Mocha's Tests 2 | 3 | - **All assertions should be made using [unexpected](http://unexpected.js.org)**, unless there's a good reason not to. Exceptions include: 4 | - 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. 5 | - `test/unit/runnable.spec.js` must avoid 3rd-party code; read source for more info 6 | - Tests asserting interop with other specific assertion libraries. 7 | - All tests have extension `.spec.js`. 8 | - All test fixtures have extension `.fixture.js`. 9 | - All test fixtures are *ignored* by ESLint. 10 | - `mocha.opts` will require `test/setup.js`, which is the main harness. 11 | - `test/assertions.js` contains Mocha-specific types and assertions for `unexpected` 12 | - `test/node-unit/` only runs in Node.js; `test/browser-specific/` only runs in the browser. 13 | - See `../karma.conf.js` for more information on which tests run in the browser. 14 | - 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. 15 | - See `../package-scripts.js` for more info about how things are split up. 16 | -------------------------------------------------------------------------------- /test/browser-specific/esm.spec.mjs: -------------------------------------------------------------------------------- 1 | import './fixtures/esm.fixture.mjs'; 2 | 3 | it('should register a global if it did not fail', function () { 4 | expect(window.MOCHA_IS_OK, 'to be ok'); 5 | }); 6 | 7 | it('should has global Mocha', function () { 8 | expect(window.Mocha, 'not to be', undefined); 9 | }); 10 | -------------------------------------------------------------------------------- /test/browser-specific/fixtures/esm.fixture.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable-next-line import/no-absolute-path */ 2 | import '/base/mocha.js'; 3 | window.MOCHA_IS_OK = true; 4 | -------------------------------------------------------------------------------- /test/browser-specific/fixtures/webpack/webpack.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const FailOnErrorsPlugin = require('fail-on-errors-webpack-plugin'); 4 | const {tmpdir} = require('node:os'); 5 | const {join} = require('node:path'); 6 | 7 | const outputPath = join(tmpdir(), 'mocha-test-webpack'); 8 | 9 | console.error('output dir: %s', outputPath); 10 | 11 | module.exports = { 12 | entry: require.resolve('./webpack.fixture.mjs'), 13 | target: 'browserslist:last 2 Chrome versions', 14 | output: { 15 | path: outputPath 16 | }, 17 | plugins: [ 18 | new FailOnErrorsPlugin({ 19 | failOnErrors: true, 20 | failOnWarnings: false 21 | }) 22 | ] 23 | }; 24 | -------------------------------------------------------------------------------- /test/browser-specific/fixtures/webpack/webpack.fixture.mjs: -------------------------------------------------------------------------------- 1 | /* eslint-disable-next-line no-unused-vars */ 2 | import mocha from '../../../../mocha.js'; 3 | -------------------------------------------------------------------------------- /test/browser-specific/setup.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | process.stdout = require('browser-stdout')(); 4 | 5 | global.expect = require('unexpected') 6 | .clone() 7 | .use(require('unexpected-set')) 8 | .use(require('unexpected-map')) 9 | .use(require('unexpected-sinon')) 10 | .use(require('unexpected-eventemitter')); 11 | -------------------------------------------------------------------------------- /test/compiler-fixtures/foo.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var fs = require('fs'); 4 | 5 | require.extensions['.foo'] = function (module, filename) { 6 | var content; 7 | content = fs.readFileSync(filename, 'utf8'); 8 | var test = 'describe("custom compiler",function(){ it("should work",function() { ' + 9 | 'expect(' + content + ', "to be", 1); }); });'; 10 | return module._compile(test, filename); 11 | }; 12 | -------------------------------------------------------------------------------- /test/compiler/test.coffee: -------------------------------------------------------------------------------- 1 | 2 | obj = foo: 'bar' 3 | 4 | describe 'coffeescript', -> 5 | it 'should work', -> 6 | expect(obj, 'to equal', foo: 'bar') 7 | -------------------------------------------------------------------------------- /test/compiler/test.foo: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /test/integration/color.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var childProcess = require('node:child_process'); 4 | var path = require('node:path'); 5 | 6 | describe('mocha binary', function () { 7 | it('should not output colors to pipe', function (done) { 8 | var command = [path.join('bin', 'mocha'), '--grep', 'missing-test']; 9 | childProcess.execFile(process.execPath, command, function (err, stdout) { 10 | if (err) return done(err); 11 | 12 | expect(stdout, 'not to contain', '[90m'); 13 | 14 | done(); 15 | }); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /test/integration/common-js-require.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const {runMochaAsync} = require('./helpers'); 4 | 5 | describe('common js require', () => { 6 | it('should be able to run a test where all mocha exports are used', async () => { 7 | const result = await runMochaAsync('common-js-require.fixture.js', [ 8 | '--delay' 9 | ]); 10 | expect(result.output, 'to contain', 'running before'); 11 | expect(result.output, 'to contain', 'running suiteSetup'); 12 | expect(result.output, 'to contain', 'running setup'); 13 | expect(result.output, 'to contain', 'running beforeEach'); 14 | expect(result.output, 'to contain', 'running it'); 15 | expect(result.output, 'to contain', 'running afterEach'); 16 | expect(result.output, 'to contain', 'running teardown'); 17 | expect(result.output, 'to contain', 'running suiteTeardown'); 18 | expect(result.output, 'to contain', 'running after'); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /test/integration/compiler-globbing.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var exec = require('node:child_process').exec; 4 | var path = require('node:path'); 5 | 6 | describe('globbing like --compilers', function () { 7 | it('should find a file of each type', function (done) { 8 | exec( 9 | '"' + 10 | process.execPath + 11 | '" "' + 12 | path.join('bin', 'mocha') + 13 | '" -R json --require coffeescript/register --require test/compiler-fixtures/foo.fixture "test/compiler/*.@(coffee|foo)"', 14 | {cwd: path.join(__dirname, '..', '..')}, 15 | function (error, stdout) { 16 | if (error && !stdout) { 17 | return done(error); 18 | } 19 | var results = JSON.parse(stdout); 20 | expect(results, 'to have property', 'tests'); 21 | var titles = []; 22 | for (var index = 0; index < results.tests.length; index += 1) { 23 | expect(results.tests[index], 'to have property', 'fullTitle'); 24 | titles.push(results.tests[index].fullTitle); 25 | } 26 | expect( 27 | titles, 28 | 'to contain', 29 | 'coffeescript should work', 30 | 'custom compiler should work' 31 | ).and('to have length', 2); 32 | done(); 33 | } 34 | ); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /test/integration/deprecate.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('node:assert'); 4 | var run = require('./helpers').runMocha; 5 | var args = []; 6 | 7 | describe('utils.deprecate test', function () { 8 | it('should print unique deprecation only once', function (done) { 9 | run( 10 | 'deprecate.fixture.js', 11 | args, 12 | function (err, res) { 13 | if (err) { 14 | return done(err); 15 | } 16 | var result = res.output.match(/deprecated thing/g) || []; 17 | assert.strictEqual(result.length, 2); 18 | done(); 19 | }, 20 | {stdio: 'pipe'} 21 | ); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /test/integration/duplicate-arguments.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var runMochaJSON = require('./helpers').runMochaJSON; 4 | 5 | describe('when non-array argument is provided multiple times', function () { 6 | describe('when the same argument name is used', function () { 7 | it('should prefer the last value', function (done) { 8 | runMochaJSON( 9 | 'passing-sync', 10 | ['--no-async-only', '--async-only', '--no-async-only'], 11 | function (err, result) { 12 | if (err) { 13 | return done(err); 14 | } 15 | expect(result, 'to have passed'); 16 | done(); 17 | } 18 | ); 19 | }); 20 | }); 21 | 22 | describe('when a different argument name is used', function () { 23 | it('should prefer the last value', function (done) { 24 | runMochaJSON( 25 | 'passing-async', 26 | ['--timeout', '100', '-t', '10'], 27 | function (err, result) { 28 | if (err) { 29 | return done(err); 30 | } 31 | expect(result, 'to have failed'); 32 | done(); 33 | } 34 | ); 35 | }); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /test/integration/fixtures/__default__.fixture.js: -------------------------------------------------------------------------------- 1 | // this generic fixture does nothing special and will be used if no fixture is supplied 2 | 3 | 'use strict'; 4 | 5 | describe('a suite', function() { 6 | it('should succeed', function(done) { 7 | done(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/collect-files.fixture.mjs: -------------------------------------------------------------------------------- 1 | var obj = {foo: 'bar'}; 2 | 3 | describe('mjs', function () { 4 | it('should work', function () { 5 | expect(obj, 'to equal', {foo: 'bar'}); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/config/mocha-config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // a comment 4 | module.exports = { 5 | require: ['foo', 'bar'], 6 | bail: true, 7 | reporter: 'dot', 8 | slow: 60 9 | }; 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/config/mocha-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mocha-config", 3 | "version": "1.0.0", 4 | "description": "Configure Mocha via package", 5 | "main": "index.js", 6 | "peerDependencies": { 7 | "mocha": "^7.0.0" 8 | }, 9 | "keywords": [ 10 | "mocha", 11 | "config" 12 | ], 13 | "license": "CC0" 14 | } 15 | -------------------------------------------------------------------------------- /test/integration/fixtures/config/mocharc.cjs: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // a comment 4 | module.exports = { 5 | require: ['foo', 'bar'], 6 | bail: true, 7 | reporter: 'dot', 8 | slow: 60 9 | }; 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/config/mocharc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // a comment 4 | module.exports = { 5 | require: ['foo', 'bar'], 6 | bail: true, 7 | reporter: 'dot', 8 | slow: 60 9 | }; 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/config/mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | // a comment 3 | "require": ["foo", "bar"], 4 | "bail": true, 5 | "reporter": "dot", 6 | "slow": 60 7 | } 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/config/mocharc.yaml: -------------------------------------------------------------------------------- 1 | # a comment 2 | require: 3 | - foo 4 | - bar 5 | bail: true 6 | reporter: dot 7 | slow: 60 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/config/mocharcWithThrowError.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | throw new Error("Error from mocharcWithThrowError"); 4 | 5 | // a comment 6 | module.exports = { 7 | require: ['foo', 'bar'], 8 | bail: true, 9 | reporter: 'dot', 10 | slow: 60 11 | }; 12 | -------------------------------------------------------------------------------- /test/integration/fixtures/current-test-title.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var assert = require('assert'); 3 | 4 | function getTitle(ctx) { 5 | return ctx.currentTest && ctx.currentTest.title; 6 | }; 7 | 8 | before(function () { 9 | assert.strictEqual(getTitle(this), undefined); 10 | }); 11 | 12 | describe('suite A', () => { 13 | 14 | before(function () { 15 | assert.strictEqual(getTitle(this), undefined); 16 | }); 17 | 18 | describe('suite B', () => { 19 | 20 | it('test1 B', () => {}); 21 | 22 | describe('suite C', function () { 23 | var lap = 0; 24 | 25 | before(function () { 26 | assert.strictEqual(getTitle(this), 'test1 C'); 27 | }); 28 | beforeEach(function () { 29 | assert.strictEqual(getTitle(this), ++lap === 1 ? 'test1 C' : 'test2 C'); 30 | }); 31 | 32 | it('test1 C', function () {}); 33 | it('test2 C', function () {}); 34 | 35 | afterEach(function () { 36 | assert.strictEqual(getTitle(this), lap === 1 ? 'test1 C' : 'test2 C'); 37 | }); 38 | after(function () { 39 | assert.strictEqual(getTitle(this), 'test2 C'); 40 | }); 41 | }); 42 | }); 43 | }); 44 | 45 | after(function () { 46 | assert.strictEqual(getTitle(this), undefined); 47 | }); 48 | -------------------------------------------------------------------------------- /test/integration/fixtures/deprecate.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var errors = require("../../../lib/errors"); 4 | 5 | it('consolidates identical calls to deprecate', function() { 6 | errors.deprecate("suite foo did a deprecated thing"); 7 | errors.deprecate("suite foo did a deprecated thing"); 8 | errors.deprecate("suite bar did a deprecated thing"); 9 | }); 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/diffs/diffs.css.in: -------------------------------------------------------------------------------- 1 | body { 2 | font: "Helvetica Neue", Helvetica, arial, sans-serif; 3 | background: black; 4 | color: white; 5 | } 6 | 7 | a { 8 | color: blue 9 | } 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/diffs/diffs.css.out: -------------------------------------------------------------------------------- 1 | body { 2 | font: "Helvetica Neue", Helvetica, arial, sans-serif; 3 | background: black; 4 | color: #fff; 5 | } 6 | 7 | a { 8 | color: blue; 9 | } 10 | 11 | foo { 12 | bar: 'baz'; 13 | } 14 | -------------------------------------------------------------------------------- /test/integration/fixtures/esm/add.mjs: -------------------------------------------------------------------------------- 1 | export function add(a, b) { 2 | return a + b; 3 | } 4 | -------------------------------------------------------------------------------- /test/integration/fixtures/esm/dir-cjs-require/index.js: -------------------------------------------------------------------------------- 1 | global.testPassesIfThisVariableIsDefined = true 2 | -------------------------------------------------------------------------------- /test/integration/fixtures/esm/esm-failure.fixture.mjs: -------------------------------------------------------------------------------- 1 | import {add} from './add.mjs'; 2 | 3 | it('should use a function from an esm, and fail', () => { 4 | expect(add(3, 5), 'to be', 9); 5 | }); 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/esm/esm-success.fixture.mjs: -------------------------------------------------------------------------------- 1 | import {add} from './add.mjs'; 2 | 3 | it('should use a function from an esm', () => { 4 | expect(add(3, 5), 'to be', 8); 5 | }); 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/esm/js-folder/add.js: -------------------------------------------------------------------------------- 1 | export function add(a, b) { 2 | return a + b; 3 | } 4 | -------------------------------------------------------------------------------- /test/integration/fixtures/esm/js-folder/esm-in-js.fixture.js: -------------------------------------------------------------------------------- 1 | import {add} from './add.js'; 2 | 3 | it('should use a function from an esm module with a js extension', () => { 4 | expect(add(3, 5), 'to be', 8); 5 | }); 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/esm/js-folder/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module" 3 | } 4 | -------------------------------------------------------------------------------- /test/integration/fixtures/esm/loader-with-module-not-found/loader-that-recognizes-ts.mjs: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import {fileURLToPath} from 'url' 3 | 4 | /** 5 | * @param {string} specifier 6 | * @param {{ 7 | * conditions: !Array, 8 | * parentURL: !(string | undefined), 9 | * }} context 10 | * @param {Function} defaultResolve 11 | * @returns {Promise<{ url: string }>} 12 | */ 13 | export async function resolve(specifier, context, defaultResolve) { 14 | const extension = path.extname( 15 | fileURLToPath(/**@type {import('url').URL}*/ (new URL(specifier, context.parentURL))), 16 | ) 17 | return await defaultResolve(specifier.replace('.ts', '.mjs'), context, defaultResolve) 18 | } 19 | -------------------------------------------------------------------------------- /test/integration/fixtures/esm/loader-with-module-not-found/test-that-imports-non-existing-module.fixture.mjs: -------------------------------------------------------------------------------- 1 | import 'non-existent-package'; 2 | -------------------------------------------------------------------------------- /test/integration/fixtures/esm/loader-with-module-not-found/test-that-imports-non-existing-module.fixture.ts: -------------------------------------------------------------------------------- 1 | // This file will be resolved to `test-that-imports-non-existing-module.fixture.mjs` by the loader 2 | import 'non-existent-package'; 3 | -------------------------------------------------------------------------------- /test/integration/fixtures/esm/syntax-error/esm-syntax-error.fixture.mjs: -------------------------------------------------------------------------------- 1 | // This is intentionally a syntax error 2 | it('should never run because of a syntax error here', => { 3 | }); 4 | -------------------------------------------------------------------------------- /test/integration/fixtures/esm/test-that-uses-dir-cjs-require.fixture.js/index.js: -------------------------------------------------------------------------------- 1 | // See https://github.com/mochajs/mocha/issues/4665 for an explanation of this test 2 | it('should require a dir import', () => { 3 | expect(global.testPassesIfThisVariableIsDefined, 'to be', true) 4 | }) 5 | -------------------------------------------------------------------------------- /test/integration/fixtures/esm/type-module/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module" 3 | } 4 | -------------------------------------------------------------------------------- /test/integration/fixtures/esm/type-module/test-that-imports-non-existing-module.fixture.js: -------------------------------------------------------------------------------- 1 | import assert from 'assert'; 2 | import './this-module-does-not-exist.js'; 3 | 4 | it('should not pass (or even run) because above import will fail', () => { 5 | assert(true); 6 | }); 7 | -------------------------------------------------------------------------------- /test/integration/fixtures/exit.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var net = require('net'); 4 | 5 | it('should hang when --no-exit used', function (done) { 6 | var server = net.createServer(); 7 | server.listen(55554, done); 8 | }); 9 | -------------------------------------------------------------------------------- /test/integration/fixtures/failing-sync.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'); 4 | 5 | describe('a suite', function() { 6 | it('should succeed', function() { 7 | assert(false); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/failing.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // One passing test and three failing tests 4 | 5 | var assert = require('assert'); 6 | 7 | describe('suite', function () { 8 | it('test1', function () { 9 | assert(true); 10 | }); 11 | 12 | it('test2', function () { 13 | assert(false); 14 | }); 15 | 16 | it('test3', function () { 17 | assert(false); 18 | }); 19 | 20 | it('test4', function () { 21 | assert(false); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /test/integration/fixtures/glob/glob.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('globbing test', function() { 4 | it('should find this test', function() { 5 | // see test/integration/glob.spec.js for details 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/glob/nested/glob.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('globbing test', function() { 4 | it('should find this test', function() { 5 | // see test/integration/glob.spec.js for details 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/hooks/after-each-hook-async-error.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('spec 1', function () { 4 | afterEach(function (done) { 5 | console.log('after'); 6 | process.nextTick(function () { 7 | throw new Error('after each hook error'); 8 | }); 9 | }); 10 | it('should be called because error is in after each hook', function () { 11 | console.log('test 1'); 12 | }); 13 | it('should not be called', function () { 14 | console.log('test 2'); 15 | }); 16 | }); 17 | describe('spec 2', function () { 18 | it('should be called, because hook error was in a sibling suite', function () { 19 | console.log('test 3'); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /test/integration/fixtures/hooks/after-each-hook-error.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('spec 1', function () { 4 | afterEach(function () { 5 | console.log('after'); 6 | throw new Error('after each hook error'); 7 | }); 8 | it('should be called because error is in after each hook', function () { 9 | console.log('test 1'); 10 | }); 11 | it('should not be called', function () { 12 | console.log('test 2'); 13 | }); 14 | }); 15 | describe('spec 2', function () { 16 | it('should be called, because hook error was in a sibling suite', function () { 17 | console.log('test 3'); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /test/integration/fixtures/hooks/after-each-this-test-error.fixture.js: -------------------------------------------------------------------------------- 1 | describe('fail the test from the "after each" hook', function() { 2 | it('should fail', function() { 3 | // but not here 4 | }); 5 | 6 | afterEach(function() { 7 | this.test.error(new Error('failing from after each')); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/hooks/after-hook-async-error.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('spec 1', function () { 4 | after(function (done) { 5 | console.log('after'); 6 | process.nextTick(function () { 7 | throw new Error('after hook error'); 8 | }); 9 | }); 10 | it('should be called because error is in after hook', function () { 11 | console.log('test 1'); 12 | }); 13 | it('should be called because error is in after hook', function () { 14 | console.log('test 2'); 15 | }); 16 | }); 17 | describe('spec 2', function () { 18 | it('should be called, because hook error was in a sibling suite', function () { 19 | console.log('test 3'); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /test/integration/fixtures/hooks/after-hook-deepnested-error.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('spec 1', function () { 4 | it('should pass', function () { }); 5 | describe('spec 2 nested - this title should be used', function () { 6 | after(function() { 7 | throw new Error('after hook nested error'); 8 | }); 9 | describe('spec 3 nested', function () { 10 | it('it nested - this title should not be used', function () { }); 11 | }); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /test/integration/fixtures/hooks/after-hook-error.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('spec 1', function () { 4 | after(function () { 5 | console.log('after'); 6 | throw new Error('after hook error'); 7 | }); 8 | it('should be called because error is in after hook', function () { 9 | console.log('test 1'); 10 | }); 11 | it('should be called because error is in after hook', function () { 12 | console.log('test 2'); 13 | }); 14 | }); 15 | describe('spec 2', function () { 16 | it('should be called, because hook error was in a sibling suite', function () { 17 | console.log('test 3'); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /test/integration/fixtures/hooks/after-hook-nested-error.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('spec 1', function () { 4 | it('should pass', function () { }); 5 | describe('spec nested', function () { 6 | after(function() { 7 | throw new Error('after hook nested error'); 8 | }); 9 | it('it nested - this title should be used', function () { }); 10 | }); 11 | describe('spec 2 nested', function () { 12 | it('it nested - not this title', function () { }); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /test/integration/fixtures/hooks/before-each-hook-async-error.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('spec 1', function () { 4 | beforeEach(function (done) { 5 | console.log('before'); 6 | process.nextTick(function () { 7 | throw new Error('before each hook error'); 8 | }); 9 | }); 10 | it('should not be called because of error in before each hook', function () { 11 | console.log('test 1'); 12 | }); 13 | it('should not be called because of error in before each hook', function () { 14 | console.log('test 2'); 15 | }); 16 | }); 17 | describe('spec 2', function () { 18 | it('should be called, because hook error was in a sibling suite', function () { 19 | console.log('test 3'); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /test/integration/fixtures/hooks/before-each-hook-error.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('spec 1', function () { 4 | beforeEach(function () { 5 | console.log('before'); 6 | throw new Error('before each hook error'); 7 | }); 8 | it('should not be called because of error in before each hook', function () { 9 | console.log('test 1'); 10 | }); 11 | it('should not be called because of error in before each hook', function () { 12 | console.log('test 2'); 13 | }); 14 | }); 15 | describe('spec 2', function () { 16 | it('should be called, because hook error was in a sibling suite', function () { 17 | console.log('test 3'); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /test/integration/fixtures/hooks/before-hook-async-error-tip.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('spec 1', function () { 4 | it('should not blame me', function () { }); 5 | }); 6 | describe('spec 2', function () { 7 | before(function (done) { 8 | process.nextTick(function () { 9 | throw new Error('before hook error'); 10 | }); 11 | }); 12 | it('skipped'); 13 | }); 14 | -------------------------------------------------------------------------------- /test/integration/fixtures/hooks/before-hook-async-error.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('spec 1', function () { 4 | before(function (done) { 5 | console.log('before'); 6 | process.nextTick(function () { 7 | throw new Error('before hook error'); 8 | }); 9 | }); 10 | it('should not be called because of error in before hook', function () { 11 | console.log('test 1'); 12 | }); 13 | it('should not be called because of error in before hook', function () { 14 | console.log('test 2'); 15 | }); 16 | }); 17 | describe('spec 2', function () { 18 | it('should be called, because hook error was in a sibling suite', function () { 19 | console.log('test 3'); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /test/integration/fixtures/hooks/before-hook-deepnested-error.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('spec 1', function () { 4 | it('should pass', function () { }); 5 | describe('spec 2 nested - this title should be used', function () { 6 | before(function() { 7 | throw new Error('before hook nested error'); 8 | }); 9 | describe('spec 3 nested', function () { 10 | it('it nested - this title should not be used', function () { }); 11 | }); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /test/integration/fixtures/hooks/before-hook-error-tip.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('spec 1', function () { 4 | it('should not blame me', function () { }); 5 | }); 6 | describe('spec 2', function () { 7 | before(function () { 8 | throw new Error('before hook error'); 9 | }); 10 | it('skipped'); 11 | }); 12 | -------------------------------------------------------------------------------- /test/integration/fixtures/hooks/before-hook-error.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('spec 1', function () { 4 | before(function () { 5 | console.log('before'); 6 | throw new Error('before hook error'); 7 | }); 8 | it('should not be called because of error in before hook', function () { 9 | console.log('test 1'); 10 | }); 11 | it('should not be called because of error in before hook', function () { 12 | console.log('test 2'); 13 | }); 14 | }); 15 | describe('spec 2', function () { 16 | it('should be called, because hook error was in a sibling suite', function () { 17 | console.log('test 3'); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /test/integration/fixtures/hooks/before-hook-nested-error.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('spec 1', function () { 4 | it('should pass', function () { }); 5 | describe('spec nested', function () { 6 | before(function() { 7 | throw new Error('before hook nested error'); 8 | }); 9 | it('it nested - this title should be used', function () { }); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /test/integration/fixtures/hooks/before-hook-root-error.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | before(function() { 4 | throw new Error('before hook root error'); 5 | }); 6 | 7 | describe('spec 1', function () { 8 | it('should not be called', function () { }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/multiple-done-async.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // The suite below should result in an additional error, but does 4 | // not. Uncomment once this bug is resolved. 5 | 6 | // describe('suite', function() { 7 | // beforeEach(function(done) { 8 | // done(); 9 | // done(); 10 | // }); 11 | 12 | // it('test', function() {}); 13 | // }); 14 | 15 | it('should fail in an async test case', function (done) { 16 | process.nextTick(function () { 17 | done(); 18 | setTimeout(done); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /test/integration/fixtures/multiple-done-before-each.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('suite1', function () { 4 | beforeEach(function (done) { 5 | setTimeout(done, 10); 6 | setTimeout(done, 20); 7 | }); 8 | 9 | it('test1', function (done) { 10 | setTimeout(done, 50); 11 | }); 12 | 13 | it('test2', function (done) { 14 | setTimeout(done, 50); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /test/integration/fixtures/multiple-done-before.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('suite1', function () { 4 | before(function (done) { 5 | setTimeout(done, 10); 6 | setTimeout(done, 30); 7 | }); 8 | 9 | it('test1', function (done) { 10 | setTimeout(done, 50); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /test/integration/fixtures/multiple-done-specs.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('suite', function () { 4 | it('test1', function (done) { 5 | done(); 6 | setTimeout(done, 10); 7 | }); 8 | 9 | it('test2', function (done) { 10 | setTimeout(done, 20); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /test/integration/fixtures/multiple-done-with-error.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | it('should fail in a test-case', function (done) { 4 | process.nextTick(function () { 5 | done(); 6 | done(new Error('second error')); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /test/integration/fixtures/multiple-done.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // The suite below should result in an additional error, but does 4 | // not. Uncomment once this bug is resolved. 5 | 6 | // describe('suite', function() { 7 | // beforeEach(function(done) { 8 | // done(); 9 | // done(); 10 | // }); 11 | 12 | // it('test', function() {}); 13 | // }); 14 | 15 | it('should fail in a test-case', function (done) { 16 | process.nextTick(function () { 17 | done(); 18 | done(); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /test/integration/fixtures/multiple-runs/clean-references.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const Mocha = require('../../../../lib/mocha'); 3 | 4 | const mocha = new Mocha({ reporter: 'json' }); 5 | mocha.cleanReferencesAfterRun(true); 6 | require('./run-thrice-helper')(mocha); 7 | -------------------------------------------------------------------------------- /test/integration/fixtures/multiple-runs/dispose.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const Mocha = require('../../../../lib/mocha'); 3 | 4 | const mocha = new Mocha({ reporter: 'json' }); 5 | mocha.dispose(); 6 | require('./run-thrice-helper')(mocha); 7 | -------------------------------------------------------------------------------- /test/integration/fixtures/multiple-runs/multiple-runs-with-different-output-suite.fixture.js: -------------------------------------------------------------------------------- 1 | describe('Multiple runs', () => { 2 | 3 | /** 4 | * Shared state! Bad practice, but nice for this test 5 | */ 6 | let i = 0; 7 | 8 | it('should skip, fail and pass respectively', function () { 9 | switch (i++) { 10 | case 0: 11 | this.skip(); 12 | case 1: 13 | throw new Error('Expected error'); 14 | default: 15 | // this is fine ☕ 16 | break; 17 | } 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /test/integration/fixtures/multiple-runs/multiple-runs-with-flaky-before-each-suite.fixture.js: -------------------------------------------------------------------------------- 1 | describe('Multiple runs', () => { 2 | 3 | /** 4 | * Shared state! Bad practice, but nice for this test 5 | */ 6 | let i = 0; 7 | 8 | beforeEach(function () { 9 | if (i++ === 0) { 10 | throw new Error('Expected error for this test'); 11 | } 12 | }); 13 | 14 | 15 | it('should be a dummy test', function () { 16 | // this is fine ☕ 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /test/integration/fixtures/multiple-runs/multiple-runs-with-flaky-before-each.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const Mocha = require('../../../../lib/mocha'); 3 | 4 | const mocha = new Mocha({ reporter: 'json' }); 5 | mocha.cleanReferencesAfterRun(false); 6 | mocha.addFile(require.resolve('./multiple-runs-with-flaky-before-each-suite.fixture.js')); 7 | console.log('['); 8 | mocha.run(() => { 9 | console.log(','); 10 | mocha.run(() => { 11 | console.log(']'); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /test/integration/fixtures/multiple-runs/run-thrice-helper.js: -------------------------------------------------------------------------------- 1 | module.exports = function (mocha) { 2 | mocha.addFile(require.resolve('./multiple-runs-with-different-output-suite.fixture.js')); 3 | console.log('['); 4 | try { 5 | mocha.run(() => { 6 | console.log(','); 7 | try { 8 | mocha.run(() => { 9 | console.log(','); 10 | mocha.run(() => { 11 | console.log(']'); 12 | }); 13 | }); 14 | } catch (err) { 15 | console.error(err.code); 16 | throw err; 17 | } 18 | }); 19 | } catch (err) { 20 | console.error(err.code); 21 | throw err; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /test/integration/fixtures/multiple-runs/run-thrice.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const Mocha = require('../../../../lib/mocha'); 3 | 4 | const mocha = new Mocha({ reporter: 'json' }); 5 | mocha.cleanReferencesAfterRun(false); 6 | require('./run-thrice-helper')(mocha); 7 | -------------------------------------------------------------------------------- /test/integration/fixtures/multiple-runs/start-second-run-if-previous-is-still-running-suite.fixture.js: -------------------------------------------------------------------------------- 1 | describe('slow suite', () => { 2 | it('should be slow', (done) => { 3 | setTimeout(200, done); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/multiple-runs/start-second-run-if-previous-is-still-running.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const Mocha = require('../../../../lib/mocha'); 3 | 4 | const mocha = new Mocha({ reporter: 'json' }); 5 | mocha.addFile(require.resolve('./start-second-run-if-previous-is-still-running-suite.fixture.js')); 6 | mocha.run(); 7 | try { 8 | mocha.run(); 9 | } catch (err) { 10 | console.error(err.code); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /test/integration/fixtures/no-diff.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var assert = require('assert'); 3 | 4 | describe('Example test', function () { 5 | it('should fail', function () { 6 | assert.deepStrictEqual([1, 2, 3], ['foo', 'bar', 'baz']); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/allow-uncaught/propagate.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Uncaught exception - throw and exit', () => { 4 | it('test1', () => { 5 | setTimeout(() => { 6 | throw new Error('Uncaught error after test1'); 7 | }, 1); 8 | }); 9 | it('test2', function () { }); 10 | it('test3', function () { }); 11 | it('test4', function () { }); 12 | }); 13 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/allow-uncaught/this-skip-it.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('test suite', () => { 4 | it('test1', function () { }); 5 | it('test2', function (done) { 6 | var self = this; 7 | setTimeout(function () { 8 | self.skip(); 9 | throw new Error("should not throw"); 10 | }, 10); 11 | }); 12 | it('test3', function () { 13 | this.skip(); 14 | throw new Error("should not throw"); 15 | }); 16 | it('test4', function () { }); 17 | it('test5', function () { 18 | this.skip(); 19 | throw new Error("should not throw"); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/async-only-async.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | it('should pass', function (done) { 4 | done(); 5 | }); 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/async-only-sync.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | it('throws an error', function () {}); 4 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/bail-async.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('suite1', function () { 4 | it('should display this spec', function () {}); 5 | 6 | it('should only display this error', function (done) { 7 | throw new Error('this should be displayed'); 8 | }); 9 | 10 | it('should not display this error', function (done) { 11 | throw new Error('this should not be displayed'); 12 | }); 13 | }); 14 | 15 | describe('suite2', function () { 16 | before(function (done) { 17 | throw new Error('this hook should not be displayed'); 18 | }); 19 | 20 | it('should not display this error', function (done) { 21 | throw new Error('this should not be displayed'); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/bail.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('suite1', function () { 4 | it('should display this spec', function () {}); 5 | 6 | it('should only display this error', function () { 7 | throw new Error('this should be displayed'); 8 | }); 9 | 10 | it('should not display this error', function () { 11 | throw new Error('this should not be displayed'); 12 | }); 13 | }); 14 | 15 | describe('suite2', function () { 16 | before(function () { 17 | throw new Error('this hook should not be displayed'); 18 | }); 19 | 20 | it('should not display this error', function () { 21 | throw new Error('this should not be displayed'); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/delay-fail.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | setTimeout(function () { 4 | throw new Error('oops'); 5 | /* eslint no-unreachable: off */ 6 | it('test', function () {}); 7 | run(); 8 | }, 100); 9 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/delay-only.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'); 4 | var delay = 200; 5 | 6 | setTimeout(function () { 7 | describe('delayed execution should execute exclusive tests only', function () { 8 | it('should not run this test', function () { 9 | (true).should.equal(false); 10 | }); 11 | 12 | it.only('should run this', function () {}); 13 | 14 | it('should not run this test, neither', function () { 15 | (true).should.equal(false); 16 | }); 17 | 18 | it.only('should run this, too', function () {}); 19 | }); 20 | 21 | run(); 22 | }, delay); 23 | 24 | 25 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/delay.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'); 4 | var delay = 200; 5 | 6 | setTimeout(function () { 7 | describe('delayed execution', function () { 8 | it('should have no effect if attempted twice in the same suite', function () { 9 | assert(true); 10 | run(); 11 | assert(true); 12 | }); 13 | }); 14 | 15 | run(); 16 | }, delay); 17 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/dry-run/dry-run.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe.only('suite1', function() { 4 | it.skip('test1 - report as skipped', function() { }); 5 | 6 | it('test2 - report as passed', function() { }); 7 | 8 | it('test3 - report as passed', function() { 9 | throw new Error('this test should not run'); 10 | }); 11 | }); 12 | 13 | describe('suite2', function () { 14 | before(function() { 15 | throw new Error('this hook should not run'); 16 | }); 17 | beforeEach(function() { 18 | throw new Error('this hook should not run'); 19 | }); 20 | 21 | it.only('test4 - report as passed', function () { 22 | throw new Error('this test should not run'); 23 | }); 24 | 25 | it('test5 - should be ignored', function () { 26 | throw new Error('this test should not run'); 27 | }); 28 | 29 | afterEach(function() { 30 | throw new Error('this hook should not run'); 31 | }); 32 | after(function() { 33 | throw new Error('this hook should not run'); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/dry-run/stack-size.fixture.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | 3 | describe('Wrapper suite', function () { 4 | for(let i=0; i < 400; i++) { 5 | describe(`suite ${i}`, function () { 6 | it(`test ${i}`, function () { 7 | assert.equal(1, 1); 8 | }); 9 | }); 10 | } 11 | }); 12 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/extension/test1.fixture.js: -------------------------------------------------------------------------------- 1 | var obj = {foo: 'bar'}; 2 | 3 | describe('js', function () { 4 | it('should work', function () { 5 | expect(obj, 'to equal', {foo: 'bar'}); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/extension/test2.fixture.coffee: -------------------------------------------------------------------------------- 1 | 2 | obj = foo: 'bar' 3 | 4 | describe 'coffeescript', -> 5 | it 'should work', -> 6 | expect(obj, 'to equal', foo: 'bar') 7 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/file-alpha.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('alpha', function () { 4 | it('should be executed first', function () { 5 | if (global.beta !== undefined) { 6 | throw new Error('alpha was not executed first'); 7 | } 8 | 9 | if (global.theta !== undefined) { 10 | throw new Error('alpha was not executed first'); 11 | } 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/file-beta.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('beta', function () { 4 | it('should be executed second', function () { 5 | global.beta = 1; 6 | 7 | if (global.theta !== undefined) { 8 | throw new Error('beta was not executed second'); 9 | } 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/file-theta.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('theta', function () { 4 | it('should be executed third', function () { 5 | global.theta = 1; 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/forbid-only/only-before-each.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('test marked with only and beforeEach has skip', function() { 4 | beforeEach(function() { 5 | this.skip(); 6 | }); 7 | it.only('only test', function() {}); 8 | }); 9 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/forbid-only/only-before.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('test marked with only and before has skip', function() { 4 | before(function() { 5 | this.skip(); 6 | }); 7 | it.only('only test', function() {}); 8 | }); 9 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/forbid-only/only-empty-suite.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe.only('forbid only - suite marked with only', function() {}); 4 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/forbid-only/only-suite.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe.only('forbid only - suite marked with only', function() { 4 | it('test1', function() {}); 5 | }); 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/forbid-only/only.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('forbid only - test marked with only', function() { 4 | it('test1', function() {}); 5 | it.only('test2', function() {}); 6 | it('test3', function() {}); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/forbid-only/passed.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('forbid only - `.only` is not used', function() { 4 | it('test1', function() {}); 5 | it('test2', function() {}); 6 | it('test3', function() {}); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/forbid-pending/before-this-skip.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('forbid pending - before calls `skip()`', function() { 4 | it('test', function() {}); 5 | before(function() { 6 | this.skip(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/forbid-pending/beforeEach-this-skip.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('forbid pending - beforeEach calls `skip()`', function() { 4 | it('test', function() {}); 5 | beforeEach(function() { 6 | this.skip(); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/forbid-pending/passed.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('forbid pending - all test pass', function() { 4 | it('test1', function() {}); 5 | it('test2', function() {}); 6 | it('test3', function() {}); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/forbid-pending/pending.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('forbid pending - test without function', function() { 4 | it('test1', function() {}); 5 | it('test2'); 6 | it('test3', function() {}); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/forbid-pending/skip-empty-suite.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe.skip('forbid pending - suite marked with skip', function() {}); 4 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/forbid-pending/skip-suite.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe.skip('forbid pending - suite marked with skip', function() { 4 | it('test1', function() {}); 5 | }); 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/forbid-pending/skip.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('forbid pending - test marked with skip', function() { 4 | it('test1', function() {}); 5 | it.skip('test2', function() {}); 6 | it('test3', function() {}); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/forbid-pending/this-skip.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('forbid pending - test calls `skip()`', function() { 4 | it('test1', function() {}); 5 | it('test2', function() { 6 | this.skip(); 7 | }); 8 | it('test3', function() {}); 9 | }); 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/grep.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('grep', function () { 4 | describe('Match', function () { 5 | it('should run', function () {}); 6 | it('should also run', function () {}); 7 | }); 8 | 9 | describe('match', function () { 10 | it('should run', function () {}); 11 | it('should also run', function () {}); 12 | }); 13 | 14 | describe('fail', function () { 15 | it('should not be ran', function () { 16 | throw new Error('Spec should not run'); 17 | }); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/ignore/fail.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('ignore test fail', function () { 4 | it('should not run this test', function () { 5 | throw new Error('should not run'); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/ignore/nested/fail.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('ignore test nested fail', function () { 4 | it('should not run this test', function () { 5 | throw new Error('should not run'); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/ignore/nested/pass.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('ignore test nested pass', function () { 4 | it('should find this test', function () {}); 5 | }); 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/ignore/pass.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('ignore test pass', function () { 4 | it('should find this test', function () {}); 5 | }); 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/jobs/fail-in-parallel.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | it('should fail if in a worker', function() { 4 | if (!require('workerpool').isMainThread) { 5 | throw new Error('in worker!'); 6 | } 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/only/qunit.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | suite.only('should run all tests in this suite'); 4 | 5 | test('should run this test #1', function () {}); 6 | 7 | test('should run this test #2', function () {}); 8 | 9 | test('should run this test #3', function () {}); 10 | 11 | test('should run this test #4', function () {}); 12 | 13 | test('should run this test #5', function () {}); 14 | 15 | suite('should not run any of this suite\'s tests'); 16 | 17 | test('should not run this test', function () { 18 | (false).should.equal(true); 19 | }); 20 | 21 | test('should not run this test', function () { 22 | (false).should.equal(true); 23 | }); 24 | 25 | test('should not run this test', function () { 26 | (false).should.equal(true); 27 | }); 28 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/only/tdd.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | suite.only('should run all tests in this tdd suite', function () { 4 | test('should run this test #1', function () {}); 5 | 6 | test('should run this test #2', function () {}); 7 | 8 | test('should run this test #3', function () {}); 9 | 10 | test('should run this test #4', function () {}); 11 | }); 12 | 13 | suite('should not run this suite', function () { 14 | test('should not run this test', function () { 15 | (true).should.equal(false); 16 | }); 17 | 18 | test('should not run this test', function () { 19 | (true).should.equal(false); 20 | }); 21 | 22 | test('should not run this test', function () { 23 | (true).should.equal(false); 24 | }); 25 | }); 26 | 27 | suite.only('should run this suite too', function () { 28 | suite('should run this nested suite', function () { 29 | test('should run this test', function () {}); 30 | 31 | test('should run this test', function () {}); 32 | 33 | test('should run this test', function () {}); 34 | 35 | test('should run this test', function () {}); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/parallel/bail.fixture.js: -------------------------------------------------------------------------------- 1 | describe('some suite', function() { 2 | this.bail(true); 3 | 4 | it('should bail', function() { 5 | throw new Error(); 6 | }); 7 | 8 | it('will not get run', function() {}); 9 | }); 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/parallel/exclusive-test-a.fixture.js: -------------------------------------------------------------------------------- 1 | describe.only('it should only run this, but it does not', function() { 2 | it('should do a thing', function() {}); 3 | }); 4 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/parallel/exclusive-test-b.fixture.js: -------------------------------------------------------------------------------- 1 | describe('it should run this anyway', function() { 2 | it('should do a different thing', function() {}); 3 | }); 4 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/parallel/retries-a.fixture.js: -------------------------------------------------------------------------------- 1 | describe('retry suite A', function() { 2 | it('should pass', function() { 3 | 4 | }); 5 | }); -------------------------------------------------------------------------------- /test/integration/fixtures/options/parallel/retries-b.fixture.js: -------------------------------------------------------------------------------- 1 | describe('retry suite B', function() { 2 | let count = 0; 3 | it('should retry', function() { 4 | this.retries(3); 5 | console.log(`count: ${++count}`); 6 | throw new Error('failure'); 7 | }); 8 | }); -------------------------------------------------------------------------------- /test/integration/fixtures/options/parallel/syntax-err.fixture.js: -------------------------------------------------------------------------------- 1 | var foo = -------------------------------------------------------------------------------- /test/integration/fixtures/options/parallel/test-a.fixture.js: -------------------------------------------------------------------------------- 1 | describe('a', function() { 2 | it('should pass', function() {}); 3 | }); 4 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/parallel/test-b.fixture.js: -------------------------------------------------------------------------------- 1 | describe('b', function() { 2 | it('should be pending'); 3 | }); 4 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/parallel/test-c.fixture.js: -------------------------------------------------------------------------------- 1 | describe('c', function() { 2 | it('should fail', function() { 3 | throw new Error('failure'); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/parallel/test-d.fixture.js: -------------------------------------------------------------------------------- 1 | describe('d', function() { 2 | it('should pass, then fail', function() { 3 | process.nextTick(function() { 4 | throw new Error('uncaught!!'); 5 | }); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/parallel/uncaught.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | it('throws an uncaught exception', function (done) { 4 | process.nextTick(function () { 5 | throw new Error('existential isolation!!'); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/reporter-with-options.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function ReporterWithOptions(runner, options) { 4 | console.log(JSON.stringify(options.reporterOption)); 5 | } 6 | 7 | module.exports = ReporterWithOptions; 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/retries.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('retries', function () { 4 | it('should fail', function () { 5 | throw new Error('retry failure'); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/slow-test.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('a suite', function() { 4 | it('should succeed in 500ms', function(done) { 5 | setTimeout(done, 500); 6 | }); 7 | 8 | it('should succeed in 1.1s', function(done) { 9 | setTimeout(done, 1100); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/sort-alpha.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('alpha', function () { 4 | it('should be executed first', function () { 5 | if (global.beta) { 6 | throw new Error('alpha was not executed first'); 7 | } 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/sort-beta.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('beta', function () { 4 | it('should be executed second', function () { 5 | global.beta = 1; 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/timeout-unref.fixture.js: -------------------------------------------------------------------------------- 1 | it('unrefs a timeout', function(done) { 2 | setTimeout(done, 10).unref(); 3 | }); 4 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/watch/dependency.fixture.js: -------------------------------------------------------------------------------- 1 | module.exports.testShouldFail = false; 2 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/watch/hook.fixture.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | mochaHooks: { 3 | [""]: function() { 4 | throw new Error(" Hook Error"); 5 | }, 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/watch/test-file-change.fixture.js: -------------------------------------------------------------------------------- 1 | // This will be replaced in the tests 2 | const testShouldFail = true; 3 | 4 | it('checks dependency', () => { 5 | if (testShouldFail === true) { 6 | throw new Error('test failed'); 7 | } 8 | }); 9 | -------------------------------------------------------------------------------- /test/integration/fixtures/options/watch/test-with-dependency.fixture.js: -------------------------------------------------------------------------------- 1 | const dependency = require('./lib/dependency'); 2 | 3 | it('checks dependency', () => { 4 | if (dependency.testShouldFail === true) { 5 | throw new Error('test failed'); 6 | } 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/parallel/circular-error-array.mjs: -------------------------------------------------------------------------------- 1 | import {describe,it} from "../../../../index.js"; 2 | 3 | describe('test1', () => { 4 | it('test', () => { 5 | const error = new Error('Foo'); 6 | error.foo = { props: [] }; 7 | error.foo.props.push(error.foo); 8 | throw error; 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /test/integration/fixtures/parallel/circular-error-object.mjs: -------------------------------------------------------------------------------- 1 | import {describe,it} from "../../../../index.js"; 2 | 3 | describe('test1', () => { 4 | it('test', () => { 5 | const errorA = {}; 6 | const objectB = {toA: errorA}; 7 | errorA.toB = objectB; 8 | 9 | const error = new Error("Oh no!"); 10 | error.error = errorA; 11 | error.values = [errorA]; 12 | 13 | throw error; 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /test/integration/fixtures/parallel/getter-error-object.mjs: -------------------------------------------------------------------------------- 1 | import {describe, it} from '../../../../index.js'; 2 | 3 | describe('test1', () => { 4 | it('test', async () => { 5 | const error = new Error('Oh no!'); 6 | 7 | error.nested = { 8 | get inner() { 9 | return 'abc'; 10 | } 11 | }; 12 | 13 | throw error; 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /test/integration/fixtures/parallel/non-circular-error.mjs: -------------------------------------------------------------------------------- 1 | import {it} from '../../../../index.js'; 2 | 3 | it('test', () => { 4 | throw new Error('Foo'); 5 | }); 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/parallel/test1.mjs: -------------------------------------------------------------------------------- 1 | import {describe,it} from "../../../../index.js"; 2 | 3 | describe('test1', () => { 4 | it('should pass', () => {}); 5 | }); 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/parallel/test2.mjs: -------------------------------------------------------------------------------- 1 | import {describe,it} from "../../../../index.js"; 2 | 3 | describe('test2', () => { 4 | it('should pass', () => {}); 5 | }); 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/parallel/test3.mjs: -------------------------------------------------------------------------------- 1 | import {describe,it} from "../../../../index.js"; 2 | 3 | describe('test3', () => { 4 | it('should fail', () => { 5 | throw new Error('expecting this error to fail'); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/parallel/testworkerid1.mjs: -------------------------------------------------------------------------------- 1 | import assert from 'assert'; 2 | 3 | describe('test1', () => { 4 | it('should always run on worker with id 0', () => { 5 | assert.ok(process.env.MOCHA_WORKER_ID === '0'); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/parallel/testworkerid2.mjs: -------------------------------------------------------------------------------- 1 | import assert from 'assert'; 2 | 3 | describe('test2', () => { 4 | it('should always run on worker with id 1', () => { 5 | assert.ok(process.env.MOCHA_WORKER_ID === '1'); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/parallel/testworkerid3.mjs: -------------------------------------------------------------------------------- 1 | import assert from 'assert'; 2 | 3 | describe('test3', () => { 4 | it('should run on worker with either id 0 or 1', () => { 5 | assert.ok( 6 | process.env.MOCHA_WORKER_ID === '0' || process.env.MOCHA_WORKER_ID === '1' 7 | ); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/passing-async.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('a suite', function() { 4 | it('should succeed in 50ms', function(done) { 5 | setTimeout(done, 50); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/passing-sync.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('a suite', function() { 4 | it('should succeed', function() { 5 | }); 6 | }); 7 | -------------------------------------------------------------------------------- /test/integration/fixtures/passing.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'); 4 | 5 | describe('suite', function () { 6 | it('test1', function () { 7 | assert(true); 8 | }); 9 | 10 | it('test2', function () { 11 | assert(true); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /test/integration/fixtures/pending/programmatic.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const Mocha = require('../../../../lib/mocha'); 3 | 4 | const mocha = new Mocha({reporter: 'json'}); 5 | mocha.addFile("./test/integration/fixtures/__default__.fixture.js"); 6 | 7 | const runner = mocha.run(); 8 | runner.on('test', function (test) { test.pending = true; }); 9 | -------------------------------------------------------------------------------- /test/integration/fixtures/pending/skip-async-before-nested.fixture.js: -------------------------------------------------------------------------------- 1 | describe('skip in before with nested describes', function () { 2 | before(function (done) { 3 | var self = this; 4 | setTimeout(function () { 5 | self.skip(); // done() is not required 6 | }, 0); 7 | }); 8 | 9 | it('should never run this test', function () { 10 | throw new Error('never run this test'); 11 | }); 12 | 13 | describe('nested describe', function () { 14 | before(function () { 15 | throw new Error('first level before should not run'); 16 | }); 17 | 18 | it('should never run this test', function () { 19 | throw new Error('never run this test'); 20 | }); 21 | 22 | after(function () { 23 | throw new Error('first level after should not run'); 24 | }); 25 | 26 | describe('nested again', function () { 27 | before(function () { 28 | throw new Error('second level before should not run'); 29 | }); 30 | 31 | it('should never run this test', function () { 32 | throw new Error('never run this test'); 33 | }); 34 | 35 | after(function () { 36 | throw new Error('second level after should not run'); 37 | }); 38 | }); 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /test/integration/fixtures/pending/skip-async-before.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('outer describe', function () { 4 | it('should run this test', function () {}); 5 | 6 | describe('skip in before', function () { 7 | before(function (done) { 8 | var self = this; 9 | setTimeout(function () { 10 | self.skip(); // done() is not required 11 | }, 0); 12 | }); 13 | 14 | it('should never run this test', function () { 15 | throw new Error('never run this test'); 16 | }); 17 | it('should never run this test', function () { 18 | throw new Error('never run this test'); 19 | }); 20 | }); 21 | 22 | it('should run this test', function () {}); 23 | }); 24 | -------------------------------------------------------------------------------- /test/integration/fixtures/pending/skip-async-spec.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var assert = require('assert'); 3 | 4 | describe('skip in test', function () { 5 | var runOrder = []; 6 | beforeEach(function () { 7 | runOrder.push('beforeEach'); 8 | }); 9 | 10 | it('should skip async', function (done) { 11 | var self = this; 12 | setTimeout(function () { 13 | self.skip(); // done() is not required 14 | }, 0); 15 | }); 16 | it('should run other tests in suite', function () {}); 17 | 18 | afterEach(function() { 19 | runOrder.push('afterEach'); 20 | }); 21 | after(function() { 22 | runOrder.push('after'); 23 | assert.deepStrictEqual(runOrder, [ 24 | 'beforeEach', 'afterEach', 25 | 'beforeEach', 'afterEach', 26 | 'after' 27 | ]); 28 | throw new Error('should throw this error'); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /test/integration/fixtures/pending/skip-hierarchy.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('a suite', function(){ 4 | describe.skip('skipped suite 1'); 5 | describe.skip('skipped suite 2'); 6 | describe('another suite', function(){ 7 | it('a test', function(){}) 8 | }) 9 | }); 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/pending/skip-shorthand.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('pending shorthand', function () { 4 | xit('pending spec', function () {}).timeout(0); 5 | xspecify('pending spec', function () {}).timeout(0); 6 | it.skip('pending spec', function () {}).timeout(0); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/pending/skip-sync-after.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('skip in after', function () { 4 | it('should run this test-1', function () {}); 5 | 6 | after('should throw "this.skip forbidden"', function () { 7 | this.skip(); 8 | }); 9 | 10 | describe('inner suite', function () { 11 | it('should run this test-2', function () {}); 12 | }); 13 | }); 14 | 15 | describe('second suite', function () { 16 | it('should run this test-3', function () {}); 17 | }); 18 | -------------------------------------------------------------------------------- /test/integration/fixtures/pending/skip-sync-before-nested.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('skip in before with nested describes', function () { 4 | before(function () { 5 | this.skip(); 6 | }); 7 | 8 | it('should never run this test', function () { 9 | throw new Error('never run this test'); 10 | }); 11 | 12 | describe('nested describe', function () { 13 | before(function () { 14 | throw new Error('first level before should not run'); 15 | }); 16 | 17 | it('should never run this test', function () { 18 | throw new Error('never run this test'); 19 | }); 20 | 21 | after(function () { 22 | throw new Error('first level after should not run'); 23 | }); 24 | 25 | describe('nested again', function () { 26 | before(function () { 27 | throw new Error('second level before should not run'); 28 | }); 29 | 30 | it('should never run this test', function () { 31 | throw new Error('never run this test'); 32 | }); 33 | 34 | after(function () { 35 | throw new Error('second level after should not run'); 36 | }); 37 | }); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /test/integration/fixtures/pending/skip-sync-before.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('outer describe', function () { 4 | it('should run this test', function () {}); 5 | 6 | describe('skip in before', function () { 7 | before(function () { 8 | this.skip(); 9 | }); 10 | 11 | it('should never run this test', function () { 12 | throw new Error('never run this test'); 13 | }); 14 | it('should never run this test', function () { 15 | throw new Error('never run this test'); 16 | }); 17 | }); 18 | 19 | it('should run this test', function () {}); 20 | }); 21 | -------------------------------------------------------------------------------- /test/integration/fixtures/pending/skip-sync-beforeEach-cond.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('skip conditionally in beforeEach', function() { 4 | var n = 1; 5 | beforeEach(function() { 6 | if (n !== 2) { 7 | this.skip(); 8 | } 9 | }); 10 | 11 | it('should skip this test-1', function() { 12 | throw new Error('never run this test'); 13 | }); 14 | it('should run this test-2', function() {}); 15 | 16 | describe('inner suite', function() { 17 | it('should skip this test-3', function() { 18 | throw new Error('never run this test'); 19 | }); 20 | }); 21 | 22 | afterEach(function() { n++; }); 23 | after(function() { 24 | if (n === 4) { 25 | throw new Error('should throw this error'); 26 | } 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /test/integration/fixtures/pending/skip-sync-beforeEach.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var assert = require('assert'); 3 | 4 | describe('skip in beforeEach', function() { 5 | var runOrder = []; 6 | beforeEach(function() { 7 | runOrder.push('beforeEach'); 8 | this.skip(); 9 | }); 10 | 11 | it('should skip this test-1', function() { 12 | throw new Error('never run this test'); 13 | }); 14 | 15 | describe('inner', function() { 16 | beforeEach(function() { 17 | runOrder.push('should not run'); 18 | }); 19 | 20 | it('should skip this test-2', function() { 21 | throw new Error('never run this test'); 22 | }); 23 | it('should skip this test-3', function() { 24 | throw new Error('never run this test'); 25 | }); 26 | 27 | afterEach(function() { 28 | runOrder.push('should not run'); 29 | }); 30 | }); 31 | 32 | afterEach(function() { 33 | runOrder.push('afterEach'); 34 | }); 35 | after(function() { 36 | runOrder.push('after'); 37 | assert.deepStrictEqual(runOrder, [ 38 | 'beforeEach', 'afterEach', 39 | 'beforeEach', 'afterEach', 40 | 'beforeEach', 'afterEach', 41 | 'after' 42 | ]); 43 | throw new Error('should throw this error'); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /test/integration/fixtures/pending/skip-sync-spec.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var assert = require('assert'); 3 | 4 | describe('skip in test', function () { 5 | var runOrder = []; 6 | beforeEach(function () { 7 | runOrder.push('beforeEach'); 8 | }); 9 | 10 | it('should skip immediately', function () { 11 | this.skip(); 12 | throw new Error('never run this test'); 13 | }); 14 | it('should run other tests in suite', function () {}); 15 | 16 | afterEach(function() { 17 | runOrder.push('afterEach'); 18 | }); 19 | after(function() { 20 | runOrder.push('after'); 21 | assert.deepStrictEqual(runOrder, [ 22 | 'beforeEach', 'afterEach', 23 | 'beforeEach', 'afterEach', 24 | 'after' 25 | ]); 26 | throw new Error('should throw this error'); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /test/integration/fixtures/pending/spec.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('suite', function () { 4 | it('pending spec'); 5 | }); 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/plugins/global-fixtures/global-setup-teardown-multiple.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.mochaGlobalSetup = [ 4 | async function() { 5 | this.foo = 0; 6 | }, 7 | function() { 8 | this.foo = this.foo + 1; 9 | } 10 | ]; 11 | 12 | exports.mochaGlobalTeardown = [ 13 | async function() { 14 | this.foo = this.foo + 1; 15 | }, 16 | function() { 17 | this.foo = this.foo + 1; 18 | console.log(`teardown: this.foo = ${this.foo}`); 19 | } 20 | ]; 21 | -------------------------------------------------------------------------------- /test/integration/fixtures/plugins/global-fixtures/global-setup-teardown.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.mochaGlobalSetup = async function() { 4 | this.foo = 'bar'; 5 | console.log(`setup: this.foo = ${this.foo}`); 6 | }; 7 | 8 | exports.mochaGlobalTeardown = async function() { 9 | console.log(`teardown: this.foo = ${this.foo}`); 10 | }; 11 | -------------------------------------------------------------------------------- /test/integration/fixtures/plugins/global-fixtures/global-setup.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.mochaGlobalSetup = async function() { 4 | console.log(`setup schmetup`); 5 | }; 6 | 7 | -------------------------------------------------------------------------------- /test/integration/fixtures/plugins/global-fixtures/global-teardown.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.mochaGlobalTeardown = async function() { 4 | console.log('teardown schmeardown'); 5 | }; 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/plugins/root-hooks/esm/package.json: -------------------------------------------------------------------------------- 1 | { "type": "module" } 2 | -------------------------------------------------------------------------------- /test/integration/fixtures/plugins/root-hooks/esm/root-hook-defs-esm.fixture.js: -------------------------------------------------------------------------------- 1 | export const mochaHooks = () => ({ 2 | beforeEach() { 3 | console.log('esm beforeEach'); 4 | }, 5 | afterEach() { 6 | console.log('esm afterEach'); 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /test/integration/fixtures/plugins/root-hooks/root-hook-defs-a.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.mochaHooks = { 4 | beforeAll() { 5 | console.log('beforeAll'); 6 | }, 7 | beforeEach() { 8 | console.log('beforeEach'); 9 | }, 10 | afterAll() { 11 | console.log('afterAll'); 12 | }, 13 | afterEach() { 14 | console.log('afterEach'); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /test/integration/fixtures/plugins/root-hooks/root-hook-defs-b.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.mochaHooks = { 4 | beforeAll: [ 5 | function() { 6 | console.log('beforeAll array 1'); 7 | }, 8 | function() { 9 | console.log('beforeAll array 2'); 10 | } 11 | ], 12 | beforeEach: [ 13 | function() { 14 | console.log('beforeEach array 1'); 15 | }, 16 | function() { 17 | console.log('beforeEach array 2'); 18 | } 19 | ], 20 | afterAll: [ 21 | function() { 22 | console.log('afterAll array 1'); 23 | }, 24 | function() { 25 | console.log('afterAll array 2'); 26 | } 27 | ], 28 | afterEach: [ 29 | function() { 30 | console.log('afterEach array 1'); 31 | }, 32 | function() { 33 | console.log('afterEach array 2'); 34 | } 35 | ] 36 | }; 37 | -------------------------------------------------------------------------------- /test/integration/fixtures/plugins/root-hooks/root-hook-defs-c.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.mochaHooks = async () => ({ 4 | beforeAll() { 5 | console.log('beforeAll'); 6 | }, 7 | beforeEach() { 8 | console.log('beforeEach'); 9 | }, 10 | afterAll() { 11 | console.log('afterAll'); 12 | }, 13 | afterEach() { 14 | console.log('afterEach'); 15 | } 16 | }); 17 | -------------------------------------------------------------------------------- /test/integration/fixtures/plugins/root-hooks/root-hook-defs-d.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.mochaHooks = async() => ({ 4 | beforeAll: [ 5 | function() { 6 | console.log('beforeAll array 1'); 7 | }, 8 | function() { 9 | console.log('beforeAll array 2'); 10 | } 11 | ], 12 | beforeEach: [ 13 | function() { 14 | console.log('beforeEach array 1'); 15 | }, 16 | function() { 17 | console.log('beforeEach array 2'); 18 | } 19 | ], 20 | afterAll: [ 21 | function() { 22 | console.log('afterAll array 1'); 23 | }, 24 | function() { 25 | console.log('afterAll array 2'); 26 | } 27 | ], 28 | afterEach: [ 29 | function() { 30 | console.log('afterEach array 1'); 31 | }, 32 | function() { 33 | console.log('afterEach array 2'); 34 | } 35 | ] 36 | }); 37 | -------------------------------------------------------------------------------- /test/integration/fixtures/plugins/root-hooks/root-hook-defs-esm-broken.fixture.js: -------------------------------------------------------------------------------- 1 | export const mochaHooks = { 2 | beforeAll() { 3 | console.log('mjs beforeAll'); 4 | }, 5 | afterAll() { 6 | console.log('mjs afterAll'); 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /test/integration/fixtures/plugins/root-hooks/root-hook-defs-esm.fixture.mjs: -------------------------------------------------------------------------------- 1 | export const mochaHooks = { 2 | beforeAll() { 3 | console.log('mjs beforeAll'); 4 | }, 5 | afterAll() { 6 | console.log('mjs afterAll'); 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /test/integration/fixtures/plugins/root-hooks/root-hook-test-2.fixture.js: -------------------------------------------------------------------------------- 1 | // run with --require root-hook-defs-a.fixture.js --require 2 | // root-hook-defs-b.fixture.js 3 | 4 | it('should also have some root hooks', function() { 5 | // test 6 | }); -------------------------------------------------------------------------------- /test/integration/fixtures/plugins/root-hooks/root-hook-test.fixture.js: -------------------------------------------------------------------------------- 1 | // run with --require root-hook-defs-a.fixture.js --require 2 | // root-hook-defs-b.fixture.js 3 | 4 | it('should have some root hooks', function() { 5 | // test 6 | }); -------------------------------------------------------------------------------- /test/integration/fixtures/regression/issue-2315.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('issue-2315: cannot read property currentRetry of undefined', function () { 4 | before(function () { 5 | process.nextTick(function () { 6 | throw new Error(); 7 | }); 8 | }); 9 | 10 | it('something', function () {}); 11 | }); 12 | -------------------------------------------------------------------------------- /test/integration/fixtures/regression/issue-2406.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('outer describe', function () { 4 | it('should not run this test', function () {}); 5 | describe('this suite should not run', function () { 6 | it('should not run this test', function () {}); 7 | }); 8 | describe.only('this .only suite should run', function () { 9 | describe('this suite should run', function () { 10 | it('should run this test in a nested suite', function () {}); 11 | }); 12 | it('should run this test', function () {}); 13 | }); 14 | describe('this suite should not run', function () { 15 | it('should not run this test', function () {}); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /test/integration/fixtures/regression/issue-2417.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('outer describe', function () { 4 | describe.only('outer describe.only', function () { 5 | it.only('inner it.only', function () { 6 | // should run and exit without error 7 | }); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/retries/async.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('retries', function () { 4 | var times = 0; 5 | before(function () { 6 | console.log('before'); 7 | }); 8 | 9 | after(function () { 10 | console.log('after'); 11 | }); 12 | 13 | beforeEach(function () { 14 | console.log('before each', times); 15 | }); 16 | 17 | afterEach(function () { 18 | console.log('after each', times); 19 | }); 20 | 21 | it('should allow override and run appropriate hooks', function (done) { 22 | this.timeout(100); 23 | this.retries(2); 24 | console.log('TEST', times); 25 | if (++times < 3) { 26 | return setTimeout(done, 300); 27 | } 28 | setTimeout(done, 50); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /test/integration/fixtures/retries/early-pass.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const assert = require('assert'); 3 | 4 | describe('retries', function () { 5 | this.retries(1); 6 | var times = 0; 7 | var self = this; 8 | 9 | it('should pass after 1 retry', function () { 10 | times++; 11 | if (times !== 2) { 12 | throw new Error('retry error ' + times); 13 | } 14 | }); 15 | 16 | it('check for updated `suite.tests`', function() { 17 | assert.strictEqual(self.tests[0]._currentRetry, 1); 18 | assert.ok(self.tests[0]._retriedTest); 19 | assert.strictEqual(self.tests[0].state, 'passed'); 20 | }) 21 | }); 22 | -------------------------------------------------------------------------------- /test/integration/fixtures/retries/hooks.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('retries', function () { 4 | var times = 0; 5 | before(function () { 6 | console.log('before'); 7 | }); 8 | 9 | after(function () { 10 | console.log('after'); 11 | }); 12 | 13 | beforeEach(function () { 14 | console.log('before each', times); 15 | }); 16 | 17 | afterEach(function () { 18 | console.log('after each', times); 19 | }); 20 | 21 | it('should allow override and run appropriate hooks', function () { 22 | this.retries(4); 23 | console.log('TEST', times); 24 | times++; 25 | throw new Error('retry error'); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /test/integration/fixtures/retries/nested.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('retries', function () { 4 | this.retries(3); 5 | describe('nested', function () { 6 | it('should fail after only 1 retry', function () { 7 | this.retries(1); 8 | throw new Error('retry error'); 9 | }); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /test/integration/fixtures/signals-sigabrt.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('signal suite', function () { 4 | it('test SIGABRT', function () { 5 | process.kill(process.pid, 'SIGABRT'); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/signals-sigterm-numeric.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const os = require('node:os'); 3 | 4 | describe('signal suite', function () { 5 | it('test SIGTERM', function () { 6 | process.kill(process.pid, os.constants.signals['SIGTERM']); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /test/integration/fixtures/signals-sigterm.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('signal suite', function () { 4 | it('test SIGTERM', function () { 5 | process.kill(process.pid, 'SIGTERM'); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/fixtures/simple-ui.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Mocha = require('../../../lib/mocha'); 4 | var Test = Mocha.Test; 5 | var EVENT_FILE_PRE_REQUIRE = Mocha.Suite.constants.EVENT_FILE_PRE_REQUIRE; 6 | 7 | /** 8 | * A simple UI that only exposes a single function: test 9 | */ 10 | module.exports = Mocha.interfaces['simple-ui'] = function(suite) { 11 | suite.on(EVENT_FILE_PRE_REQUIRE, function( 12 | context, 13 | file, 14 | mocha 15 | ) { 16 | var common = require('../../../lib/interfaces/common')( 17 | [suite], 18 | context 19 | ); 20 | 21 | context.run = mocha.options.delay && common.runWithSuite(suite); 22 | 23 | /** 24 | * Describes a specification or test-case with the given `title` 25 | * and callback `fn` acting as a thunk. 26 | */ 27 | context.test = function(title, fn) { 28 | var test = new Test(title, fn); 29 | test.file = file; 30 | suite.addTest(test); 31 | 32 | return test; 33 | }; 34 | }); 35 | }; 36 | -------------------------------------------------------------------------------- /test/integration/fixtures/suite/suite-no-callback.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('a suite without a callback'); 4 | -------------------------------------------------------------------------------- /test/integration/fixtures/suite/suite-returning-value.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('a suite returning a value', function () { 4 | return Promise.resolve(); 5 | }); 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/suite/suite-skipped-callback.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | xdescribe('a pending suite with a callback', function () {}); 4 | -------------------------------------------------------------------------------- /test/integration/fixtures/suite/suite-skipped-no-callback.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | xdescribe('a pending suite without a callback'); 4 | -------------------------------------------------------------------------------- /test/integration/fixtures/test-for-simple-ui.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | test('pass', function () { 4 | // pass 5 | }); 6 | -------------------------------------------------------------------------------- /test/integration/fixtures/timeout-override.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('timeout override', function() { 4 | it('should fail async test due to re-enable', function(done) { 5 | this.timeout(0); 6 | this.timeout(1); 7 | setTimeout(done, 2); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/timeout.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('timeout', function () { 4 | this.timeout(1); 5 | 6 | it('should be honored with sync suites', function () { 7 | sleep(2); 8 | }); 9 | 10 | it('should be honored with async suites', function (done) { 11 | sleep(2); 12 | done(); 13 | }); 14 | 15 | function sleep (ms) { 16 | var start = Date.now(); 17 | while (start + ms > Date.now()); 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /test/integration/fixtures/uncaught/after-runner.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe("Uncaught exception after runner's end", () => { 4 | it('test', () => { 5 | setTimeout(() => { 6 | throw new Error('Unexpected crash'); 7 | }, 100); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/integration/fixtures/uncaught/double.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * This file should only generate one failure per spec despite the fact that 5 | * Mocha is capable of detecting two distinct exceptions during test execution. 6 | */ 7 | 8 | it('fails exactly once when a global error is thrown first', function (done) { 9 | process.nextTick(function () { 10 | throw new Error('global error'); 11 | }); 12 | }); 13 | 14 | it('fails exactly once when a global error is thrown second', function (done) { 15 | process.nextTick(function () { 16 | done(new Error('test error')); 17 | }); 18 | 19 | process.nextTick(function () { 20 | throw new Error('global error'); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /test/integration/fixtures/uncaught/fatal.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('fatal uncaught exception', function () { 4 | describe('first suite', function () { 5 | it('should bail if a successful test asynchronously fails', function (done) { 6 | done(); 7 | process.nextTick(function () { 8 | throw new Error('global error'); 9 | }); 10 | }); 11 | 12 | it('should not actually get run', function () { 13 | throw new Error('should never throw - first suite'); 14 | }); 15 | }); 16 | 17 | describe('second suite', function () { 18 | it('should not actually get run', function () { 19 | throw new Error('should never throw - second suite'); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /test/integration/fixtures/uncaught/hook.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('uncaught', function () { 4 | beforeEach(function (done) { 5 | process.nextTick(function () { 6 | throw new Error('oh noes'); 7 | }); 8 | }); 9 | 10 | it('test', function (done) { 11 | process.nextTick(function () { 12 | throw new Error("I'm uncaught!"); 13 | }); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /test/integration/fixtures/uncaught/issue-1327.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // we cannot recover gracefully if a Runnable has already passed 4 | // then fails asynchronously 5 | it('test 1', function () { 6 | process.nextTick(function () { 7 | throw new Error('Too bad'); 8 | }); 9 | }); 10 | 11 | it('test 2', function () { 12 | throw new Error('should not run - test 2'); 13 | }); 14 | 15 | it('test 3', function () { 16 | throw new Error('should not run - test 3'); 17 | }); 18 | -------------------------------------------------------------------------------- /test/integration/fixtures/uncaught/issue-1417.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * This file should generate only one failure per spec for the thrown error. 5 | * It should not report misleading 'multiple calls to done()'. 6 | */ 7 | 8 | it('fails exactly once when a global error is thrown synchronously and done errors', function (done) { 9 | setTimeout(function () { 10 | done(new Error('test error')); 11 | }, 1); // Not 0 - it will 'succeed', but won't test the breaking condition 12 | 13 | throw new Error('sync error a'); 14 | }); 15 | 16 | it('fails exactly once when a global error is thrown synchronously and done completes', function (done) { 17 | setTimeout(function () { 18 | done(); 19 | }, 1); // Not 0 - it will 'succeed', but won't test the breaking condition 20 | 21 | throw new Error('sync error b'); 22 | }); 23 | -------------------------------------------------------------------------------- /test/integration/fixtures/uncaught/listeners.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | const mocha = require('../../../../lib/mocha'); 5 | 6 | // keep this low to avoid warning 7 | for (let i = 0; i < 5; i++) { 8 | const r = new mocha.Runner(new mocha.Suite('' + i, undefined)); 9 | r.run(); 10 | } 11 | 12 | assert.strictEqual(process.listenerCount('uncaughtException'), 1); 13 | assert.strictEqual(process.listeners('uncaughtException')[0].name, 'uncaught'); 14 | -------------------------------------------------------------------------------- /test/integration/fixtures/uncaught/pending.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Uncaught exception within pending test', () => { 4 | it('test1', function () { }); 5 | 6 | it('test2', function () { 7 | process.nextTick(function () { 8 | throw new Error('I am uncaught!'); 9 | }); 10 | this.skip(); 11 | }); 12 | 13 | it('test3 - should run', function () { }); 14 | it('test4 - should run', function () { }); 15 | }); 16 | -------------------------------------------------------------------------------- /test/integration/fixtures/uncaught/recover.fixture.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const assert = require('assert'); 3 | 4 | describe('uncaught', function() { 5 | var hookOrder = []; 6 | it('throw delayed error', (done) => { 7 | setTimeout(() => { 8 | throw new Error('Whoops!'); 9 | }, 10) 10 | setTimeout(done, 10); 11 | }); 12 | it('should wait 15ms', (done) => { 13 | setTimeout(done, 15); 14 | }); 15 | it('test 3', () => { }); 16 | 17 | afterEach(function() { 18 | hookOrder.push(this.currentTest.title); 19 | }); 20 | after(function() { 21 | hookOrder.push('after'); 22 | assert.deepEqual( 23 | hookOrder, 24 | ['throw delayed error', 'should wait 15ms', 'test 3', 'after'] 25 | ); 26 | throw new Error('should get upto here and throw'); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /test/integration/fixtures/uncaught/unhandled.fixture.js: -------------------------------------------------------------------------------- 1 | it('should emit an unhandled rejection', async function() { 2 | setTimeout(() => { 3 | Promise.resolve().then(() => { 4 | throw new Error('yikes'); 5 | }); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/integration/invalid-arguments.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var invokeMocha = require('./helpers').invokeMocha; 4 | 5 | describe('invalid arguments', function () { 6 | describe('when argument is missing required value', function () { 7 | it('should exit with failure', function (done) { 8 | invokeMocha( 9 | ['--ui'], 10 | function (err, result) { 11 | if (err) { 12 | return done(err); 13 | } 14 | expect(result, 'to have failed'); 15 | expect(result.output, 'to match', /not enough arguments/i); 16 | done(); 17 | }, 18 | {stdio: 'pipe'} 19 | ); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /test/integration/no-diff.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('./helpers'); 4 | var run = helpers.runMocha; 5 | 6 | describe('no-diff', function () { 7 | describe('when enabled', function () { 8 | it('should not display a diff', function (done) { 9 | run('no-diff.fixture.js', ['--no-diff'], function (err, res) { 10 | if (err) { 11 | done(err); 12 | return; 13 | } 14 | expect(res.output, 'not to match', /\+ expected/); 15 | expect(res.output, 'not to match', /- actual/); 16 | done(); 17 | }); 18 | }); 19 | }); 20 | 21 | describe('when disabled', function () { 22 | it('should display a diff', function (done) { 23 | run('no-diff.fixture.js', ['--diff'], function (err, res) { 24 | if (err) { 25 | done(err); 26 | return; 27 | } 28 | expect(res.output, 'to match', /\+ expected/); 29 | expect(res.output, 'to match', /- actual/); 30 | done(); 31 | }); 32 | }); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /test/integration/options/asyncOnly.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('node:path').posix; 4 | var helpers = require('../helpers'); 5 | var runMochaJSON = helpers.runMochaJSON; 6 | 7 | describe('--async-only', function () { 8 | var args = []; 9 | 10 | before(function () { 11 | args = ['--async-only']; 12 | }); 13 | 14 | it('should fail synchronous specs', function (done) { 15 | var fixture = path.join('options', 'async-only-sync'); 16 | runMochaJSON(fixture, args, function (err, res) { 17 | if (err) { 18 | return done(err); 19 | } 20 | 21 | expect(res, 'to have failed'); 22 | done(); 23 | }); 24 | }); 25 | 26 | it('should allow asynchronous specs', function (done) { 27 | var fixture = path.join('options', 'async-only-async'); 28 | runMochaJSON(fixture, args, function (err, res) { 29 | if (err) { 30 | return done(err); 31 | } 32 | 33 | expect(res, 'to have passed'); 34 | done(); 35 | }); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /test/integration/options/compilers.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | var invokeMocha = helpers.invokeMocha; 5 | 6 | describe('--compilers', function () { 7 | it('should report deprecation', function (done) { 8 | invokeMocha( 9 | ['--compilers', 'coffee:coffeescript/register'], 10 | function (err, res) { 11 | if (err) { 12 | return done(err); 13 | } 14 | 15 | expect(res, 'to have failed with output', /compilers is deprecated/i); 16 | done(); 17 | }, 18 | 'pipe' 19 | ); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /test/integration/options/failZero.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | var runMochaJSON = helpers.runMochaJSON; 5 | 6 | describe('--fail-zero', function () { 7 | var args = ['--fail-zero', '--grep', 'yyyyyy']; 8 | 9 | it('should fail since no tests are encountered', function (done) { 10 | var fixture = '__default__.fixture.js'; 11 | runMochaJSON(fixture, args, function (err, res) { 12 | if (err) { 13 | return done(err); 14 | } 15 | 16 | expect(res, 'to have passed test count', 0) 17 | .and('to have test count', 0) 18 | .and('to have exit code', 1); 19 | done(); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /test/integration/options/invert.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var runMocha = require('../helpers').runMocha; 4 | 5 | describe('--invert', function () { 6 | describe('when used without --fgrep or --grep', function () { 7 | it('it should report an error', function (done) { 8 | runMocha( 9 | 'options/grep', 10 | ['--invert'], 11 | function (err, res) { 12 | if (err) { 13 | return done(err); 14 | } 15 | expect( 16 | res, 17 | 'to have failed with output', 18 | /--invert.*--grep / 19 | ); 20 | done(); 21 | }, 22 | 'pipe' 23 | ); 24 | }); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /test/integration/options/jobs.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | var runMochaAsync = helpers.runMochaAsync; 5 | 6 | describe('--jobs', function () { 7 | describe('when set to a number less than 2', function () { 8 | it('should run tests in serial', function () { 9 | return expect( 10 | runMochaAsync( 11 | 'options/jobs/fail-in-parallel', 12 | ['--parallel', '--jobs', '1'], 13 | 'pipe' 14 | ), 15 | 'when fulfilled', 16 | 'to have passed' 17 | ); 18 | }); 19 | }); 20 | 21 | describe('when set to a number greater than 1', function () { 22 | it('should run tests in parallel', function () { 23 | return expect( 24 | runMochaAsync( 25 | 'options/jobs/fail-in-parallel', 26 | ['--parallel', '--jobs', '2'], 27 | 'pipe' 28 | ), 29 | 'when fulfilled', 30 | 'to have failed' 31 | ); 32 | }); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /test/integration/options/listInterfaces.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | var invokeMocha = helpers.invokeMocha; 5 | var escapeRegExp = helpers.escapeRegExp; 6 | var interfaces = require('../../../lib/mocha').interfaces; 7 | 8 | describe('--list-interfaces', function () { 9 | it('should dump a list of all interfaces with descriptions', function (done) { 10 | var expected = Object.keys(interfaces) 11 | .filter(function (name) { 12 | return /^[a-z]/.test(name); 13 | }) 14 | .map(function (name) { 15 | return { 16 | name: escapeRegExp(name), 17 | description: escapeRegExp(interfaces[name].description) 18 | }; 19 | }); 20 | 21 | invokeMocha(['--list-interfaces'], function (err, result) { 22 | if (err) { 23 | return done(err); 24 | } 25 | 26 | expect(result.code, 'to be', 0); 27 | expected.forEach(function (ui) { 28 | expect( 29 | result.output, 30 | 'to match', 31 | new RegExp(ui.name + '\\s*-\\s*' + ui.description) 32 | ); 33 | }); 34 | done(); 35 | }); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /test/integration/options/listReporters.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | var invokeMocha = helpers.invokeMocha; 5 | var escapeRegExp = helpers.escapeRegExp; 6 | var reporters = require('../../../lib/mocha').reporters; 7 | 8 | describe('--list-reporters', function () { 9 | it('should dump a list of all reporters with descriptions', function (done) { 10 | var expected = Object.keys(reporters) 11 | .filter(function (name) { 12 | return ( 13 | /^[a-z]/.test(name) && 14 | !(reporters[name].abstract || reporters[name].browserOnly) 15 | ); 16 | }) 17 | .map(function (name) { 18 | return { 19 | name: escapeRegExp(name), 20 | description: escapeRegExp(reporters[name].description) 21 | }; 22 | }); 23 | 24 | invokeMocha(['--list-reporters'], function (err, result) { 25 | if (err) { 26 | return done(err); 27 | } 28 | 29 | expect(result.code, 'to be', 0); 30 | expected.forEach(function (reporter) { 31 | expect( 32 | result.output, 33 | 'to match', 34 | new RegExp(reporter.name + '\\s*-\\s*' + reporter.description) 35 | ); 36 | }); 37 | done(); 38 | }); 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /test/integration/options/node-flags.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var invokeMocha = require('../helpers').invokeMocha; 4 | 5 | describe('node flags', function () { 6 | it('should not consider argument values to be node flags', function (done) { 7 | invokeMocha( 8 | ['--require', 'trace-dependency'], 9 | function (err, res) { 10 | if (err) { 11 | return done(err); 12 | } 13 | expect(res, 'not to have failed with output', /bad option/i); 14 | done(); 15 | }, 16 | 'pipe' 17 | ); 18 | }); 19 | }); 20 | 21 | describe('node flags using "--node-option"', function () { 22 | it('should pass fake option to node and fail with node exception', function (done) { 23 | invokeMocha( 24 | ['--node-option', 'fake-flag'], 25 | function (err, res) { 26 | if (err) { 27 | return done(err); 28 | } 29 | expect(res, 'to have failed with output', /bad option: --fake-flag/i); 30 | done(); 31 | }, 32 | 'pipe' 33 | ); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /test/integration/options/opts.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var invokeMocha = require('../helpers').invokeMocha; 4 | 5 | describe('--opts', function () { 6 | it('should report deprecation', function (done) { 7 | invokeMocha( 8 | ['--opts', './test/mocha.opts'], 9 | function (err, res) { 10 | if (err) { 11 | return done(err); 12 | } 13 | expect( 14 | res, 15 | 'to have failed with output', 16 | /'mocha.opts' is DEPRECATED/i 17 | ); 18 | done(); 19 | }, 20 | 'pipe' 21 | ); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /test/integration/options/passOnFailingTestSuite.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | var runMochaJSON = helpers.runMochaJSON; 5 | 6 | describe('Enabled --pass-on-failing-test-suite', function() { 7 | var args = ['--pass-on-failing-test-suite=true']; 8 | 9 | it('Test should finish with zero code with disabled option', function(done) { 10 | var fixture = 'failing-sync.fixture.js'; 11 | runMochaJSON(fixture, args, function(err, res) { 12 | if (err) { 13 | return done(err); 14 | } 15 | 16 | expect(res, 'to have passed test count', 0) 17 | .and('to have test count', 1) 18 | .and('to have exit code', 0); 19 | done(); 20 | }); 21 | }); 22 | }); 23 | 24 | describe('Disabled --pass-on-failing-test-suite', function() { 25 | var args = ['--pass-on-failing-test-suite=false']; 26 | 27 | it('Test should return non-zero code with enabled option', function(done) { 28 | var fixture = 'failing-sync.fixture.js'; 29 | runMochaJSON(fixture, args, function(err, res) { 30 | if (err) { 31 | return done(err); 32 | } 33 | 34 | expect(res, 'to have passed test count', 0) 35 | .and('to have test count', 1) 36 | .and('to have exit code', 1); 37 | done(); 38 | }); 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /test/integration/options/retries.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('node:path').posix; 4 | var helpers = require('../helpers'); 5 | var runMochaJSON = helpers.runMochaJSON; 6 | 7 | describe('--retries', function () { 8 | var args = []; 9 | 10 | it('should retry test failures after a certain threshold', function (done) { 11 | args = ['--retries', '3']; 12 | var fixture = path.join('options', 'retries'); 13 | runMochaJSON(fixture, args, function (err, res) { 14 | if (err) { 15 | return done(err); 16 | } 17 | expect(res, 'to have failed') 18 | .and('not to have pending tests') 19 | .and('not to have passed tests') 20 | .and('to have retried test', 'should fail', 3); 21 | done(); 22 | }); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /test/integration/options/sort.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('node:path').posix; 4 | var helpers = require('../helpers'); 5 | var runMochaJSON = helpers.runMochaJSON; 6 | 7 | describe('--sort', function () { 8 | var args = []; 9 | 10 | before(function () { 11 | args = ['--sort']; 12 | }); 13 | 14 | it('should sort tests in alphabetical order', function (done) { 15 | var fixtures = path.join('options', 'sort*'); 16 | runMochaJSON(fixtures, args, function (err, res) { 17 | if (err) { 18 | done(err); 19 | return; 20 | } 21 | expect(res, 'to have passed test count', 2).and( 22 | 'to have passed test order', 23 | 'should be executed first' 24 | ); 25 | done(); 26 | }); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /test/integration/options/ui.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var helpers = require('../helpers'); 4 | var runMochaJSON = helpers.runMochaJSON; 5 | 6 | describe('--ui', function () { 7 | var simpleUiPath = require.resolve('../fixtures/simple-ui.fixture'); 8 | 9 | it('should load interface and run it', function (done) { 10 | runMochaJSON( 11 | 'test-for-simple-ui', 12 | ['--ui', simpleUiPath], 13 | function (err, res) { 14 | if (err) { 15 | done(err); 16 | return; 17 | } 18 | expect(res, 'to have passed'); 19 | done(); 20 | } 21 | ); 22 | }); 23 | 24 | it("should work if required and name added to Mocha's `interfaces` prop", function (done) { 25 | runMochaJSON( 26 | 'test-for-simple-ui', 27 | ['--require', simpleUiPath, '--ui', 'simple-ui'], 28 | function (err, res) { 29 | if (err) { 30 | done(err); 31 | return; 32 | } 33 | expect(res, 'to have passed'); 34 | done(); 35 | } 36 | ); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /test/integration/timeout.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('node:assert'); 4 | var run = require('./helpers').runMochaJSON; 5 | var args = []; 6 | 7 | describe('this.timeout()', function () { 8 | it('is respected by sync and async suites', function (done) { 9 | run('timeout.fixture.js', args, function (err, res) { 10 | if (err) { 11 | done(err); 12 | return; 13 | } 14 | assert.strictEqual(res.stats.pending, 0); 15 | assert.strictEqual(res.stats.passes, 0); 16 | assert.strictEqual(res.stats.failures, 2); 17 | assert.strictEqual(res.code, 2); 18 | done(); 19 | }); 20 | }); 21 | 22 | it('should allow overriding if disabled per-test', function (done) { 23 | run('timeout-override.fixture.js', args, function (err, res) { 24 | if (err) { 25 | done(err); 26 | return; 27 | } 28 | expect(res.stats.failures, 'to be', 1); 29 | done(); 30 | }); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /test/interfaces/exports.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var calls = []; 4 | 5 | exports.Array = { 6 | before: function () { 7 | calls.push('before'); 8 | }, 9 | 10 | after: function () { 11 | calls.push('after'); 12 | expect(calls, 'to equal', [ 13 | 'before', 14 | 'before each', 15 | 'one', 16 | 'after each', 17 | 'before each', 18 | 'two', 19 | 'after each', 20 | 'after' 21 | ]); 22 | }, 23 | 24 | '#indexOf()': { 25 | beforeEach: function () { 26 | calls.push('before each'); 27 | }, 28 | 29 | afterEach: function () { 30 | calls.push('after each'); 31 | }, 32 | 33 | 'should return -1 when the value is not present': function () { 34 | calls.push('one'); 35 | expect([1, 2, 3].indexOf(5), 'to be', -1); 36 | expect([1, 2, 3].indexOf(0), 'to be', -1); 37 | }, 38 | 39 | 'should return the correct index when the value is present': function () { 40 | calls.push('two'); 41 | expect([1, 2, 3].indexOf(1), 'to be', 0); 42 | expect([1, 2, 3].indexOf(2), 'to be', 1); 43 | expect([1, 2, 3].indexOf(3), 'to be', 2); 44 | } 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /test/interfaces/qunit.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | suite('integer primitives'); 4 | 5 | test('should add', function () { 6 | expect(2 + 2, 'to be', 4); 7 | }); 8 | 9 | test('should decrement', function () { 10 | var number = 3; 11 | expect(--number, 'to be', 2); 12 | expect(--number, 'to be', 1); 13 | expect(--number, 'to be', 0); 14 | }); 15 | 16 | suite('String'); 17 | 18 | test('#length', function () { 19 | expect('foo', 'to have length', 3); 20 | }); 21 | -------------------------------------------------------------------------------- /test/interfaces/tdd.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | suite('integer primitives', function () { 4 | suite('arithmetic', function () { 5 | var initialValue = 41; 6 | 7 | suiteSetup(function (done) { 8 | expect(initialValue, 'to be', 41); 9 | initialValue += 1; 10 | done(); 11 | }); 12 | 13 | test('should add', function () { 14 | expect(initialValue, 'to be', 42); 15 | expect(1 + 1, 'to be', 2); 16 | expect(2 + 2, 'to be', 4); 17 | }); 18 | 19 | test('should subtract', function () { 20 | expect(initialValue, 'to be', 42); 21 | expect(1 - 1, 'to be', 0); 22 | expect(2 - 1, 'to be', 1); 23 | }); 24 | 25 | test.skip('should skip this test', function () { 26 | var zero = 0; 27 | expect(zero, 'to be', 1); 28 | }); 29 | 30 | suite.skip('should skip this suite', function () { 31 | test('should skip this test', function () { 32 | var zero = 0; 33 | expect(zero, 'to be', 1); 34 | }); 35 | }); 36 | 37 | suiteTeardown(function (done) { 38 | expect(initialValue, 'to be', 42); 39 | done(); 40 | }); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /test/jsapi/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Mocha = require('../../'); 4 | 5 | var mocha = new Mocha({ 6 | ui: 'bdd', 7 | globals: ['okGlobalA', 'okGlobalB', 'okGlobalC', 'callback*'], 8 | growl: true 9 | }); 10 | 11 | require('../setup'); 12 | 13 | mocha.addFile('test/unit/suite.spec.js'); 14 | mocha.addFile('test/unit/runner.spec.js'); 15 | mocha.addFile('test/unit/runnable.spec.js'); 16 | mocha.addFile('test/unit/hook-sync.spec.js'); 17 | mocha.addFile('test/unit/hook-sync-nested.spec.js'); 18 | mocha.addFile('test/unit/hook-async.spec.js'); 19 | mocha.addFile('test/unit/duration.spec.js'); 20 | mocha.addFile('test/unit/globals.spec.js'); 21 | mocha.addFile('test/unit/timeout.spec.js'); 22 | 23 | mocha.run(function () { 24 | console.log('done'); 25 | }); 26 | -------------------------------------------------------------------------------- /test/node-unit/cli/fixtures/bad-module.fixture.js: -------------------------------------------------------------------------------- 1 | throw new Error('this module is wonky'); 2 | -------------------------------------------------------------------------------- /test/node-unit/cli/fixtures/bad-require.fixture.js: -------------------------------------------------------------------------------- 1 | require('fake'); 2 | -------------------------------------------------------------------------------- /test/node-unit/cli/mocha-flags.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | types, 5 | expectedTypeForFlag 6 | } = require('../../../lib/cli/run-option-metadata'); 7 | 8 | describe('mocha-flags', function () { 9 | describe('expectedTypeForFlag()', function () { 10 | Object.entries(types).forEach(([dataType, flags]) => { 11 | flags.forEach(flag => { 12 | it(`returns expected ${flag}'s type as ${dataType}`, function () { 13 | expect(expectedTypeForFlag(flag), 'to equal', dataType); 14 | }); 15 | }); 16 | }); 17 | 18 | it('returns undefined for node flags', function () { 19 | expect(expectedTypeForFlag('--throw-deprecation'), 'to equal', undefined); 20 | expect(expectedTypeForFlag('throw-deprecation'), 'to equal', undefined); 21 | }); 22 | 23 | it('returns undefined for unsupported flags', function () { 24 | expect(expectedTypeForFlag('--foo'), 'to equal', undefined); 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /test/node-unit/cli/run.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const {builder} = require('../../../lib/cli/run'); 4 | const {types} = require('../../../lib/cli/run-option-metadata'); 5 | 6 | describe('command', function () { 7 | describe('run', function () { 8 | describe('builder', function () { 9 | const IGNORED_OPTIONS = new Set(['help', 'version']); 10 | const options = builder(require('yargs')()).getOptions(); 11 | ['number', 'string', 'boolean', 'array'].forEach(type => { 12 | describe(`${type} type`, function () { 13 | Array.from(new Set(options[type])).forEach(option => { 14 | if (!IGNORED_OPTIONS.has(option)) { 15 | it(`should include option ${option}`, function () { 16 | expect(types[type], 'to contain', option); 17 | }); 18 | } 19 | }); 20 | }); 21 | }); 22 | }); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /test/node-unit/fixtures/dumb-module.fixture.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/test/node-unit/fixtures/dumb-module.fixture.js -------------------------------------------------------------------------------- /test/node-unit/fixtures/dumber-module.fixture.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mochajs/mocha/a7ed005bf79656c28c6b6e65a197098cdd65d7f4/test/node-unit/fixtures/dumber-module.fixture.js -------------------------------------------------------------------------------- /test/node-unit/fixtures/wonky-reporter.fixture.js: -------------------------------------------------------------------------------- 1 | throw new Error('bad weirdness in this one'); 2 | -------------------------------------------------------------------------------- /test/only/bdd-require.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var mocha = require('../../lib/mocha'); 4 | 5 | var beforeEach = mocha.beforeEach; 6 | var it = mocha.it; 7 | var describe = mocha.describe; 8 | 9 | describe('it.only via require("mocha")', function () { 10 | beforeEach(function () { 11 | this.didRunBeforeEach = true; 12 | }); 13 | describe('nested within a describe/context', function () { 14 | it.only('should run all enclosing beforeEach hooks', function () { 15 | require('node:assert').strictEqual(this.didRunBeforeEach, true); 16 | }); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /test/only/global/bdd.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Root-only test cases 4 | it.only('#Root-Suite, should run this bdd test-case #1', function () { 5 | expect(true, 'to be', true); 6 | }); 7 | 8 | it('#Root-Suite, should not run this bdd test-case #2', function () { 9 | expect(false, 'to be', true); 10 | }); 11 | 12 | it('#Root-Suite, should not run this bdd test-case #3', function () { 13 | expect(false, 'to be', true); 14 | }); 15 | -------------------------------------------------------------------------------- /test/only/global/qunit.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Root-only test cases 4 | test.only('#Root-Suite, should run this qunit test-case #1', function () { 5 | expect(true, 'to be', true); 6 | }); 7 | 8 | test('#Root-Suite, should not run this qunit test-case #2', function () { 9 | expect(false, 'to be', true); 10 | }); 11 | 12 | test('#Root-Suite, should not run this qunit test-case #3', function () { 13 | expect(false, 'to be', true); 14 | }); 15 | -------------------------------------------------------------------------------- /test/only/global/tdd.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Root-only test cases 4 | test.only('#Root-Suite, should run this tdd test-case #1', function () { 5 | expect(true, 'to be', true); 6 | }); 7 | 8 | test('#Root-Suite, should not run this tdd test-case #2', function () { 9 | expect(false, 'to be', true); 10 | }); 11 | 12 | test('#Root-Suite, should not run this tdd test-case #3', function () { 13 | expect(false, 'to be', true); 14 | }); 15 | -------------------------------------------------------------------------------- /test/require/a.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | global.required = global.required || []; 4 | global.required.push('a.js'); 5 | -------------------------------------------------------------------------------- /test/require/b.coffee: -------------------------------------------------------------------------------- 1 | global.required ?= [] 2 | global.required.push 'b.coffee' 3 | -------------------------------------------------------------------------------- /test/require/c.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | global.required = global.required || []; 4 | global.required.push('c.js'); 5 | -------------------------------------------------------------------------------- /test/require/d.coffee: -------------------------------------------------------------------------------- 1 | global.required ?= [] 2 | global.required.push 'd.coffee' 3 | -------------------------------------------------------------------------------- /test/require/require.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('require test', function () { 4 | it('should require args in order', function () { 5 | var req = global.required; 6 | expect(req.indexOf('a.js'), 'to be', 0); 7 | expect(req.indexOf('b.coffee'), 'to be', 1); 8 | expect(req.indexOf('c.js'), 'to be', 2); 9 | expect(req.indexOf('d.coffee'), 'to be', 3); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /test/setup.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const unexpected = require('unexpected'); 4 | 5 | global.expect = unexpected 6 | .clone() 7 | .use(require('unexpected-sinon')) 8 | .use(require('unexpected-eventemitter')) 9 | .use(require('unexpected-map')) 10 | .use(require('unexpected-set')) 11 | .use(require('./assertions')); 12 | -------------------------------------------------------------------------------- /test/smoke/smoke.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This test ensures Mocha's dependencies are properly in place, 4 | // and is intended to be run after an `npm install --production` in a clean 5 | // working copy. It helps avoid publishing Mocha with `dependencies` 6 | // in `devDependencies` or otherwise in the wrong place. 7 | // It does not ensure that all files are present in the published package! 8 | 9 | var assert = require('node:assert'); 10 | 11 | describe('a production installation of Mocha', function () { 12 | it('should be able to execute a test', function () { 13 | assert.ok(true); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /test/unit/duration.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('durations', function () { 4 | describe('when slow', function () { 5 | it('should highlight in red', function (done) { 6 | setTimeout(function () { 7 | done(); 8 | }, 100); 9 | }); 10 | }); 11 | 12 | describe('when reasonable', function () { 13 | it('should highlight in yellow', function (done) { 14 | setTimeout(function () { 15 | done(); 16 | }, 50); 17 | }); 18 | }); 19 | 20 | describe('when fast', function () { 21 | it('should not highlight', function (done) { 22 | setTimeout(function () { 23 | done(); 24 | }, 10); 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /test/unit/globals.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('global leaks', function () { 4 | before(function () { 5 | // uncomment to test 6 | // foo = 'hey'; 7 | // bar = 'hey'; 8 | }); 9 | 10 | beforeEach(function () { 11 | // uncomment to test 12 | // foo = 'bar' 13 | }); 14 | 15 | it('should cause tests to fail', function () { 16 | // uncomment to test 17 | // foo = 'bar'; 18 | // bar = 'baz'; 19 | // baz = 'raz'; 20 | }); 21 | 22 | it('should pass when accepted', function () { 23 | global.okGlobalA = 1; 24 | global.okGlobalB = 1; 25 | global.okGlobalC = 1; 26 | }); 27 | 28 | it('should pass with wildcard', function () { 29 | global.callback123 = 'foo'; 30 | global.callback345 = 'bar'; 31 | }); 32 | 33 | it('should pass when prefixed "mocha-"', function () { 34 | // Opera and IE do this for HTML element IDs anyway 35 | // but to sure we can assert this in any browser, simulate it. 36 | global['mocha-example'] = {nodeType: 1}; 37 | }); 38 | 39 | afterEach(function () { 40 | // uncomment to test 41 | // foo = 'bar' 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /test/unit/hook-timeout.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('hook timeout', function () { 4 | before(function (done) { 5 | setTimeout(done, 100); 6 | }); 7 | 8 | it('should work', function (done) { 9 | done(); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /test/unit/overspecified-async.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('overspecified asynchronous resolution method', function () { 4 | it('should fail when multiple methods are used', function (done) { 5 | setTimeout(done, 0); 6 | 7 | // uncomment 8 | // return { then: function() {} }; 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /test/unit/parse-query.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var parseQuery = require('../../lib/browser/parse-query'); 4 | 5 | describe('parseQuery()', function () { 6 | it('should get queryString and return key-value object', function () { 7 | expect(parseQuery('?foo=1&bar=2&baz=3'), 'to equal', { 8 | foo: '1', 9 | bar: '2', 10 | baz: '3' 11 | }); 12 | 13 | expect(parseQuery('?r1=^@(?!.*\\)$)&r2=m{2}&r3=^co.*'), 'to equal', { 14 | r1: '^@(?!.*\\)$)', 15 | r2: 'm{2}', 16 | r3: '^co.*' 17 | }); 18 | }); 19 | 20 | it('should parse "+" as a space', function () { 21 | expect(parseQuery('?grep=foo+bar'), 'to equal', {grep: 'foo bar'}); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /test/unit/required-tokens.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('node:assert'); 4 | const {describe, it} = require('../..'); 5 | 6 | describe('using imported "describe"', function () { 7 | it('using imported "it"', function (done) { 8 | assert.ok(true); 9 | done(); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /test/unit/root.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var calls = []; 4 | 5 | before(function () { 6 | calls.push('before'); 7 | }); 8 | 9 | describe('root', function () { 10 | it('should be a valid suite', function () { 11 | expect(calls, 'to equal', ['before']); 12 | }); 13 | }); 14 | --------------------------------------------------------------------------------