Uh oh!
There was an error while loading. Please reload this page.
test(plugin-form): type-check its tests and clear its TEST_DEBT entry (#4040) - #4309
Merged
Conversation
…#4040) Tranche 2, package 2 of 3. `tsconfig.test.json` per the #3032 template, chained from `type-check`; TEST_DEBT declared 12, measured 13 at this branch point, now 0. Ten of the thirteen were one collision: `describe.each` over the four sectioned form containers makes JSX intersect their prop types, reducing `formType` to `never`. The parametrised suites now name the surface they exercise once, and pin `formType` to a literal union instead of `string`. The other three were stubs/fixtures declaring less than the code: the `dataSource.update` double omitted the `opts` parameter the assertion reads (`mock.calls[0][3]` against a declared 3-tuple), a `.map().concat()` field map narrowed away the relation field's `reference`, and an unread `o` parameter. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
marked this pull request as ready for review
August 11, 2026 13:58
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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.
Part of #4040 — tranche 2, package 2 of 3. One package per PR, per the 裁决 on objectstack-ai/objectstack#4118 (PM, 2026-08-03): 小包先行,
core(80)/react(76) 最后; 每包独立 PR; 守卫类 PR 必须附 pre-fix 代码报红的运行记录; TEST_DEBT 条目随包清零, 只减不增.Measured before / after — re-measured, not read off the registry
TEST_DEBT421c145af), template as-isTranche 1 found the registry two tranches stale for
plugin-grid(declared 2, measured 4), so tranche 2 re-measures rather than trusts. Here the drift is smaller and in the same direction: 13, not 12, and unusually none of them is config-tier — noTS6059source leak, nolibgap, no missingtypes. The template'spaths: {}/types/composite: falseare still required to keep it that way, they just do not happen to be hiding any error in this package.Ten of the thirteen are one collision
describe.eachover the four sectioned containers is the whole story:ModalFormProps.schemais aModalFormSchema,DrawerFormProps.schemaaDrawerFormSchema, and so on — each pinned to its ownformTypeliteral. Adescribe.eachtuple therefore hands JSX a union of four component types, and JSX resolves a union of components by intersecting their props:ModalFormSchema & DrawerFormSchema & …reducesformTypetonever, so every schema is rejected — including the correct one for the case actually running. Seven hits inrecordSwapLoading.test.tsx, three indiscardGuard.test.tsx.The suites now name the surface the parametrisation really exercises — the same two props against each container — once per file:
schemaisanythere and cannot be anything else, which the comment says out loud rather than leaving as a silent cast: assigningReact.FC< ModalFormProps >to a shared component type requires the shared schema type to be assignable toModalFormSchemaandDrawerFormSchemaand the other two at once, and nothing butanysatisfies that. It is a fact about these four having no common props base, not a cast papering over a mismatch. To keep the discriminant checked anyway,schemaFor's parameter goes fromstringto'modal' | 'drawer' | 'tabbed' | 'split'— so a typo in a case row is now a compile error where before it was astring.No public type was touched, and none looks wrong: four containers with four schema variants is the correct modelling. The absence of a shared props base is reported as an observation in the tranche report, not fixed here.
The other three each told the compiler less than the code
occSave.test.tsxstubbeddataSource.updatewith three parameters while the contract isupdate(resource, id, data, opts?: { ifMatch?: string })(packages/types/src/data.ts:322) — and the assertion under test reads the fourth argument,ds.update.mock.calls[0][3]. vitest records the real arguments whatever the stub declares, so the case passed at runtime while the compiler was told the call tuple has length 3 (TS2493). The stub now declares_opts, so the case checks the option bag it is actually about.deriveMasterDetail.test.tsbuilt a field map as[…nine plain fields].map(…).concat([[relation]]). Inference narrowed the nine to{ type: string }entries and.concat()then rejected the relation for carryingreference(TS2769), which reads as "the fixture is wrong" when the fixture is exactly right. The entry type is written out.LineItemsPanel.test.tsxhad an unreadoparameter on anupdatedouble (TS6133, from the repo'snoUnusedParameters), renamed_o— the convention the siblingcreatedouble already uses.Discrimination proof
1. The new test project can fail (the #3009 third failure mode: a
tsconfig.test.jsonthat exists but nothing runs). A provably-false line appended tooccSave.test.tsx:2. The
occSaveguard's meaning changed, so it gets a real red run — twice, in both directions.Types. Reverting only the stub's fourth parameter brings the hole straight back, at the assertion that is the case's entire point:
Runtime. And the assertion discriminates — reverting the source so the unguarded path always sends an options object (
{ ifMatch }instead ofifMatch ? { ifMatch } : undefined,src/occSave.tsx:146) turns it red for the right reason:Both reverted; neither is in the diff.
3. The
describe.eachrefactor did not collapse the case matrix. Replacing an inlineas consttuple with a typed constant is exactly the kind of change that can silently drop rows, and the type error it was fixing would not notice. Verbatim from the verbose run:All four containers still run, and the two-container overlay suite still runs two.
Verification
No consumer sweep is reported, and that is not an omission: nothing outside
src/**/*.test.*changed apart from thetype-checkscript and the new project file, so there is no exported type for a downstream package to be checked against.TEST_DEBTshrinks by exactly this package's line; no other entry is touched. Thetsconfig.typetests.jsonnext door stays chained — its one file is now read by both projects, which costs one extra compile and keeps the narrow project's reasoning where it was written.Changeset
Empty frontmatter —
check-changeset-presence.mjsarbitrated it, and it is a pass rather than a workaround: only test sources changed, so this releases nothing.Generated by Claude Code