[sprout] Allow forwardRef and memo components
Mofei Zhang committed
Aug 25, 2023 at 16:54 UTC
bcbcd37eb016c58bca124c94d416a281fe4eebc6
1 file changed
+28
-9
compiler/packages/sprout/src/runner-evaluator.ts
+28
-9
@@ -6,8 +6,8 @@
6
*/
7
8
import { JSDOM } from "jsdom";
9
-import { toJSON } from "./shared-runtime";
9
import util from "util";
10
+import { toJSON } from "./shared-runtime";
11
const React = require("react");
12
const render = require("@testing-library/react").render;
13
@@ -38,6 +38,24 @@ const PLACEHOLDER_VALUE = Symbol();
38
return toJSON(result);
39
};
40
41
+function validateEntrypoint(entrypoint: object) {
42
+ if (!("params" in entrypoint)) {
43
+ return "missing `params` property";
44
+ } else if (!Array.isArray(entrypoint.params)) {
45
+ return "unexpected type for `params` property";
46
+ } else if (!(`isComponent` in entrypoint)) {
47
+ return "missing `isComponent` property";
48
+ } else if (typeof entrypoint.isComponent !== "boolean") {
49
+ return "unexpected type for `isComponent` property";
50
+ } else if (!(`fn` in entrypoint)) {
51
+ return "missing `fn` property";
52
+ } else if (!entrypoint.isComponent && typeof entrypoint.fn !== "function") {
53
+ return "expected `fn` property to be a function";
54
+ } else {
55
+ return null;
56
+ }
57
+}
58
+
59
export function doEval(source: string): EvaluatorResult {
60
"use strict";
61
@@ -69,7 +87,8 @@ export function doEval(source: string): EvaluatorResult {
87
};
88
let reachedInvoke = false;
89
try {
72
- ${source}
90
+ // run in an iife to avoid naming collisions
91
+ (() => {${source}})();
92
reachedInvoke = true;
93
if (exports.FIXTURE_ENTRYPOINT == null ||
94
exports.FIXTURE_ENTRYPOINT.fn === globalThis.placeholderFn
@@ -78,16 +97,16 @@ export function doEval(source: string): EvaluatorResult {
97
kind: "UnexpectedError",
98
value: 'FIXTURE_ENTRYPOINT not exported!',
99
};
81
- } else if (
82
- typeof exports.FIXTURE_ENTRYPOINT.fn !== "function" ||
83
- !Array.isArray(exports.FIXTURE_ENTRYPOINT.params) ||
84
- typeof exports.FIXTURE_ENTRYPOINT.isComponent !== "boolean"
85
- ) {
100
+ }
101
+ const validationError = validateEntrypoint(exports.FIXTURE_ENTRYPOINT);
102
+ if (validationError) {
103
return {
104
kind: "UnexpectedError",
88
- value: 'Bad shape for FIXTURE_ENTRYPOINT.',
105
+ value: 'Bad shape for FIXTURE_ENTRYPOINT (' + validationError + ').',
106
};
90
- } else if (exports.FIXTURE_ENTRYPOINT.isComponent) {
107
+ }
108
+
109
+ if (exports.FIXTURE_ENTRYPOINT.isComponent) {
110
// try to run fixture as a react component
111
const result = render(
112
React.createElement(