@samitouri / QOS-React-1 / commits / 96f10e058b

[be][tests] Change fixtures to evaluate successfully instead of throwing

--- Not dependent on changes from #2366, but now the fix is easy to review

Mofei Zhang committed Nov 16, 2023 at 18:12 UTC 96f10e058b76372885f99b948e5194842bd02dc4
44 files changed +223 -196
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/capture-indirect-mutate-alias-iife.expect.md
+5 -5
@@ -16,8 +16,7 @@ function component(a) {
16
17 export const FIXTURE_ENTRYPOINT = {
18 fn: component,
19 - params: ["TodoAdd"],
20 - isComponent: "TodoAdd",
19 + params: [2],
20 };
21
22 ```
@@ -46,9 +45,10 @@ function component(a) {
45
46 export const FIXTURE_ENTRYPOINT = {
47 fn: component,
49 - params: ["TodoAdd"],
50 - isComponent: "TodoAdd",
48 + params: [2],
49 };
50
51 ```
54 -
\ No newline at end of file
52 +
53 +### Eval output
54 +(kind: ok) {"a":2,"b":1}
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/capture-indirect-mutate-alias-iife.js
+1 -2
@@ -12,6 +12,5 @@ function component(a) {
12
13 export const FIXTURE_ENTRYPOINT = {
14 fn: component,
15 - params: ["TodoAdd"],
16 - isComponent: "TodoAdd",
15 + params: [2],
16 };
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/capture_mutate-across-fns-iife.expect.md
+5 -5
@@ -14,8 +14,7 @@ function component(a) {
14
15 export const FIXTURE_ENTRYPOINT = {
16 fn: component,
17 - params: ["TodoAdd"],
18 - isComponent: "TodoAdd",
17 + params: [2],
18 };
19
20 ```
@@ -43,9 +42,10 @@ function component(a) {
42
43 export const FIXTURE_ENTRYPOINT = {
44 fn: component,
46 - params: ["TodoAdd"],
47 - isComponent: "TodoAdd",
45 + params: [2],
46 };
47
48 ```
51 -
\ No newline at end of file
49 +
50 +### Eval output
51 +(kind: ok) {"a":2,"b":1}
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/capture_mutate-across-fns-iife.js
+1 -2
@@ -10,6 +10,5 @@ function component(a) {
10
11 export const FIXTURE_ENTRYPOINT = {
12 fn: component,
13 - params: ["TodoAdd"],
14 - isComponent: "TodoAdd",
13 + params: [2],
14 };
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/capturing-function-alias-computed-load-3-iife.expect.md
+11 -5
@@ -16,8 +16,10 @@ function bar(a, b) {
16
17 export const FIXTURE_ENTRYPOINT = {
18 fn: bar,
19 - params: ["TodoAdd"],
20 - isComponent: "TodoAdd",
19 + params: [
20 + [1, 2],
21 + [2, 3],
22 + ],
23 };
24
25 ```
@@ -50,9 +52,13 @@ function bar(a, b) {
52
53 export const FIXTURE_ENTRYPOINT = {
54 fn: bar,
53 - params: ["TodoAdd"],
54 - isComponent: "TodoAdd",
55 + params: [
56 + [1, 2],
57 + [2, 3],
58 + ],
59 };
60
61 ```
58 -
\ No newline at end of file
62 +
63 +### Eval output
64 +(kind: ok) 2
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/capturing-function-alias-computed-load-3-iife.js
+4 -2
@@ -12,6 +12,8 @@ function bar(a, b) {
12
13 export const FIXTURE_ENTRYPOINT = {
14 fn: bar,
15 - params: ["TodoAdd"],
16 - isComponent: "TodoAdd",
15 + params: [
16 + [1, 2],
17 + [2, 3],
18 + ],
19 };
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/capturing-function-alias-computed-load-iife.expect.md
+3 -3
@@ -15,7 +15,6 @@ function bar(a) {
15 export const FIXTURE_ENTRYPOINT = {
16 fn: bar,
17 params: ["TodoAdd"],
18 - isComponent: "TodoAdd",
18 };
19
20 ```
@@ -44,8 +43,9 @@ function bar(a) {
43 export const FIXTURE_ENTRYPOINT = {
44 fn: bar,
45 params: ["TodoAdd"],
47 - isComponent: "TodoAdd",
46 };
47
48 ```
51 -
\ No newline at end of file
49 +
50 +### Eval output
51 +(kind: ok) "TodoAdd"
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/capturing-function-alias-computed-load-iife.js
-1
@@ -11,5 +11,4 @@ function bar(a) {
11 export const FIXTURE_ENTRYPOINT = {
12 fn: bar,
13 params: ["TodoAdd"],
14 - isComponent: "TodoAdd",
14 };
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/flatten-scopes-with-methodcall-hook.expect.md
+3 -9
@@ -6,7 +6,7 @@ const { ObjectWithHooks } = require("shared-runtime");
6
7 function Component(props) {
8 const x = [];
9 - const [y] = ObjectWithHooks.useFoo();
9 + const [y] = ObjectWithHooks.useMakeArray();
10 x.push(y);
11 return y;
12 }
@@ -25,7 +25,7 @@ const { ObjectWithHooks } = require("shared-runtime");
25
26 function Component(props) {
27 const x = [];
28 - const [y] = ObjectWithHooks.useFoo();
28 + const [y] = ObjectWithHooks.useMakeArray();
29 x.push(y);
30 return y;
31 }
@@ -38,10 +38,4 @@ export const FIXTURE_ENTRYPOINT = {
38 ```
39
40 ### Eval output
41 -(kind: exception) number 0 is not iterable (cannot read property Symbol(Symbol.iterator))
42 -logs: ['The above error occurred in the <WrapperTestComponent> component:\n' +
43 - '\n' +
44 - ' at WrapperTestComponent (<project_root>/packages/sprout/dist/runner-evaluator.js:50:26)\n' +
45 - '\n' +
46 - 'Consider adding an error boundary to your tree to customize error handling behavior.\n' +
47 - 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.']
\ No newline at end of file
41 +(kind: ok) 1
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/flatten-scopes-with-methodcall-hook.js
+1 -1
@@ -2,7 +2,7 @@ const { ObjectWithHooks } = require("shared-runtime");
2
3 function Component(props) {
4 const x = [];
5 - const [y] = ObjectWithHooks.useFoo();
5 + const [y] = ObjectWithHooks.useMakeArray();
6 x.push(y);
7 return y;
8 }
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/for-loop-let-undefined-decl.expect.md
+12 -7
@@ -2,6 +2,11 @@
2 ## Input
3
4 ```javascript
5 +// These variables are unknown to useFoo, as they are
6 +// defined at module scope or implicit globals
7 +const isSelected = false;
8 +const isCurrent = true;
9 +
10 function useFoo() {
11 for (let i = 0; i <= 5; i++) {
12 let color;
@@ -24,6 +29,11 @@ export const FIXTURE_ENTRYPOINT = {
29 ## Code
30
31 ```javascript
32 +// These variables are unknown to useFoo, as they are
33 +// defined at module scope or implicit globals
34 +const isSelected = false;
35 +const isCurrent = true;
36 +
37 function useFoo() {
38 for (let i = 0; i <= 5; i++) {
39 let color;
@@ -45,10 +55,5 @@ export const FIXTURE_ENTRYPOINT = {
55 ```
56
57 ### Eval output
48 -(kind: exception) isSelected is not defined
49 -logs: ['The above error occurred in the <WrapperTestComponent> component:\n' +
50 - '\n' +
51 - ' at WrapperTestComponent (<project_root>/packages/sprout/dist/runner-evaluator.js:50:26)\n' +
52 - '\n' +
53 - 'Consider adding an error boundary to your tree to customize error handling behavior.\n' +
54 - 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.']
\ No newline at end of file
58 +(kind: ok)
59 +logs: ['#CCFF03','#CCFF03','#CCFF03','#CCFF03','#CCFF03','#CCFF03']
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/for-loop-let-undefined-decl.js
+5
@@ -1,3 +1,8 @@
1 +// These variables are unknown to useFoo, as they are
2 +// defined at module scope or implicit globals
3 +const isSelected = false;
4 +const isCurrent = true;
5 +
6 function useFoo() {
7 for (let i = 0; i <= 5; i++) {
8 let color;
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/hoisting-computed-member-expression.expect.md
-2
@@ -18,7 +18,6 @@ function hoisting() {
18 export const FIXTURE_ENTRYPOINT = {
19 fn: hoisting,
20 params: [],
21 - isComponent: false,
21 };
22
23 ```
@@ -60,7 +59,6 @@ function hoisting() {
59 export const FIXTURE_ENTRYPOINT = {
60 fn: hoisting,
61 params: [],
63 - isComponent: false,
62 };
63
64 ```
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/hoisting-computed-member-expression.js
-1
@@ -14,5 +14,4 @@ function hoisting() {
14 export const FIXTURE_ENTRYPOINT = {
15 fn: hoisting,
16 params: [],
17 - isComponent: false,
17 };
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/hoisting-member-expression.expect.md
+7 -9
@@ -2,13 +2,15 @@
2 ## Input
3
4 ```javascript
5 +import { Stringify } from "shared-runtime";
6 +
7 function hoisting() {
8 function onClick(x) {
9 return x + bar.baz;
10 }
11 const bar = { baz: 1 };
12
11 - return <Button onClick={onClick} />;
13 + return <Stringify onClick={onClick} />;
14 }
15
16 export const FIXTURE_ENTRYPOINT = {
@@ -23,6 +25,8 @@ export const FIXTURE_ENTRYPOINT = {
25
26 ```javascript
27 import { unstable_useMemoCache as useMemoCache } from "react";
28 +import { Stringify } from "shared-runtime";
29 +
30 function hoisting() {
31 const $ = useMemoCache(2);
32 let onClick;
@@ -38,7 +42,7 @@ function hoisting() {
42 }
43 let t0;
44 if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
41 - t0 = <Button onClick={onClick} />;
45 + t0 = <Stringify onClick={onClick} />;
46 $[1] = t0;
47 } else {
48 t0 = $[1];
@@ -55,10 +59,4 @@ export const FIXTURE_ENTRYPOINT = {
59 ```
60
61 ### Eval output
58 -(kind: exception) Button is not defined
59 -logs: ['The above error occurred in the <WrapperTestComponent> component:\n' +
60 - '\n' +
61 - ' at WrapperTestComponent (<project_root>/packages/sprout/dist/runner-evaluator.js:50:26)\n' +
62 - '\n' +
63 - 'Consider adding an error boundary to your tree to customize error handling behavior.\n' +
64 - 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.']
\ No newline at end of file
62 +(kind: ok) <div>{"onClick":"[[ function params=1 ]]"}</div>
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/hoisting-member-expression.js
+3 -1
@@ -1,10 +1,12 @@
1 +import { Stringify } from "shared-runtime";
2 +
3 function hoisting() {
4 function onClick(x) {
5 return x + bar.baz;
6 }
7 const bar = { baz: 1 };
8
7 - return <Button onClick={onClick} />;
9 + return <Stringify onClick={onClick} />;
10 }
11
12 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/hoisting-nested-block-statements.expect.md
+12 -7
@@ -2,20 +2,21 @@
2 ## Input
3
4 ```javascript
5 +import { print } from "shared-runtime";
6 +
7 function hoisting(cond) {
8 if (cond) {
9 const x = 1;
8 - foo(x);
10 + print(x);
11 }
12
13 const x = 2;
12 - foo(x);
14 + print(x);
15 }
16
17 export const FIXTURE_ENTRYPOINT = {
18 fn: hoisting,
19 params: [false],
18 - isComponent: false,
20 };
21
22 ```
@@ -23,19 +24,23 @@ export const FIXTURE_ENTRYPOINT = {
24 ## Code
25
26 ```javascript
27 +import { print } from "shared-runtime";
28 +
29 function hoisting(cond) {
30 if (cond) {
28 - foo(1);
31 + print(1);
32 }
33
31 - foo(2);
34 + print(2);
35 }
36
37 export const FIXTURE_ENTRYPOINT = {
38 fn: hoisting,
39 params: [false],
37 - isComponent: false,
40 };
41
42 ```
41 -
\ No newline at end of file
43 +
44 +### Eval output
45 +(kind: ok)
46 +logs: [2]
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/hoisting-nested-block-statements.js
+4 -3
@@ -1,15 +1,16 @@
1 +import { print } from "shared-runtime";
2 +
3 function hoisting(cond) {
4 if (cond) {
5 const x = 1;
4 - foo(x);
6 + print(x);
7 }
8
9 const x = 2;
8 - foo(x);
10 + print(x);
11 }
12
13 export const FIXTURE_ENTRYPOINT = {
14 fn: hoisting,
15 params: [false],
14 - isComponent: false,
16 };
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/iife-return-modified-later-logical.expect.md
+7 -9
@@ -2,9 +2,11 @@
2 ## Input
3
4 ```javascript
5 +import { getNull } from "shared-runtime";
6 +
7 function Component(props) {
8 const items = (() => {
7 - return foo() ?? [];
9 + return getNull() ?? [];
10 })();
11 items.push(props.a);
12 return items;
@@ -21,12 +23,14 @@ export const FIXTURE_ENTRYPOINT = {
23
24 ```javascript
25 import { unstable_useMemoCache as useMemoCache } from "react";
26 +import { getNull } from "shared-runtime";
27 +
28 function Component(props) {
29 const $ = useMemoCache(3);
30 let t10;
31 let items;
32 if ($[0] !== props.a) {
29 - t10 = foo() ?? [];
33 + t10 = getNull() ?? [];
34 items = t10;
35
36 items.push(props.a);
@@ -48,10 +52,4 @@ export const FIXTURE_ENTRYPOINT = {
52 ```
53
54 ### Eval output
51 -(kind: exception) foo is not defined
52 -logs: ['The above error occurred in the <WrapperTestComponent> component:\n' +
53 - '\n' +
54 - ' at WrapperTestComponent (<project_root>/packages/sprout/dist/runner-evaluator.js:50:26)\n' +
55 - '\n' +
56 - 'Consider adding an error boundary to your tree to customize error handling behavior.\n' +
57 - 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.']
\ No newline at end of file
55 +(kind: ok) [{}]
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/iife-return-modified-later-logical.js
+3 -1
@@ -1,6 +1,8 @@
1 +import { getNull } from "shared-runtime";
2 +
3 function Component(props) {
4 const items = (() => {
3 - return foo() ?? [];
5 + return getNull() ?? [];
6 })();
7 items.push(props.a);
8 return items;
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-attribute-with-jsx-fragment-value.flow.expect.md
+14 -16
@@ -3,6 +3,8 @@
3
4 ```javascript
5 // @flow
6 +import { Stringify } from "shared-runtime";
7 +
8 function Component({items}) {
9 // Per the spec, <Foo value=<>{...}</> /> is valid.
10 // But many tools don't allow fragments as jsx attribute values,
@@ -10,14 +12,14 @@ function Component({items}) {
12 return items.length > 0
13 ? (
14 <Foo value={
13 - <>{items.map(item => <Bar key={item.id} item={item} />)}</>
15 + <>{items.map(item => <Stringify key={item.id} item={item} />)}</>
16 }></Foo>
17 )
18 : null;
19 }
20
19 -function Foo({item}) {
20 - return <div>{item.name}</div>;
21 +function Foo({value}) {
22 + return <div>{value}</div>;
23 }
24
25 export const FIXTURE_ENTRYPOINT = {
@@ -30,6 +32,8 @@ export const FIXTURE_ENTRYPOINT = {
32
33 ```javascript
34 import { unstable_useMemoCache as useMemoCache } from "react";
35 +import { Stringify } from "shared-runtime";
36 +
37 function Component(t26) {
38 const $ = useMemoCache(2);
39 const { items } = t26;
@@ -41,7 +45,7 @@ function Component(t26) {
45 value={
46 <>
47 {items.map((item) => (
44 - <Bar key={item.id} item={item} />
48 + <Stringify key={item.id} item={item} />
49 ))}
50 </>
51 }
@@ -55,13 +59,13 @@ function Component(t26) {
59 return t0;
60 }
61
58 -function Foo(t7) {
62 +function Foo(t6) {
63 const $ = useMemoCache(2);
60 - const { item } = t7;
64 + const { value } = t6;
65 let t0;
62 - if ($[0] !== item.name) {
63 - t0 = <div>{item.name}</div>;
64 - $[0] = item.name;
66 + if ($[0] !== value) {
67 + t0 = <div>{value}</div>;
68 + $[0] = value;
69 $[1] = t0;
70 } else {
71 t0 = $[1];
@@ -77,10 +81,4 @@ export const FIXTURE_ENTRYPOINT = {
81 ```
82
83 ### Eval output
80 -(kind: exception) Bar is not defined
81 -logs: ['The above error occurred in the <WrapperTestComponent> component:\n' +
82 - '\n' +
83 - ' at WrapperTestComponent (<project_root>/packages/sprout/dist/runner-evaluator.js:50:26)\n' +
84 - '\n' +
85 - 'Consider adding an error boundary to your tree to customize error handling behavior.\n' +
86 - 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.']
\ No newline at end of file
84 +(kind: ok) <div><div>{"item":{"id":1,"name":"One!"}}</div></div>
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-attribute-with-jsx-fragment-value.flow.js
+5 -3
@@ -1,4 +1,6 @@
1 // @flow
2 +import { Stringify } from "shared-runtime";
3 +
4 function Component({items}) {
5 // Per the spec, <Foo value=<>{...}</> /> is valid.
6 // But many tools don't allow fragments as jsx attribute values,
@@ -6,14 +8,14 @@ function Component({items}) {
8 return items.length > 0
9 ? (
10 <Foo value={
9 - <>{items.map(item => <Bar key={item.id} item={item} />)}</>
11 + <>{items.map(item => <Stringify key={item.id} item={item} />)}</>
12 }></Foo>
13 )
14 : null;
15 }
16
15 -function Foo({item}) {
16 - return <div>{item.name}</div>;
17 +function Foo({value}) {
18 + return <div>{value}</div>;
19 }
20
21 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-empty-expression.expect.md
+2 -4
@@ -13,8 +13,7 @@ export function Component(props) {
13
14 export const FIXTURE_ENTRYPOINT = {
15 fn: Component,
16 - params: ["TodoAdd"],
17 - isComponent: "TodoAdd",
16 + params: [{ a: "hello" }],
17 };
18
19 ```
@@ -38,8 +37,7 @@ export function Component(props) {
37
38 export const FIXTURE_ENTRYPOINT = {
39 fn: Component,
41 - params: ["TodoAdd"],
42 - isComponent: "TodoAdd",
40 + params: [{ a: "hello" }],
41 };
42
43 ```
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-empty-expression.js
+1 -2
@@ -9,6 +9,5 @@ export function Component(props) {
9
10 export const FIXTURE_ENTRYPOINT = {
11 fn: Component,
12 - params: ["TodoAdd"],
13 - isComponent: "TodoAdd",
12 + params: [{ a: "hello" }],
13 };
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/merge-consecutive-scopes-objects.expect.md
+10 -10
@@ -2,6 +2,9 @@
2 ## Input
3
4 ```javascript
5 +import { useState } from "react";
6 +import { Stringify } from "shared-runtime";
7 +
8 // @enableMergeConsecutiveScopes
9 // This is a translation of the original merge-consecutive-scopes which uses plain objects
10 // to describe the UI instead of JSX. The JSXText elements in that fixture happen to
@@ -10,7 +13,7 @@
13 function Component(props) {
14 let [state, setState] = useState(0);
15 return [
13 - { component: Title, props: { text: "Counter" } },
16 + { component: Stringify, props: { text: "Counter" } },
17 { component: "span", props: { children: [state] } },
18 {
19 component: "button",
@@ -33,7 +36,10 @@ export const FIXTURE_ENTRYPOINT = {
36 ## Code
37
38 ```javascript
36 -import { unstable_useMemoCache as useMemoCache } from "react"; // @enableMergeConsecutiveScopes
39 +import { useState, unstable_useMemoCache as useMemoCache } from "react";
40 +import { Stringify } from "shared-runtime";
41 +
42 +// @enableMergeConsecutiveScopes
43 // This is a translation of the original merge-consecutive-scopes which uses plain objects
44 // to describe the UI instead of JSX. The JSXText elements in that fixture happen to
45 // prevent scome scopes from merging, which concealed a bug with the merging logic.
@@ -43,7 +49,7 @@ function Component(props) {
49 const [state, setState] = useState(0);
50 let t0;
51 if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
46 - t0 = { component: Title, props: { text: "Counter" } };
52 + t0 = { component: Stringify, props: { text: "Counter" } };
53 $[0] = t0;
54 } else {
55 t0 = $[0];
@@ -102,10 +108,4 @@ export const FIXTURE_ENTRYPOINT = {
108 ```
109
110 ### Eval output
105 -(kind: exception) useState is not defined
106 -logs: ['The above error occurred in the <WrapperTestComponent> component:\n' +
107 - '\n' +
108 - ' at WrapperTestComponent (<project_root>/packages/sprout/dist/runner-evaluator.js:50:26)\n' +
109 - '\n' +
110 - 'Consider adding an error boundary to your tree to customize error handling behavior.\n' +
111 - 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.']
\ No newline at end of file
111 +(kind: ok) [{"component":"[[ function params=1 ]]","props":{"text":"Counter"}},{"component":"span","props":{"children":[0]}},{"component":"button","props":{"data-testid":"button","onClick":"[[ function params=0 ]]","children":["increment"]}}]
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/merge-consecutive-scopes-objects.js
+4 -1
@@ -1,3 +1,6 @@
1 +import { useState } from "react";
2 +import { Stringify } from "shared-runtime";
3 +
4 // @enableMergeConsecutiveScopes
5 // This is a translation of the original merge-consecutive-scopes which uses plain objects
6 // to describe the UI instead of JSX. The JSXText elements in that fixture happen to
@@ -6,7 +9,7 @@
9 function Component(props) {
10 let [state, setState] = useState(0);
11 return [
9 - { component: Title, props: { text: "Counter" } },
12 + { component: Stringify, props: { text: "Counter" } },
13 { component: "span", props: { children: [state] } },
14 {
15 component: "button",
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/merge-consecutive-scopes.expect.md
+10 -10
@@ -2,12 +2,15 @@
2 ## Input
3
4 ```javascript
5 +import { useState } from "react";
6 +import { Stringify } from "shared-runtime";
7 +
8 // @enableMergeConsecutiveScopes
9 function Component() {
10 let [state, setState] = useState(0);
11 return (
12 <div>
10 - <Title text="Counter" />
13 + <Stringify text="Counter" />
14 <span>{state}</span>
15 <button data-testid="button" onClick={() => setState(state + 1)}>
16 increment
@@ -26,13 +29,16 @@ export const FIXTURE_ENTRYPOINT = {
29 ## Code
30
31 ```javascript
29 -import { unstable_useMemoCache as useMemoCache } from "react"; // @enableMergeConsecutiveScopes
32 +import { useState, unstable_useMemoCache as useMemoCache } from "react";
33 +import { Stringify } from "shared-runtime";
34 +
35 +// @enableMergeConsecutiveScopes
36 function Component() {
37 const $ = useMemoCache(8);
38 const [state, setState] = useState(0);
39 let t0;
40 if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
35 - t0 = <Title text="Counter" />;
41 + t0 = <Stringify text="Counter" />;
42 $[0] = t0;
43 } else {
44 t0 = $[0];
@@ -83,10 +89,4 @@ export const FIXTURE_ENTRYPOINT = {
89 ```
90
91 ### Eval output
86 -(kind: exception) useState is not defined
87 -logs: ['The above error occurred in the <WrapperTestComponent> component:\n' +
88 - '\n' +
89 - ' at WrapperTestComponent (<project_root>/packages/sprout/dist/runner-evaluator.js:50:26)\n' +
90 - '\n' +
91 - 'Consider adding an error boundary to your tree to customize error handling behavior.\n' +
92 - 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.']
\ No newline at end of file
92 +(kind: ok) <div><div>{"text":"Counter"}</div><span>0</span><button data-testid="button">increment</button></div>
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/merge-consecutive-scopes.js
+4 -1
@@ -1,9 +1,12 @@
1 +import { useState } from "react";
2 +import { Stringify } from "shared-runtime";
3 +
4 // @enableMergeConsecutiveScopes
5 function Component() {
6 let [state, setState] = useState(0);
7 return (
8 <div>
6 - <Title text="Counter" />
9 + <Stringify text="Counter" />
10 <span>{state}</span>
11 <button data-testid="button" onClick={() => setState(state + 1)}>
12 increment
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/merge-nested-scopes-with-same-inputs.expect.md
+7 -9
@@ -3,13 +3,15 @@
3
4 ```javascript
5 // @enableMergeConsecutiveScopes
6 +import { setProperty } from "shared-runtime";
7 +
8 function Component(props) {
9 // start of scope for y, depend on props.a
10 let y = {};
11
12 // nested scope for x, dependent on props.a
13 const x = {};
12 - mutate(x, props.a);
14 + setProperty(x, props.a);
15 // end of scope for x
16
17 y.a = props.a;
@@ -30,6 +32,8 @@ export const FIXTURE_ENTRYPOINT = {
32
33 ```javascript
34 import { unstable_useMemoCache as useMemoCache } from "react"; // @enableMergeConsecutiveScopes
35 +import { setProperty } from "shared-runtime";
36 +
37 function Component(props) {
38 const $ = useMemoCache(2);
39 let y;
@@ -37,7 +41,7 @@ function Component(props) {
41 y = {};
42
43 const x = {};
40 - mutate(x, props.a);
44 + setProperty(x, props.a);
45
46 y.a = props.a;
47 y.x = x;
@@ -57,10 +61,4 @@ export const FIXTURE_ENTRYPOINT = {
61 ```
62
63 ### Eval output
60 -(kind: exception) mutate is not defined
61 -logs: ['The above error occurred in the <WrapperTestComponent> component:\n' +
62 - '\n' +
63 - ' at WrapperTestComponent (<project_root>/packages/sprout/dist/runner-evaluator.js:50:26)\n' +
64 - '\n' +
65 - 'Consider adding an error boundary to your tree to customize error handling behavior.\n' +
66 - 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.']
\ No newline at end of file
64 +(kind: ok) {"a":42,"x":{"wat0":42}}
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/merge-nested-scopes-with-same-inputs.js
+3 -1
@@ -1,11 +1,13 @@
1 // @enableMergeConsecutiveScopes
2 +import { setProperty } from "shared-runtime";
3 +
4 function Component(props) {
5 // start of scope for y, depend on props.a
6 let y = {};
7
8 // nested scope for x, dependent on props.a
9 const x = {};
8 - mutate(x, props.a);
10 + setProperty(x, props.a);
11 // end of scope for x
12
13 y.a = props.a;
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro-duplicate-instruction-from-merge-consecutive-scopes.expect.md
+14 -15
@@ -3,20 +3,22 @@
3
4 ```javascript
5 // @enableMergeConsecutiveScopes
6 -function Component(id) {
6 +import { Stringify } from "shared-runtime";
7 +
8 +function Component({ id }) {
9 const bar = (() => {})();
10
11 return (
12 <>
11 - <Bar title={bar} />
12 - <Bar title={id ? true : false} />
13 + <Stringify title={bar} />
14 + <Stringify title={id ? true : false} />
15 </>
16 );
17 }
18
19 export const FIXTURE_ENTRYPOINT = {
20 fn: Component,
19 - params: [null],
21 + params: [{}],
22 };
23
24 ```
@@ -25,11 +27,14 @@ export const FIXTURE_ENTRYPOINT = {
27
28 ```javascript
29 import { unstable_useMemoCache as useMemoCache } from "react"; // @enableMergeConsecutiveScopes
28 -function Component(id) {
30 +import { Stringify } from "shared-runtime";
31 +
32 +function Component(t23) {
33 const $ = useMemoCache(3);
34 + const { id } = t23;
35 let t0;
36 if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
32 - t0 = <Bar title={undefined} />;
37 + t0 = <Stringify title={undefined} />;
38 $[0] = t0;
39 } else {
40 t0 = $[0];
@@ -40,7 +45,7 @@ function Component(id) {
45 t2 = (
46 <>
47 {t0}
43 - <Bar title={t1} />
48 + <Stringify title={t1} />
49 </>
50 );
51 $[1] = t1;
@@ -53,16 +58,10 @@ function Component(id) {
58
59 export const FIXTURE_ENTRYPOINT = {
60 fn: Component,
56 - params: [null],
61 + params: [{}],
62 };
63
64 ```
65
66 ### Eval output
62 -(kind: exception) Bar is not defined
63 -logs: ['The above error occurred in the <WrapperTestComponent> component:\n' +
64 - '\n' +
65 - ' at WrapperTestComponent (<project_root>/packages/sprout/dist/runner-evaluator.js:50:26)\n' +
66 - '\n' +
67 - 'Consider adding an error boundary to your tree to customize error handling behavior.\n' +
68 - 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.']
\ No newline at end of file
67 +(kind: ok) <div>{}</div><div>{"title":false}</div>
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro-duplicate-instruction-from-merge-consecutive-scopes.js
+6 -4
@@ -1,16 +1,18 @@
1 // @enableMergeConsecutiveScopes
2 -function Component(id) {
2 +import { Stringify } from "shared-runtime";
3 +
4 +function Component({ id }) {
5 const bar = (() => {})();
6
7 return (
8 <>
7 - <Bar title={bar} />
8 - <Bar title={id ? true : false} />
9 + <Stringify title={bar} />
10 + <Stringify title={id ? true : false} />
11 </>
12 );
13 }
14
15 export const FIXTURE_ENTRYPOINT = {
16 fn: Component,
15 - params: [null],
17 + params: [{}],
18 };
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro-hoisting.expect.md
+5 -3
@@ -9,7 +9,7 @@ function Component(props) {
9 };
10
11 const pathname = props.wat;
12 - const deeplinkItemId = pathname ? itemID : null;
12 + const deeplinkItemId = pathname ? props.itemID : null;
13
14 return <button onClick={() => wat()}>{deeplinkItemId}</button>;
15 }
@@ -37,7 +37,7 @@ function Component(props) {
37 const wat = t0;
38
39 const pathname_0 = props.wat;
40 - const deeplinkItemId = pathname_0 ? itemID : null;
40 + const deeplinkItemId = pathname_0 ? props.itemID : null;
41 let t1;
42 if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
43 t1 = () => wat();
@@ -62,4 +62,6 @@ export const FIXTURE_ENTRYPOINT = {
62 };
63
64 ```
65 -
\ No newline at end of file
65 +
66 +### Eval output
67 +(kind: ok) <button>42</button>
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro-hoisting.js
+1 -1
@@ -5,7 +5,7 @@ function Component(props) {
5 };
6
7 const pathname = props.wat;
8 - const deeplinkItemId = pathname ? itemID : null;
8 + const deeplinkItemId = pathname ? props.itemID : null;
9
10 return <button onClick={() => wat()}>{deeplinkItemId}</button>;
11 }
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro-undefined-expression-of-jsxexpressioncontainer.expect.md
+11 -5
@@ -2,12 +2,14 @@
2 ## Input
3
4 ```javascript
5 +import { StaticText1, Stringify, Text } from "shared-runtime";
6 +
7 function Component(props) {
8 const { buttons } = props;
9 const [primaryButton, ...nonPrimaryButtons] = buttons;
10
11 const renderedNonPrimaryButtons = nonPrimaryButtons.map((buttonProps, i) => (
10 - <Button
12 + <Stringify
13 {...buttonProps}
14 key={`button-${i}`}
15 style={
@@ -16,7 +18,7 @@ function Component(props) {
18 />
19 ));
20
19 - return <View>{renderedNonPrimaryButtons}</View>;
21 + return <StaticText1>{renderedNonPrimaryButtons}</StaticText1>;
22 }
23
24 const styles = {
@@ -43,6 +45,8 @@ export const FIXTURE_ENTRYPOINT = {
45
46 ```javascript
47 import { unstable_useMemoCache as useMemoCache } from "react";
48 +import { StaticText1, Stringify, Text } from "shared-runtime";
49 +
50 function Component(props) {
51 const $ = useMemoCache(7);
52 const { buttons } = props;
@@ -60,7 +64,7 @@ function Component(props) {
64 let t0;
65 if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
66 t0 = (buttonProps, i) => (
63 - <Button
67 + <Stringify
68 {...buttonProps}
69 key={`button-${i}`}
70 style={
@@ -83,7 +87,7 @@ function Component(props) {
87 const renderedNonPrimaryButtons = t1;
88 let t2;
89 if ($[5] !== renderedNonPrimaryButtons) {
86 - t2 = <View>{renderedNonPrimaryButtons}</View>;
90 + t2 = <StaticText1>{renderedNonPrimaryButtons}</StaticText1>;
91 $[5] = renderedNonPrimaryButtons;
92 $[6] = t2;
93 } else {
@@ -111,4 +115,6 @@ export const FIXTURE_ENTRYPOINT = {
115 };
116
117 ```
114 -
\ No newline at end of file
118 +
119 +### Eval output
120 +(kind: ok) <div>StaticText1<div>{"type":"submit","children":["Submit!"],"style":{"left":true}}</div><div>{"type":"button","children":["Reset"],"style":{"right":true}}</div></div>
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro-undefined-expression-of-jsxexpressioncontainer.js
+4 -2
@@ -1,9 +1,11 @@
1 +import { StaticText1, Stringify, Text } from "shared-runtime";
2 +
3 function Component(props) {
4 const { buttons } = props;
5 const [primaryButton, ...nonPrimaryButtons] = buttons;
6
7 const renderedNonPrimaryButtons = nonPrimaryButtons.map((buttonProps, i) => (
6 - <Button
8 + <Stringify
9 {...buttonProps}
10 key={`button-${i}`}
11 style={
@@ -12,7 +14,7 @@ function Component(props) {
14 />
15 ));
16
15 - return <View>{renderedNonPrimaryButtons}</View>;
17 + return <StaticText1>{renderedNonPrimaryButtons}</StaticText1>;
18 }
19
20 const styles = {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/skip-useMemoCache.expect.md
+5 -7
@@ -2,6 +2,8 @@
2 ## Input
3
4 ```javascript
5 +import { unstable_useMemoCache as useMemoCache } from "react";
6 +
7 function Component(props) {
8 const $ = useMemoCache();
9 let x;
@@ -24,6 +26,8 @@ export const FIXTURE_ENTRYPOINT = {
26 ## Code
27
28 ```javascript
29 +import { unstable_useMemoCache as useMemoCache } from "react";
30 +
31 function Component(props) {
32 const $ = useMemoCache();
33 let x;
@@ -44,10 +48,4 @@ export const FIXTURE_ENTRYPOINT = {
48 ```
49
50 ### Eval output
47 -(kind: exception) useMemoCache is not defined
48 -logs: ['The above error occurred in the <WrapperTestComponent> component:\n' +
49 - '\n' +
50 - ' at WrapperTestComponent (<project_root>/packages/sprout/dist/runner-evaluator.js:50:26)\n' +
51 - '\n' +
52 - 'Consider adding an error boundary to your tree to customize error handling behavior.\n' +
53 - 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.']
\ No newline at end of file
51 +(kind: ok) [42]
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/skip-useMemoCache.js
+2
@@ -1,3 +1,5 @@
1 +import { unstable_useMemoCache as useMemoCache } from "react";
2 +
3 function Component(props) {
4 const $ = useMemoCache();
5 let x;
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useContext-read-context-in-callback-if-condition.expect.md
+5 -9
@@ -3,6 +3,7 @@
3
4 ```javascript
5 import { createContext, useContext } from "react";
6 +import { Stringify } from "shared-runtime";
7
8 const FooContext = createContext({ current: true });
9
@@ -18,7 +19,7 @@ function Component(props) {
19 };
20 const value = getValue();
21
21 - return <Child value={value} />;
22 + return <Stringify value={value} />;
23 }
24
25 export const FIXTURE_ENTRYPOINT = {
@@ -36,6 +37,7 @@ import {
37 useContext,
38 unstable_useMemoCache as useMemoCache,
39 } from "react";
40 +import { Stringify } from "shared-runtime";
41
42 const FooContext = createContext({ current: true });
43
@@ -68,7 +70,7 @@ function Component(props) {
70 const value = t1;
71 let t2;
72 if ($[4] !== value) {
71 - t2 = <Child value={value} />;
73 + t2 = <Stringify value={value} />;
74 $[4] = value;
75 $[5] = t2;
76 } else {
@@ -85,10 +87,4 @@ export const FIXTURE_ENTRYPOINT = {
87 ```
88
89 ### Eval output
88 -(kind: exception) Child is not defined
89 -logs: ['The above error occurred in the <WrapperTestComponent> component:\n' +
90 - '\n' +
91 - ' at WrapperTestComponent (<project_root>/packages/sprout/dist/runner-evaluator.js:50:26)\n' +
92 - '\n' +
93 - 'Consider adding an error boundary to your tree to customize error handling behavior.\n' +
94 - 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.']
\ No newline at end of file
90 +(kind: ok) <div>{"value":{}}</div>
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/useContext-read-context-in-callback-if-condition.js
+2 -1
@@ -1,4 +1,5 @@
1 import { createContext, useContext } from "react";
2 +import { Stringify } from "shared-runtime";
3
4 const FooContext = createContext({ current: true });
5
@@ -14,7 +15,7 @@ function Component(props) {
15 };
16 const value = getValue();
17
17 - return <Child value={value} />;
18 + return <Stringify value={value} />;
19 }
20
21 export const FIXTURE_ENTRYPOINT = {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/validate-no-set-state-in-render-unconditional-lambda-which-conditionally-sets-state-ok.expect.md
+6 -8
@@ -3,6 +3,8 @@
3
4 ```javascript
5 // @validateNoSetStateInRender
6 +import { useState } from "react";
7 +
8 function Component(props) {
9 const [x, setX] = useState(0);
10
@@ -35,7 +37,9 @@ export const FIXTURE_ENTRYPOINT = {
37 ## Code
38
39 ```javascript
38 -import { unstable_useMemoCache as useMemoCache } from "react"; // @validateNoSetStateInRender
40 +// @validateNoSetStateInRender
41 +import { useState, unstable_useMemoCache as useMemoCache } from "react";
42 +
43 function Component(props) {
44 const $ = useMemoCache(2);
45 const [x, setX] = useState(0);
@@ -74,10 +78,4 @@ export const FIXTURE_ENTRYPOINT = {
78 ```
79
80 ### Eval output
77 -(kind: exception) useState is not defined
78 -logs: ['The above error occurred in the <WrapperTestComponent> component:\n' +
79 - '\n' +
80 - ' at WrapperTestComponent (<project_root>/packages/sprout/dist/runner-evaluator.js:50:26)\n' +
81 - '\n' +
82 - 'Consider adding an error boundary to your tree to customize error handling behavior.\n' +
83 - 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.']
\ No newline at end of file
81 +(kind: ok) [0]
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/validate-no-set-state-in-render-unconditional-lambda-which-conditionally-sets-state-ok.js
+2
@@ -1,4 +1,6 @@
1 // @validateNoSetStateInRender
2 +import { useState } from "react";
3 +
4 function Component(props) {
5 const [x, setX] = useState(0);
6
compiler/packages/sprout/src/SproutTodoFilter.ts
-9
@@ -510,15 +510,6 @@ const skipFilter = new Set([
510 "todo.unnecessary-lambda-memoization",
511 "rules-of-hooks/rules-of-hooks-93dc5d5e538a",
512 "rules-of-hooks/rules-of-hooks-69521d94fa03",
513 -
514 - // TODO: remove
515 - "capture_mutate-across-fns-iife",
516 - "capture-indirect-mutate-alias-iife",
517 - "capturing-function-alias-computed-load-3-iife",
518 - "capturing-function-alias-computed-load-iife",
519 - "repro-undefined-expression-of-jsxexpressioncontainer",
520 - "repro-hoisting",
521 - "hoisting-nested-block-statements"
513 ]);
514
515 export default skipFilter;
compiler/packages/sprout/src/shared-runtime.ts
+13
@@ -108,6 +108,10 @@ export function getNumber(): number {
108 return 4;
109 }
110
111 +export function getNull(): null {
112 + return null;
113 +}
114 +
115 export function calculateExpensiveNumber(x: number): number {
116 return x;
117 }
@@ -127,6 +131,12 @@ export function addOne(value: number): number {
131 return value + 1;
132 }
133
134 +// Alias console.log, as it is defined as a global and may have
135 +// different compiler handling than unknown functions
136 +export function print(...args: Array<unknown>) {
137 + console.log(...args);
138 +}
139 +
140 export function sum(...args: Array<number>): number {
141 return args.reduce((result, arg) => result + arg, 0);
142 }
@@ -216,4 +226,7 @@ export const ObjectWithHooks = {
226 useFoo(): number {
227 return 0;
228 },
229 + useMakeArray(): Array<number> {
230 + return [1, 2, 3];
231 + },
232 };