mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-15 12:55: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,
|
||||
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(" · ");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user