补齐 UI 编辑器整树拖动的历史与保存落盘验收

- tests/uiEditorPage.test.ts 新增「整树拖动写回一个历史条目,保存后能原样读回」:断言 setTreeOffset 进历史、undo/redo 往返、save 落盘快照里的树偏移就是新值
- 变异验证:setTreeOffset 里 commit 换成 applyState(改状态不进历史)后只有该用例在 canUndo 处变红(1 failed / 37 passed)
- 里程碑记录第 2 条已覆盖的两句与仍缺的一句(渲染层随 root 平移的断言方式),并引用既有 pointerup/取消不写回的用例
This commit is contained in:
kdletters
2026-09-28 17:39:01 +08:00
parent 46cb3f1908
commit beaa6265da
2 changed files with 55 additions and 1 deletions
@@ -1197,4 +1197,57 @@ describe('UiEditorPage', () => {
act(() => hook.result.current.input.selectSprite('panel'));
expect(hook.result.current.canvas.activeImageId).toBe('page-2');
});
it('整树拖动写回一个历史条目,保存后能原样读回', async () => {
const save = vi
.fn()
.mockImplementation(async (_assetId, _revision, state: State) => ({
status: 'saved' as const,
state,
revision: 1,
committedProjectRevision: 1,
}));
const stateStore: IUiDesignStateStore = {
load: vi.fn().mockResolvedValue({
revision: 0,
state: stateWithPages(['page-1']),
}),
save,
generateCode: vi.fn().mockRejectedValue(new Error('测试未配置代码生成')),
};
const hook = renderHook(() =>
useUiEditorSession('/tmp/ui-editor-tree-drag', 'ui-resource', stateStore),
);
await waitFor(() => expect(hook.result.current.save.isLoading).toBe(false));
const before = hook.result.current.canvas.uiTrees[0]?.root.offset;
// 拖动落点一次提交:状态更新并进入历史。
act(() => {
hook.result.current.canvas.setTreeOffset('page-1', [24, 36]);
});
expect(hook.result.current.canvas.uiTrees[0]?.root.offset?.min).toEqual([
24, 36,
]);
expect(hook.result.current.history.canUndo).toBe(true);
// 撤销回到拖动前,重做再回到拖动后。
act(() => {
hook.result.current.history.undo();
});
expect(hook.result.current.canvas.uiTrees[0]?.root.offset).toEqual(before);
act(() => {
hook.result.current.history.redo();
});
expect(hook.result.current.canvas.uiTrees[0]?.root.offset?.min).toEqual([
24, 36,
]);
// 保存把新的树偏移写进快照(下一次加载读回的就是这份 state)。
await act(async () => {
await hook.result.current.save.save();
});
expect(save).toHaveBeenCalledTimes(1);
const savedState = save.mock.calls[0]?.[2] as State;
expect(savedState.ui_trees[0]?.root.offset?.min).toEqual([24, 36]);
});
});