Commit Graph

2 Commits

Author SHA1 Message Date
4af083e8b8 test(判据): 4 个判据读的是**另一棵树** —— 修掉硬编码的仓库根,并让 stripComments 保持行号
pi 2026-09-15 实测出来的,**这次长在判据自己身上** —— 正是我们前几轮一直在消的那个形状。

## 一、`const ROOT = '/home/program/agentmail'`:规则进来了,对象没进来

`harmony-arkts.test.mjs` 把仓库根写成了绝对路径。后果我按 pi 的步骤亲手复现了:

```
$ git worktree add --detach /tmp/wt-verify 7f4fa26      # 那个检出里 import 顺序**确实**违规
  (核对:最后 import 在第 80 行,而第 63 行已是 `const NAV_MATERIAL_OF…`)
$ cd /tmp/wt-verify/client/electron && node --test test/harmony-arkts.test.mjs
ok 1 / ok 2 / ok 3   # pass 3  # fail 0      ← **在一个明显违规的检出上 3/3 全绿**
```

因为它读的不是 `/tmp/wt-verify`,是 `/home/program/agentmail`(那份早已修好)。
两层后果,第二层最糟:
① 它**永远无法验证任何别的 checkout / CI / 镜像** —— 换目录不是"红",是 `readdirSync` 直接抛;
② 在本机做 worktree 复核时,它**静默读另一棵树并报绿**。
**判据的逻辑是对的、对象是错的** —— 这比"判据写错了"更难发现,因为它在原地永远是绿的。

同一个毛病在 4 个文件里,**恰好全是最近这几笔新写的**(另 10 个鸿蒙判据写法是对的):

```
harmony-admin / harmony-imageprep / harmony-presets / harmony-arkts  →  const ROOT = '/home/program/agentmail';
其余 10 个                                                          →  const ROOT = join(HERE, '..', '..', '..');
```

已全部照邻居改掉。**修好之后在同一个违规检出上:`# fail 1`** —— 它终于会红了。

## 二、修这条时又牵出一个:`stripComments` **改变了行号**

修好路径后,判据报出"最后一个 import 在第 64 行、第 47 行已是语句",
而**真实文件里是第 80 / 63 行**。成因:`stripComments` 把块注释整块抹成 `''`,
而块注释**自带换行** ⇒ 它之后所有行号整体前移。

这不是小节:全仓判据都用 `文件:行号` 定位(`grep -n`、编辑器跳转、`git show` 核对),
**报出来的行号必须能直接用**,否则读者第一步得先猜"这是剥过的还是没剥的"。
改成"块注释里的每个换行换成等量空行"。修完报的就是 **80 / 63**,与文件逐字对上。

## 三、新增两条判据,让这两个形状不能再回来

1. **`★ 判据不许把仓库根硬编码成绝对路径`** —— 扫判据目录里**真代码**
   (`code()` 剥注释,否则本文件自己的说明文字就会误报),找
   `const X = '/绝对路径'` 且**看着像仓库内**的声明。
   **例外按名字放行**(含 `TOOLCHAIN`/`SDK`/`HDC` 的常量)—— 工具链本来就不在仓库里、推不出来;
   按**值**做白名单会逼着下一个人为了过判据去改那个路径的写法。
2. **`★ stripComments 必须保持行号`** —— 造含多行块注释的样本,断言剥完
   **行数不变**、且第 N 行仍是原来的第 N 行;**同时**断言注释内容确实被去掉了
   (别为了保行号把注释留下)。

两条都做了**变异验证**:
- 把 `harmony-admin` 的 ROOT 改回硬编码 ⇒ 新判据**红**,并点名那个文件;还原后绿。
- 在 `MainPage.ets` **import 之前**插一条语句 ⇒ `harmony-arkts` **红**
  (第 79 行 vs 第 1 行);还原后绿。**这条同时证明了"读的是自己那棵树"** ——
  同样这个变异,在修路径**之前**是绿的。

## 四、未做 / 未验

- 到期闸门那 7 条**没动**(要真装真点,是另一件活)。
- **"把 build 做成一条判据"我探了,两个硬障碍**(详见给 pi 的回信):
  ① `client/harmony/oh_modules` 被 `.gitignore` 排除且未入库 ⇒ **全新检出没有它**,
     构建会先死在装依赖上;② 本沙箱**拒写 `/root/.hvigor`**(`mkdir` Permission denied),
     `hvigorw` 在 worktree 里直接 `EACCES: mkdir '/root/.hvigor/project_caches/…'`。
  所以它在本仓能编过、在干净检出编不过 —— 作为判据它现在会**假红**。
2026-09-15 12:06:15 +08:00
7f4fa2629e 跨端: ArkTS 编译期硬规则进判据 —— 我插的常量表把 import 挤到了后面,assembleHap 报 arkts-no-misplaced-imports
`hvigorw assembleHap` 在 `f31bc02`/`b806a05` 上都红了一条:

    ERROR: ArkTS:ERROR …/MainPage.ets
    "import" statements after other statements are not allowed  (arkts-no-misplaced-imports)

**是我造成的**:P4c 那笔我在 `MainPage.ets` 里插了 `NAV_MATERIAL_OF` 那张(带注释的)
常量表,位置在**既有 import 之前**。ArkTS 要求所有 import 在任何语句之前,
常量表算语句 —— 编译器直接报错。

## 为什么我那一笔的判据一条都没抓到它

因为**这个仓库里没有任何判据会跑 ArkTS 的编译规则**。我的判据判的是"表达式对不对、
接没接上、颜色写没写死…",它们全绿 —— **文本层面确实没问题**,问题只有编译器知道。
pi 是构建时撞上的。

⇒ 教训不是"下次小心",是**把编译器能抓、而判据不抓的那一类固化下来**。
这一类里有一批**纯文本就能判、不需要设备**,所以它们不该待在"等设备才能验"的欠账里。

## 做了什么

- 新增 `test/harmony-arkts.test.mjs`(3 条,不需要设备 ⇒ **不进** STATIC_ONLY):
  · **所有 26 个 `.ets` 的 import 必须在任何其它语句之前**(就是这次报的那条);
  · 全仓 `.ets` 的词汇层硬坑(对象解构 / `any` / `unknown` / 函数表达式)
    —— 这几条此前**只在"我自己新写的那个页面"里判**,而我恰恰是在**改既有文件**时犯的下一个错,
    编译期硬规则不该按"谁写的"分覆盖;
  · **一条自检**:造已知坏样本(常量插在两组 import 之间)确认检查会红、合法样本不误报
    —— 否则"全绿"可能只是扫描逻辑失效(我第一版就把多行 import 的成员行误判成了语句)。
- 接进 `SUITE`(判据文件数 22 → 23)。
- 文件头明确写了它**不能**替代 `hvigorw`:覆盖的只是"能静态判出来的那几类",
  类型推断/重载解析/Sendable 那些仍然只有 build 能验 ——
  不许把这个文件的存在读成"编译已经验过了"。
- 变异测试 5 条**全部被抓**,含**精确复现我那个错的形状**(把 import 搬到常量表之后)。
  基线 `7/7✓`(逐字节还原)。
- 现口径:`mutants=52 ran=52 skipped=0 on_new_criteria=36 baseline=7/7✓`。

## 工作树里**不是我做的**两处改动(已核实为正确,我没有提交也没有回退)

工作树是共享的:`AdminUsersPage.ets` 与 `MainPage.ets` 在我提交**之后**被别的进程改过,
两处都是**修构建错误**,都核实过是对的:

1. `MainPage.ets`:把两组 import(`CalendarPage`、`NavItems`)从 `NAV_MATERIAL_OF` 表**之后**
   挪到文件最前 —— 就是上面那条 `arkts-no-misplaced-imports`;
2. `AdminUsersPage.ets`:`Chip(text, bg, fg: string)` → `ResourceColor`
   (`Theme.surfaceMuted`/`textSubtle` 是 `Resource`、`chipNeutralBg` 是 `string`,
   第 368 行那个三目因此是 `Resource | string` ⇒ 旧签名编译不过)。

我不提交别人的活、更不回退它;但它们**让基线必须重算**,而**重算基线是有意动作**
(随手重算会把"某次变异没还原"永久掩盖掉),所以 `baseline.sha` 顶部记了原因与哈希来源。

## 未验

- 这三条判据**只覆盖静态可判的那几类**。`assembleHap` 仍然只有真正构建才能验 ——
  这次就是构建先于我所有判据发现的问题,下次还可能是。
- Go 侧 `debt_registry_test.go` 仍未跑(沙箱无 Go 模块缓存),只有 `gofmt`。
2026-09-15 11:27:35 +08:00