Skip to content

test(plugin-gantt): fold four more ObjectGantt pins onto the shared harness - #30745

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-3t7ug5
Nov 6, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-3t7ug5

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Sales · project thread
Part of #29469

Clause-②: no
Metadata-protocol: none

维护者速读

  • 改了什么:甘特图组件再把 4 个用同一套 mock 的单卡测试文件合进 test(plugin-gantt): fold seven ObjectGantt fetch and row pins onto one shared harness #30725 建的共享测试文件 ObjectGantt.harness.test.tsx,每个原文件变成一个顶层 describe,断言一字未改;另把 12 个测试文件注释里还写着已合并文件名的地方,改成指向共享文件里对应的块。
  • 为什么改:Tests grow 2.5 times faster than source: measure the per-fix test weight and the #25911 pilot, then roll the shared-setup merge out to the heaviest components or retire it #29469 的推广,甘特图族的第二片也是最后一片(席位修订 2:每族最多两个 PR)。本地同机实测,这 4 个文件并入后,共享文件加这 4 个的 CPU 从约 20.3 秒降到约 8.9 秒,整个甘特图测试族再快约 8%。
  • 风险与回滚:只动测试文件(含注释),不改源码、门禁、CI,不发布任何东西;块之间串状态的风险已用全包测试排除。回滚 = revert 本 PR。
  • 先看:ObjectGantt.harness.test.tsx 开头 75 行(sonner mock 改成并集、槽位类型改成 (props: never));再看 ObjectGantt.invalidationRefetch-10035 块的 beforeEach(带 hook 的替身改成具名组件)。
  • 两分钟验证:在 ui/ 下跑 pnpm exec vitest run packages/plugin-gantt/src/ObjectGantt.harness.test.tsx,应见 1 个文件、52 个测试全过。
  • 需要你做的:无,席位落地。

What changes

Slice 1b, the second and last ObjectGantt* PR of the shared-setup rollout (ruling 6583487846 on #29469; seat amendment 2, 6672694520: at most two PRs per family). Four more pins render the real ObjectGantt over the same three mocks as the seven blocks #30725 folded (sonner's toast, a ./GanttView stand-in, @object-ui/plugin-detail with RecordDetailDrawer and deriveRecordPageHref stubbed out), so they join ui/packages/plugin-gantt/src/ObjectGantt.harness.test.tsx the same way:

  • ObjectGantt.colorFieldLadder-7243, ObjectGantt.invalidationRefetch-10035, ObjectGantt.propertiesBag-10859 and ObjectGantt.retiredApiProvider-12325 are each a top-level describe named after the former file, docblock above it, stand-in installed in a beforeEach through the standIns slot, everything else moved verbatim and re-indented by two spaces.
  • Three changes to the harness's shared part, each needed by one of the four:
    • The sonner mock is now the union of the blocks' mocks, { error, success }: invalidationRefetch-10035 mocked success too. No block asserts on a toast, and ObjectGantt.tsx calls only toast.error.
    • The slot is typed (props: never) => unknown and called with props as never, so a stand-in keeps its own props annotation (propertiesBag-10859 types its tasks).
    • The invalidationRefetch-10035 stand-in calls React.useState, so its beforeEach declares it as const GanttView = … and assigns that to the slot; an arrow assigned straight to standIns.ganttView fails react-hooks/rules-of-hooks. The body is unchanged, and it still runs inside the mocked GanttView.
  • The comment above import './index' is propertiesBag-10859's, which said why the import is at module scope.
  • ObjectGantt.test.tsx names the retiredApiProvider-12325 block instead of the deleted file.

Comments that named a folded file (amendment 2). Twelve test files in eight workspace packages named one of the eleven files #30725 and this PR fold. Each now names the block and the harness file (comment text only): plugin-gantt ObjectGantt.hostRowClick-27057, plugin-list ListView.ganttPagingChrome-7210, ListView.ganttToolbarFilter-10037, ListView.selfQueryingViewsToolbarState-10250, ListView.test.tsx, ObjectGallery.hostOwnsRows-7390, plugin-view ObjectView.fetchAllowList-10982, react useSettledSchema.equalPayload-10106, app-shell ObjectView.refreshInPlace-10035, core record-color, types object-gantt-properties-bag-10859-b6, and one pins description string in ui/apps/console/src/__tests__/registry-inputs-spec-parity.test.ts (the object-gantt.gantt row). That ledger checks a pin's file (exists, is collected, names the block and the key), never its pins text. The five source files that name a folded file (ObjectGantt.tsx, index.tsx, ObjectTimeline.tsx, ListView.tsx, ObjectView.tsx) are unchanged, as amendment 2 says; each stem still git greps to its describe.

Test files only: no source file, no changeset (skip-changeset). No package entry imports a test file: the plugins and the console bundle from their entries with vite build, the built core, types and react dist hold no module that imports vitest, and app-shell is private.

Tests

Former file → describe (no title or assertion dropped)

TypeScript AST walk of each former file at f18fd963 (the #30725 head, where they still exist) against the describe of the same name in the harness at this PR's head.

former file it before it after expect( before expect( after titles identical
ObjectGantt.colorFieldLadder-7243.test.tsx 6 6 9 9 yes
ObjectGantt.invalidationRefetch-10035.test.tsx 3 3 10 10 yes
ObjectGantt.propertiesBag-10859.test.tsx 6 6 21 21 yes
ObjectGantt.retiredApiProvider-12325.test.tsx 2 2 7 7 yes
total 17 17 47 47 yes

The harness now holds 11 top-level describe blocks and 52 tests (35 from #30725, 17 from here), all passing.

CPU before and after (local A/B, one machine)

CI after: NOT MEASURED, for the reason #30725 gives: the per-file timings reporter (#29517) uploads on main's full-battery runs only. Its first after-reading is the first full-battery main run after this merges.

Local A/B on one 4-vCPU container, under os-verify-lock (shared-box seconds), same command both legs, two runs each, from ui/: pnpm exec vitest run <every ObjectGantt*.test.ts(x) in plugin-gantt> --maxWorkers=2, with a throwaway reporter reading each module's diagnostic(). Fixed = environment + prepare + setup + import. The "before" leg restores the four files and the #30725 harness from f18fd963 into this branch's tree, so both legs run the same 45 other files.

files tests passed fixed CPU test CPU total CPU wall
ObjectGantt family, before (run 1 / run 2) 50 327 143.4 / 144.6 s 10.5 / 10.6 s 153.9 / 155.2 s 82.3 / 83.1 s
ObjectGantt family, after (run 1 / run 2) 46 327 131.8 / 131.6 s 10.3 / 10.8 s 142.1 / 142.4 s 75.8 / 77.1 s
harness + the four, before → harness, after (run 1) 5 → 1 52 → 52 18.6 → 7.2 s 1.8 → 1.6 s 20.4 → 8.8 s
harness + the four, before → harness, after (run 2) 5 → 1 52 → 52 18.5 → 7.4 s 1.7 → 1.6 s 20.2 → 8.9 s

The four files cost 12.4 / 12.3 s on their own; folded, they add about 0.8 s to the harness. The family went from 154.6 s to 142.3 s of CPU (−8.0 %), wall −8 %. The A/B ran on e673f7c6, the pre-merge commit of this fold; its plugin-gantt tree is byte-identical to this branch's 7cbfc512, and the head adds one comment-only commit (6a0388d8).

Acceptance notes

  • Why this cluster and not the biggest one left. The largest cluster still unfolded is 18 pins that mock ./GanttView only, 3,722 lines; moving them into a harness changes about twice that, over 7,000 lines, which no single PR under the 3,000-line bar can carry. Amendment 2 has a family's second PR fold the next cluster that fits, and these four are the pins left on the harness's own mock set.
  • ObjectGantt.elementDataSource stays its own file. It shares the harness's three mocks, but ui/apps/console/src/__tests__/registry-inputs-spec-parity.test.ts names its path as the object-gantt.dataSource pin, and that ledger fails when the file is gone. The ledger is outside the claim's file surface.
  • Unfolded ObjectGantt* pins (amendment 2: listed in the family's last PR). 39 files in ui/packages/plugin-gantt/src/, by the setup they share; ObjectGantt.test.tsx is the component's main suite, not a per-issue pin, and is not counted. Lines at this PR's head.
setup the files share files (lines) lines
./GanttView stand-in only (real sonner, real @object-ui/plugin-detail) contractEnvelope-6839 (328), currencyDep (296), currencyMode-10422 (136), dateLocale (132), discardedConfigMemo (124), invalidBlockRefusal-13459 (102), numberLocale (333), numberResolvedWidth-11254 (195), percentResolvedWidth-11254 (158), persistfilters (113), quickfilter.i18n.fallback (84), quickfilter.i18n (149), quickfilter (377), readback (152), referenceArms-6837 (316), staleReloadFinally-7231 (359), unconfiguredRefusal-7070 (187), writeGrant-12082 (181) 3722
./GanttView stand-in and a sonner mock (error + success; writeerror mocks error only), real @object-ui/plugin-detail errorClears-10578 (339), refreshInPlace-7237 (288), silentOvertake-10633 (367), writeerror (112) 1106
no vi.mock at all (real GanttView) configPin (218), exportFileName.i18n (222), pluginDriverTree (136), taskColumnLabel-27386 (96) 672
./GanttView and ./ResourceWorkload stand-ins (viewmode's workload stand-in also writes viewMode) blockPrecedence (281), dependencyAlias (140), viewmode (112) 533
@object-ui/plugin-detail with RecordDetailPanel replaced (a different stand-in in each), plus sonner in drawerfetch and hostRowClick-27057 drawerfetch (171), drawerlock (91), hostRowClick-27057 (155) 417
an @object-ui/react useNavigationOverlay spy and sonner; navigationModeResolution-7334 stubs the record drawer, navigationPageSink-7334 replaces RecordDetailPanel navigationModeResolution-7334 (225), navigationPageSink-7334 (253) 478
@object-ui/components NavigationOverlay wrapped, plus sonner (overlayShellModes-9299 also mocks @object-ui/plugin-detail and @object-ui/react) navWidthDefault (235), overlayShellModes-9299 (292) 527
the harness's three mocks plus a patched react (useMemo, useCallback) discardedReloadIdentity-10036 (348) 348
@object-ui/permissions (usePermissions) mocked expandFls-7230 (225) 225
the harness's three mocks, but ui/apps/console's registry-inputs-spec-parity.test.ts ledger names this path (outside the claim), so it stays a file elementDataSource (243) 243
total 39 files 8271

Verification

At head 6a0388d8, after pnpm install --frozen-lockfile and building the closure (turbo run build for @objectstack/spec, formula, lint, client, metadata-protocol, then --filter='@object-ui/plugin-gantt^...' from ui/), under os-verify-lock, VERDICT command-exit 0:

  • pnpm exec vitest run packages/plugin-gantt/ --maxWorkers=2 from ui/: 96 files passed, 1 skipped; 788 tests passed, 114 skipped. Four fewer files than at main, the same 788 / 114 tests; the skipped file and tests are skipped on main too.
  • pnpm run type-check in ui/packages/plugin-gantt (tsc --noEmit && tsc -p tsconfig.test.json): exit 0, 0 error TS.
  • pnpm run lint in ui/packages/plugin-gantt: exit 0, 0 errors. eslint from ui/ on the 14 added or modified files: exit 0, 0 errors, 173 warnings. The harness's 63 warnings are the 43 the test(plugin-gantt): fold seven ObjectGantt fetch and row pins onto one shared harness #30725 harness had plus the 20 the four former files gave at f18fd963; the other 13 files changed comment or description text only.
  • Derived gates (node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, change set 18 paths against merge base 447226b2): 26 derived, 26 run under os-verify-lock (VERDICT command-exit 0), each exit 0 captured before any pipe; pnpm --dir ui exec vitest run scripts/ gave 170 files passed and 2 skipped, 4970 tests passed. --ran reconciliation: 26 derived, 26 run, 0 NOT-MEASURED, 0 UNRUN.
  • Size: git diff --shortstat origin/main HEAD is 18 files, +734 / -788, 1,522 changed lines. No open pull request touches any of the 18 files (file lists of all open PRs read after test(plugin-gantt): fold seven ObjectGantt fetch and row pins onto one shared harness #30725 merged).
  • No ablation: no tested behaviour changed; the assertions moved verbatim.

Human Minimum

  • 1. Schemas start as Zod; packages/spec holds no runtime logic. (packages/spec not touched.)
  • 2. Every name I added uses the casing for its kind.
  • 3. No formatter ran; pnpm lint passes. (ui/ is linted by its own config; the package lints are above.)
  • 4. One issue, one branch off an up-to-date main, one pull request.
  • 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset. (Nothing publishes: skip-changeset.)
  • 6. packages/spec touched: its generated artifacts are regenerated and committed. (Not touched.)
  • 7. No hand edits to content/docs/references/, packages/*/CHANGELOG.md or content/docs/releases/.
  • 8. Title, body and comments are in English (the maintainer quick-read is the allowed Chinese section).

Generated by Claude Code

🤖 Generated with Claude Code

https://claude.ai/code/session_01L6bhgXNVxCQk1CCy55gFjQ

…arness

The colorFieldLadder-7243, invalidationRefetch-10035, propertiesBag-10859
and retiredApiProvider-12325 pins render the real ObjectGantt over the
same three mocks as the harness's first seven blocks. Each becomes a
top-level describe named after its former file, its GanttView stand-in
installed through the standIns slot in a beforeEach, everything else
moved verbatim. The sonner mock becomes the union of the blocks' mocks
(error and success). ObjectGantt.elementDataSource stays its own file:
the console's registry-inputs-spec-parity ledger names its path.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L6bhgXNVxCQk1CCy55gFjQ
…ess block

Twelve test files in eight workspace packages named one of the eleven ObjectGantt
pin files now folded into plugin-gantt's ObjectGantt.harness.test.tsx.
Each now names the block (the former file's stem) and the harness file.
Comment and description text only; the five source files that name a
folded file are left as they are.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L6bhgXNVxCQk1CCy55gFjQ
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Nov 6, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:ui#1 · os-sales · session_01L6bhgWn6zhNa4LL7VB1rtL

维护者速读

  • 改了什么:甘特图组件再把 4 个用同一套 mock 的单卡测试文件并进 test(plugin-gantt): fold seven ObjectGantt fetch and row pins onto one shared harness #30725 建的共享测试文件 ObjectGantt.harness.test.tsx,每个原文件变成一个顶层 describe,断言一字未改;另有 12 个测试文件的注释和一条台账说明文字,把已合并掉的旧文件名改成指向共享文件里的对应块。
  • 为什么改:Tests grow 2.5 times faster than source: measure the per-fix test weight and the #25911 pilot, then roll the shared-setup merge out to the heaviest components or retire it #29469 共享 setup 推广,甘特图族的第二片也是最后一片(席位修订 2 6672694520:每族最多两个 PR)。同机实测这 4 个文件的 CPU 从约 20.3 秒降到并入后约 8.9 秒,整个甘特图测试族快约 8%。
  • 风险与回滚:只动测试文件和注释,不改源码、门禁、CI,不发布任何东西。回滚即撤本 PR。
  • 先看:ui/packages/plugin-gantt/src/ObjectGantt.harness.test.tsx 开头的共享部分(sonner mock 改成并集、槽位类型改成 (props: never)),再看 invalidationRefetch-10035 块的 beforeEach。
  • 两分钟验证:cd ui && pnpm exec vitest run packages/plugin-gantt/src/ObjectGantt.harness.test.tsx,预期 1 个文件 52 例全绿。
  • 需要你做的:无,席位落地。
  • 席位意见:可合。甘特图族到此结束,还没合并的 39 个文件按 setup 分组列在正文里;卡后面还有 ListView、ObjectView、RecordDetailView 三族,所以用 Part of。

席位核对 — ACCEPT · head 6a0388d

  • 形态:18 文件 +734/−788 = 1,522 行。check-governed-merges --pr 30745:0/18 条路径落在受管面,≤ 3000。Part of #29469,目标 main,标签 skip-changeset(只有测试)。删 4 个 pin 文件,harness 改 1 个;另外 13 个文件只改注释或说明文字(12 个测试文件的注释,加 ui/apps/console/src/__tests__/registry-inputs-spec-parity.test.ts 里一条 pins 说明字符串)。全在认领 6671543193 和修订 2 的文件面内,5 个源文件、门禁、CI 和 .changeset/ 都没动。
  • 契约:Clause-② no,Metadata-protocol none,与认领一致。
  • 席位自己复数:从 f18fd963(test(plugin-gantt): fold seven ObjectGantt fetch and row pins onto one shared harness #30725 的 head,4 个原文件还在)和本 PR head 各自计数:4 个原文件 it( 17 = harness 新增 17,expect( 47 = 47;harness 现在 11 个顶层 describe、52 例。没有新增 .only、.skip 或 .todo。13 个旁改文件的 diff 只落在注释和那条说明字符串上。控制台台账检查读的是 pin 的 file(registry-inputs-spec-parity.test.ts:4756),不读 pins 文字,所以改说明不影响它;elementDataSource 因为台账点名它的路径而保留为独立文件,正文写了原因。
  • 前提实测:dev 报告 6673226392。plugin-gantt 全包 96 文件通过、1 跳过,788 例通过、114 跳过,比 main 少 4 个文件、例数相同,跳过的在 main 上同样跳过。type-check、lint 0 错误;派生门禁 26/26 exit 0。没有做消融,因为没有改变任何被测行为。
  • 门禁 check-runs:head 上 60 个,44 success,16 skipped,0 红。mergeable_state clean(base 82142ed65)。
  • 接受的偏差:CPU 前后读数用的是同机本地 A/B,CI 读数只有合并后 main 的全量跑才上传,与 test(plugin-gantt): fold seven ObjectGantt fetch and row pins onto one shared harness #30725 相同。
  • 范围外:继续合并剩下的甘特图 pin 是新卡,按修订 2 由本席在 Tests grow 2.5 times faster than source: measure the per-fix test weight and the #25911 pilot, then roll the shared-setup merge out to the heaviest components or retire it #29469 关闭后提交。
  • 落地条款:中继 pr_ready + automerge_enable。卡不关(Part of),pm:dispatched 保留到最后一族的 Fixes PR 合并。合并后卡线程把分支从最新的 main 重开,开始 ListView 族。

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review November 6, 2026 00:47
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge November 6, 2026 00:47
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Nov 6, 2026
Merged via the queue into main with commit 2436b2f Nov 6, 2026
61 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-3t7ug5 branch November 6, 2026 01:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant