code-server-2/packages/protocol/test/child_process.test.ts

104 lines
2.7 KiB
TypeScript

import { ChildProcess } from "child_process";
import * as path from "path";
import { Readable } from "stream";
import * as util from "util";
import { createClient } from "@coder/protocol/test";
import { Module } from "../src/common/proxy";
describe("child_process", () => {
const client = createClient();
const cp = client.modules[Module.ChildProcess];
const getStdout = async (proc: ChildProcess): Promise<string> => {
return new Promise((r): Readable => proc.stdout!.once("data", r))
.then((s) => s.toString());
};
describe("exec", () => {
it("should get exec stdout", async () => {
await expect(util.promisify(cp.exec)("echo test", { encoding: "utf8" }))
.resolves.toEqual({
stdout: "test\n",
stderr: "",
});
});
});
describe("spawn", () => {
it("should get spawn stdout", async () => {
const proc = cp.spawn("echo", ["test"]);
await expect(Promise.all([
getStdout(proc),
new Promise((r): ChildProcess => proc.on("exit", r)),
]).then((values) => values[0])).resolves.toEqual("test\n");
});
it("should cat", async () => {
const proc = cp.spawn("cat", []);
expect(proc.pid).toBe(-1);
proc.stdin!.write("banana");
await expect(getStdout(proc)).resolves.toBe("banana");
proc.stdin!.end();
proc.kill();
expect(proc.pid).toBeGreaterThan(-1);
await new Promise((r): ChildProcess => proc.on("exit", r));
});
it("should print env", async () => {
const proc = cp.spawn("env", [], {
env: { hi: "donkey" },
});
await expect(getStdout(proc)).resolves.toContain("hi=donkey\n");
});
it("should eval", async () => {
const proc = cp.spawn("node", ["-e", "console.log('foo')"]);
await expect(getStdout(proc)).resolves.toContain("foo");
});
});
describe("fork", () => {
it("should echo messages", async () => {
const proc = cp.fork(path.join(__dirname, "forker.js"));
proc.send({ bananas: true });
await expect(new Promise((r): ChildProcess => proc.on("message", r)))
.resolves.toMatchObject({
bananas: true,
});
proc.kill();
await new Promise((r): ChildProcess => proc.on("exit", r));
});
});
it("should dispose", (done) => {
setTimeout(() => {
client.dispose();
done();
}, 100);
});
it("should disconnect", async () => {
const client = createClient();
const cp = client.modules[Module.ChildProcess];
const proc = cp.fork(path.join(__dirname, "forker.js"));
const fn = jest.fn();
proc.on("error", fn);
proc.send({ bananas: true });
await expect(new Promise((r): ChildProcess => proc.on("message", r)))
.resolves.toMatchObject({
bananas: true,
});
client.dispose();
expect(fn).toHaveBeenCalledWith(new Error("disconnected"));
});
});