| "use strict"; |
| |
| /** |
| * Metadata about various options of the `run` command |
| * @see module:lib/cli/run |
| * @module |
| * @private |
| */ |
| |
| /** |
| * Dictionary of option types to list of options having said type |
| * @type {Record<string, string[]>} |
| * @private |
| */ |
| const types = { |
| array: [ |
| "extension", |
| "file", |
| "global", |
| "ignore", |
| "node-option", |
| "reporter-option", |
| "require", |
| "spec", |
| "watch-files", |
| "watch-ignore", |
| ], |
| boolean: [ |
| "allow-uncaught", |
| "async-only", |
| "bail", |
| "check-leaks", |
| "clear-screen", |
| "color", |
| "delay", |
| "diff", |
| "dry-run", |
| "exit", |
| "fail-hook-affected-tests", |
| "pass-on-failing-test-suite", |
| "fail-zero", |
| "forbid-only", |
| "forbid-pending", |
| "full-trace", |
| "inline-diffs", |
| "invert", |
| "list-interfaces", |
| "list-reporters", |
| "no-colors", |
| "parallel", |
| "posix-exit-codes", |
| "recursive", |
| "sort", |
| "watch", |
| ], |
| number: ["retries", "jobs"], |
| string: [ |
| "config", |
| "fgrep", |
| "grep", |
| "package", |
| "reporter", |
| "ui", |
| "slow", |
| "timeout", |
| ], |
| }; |
| |
| /** |
| * Option aliases keyed by canonical option name. |
| * Arrays used to reduce |
| * @type {Record<string, string[]>} |
| * @private |
| */ |
| const aliases = { |
| "async-only": ["A"], |
| bail: ["b"], |
| color: ["c", "colors"], |
| fgrep: ["f"], |
| global: ["globals"], |
| grep: ["g"], |
| ignore: ["exclude"], |
| invert: ["i"], |
| jobs: ["j"], |
| "no-colors": ["C"], |
| "node-option": ["n"], |
| parallel: ["p"], |
| reporter: ["R"], |
| "reporter-option": ["reporter-options", "O"], |
| require: ["r"], |
| slow: ["s"], |
| sort: ["S"], |
| timeout: ["t", "timeouts"], |
| ui: ["u"], |
| watch: ["w"], |
| }; |
| |
| const descriptions = { |
| "allow-uncaught": "Allow uncaught errors to propagate", |
| "async-only": |
| "Require all tests to use a callback (async) or return a Promise", |
| bail: 'Abort ("bail") after first test failure', |
| "check-leaks": "Check for global variable leaks", |
| color: "Force-enable color output", |
| config: "Path to config file", |
| delay: "Delay initial execution of root suite", |
| diff: "Show diff on failure", |
| "dry-run": "Report tests without executing them", |
| exit: "Force Mocha to quit after tests complete", |
| extension: "File extension(s) to load", |
| "fail-hook-affected-tests": |
| "Report tests as failed when affected by hook failures (before/beforeEach)", |
| "fail-zero": "Fail test run if no test(s) encountered", |
| "pass-on-failing-test-suite": "Not fail test run if tests were failed", |
| fgrep: "Only run tests containing this string", |
| file: "Specify file(s) to be loaded prior to root suite execution", |
| "forbid-only": "Fail if exclusive test(s) encountered", |
| "forbid-pending": "Fail if pending test(s) encountered", |
| "full-trace": "Display full stack traces", |
| global: "List of allowed global variables", |
| grep: "Only run tests matching this string or regexp", |
| ignore: "Ignore file(s) or glob pattern(s)", |
| "inline-diffs": |
| "Display actual/expected differences inline within each string", |
| invert: "Inverts --grep and --fgrep matches", |
| jobs: "Number of concurrent jobs for --parallel; use 1 to run in serial", |
| "list-interfaces": "List built-in user interfaces & exit", |
| "list-reporters": "List built-in reporters & exit", |
| "no-colors": "Force-disable color output", |
| "node-option": 'Node or V8 option (no leading "--")', |
| package: "Path to package.json for config", |
| parallel: "Run tests in parallel", |
| "posix-exit-codes": |
| "Use POSIX and UNIX shell exit codes as Mocha's return value", |
| recursive: "Look for tests in subdirectories", |
| reporter: "Specify reporter to use", |
| "reporter-option": "Reporter-specific options (<k=v,[k1=v1,..]>)", |
| require: "Require module", |
| retries: "Retry failed tests this many times", |
| slow: 'Specify "slow" test threshold (in milliseconds)', |
| sort: "Sort test files", |
| timeout: "Specify test timeout threshold (in milliseconds)", |
| ui: "Specify user interface", |
| watch: "Watch files in the current working directory for changes", |
| "watch-files": "List of paths or globs to watch", |
| "watch-ignore": "List of paths or globs to exclude from watching", |
| }; |
| |
| const getRunOptionDefinitions = () => |
| Object.entries(types).flatMap(([type, names]) => |
| names.map((name) => ({ |
| name, |
| type, |
| aliases: aliases[name] || [], |
| description: descriptions[name] || "", |
| })), |
| ); |
| |
| const ALL_MOCHA_FLAGS = Object.keys(types).reduce((acc, key) => { |
| // gets all flags from each of the fields in `types`, adds those, |
| // then adds aliases of each flag (if any) |
| types[key].forEach((flag) => { |
| acc.add(flag); |
| const flagAliases = aliases[flag] || []; |
| flagAliases.forEach((alias) => { |
| acc.add(alias); |
| }); |
| }); |
| return acc; |
| }, new Set()); |
| |
| /** |
| * Strips one or two leading dashes from a flag, e.g. `--grep` becomes `grep` |
| * and `-g` becomes `g`. Barewords are returned unchanged. |
| * @param {string} flag - Flag to normalize (with or without leading dashes) |
| * @returns {string} The flag without its leading dashes |
| * @private |
| */ |
| const stripLeadingDashes = (flag) => flag.replace(/^--?/, ""); |
| |
| /** |
| * Returns `true` if the provided `flag` is known to Mocha. |
| * @param {string} flag - Flag to check |
| * @returns {boolean} If `true`, this is a Mocha flag |
| * @private |
| */ |
| const isMochaFlag = (flag) => { |
| return ALL_MOCHA_FLAGS.has(stripLeadingDashes(flag)); |
| }; |
| |
| /** |
| * Returns expected yarg option type for a given mocha flag. |
| * @param {string} flag - Flag to check (can be with or without leading dashes "--"") |
| * @returns {string | undefined} - If flag is a valid mocha flag, the expected type of argument for this flag is returned, otherwise undefined is returned. |
| * @private |
| */ |
| const expectedTypeForFlag = (flag) => { |
| const normalizedName = stripLeadingDashes(flag); |
| |
| // If flag is an alias, get it's full name. |
| const fullFlagName = |
| Object.keys(aliases).find((flagName) => |
| aliases[flagName].includes(normalizedName), |
| ) || normalizedName; |
| |
| return Object.keys(types).find((flagType) => |
| types[flagType].includes(fullFlagName), |
| ); |
| }; |
| |
| exports.types = types; |
| exports.aliases = aliases; |
| exports.getRunOptionDefinitions = getRunOptionDefinitions; |
| exports.isMochaFlag = isMochaFlag; |
| exports.expectedTypeForFlag = expectedTypeForFlag; |
| exports.stripLeadingDashes = stripLeadingDashes; |