39 lines
2.0 KiB
TypeScript
39 lines
2.0 KiB
TypeScript
import { expect, test } from "bun:test";
|
|
import { renderMarkdown } from "../src/ui/markdown";
|
|
|
|
test("headings, paragraphs, emphasis, inline code", () => {
|
|
expect(renderMarkdown("# Title\n\nSome **bold** and *em* and `x < y`.\nSecond line.")).toBe(
|
|
'<h1 id="title">Title</h1>\n<p>Some <strong>bold</strong> and <em>em</em> and <code>x < y</code>.\nSecond line.</p>',
|
|
);
|
|
});
|
|
|
|
test("raw HTML is escaped, except the details/summary hint blocks", () => {
|
|
expect(renderMarkdown("<script>alert(1)</script>")).toBe("<p><script>alert(1)</script></p>");
|
|
const h = renderMarkdown("<details>\n<summary>Exercise 1 — nudge</summary>\n\nTry **this**.\n\n</details>");
|
|
expect(h).toMatch(/<details>\s*<summary>Exercise 1 — nudge<\/summary>/);
|
|
expect(h).toContain("<p>Try <strong>this</strong>.</p>");
|
|
expect(h).toContain("</details>");
|
|
expect(renderMarkdown("<summary onclick=x>a</summary>")).not.toContain("<summary onclick");
|
|
});
|
|
|
|
test("fenced code keeps content verbatim and escaped", () => {
|
|
expect(renderMarkdown("```js\nconst a = '<b>';\n# not a heading\n```")).toBe(
|
|
'<pre class="code"><code data-lang="js">const a = \'<b>\';\n# not a heading</code></pre>',
|
|
);
|
|
});
|
|
|
|
test("lists, quotes, rules", () => {
|
|
expect(renderMarkdown("- a\n- b\n\n1. one\n2. two")).toBe("<ul><li>a</li><li>b</li></ul>\n<ol><li>one</li><li>two</li></ol>");
|
|
expect(renderMarkdown("> quoted\n\n---")).toBe("<blockquote><p>quoted</p></blockquote>\n<hr>");
|
|
});
|
|
|
|
test("links: safe schemes only; images resolved through the given resolver", () => {
|
|
expect(renderMarkdown("[ok](https://x.org/a?b=1&c=2)")).toBe('<p><a href="https://x.org/a?b=1&c=2">ok</a></p>');
|
|
expect(renderMarkdown("[bad](javascript:alert(1))")).toBe("<p>bad</p>");
|
|
expect(renderMarkdown("", { resolveUrl: (u) => `/raw/${encodeURIComponent(u)}` })).toBe('<p><img src="/raw/img%2Fa%20b.png" alt="d"></p>');
|
|
});
|
|
|
|
test("front matter is not rendered", () => {
|
|
expect(renderMarkdown("---\ntitle: x\n---\n# H")).toBe('<h1 id="h">H</h1>');
|
|
});
|