diff --git a/packages/react-client/src/__tests__/ReactFlight-test.js b/packages/react-client/src/__tests__/ReactFlight-test.js index 5bb9efea932b..5347c57425f8 100644 --- a/packages/react-client/src/__tests__/ReactFlight-test.js +++ b/packages/react-client/src/__tests__/ReactFlight-test.js @@ -92,17 +92,10 @@ describe('ReactFlight', () => { beforeEach(() => { // Mock performance.now for timing tests let time = 10; - const now = jest.fn().mockImplementation(() => { + jest.spyOn(performance, 'timeOrigin', 'get').mockReturnValue(time); + jest.spyOn(performance, 'now').mockImplementation(() => { return time++; }); - Object.defineProperty(performance, 'timeOrigin', { - value: time, - configurable: true, - }); - Object.defineProperty(performance, 'now', { - value: now, - configurable: true, - }); jest.resetModules(); jest.mock('react', () => require('react/react.react-server')); diff --git a/packages/react-client/src/__tests__/ReactFlightDebugChannel-test.js b/packages/react-client/src/__tests__/ReactFlightDebugChannel-test.js index 6d6916926147..58e68a7d865d 100644 --- a/packages/react-client/src/__tests__/ReactFlightDebugChannel-test.js +++ b/packages/react-client/src/__tests__/ReactFlightDebugChannel-test.js @@ -29,17 +29,10 @@ describe('ReactFlight', () => { beforeEach(() => { // Mock performance.now for timing tests let time = 10; - const now = jest.fn().mockImplementation(() => { + jest.spyOn(performance, 'timeOrigin', 'get').mockReturnValue(time); + jest.spyOn(performance, 'now').mockImplementation(() => { return time++; }); - Object.defineProperty(performance, 'timeOrigin', { - value: time, - configurable: true, - }); - Object.defineProperty(performance, 'now', { - value: now, - configurable: true, - }); jest.resetModules(); jest.mock('react', () => require('react/react.react-server')); diff --git a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js index 00e8e6ad4f34..00d082fecff5 100644 --- a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js +++ b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js @@ -3152,7 +3152,7 @@ function normalizeListenerOptions( opts: ?EventListenerOptionsOrUseCapture, ): string { if (opts == null) { - return '0'; + return 'c=0'; } if (typeof opts === 'boolean') { diff --git a/packages/react-dom/src/__tests__/ReactDOMFragmentRefs-test.js b/packages/react-dom/src/__tests__/ReactDOMFragmentRefs-test.js index 60c86301e4a6..3611e973cb97 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFragmentRefs-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFragmentRefs-test.js @@ -832,6 +832,47 @@ describe('FragmentRefs', () => { expect(logs).toEqual([]); }); + // @gate enableFragmentRefs + it('matches listeners by their normalized capture flag', async () => { + const fragmentRef = React.createRef(); + const childRef = React.createRef(); + const root = ReactDOMClient.createRoot(container); + const logs = []; + + function addedWithOmittedOptions() { + logs.push('addedWithOmittedOptions'); + } + + function addedWithCaptureFalse() { + logs.push('addedWithCaptureFalse'); + } + + await act(() => { + root.render( + +
child
+
, + ); + }); + + fragmentRef.current.addEventListener('click', addedWithOmittedOptions); + fragmentRef.current.addEventListener('click', addedWithCaptureFalse, { + capture: false, + }); + + // Omitted options and an explicit capture: false are the same + // EventTarget listener identity, so each removal should match. + fragmentRef.current.removeEventListener( + 'click', + addedWithOmittedOptions, + false, + ); + fragmentRef.current.removeEventListener('click', addedWithCaptureFalse); + + childRef.current.click(); + expect(logs).toEqual([]); + }); + // @gate enableFragmentRefs it('adds and removes event listeners from children with multiple fragments', async () => { const fragmentRef = React.createRef(); diff --git a/packages/react-reconciler/src/__tests__/ReactOwnerStacks-test.js b/packages/react-reconciler/src/__tests__/ReactOwnerStacks-test.js index e7b0581d5f4a..4dc2f4ef0f22 100644 --- a/packages/react-reconciler/src/__tests__/ReactOwnerStacks-test.js +++ b/packages/react-reconciler/src/__tests__/ReactOwnerStacks-test.js @@ -27,17 +27,10 @@ describe('ReactOwnerStacks', () => { time += timeMS; }; - const now = jest.fn().mockImplementation(() => { + jest.spyOn(performance, 'timeOrigin', 'get').mockReturnValue(time); + jest.spyOn(performance, 'now').mockImplementation(() => { return time++; }); - Object.defineProperty(performance, 'timeOrigin', { - value: time, - configurable: true, - }); - Object.defineProperty(performance, 'now', { - value: now, - configurable: true, - }); jest.resetModules(); React = require('react'); diff --git a/packages/react-reconciler/src/__tests__/ReactPerformanceTrack-test.js b/packages/react-reconciler/src/__tests__/ReactPerformanceTrack-test.js index cdc4f40f4a2b..77a8d66fb3d9 100644 --- a/packages/react-reconciler/src/__tests__/ReactPerformanceTrack-test.js +++ b/packages/react-reconciler/src/__tests__/ReactPerformanceTrack-test.js @@ -19,8 +19,9 @@ describe('ReactPerformanceTracks', () => { beforeEach(() => { performanceMeasureCalls.length = 0; - Object.defineProperty(performance, 'measure', { - value: jest.fn((measureName, reusableOptions) => { + jest + .spyOn(performance, 'measure') + .mockImplementation((measureName, reusableOptions) => { performanceMeasureCalls.push([ measureName, { @@ -28,9 +29,7 @@ describe('ReactPerformanceTracks', () => { ...reusableOptions, }, ]); - }), - configurable: true, - }); + }); console.timeStamp = () => {}; jest.spyOn(console, 'timeStamp').mockImplementation(() => {}); diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js index 2e846579db36..39aba780e453 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js @@ -47,17 +47,10 @@ describe('ReactFlightDOMEdge', () => { beforeEach(() => { // Mock performance.now for timing tests let time = 10; - const now = jest.fn().mockImplementation(() => { + jest.spyOn(performance, 'timeOrigin', 'get').mockReturnValue(time); + jest.spyOn(performance, 'now').mockImplementation(() => { return time++; }); - Object.defineProperty(performance, 'timeOrigin', { - value: time, - configurable: true, - }); - Object.defineProperty(performance, 'now', { - value: now, - configurable: true, - }); jest.resetModules(); diff --git a/packages/react-server/src/__tests__/ReactFlightServer-test.js b/packages/react-server/src/__tests__/ReactFlightServer-test.js index 17480985db5b..b17185b6ef1f 100644 --- a/packages/react-server/src/__tests__/ReactFlightServer-test.js +++ b/packages/react-server/src/__tests__/ReactFlightServer-test.js @@ -46,17 +46,10 @@ describe('ReactFlight', () => { time += timeMS; jest.advanceTimersByTime(timeMS); }; - const now = jest.fn().mockImplementation(() => { + jest.spyOn(performance, 'timeOrigin', 'get').mockReturnValue(time); + jest.spyOn(performance, 'now').mockImplementation(() => { return time++; }); - Object.defineProperty(performance, 'timeOrigin', { - value: time, - configurable: true, - }); - Object.defineProperty(performance, 'now', { - value: now, - configurable: true, - }); jest.resetModules(); jest.mock('react', () => require('react/react.react-server'));