import { describe, expect, mock, test } from "bun:test"; import { screen, waitFor } from "@testing-library/react"; import { createElement } from "react"; import { HighlightBlock } from "../../../../src/web/features/chat/parts/HighlightBlock"; import { renderWithProviders } from "../../test-utils"; describe("HighlightBlock JSON 高亮", () => { test("非流式状态渲染 shiki 高亮 HTML", async () => { const code = JSON.stringify({ key: "value" }, null, 2); const { container } = renderWithProviders( createElement(HighlightBlock, { code, isStreaming: false, lang: "json" }), ); expect(screen.getByText("json")).toBeTruthy(); await waitFor(() => { expect(container.querySelector(".code-block-body")).toBeTruthy(); }); }); test("流式状态渲染纯
无高亮", () => {
const code = JSON.stringify({ key: "value" }, null, 2);
const { container } = renderWithProviders(createElement(HighlightBlock, { code, isStreaming: true, lang: "json" }));
const pre = container.querySelector("pre.code-block");
expect(pre).toBeTruthy();
expect(pre!.textContent).toContain("key");
expect(container.querySelector(".code-block-header")).toBeNull();
});
});
describe("HighlightBlock 复制按钮", () => {
test("非流式状态显示复制按钮", () => {
const code = "const x = 1;";
renderWithProviders(createElement(HighlightBlock, { code, isStreaming: false, lang: "text" }));
expect(screen.getByText("text")).toBeTruthy();
const buttons = screen.getAllByRole("button");
expect(buttons.length).toBeGreaterThan(0);
});
test("复制按钮调用 clipboard.writeText", () => {
const code = JSON.stringify({ a: 1 }, null, 2);
const writeTextMock = mock(() => Promise.resolve());
Object.defineProperty(navigator, "clipboard", {
value: { writeText: writeTextMock },
writable: true,
configurable: true,
});
renderWithProviders(createElement(HighlightBlock, { code, isStreaming: false, lang: "json" }));
const button = screen.getByRole("button");
button.click();
expect(writeTextMock).toHaveBeenCalledWith(code);
});
});
describe("HighlightBlock 纯文本", () => {
test("lang=text 时头部显示 text", () => {
renderWithProviders(createElement(HighlightBlock, { code: "hello world", isStreaming: false, lang: "text" }));
expect(screen.getByText("text")).toBeTruthy();
});
});
describe("HighlightBlock 边界情况", () => {
test("code 为空时渲染空代码块不触发异步高亮", () => {
const { container } = renderWithProviders(
createElement(HighlightBlock, { code: "", isStreaming: false, lang: "json" }),
);
expect(container.querySelector(".code-block")).toBeTruthy();
expect(container.querySelector("code")).toBeTruthy();
expect(container.querySelector("code")!.textContent).toBe("");
});
test("流式切换到非流式后触发高亮", async () => {
const code = JSON.stringify({ x: 1 }, null, 2);
const { container, rerender } = renderWithProviders(
createElement(HighlightBlock, { code, isStreaming: true, lang: "json" }),
);
expect(container.querySelector("pre.code-block")).toBeTruthy();
rerender(createElement(HighlightBlock, { code, isStreaming: false, lang: "json" }));
await waitFor(() => {
expect(container.querySelector(".code-block-body")).toBeTruthy();
});
});
});