From e1728f81e20a30b8588225f44ad3ad836fdf1964 Mon Sep 17 00:00:00 2001 From: Gil Tayar Date: Sun, 29 Sep 2019 07:31:55 +0300 Subject: [PATCH] add support for Node.JS native ES modules --- .eslintrc.yml | 9 +- docs/index.md | 54 ++++++- karma.conf.js | 1 + lib/cli/config.js | 3 +- lib/cli/options.js | 2 +- lib/cli/run-helpers.js | 15 +- lib/cli/run.js | 11 +- lib/esm-utils.js | 31 ++++ lib/mocha.js | 59 +++++++- lib/mocharc.json | 2 +- lib/utils.js | 22 +++ package-lock.json | 139 ++++++++++++------ package-scripts.js | 2 +- package.json | 3 +- test/integration/config.spec.js | 2 + test/integration/esm.spec.js | 53 +++++++ test/integration/fixtures/config/mocharc.cjs | 9 ++ test/integration/fixtures/esm/add.mjs | 3 + .../fixtures/esm/esm-failure.fixture.mjs | 5 + .../fixtures/esm/esm-success.fixture.mjs | 5 + .../integration/fixtures/esm/js-folder/add.js | 3 + .../esm/js-folder/esm-in-js.fixture.js | 5 + .../fixtures/esm/js-folder/package.json | 3 + test/integration/helpers.js | 2 +- test/integration/suite.spec.js | 8 +- 25 files changed, 372 insertions(+), 79 deletions(-) create mode 100644 lib/esm-utils.js create mode 100644 test/integration/esm.spec.js create mode 100644 test/integration/fixtures/config/mocharc.cjs create mode 100644 test/integration/fixtures/esm/add.mjs create mode 100644 test/integration/fixtures/esm/esm-failure.fixture.mjs create mode 100644 test/integration/fixtures/esm/esm-success.fixture.mjs create mode 100644 test/integration/fixtures/esm/js-folder/add.js create mode 100644 test/integration/fixtures/esm/js-folder/esm-in-js.fixture.js create mode 100644 test/integration/fixtures/esm/js-folder/package.json diff --git a/.eslintrc.yml b/.eslintrc.yml index 300a48ef67..96f28ebb9f 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -31,7 +31,14 @@ overrides: ecmaVersion: 2017 env: browser: false - + - files: + - esm-utils.js + parserOptions: + ecmaVersion: 2018 + sourceType: module + parser: babel-eslint + env: + browser: false - files: - test/**/*.{js,mjs} env: diff --git a/docs/index.md b/docs/index.md index cf0f226259..1a67af108a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -39,6 +39,7 @@ Mocha is a feature-rich JavaScript test framework running on [Node.js][] and in - [mocha.opts file support](#-opts-path) - clickable suite titles to filter test execution - [node debugger support](#-inspect-inspect-brk-inspect) +- [node native ES modules support](#nodejs-native-esm-support) - [detects multiple calls to `done()`](#detects-multiple-calls-to-done) - [use any assertion library you want](#assertions) - [extensible reporting, bundled with 9+ reporters](#reporters) @@ -70,6 +71,7 @@ Mocha is a feature-rich JavaScript test framework running on [Node.js][] and in - [Command-Line Usage](#command-line-usage) - [Interfaces](#interfaces) - [Reporters](#reporters) +- [Node.JS native ESM support](#nodejs-native-esm-support) - [Running Mocha in the Browser](#running-mocha-in-the-browser) - [Desktop Notification Support](#desktop-notification-support) - [Configuring Mocha (Node.js)](#configuring-mocha-nodejs) @@ -354,11 +356,11 @@ With its default "BDD"-style interface, Mocha provides the hooks `before()`, `af ```js describe('hooks', function() { before(function() { - // runs before all tests in this block + // runs once before the first test in this block }); after(function() { - // runs after all tests in this block + // runs once after the last test in this block }); beforeEach(function() { @@ -868,7 +870,8 @@ Configuration --package Path to package.json for config [string] File Handling - --extension File extension(s) to load [array] [default: js] + --extension File extension(s) to load + [array] [default: ["js","cjs","mjs"]] --file Specify file(s) to be loaded prior to root suite execution [array] [default: (none)] --ignore, --exclude Ignore file(s) or glob pattern(s) @@ -1538,6 +1541,42 @@ Alias: `HTML`, `html` **The HTML reporter is not intended for use on the command-line.** +## Node.JS native ESM support + +> _New in v7.1.0_ + +Mocha supports writing your tests as ES modules, and not just using CommonJS. For example: + +```js +// test.mjs +import {add} from './add.mjs'; +import assert from 'assert'; + +it('should add to numbers from an es module', () => { + assert.equal(add(3, 5), 8); +}); +``` + +To enable this you don't need to do anything special. Write your test file as an ES module. In Node.js +this means either ending the file with a `.mjs` extension, or, if you want to use the regular `.js` extension, by +adding `"type": "module"` to your `package.json`. +More information can be found in the [Node.js documentation](https://nodejs.org/api/esm.html). + +> Mocha supports ES modules only from Node.js v12.11.0 and above. To enable this in versions smaller than 13.2.0, you need to add `--experimental-modules` when running +> Mocha. From version 13.2.0 of Node.js, you can use ES modules without any flags. + +### Current Limitations + +Node.JS native ESM support still has status: **Stability: 1 - Experimental** + +- [Watch mode](#-watch-w) does not support ES Module test files +- [Custom reporters](#third-party-reporters) and [custom interfaces](#interfaces) + can only be CommonJS files +- [Required modules](#-require-module-r-module) can only be CommonJS files +- [Configuration file](#configuring-mocha-nodejs) can only be a CommonJS file (`mocharc.js` or `mocharc.cjs`) +- When using module-level mocks via libs like `proxyquire`, `rewiremock` or `rewire`, hold off on using ES modules for your test files +- Node.JS native ESM support does not work with [esm][npm-esm] module + ## Running Mocha in the Browser Mocha runs in the browser. Every release of Mocha will have new builds of `./mocha.js` and `./mocha.css` for use in the browser. @@ -1609,17 +1648,17 @@ mocha.setup({ ### Browser-specific Option(s) -Browser Mocha supports many, but not all [cli options](#command-line-usage). +Browser Mocha supports many, but not all [cli options](#command-line-usage). To use a [cli option](#command-line-usage) that contains a "-", please convert the option to camel-case, (eg. `check-leaks` to `checkLeaks`). #### Options that differ slightly from [cli options](#command-line-usage): -`reporter` _{string|constructor}_ +`reporter` _{string|constructor}_ You can pass a reporter's name or a custom reporter's constructor. You can find **recommended** reporters for the browser [here](#reporting). It is possible to use [built-in reporters](#reporters) as well. Their employment in browsers is neither recommended nor supported, open the console to see the test results. #### Options that _only_ function in browser context: -`noHighlighting` _{boolean}_ +`noHighlighting` _{boolean}_ If set to `true`, do not attempt to use syntax highlighting on output test code. ### Reporting @@ -1701,7 +1740,8 @@ tests as shown below: In addition to supporting the deprecated [`mocha.opts`](#mochaopts) run-control format, Mocha now supports configuration files, typical of modern command-line tools, in several formats: -- **JavaScript**: Create a `.mocharc.js` in your project's root directory, and export an object (`module.exports = {/* ... */}`) containing your configuration. +- **JavaScript**: Create a `.mocharc.js` (or `mocharc.cjs` when using [`"type"="module"`](#nodejs-native-esm-support) in your `package.json`) + 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. - **package.json**: Create a `mocha` property in your project's `package.json`. diff --git a/karma.conf.js b/karma.conf.js index b0c713856c..ae84d7d830 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -35,6 +35,7 @@ module.exports = config => { .ignore('chokidar') .ignore('fs') .ignore('glob') + .ignore('./lib/esm-utils.js') .ignore('path') .ignore('supports-color') .on('bundled', (err, content) => { diff --git a/lib/cli/config.js b/lib/cli/config.js index 6fa4e2dbca..24de6cd474 100644 --- a/lib/cli/config.js +++ b/lib/cli/config.js @@ -21,6 +21,7 @@ const findUp = require('find-up'); * @private */ exports.CONFIG_FILES = [ + '.mocharc.cjs', '.mocharc.js', '.mocharc.yaml', '.mocharc.yml', @@ -75,7 +76,7 @@ exports.loadConfig = filepath => { try { if (ext === '.yml' || ext === '.yaml') { config = parsers.yaml(filepath); - } else if (ext === '.js') { + } else if (ext === '.js' || ext === '.cjs') { config = parsers.js(filepath); } else { config = parsers.json(filepath); diff --git a/lib/cli/options.js b/lib/cli/options.js index c87552c542..9fbc22ca0b 100644 --- a/lib/cli/options.js +++ b/lib/cli/options.js @@ -265,7 +265,7 @@ module.exports.loadPkgRc = loadPkgRc; * Priority list: * * 1. Command-line args - * 2. RC file (`.mocharc.js`, `.mocharc.ya?ml`, `mocharc.json`) + * 2. RC file (`.mocharc.c?js`, `.mocharc.ya?ml`, `mocharc.json`) * 3. `mocha` prop of `package.json` * 4. `mocha.opts` * 5. default configuration (`lib/mocharc.json`) diff --git a/lib/cli/run-helpers.js b/lib/cli/run-helpers.js index 6c662a665f..72823c48f6 100644 --- a/lib/cli/run-helpers.js +++ b/lib/cli/run-helpers.js @@ -15,8 +15,6 @@ const collectFiles = require('./collect-files'); const cwd = (exports.cwd = process.cwd()); -exports.watchRun = watchRun; - /** * Exits Mocha when tests + code under test has finished execution (default) * @param {number} code - Exit code; typically # of failures @@ -92,19 +90,21 @@ exports.handleRequires = (requires = []) => { }; /** - * Collect test files and run mocha instance. + * Collect and load test files, then run mocha instance. * @param {Mocha} mocha - Mocha instance * @param {Options} [opts] - Command line options * @param {boolean} [opts.exit] - Whether or not to force-exit after tests are complete * @param {Object} fileCollectParams - Parameters that control test * file collection. See `lib/cli/collect-files.js`. - * @returns {Runner} + * @returns {Promise} * @private */ -exports.singleRun = (mocha, {exit}, fileCollectParams) => { +const singleRun = async (mocha, {exit}, fileCollectParams) => { const files = collectFiles(fileCollectParams); debug('running tests with files', files); mocha.files = files; + + await mocha.loadFilesAsync(); return mocha.run(exit ? exitMocha : exitMochaLater); }; @@ -113,8 +113,9 @@ exports.singleRun = (mocha, {exit}, fileCollectParams) => { * @param {Mocha} mocha - Mocha instance * @param {Object} opts - Command line options * @private + * @returns {Promise} */ -exports.runMocha = (mocha, options) => { +exports.runMocha = async (mocha, options) => { const { watch = false, extension = [], @@ -140,7 +141,7 @@ exports.runMocha = (mocha, options) => { if (watch) { watchRun(mocha, {watchFiles, watchIgnore}, fileCollectParams); } else { - exports.singleRun(mocha, {exit}, fileCollectParams); + await singleRun(mocha, {exit}, fileCollectParams); } }; diff --git a/lib/cli/run.js b/lib/cli/run.js index e4e6ba2791..014227d569 100644 --- a/lib/cli/run.js +++ b/lib/cli/run.js @@ -87,7 +87,6 @@ exports.builder = yargs => }, extension: { default: defaults.extension, - defaultDescription: 'js', description: 'File extension(s) to load', group: GROUPS.FILES, requiresArg: true, @@ -299,8 +298,14 @@ exports.builder = yargs => .number(types.number) .alias(aliases); -exports.handler = argv => { +exports.handler = async function(argv) { debug('post-yargs config', argv); const mocha = new Mocha(argv); - runMocha(mocha, argv); + + try { + await runMocha(mocha, argv); + } catch (err) { + console.error('\n' + (err.stack || `Error: ${err.message || err}`)); + process.exit(1); + } }; diff --git a/lib/esm-utils.js b/lib/esm-utils.js new file mode 100644 index 0000000000..df2b5fed0e --- /dev/null +++ b/lib/esm-utils.js @@ -0,0 +1,31 @@ +const url = require('url'); +const path = require('path'); + +const requireOrImport = async file => { + file = path.resolve(file); + + if (path.extname(file) === '.mjs') { + return import(url.pathToFileURL(file)); + } + // This is currently the only known way of figuring out whether a file is CJS or ESM. + // If Node.js or the community establish a better procedure for that, we can fix this code. + // Another option here would be to always use `import()`, as this also supports CJS, but I would be + // wary of using it for _all_ existing test files, till ESM is fully stable. + try { + return require(file); + } catch (err) { + if (err.code === 'ERR_REQUIRE_ESM') { + return import(url.pathToFileURL(file)); + } else { + throw err; + } + } +}; + +exports.loadFilesAsync = async (files, preLoadFunc, postLoadFunc) => { + for (const file of files) { + preLoadFunc(file); + const result = await requireOrImport(file); + postLoadFunc(file, result); + } +}; diff --git a/lib/mocha.js b/lib/mocha.js index 0b43004abc..740e1fd841 100644 --- a/lib/mocha.js +++ b/lib/mocha.js @@ -14,6 +14,7 @@ var utils = require('./utils'); var mocharc = require('./mocharc.json'); var errors = require('./errors'); var Suite = require('./suite'); +var esmUtils = utils.supportsEsModules() ? require('./esm-utils') : undefined; var createStatsCollector = require('./stats-collector'); var createInvalidReporterError = errors.createInvalidReporterError; var createInvalidInterfaceError = errors.createInvalidInterfaceError; @@ -290,16 +291,18 @@ Mocha.prototype.ui = function(ui) { }; /** - * Loads `files` prior to execution. + * Loads `files` prior to execution. Does not support ES Modules. * * @description * The implementation relies on Node's `require` to execute * the test interface functions and will be subject to its cache. + * Supports only CommonJS modules. To load ES modules, use Mocha#loadFilesAsync. * * @private * @see {@link Mocha#addFile} * @see {@link Mocha#run} * @see {@link Mocha#unloadFiles} + * @see {@link Mocha#loadFilesAsync} * @param {Function} [fn] - Callback invoked upon completion. */ Mocha.prototype.loadFiles = function(fn) { @@ -314,6 +317,49 @@ Mocha.prototype.loadFiles = function(fn) { fn && fn(); }; +/** + * Loads `files` prior to execution. Supports Node ES Modules. + * + * @description + * The implementation relies on Node's `require` and `import` to execute + * the test interface functions and will be subject to its cache. + * Supports both CJS and ESM modules. + * + * @public + * @see {@link Mocha#addFile} + * @see {@link Mocha#run} + * @see {@link Mocha#unloadFiles} + * @returns {Promise} + * @example + * + * // loads ESM (and CJS) test files asynchronously, then runs root suite + * mocha.loadFilesAsync() + * .then(() => mocha.run(failures => process.exitCode = failures ? 1 : 0)) + * .catch(() => process.exitCode = 1); + */ +Mocha.prototype.loadFilesAsync = function() { + var self = this; + var suite = this.suite; + this.loadAsync = true; + + if (!esmUtils) { + return new Promise(function(resolve) { + self.loadFiles(resolve); + }); + } + + return esmUtils.loadFilesAsync( + this.files, + function(file) { + suite.emit(EVENT_FILE_PRE_REQUIRE, global, file, self); + }, + function(file, resultModule) { + suite.emit(EVENT_FILE_REQUIRE, resultModule, file, self); + suite.emit(EVENT_FILE_POST_REQUIRE, global, file, self); + } + ); +}; + /** * Removes a previously loaded file from Node's `require` cache. * @@ -330,8 +376,9 @@ Mocha.unloadFile = function(file) { * Unloads `files` from Node's `require` cache. * * @description - * This allows files to be "freshly" reloaded, providing the ability + * This allows required files to be "freshly" reloaded, providing the ability * to reuse a Mocha instance programmatically. + * Note: does not clear ESM module files from the cache * * Intended for consumers — not used internally * @@ -842,10 +889,14 @@ Object.defineProperty(Mocha.prototype, 'version', { * @see {@link Mocha#unloadFiles} * @see {@link Runner#run} * @param {DoneCB} [fn] - Callback invoked when test execution completed. - * @return {Runner} runner instance + * @returns {Runner} runner instance + * @example + * + * // exit with non-zero status if there were test failures + * mocha.run(failures => process.exitCode = failures ? 1 : 0); */ Mocha.prototype.run = function(fn) { - if (this.files.length) { + if (this.files.length && !this.loadAsync) { this.loadFiles(); } var suite = this.suite; diff --git a/lib/mocharc.json b/lib/mocharc.json index e6f5d99c5b..1ed9157675 100644 --- a/lib/mocharc.json +++ b/lib/mocharc.json @@ -1,6 +1,6 @@ { "diff": true, - "extension": ["js"], + "extension": ["js", "cjs", "mjs"], "opts": "./test/mocha.opts", "package": "./package.json", "reporter": "spec", diff --git a/lib/utils.js b/lib/utils.js index 805d98d463..59b250c20e 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -831,3 +831,25 @@ exports.defineConstants = function(obj) { } return Object.freeze(exports.createMap(obj)); }; + +/** + * Whether current version of Node support ES modules + * + * @description + * Versions prior to 10 did not support ES Modules, and version 10 has an old incompatibile version of ESM. + * This function returns whether Node.JS has ES Module supports that is compatible with Mocha's needs, + * which is version >=12.11. + * + * @returns {Boolean} whether the current version of Node.JS supports ES Modules in a way that is compatible with Mocha + */ +exports.supportsEsModules = function() { + if (!process.browser && process.versions && process.versions.node) { + var versionFields = process.versions.node.split('.'); + var major = +versionFields[0]; + var minor = +versionFields[1]; + + if (major >= 13 || (major === 12 && minor >= 11)) { + return true; + } + } +}; diff --git a/package-lock.json b/package-lock.json index 05f0471347..86234a92da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -104,7 +104,7 @@ }, "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, @@ -684,7 +684,7 @@ "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha1-aALmJk79GMeQobDVF/DyYnvyyUo=", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true }, "arch": { @@ -1330,7 +1330,7 @@ }, "source-map": { "version": "0.1.43", - "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", "dev": true, "optional": true, @@ -1342,7 +1342,7 @@ }, "ast-types": { "version": "0.7.8", - "resolved": "http://registry.npmjs.org/ast-types/-/ast-types-0.7.8.tgz", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.7.8.tgz", "integrity": "sha1-kC0uDWDQcb3NRtwRXhgJ7RHBOKk=", "dev": true }, @@ -1470,6 +1470,31 @@ } } }, + "babel-eslint": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.3.tgz", + "integrity": "sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -1904,7 +1929,7 @@ "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha1-LN4J617jQfSEdGuwMJsyU7GxRC8=", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", "dev": true }, "body-parser": { @@ -2069,7 +2094,7 @@ }, "brfs": { "version": "1.6.1", - "resolved": "http://registry.npmjs.org/brfs/-/brfs-1.6.1.tgz", + "resolved": "https://registry.npmjs.org/brfs/-/brfs-1.6.1.tgz", "integrity": "sha512-OfZpABRQQf+Xsmju8XE9bDjs+uU4vLREGolP7bDgcpsI17QREyZ4Bl+2KLxxx1kCgA0fAIhKQBaBYh+PEcCqYQ==", "dev": true, "requires": { @@ -2158,7 +2183,7 @@ "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha1-uqVZ7hTO1zRSIputcyZGfGH6vWA=" + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" }, "browser-sync": { "version": "2.26.7", @@ -2328,7 +2353,7 @@ }, "yargs": { "version": "6.4.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-6.4.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.4.0.tgz", "integrity": "sha1-gW4ahm1VmMzzTlWW3c4i2S2kkNQ=", "dev": true, "requires": { @@ -2350,7 +2375,7 @@ }, "yargs-parser": { "version": "4.2.1", - "resolved": "http://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", "dev": true, "requires": { @@ -3106,7 +3131,7 @@ "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94=", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "dev": true, "requires": { "inherits": "^2.0.1", @@ -3771,7 +3796,7 @@ "createerror": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/createerror/-/createerror-1.3.0.tgz", - "integrity": "sha1-xma9TNa5TjVBU5ZWnUZJ3QzbMxM=", + "integrity": "sha512-w9UZUtkaGd8MfS7eMG7Sa0lV5vCJghqQfiOnwNVrPhbZScUp5h0jwYoAF933MKlotlG1JAJOCCT3xU6r+SDKNw==", "dev": true }, "cross-env": { @@ -4615,7 +4640,7 @@ "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha1-gAwN0eCov7yVg1wgKtIg/jF+WhI=" + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" }, "diffie-hellman": { "version": "5.0.3", @@ -5744,7 +5769,7 @@ "evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha1-f8vbGY3HGVlDLv4ThCaE4FJaywI=", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "dev": true, "requires": { "md5.js": "^1.3.4", @@ -6386,13 +6411,13 @@ "dependencies": { "colors": { "version": "0.6.2", - "resolved": "http://registry.npmjs.org/colors/-/colors-0.6.2.tgz", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", "dev": true }, "commander": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/commander/-/commander-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz", "integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=", "dev": true } @@ -7218,7 +7243,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -7287,7 +7312,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -7507,7 +7532,7 @@ }, "got": { "version": "6.7.1", - "resolved": "http://registry.npmjs.org/got/-/got-6.7.1.tgz", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", "dev": true, "requires": { @@ -7848,7 +7873,7 @@ "html-encoding-sniffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha1-5w2EuU2lOqN14R/jo1G+ZkLKRvg=", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", "dev": true, "requires": { "whatwg-encoding": "^1.0.1" @@ -9084,7 +9109,7 @@ "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { "isobject": "^3.0.1" @@ -9853,6 +9878,15 @@ "strip-ansi": "^4.0.0" }, "dependencies": { + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -10074,6 +10108,15 @@ "is-extglob": "^2.1.1" } }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, "p-map": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", @@ -10237,7 +10280,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -10399,7 +10442,7 @@ }, "yargs": { "version": "6.6.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", "dev": true, "requires": { @@ -10420,7 +10463,7 @@ }, "yargs-parser": { "version": "4.2.1", - "resolved": "http://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", "dev": true, "requires": { @@ -10560,11 +10603,11 @@ "dev": true }, "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", "requires": { - "chalk": "^2.0.1" + "chalk": "^2.4.2" } }, "log-update": { @@ -10703,7 +10746,7 @@ }, "magic-string": { "version": "0.22.5", - "resolved": "http://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", "dev": true, "requires": { @@ -10869,7 +10912,7 @@ }, "globby": { "version": "6.1.0", - "resolved": "http://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", "dev": true, "requires": { @@ -10952,7 +10995,7 @@ "markdown-toc": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/markdown-toc/-/markdown-toc-1.2.0.tgz", - "integrity": "sha1-RKFWBoREkDFK/ARESD+eexEiwzk=", + "integrity": "sha512-eOsq7EGd3asV0oBfmyqngeEIhrbkc7XVP63OwcJBIhH2EpG2PzFcbZdhy1jutXSlRBBVMNXHvMtSr5LAxSUvUg==", "dev": true, "requires": { "concat-stream": "^1.5.2", @@ -11262,7 +11305,7 @@ "miller-rabin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha1-8IA1HIZbDcViqEYpZtqlNUPHik0=", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "dev": true, "requires": { "bn.js": "^4.0.0", @@ -11582,7 +11625,7 @@ "no-case": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha1-YLgTOWvjmz8SiKTB7V0efSi0ZKw=", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", "dev": true, "requires": { "lower-case": "^1.1.1" @@ -11684,7 +11727,7 @@ }, "tty-browserify": { "version": "0.0.0", - "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, @@ -11861,7 +11904,7 @@ "npmlog": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha1-CKfyqL9zRgR3mp76StXMcXq7lUs=", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, "requires": { "are-we-there-yet": "~1.1.2", @@ -12300,7 +12343,7 @@ }, "yargs": { "version": "3.32.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", "dev": true, "requires": { @@ -12381,7 +12424,7 @@ }, "resolve-from": { "version": "4.0.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, @@ -12543,7 +12586,7 @@ }, "opn": { "version": "5.3.0", - "resolved": "http://registry.npmjs.org/opn/-/opn-5.3.0.tgz", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", "dev": true, "requires": { @@ -13079,7 +13122,7 @@ "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha1-ut+hSX1GJE9jkPWLMZgw2RB4U8U=", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", "dev": true, "requires": { "chalk": "^1.1.3", @@ -13681,7 +13724,7 @@ "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha1-ut+hSX1GJE9jkPWLMZgw2RB4U8U=", + "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", "dev": true, "requires": { "chalk": "^1.1.3", @@ -13907,13 +13950,13 @@ }, "pretty-bytes": { "version": "4.0.2", - "resolved": "http://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz", "integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=", "dev": true }, "pretty-ms": { "version": "0.2.2", - "resolved": "http://registry.npmjs.org/pretty-ms/-/pretty-ms-0.2.2.tgz", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-0.2.2.tgz", "integrity": "sha1-2oeaaC/zOjcBEEbxPWJ/Z8c7hPY=", "dev": true, "requires": { @@ -14115,7 +14158,7 @@ }, "yargs": { "version": "3.10.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, "requires": { @@ -14259,7 +14302,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, @@ -14914,7 +14957,7 @@ }, "rgba-regex": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", "dev": true }, @@ -15042,7 +15085,7 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true }, "saxes": { @@ -17130,7 +17173,7 @@ }, "strip-ansi": { "version": "0.1.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", "dev": true } @@ -17173,7 +17216,7 @@ "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { "os-tmpdir": "~1.0.2" @@ -18149,7 +18192,7 @@ "webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha1-qFWYCx8LazWbodXZ+zmulB+qY60=", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", "dev": true }, "whatwg-encoding": { diff --git a/package-scripts.js b/package-scripts.js index 3f9b2d0bd4..a94de98e40 100644 --- a/package-scripts.js +++ b/package-scripts.js @@ -23,7 +23,7 @@ function test(testName, mochaParams) { module.exports = { scripts: { build: { - script: `browserify -e browser-entry.js --plugin ./scripts/dedefine --ignore './lib/cli/*.js' --ignore 'chokidar' --ignore 'fs' --ignore 'glob' --ignore 'path' --ignore 'supports-color' -o mocha.js`, + script: `browserify -e browser-entry.js --plugin ./scripts/dedefine --ignore './lib/cli/*.js' --ignore "./lib/esm-utils.js" --ignore 'chokidar' --ignore 'fs' --ignore 'glob' --ignore 'path' --ignore 'supports-color' -o mocha.js`, description: 'Build browser bundle' }, lint: { diff --git a/package.json b/package.json index fcebd7f32e..8cad374e94 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "growl": "1.10.5", "he": "1.2.0", "js-yaml": "3.13.1", - "log-symbols": "2.2.0", + "log-symbols": "3.0.0", "minimatch": "3.0.4", "mkdirp": "0.5.1", "ms": "2.1.1", @@ -74,6 +74,7 @@ "acorn": "^7.0.0", "assetgraph-builder": "^6.10.1", "autoprefixer": "^9.6.0", + "babel-eslint": "^10.0.3", "browserify": "^16.2.3", "browserify-package-json": "^1.0.1", "chai": "^4.2.0", diff --git a/test/integration/config.spec.js b/test/integration/config.spec.js index 8d81bec9ab..52fa886220 100644 --- a/test/integration/config.spec.js +++ b/test/integration/config.spec.js @@ -11,9 +11,11 @@ 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 cjs = loadConfig(path.join(configDir, 'mocharc.cjs')); var json = loadConfig(path.join(configDir, 'mocharc.json')); var yaml = loadConfig(path.join(configDir, 'mocharc.yaml')); expect(js, 'to equal', json); + expect(js, 'to equal', cjs); expect(json, 'to equal', yaml); }); diff --git a/test/integration/esm.spec.js b/test/integration/esm.spec.js new file mode 100644 index 0000000000..b4cf761f2a --- /dev/null +++ b/test/integration/esm.spec.js @@ -0,0 +1,53 @@ +'use strict'; +var run = require('./helpers').runMochaJSON; +var utils = require('../../lib/utils'); +var args = + +process.versions.node.split('.')[0] >= 13 ? [] : ['--experimental-modules']; + +describe('esm', function() { + before(function() { + if (!utils.supportsEsModules()) this.skip(); + }); + + it('should pass a passing esm test that uses esm', function(done) { + var fixture = 'esm/esm-success.fixture.mjs'; + run(fixture, args, function(err, result) { + if (err) { + done(err); + return; + } + + expect(result, 'to have passed test count', 1); + done(); + }); + }); + + it('should fail a failing esm test that uses esm', function(done) { + var fixture = 'esm/esm-failure.fixture.mjs'; + run(fixture, args, function(err, result) { + if (err) { + done(err); + return; + } + + expect(result, 'to have failed test count', 1).and( + 'to have failed test', + 'should use a function from an esm, and fail' + ); + done(); + }); + }); + + it('should recognize esm files ending with .js due to package.json type flag', function(done) { + var fixture = 'esm/js-folder/esm-in-js.fixture.js'; + run(fixture, args, function(err, result) { + if (err) { + done(err); + return; + } + + expect(result, 'to have passed test count', 1); + done(); + }); + }); +}); diff --git a/test/integration/fixtures/config/mocharc.cjs b/test/integration/fixtures/config/mocharc.cjs new file mode 100644 index 0000000000..adec9d68ed --- /dev/null +++ b/test/integration/fixtures/config/mocharc.cjs @@ -0,0 +1,9 @@ +'use strict'; + +// a comment +module.exports = { + require: ['foo', 'bar'], + bail: true, + reporter: 'dot', + slow: 60 +}; diff --git a/test/integration/fixtures/esm/add.mjs b/test/integration/fixtures/esm/add.mjs new file mode 100644 index 0000000000..7d658310b0 --- /dev/null +++ b/test/integration/fixtures/esm/add.mjs @@ -0,0 +1,3 @@ +export function add(a, b) { + return a + b; +} diff --git a/test/integration/fixtures/esm/esm-failure.fixture.mjs b/test/integration/fixtures/esm/esm-failure.fixture.mjs new file mode 100644 index 0000000000..588d8fce7f --- /dev/null +++ b/test/integration/fixtures/esm/esm-failure.fixture.mjs @@ -0,0 +1,5 @@ +import {add} from './add.mjs'; + +it('should use a function from an esm, and fail', () => { + expect(add(3, 5), 'to be', 9); +}); diff --git a/test/integration/fixtures/esm/esm-success.fixture.mjs b/test/integration/fixtures/esm/esm-success.fixture.mjs new file mode 100644 index 0000000000..0df926cae7 --- /dev/null +++ b/test/integration/fixtures/esm/esm-success.fixture.mjs @@ -0,0 +1,5 @@ +import {add} from './add.mjs'; + +it('should use a function from an esm', () => { + expect(add(3, 5), 'to be', 8); +}); diff --git a/test/integration/fixtures/esm/js-folder/add.js b/test/integration/fixtures/esm/js-folder/add.js new file mode 100644 index 0000000000..7d658310b0 --- /dev/null +++ b/test/integration/fixtures/esm/js-folder/add.js @@ -0,0 +1,3 @@ +export function add(a, b) { + return a + b; +} diff --git a/test/integration/fixtures/esm/js-folder/esm-in-js.fixture.js b/test/integration/fixtures/esm/js-folder/esm-in-js.fixture.js new file mode 100644 index 0000000000..92abf1241e --- /dev/null +++ b/test/integration/fixtures/esm/js-folder/esm-in-js.fixture.js @@ -0,0 +1,5 @@ +import {add} from './add.js'; + +it('should use a function from an esm module with a js extension', () => { + expect(add(3, 5), 'to be', 8); +}); diff --git a/test/integration/fixtures/esm/js-folder/package.json b/test/integration/fixtures/esm/js-folder/package.json new file mode 100644 index 0000000000..3dbc1ca591 --- /dev/null +++ b/test/integration/fixtures/esm/js-folder/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/test/integration/helpers.js b/test/integration/helpers.js index 0d65e91e6b..6cdf7e93cf 100644 --- a/test/integration/helpers.js +++ b/test/integration/helpers.js @@ -299,7 +299,7 @@ function _spawnMochaWithListeners(args, fn, opts) { } function resolveFixturePath(fixture) { - if (path.extname(fixture) !== '.js') { + if (path.extname(fixture) !== '.js' && path.extname(fixture) !== '.mjs') { fixture += '.fixture.js'; } return path.join('test', 'integration', 'fixtures', fixture); diff --git a/test/integration/suite.spec.js b/test/integration/suite.spec.js index d3aac74034..ce1171b0a2 100644 --- a/test/integration/suite.spec.js +++ b/test/integration/suite.spec.js @@ -12,9 +12,11 @@ describe('suite w/no callback', function() { if (err) { return done(err); } - var pattern = new RegExp('TypeError', 'g'); - var result = res.output.match(pattern) || []; - expect(result, 'to have length', 2); + expect( + res.output, + 'to match', + /no callback was supplied. Supply a callback/ + ); done(); }, {stdio: 'pipe'}