Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,219 @@
import type { ChildProcess } from "node:child_process";
import { EventEmitter } from "node:events";
import { PassThrough, type Readable, type Writable } from "node:stream";
export interface FakeSpawnPlan {
/** Bytes/messages to push to stdout in order (each becomes one "data" event). */
readonly stdout?: readonly Uint8Array[];
readonly stderr?: readonly string[];
/** Exit code emitted on "close". */
readonly exitCode?: number | null;
/** Signal returned on "close" — distinguishes signal-kill cases. */
readonly closeSignal?: NodeJS.Signals | null;
/** Throw via "error" event immediately instead of returning normally. */
readonly spawnError?: Error;
/** Delay (ms) before stdout/stderr/close emission. */
readonly delayMs?: number;
/** If true, never auto-close — caller drives close via `child.kill`. */
readonly hold?: boolean;
/** Echo stdin into stdout (loopback). */
readonly echo?: boolean;
/** Ignore `kill()` calls so SIGTERM->SIGKILL escalation can be exercised. */
readonly ignoreKill?: boolean;
/** Force stdin to be null so the no-stdin guard branch fires. */
readonly noStdin?: boolean;
/**
* Cause `stdin.write()` to return false on first call so the caller has to
* wait on the `drain` event before continuing. Used to exercise the
* backpressure branch in `runEncode`.
*/
readonly stdinBackpressure?: boolean;
/**
* Trigger close on stdin end with these values. Used to exercise the
* `code ?? -1` and `signal ?? ""` fallback branches by feeding `null`.
*/
readonly closeOnStdinEnd?: {
code: number | null;
signal: NodeJS.Signals | null;
};
}
export interface FakeChild extends ChildProcess {
/** Internal hook for tests to manually trigger close. */
triggerClose(code: number, signal?: NodeJS.Signals | null): void;
}
class StubChild extends EventEmitter implements FakeChild {
public stdin: Writable | null;
public stdout: Readable;
public stderr: Readable;
public exitCode: number | null = null;
public signalCode: NodeJS.Signals | null = null;
public pid = 4242;
private closed = false;
public constructor(public plan: FakeSpawnPlan) {
super();
const stdoutStream = new PassThrough();
this.stdout = stdoutStream;
this.stderr = new PassThrough();
if (plan.noStdin === true) {
this.stdin = null;
return;
}
const stdin = new PassThrough();
this.stdin = stdin;
if (plan.stdinBackpressure === true) {
const realWrite = stdin.write.bind(stdin);
let triggered = false;
stdin.write = ((chunk: Buffer | string): boolean => {
realWrite(chunk);
if (!triggered) {
triggered = true;
// Schedule a drain emission so the awaited promise resolves.
setImmediate(() => stdin.emit("drain"));
return false;
}
return true;
}) as typeof stdin.write;
}
if (plan.echo === true) {
stdin.on("data", (c) => stdoutStream.write(c));
stdin.on("end", () => {
stdoutStream.end();
if (plan.hold !== true) {
if (plan.closeOnStdinEnd !== undefined) {
this.triggerClose(
plan.closeOnStdinEnd.code ?? 0,
plan.closeOnStdinEnd.signal
);
} else {
this.triggerClose(plan.exitCode ?? 0);
}
}
});
}
if (plan.closeOnStdinEnd !== undefined && plan.echo !== true) {
stdin.on("end", () => {
this.triggerCloseRaw(
plan.closeOnStdinEnd!.code,
plan.closeOnStdinEnd!.signal
);
});
}
}
public kill(signal?: NodeJS.Signals | number): boolean {
if (this.closed) return false;
const s = typeof signal === "string" ? signal : "SIGTERM";
if (this.plan.ignoreKill === true && s !== "SIGKILL") {
// Pretend the process is stubbornly alive — escalation needed.
return true;
}
this.signalCode = s;
this.triggerClose(0, this.signalCode);
return true;
}
public triggerClose(code: number, signal?: NodeJS.Signals | null): void {
if (this.closed) return;
this.closed = true;
this.exitCode = code;
// Settle on next microtask so listeners attach first.
setImmediate(() => {
this.emit("close", code, signal ?? null);
});
}
/**
* Like `triggerClose` but emits the raw `code` value (including `null`)
* so the runner exercises its `code ?? -1` fallback branch.
*/
public triggerCloseRaw(
code: number | null,
signal: NodeJS.Signals | null
): void {
if (this.closed) return;
this.closed = true;
this.exitCode = code;
setImmediate(() => {
this.emit("close", code, signal);
});
}
public ref(): this {
return this;
}
public unref(): this {
return this;
}
public disconnect(): void {
// no-op stub
}
public send(): boolean {
return true;
}
public get connected(): boolean {
return false;
}
public get killed(): boolean {
return this.closed;
}
public get stdio(): ChildProcess["stdio"] {
return [
this.stdin,
this.stdout,
this.stderr,
null,
null,
] as unknown as ChildProcess["stdio"];
}
public get stdinWritable(): Writable | null {
return this.stdin;
}
public get spawnargs(): string[] {
return [];
}
public get spawnfile(): string {
return "fake-ffmpeg";
}
}
export function makeFakeSpawn(plan: FakeSpawnPlan): {
spawn: (cmd: string, args: readonly string[]) => ChildProcess;
last: () => FakeChild | undefined;
} {
let last: FakeChild | undefined;
return {
spawn(_cmd, _args) {
const child = new StubChild(plan) as FakeChild;
last = child;
// Synchronous error path.
if (plan.spawnError !== undefined) {
setImmediate(() => child.emit("error", plan.spawnError));
return child;
}
const delay = plan.delayMs ?? 0;
setTimeout(() => {
if (plan.echo !== true) {
for (const chunk of plan.stdout ?? []) {
(child.stdout as PassThrough).write(Buffer.from(chunk));
}
}
for (const e of plan.stderr ?? []) {
(child.stderr as PassThrough).write(e);
}
if (plan.hold !== true && plan.echo !== true) {
child.triggerClose(
plan.exitCode ?? 0,
plan.closeSignal ?? null
);
}
}, delay);
return child;
},
last() {
return last;
},
};
}