import { describe, it, expect } from "vitest";
import { renderToStaticMarkup } from "react-dom/server";
import { renderGenerativeUI } from "../renderGenerativeUI";
import { textVocabulary } from "./text";
const render = (node: unknown) =>
renderToStaticMarkup(<>{renderGenerativeUI(node, textVocabulary)}>);
describe("textVocabulary", () => {
it("Header renders an h2 with the text and a size hook", () => {
expect(render({ $type: "Header", text: "Title", size: "xl" })).toBe(
'
Title
',
);
});
it("Header defaults size to lg when omitted", () => {
expect(render({ $type: "Header", text: "Title" })).toBe(
'Title
',
);
});
it("Text renders a span with size/weight/color hooks and the value", () => {
expect(
render({
$type: "Text",
value: "hi",
size: "sm",
weight: "bold",
color: "secondary",
}),
).toBe(
'hi',
);
});
it("Text defaults size to md and leaves weight/color undefined", () => {
expect(render({ $type: "Text", value: "hi" })).toBe(
'hi',
);
});
it("Text renders partial value while streaming (streamProperties: true)", () => {
expect(
renderToStaticMarkup(
<>
{renderGenerativeUI(
{ $type: "Text", value: "partial" },
textVocabulary,
{ status: "streaming" },
)}
>,
),
).toBe('partial');
});
it("Text renders nested children (span-in-span, valid HTML)", () => {
expect(
render({
$type: "Text",
value: "before",
children: { $type: "Text", value: "after" },
}),
).toBe(
'beforeafter',
);
});
it("Caption renders a p with the value", () => {
expect(render({ $type: "Caption", value: "muted note" })).toBe(
'muted note
',
);
});
it.each([
[
{ $type: "Header", text: { unexpected: true } },
undefined,
'',
],
[
{ $type: "Text", value: { unexpected: true } },
{ status: "streaming" as const },
'',
],
[
{ $type: "Caption", value: { unexpected: true } },
{ status: "streaming" as const },
'',
],
[
{ $type: "Text", value: 42 },
{ status: "streaming" as const },
'42',
],
])("renders only supported text properties", (node, options, expected) => {
expect(
renderToStaticMarkup(
<>{renderGenerativeUI(node, textVocabulary, options)}>,
),
).toBe(expected);
});
});