From 9081527a2bed4fb029f73727882d2e977940b531 Mon Sep 17 00:00:00 2001 From: kdletters Date: Sun, 21 Jun 2026 18:53:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=BA=E5=8C=96=E6=A1=8C=E9=9D=A2=E5=A3=B3?= =?UTF-8?q?=E8=83=BD=E5=8A=9B=E6=B5=81=E6=B5=8B=E8=AF=95=E9=97=A8=E7=A6=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 要求 Tauri 桌面能力流由 desktop-shell:test 保护 要求每个桌面能力流关联带 Rust 单测的真实模块 同步项目决策日志中的桌面能力流测试约束 --- .../shared-memory/decision-log.md | 1 + scripts/check-native-shells.mjs | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index 91ba18efd..b51a7600c 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -3228,5 +3228,6 @@ - 背景:Expo 移动壳和 Tauri 桌面壳的 capability 清单会直接影响 H5 是否展示和调用原生能力。如果新增 capability 只写进共享契约或 Rust / TS 能力清单,却没有登记真实宿主 API、分发入口、payload 边界和测试证据,H5 可能认为能力可用,但运行时没有对应真实链路。 - 决策:`scripts/check-native-shells.mjs` 必须对 Expo 移动壳和 Tauri 桌面壳做反向覆盖:共享契约中声明的每个移动端基础能力、iOS 额外能力和桌面能力,都必须在 `mobileCapabilityFlowContracts` 或 `desktopCapabilityFlowContracts` 中登记真实能力流证据。证据必须来自生产实现、宿主配置、边界测试或单端配置检查,不能用占位、生产 mock、fallback unsupported 分支或文档愿景替代真实链路。 +- 2026-06-21 调整:Tauri 桌面能力流必须由根级 `desktop-shell:test` 保护,且每个 `desktopCapabilityFlowContracts` 条目至少关联一个带 Rust 单测的真实桌面壳模块;新增桌面 capability 时不能只登记 dispatch / 配置片段而没有 Rust 单元测试覆盖。 - 影响范围:`packages/shared/src/contracts/hostBridge.ts`、`apps/mobile-shell/src/host-bridge/`、`apps/mobile-shell/src/shell/`、`apps/desktop-shell/src-tauri/src/host_bridge/`、`apps/desktop-shell/src-tauri/src/shell/`、`scripts/check-native-shells.mjs`。 - 验证方式:`npm run check:native-shells`、`npm run typecheck`、`npm run check:encoding`、`git diff --check`。 diff --git a/scripts/check-native-shells.mjs b/scripts/check-native-shells.mjs index d75c0eb9d..46dba88fa 100644 --- a/scripts/check-native-shells.mjs +++ b/scripts/check-native-shells.mjs @@ -3272,6 +3272,15 @@ function assertTauriDesktopCapabilityFlows() { `Tauri desktop declared capabilities missing flow contracts: ${missingCapabilityContracts.join(', ')}`, ); } + const desktopShellTestStep = steps.some( + (step) => + step.label === 'desktop-shell-test' && + step.args[0] === 'run' && + step.args[1] === 'desktop-shell:test', + ); + if (!desktopShellTestStep) { + throw new Error('Tauri desktop capability flows must be guarded by desktop-shell:test'); + } for (const contract of desktopCapabilityFlowContracts) { if (!declaredCapabilitySet.has(contract.capability)) { @@ -3295,6 +3304,19 @@ function assertTauriDesktopCapabilityFlows() { `Tauri desktop ${contract.capability} flow`, ); } + + const testedRustFlowFiles = contract.files.filter((filePath) => { + if (!filePath.startsWith('apps/desktop-shell/src-tauri/src/') || !filePath.endsWith('.rs')) { + return false; + } + const source = fs.readFileSync(filePath, 'utf8'); + return source.includes('#[test]'); + }); + if (testedRustFlowFiles.length === 0) { + throw new Error( + `Tauri desktop ${contract.capability} flow must include at least one Rust unit-tested module`, + ); + } } }