fix(test): runner 的包级 test 入口指回仓根配置,不再落到 app 的 vite.config (#3746) - #3869
Merged
Conversation
`pnpm --filter @object-ui/runner test` 在干净 main 上 4 红(`window is not defined`),而同一批 13 个用例从仓根跑全绿。机制:`packages/runner` 声明了 `"test": "vitest run"` 却没有 vitest 配置,pnpm 把 cwd 定在包目录,vitest 于是 把该目录里那份 **Vite 应用**配置 `vite.config.ts` 当成自己的配置读进来 —— 它只有 `resolve.alias` / `build`,没有 `test` 块,于是没有 DOM 环境、没有 setup(那次运行自己的汇总就写着 `setup 0ms ... environment 0ms`), `App.navigation.test.tsx` 的 4 个用例在 node 环境里撞死在 `window` 上。 修法是把这个入口指回**仓根配置**,而不是给 runner 补一份包级配置: - 包级配置会是第 18 份「#3240 裁决 A(2026-08-06,全删)」要删的东西,且它解析 `@object-ui/*` 走 runner 自己那张 15 条的 alias 表(其余落 dist),而仓根配置把 ~40 个包名指向 `src` —— 正是 #3240 要消灭的「同一文件两套结论」; - 它还会把这次运行从 `scripts/vitest-invocation-guard.mjs` 底下抬出去(guard 只在 仓根配置里被调用),#3288 的 `--` 转发陷阱对本包就不再被拒绝。 所以脚本改成 AGENTS.md(§怎么跑测试)与 guard 报错正文都指定的那条写法: `vitest run --root ../.. packages/runner/`。两个入口从此是同一份配置,用例数一致 (3 文件 / 13 用例),`vitest list` 显示 runner 的 3 个文件各自只在一个 project 注册([unit] x2、[dom] x1),仓根 projects 机制不受影响。 钉子 `scripts/__tests__/runner-package-test-entry-3746.test.ts`:钉住该脚本把 vitest root 指回仓根、被 guard 接受、过滤面正好覆盖 runner 自己的全部测试文件; 另有一条全仓棘轮,记录另外 7 个同形状(有 vite.config、无 vitest 配置、bare `vitest run`)的包为**上限**,只许缩不许长 —— 它们的整改属于 #3240 的单独批次, 本单不碰。 Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt Co-authored-by: Claude <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
Collaborator
Author
|
✅ 验收(PM,session 实物核验:头 为什么 C 对、缺省 A 错(裁定理由,已在 origin/main 独立取证):
其余要点:前提原样复现(4 红 + 转 ready 并挂 auto-merge。 Generated by Claude Code |
yinlianghui
marked this pull request as ready for review
August 8, 2026 22:48
os-sales
pushed a commit
that referenced
this pull request
Sep 3, 2026
…erdict (#3240) Direction A, ruled by the maintainer 2026-08-06 and reaffirmed by the delegated ruling of 2026-08-10: the root `vitest.config.mts` becomes the single entry, and a per-package run reaches it by path filter. What was there: 19 non-root vitest configs (the card's 17 under `packages/`, plus `apps/console` and `examples/schema-catalog`). Eleven of the seventeen were byte-identical standalone `defineConfig`s — `happy-dom` + `globals` + a one-line local setup and NO alias table, where the root config maps ~40 `@object-ui/*` specifiers at a sibling's `src/`. The other six re-exported or merged the root config, so they only ever restated it. What replaces them, per package: nothing. The root config already supplies every property they declared — `globals`, `happy-dom`, and jest-dom via `vitest.setup.dom-light.tsx` — plus the alias table they lacked. The one setup file that was not the shared one-liner, `plugin-map`'s, mocked `maplibre-gl`; `vitest.setup.base.ts` has mocked it globally all along, so that copy was a duplicate no canonical invocation ever loaded. Redefining the per-package run (the ruling's second clause): every `test` script is now `vitest run --root ../.. <pkgdir>/`, the shape PR #3869 landed for `packages/runner`. `pnpm --filter <pkg> test` and `turbo run test` were REFUSED by the invocation guard before this; they now run, against the same config CI uses, over exactly that package's files. Closing route 4 first, which the ruling did not anticipate: Vitest's config fallback does not stop at `vitest.config.*`. With none present it takes the directory's `vite.config.*`, and every `packages/*` has one — carrying a vestigial `test` block (`passWithNoTests: true`, a partial alias table, a setup the root config never loads). Deleting the 14 vitest configs whose packages also have a vite config would have moved them onto that route, widening the hole #5406 closed in the name of closing it. So each `packages/<pkg>/vite.config.ts` now calls the guard — gated on `process.env.VITEST`, which Vitest sets when it loads a config and `vite build` does not (measured both ways) — and the vestigial `test` blocks are deleted. turbo's `test` keeps `dependsOn: ["^build"]`, for a re-derived reason. The reason of record was resolution through `dist`, and that is now obsolete. But `^build` is the only edge putting a dependency's sources into a dependent's `test` cache key, and `helpers/vitest-config-program.ts` narrows its sweep by delegating to exactly that. Dropping it would replay stale greens; the note now says so. Evidence: `vitest list --filesOnly` from the repo root is byte-identical before and after — 2434 (project, file) pairs, empty diff. `vitest.config.mts` and all four root setup files are unchanged, so no file's project, environment or setup moved. #7291's `dist` project (`pnpm test:dist`: 1 file / 3 tests) and #7309's `isolate: false` invariant both still hold. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019aCUUSwWefnbCJ4Xk1vqQW
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3746
现象与机制(在干净 worktree 的
origin/main@6402e253f上原样复现)packages/runner声明了"test": "vitest run"却没有 vitest 配置。pnpm 把 cwd 定在包目录,vitest 于是把该目录里那份 Vite 应用配置
vite.config.ts当成自己的配置读进来 —— 它只有resolve.alias/build,没有test块,所以没有 DOM 环境也没有 setup(上面那次运行自己的汇总就写着
setup 0ms ... environment 0ms),App.navigation.test.tsx的 4 个用例在 node环境里撞死在
window上。仓根入口带 projects/happy-dom/setup,所以 CI 一直是绿的。修法:把这个入口指回仓根配置,而不是给 runner 补一份包级配置
派单缺省形状是「给 runner 补 vitest 配置」。落地时发现那条路与仓内两处既有事实冲突,故改成
本 PR 这一行 —— 两点都有 file:line 证据:
(2026-08-06,评论 5200265431),并在同单重定义包级
test脚本的语义为「对仓根配置传路径过滤」。再新增第 18 份是往一个已有拆除方案的债上加码;而且包级配置解析
@object-ui/*走 runner 自己那张 15 条的 alias 表(其余落dist),仓根配置则把 ~40 个包名指向
src—— 正是 17 个包各自带 vitest.config.ts 与根 vitest.config.mts 行为分叉:先回答「哪些包真的需要本地配置」 #3240 要消灭的「同一文件两套结论」。scripts/vitest-invocation-guard.mjs底下抬出去。 guard 只在vitest.config.mts顶部被调用(vitest.config.mts:5、:23),包级独立配置根本不加载它,于是
pnpm --filter <pkg> test -- --run <paths>静默忽略路径过滤:新加的测试文件根本没跑,而输出看起来正常 #3288 的--转发陷阱对本包不再被拒绝。仓内已有这种独立配置的包(如packages/plugin-charts/vitest.config.ts)就处于这个状态。所以
packages/runner/package.json的脚本改成 AGENTS.md(§怎么跑测试,第 184 行)与 guard报错正文都明确指定的那条写法:
两个入口从此是同一份配置,不存在漂移面;
--root指回仓根后 guard 依旧在链路上(root 等于仓根 → 放行,
--转发 → 照样拒绝)。两个入口都绿、用例数一致
仓根 projects 机制不受影响 —— 以注册面为证,runner 的 3 个文件各自只在一个 project 注册,
既不重复也不缺:
⛔ 未改动仓根
vitest.config.mts(本 PR 只有 2 个文件)。防回归钉子
scripts/__tests__/runner-package-test-entry-3746.test.ts(独立文件,与在飞单零共享),7 条断言分两组:
vite.config.ts且其中没有test块、没有 vitest配置」的可劫持形状;脚本把 vitest root 指回仓根;该调用被 guard 判为放行;位置过滤解析得到
的目录确实在
packages/runner内,且覆盖 runner 全部测试文件(防「悄悄只跑一部分」)。runner 已不在其中;其余命中以上限方式记录(见下),断言是子集而非相等 —— 17 个包各自带 vitest.config.ts 与根 vitest.config.mts 行为分叉:先回答「哪些包真的需要本地配置」 #3240 把
它们修好时这条依然绿。
顺带测到、⛔ 本 PR 不修的面
issue 正文说 runner 的特殊之处是「只有它目录里有一个
vite.config.ts可被 vitest 误取」。实测不止它一个:同形状(有
vite.config.ts、无 vitest 配置、barevitest run)共 8 个包,除 runner 外还有
plugin-ai、plugin-chatbot、plugin-designer、plugin-editor、plugin-markdown、plugin-report、plugin-tree。是否同红取决于各自的测试是否碰 DOM(runner 碰了),本 PR 不声称、也不顺手改 —— 它们的整改属于 #3240 的单独批次,已把这份实测清单
评论到 #3240 上,并作为棘轮的 baseline 记在钉子里。
反向验证(方向先判后跑,三条全部与预判一致)
把脚本还原成
"test": "vitest run":window is not definedTests 4 failed | 9 passed (13)+ReferenceError: window is not defined✅Tests 5 failed | 2 passed (7),含expected [ 'packages/runner' ] to deeply equal []✅Test Files 3 passed (3) / Tests 13 passed (13)✅门禁
pnpm exec turbo run type-check --concurrency=2(CI 同命令):78 successful, 78 total。pnpm type-check:scripts:干净 ——turbo run type-check结构上到不了scripts/,新钉子文件由这条覆盖。
pnpm exec eslint scripts/__tests__/runner-package-test-entry-3746.test.ts:exit 0。node scripts/check-control-bytes.mjs:OK(3762 个文件);改动文件grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f]'零命中。node scripts/check-changeset-presence.mjs→ 「No source of a released packagechanged in this range, so no changeset is owed.」未动任何发版包的
src/;仓内同类先例(
pnpm --filter @object-ui/app-shell test跑的是 @object-ui/console 的 22 个文件,app-shell 自己的 276 个一个没跑,却报绿 #3378/pnpm --filter <pkg> test -- --run <paths>静默忽略路径过滤:新加的测试文件根本没跑,而输出看起来正常 #3288 的 guard PR34a3badc9,4 个文件全是测试/配置面)也没带 changeset。与在飞单的关系
任何包级 vitest 配置,只把 runner 一条脚本改成 17 个包各自带 vitest.config.ts 与根 vitest.config.mts 行为分叉:先回答「哪些包真的需要本地配置」 #3240 已裁决的那种语义;17 个包各自带 vitest.config.ts 与根 vitest.config.mts 行为分叉:先回答「哪些包真的需要本地配置」 #3240 执行时对 runner
是幂等的。
scripts/__tests__/,本 PR 用的是带 3746 的独立文件名)。
Generated by Claude Code