UNPKG

spawn-rx

Version:

An Rx-version of child_process.spawn

138 lines (123 loc) 4.65 kB
import { describe, expect, it } from "bun:test"; import type { Observable } from "rxjs"; import { of } from "rxjs"; import { spawn, spawnPromise } from "../src/index"; const uuidRegex = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i; describe("The spawnPromise method", () => { it("should return a uuid when we call uuid", async () => { // NB: Since we get run via npm run test, we know that npm bins are in our // PATH. const result = await spawnPromise("uuid", []); expect(result.match(uuidRegex)).toBeTruthy(); }); it("should split stdout and stderr when we call uuid", async () => { // NB: Since we get run via npm run test, we know that npm bins are in our // PATH. const result = await spawnPromise("uuid", [], { split: true }); expect(result[0].match(uuidRegex)).toBeTruthy(); expect(result[1].match(uuidRegex)).toBeFalsy(); }); it("should retur nthe exit code", async () => { // NB: Since we get run via npm run test, we know that npm bins are in our // PATH. try { await spawnPromise("false", [], { split: true }); expect(false).toBe(true); } catch (e: any) { expect(e.code).toBe(1); } }); it("should not stdout and stderr when we call uuid with split false", async () => { // NB: Since we get run via npm run test, we know that npm bins are in our // PATH. const result = await spawnPromise("uuid", [], { split: false }); expect(result.match(uuidRegex)).toBeTruthy(); }); }); function wrapSplitObservableInPromise( obs: Observable<{ source: any; text: any; }>, ): Promise<{ stderr: string; stdout: string; error: Error | undefined; }> { return new Promise((res) => { const out = { stderr: "", stdout: "", error: undefined }; obs.subscribe( (x) => { if (x.source === "stdout") { out.stdout += x.text; } else { out.stderr += x.text; } }, (e) => { out.error = e; res(out); }, () => res(out), ); }); } describe("The spawn method", () => { it("should return a disposable subscription", async () => { // this only check the unsubscribe goes w/o error, not that the spawned process is killed // (difficult to do that, maybe iterate through child processes and check ?) spawn("sleep", ["2"]).subscribe().unsubscribe(); }); it("should return split stderr in a inner tag when called with split", async () => { // provide an invalid param to uuid so it complains on stderr const rxSpawn: Observable<{ source: any; text: any }> = spawn("uuid", ["foo"], { split: true }) as any; const result = await wrapSplitObservableInPromise(rxSpawn); expect(result.stderr.length > 10).toBeTruthy(); expect(result.stdout).toBe(""); expect(result.error).toBeInstanceOf(Error); }); it("should return split stdout in a inner tag when called with split", async () => { const rxSpawn: Observable<{ source: any; text: any }> = spawn("uuid", [], { split: true, }); const result = await wrapSplitObservableInPromise(rxSpawn); expect(result.stdout.match(uuidRegex)).toBeTruthy(); expect(result.stderr).toBe(""); expect(result.error).toBeUndefined(); }); it("should ignore stderr if options.stdio = ignore", async () => { const rxSpawn: Observable<{ source: any; text: any }> = spawn("uuid", ["foo"], { split: true, stdio: [null, null, "ignore"], }); const result = await wrapSplitObservableInPromise(rxSpawn); expect(result.stderr).toBe(""); }); it("should ignore stdout if options.stdio = inherit", async () => { const rxSpawn: Observable<{ source: any; text: any }> = spawn("uuid", [], { split: true, stdio: [null, "inherit", null], }); const result = await wrapSplitObservableInPromise(rxSpawn); expect(result.stdout).toBe(""); }); it("should croak if stdin is provided but stdio.stdin is disabled", async () => { const stdin = of("a"); const rxSpawn: Observable<{ source: any; text: any }> = spawn("marked", [], { split: true, stdin: stdin, stdio: ["ignore", null, null], }); const result = await wrapSplitObservableInPromise(rxSpawn); expect(result.error).toBeInstanceOf(Error); }); it("should subscribe to provided stdin", async () => { const stdin = of("a"); const rxSpawn: Observable<{ source: any; text: any }> = spawn("marked", [], { split: true, stdin: stdin, }); const result = await wrapSplitObservableInPromise(rxSpawn); expect(result.stdout.trim()).toBe("<p>a</p>"); }); });