test.deploy/core/reporters/journal.reporter.test.ts
test.deploy/core/reporters/journal.reporter.test.ts is a file in Codebase Testing. 86 lines of code and 0 definitions.
import { ELLIPSIS, STEP_SUMMARY_LIMIT } from "@banes-lab/deploy/configuration/constants/deployment.constants.ts";
import { afterEach, describe, expect, it, vi } from "vitest";
import {
createByteProgress,
createJournal,
createProgress,
} from "@banes-lab/deploy/core/reporters/journal.reporter.ts";
import { SECONDS_SUFFIX } from "@banes-lab/deploy/configuration/strings/deployment.strings.ts";
describe("createJournal", () => {
afterEach(() => {
vi.restoreAllMocks();
});
it("collects logged and marked steps into the summary", () => {
vi.spyOn(process.stdout, "write").mockReturnValue(true);
const journal = createJournal();
journal.log("first");
journal.mark("second");
const summary = journal.summary();
expect(summary).toContain("first");
expect(summary).toContain("second");
expect(summary).toContain(SECONDS_SUFFIX);
});
it("truncates a summary past the step limit", () => {
vi.spyOn(process.stdout, "write").mockReturnValue(true);
const journal = createJournal();
journal.log("x".repeat(STEP_SUMMARY_LIMIT + 1));
expect(journal.summary().endsWith(ELLIPSIS)).toBe(true);
});
it("draws a live bar in a terminal and records each quarter in the journal", () => {
vi.spyOn(process.stdout, "write").mockReturnValue(true);
const journal = createJournal();
const written: string[] = [];
let clock = 0;
const sink = { isTTY: true, write: (text: string) => written.push(text) > 0 };
const progress = createProgress(
journal,
{ label: "Upload", size: 100, total: 4, unit: "file(s)" },
sink,
() => clock,
);
for (const step of [1, 2, 3, 4]) {
clock = step * 1000;
progress.advance(1, 25, step === 4);
}
progress.finish();
expect(written.some((text) => text.startsWith("\r"))).toBe(true);
expect(written.at(-1)).toBe("\n");
const summary = journal.summary();
expect(summary).toContain("Upload");
expect(summary).toContain("100%: 3 of 4 file(s)");
expect(summary).toContain("1 failed");
});
it("writes one line per step when the output is not a terminal", () => {
vi.spyOn(process.stdout, "write").mockReturnValue(true);
const written: string[] = [];
const sink = { isTTY: false, write: (text: string) => written.push(text) > 0 };
const progress = createProgress(
createJournal(),
{ label: "Upload", size: 100, total: 100, unit: "file(s)" },
sink,
() => 1,
);
for (let step = 0; step < 12; step += 1) {
progress.advance(1, 1, false);
}
expect(written).toHaveLength(2);
expect(written.every((text) => text.endsWith("\n") && !text.startsWith("\r"))).toBe(true);
});
it("turns a byte stream into one transfer that completes once", () => {
vi.spyOn(process.stdout, "write").mockReturnValue(true);
const journal = createJournal();
const sink = { isTTY: false, write: () => true };
const download = createByteProgress(journal, "Backup download", "archive", sink, () => 1);
download.step(50, 100);
download.step(100, 100);
download.step(100, 100);
download.finish();
expect(journal.summary()).toContain("100%: 1 of 1 archive");
});
it("routes errors to the console", () => {
const error = vi.spyOn(console, "error").mockImplementation(() => {});
const journal = createJournal();
journal.error("bad");
expect(error).toHaveBeenCalledWith("bad");
});
});