diff options
Diffstat (limited to 'node_modules/jest-runner/build/runTest.js')
-rw-r--r-- | node_modules/jest-runner/build/runTest.js | 494 |
1 files changed, 494 insertions, 0 deletions
diff --git a/node_modules/jest-runner/build/runTest.js b/node_modules/jest-runner/build/runTest.js new file mode 100644 index 0000000..1631e75 --- /dev/null +++ b/node_modules/jest-runner/build/runTest.js @@ -0,0 +1,494 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { + value: true +}); +exports.default = runTest; + +function _chalk() { + const data = _interopRequireDefault(require('chalk')); + + _chalk = function () { + return data; + }; + + return data; +} + +function fs() { + const data = _interopRequireWildcard(require('graceful-fs')); + + fs = function () { + return data; + }; + + return data; +} + +function _sourceMapSupport() { + const data = _interopRequireDefault(require('source-map-support')); + + _sourceMapSupport = function () { + return data; + }; + + return data; +} + +function _console() { + const data = require('@jest/console'); + + _console = function () { + return data; + }; + + return data; +} + +function _transform() { + const data = require('@jest/transform'); + + _transform = function () { + return data; + }; + + return data; +} + +function docblock() { + const data = _interopRequireWildcard(require('jest-docblock')); + + docblock = function () { + return data; + }; + + return data; +} + +function _jestLeakDetector() { + const data = _interopRequireDefault(require('jest-leak-detector')); + + _jestLeakDetector = function () { + return data; + }; + + return data; +} + +function _jestMessageUtil() { + const data = require('jest-message-util'); + + _jestMessageUtil = function () { + return data; + }; + + return data; +} + +function _jestResolve() { + const data = require('jest-resolve'); + + _jestResolve = function () { + return data; + }; + + return data; +} + +function _jestUtil() { + const data = require('jest-util'); + + _jestUtil = function () { + return data; + }; + + return data; +} + +function _getRequireWildcardCache(nodeInterop) { + if (typeof WeakMap !== 'function') return null; + var cacheBabelInterop = new WeakMap(); + var cacheNodeInterop = new WeakMap(); + return (_getRequireWildcardCache = function (nodeInterop) { + return nodeInterop ? cacheNodeInterop : cacheBabelInterop; + })(nodeInterop); +} + +function _interopRequireWildcard(obj, nodeInterop) { + if (!nodeInterop && obj && obj.__esModule) { + return obj; + } + if (obj === null || (typeof obj !== 'object' && typeof obj !== 'function')) { + return {default: obj}; + } + var cache = _getRequireWildcardCache(nodeInterop); + if (cache && cache.has(obj)) { + return cache.get(obj); + } + var newObj = {}; + var hasPropertyDescriptor = + Object.defineProperty && Object.getOwnPropertyDescriptor; + for (var key in obj) { + if (key !== 'default' && Object.prototype.hasOwnProperty.call(obj, key)) { + var desc = hasPropertyDescriptor + ? Object.getOwnPropertyDescriptor(obj, key) + : null; + if (desc && (desc.get || desc.set)) { + Object.defineProperty(newObj, key, desc); + } else { + newObj[key] = obj[key]; + } + } + } + newObj.default = obj; + if (cache) { + cache.set(obj, newObj); + } + return newObj; +} + +function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : {default: obj}; +} + +/** + * 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. + * + */ +function freezeConsole(testConsole, config) { + // @ts-expect-error: `_log` is `private` - we should figure out some proper API here + 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'); + 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". + +async function runTestInternal( + path, + globalConfig, + config, + resolver, + context, + sendMessageToJest +) { + const testSource = fs().readFileSync(path, 'utf8'); + const docblockPragmas = docblock().parse(docblock().extract(testSource)); + const customEnvironment = docblockPragmas['jest-environment']; + let testEnvironment = config.testEnvironment; + + if (customEnvironment) { + if (Array.isArray(customEnvironment)) { + throw new Error( + `You can only define a single test environment through docblocks, got "${customEnvironment.join( + ', ' + )}"` + ); + } + + testEnvironment = (0, _jestResolve().resolveTestEnvironment)({ + ...config, + requireResolveFunction: require.resolve, + testEnvironment: customEnvironment + }); + } + + const cacheFS = new Map([[path, testSource]]); + const transformer = await (0, _transform().createScriptTransformer)( + config, + cacheFS + ); + const TestEnvironment = await transformer.requireAndTranspileModule( + testEnvironment + ); + const testFramework = await transformer.requireAndTranspileModule( + process.env.JEST_JASMINE === '1' + ? require.resolve('jest-jasmine2') + : config.testRunner + ); + const Runtime = (0, _jestUtil().interopRequireDefault)( + config.moduleLoader ? require(config.moduleLoader) : require('jest-runtime') + ).default; + const consoleOut = globalConfig.useStderr ? process.stderr : process.stdout; + + const consoleFormatter = (type, message) => + (0, _console().getConsoleOutput)( + // 4 = the console call is buried 4 stack frames deep + _console().BufferedConsole.write([], type, message, 4), + config, + globalConfig + ); + + let testConsole; + + if (globalConfig.silent) { + testConsole = new (_console().NullConsole)( + consoleOut, + consoleOut, + consoleFormatter + ); + } else if (globalConfig.verbose) { + testConsole = new (_console().CustomConsole)( + consoleOut, + consoleOut, + consoleFormatter + ); + } else { + testConsole = new (_console().BufferedConsole)(); + } + + const environment = new TestEnvironment(config, { + console: testConsole, + docblockPragmas, + testPath: path + }); + + if (typeof environment.getVmContext !== 'function') { + console.error( + `Test environment found at "${testEnvironment}" does not export a "getVmContext" method, which is mandatory from Jest 27. This method is a replacement for "runScript".` + ); + process.exit(1); + } + + const leakDetector = config.detectLeaks + ? new (_jestLeakDetector().default)(environment) + : null; + (0, _jestUtil().setGlobal)(environment.global, 'console', testConsole); + const runtime = new Runtime( + config, + environment, + resolver, + transformer, + cacheFS, + { + changedFiles: + context === null || context === void 0 ? void 0 : context.changedFiles, + collectCoverage: globalConfig.collectCoverage, + collectCoverageFrom: globalConfig.collectCoverageFrom, + collectCoverageOnlyFrom: globalConfig.collectCoverageOnlyFrom, + coverageProvider: globalConfig.coverageProvider, + sourcesRelatedToTestsInChangedFiles: + context === null || context === void 0 + ? void 0 + : context.sourcesRelatedToTestsInChangedFiles + }, + path + ); + const start = Date.now(); + + for (const path of config.setupFiles) { + const esm = runtime.unstable_shouldLoadAsEsm(path); + + if (esm) { + await runtime.unstable_importModule(path); + } else { + runtime.requireModule(path); + } + } + + const sourcemapOptions = { + environment: 'node', + handleUncaughtExceptions: false, + retrieveSourceMap: source => { + var _runtime$getSourceMap; + + const sourceMapSource = + (_runtime$getSourceMap = runtime.getSourceMaps()) === null || + _runtime$getSourceMap === void 0 + ? void 0 + : _runtime$getSourceMap.get(source); + + if (sourceMapSource) { + try { + return { + map: JSON.parse(fs().readFileSync(sourceMapSource, 'utf8')), + url: source + }; + } catch {} + } + + 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); + }; + } // if we don't have `getVmContext` on the env skip coverage + + const collectV8Coverage = + globalConfig.coverageProvider === 'v8' && + typeof environment.getVmContext === 'function'; + + try { + await environment.setup(); + let result; + + try { + if (collectV8Coverage) { + await runtime.collectV8Coverage(); + } + + result = await testFramework( + globalConfig, + config, + environment, + runtime, + path, + sendMessageToJest + ); + } catch (err) { + // Access stack before uninstalling sourcemaps + err.stack; + throw err; + } finally { + if (collectV8Coverage) { + await runtime.stopCollectingV8Coverage(); + } + } + + freezeConsole(testConsole, config); + const testCount = + result.numPassingTests + + result.numFailingTests + + result.numPendingTests + + result.numTodoTests; + const end = Date.now(); + const testRuntime = end - start; + result.perfStats = { + end, + runtime: testRuntime, + slow: testRuntime / 1000 > config.slowTestThreshold, + start + }; + result.testFilePath = path; + result.console = testConsole.getBuffer(); + result.skipped = testCount === result.numPendingTests; + result.displayName = config.displayName; + const coverage = runtime.getAllCoverageInfoCopy(); + + if (coverage) { + const coverageKeys = Object.keys(coverage); + + if (coverageKeys.length) { + result.coverage = coverage; + } + } + + if (collectV8Coverage) { + const v8Coverage = runtime.getAllV8CoverageInfoCopy(); + + if (v8Coverage && v8Coverage.length > 0) { + result.v8Coverage = v8Coverage; + } + } + + 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 { + runtime.teardown(); + await environment.teardown(); + + _sourceMapSupport().default.resetRetrieveHandlers(); + } +} + +async function runTest( + path, + globalConfig, + config, + resolver, + context, + sendMessageToJest +) { + const {leakDetector, result} = await runTestInternal( + path, + globalConfig, + config, + resolver, + context, + sendMessageToJest + ); + + if (leakDetector) { + // We wanna allow a tiny but time to pass to allow last-minute cleanup + await new Promise(resolve => setTimeout(resolve, 100)); // Resolve leak detector, outside the "runTestInternal" closure. + + result.leaks = await leakDetector.isLeaking(); + } else { + result.leaks = false; + } + + return result; +} |