import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:prosappco/utils/time_of_day_extension.dart'; import 'package:prosappco/utils/time_of_day_utils.dart'; void main() { group('TimeOfDayExtension.add', () { test('carries minutes into hours', () { expect(const TimeOfDay(hour: 8, minute: 45).add(minute: 45), const TimeOfDay(hour: 9, minute: 30)); }); test('does not wrap past midnight, so range loops still terminate', () { expect(const TimeOfDay(hour: 23, minute: 30).add(minute: 45).hour, 24); }); }); group('TimeOfDayUtils.genRanges', () { // Regression: a minute-based step used to leave the hour untouched // ("8:90"), so isBefore() never became false and this looped forever, // freezing the calendar screen. test('minute-based step terminates and lands on real times', () { final slots = TimeOfDayUtils.genRanges( const TimeOfDay(hour: 8, minute: 0), const TimeOfDay(hour: 18, minute: 0), stepMinutes: 45, ); expect(slots.length, 14); expect(slots.first, const TimeOfDay(hour: 8, minute: 0)); expect(slots[1], const TimeOfDay(hour: 8, minute: 45)); expect(slots[2], const TimeOfDay(hour: 9, minute: 30)); expect(slots.last, const TimeOfDay(hour: 17, minute: 45)); expect(slots.every((t) => t.minute < 60), isTrue); }); test('two-hour step keeps the historical behaviour', () { final slots = TimeOfDayUtils.genRanges( const TimeOfDay(hour: 8, minute: 0), const TimeOfDay(hour: 18, minute: 0), stepMinutes: 120, ); expect(slots.map((t) => t.hour).toList(), [8, 10, 12, 14, 16]); }); test('end before start yields no slots', () { final slots = TimeOfDayUtils.genRanges( const TimeOfDay(hour: 18, minute: 0), const TimeOfDay(hour: 8, minute: 0), stepMinutes: 45, ); expect(slots, isEmpty); }); }); }