Skip to content

Commit c483576

Browse files
os-zhuangclaude
andcommitted
test: retire four raised hook timeouts by importing at module scope
Follow-up to #3010 and the §9 rule added in #3015. A sweep for the same anti-pattern — `beforeAll(async () => { await import(…) })`, which bills a cold module transform to `hookTimeout` — found 36 more test files, every single one already carrying a raised timeout, on an escalating ladder: 15s -> 30s -> 60s. That ladder is the evidence that raising the timeout never fixed anything. This takes the four highest-risk ones. Each drops the raised timeout instead of raising it again; the import phase has no test or hook timeout. - `plugin-markdown/src/index.test.ts` (was 15s) — the twin of the file fixed in #3010: same shape, same budget, same comment verbatim ("Increase timeout to 15 seconds for async import"). plugin-kanban proved that budget insufficient by blowing it at 15021ms, and this file's timed portion was already 5.83s of the same 15s. This was a live flake, not a theoretical one. - `plugin-charts/src/index.test.ts` (was 60s) — recharts-backed graph. - `plugin-editor/src/index.test.ts` (was 30s) — Monaco. - `apps/console/.../public-contract.test.ts` (was 60s) — also folds the `let contract` + hook assignment into a module-scope `const`, now that the two side-effect imports are evaluated before the module body. The console file was the delicate one: its assertions pin the eager/lazy registration split (objectui#2953), so the concern was whether moving the imports perturbs what is loaded when. It does not — static imports are evaluated in order before the module body, and the shared setup still runs before this module is imported at all. Its order-sensitive "reaches the lazily-registered blocks before their chunks load" test passes unchanged. Timed portion of each file, isolated (before -> after): plugin-markdown 5.83s -> 2ms plugin-charts 2.22s -> 2ms plugin-editor 1.78s -> 4ms public-contract 345ms -> 3ms Verified: full suite 100% green — 731 files passed / 1 skipped, 8521 tests passed / 24 skipped, zero failures. The `unit` project alone is 297/297 files and 4084/4084 tests, which also confirms no cross-file interference from the new module-scope registrations despite that project running `isolate: false`. Note for anyone baselining locally: the ~19 failures this repo can show on a long-lived worktree are a STALE INSTALL (`node_modules` @objectstack/spec 14.6.0 vs ^17.0.0-rc.0 declared), not a regression. `pnpm install --prefer-offline` clears all of them — hence the all-green run above. Already documented in §9. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent b0172c7 commit c483576

4 files changed

Lines changed: 46 additions & 29 deletions

File tree

apps/console/src/__tests__/public-contract.test.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,23 @@
2525
* silently disappeared; an exact list makes both directions a deliberate edit.
2626
*/
2727

28-
import { describe, it, expect, beforeAll } from 'vitest';
28+
import { describe, it, expect } from 'vitest';
2929
import { ComponentRegistry, PUBLIC_BLOCKS, type PublicComponentConfig } from '@object-ui/core';
30+
// The two graphs whose registrations this file reads. At module scope, NOT
31+
// awaited inside a `beforeAll` — there their cold transform is billed to the
32+
// hook, against `hookTimeout`, which is why this needed a 60s budget. The import
33+
// phase has no test/hook timeout, so the raised timeout goes away rather than
34+
// getting raised again (objectui#3010). See AGENTS.md §9 (test discipline).
35+
//
36+
// Loading them here rather than in a hook does not change WHAT is loaded, so the
37+
// eager/lazy split the assertions below pin is untouched: static imports are
38+
// evaluated in order before the module body, and the shared setup still runs
39+
// before this module is imported at all.
40+
//
41+
// The layout/content primitives (Tier B) …
42+
import '@object-ui/components';
43+
// … and the console's own plugin layer, from the module main.tsx boots from.
44+
import '../register-plugins';
3045

3146
/**
3247
* Every curated tag the console makes available, in `PUBLIC_BLOCKS` order.
@@ -109,15 +124,11 @@ const EXPECTED_LAZY = [
109124
'markdown',
110125
];
111126

112-
let contract: Map<string, PublicComponentConfig>;
113-
114-
beforeAll(async () => {
115-
// The layout/content primitives (Tier B) …
116-
await import('@object-ui/components');
117-
// … and the console's own plugin layer, from the module main.tsx boots from.
118-
await import('../register-plugins');
119-
contract = new Map(ComponentRegistry.getPublicConfigs().map((c) => [c.type, c]));
120-
}, 60000);
127+
// Safe at module scope: the two side-effect imports at the top of this file are
128+
// evaluated before the module body, so every registration is already in place.
129+
const contract: Map<string, PublicComponentConfig> = new Map(
130+
ComponentRegistry.getPublicConfigs().map((c) => [c.type, c]),
131+
);
121132

122133
describe('console ↔ PUBLIC_BLOCKS coverage', () => {
123134
it('exposes every curated block the console ships, eager or lazy', () => {

packages/plugin-charts/src/index.test.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@
66
* LICENSE file in the root directory of this source tree.
77
*/
88

9-
import { describe, it, expect, beforeAll } from 'vitest';
9+
import { describe, it, expect } from 'vitest';
1010
import { ComponentRegistry } from '@object-ui/core';
11+
// Imports all renderers to register them. Module scope, NOT awaited inside a
12+
// `beforeAll` — there the cold transform of the (recharts-backed) renderer graph
13+
// is billed to the hook, which is why this needed a 60s `hookTimeout` to begin
14+
// with. The import phase has no test/hook timeout, so the raised timeout goes
15+
// away rather than getting raised again (objectui#3010).
16+
// See AGENTS.md §9 (test discipline).
17+
import './index';
1118

1219
describe('Plugin Charts', () => {
13-
// Import all renderers to register them
14-
beforeAll(async () => {
15-
await import('./index');
16-
}, 60000);
17-
1820
describe('bar-chart component', () => {
1921
it('should be registered in ComponentRegistry', () => {
2022
const chartBarRenderer = ComponentRegistry.get('bar-chart');

packages/plugin-editor/src/index.test.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@
66
* LICENSE file in the root directory of this source tree.
77
*/
88

9-
import { describe, it, expect, beforeAll } from 'vitest';
9+
import { describe, it, expect } from 'vitest';
1010
import { ComponentRegistry } from '@object-ui/core';
11+
// Imports all renderers to register them. Module scope, NOT awaited inside a
12+
// `beforeAll` — Monaco is a heavy library, and loading it inside the hook billed
13+
// that cost against `hookTimeout`, which is why this needed a 30s budget. The
14+
// import phase has no test/hook timeout, so the raised timeout goes away rather
15+
// than getting raised again (objectui#3010).
16+
// See AGENTS.md §9 (test discipline).
17+
import './index';
1118

1219
describe('Plugin Editor', () => {
13-
// Import all renderers to register them
14-
// Note: Monaco Editor is a heavy library that takes time to load
15-
beforeAll(async () => {
16-
await import('./index');
17-
}, 30000); // 30 second timeout for Monaco Editor initialization
18-
1920
describe('code-editor component', () => {
2021
it('should be registered in ComponentRegistry', () => {
2122
const editorRenderer = ComponentRegistry.get('code-editor');

packages/plugin-markdown/src/index.test.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@
66
* LICENSE file in the root directory of this source tree.
77
*/
88

9-
import { describe, it, expect, beforeAll } from 'vitest';
9+
import { describe, it, expect } from 'vitest';
1010
import { ComponentRegistry } from '@object-ui/core';
11+
// Imports all renderers to register them. Module scope, NOT awaited inside a
12+
// `beforeAll` — there the cold transform of the renderer graph is billed to the
13+
// hook, against `hookTimeout`. That is what made the sibling plugin-kanban test
14+
// blow its raised 15s budget at 15021ms under full parallel load
15+
// (objectui#3010); this file's timed portion was already at 5.83s of the same
16+
// 15s. The import phase has no test/hook timeout, so no raised timeout is
17+
// needed. See AGENTS.md §9 (test discipline).
18+
import './index';
1119

1220
describe('Plugin Markdown', () => {
13-
// Import all renderers to register them
14-
beforeAll(async () => {
15-
await import('./index');
16-
}, 15000); // Increase timeout to 15 seconds for async import
17-
1821
describe('markdown component', () => {
1922
it('should be registered in ComponentRegistry', () => {
2023
const markdownRenderer = ComponentRegistry.get('markdown');

0 commit comments

Comments
 (0)