mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-20 14:39:06 +00:00
add test relative and update calc function
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
import { OffsetMode } from 'ontime-types';
|
||||||
|
import { dayInMs } from 'ontime-utils';
|
||||||
|
|
||||||
import { calculateTimeUntilStart, formatTime, nowInMillis } from '../time';
|
import { calculateTimeUntilStart, formatTime, nowInMillis } from '../time';
|
||||||
|
|
||||||
describe('nowInMillis()', () => {
|
describe('nowInMillis()', () => {
|
||||||
@@ -40,81 +43,251 @@ describe('formatTime()', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('calculateTimeUntilStart()', () => {
|
describe('calculateTimeUntilStart()', () => {
|
||||||
test('ontime', () => {
|
describe('Absolute', () => {
|
||||||
|
test('ontime', () => {
|
||||||
|
const test = {
|
||||||
|
timeStart: 100,
|
||||||
|
dayOffset: 0,
|
||||||
|
delay: 0,
|
||||||
|
currentDay: 0,
|
||||||
|
totalGap: 0,
|
||||||
|
clock: 90,
|
||||||
|
offset: 0,
|
||||||
|
offsetMode: OffsetMode.Absolute,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: false })).toBe(10);
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: true })).toBe(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('running behind', () => {
|
||||||
|
const test = {
|
||||||
|
timeStart: 100,
|
||||||
|
dayOffset: 0,
|
||||||
|
delay: 0,
|
||||||
|
currentDay: 0,
|
||||||
|
totalGap: 0,
|
||||||
|
clock: 90,
|
||||||
|
offset: -20,
|
||||||
|
offsetMode: OffsetMode.Absolute,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: false })).toBe(30);
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: true })).toBe(30);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('running ahead', () => {
|
||||||
|
const test = {
|
||||||
|
timeStart: 100,
|
||||||
|
dayOffset: 0,
|
||||||
|
delay: 0,
|
||||||
|
currentDay: 0,
|
||||||
|
totalGap: 0,
|
||||||
|
clock: 80,
|
||||||
|
offset: 10,
|
||||||
|
offsetMode: OffsetMode.Absolute,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: false })).toBe(20); // <-- when running ahead the unlinked timer stays put
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: true })).toBe(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('running behind with enough gaps', () => {
|
||||||
|
const test = {
|
||||||
|
timeStart: 100,
|
||||||
|
dayOffset: 0,
|
||||||
|
delay: 0,
|
||||||
|
currentDay: 0,
|
||||||
|
totalGap: 20,
|
||||||
|
clock: 50,
|
||||||
|
offset: -20,
|
||||||
|
offsetMode: OffsetMode.Absolute,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: false })).toBe(50);
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: true })).toBe(70); // This should not be possible
|
||||||
|
});
|
||||||
|
|
||||||
|
test('running behind with to little gaps', () => {
|
||||||
|
const test = {
|
||||||
|
timeStart: 100,
|
||||||
|
dayOffset: 0,
|
||||||
|
delay: 0,
|
||||||
|
currentDay: 0,
|
||||||
|
totalGap: 10,
|
||||||
|
clock: 50,
|
||||||
|
offset: -20,
|
||||||
|
offsetMode: OffsetMode.Absolute,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: false })).toBe(60);
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: true })).toBe(70); // This should not be possible
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Relative', () => {
|
||||||
|
test('Basic test', () => {
|
||||||
|
const test = {
|
||||||
|
timeStart: 0,
|
||||||
|
dayOffset: 0,
|
||||||
|
delay: 0,
|
||||||
|
currentDay: 0,
|
||||||
|
totalGap: 0,
|
||||||
|
clock: 100,
|
||||||
|
actualStart: 100,
|
||||||
|
plannedStart: 0,
|
||||||
|
offset: 0, // relative
|
||||||
|
// offset: -100, // absolute
|
||||||
|
offsetMode: OffsetMode.Relative,
|
||||||
|
};
|
||||||
|
|
||||||
|
const timeStartEvent2 = 10;
|
||||||
|
const timeStartEvent3 = 20;
|
||||||
|
|
||||||
|
expect(calculateTimeUntilStart({ ...test, timeStart: timeStartEvent2, isLinkedToLoaded: true })).toBe(10);
|
||||||
|
expect(calculateTimeUntilStart({ ...test, timeStart: timeStartEvent3, isLinkedToLoaded: true })).toBe(20);
|
||||||
|
expect(calculateTimeUntilStart({ ...test, timeStart: timeStartEvent2, isLinkedToLoaded: false })).toBe(10);
|
||||||
|
expect(calculateTimeUntilStart({ ...test, timeStart: timeStartEvent3, isLinkedToLoaded: false })).toBe(20);
|
||||||
|
|
||||||
|
test.clock = 105;
|
||||||
|
|
||||||
|
expect(calculateTimeUntilStart({ ...test, timeStart: timeStartEvent2, isLinkedToLoaded: true })).toBe(5);
|
||||||
|
expect(calculateTimeUntilStart({ ...test, timeStart: timeStartEvent3, isLinkedToLoaded: true })).toBe(15);
|
||||||
|
expect(calculateTimeUntilStart({ ...test, timeStart: timeStartEvent2, isLinkedToLoaded: false })).toBe(5);
|
||||||
|
expect(calculateTimeUntilStart({ ...test, timeStart: timeStartEvent3, isLinkedToLoaded: false })).toBe(15);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Test gaps', () => {
|
||||||
|
const test = {
|
||||||
|
timeStart: 20,
|
||||||
|
dayOffset: 0,
|
||||||
|
delay: 0,
|
||||||
|
currentDay: 0,
|
||||||
|
totalGap: 10,
|
||||||
|
clock: 100,
|
||||||
|
actualStart: 100,
|
||||||
|
plannedStart: 0,
|
||||||
|
offset: 0, // relative
|
||||||
|
// offset: -100, // absolute
|
||||||
|
offsetMode: OffsetMode.Relative,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: true })).toBe(20);
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: false })).toBe(20);
|
||||||
|
|
||||||
|
test.clock = 105;
|
||||||
|
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: true })).toBe(15);
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: false })).toBe(15);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Test added/remove time', () => {
|
||||||
|
const test = {
|
||||||
|
timeStart: 20,
|
||||||
|
dayOffset: 0,
|
||||||
|
delay: 0,
|
||||||
|
currentDay: 0,
|
||||||
|
totalGap: 0,
|
||||||
|
clock: 100,
|
||||||
|
actualStart: 100,
|
||||||
|
plannedStart: 0,
|
||||||
|
offset: 0, // relative
|
||||||
|
// offset: -100, // absolute
|
||||||
|
offsetMode: OffsetMode.Relative,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: true })).toBe(20);
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: false })).toBe(20);
|
||||||
|
|
||||||
|
test.offset = 5; // remove 5 with addtime - we are ahead of time
|
||||||
|
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: true })).toBe(15);
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: false })).toBe(20); // unlocked evets will stay on schedule
|
||||||
|
|
||||||
|
test.offset = -5; // add 5 with addtime - we are behind
|
||||||
|
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: true })).toBe(25);
|
||||||
|
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: false })).toBe(25);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Test next day', () => {
|
||||||
|
const test = {
|
||||||
|
// timeStart: 10,
|
||||||
|
// dayOffset: 0,
|
||||||
|
delay: 0,
|
||||||
|
currentDay: 0,
|
||||||
|
// totalGap: 0,
|
||||||
|
clock: 100,
|
||||||
|
actualStart: 100,
|
||||||
|
plannedStart: 0,
|
||||||
|
offset: 0, // relative
|
||||||
|
// offset: -100, // absolute
|
||||||
|
offsetMode: OffsetMode.Relative,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(
|
||||||
|
calculateTimeUntilStart({
|
||||||
|
...test,
|
||||||
|
timeStart: 10,
|
||||||
|
dayOffset: 0,
|
||||||
|
totalGap: 0,
|
||||||
|
isLinkedToLoaded: true,
|
||||||
|
}),
|
||||||
|
).toBe(10);
|
||||||
|
expect(
|
||||||
|
calculateTimeUntilStart({
|
||||||
|
...test,
|
||||||
|
timeStart: 10,
|
||||||
|
dayOffset: 0,
|
||||||
|
totalGap: 0,
|
||||||
|
isLinkedToLoaded: false,
|
||||||
|
}),
|
||||||
|
).toBe(10);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
calculateTimeUntilStart({
|
||||||
|
...test,
|
||||||
|
timeStart: 0,
|
||||||
|
dayOffset: 1,
|
||||||
|
totalGap: dayInMs - 20,
|
||||||
|
isLinkedToLoaded: false,
|
||||||
|
}),
|
||||||
|
).toBe(dayInMs);
|
||||||
|
|
||||||
|
test.clock = 200;
|
||||||
|
|
||||||
|
expect(
|
||||||
|
calculateTimeUntilStart({
|
||||||
|
...test,
|
||||||
|
timeStart: 0,
|
||||||
|
dayOffset: 1,
|
||||||
|
totalGap: dayInMs - 20,
|
||||||
|
isLinkedToLoaded: false,
|
||||||
|
}),
|
||||||
|
).toBe(dayInMs - 100);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Test overlap', () => {
|
||||||
const test = {
|
const test = {
|
||||||
timeStart: 100,
|
// timeStart: 20,
|
||||||
dayOffset: 0,
|
dayOffset: 0,
|
||||||
delay: 0,
|
delay: 0,
|
||||||
currentDay: 0,
|
currentDay: 0,
|
||||||
totalGap: 0,
|
// totalGap: 10,
|
||||||
clock: 90,
|
clock: 100,
|
||||||
offset: 0,
|
actualStart: 100,
|
||||||
|
plannedStart: 0,
|
||||||
|
offset: 0, // relative
|
||||||
|
// offset: -100, // absolute
|
||||||
|
offsetMode: OffsetMode.Relative,
|
||||||
|
isLinkedToLoaded: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: false })).toBe(10);
|
expect(calculateTimeUntilStart({ ...test, timeStart: 5, totalGap: -5 })).toBe(10);
|
||||||
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: true })).toBe(10);
|
|
||||||
|
test.clock = 105;
|
||||||
});
|
});
|
||||||
|
|
||||||
test('running behind', () => {
|
|
||||||
const test = {
|
|
||||||
timeStart: 100,
|
|
||||||
dayOffset: 0,
|
|
||||||
delay: 0,
|
|
||||||
currentDay: 0,
|
|
||||||
totalGap: 0,
|
|
||||||
clock: 90,
|
|
||||||
offset: -20,
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: false })).toBe(30);
|
|
||||||
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: true })).toBe(30);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('running ahead', () => {
|
|
||||||
const test = {
|
|
||||||
timeStart: 100,
|
|
||||||
dayOffset: 0,
|
|
||||||
delay: 0,
|
|
||||||
currentDay: 0,
|
|
||||||
totalGap: 0,
|
|
||||||
clock: 80,
|
|
||||||
offset: 10,
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: false })).toBe(20); // <-- when running ahead the unlinked timer stays put
|
|
||||||
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: true })).toBe(10);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('running behind with enough gaps', () => {
|
|
||||||
const test = {
|
|
||||||
timeStart: 100,
|
|
||||||
dayOffset: 0,
|
|
||||||
delay: 0,
|
|
||||||
currentDay: 0,
|
|
||||||
totalGap: 20,
|
|
||||||
clock: 50,
|
|
||||||
offset: -20,
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: false })).toBe(50);
|
|
||||||
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: true })).toBe(70); // This should not be possible
|
|
||||||
});
|
|
||||||
|
|
||||||
test('running behind with to little gaps', () => {
|
|
||||||
const test = {
|
|
||||||
timeStart: 100,
|
|
||||||
dayOffset: 0,
|
|
||||||
delay: 0,
|
|
||||||
currentDay: 0,
|
|
||||||
totalGap: 10,
|
|
||||||
clock: 50,
|
|
||||||
offset: -20,
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: false })).toBe(60);
|
|
||||||
expect(calculateTimeUntilStart({ ...test, isLinkedToLoaded: true })).toBe(70); // This should not be possible
|
|
||||||
});
|
|
||||||
|
|
||||||
//TODO: more indepth testing,
|
//TODO: more indepth testing,
|
||||||
// including day offset handling
|
// including day offset handling
|
||||||
// and more?
|
// and more?
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MaybeNumber, OntimeEvent, Settings, TimeFormat } from 'ontime-types';
|
import { MaybeNumber, OffsetMode, OntimeEvent, Settings, TimeFormat } from 'ontime-types';
|
||||||
import { dayInMs, formatFromMillis, MILLIS_PER_HOUR, MILLIS_PER_MINUTE, MILLIS_PER_SECOND } from 'ontime-utils';
|
import { dayInMs, formatFromMillis, MILLIS_PER_HOUR, MILLIS_PER_MINUTE, MILLIS_PER_SECOND } from 'ontime-utils';
|
||||||
|
|
||||||
import { FORMAT_12, FORMAT_24 } from '../../viewerConfig';
|
import { FORMAT_12, FORMAT_24 } from '../../viewerConfig';
|
||||||
@@ -138,6 +138,7 @@ export function useTimeUntilStart(
|
|||||||
data: Pick<OntimeEvent, 'timeStart' | 'dayOffset' | 'delay'> & {
|
data: Pick<OntimeEvent, 'timeStart' | 'dayOffset' | 'delay'> & {
|
||||||
totalGap: number;
|
totalGap: number;
|
||||||
isLinkedToLoaded: boolean;
|
isLinkedToLoaded: boolean;
|
||||||
|
offsetMode: OffsetMode;
|
||||||
},
|
},
|
||||||
): number {
|
): number {
|
||||||
const { offset, clock, currentDay } = useTimeUntilData();
|
const { offset, clock, currentDay } = useTimeUntilData();
|
||||||
@@ -160,9 +161,24 @@ export function calculateTimeUntilStart(
|
|||||||
isLinkedToLoaded: boolean;
|
isLinkedToLoaded: boolean;
|
||||||
clock: number;
|
clock: number;
|
||||||
offset: number;
|
offset: number;
|
||||||
|
offsetMode: OffsetMode;
|
||||||
|
actualStart?: number;
|
||||||
|
plannedStart?: number;
|
||||||
},
|
},
|
||||||
): number {
|
): number {
|
||||||
const { timeStart, dayOffset, currentDay, totalGap, isLinkedToLoaded, clock, offset, delay } = data;
|
const {
|
||||||
|
timeStart,
|
||||||
|
dayOffset,
|
||||||
|
currentDay,
|
||||||
|
totalGap,
|
||||||
|
isLinkedToLoaded,
|
||||||
|
clock,
|
||||||
|
offset,
|
||||||
|
delay,
|
||||||
|
offsetMode,
|
||||||
|
actualStart,
|
||||||
|
plannedStart,
|
||||||
|
} = data;
|
||||||
|
|
||||||
//How many days from the currently running event to this one
|
//How many days from the currently running event to this one
|
||||||
const relativeDayOffset = dayOffset - currentDay;
|
const relativeDayOffset = dayOffset - currentDay;
|
||||||
@@ -172,20 +188,25 @@ export function calculateTimeUntilStart(
|
|||||||
//The normalised start time of this event relative to the currently running event
|
//The normalised start time of this event relative to the currently running event
|
||||||
const normalisedTimeStart = delayedStart + relativeDayOffset * dayInMs;
|
const normalisedTimeStart = delayedStart + relativeDayOffset * dayInMs;
|
||||||
|
|
||||||
const offsetTimestart = normalisedTimeStart - offset;
|
let relativeStartOffset = 0;
|
||||||
const offsetTimeUntil = offsetTimestart - clock;
|
|
||||||
|
if (offsetMode === OffsetMode.Relative) {
|
||||||
|
assert(actualStart !== undefined);
|
||||||
|
assert(plannedStart !== undefined);
|
||||||
|
relativeStartOffset = actualStart - plannedStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
const scheduledTimeUntil = normalisedTimeStart - clock + relativeStartOffset;
|
||||||
|
|
||||||
|
const offsetTimeUntil = scheduledTimeUntil - offset;
|
||||||
|
|
||||||
if (isLinkedToLoaded) {
|
if (isLinkedToLoaded) {
|
||||||
//if we are directly linked back to the loaded event we just follow the offset
|
//if we are directly linked back to the loaded event we just follow the offset
|
||||||
return offsetTimeUntil;
|
return offsetTimeUntil;
|
||||||
}
|
}
|
||||||
|
|
||||||
const scheduledTimeUntil = normalisedTimeStart - clock;
|
|
||||||
|
|
||||||
const isAheadOfSchedule = offset >= 0;
|
|
||||||
const gapsCanCompensadeForOffset = totalGap + offset >= 0;
|
const gapsCanCompensadeForOffset = totalGap + offset >= 0;
|
||||||
|
if (gapsCanCompensadeForOffset) {
|
||||||
if (isAheadOfSchedule || gapsCanCompensadeForOffset) {
|
|
||||||
// if we are ahead of schedule or the gap can compensate for the amount we are behind then expect to start at the scheduled time
|
// if we are ahead of schedule or the gap can compensate for the amount we are behind then expect to start at the scheduled time
|
||||||
return scheduledTimeUntil;
|
return scheduledTimeUntil;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user