Skip to content

Commit eaa57a4

Browse files
committed
fix: jest-circus shares events among imports jestjs#11483
1 parent d2420aa commit eaa57a4

File tree

5 files changed

+47
-6
lines changed

5 files changed

+47
-6
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export const runTest = (source: string) => {
4949
5050
const testEventHandler = require('${TEST_EVENT_HANDLER_PATH}').default;
5151
const addEventHandler = require('${CIRCUS_STATE_PATH}').addEventHandler;
52+
const removeEventHandler = require('${CIRCUS_STATE_PATH}').removeEventHandler;
5253
addEventHandler(testEventHandler);
5354
5455
${source};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
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 = 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

+12-5
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
import type {Circus} 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> = [
14+
global[EVENT_HANDLERS] = global[EVENT_HANDLERS] || [
1515
eventHandler,
1616
formatNodeAssertErrors,
1717
];
@@ -49,17 +49,24 @@ export const setState = (state: Circus.State): Circus.State =>
4949
/* eslint-enable */
5050

5151
export const dispatch = async (event: Circus.AsyncEvent): Promise<void> => {
52-
for (const handler of eventHandlers) {
52+
for (const handler of global[EVENT_HANDLERS]) {
5353
await handler(event, getState());
5454
}
5555
};
5656

5757
export const dispatchSync = (event: Circus.SyncEvent): void => {
58-
for (const handler of eventHandlers) {
58+
for (const handler of global[EVENT_HANDLERS]) {
5959
handler(event, getState());
6060
}
6161
};
6262

6363
export const addEventHandler = (handler: Circus.EventHandler): void => {
64-
eventHandlers.push(handler);
64+
global[EVENT_HANDLERS].push(handler);
65+
};
66+
67+
export const removeEventHandler = (handler: Circus.EventHandler): void => {
68+
const index = global[EVENT_HANDLERS].lastIndexOf(handler);
69+
if (index !== -1) {
70+
global[EVENT_HANDLERS].splice(index, 1);
71+
}
6572
};

packages/jest-circus/src/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const STATE_SYM = Symbol('JEST_STATE_SYMBOL');
1111
export const RETRY_TIMES = Symbol.for('RETRY_TIMES');
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');
1516

1617
declare global {
@@ -20,6 +21,7 @@ declare global {
2021
[STATE_SYM]: Circus.State;
2122
[RETRY_TIMES]: string;
2223
[TEST_TIMEOUT_SYMBOL]: number;
24+
[EVENT_HANDLERS]: Array<Circus.EventHandler>;
2325
[LOG_ERRORS_BEFORE_RETRY]: boolean;
2426
}
2527
}

0 commit comments

Comments
 (0)