XuqmGroup-RNSDK/packages/update/scripts/native-baseline.test.mjs
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

97 行
3.8 KiB
JavaScript

import assert from 'node:assert/strict'
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import path from 'node:path'
import test from 'node:test'
import { computeNativeBaseline } from './native-baseline.mjs'
function fixture() {
const root = mkdtempSync(path.join(tmpdir(), 'xuqm-native-baseline-'))
mkdirSync(path.join(root, 'android', 'app', 'src', 'main', 'java'), { recursive: true })
mkdirSync(path.join(root, 'ios'), { recursive: true })
mkdirSync(path.join(root, 'node_modules', 'runtime-library'), { recursive: true })
mkdirSync(path.join(root, 'src'), { recursive: true })
writeFileSync(
path.join(root, 'package.json'),
JSON.stringify({ dependencies: { 'runtime-library': '^1.0.0' } }),
)
writeFileSync(
path.join(root, 'node_modules', 'runtime-library', 'package.json'),
JSON.stringify({ name: 'runtime-library', version: '1.0.0' }),
)
writeFileSync(path.join(root, 'android', 'settings.gradle'), 'rootProject.name = "fixture"')
writeFileSync(path.join(root, 'ios', 'App.swift'), 'struct App {}')
writeFileSync(path.join(root, 'src', 'business.ts'), 'export const value = 1')
return root
}
test('native source changes the baseline while ordinary JS does not', () => {
const root = fixture()
try {
const initial = computeNativeBaseline(root)
writeFileSync(path.join(root, 'src', 'business.ts'), 'export const value = 2')
assert.equal(computeNativeBaseline(root), initial)
writeFileSync(path.join(root, 'android', 'app', 'src', 'main', 'java', 'Main.kt'), 'class Main')
assert.notEqual(computeNativeBaseline(root), initial)
} finally {
rmSync(root, { recursive: true, force: true })
}
})
test('runtime dependencies and packaged assets require a new full-app baseline', () => {
const root = fixture()
try {
const initial = computeNativeBaseline(root, 'android')
writeFileSync(path.join(root, 'src', 'logo.png'), 'first-image')
const withAsset = computeNativeBaseline(root, 'android')
assert.notEqual(withAsset, initial)
writeFileSync(
path.join(root, 'node_modules', 'runtime-library', 'package.json'),
JSON.stringify({ name: 'runtime-library', version: '1.1.0' }),
)
assert.notEqual(computeNativeBaseline(root, 'android'), withAsset)
} finally {
rmSync(root, { recursive: true, force: true })
}
})
test('native baselines are platform-specific', () => {
const root = fixture()
try {
const android = computeNativeBaseline(root, 'android')
const ios = computeNativeBaseline(root, 'ios')
assert.match(android, /^android-sha256:/)
assert.match(ios, /^ios-sha256:/)
assert.notEqual(android, ios)
writeFileSync(path.join(root, 'ios', 'App.swift'), 'struct App { let value = 1 }')
assert.equal(computeNativeBaseline(root, 'android'), android)
assert.notEqual(computeNativeBaseline(root, 'ios'), ios)
} finally {
rmSync(root, { recursive: true, force: true })
}
})
test('native source from a local file dependency changes the full-app baseline', () => {
const root = fixture()
try {
const dependencyRoot = path.join(root, 'local-update-sdk')
const nativeFile = path.join(dependencyRoot, 'android', 'src', 'main', 'java', 'Bridge.java')
mkdirSync(path.dirname(nativeFile), { recursive: true })
writeFileSync(nativeFile, 'final class Bridge {}')
writeFileSync(
path.join(root, 'package.json'),
JSON.stringify({
dependencies: { 'runtime-library': '^1.0.0', '@xuqm/local': 'file:./local-update-sdk' },
}),
)
const initial = computeNativeBaseline(root, 'android')
writeFileSync(nativeFile, 'final class Bridge { int apiLevel = 2; }')
assert.notEqual(computeNativeBaseline(root, 'android'), initial)
} finally {
rmSync(root, { recursive: true, force: true })
}
})