Skip to content

Commit 23e5fd8

Browse files
committed
fix: jest-circus shares events among imports jestjs#11483
1 parent 611d1a4 commit 23e5fd8

File tree

5 files changed

+50
-10
lines changed

5 files changed

+50
-10
lines changed

packages/jest-circus/src/__mocks__/testUtils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export const runTest = (
3636
global.afterAll = circus.afterAll;
3737
3838
const testEventHandler = require('${TEST_EVENT_HANDLER_PATH}').default;
39-
const {addEventHandler, getState} = require('${CIRCUS_STATE_PATH}');
39+
const {addEventHandler, removeEventHandler, getState} = require('${CIRCUS_STATE_PATH}');
4040
getState().randomize = ${opts?.randomize};
4141
getState().seed = ${opts?.seed ?? 0};
4242
addEventHandler(testEventHandler);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
// addEventHandler and removeEventHandler are provided in the ./index
9+
import {addEventHandler, removeEventHandler} from '../index';
10+
// dispatch comes from the ./state
11+
import {dispatch} from '../state';
12+
13+
test('addEventHandler and removeEventHandler control handlers', async () => {
14+
const spy: any = jest.fn();
15+
16+
addEventHandler(spy);
17+
expect(spy).not.toHaveBeenCalledWith({name: 'unknown1'}, expect.anything());
18+
await dispatch({name: 'unknown1' as any});
19+
expect(spy).toHaveBeenCalledWith({name: 'unknown1'}, expect.anything());
20+
21+
removeEventHandler(spy);
22+
expect(spy).not.toHaveBeenCalledWith({name: 'unknown2'}, expect.anything());
23+
await dispatch({name: 'unknown2' as any});
24+
expect(spy).not.toHaveBeenCalledWith({name: 'unknown2'}, expect.anything());
25+
});

packages/jest-circus/src/index.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ import {bind as bindEach} from 'jest-each';
1010
import {ErrorWithStack, convertDescriptorToString, isPromise} from 'jest-util';
1111
import {dispatchSync} from './state';
1212

13-
export {setState, getState, resetState} from './state';
13+
export {
14+
setState,
15+
getState,
16+
resetState,
17+
addEventHandler,
18+
removeEventHandler,
19+
} from './state';
1420
export {default as run} from './run';
1521

1622
type THook = (fn: Circus.HookFn, timeout?: number) => void;

packages/jest-circus/src/state.ts

+16-8
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
import type {Circus, Global} from '@jest/types';
99
import eventHandler from './eventHandler';
1010
import formatNodeAssertErrors from './formatNodeAssertErrors';
11-
import {STATE_SYM} from './types';
11+
import {EVENT_HANDLERS, STATE_SYM} from './types';
1212
import {makeDescribe} from './utils';
1313

14-
const eventHandlers: Array<Circus.EventHandler> = [
15-
eventHandler,
16-
formatNodeAssertErrors,
17-
];
14+
const handlers: Array<Circus.EventHandler> = ((globalThis as Global.Global)[
15+
EVENT_HANDLERS
16+
] = ((globalThis as Global.Global)[
17+
EVENT_HANDLERS
18+
] as Array<Circus.EventHandler>) || [eventHandler, formatNodeAssertErrors]);
1819

1920
export const ROOT_DESCRIBE_BLOCK_NAME = 'ROOT_DESCRIBE_BLOCK';
2021

@@ -50,17 +51,24 @@ export const setState = (state: Circus.State): Circus.State =>
5051
((globalThis as Global.Global)[STATE_SYM] = state);
5152

5253
export const dispatch = async (event: Circus.AsyncEvent): Promise<void> => {
53-
for (const handler of eventHandlers) {
54+
for (const handler of handlers) {
5455
await handler(event, getState());
5556
}
5657
};
5758

5859
export const dispatchSync = (event: Circus.SyncEvent): void => {
59-
for (const handler of eventHandlers) {
60+
for (const handler of handlers) {
6061
handler(event, getState());
6162
}
6263
};
6364

6465
export const addEventHandler = (handler: Circus.EventHandler): void => {
65-
eventHandlers.push(handler);
66+
handlers.push(handler);
67+
};
68+
69+
export const removeEventHandler = (handler: Circus.EventHandler): void => {
70+
const index = handlers.lastIndexOf(handler);
71+
if (index !== -1) {
72+
handlers.splice(index, 1);
73+
}
6674
};

packages/jest-circus/src/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ export const RETRY_IMMEDIATELY = Symbol.for('RETRY_IMMEDIATELY');
1111
export const WAIT_BEFORE_RETRY = Symbol.for('WAIT_BEFORE_RETRY');
1212
// To pass this value from Runtime object to state we need to use global[sym]
1313
export const TEST_TIMEOUT_SYMBOL = Symbol.for('TEST_TIMEOUT_SYMBOL');
14+
export const EVENT_HANDLERS = Symbol.for('EVENT_HANDLERS');
1415
export const LOG_ERRORS_BEFORE_RETRY = Symbol.for('LOG_ERRORS_BEFORE_RETRY');

0 commit comments

Comments
 (0)