feat: 阶段1-3 桌面编辑器(Tauri 骨架/编辑核心深化/复杂内容)

This commit is contained in:
Muse
2026-11-13 21:19:23 +08:00
parent cbd7ce4b44
commit cbe641e21a
36 changed files with 10059 additions and 0 deletions

53
tests/tabs.test.ts Normal file
View File

@@ -0,0 +1,53 @@
import { describe, it, expect } from 'vitest'
import { tabsReducer, createTab, isDirty, type TabsState } from '../src/stores/tabs'
function stateWith(contents: string[]): TabsState {
const tabs = contents.map((c, i) => createTab({ title: `文档${i + 1}`, content: c }))
return { tabs, activeId: tabs[0]?.id ?? null }
}
describe('标签页会话模型', () => {
it('同路径文档重复打开只激活已有标签', () => {
const a = createTab({ title: 'a.md', path: '/x/a.md', content: 'A' })
let s: TabsState = { tabs: [a], activeId: a.id }
s = tabsReducer(s, { type: 'open', tab: createTab({ title: 'a.md', path: '/x/a.md', content: 'A2' }) })
expect(s.tabs).toHaveLength(1)
expect(s.activeId).toBe(a.id)
})
it('dirty 由 content 与 savedContent 比较得出,保存后清除,改回原样也清除', () => {
const t = createTab({ content: '原文' })
expect(isDirty(t)).toBe(false)
let s: TabsState = { tabs: [t], activeId: t.id }
s = tabsReducer(s, { type: 'updateContent', id: t.id, content: '原文改' })
expect(isDirty(s.tabs[0])).toBe(true)
s = tabsReducer(s, { type: 'updateContent', id: t.id, content: '原文' })
expect(isDirty(s.tabs[0])).toBe(false)
s = tabsReducer(s, { type: 'updateContent', id: t.id, content: '新版' })
s = tabsReducer(s, { type: 'saved', id: t.id })
expect(isDirty(s.tabs[0])).toBe(false)
expect(s.tabs[0].savedContent).toBe('新版')
})
it('关闭活动标签后激活相邻标签;关闭其他/右侧范围正确', () => {
let s = stateWith(['a', 'b', 'c'])
const [t1, t2, t3] = s.tabs
s = tabsReducer(s, { type: 'activate', id: t2.id })
s = tabsReducer(s, { type: 'close', id: t2.id })
expect(s.tabs.map((t) => t.id)).toEqual([t1.id, t3.id])
expect(s.activeId).toBe(t3.id)
s = tabsReducer(s, { type: 'open', tab: createTab({ title: 'd', content: 'd' }) })
const t4 = s.tabs[2]
s = tabsReducer(s, { type: 'closeRight', id: t1.id })
expect(s.tabs.map((t) => t.id)).toEqual([t1.id])
void t4
})
it('拖拽排序 move 到目标下标', () => {
let s = stateWith(['a', 'b', 'c'])
const [t1, , t3] = s.tabs
s = tabsReducer(s, { type: 'move', id: t1.id, toIndex: 2 })
expect(s.tabs[2].id).toBe(t1.id)
expect(s.tabs[0].id).toBe(t3.id === s.tabs[0].id ? t3.id : s.tabs[0].id)
})
})