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); }); });