Files
Genarrative/apps/ai-game-creator-shell/tests/workspaceWindowSync.test.tsx
T
k88936 25c5ecdf6e
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m58s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 6m34s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 5m29s
Project CI / Backend tests (pull_request) Failing after 4m38s
Project CI / Frontend tests (pull_request) Successful in 3m33s
Project CI / Repository checks (pull_request) Failing after 4m4s
Project CI / AI game creator shell web tests (pull_request) Successful in 3m13s
Project CI / Native shell tests (pull_request) Successful in 6m35s
测试:全仓测试统一 Tauri 运行时替身安装点
- 78 处内联 window.__TAURI__ 赋值改为 installTauriRuntime,覆盖 appSurface 之外的 37 个测试文件
- 31 处 delete window.__TAURI__ / window.__TAURI__ = undefined 复位改为 resetTauriRuntime
- 删除 recentProjectsHook、projectCreationDirectory、projectResourceLiveIntegration、useProjectResourceCardPreviews、resourceVersionReplacementModel、unityProjectOpen 里的本地 asTauriInvoke / asTauriListen 适配器与相关类型别名
- designProjectRestore 的 setup 参数由 ReturnType<typeof vi.fn> 收窄为具体 invoke 签名
- 迁移后仅 tests/tauriRuntimeFake.ts 直接读写 window.__TAURI__
2026-10-03 20:19:45 +08:00

115 lines
3.7 KiB
TypeScript

/** @vitest-environment jsdom */
import type { ReactNode } from 'react';
import { useCallback } from 'react';
import { vi } from 'vitest';
import { WindowChrome } from '../src/components/WindowChrome';
import {
useWindowChrome,
type WindowChromeActiveProjectRuns,
WindowChromeContext,
} from '../src/components/windowChromeContext';
import { WorkspaceLauncherShell } from '../src/features/app-shell/WorkspaceLauncher';
import {
act,
expect,
it,
React,
render,
testAuthUser,
} from './appSurface/harness';
import { resetTauriRuntime } from './tauriRuntimeFake';
const homeProjectOverride = vi.hoisted(() => ({
openProject: null as
| null
| ((path: string, mode: 'open' | 'create') => Promise<void>),
}));
vi.mock('../src/features/app-shell/useHomeProjectCreation', async () => {
const actual = await vi.importActual<
typeof import('../src/features/app-shell/useHomeProjectCreation')
>('../src/features/app-shell/useHomeProjectCreation');
return {
...actual,
useHomeProjectCreation(
...args: Parameters<typeof actual.useHomeProjectCreation>
) {
const result = actual.useHomeProjectCreation(...args);
return homeProjectOverride.openProject
? { ...result, openProject: homeProjectOverride.openProject }
: result;
},
};
});
it('真实窗口与工作台状态同步收敛,回调读取最新处理器且卸载才清理', async () => {
const publications: WindowChromeActiveProjectRuns[] = [];
let cleanups = 0;
// 仍经过真实 WindowChrome 的 setState/Context;上限只防止回归时测试无限循环。
function BoundedWindowBridge({ children }: { children: ReactNode }) {
const chrome = useWindowChrome();
const { setActiveProjectRuns } = chrome;
const publish = useCallback(
(next: WindowChromeActiveProjectRuns | null) => {
if (next) publications.push(next);
else cleanups += 1;
if (publications.length < 12) setActiveProjectRuns(next);
},
[setActiveProjectRuns],
);
return (
<WindowChromeContext.Provider
value={{ ...chrome, setActiveProjectRuns: publish }}
>
{children}
</WindowChromeContext.Provider>
);
}
const chat = () => null;
const view = (displayName = '测试用户') => (
<WindowChrome>
<BoundedWindowBridge>
<WorkspaceLauncherShell
currentUser={{ ...testAuthUser, displayName }}
onLogout={() => undefined}
initialView="projects"
ProjectChat={chat}
/>
</BoundedWindowBridge>
</WindowChrome>
);
resetTauriRuntime();
const rendered = render(view());
try {
await act(async () => {
await Promise.resolve();
});
// 无原生 invoke 时空快照引用不变,只发布一次。
expect(publications).toHaveLength(1);
expect(cleanups).toBe(0);
expect(new Set(publications.map((item) => item.onOpenProject)).size).toBe(
1,
);
const openProject = publications[0]!.onOpenProject!;
const latestOpen = vi.fn(async () => undefined);
homeProjectOverride.openProject = latestOpen;
rendered.rerender(view('更改显示名'));
// 非依赖变化的重渲染不能让窗口面板重新发布。
expect(publications).toHaveLength(1);
act(() => openProject('/tmp/window-latest-project'));
expect(latestOpen).toHaveBeenCalledWith(
'/tmp/window-latest-project',
'open',
);
// 回调执行只换 ref 里的实现,发布次数与清理次数都不能变。
expect(publications).toHaveLength(1);
expect(cleanups).toBe(0);
rendered.unmount();
expect(cleanups).toBe(1);
} finally {
homeProjectOverride.openProject = null;
rendered.unmount();
}
});