From 1206b5bb8e270b32ed261dbd1f39a8e6d9cde690 Mon Sep 17 00:00:00 2001 From: MG Date: Sun, 31 Oct 2021 10:22:50 +0100 Subject: [PATCH] fix: jest-circus shares events among imports #11483 --- CHANGELOG.md | 1 + .../jest-circus/src/__mocks__/testUtils.ts | 1 + .../src/__tests__/eventHandler.test.ts | 25 +++++++++++++++++++ packages/jest-circus/src/index.ts | 8 +++++- packages/jest-circus/src/state.ts | 17 +++++++++---- packages/jest-circus/src/types.ts | 4 +++ 6 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 packages/jest-circus/src/__tests__/eventHandler.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index bd9009ea09b5..6f86ae56009e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### Fixes +- `[jest-circus]` Shares events with event handlers among imports ([#11483](https://github.com/facebook/jest/pull/11483)) - `[expect]` Allow again `expect.Matchers` generic with single value ([#11986](https://github.com/facebook/jest/pull/11986)) - `[jest-environment-jsdom]` Add `@types/jsdom` dependency ([#11999](https://github.com/facebook/jest/pull/11999)) diff --git a/packages/jest-circus/src/__mocks__/testUtils.ts b/packages/jest-circus/src/__mocks__/testUtils.ts index 52557f72fcb8..17cbb071281f 100644 --- a/packages/jest-circus/src/__mocks__/testUtils.ts +++ b/packages/jest-circus/src/__mocks__/testUtils.ts @@ -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}; diff --git a/packages/jest-circus/src/__tests__/eventHandler.test.ts b/packages/jest-circus/src/__tests__/eventHandler.test.ts new file mode 100644 index 000000000000..7915e7182ee7 --- /dev/null +++ b/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()); +}); diff --git a/packages/jest-circus/src/index.ts b/packages/jest-circus/src/index.ts index 26052438c6e1..23f80dce6a16 100644 --- a/packages/jest-circus/src/index.ts +++ b/packages/jest-circus/src/index.ts @@ -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; diff --git a/packages/jest-circus/src/state.ts b/packages/jest-circus/src/state.ts index 6f208ab04fcf..09030ad0cc5b 100644 --- a/packages/jest-circus/src/state.ts +++ b/packages/jest-circus/src/state.ts @@ -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 = [ +global[EVENT_HANDLERS] = global[EVENT_HANDLERS] || [ eventHandler, formatNodeAssertErrors, ]; @@ -46,17 +46,24 @@ export const setState = (state: Circus.State): Circus.State => (global[STATE_SYM] = state); export const dispatch = async (event: Circus.AsyncEvent): Promise => { - 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); + } }; diff --git a/packages/jest-circus/src/types.ts b/packages/jest-circus/src/types.ts index d381cfec56e1..fc90e5781e4f 100644 --- a/packages/jest-circus/src/types.ts +++ b/packages/jest-circus/src/types.ts @@ -19,6 +19,9 @@ 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 { @@ -26,6 +29,7 @@ declare global { STATE_SYM_SYMBOL: Circus.State; RETRY_TIMES_SYMBOL: string; TEST_TIMEOUT_SYMBOL: number; + EVENT_HANDLERS: Array; expect: typeof expect; } }