diff --git a/apps/ai-game-creator-shell/tests/appSurface/chat-composer.suite.ts b/apps/ai-game-creator-shell/tests/appSurface/chat-composer.suite.ts index 973df9365..3d875e617 100644 --- a/apps/ai-game-creator-shell/tests/appSurface/chat-composer.suite.ts +++ b/apps/ai-game-creator-shell/tests/appSurface/chat-composer.suite.ts @@ -21,6 +21,7 @@ import { createProjectChatRuntimeHarness, expect, fireEvent, + installTauriRuntime, it, pickProjectFromLauncher, React, @@ -40,19 +41,6 @@ type InvokeOverrides = Record< (args: Record | undefined) => unknown >; -/** - * 安装测试用 Tauri 替身。 - * - * `vi.fn` 的返回类型是固定签名,装不进 `window.__TAURI__` 声明的泛型签名(invoke/listen 都是 - * 泛型函数),这里在装入点整体显式转换,行为与直接赋值一致。 - */ -function installTauriRuntime(runtime: { - core: { invoke: unknown }; - event?: { listen: unknown }; -}) { - window.__TAURI__ = runtime as unknown as Window['__TAURI__']; -} - function gameCreatorConfigView(reasoningEffort: string) { return { path: '/tmp/chat-composer-config.json', diff --git a/apps/ai-game-creator-shell/tests/appSurface/design-agent.suite.ts b/apps/ai-game-creator-shell/tests/appSurface/design-agent.suite.ts index a7b4c6a5a..4ff242c1f 100644 --- a/apps/ai-game-creator-shell/tests/appSurface/design-agent.suite.ts +++ b/apps/ai-game-creator-shell/tests/appSurface/design-agent.suite.ts @@ -6,6 +6,7 @@ import { createProjectChatRuntimeHarness, expect, fireEvent, + installTauriRuntime, it, React, render, @@ -17,16 +18,13 @@ import { type ChatRuntimeHarness = ReturnType; /** - * 安装测试用 Tauri 替身。 - * - * harness 的 invoke/listen 是 `vi.fn` 的固定签名,装不进 `window.__TAURI__` 声明的泛型签名 - * (invoke/listen 都是泛型函数),这里在装入点整体显式转换,行为与直接赋值一致。 + * 把夹具的 invoke / listen 装进 `window.__TAURI__`:转换点只有 harness.installTauriRuntime 一处。 */ -function installTauriRuntime(harness: ChatRuntimeHarness) { - window.__TAURI__ = { +function installChatRuntime(harness: ChatRuntimeHarness) { + installTauriRuntime({ core: { invoke: harness.invoke }, event: { listen: harness.listen }, - } as unknown as Window['__TAURI__']; + }); } /** @@ -50,7 +48,7 @@ const AppComponent = App as React.ComponentType< function renderDesignAgent( harness: ReturnType, ) { - installTauriRuntime(harness); + installChatRuntime(harness); window.history.pushState({}, '', '/'); return render( React.createElement(AppComponent, { @@ -401,7 +399,7 @@ export function registerDesignAgentSurfaceTests() { ], }, }); - installTauriRuntime(harness); + installChatRuntime(harness); window.history.pushState({}, '', '/'); render( React.createElement(AppComponent, { @@ -765,7 +763,7 @@ export function registerDesignAgentSurfaceTests() { const harness = createProjectChatRuntimeHarness({ designAgentView: designApprovalView(), }); - installTauriRuntime(harness); + installChatRuntime(harness); window.history.pushState({}, '', '/'); render( React.createElement(AppComponent, { @@ -808,7 +806,7 @@ export function registerDesignAgentSurfaceTests() { }, }, }); - installTauriRuntime(harness); + installChatRuntime(harness); window.history.pushState({}, '', '/'); render( React.createElement(AppComponent, { @@ -843,7 +841,7 @@ export function registerDesignAgentSurfaceTests() { designAgentView: designConversationView(), designAgentContinueView: designConversationView(), }); - installTauriRuntime(harness); + installChatRuntime(harness); window.history.pushState({}, '', '/'); render( React.createElement(AppComponent, { @@ -910,7 +908,7 @@ export function registerDesignAgentSurfaceTests() { const harness = createProjectChatRuntimeHarness({ designAgentView: designHistoryView(), }); - installTauriRuntime(harness); + installChatRuntime(harness); window.history.pushState({}, '', '/'); render( React.createElement(AppComponent, { diff --git a/apps/ai-game-creator-shell/tests/appSurface/harness.ts b/apps/ai-game-creator-shell/tests/appSurface/harness.ts index 85f623c6c..1470cb338 100644 --- a/apps/ai-game-creator-shell/tests/appSurface/harness.ts +++ b/apps/ai-game-creator-shell/tests/appSurface/harness.ts @@ -935,6 +935,33 @@ function createProjectChatRuntimeHarness({ }; } +/** + * 安装测试用 Tauri 替身。 + * + * `vi.fn` 与各夹具的 invoke / listen 是固定签名,装不进 `window.__TAURI__` 声明的泛型签名 + * (两者都是泛型函数),这里把唯一的装入点收在 harness,整体显式转换,行为与直接赋值一致。 + * + * 参数用「可调用」下界而不是 `unknown`:非函数的误装(字符串、undefined)会在编译期被挡下, + * 同时不与各夹具更具体的 mock 签名冲突;`core` / `event` 都可缺省,只装 invoke 的用例 + * 不需要伪造 event。 + */ +export function installTauriRuntime(runtime: { + core?: { + invoke?: ( + command: string, + args?: Record, + ) => Promise; + }; + event?: { + listen?: ( + event: string, + handler: (event: { payload: unknown }) => void, + ) => Promise<() => void>; + }; +}) { + window.__TAURI__ = runtime as unknown as Window['__TAURI__']; +} + export function installResizeObserverStub() { let observerCount = 0; let observerDisconnected = false; diff --git a/apps/ai-game-creator-shell/tests/appSurface/project-conversation.suite.ts b/apps/ai-game-creator-shell/tests/appSurface/project-conversation.suite.ts index 713ce074f..1b13530fd 100644 --- a/apps/ai-game-creator-shell/tests/appSurface/project-conversation.suite.ts +++ b/apps/ai-game-creator-shell/tests/appSurface/project-conversation.suite.ts @@ -10,6 +10,7 @@ import { emptyProjectPolicy, expect, fireEvent, + installTauriRuntime, it, mockRoleAgentReply, renderAppAt, @@ -20,19 +21,6 @@ import { within, } from './harness'; -/** - * 安装测试用 Tauri 替身。 - * - * `vi.fn` 的返回类型是固定签名,装不进 `window.__TAURI__` 声明的泛型签名(invoke/listen 都是 - * 泛型函数),这里在装入点整体显式转换,行为与直接赋值一致。 - */ -function installTauriRuntime(runtime: { - core: { invoke: unknown }; - event?: { listen: unknown }; -}) { - window.__TAURI__ = runtime as unknown as Window['__TAURI__']; -} - export function registerProjectConversationTests() { it('splits structured rejections by variant and never by copy', () => { // 入队失败是**结构化**载荷:分流只看 `instanceof` 与 `error.type`,文案不参与任何判断, diff --git a/apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts b/apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts index 57909fb75..0304c4567 100644 --- a/apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts +++ b/apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts @@ -38,6 +38,7 @@ import { fireEvent, getResourceSelectButton, installResizeObserverStub, + installTauriRuntime, it, openResourceFilterPanel, ProjectDevelopmentView, @@ -52,17 +53,6 @@ import { within, } from './harness'; -/** - * 安装测试用 Tauri 替身。 - * - * `vi.fn` 的返回类型是固定签名,装不进 `window.__TAURI__` 声明的泛型签名(invoke 是泛型函数), - * 这里在装入点整体显式转换,行为与直接赋值一致。 - */ -function installTauriRuntime(runtime: { core: { invoke: unknown } }) { - // `vi.fn` 固定签名装不进 `window.__TAURI__` 的泛型签名,这里显式转换,运行时行为不变。 - window.__TAURI__ = runtime as unknown as Window['__TAURI__']; -} - /** * 历史夹具沿用的旧 kind 字面量(如 `design-document` / `game-code`)已不在当前 * `GameCreationAppAssetKind` 联合里;这些用例依赖未识别 kind 落「待归类」的运行时语义, diff --git a/apps/ai-game-creator-shell/tests/appSurface/runtime-settings.suite.ts b/apps/ai-game-creator-shell/tests/appSurface/runtime-settings.suite.ts index 19da5e36c..c972a52bc 100644 --- a/apps/ai-game-creator-shell/tests/appSurface/runtime-settings.suite.ts +++ b/apps/ai-game-creator-shell/tests/appSurface/runtime-settings.suite.ts @@ -11,6 +11,7 @@ import { fireEvent, GAME_CREATION_AGENT_RUN_SCHEMA_VERSION, type GameCreationAgentRunTrace, + installTauriRuntime, it, renderLauncherAt, screen, @@ -19,16 +20,6 @@ import { within, } from './harness'; -/** - * 安装测试用 Tauri invoke 替身。 - * - * `vi.fn` 的返回类型是固定签名,装不进 `window.__TAURI__` 声明的泛型签名(invoke 是泛型 - * 函数),这里在装入点整体显式转换,行为与直接赋值一致。 - */ -function installTauriRuntime(runtime: { core: { invoke: unknown } }) { - window.__TAURI__ = runtime as unknown as Window['__TAURI__']; -} - export function registerAgentStatusDerivationTests() { it('keeps fixed overlays below the in-page window title bar', () => { const styles = fs.readFileSync(