mocha
Version:
Classic, reliable, trusted test framework for Node.js and the browser
105 lines (96 loc) • 2.82 kB
JavaScript
;
/**
* Responsible for loading / finding Mocha's "rc" files.
*
* @private
* @module
*/
const fs = require("node:fs");
const path = require("node:path");
const debug = require("debug")("mocha:cli:config");
const findUp = require("find-up");
const { createUnparsableFileError } = require("../errors.js");
const utils = require("../utils.cjs");
/**
* These are the valid config files, in order of precedence;
* e.g., if `.mocharc.js` is present, then `.mocharc.yaml` and the rest
* will be ignored.
* The user should still be able to explicitly specify a file.
* @private
*/
// This is documented publicly in `configuring.mdx`
exports.CONFIG_FILES = [
".mocharc.cjs",
".mocharc.js",
".mocharc.mjs",
".mocharc.yaml",
".mocharc.yml",
".mocharc.jsonc",
".mocharc.json",
];
/**
* Parsers for various config filetypes. Each accepts a filepath and
* returns an object (but could throw)
*/
const parsers = (exports.parsers = {
yaml: (filepath) =>
require("js-yaml").load(fs.readFileSync(filepath, "utf8")),
js: (filepath) => {
let cwdFilepath;
try {
debug('parsers: load cwd-relative path: "%s"', path.resolve(filepath));
cwdFilepath = require.resolve(path.resolve(filepath)); // evtl. throws
return require(cwdFilepath);
} catch (err) {
if (cwdFilepath) throw err;
debug('parsers: retry load as module-relative path: "%s"', filepath);
return require(filepath);
}
},
json: (filepath) =>
JSON.parse(
require("strip-json-comments").default(fs.readFileSync(filepath, "utf8")),
),
});
/**
* Loads and parses, based on file extension, a config file.
* "JSON" files may have comments.
*
* @private
* @param {string} filepath - Config file path to load
* @returns {Object} Parsed config object
*/
exports.loadConfig = (filepath) => {
let config;
debug("loadConfig: trying to parse config at %s", filepath);
const ext = path.extname(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 {
config = parsers.json(filepath);
}
} catch (err) {
throw createUnparsableFileError(
`Unable to read/parse ${filepath}: ${err}`,
filepath,
);
}
return config;
};
/**
* Find ("find up") config file starting at `cwd`
*
* @param {string} [cwd] - Current working directory
* @returns {string|null} Filepath to config, if found
*/
exports.findConfig = (cwd = utils.cwd()) => {
const filepath = findUp.sync(exports.CONFIG_FILES, { cwd });
if (filepath) {
debug("findConfig: found config file %s", filepath);
}
return filepath;
};