Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

await for async jest config #8357

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,16 @@ Or through JavaScript:

```js
// jest.config.js
//Sync object
module.exports = {
verbose: true,
};
//Or async function
module.exports = async () => {
return {
verbose: true,
};
};
```

Please keep in mind that the resulting configuration must be JSON-serializable.
Expand Down
2 changes: 1 addition & 1 deletion packages/jest-config/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jest-config",
"version": "24.9.0",
"version": "25.0.0",
"repository": {
"type": "git",
"url": "https://github.com/facebook/jest.git",
Expand Down
19 changes: 9 additions & 10 deletions packages/jest-config/src/__tests__/readConfig.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@

import {readConfig} from '../index';

test('readConfig() throws when an object is passed without a file path', () => {
expect(() => {
readConfig(
// @ts-ignore
null /* argv */,
{} /* packageRootOrConfig */,
false /* skipArgvConfigOption */,
null /* parentConfigPath */,
);
}).toThrowError(
test('readConfig() throws when an object is passed without a file path', async () => {
// @ts-ignore
const asyncConfig = readConfig(
null /* argv */,
{} /* packageRootOrConfig */,
false /* skipArgvConfigOption */,
null /* parentConfigPath */,
);
await expect(asyncConfig).rejects.toThrowError(
'Jest: Cannot use configuration as an object without a file path',
);
});
11 changes: 6 additions & 5 deletions packages/jest-config/src/__tests__/readConfigs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@

import {readConfigs} from '../index';

test('readConfigs() throws when called without project paths', () => {
expect(() => {
// @ts-ignore
readConfigs(null /* argv */, [] /* projectPaths */);
}).toThrowError('jest: No configuration found for any project.');
test('readConfigs() throws when called without project paths', async () => {
// @ts-ignore
const asyncConfig = readConfigs(null /* argv */, [] /* projectPaths */);
await expect(asyncConfig).rejects.toThrowError(
'jest: No configuration found for any project.',
);
});
52 changes: 27 additions & 25 deletions packages/jest-config/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type ReadConfig = {
projectConfig: Config.ProjectConfig;
};

export function readConfig(
export async function readConfig(
argv: Config.Argv,
packageRootOrConfig: Config.Path | Config.InitialOptions,
// Whether it needs to look into `--config` arg passed to CLI.
Expand All @@ -37,7 +37,7 @@ export function readConfig(
skipArgvConfigOption?: boolean,
parentConfigPath?: Config.Path | null,
projectIndex: number = Infinity,
): ReadConfig {
): Promise<ReadConfig> {
let rawOptions;
let configPath = null;

Expand Down Expand Up @@ -72,11 +72,11 @@ export function readConfig(
// or a path to directory containing `package.json` or `jest.config.js`
} else if (!skipArgvConfigOption && typeof argv.config == 'string') {
configPath = resolveConfigPath(argv.config, process.cwd());
rawOptions = readConfigFileAndSetRootDir(configPath);
rawOptions = await readConfigFileAndSetRootDir(configPath);
} else {
// Otherwise just try to find config in the current rootDir.
configPath = resolveConfigPath(packageRootOrConfig, process.cwd());
rawOptions = readConfigFileAndSetRootDir(configPath);
rawOptions = await readConfigFileAndSetRootDir(configPath);
}

const {options, hasDeprecationWarnings} = normalize(
Expand Down Expand Up @@ -260,22 +260,22 @@ This usually means that your ${chalk.bold(
//
// If no projects are specified, process.cwd() will be used as the default
// (and only) project.
export function readConfigs(
export async function readConfigs(
argv: Config.Argv,
projectPaths: Array<Config.Path>,
): {
): Promise<{
globalConfig: Config.GlobalConfig;
configs: Array<Config.ProjectConfig>;
hasDeprecationWarnings: boolean;
} {
}> {
let globalConfig;
let hasDeprecationWarnings;
let configs: Array<Config.ProjectConfig> = [];
let projects = projectPaths;
let configPath: Config.Path | null | undefined;

if (projectPaths.length === 1) {
const parsedConfig = readConfig(argv, projects[0]);
const parsedConfig = await readConfig(argv, projects[0]);
configPath = parsedConfig.configPath;

if (parsedConfig.globalConfig.projects) {
Expand All @@ -298,24 +298,26 @@ export function readConfigs(
projects.length > 1 ||
(projects.length && typeof projects[0] === 'object')
) {
const parsedConfigs = projects
.filter(root => {
// Ignore globbed files that cannot be `require`d.
if (
typeof root === 'string' &&
fs.existsSync(root) &&
!fs.lstatSync(root).isDirectory() &&
!root.endsWith('.js') &&
!root.endsWith('.json')
) {
return false;
}
const parsedConfigs = await Promise.all(
projects
.filter(root => {
// Ignore globbed files that cannot be `require`d.
if (
typeof root === 'string' &&
fs.existsSync(root) &&
!fs.lstatSync(root).isDirectory() &&
!root.endsWith('.js') &&
!root.endsWith('.json')
) {
return false;
}

return true;
})
.map((root, projectIndex) =>
readConfig(argv, root, true, configPath, projectIndex),
);
return true;
})
.map(async (root, projectIndex) =>
readConfig(argv, root, true, configPath, projectIndex),
),
);

ensureNoDuplicateConfigs(parsedConfigs, projects);
configs = parsedConfigs.map(({projectConfig}) => projectConfig);
Expand Down
4 changes: 3 additions & 1 deletion packages/jest-config/src/readConfigFileAndSetRootDir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import {PACKAGE_JSON} from './constants';
// Read the configuration and set its `rootDir`
// 1. If it's a `package.json` file, we look into its "jest" property
// 2. For any other file, we just require it.
export default (configPath: Config.Path): Config.InitialOptions => {
export default async (
configPath: Config.Path,
): Promise<Config.InitialOptions> => {
const isJSON = configPath.endsWith('.json');
let configObject;

Expand Down
2 changes: 1 addition & 1 deletion packages/jest-core/src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export const runCLI = async (
const outputStream =
argv.json || argv.useStderr ? process.stderr : process.stdout;

const {globalConfig, configs, hasDeprecationWarnings} = readConfigs(
const {globalConfig, configs, hasDeprecationWarnings} = await readConfigs(
argv,
projects,
);
Expand Down
4 changes: 2 additions & 2 deletions packages/jest-runtime/src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {VERSION} from '../version';
import {Context} from '../types';
import * as args from './args';

export function run(cliArgv?: Config.Argv, cliInfo?: Array<string>) {
export async function run(cliArgv?: Config.Argv, cliInfo?: Array<string>) {
const realFs = require('fs');
const fs = require('graceful-fs');
fs.gracefulify(realFs);
Expand Down Expand Up @@ -65,7 +65,7 @@ export function run(cliArgv?: Config.Argv, cliInfo?: Array<string>) {
}
// TODO: Figure this out
// @ts-ignore: this might not have the correct arguments
const options = readConfig(argv, root);
const options = await readConfig(argv, root);
const globalConfig = options.globalConfig;
// Always disable automocking in scripts.
const config: Config.ProjectConfig = {
Expand Down
2 changes: 1 addition & 1 deletion packages/jest-runtime/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@ class Runtime {
filename,
localModule.require as LocalModuleRequire,
), // jest object
...this._config.extraGlobals.map(globalVariable => {
...(this._config.extraGlobals || []).map(globalVariable => {
if (this._environment.global[globalVariable]) {
return this._environment.global[globalVariable];
}
Expand Down