Sfoglia il codice sorgente

fix(test): release default slot runtime sources symmetrically

imccyu 5 giorni fa
parent
commit
385f651c5f

+ 2 - 1
packages/test-support/client-runtime/src/index.ts

@@ -423,7 +423,7 @@ export class SlotTestRuntime {
 
   /**
    * Tear down: unmount React trees first, then dispose feature fibers, the
-   * root registration, minted session scopes, and persisted test state.
+   * root registration and standard sources, minted session scopes, and persisted test state.
    * Idempotent.
    * @returns completion of the teardown.
    */
@@ -434,6 +434,7 @@ export class SlotTestRuntime {
     for (const view of this.views.splice(0)) view.unmount()
     for (const handle of this.handles.splice(0)) await handle.dispose()
     this.root.release()
+    this.disposeWorkspaceSource()
     this.disposePanelInfoSource()
     await this.sessions.disposeScopes()
     localStorage.clear()

+ 29 - 0
packages/test-support/client-runtime/tests/helpers.client.spec.tsx

@@ -46,6 +46,35 @@ function entry(seq: number): SessionLiveEventEntry {
 }
 
 describe('fixture helpers', () => {
+  it.each([false, true])('retracts default root sources without removing replacements (release first: %s)', async (releaseFirst) => {
+    const runtime = await SlotTestRuntime.create()
+    const hooks = { workspaces: runtime.workspaces.list, panelInfo: runtime.panelInfo }
+    let releaseReplacement: (() => void) | undefined
+    try {
+      if (releaseFirst) {
+        runtime.releaseWorkspaceSource()
+        runtime.releasePanelInfoSource()
+      } else {
+        await runtime.dispose()
+      }
+      releaseReplacement = runtime.slots.provideRoot({ hooks })
+      await runtime.dispose()
+      await runtime.dispose()
+      for (const key of ['workspaces', 'panelInfo'] as const) {
+        expect(() => runtime.slots.provideRoot({ hooks: { [key]: hooks[key] } }))
+          .toThrow(`duplicate root standard hook '${key}'`)
+      }
+    } finally {
+      try {
+        releaseReplacement?.()
+        runtime.releaseWorkspaceSource()
+        runtime.releasePanelInfoSource()
+      } finally {
+        await runtime.dispose()
+      }
+    }
+  })
+
   it('drives panel hooks, retains keyed selection on owner updates, and releases the default source', async () => {
     const runtime = await SlotTestRuntime.create()
     try {