|
|
@@ -0,0 +1,48 @@
|
|
|
+import { afterEach, expect, test } from "bun:test"
|
|
|
+import { Effect } from "effect"
|
|
|
+import fs from "fs/promises"
|
|
|
+import { Instance } from "../../src/project/instance"
|
|
|
+import { disposeAllInstances, provideTestInstance, tmpdir } from "../fixture/fixture"
|
|
|
+
|
|
|
+afterEach(async () => {
|
|
|
+ await disposeAllInstances()
|
|
|
+})
|
|
|
+
|
|
|
+// Regression for PR #25522: when an effectCmd handler does
|
|
|
+// `yield* Effect.promise(async () => { ... await runPromise(svcMethod) ... })`,
|
|
|
+// the inner runPromise creates a fresh fiber after `await` whose Effect context
|
|
|
+// has lost the outer InstanceRef. Services that read `InstanceState.context`
|
|
|
+// then fall back to `Instance.current` ALS, which must be installed at the JS
|
|
|
+// callback boundary (Node ALS persists across awaits, Effect's fiber context
|
|
|
+// does not). `provideTestInstance` mirrors effectCmd's load + ALS-restore wrap.
|
|
|
+// Pins effect-cmd.ts directly: the pattern test below exercises the load +
|
|
|
+// Instance.restore + dispose triple via the shared `provideTestInstance` fixture,
|
|
|
+// so a regression that removed `Instance.restore` from effect-cmd.ts wouldn't
|
|
|
+// fail it. This grep guards the actual production callsite.
|
|
|
+test("effect-cmd.ts wraps the handler body in Instance.restore", async () => {
|
|
|
+ const source = await fs.readFile(new URL("../../src/cli/effect-cmd.ts", import.meta.url), "utf8")
|
|
|
+ expect(source).toContain("Instance.restore(ctx")
|
|
|
+})
|
|
|
+
|
|
|
+test("Instance.current reachable from inner runPromise inside Effect.promise(async)", async () => {
|
|
|
+ await using dir = await tmpdir({ git: true })
|
|
|
+ await provideTestInstance({
|
|
|
+ directory: dir.path,
|
|
|
+ fn: () =>
|
|
|
+ Effect.runPromise(
|
|
|
+ Effect.promise(async () => {
|
|
|
+ await new Promise((r) => setTimeout(r, 5))
|
|
|
+ const current = await Effect.runPromise(
|
|
|
+ Effect.sync(() => {
|
|
|
+ try {
|
|
|
+ return Instance.current
|
|
|
+ } catch {
|
|
|
+ return undefined
|
|
|
+ }
|
|
|
+ }),
|
|
|
+ )
|
|
|
+ expect(current?.directory).toBe(dir.path)
|
|
|
+ }),
|
|
|
+ ),
|
|
|
+ })
|
|
|
+})
|