55 lines
2.0 KiB
JavaScript
55 lines
2.0 KiB
JavaScript
import assert from 'node:assert/strict'
|
||||
|
|
import { spawnSync } from 'node:child_process'
|
|||
|
|
import { dirname, resolve } from 'node:path'
|
|||
|
|
import { fileURLToPath } from 'node:url'
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 小程序界面语种契约守卫
|
|||
|
|
* ============================
|
|||
|
|
* 复用 scripts/audit-miniapp-language.mjs 的全量扫描(A 文本节点 / B 属性 /
|
|||
|
|
* C picker 选项 / D JS 文案字段 / E 繁体字 / F 窗口标题),断言「0 命中」。
|
|||
|
|
*
|
|||
|
|
* 为什么必须独立成守卫:2026-09 真机事故——后端枚举码(never_married / bachelor /
|
|||
|
|
* any / accept / reject)直接当展示值上屏,静态类型检查 / WXML·WXSS 编译 / 结构
|
|||
|
|
* 守卫全都抓不到,只有人眼在真机才看得见。这是「界面必须全中文简体」唯一的自动化兜底。
|
|||
|
|
*
|
|||
|
|
* 单一事实源:本守卫不重复实现扫描逻辑,而是直接派生 audit 脚本——改扫描规则只改一处。
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
const root = resolve(dirname(fileURLToPath(import.meta.url)), '..')
|
|||
|
|
const auditScript = resolve(root, 'scripts/audit-miniapp-language.mjs')
|
|||
|
|
|
|||
|
|
const r = spawnSync(process.execPath, [auditScript, '--json'], {
|
|||
|
|
cwd: root,
|
|||
|
|
encoding: 'utf8',
|
|||
|
|
env: { ...process.env, NO_COLOR: '1' },
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
let findings = []
|
|||
|
|
if (r.status === 3) {
|
|||
|
|
// 审计脚本自身崩溃(异常分支),绝不能当成「通过」默默绿掉
|
|||
|
|
throw new Error(
|
|||
|
|
'语种审计脚本执行失败(exit 3),请先修复 scripts/audit-miniapp-language.mjs:\n' +
|
|||
|
|
(r.stderr || r.stdout || '(无输出)'),
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
if (r.stdout && r.stdout.trim()) {
|
|||
|
|
try {
|
|||
|
|
findings = JSON.parse(r.stdout)
|
|||
|
|
} catch {
|
|||
|
|
// 理论上 --json 只输出 JSON;解析失败则交给下面的长度断言兜底
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
assert.equal(
|
|||
|
|
findings.length,
|
|||
|
|
0,
|
|||
|
|
`小程序仍存在英文/非中文简体上屏(${findings.length} 处)。示例:\n` +
|
|||
|
|
findings
|
|||
|
|
.slice(0, 8)
|
|||
|
|
.map((f) => ` ${f.file}:${f.line} [${f.kind}] ${f.detail}`)
|
|||
|
|
.join('\n'),
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
console.log(`Miniapp language contracts passed(语种审计 0 命中)`)
|