From 3c8111cf46be6e3028bce4a61cc79cb6bff8305f Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 2 Sep 2026 05:58:16 +0000 Subject: [PATCH] test(console): take the app-shell barrel out of three vi.mock factories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `@object-ui/app-shell` is aliased to `packages/app-shell/src` in `apps/console/vite.config.ts`, so a `vi.mock` factory that calls `importOriginal()` on it transforms the whole barrel graph on demand — 447 lines and thirteen bare side-effect imports. Re-measured on this tree with `performance.now()` around the call: 10019ms, against 237ms for `@object-ui/auth` in the same file. A per-file read of every console test that mocks the package attributes each `importOriginal` to the factory it sits in. The population is three files, not the twelve the path-intersection upper bound suggested: the other nineteen either use no `importOriginal` at all or use it for `../../services/approvalsApi`, `@object-ui/i18n` or `@object-ui/auth`. Each of the three factories overrides most of what its graph reads from the barrel and needs only a handful of real exports, all of which live in submodules that cost ~2.0s together. Timed individually, the barrel still costs 7828ms AFTER every one of those submodules is already loaded — that residue is the side-effect imports and the rest of the package, none of which these tests touch. So the factories now spread those submodules instead of the barrel. Which names each file's graph reads from the barrel was enumerated statically over the whole transitive module graph (~1237 modules per file), not from the paths the tests happen to exercise, and every one of them is an override, a type-only export, or an export of a spread submodule. Three files, same 37 tests, same flags, from the repo root: import phase 13.07s -> 2.64s, transform 17.09s -> 11.27s. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01BGMDbrVa8JjZcCQ7DWYH1b --- .changeset/six-donkeys-shake.md | 7 ++++ .../FormPage.predicateScope.test.tsx | 37 +++++++++++++------ .../src/components/SetupRoute.test.tsx | 22 ++++++++++- .../src/components/StudioRoute.test.tsx | 14 ++++++- 4 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 .changeset/six-donkeys-shake.md diff --git a/.changeset/six-donkeys-shake.md b/.changeset/six-donkeys-shake.md new file mode 100644 index 0000000000..3a674dcb50 --- /dev/null +++ b/.changeset/six-donkeys-shake.md @@ -0,0 +1,7 @@ +--- +--- + +Test-only change to three `apps/console` test files: the `vi.mock('@object-ui/app-shell', …)` +factories no longer call `importOriginal()`, which was transforming the whole source-aliased +barrel graph (measured 10019 ms per file) to reach a handful of real exports. They now spread +only the app-shell submodules those exports live in. No published behaviour changes. diff --git a/apps/console/src/components/FormPage.predicateScope.test.tsx b/apps/console/src/components/FormPage.predicateScope.test.tsx index 48de6d8fad..838d015802 100644 --- a/apps/console/src/components/FormPage.predicateScope.test.tsx +++ b/apps/console/src/components/FormPage.predicateScope.test.tsx @@ -73,14 +73,16 @@ import { FormPage } from './FormPage'; * * This module's graph is the first VALUE request for `@object-ui/app-shell` in * the file (`FormPage` only `import type`s it), so it is what runs the - * `vi.mock('@object-ui/app-shell')` factory's `importOriginal()` below — and - * that specifier is aliased to `packages/app-shell/src` - * (`apps/console/vite.config.ts`), a barrel carrying eight side-effect imports, - * transformed on demand. Measured on an IDLE machine it cost **10204ms** of - * `hop1SessionPrincipal`'s 15000ms budget; the render and the assertions cost - * ~12ms, the same as the seven cases above. Nothing was wrong with the test — - * it was racing the module loader, and lost whenever the transform pipeline was - * saturated by a full-project run. + * `vi.mock('@object-ui/app-shell')` factory below — and that specifier is + * aliased to `packages/app-shell/src` (`apps/console/vite.config.ts`), a barrel + * carrying thirteen side-effect imports, transformed on demand. While that + * factory still called `importOriginal()` the load cost **10204ms** of + * `hop1SessionPrincipal`'s 15000ms budget on an IDLE machine, against ~12ms for + * the render and the assertions. Nothing was wrong with the test — it was + * racing the module loader, and lost whenever the transform pipeline was + * saturated by a full-project run. objectui#6580 took the barrel out of the + * factory; the module-scope import below is what keeps the remaining load out + * of a bounded window. * * Module scope moves that cost into the IMPORT phase, which no test or hook * timeout bounds. `beforeAll` would not do: it is bounded by `hookTimeout` @@ -342,10 +344,23 @@ describe('#6110 controls — green before AND after the fix, by construction', ( * `vi.mock` calls are hoisted above every import in the file, so the factories * are registered before that import executes. */ -vi.mock('@object-ui/app-shell', async (importOriginal) => { - const actual = await importOriginal>(); +// The barrel is aliased to `packages/app-shell/src`, so an `importOriginal()` +// on it transforms that whole graph on demand — 10204ms when objectui#6567 +// instrumented it, 10019ms re-measured for objectui#6580. The three submodules +// below carry every name this file's graph reads from the barrel and cost a few +// ms together: `ExpressionProvider`, `buildExpressionUser` (`expressionUser`) +// and `resolveHostAppSegment` (`utils/`). +vi.mock('@object-ui/app-shell', async () => { return { - ...actual, + ...(await vi.importActual>( + '../../../../packages/app-shell/src/providers/ExpressionProvider' + )), + ...(await vi.importActual>( + '../../../../packages/app-shell/src/providers/expressionUser' + )), + ...(await vi.importActual>( + '../../../../packages/app-shell/src/utils/index' + )), useMetadata: () => ({ apps: [] }), useNavigationContext: () => ({ currentAppName: undefined }), DefaultHomeLayout: ({ children }: { children?: unknown }) => children as never, diff --git a/apps/console/src/components/SetupRoute.test.tsx b/apps/console/src/components/SetupRoute.test.tsx index c853773de0..741a254abf 100644 --- a/apps/console/src/components/SetupRoute.test.tsx +++ b/apps/console/src/components/SetupRoute.test.tsx @@ -68,8 +68,26 @@ vi.mock('../../../../packages/app-shell/src/providers/MetadataProvider', async ( useMetadata: () => ({ apps, objects: [], loading: false, error: null, refresh: async () => {} }), })); -vi.mock('@object-ui/app-shell', async (importOriginal) => ({ - ...(await importOriginal>()), +// `@object-ui/app-shell` is aliased to `packages/app-shell/src` +// (`apps/console/vite.config.ts`), so an `importOriginal()` on it transforms the +// whole barrel graph on demand — measured on this tree at **10019ms** +// (objectui#6580). The three submodules below carry every name this file's graph +// reads from the barrel and cost ~2.0s together: `chrome/` has +// `RedirectWithSplash`, `console/ConsoleShell` has `SetupRedirect`, +// `SETUP_APP_PACKAGE_ID` and `SETUP_APP_NAME`. +vi.mock('@object-ui/app-shell', async () => ({ + ...(await vi.importActual>( + '../../../../packages/app-shell/src/chrome/index' + )), + ...(await vi.importActual>( + '../../../../packages/app-shell/src/console/ConsoleShell' + )), + // `RootLandingRedirect` reads `useMetadata` through the BARREL, so the + // provider mock above — which only reaches importers of the provider module + // itself — does not cover it. The whole-barrel spread this factory used to do + // covered it by re-exporting the already-mocked provider; spelling the same + // stub out here keeps that, and is why the two must stay in step. + useMetadata: () => ({ apps, objects: [], loading: false, error: null, refresh: async () => {} }), // Pass-through: the provider stack is not what decides this question. ConnectedShell: ({ children }: { children?: React.ReactNode }) => <>{children}, RequireOrganization: ({ children }: { children?: React.ReactNode }) => <>{children}, diff --git a/apps/console/src/components/StudioRoute.test.tsx b/apps/console/src/components/StudioRoute.test.tsx index d50566c3e8..87a67b22e5 100644 --- a/apps/console/src/components/StudioRoute.test.tsx +++ b/apps/console/src/components/StudioRoute.test.tsx @@ -90,8 +90,18 @@ vi.mock('../../../../packages/auth/src/useAuth', async (importOriginal) => ({ const builderLanding = vi.fn(); const designSurface = vi.fn(); -vi.mock('@object-ui/app-shell', async (importOriginal) => ({ - ...(await importOriginal>()), +// `@object-ui/app-shell` is aliased to `packages/app-shell/src` +// (`apps/console/vite.config.ts`), so an `importOriginal()` on it transforms the +// whole barrel graph on demand: measured on this tree at **10019ms**, against +// 237ms for `@object-ui/auth` in this same file (objectui#6580). Every name this +// file's graph reads from the barrel is either overridden below or lives in +// `chrome/`, so the factory pulls that ONE submodule (**549ms**) instead. +// `RedirectWithSplash` is the only real export left standing: `ProtectedRoute` +// renders it for the unauthenticated case, which this file asserts. +vi.mock('@object-ui/app-shell', async () => ({ + ...(await vi.importActual>( + '../../../../packages/app-shell/src/chrome/index' + )), // Pass-through: the provider stack is not what decides this question. ConnectedShell: ({ children }: { children?: React.ReactNode }) => <>{children}, RequireOrganization: ({ children }: { children?: React.ReactNode }) => <>{children},