}).then((reports: any[]) => { // console.log(util.inspect(reports, false, 10)); reports.forEach((report) => { console.log(''); console.log(report.group.name); console.log(' passed %d of %d', report.results.length - report.failed, report.results.length); console.log(''); if (report.failed > 0) { report.results.filter(res => !res.result.pass).forEach((res) => { console.log(res.test.group + '/' + res.test.name); console.log('---'); if (res.result.header) { console.log(formatter.getStyledDiff(res.result.header, res.fields.parsed)); console.log('---'); } if (res.result.error) { console.log(res.result.error); console.log('---'); } console.log(''); }); } }); if (!reports.every(report => report.failed === 0)) { exit(1); } console.log('done!'); exit(0); }).catch((e) => {
export async function run(maybeArgv?: Array<string>, project?: Config.Path) { try { const argv: Config.Argv = buildArgv(maybeArgv); if (argv.init) { await init(); return; } const projects = getProjectListFromCLIArgs(argv, project); const {results, globalConfig} = await runCLI(argv, projects); readResultsAndExit(results, globalConfig); } catch (error) { clearLine(process.stderr); clearLine(process.stdout); if (error.stack) { console.error(chalk.red(error.stack)); } else { console.error(chalk.red(error)); } exit(1); throw error; } }
map: async ({ sample, fixtureName }: WorkItem, index) => { let fixture = _.find(fixtures, { name: fixtureName }) as Fixture; try { await fixture.runWithSample(sample, index, tests.length); } catch (e) { console.trace(e); exit(1); } }
const onError = async (err: SerializableError, test: JestTest) => { await onFailure(test, err); if (err.type === 'ProcessTerminatedError') { console.error( 'A worker process has quit unexpectedly! ' + 'Most likely this is an initialization error.', ); exit(1); } };
cluster.on("exit", (_worker, code, _signal) => { if (code && code !== 0) { // Kill workers and exit if any worker dies _.forIn(cluster.workers, w => { if (w) { w.kill(); } }); exit(code); } });
(err, _, metadata) => { if (err || !metadata) { return; } if (metadata.activationValue === quitAnswer) { exit(0); return; } if (metadata.activationValue === restartAnswer) { this._startRun(this._globalConfig); } },
const runWatch = async ( contexts: Array<Context>, _configs: Array<Config.ProjectConfig>, hasDeprecationWarnings: boolean, globalConfig: Config.GlobalConfig, outputStream: NodeJS.WriteStream, hasteMapInstances: Array<HasteMap>, ) => { if (hasDeprecationWarnings) { try { await handleDeprecationWarnings(outputStream, process.stdin); return watch(globalConfig, contexts, outputStream, hasteMapInstances); } catch (e) { exit(0); } } return watch(globalConfig, contexts, outputStream, hasteMapInstances); };
const readResultsAndExit = ( result: AggregatedResult | null, globalConfig: Config.GlobalConfig, ) => { const code = !result || result.success ? 0 : globalConfig.testFailureExitCode; // Only exit if needed process.on('exit', () => { if (typeof code === 'number' && code !== 0) { process.exitCode = code; } }); if (globalConfig.forceExit) { if (!globalConfig.detectOpenHandles) { console.error( chalk.red.bold('Force exiting Jest\n\n') + chalk.red( 'Have you considered using `--detectOpenHandles` to detect ' + 'async operations that kept running after all tests finished?', ), ); } exit(code); } else if (!globalConfig.detectOpenHandles) { setTimeout(() => { console.error( chalk.red.bold( 'Jest did not exit one second after the test run has completed.\n\n', ) + chalk.red( 'This usually means that there are asynchronous operations that ' + "weren't stopped in your tests. Consider running Jest with " + '`--detectOpenHandles` to troubleshoot this issue.', ), ); }, 1000).unref(); } };
const onKeypress = (key: string) => { if (key === KEYS.CONTROL_C || key === KEYS.CONTROL_D) { if (typeof stdin.setRawMode === 'function') { stdin.setRawMode(false); } outputStream.write('\n'); exit(0); return; } if (activePlugin != null && activePlugin.onKey) { // if a plugin is activate, Jest should let it handle keystrokes, so ignore // them here activePlugin.onKey(key); return; } // Abort test run const pluginKeys = getSortedUsageRows(watchPlugins, globalConfig).map( usage => Number(usage.key).toString(16), ); if ( isRunning && testWatcher && ['q', KEYS.ENTER, 'a', 'o', 'f'].concat(pluginKeys).includes(key) ) { testWatcher.setState({interrupted: true}); return; } const matchingWatchPlugin = filterInteractivePlugins( watchPlugins, globalConfig, ).find(plugin => getPluginKey(plugin, globalConfig) === key); if (matchingWatchPlugin != null) { if (isRunning) { testWatcher.setState({interrupted: true}); return; } // "activate" the plugin, which has jest ignore keystrokes so the plugin // can handle them activePlugin = matchingWatchPlugin; if (activePlugin.run) { activePlugin.run(globalConfig, updateConfigAndRun).then( shouldRerun => { activePlugin = null; if (shouldRerun) { updateConfigAndRun(); } }, () => { activePlugin = null; onCancelPatternPrompt(); }, ); } else { activePlugin = null; } } switch (key) { case KEYS.ENTER: startRun(globalConfig); break; case 'a': globalConfig = updateGlobalConfig(globalConfig, { mode: 'watchAll', testNamePattern: '', testPathPattern: '', }); startRun(globalConfig); break; case 'c': updateConfigAndRun({ mode: 'watch', testNamePattern: '', testPathPattern: '', }); break; case 'f': globalConfig = updateGlobalConfig(globalConfig, { onlyFailures: !globalConfig.onlyFailures, }); startRun(globalConfig); break; case 'o': globalConfig = updateGlobalConfig(globalConfig, { mode: 'watch', testNamePattern: '', testPathPattern: '', }); startRun(globalConfig); break; case '?': break; case 'w': if (!shouldDisplayWatchUsage && !isWatchUsageDisplayed) { outputStream.write(ansiEscapes.cursorUp()); outputStream.write(ansiEscapes.eraseDown); outputStream.write(usage(globalConfig, watchPlugins)); isWatchUsageDisplayed = true; shouldDisplayWatchUsage = false; } break; } };
export default (async function runJest({ contexts, globalConfig, outputStream, testWatcher, jestHooks = new JestHook().getEmitter(), startRun, changedFilesPromise, onComplete, failedTestsCache, }: { globalConfig: Config.GlobalConfig; contexts: Array<Context>; outputStream: NodeJS.WritableStream; testWatcher: TestWatcher; jestHooks?: JestHookEmitter; startRun: (globalConfig: Config.GlobalConfig) => void; changedFilesPromise?: ChangedFilesPromise; onComplete: (testResults: AggregatedResult) => void; failedTestsCache?: FailedTestsCache; }) { const sequencer = new TestSequencer(); let allTests: Array<Test> = []; if (changedFilesPromise && globalConfig.watch) { const {repos} = await changedFilesPromise; const noSCM = (Object.keys(repos) as Array< keyof ChangedFiles['repos'] >).every(scm => repos[scm].size === 0); if (noSCM) { process.stderr.write( '\n' + chalk.bold('--watch') + ' is not supported without git/hg, please use --watchAll ' + '\n', ); exit(1); } } const testRunData: TestRunData = await Promise.all( contexts.map(async context => { const matches = await getTestPaths( globalConfig, context, outputStream, changedFilesPromise && (await changedFilesPromise), jestHooks, ); allTests = allTests.concat(matches.tests); return {context, matches}; }), ); allTests = sequencer.sort(allTests); if (globalConfig.listTests) { const testsPaths = Array.from(new Set(allTests.map(test => test.path))); if (globalConfig.json) { console.log(JSON.stringify(testsPaths)); } else { console.log(testsPaths.join('\n')); } onComplete && onComplete(makeEmptyAggregatedTestResult()); return null; } if (globalConfig.onlyFailures && failedTestsCache) { allTests = failedTestsCache.filterTests(allTests); globalConfig = failedTestsCache.updateConfig(globalConfig); } const hasTests = allTests.length > 0; if (!hasTests) { const noTestsFoundMessage = getNoTestsFoundMessage( testRunData, globalConfig, ); if ( globalConfig.passWithNoTests || globalConfig.findRelatedTests || globalConfig.lastCommit || globalConfig.onlyChanged ) { new CustomConsole(outputStream, outputStream).log(noTestsFoundMessage); } else { new CustomConsole(outputStream, outputStream).error(noTestsFoundMessage); exit(1); } } else if ( allTests.length === 1 && globalConfig.silent !== true && globalConfig.verbose !== false ) { const newConfig: Config.GlobalConfig = {...globalConfig, verbose: true}; globalConfig = Object.freeze(newConfig); } let collectHandles; if (globalConfig.detectOpenHandles) { collectHandles = collectNodeHandles(); } if (hasTests) { await runGlobalHook({allTests, globalConfig, moduleName: 'globalSetup'}); } if (changedFilesPromise) { testSchedulerContext.changedFiles = (await changedFilesPromise).changedFiles; } const results = await new TestScheduler( globalConfig, {startRun}, testSchedulerContext, ).scheduleTests(allTests, testWatcher); sequencer.cacheResults(allTests, results); if (hasTests) { await runGlobalHook({allTests, globalConfig, moduleName: 'globalTeardown'}); } return processResults(results, { collectHandles, json: globalConfig.json, onComplete, outputFile: globalConfig.outputFile, outputStream, testResultsProcessor: globalConfig.testResultsProcessor, }); });