// @vitest-environment jsdom /** * App-shell assembly plugin on the real machinery: bare Context + production * SlotsService + the test-runtime session/workspace doubles. Deliberately NOT * mounted through SlotTestRuntime — its create() installs the capturing * renderer and install() is boot-once; app-shell IS the production installer, * so this bench hands it the uninstalled service exactly as boot does. */ import { afterEach, describe, expect, it, vi } from 'vitest' import { act, cleanup, render } from '@testing-library/react' import { Context } from 'cordis' import { SlotsService } from '@deepseek-ai/dsh-client-runtime/client' import { TestSessions, TestWorkspaces } from '@deepseek-ai/dsh-client-test-runtime' import type { Stabilizer } from '@deepseek-ai/dsh-client-test-runtime' import * as AppShell from '@deepseek-ai/dsh-client-web/src/app-shell.ts' afterEach(cleanup) const stabilize: Stabilizer = async (fn) => { await act(async () => { await fn() }) } async function bench() { const ctx = new Context() await ctx.plugin(SlotsService).await() const slots = ctx.get('slots') as SlotsService ctx.provide('sessions', new TestSessions(stabilize, ctx)) ctx.provide('workspaces', new TestWorkspaces(stabilize)) ctx.provide('layout', { openDetails: vi.fn(), closeDetails: vi.fn() }) const fiber = ctx.plugin({ inject: [...AppShell.inject], apply: AppShell.apply }) await fiber.await() return { ctx, slots, fiber } } describe('app-shell assembly plugin', () => { it('installs the renderer and provides the assembled appShell face', async () => { const { ctx, slots } = await bench() slots.register({ name: 'root' }, () =>
) const shell = ctx.get('appShell') expect(shell).toBeDefined() const view = render(<>{shell!.renderApp()}) expect(view.getByTestId('root-probe')).toBeTruthy() }) it('assembles once: repeated renderApp calls reuse the built closure', async () => { const { ctx, slots } = await bench() slots.register({ name: 'root' }, () =>
) const shell = ctx.get('appShell')! const first = render(<>{shell.renderApp()}) expect(first.getByTestId('root-probe')).toBeTruthy() first.unmount() // Second call rides the cached closure (renderApp ??=) and still renders. const second = render(<>{shell.renderApp()}) expect(second.getByTestId('root-probe')).toBeTruthy() }) it('fiber dispose retracts the service and uninstalls the renderer', async () => { const { ctx, slots, fiber } = await bench() await stabilize(() => fiber.dispose()) expect(ctx.get('appShell')).toBeUndefined() expect(() => slots.renderSlot('root', {})).toThrow('not installed') }) })