Skip to content

Commit

Permalink
Throw error for numeric positional arg after yargs-parser has parsed …
Browse files Browse the repository at this point in the history
…args

Signed-off-by: Dinika Saxena <dinikasaxenas@gmail.com>
  • Loading branch information
Dinika committed Dec 5, 2024
1 parent 19bd2a4 commit 912bdd1
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 19 deletions.
66 changes: 47 additions & 19 deletions lib/cli/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,44 @@ const nargOpts = types.array
.concat(types.string, types.number)
.reduce((acc, arg) => Object.assign(acc, {[arg]: 1}), {});

/**
* Throws either "UNSUPPORTED" error or "INVALID_ARG_TYPE" error for numeric positional arguments.
* @param {string[]} allArgs - Stringified args passed to mocha cli
* @param {number} numericArg - Numeric positional arg for which error must be thrown
* @param {Object} parsedResult - Result from `yargs-parser`
* @private
* @ignore
*/
const createErrorForNumericPositionalArg = (
allArgs,
numericArg,
parsedResult
) => {
// A flag for `numericArg` exists if:
// 1. A mocha flag immediately preceeded the numericArg in `allArgs` array and
// 2. `numericArg` value could not be assigned to this flag by `yargs-parser` because of incompatible datatype.
const flag = allArgs.find((arg, index) => {
const normalizedArg = arg.replace(/^--?/, '');
return (
isMochaFlag(arg) &&
allArgs[index + 1] === String(numericArg) &&
parsedResult[normalizedArg] !== numericArg
);
});

if (flag) {
throw createInvalidArgumentTypeError(
`Mocha flag '${flag}' given invalid option: '${numericArg}'`,
numericArg,
expectedTypeForFlag(flag)
);
} else {
throw createUnsupportedError(
`Option ${numericArg} is unsupported by the mocha cli`
);
}
};

/**
* Wrapper around `yargs-parser` which applies our settings
* @param {string|string[]} args - Arguments to parse
Expand All @@ -120,25 +158,6 @@ const parse = (args = [], defaultValues = {}, ...configObjects) => {
// 4. we can then reapply the values after yargs-parser is done.
const allArgs = Array.isArray(args) ? args : args.split(' ');
const nodeArgs = allArgs.reduce((acc, arg, index, allArgs) => {
const maybeFlag = allArgs[index - 1];

if (isNumeric(arg) && (!maybeFlag || !isMochaFlag(maybeFlag))) {
throw createUnsupportedError(
`Option ${arg} is unsupported by the mocha cli`
);
}
if (
isNumeric(arg) &&
isMochaFlag(maybeFlag) &&
expectedTypeForFlag(maybeFlag) !== 'number'
) {
throw createInvalidArgumentTypeError(
`Mocha flag '${maybeFlag}' given invalid option: '${arg}'`,
Number(arg),
expectedTypeForFlag(maybeFlag)
);
}

const pair = arg.split('=');
let flag = pair[0];
if (isNodeFlag(flag, false)) {
Expand All @@ -165,6 +184,15 @@ const parse = (args = [], defaultValues = {}, ...configObjects) => {
process.exit(1);
}

const numericPositionalArg = result.argv._.find(arg => isNumeric(arg));
if (numericPositionalArg) {
createErrorForNumericPositionalArg(
allArgs,
numericPositionalArg,
result.argv
);
}

// reapply "=" arg values from above
nodeArgs.forEach(([key, value]) => {
result.argv[key] = value;
Expand Down
8 changes: 8 additions & 0 deletions test/node-unit/cli/options.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,14 @@ describe('options', function () {
'not to throw'
);
});

it('does not throw error if numeric value is passed to string flag', function () {
expect(() => loadOptions(`--grep ${numericArg}`), 'not to throw');
});

it('does not throw error if numeric value is passed to an array flag', function () {
expect(() => loadOptions(`--spec ${numericArg}`), 'not to throw');
});
});
});
});

0 comments on commit 912bdd1

Please sign in to comment.