test: add initial test files and component stubs

This commit is contained in:
Loic Coenen
2026-06-23 16:04:30 +02:00
committed by Loic Coenen (aider)
parent 5a6de57a91
commit 826069e8dd
16 changed files with 192 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
import { render } from '@testing-library/react';
import { BerlinClock } from '../containers/BerlinClock';
describe('BerlinClock', () => {
it('renders when enabled', () => {
render(<BerlinClock enabled={true} />);
});
it('does not render when disabled', () => {
render(<BerlinClock enabled={false} />);
});
});

View File

@@ -0,0 +1,8 @@
import { render } from '@testing-library/react';
import { DigitalClock } from '../containers/DigitalClock';
describe('DigitalClock', () => {
it('renders when enabled', () => {
render(<DigitalClock enabled={true} />);
});
});

View File

@@ -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(<Lamp state={LampState.Y} />);
});
});

View File

@@ -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(<LampLine states={states} />);
// TODO: assert number of child lamps
});
});

View File

@@ -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(<TimeConverter />);
expect(screen.getByRole('checkbox')).toBeInTheDocument();
});
it('disables clocks when checkbox is checked', () => {
render(<TimeConverter />);
// TODO
});
});

View File

@@ -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');
});
});

View File

@@ -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');
});
});

View File

@@ -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
});
});

9
src/components/Lamp.tsx Normal file
View File

@@ -0,0 +1,9 @@
import { LampState } from '../types';
interface LampProps {
state: LampState;
}
export function Lamp({ state }: LampProps) {
return null;
}

View File

@@ -0,0 +1,9 @@
import { LampState } from '../types';
interface LampLineProps {
states: LampState[];
}
export function LampLine({ states }: LampLineProps) {
return null;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -0,0 +1,9 @@
import { useState } from 'react';
export function useCurrentTime(): {
currentTime: Date;
setCurrentTime: React.Dispatch<React.SetStateAction<Date>>;
} {
const [currentTime, setCurrentTime] = useState(new Date());
return { currentTime, setCurrentTime };
}

14
src/types/index.ts Normal file
View File

@@ -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[];
}

25
src/utils/index.ts Normal file
View File

@@ -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();
}