Skip to content

Commit 447226b

Browse files
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

‎ui/packages/plugin-gantt/src/ObjectGantt.emptyHostData-7333.test.tsx‎

Lines changed: 0 additions & 204 deletions
This file was deleted.

‎ui/packages/plugin-gantt/src/ObjectGantt.expandFls-7230.test.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ function makeDataSource() {
132132
* schema arrived. objectui#7225 ask 2 deleted that first query — the object
133133
* schema now GATES the fetch instead of refining it afterwards, so `reload`
134134
* fires once, with the schema already in hand, and
135-
* `ObjectGantt.fetchGate-7225.test.tsx` pins that count at exactly one.
135+
* the `ObjectGantt.fetchGate-7225` block of `ObjectGantt.harness.test.tsx` pins that count at exactly one.
136136
* `toBeGreaterThan(1)` was therefore not a stronger assertion under the gate,
137137
* it was an unsatisfiable one: it waited for a second query that no longer
138138
* exists, and the six pins below timed out while the behaviour they grade —

0 commit comments

Comments
 (0)