jestAdapterInit.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', {
  3. value: true
  4. });
  5. exports.runAndTransformResultsToJestFormat = exports.initialize = void 0;
  6. var _throat = _interopRequireDefault(require('throat'));
  7. var _testResult = require('@jest/test-result');
  8. var _expect = require('expect');
  9. var _jestEach = require('jest-each');
  10. var _jestMessageUtil = require('jest-message-util');
  11. var _jestSnapshot = require('jest-snapshot');
  12. var _ = _interopRequireDefault(require('..'));
  13. var _run = _interopRequireDefault(require('../run'));
  14. var _state = require('../state');
  15. var _testCaseReportHandler = _interopRequireDefault(
  16. require('../testCaseReportHandler')
  17. );
  18. var _utils = require('../utils');
  19. var _jestExpect = _interopRequireDefault(require('./jestExpect'));
  20. function _interopRequireDefault(obj) {
  21. return obj && obj.__esModule ? obj : {default: obj};
  22. }
  23. /**
  24. * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
  25. *
  26. * This source code is licensed under the MIT license found in the
  27. * LICENSE file in the root directory of this source tree.
  28. */
  29. const initialize = async ({
  30. config,
  31. environment,
  32. globalConfig,
  33. localRequire,
  34. parentProcess,
  35. sendMessageToJest,
  36. setGlobalsForRuntime,
  37. testPath
  38. }) => {
  39. if (globalConfig.testTimeout) {
  40. (0, _state.getState)().testTimeout = globalConfig.testTimeout;
  41. }
  42. const mutex = (0, _throat.default)(globalConfig.maxConcurrency); // @ts-expect-error
  43. const globalsObject = {
  44. ..._.default,
  45. fdescribe: _.default.describe.only,
  46. fit: _.default.it.only,
  47. xdescribe: _.default.describe.skip,
  48. xit: _.default.it.skip,
  49. xtest: _.default.it.skip
  50. };
  51. globalsObject.test.concurrent = (test => {
  52. const concurrent = (testName, testFn, timeout) => {
  53. // For concurrent tests we first run the function that returns promise, and then register a
  54. // normal test that will be waiting on the returned promise (when we start the test, the promise
  55. // will already be in the process of execution).
  56. // Unfortunately at this stage there's no way to know if there are any `.only` tests in the suite
  57. // that will result in this test to be skipped, so we'll be executing the promise function anyway,
  58. // even if it ends up being skipped.
  59. const promise = mutex(() => testFn()); // Avoid triggering the uncaught promise rejection handler in case the test errors before
  60. // being awaited on.
  61. promise.catch(() => {});
  62. globalsObject.test(testName, () => promise, timeout);
  63. };
  64. const only = (testName, testFn, timeout) => {
  65. const promise = mutex(() => testFn()); // eslint-disable-next-line jest/no-focused-tests
  66. test.only(testName, () => promise, timeout);
  67. };
  68. concurrent.only = only;
  69. concurrent.skip = test.skip;
  70. concurrent.each = (0, _jestEach.bind)(test, false);
  71. concurrent.skip.each = (0, _jestEach.bind)(test.skip, false);
  72. only.each = (0, _jestEach.bind)(test.only, false);
  73. return concurrent;
  74. })(globalsObject.test);
  75. (0, _state.addEventHandler)(eventHandler);
  76. if (environment.handleTestEvent) {
  77. (0, _state.addEventHandler)(environment.handleTestEvent.bind(environment));
  78. }
  79. const runtimeGlobals = {
  80. ...globalsObject,
  81. expect: (0, _jestExpect.default)(globalConfig)
  82. };
  83. setGlobalsForRuntime(runtimeGlobals);
  84. if (config.injectGlobals) {
  85. Object.assign(environment.global, runtimeGlobals);
  86. }
  87. await (0, _state.dispatch)({
  88. name: 'setup',
  89. parentProcess,
  90. runtimeGlobals,
  91. testNamePattern: globalConfig.testNamePattern
  92. });
  93. if (config.testLocationInResults) {
  94. await (0, _state.dispatch)({
  95. name: 'include_test_location_in_result'
  96. });
  97. } // Jest tests snapshotSerializers in order preceding built-in serializers.
  98. // Therefore, add in reverse because the last added is the first tested.
  99. config.snapshotSerializers
  100. .concat()
  101. .reverse()
  102. .forEach(path => (0, _jestSnapshot.addSerializer)(localRequire(path)));
  103. const {expand, updateSnapshot} = globalConfig;
  104. const snapshotResolver = await (0, _jestSnapshot.buildSnapshotResolver)(
  105. config,
  106. localRequire
  107. );
  108. const snapshotPath = snapshotResolver.resolveSnapshotPath(testPath);
  109. const snapshotState = new _jestSnapshot.SnapshotState(snapshotPath, {
  110. expand,
  111. prettierPath: config.prettierPath,
  112. snapshotFormat: config.snapshotFormat,
  113. updateSnapshot
  114. }); // @ts-expect-error: snapshotState is a jest extension of `expect`
  115. (0, _expect.setState)({
  116. snapshotState,
  117. testPath
  118. });
  119. (0, _state.addEventHandler)(handleSnapshotStateAfterRetry(snapshotState));
  120. if (sendMessageToJest) {
  121. (0, _state.addEventHandler)(
  122. (0, _testCaseReportHandler.default)(testPath, sendMessageToJest)
  123. );
  124. } // Return it back to the outer scope (test runner outside the VM).
  125. return {
  126. globals: globalsObject,
  127. snapshotState
  128. };
  129. };
  130. exports.initialize = initialize;
  131. const runAndTransformResultsToJestFormat = async ({
  132. config,
  133. globalConfig,
  134. testPath
  135. }) => {
  136. const runResult = await (0, _run.default)();
  137. let numFailingTests = 0;
  138. let numPassingTests = 0;
  139. let numPendingTests = 0;
  140. let numTodoTests = 0;
  141. const assertionResults = runResult.testResults.map(testResult => {
  142. let status;
  143. if (testResult.status === 'skip') {
  144. status = 'pending';
  145. numPendingTests += 1;
  146. } else if (testResult.status === 'todo') {
  147. status = 'todo';
  148. numTodoTests += 1;
  149. } else if (testResult.errors.length) {
  150. status = 'failed';
  151. numFailingTests += 1;
  152. } else {
  153. status = 'passed';
  154. numPassingTests += 1;
  155. }
  156. const ancestorTitles = testResult.testPath.filter(
  157. name => name !== _state.ROOT_DESCRIBE_BLOCK_NAME
  158. );
  159. const title = ancestorTitles.pop();
  160. return {
  161. ancestorTitles,
  162. duration: testResult.duration,
  163. failureDetails: testResult.errorsDetailed,
  164. failureMessages: testResult.errors,
  165. fullName: title
  166. ? ancestorTitles.concat(title).join(' ')
  167. : ancestorTitles.join(' '),
  168. invocations: testResult.invocations,
  169. location: testResult.location,
  170. numPassingAsserts: 0,
  171. status,
  172. title: testResult.testPath[testResult.testPath.length - 1]
  173. };
  174. });
  175. let failureMessage = (0, _jestMessageUtil.formatResultsErrors)(
  176. assertionResults,
  177. config,
  178. globalConfig,
  179. testPath
  180. );
  181. let testExecError;
  182. if (runResult.unhandledErrors.length) {
  183. testExecError = {
  184. message: '',
  185. stack: runResult.unhandledErrors.join('\n')
  186. };
  187. failureMessage =
  188. (failureMessage || '') +
  189. '\n\n' +
  190. runResult.unhandledErrors
  191. .map(err =>
  192. (0, _jestMessageUtil.formatExecError)(err, config, globalConfig)
  193. )
  194. .join('\n');
  195. }
  196. await (0, _state.dispatch)({
  197. name: 'teardown'
  198. });
  199. return {
  200. ...(0, _testResult.createEmptyTestResult)(),
  201. console: undefined,
  202. displayName: config.displayName,
  203. failureMessage,
  204. numFailingTests,
  205. numPassingTests,
  206. numPendingTests,
  207. numTodoTests,
  208. testExecError,
  209. testFilePath: testPath,
  210. testResults: assertionResults
  211. };
  212. };
  213. exports.runAndTransformResultsToJestFormat = runAndTransformResultsToJestFormat;
  214. const handleSnapshotStateAfterRetry = snapshotState => event => {
  215. switch (event.name) {
  216. case 'test_retry': {
  217. // Clear any snapshot data that occurred in previous test run
  218. snapshotState.clear();
  219. }
  220. }
  221. };
  222. const eventHandler = async event => {
  223. switch (event.name) {
  224. case 'test_start': {
  225. (0, _expect.setState)({
  226. currentTestName: (0, _utils.getTestID)(event.test)
  227. });
  228. break;
  229. }
  230. case 'test_done': {
  231. _addSuppressedErrors(event.test);
  232. _addExpectedAssertionErrors(event.test);
  233. break;
  234. }
  235. }
  236. };
  237. const _addExpectedAssertionErrors = test => {
  238. const failures = (0, _expect.extractExpectedAssertionsErrors)();
  239. const errors = failures.map(failure => failure.error);
  240. test.errors = test.errors.concat(errors);
  241. }; // Get suppressed errors from ``jest-matchers`` that weren't throw during
  242. // test execution and add them to the test result, potentially failing
  243. // a passing test.
  244. const _addSuppressedErrors = test => {
  245. const {suppressedErrors} = (0, _expect.getState)();
  246. (0, _expect.setState)({
  247. suppressedErrors: []
  248. });
  249. if (suppressedErrors.length) {
  250. test.errors = test.errors.concat(suppressedErrors);
  251. }
  252. };