Skip to content

Instantly share code, notes, and snippets.

@LeeCheneler
Created April 13, 2020 22:10
Show Gist options
  • Save LeeCheneler/f5d346fd98ef0a2414e9b1db40c5b451 to your computer and use it in GitHub Desktop.
Save LeeCheneler/f5d346fd98ef0a2414e9b1db40c5b451 to your computer and use it in GitHub Desktop.
run cli command for tests
import { spawn } from "child_process";
import terminate from "terminate";
export interface RunCliCommandOptions {
cwd?: string;
}
export const runCliCommand = (
command: string,
options: RunCliCommandOptions = { cwd: process.cwd() }
) => {
// Setup runner
const [tool, ...args] = command.split(" ");
const runner = spawn(tool, args, {
cwd: options.cwd,
stdio: "pipe",
});
// Set readable encoding
runner.stdout.setEncoding("utf8");
runner.stderr.setEncoding("utf8");
// Store stderr lines
const stdoutLines: string[] = [];
runner.stdout.on("data", (data: string) => {
stdoutLines.push(...data.split("\n"));
});
// Store non-empty stderr lines
const stderrLines: string[] = [];
runner.stderr.on("data", (data: string) => {
stderrLines.push(...data.split("\n"));
});
// Store status code
let status: number | null = null;
runner.on("close", (code) => {
status = code;
});
// Wait until stdout prints line
const waitUntilStdoutLine = (line: string): Promise<void> => {
return new Promise((resolve) => {
runner.stdout.on("data", (data: string) => {
if (data.split("\n").includes(line)) {
resolve();
}
});
});
};
// Wait until stderr prints line
const waitUntilStderrLine = (line: string): Promise<void> => {
return new Promise((resolve) => {
runner.stderr.on("data", (data: string) => {
if (data.split("\n").includes(line)) {
resolve();
}
});
});
};
// Wait for tool to close and provide status code
const waitForStatusCode = (): Promise<number> => {
// Early escape if the tool has already exited as we store the status above
if (status !== null) {
return Promise.resolve(status);
}
return new Promise((resolve) => {
runner.on("close", (code) => {
resolve(code);
});
});
};
// Kill the process
const kill = () => {
terminate(runner.pid);
};
return {
stdoutLines,
stderrLines,
waitUntilStdoutLine,
waitUntilStderrLine,
waitForStatusCode,
kill,
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment