Repository navigation
test(tui): pin the runner locale and the update host so the suite is machine-independent - #137
Merged
Merged
Conversation
added 2 commits
September 30, 2026 22:08
The TUI resolves its language from the environment: sessionMutationLocale() falls back to Intl's resolved locale, which Node derives from LANG, and packages/tui/src/update/messages.ts reads LC_ALL/LC_MESSAGES/LANG directly. A developer shell running LANG=zh_CN.utf8 therefore renders Chinese copy while the suites assert the English strings they ship, and 29 capability tests fail on a host CI never exercises. Spawn the suite with LC_ALL and LANG set to en_US.UTF-8 so every group runs under one locale. Pinning the two variables together covers the Intl and the environment lookup paths, which stubbing each test would miss. Fixing it in the runner keeps the suites aligned with CI instead of teaching every translation-sensitive assertion about the developer's shell. Purely test infrastructure; no product behaviour changes.
McodeUpdateService.check() calls resolveMcodeReleaseTarget() with no override, so it reads process.platform and process.arch. release.ts publishes only darwin-arm64, darwin-x64, linux-x64, windows-x64 and windows-arm64, and a host outside that set — linux-arm64, for example — fails every check with "Unsupported MCode update host" regardless of what the test asserts. Pin both properties with Object.defineProperty in beforeEach and restore the captured host descriptors in afterEach, so the rest of the process is untouched. The fallback is linux-x64, a real REQUIRED_V1_TARGETS entry, so the tests keep exercising a shipped target instead of an invented one. Hosts that already publish keep their own platform and arch, which leaves the win32-only install test on Windows driving the real win32 branch of resolveMcodeInstallRoot and detectMcodeInstallSource. Purely test infrastructure; release.ts TARGETS is unchanged, so whether linux-arm64 should become a published target stays a product decision.
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.
问题
pnpm test:capabilities在本机红 37 条,历史工单多次记录,从未归因。诊断(94 号工单)
copy.ts:13的sessionMutationLocale()回落 Intl 默认 locale、messages.ts:86读LANG;本机LANG=zh_CN.utf8使 TUI 输出中文("2 个文件 · 5分钟前"),测试硬编码英文断言release.ts:39-45的TARGETS只有 darwin×2 / linux-x64 / windows×2;本机 linux-arm64 不在其中,release.ts:188抛Unsupported MCode update host: linux-arm640 条真缺陷。 且 CI 一直是绿的——CI runner 是 en locale + x64/darwin-arm64,两个触发条件都不满足。只有中文 locale 或 linux-arm64 开发机本地会红。
对照实验:
LC_ALL=en_US.UTF-8下那 4 个文件 449/449 全绿(单一变量坐实)。94a:locale 隔离
scripts/run-vitest-suite.mjsspawn 时注入LC_ALL与LANG=en_US.UTF-8。sessionMutationLocale()走Intl.DateTimeFormat().resolvedOptions().locale(Node 从 LANG 推导),而process.env.LANG是字面量读取、不受LC_ALL影响。只设LC_ALL会漏掉copy.ts:13、runtime/locale.ts:7、static-prompt-reader.ts:147、validation.ts:121四条路径。副作用核查
test:webapp/test:webui是node --test直连,根本不经过 runner,注入到不了(最强因果隔离)——但仍全跑test:release-tools(73/74)——source-sync.test.mjs:1002会 copyFileSync 本 runner 并断言参数,是唯一直接覆盖被改文件的回归packages/**/*.test.*对LANG/LC_ALL的引用:0 命中,无测试故意依赖非英文 locale残留面如实记录:
node-runtime.ts:850的透传白名单会把LANG/LC_ALL转发给 miniapp 子进程。94b:平台固定(偏离了原指定,理由如下)
Object.defineProperty固定process.platform/process.arch,afterEach用捕获的原始 descriptor 还原。process.platform是{writable:false, configurable:true}—— 直接赋值会被静默忽略,只有defineProperty有效。为什么不是无条件钉死 linux/x64
CI 矩阵含
windows-latest,而产品代码在安装路径上确实读 platform(service.ts:265的 win32 分支要求LOCALAPPDATA、install-source.ts:87/272)。无条件钉 linux 会让该文件里.skipIf(process.platform !== 'win32')的 Windows 独占安装测试在 Windows 上跑进错误分支——等于拿本机修复换 Windows CI 回归。当前写法:宿主本身是 required target 就用宿主值,否则回落
linux-x64(对应release.ts:39REQUIRED_V1_TARGETS第三条真实条目)。对 CI 三平台行为逐字节不变,win32 测试照旧走真实分支;skipIf在 collection 期求值、早于beforeEach,不受影响。变异验证(都精确复现)
两次还原后
md5sum -c均「成功」,逐字节一致。数字
门禁(提交后干净树,全 exit 0)
webui:typecheck·typecheck·test:webapp(1842 pass) ·test:webui(2179 pass/2 skip) ·check:source(4900 files) ·check-docs-alignment(6/6) ·test:capabilities·test:release-tools明确未做
release.ts的TARGETS加 linux-arm64 —— 那是发布契约变更(TARGETS + manifest + 发布制品),留产品决策docs/—— 核查确认仓库无DEVELOPMENT.md,且README/CONTRIBUTING/docs检索locale|LANG=|LC_ALL无任何一处描述 runner 的环境行为顺带确认:
test:webui的既有 flake 与本单无关chat-run-mirror.check.mjs的waitFor timed out: turn to drain(2s 超时级联 8 条)。已 stash 掉本单两处改动、在基线上单文件循环 8 次复现 2 次失败,证明无关。建议另开工单(该 flaky 的根因已由 #132 定位为毫秒边界竞态)。🤖 Generated with DeepSeek Harness