// tests/r3debug/markdown.test.js —— 缺陷 #7b 标题编号注入 import { describe, it, expect } from 'vitest'; import { renderMarkdown, renderMarkdownPlain } from '../../src/components/chat/markdown.js'; describe('#7b 标题编号注入', () => { it('h1→「一、」,h2→「1.1」,h3→「1.2.3」;层级变化归零', () => { const out = renderMarkdown( '# 第一章\n\n## 节一\n\n### 小节一\n\n## 节二\n\n# 第二章\n\n## 节一\n\n### 小节一', ); const hs = out.split('\n').filter((l) => l.startsWith('一、 第一章'); expect(hs[1]).toBe('

1.1 节一

'); expect(hs[2]).toBe('

1.1.1 小节一

'); expect(hs[3]).toBe('

1.2 节二

'); expect(hs[4]).toBe('

二、 第二章

'); expect(hs[5]).toBe('

2.1 节一

'); // h1 变化后 h2 归零 expect(hs[6]).toBe('

2.1.1 小节一

'); }); it('已带数字/中文序号开头的标题跳过注入(原文保持)', () => { const out = renderMarkdown('## 1. 概述\n\n### 1.1 目标\n\n## 一、背景'); const hs = out.split('\n').filter((l) => l.startsWith('1. 概述'); expect(hs[1]).toBe('

1.1 目标

'); expect(hs[2]).toBe('

一、背景

'); }); it('计数器每次渲染入口重置(渲染器单例不跨消息延续编号)', () => { const a = renderMarkdown('# A'); const b = renderMarkdown('# B'); expect(a).toContain('一、 A'); expect(b).toContain('一、 B'); // 若未重置会是「二、 B」 }); it('文档以 h2 开头:父级计数兜底 1(不出现 0.1)', () => { const out = renderMarkdown('## 直接节\n\n### 小节'); const hs = out.split('\n').filter((l) => l.startsWith('1.1 直接节'); expect(hs[1]).toBe('

1.1.1 小节

'); }); it('行内强调(strong 等)保留', () => { const out = renderMarkdown('## 加粗**重点**标题'); expect(out).toContain('

1.1 加粗重点标题

'); }); it('renderMarkdownPlain 不注入编号(DocPane md 回退预览保护正本)', () => { const out = renderMarkdownPlain('# 不应编号'); expect(out.trim()).toBe('

不应编号

'); }); it('所有 h1-h6 均挂 md-hN class(含非 1-3 级)', () => { const out = renderMarkdown('#### 四级\n\n##### 五级'); expect(out).toContain('

'); expect(out).toContain('

'); }); });