fbd30d7c66
Project CI / AI game creator shell Rust smoke (push) Successful in 2m15s
Project CI / AI game creator shell Rust crates (push) Successful in 1m23s
Project CI / Backend tests (push) Successful in 4m34s
Project CI / Native shell tests (push) Successful in 6m35s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 9m49s
Project CI / Frontend tests (push) Successful in 2m43s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 11m59s
Project CI / AI game creator shell web tests (push) Successful in 1m46s
Project CI / Repository checks (push) Successful in 2m25s
界面树循环游标改为渲染期换算有效游标,不再用被动 effect 事后重置 复制路径按钮把复制态绑定到具体路径,去掉延迟重置的 effect 复制态断言改为等待异步落盘,避免同步断言抢跑 新增 useUiTreeNodeCycle 循环顺序与界面树替换重置用例
97 lines
2.8 KiB
TypeScript
97 lines
2.8 KiB
TypeScript
// @vitest-environment jsdom
|
|
|
|
import { act, renderHook } from '@testing-library/react';
|
|
import { describe, expect, it, vi } from 'vitest';
|
|
|
|
import {
|
|
isNeedReview,
|
|
type UiTreeNodeTarget,
|
|
} from '../src/features/ui-editor/stageStatusOverview';
|
|
import type { Node as UiNode } from '../src/features/ui-editor/types/Node';
|
|
import type { UITree } from '../src/features/ui-editor/types/UITree';
|
|
import { useUiTreeNodeCycle } from '../src/view/ui-editor/useUiTreeNodeCycle';
|
|
|
|
function node(
|
|
id: string,
|
|
layoutStatus: UiNode['metadata']['layout_status'],
|
|
): UiNode {
|
|
return {
|
|
id,
|
|
layout: {
|
|
transform: {
|
|
anchor_min: [0, 0],
|
|
anchor_max: [1, 1],
|
|
offset_min: [0, 0],
|
|
offset_max: [0, 0],
|
|
},
|
|
custom_minimum_size: [0, 0],
|
|
size_flags_horizontal: 1,
|
|
size_flags_vertical: 1,
|
|
size_flags_stretch_ratio: 1,
|
|
container: 'None',
|
|
},
|
|
metadata: {
|
|
name: id,
|
|
description: '',
|
|
layout_status: layoutStatus,
|
|
component_status: 'NoProblem',
|
|
allow_llm_edit_layout: true,
|
|
allow_llm_edit_component: true,
|
|
source: 'System',
|
|
},
|
|
component: null,
|
|
children_display_mode: undefined,
|
|
offset: { min: [0, 0], max: [0, 0] },
|
|
children: [],
|
|
};
|
|
}
|
|
|
|
function reviewTree(): UITree {
|
|
return {
|
|
src_ui_design: 'page',
|
|
root: {
|
|
...node('page-root', 'NoProblem'),
|
|
children: [
|
|
node('review-a', { NeedReview: '请检查 0' }),
|
|
node('review-b', { NeedReview: '请检查 1' }),
|
|
node('review-c', { NeedReview: '请检查 2' }),
|
|
],
|
|
},
|
|
};
|
|
}
|
|
|
|
const matchesReviewNode = ({ node }: UiTreeNodeTarget) =>
|
|
isNeedReview(node.metadata.layout_status);
|
|
|
|
describe('useUiTreeNodeCycle', () => {
|
|
it('按顺序循环待检查节点,并在界面树整体替换后重新从第一项开始', () => {
|
|
const uiTrees = [reviewTree()];
|
|
const onFocusNode = vi.fn();
|
|
const { result, rerender } = renderHook(
|
|
({ trees }: { trees: UITree[] }) =>
|
|
useUiTreeNodeCycle({
|
|
uiTrees: trees,
|
|
matches: matchesReviewNode,
|
|
onFocusNode,
|
|
}),
|
|
{ initialProps: { trees: uiTrees } },
|
|
);
|
|
|
|
act(() => result.current.focusNext());
|
|
expect(onFocusNode).toHaveBeenLastCalledWith('page', 'review-a');
|
|
|
|
act(() => result.current.focusNext());
|
|
expect(onFocusNode).toHaveBeenLastCalledWith('page', 'review-b');
|
|
|
|
// 同一版界面树上的无关渲染不得重置循环游标。
|
|
rerender({ trees: uiTrees });
|
|
act(() => result.current.focusNext());
|
|
expect(onFocusNode).toHaveBeenLastCalledWith('page', 'review-c');
|
|
|
|
// 界面树被整体替换时,下一项回到第一项。
|
|
rerender({ trees: [...uiTrees] });
|
|
act(() => result.current.focusNext());
|
|
expect(onFocusNode).toHaveBeenLastCalledWith('page', 'review-a');
|
|
});
|
|
});
|