Files
2026-10-18 22:42:00 +01:00

63 lines
2.1 KiB
TypeScript

import { parseServerTime, relativeTime, relativeSince, absoluteLocal } from '../src/lib/time';
const NOW = Date.parse('2026-10-18T20:00:00Z');
const at = (msAgo: number) => new Date(NOW - msAgo);
describe('parseServerTime', () => {
it('parses RFC3339', () => {
expect(parseServerTime('2026-10-18T19:59:00Z')?.getTime()).toBe(
Date.parse('2026-10-18T19:59:00Z'),
);
});
it('returns null for absent or garbage values', () => {
expect(parseServerTime(undefined)).toBeNull();
expect(parseServerTime(null)).toBeNull();
expect(parseServerTime('')).toBeNull();
expect(parseServerTime('not-a-date')).toBeNull();
});
});
describe('relativeTime', () => {
it('says "just now" under a second, including for clock skew', () => {
expect(relativeTime(at(0), NOW)).toBe('just now');
expect(relativeTime(at(500), NOW)).toBe('just now');
// A phone clock ahead of the server must never render "in 3 seconds".
expect(relativeTime(at(-5000), NOW)).toBe('just now');
});
it('counts seconds under a minute', () => {
expect(relativeTime(at(1000), NOW)).toBe('1s ago');
expect(relativeTime(at(2000), NOW)).toBe('2s ago');
expect(relativeTime(at(59000), NOW)).toBe('59s ago');
});
it('counts minutes, hours and days above that', () => {
expect(relativeTime(at(60000), NOW)).toBe('1m ago');
expect(relativeTime(at(13 * 60000 + 42000), NOW)).toBe('13m ago');
expect(relativeTime(at(3600000), NOW)).toBe('1h ago');
expect(relativeTime(at(47 * 3600000), NOW)).toBe('1d ago');
expect(relativeTime(at(3 * 86400000), NOW)).toBe('3d ago');
});
});
describe('relativeSince', () => {
it('formats a server string', () => {
const iso = new Date(NOW - 2000).toISOString();
expect(relativeSince(iso, NOW)).toBe('2s ago');
});
it('returns null when there is nothing to format', () => {
expect(relativeSince(undefined, NOW)).toBeNull();
expect(relativeSince('nope', NOW)).toBeNull();
});
});
describe('absoluteLocal', () => {
it('renders zero-padded local hh:mm:ss', () => {
const d = new Date(2026, 9, 18, 8, 5, 3);
expect(absoluteLocal(d)).toBe('08:05:03');
});
});