Explorar el Código

test(project): migrate instance tests to effect runner (#27215)

Kit Langton hace 4 meses
padre
commit
6fbb08b724
Se han modificado 1 ficheros con 64 adiciones y 41 borrados
  1. 64 41
      packages/opencode/test/project/instance.test.ts

+ 64 - 41
packages/opencode/test/project/instance.test.ts

@@ -1,12 +1,12 @@
-import { afterEach, describe, expect } from "bun:test"
+import { describe, expect } from "bun:test"
 import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
 import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
-import { Deferred, Effect, Fiber, Layer } from "effect"
+import { Deferred, Effect, Fiber, Layer, Queue } from "effect"
 import { InstanceRef } from "../../src/effect/instance-ref"
 import { InstanceRef } from "../../src/effect/instance-ref"
 import { registerDisposer } from "../../src/effect/instance-registry"
 import { registerDisposer } from "../../src/effect/instance-registry"
 import { InstanceBootstrap } from "../../src/project/bootstrap-service"
 import { InstanceBootstrap } from "../../src/project/bootstrap-service"
 import { Instance } from "../../src/project/instance"
 import { Instance } from "../../src/project/instance"
 import { InstanceStore } from "../../src/project/instance-store"
 import { InstanceStore } from "../../src/project/instance-store"
-import { disposeAllInstances, TestInstance, tmpdirScoped } from "../fixture/fixture"
+import { TestInstance, tmpdirScoped } from "../fixture/fixture"
 import { testEffect } from "../lib/effect"
 import { testEffect } from "../lib/effect"
 
 
 let bootstrapRun: Effect.Effect<void> = Effect.void
 let bootstrapRun: Effect.Effect<void> = Effect.void
@@ -19,10 +19,19 @@ const it = testEffect(
   Layer.mergeAll(InstanceStore.defaultLayer, CrossSpawnSpawner.defaultLayer).pipe(Layer.provide(noopBootstrap)),
   Layer.mergeAll(InstanceStore.defaultLayer, CrossSpawnSpawner.defaultLayer).pipe(Layer.provide(noopBootstrap)),
 )
 )
 
 
-afterEach(async () => {
-  bootstrapRun = Effect.void
-  await disposeAllInstances()
-})
+const setBootstrap = (run: Effect.Effect<void>) =>
+  Effect.acquireRelease(
+    Effect.sync(() => {
+      bootstrapRun = run
+    }),
+    () =>
+      Effect.sync(() => {
+        bootstrapRun = Effect.void
+      }),
+  )
+
+const registerDisposerScoped = (disposer: (directory: string) => Promise<void>) =>
+  Effect.acquireRelease(Effect.sync(() => registerDisposer(disposer)), (off) => Effect.sync(off))
 
 
 describe("InstanceStore", () => {
 describe("InstanceStore", () => {
   it.live("loads instance context without installing ALS for the caller", () =>
   it.live("loads instance context without installing ALS for the caller", () =>
@@ -43,9 +52,11 @@ describe("InstanceStore", () => {
       const store = yield* InstanceStore.Service
       const store = yield* InstanceStore.Service
       let initializedDirectory: string | undefined
       let initializedDirectory: string | undefined
 
 
-      bootstrapRun = Effect.gen(function* () {
-        initializedDirectory = (yield* InstanceRef)?.directory
-      })
+      yield* setBootstrap(
+        Effect.gen(function* () {
+          initializedDirectory = (yield* InstanceRef)?.directory
+        }),
+      )
       yield* store.load({ directory: dir })
       yield* store.load({ directory: dir })
 
 
       expect(initializedDirectory).toBe(dir)
       expect(initializedDirectory).toBe(dir)
@@ -59,9 +70,11 @@ describe("InstanceStore", () => {
       const store = yield* InstanceStore.Service
       const store = yield* InstanceStore.Service
       let initialized = 0
       let initialized = 0
 
 
-      bootstrapRun = Effect.sync(() => {
-        initialized++
-      })
+      yield* setBootstrap(
+        Effect.sync(() => {
+          initialized++
+        }),
+      )
       const first = yield* store.load({ directory: dir })
       const first = yield* store.load({ directory: dir })
       const second = yield* store.load({ directory: dir })
       const second = yield* store.load({ directory: dir })
 
 
@@ -78,18 +91,22 @@ describe("InstanceStore", () => {
       const release = yield* Deferred.make<void>()
       const release = yield* Deferred.make<void>()
       let initialized = 0
       let initialized = 0
 
 
-      bootstrapRun = Effect.gen(function* () {
-        initialized++
-        yield* Deferred.succeed(started, undefined)
-        yield* Deferred.await(release)
-      })
+      yield* setBootstrap(
+        Effect.gen(function* () {
+          initialized++
+          yield* Deferred.succeed(started, undefined)
+          yield* Deferred.await(release)
+        }),
+      )
       const first = yield* store.load({ directory: dir }).pipe(Effect.forkScoped)
       const first = yield* store.load({ directory: dir }).pipe(Effect.forkScoped)
 
 
       yield* Deferred.await(started)
       yield* Deferred.await(started)
 
 
-      bootstrapRun = Effect.sync(() => {
-        initialized++
-      })
+      yield* setBootstrap(
+        Effect.sync(() => {
+          initialized++
+        }),
+      )
       const second = yield* store.load({ directory: dir }).pipe(Effect.forkScoped)
       const second = yield* store.load({ directory: dir }).pipe(Effect.forkScoped)
 
 
       expect(initialized).toBe(1)
       expect(initialized).toBe(1)
@@ -107,10 +124,12 @@ describe("InstanceStore", () => {
       const store = yield* InstanceStore.Service
       const store = yield* InstanceStore.Service
       let attempts = 0
       let attempts = 0
 
 
-      bootstrapRun = Effect.sync(() => {
-        attempts++
-        throw new Error("init failed")
-      })
+      yield* setBootstrap(
+        Effect.sync(() => {
+          attempts++
+          throw new Error("init failed")
+        }),
+      )
       const failed = yield* store.load({ directory: dir }).pipe(
       const failed = yield* store.load({ directory: dir }).pipe(
         Effect.as(false),
         Effect.as(false),
         Effect.catchCause(() => Effect.succeed(true)),
         Effect.catchCause(() => Effect.succeed(true)),
@@ -118,9 +137,11 @@ describe("InstanceStore", () => {
 
 
       expect(failed).toBe(true)
       expect(failed).toBe(true)
 
 
-      bootstrapRun = Effect.sync(() => {
-        attempts++
-      })
+      yield* setBootstrap(
+        Effect.sync(() => {
+          attempts++
+        }),
+      )
       const ctx = yield* store.load({ directory: dir })
       const ctx = yield* store.load({ directory: dir })
 
 
       expect(ctx.directory).toBe(dir)
       expect(ctx.directory).toBe(dir)
@@ -149,16 +170,17 @@ describe("InstanceStore", () => {
       const reloading = yield* Deferred.make<void>()
       const reloading = yield* Deferred.make<void>()
       const releaseReload = yield* Deferred.make<void>()
       const releaseReload = yield* Deferred.make<void>()
       const disposed: Array<string> = []
       const disposed: Array<string> = []
-      const off = registerDisposer(async (directory) => {
+      yield* registerDisposerScoped(async (directory) => {
         disposed.push(directory)
         disposed.push(directory)
       })
       })
-      yield* Effect.addFinalizer(() => Effect.sync(off))
 
 
       const first = yield* store.load({ directory: dir })
       const first = yield* store.load({ directory: dir })
-      bootstrapRun = Effect.gen(function* () {
-        yield* Deferred.succeed(reloading, undefined)
-        yield* Deferred.await(releaseReload)
-      })
+      yield* setBootstrap(
+        Effect.gen(function* () {
+          yield* Deferred.succeed(reloading, undefined)
+          yield* Deferred.await(releaseReload)
+        }),
+      )
       const reload = yield* store.reload({ directory: dir }).pipe(Effect.forkScoped)
       const reload = yield* store.reload({ directory: dir }).pipe(Effect.forkScoped)
 
 
       yield* Deferred.await(reloading)
       yield* Deferred.await(reloading)
@@ -178,22 +200,24 @@ describe("InstanceStore", () => {
       const dir = yield* tmpdirScoped({ git: true })
       const dir = yield* tmpdirScoped({ git: true })
       const store = yield* InstanceStore.Service
       const store = yield* InstanceStore.Service
       const disposing = yield* Deferred.make<void>()
       const disposing = yield* Deferred.make<void>()
-      const releaseDispose = yield* Deferred.make<void>()
+      const releaseDispose = yield* Queue.unbounded<() => void>()
       const disposed: Array<string> = []
       const disposed: Array<string> = []
-      const off = registerDisposer(async (directory) => {
+      yield* registerDisposerScoped((directory) => {
         disposed.push(directory)
         disposed.push(directory)
         Deferred.doneUnsafe(disposing, Effect.void)
         Deferred.doneUnsafe(disposing, Effect.void)
-        await Effect.runPromise(Deferred.await(releaseDispose))
+        return new Promise<void>((resolve) => {
+          Queue.offerUnsafe(releaseDispose, resolve)
+        })
       })
       })
-      yield* Effect.addFinalizer(() => Effect.sync(off))
 
 
       yield* store.load({ directory: dir })
       yield* store.load({ directory: dir })
       const first = yield* store.disposeAll().pipe(Effect.forkScoped)
       const first = yield* store.disposeAll().pipe(Effect.forkScoped)
       yield* Deferred.await(disposing)
       yield* Deferred.await(disposing)
+      const release = yield* Queue.take(releaseDispose)
       const second = yield* store.disposeAll().pipe(Effect.forkScoped)
       const second = yield* store.disposeAll().pipe(Effect.forkScoped)
 
 
       expect(disposed).toEqual([dir])
       expect(disposed).toEqual([dir])
-      yield* Deferred.succeed(releaseDispose, undefined)
+      yield* Effect.sync(release)
       yield* Effect.all([Fiber.join(first), Fiber.join(second)])
       yield* Effect.all([Fiber.join(first), Fiber.join(second)])
       expect(disposed).toEqual([dir])
       expect(disposed).toEqual([dir])
     }),
     }),
@@ -205,10 +229,9 @@ describe("InstanceStore", () => {
       const dir2 = yield* tmpdirScoped({ git: true })
       const dir2 = yield* tmpdirScoped({ git: true })
       const store = yield* InstanceStore.Service
       const store = yield* InstanceStore.Service
       const disposed: Array<string> = []
       const disposed: Array<string> = []
-      const off = registerDisposer(async (directory) => {
+      yield* registerDisposerScoped(async (directory) => {
         disposed.push(directory)
         disposed.push(directory)
       })
       })
-      yield* Effect.addFinalizer(() => Effect.sync(off))
 
 
       yield* store.load({ directory: dir1 })
       yield* store.load({ directory: dir1 })
       yield* store.disposeAll()
       yield* store.disposeAll()