Skip to content

Commit 3685e65

Browse files
committed
Move and refactor child_process tests
1 parent d80f82a commit 3685e65

6 files changed

Lines changed: 103 additions & 22 deletions

File tree

packages/ide/src/fill/child_process.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ class ChildProcess extends CallbackEmitter implements cp.ChildProcess {
6060
}
6161

6262
ae.on("disconnect", () => childProcess.disconnect());
63-
ae.on("kill", (signal) => childProcess.kill(signal));
63+
ae.on("kill", (signal: string) => childProcess.kill(signal));
6464
ae.on("ref", () => childProcess.ref());
65-
ae.on("send", (message, callbackId) => childProcess.send(message, maybeCallback(ae, callbackId)));
65+
ae.on("send", (message: string, callbackId: number) => childProcess.send(message, maybeCallback(ae, callbackId)));
6666
ae.on("unref", () => childProcess.unref());
6767

6868
ae.emit("pid", childProcess.pid);
@@ -72,9 +72,15 @@ class ChildProcess extends CallbackEmitter implements cp.ChildProcess {
7272
childProcess.on("exit", (code, signal) => ae.emit("exit", code, signal));
7373
childProcess.on("message", (message) => ae.emit("message", message));
7474

75-
bindWritable(createUniqueEval(ae, "stdin"), childProcess.stdin);
76-
bindReadable(createUniqueEval(ae, "stdout"), childProcess.stdout);
77-
bindReadable(createUniqueEval(ae, "stderr"), childProcess.stderr);
75+
if (childProcess.stdin) {
76+
bindWritable(createUniqueEval(ae, "stdin"), childProcess.stdin);
77+
}
78+
if (childProcess.stdout) {
79+
bindReadable(createUniqueEval(ae, "stdout"), childProcess.stdout);
80+
}
81+
if (childProcess.stderr) {
82+
bindReadable(createUniqueEval(ae, "stderr"), childProcess.stderr);
83+
}
7884

7985
return {
8086
onDidDispose: (cb): cp.ChildProcess => childProcess.on("close", cb),
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { ChildProcess } from "child_process";
2+
import * as path from "path";
3+
import { Readable } from "stream";
4+
import * as util from "util";
5+
import { createClient } from "@coder/protocol/test";
6+
7+
const client = createClient();
8+
jest.mock("../src/fill/client", () => ({ client }));
9+
const cp = require("../src/fill/child_process") as typeof import("child_process");
10+
11+
describe("child_process", () => {
12+
const getStdout = async (proc: ChildProcess): Promise<string> => {
13+
return new Promise((r): Readable => proc.stdout.on("data", r))
14+
.then((s) => s.toString());
15+
};
16+
17+
describe("exec", () => {
18+
it("should get exec stdout", async () => {
19+
await expect(util.promisify(cp.exec)("echo test", { encoding: "utf8" }))
20+
.resolves.toEqual({
21+
stdout: "test\n",
22+
stderr: "",
23+
});
24+
});
25+
});
26+
27+
describe("spawn", () => {
28+
it("should get spawn stdout", async () => {
29+
const proc = cp.spawn("echo", ["test"]);
30+
await expect(Promise.all([
31+
getStdout(proc),
32+
new Promise((r): ChildProcess => proc.on("exit", r)),
33+
]).then((values) => values[0])).resolves.toEqual("test\n");
34+
});
35+
36+
it("should cat", async () => {
37+
const proc = cp.spawn("cat", []);
38+
expect(proc.pid).toBe(-1);
39+
proc.stdin.write("banana");
40+
await expect(getStdout(proc)).resolves.toBe("banana");
41+
42+
proc.stdin.end();
43+
proc.kill();
44+
45+
expect(proc.pid).toBeGreaterThan(-1);
46+
await new Promise((r): ChildProcess => proc.on("exit", r));
47+
});
48+
49+
it("should print env", async () => {
50+
const proc = cp.spawn("env", [], {
51+
env: { hi: "donkey" },
52+
});
53+
54+
await expect(getStdout(proc)).resolves.toContain("hi=donkey\n");
55+
});
56+
});
57+
58+
describe("fork", () => {
59+
it("should echo messages", async () => {
60+
const proc = cp.fork(path.join(__dirname, "forker.js"));
61+
62+
proc.send({ bananas: true });
63+
64+
await expect(new Promise((r): ChildProcess => proc.on("message", r)))
65+
.resolves.toMatchObject({
66+
bananas: true,
67+
});
68+
69+
proc.kill();
70+
71+
await new Promise((r): ChildProcess => proc.on("exit", r));
72+
});
73+
});
74+
});
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
process.on("message", (data) => {
22
process.send(data);
3-
});
3+
});

packages/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
],
2424
"moduleNameMapper": {
2525
"^.+\\.(s?css|png|svg)$": "<rootDir>/../scripts/dummy.js",
26+
"@coder/ide/src/fill/evaluation": "<rootDir>/ide/src/fill/evaluation",
2627
"@coder/(.*)/test": "<rootDir>/$1/test",
2728
"@coder/(.*)": "<rootDir>/$1/src"
2829
},

packages/vscode/src/fill/node-pty.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ class Pty implements nodePty.IPty {
4242

4343
ptyProc.on("data", (data) => ae.emit("data", data));
4444

45-
ae.on("resize", (cols, rows) => ptyProc.resize(cols, rows));
46-
ae.on("write", (data) => ptyProc.write(data));
47-
ae.on("kill", (signal) => ptyProc.kill(signal));
45+
ae.on("resize", (cols: number, rows: number) => ptyProc.resize(cols, rows));
46+
ae.on("write", (data: string) => ptyProc.write(data));
47+
ae.on("kill", (signal: string) => ptyProc.kill(signal));
4848

4949
return {
5050
onDidDispose: (cb): void => ptyProc.on("exit", cb),

packages/vscode/src/fill/spdlog.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,22 @@ const ae = client.run((ae) => {
99
const spdlog = __non_webpack_require__("spdlog") as typeof import("spdlog");
1010
const loggers = new Map<number, NodeRotatingLogger>();
1111

12-
ae.on("new", (id, name, filePath, fileSize, fileCount) => {
12+
ae.on("new", (id: number, name: string, filePath: string, fileSize: number, fileCount: number) => {
1313
const logger = new spdlog.RotatingLogger(name, filePath, fileSize, fileCount);
1414
loggers.set(id, logger);
1515
});
1616

17-
ae.on("clearFormatters", (id) => loggers.get(id)!.clearFormatters());
18-
ae.on("critical", (id, message) => loggers.get(id)!.critical(message));
19-
ae.on("debug", (id, message) => loggers.get(id)!.debug(message));
20-
ae.on("drop", (id) => loggers.get(id)!.drop());
21-
ae.on("errorLog", (id, message) => loggers.get(id)!.error(message));
22-
ae.on("flush", (id) => loggers.get(id)!.flush());
23-
ae.on("info", (id, message) => loggers.get(id)!.info(message));
24-
ae.on("setAsyncMode", (bufferSize, flushInterval) => spdlog.setAsyncMode(bufferSize, flushInterval));
25-
ae.on("setLevel", (id, level) => loggers.get(id)!.setLevel(level));
26-
ae.on("trace", (id, message) => loggers.get(id)!.trace(message));
27-
ae.on("warn", (id, message) => loggers.get(id)!.warn(message));
17+
ae.on("clearFormatters", (id: number) => loggers.get(id)!.clearFormatters());
18+
ae.on("critical", (id: number, message: string) => loggers.get(id)!.critical(message));
19+
ae.on("debug", (id: number, message: string) => loggers.get(id)!.debug(message));
20+
ae.on("drop", (id: number) => loggers.get(id)!.drop());
21+
ae.on("errorLog", (id: number, message: string) => loggers.get(id)!.error(message));
22+
ae.on("flush", (id: number) => loggers.get(id)!.flush());
23+
ae.on("info", (id: number, message: string) => loggers.get(id)!.info(message));
24+
ae.on("setAsyncMode", (bufferSize: number, flushInterval: number) => spdlog.setAsyncMode(bufferSize, flushInterval));
25+
ae.on("setLevel", (id: number, level: number) => loggers.get(id)!.setLevel(level));
26+
ae.on("trace", (id: number, message: string) => loggers.get(id)!.trace(message));
27+
ae.on("warn", (id: number, message: string) => loggers.get(id)!.warn(message));
2828

2929
const disposeCallbacks = <Array<() => void>>[];
3030

@@ -40,7 +40,7 @@ const ae = client.run((ae) => {
4040

4141
const spdLogger = logger.named("spdlog");
4242
ae.on("close", () => spdLogger.error("session closed prematurely"));
43-
ae.on("error", (error) => spdLogger.error(error.message));
43+
ae.on("error", (error: Error) => spdLogger.error(error.message));
4444

4545
let id = 0;
4646
export class RotatingLogger implements NodeRotatingLogger {

0 commit comments

Comments
 (0)