Repository navigation
Commit b83baed
test(ui/scripts): take the vi-mock-inherit test's whole-repo readings once, at collection (#27804)
domain:ui#2 · os-bill · session_01Utp6CY2n1JmZZKrHgtp9jC
<!-- claude-projects-attribution: {"github_login":"os-bill"} -->
_Requested by **Bill** · [project
thread](https://claude.ai/code/project/chan_016iMXWSZDzqWRWvWzdNo8wg?thread=cmsg_016iMXWSZDzqWRWvWzdNo8wgP6XkfpjCfyzzG2KwQPUZfy)_
Fixes #27449
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:`check-vi-mock-inherit.test.ts` 里读真实仓库的三个读数(全量 `scan`、门禁 CLI
一次运行、`@object-ui/i18n` 的 `scan`)每个文件只取一次,在 describe
体(收集阶段)里取,三个慢用例不再在自己的 15 秒预算里重扫整个仓库。
- 为什么改:这三个用例空闲各 5.4–6.0 秒、四核满载下 6.9–7.7 秒,再翻一倍负载就会贴近 15 秒超时,和 #27423
是同一形态。按裁决不调超时、不跳过、不重试、不改断言。
-
风险与回滚:只动一个测试文件,断言逐条不变;读数被冻结,用例之间无法互相污染;读数若抛错,错误被保存并只让读它的那个用例失败,不会在收集阶段弄死整个文件。回滚即
revert 本 PR。
- 先看:`ui/scripts/__tests__/check-vi-mock-inherit.test.ts` 顶部新增的
`realTree` 备忘块(含 `once` / `warm`),以及 `repo state` 和 `the sweep` 两个
describe 体里的取值行。
- 两分钟验证:`pnpm --dir ui exec vitest run
scripts/__tests__/check-vi-mock-inherit.test.ts`,预期 83 passed,三个原慢用例各在约
1 毫秒内完成。
- 需要你做的:无,席位落地。
## What changes
`ui/scripts/__tests__/check-vi-mock-inherit.test.ts` only.
`scripts/check-vi-mock-inherit.mjs` is untouched: no seam was needed.
- A module-level `realTree` memo takes each whole-repository reading
once per file: `gate` = `scan(repoRoot)`, `cli` = one run of `node
scripts/check-vi-mock-inherit.mjs` over the tree, and `i18n` =
`scan(repoRoot, { covered: [I18N], floors: {} })`. Values are frozen
(arrays and plain objects, recursively) with the same `frozen()` helper
#27437 introduced, so a case that sorted or spliced one in place would
throw instead of leaking into the next case.
- `repo state — the gate is green on this tree` takes `realTree.gate()`
(it already scanned in its body; now through the memo) and warms
`realTree.cli` in its body. The case `puts the census in the verdict, so
a reader sees the population` reads the held CLI output instead of
spawning the CLI itself.
- `the sweep — every @object-ui/i18n factory inherits…` warms
`realTree.i18n` in its body. `no @object-ui/i18n factory freezes the
surface` and `walked a real population…` read the one held scan instead
of each running its own.
- One addition over #27437's shape: `once()` also holds a reading that
THREW and rethrows it to each case that reads it, and `warm()` takes the
reading at collection without letting the throw escape. Without it, a
red CLI (non-zero exit) would throw during collection and fail the whole
file with 0 cases run; before this PR it failed only the census case.
Measured below: the failure stays in that one case.
## Why
The ruling on the card: take each reading once per file, at collection,
through a frozen memo, so no case walks the repo; never raise a timeout,
skip, retry or change an assertion. Every `expect` line is
byte-identical; only where the value comes from moved.
Collection is the right home. `ui/AGENTS.md` (测试纪律) puts warm-up cost
where no test or hook timeout bounds it and rules out a `beforeAll`,
whose 10 s `hookTimeout` is narrower than the 15 s `testTimeout`.
## Tests
Measured on this container (4 cores, a shared box). "Load" means four
`node -e 'for(;;){}'` CPU burners beside the run, the method #27437
used. Every run went through `scripts/pm/os-verify-lock.sh`. Per-case
durations come from vitest's JSON reporter; the file figure is its
`Duration` line.
| leg | `puts the census in the verdict…` | `no @object-ui/i18n factory
freezes…` | `walked a real population…` | file `Duration` (import /
tests) | result |
|---|---|---|---|---|---|
| before, idle | 5950 ms | 5627 ms | 5415 ms | 25.67 s (6.17 / 19.07) |
83/83 |
| before, load | 7748 ms | 6897 ms | 7373 ms | 33.12 s (7.56 / 25.08) |
83/83 |
| after, idle | 0.8 ms | 0.2 ms | 0.2 ms | 20.43 s (17.80 / 2.25) |
83/83 |
| after, load | 1.0 ms | 0.2 ms | 0.1 ms | 27.61 s (23.82 / 3.27) |
83/83 |
After the change the slowest cases in the file are the three `THE DEATH`
legs (each spawns a child vitest over a temp root, not the repository):
about 0.6 s idle and up to 1.0 s loaded. The collection phase grows by
the readings it now takes, about 11.6 s idle and 16.3 s loaded; no
timeout bounds that phase. The tests phase drops from 19.07 s to 2.25 s
idle and from 25.08 s to 3.27 s loaded, and the file's total wall drops
by about 5 s either way. The "after" rows were measured at the final
head `2d8468bb` (after the merge of `main`).
Failure-locality probe (one run, then restored): the `cli` reading was
pointed at a non-existent script, so the CLI exits non-zero. Result:
`Tests 1 failed | 82 passed (83)`, the one failure being `puts the
census in the verdict…` with `Error: Command failed: node
scripts/no-such-gate.mjs`. The file was restored with `git checkout HEAD
--` under a trap; proof: `git hash-object` equals `git rev-parse
HEAD:<file>`, and `git diff HEAD` is empty.
## Acceptance notes
- `ui/` is a private workspace root (`"private": true`) and this is a
test file, so nothing publishes: the PR carries `skip-changeset`.
- The card's "Done when" readings that need CI runs after merge are the
seat's to read.
- No assignee and no reviewer were set on this PR: the project's routing
rule asks nobody before the seat's ACCEPT and review.
## Verification
Gates derived by `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` at `2d8468bb`, plus `node
scripts/check-sdui-manifest.mjs` and `pnpm --dir ui run
type-check:scripts`. Each command's exit code and the `--ran`
reconciliation are in the os-dev report on #27449.
<details><summary>Local gate exit codes</summary>
```
node scripts/check-closing-keyword-parity.mjs :: exit 0
node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0
node scripts/check-comment-mask-corpus.mjs :: exit 0
pnpm check:cross-package-test-inputs :: exit 0
pnpm check:driver-memory-census :: exit 0
pnpm check:engine-double-contract :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:published-files :: exit 0
pnpm check:query-options-erasure :: exit 0
pnpm check:refd-timer-probe :: exit 0
pnpm check:tier-file-adoption :: exit 0
pnpm check:type-check-coverage :: exit 0
pnpm check:type-check-debt :: exit 0
pnpm check:undeclared-dep-imports :: exit 0
pnpm check:watch-hint-literal :: exit 0
pnpm check:where-matcher :: exit 0
node scripts/check-sdui-manifest.mjs :: exit 0
pnpm --dir ui run type-check:scripts :: exit 0
pnpm --dir ui exec vitest run scripts/ :: exit 0
(the first `vitest run scripts/` run exited 1 before `@objectstack/spec` was built: 16 files failed on `Cannot find package '@objectstack/spec/...'`, none of them this file; after `pnpm --filter @objectstack/spec build` it ran 169 files passed, 2 skipped, 4902 tests passed)
dispatch-gates --ran: 18 derived families accounted for, 18 run, 0 NOT-MEASURED
```
</details>
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(not touched)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes. (CI owns the lint run)
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset. This one publishes
nothing: it is a test file under the private `ui/` root, so the PR
carries `skip-changeset`.
- [x] 6. `packages/spec` touched: n/a.
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English. (The 维护者速读 block is
the repo's Chinese summary convention.)
---
_Generated by [Claude
Code](https://claude.ai/code/session_01Utp6CXUtMecKADTTusrK3z)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 63fc947 commit b83baed
1 file changed
Lines changed: 69 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
53 | 53 | | |
54 | 54 | | |
55 | 55 | | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
56 | 117 | | |
57 | 118 | | |
58 | 119 | | |
| |||
985 | 1046 | | |
986 | 1047 | | |
987 | 1048 | | |
988 | | - | |
| 1049 | + | |
| 1050 | + | |
| 1051 | + | |
989 | 1052 | | |
990 | 1053 | | |
991 | 1054 | | |
| |||
1076 | 1139 | | |
1077 | 1140 | | |
1078 | 1141 | | |
1079 | | - | |
| 1142 | + | |
1080 | 1143 | | |
1081 | 1144 | | |
1082 | 1145 | | |
| |||
1215 | 1278 | | |
1216 | 1279 | | |
1217 | 1280 | | |
1218 | | - | |
| 1281 | + | |
| 1282 | + | |
1219 | 1283 | | |
1220 | 1284 | | |
1221 | | - | |
| 1285 | + | |
1222 | 1286 | | |
1223 | 1287 | | |
1224 | 1288 | | |
| |||
1229 | 1293 | | |
1230 | 1294 | | |
1231 | 1295 | | |
1232 | | - | |
| 1296 | + | |
1233 | 1297 | | |
1234 | 1298 | | |
1235 | 1299 | | |
| |||
0 commit comments