roymondchen 4c855ba50b feat(editor): 写操作支持 doNotPushHistory 选项以跳过历史记录
- editor/codeBlock/dataSource 的 add/update/delete 等接口新增 doNotPushHistory 选项
- 移除不再使用的 editor-history 工具及其单测
- 修复 layer 节点状态在重建时丢失已有 status 的问题
- 同步更新 service 方法文档,新增 dragto 复现用例
2026-05-28 16:03:29 +08:00

111 lines
2.9 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 { beforeAll, describe, expect, test } from 'vitest';
import { cloneDeep } from 'lodash-es';
import type { MApp, MContainer } from '@tmagic/core';
import { NodeType } from '@tmagic/core';
import editorService from '@editor/services/editor';
import historyService from '@editor/services/history';
import { setEditorConfig } from '@editor/utils';
setEditorConfig({
// eslint-disable-next-line no-eval
parseDSL: (dsl: string) => eval(dsl),
});
class LocalStorageMock {
public length = 0;
private store: Record<string, string> = {};
clear() {
this.store = {};
this.length = 0;
}
getItem(key: string) {
return this.store[key] || null;
}
setItem(key: string, value: string) {
this.store[key] = String(value);
this.length += 1;
}
removeItem(key: string) {
delete this.store[key];
this.length -= 1;
}
key(key: number) {
return Object.keys(this.store)[key];
}
}
globalThis.localStorage = new LocalStorageMock();
const ROOT_ID = 1;
const PAGE_ID = 2;
const CONTAINER_ID = 10;
const NODE_A = 11;
const NODE_B = 12;
const root: MApp = {
id: ROOT_ID,
type: NodeType.ROOT,
items: [
{
id: PAGE_ID,
type: NodeType.PAGE,
layout: 'absolute',
style: { width: 375 },
items: [
{
id: CONTAINER_ID,
type: NodeType.CONTAINER,
layout: 'absolute',
style: {},
items: [
{ id: NODE_A, type: 'text', style: {} },
{ id: NODE_B, type: 'text', style: {} },
],
},
],
},
],
};
describe('dragTo undo/redo selection', () => {
beforeAll(() => editorService.set('root', cloneDeep(root)));
test('dragTo 内同父排序后 undo/redo 不应在 nodes 中同时残留页面和组件', async () => {
historyService.reset();
await editorService.select(NODE_A);
expect(editorService.get('nodes').map((n) => n.id)).toEqual([NODE_A]);
const container = editorService.getNodeById(CONTAINER_ID, false) as MContainer;
const nodeA = editorService.getNodeById(NODE_A, false)!;
// 同容器内拖到末尾
await editorService.dragTo([nodeA], container, 2);
console.log(
'after dragTo nodes:',
editorService.get('nodes').map((n) => n.id),
);
await editorService.undo();
// setTimeout(0) -> wait
await new Promise((r) => setTimeout(r, 20));
console.log(
'after undo nodes:',
editorService.get('nodes').map((n) => n.id),
);
console.log('after undo page:', editorService.get('page')?.id);
await editorService.redo();
await new Promise((r) => setTimeout(r, 20));
console.log(
'after redo nodes:',
editorService.get('nodes').map((n) => n.id),
);
// 假设undo 后 nodes 不应同时含有 page 和 component
const undoNodes = editorService.get('nodes').map((n) => n.id);
expect(undoNodes).not.toContain(PAGE_ID);
});
});