UNPKG

mocha

Version:

Classic, reliable, trusted test framework for Node.js and the browser

149 lines (125 loc) 3.89 kB
"use strict"; /** * Definition for Mocha's default ("run tests") command * * @module * @private */ const Mocha = require("../mocha.cjs"); const { createUnsupportedError, createInvalidArgumentValueError, createMissingArgumentError, } = require("../errors.js"); const { list, handleRequires, validateLegacyPlugin, runMocha, } = require("./run-helpers.cjs"); const { ONE_AND_DONES } = require("./one-and-dones.js"); const debug = require("debug")("mocha:cli:run"); exports.command = ["$0 [spec..]", "inspect"]; exports.describe = "Run tests with Mocha"; const camelCase = (name) => name.replace(/-([a-z])/g, (_, char) => char.toUpperCase()); const coerceReporterOption = (opts) => list(opts).reduce((acc, opt) => { const pair = opt.split("="); if (pair.length > 2 || !pair.length) { throw createInvalidArgumentValueError( `invalid reporter option '${opt}'`, "--reporter-option", opt, 'expected "key=value" format', ); } acc[pair[0]] = pair.length === 2 ? pair[1] : true; return acc; }, {}); const normalizeRunOptions = (argv) => { Object.keys(argv).forEach((name) => { const reporterOptionMatch = name.match(/^reporter-options?\.(.+)$/); if (reporterOptionMatch) { argv["reporter-option"] = Object.assign({}, argv["reporter-option"], { [reporterOptionMatch[1]]: argv[name], }); } if (name.includes("-")) { const normalizedName = camelCase(name); if (!(normalizedName in argv)) { argv[normalizedName] = argv[name]; } } }); if (Array.isArray(argv["reporter-option"])) { argv["reporter-option"] = coerceReporterOption(argv["reporter-option"]); } }; const validateRunOptions = (argv) => { // "one-and-dones"; help and version are handled by the top-level CLI. const oneAndDoneOptions = Object.keys(ONE_AND_DONES).filter((opt) => Boolean(argv[opt]), ); if (oneAndDoneOptions.length > 1) { throw createUnsupportedError( `Arguments ${oneAndDoneOptions.join(" and ")} are mutually exclusive`, ); } Object.keys(ONE_AND_DONES).forEach((opt) => { if (argv[opt]) { ONE_AND_DONES[opt].call(null); process.exit(0); } }); if (argv.invert && !("fgrep" in argv || "grep" in argv)) { throw createMissingArgumentError( '"--invert" requires one of "--fgrep <str>" or "--grep <regexp>"', "--fgrep|--grep", "string|regexp", ); } if (argv.fgrep && argv.grep) { throw createUnsupportedError( "Arguments fgrep and grep are mutually exclusive", ); } if (argv.parallel) { if (argv.file) { throw createUnsupportedError( "--parallel runs test files in a non-deterministic order, and is mutually exclusive with --file", ); } if (argv.sort) { throw createUnsupportedError( "--parallel runs test files in a non-deterministic order, and is mutually exclusive with --sort", ); } if (["progress", "markdown", "json-stream"].includes(argv.reporter)) { throw createUnsupportedError( `--reporter=${argv.reporter} is mutually exclusive with --parallel`, ); } } }; const prepareRunOptions = async (argv) => { const plugins = await handleRequires(argv.require); validateLegacyPlugin(argv, "reporter", Mocha.reporters); validateLegacyPlugin(argv, "ui", Mocha.interfaces); Object.assign(argv, plugins); return argv; }; exports.validateRunOptions = validateRunOptions; exports.prepareRunOptions = prepareRunOptions; exports.normalizeRunOptions = normalizeRunOptions; exports.handler = async function (argv) { normalizeRunOptions(argv); debug("running with config", argv); const mocha = new Mocha(argv); try { await runMocha(mocha, argv); } catch (err) { console.error("\n Exception during run:", err); process.exit(1); } };