// 阶段 4 验收:恢复记录纯逻辑(键/提供与清理划分)与标签 reducer 的重载/改路径动作。 import { describe, it, expect } from 'vitest' import { recoveryKey, planRecovery } from '../src/utils/recovery' import { tabsReducer, createTab, isDirty, type TabsState } from '../src/stores/tabs' import type { RecoveryEntry } from '../src/services/platform' describe('recoveryKey', () => { it('文件文档按路径键,未命名按标签 id', () => { // docs/29:路径先归一(斜杠统一 + Windows 大小写折叠),同文件不同写法同键 expect(recoveryKey({ id: 't1', path: 'D:\\a.md' })).toBe('path:d:/a.md') expect(recoveryKey({ id: 't1', path: 'd:/A.md' })).toBe('path:d:/a.md') expect(recoveryKey({ id: 't2', path: null })).toBe('untitled:t2') }) }) describe('planRecovery', () => { const fileRecord: RecoveryEntry = { docKey: 'path:D:\\a.md', path: 'D:\\a.md', title: 'a', content: '新草稿', updatedAt: 2, } const savedRecord: RecoveryEntry = { docKey: 'path:D:\\b.md', path: 'D:\\b.md', title: 'b', content: '已存内容', updatedAt: 1, } const untitledRecord: RecoveryEntry = { docKey: 'untitled:t9', path: null, title: '未命名', content: '临时', updatedAt: 3, } it('与磁盘一致的记录清理、不一致与未命名的提供恢复、文件已删的也提供', () => { const plan = planRecovery([fileRecord, savedRecord, untitledRecord], (path) => path === 'D:\\b.md' ? '已存内容' : '磁盘旧内容', ) expect(plan.purgeKeys).toEqual(['path:D:\\b.md']) expect(plan.offer.map((r) => r.docKey)).toEqual(['path:D:\\a.md', 'untitled:t9']) const gonePlan = planRecovery([fileRecord], () => null) expect(gonePlan.offer).toHaveLength(1) expect(gonePlan.purgeKeys).toEqual([]) }) }) describe('tabs reducer 阶段 4 动作', () => { it('loadContent 整表替换并变干净,setPath 改路径与标题', () => { const tab = createTab({ path: 'D:\\a.md', title: 'a', content: '旧' }) let state: TabsState = { tabs: [tab], activeId: tab.id } state = tabsReducer(state, { type: 'updateContent', id: tab.id, content: '我的修改' }) expect(isDirty(state.tabs[0])).toBe(true) state = tabsReducer(state, { type: 'loadContent', id: tab.id, content: '磁盘新内容', encoding: 'GBK' }) expect(state.tabs[0].content).toBe('磁盘新内容') expect(isDirty(state.tabs[0])).toBe(false) expect(state.tabs[0].encoding).toBe('GBK') state = tabsReducer(state, { type: 'setPath', id: tab.id, path: 'D:\\b.md', title: 'b' }) expect(state.tabs[0].path).toBe('D:\\b.md') expect(state.tabs[0].title).toBe('b') }) })