Files
MyNote/tests/unit/frontmatter-codec.test.ts
T
hunter-dev 96f5c72fa7 fix: 知识图谱与思维导图不显示内容
三个独立 bug 修复:
1. MindmapTree StrictMode 双重渲染: Effect 1 创建 mm 实例, Effect 2 设置数据,
   StrictMode 下 Effect 1 重建 mm 但 Effect 2 不重新运行 → 新 mm 无数据
   修复: 在 Effect 1 中用 useStore.getState().tree 设置初始数据

2. LinkGraph onSwitchToEditor 不稳定: App 传内联箭头函数每次渲染新引用,
   导致 D3 力导向图 Effect 2 依赖变化不断重置 → 图谱闪烁/不显示
   修复: useCallback 稳定 switchToEditor 引用

3. frontmatter 块式 YAML 列表解析: parseList 只支持内联 [a, b] 格式,
   用户手写 links:/tags: 多行 - item 格式无法解析 → 知识图谱无边
   修复: parseYaml 支持 YAML 块式列表 (- item 多行)

新增 E2E 测试 graph-render.spec.ts 验证思维导图+知识图谱渲染内容
新增单元测试覆盖块式 YAML 列表解析
2026-08-27 16:35:47 +08:00

67 lines
2.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect } from 'vitest';
import { splitFrontmatter, joinFrontmatter } from '../../apps/desktop/src/main/safe/frontmatter-codec';
import type { DocMeta } from '@hunter/shared';
describe('splitFrontmatter', () => {
it('无 frontmatter 的纯 Markdown', () => {
const { meta, body } = splitFrontmatter('# 标题\n正文');
expect(meta).toEqual({});
expect(body).toBe('# 标题\n正文');
});
it('解析四字段', () => {
const raw = '---\ntitle: 我的标题\ntags: [a, b]\nstar: true\nlinks: [x/y.md]\n---\n# 正文';
const { meta, body } = splitFrontmatter(raw);
expect(meta).toEqual<DocMeta>({ title: '我的标题', tags: ['a','b'], star: true, links: ['x/y.md'] });
expect(body).toBe('# 正文');
});
it('块式 YAML 列表(多行 - item)', () => {
const raw = '---\ntitle: 标题\nlinks:\n - a.md\n - b.md\ntags:\n - x\n - y\n---\n# 正文';
const { meta, body } = splitFrontmatter(raw);
expect(meta.links).toEqual(['a.md', 'b.md']);
expect(meta.tags).toEqual(['x', 'y']);
expect(meta.title).toBe('标题');
expect(body).toBe('# 正文');
});
it('块式列表后紧跟其他字段', () => {
const raw = '---\nlinks:\n - a.md\nstar: true\n---\n# B';
const { meta } = splitFrontmatter(raw);
expect(meta.links).toEqual(['a.md']);
expect(meta.star).toBe(true);
});
it('带引号的值', () => {
const { meta } = splitFrontmatter('---\ntitle: "含: 冒号"\n---\n');
expect(meta.title).toBe('含: 冒号');
});
it('空数组与 false 不解析为有值', () => {
const { meta } = splitFrontmatter('---\ntags: []\nstar: false\n---\n');
expect(meta.tags).toEqual([]);
expect(meta.star).toBe(false);
});
});
describe('joinFrontmatter (FR-M2 精简)', () => {
it('空 meta 不写围栏', () => {
expect(joinFrontmatter({}, '# 正文')).toBe('# 正文');
});
it('默认值不落盘:star:false / 空数组', () => {
const out = joinFrontmatter({ star: false, tags: [], links: [] }, 'body');
expect(out).toBe('body');
});
it('star:true 落盘', () => {
const out = joinFrontmatter({ star: true }, 'body');
expect(out).toContain('star: true');
});
it('含特殊字符的标题加引号', () => {
const out = joinFrontmatter({ title: 'a:b#c' }, 'body');
expect(out).toContain('title: "a:b#c"');
});
it('往返:解析后再序列化保持等价', () => {
const raw = '---\ntitle: T\ntags: [x, y]\nstar: true\n---\n# H\n正文';
const { meta, body } = splitFrontmatter(raw);
const out = joinFrontmatter(meta, body);
const again = splitFrontmatter(out);
expect(again.meta).toEqual(meta);
expect(again.body).toBe(body);
});
});