From 1db25d486c2a1121bc2c8c739038c3007371107e Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Wed, 20 Feb 2019 12:16:38 +0800 Subject: [PATCH 01/26] Add a tsconfig --- packages/jest-runner/tsconfig.json | 39 ++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 packages/jest-runner/tsconfig.json diff --git a/packages/jest-runner/tsconfig.json b/packages/jest-runner/tsconfig.json new file mode 100644 index 000000000000..c4c84985f77b --- /dev/null +++ b/packages/jest-runner/tsconfig.json @@ -0,0 +1,39 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "build" + }, + "references": [ + { + "path": "../jest-config" + }, + { + "path": "../jest-docblock" + }, + { + "path": "../jest-haste-map" + }, + { + "path": "../jest-jasmine2" + }, + { + "path": "../jest-leak-detector" + }, + { + "path": "../jest-message-util" + }, + { + "path": "../jest-runtime" + }, + { + "path": "../jest-util" + }, + { + "path": "../jest-worker" + }, + { + "path": "../jest-types" + }, + ] +} From 7f32f83537028386c5dcfa082aac03b24f83e2a7 Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Wed, 20 Feb 2019 12:16:47 +0800 Subject: [PATCH 02/26] Rename files to .ts --- packages/jest-runner/src/{index.js => index.ts} | 0 packages/jest-runner/src/{runTest.js => runTest.ts} | 0 packages/jest-runner/src/{testWorker.js => testWorker.ts} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename packages/jest-runner/src/{index.js => index.ts} (100%) rename packages/jest-runner/src/{runTest.js => runTest.ts} (100%) rename packages/jest-runner/src/{testWorker.js => testWorker.ts} (100%) diff --git a/packages/jest-runner/src/index.js b/packages/jest-runner/src/index.ts similarity index 100% rename from packages/jest-runner/src/index.js rename to packages/jest-runner/src/index.ts diff --git a/packages/jest-runner/src/runTest.js b/packages/jest-runner/src/runTest.ts similarity index 100% rename from packages/jest-runner/src/runTest.js rename to packages/jest-runner/src/runTest.ts diff --git a/packages/jest-runner/src/testWorker.js b/packages/jest-runner/src/testWorker.ts similarity index 100% rename from packages/jest-runner/src/testWorker.js rename to packages/jest-runner/src/testWorker.ts From 59800123376ad79a90a32d3c8df87391f5394a6d Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Wed, 20 Feb 2019 12:35:33 +0800 Subject: [PATCH 03/26] Add a types key and import @jest/types in jest-runner --- packages/jest-runner/package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/jest-runner/package.json b/packages/jest-runner/package.json index 98ecf80ca1e7..b645b365494a 100644 --- a/packages/jest-runner/package.json +++ b/packages/jest-runner/package.json @@ -8,7 +8,9 @@ }, "license": "MIT", "main": "build/index.js", + "types": "build/index.d.ts", "dependencies": { + "@jest/types": "^24.1.0", "chalk": "^2.4.2", "exit": "^0.1.2", "graceful-fs": "^4.1.15", From 5eaaf5325093c6bbaf891120a6d5ce2efaa247be Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Sat, 23 Feb 2019 20:00:42 +0800 Subject: [PATCH 04/26] Migrate basic types in test-worker --- packages/jest-runner/src/testWorker.ts | 33 +++++++++++++------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/packages/jest-runner/src/testWorker.ts b/packages/jest-runner/src/testWorker.ts index 1651803861e6..1d9ae2ce9898 100644 --- a/packages/jest-runner/src/testWorker.ts +++ b/packages/jest-runner/src/testWorker.ts @@ -7,25 +7,26 @@ * @flow */ -import type {GlobalConfig, Path, ProjectConfig} from 'types/Config'; -import type {SerializableError, TestResult} from 'types/TestResult'; -import type {SerializableModuleMap} from 'types/HasteMap'; -import type {ErrorWithCode} from 'types/Errors'; -import type {TestRunnerContext} from 'types/TestRunner'; +import { Config, TestResult } from '@jest/types'; +import { ErrorWithCode } from './types'; +import { SerializableModuleMap, ModuleMap } from 'jest-haste-map'; +import { TestRunnerContext } from 'types/TestRunner'; import exit from 'exit'; import HasteMap from 'jest-haste-map'; -import {separateMessageFromStack} from 'jest-message-util'; +import { separateMessageFromStack } from 'jest-message-util'; + import Runtime from 'jest-runtime'; import runTest from './runTest'; -export type WorkerData = {| - config: ProjectConfig, - globalConfig: GlobalConfig, - path: Path, - serializableModuleMap: ?SerializableModuleMap, +export type WorkerData = { + config: Config.ProjectConfig, + globalConfig: Config.GlobalConfig, + path: Config.Path, + serializableModuleMap?: SerializableModuleMap, context?: TestRunnerContext, -|}; +} + ; // Make sure uncaught errors are logged before we exit. process.on('uncaughtException', err => { @@ -33,9 +34,9 @@ process.on('uncaughtException', err => { exit(1); }); -const formatError = (error: string | ErrorWithCode): SerializableError => { +const formatError = (error: string | ErrorWithCode): TestResult.SerializableError => { if (typeof error === 'string') { - const {message, stack} = separateMessageFromStack(error); + const { message, stack } = separateMessageFromStack(error); return { message, stack, @@ -52,7 +53,7 @@ const formatError = (error: string | ErrorWithCode): SerializableError => { }; const resolvers = Object.create(null); -const getResolver = (config, moduleMap) => { +const getResolver = (config: Config.ProjectConfig, moduleMap: ModuleMap | null) => { // In watch mode, the raw module map with all haste modules is passed from // the test runner to the watch command. This is because jest-haste-map's // watch mode does not persist the haste map on disk after every file change. @@ -77,7 +78,7 @@ export async function worker({ path, serializableModuleMap, context, -}: WorkerData): Promise { +}: WorkerData): Promise { try { const moduleMap = serializableModuleMap ? HasteMap.ModuleMap.fromJSON(serializableModuleMap) From 1cf462023f1ba98d3647c9f9950af29e3350706c Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Sat, 23 Feb 2019 23:47:00 +0800 Subject: [PATCH 05/26] Migrate test-runner types here and add some types --- packages/jest-runner/src/types.ts | 85 +++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 packages/jest-runner/src/types.ts diff --git a/packages/jest-runner/src/types.ts b/packages/jest-runner/src/types.ts new file mode 100644 index 000000000000..c1d353fe8a0d --- /dev/null +++ b/packages/jest-runner/src/types.ts @@ -0,0 +1,85 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. 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. + * + */ + +import { Environment, Config, TestResult } from "@jest/types"; +import { ModuleMap, FS as HasteFS } from 'jest-haste-map'; +import HasteResolver from 'jest-resolve' + +import Runtime from 'jest-runtime'; + +import { TestWatcher as _TestWatcher } from '@jest/core'; + +export type ErrorWithCode = Error & { code?: string }; + +export type Test = { + context: Context, + duration?: number, + path: Config.Path, +}; + + +export type Context = { + config: Config.ProjectConfig, + hasteFS: HasteFS, + moduleMap: ModuleMap, + resolver: HasteResolver, +}; + +// TODO: Obtain this from jest-reporter once its been migrated +type ReporterOnStartOptions = { + estimatedTime: number, + showStatus: boolean, +}; + + + +// TODO: Obtain this from @jest/core once its been migrated +export type TestWatcher = _TestWatcher; + +export type OnTestStart = (test: Test) => Promise; +export type OnTestFailure = (test: Test, serializableError: TestResult.SerializableError) => Promise +export type OnTestSuccess = (test: Test, testResult: TestResult.TestResult) => Promise; + +export type Reporter = { + onTestResult: ( + test: Test, + testResult: TestResult.TestResult, + aggregatedResult: TestResult.AggregatedResult, + ) => Promise, + onRunStart: ( + results: TestResult.AggregatedResult, + options: ReporterOnStartOptions, + ) => Promise, + onTestStart: (test: Test) => Promise, + onRunComplete: ( + contexts: Set, + results: TestResult.AggregatedResult, + ) => Promise, + getLastError: () => Error, +}; + +export type TestFramework = ( + globalConfig: Config.GlobalConfig, + config: Config.ProjectConfig, + environment: Environment.Environment, + runtime: Runtime, + testPath: string, +) => Promise; + +export type TestRunnerOptions = { + serial: boolean, +}; + +export type TestRunnerContext = { + changedFiles?: Set, +}; + +export type TestRunData = Array<{ + context: Context, + matches: { allTests: number, tests: Array, total: number }, +}>; From f7ebefbf1f97f11ab4b8e2b916f5cf53ed02abf6 Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Sat, 23 Feb 2019 23:47:48 +0800 Subject: [PATCH 06/26] Type runTest --- packages/jest-runner/src/runTest.ts | 89 +++++++++++++++-------------- 1 file changed, 47 insertions(+), 42 deletions(-) diff --git a/packages/jest-runner/src/runTest.ts b/packages/jest-runner/src/runTest.ts index 88fe237666cb..ba86bba434ef 100644 --- a/packages/jest-runner/src/runTest.ts +++ b/packages/jest-runner/src/runTest.ts @@ -7,13 +7,9 @@ * @flow */ -import type {EnvironmentClass} from 'types/Environment'; -import type {GlobalConfig, Path, ProjectConfig} from 'types/Config'; -import type {Resolver} from 'types/Resolve'; -import type {TestFramework, TestRunnerContext} from 'types/TestRunner'; -import type {TestResult} from 'types/TestResult'; -import type RuntimeClass from 'jest-runtime'; - +import { Environment, Config, TestResult, Console as ConsoleType } from '@jest/types'; +import { TestFramework, TestRunnerContext } from './types'; +import RuntimeClass from 'jest-runtime'; import fs from 'graceful-fs'; import { BufferedConsole, @@ -24,22 +20,26 @@ import { setGlobal, } from 'jest-util'; import LeakDetector from 'jest-leak-detector'; -import {getTestEnvironment} from 'jest-config'; +import Resolver from 'jest-resolve'; +import { getTestEnvironment } from 'jest-config'; import * as docblock from 'jest-docblock'; -import {formatExecError} from 'jest-message-util'; +import { formatExecError } from 'jest-message-util'; import sourcemapSupport from 'source-map-support'; import chalk from 'chalk'; type RunTestInternalResult = { - leakDetector: ?LeakDetector, - result: TestResult, + leakDetector: LeakDetector | null, + result: TestResult.TestResult, }; + function freezeConsole( + // TODO: clarify this in the PR + // why cant the names be found even though I've exported them testConsole: BufferedConsole | Console | NullConsole, - config: ProjectConfig, + config: Config.ProjectConfig, ) { - testConsole._log = function fakeConsolePush(_type, message) { + testConsole.log = function fakeConsolePush(_type: unknown, message: string) { const error = new ErrorWithStack( `${chalk.red( `${chalk.bold( @@ -52,7 +52,7 @@ function freezeConsole( const formattedError = formatExecError( error, config, - {noStackTrace: false}, + { noStackTrace: false }, undefined, true, ); @@ -73,11 +73,11 @@ function freezeConsole( // references to verify if there is a leak, which is not maintainable and error // prone. That's why "runTestInternal" CANNOT be inlined inside "runTest". async function runTestInternal( - path: Path, - globalConfig: GlobalConfig, - config: ProjectConfig, + path: Config.Path, + globalConfig: Config.GlobalConfig, + config: Config.ProjectConfig, resolver: Resolver, - context: ?TestRunnerContext, + context?: TestRunnerContext, ): Promise { const testSource = fs.readFileSync(path, 'utf8'); const parsedDocblock = docblock.parse(docblock.extract(testSource)); @@ -93,20 +93,20 @@ async function runTestInternal( } /* $FlowFixMe */ - const TestEnvironment = (require(testEnvironment): EnvironmentClass); + const TestEnvironment = (require(testEnvironment) as Environment.EnvironmentClass); const testFramework = ((process.env.JEST_CIRCUS === '1' ? require('jest-circus/runner') // eslint-disable-line import/no-extraneous-dependencies : /* $FlowFixMe */ - require(config.testRunner)): TestFramework); + require(config.testRunner)) as TestFramework); const Runtime = ((config.moduleLoader ? /* $FlowFixMe */ - require(config.moduleLoader) - : require('jest-runtime')): Class); + require(config.moduleLoader) + : require('jest-runtime')) as RuntimeClass); - let runtime = undefined; + let runtime: RuntimeClass = undefined; const consoleOut = globalConfig.useStderr ? process.stderr : process.stdout; - const consoleFormatter = (type, message) => + const consoleFormatter = (type: ConsoleType.LogType, message: ConsoleType.LogMessage) => getConsoleOutput( config.cwd, !!globalConfig.verbose, @@ -138,7 +138,9 @@ async function runTestInternal( ? new LeakDetector(environment) : null; - const cacheFS = {[path]: testSource}; + const cacheFS = { [path]: testSource }; + + // @ts-ignore setGlobal(environment.global, 'console', testConsole); runtime = new Runtime(config, environment, resolver, cacheFS, { @@ -150,20 +152,21 @@ async function runTestInternal( const start = Date.now(); - const sourcemapOptions = { + const sourcemapOptions: sourcemapSupport.Options = { environment: 'node', handleUncaughtExceptions: false, - retrieveSourceMap: source => { + retrieveSourceMap: (source: string) => { const sourceMaps = runtime && runtime.getSourceMaps(); const sourceMapSource = sourceMaps && sourceMaps[source]; if (sourceMapSource) { try { return { + // @ts-ignore TODO: clarify in PR map: JSON.parse(fs.readFileSync(sourceMapSource)), url: source, }; - } catch (e) {} + } catch (e) { } } return null; }, @@ -182,12 +185,12 @@ async function runTestInternal( if ( environment.global && - environment.global.process && - environment.global.process.exit + (environment.global as NodeJS.Global).process && + (environment.global as NodeJS.Global).process.exit ) { - const realExit = environment.global.process.exit; + const realExit = (environment.global as NodeJS.Global).process.exit; - environment.global.process.exit = function exit(...args) { + (environment.global as NodeJS.Global).process.exit = function exit(...args: Array) { const error = new ErrorWithStack( `process.exit called with "${args.join(', ')}"`, exit, @@ -196,7 +199,7 @@ async function runTestInternal( const formattedError = formatExecError( error, config, - {noStackTrace: false}, + { noStackTrace: false }, undefined, true, ); @@ -210,7 +213,7 @@ async function runTestInternal( try { await environment.setup(); - let result: TestResult; + let result: TestResult.TestResult; try { result = await testFramework( @@ -235,7 +238,7 @@ async function runTestInternal( result.numPendingTests + result.numTodoTests; - result.perfStats = {end: Date.now(), start}; + result.perfStats = { end: Date.now(), start }; result.testFilePath = path; result.coverage = runtime.getAllCoverageInfoCopy(); result.sourceMaps = runtime.getSourceMapInfo( @@ -254,23 +257,25 @@ async function runTestInternal( // Delay the resolution to allow log messages to be output. return new Promise(resolve => { - setImmediate(() => resolve({leakDetector, result})); + setImmediate(() => resolve({ leakDetector, result })); }); } finally { await environment.teardown(); + // @ts-ignore + // TODO: clarify this in PR why this is not on the module sourcemapSupport.resetRetrieveHandlers(); } } export default async function runTest( - path: Path, - globalConfig: GlobalConfig, - config: ProjectConfig, + path: Config.Path, + globalConfig: Config.GlobalConfig, + config: Config.ProjectConfig, resolver: Resolver, - context: ?TestRunnerContext, -): Promise { - const {leakDetector, result} = await runTestInternal( + context?: TestRunnerContext, +): Promise { + const { leakDetector, result } = await runTestInternal( path, globalConfig, config, From 3298bd0ba5f4c79a003049a217d67fad5d3a70af Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Sat, 23 Feb 2019 23:50:29 +0800 Subject: [PATCH 07/26] Update types --- packages/jest-runner/src/types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/jest-runner/src/types.ts b/packages/jest-runner/src/types.ts index c1d353fe8a0d..8cda58bf8cfb 100644 --- a/packages/jest-runner/src/types.ts +++ b/packages/jest-runner/src/types.ts @@ -41,9 +41,9 @@ type ReporterOnStartOptions = { // TODO: Obtain this from @jest/core once its been migrated export type TestWatcher = _TestWatcher; -export type OnTestStart = (test: Test) => Promise; -export type OnTestFailure = (test: Test, serializableError: TestResult.SerializableError) => Promise -export type OnTestSuccess = (test: Test, testResult: TestResult.TestResult) => Promise; +export type OnTestStart = (test: Test) => Promise; +export type OnTestFailure = (test: Test, serializableError: TestResult.SerializableError) => Promise +export type OnTestSuccess = (test: Test, testResult: TestResult.TestResult) => Promise; export type Reporter = { onTestResult: ( From 2e222bd7992d867e5b7d6b8dc964e3bdfa2a5257 Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Sat, 23 Feb 2019 23:52:32 +0800 Subject: [PATCH 08/26] Update workerData type --- packages/jest-runner/src/testWorker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-runner/src/testWorker.ts b/packages/jest-runner/src/testWorker.ts index 1d9ae2ce9898..8861d43a3490 100644 --- a/packages/jest-runner/src/testWorker.ts +++ b/packages/jest-runner/src/testWorker.ts @@ -23,7 +23,7 @@ export type WorkerData = { config: Config.ProjectConfig, globalConfig: Config.GlobalConfig, path: Config.Path, - serializableModuleMap?: SerializableModuleMap, + serializableModuleMap: SerializableModuleMap | null, context?: TestRunnerContext, } ; From fb04d2ac7ed5f7dfd8e558d07f26203a230e90dc Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Sun, 24 Feb 2019 00:32:18 +0800 Subject: [PATCH 09/26] Add jsresolve in dependencies --- packages/jest-runner/tsconfig.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/jest-runner/tsconfig.json b/packages/jest-runner/tsconfig.json index c4c84985f77b..5dfced42b99c 100644 --- a/packages/jest-runner/tsconfig.json +++ b/packages/jest-runner/tsconfig.json @@ -6,10 +6,10 @@ }, "references": [ { - "path": "../jest-config" + "path": "../jest-docblock" }, { - "path": "../jest-docblock" + "path": "../jest-config" }, { "path": "../jest-haste-map" @@ -35,5 +35,8 @@ { "path": "../jest-types" }, + { + "path": "../jest-resolve" + } ] } From fd30cc7ab9cff6991a7c58136c890cb748fd8dc2 Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Sun, 24 Feb 2019 00:52:59 +0800 Subject: [PATCH 10/26] Run eslint and remove flow declarations --- packages/jest-runner/src/index.ts | 47 ++++++++++--------- packages/jest-runner/src/runTest.ts | 54 ++++++++++++---------- packages/jest-runner/src/testWorker.ts | 37 ++++++++------- packages/jest-runner/src/types.ts | 62 +++++++++++++------------- 4 files changed, 106 insertions(+), 94 deletions(-) diff --git a/packages/jest-runner/src/index.ts b/packages/jest-runner/src/index.ts index 538978903fd8..4593dcea2658 100644 --- a/packages/jest-runner/src/index.ts +++ b/packages/jest-runner/src/index.ts @@ -4,11 +4,15 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow */ -import type {GlobalConfig} from 'types/Config'; -import type { +import {Config, TestResult} from '@jest/types'; +import exit from 'exit'; +import throat from 'throat'; +import Worker from 'jest-worker'; +import runTest from './runTest'; +import {WorkerData} from './testWorker'; +import { OnTestFailure, OnTestStart, OnTestSuccess, @@ -16,24 +20,23 @@ import type { TestRunnerContext, TestRunnerOptions, TestWatcher, -} from 'types/TestRunner'; - -import typeof {worker} from './testWorker'; - -import exit from 'exit'; -import runTest from './runTest'; -import throat from 'throat'; -import Worker from 'jest-worker'; +} from './types'; const TEST_WORKER_PATH = require.resolve('./testWorker'); -type WorkerInterface = Worker & {worker: worker}; +type WorkerInterface = Worker & { + worker: (workerData: WorkerData) => Promise; +}; + +type WatcherState = { + interrupted: boolean; +}; class TestRunner { - _globalConfig: GlobalConfig; + _globalConfig: Config.GlobalConfig; _context: TestRunnerContext; - constructor(globalConfig: GlobalConfig, context?: TestRunnerContext) { + constructor(globalConfig: Config.GlobalConfig, context?: TestRunnerContext) { this._globalConfig = globalConfig; this._context = context || {}; } @@ -98,12 +101,14 @@ class TestRunner { onResult: OnTestSuccess, onFailure: OnTestFailure, ) { - const worker: WorkerInterface = new Worker(TEST_WORKER_PATH, { + const worker = new Worker(TEST_WORKER_PATH, { exposedMethods: ['worker'], - forkOptions: {stdio: 'pipe'}, + // TODO: clarify this in PR + // doing this to satify the type + forkOptions: {stdio: ['pipe']}, maxRetries: 3, numWorkers: this._globalConfig.maxWorkers, - }); + }) as WorkerInterface; if (worker.getStdout()) worker.getStdout().pipe(process.stdout); if (worker.getStderr()) worker.getStderr().pipe(process.stderr); @@ -112,7 +117,7 @@ class TestRunner { // Send test suites to workers continuously instead of all at once to track // the start time of individual tests. - const runTestInWorker = test => + const runTestInWorker = (test: Test) => mutex(async () => { if (watcher.isInterrupted()) { return Promise.reject(); @@ -131,7 +136,7 @@ class TestRunner { }); }); - const onError = async (err, test) => { + const onError = async (err: TestResult.SerializableError, test: Test) => { await onFailure(test, err); if (err.type === 'ProcessTerminatedError') { console.error( @@ -143,7 +148,7 @@ class TestRunner { }; const onInterrupt = new Promise((_, reject) => { - watcher.on('change', state => { + watcher.on('change', (state: WatcherState) => { if (state.interrupted) { reject(new CancelRun()); } @@ -164,7 +169,7 @@ class TestRunner { } class CancelRun extends Error { - constructor(message: ?string) { + constructor(message?: string) { super(message); this.name = 'CancelRun'; } diff --git a/packages/jest-runner/src/runTest.ts b/packages/jest-runner/src/runTest.ts index ba86bba434ef..947b0d68b2e8 100644 --- a/packages/jest-runner/src/runTest.ts +++ b/packages/jest-runner/src/runTest.ts @@ -4,11 +4,14 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow */ -import { Environment, Config, TestResult, Console as ConsoleType } from '@jest/types'; -import { TestFramework, TestRunnerContext } from './types'; +import { + Environment, + Config, + TestResult, + Console as ConsoleType, +} from '@jest/types'; import RuntimeClass from 'jest-runtime'; import fs from 'graceful-fs'; import { @@ -21,18 +24,18 @@ import { } from 'jest-util'; import LeakDetector from 'jest-leak-detector'; import Resolver from 'jest-resolve'; -import { getTestEnvironment } from 'jest-config'; +import {getTestEnvironment} from 'jest-config'; import * as docblock from 'jest-docblock'; -import { formatExecError } from 'jest-message-util'; +import {formatExecError} from 'jest-message-util'; import sourcemapSupport from 'source-map-support'; import chalk from 'chalk'; +import {TestFramework, TestRunnerContext} from './types'; type RunTestInternalResult = { - leakDetector: LeakDetector | null, - result: TestResult.TestResult, + leakDetector: LeakDetector | null; + result: TestResult.TestResult; }; - function freezeConsole( // TODO: clarify this in the PR // why cant the names be found even though I've exported them @@ -52,7 +55,7 @@ function freezeConsole( const formattedError = formatExecError( error, config, - { noStackTrace: false }, + {noStackTrace: false}, undefined, true, ); @@ -93,20 +96,23 @@ async function runTestInternal( } /* $FlowFixMe */ - const TestEnvironment = (require(testEnvironment) as Environment.EnvironmentClass); - const testFramework = ((process.env.JEST_CIRCUS === '1' + const TestEnvironment = require(testEnvironment) as Environment.EnvironmentClass; + const testFramework = (process.env.JEST_CIRCUS === '1' ? require('jest-circus/runner') // eslint-disable-line import/no-extraneous-dependencies : /* $FlowFixMe */ - require(config.testRunner)) as TestFramework); - const Runtime = ((config.moduleLoader + require(config.testRunner)) as TestFramework; + const Runtime = (config.moduleLoader ? /* $FlowFixMe */ - require(config.moduleLoader) - : require('jest-runtime')) as RuntimeClass); + require(config.moduleLoader) + : require('jest-runtime')) as RuntimeClass; let runtime: RuntimeClass = undefined; const consoleOut = globalConfig.useStderr ? process.stderr : process.stdout; - const consoleFormatter = (type: ConsoleType.LogType, message: ConsoleType.LogMessage) => + const consoleFormatter = ( + type: ConsoleType.LogType, + message: ConsoleType.LogMessage, + ) => getConsoleOutput( config.cwd, !!globalConfig.verbose, @@ -138,7 +144,7 @@ async function runTestInternal( ? new LeakDetector(environment) : null; - const cacheFS = { [path]: testSource }; + const cacheFS = {[path]: testSource}; // @ts-ignore setGlobal(environment.global, 'console', testConsole); @@ -166,7 +172,7 @@ async function runTestInternal( map: JSON.parse(fs.readFileSync(sourceMapSource)), url: source, }; - } catch (e) { } + } catch (e) {} } return null; }, @@ -190,7 +196,9 @@ async function runTestInternal( ) { const realExit = (environment.global as NodeJS.Global).process.exit; - (environment.global as NodeJS.Global).process.exit = function exit(...args: Array) { + (environment.global as NodeJS.Global).process.exit = function exit( + ...args: Array + ) { const error = new ErrorWithStack( `process.exit called with "${args.join(', ')}"`, exit, @@ -199,7 +207,7 @@ async function runTestInternal( const formattedError = formatExecError( error, config, - { noStackTrace: false }, + {noStackTrace: false}, undefined, true, ); @@ -238,7 +246,7 @@ async function runTestInternal( result.numPendingTests + result.numTodoTests; - result.perfStats = { end: Date.now(), start }; + result.perfStats = {end: Date.now(), start}; result.testFilePath = path; result.coverage = runtime.getAllCoverageInfoCopy(); result.sourceMaps = runtime.getSourceMapInfo( @@ -257,7 +265,7 @@ async function runTestInternal( // Delay the resolution to allow log messages to be output. return new Promise(resolve => { - setImmediate(() => resolve({ leakDetector, result })); + setImmediate(() => resolve({leakDetector, result})); }); } finally { await environment.teardown(); @@ -275,7 +283,7 @@ export default async function runTest( resolver: Resolver, context?: TestRunnerContext, ): Promise { - const { leakDetector, result } = await runTestInternal( + const {leakDetector, result} = await runTestInternal( path, globalConfig, config, diff --git a/packages/jest-runner/src/testWorker.ts b/packages/jest-runner/src/testWorker.ts index 8861d43a3490..cf5a92e9bfd8 100644 --- a/packages/jest-runner/src/testWorker.ts +++ b/packages/jest-runner/src/testWorker.ts @@ -4,29 +4,23 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow */ -import { Config, TestResult } from '@jest/types'; -import { ErrorWithCode } from './types'; -import { SerializableModuleMap, ModuleMap } from 'jest-haste-map'; -import { TestRunnerContext } from 'types/TestRunner'; - +import {Config, TestResult} from '@jest/types'; +import HasteMap, {SerializableModuleMap, ModuleMap} from 'jest-haste-map'; import exit from 'exit'; -import HasteMap from 'jest-haste-map'; -import { separateMessageFromStack } from 'jest-message-util'; - +import {separateMessageFromStack} from 'jest-message-util'; import Runtime from 'jest-runtime'; +import {ErrorWithCode, TestRunnerContext} from './types'; import runTest from './runTest'; export type WorkerData = { - config: Config.ProjectConfig, - globalConfig: Config.GlobalConfig, - path: Config.Path, - serializableModuleMap: SerializableModuleMap | null, - context?: TestRunnerContext, -} - ; + config: Config.ProjectConfig; + globalConfig: Config.GlobalConfig; + path: Config.Path; + serializableModuleMap: SerializableModuleMap | null; + context?: TestRunnerContext; +}; // Make sure uncaught errors are logged before we exit. process.on('uncaughtException', err => { @@ -34,9 +28,11 @@ process.on('uncaughtException', err => { exit(1); }); -const formatError = (error: string | ErrorWithCode): TestResult.SerializableError => { +const formatError = ( + error: string | ErrorWithCode, +): TestResult.SerializableError => { if (typeof error === 'string') { - const { message, stack } = separateMessageFromStack(error); + const {message, stack} = separateMessageFromStack(error); return { message, stack, @@ -53,7 +49,10 @@ const formatError = (error: string | ErrorWithCode): TestResult.SerializableErro }; const resolvers = Object.create(null); -const getResolver = (config: Config.ProjectConfig, moduleMap: ModuleMap | null) => { +const getResolver = ( + config: Config.ProjectConfig, + moduleMap: ModuleMap | null, +) => { // In watch mode, the raw module map with all haste modules is passed from // the test runner to the watch command. This is because jest-haste-map's // watch mode does not persist the haste map on disk after every file change. diff --git a/packages/jest-runner/src/types.ts b/packages/jest-runner/src/types.ts index 8cda58bf8cfb..2912bf027691 100644 --- a/packages/jest-runner/src/types.ts +++ b/packages/jest-runner/src/types.ts @@ -6,61 +6,61 @@ * */ -import { Environment, Config, TestResult } from "@jest/types"; -import { ModuleMap, FS as HasteFS } from 'jest-haste-map'; -import HasteResolver from 'jest-resolve' - +import {Environment, Config, TestResult} from '@jest/types'; +import {ModuleMap, FS as HasteFS} from 'jest-haste-map'; +import HasteResolver from 'jest-resolve'; import Runtime from 'jest-runtime'; +import {TestWatcher as _TestWatcher} from '@jest/core'; -import { TestWatcher as _TestWatcher } from '@jest/core'; - -export type ErrorWithCode = Error & { code?: string }; - +export type ErrorWithCode = Error & {code?: string}; export type Test = { - context: Context, - duration?: number, - path: Config.Path, + context: Context; + duration?: number; + path: Config.Path; }; - export type Context = { - config: Config.ProjectConfig, - hasteFS: HasteFS, - moduleMap: ModuleMap, - resolver: HasteResolver, + config: Config.ProjectConfig; + hasteFS: HasteFS; + moduleMap: ModuleMap; + resolver: HasteResolver; }; // TODO: Obtain this from jest-reporter once its been migrated type ReporterOnStartOptions = { - estimatedTime: number, - showStatus: boolean, + estimatedTime: number; + showStatus: boolean; }; - - // TODO: Obtain this from @jest/core once its been migrated export type TestWatcher = _TestWatcher; export type OnTestStart = (test: Test) => Promise; -export type OnTestFailure = (test: Test, serializableError: TestResult.SerializableError) => Promise -export type OnTestSuccess = (test: Test, testResult: TestResult.TestResult) => Promise; +export type OnTestFailure = ( + test: Test, + serializableError: TestResult.SerializableError, +) => Promise; +export type OnTestSuccess = ( + test: Test, + testResult: TestResult.TestResult, +) => Promise; export type Reporter = { onTestResult: ( test: Test, testResult: TestResult.TestResult, aggregatedResult: TestResult.AggregatedResult, - ) => Promise, + ) => Promise; onRunStart: ( results: TestResult.AggregatedResult, options: ReporterOnStartOptions, - ) => Promise, - onTestStart: (test: Test) => Promise, + ) => Promise; + onTestStart: (test: Test) => Promise; onRunComplete: ( contexts: Set, results: TestResult.AggregatedResult, - ) => Promise, - getLastError: () => Error, + ) => Promise; + getLastError: () => Error; }; export type TestFramework = ( @@ -72,14 +72,14 @@ export type TestFramework = ( ) => Promise; export type TestRunnerOptions = { - serial: boolean, + serial: boolean; }; export type TestRunnerContext = { - changedFiles?: Set, + changedFiles?: Set; }; export type TestRunData = Array<{ - context: Context, - matches: { allTests: number, tests: Array, total: number }, + context: Context; + matches: {allTests: number; tests: Array; total: number}; }>; From c4b75efbe15a7d713eef6218384e6f72dd52af7c Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Sun, 24 Feb 2019 00:58:09 +0800 Subject: [PATCH 11/26] Add jest-core in tsconfig --- packages/jest-runner/tsconfig.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/jest-runner/tsconfig.json b/packages/jest-runner/tsconfig.json index 5dfced42b99c..b509578657f2 100644 --- a/packages/jest-runner/tsconfig.json +++ b/packages/jest-runner/tsconfig.json @@ -37,6 +37,9 @@ }, { "path": "../jest-resolve" + }, + { + "path": "../jest-core" } ] } From e734a23627d621b2de78e43ad1b16e10f94f47ac Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Sun, 24 Feb 2019 01:06:56 +0800 Subject: [PATCH 12/26] Add dependencies --- packages/jest-runner/package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/jest-runner/package.json b/packages/jest-runner/package.json index b645b365494a..4c1caaa89bbc 100644 --- a/packages/jest-runner/package.json +++ b/packages/jest-runner/package.json @@ -10,6 +10,7 @@ "main": "build/index.js", "types": "build/index.d.ts", "dependencies": { + "@jest/core": "^24.1.0", "@jest/types": "^24.1.0", "chalk": "^2.4.2", "exit": "^0.1.2", @@ -20,6 +21,7 @@ "jest-jasmine2": "^24.1.0", "jest-leak-detector": "^24.0.0", "jest-message-util": "^24.0.0", + "jest-resolve": "^24.1.0", "jest-runtime": "^24.1.0", "jest-util": "^24.0.0", "jest-worker": "^24.0.0", From 68a88f6f59efae75aefcce7afbff2537b3cc1d1a Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Sun, 24 Feb 2019 08:50:03 +0800 Subject: [PATCH 13/26] Fix arguments for jest worker instantiation --- packages/jest-runner/src/index.ts | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/jest-runner/src/index.ts b/packages/jest-runner/src/index.ts index 4593dcea2658..8b42569377a8 100644 --- a/packages/jest-runner/src/index.ts +++ b/packages/jest-runner/src/index.ts @@ -6,12 +6,12 @@ * */ -import {Config, TestResult} from '@jest/types'; +import { Config, TestResult } from '@jest/types'; import exit from 'exit'; import throat from 'throat'; import Worker from 'jest-worker'; import runTest from './runTest'; -import {WorkerData} from './testWorker'; +import { WorkerData } from './testWorker'; import { OnTestFailure, OnTestStart, @@ -52,12 +52,12 @@ class TestRunner { return await (options.serial ? this._createInBandTestRun(tests, watcher, onStart, onResult, onFailure) : this._createParallelTestRun( - tests, - watcher, - onStart, - onResult, - onFailure, - )); + tests, + watcher, + onStart, + onResult, + onFailure, + )); } async _createInBandTestRun( @@ -101,11 +101,12 @@ class TestRunner { onResult: OnTestSuccess, onFailure: OnTestFailure, ) { + + // TODO: Resolve typing since this is correct code + //@ts-ignore const worker = new Worker(TEST_WORKER_PATH, { exposedMethods: ['worker'], - // TODO: clarify this in PR - // doing this to satify the type - forkOptions: {stdio: ['pipe']}, + forkOptions: { stdio: 'pipe' }, maxRetries: 3, numWorkers: this._globalConfig.maxWorkers, }) as WorkerInterface; @@ -141,7 +142,7 @@ class TestRunner { if (err.type === 'ProcessTerminatedError') { console.error( 'A worker process has quit unexpectedly! ' + - 'Most likely this is an initialization error.', + 'Most likely this is an initialization error.', ); exit(1); } From d111542df80f0e9ced4fb29f76af3a62dfea2f6c Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Sun, 24 Feb 2019 08:59:18 +0800 Subject: [PATCH 14/26] Resolve comments for now --- packages/jest-runner/src/runTest.ts | 30 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/jest-runner/src/runTest.ts b/packages/jest-runner/src/runTest.ts index 947b0d68b2e8..146abe402d46 100644 --- a/packages/jest-runner/src/runTest.ts +++ b/packages/jest-runner/src/runTest.ts @@ -24,12 +24,12 @@ import { } from 'jest-util'; import LeakDetector from 'jest-leak-detector'; import Resolver from 'jest-resolve'; -import {getTestEnvironment} from 'jest-config'; +import { getTestEnvironment } from 'jest-config'; import * as docblock from 'jest-docblock'; -import {formatExecError} from 'jest-message-util'; +import { formatExecError } from 'jest-message-util'; import sourcemapSupport from 'source-map-support'; import chalk from 'chalk'; -import {TestFramework, TestRunnerContext} from './types'; +import { TestFramework, TestRunnerContext } from './types'; type RunTestInternalResult = { leakDetector: LeakDetector | null; @@ -37,8 +37,7 @@ type RunTestInternalResult = { }; function freezeConsole( - // TODO: clarify this in the PR - // why cant the names be found even though I've exported them + // @ts-ignore testConsole: BufferedConsole | Console | NullConsole, config: Config.ProjectConfig, ) { @@ -55,7 +54,7 @@ function freezeConsole( const formattedError = formatExecError( error, config, - {noStackTrace: false}, + { noStackTrace: false }, undefined, true, ); @@ -100,10 +99,10 @@ async function runTestInternal( const testFramework = (process.env.JEST_CIRCUS === '1' ? require('jest-circus/runner') // eslint-disable-line import/no-extraneous-dependencies : /* $FlowFixMe */ - require(config.testRunner)) as TestFramework; + require(config.testRunner)) as TestFramework; const Runtime = (config.moduleLoader ? /* $FlowFixMe */ - require(config.moduleLoader) + require(config.moduleLoader) : require('jest-runtime')) as RuntimeClass; let runtime: RuntimeClass = undefined; @@ -144,7 +143,7 @@ async function runTestInternal( ? new LeakDetector(environment) : null; - const cacheFS = {[path]: testSource}; + const cacheFS = { [path]: testSource }; // @ts-ignore setGlobal(environment.global, 'console', testConsole); @@ -168,11 +167,12 @@ async function runTestInternal( if (sourceMapSource) { try { return { - // @ts-ignore TODO: clarify in PR + // @ts-ignore + // This code works map: JSON.parse(fs.readFileSync(sourceMapSource)), url: source, }; - } catch (e) {} + } catch (e) { } } return null; }, @@ -207,7 +207,7 @@ async function runTestInternal( const formattedError = formatExecError( error, config, - {noStackTrace: false}, + { noStackTrace: false }, undefined, true, ); @@ -246,7 +246,7 @@ async function runTestInternal( result.numPendingTests + result.numTodoTests; - result.perfStats = {end: Date.now(), start}; + result.perfStats = { end: Date.now(), start }; result.testFilePath = path; result.coverage = runtime.getAllCoverageInfoCopy(); result.sourceMaps = runtime.getSourceMapInfo( @@ -265,7 +265,7 @@ async function runTestInternal( // Delay the resolution to allow log messages to be output. return new Promise(resolve => { - setImmediate(() => resolve({leakDetector, result})); + setImmediate(() => resolve({ leakDetector, result })); }); } finally { await environment.teardown(); @@ -283,7 +283,7 @@ export default async function runTest( resolver: Resolver, context?: TestRunnerContext, ): Promise { - const {leakDetector, result} = await runTestInternal( + const { leakDetector, result } = await runTestInternal( path, globalConfig, config, From fff3691fde8860f44c71c1c7f97fe4da5f0e0ffb Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Sun, 24 Feb 2019 09:02:34 +0800 Subject: [PATCH 15/26] Update tsconfig --- packages/jest-runner/tsconfig.json | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/packages/jest-runner/tsconfig.json b/packages/jest-runner/tsconfig.json index b509578657f2..39fc78e6477b 100644 --- a/packages/jest-runner/tsconfig.json +++ b/packages/jest-runner/tsconfig.json @@ -8,24 +8,15 @@ { "path": "../jest-docblock" }, - { - "path": "../jest-config" - }, { "path": "../jest-haste-map" }, - { - "path": "../jest-jasmine2" - }, { "path": "../jest-leak-detector" }, { "path": "../jest-message-util" }, - { - "path": "../jest-runtime" - }, { "path": "../jest-util" }, @@ -38,8 +29,5 @@ { "path": "../jest-resolve" }, - { - "path": "../jest-core" - } ] } From 525783e2d090fb6792539b86b15b4af565a44fab Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 25 Feb 2019 00:00:21 +0100 Subject: [PATCH 16/26] tweaks --- packages/jest-runner/package.json | 1 - packages/jest-runner/src/index.ts | 21 ++++++++--------- packages/jest-runner/src/runTest.ts | 29 +++++++++++------------ packages/jest-runner/src/testWorker.ts | 1 + packages/jest-runner/src/types.ts | 20 ++++++++++++---- packages/jest-runner/tsconfig.json | 32 +++++++------------------- 6 files changed, 48 insertions(+), 56 deletions(-) diff --git a/packages/jest-runner/package.json b/packages/jest-runner/package.json index 4c1caaa89bbc..67cd2369cb63 100644 --- a/packages/jest-runner/package.json +++ b/packages/jest-runner/package.json @@ -10,7 +10,6 @@ "main": "build/index.js", "types": "build/index.d.ts", "dependencies": { - "@jest/core": "^24.1.0", "@jest/types": "^24.1.0", "chalk": "^2.4.2", "exit": "^0.1.2", diff --git a/packages/jest-runner/src/index.ts b/packages/jest-runner/src/index.ts index 8b42569377a8..e4b834815d1f 100644 --- a/packages/jest-runner/src/index.ts +++ b/packages/jest-runner/src/index.ts @@ -6,12 +6,12 @@ * */ -import { Config, TestResult } from '@jest/types'; +import {Config, TestResult} from '@jest/types'; import exit from 'exit'; import throat from 'throat'; import Worker from 'jest-worker'; import runTest from './runTest'; -import { WorkerData } from './testWorker'; +import {WorkerData} from './testWorker'; import { OnTestFailure, OnTestStart, @@ -52,12 +52,12 @@ class TestRunner { return await (options.serial ? this._createInBandTestRun(tests, watcher, onStart, onResult, onFailure) : this._createParallelTestRun( - tests, - watcher, - onStart, - onResult, - onFailure, - )); + tests, + watcher, + onStart, + onResult, + onFailure, + )); } async _createInBandTestRun( @@ -101,12 +101,11 @@ class TestRunner { onResult: OnTestSuccess, onFailure: OnTestFailure, ) { - // TODO: Resolve typing since this is correct code //@ts-ignore const worker = new Worker(TEST_WORKER_PATH, { exposedMethods: ['worker'], - forkOptions: { stdio: 'pipe' }, + forkOptions: {stdio: 'pipe'}, maxRetries: 3, numWorkers: this._globalConfig.maxWorkers, }) as WorkerInterface; @@ -142,7 +141,7 @@ class TestRunner { if (err.type === 'ProcessTerminatedError') { console.error( 'A worker process has quit unexpectedly! ' + - 'Most likely this is an initialization error.', + 'Most likely this is an initialization error.', ); exit(1); } diff --git a/packages/jest-runner/src/runTest.ts b/packages/jest-runner/src/runTest.ts index 146abe402d46..d5a0e2648f6b 100644 --- a/packages/jest-runner/src/runTest.ts +++ b/packages/jest-runner/src/runTest.ts @@ -12,6 +12,7 @@ import { TestResult, Console as ConsoleType, } from '@jest/types'; +// @ts-ignore: not migrated to TS import RuntimeClass from 'jest-runtime'; import fs from 'graceful-fs'; import { @@ -24,12 +25,13 @@ import { } from 'jest-util'; import LeakDetector from 'jest-leak-detector'; import Resolver from 'jest-resolve'; -import { getTestEnvironment } from 'jest-config'; +// @ts-ignore: not migrated to TS +import {getTestEnvironment} from 'jest-config'; import * as docblock from 'jest-docblock'; -import { formatExecError } from 'jest-message-util'; +import {formatExecError} from 'jest-message-util'; import sourcemapSupport from 'source-map-support'; import chalk from 'chalk'; -import { TestFramework, TestRunnerContext } from './types'; +import {TestFramework, TestRunnerContext} from './types'; type RunTestInternalResult = { leakDetector: LeakDetector | null; @@ -54,7 +56,7 @@ function freezeConsole( const formattedError = formatExecError( error, config, - { noStackTrace: false }, + {noStackTrace: false}, undefined, true, ); @@ -94,15 +96,12 @@ async function runTestInternal( }); } - /* $FlowFixMe */ const TestEnvironment = require(testEnvironment) as Environment.EnvironmentClass; const testFramework = (process.env.JEST_CIRCUS === '1' ? require('jest-circus/runner') // eslint-disable-line import/no-extraneous-dependencies - : /* $FlowFixMe */ - require(config.testRunner)) as TestFramework; + : require(config.testRunner)) as TestFramework; const Runtime = (config.moduleLoader - ? /* $FlowFixMe */ - require(config.moduleLoader) + ? require(config.moduleLoader) : require('jest-runtime')) as RuntimeClass; let runtime: RuntimeClass = undefined; @@ -143,7 +142,7 @@ async function runTestInternal( ? new LeakDetector(environment) : null; - const cacheFS = { [path]: testSource }; + const cacheFS = {[path]: testSource}; // @ts-ignore setGlobal(environment.global, 'console', testConsole); @@ -172,7 +171,7 @@ async function runTestInternal( map: JSON.parse(fs.readFileSync(sourceMapSource)), url: source, }; - } catch (e) { } + } catch (e) {} } return null; }, @@ -207,7 +206,7 @@ async function runTestInternal( const formattedError = formatExecError( error, config, - { noStackTrace: false }, + {noStackTrace: false}, undefined, true, ); @@ -246,7 +245,7 @@ async function runTestInternal( result.numPendingTests + result.numTodoTests; - result.perfStats = { end: Date.now(), start }; + result.perfStats = {end: Date.now(), start}; result.testFilePath = path; result.coverage = runtime.getAllCoverageInfoCopy(); result.sourceMaps = runtime.getSourceMapInfo( @@ -265,7 +264,7 @@ async function runTestInternal( // Delay the resolution to allow log messages to be output. return new Promise(resolve => { - setImmediate(() => resolve({ leakDetector, result })); + setImmediate(() => resolve({leakDetector, result})); }); } finally { await environment.teardown(); @@ -283,7 +282,7 @@ export default async function runTest( resolver: Resolver, context?: TestRunnerContext, ): Promise { - const { leakDetector, result } = await runTestInternal( + const {leakDetector, result} = await runTestInternal( path, globalConfig, config, diff --git a/packages/jest-runner/src/testWorker.ts b/packages/jest-runner/src/testWorker.ts index cf5a92e9bfd8..83fc9ab56253 100644 --- a/packages/jest-runner/src/testWorker.ts +++ b/packages/jest-runner/src/testWorker.ts @@ -10,6 +10,7 @@ import {Config, TestResult} from '@jest/types'; import HasteMap, {SerializableModuleMap, ModuleMap} from 'jest-haste-map'; import exit from 'exit'; import {separateMessageFromStack} from 'jest-message-util'; +// @ts-ignore: Not migrated to TS import Runtime from 'jest-runtime'; import {ErrorWithCode, TestRunnerContext} from './types'; import runTest from './runTest'; diff --git a/packages/jest-runner/src/types.ts b/packages/jest-runner/src/types.ts index 2912bf027691..27551bfb36ce 100644 --- a/packages/jest-runner/src/types.ts +++ b/packages/jest-runner/src/types.ts @@ -6,11 +6,12 @@ * */ +import EventEmitter from 'events'; import {Environment, Config, TestResult} from '@jest/types'; import {ModuleMap, FS as HasteFS} from 'jest-haste-map'; import HasteResolver from 'jest-resolve'; +// @ts-ignore: not migrated to TS import Runtime from 'jest-runtime'; -import {TestWatcher as _TestWatcher} from '@jest/core'; export type ErrorWithCode = Error & {code?: string}; export type Test = { @@ -26,15 +27,12 @@ export type Context = { resolver: HasteResolver; }; -// TODO: Obtain this from jest-reporter once its been migrated +// TODO: Obtain this from @jest/reporters once its been migrated type ReporterOnStartOptions = { estimatedTime: number; showStatus: boolean; }; -// TODO: Obtain this from @jest/core once its been migrated -export type TestWatcher = _TestWatcher; - export type OnTestStart = (test: Test) => Promise; export type OnTestFailure = ( test: Test, @@ -83,3 +81,15 @@ export type TestRunData = Array<{ context: Context; matches: {allTests: number; tests: Array; total: number}; }>; + +// TODO: Should live in `@jest/core` or `jest-watcher` +declare type State = { + interrupted: boolean; +}; +export interface TestWatcher extends EventEmitter { + state: State; + new ({isWatchMode}: {isWatchMode: boolean}): TestWatcher; + setState(state: State): void; + isInterrupted(): boolean; + isWatchMode(): boolean; +} diff --git a/packages/jest-runner/tsconfig.json b/packages/jest-runner/tsconfig.json index 39fc78e6477b..59665ff7c74e 100644 --- a/packages/jest-runner/tsconfig.json +++ b/packages/jest-runner/tsconfig.json @@ -5,29 +5,13 @@ "outDir": "build" }, "references": [ - { - "path": "../jest-docblock" - }, - { - "path": "../jest-haste-map" - }, - { - "path": "../jest-leak-detector" - }, - { - "path": "../jest-message-util" - }, - { - "path": "../jest-util" - }, - { - "path": "../jest-worker" - }, - { - "path": "../jest-types" - }, - { - "path": "../jest-resolve" - }, + {"path": "../jest-docblock"}, + {"path": "../jest-haste-map"}, + {"path": "../jest-leak-detector"}, + {"path": "../jest-message-util"}, + {"path": "../jest-resolve"}, + {"path": "../jest-types"}, + {"path": "../jest-worker"}, + {"path": "../jest-util"} ] } From fb7ea5c1eb7464759105a05293060a5c1870948c Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 25 Feb 2019 01:11:21 +0100 Subject: [PATCH 17/26] correct export --- packages/jest-runner/src/__tests__/testRunner.test.js | 1 - packages/jest-runner/src/index.ts | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/jest-runner/src/__tests__/testRunner.test.js b/packages/jest-runner/src/__tests__/testRunner.test.js index 9601969f012d..ca604b10c0ee 100644 --- a/packages/jest-runner/src/__tests__/testRunner.test.js +++ b/packages/jest-runner/src/__tests__/testRunner.test.js @@ -7,7 +7,6 @@ */ import {TestWatcher} from '@jest/core'; -// eslint-disable-next-line import/default import TestRunner from '../index'; let mockWorkerFarm; diff --git a/packages/jest-runner/src/index.ts b/packages/jest-runner/src/index.ts index e4b834815d1f..c602d29fbc23 100644 --- a/packages/jest-runner/src/index.ts +++ b/packages/jest-runner/src/index.ts @@ -33,8 +33,8 @@ type WatcherState = { }; class TestRunner { - _globalConfig: Config.GlobalConfig; - _context: TestRunnerContext; + private _globalConfig: Config.GlobalConfig; + private _context: TestRunnerContext; constructor(globalConfig: Config.GlobalConfig, context?: TestRunnerContext) { this._globalConfig = globalConfig; @@ -60,7 +60,7 @@ class TestRunner { )); } - async _createInBandTestRun( + private async _createInBandTestRun( tests: Array, watcher: TestWatcher, onStart: OnTestStart, @@ -94,7 +94,7 @@ class TestRunner { ); } - async _createParallelTestRun( + private async _createParallelTestRun( tests: Array, watcher: TestWatcher, onStart: OnTestStart, @@ -175,4 +175,4 @@ class CancelRun extends Error { } } -module.exports = TestRunner; +export = TestRunner; From 20d9d4b252b08bba1b47dc30f1f2136b62b59d0d Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 25 Feb 2019 01:18:29 +0100 Subject: [PATCH 18/26] remove some casts and ignores --- packages/jest-runner/src/runTest.ts | 22 ++++++++-------------- packages/jest-types/src/Global.ts | 2 +- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/packages/jest-runner/src/runTest.ts b/packages/jest-runner/src/runTest.ts index d5a0e2648f6b..ad9c620889b2 100644 --- a/packages/jest-runner/src/runTest.ts +++ b/packages/jest-runner/src/runTest.ts @@ -39,11 +39,11 @@ type RunTestInternalResult = { }; function freezeConsole( - // @ts-ignore + // @ts-ignore: Correct types when `jest-util` is ESM testConsole: BufferedConsole | Console | NullConsole, config: Config.ProjectConfig, ) { - testConsole.log = function fakeConsolePush(_type: unknown, message: string) { + testConsole._log = function fakeConsolePush(_type: unknown, message: string) { const error = new ErrorWithStack( `${chalk.red( `${chalk.bold( @@ -144,7 +144,6 @@ async function runTestInternal( const cacheFS = {[path]: testSource}; - // @ts-ignore setGlobal(environment.global, 'console', testConsole); runtime = new Runtime(config, environment, resolver, cacheFS, { @@ -166,9 +165,7 @@ async function runTestInternal( if (sourceMapSource) { try { return { - // @ts-ignore - // This code works - map: JSON.parse(fs.readFileSync(sourceMapSource)), + map: JSON.parse(fs.readFileSync(sourceMapSource, 'utf8')), url: source, }; } catch (e) {} @@ -190,14 +187,12 @@ async function runTestInternal( if ( environment.global && - (environment.global as NodeJS.Global).process && - (environment.global as NodeJS.Global).process.exit + environment.global.process && + environment.global.process.exit ) { - const realExit = (environment.global as NodeJS.Global).process.exit; + const realExit = environment.global.process.exit; - (environment.global as NodeJS.Global).process.exit = function exit( - ...args: Array - ) { + environment.global.process.exit = function exit(...args: Array) { const error = new ErrorWithStack( `process.exit called with "${args.join(', ')}"`, exit, @@ -269,8 +264,7 @@ async function runTestInternal( } finally { await environment.teardown(); - // @ts-ignore - // TODO: clarify this in PR why this is not on the module + // @ts-ignore: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/33351 sourcemapSupport.resetRetrieveHandlers(); } } diff --git a/packages/jest-types/src/Global.ts b/packages/jest-types/src/Global.ts index ed7739615e14..1a782eaaa386 100644 --- a/packages/jest-types/src/Global.ts +++ b/packages/jest-types/src/Global.ts @@ -48,7 +48,7 @@ export interface Describe extends DescribeBase { skip: ItBase; } -export interface Global { +export interface Global extends NodeJS.Global { it: It; test: ItConcurrent; fit: ItBase; From d8ff4eaae7324cbed64553a65a8bf30eb8feedf2 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 25 Feb 2019 01:36:54 +0100 Subject: [PATCH 19/26] reuse ForkOptions from node core instead of redefining them (wrongly) --- packages/jest-runner/src/index.ts | 2 -- packages/jest-worker/src/types.ts | 16 ++++------------ 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/packages/jest-runner/src/index.ts b/packages/jest-runner/src/index.ts index c602d29fbc23..7543098d8d7a 100644 --- a/packages/jest-runner/src/index.ts +++ b/packages/jest-runner/src/index.ts @@ -101,8 +101,6 @@ class TestRunner { onResult: OnTestSuccess, onFailure: OnTestFailure, ) { - // TODO: Resolve typing since this is correct code - //@ts-ignore const worker = new Worker(TEST_WORKER_PATH, { exposedMethods: ['worker'], forkOptions: {stdio: 'pipe'}, diff --git a/packages/jest-worker/src/types.ts b/packages/jest-worker/src/types.ts index f0f4d86aecae..3518bee46fa9 100644 --- a/packages/jest-worker/src/types.ts +++ b/packages/jest-worker/src/types.ts @@ -5,6 +5,9 @@ * LICENSE file in the root directory of this source tree. */ +import EventEmitter from 'events'; +import {ForkOptions} from 'child_process'; + // Because of the dynamic nature of a worker communication process, all messages // coming from any of the other processes cannot be typed. Thus, many types // include "unknown" as a TS type, which is (unfortunately) correct here. @@ -23,18 +26,7 @@ export type PARENT_MESSAGE_ERROR = // Option objects. -const EventEmitter = require('events'); - -export type ForkOptions = { - cwd?: string; - env?: NodeJS.ProcessEnv; - execPath?: string; - execArgv?: Array; - silent?: boolean; - stdio?: Array; - uid?: number; - gid?: number; -}; +export {ForkOptions}; export interface WorkerPoolInterface { getStderr(): NodeJS.ReadableStream; From bca1d290f1c5a21e37e1256fa891b6c0777a96eb Mon Sep 17 00:00:00 2001 From: Alcedo Nathaniel De Guzman Jr Date: Mon, 25 Feb 2019 08:54:07 +0800 Subject: [PATCH 20/26] Update changelog to include info about jest-runner typescript migration --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 227365427b90..6860dc1db887 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,7 @@ - `[expect]`: Migrate to TypeScript ([#7919](https://github.com/facebook/jest/pull/7919)) - `[jest-circus]`: Migrate to TypeScript ([#7916](https://github.com/facebook/jest/pull/7916)) - `[jest-phabricator]`: Migrate to TypeScript ([#7965](https://github.com/facebook/jest/pull/7965)) +- `[jest-runner]`: Migrate to TypeScript ([#7968](https://github.com/facebook/jest/pull/7968)) ### Performance From 951dadca052b632825b093bbf407843198323228 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 25 Feb 2019 02:34:00 +0100 Subject: [PATCH 21/26] final type tweak --- packages/jest-runner/src/index.ts | 10 +++------- packages/jest-runner/src/runTest.ts | 27 ++++++++++++++++----------- packages/jest-runner/src/types.ts | 7 +++---- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/jest-runner/src/index.ts b/packages/jest-runner/src/index.ts index 7543098d8d7a..cd372ed5ddde 100644 --- a/packages/jest-runner/src/index.ts +++ b/packages/jest-runner/src/index.ts @@ -3,7 +3,6 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - * */ import {Config, TestResult} from '@jest/types'; @@ -20,17 +19,14 @@ import { TestRunnerContext, TestRunnerOptions, TestWatcher, + WatcherState, } from './types'; const TEST_WORKER_PATH = require.resolve('./testWorker'); -type WorkerInterface = Worker & { +interface WorkerInterface extends Worker { worker: (workerData: WorkerData) => Promise; -}; - -type WatcherState = { - interrupted: boolean; -}; +} class TestRunner { private _globalConfig: Config.GlobalConfig; diff --git a/packages/jest-runner/src/runTest.ts b/packages/jest-runner/src/runTest.ts index ad9c620889b2..7b581863bb2a 100644 --- a/packages/jest-runner/src/runTest.ts +++ b/packages/jest-runner/src/runTest.ts @@ -29,7 +29,9 @@ import Resolver from 'jest-resolve'; import {getTestEnvironment} from 'jest-config'; import * as docblock from 'jest-docblock'; import {formatExecError} from 'jest-message-util'; -import sourcemapSupport from 'source-map-support'; +import sourcemapSupport, { + Options as SourceMapOptions, +} from 'source-map-support'; import chalk from 'chalk'; import {TestFramework, TestRunnerContext} from './types'; @@ -43,7 +45,10 @@ function freezeConsole( testConsole: BufferedConsole | Console | NullConsole, config: Config.ProjectConfig, ) { - testConsole._log = function fakeConsolePush(_type: unknown, message: string) { + testConsole._log = function fakeConsolePush( + _type: ConsoleType.LogType, + message: ConsoleType.LogMessage, + ) { const error = new ErrorWithStack( `${chalk.red( `${chalk.bold( @@ -96,13 +101,14 @@ async function runTestInternal( }); } - const TestEnvironment = require(testEnvironment) as Environment.EnvironmentClass; - const testFramework = (process.env.JEST_CIRCUS === '1' - ? require('jest-circus/runner') // eslint-disable-line import/no-extraneous-dependencies - : require(config.testRunner)) as TestFramework; - const Runtime = (config.moduleLoader + const TestEnvironment: Environment.EnvironmentClass = require(testEnvironment); + const testFramework: TestFramework = + process.env.JEST_CIRCUS === '1' + ? require('jest-circus/runner') // eslint-disable-line import/no-extraneous-dependencies + : require(config.testRunner); + const Runtime: RuntimeClass = config.moduleLoader ? require(config.moduleLoader) - : require('jest-runtime')) as RuntimeClass; + : require('jest-runtime'); let runtime: RuntimeClass = undefined; @@ -143,7 +149,6 @@ async function runTestInternal( : null; const cacheFS = {[path]: testSource}; - setGlobal(environment.global, 'console', testConsole); runtime = new Runtime(config, environment, resolver, cacheFS, { @@ -155,10 +160,10 @@ async function runTestInternal( const start = Date.now(); - const sourcemapOptions: sourcemapSupport.Options = { + const sourcemapOptions: SourceMapOptions = { environment: 'node', handleUncaughtExceptions: false, - retrieveSourceMap: (source: string) => { + retrieveSourceMap: source => { const sourceMaps = runtime && runtime.getSourceMaps(); const sourceMapSource = sourceMaps && sourceMaps[source]; diff --git a/packages/jest-runner/src/types.ts b/packages/jest-runner/src/types.ts index 27551bfb36ce..7193eab96e1c 100644 --- a/packages/jest-runner/src/types.ts +++ b/packages/jest-runner/src/types.ts @@ -3,7 +3,6 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - * */ import EventEmitter from 'events'; @@ -83,13 +82,13 @@ export type TestRunData = Array<{ }>; // TODO: Should live in `@jest/core` or `jest-watcher` -declare type State = { +export type WatcherState = { interrupted: boolean; }; export interface TestWatcher extends EventEmitter { - state: State; + state: WatcherState; new ({isWatchMode}: {isWatchMode: boolean}): TestWatcher; - setState(state: State): void; + setState(state: WatcherState): void; isInterrupted(): boolean; isWatchMode(): boolean; } From 949baad94cb3610492183a17556be8fdad0d4634 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 25 Feb 2019 02:42:33 +0100 Subject: [PATCH 22/26] i lied, one more --- packages/jest-runner/src/index.ts | 4 ++-- packages/jest-runner/src/testWorker.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/jest-runner/src/index.ts b/packages/jest-runner/src/index.ts index cd372ed5ddde..e50e94fcf8e3 100644 --- a/packages/jest-runner/src/index.ts +++ b/packages/jest-runner/src/index.ts @@ -10,7 +10,7 @@ import exit from 'exit'; import throat from 'throat'; import Worker from 'jest-worker'; import runTest from './runTest'; -import {WorkerData} from './testWorker'; +import {worker} from './testWorker'; import { OnTestFailure, OnTestStart, @@ -25,7 +25,7 @@ import { const TEST_WORKER_PATH = require.resolve('./testWorker'); interface WorkerInterface extends Worker { - worker: (workerData: WorkerData) => Promise; + worker: typeof worker; } class TestRunner { diff --git a/packages/jest-runner/src/testWorker.ts b/packages/jest-runner/src/testWorker.ts index 83fc9ab56253..51c8fbc3dd1c 100644 --- a/packages/jest-runner/src/testWorker.ts +++ b/packages/jest-runner/src/testWorker.ts @@ -15,7 +15,7 @@ import Runtime from 'jest-runtime'; import {ErrorWithCode, TestRunnerContext} from './types'; import runTest from './runTest'; -export type WorkerData = { +type WorkerData = { config: Config.ProjectConfig; globalConfig: Config.GlobalConfig; path: Config.Path; From 266a8c98d7b3a4f2860a247d2ee812a5a0c303f5 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 25 Feb 2019 02:45:12 +0100 Subject: [PATCH 23/26] --wip-- [skip ci] --- packages/jest-runner/build/index.js | 220 +++++++++++ packages/jest-runner/build/runTest.js | 455 +++++++++++++++++++++++ packages/jest-runner/build/testWorker.js | 167 +++++++++ packages/jest-runner/build/types.js | 1 + 4 files changed, 843 insertions(+) create mode 100644 packages/jest-runner/build/index.js create mode 100644 packages/jest-runner/build/runTest.js create mode 100644 packages/jest-runner/build/testWorker.js create mode 100644 packages/jest-runner/build/types.js diff --git a/packages/jest-runner/build/index.js b/packages/jest-runner/build/index.js new file mode 100644 index 000000000000..d9b5092bd803 --- /dev/null +++ b/packages/jest-runner/build/index.js @@ -0,0 +1,220 @@ +'use strict'; + +function _exit() { + const data = _interopRequireDefault(require('exit')); + + _exit = function _exit() { + return data; + }; + + return data; +} + +function _throat() { + const data = _interopRequireDefault(require('throat')); + + _throat = function _throat() { + return data; + }; + + return data; +} + +function _jestWorker() { + const data = _interopRequireDefault(require('jest-worker')); + + _jestWorker = function _jestWorker() { + return data; + }; + + return data; +} + +var _runTest = _interopRequireDefault(require('./runTest')); + +var _testWorker = require('./testWorker'); + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : {default: obj}; +} + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } + if (info.done) { + resolve(value); + } else { + Promise.resolve(value).then(_next, _throw); + } +} + +function _asyncToGenerator(fn) { + return function() { + var self = this, + args = arguments; + return new Promise(function(resolve, reject) { + var gen = fn.apply(self, args); + function _next(value) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'next', value); + } + function _throw(err) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'throw', err); + } + _next(undefined); + }); + }; +} + +const TEST_WORKER_PATH = require.resolve('./testWorker'); + +class TestRunner { + constructor(globalConfig, context) { + this._globalConfig = globalConfig; + this._context = context || {}; + } + + runTests(tests, watcher, onStart, onResult, onFailure, options) { + var _this = this; + + return _asyncToGenerator(function*() { + return yield options.serial + ? _this._createInBandTestRun( + tests, + watcher, + onStart, + onResult, + onFailure + ) + : _this._createParallelTestRun( + tests, + watcher, + onStart, + onResult, + onFailure + ); + })(); + } + + _createInBandTestRun(tests, watcher, onStart, onResult, onFailure) { + var _this2 = this; + + return _asyncToGenerator(function*() { + process.env.JEST_WORKER_ID = '1'; + const mutex = (0, _throat().default)(1); + return tests.reduce( + (promise, test) => + mutex(() => + promise + .then( + /*#__PURE__*/ + _asyncToGenerator(function*() { + if (watcher.isInterrupted()) { + throw new CancelRun(); + } + + yield onStart(test); + return (0, + _runTest.default)(test.path, _this2._globalConfig, test.context.config, test.context.resolver, _this2._context); + }) + ) + .then(result => onResult(test, result)) + .catch(err => onFailure(test, err)) + ), + Promise.resolve() + ); + })(); + } + + _createParallelTestRun(tests, watcher, onStart, onResult, onFailure) { + var _this3 = this; + + return _asyncToGenerator(function*() { + const worker = new (_jestWorker()).default(TEST_WORKER_PATH, { + exposedMethods: ['worker'], + forkOptions: { + stdio: 'pipe' + }, + maxRetries: 3, + numWorkers: _this3._globalConfig.maxWorkers + }); + if (worker.getStdout()) worker.getStdout().pipe(process.stdout); + if (worker.getStderr()) worker.getStderr().pipe(process.stderr); + const mutex = (0, _throat().default)(_this3._globalConfig.maxWorkers); // Send test suites to workers continuously instead of all at once to track + // the start time of individual tests. + + const runTestInWorker = test => + mutex( + /*#__PURE__*/ + _asyncToGenerator(function*() { + if (watcher.isInterrupted()) { + return Promise.reject(); + } + + yield onStart(test); + return worker.worker({ + config: test.context.config, + context: _this3._context, + globalConfig: _this3._globalConfig, + path: test.path, + serializableModuleMap: watcher.isWatchMode() + ? test.context.moduleMap.toJSON() + : null + }); + }) + ); + + const onError = + /*#__PURE__*/ + (function() { + var _ref3 = _asyncToGenerator(function*(err, test) { + yield onFailure(test, err); + + if (err.type === 'ProcessTerminatedError') { + console.error( + 'A worker process has quit unexpectedly! ' + + 'Most likely this is an initialization error.' + ); + (0, _exit().default)(1); + } + }); + + return function onError(_x, _x2) { + return _ref3.apply(this, arguments); + }; + })(); + + const onInterrupt = new Promise((_, reject) => { + watcher.on('change', state => { + if (state.interrupted) { + reject(new CancelRun()); + } + }); + }); + const runAllTests = Promise.all( + tests.map(test => + runTestInWorker(test) + .then(testResult => onResult(test, testResult)) + .catch(error => onError(error, test)) + ) + ); + + const cleanup = () => worker.end(); + + return Promise.race([runAllTests, onInterrupt]).then(cleanup, cleanup); + })(); + } +} + +class CancelRun extends Error { + constructor(message) { + super(message); + this.name = 'CancelRun'; + } +} + +module.exports = TestRunner; diff --git a/packages/jest-runner/build/runTest.js b/packages/jest-runner/build/runTest.js new file mode 100644 index 000000000000..5439bd4fe7d9 --- /dev/null +++ b/packages/jest-runner/build/runTest.js @@ -0,0 +1,455 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.default = runTest; + +function _gracefulFs() { + const data = _interopRequireDefault(require('graceful-fs')); + + _gracefulFs = function _gracefulFs() { + return data; + }; + + return data; +} + +function _jestUtil() { + const data = require('jest-util'); + + _jestUtil = function _jestUtil() { + return data; + }; + + return data; +} + +function _jestLeakDetector() { + const data = _interopRequireDefault(require('jest-leak-detector')); + + _jestLeakDetector = function _jestLeakDetector() { + return data; + }; + + return data; +} + +function _jestConfig() { + const data = require('jest-config'); + + _jestConfig = function _jestConfig() { + return data; + }; + + return data; +} + +function docblock() { + const data = _interopRequireWildcard(require('jest-docblock')); + + docblock = function docblock() { + return data; + }; + + return data; +} + +function _jestMessageUtil() { + const data = require('jest-message-util'); + + _jestMessageUtil = function _jestMessageUtil() { + return data; + }; + + return data; +} + +function _sourceMapSupport() { + const data = _interopRequireDefault(require('source-map-support')); + + _sourceMapSupport = function _sourceMapSupport() { + return data; + }; + + return data; +} + +function _chalk() { + const data = _interopRequireDefault(require('chalk')); + + _chalk = function _chalk() { + return data; + }; + + return data; +} + +function _interopRequireWildcard(obj) { + if (obj && obj.__esModule) { + return obj; + } else { + var newObj = {}; + if (obj != null) { + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + var desc = + Object.defineProperty && Object.getOwnPropertyDescriptor + ? Object.getOwnPropertyDescriptor(obj, key) + : {}; + if (desc.get || desc.set) { + Object.defineProperty(newObj, key, desc); + } else { + newObj[key] = obj[key]; + } + } + } + } + newObj.default = obj; + return newObj; + } +} + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : {default: obj}; +} + +function _objectSpread(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + var ownKeys = Object.keys(source); + if (typeof Object.getOwnPropertySymbols === 'function') { + ownKeys = ownKeys.concat( + Object.getOwnPropertySymbols(source).filter(function(sym) { + return Object.getOwnPropertyDescriptor(source, sym).enumerable; + }) + ); + } + ownKeys.forEach(function(key) { + _defineProperty(target, key, source[key]); + }); + } + return target; +} + +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + return obj; +} + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } + if (info.done) { + resolve(value); + } else { + Promise.resolve(value).then(_next, _throw); + } +} + +function _asyncToGenerator(fn) { + return function() { + var self = this, + args = arguments; + return new Promise(function(resolve, reject) { + var gen = fn.apply(self, args); + function _next(value) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'next', value); + } + function _throw(err) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'throw', err); + } + _next(undefined); + }); + }; +} + +function freezeConsole(testConsole, config) { // @ts-ignore: Correct types when `jest-util` is ESM + testConsole._log = function fakeConsolePush(_type, message) { + const error = new (_jestUtil()).ErrorWithStack( + `${_chalk().default.red( + `${_chalk().default.bold( + 'Cannot log after tests are done.' + )} Did you forget to wait for something async in your test?` + )}\nAttempted to log "${message}".`, + fakeConsolePush + ); + const formattedError = (0, _jestMessageUtil().formatExecError)( + error, + config, + { + noStackTrace: false + }, + undefined, + true + ); + process.stderr.write('\n' + formattedError + '\n'); // TODO: set exit code in Jest 25 + // process.exitCode = 1; + }; +} // Keeping the core of "runTest" as a separate function (as "runTestInternal") +// is key to be able to detect memory leaks. Since all variables are local to +// the function, when "runTestInternal" finishes its execution, they can all be +// freed, UNLESS something else is leaking them (and that's why we can detect +// the leak!). +// +// If we had all the code in a single function, we should manually nullify all +// references to verify if there is a leak, which is not maintainable and error +// prone. That's why "runTestInternal" CANNOT be inlined inside "runTest". + +function runTestInternal(_x, _x2, _x3, _x4, _x5) { + return _runTestInternal.apply(this, arguments); +} + +function _runTestInternal() { + _runTestInternal = _asyncToGenerator(function*( + path, + globalConfig, + config, + resolver, + context + ) { + const testSource = _gracefulFs().default.readFileSync(path, 'utf8'); + + const parsedDocblock = docblock().parse(docblock().extract(testSource)); + const customEnvironment = parsedDocblock['jest-environment']; + let testEnvironment = config.testEnvironment; + + if (customEnvironment) { + testEnvironment = (0, _jestConfig().getTestEnvironment)( + _objectSpread({}, config, { + testEnvironment: customEnvironment + }) + ); + } + + const TestEnvironment = require(testEnvironment); + + const testFramework = + process.env.JEST_CIRCUS === '1' + ? require('jest-circus/runner') // eslint-disable-line import/no-extraneous-dependencies + : require(config.testRunner); + const Runtime = config.moduleLoader + ? require(config.moduleLoader) + : require('jest-runtime'); + let runtime = undefined; + const consoleOut = globalConfig.useStderr ? process.stderr : process.stdout; + + const consoleFormatter = (type, message) => + (0, _jestUtil().getConsoleOutput)( + config.cwd, + !!globalConfig.verbose, // 4 = the console call is buried 4 stack frames deep + _jestUtil().BufferedConsole.write( + [], + type, + message, + 4, + runtime && runtime.getSourceMaps() + ) + ); + + let testConsole; + + if (globalConfig.silent) { + testConsole = new (_jestUtil()).NullConsole( + consoleOut, + process.stderr, + consoleFormatter + ); + } else if (globalConfig.verbose) { + testConsole = new (_jestUtil()).Console( + consoleOut, + process.stderr, + consoleFormatter + ); + } else { + testConsole = new (_jestUtil()).BufferedConsole( + () => runtime && runtime.getSourceMaps() + ); + } + + const environment = new TestEnvironment(config, { + console: testConsole, + testPath: path + }); + const leakDetector = config.detectLeaks + ? new (_jestLeakDetector()).default(environment) + : null; + const cacheFS = { + [path]: testSource + }; + (0, _jestUtil().setGlobal)(environment.global, 'console', testConsole); + runtime = new Runtime(config, environment, resolver, cacheFS, { + changedFiles: context && context.changedFiles, + collectCoverage: globalConfig.collectCoverage, + collectCoverageFrom: globalConfig.collectCoverageFrom, + collectCoverageOnlyFrom: globalConfig.collectCoverageOnlyFrom + }); + const start = Date.now(); + const sourcemapOptions = { + environment: 'node', + handleUncaughtExceptions: false, + retrieveSourceMap: source => { + const sourceMaps = runtime && runtime.getSourceMaps(); + const sourceMapSource = sourceMaps && sourceMaps[source]; + + if (sourceMapSource) { + try { + return { + map: JSON.parse( + _gracefulFs().default.readFileSync(sourceMapSource, 'utf8') + ), + url: source + }; + } catch (e) {} + } + + return null; + } + }; // For tests + + runtime + .requireInternalModule( + require.resolve('source-map-support'), + 'source-map-support' + ) + .install(sourcemapOptions); // For runtime errors + + _sourceMapSupport().default.install(sourcemapOptions); + + if ( + environment.global && + environment.global.process && + environment.global.process.exit + ) { + const realExit = environment.global.process.exit; + + environment.global.process.exit = function exit(...args) { + const error = new (_jestUtil()).ErrorWithStack( + `process.exit called with "${args.join(', ')}"`, + exit + ); + const formattedError = (0, _jestMessageUtil().formatExecError)( + error, + config, + { + noStackTrace: false + }, + undefined, + true + ); + process.stderr.write(formattedError); + return realExit(...args); + }; + } + + try { + yield environment.setup(); + let result; + + try { + result = yield testFramework( + globalConfig, + config, + environment, + runtime, + path + ); + } catch (err) { + // Access stack before uninstalling sourcemaps + err.stack; + throw err; + } + + freezeConsole(testConsole, config); + const testCount = + result.numPassingTests + + result.numFailingTests + + result.numPendingTests + + result.numTodoTests; + result.perfStats = { + end: Date.now(), + start + }; + result.testFilePath = path; + result.coverage = runtime.getAllCoverageInfoCopy(); + result.sourceMaps = runtime.getSourceMapInfo( + new Set(Object.keys(result.coverage || {})) + ); + result.console = testConsole.getBuffer(); + result.skipped = testCount === result.numPendingTests; + result.displayName = config.displayName; + + if (globalConfig.logHeapUsage) { + if (global.gc) { + global.gc(); + } + + result.memoryUsage = process.memoryUsage().heapUsed; + } // Delay the resolution to allow log messages to be output. + + return new Promise(resolve => { + setImmediate(() => + resolve({ + leakDetector, + result + }) + ); + }); + } finally { + yield environment.teardown(); // @ts-ignore: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/33351 + + _sourceMapSupport().default.resetRetrieveHandlers(); + } + }); + return _runTestInternal.apply(this, arguments); +} + +function runTest(_x6, _x7, _x8, _x9, _x10) { + return _runTest.apply(this, arguments); +} + +function _runTest() { + _runTest = _asyncToGenerator(function*( + path, + globalConfig, + config, + resolver, + context + ) { + const _ref = yield runTestInternal( + path, + globalConfig, + config, + resolver, + context + ), + leakDetector = _ref.leakDetector, + result = _ref.result; + + if (leakDetector) { + // We wanna allow a tiny but time to pass to allow last-minute cleanup + yield new Promise(resolve => setTimeout(resolve, 100)); // Resolve leak detector, outside the "runTestInternal" closure. + + result.leaks = leakDetector.isLeaking(); + } else { + result.leaks = false; + } + + return result; + }); + return _runTest.apply(this, arguments); +} diff --git a/packages/jest-runner/build/testWorker.js b/packages/jest-runner/build/testWorker.js new file mode 100644 index 000000000000..ba8bc6c58596 --- /dev/null +++ b/packages/jest-runner/build/testWorker.js @@ -0,0 +1,167 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.worker = worker; + +function _jestHasteMap() { + const data = _interopRequireDefault(require('jest-haste-map')); + + _jestHasteMap = function _jestHasteMap() { + return data; + }; + + return data; +} + +function _exit() { + const data = _interopRequireDefault(require('exit')); + + _exit = function _exit() { + return data; + }; + + return data; +} + +function _jestMessageUtil() { + const data = require('jest-message-util'); + + _jestMessageUtil = function _jestMessageUtil() { + return data; + }; + + return data; +} + +function _jestRuntime() { + const data = _interopRequireDefault(require('jest-runtime')); + + _jestRuntime = function _jestRuntime() { + return data; + }; + + return data; +} + +var _runTest = _interopRequireDefault(require('./runTest')); + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : {default: obj}; +} + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } + if (info.done) { + resolve(value); + } else { + Promise.resolve(value).then(_next, _throw); + } +} + +function _asyncToGenerator(fn) { + return function() { + var self = this, + args = arguments; + return new Promise(function(resolve, reject) { + var gen = fn.apply(self, args); + function _next(value) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'next', value); + } + function _throw(err) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'throw', err); + } + _next(undefined); + }); + }; +} + +// Make sure uncaught errors are logged before we exit. +process.on('uncaughtException', err => { + console.error(err.stack); + (0, _exit().default)(1); +}); + +const formatError = error => { + if (typeof error === 'string') { + const _separateMessageFromS = (0, + _jestMessageUtil().separateMessageFromStack)(error), + message = _separateMessageFromS.message, + stack = _separateMessageFromS.stack; + + return { + message, + stack, + type: 'Error' + }; + } + + return { + code: error.code || undefined, + message: error.message, + stack: error.stack, + type: 'Error' + }; +}; + +const resolvers = Object.create(null); + +const getResolver = (config, moduleMap) => { + // In watch mode, the raw module map with all haste modules is passed from + // the test runner to the watch command. This is because jest-haste-map's + // watch mode does not persist the haste map on disk after every file change. + // To make this fast and consistent, we pass it from the TestRunner. + if (moduleMap) { + return _jestRuntime().default.createResolver(config, moduleMap); + } else { + const name = config.name; + + if (!resolvers[name]) { + resolvers[name] = _jestRuntime().default.createResolver( + config, + _jestRuntime() + .default.createHasteMap(config) + .readModuleMap() + ); + } + + return resolvers[name]; + } +}; + +function worker(_x) { + return _worker.apply(this, arguments); +} + +function _worker() { + _worker = _asyncToGenerator(function*({ + config, + globalConfig, + path, + serializableModuleMap, + context + }) { + try { + const moduleMap = serializableModuleMap + ? _jestHasteMap().default.ModuleMap.fromJSON(serializableModuleMap) + : null; + return yield (0, _runTest.default)( + path, + globalConfig, + config, + getResolver(config, moduleMap), + context + ); + } catch (error) { + throw formatError(error); + } + }); + return _worker.apply(this, arguments); +} diff --git a/packages/jest-runner/build/types.js b/packages/jest-runner/build/types.js new file mode 100644 index 000000000000..ad9a93a7c160 --- /dev/null +++ b/packages/jest-runner/build/types.js @@ -0,0 +1 @@ +'use strict'; From 01485d435fb7ca746a7c7b686bda3782d4eb7ab0 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 25 Feb 2019 09:42:35 +0100 Subject: [PATCH 24/26] named import --- packages/jest-worker/src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-worker/src/types.ts b/packages/jest-worker/src/types.ts index 3518bee46fa9..ce25219f525c 100644 --- a/packages/jest-worker/src/types.ts +++ b/packages/jest-worker/src/types.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import EventEmitter from 'events'; +import {EventEmitter} from 'events'; import {ForkOptions} from 'child_process'; // Because of the dynamic nature of a worker communication process, all messages From a1e9a6b51594313d55435fb3bed24b037031246d Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 25 Feb 2019 09:45:06 +0100 Subject: [PATCH 25/26] another named --- packages/jest-runner/src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-runner/src/types.ts b/packages/jest-runner/src/types.ts index 7193eab96e1c..5f1aeb7c557a 100644 --- a/packages/jest-runner/src/types.ts +++ b/packages/jest-runner/src/types.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import EventEmitter from 'events'; +import {EventEmitter} from 'events'; import {Environment, Config, TestResult} from '@jest/types'; import {ModuleMap, FS as HasteFS} from 'jest-haste-map'; import HasteResolver from 'jest-resolve'; From b926c322aefc27775fa4aaec4be554955d5b5fac Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 25 Feb 2019 10:58:44 +0100 Subject: [PATCH 26/26] Revert "--wip-- [skip ci]" This reverts commit 266a8c98d7b3a4f2860a247d2ee812a5a0c303f5. --- packages/jest-runner/build/index.js | 220 ----------- packages/jest-runner/build/runTest.js | 455 ----------------------- packages/jest-runner/build/testWorker.js | 167 --------- packages/jest-runner/build/types.js | 1 - 4 files changed, 843 deletions(-) delete mode 100644 packages/jest-runner/build/index.js delete mode 100644 packages/jest-runner/build/runTest.js delete mode 100644 packages/jest-runner/build/testWorker.js delete mode 100644 packages/jest-runner/build/types.js diff --git a/packages/jest-runner/build/index.js b/packages/jest-runner/build/index.js deleted file mode 100644 index d9b5092bd803..000000000000 --- a/packages/jest-runner/build/index.js +++ /dev/null @@ -1,220 +0,0 @@ -'use strict'; - -function _exit() { - const data = _interopRequireDefault(require('exit')); - - _exit = function _exit() { - return data; - }; - - return data; -} - -function _throat() { - const data = _interopRequireDefault(require('throat')); - - _throat = function _throat() { - return data; - }; - - return data; -} - -function _jestWorker() { - const data = _interopRequireDefault(require('jest-worker')); - - _jestWorker = function _jestWorker() { - return data; - }; - - return data; -} - -var _runTest = _interopRequireDefault(require('./runTest')); - -var _testWorker = require('./testWorker'); - -function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : {default: obj}; -} - -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { - try { - var info = gen[key](arg); - var value = info.value; - } catch (error) { - reject(error); - return; - } - if (info.done) { - resolve(value); - } else { - Promise.resolve(value).then(_next, _throw); - } -} - -function _asyncToGenerator(fn) { - return function() { - var self = this, - args = arguments; - return new Promise(function(resolve, reject) { - var gen = fn.apply(self, args); - function _next(value) { - asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'next', value); - } - function _throw(err) { - asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'throw', err); - } - _next(undefined); - }); - }; -} - -const TEST_WORKER_PATH = require.resolve('./testWorker'); - -class TestRunner { - constructor(globalConfig, context) { - this._globalConfig = globalConfig; - this._context = context || {}; - } - - runTests(tests, watcher, onStart, onResult, onFailure, options) { - var _this = this; - - return _asyncToGenerator(function*() { - return yield options.serial - ? _this._createInBandTestRun( - tests, - watcher, - onStart, - onResult, - onFailure - ) - : _this._createParallelTestRun( - tests, - watcher, - onStart, - onResult, - onFailure - ); - })(); - } - - _createInBandTestRun(tests, watcher, onStart, onResult, onFailure) { - var _this2 = this; - - return _asyncToGenerator(function*() { - process.env.JEST_WORKER_ID = '1'; - const mutex = (0, _throat().default)(1); - return tests.reduce( - (promise, test) => - mutex(() => - promise - .then( - /*#__PURE__*/ - _asyncToGenerator(function*() { - if (watcher.isInterrupted()) { - throw new CancelRun(); - } - - yield onStart(test); - return (0, - _runTest.default)(test.path, _this2._globalConfig, test.context.config, test.context.resolver, _this2._context); - }) - ) - .then(result => onResult(test, result)) - .catch(err => onFailure(test, err)) - ), - Promise.resolve() - ); - })(); - } - - _createParallelTestRun(tests, watcher, onStart, onResult, onFailure) { - var _this3 = this; - - return _asyncToGenerator(function*() { - const worker = new (_jestWorker()).default(TEST_WORKER_PATH, { - exposedMethods: ['worker'], - forkOptions: { - stdio: 'pipe' - }, - maxRetries: 3, - numWorkers: _this3._globalConfig.maxWorkers - }); - if (worker.getStdout()) worker.getStdout().pipe(process.stdout); - if (worker.getStderr()) worker.getStderr().pipe(process.stderr); - const mutex = (0, _throat().default)(_this3._globalConfig.maxWorkers); // Send test suites to workers continuously instead of all at once to track - // the start time of individual tests. - - const runTestInWorker = test => - mutex( - /*#__PURE__*/ - _asyncToGenerator(function*() { - if (watcher.isInterrupted()) { - return Promise.reject(); - } - - yield onStart(test); - return worker.worker({ - config: test.context.config, - context: _this3._context, - globalConfig: _this3._globalConfig, - path: test.path, - serializableModuleMap: watcher.isWatchMode() - ? test.context.moduleMap.toJSON() - : null - }); - }) - ); - - const onError = - /*#__PURE__*/ - (function() { - var _ref3 = _asyncToGenerator(function*(err, test) { - yield onFailure(test, err); - - if (err.type === 'ProcessTerminatedError') { - console.error( - 'A worker process has quit unexpectedly! ' + - 'Most likely this is an initialization error.' - ); - (0, _exit().default)(1); - } - }); - - return function onError(_x, _x2) { - return _ref3.apply(this, arguments); - }; - })(); - - const onInterrupt = new Promise((_, reject) => { - watcher.on('change', state => { - if (state.interrupted) { - reject(new CancelRun()); - } - }); - }); - const runAllTests = Promise.all( - tests.map(test => - runTestInWorker(test) - .then(testResult => onResult(test, testResult)) - .catch(error => onError(error, test)) - ) - ); - - const cleanup = () => worker.end(); - - return Promise.race([runAllTests, onInterrupt]).then(cleanup, cleanup); - })(); - } -} - -class CancelRun extends Error { - constructor(message) { - super(message); - this.name = 'CancelRun'; - } -} - -module.exports = TestRunner; diff --git a/packages/jest-runner/build/runTest.js b/packages/jest-runner/build/runTest.js deleted file mode 100644 index 5439bd4fe7d9..000000000000 --- a/packages/jest-runner/build/runTest.js +++ /dev/null @@ -1,455 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { - value: true -}); -exports.default = runTest; - -function _gracefulFs() { - const data = _interopRequireDefault(require('graceful-fs')); - - _gracefulFs = function _gracefulFs() { - return data; - }; - - return data; -} - -function _jestUtil() { - const data = require('jest-util'); - - _jestUtil = function _jestUtil() { - return data; - }; - - return data; -} - -function _jestLeakDetector() { - const data = _interopRequireDefault(require('jest-leak-detector')); - - _jestLeakDetector = function _jestLeakDetector() { - return data; - }; - - return data; -} - -function _jestConfig() { - const data = require('jest-config'); - - _jestConfig = function _jestConfig() { - return data; - }; - - return data; -} - -function docblock() { - const data = _interopRequireWildcard(require('jest-docblock')); - - docblock = function docblock() { - return data; - }; - - return data; -} - -function _jestMessageUtil() { - const data = require('jest-message-util'); - - _jestMessageUtil = function _jestMessageUtil() { - return data; - }; - - return data; -} - -function _sourceMapSupport() { - const data = _interopRequireDefault(require('source-map-support')); - - _sourceMapSupport = function _sourceMapSupport() { - return data; - }; - - return data; -} - -function _chalk() { - const data = _interopRequireDefault(require('chalk')); - - _chalk = function _chalk() { - return data; - }; - - return data; -} - -function _interopRequireWildcard(obj) { - if (obj && obj.__esModule) { - return obj; - } else { - var newObj = {}; - if (obj != null) { - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - var desc = - Object.defineProperty && Object.getOwnPropertyDescriptor - ? Object.getOwnPropertyDescriptor(obj, key) - : {}; - if (desc.get || desc.set) { - Object.defineProperty(newObj, key, desc); - } else { - newObj[key] = obj[key]; - } - } - } - } - newObj.default = obj; - return newObj; - } -} - -function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : {default: obj}; -} - -function _objectSpread(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i] != null ? arguments[i] : {}; - var ownKeys = Object.keys(source); - if (typeof Object.getOwnPropertySymbols === 'function') { - ownKeys = ownKeys.concat( - Object.getOwnPropertySymbols(source).filter(function(sym) { - return Object.getOwnPropertyDescriptor(source, sym).enumerable; - }) - ); - } - ownKeys.forEach(function(key) { - _defineProperty(target, key, source[key]); - }); - } - return target; -} - -function _defineProperty(obj, key, value) { - if (key in obj) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - } else { - obj[key] = value; - } - return obj; -} - -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { - try { - var info = gen[key](arg); - var value = info.value; - } catch (error) { - reject(error); - return; - } - if (info.done) { - resolve(value); - } else { - Promise.resolve(value).then(_next, _throw); - } -} - -function _asyncToGenerator(fn) { - return function() { - var self = this, - args = arguments; - return new Promise(function(resolve, reject) { - var gen = fn.apply(self, args); - function _next(value) { - asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'next', value); - } - function _throw(err) { - asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'throw', err); - } - _next(undefined); - }); - }; -} - -function freezeConsole(testConsole, config) { // @ts-ignore: Correct types when `jest-util` is ESM - testConsole._log = function fakeConsolePush(_type, message) { - const error = new (_jestUtil()).ErrorWithStack( - `${_chalk().default.red( - `${_chalk().default.bold( - 'Cannot log after tests are done.' - )} Did you forget to wait for something async in your test?` - )}\nAttempted to log "${message}".`, - fakeConsolePush - ); - const formattedError = (0, _jestMessageUtil().formatExecError)( - error, - config, - { - noStackTrace: false - }, - undefined, - true - ); - process.stderr.write('\n' + formattedError + '\n'); // TODO: set exit code in Jest 25 - // process.exitCode = 1; - }; -} // Keeping the core of "runTest" as a separate function (as "runTestInternal") -// is key to be able to detect memory leaks. Since all variables are local to -// the function, when "runTestInternal" finishes its execution, they can all be -// freed, UNLESS something else is leaking them (and that's why we can detect -// the leak!). -// -// If we had all the code in a single function, we should manually nullify all -// references to verify if there is a leak, which is not maintainable and error -// prone. That's why "runTestInternal" CANNOT be inlined inside "runTest". - -function runTestInternal(_x, _x2, _x3, _x4, _x5) { - return _runTestInternal.apply(this, arguments); -} - -function _runTestInternal() { - _runTestInternal = _asyncToGenerator(function*( - path, - globalConfig, - config, - resolver, - context - ) { - const testSource = _gracefulFs().default.readFileSync(path, 'utf8'); - - const parsedDocblock = docblock().parse(docblock().extract(testSource)); - const customEnvironment = parsedDocblock['jest-environment']; - let testEnvironment = config.testEnvironment; - - if (customEnvironment) { - testEnvironment = (0, _jestConfig().getTestEnvironment)( - _objectSpread({}, config, { - testEnvironment: customEnvironment - }) - ); - } - - const TestEnvironment = require(testEnvironment); - - const testFramework = - process.env.JEST_CIRCUS === '1' - ? require('jest-circus/runner') // eslint-disable-line import/no-extraneous-dependencies - : require(config.testRunner); - const Runtime = config.moduleLoader - ? require(config.moduleLoader) - : require('jest-runtime'); - let runtime = undefined; - const consoleOut = globalConfig.useStderr ? process.stderr : process.stdout; - - const consoleFormatter = (type, message) => - (0, _jestUtil().getConsoleOutput)( - config.cwd, - !!globalConfig.verbose, // 4 = the console call is buried 4 stack frames deep - _jestUtil().BufferedConsole.write( - [], - type, - message, - 4, - runtime && runtime.getSourceMaps() - ) - ); - - let testConsole; - - if (globalConfig.silent) { - testConsole = new (_jestUtil()).NullConsole( - consoleOut, - process.stderr, - consoleFormatter - ); - } else if (globalConfig.verbose) { - testConsole = new (_jestUtil()).Console( - consoleOut, - process.stderr, - consoleFormatter - ); - } else { - testConsole = new (_jestUtil()).BufferedConsole( - () => runtime && runtime.getSourceMaps() - ); - } - - const environment = new TestEnvironment(config, { - console: testConsole, - testPath: path - }); - const leakDetector = config.detectLeaks - ? new (_jestLeakDetector()).default(environment) - : null; - const cacheFS = { - [path]: testSource - }; - (0, _jestUtil().setGlobal)(environment.global, 'console', testConsole); - runtime = new Runtime(config, environment, resolver, cacheFS, { - changedFiles: context && context.changedFiles, - collectCoverage: globalConfig.collectCoverage, - collectCoverageFrom: globalConfig.collectCoverageFrom, - collectCoverageOnlyFrom: globalConfig.collectCoverageOnlyFrom - }); - const start = Date.now(); - const sourcemapOptions = { - environment: 'node', - handleUncaughtExceptions: false, - retrieveSourceMap: source => { - const sourceMaps = runtime && runtime.getSourceMaps(); - const sourceMapSource = sourceMaps && sourceMaps[source]; - - if (sourceMapSource) { - try { - return { - map: JSON.parse( - _gracefulFs().default.readFileSync(sourceMapSource, 'utf8') - ), - url: source - }; - } catch (e) {} - } - - return null; - } - }; // For tests - - runtime - .requireInternalModule( - require.resolve('source-map-support'), - 'source-map-support' - ) - .install(sourcemapOptions); // For runtime errors - - _sourceMapSupport().default.install(sourcemapOptions); - - if ( - environment.global && - environment.global.process && - environment.global.process.exit - ) { - const realExit = environment.global.process.exit; - - environment.global.process.exit = function exit(...args) { - const error = new (_jestUtil()).ErrorWithStack( - `process.exit called with "${args.join(', ')}"`, - exit - ); - const formattedError = (0, _jestMessageUtil().formatExecError)( - error, - config, - { - noStackTrace: false - }, - undefined, - true - ); - process.stderr.write(formattedError); - return realExit(...args); - }; - } - - try { - yield environment.setup(); - let result; - - try { - result = yield testFramework( - globalConfig, - config, - environment, - runtime, - path - ); - } catch (err) { - // Access stack before uninstalling sourcemaps - err.stack; - throw err; - } - - freezeConsole(testConsole, config); - const testCount = - result.numPassingTests + - result.numFailingTests + - result.numPendingTests + - result.numTodoTests; - result.perfStats = { - end: Date.now(), - start - }; - result.testFilePath = path; - result.coverage = runtime.getAllCoverageInfoCopy(); - result.sourceMaps = runtime.getSourceMapInfo( - new Set(Object.keys(result.coverage || {})) - ); - result.console = testConsole.getBuffer(); - result.skipped = testCount === result.numPendingTests; - result.displayName = config.displayName; - - if (globalConfig.logHeapUsage) { - if (global.gc) { - global.gc(); - } - - result.memoryUsage = process.memoryUsage().heapUsed; - } // Delay the resolution to allow log messages to be output. - - return new Promise(resolve => { - setImmediate(() => - resolve({ - leakDetector, - result - }) - ); - }); - } finally { - yield environment.teardown(); // @ts-ignore: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/33351 - - _sourceMapSupport().default.resetRetrieveHandlers(); - } - }); - return _runTestInternal.apply(this, arguments); -} - -function runTest(_x6, _x7, _x8, _x9, _x10) { - return _runTest.apply(this, arguments); -} - -function _runTest() { - _runTest = _asyncToGenerator(function*( - path, - globalConfig, - config, - resolver, - context - ) { - const _ref = yield runTestInternal( - path, - globalConfig, - config, - resolver, - context - ), - leakDetector = _ref.leakDetector, - result = _ref.result; - - if (leakDetector) { - // We wanna allow a tiny but time to pass to allow last-minute cleanup - yield new Promise(resolve => setTimeout(resolve, 100)); // Resolve leak detector, outside the "runTestInternal" closure. - - result.leaks = leakDetector.isLeaking(); - } else { - result.leaks = false; - } - - return result; - }); - return _runTest.apply(this, arguments); -} diff --git a/packages/jest-runner/build/testWorker.js b/packages/jest-runner/build/testWorker.js deleted file mode 100644 index ba8bc6c58596..000000000000 --- a/packages/jest-runner/build/testWorker.js +++ /dev/null @@ -1,167 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { - value: true -}); -exports.worker = worker; - -function _jestHasteMap() { - const data = _interopRequireDefault(require('jest-haste-map')); - - _jestHasteMap = function _jestHasteMap() { - return data; - }; - - return data; -} - -function _exit() { - const data = _interopRequireDefault(require('exit')); - - _exit = function _exit() { - return data; - }; - - return data; -} - -function _jestMessageUtil() { - const data = require('jest-message-util'); - - _jestMessageUtil = function _jestMessageUtil() { - return data; - }; - - return data; -} - -function _jestRuntime() { - const data = _interopRequireDefault(require('jest-runtime')); - - _jestRuntime = function _jestRuntime() { - return data; - }; - - return data; -} - -var _runTest = _interopRequireDefault(require('./runTest')); - -function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : {default: obj}; -} - -function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { - try { - var info = gen[key](arg); - var value = info.value; - } catch (error) { - reject(error); - return; - } - if (info.done) { - resolve(value); - } else { - Promise.resolve(value).then(_next, _throw); - } -} - -function _asyncToGenerator(fn) { - return function() { - var self = this, - args = arguments; - return new Promise(function(resolve, reject) { - var gen = fn.apply(self, args); - function _next(value) { - asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'next', value); - } - function _throw(err) { - asyncGeneratorStep(gen, resolve, reject, _next, _throw, 'throw', err); - } - _next(undefined); - }); - }; -} - -// Make sure uncaught errors are logged before we exit. -process.on('uncaughtException', err => { - console.error(err.stack); - (0, _exit().default)(1); -}); - -const formatError = error => { - if (typeof error === 'string') { - const _separateMessageFromS = (0, - _jestMessageUtil().separateMessageFromStack)(error), - message = _separateMessageFromS.message, - stack = _separateMessageFromS.stack; - - return { - message, - stack, - type: 'Error' - }; - } - - return { - code: error.code || undefined, - message: error.message, - stack: error.stack, - type: 'Error' - }; -}; - -const resolvers = Object.create(null); - -const getResolver = (config, moduleMap) => { - // In watch mode, the raw module map with all haste modules is passed from - // the test runner to the watch command. This is because jest-haste-map's - // watch mode does not persist the haste map on disk after every file change. - // To make this fast and consistent, we pass it from the TestRunner. - if (moduleMap) { - return _jestRuntime().default.createResolver(config, moduleMap); - } else { - const name = config.name; - - if (!resolvers[name]) { - resolvers[name] = _jestRuntime().default.createResolver( - config, - _jestRuntime() - .default.createHasteMap(config) - .readModuleMap() - ); - } - - return resolvers[name]; - } -}; - -function worker(_x) { - return _worker.apply(this, arguments); -} - -function _worker() { - _worker = _asyncToGenerator(function*({ - config, - globalConfig, - path, - serializableModuleMap, - context - }) { - try { - const moduleMap = serializableModuleMap - ? _jestHasteMap().default.ModuleMap.fromJSON(serializableModuleMap) - : null; - return yield (0, _runTest.default)( - path, - globalConfig, - config, - getResolver(config, moduleMap), - context - ); - } catch (error) { - throw formatError(error); - } - }); - return _worker.apply(this, arguments); -} diff --git a/packages/jest-runner/build/types.js b/packages/jest-runner/build/types.js deleted file mode 100644 index ad9a93a7c160..000000000000 --- a/packages/jest-runner/build/types.js +++ /dev/null @@ -1 +0,0 @@ -'use strict';