import { expect, test } from "vitest"; import { renderResultToHtml } from "./render_lua_html.ts"; import { LuaTable } from "./runtime.ts"; import { makeLuaFloat } from "./numeric.ts"; import { LIQ_NULL } from "./liq_null.ts"; // ── Nil / empty values ────────────────────────────────────────────── test("null renders as empty span with dataType nil", async () => { const r = await renderResultToHtml(null); expect(r).toEqual({ html: ``, dataType: "nil" }); }); test("undefined renders as empty span with dataType nil", async () => { const r = await renderResultToHtml(undefined); expect(r).toEqual({ html: ``, dataType: "nil" }); }); test("LIQ_NULL (SQL NULL) renders as empty span with dataType nil", async () => { const r = await renderResultToHtml(LIQ_NULL); expect(r).toEqual({ html: ``, dataType: "nil" }); }); // ── Strings ───────────────────────────────────────────────────────── test("string renders with default escaping", async () => { const r = await renderResultToHtml("hello world"); expect(r).toEqual({ html: "hello world", dataType: "string" }); }); test("empty string is rendered (not treated as nil)", async () => { const r = await renderResultToHtml(""); expect(r).toEqual({ html: "", dataType: "string" }); }); test("string with HTML special chars is escaped", async () => { const r = await renderResultToHtml('"Tom & Jerry"'); expect(r).toEqual({ html: '<b>"Tom & Jerry"</b>', dataType: "string", }); }); // ── Numbers ───────────────────────────────────────────────────────── test("integer number", async () => { const r = await renderResultToHtml(42); expect(r).toEqual({ html: "42", dataType: "number" }); }); test("zero", async () => { const r = await renderResultToHtml(0); expect(r).toEqual({ html: "0", dataType: "number" }); }); test("non-integer float", async () => { const r = await renderResultToHtml(1.5); expect(r).toEqual({ html: "1.5", dataType: "number" }); }); test("tagged float (integer-valued)", async () => { const r = await renderResultToHtml(makeLuaFloat(2)); expect(r).toEqual({ html: "2.0", dataType: "number" }); }); // ── Booleans ──────────────────────────────────────────────────────── test("boolean true", async () => { const r = await renderResultToHtml(true); expect(r).toEqual({ html: "true", dataType: "boolean" }); }); test("boolean false", async () => { const r = await renderResultToHtml(false); expect(r).toEqual({ html: "false", dataType: "boolean" }); }); // ── Fallback (unknown object type) ────────────────────────────────── test("non-matching object is stringified via renderInline", async () => { const d = new Date("2024-01-15T00:00:00.000Z"); const r = await renderResultToHtml(d); expect(r.dataType).toBe("string"); expect(r.html).toContain("2024"); // toString includes year }); // ── Custom renderInline ───────────────────────────────────────────── test("custom renderInline is used for strings", async () => { const custom = (s: string) => `${s}`; const r = await renderResultToHtml("hello", custom); expect(r).toEqual({ html: "hello", dataType: "string" }); }); // ── LuaTable: empty ───────────────────────────────────────────────── test("empty LuaTable", async () => { const r = await renderResultToHtml(new LuaTable()); expect(r).toEqual({ html: `
`, dataType: "table", }); }); // ── LuaTable: pure array of scalars ───────────────────────────────── test("LuaTable array of scalars renders as