diff --git a/lib/cli/config.js b/lib/cli/config.js index 10f16d8aa3..238f2839cd 100644 --- a/lib/cli/config.js +++ b/lib/cli/config.js @@ -11,7 +11,10 @@ const fs = require('fs'); const path = require('path'); const debug = require('debug')('mocha:cli:config'); const findUp = require('find-up'); -const {createUnparsableFileError} = require('../errors'); +const { + createUnparsableFileError, + createModuleNotFoundError +} = require('../errors'); const utils = require('../utils'); /** @@ -82,6 +85,12 @@ exports.loadConfig = filepath => { config = parsers.json(filepath); } } catch (err) { + if (isModuleNotFoundError(err)) { + throw createModuleNotFoundError( + `${filepath} is attempting to import a module that does not exist: ${err}`, + filepath + ); + } throw createUnparsableFileError( `Unable to read/parse ${filepath}: ${err}`, filepath diff --git a/lib/errors.js b/lib/errors.js index bcc7291c99..53d5168ea0 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -170,7 +170,14 @@ var constants = { * @constant * @default */ - UNPARSABLE_FILE: 'ERR_MOCHA_UNPARSABLE_FILE' + UNPARSABLE_FILE: 'ERR_MOCHA_UNPARSABLE_FILE', + + /** + * File attempts to import non-existent module + * @constant + * @default + */ + MODULE_NOT_FOUND: 'ERR_MOCHA_MODULE_NOT_FOUND' }; /** @@ -516,6 +523,25 @@ function createUnparsableFileError(message, filename) { return err; } +/** + * Creates an error object to be thrown when file attempts to import module that does not exist. + * @public + * @static + * @param {string} message - Error message to be displayed. + * @param {string} importerFilename - File name of importing module + * @param {string} importedFilename - File name of imported module + * @returns {Error} Error with code {@link constants.MODULE_NOT_FOUND} + */ +function createModuleNotFoundError( + message, + importerFilename, + importedFilename +) { + var err = new Error(message); + err.code = constants.MODULE_NOT_FOUND; + return err; +} + /** * Returns `true` if an error came out of Mocha. * _Can suffer from false negatives, but not false positives._ @@ -547,6 +573,7 @@ module.exports = { createNoFilesMatchPatternError, createTimeoutError, createUnparsableFileError, + createModuleNotFoundError, createUnsupportedError, deprecate, isMochaError, diff --git a/package-lock.json b/package-lock.json index 49ce52ee44..3dd2bec5b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,6 @@ "requires": true, "packages": { "": { - "name": "mocha", "version": "9.2.0", "license": "MIT", "dependencies": { diff --git a/test/integration/config.spec.js b/test/integration/config.spec.js index 7009a89044..f0e80633ca 100644 --- a/test/integration/config.spec.js +++ b/test/integration/config.spec.js @@ -5,6 +5,7 @@ var fs = require('fs'); var path = require('path'); +const {constants} = require('../../lib/errors'); var loadConfig = require('../../lib/cli/config').loadConfig; describe('config', function () { @@ -47,6 +48,28 @@ describe('config', function () { expect(js, 'to equal', json); }); + it('should throw module not found error from absolute path configuration', function () { + function _loadConfig() { + loadConfig(path.join(configDir, 'mocharcWithInvalidImport.js')); + } + + expect(_loadConfig, 'to throw', { + code: constants.MODULE_NOT_FOUND + }); + }); + + it('should throw module not found error from relative path configuration', function () { + var relConfigDir = configDir.substring(projRootDir.length + 1); + + function _loadConfig() { + loadConfig(path.join('.', relConfigDir, 'mocharcWithInvalidImport.js')); + } + + expect(_loadConfig, 'to throw', { + code: constants.MODULE_NOT_FOUND + }); + }); + it('should rethrow error from absolute path configuration', function () { function _loadConfig() { loadConfig(path.join(configDir, 'mocharcWithThrowError.js')); diff --git a/test/integration/fixtures/config/mocharcWithInvalidImport.js b/test/integration/fixtures/config/mocharcWithInvalidImport.js new file mode 100644 index 0000000000..848de9e5ea --- /dev/null +++ b/test/integration/fixtures/config/mocharcWithInvalidImport.js @@ -0,0 +1,10 @@ +'use strict'; + +require('invalidImport.js'); +// a comment +module.exports = { + require: ['foo', 'bar'], + bail: true, + reporter: 'dot', + slow: 60 +}; diff --git a/test/integration/fixtures/config/mocharcWithThrowError.js b/test/integration/fixtures/config/mocharcWithThrowError.js index f88872027e..76343f5b11 100644 --- a/test/integration/fixtures/config/mocharcWithThrowError.js +++ b/test/integration/fixtures/config/mocharcWithThrowError.js @@ -1,6 +1,6 @@ 'use strict'; -throw new Error("Error from mocharcWithThrowError"); +throw new Error('Error from mocharcWithThrowError'); // a comment module.exports = {