import type { ExpectStatic, MatcherState, Tester } from './types' import { ASYMMETRIC_MATCHERS_OBJECT, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, MATCHERS_OBJECT, } from './constants' if (!Object.hasOwn(globalThis, MATCHERS_OBJECT)) { const globalState = new WeakMap() const matchers = Object.create(null) const customEqualityTesters: Array = [] const asymmetricMatchers = Object.create(null) // `configurable` so that vm pools can strip the accessors from a disposed // context: the getters capture the expect state, which would otherwise keep // the whole test-file world reachable from the leaked context shell Object.defineProperty(globalThis, MATCHERS_OBJECT, { configurable: true, get: () => globalState, }) Object.defineProperty(globalThis, JEST_MATCHERS_OBJECT, { configurable: true, get: () => ({ state: globalState.get((globalThis as any)[GLOBAL_EXPECT]), matchers, customEqualityTesters, }), }) Object.defineProperty(globalThis, ASYMMETRIC_MATCHERS_OBJECT, { configurable: true, get: () => asymmetricMatchers, }) } export function getState(expect: ExpectStatic): State { return (globalThis as any)[MATCHERS_OBJECT].get(expect) } export function setState( state: Partial, expect: ExpectStatic, ): void { const map = (globalThis as any)[MATCHERS_OBJECT] const current = map.get(expect) // so it keeps getters from `testPath` const next = Object.defineProperties(current || {}, Object.getOwnPropertyDescriptors(state)) if (!current) { map.set(expect, next) } }