fix: delays account for midnight

This commit is contained in:
Carlos Valente
2026-07-14 13:06:35 +02:00
parent 0ff226f0ec
commit e1f6b22d19
4 changed files with 82 additions and 13 deletions
@@ -99,6 +99,36 @@ describe('getExpectedStart()', () => {
expect(getExpectedStart(testEvent, { ...testState, isLinkedToLoaded: false })).toBe(110); // <-- when gap is not enough to compensate for the running behind it absorbs at much as possible
// expect(getExpectedStart(testEvent, { ...testState, isLinkedToLoaded: true })).toBe(70); This should not be possible
});
test('negative delay cannot move a day 0 event before the rundown start', () => {
const testState = {
currentDay: 0,
totalGap: 0,
offset: 0,
mode: OffsetMode.Absolute,
actualStart: null,
plannedStart: null,
isLinkedToLoaded: true,
};
expect(getExpectedStart({ timeStart: 0, delay: -5, dayOffset: 0 as Day }, testState)).toBe(0);
expect(getExpectedStart({ timeStart: 10, delay: -5, dayOffset: 0 as Day }, testState)).toBe(5);
});
test('negative delay can move a later-day event back to the previous day', () => {
const testState = {
currentDay: 0,
totalGap: 0,
offset: 0,
mode: OffsetMode.Absolute,
actualStart: null,
plannedStart: null,
isLinkedToLoaded: true,
};
expect(getExpectedStart({ timeStart: 0, delay: -5, dayOffset: 1 as Day }, testState)).toBe(dayInMs - 5);
expect(getExpectedStart({ timeStart: 10, delay: -20, dayOffset: 1 as Day }, testState)).toBe(dayInMs - 10);
});
});
describe('Relative offset mode', () => {
@@ -413,6 +443,19 @@ describe('getExpectedEnd()', () => {
expect(getExpectedEnd({ ...testEvent, dayOffset: 0 as Day }, { ...baseState, currentDay: 0, offset: 0 })).toBe(150);
});
test('a countToEnd event with negative delay can start on the previous day but keeps its fixed end', () => {
const testEvent = {
timeStart: 0,
duration: 50,
delay: -10,
dayOffset: 1 as Day,
countToEnd: true,
};
expect(getExpectedStart(testEvent, { ...baseState, currentDay: 0, offset: 0 })).toBe(dayInMs - 10);
expect(getExpectedEnd(testEvent, { ...baseState, currentDay: 0, offset: 0 })).toBe(dayInMs + 50);
});
test('a countToEnd event is anchored to its wall-clock end in relative mode', () => {
const testEvent = {
timeStart: 100,
+3 -10
View File
@@ -23,13 +23,8 @@ export function getExpectedStart(
const { timeStart, dayOffset, delay } = event;
const { currentDay, totalGap, isLinkedToLoaded, offset, mode, actualStart, plannedStart } = state;
//How many days from the currently running event to this one
const relativeDayOffset = dayOffset - currentDay;
const delayedStart = Math.max(0, timeStart + delay);
//The normalised start time of this event relative to the currently running event
const normalisedTimeStart = delayedStart + relativeDayOffset * dayInMs;
const absoluteDelayedStart = Math.max(0, dayOffset * dayInMs + timeStart + delay);
const normalisedTimeStart = absoluteDelayedStart - currentDay * dayInMs;
let relativeStartOffset = 0;
@@ -69,9 +64,7 @@ export function getExpectedEnd(
* - the end time is always the wall clock
*/
if (event.countToEnd) {
// account for day offset
const relativeDayOffset = event.dayOffset - state.currentDay;
const plannedEnd = event.timeStart + event.duration + relativeDayOffset * dayInMs;
const plannedEnd = event.dayOffset * dayInMs + event.timeStart + event.duration - state.currentDay * dayInMs;
// count to end should finish on the planned time or on start
return Math.max(expectedStart, plannedEnd);