index.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.runCLI = runCLI;
  6. function _chalk() {
  7. const data = _interopRequireDefault(require('chalk'));
  8. _chalk = function () {
  9. return data;
  10. };
  11. return data;
  12. }
  13. function _exit() {
  14. const data = _interopRequireDefault(require('exit'));
  15. _exit = function () {
  16. return data;
  17. };
  18. return data;
  19. }
  20. function _rimraf() {
  21. const data = _interopRequireDefault(require('rimraf'));
  22. _rimraf = function () {
  23. return data;
  24. };
  25. return data;
  26. }
  27. function _console() {
  28. const data = require('@jest/console');
  29. _console = function () {
  30. return data;
  31. };
  32. return data;
  33. }
  34. function _jestConfig() {
  35. const data = require('jest-config');
  36. _jestConfig = function () {
  37. return data;
  38. };
  39. return data;
  40. }
  41. function _jestRuntime() {
  42. const data = _interopRequireDefault(require('jest-runtime'));
  43. _jestRuntime = function () {
  44. return data;
  45. };
  46. return data;
  47. }
  48. function _jestUtil() {
  49. const data = require('jest-util');
  50. _jestUtil = function () {
  51. return data;
  52. };
  53. return data;
  54. }
  55. var _TestWatcher = _interopRequireDefault(require('../TestWatcher'));
  56. var _collectHandles = require('../collectHandles');
  57. var _getChangedFilesPromise = _interopRequireDefault(
  58. require('../getChangedFilesPromise')
  59. );
  60. var _getConfigsOfProjectsToRun = _interopRequireDefault(
  61. require('../getConfigsOfProjectsToRun')
  62. );
  63. var _getProjectNamesMissingWarning = _interopRequireDefault(
  64. require('../getProjectNamesMissingWarning')
  65. );
  66. var _getSelectProjectsMessage = _interopRequireDefault(
  67. require('../getSelectProjectsMessage')
  68. );
  69. var _createContext = _interopRequireDefault(require('../lib/createContext'));
  70. var _handleDeprecationWarnings = _interopRequireDefault(
  71. require('../lib/handleDeprecationWarnings')
  72. );
  73. var _logDebugMessages = _interopRequireDefault(
  74. require('../lib/logDebugMessages')
  75. );
  76. var _pluralize = _interopRequireDefault(require('../pluralize'));
  77. var _runJest = _interopRequireDefault(require('../runJest'));
  78. var _watch = _interopRequireDefault(require('../watch'));
  79. function _interopRequireDefault(obj) {
  80. return obj && obj.__esModule ? obj : {default: obj};
  81. }
  82. /**
  83. * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
  84. *
  85. * This source code is licensed under the MIT license found in the
  86. * LICENSE file in the root directory of this source tree.
  87. */
  88. const {print: preRunMessagePrint} = _jestUtil().preRunMessage;
  89. async function runCLI(argv, projects) {
  90. let results; // If we output a JSON object, we can't write anything to stdout, since
  91. // it'll break the JSON structure and it won't be valid.
  92. const outputStream =
  93. argv.json || argv.useStderr ? process.stderr : process.stdout;
  94. const {globalConfig, configs, hasDeprecationWarnings} = await (0,
  95. _jestConfig().readConfigs)(argv, projects);
  96. if (argv.debug) {
  97. (0, _logDebugMessages.default)(globalConfig, configs, outputStream);
  98. }
  99. if (argv.showConfig) {
  100. (0, _logDebugMessages.default)(globalConfig, configs, process.stdout);
  101. (0, _exit().default)(0);
  102. }
  103. if (argv.clearCache) {
  104. configs.forEach(config => {
  105. _rimraf().default.sync(config.cacheDirectory);
  106. process.stdout.write(`Cleared ${config.cacheDirectory}\n`);
  107. });
  108. (0, _exit().default)(0);
  109. }
  110. let configsOfProjectsToRun = configs;
  111. if (argv.selectProjects) {
  112. const namesMissingWarning = (0, _getProjectNamesMissingWarning.default)(
  113. configs
  114. );
  115. if (namesMissingWarning) {
  116. outputStream.write(namesMissingWarning);
  117. }
  118. configsOfProjectsToRun = (0, _getConfigsOfProjectsToRun.default)(
  119. argv.selectProjects,
  120. configs
  121. );
  122. outputStream.write(
  123. (0, _getSelectProjectsMessage.default)(configsOfProjectsToRun)
  124. );
  125. }
  126. await _run10000(
  127. globalConfig,
  128. configsOfProjectsToRun,
  129. hasDeprecationWarnings,
  130. outputStream,
  131. r => {
  132. results = r;
  133. }
  134. );
  135. if (argv.watch || argv.watchAll) {
  136. // If in watch mode, return the promise that will never resolve.
  137. // If the watch mode is interrupted, watch should handle the process
  138. // shutdown.
  139. return new Promise(() => {});
  140. }
  141. if (!results) {
  142. throw new Error(
  143. 'AggregatedResult must be present after test run is complete'
  144. );
  145. }
  146. const {openHandles} = results;
  147. if (openHandles && openHandles.length) {
  148. const formatted = (0, _collectHandles.formatHandleErrors)(
  149. openHandles,
  150. configs[0]
  151. );
  152. const openHandlesString = (0, _pluralize.default)(
  153. 'open handle',
  154. formatted.length,
  155. 's'
  156. );
  157. const message =
  158. _chalk().default.red(
  159. `\nJest has detected the following ${openHandlesString} potentially keeping Jest from exiting:\n\n`
  160. ) + formatted.join('\n\n');
  161. console.error(message);
  162. }
  163. return {
  164. globalConfig,
  165. results
  166. };
  167. }
  168. const buildContextsAndHasteMaps = async (
  169. configs,
  170. globalConfig,
  171. outputStream
  172. ) => {
  173. const hasteMapInstances = Array(configs.length);
  174. const contexts = await Promise.all(
  175. configs.map(async (config, index) => {
  176. (0, _jestUtil().createDirectory)(config.cacheDirectory);
  177. const hasteMapInstance = _jestRuntime().default.createHasteMap(config, {
  178. console: new (_console().CustomConsole)(outputStream, outputStream),
  179. maxWorkers: Math.max(
  180. 1,
  181. Math.floor(globalConfig.maxWorkers / configs.length)
  182. ),
  183. resetCache: !config.cache,
  184. watch: globalConfig.watch || globalConfig.watchAll,
  185. watchman: globalConfig.watchman
  186. });
  187. hasteMapInstances[index] = hasteMapInstance;
  188. return (0, _createContext.default)(
  189. config,
  190. await hasteMapInstance.build()
  191. );
  192. })
  193. );
  194. return {
  195. contexts,
  196. hasteMapInstances
  197. };
  198. };
  199. const _run10000 = async (
  200. globalConfig,
  201. configs,
  202. hasDeprecationWarnings,
  203. outputStream,
  204. onComplete
  205. ) => {
  206. // Queries to hg/git can take a while, so we need to start the process
  207. // as soon as possible, so by the time we need the result it's already there.
  208. const changedFilesPromise = (0, _getChangedFilesPromise.default)(
  209. globalConfig,
  210. configs
  211. ); // Filter may need to do an HTTP call or something similar to setup.
  212. // We will wait on an async response from this before using the filter.
  213. let filter;
  214. if (globalConfig.filter && !globalConfig.skipFilter) {
  215. const rawFilter = require(globalConfig.filter);
  216. let filterSetupPromise;
  217. if (rawFilter.setup) {
  218. // Wrap filter setup Promise to avoid "uncaught Promise" error.
  219. // If an error is returned, we surface it in the return value.
  220. filterSetupPromise = (async () => {
  221. try {
  222. await rawFilter.setup();
  223. } catch (err) {
  224. return err;
  225. }
  226. return undefined;
  227. })();
  228. }
  229. filter = async testPaths => {
  230. if (filterSetupPromise) {
  231. // Expect an undefined return value unless there was an error.
  232. const err = await filterSetupPromise;
  233. if (err) {
  234. throw err;
  235. }
  236. }
  237. return rawFilter(testPaths);
  238. };
  239. }
  240. const {contexts, hasteMapInstances} = await buildContextsAndHasteMaps(
  241. configs,
  242. globalConfig,
  243. outputStream
  244. );
  245. globalConfig.watch || globalConfig.watchAll
  246. ? await runWatch(
  247. contexts,
  248. configs,
  249. hasDeprecationWarnings,
  250. globalConfig,
  251. outputStream,
  252. hasteMapInstances,
  253. filter
  254. )
  255. : await runWithoutWatch(
  256. globalConfig,
  257. contexts,
  258. outputStream,
  259. onComplete,
  260. changedFilesPromise,
  261. filter
  262. );
  263. };
  264. const runWatch = async (
  265. contexts,
  266. _configs,
  267. hasDeprecationWarnings,
  268. globalConfig,
  269. outputStream,
  270. hasteMapInstances,
  271. filter
  272. ) => {
  273. if (hasDeprecationWarnings) {
  274. try {
  275. await (0, _handleDeprecationWarnings.default)(
  276. outputStream,
  277. process.stdin
  278. );
  279. return (0, _watch.default)(
  280. globalConfig,
  281. contexts,
  282. outputStream,
  283. hasteMapInstances,
  284. undefined,
  285. undefined,
  286. filter
  287. );
  288. } catch {
  289. (0, _exit().default)(0);
  290. }
  291. }
  292. return (0, _watch.default)(
  293. globalConfig,
  294. contexts,
  295. outputStream,
  296. hasteMapInstances,
  297. undefined,
  298. undefined,
  299. filter
  300. );
  301. };
  302. const runWithoutWatch = async (
  303. globalConfig,
  304. contexts,
  305. outputStream,
  306. onComplete,
  307. changedFilesPromise,
  308. filter
  309. ) => {
  310. const startRun = async () => {
  311. if (!globalConfig.listTests) {
  312. preRunMessagePrint(outputStream);
  313. }
  314. return (0, _runJest.default)({
  315. changedFilesPromise,
  316. contexts,
  317. failedTestsCache: undefined,
  318. filter,
  319. globalConfig,
  320. onComplete,
  321. outputStream,
  322. startRun,
  323. testWatcher: new _TestWatcher.default({
  324. isWatchMode: false
  325. })
  326. });
  327. };
  328. return startRun();
  329. };