Deduplicate duration and number formatting internals

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RaRBJFZKSTA7naHGuQHfnQ
This commit is contained in:
2026-07-05 07:44:55 +08:00
co-authored by Claude Fable 5
parent ab1eacc1c2
commit 8b06094978
6 changed files with 207 additions and 190 deletions
+61
View File
@@ -0,0 +1,61 @@
// The Lucia project.
// Copyright 2026-2026 DSP, inc. All rights reserved.
// Authors:
// imacat.yang@dsp.im (imacat), 2026/7/5
// AI assistance: Claude Code (Anthropic)
import { describe, it, expect } from "vitest";
import formatDuration, { pickDurationUnit } from "@/module/formatDuration.js";
describe("formatDuration", () => {
it("formats a full cascade with the default separator", () => {
expect(formatDuration(93784)).toBe("1d 2h 3m 4s");
});
it("omits zero-valued units", () => {
expect(formatDuration(86400)).toBe("1d");
expect(formatDuration(3661)).toBe("1h 1m 1s");
});
it("returns an empty string when no unit qualifies", () => {
expect(formatDuration(0)).toBe("");
expect(formatDuration(NaN)).toBe("");
});
it("supports a custom separator", () => {
expect(formatDuration(90061, { separator: "" })).toBe("1d1h1m1s");
});
it("always appends seconds when alwaysSeconds is set", () => {
expect(formatDuration(0, { alwaysSeconds: true })).toBe("0s");
expect(formatDuration(60, { separator: "", alwaysSeconds: true })).toBe(
"1m0s",
);
});
it("truncates to maxUnits largest units", () => {
expect(formatDuration(93784, { maxUnits: 2 })).toBe("1d 2h");
expect(formatDuration(45, { maxUnits: 2 })).toBe("45s");
});
});
describe("pickDurationUnit", () => {
it("picks the largest unit reached by the value", () => {
expect(pickDurationUnit(86400).symbol).toBe("d");
expect(pickDurationUnit(3600).symbol).toBe("h");
expect(pickDurationUnit(60).symbol).toBe("m");
expect(pickDurationUnit(59).symbol).toBe("s");
});
it("requires strictly more than one unit when exclusive", () => {
expect(pickDurationUnit(86400, true).symbol).toBe("h");
expect(pickDurationUnit(86401, true).symbol).toBe("d");
expect(pickDurationUnit(60, true).symbol).toBe("s");
expect(pickDurationUnit(61, true).symbol).toBe("m");
});
it("falls back to seconds for zero and negative values", () => {
expect(pickDurationUnit(0).symbol).toBe("s");
expect(pickDurationUnit(-100).symbol).toBe("s");
});
});