feat(frontend): add types + format helpers with tdd
This commit is contained in:
parent
3b8400b2ed
commit
a1e24c6a81
5 changed files with 150 additions and 0 deletions
61
frontend/src/tests/format.test.ts
Normal file
61
frontend/src/tests/format.test.ts
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
import { fmtMs, fmtRelative, fmtJpDate, fmtJpTime } from '@lib/format';
|
||||
|
||||
describe('fmtMs', () => {
|
||||
it('formats zero as 0:00', () => {
|
||||
expect(fmtMs(0)).toBe('0:00');
|
||||
});
|
||||
it('pads seconds to two digits', () => {
|
||||
expect(fmtMs(7)).toBe('0:07');
|
||||
});
|
||||
it('formats 215 as 3:35', () => {
|
||||
expect(fmtMs(215)).toBe('3:35');
|
||||
});
|
||||
it('handles minutes >= 10 correctly', () => {
|
||||
expect(fmtMs(605)).toBe('10:05');
|
||||
});
|
||||
it('clamps negative input to 0:00', () => {
|
||||
expect(fmtMs(-3)).toBe('0:00');
|
||||
});
|
||||
it('floors fractional seconds', () => {
|
||||
expect(fmtMs(7.9)).toBe('0:07');
|
||||
});
|
||||
});
|
||||
|
||||
describe('fmtRelative', () => {
|
||||
const now = new Date('2026-04-30T12:00:00Z');
|
||||
it('formats <60s as Xs', () => {
|
||||
expect(fmtRelative(new Date('2026-04-30T11:59:30Z'), now)).toBe('30s');
|
||||
});
|
||||
it('formats <1h as Xm', () => {
|
||||
expect(fmtRelative(new Date('2026-04-30T11:55:00Z'), now)).toBe('5m');
|
||||
});
|
||||
it('formats <24h as Xh', () => {
|
||||
expect(fmtRelative(new Date('2026-04-30T09:00:00Z'), now)).toBe('3h');
|
||||
});
|
||||
it('formats >=24h as Xd', () => {
|
||||
expect(fmtRelative(new Date('2026-04-28T12:00:00Z'), now)).toBe('2d');
|
||||
});
|
||||
it('returns "now" for the current moment', () => {
|
||||
expect(fmtRelative(new Date('2026-04-30T12:00:00Z'), now)).toBe('now');
|
||||
});
|
||||
it('returns "now" for a future timestamp (clock skew)', () => {
|
||||
expect(fmtRelative(new Date('2026-04-30T12:00:05Z'), now)).toBe('now');
|
||||
});
|
||||
});
|
||||
|
||||
describe('fmtJpDate', () => {
|
||||
it('formats with full kanji', () => {
|
||||
// build the date in local time so the test isn't tz-sensitive
|
||||
const d = new Date(2026, 3, 30); // month is 0-indexed → April
|
||||
expect(fmtJpDate(d)).toBe('2026年4月30日');
|
||||
});
|
||||
});
|
||||
|
||||
describe('fmtJpTime', () => {
|
||||
it('formats HH:MM:SS', () => {
|
||||
const d = new Date();
|
||||
d.setHours(7); d.setMinutes(3); d.setSeconds(9);
|
||||
expect(fmtJpTime(d)).toBe('07:03:09');
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue