mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-06 14:59:09 +00:00
@@ -1,6 +1,6 @@
|
|||||||
import { Timer } from './Timer.js';
|
import { Timer } from './Timer.js';
|
||||||
import { Server } from 'socket.io';
|
import { Server } from 'socket.io';
|
||||||
import { getSelectionByRoll } from './classUtils.js';
|
import {DAYMS, getSelectionByRoll} from './classUtils.js';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* EventTimer adds functions specific to APP
|
* EventTimer adds functions specific to APP
|
||||||
@@ -11,9 +11,6 @@ import { getSelectionByRoll } from './classUtils.js';
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export class EventTimer extends Timer {
|
export class EventTimer extends Timer {
|
||||||
// AUX
|
|
||||||
DAYMS = 86400000;
|
|
||||||
|
|
||||||
// Socket IO Object
|
// Socket IO Object
|
||||||
io = null;
|
io = null;
|
||||||
|
|
||||||
@@ -701,7 +698,7 @@ export class EventTimer extends Timer {
|
|||||||
const start = e.timeStart == null || e.timeStart === '' ? 0 : e.timeStart;
|
const start = e.timeStart == null || e.timeStart === '' ? 0 : e.timeStart;
|
||||||
let end = e.timeEnd == null || e.timeEnd === '' ? 0 : e.timeEnd;
|
let end = e.timeEnd == null || e.timeEnd === '' ? 0 : e.timeEnd;
|
||||||
// in case the end is earlier than start, we assume is the day after
|
// in case the end is earlier than start, we assume is the day after
|
||||||
if (end < start) end += this.DAYMS;
|
if (end < start) end += DAYMS;
|
||||||
|
|
||||||
// time stuff changes on wheter we keep the running clock
|
// time stuff changes on wheter we keep the running clock
|
||||||
|
|
||||||
|
|||||||
@@ -24,29 +24,6 @@ export class Timer {
|
|||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
// call setup separately
|
|
||||||
setupWithSeconds(seconds, autoStart = false) {
|
|
||||||
// aux
|
|
||||||
const now = this._getCurrentTime();
|
|
||||||
this.clock = now;
|
|
||||||
|
|
||||||
// populate targets
|
|
||||||
this.duration = seconds * 1000;
|
|
||||||
this._finishAt = now + seconds * 1000;
|
|
||||||
|
|
||||||
// start counting
|
|
||||||
this._startedAt = now;
|
|
||||||
|
|
||||||
if (autoStart) {
|
|
||||||
this.state = 'start';
|
|
||||||
} else {
|
|
||||||
this._pausedAt = now;
|
|
||||||
this._pausedInterval = 0;
|
|
||||||
}
|
|
||||||
this._pausedTotal = 0;
|
|
||||||
this.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
// update()
|
// update()
|
||||||
update() {
|
update() {
|
||||||
// get current time
|
// get current time
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { getSelectionByRoll, sortArrayByProperty } from '../classUtils.js';
|
import {DAYMS, getSelectionByRoll, normaliseEndTime, sortArrayByProperty} from '../classUtils.js';
|
||||||
|
|
||||||
// test sortArrayByProperty()
|
// test sortArrayByProperty()
|
||||||
describe('sort simple arrays of objects', () => {
|
describe('sort simple arrays of objects', () => {
|
||||||
@@ -244,6 +244,7 @@ describe('test that roll loads selection in right order', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// test getSelectionByRoll()
|
// test getSelectionByRoll()
|
||||||
|
|
||||||
describe('test that roll behaviour with overlapping times', () => {
|
describe('test that roll behaviour with overlapping times', () => {
|
||||||
const eventlist = [
|
const eventlist = [
|
||||||
{
|
{
|
||||||
@@ -382,3 +383,90 @@ describe('test that roll behaviour with overlapping times', () => {
|
|||||||
expect(state).toStrictEqual(expected);
|
expect(state).toStrictEqual(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// test getSelectionByRoll() on issue #58
|
||||||
|
describe('test that roll behaviour multi day event edge cases', () => {
|
||||||
|
|
||||||
|
it('if the start time is the day after end time, and start time is earlier than now', () => {
|
||||||
|
const now = 66600000; // 19:30
|
||||||
|
const eventlist = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
timeStart: 66000000, // 19:20
|
||||||
|
timeEnd: 54600000, // 16:10
|
||||||
|
isPublic: false,
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const expected = {
|
||||||
|
nowIndex: 0,
|
||||||
|
nowId: 1,
|
||||||
|
publicIndex: null,
|
||||||
|
nextIndex: null,
|
||||||
|
publicNextIndex: null,
|
||||||
|
timers: {
|
||||||
|
_startedAt: eventlist[0].timeStart,
|
||||||
|
_finishAt: eventlist[0].timeEnd,
|
||||||
|
current: eventlist[0].timeEnd + DAYMS - now,
|
||||||
|
duration: DAYMS - eventlist[0].timeStart + eventlist[0].timeEnd,
|
||||||
|
},
|
||||||
|
timeToNext: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const state = getSelectionByRoll(eventlist, now);
|
||||||
|
expect(state).toStrictEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('if the start time is the day after end time, and both are later than now', () => {
|
||||||
|
const now = 66840000; // 19:34
|
||||||
|
const eventlist = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
timeStart: 67200000, // 19:40
|
||||||
|
timeEnd: 66900000, // 19:35
|
||||||
|
isPublic: false,
|
||||||
|
}
|
||||||
|
];
|
||||||
|
const expected = {
|
||||||
|
nowIndex: null,
|
||||||
|
nowId: null,
|
||||||
|
publicIndex: null,
|
||||||
|
nextIndex: 0,
|
||||||
|
publicNextIndex: null,
|
||||||
|
timers: null,
|
||||||
|
timeToNext: eventlist[0].timeStart - now,
|
||||||
|
};
|
||||||
|
|
||||||
|
const state = getSelectionByRoll(eventlist, now);
|
||||||
|
expect(state).toStrictEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// test normaliseEndTime() on issue #58
|
||||||
|
test('test typical scenarios', () => {
|
||||||
|
|
||||||
|
const t1 = {
|
||||||
|
start: 10,
|
||||||
|
end: 20,
|
||||||
|
}
|
||||||
|
const t1_expected = 20;
|
||||||
|
|
||||||
|
expect(normaliseEndTime(t1.start, t1.end)).toBe(t1_expected);
|
||||||
|
|
||||||
|
const t2 = {
|
||||||
|
start: 10+DAYMS,
|
||||||
|
end: 20,
|
||||||
|
}
|
||||||
|
const t2_expected = 20+DAYMS;
|
||||||
|
|
||||||
|
expect(normaliseEndTime(t2.start, t2.end)).toBe(t2_expected);
|
||||||
|
|
||||||
|
const t3 = {
|
||||||
|
start: 10,
|
||||||
|
end: 10,
|
||||||
|
}
|
||||||
|
const t3_expected = 10;
|
||||||
|
|
||||||
|
expect(normaliseEndTime(t3.start, t3.end)).toBe(t3_expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import {Timer} from "../Timer";
|
||||||
|
|
||||||
|
test('object instantiates correctly', () => {
|
||||||
|
const t = new Timer();
|
||||||
|
|
||||||
|
expect(t.clock).toBeNull;
|
||||||
|
expect(t.duration).toBeNull;
|
||||||
|
expect(t.current).toBeNull;
|
||||||
|
expect(t.timeTag).toBeNull;
|
||||||
|
expect(t.secondaryTimer).toBeNull;
|
||||||
|
expect(t._secondaryTarget).toBeNull;
|
||||||
|
expect(t._finishAt).toBeNull;
|
||||||
|
expect(t._finishedAt).toBeNull;
|
||||||
|
expect(t._finishedFlag).toBeFalsy;
|
||||||
|
expect(t._startedAt).toBeNull;
|
||||||
|
expect(t._pausedAt).toBeNull;
|
||||||
|
expect(t._pausedInterval).toBeNull;
|
||||||
|
expect(t._pausedTotal).toBeNull;
|
||||||
|
expect(t.state).toBe('stop');
|
||||||
|
})
|
||||||
@@ -1,3 +1,14 @@
|
|||||||
|
export const DAYMS = 86400000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description handle events that span over midnight
|
||||||
|
* @param {num} start - When does the event start
|
||||||
|
* @param {num} end - When does the event end
|
||||||
|
* @returns {num} normalised time
|
||||||
|
*/
|
||||||
|
export const normaliseEndTime = (start, end) => (end < start ? end + DAYMS : end);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Sorts an array of objects by given property
|
* @description Sorts an array of objects by given property
|
||||||
* @param {array} arr - array to be sorted
|
* @param {array} arr - array to be sorted
|
||||||
@@ -41,8 +52,9 @@ export const getSelectionByRoll = (arr, now) => {
|
|||||||
let nowFound = false;
|
let nowFound = false;
|
||||||
|
|
||||||
// exit early if we are past the events
|
// exit early if we are past the events
|
||||||
const lastEventEnd = orderedEvents[orderedEvents.length - 1].timeEnd;
|
const lastEvent = orderedEvents[orderedEvents.length - 1];
|
||||||
if (now > lastEventEnd) {
|
const lastNormalEnd = normaliseEndTime(lastEvent.timeStart, lastEvent.timeEnd);
|
||||||
|
if (now > lastNormalEnd) {
|
||||||
return {
|
return {
|
||||||
nowIndex,
|
nowIndex,
|
||||||
nowId,
|
nowId,
|
||||||
@@ -57,8 +69,7 @@ export const getSelectionByRoll = (arr, now) => {
|
|||||||
// loop through events, look for where we should be
|
// loop through events, look for where we should be
|
||||||
for (const e of orderedEvents) {
|
for (const e of orderedEvents) {
|
||||||
// When does the event end (handle midnight)
|
// When does the event end (handle midnight)
|
||||||
const normalEnd =
|
const normalEnd = normaliseEndTime(e.timeStart, e.timeEnd);
|
||||||
e.timeEnd < e.timeStart ? (e.timeEnd += this.DAYMS) : e.timeEnd;
|
|
||||||
|
|
||||||
if (normalEnd <= now) {
|
if (normalEnd <= now) {
|
||||||
// event ran already
|
// event ran already
|
||||||
@@ -83,7 +94,7 @@ export const getSelectionByRoll = (arr, now) => {
|
|||||||
// set timers
|
// set timers
|
||||||
timers = {
|
timers = {
|
||||||
_startedAt: e.timeStart,
|
_startedAt: e.timeStart,
|
||||||
_finishAt: normalEnd,
|
_finishAt: e.timeEnd,
|
||||||
duration: normalEnd - e.timeStart,
|
duration: normalEnd - e.timeStart,
|
||||||
current: normalEnd - now,
|
current: normalEnd - now,
|
||||||
};
|
};
|
||||||
@@ -118,3 +129,4 @@ export const getSelectionByRoll = (arr, now) => {
|
|||||||
timeToNext,
|
timeToNext,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ describe('test excel date parser', () => {
|
|||||||
expect(excelDateStringToMillis(d2)).toBe(d2Millis);
|
expect(excelDateStringToMillis(d2)).toBe(d2Millis);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.only('handles an invalid date string', () => {
|
it('handles an invalid date string', () => {
|
||||||
const s = 'hello';
|
const s = 'hello';
|
||||||
expect(excelDateStringToMillis(s)).toBe(null);
|
expect(excelDateStringToMillis(s)).toBe(null);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user