feat: 聊天室对话渲染增强 - 思考内容Markdown渲染 + 工具调用参数卡片化
This commit is contained in:
97
tests/web/components/chat/HighlightBlock.test.tsx
Normal file
97
tests/web/components/chat/HighlightBlock.test.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
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("流式状态渲染纯 <pre><code> 无高亮", () => {
|
||||
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();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user