Repository navigation
test(app-shell): stub useRecordPresence as the array the hook returns - #8902
Merged
Merged
Conversation
13 RecordDetailView test files stubbed `useRecordPresence` as
`{ viewers: [], others: [] }`. The hook returns `PresenceUser[]` and its
only consumer reads `recordPresence.length > 0`, so an object stub made
`.length` `undefined` and the presence row structurally unrenderable —
those files exercised the no-presence branch through a shape mismatch
rather than through the empty array the branch is about.
Align all 13 with the 9 that already stub `[]`. Value-identical today
(both render nothing); the change is that the row can now render at all
when a stub is given users, which is what makes the branch pinnable.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01611D6ZaRaMmwTNQmSbk8MH
Empty frontmatter: no published package moves. Measured rather than asserted — every package's `files[]` ships `dist`, and no built `dist` in the tree contains a single `*.test.*` artefact (positive control: the published `useRecordPresence` symbol IS in `packages/collaboration/dist`). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01611D6ZaRaMmwTNQmSbk8MH
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
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 #8083
13
RecordDetailViewtest files stubbeduseRecordPresenceas{ viewers: [], others: [] }. The hook returnsPresenceUser[](
packages/collaboration/src/PresenceProvider.tsx, anchorexport function useRecordPresence) and its only consumer readsrecordPresence.length > 0(packages/app-shell/src/views/RecordDetailView.tsx,anchor
recordPresence.length). An object has nolength, so the presence rowwas structurally unrenderable in those files. All 13 now stub
[], matchingthe 9 files that already did.
Diff: 13 files, one line each, plus one changeset. Nothing else.
Why "all 13 are still green" is not the evidence
Swapping
{ viewers: [], others: [] }for[]leavesrecordPresence.length > 0falseeither way, so the row still does not render and the 13 stay green. Acorrect fix and a no-op produce byte-identical green. The reading that
discriminates is can it now go red — feed the stub a non-empty array and the
row must render.
Measured with a mutation probe: the stub is filled with one
PresenceUser, andPresenceAvatarsis replaced by a stand-in that throwsOS8083_PROBE_ROW_RENDEREDon render. A file goes red exactly when the row reaches the DOM. Every leg
proves its edit landed on disk (injected-marker count, removed-marker count and
git hash-objectbefore/after) before anything is run, and restores bygit checkout HEAD -- pathverified withgit diff HEADempty. All runs wentthrough the shared heavy-verify lock; the verdict quoted is the runner's own
line, never a bare
$?.[user]OS8083_PROBE_ROW_RENDERED{ viewers: [user], others: [user] }[user][]Row 2 is the card's thesis turned into a number: the object stub was fed users
in both of its fields and the row still could not render. Row 3 is the class
judgement — the branch is now pinnable.
The 13th file,
RecordDetailView.expandFls-7230.test.tsx, does not fire, andthat is a property of the file, not of the stub. Its 6 cases resolve as soon as
a
findOneis recorded, which happens whileRecordDetailViewis still in theisLoadingskeleton — an early return that sits above the presence chrome. Notargued: with the same corrected stub and a one-shot case appended that awaits
the loaded tree, the presence element is found (7/7 green). So the stub is
capable there too; the file simply never observes the loaded tree.
The second half — what broke when the row actually rendered
Nothing. No assertion in any of the 13 was relying on the row being
unrenderable, and no existing assertion was touched.
That negative was made in the strongest available form and then checked for
vacuity. The
PresenceAvatarsoverride line was deleted rather thanrestubbed, so the real component came through the factory's
...(await importOriginal())and rendered its actual DOM, with the stub fed areal
PresenceUser. All 22 files: 157/157 green.A green from a probe that renders nothing would be the very defect this card is
about, so the probe carries its own two-legged control on
RecordDetailView.headerRefresh.test.tsx:role="group"stack is in the document passes (6/6);AssertionError: real PresenceAvatars renders a role=group stack: expected 0 to be greater than 0.So the element counted is exclusively the real
PresenceAvatars, and the 157/157above is a measurement rather than an absence.
Ablation
Prediction written before the run: from the committed tree, ablate exactly one
file (
headerRefresh) back to the object stub, give the other 21 the arraystub, throwing stand-in everywhere; 20 of 22 red, with
headerRefreshgreen(ablated) and
expandFls-7230green (never reaches the loaded tree), andnothing else moving.
Observed:
Test Files 20 failed | 2 passed (22)/Tests 128 failed | 29 passed (157).The two green files are exactly
headerRefreshandexpandFls-7230. Restoreverified both ways:
git diff HEADempty over all 22 and the ablated file'sblob hash back to
c44714e63278.验收备注
1. The two vi.mock gates cannot see this class — measured, not inferred, and
deliberately not extended here.
check:vi-mock-specifiersjudges whether a relative specifier resolves to afile. These stubs mock the bare specifier
@object-ui/collaboration, whichthe gate's own summary counts as
935 bare (out of scope).check:vi-mock-inheritjudges whether a factory obtains the real module.All 13 already spread
...(await importOriginal())and always did — they werecompliant while carrying the drift. The gate judges the factory's inheritance,
never an override's value.
Empirically: with all 13 object-shaped stubs put back on disk, both gates print
the same verdict line and the same exit code as on the repaired tree —
✅ check-vi-mock-specifiers: OK/✅ check-vi-mock-inherit: OK, exit 0 both.This class has no automated guard today; 13 drifted stubs were found only by a
hand census. Extending a gate is a separate card and is not attempted here.
2. Position axis, both carriers.
file:linecitations.scripts/cross-file-line-citation-census.mjsrun three times — at the branch point, on this branch, and on the tree
produced by a real
git merge --no-ffof this branch intoorigin/mainin athrowaway detached worktree. All three outputs are 634 lines and byte-identical
except the header's HEAD sha. Zero citations moved.
cannot see. The confirmed carrier
UNGATED_EXAMPLESinscripts/check-doc-example-types.mjsholds 90 rows; 0 address app-shell orany
.test.tsx. Swept for the class, not just that instance: the only otherliteral
path:NUMBERentries in the tree areskills/objectui/guides/*fixtures inside
scripts/__tests__/, untouched. And there is no line-addressedcitation into any of the 13 anywhere in the tree.
with one line in each file, and every touched file kept its exact line
count, so nothing downstream of the edit shifted.
3.
Clause-②: no— judged from the diff, not from convenience. 13*.test.tsxlines plus one changeset: no new exported symbol, no new key on apublished payload, no schema key, closed-set member or registry entry. Measured
rather than asserted: every package's
files[]shipsdist, and no builtdistin the tree contains a single
*.test.*artefact (positive control: thepublished
useRecordPresencesymbol is present inpackages/collaboration/dist).Hence the empty-frontmatter changeset.
4.
{ viewers, others }exists nowhere in this repo as a real shape — atree-wide sweep finds it only in the 13 stubs this PR removes, confirming the
card's reading that it was borrowed from a different presence surface.
Verification
Run through
os-verify-lock.sh, verdict lines quoted from the runner:Test Files 22 passed (22)/Tests 157 passed (157),VERDICT command-exit 0pnpm --filter @object-ui/app-shell run type-check(tsc --noEmit && tsc -p tsconfig.test.json, so the test files are covered):VERDICT command-exit 0. First attempt returned exit 2 withCannot find module '@object-ui/fields'— a workspace not yet built, read as NOT MEASURED; re-run afterpnpm --filter '@object-ui/app-shell^...' build.pnpm --filter @object-ui/app-shell run lint:✖ 2943 problems (0 errors, 2943 warnings), exit 0 — all warnings pre-existing, none on the touched lines.pnpm check:vi-mock-specifiers,pnpm check:vi-mock-inherit,pnpm changeset:check,pnpm check:control-bytes: all exit 0, verdict lines green.node scripts/check-governed-queue-guard.mjs --testover all 14 paths:NOT GOVERNED.Declared narrowing. Vitest's own config collects 669 test files for
packages/app-shell/; this branch ran 22 of them (count from vitest's ownTest Filesline) plus the whole package's type-check and lint. The narrowingexcludes nothing that could move: a
vi.mockfactory is scoped to the file thatdeclares it, each of the 13 is an import leaf (nothing in the tree imports any of
them), and no touched file changed its line count. A 37-file presence-consumer
radius was queued for the lock twice and returned
exit 99/queue-timeoutboth times behind an 18-minute sibling holder — NOT MEASURED, not green and
not red. CI runs the full farm.
🤖 Generated with Claude Code
https://claude.ai/code/session_01611D6ZaRaMmwTNQmSbk8MH
Generated by Claude Code