补齐移动壳外观单测

移动壳 appearance helper 增加独立单测覆盖

原生壳结构门禁登记移动外观测试

宿主壳文档和共享决策同步外观测试边界
This commit is contained in:
2026-06-20 08:04:46 +08:00
parent c62ccf66e6
commit 6bd24cc7f8
6 changed files with 102 additions and 4 deletions
@@ -14,6 +14,11 @@ const qrScannerOverlayPath = new URL('../src/shell/QrScannerOverlay.tsx', import
const qrScannerOverlaySource = fs.readFileSync(qrScannerOverlayPath, 'utf8');
const appearancePath = new URL('../src/host-bridge/appearance.ts', import.meta.url);
const appearanceSource = fs.readFileSync(appearancePath, 'utf8');
const appearanceTestPath = new URL(
'../src/host-bridge/appearance.test.ts',
import.meta.url,
);
const appearanceTestSource = fs.readFileSync(appearanceTestPath, 'utf8');
const bridgePath = new URL('../src/host-bridge/bridge.ts', import.meta.url);
const bridgeSource = fs.readFileSync(bridgePath, 'utf8');
const bridgeTestPath = new URL('../src/host-bridge/bridge.test.ts', import.meta.url);
@@ -2242,6 +2247,18 @@ for (const snippet of [
throw new Error(`mobile shell appearance module is missing ${snippet}`);
}
}
for (const snippet of [
'reads the current light or dark system color scheme',
'normalizes missing or unknown native color schemes to unknown',
'wraps the system color scheme in the HostBridge response shape',
"mockReturnValue('light')",
"mockReturnValue('dark')",
'colorScheme: \'unknown\'',
]) {
if (!appearanceTestSource.includes(snippet)) {
throw new Error(`mobile shell appearance tests missing ${snippet}`);
}
}
if (
!dispatchSource.includes('openMobileHostBridgeExternalUrl(request)') ||
@@ -0,0 +1,73 @@
import { Appearance } from 'react-native';
import { beforeEach, describe, expect, test, vi } from 'vitest';
import {
HOST_BRIDGE_PROTOCOL,
HOST_BRIDGE_VERSION,
type HostBridgeRequest,
} from '../../../../packages/shared/src/contracts/hostBridge';
import {
getMobileAppearanceColorScheme,
getMobileHostBridgeAppearanceColorScheme,
} from './appearance';
vi.mock('react-native', () => ({
Appearance: {
getColorScheme: vi.fn(),
},
}));
function request(): HostBridgeRequest {
return {
bridge: HOST_BRIDGE_PROTOCOL,
version: HOST_BRIDGE_VERSION,
id: 'appearance-request',
method: 'appearance.getColorScheme',
};
}
beforeEach(() => {
vi.mocked(Appearance.getColorScheme).mockReset();
});
describe('mobile appearance helpers', () => {
test('reads the current light or dark system color scheme', () => {
vi.mocked(Appearance.getColorScheme).mockReturnValue('light');
expect(getMobileAppearanceColorScheme()).toEqual({
colorScheme: 'light',
});
vi.mocked(Appearance.getColorScheme).mockReturnValue('dark');
expect(getMobileAppearanceColorScheme()).toEqual({
colorScheme: 'dark',
});
});
test('normalizes missing or unknown native color schemes to unknown', () => {
vi.mocked(Appearance.getColorScheme).mockReturnValue(null);
expect(getMobileAppearanceColorScheme()).toEqual({
colorScheme: 'unknown',
});
vi.mocked(Appearance.getColorScheme).mockReturnValue(
'unspecified' as ReturnType<typeof Appearance.getColorScheme>,
);
expect(getMobileAppearanceColorScheme()).toEqual({
colorScheme: 'unknown',
});
});
test('wraps the system color scheme in the HostBridge response shape', () => {
vi.mocked(Appearance.getColorScheme).mockReturnValue('dark');
expect(getMobileHostBridgeAppearanceColorScheme(request())).toEqual({
bridge: HOST_BRIDGE_PROTOCOL,
version: HOST_BRIDGE_VERSION,
id: 'appearance-request',
ok: true,
result: {
colorScheme: 'dark',
},
});
});
});
@@ -2934,3 +2934,10 @@
- 决策:新增 `apps/mobile-shell/src/host-bridge/network.test.ts`,直接覆盖 `network.status` 成功响应、断网响应和原生查询失败传播;移动壳单端配置检查和根级原生壳门禁登记该测试文件并反查关键断言片段。该变更不新增 capability,不改变 shell network 归一化逻辑,也不在分发层包装网络状态。
- 影响范围:`apps/mobile-shell/src/host-bridge/network.test.ts``apps/mobile-shell/scripts/check-config.mjs``scripts/check-native-shells.mjs`、宿主壳方案文档、宿主壳能力统一协议文档。
- 验证方式:`npm run mobile-shell:test -- src/host-bridge/network.test.ts``npm run mobile-shell:typecheck``npm run check:native-shells``npm run check:encoding``git diff --check`
## 2026-06-20 移动外观 HostBridge 单测边界
- 背景:Expo 移动壳 `appearance.getColorScheme` 是 H5 判断宿主配色的只读系统能力,但此前直接 helper 边界主要压在巨型 bridge 测试中;后续拆分桥接 helper 时需要固定 light / dark / unknown 归一和 HostBridge response 形状。
- 决策:新增 `apps/mobile-shell/src/host-bridge/appearance.test.ts`,直接覆盖 React Native `Appearance.getColorScheme()` 的 light / dark、空值 / 未知值归一为 `unknown`,以及 `appearance.getColorScheme` HostBridge 成功响应形状;移动壳单端配置检查和根级原生壳门禁登记该测试文件并反查关键断言片段。该变更不改变 H5 主题策略,也不让壳层覆盖系统或用户偏好。
- 影响范围:`apps/mobile-shell/src/host-bridge/appearance.test.ts``apps/mobile-shell/scripts/check-config.mjs``scripts/check-native-shells.mjs`、宿主壳方案文档、宿主壳能力统一协议文档。
- 验证方式:`npm run mobile-shell:test -- src/host-bridge/appearance.test.ts``npm run mobile-shell:typecheck``npm run check:native-shells``npm run check:encoding``git diff --check`
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -249,6 +249,7 @@ const expectedWechatPageFilesByRoute = {
'wechat-pay': ['index.js', 'index.json', 'index.wxml', 'index.wxss'],
};
const expectedMobileHostBridgeFiles = [
'appearance.test.ts',
'appearance.ts',
'badge.ts',
'bridge.test.ts',