1import { assert, describe, it } from "@effect/vitest";
2import * as Effect from "effect/Effect";
3import * as PlatformError from "effect/PlatformError";
4import { ChildProcessSpawner } from "effect/process";
5
6import * as AcpError from "../errors.ts";
7import { makeTerminationError } from "./stdio.ts";
8
9describe("ACP child process termination", () => {
10 it.effect("retains the process identifier with the exit code", () =>
11 Effect.gen(function* () {
12 const error = yield* makeTerminationError({
13 pid: ChildProcessSpawner.ProcessId(41),
14 exitCode: Effect.succeed(ChildProcessSpawner.ExitCode(7)),
15 });
16
17 assert.instanceOf(error, AcpError.AcpProcessExitedError);
18 assert.equal(error.pid, 41);
19 assert.equal(error.code, 7);
20 assert.equal(error.message, "ACP process exited with code 7");
21 }),
22 );
23
24 it.effect("retains the process identifier and exact exit-status cause", () =>
25 Effect.gen(function* () {
26 const rootCause = new Error("private process diagnostics");
27 const cause = PlatformError.systemError({
28 _tag: "Unknown",
29 module: "ChildProcess",
30 method: "exitCode",
31 cause: rootCause,
32 });
33 const error = yield* makeTerminationError({
34 pid: ChildProcessSpawner.ProcessId(42),
35 exitCode: Effect.fail(cause),
36 });
37
38 assert.instanceOf(error, AcpError.AcpTransportError);
39 assert.equal(error.pid, 42);
40 assert.strictEqual(error.cause, cause);
41 assert.equal(error.message, "ACP transport operation read-process-exit-status failed.");
42 assert.notInclude(error.message, rootCause.message);
43 }),
44 );
45});