Skip to content

Commit e865c87

Browse files
committed
chore: tests for isReactComponent
1 parent 7897ce7 commit e865c87

File tree

1 file changed

+115
-2
lines changed

1 file changed

+115
-2
lines changed

cmp/compiler/src/plugin/transform/utils.test.ts

Lines changed: 115 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
import { describe, expect, it } from "vitest";
55
import IntlMessageFormat from "intl-messageformat";
66
import { parse } from "@babel/parser";
7-
import traverse from "@babel/traverse";
8-
import * as t from "@babel/types";
7+
import { traverse } from "./babel-compat";
98
import { escapeTextForICU, isReactComponent } from "./utils";
109

1110
describe("escapeTextForICU", () => {
@@ -53,3 +52,117 @@ describe("escapeTextForICU", () => {
5352
},
5453
);
5554
});
55+
56+
describe("isReactComponent", () => {
57+
/**
58+
* Helper to parse code and test isReactComponent on the first function found
59+
*/
60+
function testIsReactComponent(code: string): boolean {
61+
const ast = parse(code, {
62+
sourceType: "module",
63+
plugins: ["jsx", "typescript"],
64+
});
65+
66+
let result = false;
67+
traverse(ast, {
68+
"FunctionDeclaration|FunctionExpression|ArrowFunctionExpression"(path) {
69+
if (
70+
path.isFunctionDeclaration() ||
71+
path.isFunctionExpression() ||
72+
path.isArrowFunctionExpression()
73+
) {
74+
result = isReactComponent(path);
75+
path.stop(); // Stop after first function
76+
}
77+
},
78+
});
79+
80+
return result;
81+
}
82+
83+
describe("simple cases", () => {
84+
it("should detect arrow function returning JSX element", () => {
85+
const code = `const MyComponent = () => <div>Hello</div>;`;
86+
expect(testIsReactComponent(code)).toBe(true);
87+
});
88+
89+
it("should detect arrow function returning JSX fragment", () => {
90+
const code = `const MyComponent = () => <>Hello</>;`;
91+
expect(testIsReactComponent(code)).toBe(true);
92+
});
93+
94+
it("should detect function with explicit return of JSX element", () => {
95+
const code = `
96+
function MyComponent() {
97+
return <div>Hello</div>;
98+
}
99+
`;
100+
expect(testIsReactComponent(code)).toBe(true);
101+
});
102+
103+
it("should detect function with explicit return of JSX fragment", () => {
104+
const code = `
105+
function MyComponent() {
106+
return <>Hello</>;
107+
}
108+
`;
109+
expect(testIsReactComponent(code)).toBe(true);
110+
});
111+
112+
it("should return false for function returning non-JSX", () => {
113+
const code = `
114+
function notAComponent() {
115+
return "hello";
116+
}
117+
`;
118+
expect(testIsReactComponent(code)).toBe(false);
119+
});
120+
121+
it("should return false for function with no return", () => {
122+
const code = `
123+
function notAComponent() {
124+
console.log("hello");
125+
}
126+
`;
127+
expect(testIsReactComponent(code)).toBe(false);
128+
});
129+
});
130+
131+
describe("nested function cases", () => {
132+
it("should detect component with nested helper function that returns JSX", () => {
133+
const code = `
134+
function MyComponent() {
135+
const renderHelper = () => <span>Helper</span>;
136+
return <div>{renderHelper()}</div>;
137+
}
138+
`;
139+
expect(testIsReactComponent(code)).toBe(true);
140+
});
141+
142+
it("should detect component with nested non-JSX helper function", () => {
143+
const code = `
144+
function MyComponent() {
145+
const helper = () => "string";
146+
return <div>{helper()}</div>;
147+
}
148+
`;
149+
expect(testIsReactComponent(code)).toBe(true);
150+
});
151+
152+
// // Corner case
153+
// it("should return false when outer function doesn't return JSX but nested does", () => {
154+
// const code = `
155+
// function notAComponent() {
156+
// function MyComponent() {
157+
// const helper = () => "string";
158+
// return <div>{helper()}</div>;
159+
// }
160+
// const Inner = () => <div>Hello</div>;
161+
// return Inner;
162+
// }
163+
// `;
164+
// // This tests the outer function, which returns a function, not JSX
165+
// expect(testIsReactComponent(code)).toBe(false);
166+
// });
167+
});
168+
});

0 commit comments

Comments
 (0)