diff --git a/docs-next/src/content/docs/running/configuring.mdx b/docs-next/src/content/docs/running/configuring.mdx index 64f8052575..e4cdb758d9 100644 --- a/docs-next/src/content/docs/running/configuring.mdx +++ b/docs-next/src/content/docs/running/configuring.mdx @@ -9,7 +9,8 @@ title: Configuring Mocha (Node.js) Mocha supports configuration files, typical of modern command-line tools, in several formats: - **JavaScript**: Create a `.mocharc.js` (or `.mocharc.cjs` when using [`"type"="module"`](/explainers/nodejs-native-esm-support) in your `package.json`) - in your project's root directory, and export an object (`module.exports = {/* ... */}`) containing your configuration. + in your project's root directory, and export an object (`module.exports = {/* ... */}`) containing your configuration. For native ESM and using `type="module"` + or using `.mjs`, use a default export (`default export {/* ... */}`). - **YAML**: Create a `.mocharc.yaml` (or `.mocharc.yml`) in your project's root directory. - **JSON**: Create a `.mocharc.json` (or `.mocharc.jsonc`) in your project's root directory. Comments--while not valid JSON--are allowed in this file, and will be ignored by Mocha. diff --git a/docs/index.md b/docs/index.md index 0e0f8c4ed0..495fce5658 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2254,7 +2254,9 @@ The HTML reporter is the default reporter when running Mocha in the browser. It Mocha supports configuration files, typical of modern command-line tools, in several formats: -- **JavaScript**: Create a `.mocharc.js` (or `.mocharc.cjs` when using [`"type"="module"`](#nodejs-native-esm-support) in your `package.json`) +- **JavaScript**: Create a `.mocharc.js` (or `.mocharc.cjs` when using [`"type"="module"`](/explainers/nodejs-native-esm-support) in your `package.json`) + in your project's root directory, and export an object (`module.exports = {/* ... */}`) containing your configuration. For native ESM and using `type="module"` + or using `.mjs`, use a default export (`default export {/* ... */}`). in your project's root directory, and export an object (`module.exports = {/* ... */}`) containing your configuration. - **YAML**: Create a `.mocharc.yaml` (or `.mocharc.yml`) in your project's root directory. - **JSON**: Create a `.mocharc.json` (or `.mocharc.jsonc`) in your project's root directory. Comments — while not valid JSON — are allowed in this file, and will be ignored by Mocha. diff --git a/lib/cli/config.js b/lib/cli/config.js index 206828118e..5df88ff64b 100644 --- a/lib/cli/config.js +++ b/lib/cli/config.js @@ -24,6 +24,7 @@ const utils = require("../utils"); exports.CONFIG_FILES = [ ".mocharc.cjs", ".mocharc.js", + ".mocharc.mjs", ".mocharc.yaml", ".mocharc.yml", ".mocharc.jsonc", @@ -72,6 +73,9 @@ exports.loadConfig = (filepath) => { try { if (ext === ".yml" || ext === ".yaml") { config = parsers.yaml(filepath); + } else if (ext === ".js" || ext === ".cjs" || ext === ".mjs") { + const parsedConfig = parsers.js(filepath); + config = parsedConfig.default ?? parsedConfig; } else if (ext === ".js" || ext === ".cjs") { config = parsers.js(filepath); } else { diff --git a/test/integration/config.spec.js b/test/integration/config.spec.js index 7c1c8b5d2c..a5d820941e 100644 --- a/test/integration/config.spec.js +++ b/test/integration/config.spec.js @@ -10,13 +10,15 @@ var loadConfig = require("../../lib/cli/config").loadConfig; describe("config", function () { it("should return the same values for all supported config types", function () { var configDir = path.join(__dirname, "fixtures", "config"); - var js = loadConfig(path.join(configDir, "mocharc.js")); + var js = loadConfig(path.join(configDir, "mocharc.js")); // canonical form var cjs = loadConfig(path.join(configDir, "mocharc.cjs")); var json = loadConfig(path.join(configDir, "mocharc.json")); + var mjs = loadConfig(path.join(configDir, "mocharc.mjs")); var yaml = loadConfig(path.join(configDir, "mocharc.yaml")); - expect(js, "to equal", json); - expect(js, "to equal", cjs); - expect(json, "to equal", yaml); + expect(cjs, "to equal", js); + expect(json, "to equal", js); + expect(mjs, "to equal", js); + expect(yaml, "to equal", js); }); describe('when configuring Mocha via a ".js" file', function () { diff --git a/test/integration/fixtures/config/mocharc.mjs b/test/integration/fixtures/config/mocharc.mjs new file mode 100644 index 0000000000..7cbe079d2c --- /dev/null +++ b/test/integration/fixtures/config/mocharc.mjs @@ -0,0 +1,7 @@ +// a comment +export default { + require: ['foo', 'bar'], + bail: true, + reporter: 'dot', + slow: 60 +}; diff --git a/test/node-unit/cli/config.spec.js b/test/node-unit/cli/config.spec.js index 922f24e0ad..314fbdf2fd 100644 --- a/test/node-unit/cli/config.spec.js +++ b/test/node-unit/cli/config.spec.js @@ -30,23 +30,12 @@ describe("cli/config", function () { sinon.stub(parsers, "js").returns(phonyConfigObject); }); - describe('when supplied a filepath with ".yaml" extension', function () { - const filepath = "foo.yaml"; - - it("should use the YAML parser", function () { - loadConfig(filepath); - expect(parsers.yaml, "to have calls satisfying", [ - { args: [filepath], returned: phonyConfigObject }, - ]).and("was called once"); - }); - }); - - describe('when supplied a filepath with ".yml" extension', function () { - const filepath = "foo.yml"; + describe('when supplied a filepath with ".cjs" extension', function () { + const filepath = "foo.cjs"; - it("should use the YAML parser", function () { + it("should use the JS parser", function () { loadConfig(filepath); - expect(parsers.yaml, "to have calls satisfying", [ + expect(parsers.js, "to have calls satisfying", [ { args: [filepath], returned: phonyConfigObject }, ]).and("was called once"); }); @@ -63,12 +52,12 @@ describe("cli/config", function () { }); }); - describe('when supplied a filepath with ".cjs" extension', function () { - const filepath = "foo.cjs"; + describe('when supplied a filepath with ".json" extension', function () { + const filepath = "foo.json"; - it("should use the JS parser", function () { - loadConfig(filepath); - expect(parsers.js, "to have calls satisfying", [ + it("should use the JSON parser", function () { + loadConfig("foo.json"); + expect(parsers.json, "to have calls satisfying", [ { args: [filepath], returned: phonyConfigObject }, ]).and("was called once"); }); @@ -85,12 +74,34 @@ describe("cli/config", function () { }); }); - describe('when supplied a filepath with ".json" extension', function () { - const filepath = "foo.json"; + describe('when supplied a filepath with ".mjs" extension', function () { + const filepath = "foo.mjs"; - it("should use the JSON parser", function () { - loadConfig("foo.json"); - expect(parsers.json, "to have calls satisfying", [ + it("should use the JS parser", function () { + loadConfig(filepath); + expect(parsers.js, "to have calls satisfying", [ + { args: [filepath], returned: phonyConfigObject }, + ]).and("was called once"); + }); + }); + + describe('when supplied a filepath with ".yaml" extension', function () { + const filepath = "foo.yaml"; + + it("should use the YAML parser", function () { + loadConfig(filepath); + expect(parsers.yaml, "to have calls satisfying", [ + { args: [filepath], returned: phonyConfigObject }, + ]).and("was called once"); + }); + }); + + describe('when supplied a filepath with ".yml" extension', function () { + const filepath = "foo.yml"; + + it("should use the YAML parser", function () { + loadConfig(filepath); + expect(parsers.yaml, "to have calls satisfying", [ { args: [filepath], returned: phonyConfigObject }, ]).and("was called once"); });