test(tui): inject renderer factory

This commit is contained in:
LukeParkerDev 2026-06-26 14:37:44 +10:00
commit 7409c954dc
2 changed files with 30 additions and 47 deletions

View file

@ -177,33 +177,35 @@ function isVersionGreater(left: string, right: string) {
return a.prerelease.localeCompare(b.prerelease, undefined, { numeric: true }) > 0
}
export function initializeRenderer(config: TuiConfig.Resolved, factory = createCliRenderer) {
return Effect.tryPromise({
try: () =>
factory({
externalOutputMode: "passthrough",
targetFps: 60,
gatherStats: false,
exitOnCtrlC: false,
useKittyKeyboard: {},
autoFocus: false,
openConsoleOnError: false,
useMouse: !Flag.OPENCODE_DISABLE_MOUSE && config.mouse,
consoleOptions: {
keyBindings: [{ name: "y", ctrl: true, action: "copy-selection" }],
},
}),
catch: (error) => (error instanceof Error ? error : new Error(String(error))),
})
}
export const run = Effect.fn("Tui.run")(function* (input: TuiInput) {
const global = yield* Global.Service
const exit = { epilogue: undefined as string | undefined, reason: undefined as unknown }
const result = yield* Effect.scoped(
Effect.gen(function* () {
const renderer = yield* Effect.acquireRelease(
Effect.tryPromise({
try: () =>
createCliRenderer({
externalOutputMode: "passthrough",
targetFps: 60,
gatherStats: false,
exitOnCtrlC: false,
useKittyKeyboard: {},
autoFocus: false,
openConsoleOnError: false,
useMouse: !Flag.OPENCODE_DISABLE_MOUSE && input.config.mouse,
consoleOptions: {
keyBindings: [{ name: "y", ctrl: true, action: "copy-selection" }],
},
}),
catch: (error) => (error instanceof Error ? error : new Error(String(error))),
const renderer = yield* Effect.acquireRelease(initializeRenderer(input.config), (renderer) =>
Effect.sync(() => {
destroyRenderer(renderer)
}),
(renderer) =>
Effect.sync(() => {
destroyRenderer(renderer)
}),
)
win32DisableProcessedInput()
const keymap = createDefaultOpenTuiKeymap(renderer)

View file

@ -7,34 +7,15 @@ import { createTuiResolvedConfig } from "./fixture/tui-runtime"
import { createEventSource, createFetch, directory, json } from "./fixture/tui-sdk"
test("renderer initialization preserves the original error message", async () => {
const core = await import("@opentui/core")
const message = 'Failed to open library "opentui.dll": error code 126'
mock.module("@opentui/core", () => ({
...core,
createCliRenderer: async () => {
throw new Error(message)
},
}))
try {
const { run } = await import("../src/app")
await expect(
Effect.runPromise(
run({
url: "http://test",
directory,
config: createTuiResolvedConfig({ plugin_enabled: {} }),
args: {},
pluginHost: {
async start() {},
async dispose() {},
},
}).pipe(Effect.provide(Global.defaultLayer)),
),
).rejects.toThrow(message)
} finally {
mock.restore()
const { initializeRenderer } = await import("../src/app")
const factory = async () => {
throw new Error(message)
}
await expect(
Effect.runPromise(initializeRenderer(createTuiResolvedConfig({ plugin_enabled: {} }), factory)),
).rejects.toThrow(message)
})
test("SIGHUP clears title and disposes scoped resources once", async () => {