Skip to content

Commit

Permalink
refactor: inject a Reporter (implemented as ConsoleReporter) in usage…
Browse files Browse the repository at this point in the history
…Command
  • Loading branch information
tomsquest committed Nov 18, 2024
1 parent bc7fbb6 commit 92d909e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 35 deletions.
38 changes: 13 additions & 25 deletions src/commands.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
import {
type Mock,
afterEach,
beforeEach,
describe,
expect,
spyOn,
test,
} from "bun:test";
import { getCommand, usageCommand } from "./commands.ts";
import { afterEach, describe, expect, mock, test } from "bun:test";
import { type Reporter, getCommand, usageCommand } from "./commands.ts";

describe("getCommand", () => {
test("show config", () => {
Expand Down Expand Up @@ -52,36 +44,32 @@ describe("getCommand", () => {
});

describe("usage", () => {
let consoleLog: Mock<() => void>;
let consoleError: Mock<() => void>;

beforeEach(() => {
consoleLog = spyOn(console, "log");
consoleError = spyOn(console, "error");
});
const infoLog = mock();
const errorLog = mock();
const reporterMock = { info: infoLog, error: errorLog } as Reporter;

afterEach(() => {
consoleLog.mockRestore();
consoleError.mockRestore();
infoLog.mockRestore();
errorLog.mockRestore();
});

test("no error message", async () => {
const cmd = usageCommand();
const cmd = usageCommand({ reporter: reporterMock })();

const result = await cmd();

expect(result.success).toEqual(true);
expect(consoleError).toHaveBeenCalledTimes(0);
expect(consoleLog.mock.calls.join(" ")).toMatch(/Usage: /);
expect(errorLog).toHaveBeenCalledTimes(0);
expect(infoLog.mock.calls.join(" ")).toMatch(/Usage: /);
});

test("with error message", async () => {
const cmd = usageCommand("OMG");
const cmd = usageCommand({ reporter: reporterMock })("OMG");

const result = await cmd();

expect(result.success).toEqual(true);
expect(consoleError.mock.calls.join(" ")).toMatch(/OMG/);
expect(consoleLog.mock.calls.join(" ")).toMatch(/Usage: /);
expect(errorLog.mock.calls.join(" ")).toMatch(/OMG/);
expect(infoLog.mock.calls.join(" ")).toMatch(/Usage: /);
});
});
39 changes: 29 additions & 10 deletions src/commands.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { promises as fs } from "node:fs";
import { EOL } from "node:os";
import { sep } from "node:path";
import { type Result, pipe, success } from "composable-functions";

Expand All @@ -7,16 +8,27 @@ export type Command = {
run: () => Promise<Result>;
};

export type Reporter = {
info(...data: unknown[]): void;
error(...data: unknown[]): void;
};

export const consoleReporter: Reporter = {
info: console.info,
error: console.error,
};

export const usageCommand =
(errorMessage?: string) => async (): Promise<Result> => {
({ reporter }: { reporter: Reporter }) =>
(errorMessage?: string) =>
async (): Promise<Result> => {
if (errorMessage) {
console.error(errorMessage);
console.error(); // blank line
reporter.error(errorMessage + EOL);
}
console.log("Usage: npx mediathequeroubaix <command>");
console.log("Commands:");
console.log(" loans: List all loans");
console.log(" usage: Show this usage information");
reporter.info("Usage: npx mediathequeroubaix <command>");
reporter.info("Commands:");
reporter.info(" loans: List all loans");
reporter.info(" usage: Show this usage information");
return success(undefined);
};

Expand Down Expand Up @@ -76,21 +88,28 @@ export const getCommand = (args: string[]): Command => {
const firstArg = args[0];
switch (firstArg) {
case "usage":
return { type: "usage", run: usageCommand() };
return {
type: "usage",
run: usageCommand({ reporter: consoleReporter })(),
};
case "loans":
return { type: "loans", run: loanCommand };
case "config":
return { type: "config", run: showConfigCommand };
default:
return {
type: "usage",
run: usageCommand(`Unknown command: ${firstArg}`),
run: usageCommand({ reporter: consoleReporter })(
`Unknown command: ${firstArg}`,
),
};
}
}

return {
type: "usage",
run: usageCommand("Missing argument, none provided"),
run: usageCommand({ reporter: consoleReporter })(
"Missing argument, none provided",
),
};
};

0 comments on commit 92d909e

Please sign in to comment.