mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-10 18:03:47 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6d7cd416dc |
@@ -225,7 +225,7 @@ describe('getExpectedFinish()', () => {
|
|||||||
expect(calculatedFinish).toBe(10);
|
expect(calculatedFinish).toBe(10);
|
||||||
});
|
});
|
||||||
describe('on timers of type time-to-end', () => {
|
describe('on timers of type time-to-end', () => {
|
||||||
it('finish time is as schedule + added time', () => {
|
it('finish time is the fixed end, ignoring added time', () => {
|
||||||
const state = {
|
const state = {
|
||||||
eventNow: {
|
eventNow: {
|
||||||
timeEnd: 30,
|
timeEnd: 30,
|
||||||
@@ -245,6 +245,29 @@ describe('getExpectedFinish()', () => {
|
|||||||
const calculatedFinish = getExpectedFinish(state);
|
const calculatedFinish = getExpectedFinish(state);
|
||||||
expect(calculatedFinish).toBe(40);
|
expect(calculatedFinish).toBe(40);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('finish time is the fixed end, including paused time', () => {
|
||||||
|
const state = {
|
||||||
|
eventNow: {
|
||||||
|
timeEnd: 30,
|
||||||
|
countToEnd: true,
|
||||||
|
},
|
||||||
|
clock: 25,
|
||||||
|
timer: {
|
||||||
|
addedTime: 0,
|
||||||
|
duration: dayInMs,
|
||||||
|
startedAt: 10,
|
||||||
|
},
|
||||||
|
_timer: {
|
||||||
|
pausedAt: 20, // paused 5 ago
|
||||||
|
hasFinished: false,
|
||||||
|
},
|
||||||
|
} as RuntimeState;
|
||||||
|
|
||||||
|
const calculatedFinish = getExpectedFinish(state);
|
||||||
|
expect(calculatedFinish).toBe(35);
|
||||||
|
});
|
||||||
|
|
||||||
it('handles events that finish the day after', () => {
|
it('handles events that finish the day after', () => {
|
||||||
const state = {
|
const state = {
|
||||||
eventNow: {
|
eventNow: {
|
||||||
@@ -404,6 +427,9 @@ describe('getCurrent()', () => {
|
|||||||
it('current time is the time to end even if it hasnt started, this is weird, but by design', () => {
|
it('current time is the time to end even if it hasnt started, this is weird, but by design', () => {
|
||||||
const state = {
|
const state = {
|
||||||
eventNow: {
|
eventNow: {
|
||||||
|
timeStart: 0,
|
||||||
|
duration: 100,
|
||||||
|
dayOffset: 0,
|
||||||
timeEnd: 100,
|
timeEnd: 100,
|
||||||
countToEnd: true,
|
countToEnd: true,
|
||||||
},
|
},
|
||||||
@@ -429,6 +455,9 @@ describe('getCurrent()', () => {
|
|||||||
it('current time is the time to end', () => {
|
it('current time is the time to end', () => {
|
||||||
const state = {
|
const state = {
|
||||||
eventNow: {
|
eventNow: {
|
||||||
|
timeStart: 0,
|
||||||
|
duration: 100,
|
||||||
|
dayOffset: 0,
|
||||||
timeEnd: 100,
|
timeEnd: 100,
|
||||||
countToEnd: true,
|
countToEnd: true,
|
||||||
},
|
},
|
||||||
@@ -451,10 +480,13 @@ describe('getCurrent()', () => {
|
|||||||
expect(current).toBe(70);
|
expect(current).toBe(70);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('current time is the time to end + added time', () => {
|
it('current time is the time to end, ignoring added time', () => {
|
||||||
const state = {
|
const state = {
|
||||||
eventNow: {
|
eventNow: {
|
||||||
|
timeStart: 0,
|
||||||
|
duration: 100,
|
||||||
timeEnd: 100,
|
timeEnd: 100,
|
||||||
|
dayOffset: 0,
|
||||||
countToEnd: true,
|
countToEnd: true,
|
||||||
},
|
},
|
||||||
clock: 30,
|
clock: 30,
|
||||||
@@ -480,8 +512,10 @@ describe('getCurrent()', () => {
|
|||||||
const state = {
|
const state = {
|
||||||
eventNow: {
|
eventNow: {
|
||||||
timeStart: 79200000, // 22:00:00
|
timeStart: 79200000, // 22:00:00
|
||||||
|
duration: 2 * MILLIS_PER_HOUR + 10 * MILLIS_PER_MINUTE,
|
||||||
timeEnd: 600000, // 00:10:00
|
timeEnd: 600000, // 00:10:00
|
||||||
countToEnd: true,
|
countToEnd: true,
|
||||||
|
dayOffset: 0,
|
||||||
},
|
},
|
||||||
clock: 79500000, // 22:05:00
|
clock: 79500000, // 22:05:00
|
||||||
timer: {
|
timer: {
|
||||||
@@ -492,6 +526,7 @@ describe('getCurrent()', () => {
|
|||||||
rundown: {
|
rundown: {
|
||||||
actualStart: 79200000,
|
actualStart: 79200000,
|
||||||
plannedEnd: 600000,
|
plannedEnd: 600000,
|
||||||
|
currentDay: 0,
|
||||||
},
|
},
|
||||||
_timer: {
|
_timer: {
|
||||||
pausedAt: null,
|
pausedAt: null,
|
||||||
@@ -503,6 +538,36 @@ describe('getCurrent()', () => {
|
|||||||
expect(current).toBe(dayInMs - 79500000 + 600000);
|
expect(current).toBe(dayInMs - 79500000 + 600000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('handles overnight count-to-end after midnight', () => {
|
||||||
|
const state = {
|
||||||
|
eventNow: {
|
||||||
|
timeStart: 23 * MILLIS_PER_HOUR, // 23:00:00
|
||||||
|
duration: 2 * MILLIS_PER_HOUR, // 2h
|
||||||
|
timeEnd: 1 * MILLIS_PER_HOUR, // 01:00:00
|
||||||
|
countToEnd: true,
|
||||||
|
dayOffset: 0,
|
||||||
|
},
|
||||||
|
clock: 30 * MILLIS_PER_MINUTE, // 00:30:00 on day 1
|
||||||
|
timer: {
|
||||||
|
addedTime: 0,
|
||||||
|
duration: Infinity, // not relevant,
|
||||||
|
startedAt: 23 * MILLIS_PER_HOUR,
|
||||||
|
},
|
||||||
|
rundown: {
|
||||||
|
actualStart: 23 * MILLIS_PER_HOUR,
|
||||||
|
plannedEnd: 1 * MILLIS_PER_HOUR,
|
||||||
|
currentDay: 1,
|
||||||
|
},
|
||||||
|
_timer: {
|
||||||
|
pausedAt: null,
|
||||||
|
hasFinished: false,
|
||||||
|
},
|
||||||
|
} as RuntimeState;
|
||||||
|
|
||||||
|
const current = getCurrent(state);
|
||||||
|
expect(current).toBe(30 * MILLIS_PER_MINUTE);
|
||||||
|
});
|
||||||
|
|
||||||
it('handles events that were started late', () => {
|
it('handles events that were started late', () => {
|
||||||
const state = {
|
const state = {
|
||||||
clock: 82000000, // 22:46:40 <--- starting 16 min after the scheduled end
|
clock: 82000000, // 22:46:40 <--- starting 16 min after the scheduled end
|
||||||
@@ -511,6 +576,7 @@ describe('getCurrent()', () => {
|
|||||||
timeEnd: 81000000, // 22:30:00
|
timeEnd: 81000000, // 22:30:00
|
||||||
duration: 3600000, // 01:00:00
|
duration: 3600000, // 01:00:00
|
||||||
countToEnd: true,
|
countToEnd: true,
|
||||||
|
dayOffset: 0,
|
||||||
},
|
},
|
||||||
timer: {
|
timer: {
|
||||||
addedTime: 0,
|
addedTime: 0,
|
||||||
@@ -1073,7 +1139,7 @@ describe('getRuntimeOffset()', () => {
|
|||||||
expect(absolute).toBe(0);
|
expect(absolute).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with time-to-end, offset is the overtime', () => {
|
it('with time-to-end, offset combines overtime and added time', () => {
|
||||||
const state = {
|
const state = {
|
||||||
clock: 82000000, // 22:46:40
|
clock: 82000000, // 22:46:40
|
||||||
eventNow: {
|
eventNow: {
|
||||||
@@ -1126,7 +1192,45 @@ describe('getRuntimeOffset()', () => {
|
|||||||
} as RuntimeState;
|
} as RuntimeState;
|
||||||
|
|
||||||
const { absolute } = getRuntimeOffset(state);
|
const { absolute } = getRuntimeOffset(state);
|
||||||
expect(absolute).toBe(400000 - 200000); // <--- offset is always the overtime + added time
|
// overtime (400000) plus the operator's added time (-200000)
|
||||||
|
expect(absolute).toBe(200000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('with time-to-end', () => {
|
||||||
|
const state = {
|
||||||
|
clock: 80000000, // 22:13:20 - before the scheduled end, not in overtime
|
||||||
|
eventNow: {
|
||||||
|
id: 'd6a2ce',
|
||||||
|
timeStart: 77400000, // 21:30:00
|
||||||
|
timeEnd: 81000000, // 22:30:00
|
||||||
|
duration: 3600000, // 01:00:00
|
||||||
|
timeStrategy: TimeStrategy.LockEnd,
|
||||||
|
countToEnd: true,
|
||||||
|
dayOffset: 0,
|
||||||
|
delay: 0,
|
||||||
|
},
|
||||||
|
rundown: {
|
||||||
|
plannedStart: 77400000, // 21:30:00
|
||||||
|
plannedEnd: 81000000, // 22:30:00
|
||||||
|
actualStart: 78000000, // 21:40:00
|
||||||
|
currentDay: 0,
|
||||||
|
},
|
||||||
|
offset: {
|
||||||
|
absolute: 0,
|
||||||
|
},
|
||||||
|
timer: {
|
||||||
|
addedTime: 300000, // operator added 5 minutes
|
||||||
|
current: 1000000, // still counting down, no overtime
|
||||||
|
duration: 3600000,
|
||||||
|
startedAt: 78000000,
|
||||||
|
},
|
||||||
|
_startDayOffset: 0,
|
||||||
|
_timer: { pausedAt: null },
|
||||||
|
} as RuntimeState;
|
||||||
|
|
||||||
|
// the end is anchored, so the added 5 minutes shows up as offset
|
||||||
|
const { absolute } = getRuntimeOffset(state);
|
||||||
|
expect(absolute).toBe(300000);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('handles time-to-end started after the end time', () => {
|
it('handles time-to-end started after the end time', () => {
|
||||||
|
|||||||
@@ -62,34 +62,34 @@ export function getExpectedFinish(state: RuntimeState): MaybeNumber {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export function getCurrent(state: RuntimeState): number {
|
export function getCurrent(state: RuntimeState): number {
|
||||||
|
const { timer, eventNow } = state;
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-labels -- dev code path
|
// eslint-disable-next-line no-unused-labels -- dev code path
|
||||||
DEV: {
|
DEV: {
|
||||||
if (state.eventNow === null || state.timer.duration === null) {
|
if (eventNow === null || timer.duration === null) {
|
||||||
throw new Error('timerUtils.getCurrent: invalid state received');
|
throw new Error('timerUtils.getCurrent: invalid state received');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const { startedAt, duration, addedTime } = state.timer;
|
|
||||||
const { countToEnd, timeStart, timeEnd } = state.eventNow;
|
|
||||||
const { pausedAt } = state._timer;
|
const { pausedAt } = state._timer;
|
||||||
const { clock } = state;
|
const { clock } = state;
|
||||||
|
|
||||||
if (countToEnd) {
|
if (eventNow.countToEnd) {
|
||||||
const isEventOverMidnight = timeStart > timeEnd;
|
const clockDayCorrected = clock + (state.rundown.currentDay ?? 0) * dayInMs;
|
||||||
const correctDay = isEventOverMidnight ? dayInMs : 0;
|
const eventDayOffset = eventNow.dayOffset * dayInMs;
|
||||||
return correctDay - clock + timeEnd + addedTime;
|
return eventDayOffset + eventNow.timeStart + eventNow.duration + timer.addedTime - clockDayCorrected;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startedAt === null) {
|
if (timer.startedAt === null) {
|
||||||
return duration;
|
return timer.duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pausedAt != null) {
|
if (pausedAt != null) {
|
||||||
return startedAt + duration + addedTime - pausedAt;
|
return timer.startedAt + timer.duration + timer.addedTime - pausedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasPassedMidnight = startedAt > clock;
|
const hasPassedMidnight = timer.startedAt > clock;
|
||||||
const correctDay = hasPassedMidnight ? dayInMs : 0;
|
const correctDay = hasPassedMidnight ? dayInMs : 0;
|
||||||
return startedAt + duration + addedTime - clock - correctDay;
|
return timer.startedAt + timer.duration + timer.addedTime - clock - correctDay;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user