123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- 'use strict';
- Object.defineProperty(exports, '__esModule', {
- value: true
- });
- exports.default = void 0;
- var _jestUtil = require('jest-util');
- var _globalErrorHandlers = require('./globalErrorHandlers');
- var _types = require('./types');
- var _utils = require('./utils');
- var Symbol = globalThis['jest-symbol-do-not-touch'] || globalThis.Symbol;
- var Symbol = globalThis['jest-symbol-do-not-touch'] || globalThis.Symbol;
- var jestNow = globalThis[Symbol.for('jest-native-now')] || globalThis.Date.now;
- /**
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
- const eventHandler = (event, state) => {
- switch (event.name) {
- case 'include_test_location_in_result': {
- state.includeTestLocationInResult = true;
- break;
- }
- case 'hook_start': {
- event.hook.seenDone = false;
- break;
- }
- case 'start_describe_definition': {
- const {blockName, mode} = event;
- const {currentDescribeBlock, currentlyRunningTest} = state;
- if (currentlyRunningTest) {
- currentlyRunningTest.errors.push(
- new Error(
- `Cannot nest a describe inside a test. Describe block "${blockName}" cannot run because it is nested within "${currentlyRunningTest.name}".`
- )
- );
- break;
- }
- const describeBlock = (0, _utils.makeDescribe)(
- blockName,
- currentDescribeBlock,
- mode
- );
- currentDescribeBlock.children.push(describeBlock);
- state.currentDescribeBlock = describeBlock;
- break;
- }
- case 'finish_describe_definition': {
- const {currentDescribeBlock} = state;
- (0, _jestUtil.invariant)(
- currentDescribeBlock,
- 'currentDescribeBlock must be there'
- );
- if (!(0, _utils.describeBlockHasTests)(currentDescribeBlock)) {
- currentDescribeBlock.hooks.forEach(hook => {
- hook.asyncError.message = `Invalid: ${hook.type}() may not be used in a describe block containing no tests.`;
- state.unhandledErrors.push(hook.asyncError);
- });
- }
- // pass mode of currentDescribeBlock to tests
- // but do not when there is already a single test with "only" mode
- const shouldPassMode = !(
- currentDescribeBlock.mode === 'only' &&
- currentDescribeBlock.children.some(
- child => child.type === 'test' && child.mode === 'only'
- )
- );
- if (shouldPassMode) {
- currentDescribeBlock.children.forEach(child => {
- if (child.type === 'test' && !child.mode) {
- child.mode = currentDescribeBlock.mode;
- }
- });
- }
- if (
- !state.hasFocusedTests &&
- currentDescribeBlock.mode !== 'skip' &&
- currentDescribeBlock.children.some(
- child => child.type === 'test' && child.mode === 'only'
- )
- ) {
- state.hasFocusedTests = true;
- }
- if (currentDescribeBlock.parent) {
- state.currentDescribeBlock = currentDescribeBlock.parent;
- }
- break;
- }
- case 'add_hook': {
- const {currentDescribeBlock, currentlyRunningTest, hasStarted} = state;
- const {asyncError, fn, hookType: type, timeout} = event;
- if (currentlyRunningTest) {
- currentlyRunningTest.errors.push(
- new Error(
- `Hooks cannot be defined inside tests. Hook of type "${type}" is nested within "${currentlyRunningTest.name}".`
- )
- );
- break;
- } else if (hasStarted) {
- state.unhandledErrors.push(
- new Error(
- 'Cannot add a hook after tests have started running. Hooks must be defined synchronously.'
- )
- );
- break;
- }
- const parent = currentDescribeBlock;
- currentDescribeBlock.hooks.push({
- asyncError,
- fn,
- parent,
- seenDone: false,
- timeout,
- type
- });
- break;
- }
- case 'add_test': {
- const {currentDescribeBlock, currentlyRunningTest, hasStarted} = state;
- const {
- asyncError,
- fn,
- mode,
- testName: name,
- timeout,
- concurrent,
- failing
- } = event;
- if (currentlyRunningTest) {
- currentlyRunningTest.errors.push(
- new Error(
- `Tests cannot be nested. Test "${name}" cannot run because it is nested within "${currentlyRunningTest.name}".`
- )
- );
- break;
- } else if (hasStarted) {
- state.unhandledErrors.push(
- new Error(
- 'Cannot add a test after tests have started running. Tests must be defined synchronously.'
- )
- );
- break;
- }
- const test = (0, _utils.makeTest)(
- fn,
- mode,
- concurrent,
- name,
- currentDescribeBlock,
- timeout,
- asyncError,
- failing
- );
- if (currentDescribeBlock.mode !== 'skip' && test.mode === 'only') {
- state.hasFocusedTests = true;
- }
- currentDescribeBlock.children.push(test);
- currentDescribeBlock.tests.push(test);
- break;
- }
- case 'hook_failure': {
- const {test, describeBlock, error, hook} = event;
- const {asyncError, type} = hook;
- if (type === 'beforeAll') {
- (0, _jestUtil.invariant)(
- describeBlock,
- 'always present for `*All` hooks'
- );
- (0, _utils.addErrorToEachTestUnderDescribe)(
- describeBlock,
- error,
- asyncError
- );
- } else if (type === 'afterAll') {
- // Attaching `afterAll` errors to each test makes execution flow
- // too complicated, so we'll consider them to be global.
- state.unhandledErrors.push([error, asyncError]);
- } else {
- (0, _jestUtil.invariant)(test, 'always present for `*Each` hooks');
- test.errors.push([error, asyncError]);
- }
- break;
- }
- case 'test_skip': {
- event.test.status = 'skip';
- break;
- }
- case 'test_todo': {
- event.test.status = 'todo';
- break;
- }
- case 'test_done': {
- event.test.duration = (0, _utils.getTestDuration)(event.test);
- event.test.status = 'done';
- state.currentlyRunningTest = null;
- break;
- }
- case 'test_start': {
- state.currentlyRunningTest = event.test;
- event.test.startedAt = jestNow();
- event.test.invocations += 1;
- break;
- }
- case 'test_fn_start': {
- event.test.seenDone = false;
- break;
- }
- case 'test_fn_failure': {
- const {
- error,
- test: {asyncError}
- } = event;
- event.test.errors.push([error, asyncError]);
- break;
- }
- case 'test_retry': {
- const logErrorsBeforeRetry =
- // eslint-disable-next-line no-restricted-globals
- global[_types.LOG_ERRORS_BEFORE_RETRY] || false;
- if (logErrorsBeforeRetry) {
- event.test.retryReasons.push(...event.test.errors);
- }
- event.test.errors = [];
- break;
- }
- case 'run_start': {
- state.hasStarted = true;
- /* eslint-disable no-restricted-globals */
- global[_types.TEST_TIMEOUT_SYMBOL] &&
- (state.testTimeout = global[_types.TEST_TIMEOUT_SYMBOL]);
- /* eslint-enable */
- break;
- }
- case 'run_finish': {
- break;
- }
- case 'setup': {
- // Uncaught exception handlers should be defined on the parent process
- // object. If defined on the VM's process object they just no op and let
- // the parent process crash. It might make sense to return a `dispatch`
- // function to the parent process and register handlers there instead, but
- // i'm not sure if this is works. For now i just replicated whatever
- // jasmine was doing -- dabramov
- state.parentProcess = event.parentProcess;
- (0, _jestUtil.invariant)(state.parentProcess);
- state.originalGlobalErrorHandlers = (0,
- _globalErrorHandlers.injectGlobalErrorHandlers)(state.parentProcess);
- if (event.testNamePattern) {
- state.testNamePattern = new RegExp(event.testNamePattern, 'i');
- }
- break;
- }
- case 'teardown': {
- (0, _jestUtil.invariant)(state.originalGlobalErrorHandlers);
- (0, _jestUtil.invariant)(state.parentProcess);
- (0, _globalErrorHandlers.restoreGlobalErrorHandlers)(
- state.parentProcess,
- state.originalGlobalErrorHandlers
- );
- break;
- }
- case 'error': {
- // It's very likely for long-running async tests to throw errors. In this
- // case we want to catch them and fail the current test. At the same time
- // there's a possibility that one test sets a long timeout, that will
- // eventually throw after this test finishes but during some other test
- // execution, which will result in one test's error failing another test.
- // In any way, it should be possible to track where the error was thrown
- // from.
- state.currentlyRunningTest
- ? state.currentlyRunningTest.errors.push(event.error)
- : state.unhandledErrors.push(event.error);
- break;
- }
- }
- };
- var _default = eventHandler;
- exports.default = _default;
|