Skip to content

Commit

Permalink
fix: jest-circus shares events among imports #11483
Browse files Browse the repository at this point in the history
  • Loading branch information
satanTime committed Oct 17, 2021
1 parent ed132a6 commit bbdb845
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,7 @@

### Fixes

- `[jest-circus]` Shares events with event handlers among imports ([#11483](https://github.com/facebook/jest/pull/11483))
- `[expect]` Tweak and improve types ([#11949](https://github.com/facebook/jest/pull/11949))
- `[jest-runtime]` Ensure absolute paths can be resolved within test modules ([#11943](https://github.com/facebook/jest/pull/11943))
- `[jest-runtime]` Fix `instanceof` for `ModernFakeTimers` and `LegacyFakeTimers` methods ([#11946](https://github.com/facebook/jest/pull/11946))
Expand Down
1 change: 1 addition & 0 deletions packages/jest-circus/src/__mocks__/testUtils.ts
Expand Up @@ -46,6 +46,7 @@ export const runTest = (source: string) => {
const testEventHandler = require('${TEST_EVENT_HANDLER_PATH}').default;
const addEventHandler = require('${CIRCUS_STATE_PATH}').addEventHandler;
const removeEventHandler = require('${CIRCUS_STATE_PATH}').removeEventHandler;
addEventHandler(testEventHandler);
${source};
Expand Down
25 changes: 25 additions & 0 deletions packages/jest-circus/src/__tests__/eventHandler.test.ts
@@ -0,0 +1,25 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

// addEventHandler and removeEventHandler are provided in the ./index
import {addEventHandler, removeEventHandler} from '../index';
// dispatch comes from the ./state
import {dispatch} from '../state';

test('addEventHandler and removeEventHandler control handlers', async () => {
const spy = jest.fn();

addEventHandler(spy);
expect(spy).not.toHaveBeenCalledWith({name: 'unknown1'}, expect.anything());
await dispatch({name: 'unknown1' as any});
expect(spy).toHaveBeenCalledWith({name: 'unknown1'}, expect.anything());

removeEventHandler(spy);
expect(spy).not.toHaveBeenCalledWith({name: 'unknown2'}, expect.anything());
await dispatch({name: 'unknown2' as any});
expect(spy).not.toHaveBeenCalledWith({name: 'unknown2'}, expect.anything());
});
8 changes: 7 additions & 1 deletion packages/jest-circus/src/index.ts
Expand Up @@ -10,7 +10,13 @@ import {bind as bindEach} from 'jest-each';
import {ErrorWithStack, isPromise} from 'jest-util';
import {dispatchSync} from './state';

export {setState, getState, resetState} from './state';
export {
setState,
getState,
resetState,
addEventHandler,
removeEventHandler,
} from './state';
export {default as run} from './run';

type THook = (fn: Circus.HookFn, timeout?: number) => void;
Expand Down
17 changes: 12 additions & 5 deletions packages/jest-circus/src/state.ts
Expand Up @@ -8,10 +8,10 @@
import type {Circus} from '@jest/types';
import eventHandler from './eventHandler';
import formatNodeAssertErrors from './formatNodeAssertErrors';
import {STATE_SYM} from './types';
import {EVENT_HANDLERS, STATE_SYM} from './types';
import {makeDescribe} from './utils';

const eventHandlers: Array<Circus.EventHandler> = [
global[EVENT_HANDLERS] = global[EVENT_HANDLERS] || [
eventHandler,
formatNodeAssertErrors,
];
Expand Down Expand Up @@ -46,17 +46,24 @@ export const setState = (state: Circus.State): Circus.State =>
(global[STATE_SYM] = state);

export const dispatch = async (event: Circus.AsyncEvent): Promise<void> => {
for (const handler of eventHandlers) {
for (const handler of global[EVENT_HANDLERS]) {
await handler(event, getState());
}
};

export const dispatchSync = (event: Circus.SyncEvent): void => {
for (const handler of eventHandlers) {
for (const handler of global[EVENT_HANDLERS]) {
handler(event, getState());
}
};

export const addEventHandler = (handler: Circus.EventHandler): void => {
eventHandlers.push(handler);
global[EVENT_HANDLERS].push(handler);
};

export const removeEventHandler = (handler: Circus.EventHandler): void => {
const index = global[EVENT_HANDLERS].lastIndexOf(handler);
if (index !== -1) {
global[EVENT_HANDLERS].splice(index, 1);
}
};
4 changes: 4 additions & 0 deletions packages/jest-circus/src/types.ts
Expand Up @@ -19,13 +19,17 @@ export const RETRY_TIMES = Symbol.for(
export const TEST_TIMEOUT_SYMBOL = Symbol.for(
'TEST_TIMEOUT_SYMBOL',
) as unknown as 'TEST_TIMEOUT_SYMBOL';
export const EVENT_HANDLERS = Symbol.for(
'EVENT_HANDLERS',
) as unknown as 'EVENT_HANDLERS';

declare global {
module NodeJS {
interface Global {
STATE_SYM_SYMBOL: Circus.State;
RETRY_TIMES_SYMBOL: string;
TEST_TIMEOUT_SYMBOL: number;
EVENT_HANDLERS: Array<Circus.EventHandler>;
expect: typeof expect;
}
}
Expand Down

0 comments on commit bbdb845

Please sign in to comment.