mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-22 16:25:51 +00:00
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:
@@ -6,6 +6,8 @@ import {
|
|||||||
formatNumber,
|
formatNumber,
|
||||||
formatTokens,
|
formatTokens,
|
||||||
formatRelativeTime,
|
formatRelativeTime,
|
||||||
|
formatRelativeTimeAgo,
|
||||||
|
formatLogMetadata,
|
||||||
} from "../format";
|
} from "../format";
|
||||||
|
|
||||||
describe("formatFileSize", () => {
|
describe("formatFileSize", () => {
|
||||||
@@ -153,3 +155,144 @@ describe("formatRelativeTime", () => {
|
|||||||
expect(formatRelativeTime(date, { now })).toBe("2w ago");
|
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(" · ");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user