Repository navigation
Commit 447226b
test(plugin-gantt): fold seven ObjectGantt fetch and row pins onto one shared harness (#30725)
<!-- claude-projects-attribution: {"github_login":"os-sales"} -->
_Requested by **Sales** · [project
thread](https://claude.ai/code/project/chan_01D5bWFY3rFzgJcytD5gD4Uu?thread=cmsg_01D5bWFY3rFzgJcytD5gD4UuDYk72QQ4SmR4iyCBay2TWJ)_
Part of #29469
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么**:甘特图组件 7 个按 issue 单独成文件的测试,合并进一个共享测试文件
`ObjectGantt.harness.test.tsx`,每个原文件变成文件里一个顶层 `describe`;断言一字未改。
- **为什么改**:这 7 个文件用同一套 mock,却各自重新加载整张模块图,时间几乎全花在加载上。合并后只加载一次:本地同机实测这 7 个
pin 从 20.8 s CPU 降到 8.3 s(-60%),整个 ObjectGantt 测试族 -10%。
- **风险与回滚**:只动测试文件,不发布任何东西;风险是块与块之间串状态,已全包跑绿排除。回滚 = revert 本 PR。
- **先看**:`ObjectGantt.harness.test.tsx` 开头 70 行(共享 mock 与 `standIns`
槽位);再看任一块的 `beforeEach`。
- **两分钟验证**:在 `ui/` 下跑 `pnpm exec vitest run
packages/plugin-gantt/src/ObjectGantt.harness.test.tsx`,应见 1 个文件、35
个测试全过。
- **需要你做的**:无,席位落地。
## What changes
Slice 1 of the `ObjectGantt*` family in the shared-setup rollout that
ruling 6583487846 on #29469 orders, in the shape of the #25911 pilot (PR
#26309). Seven `ObjectGantt` pins render the real `ObjectGantt` over the
same three mocks: `sonner`'s toast, a `./GanttView` stand-in, and
`@object-ui/plugin-detail` with `RecordDetailDrawer` and
`deriveRecordPageHref` stubbed out. Only the `GanttView` stand-in
differed between them, in which task attributes it writes to the DOM.
They now live in one new file,
`ui/packages/plugin-gantt/src/ObjectGantt.harness.test.tsx`:
- Each former file is a top-level `describe` named after it
(`ObjectGantt.fetchGate-7225` and so on), with its docblock above it.
- The `./GanttView` mock reads a `vi.hoisted` slot
(`standIns.ganttView`), and each block installs its own stand-in,
verbatim, in a `beforeEach`.
- Everything that was module-level in a former file (fixtures, adapters,
call logs, helpers, hooks) moved inside its block unchanged, re-indented
by two spaces. A sorted line diff of each former file against its block
shows only the license header, the imports, the three `vi.mock` calls
and the wrapper lines.
- The `sonner` and `plugin-detail` mocks were byte-identical in all
seven files and are declared once.
- `./index` is imported once (one block renders through
`SchemaRenderer`), so `object-gantt` is registered for the whole file.
No block asserts that key absent.
The test-only diff: no `src` file, no changeset (`skip-changeset`:
`@object-ui/plugin-gantt` ships `dist`, `README.md`, `CHANGELOG.md` and
`LICENSE` only). Besides the move, comments that named a folded file now
name its block: five inside the harness, one in
`ObjectGantt.expandFls-7230.test.tsx` and one in
`__tests__/recordSourceInputs-10394.test.tsx`.
## Why
Every `dom`-project test file pays a fixed cost (environment, setup and
the module graph) before its first test runs, and for these seven that
fixed cost was about 95 % of their CPU (19.9 of 20.9 s, run 1). One
harness file pays it once. #29469 rolls the #25911 pilot out component
by component; this is the first `ObjectGantt` slice.
## Tests
### Former file → describe (no title or assertion dropped)
Mechanical count: a TypeScript AST walk of each former file at
`4bf9a2d7e` (`it`/`test` titles and `expect(` calls) 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.fetchGate-7225.test.tsx` | 5 | 5 | 15 | 15 | yes |
| `ObjectGantt.rowCeiling-7210.test.tsx` | 4 | 4 | 15 | 15 | yes |
| `ObjectGantt.hostDataProp-7210.test.tsx` | 2 | 2 | 9 | 9 | yes |
| `ObjectGantt.emptyHostData-7333.test.tsx` | 5 | 5 | 16 | 16 | yes |
| `ObjectGantt.inlineQueryKeys-8769.test.tsx` | 8 | 8 | 23 | 23 | yes |
| `ObjectGantt.searchTerm-10250.test.tsx` | 7 | 7 | 16 | 16 | yes |
| `ObjectGantt.ruleArrayFilter-10767.test.tsx` | 4 | 4 | 12 | 12 | yes |
| **total** | 35 | 35 | 106 | 106 | yes |
The run agrees: the seven files reported 35 passed tests, and the
harness reports the same 35.
### CPU before and after (local A/B, one machine)
**CI after: NOT MEASURED.** The per-file timings reporter (#29517)
uploads its reports on `main`'s full-battery `push` and `schedule` runs
only, never on a pull request, and `ui/scripts/test-shard-timings.json`
was last regenerated on 2026-10-19. The first CI after-reading is the
first full-battery run on `main` after this merges. The CI
before-reading from that dataset is 35.6 s of module time for the seven
files.
Local A/B on one 4-vCPU container, same command both legs, run twice
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 is `4bf9a2d7e`'s seven files restored into this
branch's tree and the harness removed, so both legs run the same 49
other files. Shared-box seconds.
| | files | tests passed | fixed CPU | test CPU | total CPU | wall |
|---|--:|--:|--:|--:|--:|--:|
| ObjectGantt family, before (run 1 / run 2) | 56 | 327 | 164.0 / 165.3
s | 11.0 / 11.1 s | 174.9 / 176.4 s | 92.6 / 94.1 s |
| ObjectGantt family, after (run 1 / run 2) | 50 | 327 | 146.7 / 145.1 s
| 11.1 / 10.6 s | 157.8 / 155.7 s | 84.1 / 83.2 s |
| the seven pins alone, before → after (run 1) | 7 → 1 | 35 → 35 | 19.9
→ 7.4 s | 1.0 → 0.8 s | 20.9 → 8.2 s | |
| the seven pins alone, before → after (run 2) | 7 → 1 | 35 → 35 | 19.6
→ 7.6 s | 1.1 → 0.8 s | 20.7 → 8.3 s | |
The seven pins went from 20.8 s to 8.3 s of CPU (−60 %), and the family
from 175.7 s to 156.8 s (−10.8 %), wall −10 %. Each folded file saved
about 2.1 s of fixed cost on this box; the harness's own fixed cost (7.5
s) is that of one cold file. The A/B ran on `10033623`; the head adds
one comment-only commit (`f18fd963`).
## Acceptance notes
- **Why seven and not the whole family.** The 55 `ObjectGantt.*` pin
files carry 29 different `GanttView` stand-ins and seven different mock
sets. These seven share one mock set exactly, and folding them moves
2,650 changed lines, under the 3,000-line bar. The other files on the
same three mocks (`colorFieldLadder-7243`, `elementDataSource`,
`invalidationRefetch-10035`, `propertiesBag-10859`,
`retiredApiProvider-12325`) are the family's next slice, into this same
file, after this one merges.
- **References outside this PR's file surface still name the old
files.** Five source files (`ObjectGantt.tsx`, `index.tsx`,
`plugin-timeline/src/ObjectTimeline.tsx`,
`plugin-list/src/ListView.tsx`, `plugin-view/src/ObjectView.tsx`) and
seven test files in other packages (`plugin-list` ×5, `react` ×1,
`plugin-view` ×1) mention a folded file by name in a comment. The claim
forbids source edits, and the stems still find the right block: `git
grep ObjectGantt.hostDataProp-7210` lands on its `describe` in the
harness. Noted, not filed.
- The `react-i18next` `NO_I18NEXT_INSTANCE` warning printed once per
former file before, and once for the harness now. It was there before
this change.
## Verification
At head `f18fd963`:
- `pnpm exec vitest run packages/plugin-gantt/ --maxWorkers=2` from
`ui/`: 100 files passed, 1 skipped; 788 tests passed, 114 skipped. 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`), after `turbo run build
--filter='@object-ui/plugin-gantt^...'`: exit 0, 0 `error TS`. `tsc -p
tsconfig.test.json --listFilesOnly` lists the harness (101 test files in
the program).
- `eslint` on the harness: 0 errors, 43 warnings, all `no-explicit-any`.
The seven former files gave the same 43 warnings at `4bf9a2d7e`.
- `pnpm run lint` in `ui/packages/plugin-gantt`: exit 0, 0 errors.
- Derived gates (`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`): 26 derived, 26 run, each exit 0 (24 quick
checks re-run at `f18fd963`; `pnpm check:type-check-debt` and `pnpm
--dir ui exec vitest run scripts/`, 170 files passed and 2 skipped, 4970
tests passed). `--ran` reconciliation: 26 derived, 26 run, 0
NOT-MEASURED.
- Size: `git diff --shortstat 4bf9a2d f18fd96` is 10 files, +1297 /
-1353, 2,650 changed lines, under 3,000. The branch merges cleanly onto
`main` at `6ef7f583` (no commit since the base touches `plugin-gantt`).
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(`packages/spec` not touched.)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes. (`ui/` is linted by its
own config; the package lint is above.)
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset. (Nothing
publishes: `skip-changeset`.)
- [x] 6. `packages/spec` touched: its generated artifacts are
regenerated and committed. (Not touched.)
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English (the maintainer
quick-read is the allowed Chinese section).
---
_Generated by [Claude
Code](https://claude.ai/code/session_01L6bhgXNVxCQk1CCy55gFjQ)_
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01L6bhgXNVxCQk1CCy55gFjQ
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent f0ad1f7 commit 447226b
10 files changed
Lines changed: 1297 additions & 1353 deletions
File tree
- ui/packages/plugin-gantt/src
- __tests__
This file was deleted.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
132 | 132 | | |
133 | 133 | | |
134 | 134 | | |
135 | | - | |
| 135 | + | |
136 | 136 | | |
137 | 137 | | |
138 | 138 | | |
| |||
0 commit comments