Просмотр исходного кода

test(tui): add renderMarkdown unit tests

Cover bold conversion, bullet replacement, bold-inside-lists,
bold leak prevention, table rendering, and full-reset stripping.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fanghanjun 7 месяцев назад
Родитель
Сommit
b4a4ea47ac
1 измененных файлов с 59 добавлено и 0 удалено
  1. 59 0
      packages/cli/src/tui/__tests__/markdown.test.ts

+ 59 - 0
packages/cli/src/tui/__tests__/markdown.test.ts

@@ -0,0 +1,59 @@
+import { describe, expect, it } from "vitest";
+import { renderMarkdown } from "../markdown.js";
+
+describe("renderMarkdown", () => {
+  it("converts **text** to ANSI bold", () => {
+    const result = renderMarkdown("这是 **加粗** 文本");
+    // Should contain ANSI bold on/off around 加粗
+    expect(result).toContain("\x1b[1m加粗\x1b[22m");
+    // Should NOT contain raw ** markers
+    expect(result).not.toContain("**");
+  });
+
+  it("converts * bullets to · bullets", () => {
+    const result = renderMarkdown("* 第一项\n* 第二项");
+    expect(result).toContain("· 第一项");
+    expect(result).toContain("· 第二项");
+    // No raw * bullets remaining
+    expect(result).not.toMatch(/^\s*\* /m);
+  });
+
+  it("renders bold inside list items", () => {
+    const result = renderMarkdown("* **昨日**: 总统套房\n* **今日**: 桥洞");
+    expect(result).toContain("\x1b[1m昨日\x1b[22m");
+    expect(result).toContain("\x1b[1m今日\x1b[22m");
+    expect(result).toContain("·");
+    expect(result).not.toContain("**");
+  });
+
+  it("does not leak bold across lines", () => {
+    const result = renderMarkdown("打磨**冲突场景**,还是梳理**心理转变弧线**。");
+    // Each bold region should be self-contained
+    const boldRegions = [...result.matchAll(/\x1b\[1m(.*?)\x1b\[22m/g)];
+    expect(boldRegions).toHaveLength(2);
+    expect(boldRegions[0][1]).toBe("冲突场景");
+    expect(boldRegions[1][1]).toBe("心理转变弧线");
+  });
+
+  it("renders tables with box-drawing characters", () => {
+    const result = renderMarkdown(
+      "| 属性 | 值 |\n|------|----|\n| 住所 | 桥洞 |",
+    );
+    expect(result).toContain("┌");
+    expect(result).toContain("│");
+    expect(result).toContain("└");
+  });
+
+  it("does not contain full-reset codes that override parent Ink color", () => {
+    // \x1b[0m resets ALL terminal attributes including color set by Ink's <Text>.
+    // renderMarkdown must not emit it, so the parent <Text color={...}> stays in effect.
+    const result = renderMarkdown("这是 **加粗** 文本");
+    expect(result).not.toContain("\x1b[0m");
+  });
+
+  it("falls back to raw text on parse error", () => {
+    // renderMarkdown should never throw; it returns raw text on failure
+    const result = renderMarkdown("plain text");
+    expect(result).toContain("plain text");
+  });
+});