import { describe, it, expect } from 'vitest' import { anchorFromMarkdown, offsetInMarkdown, findBlockIndex } from '../src/editor/cursorSync' const MD = '# 标题一行\n\n正文段落内容。\n\n- 列表项甲\n- [ ] 任务项乙\n\n> 引用一句\n' describe('光标锚点同步', () => { it('源码偏移 → 锚点:剥掉标题/列表/引用标记', () => { const headingOffset = MD.indexOf('标题一行') + 2 expect(anchorFromMarkdown(MD, headingOffset)).toEqual({ blockText: '标题一行', offsetInBlock: 2 }) const taskOffset = MD.indexOf('任务项乙') + 1 expect(anchorFromMarkdown(MD, taskOffset)).toEqual({ blockText: '任务项乙', offsetInBlock: 1 }) const quoteOffset = MD.indexOf('引用一句') expect(anchorFromMarkdown(MD, quoteOffset)).toEqual({ blockText: '引用一句', offsetInBlock: 0 }) }) it('锚点 → 源码偏移:往返一致', () => { for (const text of ['标题一行', '正文段落内容。', '列表项甲', '任务项乙', '引用一句']) { const start = MD.indexOf(text) const anchor = anchorFromMarkdown(MD, start + 1) expect(offsetInMarkdown(MD, anchor)).toBe(start + 1) } }) it('找不到锚点时回落 0,不抛错', () => { expect(offsetInMarkdown(MD, { blockText: '不存在的块', offsetInBlock: 3 })).toBe(0) expect(anchorFromMarkdown('', 10)).toEqual({ blockText: '', offsetInBlock: 0 }) }) it('findBlockIndex 精确优先、子串兜底', () => { const blocks = ['标题一行', '正文段落内容。', '列表项甲'] expect(findBlockIndex(blocks, { blockText: '正文段落内容。', offsetInBlock: 0 })).toBe(1) expect(findBlockIndex(blocks, { blockText: '正文段落', offsetInBlock: 0 })).toBe(1) expect(findBlockIndex(blocks, { blockText: '没有', offsetInBlock: 0 })).toBe(-1) }) })