test: add coverage for formatRelativeTimeAgo and formatLogMetadata (#94)

These two exported functions in src/utils/format.ts had no test
coverage. formatRelativeTimeAgo wraps formatRelativeTime and forces
numeric:'always' for past dates; formatLogMetadata assembles parts
(time, branch, size/count, tag, agentSetting, prNumber) into a
' · '-separated string.

Added 8 tests for formatRelativeTimeAgo covering past dates, future
dates, equal-to-now, and the no-'ago'-for-future invariant. Added
9 tests for formatLogMetadata covering all optional fields and the
separator format.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
JiayuWang(王嘉宇)
2026-04-03 22:17:58 +08:00
committed by GitHub
parent 29db9d99de
commit 465e9f01c6

View File

@@ -6,6 +6,8 @@ import {
formatNumber,
formatTokens,
formatRelativeTime,
formatRelativeTimeAgo,
formatLogMetadata,
} from "../format";
describe("formatFileSize", () => {
@@ -153,3 +155,144 @@ describe("formatRelativeTime", () => {
expect(formatRelativeTime(date, { now })).toBe("2w ago");
});
});
describe("formatRelativeTimeAgo", () => {
const now = new Date("2026-01-15T12:00:00Z");
test("formats past date with 'ago' suffix", () => {
const date = new Date("2026-01-15T11:59:30Z");
const result = formatRelativeTimeAgo(date, { now });
expect(result).toBe("30s ago");
});
test("formats future date without 'ago' suffix", () => {
const date = new Date("2026-01-15T13:00:00Z");
const result = formatRelativeTimeAgo(date, { now });
expect(result).toBe("in 1h");
});
test("formats minutes ago", () => {
const date = new Date("2026-01-15T11:55:00Z");
const result = formatRelativeTimeAgo(date, { now });
expect(result).toBe("5m ago");
});
test("formats hours ago", () => {
const date = new Date("2026-01-15T09:00:00Z");
const result = formatRelativeTimeAgo(date, { now });
expect(result).toBe("3h ago");
});
test("formats days ago", () => {
const date = new Date("2026-01-13T12:00:00Z");
const result = formatRelativeTimeAgo(date, { now });
expect(result).toBe("2d ago");
});
test("handles date equal to now as past", () => {
// date === now, treated as past (not future)
const result = formatRelativeTimeAgo(now, { now });
expect(result).toBe("0s ago");
});
test("uses numeric always for past dates", () => {
// Should always use numeric format for past dates
const date = new Date("2026-01-15T11:59:00Z");
const result = formatRelativeTimeAgo(date, { now });
expect(result).toContain("ago");
});
test("future date does not contain 'ago'", () => {
const date = new Date("2026-01-15T14:00:00Z");
const result = formatRelativeTimeAgo(date, { now });
expect(result).not.toContain("ago");
});
});
describe("formatLogMetadata", () => {
// Use a date very recently in the past so it always shows "Xs ago" or similar
const modified = new Date(Date.now() - 5 * 60 * 1000); // 5 minutes ago
test("includes relative time and message count", () => {
const result = formatLogMetadata({
modified,
messageCount: 10,
});
expect(result).toContain("ago");
expect(result).toContain("10 messages");
});
test("uses fileSize instead of messageCount when provided", () => {
const result = formatLogMetadata({
modified,
messageCount: 5,
fileSize: 1536,
});
expect(result).toContain("1.5KB");
expect(result).not.toContain("messages");
});
test("includes gitBranch when provided", () => {
const result = formatLogMetadata({
modified,
messageCount: 3,
gitBranch: "main",
});
expect(result).toContain("main");
});
test("omits gitBranch when not provided", () => {
const result = formatLogMetadata({
modified,
messageCount: 3,
});
// Should not have a dangling separator from missing branch
expect(result).not.toMatch(/^ · | · $/);
});
test("includes tag when provided", () => {
const result = formatLogMetadata({
modified,
messageCount: 3,
tag: "my-tag",
});
expect(result).toContain("#my-tag");
});
test("includes agentSetting when provided", () => {
const result = formatLogMetadata({
modified,
messageCount: 3,
agentSetting: "custom-agent",
});
expect(result).toContain("@custom-agent");
});
test("includes prNumber when provided", () => {
const result = formatLogMetadata({
modified,
messageCount: 3,
prNumber: 42,
});
expect(result).toContain("#42");
});
test("includes prRepository with prNumber when both provided", () => {
const result = formatLogMetadata({
modified,
messageCount: 3,
prNumber: 99,
prRepository: "owner/repo",
});
expect(result).toContain("owner/repo#99");
});
test("parts are joined with ' · ' separator", () => {
const result = formatLogMetadata({
modified,
messageCount: 5,
gitBranch: "feat/x",
});
expect(result).toContain(" · ");
});
});