mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-08-14 08:49:00 +00:00
* fix(frontend): avoid highlighting code while streaming * fix(frontend): harden streaming code rendering
86 lines
2.8 KiB
TypeScript
86 lines
2.8 KiB
TypeScript
import { describe, expect, it } from "@rstest/core";
|
|
import { createElement, type ImgHTMLAttributes } from "react";
|
|
import { renderToStaticMarkup } from "react-dom/server";
|
|
|
|
import { MarkdownContent } from "@/components/workspace/messages/markdown-content";
|
|
|
|
function renderMarkdown(
|
|
content: string,
|
|
isLoading: boolean,
|
|
components?: Parameters<typeof MarkdownContent>[0]["components"],
|
|
) {
|
|
return renderToStaticMarkup(
|
|
createElement(MarkdownContent, { content, isLoading, components }),
|
|
);
|
|
}
|
|
|
|
describe("MarkdownContent streaming code blocks", () => {
|
|
it("renders fenced code without Streamdown highlighting while streaming", () => {
|
|
const html = renderMarkdown(
|
|
["```html", '<main class="report">Hello</main>', "```"].join("\n"),
|
|
true,
|
|
);
|
|
|
|
expect(html).toContain("data-streaming-code-block");
|
|
expect(html).toContain('data-language="html"');
|
|
expect(html).toContain(
|
|
"<main class="report">Hello</main>",
|
|
);
|
|
expect(html).not.toContain('data-streamdown="code-block"');
|
|
});
|
|
|
|
it("keeps inline code inline while streaming", () => {
|
|
const html = renderMarkdown("Use `const answer = 42` here.", true);
|
|
|
|
expect(html).toContain('data-streaming-inline-code="true"');
|
|
expect(html).not.toContain("data-streaming-code-block");
|
|
});
|
|
|
|
it("keeps an unlabeled single-line fence as a block while streaming", () => {
|
|
const html = renderMarkdown(["```", "x", "```"].join("\n"), true);
|
|
|
|
expect(html).toContain("data-streaming-code-block");
|
|
expect(html).not.toContain('data-streaming-inline-code="true"');
|
|
});
|
|
|
|
it("restores Streamdown highlighting after streaming finishes", () => {
|
|
const html = renderMarkdown(
|
|
["```html", '<main class="report">Hello</main>', "```"].join("\n"),
|
|
false,
|
|
);
|
|
|
|
expect(html).toContain('data-streamdown="code-block"');
|
|
expect(html).not.toContain("data-streaming-code-block");
|
|
});
|
|
|
|
it("preserves custom non-code renderers while streaming", () => {
|
|
const html = renderMarkdown(
|
|
"[Docs](https://example.com)\n\n",
|
|
true,
|
|
{
|
|
a: ({ children, href }) =>
|
|
createElement("a", { "data-custom-link": true, href }, children),
|
|
img: (props: ImgHTMLAttributes<HTMLImageElement>) =>
|
|
createElement("img", { ...props, "data-custom-image": true }),
|
|
},
|
|
);
|
|
|
|
expect(html).toContain('data-custom-link="true"');
|
|
expect(html).toContain('data-custom-image="true"');
|
|
});
|
|
|
|
it("preserves a caller-provided code renderer while streaming", () => {
|
|
const html = renderMarkdown(
|
|
["```html", "<main />", "```"].join("\n"),
|
|
true,
|
|
{
|
|
code: ({ children }) =>
|
|
createElement("code", { "data-custom-code": true }, children),
|
|
},
|
|
);
|
|
|
|
expect(html).toContain('data-custom-code="true"');
|
|
expect(html).toContain("data-streaming-code-block");
|
|
});
|
|
});
|