Skip to content

Commit cfc3426

Browse files
committed
test: add global bus wait helper
1 parent 5ad32d4 commit cfc3426

2 files changed

Lines changed: 45 additions & 24 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { GlobalBus, type GlobalEvent } from "@/bus/global"
2+
import { Effect } from "effect"
3+
4+
export function waitGlobalBusEvent(input: {
5+
timeout?: number
6+
message?: string
7+
predicate: (event: GlobalEvent) => boolean
8+
}) {
9+
return Effect.callback<GlobalEvent, unknown>((resume) => {
10+
const cleanup = () => {
11+
clearTimeout(timeout)
12+
GlobalBus.off("event", handler)
13+
}
14+
15+
const handler = (event: GlobalEvent) => {
16+
try {
17+
if (!input.predicate(event)) return
18+
cleanup()
19+
resume(Effect.succeed(event))
20+
} catch (error) {
21+
cleanup()
22+
resume(Effect.fail(error))
23+
}
24+
}
25+
26+
const timeout = setTimeout(() => {
27+
cleanup()
28+
resume(Effect.fail(new Error(input.message ?? "timed out waiting for global bus event")))
29+
}, input.timeout ?? 10_000)
30+
31+
GlobalBus.on("event", handler)
32+
return Effect.sync(cleanup)
33+
})
34+
}
35+
36+
export const waitGlobalBusEventPromise = (input: Parameters<typeof waitGlobalBusEvent>[0]) =>
37+
Effect.runPromise(waitGlobalBusEvent(input))

packages/opencode/test/server/httpapi-instance.legacy.test.ts

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import { afterEach, describe, expect, test } from "bun:test"
22
import { Flag } from "@opencode-ai/core/flag/flag"
3-
import { GlobalBus } from "@/bus/global"
4-
import { Instance } from "../../src/project/instance"
53
import { Server } from "../../src/server/server"
64
import { InstancePaths } from "../../src/server/routes/instance/httpapi/groups/instance"
75
import * as Log from "@opencode-ai/core/util/log"
86
import { resetDatabase } from "../fixture/db"
97
import { disposeAllInstances, tmpdir } from "../fixture/fixture"
8+
import { waitGlobalBusEventPromise } from "./global-bus"
109

1110
void Log.init({ print: false })
1211

@@ -18,20 +17,9 @@ function app() {
1817
}
1918

2019
async function waitDisposed(directory: string) {
21-
return await new Promise<void>((resolve, reject) => {
22-
const timer = setTimeout(() => {
23-
GlobalBus.off("event", onEvent)
24-
reject(new Error("timed out waiting for instance disposal"))
25-
}, 10_000)
26-
27-
function onEvent(event: { directory?: string; payload: { type?: string } }) {
28-
if (event.payload.type !== "server.instance.disposed" || event.directory !== directory) return
29-
clearTimeout(timer)
30-
GlobalBus.off("event", onEvent)
31-
resolve()
32-
}
33-
34-
GlobalBus.on("event", onEvent)
20+
await waitGlobalBusEventPromise({
21+
message: "timed out waiting for instance disposal",
22+
predicate: (event) => event.payload.type === "server.instance.disposed" && event.directory === directory,
3523
})
3624
}
3725

@@ -117,13 +105,9 @@ describe("instance HttpApi", () => {
117105
test("serves instance dispose through Hono bridge", async () => {
118106
await using tmp = await tmpdir()
119107

120-
const disposed = new Promise<string | undefined>((resolve) => {
121-
const onEvent = (event: { directory?: string; payload: { type?: string } }) => {
122-
if (event.payload.type !== "server.instance.disposed") return
123-
GlobalBus.off("event", onEvent)
124-
resolve(event.directory)
125-
}
126-
GlobalBus.on("event", onEvent)
108+
const disposed = waitGlobalBusEventPromise({
109+
message: "timed out waiting for instance disposal",
110+
predicate: (event) => event.payload.type === "server.instance.disposed",
127111
})
128112

129113
const response = await app().request(InstancePaths.dispose, {
@@ -133,6 +117,6 @@ describe("instance HttpApi", () => {
133117

134118
expect(response.status).toBe(200)
135119
expect(await response.json()).toBe(true)
136-
expect(await disposed).toBe(tmp.path)
120+
expect((await disposed).directory).toBe(tmp.path)
137121
})
138122
})

0 commit comments

Comments
 (0)