chore(ui-golden): 像素黄金参考 ref/*.bin 入库(把门禁改成可移植)

问题:ui-golden 是逐字节比对(check_content_pages.py 里 data == refdata),
而基准 simulator/tests/ref/ 整目录被 .gitignore 忽略、从未入库。后果不是
"少几个文件",而是这条门禁在任何新克隆 / 新并行工作树里必然报「缺黄金
参考」——只在有老副本的机器上它才是真的回归门禁。本会话已两次实测踩到
(并行工作树里只能现场 --update 造基准,而现场造出来的基准恰好失去意义)。

入库前先证明基线可复现,否则等于把一条天天误报的门禁写进仓库:
- 主树 ref/ 生成于 2026-10-11,其间合入 B6~B9 与 UI 令牌化等多次改动;
  今天用刚重建的 lvgl_sim 重跑 → 11 页 + 开页-关页往返池水位逐字节全过
- 主树与新工作树两份**独立构建**的 lvgl_sim(不同构建目录、不同绝对路径)
  各自生成基准 → 11 个 .bin 的 SHA-256 全部一致
即渲染是 CPU 侧确定性输出,可以当仓库内容。

改动:
- .gitignore:整目录忽略 → 只忽略派生的目检 PNG。另加一条
  !simulator/tests/ref/*.bin 反选——第 115 行的全仓 *.bin 兜底(挡
  sim_netcfg.bin 之类运行产物)会把基线一起挡掉,且反选必须排在它之后
  才生效
- 不引入 LFS:11 x 3200 B = 34.4 KB(160x160 单色打包)。走 LFS 反而新增
  失效面——没拉 LFS 的克隆会拿 pointer 文本去比像素,把"缺基准"换成
  "比不中"。.gitattributes 已有 *.bin binary,check-attr 确认 text unset,
  不会被行尾转换改写
- 基线不会被改写型钩子毁掉:trailing-whitespace / end-of-file-fixer 声明
  types: [text],位图含 NUL 被判二进制 → 实测 Skipped;索引 blob、磁盘、
  主树参照三方哈希 11/11 一致
- 新增 11 个基线;同步 5 份文档与 3 处脚本口径:缺基准的提示从"首次/换机
  请加 --update"改为"检出不完整 → git checkout -- simulator/tests/ref/ 取回,
  不要用 --update 就地造基准"(旧提示正是自我实现型基准的来源)
- 顺带修掉 simulator/tests/README.md 两处与实现不符的描述:基准写成 PNG
  (实为 .bin)、regen_ref_png.py 写成"重建黄金参考"(它只出目检图,基准
  由 check_content_pages.py --update 刷)
- .pre-commit-config.yaml 只改注释(原文明确断言 ref/ "永远不会进 git
  索引",已被本改动推翻);ui-golden 的 files 面覆盖 simulator/tests/,
  基线被改即触发回归,刷参考从此在 git diff 里显形

历史口径按纪律冻结:UI_自动化测试流程 2026-09-10 的"整目录不入库"等 6 处
变更记录行不改写,以新行登记反转。

实测:@build 0 错 0 警(Code=213520,与内存台账一致);ui-golden Passed;
pre-commit run --all-files = 36 Passed / 0 Failed(RC=0)。
This commit is contained in:
2026-10-22 06:17:00 +08:00
parent ebe2807ffd
commit a38f862fb9
21 changed files with 52 additions and 23 deletions
+11 -3
View File
@@ -8,8 +8,15 @@ default_install_hook_types: [pre-commit, commit-msg]
# tests/*.py、两份配置与 README)。整目录豁免 = 自研代码落在所有钩子之外(连
# lv-conf-sync 都拦不到);实测把 simulator/ 纳入 cppcheck 后,立刻揪出
# sim_syslog.c 一处真实的空指针解引用。真正的生成物/第三方(`simulator/build/`、
# `simulator/SDL2/`、`simulator/tests/ref/`、`simulator/shot*.{bin,png}`、`__pycache__/`)
# **已在 .gitignore 里**,永远不会进 git 索引 → 无需在此重复豁免,故直接删掉该条。
# `simulator/SDL2/`、`simulator/shot*.{bin,png}`、`__pycache__/`)**已在 .gitignore 里**,
# 不会进 git 索引 → 无需在此重复豁免,故直接删掉该条。
# ⚠ 例外(2026-10-22):`simulator/tests/ref/*.bin`(ui-golden 的像素黄金参考)已从
# 「整目录 gitignore」改为**入库**——基线不入库时任何新克隆 / 新工作树都必然报
# 「缺黄金参考」,这条门禁就只在有老副本的机器上真实存在。入库前提是实测可复现:
# 两份各自独立构建的 lvgl_sim(不同构建目录、相隔 11 天的代码)对同一批 11 个 .bin
# SHA-256 全部一致。改写型钩子(trailing-whitespace / end-of-file-fixer)声明
# `types: [text]`,位图含 NUL → 被判二进制自动 Skipped(实测「索引 blob == 磁盘 ==
# 参照」三方一致),无需为它另加 exclude。
exclude: |
(?x)^(
\.opencode/node_modules/|
@@ -509,7 +516,8 @@ repos:
# golden FAIL 且点名 `[dc] FAIL 与参考页不一致(1366 px 差异)`、退出码 1;还原后 diff 干净。
# ⚠ 两条 golden 按"整棵菜单树 + 全量参考图"工作、不接受文件参数,故包装器有意忽略
# argv 并 pass_filenames: false(pre-commit 传的变更名对它无意义)。
# ⚠ 参考图 simulator/tests/ref/*.bin 是判据本身,改动它等于改判据——评审时必须盯紧,
# ⚠ 参考图 simulator/tests/ref/*.bin 是判据本身,改动它等于改判据——它已入库,
# 评审时看 `git diff -- simulator/tests/ref` 必须逐页过目并在提交正文说明;
# 任何时候都不得用 --update 刷基线来"让钩子变绿"。
# ⚠ pre-commit 4.x 无 `always: true` → files 必须覆盖所有能改变像素的触发面。
# ⚠ 已知瞬时现象:首次实测时在"连续注入/还原的紧邻重建"之间偶发失败一次,