Repository navigation
test(plugin-view): fold six more ObjectView pins over stand-in child renderers onto the shared harness - #30900
Merged
Conversation
…renderers onto the shared harness The three clean trio pins (tableColumnsForwarding, strayGroupByLane-9242, canonicalTableKeys) and the three smallest pins another test file names (createGrant-12082, calendarBinding-7029, formTitleNoProviderFallback) become blocks of ObjectView.harness.test.tsx, each opening with restoreAfterBlock() and installing its own three stand-ins. Every test, title and assertion is kept. The test-file comments that named the folded files now name the block. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L9qibxkcTyv8QYYuvpzAFL
Contributor
Author
|
domain:ui#2 · os-tesla · session_01L9qibw7DekEe3wx5f3zphf 席位核对 · ACCEPT · 2026-11-06T10:23Z · head
|
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.
Requested by Tesla · project thread
Part of #29469
Clause-②: no
Metadata-protocol: none
维护者速读
ObjectView(plugin-view包)再有 6 个单卡测试文件并入上一片(test(plugin-view): fold nine ObjectView pins over stand-in child renderers onto one shared harness #30872)建好的共享测试文件ObjectView.harness.test.tsx,每个原文件变成一个顶层describe,断言和标题一字未改;另有 3 个测试文件里点名这些文件的注释改成点名对应的块。plugin-view39 个、app-shell87 个)按共享的 setup 列在正文末尾。formTitleNoProviderFallback和createGrant-12082依赖ui/vitest.setup.i18n-global.ts每个测试后复原 react-i18next 全局实例:临时关掉那一步,这两块 7 个测试变红,恢复后全绿。回滚 = revert 本 PR。ObjectView.formTitleNoProviderFallback一块的文档注释(原来写着"必须单独成文件",现在说明为什么可以同文件),再看ObjectView.formTitleI18n.test.tsx改过的那段注释。ui/下跑pnpm exec vitest run packages/plugin-view/src/__tests__/ObjectView.harness.test.tsx,应见 1 个文件、119 个测试全过。f5053769的 diff 复核:10 个文件,6 个 ObjectView 单卡文件并入已有的 plugin-view 共享文件,另 3 个文件只改指向被并文件的注释(其一在 plugin-form,超出认领面但仅 1 行注释);断言与标题一字未改(it(61=61、expect(113=113),乱序三种种子全过;2,867 行未过 3,000 行线;CI 全绿,纯测试改动无发布面,不欠契约复审。未并入的 39 个 plugin-view 文件与 87 个 app-shell 文件已在正文列明。同意落地。What changes
Slice 3b, the second and last
ObjectView*PR of the shared-setup rollout (ruling 6583487846 on #29469; seat amendment 2, 6672694520: at most two PRs per family). Six more pins inui/packages/plugin-view/src/__tests__/that render the realObjectViewover the three-mock trio joinObjectView.harness.test.tsx, which slice 3a (#30872) created:tableColumnsForwarding,strayGroupByLane-9242andcanonicalTableKeys. Then the three smallest trio pins that pass every census check except that another file names them:createGrant-12082,calendarBinding-7029andformTitleNoProviderFallback.describenamed after its file stem, with its docblock above it, appended after the nine 3a blocks. Its first lines arerestoreAfterBlock()and abeforeEachthat installs its three stand-ins, each copied verbatim from that file's mock factory; everything else is moved verbatim, re-indented by two spaces. A module-levelbeforeEach/afterEachof a former file is now the block's own hook. The 6 files are deleted. The harness goes from 9 to 15 top-leveldescribeblocks. No 3a block, and no line of the header, the mocks orrestoreAfterBlock(), changed.MePermissionsProviderand the typeMePermissionsAuthenticatedResponsefrom@object-ui/permissions, whichcreateGrant-12082used.formTitleNoProviderFallbacksaid it had to be its own file. Its docblock explained that a mountedI18nProviderinstalls react-i18next's global instance and that this survivescleanup(), so a provider-less render later in the same file would assert nothing. That no longer holds:ui/vitest.setup.i18n-global.ts(objectui#4514) puts back the pointer the file inherited after every test. The section is rewritten to say so, and keeps the rule not to mount a provider in that block. Measured both ways: the block runs afterObjectView.formLabelsI18nLabel-10993, which mounts a zh provider, and passes in declaration order and under three shuffled orders; with the reset'ssetI18ncall disabled for one throwaway run, 7 tests go red (the 4 offormTitleNoProviderFallbackand 3 ofcreateGrant-12082, whoseNewbutton label resolves through the same global), and the other 112 stay green. The probe below also readsgetI18n()asundefinedat every block's start.Comments that named a folded file (amendment 2: test files are updated, source files stay):
ui/packages/plugin-view/src/__tests__/ObjectView.formTitleI18n.test.tsxnamedObjectView.formTitleNoProviderFallback.test.tsxand why it lived elsewhere; it now names the block and the setup file.ui/packages/plugin-view/src/__tests__/ObjectView.ganttBinding-7070.test.tsxnamedObjectView.calendarBinding-7029as its sibling next door; it now names the block.ui/packages/plugin-form/src/affordanceGrantMap-12082.test.tsxnamedObjectView.createGrant-12082.test.tsxas the opener's runtime pin; it now names the block.The two
ui/packages/app-shell/src/views/files that nameObjectView.calendarBinding-7029(ObjectView.galleryBinding-7547,ObjectView.ganttBinding-7070) mean app-shell's ownObjectView.calendarBinding-7029.test.tsx, which stays, so they are unchanged.git grepof each of the 6 stems overui,scripts,packages,content,appsand.githubfinds no other hit outsideCHANGELOG.mdhistory.Test files only: no source file, no changeset (
skip-changeset).@object-ui/plugin-viewand@object-ui/plugin-formbuild from their entries withvite build, and no entry imports a test file.Tests
Former file → describe (no title or assertion dropped)
TypeScript AST walk of each former file at
8b9cc712(themainthis was cut from, where they still exist) against thedescribeof the same name in the harness at this PR's head. Anitis a call toit/test(anit.each(...)(...)counts once); titles are thedescribe > itpaths under the block, compared as sorted lists.ObjectView.tableColumnsForwarding.test.tsxObjectView.strayGroupByLane-9242.test.tsxObjectView.canonicalTableKeys.test.tsxObjectView.createGrant-12082.test.tsxObjectView.calendarBinding-7029.test.tsxObjectView.formTitleNoProviderFallback.test.tsxThe whole harness: 47
it/ 97expect(at8b9cc712, 108 / 210 at this head (47 + 61, 97 + 113); no statement outside the blocks holds anitorexpect(. The 108itcalls run as 119 tests (it.eachrows), 55 of them the 3a blocks.The diff adds one import line and appends after the last 3a block (
ObjectView.filterSources); it removes no line of the harness.CPU before and after (local A/B, one machine)
CI after: NOT MEASURED: the per-file timings reporter (#29517) uploads on
main's full-battery runs only. Its first after-reading is the first full-batterymainrun after this merges.Local A/B on one 4-vCPU container, under
os-verify-lock(shared-box seconds), same command both legs, fromui/:pnpm exec vitest run packages/plugin-view/src/__tests__/ObjectView. --maxWorkers=2(everyObjectView.*file in that directory,ObjectView.test.tsxincluded), with a throwaway reporter summing each module'sdiagnostic(). Fixed = environment + prepare + setup + collect (import). The "before" leg writes the 6 files and the harness from8b9cc712into the branch's tree, so both legs run the same 40 other files; run order before, after, before, after.The 6 files took 29.2 / 29.0 s of CPU on their own; the harness grew from 6.7 / 6.3 s to 9.1 / 7.6 s to hold them, so the fold saves about 27 s of CPU (−76 % for those seven files together). The family read 249.6 s before and 236.0 s after on average (−5.4 %), and wall 130.3 s to 123.2 s; the two after runs differ by 31.9 s, so that family figure is a reading inside this box's run-to-run spread, not a measured saving; the per-file figures above are the measurement. Across both slices the nine 3a files and these six, 15 files and 2,802 lines, now load the module graph once.
Acceptance notes
ObjectViewpins in a second harness. Measured at8b9cc712, that is about 14,000 changed lines: the 3 clean pins are 1,081 lines, the named-by trio pins about 3,300 more, and the app-shell pins 25,358 lines over 20 different mock-module sets. The dev reported that to the seat before writing anything, and the seat agreed (09:06Z) to the 3 clean pins plus the smallest named-by trio pins that fit the 3,000-line bar. 1,485 lines moved make 2,867 changed lines; the next smallest eligible pin (ObjectView.rowColorRelay-7218, 175 lines) would take it past 3,000.ObjectView.*pin left unfolded is listed below by the setup it shares, from this head's tree. Whether to fold further is a new card the seat files (amendment 2). Two of the rows are not candidates at all:contractEnvelope-6726is named by path inui/scripts/check-vi-mock-inherit.mjs, a ledger outside__tests__, so it stays a file of its own;galleryBlockNested-12053registers its tests from aforloop over its routes at collection time.ObjectViewin@object-ui/app-shell, a different component from@object-ui/plugin-view's, and none of them uses the trio. Their largest dom clusters share a base of./MetadataInspector,./RecordDetailView,@object-ui/auth,@object-ui/collaborationand@object-ui/permissionsmocks but differ in the rest of the set (and, file by file, in the overridden keys), so a fold there needs its own harness inapp-shelland its own census; the seat judges whether that is a separate card. 12 dom files there mock nothing (2,548 lines), the natural first cluster for such a harness; 12 more mock nothing but are.test.tsfiles in theunitproject, which is not isolated per file, so folding them saves nothing.formTitleNoProviderFallbackandcreateGrant-12082fold cleanly only because theui/setup resets react-i18next's global after every test (the reverse run above is the evidence); a later change toui/vitest.setup.i18n-global.tsis the thing that would undo it, and the rewritten docblock says so.ObjectView pins left unfolded in
@object-ui/plugin-viewat this head: 39 files, 9,677 linesObjectView.test.tsxis the component's main suite, not a per-issue pin, and is not counted. "The trio" is the harness's three mocks (@object-ui/reactwithSchemaRenderer,SchemaRendererContext,subscribeDataChangesandnotifyDataChangedreplaced;@object-ui/plugin-gridwithObjectGrid;@object-ui/plugin-formwithObjectForm). A file sits under the first row it fails, top to bottom. Names drop theObjectView.prefix and.test.tsx.namedViewProtocolKeys-8980(694; named byplugin-view.mdx,view-overlay-options-bag.test.ts,README.md),specShapedNamedView-8254(379; named byObjectView.tsx),mapFlatten(347; named byListView.mapFlatten.test.tsx,CHANGELOG.md,ObjectMap.filterConfig.test.tsx,ObjectMap.topLevelStyle.test.tsx,index.bareMapKeyRetired-10393.test.tsx,ObjectView.tsx,CHANGELOG.md),calendarAliasRefused-8355(305; named byCHANGELOG.md,CHANGELOG.md,CHANGELOG.md,CHANGELOG.md,ObjectView.harness.test.tsx,CHANGELOG.md),formTitleI18n(272; named byObjectView.harness.test.tsx),kanbanConditionalFormatting(226; named byCHANGELOG.md),contractEnvelope-6840(191; named byObjectView.tsx),ganttBinding-7070(191; named byObjectView.galleryBinding-7547.test.tsx,ObjectView.harness.test.tsx),rowColorRelay-7218(175; named byCHANGELOG.md,ObjectView.fieldOrderRelay-7516.test.tsx)__tests__(check-vi-mock-inherit.mjs): stays a file of its owncontractEnvelope-6726(161)galleryBlockNested-12053(160)vi.spyOn,vi.stubGlobal,vi.useFakeTimersorvi.stubEnvexpandGate(355),sortSink(303),namedViewContextTokens-10506(301),legacyChartRetired-6152(159)vi.hoistedorglobalThisslot of its ownviewIdentityDeps(348)@object-ui/reactkeeps its realSchemaRendererContextor data-change busrefreshInPlace-10035(285),dataSourceContextFallback-7842(220)@object-ui/plugin-form+@object-ui/plugin-grid, not the triotableSlotRelay-10976(280),routeTwoNamedGridMembers-10885(264),pageSurfaceFallback-11015(224),drawerDirection-11775(193),splitPopoverCreate-10975(148),namedViewNavigation-10885(145),gridOperationsWithoutRead-6152(95)@object-ui/plugin-form, not the triogridFilterHandoff-11880(319),namedViewInlineEdit-10885(129),tableEditable-10976(121),tableTitleI18nLabel-10993(114)@object-ui/permissions, not the triogridDelete-10383(401)@object-ui/plugin-grid, not the triofetchAllowList-10982(278)../ViewSwitcher+@object-ui/plugin-form+@object-ui/plugin-grid+@object-ui/react, not the triohostOnlyViewTypes(243)@object-ui/permissions+@object-ui/plugin-form+@object-ui/plugin-grid+@object-ui/react, not the trioexpandFls-7429(232)@object-ui/plugin-grid+@object-ui/react, not the trionamedViewSpecRecord-7928(138)@object-ui/react, not the triorecordIdFilterToken-7297(100)vi.mock(renders the real children), a setup of its ownmodifierClickNewTab-9806(493),namedViewSortArity(312),busReread-10887(232).test.tsin theunitproject, which is not isolated per file, so a fold saves nothingtreeViewConfigDeclared-8253.test.ts(144)ObjectView pins in
@object-ui/app-shell(ui/packages/app-shell/src/views/), another family: 87 files, 25,358 linesGrouped by the set of modules each file passes to
vi.mock. Names drop theObjectView.prefix and.test.tsx.vi.mockmodules)./MetadataInspector+./RecordDetailView+@object-ui/auth+@object-ui/collaboration+@object-ui/permissions+@object-ui/plugin-list+@object-ui/plugin-view+sonnercreatePredicates(434),objectBoundActions-7234(392),chartRelay-7823(355),titleFieldConvergence(350),viewRowDeclaredReads-11013(338),rowColorRelay-7218(304),servedViewLabel-11295(302),labelLessViewTab-12774(291),importPredicates(290),viewDescriptionRelay-7199(288),fieldOrderRelay-7516(257),mobileFabListClearance-13134(232)setDefaultViewIdentity(467),defaultViewIdentity(337),kanbanLane-8193(230),kanbanGroupByRetired-8213(219),galleryBinding-7547(206),overlayFilterRecovery(201),defaultColumns(187),ganttBinding-7070(182),calendarBinding-7029(174),viewOverrides(139),consoleProps.types(124),timelineBinding(82)./MetadataInspector+./RecordDetailView+@object-ui/auth+@object-ui/collaboration+@object-ui/permissions+sonnerlistUrlState-11860(746),personalViews-29635(678),refreshInPlace-10035(400),ufViewSwitch-11992(294),hostRerenderRefetch-10046(281),externalRefreshSum-10572(274),stableFilterIdentity-7237(274),objectDocSwapNoRefetch-27626(216),refreshRereadsViews-13057(192),setupListChrome-12606(147)./MetadataInspector+./RecordDetailView+./metadata-admin/useMetadata+@object-ui/auth+@object-ui/collaboration+@object-ui/permissions+sonneremptyStateMatchesPage-11687(321),recordCountFooter-10636(279),recordOpenDisplay-26681(261),createViewRefusal-11578(249),phoneRecordPage-27058(244),recordOpenPreference-26677(200),addRecordOpensCreate-13089(181),createKanbanView-11581(173)./MetadataInspector+./RecordDetailView+./metadata-admin/useMetadata+@object-ui/auth+@object-ui/collaboration+@object-ui/permissionstoolbarScriptSelection-12331(446),inviteOutcome-27797(357),inviteFeedback-11817(354),headerSelectionGate-27831(316),bulkWiredHeaderDuplicate-12462(297)./MetadataInspector+./RecordDetailView+@object-ui/auth+@object-ui/collaboration+@object-ui/permissions+@object-ui/plugin-list+sonnerfallbackTabSessionOnly-11643(399),inlineEditSessionOnly-5144(396),toolbarWritesCompose-11642(368),densityModeThroughFold-7924(253),recordRelatedNotOnOwnList-11270(151)./MetadataInspector+./RecordDetailView+@object-ui/auth+@object-ui/collaboration+@object-ui/permissions+@object-ui/plugin-view+sonnerlistLinksPlural-11733(237),favoritesEntry-12427(223),starredView-27594(221),listCrossObjectHost-12673(218),listTitlePlural-11696(215)./MetadataInspector+./RecordDetailView+@object-ui/auth+@object-ui/collaboration+@object-ui/permissionstitleViewSwitcher-27594(295),objectListTitle-27950(254),chartViewTabs-13114(229)./MetadataInspector+./RecordDetailView+./metadata-admin/inspectors/ViewVariantInspector+./metadata-admin/useMetadata+@object-ui/auth+@object-ui/collaboration+@object-ui/permissions+@object-ui/plugin-list+@object-ui/plugin-view+sonneruserListState-12418(1045),viewWriteRefusal-11583(478)./MetadataInspector+./RecordDetailView+./metadata-admin/useMetadata+@object-ui/auth+@object-ui/collaboration+@object-ui/permissions+@object-ui/plugin-list+sonnerlistPersonalized-28950(346),recordDrawer-27545(272)./MetadataInspector+./RecordDetailView+@object-ui/auth+@object-ui/collaboration+@object-ui/plugin-list+@object-ui/plugin-view+sonnerviewRefusal-12112(243),listActionsReadGate-12109(171)./MetadataInspector+./RecordDetailView+@object-ui/auth+@object-ui/collaboration+@object-ui/plugin-view+sonnermanagedByBadgeAuthoring-12194(177),setupListBadge-13385(165)./MetadataInspector+./RecordDetailView+./RuntimeDraftBar+./metadata-admin/inspectors/ViewVariantInspector+@object-ui/auth+@object-ui/collaboration+@object-ui/permissions+@object-ui/plugin-view+sonneremptyColumnsNoProjection-10694(618)../providers/MetadataProvider.js+./MetadataInspector+./RecordDetailView+@object-ui/auth+@object-ui/collaboration+@object-ui/permissions+@object-ui/plugin-list+@object-ui/plugin-view+@object-ui/react+sonnerstoredRowParity-10380(444)./MetadataInspector+./RecordDetailView+@object-ui/auth+@object-ui/collaboration+@object-ui/permissions+@object-ui/plugin-charts+@object-ui/plugin-view+sonnerchartConfigForward-7891(371)./MetadataInspector+./RecordDetailView+@object-ui/auth+@object-ui/collaboration+@object-ui/permissions+@object-ui/plugin-grid+@object-ui/plugin-list+@object-ui/plugin-view+sonnerheaderFold-12705(294)./MetadataInspector+./RecordDetailView+./metadata-admin/useMetadata+@object-ui/auth+@object-ui/collaboration+@object-ui/permissions+@object-ui/plugin-charts+sonnercreateChartView-11576(261)./MetadataInspector+./RecordDetailView+./metadata-admin/useMetadata+@object-ui/auth+@object-ui/collaboration+@object-ui/permissions+@object-ui/reactmanagedEnvironmentUsers-13330(253)./MetadataInspector+./RecordDetailView+./ViewConfigPanel+./metadata-admin/useMetadata+@object-ui/auth+@object-ui/collaboration+@object-ui/permissions+sonnerviewConfigSaveWiring-10210(188).test.tsin theunitproject (not isolated per file, so a fold saves nothing)relayRungCensus-7559.test.ts(861),overlayPatchOnly.test.ts(388),overlayPairValue.test.ts(249),viewConfigSaveEnvelope-10210.test.ts(237),urlFilterSuffix-9196.test.ts(221),unboundAdapterCall.test.ts(214),overrideMasquerade.test.ts(205),listRecordHref.test.ts(188),filterParamsKeyEncoding-9287.test.ts(172),flatOverlayColumns-8411.test.ts(131),relayedBlocksParse-6152.test.ts(81),kanbanSummarizeField-11629.test.ts(65)Verification
At head
f5053769, afterpnpm install --frozen-lockfileand the closure build from slice 3a (turbo run buildfor@objectstack/spec,formula,lint,client,metadata-protocol, then--filter='@object-ui/plugin-view^...'fromui/), every run underos-verify-lock:pnpm exec vitest run packages/plugin-view/ packages/plugin-form/src/affordanceGrantMap-12082.test.tsx --maxWorkers=2fromui/(VERDICT command-exit 0): 66 files, 775 tests, all passed. That is the 65 plugin-view files left after this PR plus the edited plugin-form file.pnpm run type-checkinui/packages/plugin-view(tsc --noEmit && tsc -p tsconfig.test.json) andtsc -p tsconfig.test.json --noEmitinui/packages/plugin-form: exit 0, 0error TS.eslintfrom the package directories: 0 errors. The harness and the two edited plugin-view files give 145 warnings (136 + 3 + 6, allno-explicit-any), the same 145 that the slice-3a harness, the 6 former files and the two edited files give at8b9cc712;affordanceGrantMap-12082.test.tsxgives 0 before and after.--sequence.shuffle.testswith--sequence.seed11, 222 and 3333. A throwaway probe (a copy of the harness whoserestoreAfterBlock()logs state at each block's first test: each registry entry's renderer and meta, thelocalStorageown property and both storage lengths, thehtmlelement'slang/dir, react-i18next'sgetI18n(), the three slots,body, globals added since import) reads every one of the 15 blocks starting from the same state in all four orders. The same probe with the helper's body removed finds the leaks 3a named (slots carried into the next block;lang="zh"/dir="ltr"afterformLabelsI18nLabel-10993). The probe copies were deleted.ui/vitest.setup.i18n-global.ts'ssetI18nrestore disabled for one run and then checked out again, the harness gave 7 failed / 112 passed (the 4formTitleNoProviderFallbackand 3createGrant-12082tests), as stated in What changes.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, change set 10 paths against merge base8b9cc712): 26 derived, 26 run with stdin from/dev/null, each exit 0 captured before any pipe;pnpm --dir ui exec vitest run scripts/(VERDICT command-exit 0) gave 170 files passed and 2 skipped, 4,979 tests passed and 2 skipped;node scripts/check-sdui-manifest.mjsand its--self-testexit 0.--ranreconciliation: 26 derived, 26 run, 0 NOT-MEASURED, 0 UNRUN.pnpm check:new-line-citationsfromui/: exit 0, 0 new citations.git diff --shortstat 8b9cc712 HEADis 10 files, +1,373 / −1,494, 2,867 changed lines.mainhas moved 3 commits past8b9cc712; none touchesui/packages/plugin-view,ui/packages/plugin-form/src/affordanceGrantMap-12082.test.tsx,ui/vitest.config.mtsor theui/vitest.setup.*files, so the branch is not re-merged and the readings above stand for this head.8b9cc712at the 10 paths, are equal except 4 (feat(i18n)!: the Console's language packs follow the platform locale table, keyed by its tags, and Traditional Chinese (zh-Hant) ships #30595, pm:mailbox — domain:devx#2 · marchtian #30515, pm:mailbox — epic:#3600#1 · hotlong #30297, pm:mailbox — triage#1 · os-zhuang #28646) whoseaffordanceGrantMap-12082.test.tsx(and, for pm:mailbox — triage#1 · os-zhuang #28646,ObjectView.createGrant-12082.test.tsx) lack linesmainadded after they branched; none of those lines is in a hunk this PR changes.Human Minimum
packages/specholds no runtime logic. (packages/specnot touched.)pnpm lintpasses. (ui/is linted by its own config; the lint readings are above.)main, one pull request.skip-changeset.)packages/spectouched: its generated artifacts are regenerated and committed. (Not touched.)content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.