Skip to content

Commit

Permalink
Implement review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
nicojs committed Apr 10, 2023
1 parent 908c73d commit e2c65f8
Show file tree
Hide file tree
Showing 4 changed files with 247 additions and 219 deletions.
23 changes: 16 additions & 7 deletions packages/jest-core/src/__tests__/runCore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
* LICENSE file in the root directory of this source tree.
*/

import {tmpdir} from 'os';
import {resolve} from 'path';
import {makeGlobalConfig, makeProjectConfig} from '@jest/test-utils';
import {runCore} from '../';
import * as jestUtil from 'jest-util';
import {runCore} from '../runCore';
import runJest from '../runJest';

jest.mock('jest-runtime', () => ({
Expand All @@ -22,15 +21,25 @@ jest.mock('../runJest', () =>
onComplete({results: {success: true}});
}),
);
jest.mock('jest-util', () => {
const original = jest.requireActual<typeof jestUtil>('jest-util');

return {
...original,
createDirectory: jest.fn(),
};
});

describe(runCore, () => {
beforeEach(() => {
jest.spyOn(jestUtil, 'createDirectory').mockReturnValue();
});

it('should run once and provide the result', async () => {
const actualResult = await runCore(makeGlobalConfig(), [
makeProjectConfig({
cacheDirectory: resolve(tmpdir(), 'jest_runCore_test'),
}),
makeProjectConfig(),
]);
expect(jest.mocked(runJest)).toHaveBeenCalled();
expect(actualResult).toEqual({results: {success: true}});
expect(actualResult).toEqual({result: {results: {success: true}}});
});
});
214 changes: 3 additions & 211 deletions packages/jest-core/src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,16 @@ import {performance} from 'perf_hooks';
import chalk = require('chalk');
import exit = require('exit');
import * as fs from 'graceful-fs';
import {CustomConsole} from '@jest/console';
import type {AggregatedResult, TestContext} from '@jest/test-result';
import type {AggregatedResult} from '@jest/test-result';
import type {Config} from '@jest/types';
import type {ChangedFilesPromise} from 'jest-changed-files';
import {readConfigs} from 'jest-config';
import type {IHasteMap} from 'jest-haste-map';
import Runtime from 'jest-runtime';
import {createDirectory, preRunMessage} from 'jest-util';
import {TestWatcher} from 'jest-watcher';
import {formatHandleErrors} from '../collectHandles';
import getChangedFilesPromise from '../getChangedFilesPromise';
import getConfigsOfProjectsToRun from '../getConfigsOfProjectsToRun';
import getProjectNamesMissingWarning from '../getProjectNamesMissingWarning';
import getSelectProjectsMessage from '../getSelectProjectsMessage';
import createContext from '../lib/createContext';
import handleDeprecationWarnings from '../lib/handleDeprecationWarnings';
import logDebugMessages from '../lib/logDebugMessages';
import pluralize from '../pluralize';
import runJest from '../runJest';
import type {Filter} from '../types';
import watch from '../watch';

const {print: preRunMessagePrint} = preRunMessage;

type OnCompleteCallback = (results: AggregatedResult) => void | undefined;
import {_run} from '../runCore';

export async function runCLI(
argv: Config.Argv,
Expand Down Expand Up @@ -95,7 +80,7 @@ export async function runCLI(
);
}

const results = await runCore(
const results = await _run(
globalConfig,
configsOfProjectsToRun,
hasDeprecationWarnings,
Expand Down Expand Up @@ -126,196 +111,3 @@ export async function runCLI(
performance.mark('jest/runCLI:end');
return {globalConfig, results};
}

const buildContextsAndHasteMaps = async (
configs: Array<Config.ProjectConfig>,
globalConfig: Config.GlobalConfig,
outputStream: NodeJS.WriteStream,
) => {
const hasteMapInstances = Array(configs.length);
const contexts = await Promise.all(
configs.map(async (config, index) => {
createDirectory(config.cacheDirectory);
const hasteMapInstance = await Runtime.createHasteMap(config, {
console: new CustomConsole(outputStream, outputStream),
maxWorkers: Math.max(
1,
Math.floor(globalConfig.maxWorkers / configs.length),
),
resetCache: !config.cache,
watch: globalConfig.watch || globalConfig.watchAll,
watchman: globalConfig.watchman,
workerThreads: globalConfig.workerThreads,
});
hasteMapInstances[index] = hasteMapInstance;
return createContext(config, await hasteMapInstance.build());
}),
);

return {contexts, hasteMapInstances};
};

/**
* Runs Jest either in watch mode or as a one-off. This is a lower-level API than `runCLI` and is intended for internal use by `runCLI` or externally.
* Note that `process.exit` might be called when using `globalConfig.watch` or `globalConfig.watchAll` is true.
*
* @param globalConfig The global configuration to use for this run. It can be obtained using `readConfigs` (imported from 'jest-config').
* @param configs The project configurations to run. It can be obtained using `readConfigs` (imported from 'jest-config').
* @param warnForDeprecations Whether or not to warn for deprecation messages when `globalConfig.watch` or `globalConfig.watchAll` is true.
* @param outputStream The stream to write output to. If not provided, it defaults to `process.stdout`.
* @returns A Promise that resolves to the result, or never resolves when `globalConfig.watch` or `globalConfig.watchAll` is true.
* @example
* import { runCore, readConfigs } from 'jest';
*
* const { globalConfig, configs } = await readConfigs(process.argv, [process.cwd()]);
* const results = await runCore(globalConfig, configs);
* console.log(results);
*/
export const runCore = async (
globalConfig: Config.GlobalConfig,
configs: Array<Config.ProjectConfig>,
warnForDeprecations = false,
outputStream: NodeJS.WriteStream = process.stdout,
): Promise<AggregatedResult> => {
// Queries to hg/git can take a while, so we need to start the process
// as soon as possible, so by the time we need the result it's already there.
const changedFilesPromise = getChangedFilesPromise(globalConfig, configs);
if (changedFilesPromise) {
performance.mark('jest/getChangedFiles:start');
changedFilesPromise.finally(() => {
performance.mark('jest/getChangedFiles:end');
});
}

// Filter may need to do an HTTP call or something similar to setup.
// We will wait on an async response from this before using the filter.
let filter: Filter | undefined;
if (globalConfig.filter && !globalConfig.skipFilter) {
const rawFilter = require(globalConfig.filter);
let filterSetupPromise: Promise<unknown | undefined> | undefined;
if (rawFilter.setup) {
// Wrap filter setup Promise to avoid "uncaught Promise" error.
// If an error is returned, we surface it in the return value.
filterSetupPromise = (async () => {
try {
await rawFilter.setup();
} catch (err) {
return err;
}
return undefined;
})();
}
filter = async (testPaths: Array<string>) => {
if (filterSetupPromise) {
// Expect an undefined return value unless there was an error.
const err = await filterSetupPromise;
if (err) {
throw err;
}
}
return rawFilter(testPaths);
};
}

performance.mark('jest/buildContextsAndHasteMaps:start');
const {contexts, hasteMapInstances} = await buildContextsAndHasteMaps(
configs,
globalConfig,
outputStream,
);
performance.mark('jest/buildContextsAndHasteMaps:end');

if (globalConfig.watch || globalConfig.watchAll) {
await runWatch(
contexts,
configs,
warnForDeprecations,
globalConfig,
outputStream,
hasteMapInstances,
filter,
);
// If in watch mode, return the promise that will never resolve.
// If the watch mode is interrupted, watch should handle the process
// shutdown.
// eslint-disable-next-line @typescript-eslint/no-empty-function
return new Promise(() => {});
} else {
let result: AggregatedResult;
await runWithoutWatch(
globalConfig,
contexts,
outputStream,
r => {
result = r;
},
changedFilesPromise,
filter,
);
return result!;
}
};

const runWatch = async (
contexts: Array<TestContext>,
_configs: Array<Config.ProjectConfig>,
warnForDeprecations: boolean,
globalConfig: Config.GlobalConfig,
outputStream: NodeJS.WriteStream,
hasteMapInstances: Array<IHasteMap>,
filter?: Filter,
) => {
if (warnForDeprecations) {
try {
await handleDeprecationWarnings(outputStream, process.stdin);
return await watch(
globalConfig,
contexts,
outputStream,
hasteMapInstances,
undefined,
undefined,
filter,
);
} catch {
exit(0);
}
}

return watch(
globalConfig,
contexts,
outputStream,
hasteMapInstances,
undefined,
undefined,
filter,
);
};

const runWithoutWatch = async (
globalConfig: Config.GlobalConfig,
contexts: Array<TestContext>,
outputStream: NodeJS.WriteStream,
onComplete: OnCompleteCallback,
changedFilesPromise?: ChangedFilesPromise,
filter?: Filter,
) => {
const startRun = async (): Promise<void | null> => {
if (!globalConfig.listTests) {
preRunMessagePrint(outputStream);
}
return runJest({
changedFilesPromise,
contexts,
failedTestsCache: undefined,
filter,
globalConfig,
onComplete,
outputStream,
startRun,
testWatcher: new TestWatcher({isWatchMode: false}),
});
};
return startRun();
};
3 changes: 2 additions & 1 deletion packages/jest-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

export {default as SearchSource} from './SearchSource';
export {createTestScheduler} from './TestScheduler';
export {runCLI, runCore} from './cli';
export {runCLI} from './cli';
export {runCore} from './runCore';
export {default as getVersion} from './version';
export {readConfigs, readInitialOptions} from 'jest-config';
Loading

0 comments on commit e2c65f8

Please sign in to comment.