mirror of
https://github.com/status-im/sourcecred.git
synced 2025-01-30 22:35:02 +00:00
4c433d417e
Summary: This commit introduces the notion of a `Command`, which is simply a function that takes command-line arguments and interacts with the real world. This infrastructure will enable us to write a well-tested CLI. The `Command` interface is asynchronous because commands like `load` need to block on promise resolution (for loading GitHub and Git data). This is annoying for testing, but does not actually appear to be a problem in practice. Test Plan: Unit tests added. See later commits for real-world usage. wchargin-branch: cli-command-infrastructure
79 lines
3.0 KiB
JavaScript
79 lines
3.0 KiB
JavaScript
// @flow
|
|
|
|
import {type Command, handlingErrors} from "./command";
|
|
|
|
describe("cli/command", () => {
|
|
describe("handlingErrors", () => {
|
|
it("passes through arguments appropriately", async () => {
|
|
const expectedArgs = ["arg", "arg", "arg"];
|
|
const expectedStdio = {out: () => {}, err: () => {}};
|
|
let called = false;
|
|
const cmd: Command = async (args, stdio) => {
|
|
expect(args).toBe(expectedArgs);
|
|
expect(args).toEqual(["arg", "arg", "arg"]);
|
|
expect(stdio).toBe(expectedStdio);
|
|
called = true;
|
|
return 0;
|
|
};
|
|
await handlingErrors(cmd)(expectedArgs, expectedStdio);
|
|
expect(called).toBe(true);
|
|
});
|
|
|
|
it("passes through a return value", async () => {
|
|
const cmd: Command = (args) => Promise.resolve(parseInt(args[0], 10));
|
|
const stdio = {out: () => {}, err: () => {}};
|
|
expect(await handlingErrors(cmd)(["0"], stdio)).toBe(0);
|
|
expect(await handlingErrors(cmd)(["1"], stdio)).toBe(1);
|
|
expect(await handlingErrors(cmd)(["2"], stdio)).toBe(2);
|
|
});
|
|
|
|
it("handles a thrown Error", async () => {
|
|
const stdio = {out: jest.fn(), err: jest.fn()};
|
|
const cmd: Command = () => {
|
|
throw new Error("wat");
|
|
};
|
|
const exitCode = await handlingErrors(cmd)([], stdio);
|
|
expect(exitCode).toBe(1);
|
|
expect(stdio.out).toHaveBeenCalledTimes(0);
|
|
expect(stdio.err).toHaveBeenCalledTimes(1);
|
|
expect(stdio.err.mock.calls[0]).toHaveLength(1);
|
|
expect(stdio.err.mock.calls[0][0]).toMatch(/^Error: wat\n *at cmd/);
|
|
});
|
|
|
|
it("handles a thrown string", async () => {
|
|
const stdio = {out: jest.fn(), err: jest.fn()};
|
|
const cmd: Command = () => {
|
|
// This is bad form, but we should try not to die in case clients do it.
|
|
// eslint-disable-next-line no-throw-literal
|
|
throw "wat";
|
|
};
|
|
const exitCode = await handlingErrors(cmd)([], stdio);
|
|
expect(exitCode).toBe(1);
|
|
expect(stdio.out).toHaveBeenCalledTimes(0);
|
|
expect(stdio.err).toHaveBeenCalledTimes(1);
|
|
expect(stdio.err.mock.calls).toEqual([['"wat"']]);
|
|
});
|
|
|
|
it("handles a rejection with an Error", async () => {
|
|
const stdio = {out: jest.fn(), err: jest.fn()};
|
|
const cmd: Command = () => Promise.reject(new Error("wat"));
|
|
const exitCode = await handlingErrors(cmd)([], stdio);
|
|
expect(exitCode).toBe(1);
|
|
expect(stdio.out).toHaveBeenCalledTimes(0);
|
|
expect(stdio.err).toHaveBeenCalledTimes(1);
|
|
expect(stdio.err.mock.calls[0]).toHaveLength(1);
|
|
expect(stdio.err.mock.calls[0][0]).toMatch(/^Error: wat\n *at cmd/);
|
|
});
|
|
|
|
it("handles rejection with a string", async () => {
|
|
const stdio = {out: jest.fn(), err: jest.fn()};
|
|
const cmd: Command = () => Promise.reject("wat");
|
|
const exitCode = await handlingErrors(cmd)([], stdio);
|
|
expect(exitCode).toBe(1);
|
|
expect(stdio.out).toHaveBeenCalledTimes(0);
|
|
expect(stdio.err).toHaveBeenCalledTimes(1);
|
|
expect(stdio.err.mock.calls).toEqual([['"wat"']]);
|
|
});
|
|
});
|
|
});
|