From 88ce663b442af347aa2f9c4dad4aa64704a09e34 Mon Sep 17 00:00:00 2001 From: Loic Coenen Date: Wed, 24 Jun 2026 16:29:02 +0200 Subject: [PATCH] test: add comprehensive tests for date and Berlin clock conversions --- src/__tests__/types.test.ts | 10 --- src/__tests__/utils.test.ts | 120 +++++++++++++++++++++++++++++++++--- 2 files changed, 112 insertions(+), 18 deletions(-) delete mode 100644 src/__tests__/types.test.ts diff --git a/src/__tests__/types.test.ts b/src/__tests__/types.test.ts deleted file mode 100644 index 5497cae..0000000 --- a/src/__tests__/types.test.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { LampState, BerlinClock } from '../types'; - -describe('Types', () => { - it('LampState has correct values', () => { - expect(LampState.Y).toBe('Y'); - expect(LampState.R).toBe('R'); - expect(LampState.O).toBe('O'); - expect(LampState.N).toBe('N'); - }); -}); diff --git a/src/__tests__/utils.test.ts b/src/__tests__/utils.test.ts index 02562c3..5123a9e 100644 --- a/src/__tests__/utils.test.ts +++ b/src/__tests__/utils.test.ts @@ -1,16 +1,120 @@ import { dateToDigital, digitalToDate, dateToBerlin, berlinToDate } from '../utils'; +import { LampState } from '../types'; describe('Utils', () => { - it('dateToDigital returns correct format', () => { - // TODO + describe('dateToDigital', () => { + it('returns "HH:mm:ss" for a given date', () => { + const date = new Date(2025, 0, 1, 14, 5, 9); + expect(dateToDigital(date)).toBe('14:05:09'); + }); + + it('pads single-digit hours, minutes, seconds', () => { + const date = new Date(2025, 0, 1, 2, 3, 4); + expect(dateToDigital(date)).toBe('02:03:04'); + }); }); - it('digitalToDate returns a Date', () => { - // TODO + + describe('digitalToDate', () => { + it('parses a valid digital string', () => { + const result = digitalToDate('12:34:56'); + expect(result).toBeInstanceOf(Date); + expect(result.getHours()).toBe(12); + expect(result.getMinutes()).toBe(34); + expect(result.getSeconds()).toBe(56); + }); + + it('returns an invalid date for invalid input', () => { + const result = digitalToDate('abc'); + expect(isNaN(result.getTime())).toBe(true); + }); }); - it('dateToBerlin returns a BerlinClock', () => { - // TODO + + describe('dateToBerlin', () => { + const makeTime = (h: number, m: number, s: number) => { + const d = new Date(2025, 0, 1, h, m, s); + return d; + }; + + it('returns correct clock for 00:00:00', () => { + const clock = dateToBerlin(makeTime(0, 0, 0)); + expect(clock.secondsRow).toEqual([LampState.Y]); + expect(clock.fiveHours).toEqual([LampState.O, LampState.O, LampState.O, LampState.O]); + expect(clock.oneHour).toEqual([LampState.O, LampState.O, LampState.O, LampState.O]); + expect(clock.fiveMinutes).toEqual([ + LampState.O, LampState.O, LampState.O, + LampState.O, LampState.O, LampState.O, + LampState.O, LampState.O, LampState.O, + LampState.O, LampState.O, + ]); + expect(clock.oneMinute).toEqual([LampState.O, LampState.O, LampState.O, LampState.O]); + }); + + it('returns correct clock for 23:59:59', () => { + const clock = dateToBerlin(makeTime(23, 59, 59)); + expect(clock.secondsRow).toEqual([LampState.O]); + expect(clock.fiveHours).toEqual([LampState.R, LampState.R, LampState.R, LampState.R]); + expect(clock.oneHour).toEqual([LampState.R, LampState.R, LampState.R, LampState.O]); + expect(clock.fiveMinutes).toEqual([ + LampState.Y, LampState.Y, LampState.R, + LampState.Y, LampState.Y, LampState.R, + LampState.Y, LampState.Y, LampState.R, + LampState.Y, LampState.Y, + ]); + expect(clock.oneMinute).toEqual([LampState.Y, LampState.Y, LampState.Y, LampState.Y]); + }); + + it('returns correct clock for 12:34:00', () => { + const clock = dateToBerlin(makeTime(12, 34, 0)); + expect(clock.secondsRow).toEqual([LampState.Y]); + expect(clock.fiveHours).toEqual([LampState.R, LampState.R, LampState.O, LampState.O]); + expect(clock.oneHour).toEqual([LampState.R, LampState.R, LampState.O, LampState.O]); + const expectedFiveMinutes = [ + LampState.Y, LampState.Y, LampState.R, + LampState.Y, LampState.Y, LampState.R, + LampState.O, LampState.O, LampState.O, + LampState.O, LampState.O, + ]; + expect(clock.fiveMinutes).toEqual(expectedFiveMinutes); + expect(clock.oneMinute).toEqual([LampState.Y, LampState.Y, LampState.Y, LampState.Y]); + }); }); - it('berlinToDate returns a Date', () => { - // TODO + + describe('berlinToDate', () => { + it('roundtrips correctly: dateToBerlin then berlinToDate returns the original date (seconds floor to even)', () => { + const original = new Date(2025, 0, 1, 14, 30, 0); + const clock = dateToBerlin(original); + const result = berlinToDate(clock); + expect(result.getHours()).toBe(14); + expect(result.getMinutes()).toBe(30); + expect(result.getSeconds()).toBe(0); + }); + + it('roundtrips with odd seconds: result seconds will be zero (only parity stored)', () => { + const original = new Date(2025, 0, 1, 23, 59, 59); + const clock = dateToBerlin(original); + const result = berlinToDate(clock); + expect(result.getHours()).toBe(23); + expect(result.getMinutes()).toBe(59); + expect(result.getSeconds()).toBe(0); + }); + + it('converts a known Berlin clock to the correct time', () => { + const clock = { + secondsRow: [LampState.Y], + fiveHours: [LampState.R, LampState.R, LampState.O, LampState.O], + oneHour: [LampState.R, LampState.R, LampState.O, LampState.O], + fiveMinutes: [ + LampState.Y, LampState.Y, LampState.R, + LampState.Y, LampState.Y, LampState.R, + LampState.Y, LampState.Y, LampState.O, + LampState.O, LampState.O, + ], + oneMinute: [LampState.Y, LampState.Y, LampState.Y, LampState.Y], + }; + const result = berlinToDate(clock); + expect(result.getHours()).toBe(12); + expect(result.getMinutes()).toBe(34); + expect(result.getSeconds()).toBe(0); + }); }); });