From 6f69a0cfe25a1f4c347335f01cc8bae992d117d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Mon, 17 Aug 2026 14:26:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=B4=A0=E6=9D=90=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E6=A3=80=E6=9F=A5=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 选择独立素材时清除当前节点选择,确保检查器切换到素材面板。 补充节点选择后切换素材检查器的回归测试。 --- .../src/view/ui-editor/useUiEditorPage.ts | 1 + .../tests/uiEditorPage.test.ts | 97 +++++++++++++++++-- 2 files changed, 89 insertions(+), 9 deletions(-) diff --git a/apps/ai-game-creator-shell/src/view/ui-editor/useUiEditorPage.ts b/apps/ai-game-creator-shell/src/view/ui-editor/useUiEditorPage.ts index eab962fb7..dd546edc7 100644 --- a/apps/ai-game-creator-shell/src/view/ui-editor/useUiEditorPage.ts +++ b/apps/ai-game-creator-shell/src/view/ui-editor/useUiEditorPage.ts @@ -441,6 +441,7 @@ export function useUiEditorPage( } function selectSprite(id: SpriteAssetId) { + setSelectedNodeId(null); setSelectedSpriteId(id); } diff --git a/apps/ai-game-creator-shell/tests/uiEditorPage.test.ts b/apps/ai-game-creator-shell/tests/uiEditorPage.test.ts index f0287fb4e..2836d37e0 100644 --- a/apps/ai-game-creator-shell/tests/uiEditorPage.test.ts +++ b/apps/ai-game-creator-shell/tests/uiEditorPage.test.ts @@ -1,31 +1,85 @@ // @vitest-environment jsdom -import { fireEvent, render, screen } from '@testing-library/react'; +import { + act, + fireEvent, + render, + renderHook, + screen, +} from '@testing-library/react'; import { createElement, type ReactNode } from 'react'; import { describe, expect, it, vi } from 'vitest'; +import type { State } from '../src/features/ui-editor/types/State'; + vi.mock('../src/components/AssetImporter', () => ({ AssetImporter: ({ open }: { open: boolean }) => open ? createElement('div', { role: 'dialog' }, '素材导入器') : null, })); vi.mock('../src/components/modal/ThemedModal', () => ({ - ThemedModal: ({ - open, - children, - }: { - open: boolean; - children: ReactNode; - }) => (open ? createElement('div', { role: 'dialog' }, children) : null), + ThemedModal: ({ open, children }: { open: boolean; children: ReactNode }) => + open ? createElement('div', { role: 'dialog' }, children) : null, })); import UiEditorPage from '../src/view/ui-editor'; +import { InspectorSidebar } from '../src/view/ui-editor/components/Inspector/InspectorSidebar'; +import { useUiEditorPage } from '../src/view/ui-editor/useUiEditorPage'; + +const SELECTABLE_STATE: State = { + ui_design_images: { + page: { + metadata: { name: '主界面', role: 'Page', slave_to: null }, + path: 'assets/page.png', + pixel_size: [100, 80], + pixels_per_unit: 1, + }, + }, + sprite_assets: { + button: { + asset_id: 'button', + metadata: { name: '按钮素材', asset_type: '' }, + path: 'assets/button.png', + pixel_size: [32, 32], + pixels_per_unit: 1, + border: { left: 0, right: 0, top: 0, bottom: 0 }, + }, + }, + font_assets: {}, + ui_trees: [ + { + src_ui_design: 'page', + root: { + id: 'page-root', + transform: { + anchor_min: [0, 0], + anchor_max: [1, 1], + offset_min: [0, 0], + offset_max: [0, 0], + }, + metadata: { + name: '根节点', + description: '', + layout_status: 'Passed', + components_status: 'Pending', + allow_llm_edit_layout: true, + allow_llm_edit_component: true, + source: 'System', + }, + components: [], + children: [], + }, + }, + ], +}; describe('UiEditorPage', () => { it('renders split input tools over a real empty State', () => { render(createElement(UiEditorPage, { projectPath: '/tmp/ui-editor' })); - expect(screen.getByRole('navigation', { name: 'UI 编辑工具' })).toBeTruthy(); + expect( + screen.getByRole('navigation', { name: 'UI 编辑工具' }), + ).toBeTruthy(); expect(screen.getByRole('button', { name: '导入界面图' })).toBeTruthy(); expect(screen.getByRole('button', { name: '导入独立素材' })).toBeTruthy(); expect(screen.getByText('从界面图开始')).toBeTruthy(); @@ -50,4 +104,29 @@ describe('UiEditorPage', () => { fireEvent.click(screen.getByRole('button', { name: '导入界面图' })); expect(screen.getByText('素材导入器')).toBeTruthy(); }); + + it('shows the asset inspector after selecting an asset from a selected node', () => { + const { result } = renderHook(() => useUiEditorPage('/tmp/ui-editor')); + + act(() => { + result.current.editor.replaceState(structuredClone(SELECTABLE_STATE)); + result.current.selectDesignImage('page'); + result.current.selectNode('page-root'); + }); + + const inspector = render( + createElement(InspectorSidebar, { controller: result.current }), + ); + expect(screen.getByRole('heading', { name: '当前节点' })).toBeTruthy(); + + act(() => { + result.current.selectSprite('button'); + }); + inspector.rerender( + createElement(InspectorSidebar, { controller: result.current }), + ); + + expect(screen.getByRole('heading', { name: '当前素材' })).toBeTruthy(); + expect(screen.queryByRole('heading', { name: '当前节点' })).toBeNull(); + }); });