ui cleanup

This commit is contained in:
2026-08-07 13:38:32 -04:00
parent c8d29ed59d
commit 85cb9fba26
24 changed files with 1839 additions and 1375 deletions

View File

@@ -0,0 +1,38 @@
/**
* Audio backend dispose regression test.
*
* The `q` (quit) action routes through `process.exit(0)`, which bypasses
* Solid's onCleanup (where useAudio's onCleanup disposes the backend). To
* keep spawned players (mpv/ffplay/afplay) from surviving the host, useAudio
* registers a `process.on("exit")` handler that synchronously disposes the
* backend. The exit handler's whole job is "kill the child process", so this
* test pins the contract directly: a backend holding a real spawned subprocess
* must have killed it once `dispose()` returns.
*
* Uses a real `Bun.spawn(["sleep", "60"])` subprocess as a stand-in for the
* player process, injected into the (private) `proc` slot of an MpvBackend —
* mpv/ffplay/afplay all share the identical kill-on-dispose pattern, so
* exercising one is enough to guard the family.
*/
import { test, expect } from "bun:test";
import { MpvBackend } from "../src/utils/audio-player";
test("MpvBackend.dispose() kills the spawned child process", async () => {
const backend = new MpvBackend();
// Inject a real long-lived subprocess as if mpv had been spawned.
const child = Bun.spawn(["sleep", "60"], {
stdout: "ignore",
stderr: "ignore",
stdin: "ignore",
});
(backend as unknown as { proc: typeof child }).proc = child;
// Sanity: the child is alive.
expect(child.killed).toBe(false);
backend.dispose();
// dispose() sent SIGTERM (proc.kill()); wait for the child to exit.
await child.exited;
expect(child.killed).toBe(true);
});