ui cleanup
This commit is contained in:
38
tests/audio-dispose.test.ts
Normal file
38
tests/audio-dispose.test.ts
Normal 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);
|
||||
});
|
||||
Reference in New Issue
Block a user