Skip to content

fix(client): 把 tests/integration/ 纳入 tsc,并把 discovery 断言改到真实存在的表面 (#5544) - #5565

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-5544-client-integration-tsconfig
Aug 5, 2026
Merged

fix(client): 把 tests/integration/ 纳入 tsc,并把 discovery 断言改到真实存在的表面 (#5544)#5565
baozhoutao merged 1 commit into
mainfrom
claude/issue-5544-client-integration-tsconfig

Conversation

@baozhoutao

Copy link
Copy Markdown
Contributor

Fixes #5544

前提复核(先证后改)

在合入 #5546 之后的 origin/main @ 229d29ea4 上逐条复核,issue 的前提完全成立:

tests/integration/01-discovery.test.ts(41,14): error TS18048: 'discovery.apiName' is possibly 'undefined'.
tests/integration/01-discovery.test.ts(61,21): error TS2339: Property 'discovery' does not exist on type 'ObjectStackClient'.
tests/integration/01-discovery.test.ts(62,21): error TS2339: Property 'discovery' does not exist on type 'ObjectStackClient'.
  • 该文件不含任何 @ts-expect-error(grep 为空),PINS_CHECKED / PHANTOM_PIN_DEBT 不受影响。

改了什么

1. tsconfig.test.jsoninclude 纳入 tests/**/*,并把配置头部那段「tests/integration/ 不在任何 tsconfig 里,留给 #5544」的注释改写成现在的事实。

运行通道一个字没动:vitest.config.ts 仍然排除 tests/integration/**,test:integration 仍然走 vitest.integration.config.ts、仍然需要 README 里那台外部服务器。让 tsc 读它,不等于让 CI 跑它 —— 两条通道里,只有 tsc 这条在没有服务器时也能工作。

2. 3 条错误全修,该文件不进 debt 台账。

一个刻意没做的改动(附证据)

apiName 在 spec 里被标注为 deprecated(protocol.zod.ts:118-127,canonical 是 name)。看上去应该顺手把断言改写成 name,但两个 discovery 生产者的拼法是相反的:

  • packages/metadata-protocol/src/protocol.ts:2509getDiscovery() 只发 apiName,不发 name;
  • packages/runtimegetDiscoveryInfo() 只发 name —— 同仓 packages/runtime/src/http-dispatcher.root.test.ts:38 的注释原话就是 "getDiscoveryInfo returns 'name' not 'apiName'"。

该套件跑在一台外部服务器上,本单无法证伪它背后是哪个生产者;而在消费者侧写 discovery.name ?? discovery.apiName 正是契约优先原则禁止的宽松兜底。所以断言的键原样保留,只修类型错误,并把这份证据补到已有的 #4828(它的决策点 4 正是 name 必填 vs 生产者不产出),没有另开重复单。

反向验证(方向先判后跑,两个方向都对上了)

状态 预判 实测
旧断言 + include 红,且恰好是原来那 3 条 3 条一字不差复现
旧断言 + include 绿 —— 因为 tsc 根本看不见这个文件 tests/ 前缀错误数 = 0

值得写明:这条改动回滚不会变红,而是变瞎。第二行才是这个 issue 的本体 —— 一个既不被 vitest 跑、也不被 tsc 读的文件,可以对着一个不存在的属性断言好几个月而全绿。

验证

$ pnpm --filter @objectstack/client typecheck
✓ check:test-typecheck --self-test — 8 semantic case(s) + the parser hold.
check:test-typecheck: OK — @objectstack/client's test layer compiles under
packages/client/tsconfig.test.json; 3 file(s) / 6 error(s) held in
test-typecheck-debt.json (shrink-only, ... issues/5286).

$ pnpm --filter @objectstack/client test
 Test Files  17 passed (17)
      Tests  222 passed (222)

$ pnpm check:type-check-coverage
check-type-check-coverage: OK — 62/77 workspace packages type-checked ...

$ node scripts/check-nul-bytes.mjs
check-nul-bytes: OK (scanned 5507 tracked text file(s) ...)

test-typecheck-debt.json 未改动(仍是 3 文件 / 6 条 #5543 家族),该集成文件零错误、不入台账。集成套件本身仍能被 vitest list --config vitest.integration.config.ts 正常收集到 4 个用例;常规 vitest list 里它依然是 0 命中(排除关系未变)。

changeset

无 changeset,请打 skip-changeset 标签。 本 PR 只改一个 tsconfig 的 include 与一个从未被任何通道执行过的测试文件,不发布任何包、不改变任何运行时行为 —— 与同包 #5546(PR 走的正是 skip-changeset 路径)同型。

界外发现


🤖 Generated with Claude Code

https://claude.ai/code/session_016FNvXhtSdnEGEfLEsMmvxh


Generated by Claude Code

…ertions at the surface that exists

`packages/client/tests/integration/01-discovery.test.ts` was read by neither
gate: `tsconfig.test.json`'s `include` stopped at `src/**/*` and no `exclude`
anywhere named the file (the #5476 shape — outside every program, not inside an
excluded region), while the regular `vitest.config.ts` excludes
`tests/integration/**` because the suite needs a live server. Two channels, both
blind, and the suite had drifted onto a `client.discovery` property
`ObjectStackClient` does not have.

- `tsconfig.test.json`: `include` gains `tests/**/*`. The vitest split is
  untouched — compiling the file does not run it, and the suite still needs the
  external server its README describes. tsc is the gate that works without one.
- `01-discovery.test.ts`, all three errors the inclusion surfaces:
  - TC-DISC-004 read `client.discovery`, which never existed on the class
    (TS2339 x2). The payload lives on the private `discoveryInfo` field, read
    here through the bracket-notation escape hatch exactly as this package's
    `src/client.hono.test.ts` already reads it. No public API was invented for
    the suite. The case also now asserts `routes` is populated — the thing
    "Route Resolution" is named for, and what `getRoute()` steers every later
    call with — so assertion strength goes up, not down.
  - TC-DISC-002's `discovery.apiName.length` (TS18048) is reached optionally and
    asserted, per #5449's convention in this package: a missing value fails
    `toBeGreaterThan` rather than being waved through by a `!` or a `?? ''`.
    Which KEY that assertion should name is a producer-side contract question,
    not a test's to settle — metadata-protocol emits the deprecated `apiName`
    and no `name`, the runtime dispatcher emits `name` and no `apiName` —
    so the spelling is left alone and the evidence is recorded on #4828.

Reverse verification, both directions predicted before running: restoring the
old assertions under the new `include` reports exactly the 3 original errors;
restoring the old `include` as well makes them vanish — rolling this change back
does not go red, it goes BLIND, which is the defect being fixed.

Fixes #5544

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016FNvXhtSdnEGEfLEsMmvxh
@vercel

vercel Bot commented Aug 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 5, 2026 6:34pm

Request Review

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

No hand-written docs reference the 0 changed package(s). ✅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

1 participant