@samitouri / QOS-React / commits / 9a1db2d21f

chore: add single versioned implementation of act for DevTools tests (#28186)

- Moving `act` implementation to a single getter-function, which is based on React version we are testing RDT against. - Removing unused mocks for `act`, which were designed for legacy versions of React, validated with running tests against React 16 build.

Ruslan Lesiutin committed Feb 5, 2024 at 15:38 UTC 9a1db2d21fac88a42094fa3fc266d1692551a5bd
3 files changed +32 -40
packages/react-devtools-shared/src/__tests__/utils.js
+32 -8
@@ -7,6 +7,8 @@
7 * @flow
8 */
9
10 +import semver from 'semver';
11 +
12 import typeof ReactTestRenderer from 'react-test-renderer';
13
14 import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
@@ -14,16 +16,38 @@ import type Store from 'react-devtools-shared/src/devtools/store';
16 import type {ProfilingDataFrontend} from 'react-devtools-shared/src/devtools/views/Profiler/types';
17 import type {ElementType} from 'react-devtools-shared/src/frontend/types';
18
19 +import {ReactVersion} from '../../../../ReactVersions';
20 +
21 +const requestedReactVersion = process.env.REACT_VERSION || ReactVersion;
22 +export function getActDOMImplementation(): () => void | Promise<void> {
23 + // This is for React < 18, where act was distributed in react-dom/test-utils.
24 + if (semver.lt(requestedReactVersion, '18.0.0')) {
25 + const ReactDOMTestUtils = require('react-dom/test-utils');
26 + return ReactDOMTestUtils.act;
27 + }
28 +
29 + const React = require('react');
30 + // This is for React 18, where act was distributed in react as unstable.
31 + if (React.unstable_act) {
32 + return React.unstable_act;
33 + }
34 +
35 + // This is for React > 18, where act is marked as stable.
36 + if (React.act) {
37 + return React.act;
38 + }
39 +
40 + throw new Error("Couldn't find any available act implementation");
41 +}
42 +
43 export function act(
44 callback: Function,
45 recursivelyFlush: boolean = true,
46 ): void {
47 + // act from react-test-renderer has some side effects on React DevTools
48 + // it injects the renderer for DevTools, see ReactTestRenderer.js
49 const {act: actTestRenderer} = require('react-test-renderer');
22 - // Use `require('react-dom/test-utils').act` as a fallback for React 17, which can be used in integration tests for React DevTools.
23 - const actDOM =
24 - require('react').act ||
25 - require('react').unstable_act ||
26 - require('react-dom/test-utils').act;
50 + const actDOM = getActDOMImplementation();
51
52 actDOM(() => {
53 actTestRenderer(() => {
@@ -47,10 +71,10 @@ export async function actAsync(
71 cb: () => *,
72 recursivelyFlush: boolean = true,
73 ): Promise<void> {
74 + // act from react-test-renderer has some side effects on React DevTools
75 + // it injects the renderer for DevTools, see ReactTestRenderer.js
76 const {act: actTestRenderer} = require('react-test-renderer');
51 - // Use `require('react-dom/test-utils').act` as a fallback for React 17, which can be used in integration tests for React DevTools.
52 - const actDOM =
53 - require('react').unstable_act || require('react-dom/test-utils').act;
77 + const actDOM = getActDOMImplementation();
78
79 await actDOM(async () => {
80 await actTestRenderer(async () => {
scripts/jest/devtools/config.build-devtools-regression.js
-2
@@ -31,8 +31,6 @@ if (REACT_VERSION) {
31 '^react-dom/client$'
32 ] = `<rootDir>/build/${NODE_MODULES_DIR}/react-dom`;
33 }
34 -
35 - setupFiles.push(require.resolve('./setupTests.build-devtools-regression'));
34 }
35
36 module.exports = {
scripts/jest/devtools/setupTests.build-devtools-regression.js deleted
-30
@@ -1,30 +0,0 @@
1 -'use strict';
2 -
3 -// Regression tests use a React DOM profiling, so we need
4 -// to replace these tests with scheduler/tracing-profiling
5 -jest.mock('scheduler/tracing', () => {
6 - return jest.requireActual('scheduler/tracing-profiling');
7 -});
8 -
9 -// act doesn't exist in older versions of React, but
10 -// DevTools tests sometimes import and depend on act to run.
11 -// If act doesn't exist for a particular version of React, we will
12 -// mock it with a function. This should work in most tests
13 -// that we want to call with older versions of React.
14 -// TODO (luna) Refactor act in DevTools test utils to not depend
15 -// on act in react-dom or react-test-renderer so we don't need to do this
16 -jest.mock('react-test-renderer', () => {
17 - const reactTestRenderer = jest.requireActual('react-test-renderer');
18 - if (!reactTestRenderer.act) {
19 - reactTestRenderer.act = fn => fn();
20 - }
21 - return reactTestRenderer;
22 -});
23 -
24 -jest.mock('react-dom/test-utils', () => {
25 - const testUtils = jest.requireActual('react-dom/test-utils');
26 - if (!testUtils.act) {
27 - testUtils.act = fn => fn();
28 - }
29 - return testUtils;
30 -});