[ {"name":"a legal day: 4h30, 45 minute break, 4h30, then daily rest","args":["2026-09-21","06:00",[{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":660}]],"expect":{"compliant":true,"drivingMinutes":540,"breaches":[]}}, {"name":"five hours without a break passes the 4h30 limit at 10:30","args":["2026-09-21","06:00",[{"kind":"driving","minutes":300},{"kind":"rest","minutes":45}]],"expect":{"compliant":false,"drivingMinutes":300,"breaches":[{"rule":"break","at":"2026-09-21T10:30","actual":300,"limit":270}]}}, {"name":"a split break of 15 then 30 minutes is legal","args":["2026-09-21","06:00",[{"kind":"driving","minutes":120},{"kind":"rest","minutes":15},{"kind":"driving","minutes":150},{"kind":"rest","minutes":30},{"kind":"driving","minutes":240}]],"expect":{"compliant":true,"drivingMinutes":510,"breaches":[]}}, {"name":"30 then 15 is not a split break: the second part must be at least 30","args":["2026-09-21","06:00",[{"kind":"driving","minutes":120},{"kind":"rest","minutes":30},{"kind":"driving","minutes":150},{"kind":"rest","minutes":15},{"kind":"driving","minutes":60}]],"expect":{"compliant":false,"drivingMinutes":330,"breaches":[{"rule":"break","at":"2026-09-21T11:15","actual":330,"limit":270}]}}, {"name":"an hour of other work is not a break","args":["2026-09-21","06:00",[{"kind":"driving","minutes":200},{"kind":"work","minutes":60},{"kind":"driving","minutes":100}]],"expect":{"compliant":false,"drivingMinutes":300,"breaches":[{"rule":"break","at":"2026-09-21T11:30","actual":300,"limit":270}]}}, {"name":"a period of availability is not a break","args":["2026-09-21","06:00",[{"kind":"driving","minutes":270},{"kind":"availability","minutes":45},{"kind":"driving","minutes":10}]],"expect":{"compliant":false,"drivingMinutes":280,"breaches":[{"rule":"break","at":"2026-09-21T11:15","actual":280,"limit":270}]}}, {"name":"two rests recorded back to back are one 45 minute break","args":["2026-09-21","06:00",[{"kind":"driving","minutes":270},{"kind":"rest","minutes":20},{"kind":"rest","minutes":25},{"kind":"driving","minutes":270}]],"expect":{"compliant":true,"drivingMinutes":540,"breaches":[]}}, {"name":"a 15 minute rest before any driving is not the first part of a split break","args":["2026-09-21","06:00",[{"kind":"rest","minutes":15},{"kind":"driving","minutes":200},{"kind":"rest","minutes":30},{"kind":"driving","minutes":100}]],"expect":{"compliant":false,"drivingMinutes":300,"breaches":[{"rule":"break","at":"2026-09-21T11:15","actual":300,"limit":270}]}}, {"name":"10h30 of driving in a day passes the 10 hour ceiling at 16:30","args":["2026-09-21","05:00",[{"kind":"driving","minutes":240},{"kind":"rest","minutes":45},{"kind":"driving","minutes":240},{"kind":"rest","minutes":45},{"kind":"driving","minutes":150}]],"expect":{"compliant":false,"drivingMinutes":630,"breaches":[{"rule":"daily-driving","at":"2026-09-21T16:30","actual":630,"limit":600}]}}, {"name":"two 10 hour days in a week are allowed","args":["2026-09-21","06:00",[{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":60},{"kind":"rest","minutes":750},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":60}]],"expect":{"compliant":true,"drivingMinutes":1200,"breaches":[]}}, {"name":"a third 10 hour day in the same fixed week breaks the 9 hour limit","args":["2026-09-21","06:00",[{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":60},{"kind":"rest","minutes":750},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":60},{"kind":"rest","minutes":750},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":60}]],"expect":{"compliant":false,"drivingMinutes":1800,"breaches":[{"rule":"daily-driving","at":"2026-09-23T16:30","actual":600,"limit":540}]}}, {"name":"six 9 hour days and 3 hours on Sunday pass 56 hours at 08:00 on Sunday","args":["2026-09-21","06:00",[{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":180}]],"expect":{"compliant":false,"drivingMinutes":3420,"breaches":[{"rule":"weekly-driving","at":"2026-09-27T08:00","actual":3420,"limit":3360}]}}, {"name":"driving across Sunday midnight is split between the two fixed weeks","args":["2026-09-21","06:00",[{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":1815},{"kind":"driving","minutes":240}]],"expect":{"compliant":true,"drivingMinutes":3480,"breaches":[]}}, {"name":"54 hours then 36 hours is exactly 90; half an hour more passes the fortnightly limit","args":["2026-09-21","06:00",[{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":2295},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":270},{"kind":"rest","minutes":45},{"kind":"driving","minutes":270},{"kind":"rest","minutes":855},{"kind":"driving","minutes":30}]],"expect":{"compliant":false,"drivingMinutes":5430,"breaches":[{"rule":"fortnightly-driving","at":"2026-10-02T06:00","actual":5430,"limit":5400}]}}, {"name":"breaches come back in time order","args":["2026-09-21","06:00",[{"kind":"driving","minutes":300},{"kind":"rest","minutes":45},{"kind":"driving","minutes":310}]],"expect":{"compliant":false,"drivingMinutes":610,"breaches":[{"rule":"break","at":"2026-09-21T10:30","actual":300,"limit":270},{"rule":"break","at":"2026-09-21T16:15","actual":310,"limit":270},{"rule":"daily-driving","at":"2026-09-21T16:45","actual":610,"limit":600}]}}, {"name":"no activities is compliant","args":["2026-09-21","06:00",[]],"expect":{"compliant":true,"drivingMinutes":0,"breaches":[]}}, {"name":"a start time of 24:00 is refused","args":["2026-09-21","24:00",[{"kind":"driving","minutes":60}]],"expectError":"startTime must be HH:MM, 24-hour"}, {"name":"a date that is not ISO is refused","args":["21/09/2026","06:00",[{"kind":"driving","minutes":60}]],"expectError":"startDate must be an ISO date (YYYY-MM-DD)"}, {"name":"an unknown activity kind is refused","args":["2026-09-21","06:00",[{"kind":"sleeping","minutes":60}]],"expectError":"unknown activity kind \"sleeping\""}, {"name":"a zero-length activity is refused","args":["2026-09-21","06:00",[{"kind":"driving","minutes":0}]],"expectError":"minutes must be a whole number of at least 1"}, {"name":"a fractional minute is refused","args":["2026-09-21","06:00",[{"kind":"driving","minutes":30.5}]],"expectError":"minutes must be a whole number of at least 1"}, {"name":"dates before Regulation 561/2006 applied (11 April 2007) are refused","args":["2007-04-10","06:00",[{"kind":"driving","minutes":60}]],"expectError":"no drivers' hours limit"}, {"name": "a start date with a trailing newline is refused", "args": ["2026-09-21\n", "06:00", [{"kind": "driving", "minutes": 60}]], "expectError": "startDate must be an ISO date (YYYY-MM-DD), received \"2026-09-21\n\""}, {"name": "a start date in Arabic-Indic digits is refused", "args": ["٢٠٢٦-٠٩-٢١", "06:00", [{"kind": "driving", "minutes": 60}]], "expectError": "startDate must be an ISO date (YYYY-MM-DD), received \"٢٠٢٦-٠٩-٢١\""}, {"name": "a start time with a trailing newline is refused", "args": ["2026-09-21", "06:00\n", [{"kind": "driving", "minutes": 60}]], "expectError": "startTime must be HH:MM, 24-hour, received \"06:00\n\""}, {"name": "a start time in Arabic-Indic digits is refused", "args": ["2026-09-21", "0٦:0٠", [{"kind": "driving", "minutes": 60}]], "expectError": "startTime must be HH:MM, 24-hour, received \"0٦:0٠\""} ]