93 lines
3.5 KiB
TypeScript
93 lines
3.5 KiB
TypeScript
import { screen } from "@testing-library/react";
|
|
import { describe, expect, test } from "bun:test";
|
|
import { createElement } from "react";
|
|
|
|
import { TextPart } from "../../../../src/web/features/chat/parts/TextPart";
|
|
import { renderWithProviders } from "../../test-utils";
|
|
|
|
function createTextPart(text: string, _isStreaming = false, _role = "assistant"): Record<string, unknown> {
|
|
return { text, type: "text" };
|
|
}
|
|
|
|
describe("TextPart AI 消息含 Markdown 渲染", () => {
|
|
test("代码块使用 pre override 渲染", () => {
|
|
const part = createTextPart("```javascript\nconst x = 1;\n```");
|
|
|
|
renderWithProviders(createElement(TextPart, { isStreaming: false, part, role: "assistant" }));
|
|
|
|
expect(screen.getByText("const x = 1;")).toBeTruthy();
|
|
expect(document.querySelector(".code-block")).toBeTruthy();
|
|
});
|
|
|
|
test("表格使用 markdown-table class 渲染", () => {
|
|
const part = createTextPart("| A | B |\n| --- | --- |\n| 1 | 2 |");
|
|
|
|
renderWithProviders(createElement(TextPart, { isStreaming: false, part, role: "assistant" }));
|
|
|
|
expect(screen.getByText("A")).toBeTruthy();
|
|
expect(document.querySelector(".markdown-table")).toBeTruthy();
|
|
});
|
|
|
|
test("表格单元格内富文本正常渲染", () => {
|
|
const part = createTextPart("| A | B |\n| --- | --- |\n| **粗体** | `code` |");
|
|
|
|
renderWithProviders(createElement(TextPart, { isStreaming: false, part, role: "assistant" }));
|
|
|
|
const bold = screen.getByText("粗体");
|
|
expect(bold).toBeTruthy();
|
|
expect(bold.tagName).toBe("STRONG");
|
|
expect(screen.getByText("code")).toBeTruthy();
|
|
});
|
|
});
|
|
|
|
describe("TextPart 用户消息不受 overrides 影响", () => {
|
|
test("用户消息不应用 Markdown 渲染", () => {
|
|
const part = createTextPart("```javascript\nconst x = 1;\n```");
|
|
|
|
const { container } = renderWithProviders(createElement(TextPart, { isStreaming: false, part, role: "user" }));
|
|
|
|
expect(container.textContent).toContain("const x = 1;");
|
|
expect(document.querySelector(".code-block")).toBeNull();
|
|
});
|
|
|
|
test("用户消息使用 Typography.Paragraph 渲染", () => {
|
|
const part = createTextPart("普通文本消息");
|
|
|
|
renderWithProviders(createElement(TextPart, { isStreaming: false, part, role: "user" }));
|
|
|
|
expect(document.querySelector(".message-body-text")).toBeTruthy();
|
|
});
|
|
});
|
|
|
|
describe("TextPart 流式状态传递", () => {
|
|
test("流式状态下 isStreaming 传递给 CodeBlock", () => {
|
|
const part = createTextPart("```javascript\nconst x = 1;\n```");
|
|
|
|
renderWithProviders(createElement(TextPart, { isStreaming: true, part, role: "assistant" }));
|
|
|
|
const codeBlock = document.querySelector(".code-block");
|
|
expect(codeBlock).toBeTruthy();
|
|
expect(codeBlock!.tagName).toBe("PRE");
|
|
});
|
|
|
|
test("非流式状态下渲染完整代码块结构", () => {
|
|
const part = createTextPart("```javascript\nconst x = 1;\n```");
|
|
|
|
renderWithProviders(createElement(TextPart, { isStreaming: false, part, role: "assistant" }));
|
|
|
|
expect(document.querySelector(".code-block-header")).toBeTruthy();
|
|
});
|
|
});
|
|
|
|
describe("TextPart 纯文本 AI 消息", () => {
|
|
test("无代码块无表格的消息正常渲染", () => {
|
|
const part = createTextPart("这是一条普通的 AI 回复。");
|
|
|
|
const { container } = renderWithProviders(createElement(TextPart, { isStreaming: false, part, role: "assistant" }));
|
|
|
|
expect(screen.getByText("这是一条普通的 AI 回复。")).toBeTruthy();
|
|
expect(container.querySelector(".code-block")).toBeNull();
|
|
expect(container.querySelector(".markdown-table")).toBeNull();
|
|
});
|
|
});
|