1// @effect-diagnostics nodeBuiltinImport:off - compiles real source files on disk.
2import * as NodeFS from "node:fs";
3import * as NodePath from "node:path";
4import * as NodeURL from "node:url";
5import { transform } from "oxc-transform-react";
6import { describe, expect, it } from "vite-plus/test";
7
8const repoRoot = NodePath.resolve(
9 NodePath.dirname(NodeURL.fileURLToPath(import.meta.url)),
10 "../../..",
11);
12
13const webSourceFiles = NodeFS.readdirSync(NodePath.join(repoRoot, "apps/web/src"), {
14 recursive: true,
15})
16 .map(String)
17 .filter((file) => /\.tsx?$/.test(file) && !/\.(test|browser)\.tsx?$/.test(file))
18 .filter((file) => !file.endsWith(".gen.ts"))
19 .map((file) => `apps/web/src/${file}`);
20
21// ChatView is ~9k lines. Compiling it takes ~9s on a fast machine and can pass the
22// 15s project limit on loaded CI runners, so slow files get a 60s limit below.
23const slowFiles = new Set(["apps/web/src/components/ChatView.tsx"]);
24
25const compile = async (file: string) => {
26 const absolute = NodePath.join(repoRoot, file);
27 const result = await transform(absolute, NodeFS.readFileSync(absolute, "utf8"), {
28 jsx: { runtime: "automatic", development: false, refresh: false },
29 reactCompiler: { reportDiagnostics: true },
30 });
31 const bailouts = result.errors.map((error) => error.codeframe ?? error.message);
32 expect(bailouts).toEqual([]);
33};
34
35// Lint reports most compiler bailouts, but not every one (try/finally, throw
36// inside try). A skipped file still builds, just unmemoized, so check the output.
37describe("React Compiler coverage", () => {
38 it.each(webSourceFiles.filter((file) => !slowFiles.has(file)))("compiles %s", compile);
39 // oxlint-disable-next-line t3code/no-test-timeout-or-unreasoned-skip -- CPU-bound compile of a huge file, not a hidden wait.
40 it.each([...slowFiles])("compiles %s", compile, 60_000);
41});