/** @jsxImportSource @opentui/solid */ import { describe, expect, test } from "bun:test" import { testRender } from "@opentui/solid" import type { Event, GlobalEvent } from "@opencode-ai/sdk/v2" import { onMount } from "solid-js" import { ProjectProvider, useProject } from "../../../src/cli/cmd/tui/context/project" import { SDKProvider } from "../../../src/cli/cmd/tui/context/sdk" import { useEvent } from "../../../src/cli/cmd/tui/context/event" import { createEventSource, createFetch, directory } from "../../fixture/tui-sdk" const projectID = "proj_test" async function wait(fn: () => boolean, timeout = 2000) { const start = Date.now() while (!fn()) { if (Date.now() - start > timeout) throw new Error("timed out waiting for condition") await Bun.sleep(10) } } function event(payload: Event, input: { directory: string; project?: string; workspace?: string }): GlobalEvent { return { directory: input.directory, project: input.project, workspace: input.workspace, payload, } } function vcs(branch: string): Event { return { id: `evt_vcs_${branch}`, type: "vcs.branch.updated", properties: { branch, }, } } function update(version: string): Event { return { id: `evt_update_${version}`, type: "installation.update-available", properties: { version, }, } } async function mount() { const events = createEventSource() const calls = createFetch() const seen: Event[] = [] const workspaces: Array = [] let project!: ReturnType let done!: () => void const ready = new Promise((resolve) => { done = resolve }) const app = await testRender(() => ( { project = ctx.project await project.sync() done() }} seen={seen} workspaces={workspaces} /> )) await ready return { app, emit: events.emit, project, seen, workspaces } } function Probe(props: { seen: Event[] workspaces: Array onReady: (ctx: { project: ReturnType }) => void }) { const project = useProject() const event = useEvent() onMount(() => { event.subscribe((evt, { workspace }) => { props.seen.push(evt) props.workspaces.push(workspace) }) props.onReady({ project }) }) return } describe("useEvent", () => { test("delivers events for the current project", async () => { const { app, emit, seen, workspaces } = await mount() try { emit(event(vcs("main"), { directory: "/tmp/other", project: projectID, workspace: "ws_a" })) await wait(() => seen.length === 1) expect(seen).toEqual([vcs("main")]) expect(workspaces).toEqual(["ws_a"]) } finally { app.renderer.destroy() } }) test("delivers current project events regardless of active workspace", async () => { const { app, emit, project, seen } = await mount() try { project.workspace.set("ws_a") emit(event(vcs("ws"), { directory: "/tmp/other", project: projectID, workspace: "ws_b" })) await wait(() => seen.length === 1) expect(seen).toEqual([vcs("ws")]) } finally { app.renderer.destroy() } }) test("delivers truly global events even when a workspace is active", async () => { const { app, emit, project, seen } = await mount() try { project.workspace.set("ws_a") emit(event(update("1.2.3"), { directory: "global" })) await wait(() => seen.length === 1) expect(seen).toEqual([update("1.2.3")]) } finally { app.renderer.destroy() } }) })