import { describe, expect, test } from "vitest"; import { bootstrap } from "./bootstrap.js"; import { renderAsync } from "./render.js"; import { putSchema } from "./schema.js"; import { createMemoryStore } from "./store.js"; describe("Structured HTML Fallback (#179)", () => { describe("Object payloads →
YAML
expect(output).toContain("");
// Key-value pairs visible
expect(output).toContain("name");
expect(output).toContain("Alice");
expect(output).toContain("age");
expect(output).toContain("30");
});
test("key ordering matches object's own key order", async () => {
const store = createMemoryStore();
bootstrap(store);
const schema = putSchema(store, {
type: "object",
properties: {
zebra: { type: "string" },
alpha: { type: "string" },
},
});
const hash = store.cas.put(schema, { zebra: "z", alpha: "a" });
const output = await renderAsync(store, hash, { format: "html" });
// zebra should appear before alpha
const zebraPos = output.indexOf("zebra");
const alphaPos = output.indexOf("alpha");
expect(zebraPos).toBeLessThan(alphaPos);
});
});
describe("Array payloads → lists", () => {
test("renders array payload as with - per item", async () => {
const store = createMemoryStore();
bootstrap(store);
const arraySchema = putSchema(store, {
type: "array",
items: { type: "string" },
});
const hash = store.cas.put(arraySchema, ["apple", "banana", "cherry"]);
const output = await renderAsync(store, hash, { format: "html" });
expect(output).toContain("
");
expect(output).toContain("apple");
expect(output).toContain("banana");
expect(output).toContain("cherry");
});
test("array items appear in original order", async () => {
const store = createMemoryStore();
bootstrap(store);
const schema = putSchema(store, {
type: "array",
items: { type: "string" },
});
const hash = store.cas.put(schema, ["first", "second", "third"]);
const output = await renderAsync(store, hash, { format: "html" });
const firstPos = output.indexOf("first");
const secondPos = output.indexOf("second");
const thirdPos = output.indexOf("third");
expect(firstPos).toBeLessThan(secondPos);
expect(secondPos).toBeLessThan(thirdPos);
});
});
describe("Primitive payloads → inline elements", () => {
test("string value rendered as inline element", async () => {
const store = createMemoryStore();
bootstrap(store);
const strSchema = putSchema(store, { type: "string" });
const hash = store.cas.put(strSchema, "hello world");
const output = await renderAsync(store, hash, { format: "html" });
expect(output).toContain("hello world");
expect(output).not.toContain("");
});
test("number value rendered as inline element", async () => {
const store = createMemoryStore();
bootstrap(store);
const numSchema = putSchema(store, { type: "number" });
const hash = store.cas.put(numSchema, 42);
const output = await renderAsync(store, hash, { format: "html" });
expect(output).toContain("42");
expect(output).not.toContain("");
});
test("boolean value rendered as inline element", async () => {
const store = createMemoryStore();
bootstrap(store);
const boolSchema = putSchema(store, { type: "boolean" });
const hash = store.cas.put(boolSchema, true);
const output = await renderAsync(store, hash, { format: "html" });
expect(output).toContain("true");
expect(output).not.toContain("");
});
test("HTML special characters are escaped in primitive values", async () => {
const store = createMemoryStore();
bootstrap(store);
const schema = putSchema(store, { type: "string" });
const hash = store.cas.put(schema, '');
const output = await renderAsync(store, hash, { format: "html" });
expect(output).toContain("<script>");
expect(output).not.toContain("',
});
const output = await renderAsync(store, hash, { format: "html" });
expect(output).toContain("<script>");
expect(output).not.toContain('