测试:全仓测试统一 Tauri 运行时替身安装点
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

- 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__
This commit is contained in:
2026-10-03 20:19:45 +08:00
parent a77d58b901
commit 25c5ecdf6e
44 changed files with 201 additions and 255 deletions
@@ -14,9 +14,9 @@ const platformSession = vi.hoisted(() => ({
}));
// 与仓库其它 App 内调用方同口径:通过 `window.__TAURI__.core.invoke` 解析原生桥。
window.__TAURI__ = {
installTauriRuntime({
core: { invoke: (...args: unknown[]) => invoke(...args) },
} as never;
});
vi.mock('../src/services/platformSession', () => ({
currentPlatformSessionGeneration: () => platformSession.generation,
requestPlatformSessionRefresh: (...args: unknown[]) =>
@@ -31,6 +31,7 @@ import {
getClientProfileWalletLedger,
redeemClientProfileRewardCode,
} from '../src/services/accountHost';
import { installTauriRuntime } from './tauriRuntimeFake';
beforeEach(() => {
invoke.mockReset();
@@ -17,6 +17,7 @@ import {
it,
React,
render,
resetTauriRuntime,
screen,
testAuthUser,
vi,
@@ -92,7 +93,7 @@ function captureWindowRejections() {
export function registerAuthTests() {
afterEach(() => {
resetPlatformSessionForTests();
delete window.__TAURI__;
resetTauriRuntime();
});
it('throws a startup timeout through to unhandledrejection and leaves the loading state', async () => {
@@ -18,6 +18,7 @@ import { useLauncherHomeDraftStore } from '../../src/view/home/useHomeDraftStore
import {
createTauriEventBridge,
installTauriRuntime,
resetTauriRuntime,
} from '../tauriRuntimeFake';
const nativeClipboardMock = vi.hoisted(() => ({
@@ -945,7 +946,7 @@ function createProjectChatRuntimeHarness({
* 定义已收进 `tests/tauriRuntimeFake.ts`(全仓唯一安装点),这里只转出,供 appSurface 各
* suite 沿用既有的 `./harness` 导入路径。
*/
export { createTauriEventBridge, installTauriRuntime };
export { createTauriEventBridge, installTauriRuntime, resetTauriRuntime };
export function installResizeObserverStub() {
let observerCount = 0;
@@ -1014,7 +1015,7 @@ afterEach(() => {
window.history.pushState({}, '', '/');
window.localStorage.clear();
window.sessionStorage.clear();
delete window.__TAURI__;
resetTauriRuntime();
vi.restoreAllMocks();
if (originalCreateObjectUrl) {
@@ -14,6 +14,7 @@ import {
it,
mockRoleAgentReply,
renderAppAt,
resetTauriRuntime,
roleAgentMockReply,
screen,
vi,
@@ -691,7 +692,7 @@ export function registerProjectConversationTests() {
fireEvent.click(screen.getByRole('button', { name: /拆解创作方向/ }));
const input = await screen.findByLabelText('Agent 对话内容');
fireEvent.change(input, { target: { value: '确认运行环境提示' } });
delete window.__TAURI__;
resetTauriRuntime();
fireEvent.submit(input.closest('form') as HTMLFormElement);
expect(await screen.findByText('需要在 Tauri App 内运行')).not.toBeNull();
@@ -28,6 +28,7 @@ import { invoke } from '@tauri-apps/api/core';
import { AuthenticatedClient } from '../src/app/AuthenticatedClient';
import { resetPlatformSessionForTests } from '../src/services/platformSession';
import { installTauriRuntime, resetTauriRuntime } from './tauriRuntimeFake';
import { installUnhandledRejectionBridge } from './unhandledRejectionBridge';
type AuthInvoke = (
@@ -42,7 +43,7 @@ function reportCalls() {
}
function renderLogin(invokeAuth: AuthInvoke) {
window.__TAURI__ = { core: { invoke: invokeAuth } } as never;
installTauriRuntime({ core: { invoke: invokeAuth } });
render(
// React 19 的 createElement 的 children 形参只接受 ReactNode,渲染函数子节点改编进 props。
createElement(AuthenticatedClient, {
@@ -68,7 +69,7 @@ describe('认证失败的上报判据', () => {
afterEach(() => {
cleanup();
resetPlatformSessionForTests();
delete window.__TAURI__;
resetTauriRuntime();
vi.mocked(invoke).mockClear();
});
@@ -7,6 +7,7 @@ import {
useDirectProjectChatController,
} from '../src/view/project-development/chat/controller/useDirectProjectChatController';
import type { DirectCodexTurnAttachment } from '../src/view/project-development/chat/conversation/directCodexTurnAttachments';
import { installTauriRuntime, resetTauriRuntime } from './tauriRuntimeFake';
// jsdom 的 Blob/File 没实现 `arrayBuffer`,而附件导入链路要按字节读文件。
if (typeof Blob.prototype.arrayBuffer !== 'function') {
@@ -25,7 +26,7 @@ function files(count: number, prefix: string) {
afterEach(() => {
cleanup();
vi.restoreAllMocks();
window.__TAURI__ = undefined;
resetTauriRuntime();
});
describe('聊天输入盒的附件上限', () => {
@@ -38,7 +39,7 @@ describe('聊天输入盒的附件上限', () => {
const fileName = (args as { fileName?: string }).fileName ?? 'file';
return { localPath: `assets/upload-${(uploadSeq += 1)}-${fileName}` };
});
window.__TAURI__ = { core: { invoke: invoke as never } };
installTauriRuntime({ core: { invoke } });
const { result } = renderHook(() =>
useDirectProjectChatController({
@@ -10,6 +10,7 @@ import {
beginProjectOpenAnalytics,
beginUiSaveAnalytics,
} from '../src/services/clientAnalytics';
import { installTauriRuntime, resetTauriRuntime } from './tauriRuntimeFake';
const context = {
route: { user_id: 'user-a', destination_origin: 'https://a.example' },
@@ -27,7 +28,7 @@ function deferred<T>() {
}
afterEach(() => {
cleanup();
delete window.__TAURI__;
resetTauriRuntime();
vi.restoreAllMocks();
});
@@ -54,7 +55,7 @@ function mount(
return null;
},
);
window.__TAURI__ = { core: { invoke } } as unknown as typeof window.__TAURI__;
installTauriRuntime({ core: { invoke } });
const hook = renderHook(
() =>
useHomeProjectCreation({
@@ -24,6 +24,7 @@ import type { RuntimeSessionInstallFailed } from '../src/services/generated/Runt
import type { SendCodeRejected } from '../src/services/generated/SendCodeRejected';
import type { ServerAddressRejected } from '../src/services/generated/ServerAddressRejected';
import type { UnexpectedRejection } from '../src/services/generated/UnexpectedRejection';
import { installTauriRuntime, resetTauriRuntime } from './tauriRuntimeFake';
function expectNever(value: never): void {
void value;
@@ -127,7 +128,7 @@ function variantMessage(error: ClientAuthError): string {
}
function installInvoke(handler: () => Promise<unknown>) {
window.__TAURI__ = { core: { invoke: vi.fn(handler) } } as never;
installTauriRuntime({ core: { invoke: vi.fn(handler) } });
}
describe('认证命令失败的 JS 侧载体', () => {
@@ -150,7 +151,7 @@ describe('认证命令失败的 JS 侧载体', () => {
});
it('认证桥未安装时保持原样抛出,不包装成命令失败', async () => {
delete window.__TAURI__;
resetTauriRuntime();
await expect(
loginClientWithPassword(
@@ -18,6 +18,7 @@ import {
refreshClientAuthSession,
sendClientPhoneLoginCode,
} from '../src/services/clientAuth';
import { installTauriRuntime, resetTauriRuntime } from './tauriRuntimeFake';
const testUser = {
id: 'user-1',
@@ -35,9 +36,9 @@ const testUser = {
beforeEach(() => {
invoke.mockReset();
window.__TAURI__ = {
installTauriRuntime({
core: { invoke: (...args: unknown[]) => invoke(...args) },
} as never;
});
});
test('手机号归一化只保留可提交的纯号码', () => {
@@ -144,7 +145,7 @@ test('续期结果区分成功、失效与身份变化', async () => {
});
test('没有原生宿主时登录能力明确失败关闭', async () => {
delete window.__TAURI__;
resetTauriRuntime();
await expect(readClientAuthState()).rejects.toThrow(
'需要在 Tauri App 内登录',
);
@@ -4,9 +4,10 @@ import { afterEach, expect, test, vi } from 'vitest';
import { createGameCreationAppManifest } from '../../../packages/shared/src/contracts/gameCreationApp';
import { useHomeProjectCreation } from '../src/features/app-shell/useHomeProjectCreation';
import { installTauriRuntime, resetTauriRuntime } from './tauriRuntimeFake';
afterEach(() => {
delete window.__TAURI__;
resetTauriRuntime();
});
test('打开 Cocos 目录走导入入口,不创建 Web 脚手架或发送初始消息', async () => {
@@ -39,7 +40,7 @@ test('打开 Cocos 目录走导入入口,不创建 Web 脚手架或发送初
throw new Error(`意外调用:${command}`);
});
// TauriInvoke 是泛型函数签名,vi.fn 的具体返回类型无法直接赋给它,这里只在装配处桥接。
window.__TAURI__ = { core: { invoke } } as unknown as typeof window.__TAURI__;
installTauriRuntime({ core: { invoke } });
const setLauncherView = vi.fn();
const { result } = renderHook(() =>
useHomeProjectCreation({
@@ -18,6 +18,7 @@ import type {
} from '../src/app/types';
import { CustomLlmSettings } from '../src/features/runtime-config/CustomLlmSettings';
import { RuntimeConfigDialog } from '../src/features/runtime-config/RuntimeConfigDialog';
import { installTauriRuntime, resetTauriRuntime } from './tauriRuntimeFake';
const invoke = vi.fn();
const llm = {
@@ -34,11 +35,11 @@ function Harness() {
beforeEach(() => {
invoke.mockReset();
window.__TAURI__ = { core: { invoke } };
installTauriRuntime({ core: { invoke } });
});
afterEach(() => {
cleanup();
delete window.__TAURI__;
resetTauriRuntime();
});
test('reads endpoint models, filters candidates, and previews only checked models', async () => {
@@ -4,17 +4,20 @@ import { afterEach, expect, it, vi } from 'vitest';
import { createGameCreationAppManifest } from '../../../packages/shared/src/contracts/gameCreationApp';
import { useHomeProjectCreation } from '../src/features/app-shell/useHomeProjectCreation';
import { installTauriRuntime, resetTauriRuntime } from './tauriRuntimeFake';
afterEach(() => {
cleanup();
delete window.__TAURI__;
resetTauriRuntime();
});
const projectPath = 'C:/test/design-project';
const manifest = createGameCreationAppManifest('test-project', '策划项目');
function setup(invoke: ReturnType<typeof vi.fn>) {
window.__TAURI__ = { core: { invoke } } as unknown as typeof window.__TAURI__;
function setup(
invoke: (command: string, args?: Record<string, unknown>) => Promise<unknown>,
) {
installTauriRuntime({ core: { invoke } });
return renderHook(() =>
useHomeProjectCreation({
setStatus: vi.fn(),
@@ -12,6 +12,7 @@ import React from 'react';
import { afterEach, expect, it, vi } from 'vitest';
import { DesignWorkspacePanel } from '../src/features/project-workspace/DesignWorkspacePanel';
import { installTauriRuntime, resetTauriRuntime } from './tauriRuntimeFake';
vi.mock('../src/components/ChatMarkdownMessage', () => ({
ChatMarkdownMessage: () => null,
@@ -20,7 +21,7 @@ vi.mock('../src/components/ChatMarkdownMessage', () => ({
afterEach(() => {
cleanup();
vi.unstubAllEnvs();
delete window.__TAURI__;
resetTauriRuntime();
});
it('shows imported references after a workspace event without reloading the design session', async () => {
@@ -41,7 +42,7 @@ it('shows imported references after a workspace event without reloading the desi
if (command === 'read_design_workspace_file') return '# 导入的需求';
throw new Error(`Unexpected command: ${command}`);
});
window.__TAURI__ = {
installTauriRuntime({
core: { invoke },
event: {
listen: vi.fn(async (_name, callback) => {
@@ -49,7 +50,7 @@ it('shows imported references after a workspace event without reloading the desi
return () => undefined;
}),
},
} as unknown as typeof window.__TAURI__;
});
render(<DesignWorkspacePanel projectPath="imported-project" />);
await waitFor(() => expect(onUpdate).toBeDefined());
await waitFor(() =>
@@ -95,7 +96,7 @@ it('prepares debug fixtures from the header and refreshes the phase and files wi
}
throw new Error(`Unexpected command: ${command}`);
});
window.__TAURI__ = { core: { invoke } } as unknown as typeof window.__TAURI__;
installTauriRuntime({ core: { invoke } });
render(<DesignWorkspacePanel projectPath="test-project" />);
await waitFor(() =>
expect(
@@ -4,6 +4,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest';
import { useDirectThreadChatSubscription } from '../src/view/project-development/chat/controller/useDirectThreadChatSubscription';
import { createTauriEventFake, type TauriEventFake } from './tauriEventFake';
import { resetTauriRuntime } from './tauriRuntimeFake';
const BOOTSTRAP = {
subscriptionId: 'direct-subscription-1',
@@ -17,7 +18,7 @@ afterEach(() => {
cleanup();
eventFake?.restore();
eventFake = null;
delete window.__TAURI__;
resetTauriRuntime();
delete (window as Window & { __TAURI_INTERNALS__?: unknown })
.__TAURI_INTERNALS__;
});
@@ -85,6 +85,7 @@ import {
subscribeClientErrorEvents,
} from '../src/services/errorReporting';
import type { ClientAuthError } from '../src/services/generated/ClientAuthError';
import { resetTauriRuntime } from './tauriRuntimeFake';
describe('客户端错误报告池', () => {
afterEach(() => {
@@ -272,7 +273,7 @@ describe('客户端错误报告池', () => {
});
it('浏览器预览中订阅错误事件不会产生未处理拒绝', async () => {
delete window.__TAURI__;
resetTauriRuntime();
const unsubscribe = subscribeClientErrorEvents(vi.fn());
unsubscribe();
@@ -29,6 +29,7 @@ import {
parseStyleSheet,
resolveDeclarations,
} from './styleCascade';
import { installTauriRuntime } from './tauriRuntimeFake';
const readGamePublishAvailabilityMock = vi.hoisted(() =>
vi.fn(async () => true),
@@ -107,10 +108,10 @@ function installTauri(
return chatHarness.invoke(command, args);
},
);
window.__TAURI__ = {
core: { invoke: invoke as never },
event: { listen: chatHarness.listen as never },
};
installTauriRuntime({
core: { invoke },
event: { listen: chatHarness.listen },
});
return { invoke };
}
@@ -8,10 +8,11 @@ import {
HOME_WEB_PREFLIGHT_IPC_FAILURE,
} from '../src/features/app-shell/homeWebPreflight';
import { useHomeProjectCreation } from '../src/features/app-shell/useHomeProjectCreation';
import { installTauriRuntime, resetTauriRuntime } from './tauriRuntimeFake';
afterEach(() => {
cleanup();
delete window.__TAURI__;
resetTauriRuntime();
});
function mount(preflight: () => Promise<unknown>) {
@@ -31,7 +32,7 @@ function mount(preflight: () => Promise<unknown>) {
return { activeRuntime: 'design' };
return null;
});
window.__TAURI__ = { core: { invoke } } as unknown as typeof window.__TAURI__;
installTauriRuntime({ core: { invoke } });
const hook = renderHook(() =>
useHomeProjectCreation({
setStatus: vi.fn(),
@@ -26,6 +26,7 @@ import {
pickProjectFromLauncher,
testAuthUser,
} from './appSurface/harness';
import { installTauriRuntime } from './tauriRuntimeFake';
const PROJECT_PATH = '/tmp/run-notice-shell-project';
@@ -115,10 +116,10 @@ function renderWorkbench() {
return runtimeHarness.invoke(command, args);
},
);
window.__TAURI__ = {
core: { invoke: invoke as never },
event: { listen: runtimeHarness.listen as never },
};
installTauriRuntime({
core: { invoke },
event: { listen: runtimeHarness.listen },
});
render(
<WorkspaceLauncherShell
currentUser={testAuthUser}
@@ -179,10 +180,10 @@ describe('浮层提示的外壳接线', () => {
}
return runtimeHarness.invoke(command);
});
window.__TAURI__ = {
core: { invoke: invoke as never },
event: { listen: runtimeHarness.listen as never },
};
installTauriRuntime({
core: { invoke },
event: { listen: runtimeHarness.listen },
});
render(
<WorkspaceLauncherShell
currentUser={testAuthUser}
@@ -32,6 +32,7 @@ import {
screen,
waitFor,
} from './appSurface/harness';
import { installTauriRuntime } from './tauriRuntimeFake';
const PROJECT_PATH = '/tmp/preview-activation-project';
const PROJECT_ID = 'preview-activation-project';
@@ -75,10 +76,10 @@ function installTauri(
return chatHarness.invoke(command, args);
},
);
window.__TAURI__ = {
core: { invoke: invoke as never },
event: { listen: chatHarness.listen as never },
};
installTauriRuntime({
core: { invoke },
event: { listen: chatHarness.listen },
});
return { invoke, invokeCounts };
}
@@ -9,36 +9,12 @@ import {
resetWorkspacePreferencesForTests,
setProjectCreationDirectory,
} from '../src/features/app-shell/workspacePreferences';
type TauriInvoke = NonNullable<
NonNullable<NonNullable<Window['__TAURI__']>['core']>['invoke']
>;
type TauriListen = NonNullable<
NonNullable<NonNullable<Window['__TAURI__']>['event']>['listen']
>;
function asTauriInvoke(
invoke: (command: string, args?: Record<string, unknown>) => Promise<unknown>,
): TauriInvoke {
// 泛型 invoke 与具体的非泛型 mock 结构上不可兼容,只能用 as unknown as 收敛。
return invoke as unknown as TauriInvoke;
}
function asTauriListen(
listen: (
event: string,
handler: (event: { payload: unknown }) => void,
) => Promise<unknown>,
): TauriListen {
// 泛型 listen 与携带具体负载的 mock 结构上不可兼容,只能用 as unknown as 收敛。
return listen as unknown as TauriListen;
}
import { installTauriRuntime, resetTauriRuntime } from './tauriRuntimeFake';
describe('项目创建目录偏好', () => {
beforeEach(() => {
resetWorkspacePreferencesForTests();
delete window.__TAURI__;
resetTauriRuntime();
});
it('去掉首尾空白与多余分隔符,并保留盘根', () => {
@@ -106,19 +82,17 @@ describe('项目创建目录偏好', () => {
}
throw new Error('unexpected invoke ' + command);
});
window.__TAURI__ = {
core: { invoke: asTauriInvoke(invoke) },
installTauriRuntime({
core: { invoke },
event: {
listen: asTauriListen(
vi.fn(async (_event, handler) => {
eventHandler = handler;
return () => {
eventHandler = null;
};
}),
),
listen: vi.fn(async (_event, handler) => {
eventHandler = handler;
return () => {
eventHandler = null;
};
}),
},
};
});
const { result } = renderHook(() => useProjectCreationDirectory());
await waitFor(() => {
@@ -7,7 +7,6 @@ import type {
GameCreationAppAssetManifestEntry,
GameCreationAppManifest,
} from '../../../packages/shared/src/contracts/gameCreationApp';
import type { TauriInvoke } from '../src/app/types';
const canvasFixture = vi.hoisted(() => ({
manifest: null as GameCreationAppManifest | null,
@@ -34,6 +33,7 @@ import {
waitFor,
within,
} from './appSurface/harness';
import { installTauriRuntime, resetTauriRuntime } from './tauriRuntimeFake';
const projectPath = '/tmp/live-canvas-integration';
@@ -47,16 +47,6 @@ function legacyAssetKind(kind: string): GameCreationAppAssetKind {
return kind as unknown as GameCreationAppAssetKind;
}
/**
* 泛型 `invoke` 与具体的非泛型 mock 结构上不可兼容,只能用显式转换收敛类型;
* 运行时原样返回同一个 mock,调用方仍持有原引用(`mock.calls` 等断言不受影响)。
*/
function asTauriInvoke(
invoke: (command: string, args?: Record<string, unknown>) => Promise<unknown>,
): TauriInvoke {
return invoke as unknown as TauriInvoke;
}
/**
* 切栏目走「资源总览」的栏目缩略卡片(左侧大纲导航已删除)。
* 与两个 appSurface suite 里的同名助手同口径:切完必须落到目标栏目的子画布。
@@ -543,7 +533,7 @@ function SwitchableDerivedWorkbench({
describe('project resource live canvas integration', () => {
afterEach(() => {
delete window.__TAURI__;
resetTauriRuntime();
canvasFixture.manifest = null;
canvasFixture.revision = 0;
});
@@ -837,10 +827,10 @@ describe('project resource live canvas integration', () => {
throw new Error(`unexpected invoke ${command}`);
},
);
window.__TAURI__ = {
core: { invoke: asTauriInvoke(invoke) },
installTauriRuntime({
core: { invoke },
event: { listen: async () => () => undefined },
};
});
return {
invoke,
deriveCalls,
@@ -5,16 +5,17 @@ import { afterEach, describe, expect, it, vi } from 'vitest';
import { useProjectSnapshotWorkspace } from '../src/features/app-shell/useProjectSnapshotWorkspace';
import { createProjectSnapshotWorkspaceRegistration } from '../src/services/projectSnapshotWorkspace';
import { installTauriRuntime, resetTauriRuntime } from './tauriRuntimeFake';
afterEach(() => {
cleanup();
delete window.__TAURI__;
resetTauriRuntime();
});
describe('项目快照窗口登记', () => {
it('在无 projectPath URL 的单窗口登记、切换、离开,StrictMode 不误关项目', async () => {
const invoke = vi.fn(async () => undefined);
window.__TAURI__ = { core: { invoke: invoke as never } };
installTauriRuntime({ core: { invoke } });
function Workspace({ path }: { path: string | null }) {
useProjectSnapshotWorkspace(path);
return null;
@@ -3,31 +3,7 @@ import { act, renderHook, waitFor } from '@testing-library/react';
import { afterEach, expect, test, vi } from 'vitest';
import { useRecentProjects } from '../src/features/app-shell/useRecentProjects';
type TauriInvoke = NonNullable<
NonNullable<NonNullable<Window['__TAURI__']>['core']>['invoke']
>;
type TauriListen = NonNullable<
NonNullable<NonNullable<Window['__TAURI__']>['event']>['listen']
>;
function asTauriInvoke(
invoke: (command: string, args?: Record<string, unknown>) => Promise<unknown>,
): TauriInvoke {
// 泛型 invoke 与具体的非泛型 mock 结构上不可兼容,只能用 as unknown as 收敛。
return invoke as unknown as TauriInvoke;
}
function asTauriListen(
listen: (
event: string,
handler: (event: { payload: unknown }) => void,
) => Promise<unknown>,
): TauriListen {
// 泛型 listen 与携带具体负载的 mock 结构上不可兼容,只能用 as unknown as 收敛。
return listen as unknown as TauriListen;
}
import { installTauriRuntime, resetTauriRuntime } from './tauriRuntimeFake';
const READY_PROJECT = {
projectPath: '/tmp/ready-project',
@@ -46,7 +22,7 @@ const READY_PROJECT = {
};
afterEach(() => {
delete window.__TAURI__;
resetTauriRuntime();
window.localStorage.clear();
});
@@ -72,7 +48,7 @@ test('刷新坏项目时保留其它项目已确认的正常状态', async () =>
return READY_PROJECT;
},
);
window.__TAURI__ = { core: { invoke: asTauriInvoke(invoke) } };
installTauriRuntime({ core: { invoke } });
window.localStorage.setItem(
'genarrative-ai-game-creator.recent-workspaces.v1',
JSON.stringify(['/tmp/ready-project']),
@@ -131,7 +107,7 @@ test('单次目录检查失败会就地重试,不会把整行钉成「检查
return READY_PROJECT;
},
);
window.__TAURI__ = { core: { invoke: asTauriInvoke(invoke) } };
installTauriRuntime({ core: { invoke } });
window.localStorage.setItem(
'genarrative-ai-game-creator.recent-workspaces.v1',
JSON.stringify(['/tmp/ready-project']),
@@ -173,7 +149,7 @@ test('失败结果不跨轮保留:刷新时该项回到「检查中」并重
return { ...READY_PROJECT, projectPath };
},
);
window.__TAURI__ = { core: { invoke: asTauriInvoke(invoke) } };
installTauriRuntime({ core: { invoke } });
window.localStorage.setItem(
'genarrative-ai-game-creator.recent-workspaces.v1',
JSON.stringify(['/tmp/broken-project']),
@@ -218,7 +194,7 @@ test('提权类失败不重试:不放大 UAC 弹窗', async () => {
);
},
);
window.__TAURI__ = { core: { invoke: asTauriInvoke(invoke) } };
installTauriRuntime({ core: { invoke } });
window.localStorage.setItem(
'genarrative-ai-game-creator.recent-workspaces.v1',
JSON.stringify(['/tmp/elevation-project']),
@@ -263,19 +239,17 @@ test('Rust 偏好事件与 command 返回同时到达时只检查新增项目一
throw new Error('unexpected invoke ' + command);
},
);
window.__TAURI__ = {
core: { invoke: asTauriInvoke(invoke) },
installTauriRuntime({
core: { invoke },
event: {
listen: asTauriListen(
vi.fn(async (_event, handler) => {
emitPreferenceEvent = handler;
return () => {
emitPreferenceEvent = null;
};
}),
),
listen: vi.fn(async (_event, handler) => {
emitPreferenceEvent = handler;
return () => {
emitPreferenceEvent = null;
};
}),
},
};
});
const { result } = renderHook(() => useRecentProjects(vi.fn()));
await waitFor(() => {
@@ -309,7 +283,7 @@ test('Rust 偏好事件与 command 返回同时到达时只检查新增项目一
);
},
);
window.__TAURI__ = { core: { invoke: asTauriInvoke(invoke) } };
installTauriRuntime({ core: { invoke } });
window.localStorage.setItem(
'genarrative-ai-game-creator.recent-workspaces.v1',
JSON.stringify(['/tmp/denied-elevation-project']),
@@ -19,6 +19,7 @@ import {
type RuntimeRegionReference,
} from '../src/features/project-workspace/resourceReferences';
import type { UserContentPart } from '../src/view/project-development/chat/generated/UserContentPart';
import { installTauriRuntime, resetTauriRuntime } from './tauriRuntimeFake';
function asset(
id: string,
@@ -67,7 +68,7 @@ const attachmentPart: UserContentPart = {
afterEach(() => {
cleanup();
vi.restoreAllMocks();
window.__TAURI__ = undefined;
resetTauriRuntime();
});
describe('资源引用 provider', () => {
@@ -368,7 +369,7 @@ describe('Skill provider', () => {
if (command === 'list_client_extensions') return [];
throw new Error(`unexpected invoke ${command}`);
});
window.__TAURI__ = { core: { invoke: invoke as never } };
installTauriRuntime({ core: { invoke } });
const { result } = renderHook(() => useSkillReferenceProvider());
expect(result.current.trigger).toBe('$');
@@ -420,7 +421,7 @@ describe('Skill provider', () => {
}
throw new Error(`unexpected invoke ${command}`);
});
window.__TAURI__ = { core: { invoke: invoke as never } };
installTauriRuntime({ core: { invoke } });
const { result } = renderHook(() => useSkillReferenceProvider());
act(() => {
@@ -450,7 +451,7 @@ describe('Skill provider', () => {
if (command === 'list_client_extensions') return [];
throw new Error(`unexpected invoke ${command}`);
});
window.__TAURI__ = { core: { invoke: invoke as never } };
installTauriRuntime({ core: { invoke } });
const { result } = renderHook(() => useSkillReferenceProvider());
@@ -511,7 +512,7 @@ describe('Skill provider', () => {
}
throw new Error(`unexpected invoke ${command}`);
});
window.__TAURI__ = { core: { invoke: invoke as never } };
installTauriRuntime({ core: { invoke } });
const { result } = renderHook(() => useSkillReferenceProvider());
act(() => {
@@ -542,7 +543,7 @@ describe('Skill provider', () => {
throw new Error(`unexpected invoke ${command}`);
})
.mockRejectedValueOnce(new Error('transient'));
window.__TAURI__ = { core: { invoke: invoke as never } };
installTauriRuntime({ core: { invoke } });
const { result } = renderHook(() => useSkillReferenceProvider());
act(() => {
@@ -568,7 +569,7 @@ describe('Skill provider', () => {
it('`toReference` / `refresh` / `mentionToken` 只认 Skill', async () => {
const invoke = vi.fn(async () => []);
window.__TAURI__ = { core: { invoke: invoke as never } };
installTauriRuntime({ core: { invoke } });
const { result } = renderHook(() => useSkillReferenceProvider());
expect(
@@ -17,6 +17,7 @@ import {
waitFor,
within,
} from './appSurface/harness';
import { installTauriRuntime } from './tauriRuntimeFake';
const PROJECT_PATH = '/tmp/batch-tags-project';
const PROJECT_ID = 'batch-tags-project';
@@ -294,10 +295,10 @@ function installHostTauri(
throw new Error(`unexpected invoke ${command}`);
},
);
window.__TAURI__ = {
core: { invoke: invoke as never },
event: { listen: (async () => () => undefined) as never },
};
installTauriRuntime({
core: { invoke },
event: { listen: async () => () => undefined },
});
return {
invoke,
batchWrites,

Some files were not shown because too many files have changed in this diff Show More