diff --git a/src/__tests__/BerlinClock.test.tsx b/src/__tests__/BerlinClock.test.tsx new file mode 100644 index 0000000..7a18e9d --- /dev/null +++ b/src/__tests__/BerlinClock.test.tsx @@ -0,0 +1,11 @@ +import { render } from '@testing-library/react'; +import { BerlinClock } from '../containers/BerlinClock'; + +describe('BerlinClock', () => { + it('renders when enabled', () => { + render(); + }); + it('does not render when disabled', () => { + render(); + }); +}); diff --git a/src/__tests__/DigitalClock.test.tsx b/src/__tests__/DigitalClock.test.tsx new file mode 100644 index 0000000..0381d1e --- /dev/null +++ b/src/__tests__/DigitalClock.test.tsx @@ -0,0 +1,8 @@ +import { render } from '@testing-library/react'; +import { DigitalClock } from '../containers/DigitalClock'; + +describe('DigitalClock', () => { + it('renders when enabled', () => { + render(); + }); +}); diff --git a/src/__tests__/Lamp.test.tsx b/src/__tests__/Lamp.test.tsx new file mode 100644 index 0000000..6b71f95 --- /dev/null +++ b/src/__tests__/Lamp.test.tsx @@ -0,0 +1,9 @@ +import { render, screen } from '@testing-library/react'; +import { Lamp } from '../components/Lamp'; +import { LampState } from '../types'; + +describe('Lamp', () => { + it('renders without crashing', () => { + render(); + }); +}); diff --git a/src/__tests__/LampLine.test.tsx b/src/__tests__/LampLine.test.tsx new file mode 100644 index 0000000..45f0f37 --- /dev/null +++ b/src/__tests__/LampLine.test.tsx @@ -0,0 +1,11 @@ +import { render } from '@testing-library/react'; +import { LampLine } from '../components/LampLine'; +import { LampState } from '../types'; + +describe('LampLine', () => { + it('renders correct number of lamps', () => { + const states = [LampState.Y, LampState.R, LampState.O]; + render(); + // TODO: assert number of child lamps + }); +}); diff --git a/src/__tests__/TimeConverter.test.tsx b/src/__tests__/TimeConverter.test.tsx new file mode 100644 index 0000000..cf4c3de --- /dev/null +++ b/src/__tests__/TimeConverter.test.tsx @@ -0,0 +1,13 @@ +import { render, screen, fireEvent } from '@testing-library/react'; +import { TimeConverter } from '../containers/TimeConverter'; + +describe('TimeConverter', () => { + it('renders the toggle checkbox', () => { + render(); + expect(screen.getByRole('checkbox')).toBeInTheDocument(); + }); + it('disables clocks when checkbox is checked', () => { + render(); + // TODO + }); +}); diff --git a/src/__tests__/types.test.ts b/src/__tests__/types.test.ts new file mode 100644 index 0000000..5497cae --- /dev/null +++ b/src/__tests__/types.test.ts @@ -0,0 +1,10 @@ +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__/useCurrentTime.test.ts b/src/__tests__/useCurrentTime.test.ts new file mode 100644 index 0000000..5348220 --- /dev/null +++ b/src/__tests__/useCurrentTime.test.ts @@ -0,0 +1,10 @@ +import { renderHook, act } from '@testing-library/react'; +import { useCurrentTime } from '../hooks/useCurrentTime'; + +describe('useCurrentTime', () => { + it('returns a date and setter', () => { + const { result } = renderHook(() => useCurrentTime()); + expect(result.current.currentTime).toBeInstanceOf(Date); + expect(typeof result.current.setCurrentTime).toBe('function'); + }); +}); diff --git a/src/__tests__/utils.test.ts b/src/__tests__/utils.test.ts new file mode 100644 index 0000000..02562c3 --- /dev/null +++ b/src/__tests__/utils.test.ts @@ -0,0 +1,16 @@ +import { dateToDigital, digitalToDate, dateToBerlin, berlinToDate } from '../utils'; + +describe('Utils', () => { + it('dateToDigital returns correct format', () => { + // TODO + }); + it('digitalToDate returns a Date', () => { + // TODO + }); + it('dateToBerlin returns a BerlinClock', () => { + // TODO + }); + it('berlinToDate returns a Date', () => { + // TODO + }); +}); diff --git a/src/components/Lamp.tsx b/src/components/Lamp.tsx new file mode 100644 index 0000000..286dfeb --- /dev/null +++ b/src/components/Lamp.tsx @@ -0,0 +1,9 @@ +import { LampState } from '../types'; + +interface LampProps { + state: LampState; +} + +export function Lamp({ state }: LampProps) { + return null; +} diff --git a/src/components/LampLine.tsx b/src/components/LampLine.tsx new file mode 100644 index 0000000..4826284 --- /dev/null +++ b/src/components/LampLine.tsx @@ -0,0 +1,9 @@ +import { LampState } from '../types'; + +interface LampLineProps { + states: LampState[]; +} + +export function LampLine({ states }: LampLineProps) { + return null; +} diff --git a/src/containers/BerlinClock.tsx b/src/containers/BerlinClock.tsx new file mode 100644 index 0000000..1894707 --- /dev/null +++ b/src/containers/BerlinClock.tsx @@ -0,0 +1,15 @@ +import { useState } from 'react'; +import { LampLine } from '../components/LampLine'; +import { useCurrentTime } from '../hooks/useCurrentTime'; +import { dateToBerlin } from '../utils'; + +interface BerlinClockProps { + enabled: boolean; +} + +export function BerlinClock({ enabled }: BerlinClockProps) { + const { currentTime } = useCurrentTime(); + const berlin = dateToBerlin(currentTime); + // Will render four LampLine components + return null; +} diff --git a/src/containers/DigitalClock.tsx b/src/containers/DigitalClock.tsx new file mode 100644 index 0000000..4408719 --- /dev/null +++ b/src/containers/DigitalClock.tsx @@ -0,0 +1,13 @@ +import { useState } from 'react'; +import { useCurrentTime } from '../hooks/useCurrentTime'; +import { dateToDigital } from '../utils'; + +interface DigitalClockProps { + enabled: boolean; +} + +export function DigitalClock({ enabled }: DigitalClockProps) { + const { currentTime } = useCurrentTime(); + const digital = dateToDigital(currentTime); + return null; +} diff --git a/src/containers/TimeConverter.tsx b/src/containers/TimeConverter.tsx new file mode 100644 index 0000000..9e35a2e --- /dev/null +++ b/src/containers/TimeConverter.tsx @@ -0,0 +1,10 @@ +import { useState } from 'react'; +import { BerlinClock } from './BerlinClock'; +import { DigitalClock } from './DigitalClock'; +import { useCurrentTime } from '../hooks/useCurrentTime'; + +export function TimeConverter() { + const [useSystemTime, setUseSystemTime] = useState(false); + // When useSystemTime is true, both BerlinClock and DigitalClock are disabled. + return null; +} diff --git a/src/hooks/useCurrentTime.ts b/src/hooks/useCurrentTime.ts new file mode 100644 index 0000000..da9055d --- /dev/null +++ b/src/hooks/useCurrentTime.ts @@ -0,0 +1,9 @@ +import { useState } from 'react'; + +export function useCurrentTime(): { + currentTime: Date; + setCurrentTime: React.Dispatch>; +} { + const [currentTime, setCurrentTime] = useState(new Date()); + return { currentTime, setCurrentTime }; +} diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..8ec6dc0 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,14 @@ +export enum LampState { + Y = 'Y', // Yellow + R = 'R', // Red + O = 'O', // Off + N = 'N', // None / undefined +} + +export interface BerlinClock { + secondsRow: LampState[]; + fiveHours: LampState[]; + oneHour: LampState[]; + fiveMinutes: LampState[]; + oneMinute: LampState[]; +} diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..a864c13 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,25 @@ +import { BerlinClock } from '../types'; + +export function dateToDigital(date: Date): string { + // returns "HH:mm:ss" + return ''; +} + +export function digitalToDate(digital: string): Date { + // parses "HH:mm:ss" + return new Date(); +} + +export function dateToBerlin(date: Date): BerlinClock { + return { + secondsRow: [], + fiveHours: [], + oneHour: [], + fiveMinutes: [], + oneMinute: [], + }; +} + +export function berlinToDate(berlin: BerlinClock): Date { + return new Date(); +}