8779c88d79
Co-authored-by: nova28 <17953305+nova28@users.noreply.github.com> Co-authored-by: Carlos Florencio <carlosmflorencio@gmail.com>
119 lines
3.1 KiB
TypeScript
119 lines
3.1 KiB
TypeScript
import type { TFunction } from "i18next";
|
|
import i18next from "i18next";
|
|
import { afterEach, describe, expect, it } from "vitest";
|
|
import {
|
|
formatDuration,
|
|
formatElapsed,
|
|
formatEta,
|
|
formatPhaseLabel,
|
|
formatStalled,
|
|
formatStepLabel,
|
|
formatStepProgress,
|
|
percentDone,
|
|
} from "./format";
|
|
import type { StartupStepSnapshot } from "./types";
|
|
|
|
const t = i18next.t.bind(i18next) as TFunction;
|
|
|
|
afterEach(async () => {
|
|
await i18next.changeLanguage("en");
|
|
});
|
|
|
|
function step(overrides: Partial<StartupStepSnapshot>): StartupStepSnapshot {
|
|
return {
|
|
id: "stores.repositories",
|
|
label_key: "startup.step.stores_repositories",
|
|
measure: "counted",
|
|
unit: "turns",
|
|
elapsed_ms: 0,
|
|
stalled: false,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
describe("formatDuration", () => {
|
|
it("renders singular seconds", () => {
|
|
expect(formatDuration(t, 1000)).toBe("1 second");
|
|
});
|
|
|
|
it("renders plural seconds", () => {
|
|
expect(formatDuration(t, 2000)).toBe("2 seconds");
|
|
});
|
|
|
|
it("renders minutes past the 60s boundary", () => {
|
|
expect(formatDuration(t, 60001)).toBe("2 minutes");
|
|
});
|
|
});
|
|
|
|
describe("formatElapsed", () => {
|
|
it("wraps the duration in the elapsed template", () => {
|
|
expect(formatElapsed(t, 5000)).toBe("5 seconds elapsed");
|
|
});
|
|
});
|
|
|
|
describe("formatEta", () => {
|
|
it("wraps the duration in the eta template", () => {
|
|
expect(formatEta(t, 30000)).toBe("About 30 seconds remaining");
|
|
});
|
|
});
|
|
|
|
describe("formatStalled", () => {
|
|
it("wraps the duration in the stalled template", () => {
|
|
expect(formatStalled(t, 125000)).toBe("Stalled for 3 minutes");
|
|
});
|
|
});
|
|
|
|
describe("formatPhaseLabel", () => {
|
|
it("resolves a known phase", () => {
|
|
expect(formatPhaseLabel(t, "opening_database")).toBe("Opening database");
|
|
});
|
|
});
|
|
|
|
describe("formatStepLabel", () => {
|
|
it("strips the startup. prefix before the namespace lookup", () => {
|
|
expect(formatStepLabel(t, step({ label_key: "startup.step.database_backup" }))).toBe(
|
|
"Database backup",
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("formatStepProgress", () => {
|
|
it("renders the progress-unavailable statement for an opaque step", () => {
|
|
expect(formatStepProgress(t, step({ measure: "opaque" }))).toBe(
|
|
"Progress cannot be measured for this step.",
|
|
);
|
|
});
|
|
|
|
it("pluralizes a counting step's unit off done", () => {
|
|
expect(formatStepProgress(t, step({ measure: "counting", unit: "bytes", done: 1 }))).toBe(
|
|
"1 byte",
|
|
);
|
|
});
|
|
|
|
it("pluralizes a counted step's unit off total", () => {
|
|
expect(
|
|
formatStepProgress(t, step({ measure: "counted", unit: "turns", done: 5, total: 10 })),
|
|
).toBe("5 of 10 turns");
|
|
});
|
|
|
|
it("uses a singular unit when total is 1", () => {
|
|
expect(
|
|
formatStepProgress(t, step({ measure: "counted", unit: "turns", done: 1, total: 1 })),
|
|
).toBe("1 of 1 turn");
|
|
});
|
|
});
|
|
|
|
describe("percentDone", () => {
|
|
it("computes the plain percentage", () => {
|
|
expect(percentDone(5, 10)).toBe(50);
|
|
});
|
|
|
|
it("clamps to 0 when total is 0", () => {
|
|
expect(percentDone(0, 0)).toBe(0);
|
|
});
|
|
|
|
it("clamps above 100", () => {
|
|
expect(percentDone(15, 10)).toBe(100);
|
|
});
|
|
});
|