Skip to content

Commit

Permalink
Support dashed args (jestjs#7497)
Browse files Browse the repository at this point in the history
* added dashed arg support to fix jestjs#7424

* update docs & changelog

* fix dashed arg support tests

* move changelog item to correct location, small edit to docs

* use camelcase, filter dashed args on returns config
  • Loading branch information
hulkish authored and aleclarson committed Dec 25, 2018
1 parent fca9860 commit 6ce676a
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 5 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@
- `[jest-runtime]` Fix missing coverage when using negative glob pattern in `testMatch` ([#7170](https://github.com/facebook/jest/pull/7170))
- `[*]` Ensure `maxWorkers` is at least 1 (was 0 in some cases where there was only 1 CPU) ([#7182](https://github.com/facebook/jest/pull/7182))
- `[jest-runtime]` Fix transform cache invalidation when requiring a test file from multiple projects ([#7186](https://github.com/facebook/jest/pull/7186))
- `[jest-changed-files]` Return correctly the changed files when using `lastCommit=true` on Mercurial repositories ([#7228](https://github.com/facebook/jest/pull/7228))
- `[babel-jest]` Cache includes babel environment variables ([#7239](https://github.com/facebook/jest/pull/7239))
- `[jest-config]` Use strings instead of `RegExp` instances in normalized configuration ([#7251](https://github.com/facebook/jest/pull/7251))
- `[jest-circus]` Make sure to display real duration even if time is mocked ([#7264](https://github.com/facebook/jest/pull/7264))
- `[expect]` Improves the failing message for `toStrictEqual` matcher. ([#7224](https://github.com/facebook/jest/pull/7224))
- `[jest-resolve]` Fix not being able to resolve path to mapped file with custom platform ([#7312](https://github.com/facebook/jest/pull/7312))
- `[jest-message-util]` Improve parsing of error messages for unusually formatted stack traces ([#7319](https://github.com/facebook/jest/pull/7319))
- `[jest-runtime]` Ensure error message text is not lost on errors with code frames ([#7319](https://github.com/facebook/jest/pull/7319))
- `[jest-haste-map]` Fix to resolve path that is start with words same as rootDir ([#7324](https://github.com/facebook/jest/pull/7324))
- `[expect]` Fix toMatchObject matcher when used with `Object.create(null)` ([#7334](https://github.com/facebook/jest/pull/7334))
- `[jest-haste-map]` Remove legacy condition for duplicate module detection ([#7333](https://github.com/facebook/jest/pull/7333))
- `[jest-haste-map]` Fix `require` detection with trailing commas and ignore `import typeof` modules ([#7385](https://github.com/facebook/jest/pull/7385))
- `[jest-cli]` Fix to set prettierPath via config file ([#7412](https://github.com/facebook/jest/pull/7412))
- `[jest-cli]` Support dashed args ([#7497](https://github.com/facebook/jest/pull/7497))

### Chore & Maintenance

Expand Down
15 changes: 15 additions & 0 deletions docs/CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,21 @@ you can use:
npm test -- -u -t="ColorPicker"
```

## Camelcase & dashed args support

Jest supports both camelcase and dashed arg formats. The following examples will have equal result:

```bash
jest --collect-coverage
jest --collectCoverage
```

Arguments can also be mixed:

```bash
jest --update-snapshot --detectOpenHandles
```

## Options

_Note: CLI options take precedence over values from the [Configuration](Configuration.md)._
Expand Down
63 changes: 63 additions & 0 deletions e2e/__tests__/supports-dashed-args.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* Copyright (c) 2018-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

'use strict';

import path from 'path';
import runJest from '../runJest';

const consoleDir = path.resolve(__dirname, '../console');
const eachDir = path.resolve(__dirname, '../each');

expect.addSnapshotSerializer({
print: value => value,
test: received => typeof received === 'string',
});

test('works with passing tests', () => {
const result = runJest(eachDir, [
'success.test.js',
'--runInBand',
'--collect-coverage',
'--coverageReporters',
'text-summary',
'--clear-mocks',
'--useStderr',
]);
if (result.status !== 0) {
console.error(result.stderr);
}
expect(result.status).toBe(0);
});

test('throws error for unknown dashed & camelcase args', () => {
const result = runJest(consoleDir, [
'success.test.js',
'--runInBand',
'--collect-coverage',
'--coverageReporters',
'text-summary',
'--clear-mocks',
'--doesNotExist',
'--also-does-not-exist',
'--useStderr',
]);
expect(result.stderr).toMatchInlineSnapshot(`
● Unrecognized CLI Parameters:
Following options were not recognized:
["doesNotExist", "also-does-not-exist"]
CLI Options Documentation:
https://jestjs.io/docs/en/cli.html
`);
expect(result.status).toBe(1);
});
13 changes: 13 additions & 0 deletions packages/jest-cli/src/__tests__/cli/args.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import type {Argv} from 'types/Argv';
import {check} from '../../cli/args';
import {buildArgv} from '../../cli';

describe('check', () => {
it('returns true if the arguments are valid', () => {
Expand Down Expand Up @@ -59,3 +60,15 @@ describe('check', () => {
);
});
});

describe('buildArgv', () => {
it('should return only camelcased args ', () => {
const mockProcessArgv = jest
.spyOn(process.argv, 'slice')
.mockImplementation(() => ['--clear-mocks']);
const actual = buildArgv(null);
expect(actual).not.toHaveProperty('clear-mocks');
expect(actual).toHaveProperty('clearMocks', true);
mockProcessArgv.mockRestore();
});
});
19 changes: 16 additions & 3 deletions packages/jest-cli/src/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import logDebugMessages from '../lib/log_debug_messages';

export async function run(maybeArgv?: Argv, project?: Path) {
try {
// $FlowFixMe:`allow reduced return
const argv: Argv = buildArgv(maybeArgv, project);

if (argv.init) {
Expand Down Expand Up @@ -169,8 +170,9 @@ const readResultsAndExit = (
}
};

const buildArgv = (maybeArgv: ?Argv, project: ?Path) => {
const argv: Argv = yargs(maybeArgv || process.argv.slice(2))
export const buildArgv = (maybeArgv: ?Argv, project: ?Path) => {
const rawArgv: Argv | string[] = maybeArgv || process.argv.slice(2);
const argv: Argv = yargs(rawArgv)
.usage(args.usage)
.alias('help', 'h')
.options(args.options)
Expand All @@ -180,9 +182,20 @@ const buildArgv = (maybeArgv: ?Argv, project: ?Path) => {
validateCLIOptions(
argv,
Object.assign({}, args.options, {deprecationEntries}),
// strip leading dashes
Array.isArray(rawArgv)
? rawArgv.map(rawArgv => rawArgv.replace(/^--?/, ''))
: Object.keys(rawArgv),
);

return argv;
// strip dashed args
return Object.keys(argv).reduce((result, key) => {
if (!key.includes('-')) {
// $FlowFixMe:`allow reduced return
result[key] = argv[key];
}
return result;
}, {});
};

const getProjectListFromCLIArgs = (argv, project: ?Path) => {
Expand Down
1 change: 1 addition & 0 deletions packages/jest-validate/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"license": "MIT",
"main": "build/index.js",
"dependencies": {
"camelcase": "^5.0.0",
"chalk": "^2.0.1",
"jest-get-type": "^22.1.0",
"leven": "^2.1.0",
Expand Down
12 changes: 10 additions & 2 deletions packages/jest-validate/src/validate_cli_options.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import type {Argv} from 'types/Argv';

import chalk from 'chalk';
import camelcase from 'camelcase';
import {createDidYouMeanMessage, format, ValidationError} from './utils';
import {deprecationWarning} from './deprecated';
import defaultConfig from './default_config';
Expand Down Expand Up @@ -65,15 +66,22 @@ const logDeprecatedOptions = (
});
};

export default function validateCLIOptions(argv: Argv, options: Object) {
export default function validateCLIOptions(
argv: Argv,
options: Object,
rawArgv: string[] = [],
) {
const yargsSpecialOptions = ['$0', '_', 'help', 'h'];
const deprecationEntries = options.deprecationEntries || {};
const allowedOptions = Object.keys(options).reduce(
(acc, option) => acc.add(option).add(options[option].alias || option),
new Set(yargsSpecialOptions),
);
const unrecognizedOptions = Object.keys(argv).filter(
arg => !allowedOptions.has(arg),
arg =>
!allowedOptions.has(camelcase(arg)) &&
(!rawArgv.length || rawArgv.includes(arg)),
[],
);

if (unrecognizedOptions.length) {
Expand Down

0 comments on commit 6ce676a

Please sign in to comment.