mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
[tests] Revive Forget e2e tests
--- Revives e2e test infra from #587. - All React component-like functions are compiled. - `yarn jest` runs each e2e test twice (forget and no forget) Github Actions is already running `yarn test`, which includes all jest tests ``` Run yarn test yarn run v1.22.19 $ yarn workspaces run test > babel-plugin-react-forget $ yarn jest && yarn snap:build && yarn snap $ tsc && jest PASS main src/__tests__/Result-test.ts PASS main src/__tests__/DisjointSet-test.ts PASS e2e with forget src/__tests__/e2e/hello.e2e.js PASS e2e no forget src/__tests__/e2e/hello.e2e.js Test Suites: [4](https://github.com/facebook/react-forget/actions/runs/5732016200/job/15534129231?pr=1881#step:8:5) passed, 4 total Tests: 23 passed, 23 total Snapshots: 11 passed, 11 total Time: 6.1[5](https://github.com/facebook/react-forget/actions/runs/5732016200/job/15534129231?pr=1881#step:8:6)3 s ```
This commit is contained in:
@@ -55,8 +55,8 @@
|
||||
"glob": "^7.1.6",
|
||||
"jest": "^29.0.3",
|
||||
"jest-environment-jsdom": "^29.0.3",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react": "^0.0.0-experimental-493f72b0a-20230727",
|
||||
"react-dom": "^0.0.0-experimental-493f72b0a-20230727",
|
||||
"rimraf": "^3.0.2",
|
||||
"test262-harness": "^8.0.0",
|
||||
"ts-jest": "^29.1.1",
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
const ReactForgetBabelPlugin = require("../../dist").BabelPlugin;
|
||||
const babelJest = require("babel-jest");
|
||||
const { readFileSync } = require("fs");
|
||||
const { compile } = require("babel-plugin-react-forget");
|
||||
const { jsx } = require("@babel/plugin-syntax-jsx");
|
||||
const { execSync } = require("child_process");
|
||||
|
||||
module.exports = (useForget) => {
|
||||
function createTransformer() {
|
||||
@@ -17,18 +18,18 @@ module.exports = (useForget) => {
|
||||
"@babel/preset-typescript",
|
||||
{
|
||||
plugins: [
|
||||
"@babel/plugin-syntax-jsx",
|
||||
...(useForget
|
||||
useForget
|
||||
? [
|
||||
[
|
||||
ReactForgetBabelPlugin,
|
||||
{
|
||||
// Jest hashes the babel config as a cache breaker.
|
||||
cacheBreaker: readFileSync("dist/HASH", "utf8"),
|
||||
},
|
||||
],
|
||||
ReactForgetFunctionTransform,
|
||||
{
|
||||
// Jest hashes the babel config as a cache breaker.
|
||||
// (see https://github.com/jestjs/jest/blob/v29.6.2/packages/babel-jest/src/index.ts#L84)
|
||||
cacheKey: execSync(
|
||||
"yarn --silent --cwd ../.. hash packages/babel-plugin-react-forget/dist"
|
||||
).toString(),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
: "@babel/plugin-syntax-jsx",
|
||||
],
|
||||
},
|
||||
"@babel/preset-react",
|
||||
@@ -68,3 +69,68 @@ module.exports = (useForget) => {
|
||||
createTransformer,
|
||||
};
|
||||
};
|
||||
|
||||
// Copied from react/scripts/babel/transform-forget.js
|
||||
function isReactComponentLike(fn) {
|
||||
let isReactComponent = false;
|
||||
let hasNoUseForgetDirective = false;
|
||||
|
||||
// React components start with an upper case letter
|
||||
if (fn.node.id.name[0].toUpperCase() !== fn.node.id.name[0]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fn.traverse({
|
||||
DirectiveLiteral(path) {
|
||||
if (path.node.value === "use no forget") {
|
||||
hasNoUseForgetDirective = true;
|
||||
}
|
||||
},
|
||||
|
||||
JSX(path) {
|
||||
// Is there is a JSX node created in the current function context?
|
||||
if (path.scope.getFunctionParent()?.path.node === fn.node) {
|
||||
isReactComponent = true;
|
||||
}
|
||||
},
|
||||
|
||||
CallExpression(path) {
|
||||
// Is there hook usage?
|
||||
if (
|
||||
path.node.callee.type === "Identifier" &&
|
||||
path.node.callee.name.startsWith("use")
|
||||
) {
|
||||
isReactComponent = true;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (hasNoUseForgetDirective) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isReactComponent;
|
||||
}
|
||||
|
||||
function ReactForgetFunctionTransform() {
|
||||
const compiledFns = new Set();
|
||||
return {
|
||||
name: "react-forget-e2e",
|
||||
inherits: jsx,
|
||||
visitor: {
|
||||
FunctionDeclaration(fn) {
|
||||
if (compiledFns.has(fn.node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isReactComponentLike(fn)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const compiled = compile(fn);
|
||||
compiledFns.add(compiled);
|
||||
fn.replaceWith(compiled);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
*/
|
||||
|
||||
const React = require("react");
|
||||
const ForgetRuntime = require("../../packages/react-forget-runtime");
|
||||
React.unstable_ForgetRuntime = ForgetRuntime;
|
||||
React.unstable_useMemoCache = ForgetRuntime.unstable_useMemoCache;
|
||||
|
||||
// Our e2e babel transform currently only compiles functions, not programs.
|
||||
// As a result, our e2e transpiled code does not contain an import for `useMemoCache`
|
||||
// This is a hack.
|
||||
React.useMemoCache = React.unstable_useMemoCache;
|
||||
globalThis.useMemoCache = React.unstable_useMemoCache;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
const logs = [];
|
||||
|
||||
export function log(message) {
|
||||
logs.push(message);
|
||||
}
|
||||
|
||||
export function expectLogsAndClear(expected) {
|
||||
expect(logs).toEqual(expected);
|
||||
logs.length = 0;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import * as React from "react";
|
||||
import { render } from "@testing-library/react";
|
||||
import { expectLogsAndClear, log } from "./expectLogs";
|
||||
|
||||
function Hello({ name }) {
|
||||
const items = [1, 2, 3].map((item) => {
|
||||
log(`recomputing ${item}`);
|
||||
return <div key={item}>Item {item}</div>;
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
Hello<b>{name}</b>
|
||||
{items}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
test("hello", () => {
|
||||
const { asFragment, rerender } = render(<Hello name="World" />);
|
||||
|
||||
expect(asFragment()).toMatchInlineSnapshot(`
|
||||
<DocumentFragment>
|
||||
<div>
|
||||
Hello
|
||||
<b>
|
||||
World
|
||||
</b>
|
||||
<div>
|
||||
Item 1
|
||||
</div>
|
||||
<div>
|
||||
Item 2
|
||||
</div>
|
||||
<div>
|
||||
Item 3
|
||||
</div>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`);
|
||||
|
||||
expectLogsAndClear(["recomputing 1", "recomputing 2", "recomputing 3"]);
|
||||
|
||||
rerender(<Hello name="Universe" />);
|
||||
|
||||
expect(asFragment()).toMatchInlineSnapshot(`
|
||||
<DocumentFragment>
|
||||
<div>
|
||||
Hello
|
||||
<b>
|
||||
Universe
|
||||
</b>
|
||||
<div>
|
||||
Item 1
|
||||
</div>
|
||||
<div>
|
||||
Item 2
|
||||
</div>
|
||||
<div>
|
||||
Item 3
|
||||
</div>
|
||||
</div>
|
||||
</DocumentFragment>
|
||||
`);
|
||||
|
||||
expectLogsAndClear(
|
||||
__FORGET__ ? [] : ["recomputing 1", "recomputing 2", "recomputing 3"]
|
||||
);
|
||||
});
|
||||
@@ -4208,9 +4208,9 @@ caniuse-lite@^1.0.30001406, caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.300014
|
||||
integrity sha512-2efF8SAZwgAX1FJr87KWhvuJxnGJKOnctQa8xLOskAXNXq8oiuqgl6u1kk3fFpsp3GgvzlRjiK1sl63hNtFADw==
|
||||
|
||||
caniuse-lite@^1.0.30001503:
|
||||
version "1.0.30001517"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz#90fabae294215c3495807eb24fc809e11dc2f0a8"
|
||||
integrity sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==
|
||||
version "1.0.30001518"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001518.tgz#b3ca93904cb4699c01218246c4d77a71dbe97150"
|
||||
integrity sha512-rup09/e3I0BKjncL+FesTayKtPrdwKhUufQFd3riFw1hHg8JmIFoInYfB102cFcY/pPgGmdyl/iy+jgiDi2vdA==
|
||||
|
||||
caseless@~0.12.0:
|
||||
version "0.12.0"
|
||||
@@ -4979,9 +4979,9 @@ electron-to-chromium@^1.4.411:
|
||||
integrity sha512-1KnpDTS9onwAfMzW50LcpNtyOkMyjd/OLoD2Kx/DDITZqgNYixY71XNszPHNxyQQ/Brh+FDcUnf4BaM041sdWg==
|
||||
|
||||
electron-to-chromium@^1.4.431:
|
||||
version "1.4.476"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.476.tgz#693df619ce1785ada6d5aec71fd3ce7ace71adc3"
|
||||
integrity sha512-gzWl1m8pNy+5Kj17XcziNcbOhripjTqR2wAQmtdlFUngPYuFy7zUpJScVQAvCvQSFHNk3mS5fetNKW6BSpytFg==
|
||||
version "1.4.479"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.479.tgz#ec9f676f23d3a0b0e429bc454d25e0b3253d2118"
|
||||
integrity sha512-ABv1nHMIR8I5n3O3Een0gr6i0mfM+YcTZqjHy3pAYaOjgFG+BMquuKrSyfYf5CbEkLr9uM05RA3pOk4udNB/aQ==
|
||||
|
||||
elliptic@^6.5.3:
|
||||
version "6.5.4"
|
||||
@@ -9695,7 +9695,7 @@ rc@^1.2.7:
|
||||
minimist "^1.2.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
|
||||
react-dom@18.2.0, react-dom@^18.2.0:
|
||||
react-dom@18.2.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
|
||||
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
|
||||
@@ -9703,6 +9703,14 @@ react-dom@18.2.0, react-dom@^18.2.0:
|
||||
loose-envify "^1.1.0"
|
||||
scheduler "^0.23.0"
|
||||
|
||||
react-dom@^0.0.0-experimental-493f72b0a-20230727:
|
||||
version "0.0.0-experimental-493f72b0a-20230727"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-0.0.0-experimental-493f72b0a-20230727.tgz#02b95966cbccafdb5eff411bd77cf9a99b4ac38c"
|
||||
integrity sha512-Ms+rLKteABVNHRjqj2VIQg7biJYb3jB2paJJGGF579Mi22UQnyAVypbCTedzFUDhtpxs+LDR45QNFT5kDIEeaw==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
scheduler "0.0.0-experimental-493f72b0a-20230727"
|
||||
|
||||
react-is@^16.13.1, react-is@^16.8.4:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
@@ -9718,13 +9726,20 @@ react-is@^18.0.0:
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
|
||||
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
|
||||
|
||||
react@18.2.0, react@^18.2.0:
|
||||
react@18.2.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
|
||||
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
|
||||
react@^0.0.0-experimental-493f72b0a-20230727:
|
||||
version "0.0.0-experimental-493f72b0a-20230727"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-0.0.0-experimental-493f72b0a-20230727.tgz#c1e165db1d1c2dc944e5e1759a860807b06503ed"
|
||||
integrity sha512-AivNXEA/rd+x9Oe+5JIgsAFGaBQZg0c85upbziIYbgxW1BT6iOFUFA38i+SMfd1ktD82E1yj4nH/OpfA8kC3Cg==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
|
||||
read-cache@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774"
|
||||
@@ -10098,6 +10113,13 @@ saxes@^6.0.0:
|
||||
dependencies:
|
||||
xmlchars "^2.2.0"
|
||||
|
||||
scheduler@0.0.0-experimental-493f72b0a-20230727:
|
||||
version "0.0.0-experimental-493f72b0a-20230727"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.0.0-experimental-493f72b0a-20230727.tgz#a4d1fd57d9bfbd68b1b3e3c3249765f92c1a7b34"
|
||||
integrity sha512-6bKnt2pR0XjH4ix7rYCp8+KR5eutR0hDpCiU++14SuImTH0uMYa3Gp4ayLeMyAvOEFTCgewDS/faZF1J14sRew==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
|
||||
scheduler@^0.23.0:
|
||||
version "0.23.0"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
|
||||
|
||||
Reference in New Issue
Block a user