tests[react-devtools]: added tests for Compiler integration (#31241)

Adds tests for Compiler integration.

This includes:
- Tests against Compiler from source.
- Versioned (18.2 - <19) tests against Compiler from npm.

For tests against React 18.2, I had to download `react-compiler-runtime`
from npm and put it to `react/compiler-runtime.js`.
This commit is contained in:
Ruslan Lesiutin
2024-10-17 09:02:41 +01:00
committed by GitHub
parent 3ed64f8232
commit bf7e210cb5
3 changed files with 120 additions and 1 deletions

View File

@@ -103,6 +103,7 @@ jobs:
- "16.8" # hooks
- "17.0"
- "18.0"
- "18.2" # compiler polyfill
continue-on-error: true
steps:
- uses: actions/checkout@v4

View File

@@ -0,0 +1,101 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import {getVersionedRenderImplementation} from './utils';
describe('CompilerIntegration', () => {
global.IS_REACT_ACT_ENVIRONMENT = true;
let React;
let act;
let useMemoCache;
beforeEach(() => {
React = require('react');
require('react-dom');
require('react-dom/client');
useMemoCache = require('react/compiler-runtime').c;
const utils = require('./utils');
act = utils.act;
});
afterEach(() => {
jest.restoreAllMocks();
});
const {render} = getVersionedRenderImplementation();
// @reactVersion >= 18.2
it('By default, component display names should not have Forget prefix', () => {
const hook = global.__REACT_DEVTOOLS_GLOBAL_HOOK__;
const reactDOMFiberRendererInterface = hook.rendererInterfaces.get(1);
expect(reactDOMFiberRendererInterface).not.toBeFalsy();
const Foo = () => {
// eslint-disable-next-line no-unused-vars
const [val, setVal] = React.useState(null);
return (
<div>
<Bar />
</div>
);
};
const Bar = () => <div>Hi!</div>;
act(() => render(<Foo />));
expect(
reactDOMFiberRendererInterface
.getDisplayNameForElementID(2)
.indexOf('Forget'),
).toBe(-1);
expect(
reactDOMFiberRendererInterface
.getDisplayNameForElementID(3)
.indexOf('Forget'),
).toBe(-1);
});
// For React 18.2, this will install uMC polyfill from react-compiler-runtime available on npm.
// @reactVersion >= 18.2
it('If useMemoCache used, the corresponding displayName for a component should have Forget prefix', () => {
const hook = global.__REACT_DEVTOOLS_GLOBAL_HOOK__;
const reactDOMFiberRendererInterface = hook.rendererInterfaces.get(1);
expect(reactDOMFiberRendererInterface).not.toBeFalsy();
const Foo = () => {
// eslint-disable-next-line no-unused-vars
const $ = useMemoCache(1);
// eslint-disable-next-line no-unused-vars
const [val, setVal] = React.useState(null);
return (
<div>
<Bar />
</div>
);
};
const Bar = () => <div>Hi!</div>;
act(() => render(<Foo />));
// useMemoCache is only used by Foo component
expect(
reactDOMFiberRendererInterface
.getDisplayNameForElementID(2)
.indexOf('Forget'),
).toBe(0);
expect(
reactDOMFiberRendererInterface
.getDisplayNameForElementID(3)
.indexOf('Forget'),
).toBe(-1);
});
});

View File

@@ -82,11 +82,12 @@ async function downloadRegressionBuild() {
);
await exec(`mv ${movePackageString} ${buildPath}`);
const reactVersion = semver.coerce(version).version;
// For React versions earlier than 18.0.0, we explicitly scheduler v0.20.1, which
// is the first version that has unstable_mock, which DevTools tests need, but also
// has Scheduler.unstable_trace, which, although we don't use in DevTools tests
// is imported by older React versions and will break if it's not there
if (semver.lte(semver.coerce(version).version, '18.0.0')) {
if (semver.lte(reactVersion, '18.0.0')) {
await exec(`npm install --prefix ${REGRESSION_FOLDER} scheduler@0.20.1`);
}
@@ -108,6 +109,22 @@ async function downloadRegressionBuild() {
)} ${buildPath}`
);
}
if (semver.gte(reactVersion, '18.2.0') && semver.lt(reactVersion, '19')) {
console.log(chalk.white(`Downloading react-compiler-runtime\n`));
await exec(
`npm install --prefix ${REGRESSION_FOLDER} react-compiler-runtime`
);
console.log(
chalk.white(
`Moving react-compiler-runtime to react/compiler-runtime.js\n`
)
);
await exec(
`mv ${REGRESSION_FOLDER}/node_modules/react-compiler-runtime/dist/index.js ${buildPath}/react/compiler-runtime.js`
);
}
}
async function main() {