'use strict'; var _exit; function _load_exit() { return (_exit = _interopRequireDefault(require('exit'))); } var _run_test; function _load_run_test() { return (_run_test = _interopRequireDefault(require('./run_test'))); } var _throat; function _load_throat() { return (_throat = _interopRequireDefault(require('throat'))); } var _jestWorker; function _load_jestWorker() { return (_jestWorker = _interopRequireDefault(require('jest-worker'))); } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : {default: obj}; } function _asyncToGenerator(fn) { return function() { var gen = fn.apply(this, arguments); return new Promise(function(resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then( function(value) { step('next', value); }, function(err) { step('throw', err); } ); } } return step('next'); }); }; } /** * Copyright (c) 2014-present, Facebook, Inc. 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. * * */ const TEST_WORKER_PATH = require.resolve('./test_worker'); class TestRunner { constructor(globalConfig) { this._globalConfig = globalConfig; } 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 || _load_throat()).default)(1); return tests.reduce(function(promise, test) { return mutex(function() { return promise .then( _asyncToGenerator(function*() { if (watcher.isInterrupted()) { throw new CancelRun(); } yield onStart(test); return (0, (_run_test || _load_run_test()) .default)(test.path, _this2._globalConfig, test.context.config, test.context.resolver); }) ) .then(function(result) { return onResult(test, result); }) .catch(function(err) { return onFailure(test, err); }); }); }, Promise.resolve()); })(); } _createParallelTestRun(tests, watcher, onStart, onResult, onFailure) { var _this3 = this; return _asyncToGenerator(function*() { // $FlowFixMe: class object is augmented with worker when instantiating. const worker = new (_jestWorker || _load_jestWorker()).default( TEST_WORKER_PATH, { exposedMethods: ['worker'], forkOptions: {stdio: 'inherit'}, maxRetries: 3, numWorkers: _this3._globalConfig.maxWorkers } ); const mutex = (0, (_throat || _load_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 = function(test) { return mutex( _asyncToGenerator(function*() { if (watcher.isInterrupted()) { return Promise.reject(); } yield onStart(test); return worker.worker({ config: test.context.config, globalConfig: _this3._globalConfig, path: test.path, rawModuleMap: watcher.isWatchMode() ? test.context.moduleMap.getRawModuleMap() : null }); }) ); }; const onError = (() => { 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 || _load_exit()).default)(1); } }); return function onError(_x, _x2) { return _ref3.apply(this, arguments); }; })(); const onInterrupt = new Promise(function(_, reject) { watcher.on('change', function(state) { if (state.interrupted) { reject(new CancelRun()); } }); }); const runAllTests = Promise.all( tests.map(function(test) { return runTestInWorker(test) .then(function(testResult) { return onResult(test, testResult); }) .catch(function(error) { return onError(error, test); }); }) ); const cleanup = function() { return worker.end(); }; return Promise.race([runAllTests, onInterrupt]).then(cleanup, cleanup); })(); } } class CancelRun extends Error { constructor(message) { super(message); this.name = 'CancelRun'; } } module.exports = TestRunner;