// Tests which apply to both dev and prod. They are run twice. import { devAndProductionTest, devTest, emptyHtmlFile } from "./bake-harness"; devAndProductionTest("define config via bunfig.toml", { files: { "index.html": emptyHtmlFile({ styles: [], scripts: ["index.ts"], }), "index.ts": ` console.log("a=" + DEFINE); `, "bunfig.toml": ` [serve.static] define = { "DEFINE" = "\\"HELLO\\"" } `, }, async test(dev) { const c = await dev.client("/"); await c.expectMessage("a=HELLO"); }, }); devAndProductionTest("invalid html does not crash 1", { files: { "public/index.html": ` Dashboard
`, "src/app/index.tsx": ` console.log("hello"); `, "src/app/styles.css": ` body { background-color: red; } `, }, async test(dev) { await using c = await dev.client("/"); await c.expectMessage("hello"); await c.style("body").backgroundColor.expect.toBe("red"); }, }); devAndProductionTest("missing all meta tags works fine", { files: { "public/index.html": ` Dashboard
`, "src/app/index.tsx": ` console.log("hello"); `, "src/app/styles.css": ` body { background-color: red; } `, }, async test(dev) { await dev.fetch("/").expect.toInclude("root"); await using c = await dev.client("/"); await c.expectMessage("hello"); await c.style("body").backgroundColor.expect.toBe("red"); }, }); devAndProductionTest("inline script and styles appear", { files: { "public/index.html": ` Dashboard `, }, async test(dev) { await dev.fetch("/").expect.toInclude("hello"); await dev.fetch("/").expect.not.toInclude("hello 3"); // TODO: await using c = await dev.client("/"); await c.expectMessage("hello 3"); await c.style("body").backgroundColor.expect.toBe("red"); }, }); // TODO: revive production devTest("using runtime import", { files: { "index.html": emptyHtmlFile({ styles: [], scripts: ["index.ts"], }), "index.ts": ` // __using { using a = { [Symbol.dispose]: () => console.log("a") }; console.log("b"); } // __legacyDecorateClassTS function undefinedDecorator(target) { console.log("decorator"); } @undefinedDecorator class x {} // __require const A = () => require; const B = () => module.require; const C = () => import.meta.require; if (import.meta.hot) { console.log(A.toString().replaceAll(" ", "").replaceAll("\\n", "")); console.log(B.toString().replaceAll(" ", "").replaceAll("\\n", "")); console.log(C.toString().replaceAll(" ", "").replaceAll("\\n", "")); console.log(A() === eval("hmr.require")); console.log(B() === eval("hmr.require")); console.log(C() === eval("hmr.require")); if (typeof A() !== "function") throw new Error("A is not a function"); if (typeof B() !== "function") throw new Error("B is not a function"); if (typeof C() !== "function") throw new Error("C is not a function"); } `, "tsconfig.json": ` { "compilerOptions": { "experimentalDecorators": true } } `, }, async test(dev) { await using c = await dev.client("/"); await c.expectMessage( "b", "a", "decorator", ...(dev.nodeEnv === "development" ? [ // TODO: all of these should be `hmr.require` "()=>hmr.require", "()=>module.require", // not being visited "()=>hmr.importMeta.require", // not being visited true, false, false, ] : []), ); }, });