68 lines
2.7 KiB
TypeScript
68 lines
2.7 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { formatCash, formatDeadlineRelative, formatDuration, formatFuel, formatSimClock } from './format';
|
|
|
|
describe('formatCash', () => {
|
|
it('formats EUR with thousands separators and two decimals', () => {
|
|
expect(formatCash(20_000)).toBe('€20,000.00');
|
|
expect(formatCash(1_234_567.891)).toBe('€1,234,567.89');
|
|
});
|
|
|
|
it('handles zero and fractional values (refuel costs are fractional)', () => {
|
|
expect(formatCash(0)).toBe('€0.00');
|
|
expect(formatCash(30.4)).toBe('€30.40');
|
|
});
|
|
});
|
|
|
|
describe('formatFuel', () => {
|
|
it('shows current / max liters with the current value rounded', () => {
|
|
expect(formatFuel(6300, 6300)).toBe('6300 / 6300 L');
|
|
expect(formatFuel(1234.6, 6300)).toBe('1235 / 6300 L');
|
|
expect(formatFuel(0, 6300)).toBe('0 / 6300 L');
|
|
});
|
|
});
|
|
|
|
describe('formatSimClock', () => {
|
|
it('formats epoch ms as a UTC wall-clock string with seconds (deterministic across timezones)', () => {
|
|
expect(formatSimClock(Date.UTC(2026, 8, 17, 14, 5))).toBe('2026-09-17 14:05:00 UTC');
|
|
expect(formatSimClock(Date.UTC(2026, 0, 1, 0, 0))).toBe('2026-01-01 00:00:00 UTC');
|
|
expect(formatSimClock(Date.UTC(2026, 8, 17, 14, 5, 9))).toBe('2026-09-17 14:05:09 UTC');
|
|
});
|
|
});
|
|
|
|
const MIN = 60_000;
|
|
const HOUR = 3_600_000;
|
|
const DAY = 86_400_000;
|
|
|
|
describe('formatDuration', () => {
|
|
it('renders days + hours, hours + minutes, or bare minutes (rounded to the minute)', () => {
|
|
expect(formatDuration(2 * DAY + 3 * HOUR)).toBe('2d 3h');
|
|
expect(formatDuration(14 * HOUR + 30 * MIN)).toBe('14h 30m');
|
|
expect(formatDuration(45 * MIN)).toBe('45m');
|
|
expect(formatDuration(60 * MIN)).toBe('1h 0m');
|
|
// Rounding to the nearest minute: 29m29s stays at 29, 29m31s rounds up to 30.
|
|
expect(formatDuration(29 * MIN + 29_000)).toBe('29m');
|
|
expect(formatDuration(29 * MIN + 31_000)).toBe('30m');
|
|
});
|
|
|
|
it('clamps zero and negative input to "0m"', () => {
|
|
expect(formatDuration(0)).toBe('0m');
|
|
expect(formatDuration(-5 * MIN)).toBe('0m');
|
|
});
|
|
});
|
|
|
|
describe('formatDeadlineRelative', () => {
|
|
const NOW = Date.UTC(2026, 8, 17, 12, 0);
|
|
|
|
it('renders "in <duration>" for future deadlines relative to the sim clock', () => {
|
|
expect(formatDeadlineRelative(NOW + 14 * HOUR + 30 * MIN, NOW)).toBe('in 14h 30m');
|
|
expect(formatDeadlineRelative(NOW + 2 * DAY + 3 * HOUR, NOW)).toBe('in 2d 3h');
|
|
expect(formatDeadlineRelative(NOW + 45 * MIN, NOW)).toBe('in 45m');
|
|
});
|
|
|
|
it('renders "now" for sub-minute deadlines and "overdue" at or past the deadline', () => {
|
|
expect(formatDeadlineRelative(NOW + 30_000, NOW)).toBe('now');
|
|
expect(formatDeadlineRelative(NOW, NOW)).toBe('overdue');
|
|
expect(formatDeadlineRelative(NOW - HOUR, NOW)).toBe('overdue');
|
|
});
|
|
});
|