Files
Genarrative/apps/ai-game-creator-shell/tests/uiTreeNodeCycle.test.ts
T
k88936 594063a1e0 测试:修正 AGC 测试文件的类型错误
- 按 vitest 0.34 的参数元组口径改写 mock 泛型
- 修正 noUncheckedIndexedAccess 下的下标访问
- 补齐与当前类型脱节的测试桩字段
- 按 scripts/*.mjs 的运行时契约补局部类型声明
2026-10-03 17:41:30 +08:00

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: 'Stack',
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');
});
});