mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-20 22:49:18 +00:00
refactor: restructure model to contain an object of rundowns
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import type { NormalisedRundown, OntimeEvent, OntimeRundown } from 'ontime-types';
|
||||
import type { OntimeBlock, OntimeDelay, OntimeEntry, OntimeEvent } from 'ontime-types';
|
||||
import { SupportedEvent } from 'ontime-types';
|
||||
|
||||
import {
|
||||
filterPlayable,
|
||||
getLastEvent,
|
||||
getLastNormal,
|
||||
getNext,
|
||||
@@ -15,36 +14,46 @@ import {
|
||||
|
||||
describe('getNext()', () => {
|
||||
it('returns the next event of type event', () => {
|
||||
const testRundown = [
|
||||
{ id: '1', type: SupportedEvent.Event },
|
||||
{ id: '2', type: SupportedEvent.Event },
|
||||
{ id: '3', type: SupportedEvent.Event },
|
||||
];
|
||||
const testRundown = {
|
||||
entries: {
|
||||
'1': { id: '1', type: SupportedEvent.Event } as OntimeEvent,
|
||||
'2': { id: '2', type: SupportedEvent.Event } as OntimeEvent,
|
||||
'3': { id: '3', type: SupportedEvent.Event } as OntimeEvent,
|
||||
},
|
||||
order: ['1', '2', '3'],
|
||||
};
|
||||
|
||||
const { nextEvent, nextIndex } = getNext(testRundown as OntimeRundown, '1');
|
||||
const { nextEvent, nextIndex } = getNext(testRundown, '1');
|
||||
expect(nextEvent?.id).toBe('2');
|
||||
expect(nextIndex).toBe(1);
|
||||
});
|
||||
it('alows other event types', () => {
|
||||
const testRundown = [
|
||||
{ id: '1', type: SupportedEvent.Event },
|
||||
{ id: '2', type: SupportedEvent.Delay },
|
||||
{ id: '3', type: SupportedEvent.Block },
|
||||
{ id: '4', type: SupportedEvent.Event },
|
||||
];
|
||||
|
||||
const { nextEvent, nextIndex } = getNext(testRundown as OntimeRundown, '1');
|
||||
it('returns any type of OntimeEntry ', () => {
|
||||
const testRundown = {
|
||||
entries: {
|
||||
'1': { id: '1', type: SupportedEvent.Event } as OntimeEvent,
|
||||
'2': { id: '2', type: SupportedEvent.Delay } as OntimeDelay,
|
||||
'3': { id: '3', type: SupportedEvent.Block } as OntimeBlock,
|
||||
'4': { id: '4', type: SupportedEvent.Event } as OntimeEvent,
|
||||
},
|
||||
order: ['1', '2', '3', '4'],
|
||||
};
|
||||
|
||||
const { nextEvent, nextIndex } = getNext(testRundown, '1');
|
||||
expect(nextEvent?.id).toBe('2');
|
||||
expect(nextIndex).toBe(1);
|
||||
});
|
||||
|
||||
it('returns null if none found', () => {
|
||||
const testRundown = [
|
||||
{ id: '1', type: SupportedEvent.Event },
|
||||
{ id: '2', type: SupportedEvent.Delay },
|
||||
{ id: '3', type: SupportedEvent.Block },
|
||||
];
|
||||
|
||||
const { nextEvent, nextIndex } = getNext(testRundown as OntimeRundown, '3');
|
||||
const testRundown = {
|
||||
entries: {
|
||||
'1': { id: '1', type: SupportedEvent.Event } as OntimeEvent,
|
||||
'2': { id: '2', type: SupportedEvent.Event } as OntimeEvent,
|
||||
'3': { id: '3', type: SupportedEvent.Event } as OntimeEvent,
|
||||
},
|
||||
order: ['1', '2', '3'],
|
||||
};
|
||||
const { nextEvent, nextIndex } = getNext(testRundown, '3');
|
||||
expect(nextEvent).toBe(null);
|
||||
expect(nextIndex).toBe(null);
|
||||
});
|
||||
@@ -53,35 +62,37 @@ describe('getNext()', () => {
|
||||
describe('getNextEvent()', () => {
|
||||
it('returns the next event of type event', () => {
|
||||
const testRundown = [
|
||||
{ id: '1', type: SupportedEvent.Event },
|
||||
{ id: '2', type: SupportedEvent.Event },
|
||||
{ id: '3', type: SupportedEvent.Event },
|
||||
{ id: '1', type: SupportedEvent.Event } as OntimeEvent,
|
||||
{ id: '2', type: SupportedEvent.Event } as OntimeEvent,
|
||||
{ id: '3', type: SupportedEvent.Event } as OntimeEvent,
|
||||
];
|
||||
|
||||
const { nextEvent, nextIndex } = getNextEvent(testRundown as OntimeRundown, '1');
|
||||
const { nextEvent, nextIndex } = getNextEvent(testRundown, '1');
|
||||
expect(nextEvent?.id).toBe('2');
|
||||
expect(nextIndex).toBe(1);
|
||||
});
|
||||
|
||||
it('ignores other event types', () => {
|
||||
const testRundown = [
|
||||
{ id: '1', type: SupportedEvent.Event },
|
||||
{ id: '2', type: SupportedEvent.Delay },
|
||||
{ id: '3', type: SupportedEvent.Block },
|
||||
{ id: '4', type: SupportedEvent.Event },
|
||||
{ id: '1', type: SupportedEvent.Event } as OntimeEvent,
|
||||
{ id: '2', type: SupportedEvent.Delay } as OntimeDelay,
|
||||
{ id: '3', type: SupportedEvent.Block } as OntimeBlock,
|
||||
{ id: '4', type: SupportedEvent.Event } as OntimeEvent,
|
||||
];
|
||||
|
||||
const { nextEvent, nextIndex } = getNextEvent(testRundown as OntimeRundown, '1');
|
||||
const { nextEvent, nextIndex } = getNextEvent(testRundown, '1');
|
||||
expect(nextEvent?.id).toBe('4');
|
||||
expect(nextIndex).toBe(3);
|
||||
});
|
||||
|
||||
it('returns null if none found', () => {
|
||||
const testRundown = [
|
||||
{ id: '1', type: SupportedEvent.Event },
|
||||
{ id: '2', type: SupportedEvent.Delay },
|
||||
{ id: '3', type: SupportedEvent.Block },
|
||||
{ id: '1', type: SupportedEvent.Event } as OntimeEvent,
|
||||
{ id: '2', type: SupportedEvent.Delay } as OntimeDelay,
|
||||
{ id: '3', type: SupportedEvent.Block } as OntimeBlock,
|
||||
];
|
||||
|
||||
const { nextEvent, nextIndex } = getNextEvent(testRundown as OntimeRundown, '1');
|
||||
const { nextEvent, nextIndex } = getNextEvent(testRundown, '1');
|
||||
expect(nextEvent).toBe(null);
|
||||
expect(nextIndex).toBe(null);
|
||||
});
|
||||
@@ -89,36 +100,46 @@ describe('getNextEvent()', () => {
|
||||
|
||||
describe('getPrevious()', () => {
|
||||
it('returns the previous event of type event', () => {
|
||||
const testRundown = [
|
||||
{ id: '1', type: SupportedEvent.Event },
|
||||
{ id: '2', type: SupportedEvent.Event },
|
||||
{ id: '3', type: SupportedEvent.Event },
|
||||
];
|
||||
const testRundown = {
|
||||
entries: {
|
||||
'1': { id: '1', type: SupportedEvent.Event } as OntimeEvent,
|
||||
'2': { id: '2', type: SupportedEvent.Event } as OntimeEvent,
|
||||
'3': { id: '3', type: SupportedEvent.Event } as OntimeEvent,
|
||||
},
|
||||
order: ['1', '2', '3'],
|
||||
};
|
||||
|
||||
const { entry, index } = getPrevious(testRundown as OntimeRundown, '3');
|
||||
const { entry, index } = getPrevious(testRundown, '3');
|
||||
expect(entry?.id).toBe('2');
|
||||
expect(index).toBe(1);
|
||||
});
|
||||
|
||||
it('allow other event types', () => {
|
||||
const testRundown = [
|
||||
{ id: '1', type: SupportedEvent.Event },
|
||||
{ id: '2', type: SupportedEvent.Delay },
|
||||
{ id: '3', type: SupportedEvent.Block },
|
||||
{ id: '4', type: SupportedEvent.Event },
|
||||
];
|
||||
const testRundown = {
|
||||
entries: {
|
||||
'1': { id: '1', type: SupportedEvent.Event } as OntimeEvent,
|
||||
'2': { id: '2', type: SupportedEvent.Delay } as OntimeDelay,
|
||||
'3': { id: '3', type: SupportedEvent.Block } as OntimeBlock,
|
||||
'4': { id: '4', type: SupportedEvent.Event } as OntimeEvent,
|
||||
},
|
||||
order: ['1', '2', '3', '4'],
|
||||
};
|
||||
|
||||
const { entry, index } = getPrevious(testRundown as OntimeRundown, '3');
|
||||
const { entry, index } = getPrevious(testRundown, '3');
|
||||
expect(entry?.id).toBe('2');
|
||||
expect(index).toBe(1);
|
||||
});
|
||||
it('returns null if none found', () => {
|
||||
const testRundown = [
|
||||
{ id: '2', type: SupportedEvent.Delay },
|
||||
{ id: '3', type: SupportedEvent.Block },
|
||||
{ id: '4', type: SupportedEvent.Event },
|
||||
];
|
||||
|
||||
const { entry, index } = getPrevious(testRundown as OntimeRundown, '2');
|
||||
it('returns null if none found', () => {
|
||||
const testRundown = {
|
||||
entries: {
|
||||
'2': { id: '2', type: SupportedEvent.Event } as OntimeEvent,
|
||||
'3': { id: '3', type: SupportedEvent.Event } as OntimeEvent,
|
||||
},
|
||||
order: ['1', '2', '3'],
|
||||
};
|
||||
|
||||
const { entry, index } = getPrevious(testRundown, '2');
|
||||
expect(entry).toBe(null);
|
||||
expect(index).toBe(null);
|
||||
});
|
||||
@@ -126,36 +147,47 @@ describe('getPrevious()', () => {
|
||||
|
||||
describe('getPreviousEvent()', () => {
|
||||
it('returns the previous event of type event', () => {
|
||||
const testRundown = [
|
||||
{ id: '1', type: SupportedEvent.Event },
|
||||
{ id: '2', type: SupportedEvent.Event },
|
||||
{ id: '3', type: SupportedEvent.Event },
|
||||
];
|
||||
const testRundown = {
|
||||
entries: {
|
||||
'1': { id: '1', type: SupportedEvent.Event } as OntimeEvent,
|
||||
'2': { id: '2', type: SupportedEvent.Event } as OntimeEvent,
|
||||
'3': { id: '3', type: SupportedEvent.Event } as OntimeEvent,
|
||||
},
|
||||
order: ['1', '2', '3'],
|
||||
};
|
||||
|
||||
const { previousEvent, previousIndex } = getPreviousEvent(testRundown as OntimeRundown, '3');
|
||||
const { previousEvent, previousIndex } = getPreviousEvent(testRundown, '3');
|
||||
expect(previousEvent?.id).toBe('2');
|
||||
expect(previousIndex).toBe(1);
|
||||
});
|
||||
it('ignores other event types', () => {
|
||||
const testRundown = [
|
||||
{ id: '1', type: SupportedEvent.Event },
|
||||
{ id: '2', type: SupportedEvent.Delay },
|
||||
{ id: '3', type: SupportedEvent.Block },
|
||||
{ id: '4', type: SupportedEvent.Event },
|
||||
];
|
||||
|
||||
const { previousEvent, previousIndex } = getPreviousEvent(testRundown as OntimeRundown, '4');
|
||||
it('ignores other event types', () => {
|
||||
const testRundown = {
|
||||
entries: {
|
||||
'1': { id: '1', type: SupportedEvent.Event } as OntimeEvent,
|
||||
'2': { id: '2', type: SupportedEvent.Delay } as OntimeDelay,
|
||||
'3': { id: '3', type: SupportedEvent.Block } as OntimeBlock,
|
||||
'4': { id: '4', type: SupportedEvent.Event } as OntimeEvent,
|
||||
},
|
||||
order: ['1', '2', '3', '4'],
|
||||
};
|
||||
|
||||
const { previousEvent, previousIndex } = getPreviousEvent(testRundown, '4');
|
||||
expect(previousEvent?.id).toBe('1');
|
||||
expect(previousIndex).toBe(0);
|
||||
});
|
||||
it('returns null if none found', () => {
|
||||
const testRundown = [
|
||||
{ id: '2', type: SupportedEvent.Delay },
|
||||
{ id: '3', type: SupportedEvent.Block },
|
||||
{ id: '4', type: SupportedEvent.Event },
|
||||
];
|
||||
|
||||
const { previousEvent, previousIndex } = getPreviousEvent(testRundown as OntimeRundown, '2');
|
||||
it('returns null if none found', () => {
|
||||
const testRundown = {
|
||||
entries: {
|
||||
'2': { id: '2', type: SupportedEvent.Delay } as OntimeDelay,
|
||||
'3': { id: '3', type: SupportedEvent.Block } as OntimeBlock,
|
||||
'4': { id: '4', type: SupportedEvent.Event } as OntimeEvent,
|
||||
},
|
||||
order: ['2', '3', '4'],
|
||||
};
|
||||
|
||||
const { previousEvent, previousIndex } = getPreviousEvent(testRundown, '2');
|
||||
expect(previousEvent).toBe(null);
|
||||
expect(previousIndex).toBe(null);
|
||||
});
|
||||
@@ -170,6 +202,7 @@ describe('swapEventData', () => {
|
||||
timeEnd: 1,
|
||||
duration: 1,
|
||||
delay: 1,
|
||||
revision: 3,
|
||||
} as OntimeEvent;
|
||||
const eventB = {
|
||||
id: '2',
|
||||
@@ -178,9 +211,10 @@ describe('swapEventData', () => {
|
||||
timeEnd: 2,
|
||||
duration: 2,
|
||||
delay: 2,
|
||||
revision: 7,
|
||||
} as OntimeEvent;
|
||||
|
||||
const { newA, newB } = swapEventData(eventA, eventB);
|
||||
const [newA, newB] = swapEventData(eventA, eventB);
|
||||
|
||||
expect(newA).toMatchObject({
|
||||
id: '1',
|
||||
@@ -189,6 +223,7 @@ describe('swapEventData', () => {
|
||||
timeEnd: 1,
|
||||
duration: 1,
|
||||
delay: 1,
|
||||
revision: 4,
|
||||
});
|
||||
expect(newB).toMatchObject({
|
||||
id: '2',
|
||||
@@ -197,121 +232,119 @@ describe('swapEventData', () => {
|
||||
timeEnd: 2,
|
||||
duration: 2,
|
||||
delay: 2,
|
||||
revision: 8,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getLastEvent', () => {
|
||||
it('returns the last event of type event', () => {
|
||||
const testRundown = [
|
||||
{ id: '1', type: SupportedEvent.Event },
|
||||
{ id: '2', type: SupportedEvent.Delay },
|
||||
{ id: '3', type: SupportedEvent.Event },
|
||||
{ id: '4', type: SupportedEvent.Block },
|
||||
const testRundown: OntimeEntry[] = [
|
||||
{ id: '1', type: SupportedEvent.Event } as OntimeEvent,
|
||||
{ id: '2', type: SupportedEvent.Delay } as OntimeDelay,
|
||||
{ id: '3', type: SupportedEvent.Event } as OntimeEvent,
|
||||
{ id: '4', type: SupportedEvent.Block } as OntimeBlock,
|
||||
];
|
||||
|
||||
const { lastEvent } = getLastEvent(testRundown as OntimeRundown);
|
||||
const { lastEvent } = getLastEvent(testRundown);
|
||||
expect(lastEvent?.id).toBe('3');
|
||||
});
|
||||
it('handles rundowns with a single event', () => {
|
||||
const testRundown = [{ id: '1', type: SupportedEvent.Event }];
|
||||
|
||||
const { lastEvent } = getLastEvent(testRundown as OntimeRundown);
|
||||
it('handles rundowns with a single event', () => {
|
||||
const testRundown: OntimeEntry[] = [{ id: '1', type: SupportedEvent.Event } as OntimeEvent];
|
||||
const { lastEvent } = getLastEvent(testRundown);
|
||||
expect(lastEvent?.id).toBe('1');
|
||||
});
|
||||
|
||||
describe('getLastNormal', () => {
|
||||
it('returns the last entry', () => {
|
||||
const testRundown = {
|
||||
4: { id: '4', type: SupportedEvent.Block },
|
||||
1: { id: '1', type: SupportedEvent.Event },
|
||||
3: { id: '3', type: SupportedEvent.Event },
|
||||
2: { id: '2', type: SupportedEvent.Delay },
|
||||
const entries = {
|
||||
4: { id: '4', type: SupportedEvent.Block } as OntimeBlock,
|
||||
1: { id: '1', type: SupportedEvent.Event } as OntimeEvent,
|
||||
3: { id: '3', type: SupportedEvent.Event } as OntimeEvent,
|
||||
2: { id: '2', type: SupportedEvent.Delay } as OntimeDelay,
|
||||
};
|
||||
|
||||
const order = ['1', '2', '3', '4'];
|
||||
|
||||
const lastEntry = getLastNormal(testRundown as unknown as NormalisedRundown, order);
|
||||
const lastEntry = getLastNormal(entries, order);
|
||||
expect(lastEntry?.id).toBe('4');
|
||||
});
|
||||
it('handles rundowns with a single event', () => {
|
||||
const testRundown = [{ id: '1', type: SupportedEvent.Event }];
|
||||
|
||||
const { lastEvent } = getLastEvent(testRundown as OntimeRundown);
|
||||
it('handles rundowns with a single event', () => {
|
||||
const entries = {
|
||||
1: { id: '1', type: SupportedEvent.Event } as OntimeEvent,
|
||||
};
|
||||
|
||||
const lastEvent = getLastNormal(entries, ['1']);
|
||||
expect(lastEvent?.id).toBe('1');
|
||||
});
|
||||
|
||||
it('handles empty order', () => {
|
||||
const testRundown = {
|
||||
4: { id: '4', type: SupportedEvent.Block },
|
||||
1: { id: '1', type: SupportedEvent.Event },
|
||||
3: { id: '3', type: SupportedEvent.Event },
|
||||
2: { id: '2', type: SupportedEvent.Delay },
|
||||
1: { id: '1', type: SupportedEvent.Event } as OntimeEvent,
|
||||
2: { id: '2', type: SupportedEvent.Event } as OntimeEvent,
|
||||
};
|
||||
|
||||
const order: string[] = [];
|
||||
|
||||
const lastEntry = getLastNormal(testRundown as unknown as NormalisedRundown, order);
|
||||
const lastEntry = getLastNormal(testRundown, []);
|
||||
expect(lastEntry).toBe(null);
|
||||
});
|
||||
|
||||
it('handles empty rundown', () => {
|
||||
const testRundown = {};
|
||||
|
||||
const order = ['1', '2', '3', '4'];
|
||||
|
||||
const lastEntry = getLastNormal(testRundown as unknown as NormalisedRundown, order);
|
||||
const lastEntry = getLastNormal({}, ['1', '2', '3', '4']);
|
||||
expect(lastEntry).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('relevantBlock', () => {
|
||||
const testRundown = [
|
||||
{ id: 'a', type: SupportedEvent.Event },
|
||||
{ id: 'b', type: SupportedEvent.Event },
|
||||
{ id: 'c', type: SupportedEvent.Event },
|
||||
{ id: 'd', type: SupportedEvent.Delay },
|
||||
{ id: 'e', type: SupportedEvent.Block },
|
||||
{ id: 'f', type: SupportedEvent.Event },
|
||||
{ id: 'g', type: SupportedEvent.Block },
|
||||
{ id: 'h', type: SupportedEvent.Event },
|
||||
];
|
||||
describe('getPreviousBlock()', () => {
|
||||
const testRundown = {
|
||||
entries: {
|
||||
a: { id: 'a', type: SupportedEvent.Event } as OntimeEvent,
|
||||
b: { id: 'b', type: SupportedEvent.Event } as OntimeEvent,
|
||||
c: { id: 'c', type: SupportedEvent.Event } as OntimeEvent,
|
||||
d: { id: 'd', type: SupportedEvent.Delay } as OntimeDelay,
|
||||
e: { id: 'e', type: SupportedEvent.Block } as OntimeBlock,
|
||||
f: { id: 'f', type: SupportedEvent.Event } as OntimeEvent,
|
||||
g: { id: 'g', type: SupportedEvent.Block } as OntimeBlock,
|
||||
h: { id: 'h', type: SupportedEvent.Event } as OntimeEvent,
|
||||
},
|
||||
order: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],
|
||||
};
|
||||
|
||||
it('returns the relevant block', () => {
|
||||
const block = getPreviousBlock(testRundown as unknown as OntimeRundown, 'h');
|
||||
|
||||
expect(block?.id).toBe('g');
|
||||
test.each([
|
||||
['h', 'g'],
|
||||
['f', 'e'],
|
||||
])('returns the relevant block', (id, expected) => {
|
||||
const block = getPreviousBlock(testRundown, id);
|
||||
expect(block?.id).toBe(expected);
|
||||
});
|
||||
it('returns the relevant block', () => {
|
||||
const block = getPreviousBlock(testRundown as unknown as OntimeRundown, 'f');
|
||||
|
||||
expect(block?.id).toBe('e');
|
||||
it('returns null if there is no parent block relevant block', () => {
|
||||
const block = getPreviousBlock(testRundown, 'a');
|
||||
expect(block).toBe(null);
|
||||
});
|
||||
it('returns the relevant block', () => {
|
||||
const block = getPreviousBlock(testRundown as unknown as OntimeRundown, 'a');
|
||||
|
||||
expect(block).toBeNull();
|
||||
});
|
||||
it('also works on index 0', () => {
|
||||
testRundown.unshift({ id: '0', type: SupportedEvent.Block });
|
||||
const block = getPreviousBlock(testRundown as unknown as OntimeRundown, 'a');
|
||||
testRundown.order.unshift('0');
|
||||
// @ts-expect-error -- we are adding an event to the rundown
|
||||
testRundown.entries['0'] = { id: '0', type: SupportedEvent.Block } as OntimeBlock;
|
||||
const block = getPreviousBlock(testRundown, 'a');
|
||||
expect(block?.id).toBe('0');
|
||||
});
|
||||
});
|
||||
|
||||
describe('filterPlayable()', () => {
|
||||
test('should return an array with only playable events', () => {
|
||||
const eventA = { id: 'a', type: SupportedEvent.Event } as OntimeEvent;
|
||||
const eventB = { id: 'b', skip: true, type: SupportedEvent.Event } as OntimeEvent;
|
||||
const testRundown = [
|
||||
eventA,
|
||||
eventB,
|
||||
{ id: 'c', type: SupportedEvent.Delay },
|
||||
{ id: 'd', type: SupportedEvent.Block },
|
||||
];
|
||||
|
||||
const result = filterPlayable(testRundown as unknown as OntimeRundown);
|
||||
expect(result).toMatchObject([eventA]);
|
||||
it('returns the parent block if nested event', () => {
|
||||
const testRundown = {
|
||||
entries: {
|
||||
1: { id: '1', type: SupportedEvent.Event } as OntimeEvent,
|
||||
block: { id: 'block', type: SupportedEvent.Block, events: ['21', '22', '23'] } as OntimeBlock,
|
||||
21: { id: '21', type: SupportedEvent.Event, currentBlock: 'block' } as OntimeEvent,
|
||||
22: { id: '22', type: SupportedEvent.Event, currentBlock: 'block' } as OntimeEvent,
|
||||
23: { id: '23', type: SupportedEvent.Event, currentBlock: 'block' } as OntimeEvent,
|
||||
},
|
||||
order: ['1', 'block'],
|
||||
};
|
||||
const block = getPreviousBlock(testRundown, '21');
|
||||
expect(block?.id).toBe('block');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user