update
This commit is contained in:
56
tests/unit/file-ops-lazy-editor.test.js
Normal file
56
tests/unit/file-ops-lazy-editor.test.js
Normal file
@@ -0,0 +1,56 @@
|
||||
// P2-9(audit C-4)配套:createFileOps 不得构造时缓存 editor。
|
||||
//
|
||||
// 背景:app.js 顶层不再 new MarkdownEditor(CM6 走 dynamic import,bootstrap
|
||||
// 里才实例化),所以 createFileOps 在模块 eval 时拿到的 controls.editor 是
|
||||
// null。file-ops.js 若构造时 `const { editor } = controls` 解构缓存,之后
|
||||
// bootstrap 给 editor 赋值也传不进来 —— deleteFile 等路径 syncDirtyFromEditor
|
||||
// (state, null) 直接 TypeError。
|
||||
//
|
||||
// 契约:controls.editor 必须运行时现取(app.js 侧用对象字面量 getter 提供
|
||||
// 活视图),createFileOps 之后赋值也生效。
|
||||
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { createFileOps } from '../../src/file-ops.js';
|
||||
|
||||
describe('createFileOps editor 惰性解析(P2-9)', () => {
|
||||
it('createFileOps 之后才赋值的 editor 也能被 deleteFile 用到', async () => {
|
||||
let lateEditor = null;
|
||||
const calls = [];
|
||||
const controls = {
|
||||
fileList: {},
|
||||
contextMenu: {},
|
||||
viewer: {},
|
||||
// app.js 实际形态:对象字面量 getter,运行时才读模块级 let editor
|
||||
get editor() { return lateEditor; },
|
||||
};
|
||||
const state = { currentFile: null, isDirty: false, deletingPath: null };
|
||||
const ops = createFileOps({
|
||||
state,
|
||||
controls,
|
||||
api: { deleteFile: async () => ({ ok: true }) },
|
||||
callbacks: {
|
||||
openFile() {},
|
||||
updateWindowTitle() {},
|
||||
clearCurrentFile() {},
|
||||
updateStatusStats() {},
|
||||
syncSaveButton() {},
|
||||
applyEditorMode() {},
|
||||
},
|
||||
});
|
||||
|
||||
// bootstrap 完成:editor 才实例化(模拟 app.js 的时序)
|
||||
lateEditor = {
|
||||
isDirty: () => { calls.push('isDirty'); return false; },
|
||||
getContent: () => 'content',
|
||||
};
|
||||
|
||||
await ops.deleteFile({ path: '/tmp/a.md', name: 'a.md' });
|
||||
|
||||
// deleteFile 第一行就 syncDirtyFromEditor(state, editor) —— 旧实现这里
|
||||
// 拿到构造时缓存的 null,editor.isDirty() 直接 TypeError
|
||||
expect(calls).toContain('isDirty');
|
||||
expect(state.deletingPath).toBe(null); // finally 清守卫,流程走完了
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user