From 7f9268f147a4553bd1c866f8f1c30a7e7dcdc9e7 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Tue, 12 May 2026 22:04:46 -0400 Subject: [PATCH] test(server): migrate global bus helper to Effect (#27214) --- packages/opencode/test/server/global-bus.ts | 3 - .../test/server/httpapi-config.test.ts | 126 +++++++++++------- 2 files changed, 76 insertions(+), 53 deletions(-) diff --git a/packages/opencode/test/server/global-bus.ts b/packages/opencode/test/server/global-bus.ts index c8d0f92191..24e5cf77b5 100644 --- a/packages/opencode/test/server/global-bus.ts +++ b/packages/opencode/test/server/global-bus.ts @@ -29,6 +29,3 @@ export function waitGlobalBusEvent(input: { ), ) } - -export const waitGlobalBusEventPromise = (input: Parameters[0]) => - Effect.runPromise(waitGlobalBusEvent(input)) diff --git a/packages/opencode/test/server/httpapi-config.test.ts b/packages/opencode/test/server/httpapi-config.test.ts index 26c0fe03e6..7619a0c881 100644 --- a/packages/opencode/test/server/httpapi-config.test.ts +++ b/packages/opencode/test/server/httpapi-config.test.ts @@ -1,10 +1,12 @@ -import { afterEach, describe, expect, test } from "bun:test" +import { afterEach, describe, expect } from "bun:test" import path from "path" import { Server } from "../../src/server/server" import * as Log from "@opencode-ai/core/util/log" +import { Effect, Fiber } from "effect" import { resetDatabase } from "../fixture/db" import { disposeAllInstances, tmpdir } from "../fixture/fixture" -import { waitGlobalBusEventPromise } from "./global-bus" +import { it } from "../lib/effect" +import { waitGlobalBusEvent } from "./global-bus" void Log.init({ print: false }) @@ -12,47 +14,90 @@ function app() { return Server.Default().app } -async function waitDisposed(directory: string) { - await waitGlobalBusEventPromise({ +function waitDisposed(directory: string) { + return waitGlobalBusEvent({ message: "timed out waiting for instance disposal", predicate: (event) => event.payload.type === "server.instance.disposed" && event.directory === directory, }) } +const tmpdirEffect = (options: Parameters[0]) => + Effect.acquireRelease( + Effect.promise(() => tmpdir(options)), + (tmp) => Effect.promise(() => tmp[Symbol.asyncDispose]()), + ) + afterEach(async () => { await disposeAllInstances() await resetDatabase() }) describe("config HttpApi", () => { - test("serves config update through the default server app", async () => { - await using tmp = await tmpdir({ config: { formatter: false, lsp: false } }) - const disposed = waitDisposed(tmp.path) + it.live( + "serves config update through the default server app", + Effect.gen(function* () { + const tmp = yield* tmpdirEffect({ config: { formatter: false, lsp: false } }) + const disposed = yield* waitDisposed(tmp.path).pipe(Effect.forkScoped) - const response = await app().request("/config", { - method: "PATCH", - headers: { - "content-type": "application/json", - "x-opencode-directory": tmp.path, - }, - body: JSON.stringify({ username: "patched-user", formatter: false, lsp: false }), - }) + const response = yield* Effect.promise(() => + Promise.resolve( + app().request("/config", { + method: "PATCH", + headers: { + "content-type": "application/json", + "x-opencode-directory": tmp.path, + }, + body: JSON.stringify({ username: "patched-user", formatter: false, lsp: false }), + }), + ), + ) - expect(response.status).toBe(200) - expect(await response.json()).toMatchObject({ username: "patched-user", formatter: false, lsp: false }) - await disposed - expect(await Bun.file(path.join(tmp.path, "config.json")).json()).toMatchObject({ - username: "patched-user", - formatter: false, - lsp: false, - }) - }) - - test("serves config with active provider model status", async () => { - await using tmp = await tmpdir({ - config: { + expect(response.status).toBe(200) + expect(yield* Effect.promise(() => response.json())).toMatchObject({ + username: "patched-user", formatter: false, lsp: false, + }) + yield* Fiber.join(disposed) + expect(yield* Effect.promise(() => Bun.file(path.join(tmp.path, "config.json")).json())).toMatchObject({ + username: "patched-user", + formatter: false, + lsp: false, + }) + }), + ) + + it.live( + "serves config with active provider model status", + Effect.gen(function* () { + const tmp = yield* tmpdirEffect({ + config: { + formatter: false, + lsp: false, + provider: { + omniroute: { + models: { + "gpt-4o": { + status: "active", + }, + }, + }, + }, + }, + }) + + const response = yield* Effect.promise(() => + Promise.resolve( + app().request("/config", { + headers: { + "x-opencode-directory": tmp.path, + }, + }), + ), + ) + + expect(response.status).toBe(200) + expect(yield* Effect.promise(() => response.json())).toMatchObject({ provider: { omniroute: { models: { @@ -62,26 +107,7 @@ describe("config HttpApi", () => { }, }, }, - }, - }) - - const response = await app().request("/config", { - headers: { - "x-opencode-directory": tmp.path, - }, - }) - - expect(response.status).toBe(200) - expect(await response.json()).toMatchObject({ - provider: { - omniroute: { - models: { - "gpt-4o": { - status: "active", - }, - }, - }, - }, - }) - }) + }) + }), + ) })