159 lines
5.4 KiB
TypeScript
159 lines
5.4 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import {
|
|
buildTimetableSlots,
|
|
computeWakeupMinutes,
|
|
computeBedtimeMinutes,
|
|
computeDailySummaryData,
|
|
computeAverageStats,
|
|
reverseDateOrder,
|
|
filterDaysWithData,
|
|
} from '../../src/utils/chartHelpers';
|
|
import type { TimetableSlot, WakeupBedtimeDay, DailySummaryDay } from '../../src/types';
|
|
|
|
describe('buildTimetableSlots', () => {
|
|
it('groups slots by date', () => {
|
|
const slots: TimetableSlot[] = [
|
|
{ date: '2024-01-15', slot_start: '00:00', slot_end: '00:15', sleeping: true },
|
|
{ date: '2024-01-15', slot_start: '00:15', slot_end: '00:30', sleeping: false },
|
|
{ date: '2024-01-16', slot_start: '00:00', slot_end: '00:15', sleeping: true },
|
|
];
|
|
const result = buildTimetableSlots(slots);
|
|
expect(Object.keys(result)).toHaveLength(2);
|
|
expect(result['2024-01-15']).toHaveLength(2);
|
|
expect(result['2024-01-16']).toHaveLength(1);
|
|
});
|
|
|
|
it('handles empty array', () => {
|
|
const result = buildTimetableSlots([]);
|
|
expect(result).toEqual({});
|
|
});
|
|
});
|
|
|
|
describe('computeWakeupMinutes', () => {
|
|
it('transforms wakeup data for chart', () => {
|
|
const days: WakeupBedtimeDay[] = [
|
|
{ date: '2024-01-15', wakeup_minutes: 195, bedtime_minutes: 75 },
|
|
];
|
|
const result = computeWakeupMinutes(days, '04:00');
|
|
expect(result[0].time).toBe('07:15');
|
|
expect(result[0].minutes).toBe(195);
|
|
});
|
|
|
|
it('handles null values', () => {
|
|
const days: WakeupBedtimeDay[] = [
|
|
{ date: '2024-01-15', wakeup_minutes: null, bedtime_minutes: null },
|
|
];
|
|
const result = computeWakeupMinutes(days, '04:00');
|
|
expect(result[0].time).toBe('N/A');
|
|
});
|
|
|
|
it('handles midnight crossover', () => {
|
|
const days: WakeupBedtimeDay[] = [
|
|
{ date: '2024-01-15', wakeup_minutes: 60, bedtime_minutes: null },
|
|
];
|
|
const result = computeWakeupMinutes(days, '23:00');
|
|
expect(result[0].time).toBe('00:00');
|
|
});
|
|
|
|
it('handles mixed data (valid, null, zero)', () => {
|
|
const days: WakeupBedtimeDay[] = [
|
|
{ date: '2024-01-15', wakeup_minutes: 120, bedtime_minutes: null },
|
|
{ date: '2024-01-16', wakeup_minutes: null, bedtime_minutes: null },
|
|
{ date: '2024-01-17', wakeup_minutes: 0, bedtime_minutes: null },
|
|
];
|
|
const result = computeWakeupMinutes(days, '04:00');
|
|
expect(result[0]).toEqual({ date: '2024-01-15', minutes: 120, time: '06:00' });
|
|
expect(result[1]).toEqual({ date: '2024-01-16', minutes: 0, time: 'N/A' });
|
|
expect(result[2]).toEqual({ date: '2024-01-17', minutes: 0, time: '04:00' });
|
|
});
|
|
});
|
|
|
|
describe('computeBedtimeMinutes', () => {
|
|
it('transforms bedtime data for chart', () => {
|
|
const days: WakeupBedtimeDay[] = [
|
|
{ date: '2024-01-15', wakeup_minutes: 195, bedtime_minutes: 75 },
|
|
];
|
|
const result = computeBedtimeMinutes(days, '19:00');
|
|
expect(result[0].time).toBe('20:15');
|
|
});
|
|
|
|
it('handles midnight crossover', () => {
|
|
const days: WakeupBedtimeDay[] = [
|
|
{ date: '2024-01-15', wakeup_minutes: null, bedtime_minutes: 60 },
|
|
];
|
|
const result = computeBedtimeMinutes(days, '23:00');
|
|
expect(result[0].time).toBe('00:00');
|
|
});
|
|
|
|
it('handles mixed data (valid, null, zero)', () => {
|
|
const days: WakeupBedtimeDay[] = [
|
|
{ date: '2024-01-15', wakeup_minutes: null, bedtime_minutes: 120 },
|
|
{ date: '2024-01-16', wakeup_minutes: null, bedtime_minutes: null },
|
|
{ date: '2024-01-17', wakeup_minutes: null, bedtime_minutes: 0 },
|
|
];
|
|
const result = computeBedtimeMinutes(days, '19:00');
|
|
expect(result[0]).toEqual({ date: '2024-01-15', minutes: 120, time: '21:00' });
|
|
expect(result[1]).toEqual({ date: '2024-01-16', minutes: 0, time: 'N/A' });
|
|
expect(result[2]).toEqual({ date: '2024-01-17', minutes: 0, time: '19:00' });
|
|
});
|
|
});
|
|
|
|
describe('computeDailySummaryData', () => {
|
|
it('transforms daily summary for BarChart', () => {
|
|
const days: DailySummaryDay[] = [
|
|
{ date: '2024-01-15', total_minutes: 720, day_minutes: 120, night_minutes: 600 },
|
|
];
|
|
const result = computeDailySummaryData(days);
|
|
expect(result[0]).toEqual({
|
|
date: '2024-01-15',
|
|
daySleep: 120,
|
|
nightSleep: 600,
|
|
total: 720,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('computeAverageStats', () => {
|
|
it('calculates averages from daily data', () => {
|
|
const days: DailySummaryDay[] = [
|
|
{ date: '2024-01-15', total_minutes: 720, day_minutes: 120, night_minutes: 600 },
|
|
{ date: '2024-01-16', total_minutes: 600, day_minutes: 100, night_minutes: 500 },
|
|
];
|
|
const result = computeAverageStats(days);
|
|
expect(result.avgTotal).toBe(660);
|
|
expect(result.avgDay).toBe(110);
|
|
expect(result.avgNight).toBe(550);
|
|
expect(result.count).toBe(2);
|
|
});
|
|
|
|
it('handles empty array', () => {
|
|
const result = computeAverageStats([]);
|
|
expect(result.avgTotal).toBe(0);
|
|
expect(result.count).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe('reverseDateOrder', () => {
|
|
it('reverses array order', () => {
|
|
const days = [
|
|
{ date: '2024-01-16' },
|
|
{ date: '2024-01-15' },
|
|
{ date: '2024-01-14' },
|
|
];
|
|
const result = reverseDateOrder(days);
|
|
expect(result[0].date).toBe('2024-01-14');
|
|
});
|
|
});
|
|
|
|
describe('filterDaysWithData', () => {
|
|
it('filters days with zero total', () => {
|
|
const days = [
|
|
{ date: '2024-01-15', total_minutes: 720 },
|
|
{ date: '2024-01-16', total_minutes: 0 },
|
|
];
|
|
const result = filterDaysWithData(days);
|
|
expect(result).toHaveLength(1);
|
|
expect(result[0].date).toBe('2024-01-15');
|
|
});
|
|
});
|