@sigil-dev/compiler 0.9.6 → 0.9.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,56 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { mkdtempSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { transformSSR } from "./helpers/transform.ts";
6
+
7
+ // Render through the real SSR output: write the compiled module to disk and
8
+ // import it, so the assertions are on the HTML a browser would receive.
9
+ const dir = mkdtempSync(join(tmpdir(), "sigil-ssr-bool-"));
10
+ let n = 0;
11
+ async function render(src: string, ...args: unknown[]): Promise<string> {
12
+ const file = join(dir, `m${n++}.js`);
13
+ writeFileSync(file, transformSSR(src));
14
+ const mod = await import(file);
15
+ return String(mod.default(...args));
16
+ }
17
+
18
+ describe("SSR boolean attributes", () => {
19
+ const box = `export default (on) => <input type="checkbox" checked={on} />;`;
20
+
21
+ test("true renders the bare attribute", async () => {
22
+ expect(await render(box, true)).toBe(`<input type="checkbox" checked>`);
23
+ });
24
+
25
+ test("false, null and undefined omit it", async () => {
26
+ // checked="" would mean checked: every box ticked, every option selected
27
+ for (const v of [false, null, undefined]) {
28
+ expect(await render(box, v)).toBe(`<input type="checkbox">`);
29
+ }
30
+ });
31
+
32
+ test("selected, disabled and friends follow the same rule", async () => {
33
+ const src = `export default (a, b) => <select disabled={a}><option selected={b}>x</option></select>;`;
34
+ expect(await render(src, false, true)).toBe(
35
+ `<select><option selected>x</option></select>`,
36
+ );
37
+ expect(await render(src, true, false)).toBe(
38
+ `<select disabled><option>x</option></select>`,
39
+ );
40
+ });
41
+
42
+ test("a string value is kept, escaped", async () => {
43
+ expect(
44
+ await render(`export default (v) => <div hidden={v} />;`, "until-found"),
45
+ ).toBe(`<div hidden="until-found"></div>`);
46
+ expect(
47
+ await render(`export default (v) => <div hidden={v} />;`, `"><x`),
48
+ ).toBe(`<div hidden="&quot;&gt;&lt;x"></div>`);
49
+ });
50
+
51
+ test("literal attributes are untouched", async () => {
52
+ expect(
53
+ await render(`export default () => <input checked="checked" />;`),
54
+ ).toBe(`<input checked="checked">`);
55
+ });
56
+ });
@@ -0,0 +1,68 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { mkdtempSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { transformSync } from "@babel/core";
6
+ import sigilPlugin from "../src/babel/index.ts";
7
+ import { transformSSR } from "./helpers/transform.ts";
8
+
9
+ // Real SSR output: compile, write to disk, import, render.
10
+ const dir = mkdtempSync(join(tmpdir(), "sigil-ssr-raw-"));
11
+ let n = 0;
12
+ async function render(src: string, ...args: unknown[]): Promise<string> {
13
+ const file = join(dir, `m${n++}.js`);
14
+ writeFileSync(file, transformSSR(src));
15
+ const mod = await import(file);
16
+ return String(mod.default(...args));
17
+ }
18
+
19
+ const CODE = `if (a > 1 && b < 2) x = "q";`;
20
+ // "<!-" + "-": a literal comment opener is a legacy HTML comment in JS source
21
+ const G_OPEN = "<!-" + "-g-->";
22
+ const G_CLOSE = "<!-" + "-/g-->";
23
+
24
+ describe("SSR script text", () => {
25
+ test("{code} inside a script is emitted as is", async () => {
26
+ expect(
27
+ await render("export default (c) => <script>{c}</script>;", CODE),
28
+ ).toBe(`<script>${CODE}</script>`);
29
+ });
30
+
31
+ test("the code can't close its own element", async () => {
32
+ expect(
33
+ await render(
34
+ "export default (c) => <script>{c}</script>;",
35
+ 'x = "</SCRIPT>"',
36
+ ),
37
+ ).toBe('<script>x = "<\\/SCRIPT>"</script>');
38
+ });
39
+
40
+ test("null, undefined and false render nothing", async () => {
41
+ for (const v of [null, undefined, false]) {
42
+ expect(
43
+ await render("export default (c) => <script>{c}</script>;", v),
44
+ ).toBe("<script></script>");
45
+ }
46
+ });
47
+
48
+ test("other elements still escape and mark their text", async () => {
49
+ expect(await render("export default (c) => <p>{c}</p>;", "<b>")).toBe(
50
+ `<p>${G_OPEN}&lt;b&gt;${G_CLOSE}</p>`,
51
+ );
52
+ });
53
+
54
+ test("hydration leaves script text alone", () => {
55
+ const code = transformSync(
56
+ "const el = <div><script>{code}</script><p>{text}</p></div>;",
57
+ {
58
+ plugins: [
59
+ "@babel/plugin-syntax-jsx",
60
+ [sigilPlugin, { mode: "hydrate" }],
61
+ ],
62
+ filename: "test.tsx",
63
+ },
64
+ )!.code!;
65
+ expect(code.match(/hydrateSlot\(/g)?.length).toBe(1); // only the <p> slot
66
+ expect(code).not.toContain("() => code");
67
+ });
68
+ });
@@ -1,13 +1,13 @@
1
- import { describe, expect, test } from "bun:test";
2
- import { transformSSR } from "./helpers/transform.ts";
3
-
4
- describe("SSR style objects", () => {
5
- test("style={{...}} serializes to CSS string, not [object Object]", () => {
6
- const out = transformSSR(
7
- `export function Card() { return <div style={{ display: "grid", marginTop: 12 }}>x</div>; }`,
8
- );
9
- // the __e helper must carry the object branch
10
- expect(out).toContain("constructor === Object");
11
- expect(out).toContain("UNITLESS");
12
- });
13
- });
1
+ import { describe, expect, test } from "bun:test";
2
+ import { transformSSR } from "./helpers/transform.ts";
3
+
4
+ describe("SSR style objects", () => {
5
+ test("style={{...}} serializes to CSS string, not [object Object]", () => {
6
+ const out = transformSSR(
7
+ `export function Card() { return <div style={{ display: "grid", marginTop: 12 }}>x</div>; }`,
8
+ );
9
+ // the __e helper must carry the object branch
10
+ expect(out).toContain("constructor === Object");
11
+ expect(out).toContain("UNITLESS");
12
+ });
13
+ });