refactor: account for overlapping in rundown

This commit is contained in:
Carlos Valente
2024-08-26 10:49:17 +02:00
committed by Carlos Valente
parent c43b6f37f9
commit 25c7915cf7
8 changed files with 149 additions and 82 deletions
@@ -1,16 +0,0 @@
import { checkOverlap } from './checkOverlap';
describe('checkOverlap', () => {
it('should return true if events fully overlap', () => {
expect(checkOverlap(1000, 2000, 1000, 2000)).toBe(true);
});
it('should return true if one of the events is inside the other', () => {
expect(checkOverlap(1000, 2000, 1000, 1000)).toBe(true);
expect(checkOverlap(1000, 2000, 1500, 1750)).toBe(true);
});
it("should return false if events don't overlap", () => {
expect(checkOverlap(1000, 2000, 2000, 3000)).toBe(false);
});
});
@@ -1,19 +0,0 @@
/**
* Check if two Ontime events overlap
* @link https://stackoverflow.com/questions/3269434/whats-the-most-efficient-way-to-test-if-two-ranges-overlap
* We use the deconstructed times to facilitate implementation in UI
*/
export function checkOverlap(
previousStart: number,
previousEnd: number,
currentStart: number,
currentEnd: number,
): boolean {
// deal with simple case where the event is later
if (currentStart >= previousEnd) {
return false;
}
// at this point we know there may be an overlap
return Math.max(previousStart, currentStart) - Math.min(previousEnd, currentEnd) <= 0;
}
@@ -1,3 +1,4 @@
import { dayInMs, MILLIS_PER_HOUR } from './conversionUtils';
import { getTimeFromPrevious } from './getTimeFromPrevious';
describe('getTimeFromPrevious', () => {
@@ -7,7 +8,40 @@ describe('getTimeFromPrevious', () => {
const previousDuration = 2100000; // 35 minutes
const currentStart = 75600000; // 21:00
const currentEnd = 81000000; // 22:30
const expected = 75600000 - 71700000; // current staart - previousEnd
const expected = 75600000 - 71700000; // current start - previousEnd
expect(getTimeFromPrevious(currentStart, currentEnd, previousStart, previousEnd, previousDuration)).toBe(expected);
});
it('accounts for partially overlapping events', () => {
const previousStart = 10;
const previousEnd = 12;
const previousDuration = 2;
const currentStart = 11;
const currentEnd = 12;
const expected = -(previousEnd - currentStart);
expect(getTimeFromPrevious(currentStart, currentEnd, previousStart, previousEnd, previousDuration)).toBe(expected);
});
it('accounts for events that are fully contained', () => {
const previousStart = 8;
const previousEnd = 16;
const previousDuration = 8;
const currentStart = 10;
const currentEnd = 15;
const expected = -(previousEnd - currentStart);
expect(getTimeFromPrevious(currentStart, currentEnd, previousStart, previousEnd, previousDuration)).toBe(expected);
});
it('fully overlapping events are the next day', () => {
const previousStart = 10 * MILLIS_PER_HOUR;
const previousEnd = 12 * MILLIS_PER_HOUR;
const previousDuration = previousEnd - previousStart;
const currentStart = 10 * MILLIS_PER_HOUR;
const currentEnd = 12 * MILLIS_PER_HOUR;
const expected = dayInMs - previousDuration;
expect(getTimeFromPrevious(currentStart, currentEnd, previousStart, previousEnd, previousDuration)).toBe(expected);
});
@@ -1,6 +1,5 @@
import { checkIsNextDay } from './checkIsNextDay';
import { checkOverlap } from './checkOverlap';
import { dayInMs } from './conversionUtils';
import { checkIsNextDay } from './checkIsNextDay.js';
import { dayInMs } from './conversionUtils.js';
/**
* Utility returns the time elapsed (gap or overlap) from the previous
@@ -25,20 +24,22 @@ export function getTimeFromPrevious(
// event is the day after
if (checkIsNextDay(previousStart, currentStart, previousDuration)) {
// duration is difference between normalised start and previous end
// time from previous is difference between normalised start and previous end
return currentStart + dayInMs - previousEnd;
}
// event has a gap from previous
if (currentStart > previousEnd) {
// time from previous is difference between start and previous end
return currentStart - previousEnd;
}
// event overlaps with previous
if (checkOverlap(previousStart, previousEnd, currentStart, currentEnd)) {
// duration is the amount of time the current event has over the previous
// this value must be capped at 0
return Math.max(currentEnd - previousEnd, 0);
// TODO: account for midnight roll
const overlap = previousEnd - currentStart;
if (overlap > 0) {
// time is a negative number indicating the amount of overlap
return -overlap;
}
// we need to make sure we return a number, but there are no business cases for this