Skip to content

Commit 446d174

Browse files
the-spykeSimenB
authored andcommitted
Support '.js', '.cjs', '.json' configs (#9291)
1 parent b2c8a69 commit 446d174

File tree

21 files changed

+240
-106
lines changed

21 files changed

+240
-106
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- `[jest-config]` Throw the full error message and stack when a Jest preset is missing a dependency ([#8924](https://github.com/facebook/jest/pull/8924))
1212
- `[jest-config]` [**BREAKING**] Set default display name color based on runner ([#8689](https://github.com/facebook/jest/pull/8689))
1313
- `[jest-config]` Merge preset globals with project globals ([#9027](https://github.com/facebook/jest/pull/9027))
14+
- `[jest-config]` Support `.cjs` config files ([#9291](https://github.com/facebook/jest/pull/9291))
1415
- `[jest-core]` Support reporters as default exports ([#9161](https://github.com/facebook/jest/pull/9161))
1516
- `[jest-diff]` Add options for colors and symbols ([#8841](https://github.com/facebook/jest/pull/8841))
1617
- `[jest-diff]` [**BREAKING**] Export as ECMAScript module ([#8873](https://github.com/facebook/jest/pull/8873))

docs/Configuration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ id: configuration
33
title: Configuring Jest
44
---
55

6-
Jest's configuration can be defined in the `package.json` file of your project, or through a `jest.config.js` file or through the `--config <path/to/js|json>` option. If you'd like to use your `package.json` to store Jest's config, the "jest" key should be used on the top level so Jest will know how to find your settings:
6+
Jest's configuration can be defined in the `package.json` file of your project, or through a `jest.config.js` file or through the `--config <path/to/file.js|cjs|json>` option. If you'd like to use your `package.json` to store Jest's config, the "jest" key should be used on the top level so Jest will know how to find your settings:
77

88
```json
99
{

e2e/__tests__/cjsConfigFile.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
import {json as runWithJson} from '../runJest';
9+
10+
test('reads config from cjs file', () => {
11+
const {json, exitCode} = runWithJson('cjs-config', ['--show-config'], {
12+
skipPkgJsonCheck: true,
13+
});
14+
15+
expect(exitCode).toBe(0);
16+
expect(json.configs).toHaveLength(1);
17+
expect(json.configs[0].displayName).toEqual({
18+
color: 'white',
19+
name: 'Config from cjs file',
20+
});
21+
});

e2e/cjs-config/__tests__/test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
test('dummy test', () => {
9+
expect(1).toBe(1);
10+
});

e2e/cjs-config/jest.config.cjs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
module.exports = {
9+
displayName: 'Config from cjs file',
10+
testEnvironment: 'node',
11+
};

e2e/cjs-config/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"jest": {}
3+
}

packages/jest-cli/src/init/__tests__/__snapshots__/init.test.js.snap

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,25 @@ Object {
99
}
1010
`;
1111

12-
exports[`init has-jest-config-file ask the user whether to override config or not user answered with "Yes" 1`] = `
12+
exports[`init has-jest-config-file-cjs ask the user whether to override config or not user answered with "Yes" 1`] = `
13+
Object {
14+
"initial": true,
15+
"message": "It seems that you already have a jest configuration, do you want to override it?",
16+
"name": "continue",
17+
"type": "confirm",
18+
}
19+
`;
20+
21+
exports[`init has-jest-config-file-js ask the user whether to override config or not user answered with "Yes" 1`] = `
22+
Object {
23+
"initial": true,
24+
"message": "It seems that you already have a jest configuration, do you want to override it?",
25+
"name": "continue",
26+
"type": "confirm",
27+
}
28+
`;
29+
30+
exports[`init has-jest-config-file-json ask the user whether to override config or not user answered with "Yes" 1`] = `
1331
Object {
1432
"initial": true,
1533
"message": "It seems that you already have a jest configuration, do you want to override it?",
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
module.exports = {};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

packages/jest-cli/src/init/__tests__/init.test.js

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import * as fs from 'fs';
1010
import * as path from 'path';
1111
import prompts from 'prompts';
1212
import init from '../';
13+
import {JEST_CONFIG_EXT_ORDER} from '../constants';
1314

1415
jest.mock('prompts');
1516
jest.mock('../../../../jest-config/build/getCacheDirectory', () => () =>
@@ -125,29 +126,32 @@ describe('init', () => {
125126
});
126127
});
127128

128-
describe('has-jest-config-file', () => {
129-
describe('ask the user whether to override config or not', () => {
130-
it('user answered with "Yes"', async () => {
131-
prompts.mockReturnValueOnce({continue: true}).mockReturnValueOnce({});
129+
describe.each(JEST_CONFIG_EXT_ORDER.map(e => e.substring(1)))(
130+
'has-jest-config-file-%s',
131+
extension => {
132+
describe('ask the user whether to override config or not', () => {
133+
it('user answered with "Yes"', async () => {
134+
prompts.mockReturnValueOnce({continue: true}).mockReturnValueOnce({});
132135

133-
await init(resolveFromFixture('has_jest_config_file'));
136+
await init(resolveFromFixture(`has_jest_config_file_${extension}`));
134137

135-
expect(prompts.mock.calls[0][0]).toMatchSnapshot();
138+
expect(prompts.mock.calls[0][0]).toMatchSnapshot();
136139

137-
const writtenJestConfig = fs.writeFileSync.mock.calls[0][1];
140+
const writtenJestConfig = fs.writeFileSync.mock.calls[0][1];
138141

139-
expect(writtenJestConfig).toBeDefined();
140-
});
142+
expect(writtenJestConfig).toBeDefined();
143+
});
141144

142-
it('user answered with "No"', async () => {
143-
prompts.mockReturnValueOnce({continue: false});
145+
it('user answered with "No"', async () => {
146+
prompts.mockReturnValueOnce({continue: false});
144147

145-
await init(resolveFromFixture('has_jest_config_file'));
146-
// return after first prompt
147-
expect(prompts).toHaveBeenCalledTimes(1);
148+
await init(resolveFromFixture(`has_jest_config_file_${extension}`));
149+
// return after first prompt
150+
expect(prompts).toHaveBeenCalledTimes(1);
151+
});
148152
});
149-
});
150-
});
153+
},
154+
);
151155

152156
describe('has jest config in package.json', () => {
153157
it('should ask the user whether to override config or not', async () => {

packages/jest-cli/src/init/constants.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,12 @@
66
*/
77

88
export const PACKAGE_JSON = 'package.json';
9-
export const JEST_CONFIG = 'jest.config.js';
9+
export const JEST_CONFIG_BASE_NAME = 'jest.config';
10+
export const JEST_CONFIG_EXT_CJS = '.cjs';
11+
export const JEST_CONFIG_EXT_JS = '.js';
12+
export const JEST_CONFIG_EXT_JSON = '.json';
13+
export const JEST_CONFIG_EXT_ORDER = Object.freeze([
14+
JEST_CONFIG_EXT_JS,
15+
JEST_CONFIG_EXT_CJS,
16+
JEST_CONFIG_EXT_JSON,
17+
]);

packages/jest-cli/src/init/index.ts

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ import prompts = require('prompts');
1212
import {sync as realpath} from 'realpath-native';
1313
import defaultQuestions, {testScriptQuestion} from './questions';
1414
import {MalformedPackageJsonError, NotFoundPackageJsonError} from './errors';
15-
import {JEST_CONFIG, PACKAGE_JSON} from './constants';
15+
import {
16+
JEST_CONFIG_BASE_NAME,
17+
JEST_CONFIG_EXT_CJS,
18+
JEST_CONFIG_EXT_JS,
19+
JEST_CONFIG_EXT_ORDER,
20+
PACKAGE_JSON,
21+
} from './constants';
1622
import generateConfigFile from './generate_config_file';
1723
import modifyPackageJson from './modify_package_json';
1824
import {ProjectPackageJson} from './types';
@@ -24,18 +30,18 @@ type PromptsResults = {
2430
scripts: boolean;
2531
};
2632

33+
const getConfigFilename = (ext: string) => JEST_CONFIG_BASE_NAME + ext;
34+
2735
export default async (rootDir: string = realpath(process.cwd())) => {
2836
// prerequisite checks
2937
const projectPackageJsonPath: string = path.join(rootDir, PACKAGE_JSON);
30-
const jestConfigPath: string = path.join(rootDir, JEST_CONFIG);
3138

3239
if (!fs.existsSync(projectPackageJsonPath)) {
3340
throw new NotFoundPackageJsonError(rootDir);
3441
}
3542

3643
const questions = defaultQuestions.slice(0);
3744
let hasJestProperty: boolean = false;
38-
let hasJestConfig: boolean = false;
3945
let projectPackageJson: ProjectPackageJson;
4046

4147
try {
@@ -50,11 +56,21 @@ export default async (rootDir: string = realpath(process.cwd())) => {
5056
hasJestProperty = true;
5157
}
5258

53-
if (fs.existsSync(jestConfigPath)) {
54-
hasJestConfig = true;
55-
}
59+
const existingJestConfigPath = JEST_CONFIG_EXT_ORDER.find(ext =>
60+
fs.existsSync(path.join(rootDir, getConfigFilename(ext))),
61+
);
62+
const jestConfigPath =
63+
existingJestConfigPath ||
64+
path.join(
65+
rootDir,
66+
getConfigFilename(
67+
projectPackageJson.type === 'module'
68+
? JEST_CONFIG_EXT_CJS
69+
: JEST_CONFIG_EXT_JS,
70+
),
71+
);
5672

57-
if (hasJestProperty || hasJestConfig) {
73+
if (hasJestProperty || existingJestConfigPath) {
5874
const result: {continue: boolean} = await prompts({
5975
initial: true,
6076
message:

packages/jest-cli/src/init/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ import {Config} from '@jest/types';
1010
export type ProjectPackageJson = {
1111
jest?: Partial<Config.InitialOptions>;
1212
scripts?: Record<string, string>;
13+
type?: 'commonjs' | 'module';
1314
};

0 commit comments

Comments
 (0)