/** * markdown.ts Markdown 渲染器单元测试 * * 重点覆盖: * 1. 基础语法正确性(标题、粗体、斜体、列表、链接、引用、代码) * 2. XSS 防护(先转义再转换、链接白名单 http/https) */ import { describe, it, expect } from 'vitest'; import { renderMarkdown } from '../src/markdown'; describe('renderMarkdown - 基础语法', () => { it('空字符串返回空', () => { expect(renderMarkdown('')).toBe(''); }); it('null/undefined 返回空', () => { expect(renderMarkdown(null as never)).toBe(''); expect(renderMarkdown(undefined as never)).toBe(''); }); it('普通文本渲染为段落', () => { expect(renderMarkdown('你好世界')).toContain('
你好世界
'); }); it('标题渲染 h1-h6', () => { expect(renderMarkdown('# 标题一')).toContain(''); expect(result).toContain('这是引用'); }); it('链接渲染(http 协议)', () => { const result = renderMarkdown('[百度](https://www.baidu.com)'); expect(result).toContain('href="https://www.baidu.com"'); expect(result).toContain('target="_blank"'); expect(result).toContain('rel="noopener noreferrer"'); }); it('水平线渲染', () => { expect(renderMarkdown('---')).toContain('
'); }); }); describe('renderMarkdown - 代码', () => { it('行内代码渲染', () => { const result = renderMarkdown('使用 `console.log` 调试'); expect(result).toContain('console.log'); }); it('代码块渲染', () => { const result = renderMarkdown('```js\nconsole.log("hello");\n```'); expect(result).toContain(''); expect(result).toContain('class="language-js"'); expect(result).toContain('console.log'); }); it('代码块内容不被 Markdown 处理', () => { const result = renderMarkdown('```\n**粗体** *斜体*\n```'); // 代码块内的 Markdown 语法不应被转换 expect(result).toContain('**粗体**'); expect(result).toContain('*斜体*'); expect(result).not.toContain(''); }); }); describe('renderMarkdown - XSS 防护', () => { it('转义 HTML 标签', () => { const result = renderMarkdown(''); expect(result).not.toContain('\n```'); expect(result).not.toContain('