XuqmGroup-RNSDK/packages/update/tests/releaseSet.test.ts
XuqmGroup 507ce3d2ee feat(update): release-set 事务制品与原生层职责拆分
- 插件包改为 .xuqm.zip 事务制品,manifest/bundle/资源/SHA-256 统一校验
- 原生层拆分为桥接编排、插件包暂存、底层存储三个单一职责类
- 状态查询改为纯读取,不再误触发安装;新增 NATIVE_BASELINE_INCOMPATIBLE 拒绝
- SemVer 解析拆分为独立原生类并补原生测试
- XWebView 收口唯一内核,错误态统一中文层与重试
- common 增加请求头/运行时契约收口与 http 测试
2026-07-20 19:31:43 +08:00

192 行
4.9 KiB
TypeScript

import assert from 'node:assert/strict'
import test from 'node:test'
import {
ReleaseSetCompatibilityError,
planReleaseSet,
type InstalledPluginModule,
type PluginReleaseCandidate,
} from '../src/releaseSet'
const installed: InstalledPluginModule[] = [
{
moduleId: 'common',
type: 'common',
version: '1.0.0',
appVersionRange: '>=8.0.0 <9.0.0',
minNativeApiLevel: 1,
},
{
moduleId: 'app',
type: 'app',
version: '1.0.0',
appVersionRange: '>=8.0.0 <9.0.0',
commonVersionRange: '>=1.0.0 <2.0.0',
},
{
moduleId: 'buz2',
type: 'buz',
version: '1.0.0',
appVersionRange: '>=8.0.0 <9.0.0',
commonVersionRange: '>=1.0.0 <2.0.0',
},
]
function candidate(
module: Omit<PluginReleaseCandidate, 'downloadUrl' | 'sha256'>,
): PluginReleaseCandidate {
return {
appVersionRange: '>=8.0.0 <9.0.0',
...module,
downloadUrl: `https://updates.example/${module.moduleId}.bundle`,
sha256: 'a'.repeat(64),
}
}
test('orders common before app and buz in one cold-start release set', () => {
const plan = planReleaseSet({
installed,
appVersion: '8.0.0',
nativeApiLevel: 3,
candidates: [
candidate({
moduleId: 'buz1',
type: 'buz',
version: '1.0.2',
commonVersionRange: '>=1.0.1 <2.0.0',
}),
candidate({ moduleId: 'common', type: 'common', version: '1.0.2' }),
candidate({
moduleId: 'app',
type: 'app',
version: '1.0.1',
commonVersionRange: '>=1.0.1 <2.0.0',
}),
],
})
assert.deepEqual(
plan?.modules.map(module => module.moduleId),
['common', 'app', 'buz1'],
)
assert.equal(plan?.commonVersion, '1.0.2')
assert.equal(plan?.requiresColdStart, true)
})
test('keeps an older buz compatible when common advances in the same major range', () => {
const plan = planReleaseSet({
installed,
appVersion: '8.0.0',
nativeApiLevel: 1,
candidates: [candidate({ moduleId: 'common', type: 'common', version: '1.0.2' })],
})
assert.equal(plan?.modules.length, 1)
assert.equal(plan?.commonVersion, '1.0.2')
})
test('rejects a common upgrade that breaks an installed plugin', () => {
assert.throws(
() =>
planReleaseSet({
installed,
appVersion: '8.0.0',
nativeApiLevel: 1,
candidates: [candidate({ moduleId: 'common', type: 'common', version: '2.0.0' })],
}),
(error: unknown) =>
error instanceof ReleaseSetCompatibilityError &&
error.moduleId === 'app' &&
error.reason === 'COMMON_INCOMPATIBLE',
)
})
test('rejects candidates that require a newer native API', () => {
assert.throws(
() =>
planReleaseSet({
installed,
appVersion: '8.0.0',
nativeApiLevel: 1,
candidates: [
candidate({
moduleId: 'buz1',
type: 'buz',
version: '1.0.1',
commonVersionRange: '^1.0.0',
minNativeApiLevel: 2,
}),
],
}),
(error: unknown) =>
error instanceof ReleaseSetCompatibilityError && error.reason === 'NATIVE_API_INCOMPATIBLE',
)
})
test('rejects a plugin built against a different native baseline', () => {
const nativeBaselineId = 'android-sha256:current'
const installedForBaseline = installed.map(module => ({
...module,
builtAgainstNativeBaselineId: nativeBaselineId,
}))
assert.throws(
() =>
planReleaseSet({
installed: installedForBaseline,
appVersion: '8.0.0',
nativeApiLevel: 1,
nativeBaselineId,
candidates: [
candidate({
moduleId: 'common',
type: 'common',
version: '1.0.1',
builtAgainstNativeBaselineId: 'android-sha256:old',
}),
],
}),
(error: unknown) =>
error instanceof ReleaseSetCompatibilityError &&
error.reason === 'NATIVE_BASELINE_INCOMPATIBLE',
)
})
test('rejects a plugin outside the current full-app version range', () => {
assert.throws(
() =>
planReleaseSet({
installed,
appVersion: '8.0.0',
nativeApiLevel: 1,
candidates: [
candidate({
moduleId: 'buz1',
type: 'buz',
version: '1.0.1',
appVersionRange: '>=8.0.1 <9.0.0',
commonVersionRange: '^1.0.0',
}),
],
}),
(error: unknown) =>
error instanceof ReleaseSetCompatibilityError && error.reason === 'APP_INCOMPATIBLE',
)
})
test('ignores equal versions and downgrades', () => {
const plan = planReleaseSet({
installed,
appVersion: '8.0.0',
nativeApiLevel: 1,
candidates: [
candidate({ moduleId: 'common', type: 'common', version: '0.9.0' }),
candidate({
moduleId: 'buz2',
type: 'buz',
version: '1.0.0',
commonVersionRange: '^1.0.0',
}),
],
})
assert.equal(plan, null)
})