1import { renderToStaticMarkup } from "react-dom/server";
2import ReactMarkdown from "react-markdown";
3import remarkGfm from "remark-gfm";
4import { describe, expect, it } from "vite-plus/test";
5
6import { remarkNormalizeListItemIndentation } from "@t3tools/shared/markdownListIndentation";
7
8function renderMarkdown(markdown: string): string {
9 return renderToStaticMarkup(
10 <ReactMarkdown remarkPlugins={[remarkGfm, remarkNormalizeListItemIndentation]}>
11 {markdown}
12 </ReactMarkdown>,
13 );
14}
15
16describe("remarkNormalizeListItemIndentation", () => {
17 it("renders same-line over-indented list content as list text", () => {
18 const html = renderMarkdown(`why did you do this?
19
20- for (const step of rest.steps) {
21- if (step.request.body) {
22- step.request.body = "<redacted>";
23- }
24- }`);
25
26 expect(html).not.toContain("<pre>");
27 expect(html).toContain("<li>for (const step of rest.steps) {</li>");
28 expect(html).toContain("<li>if (step.request.body) {</li>");
29 expect(html).toContain("<li>step.request.body = &quot;&lt;redacted&gt;&quot;;</li>");
30 });
31
32 it("parses inline markdown in recovered list content", () => {
33 const html = renderMarkdown(
34 "- **important** [docs](https://example.com) use `inline code`, not ~~plain text~~",
35 );
36
37 expect(html).toContain("<strong>important</strong>");
38 expect(html).toContain('<a href="https://example.com">docs</a>');
39 expect(html).toContain("<code>inline code</code>");
40 expect(html).toContain("<del>plain text</del>");
41 expect(html).not.toContain("**important**");
42 });
43
44 it("preserves every recovered block separated by blank lines", () => {
45 const html = renderMarkdown(`- **first block**
46
47 [second block](https://example.com)`);
48
49 expect(html).toContain("<strong>first block</strong>");
50 expect(html).toContain('<a href="https://example.com">second block</a>');
51 });
52
53 it("recursively normalizes lists in recovered tail blocks", () => {
54 const html = renderMarkdown(`- first block
55
56 - nested block`);
57
58 expect(html).not.toContain("<pre>");
59 expect(html).toContain("<li>nested block</li>");
60 });
61
62 it("preserves fenced code blocks within list items", () => {
63 const html = renderMarkdown(`- \`\`\`ts
64 const value = 1;
65 \`\`\``);
66
67 expect(html).toContain('<pre><code class="language-ts">const value = 1;');
68 });
69
70 it("preserves indented code blocks that start below a list marker", () => {
71 const html = renderMarkdown(`-
72 const value = 1;`);
73
74 expect(html).toContain("<pre><code>const value = 1;");
75 });
76
77 it("preserves same-line code blocks without excess indentation", () => {
78 const html = renderMarkdown("- const value = 1;");
79
80 expect(html).toContain("<pre><code>const value = 1;");
81 });
82});