Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,311 @@
import TextTrackCuesStore from "../text_track_cues_store";
import { ICuesGroup } from "../types";

/**
* Mocks document.createElement to simplify comparison of cuesElement by returning
* a plain object with innerText property instead of an HTMLElement.
* @param text innerText
* @returns
*/
function mockCreateElementFn() {
jest
.spyOn(document, "createElement")
.mockImplementation((n: string) => ({ innerText: n }) as HTMLElement);

return (text: string) => document.createElement(text);
}

describe("TextTrackCuesStore - insert()", () => {
const createCueElement = mockCreateElementFn();

it("test the mock function, a and b should be considered different", () => {
const a = createCueElement("hello");
const b = createCueElement("bye");
expect(a).not.toEqual(b);
expect(a.innerText).toEqual("hello");
});

it("inserting strictly after previous one", () => {
// ours: |AAAAA|
// the current one: |BBBBB|
// Result: |BBBBB|AAAAA|
const textTrackCuesStore = new TextTrackCuesStore();
const currentCues: ICuesGroup[] = [
{
cues: [{ element: createCueElement("hello"), start: 0, end: 1 }],
start: 0,
end: 1,
},
];

const expectedCues: ICuesGroup[] = [
{
cues: [{ element: createCueElement("hello"), start: 0, end: 1 }],
start: 0,
end: 1,
},
{
cues: [{ element: createCueElement("bye"), start: 1, end: 2 }],
start: 1,
end: 2,
},
];

// small hack to access class private property with bracket notation without
// having ts errors
/* eslint-disable @typescript-eslint/dot-notation */
textTrackCuesStore["_cuesBuffer"] = currentCues;
textTrackCuesStore.insert(
[{ element: createCueElement("bye"), start: 1, end: 2 }],
1,
2
);

expect(textTrackCuesStore["_cuesBuffer"]).toEqual(expectedCues);
});

it("inserting strictly before existing cue", () => {
// ours: |AAAAA|
// the current one: |BBBBB|
// Result: |AAAAA|BBBBB|
const textTrackCuesStore = new TextTrackCuesStore();
const currentCues: ICuesGroup[] = [
{
cues: [{ element: createCueElement("bye"), start: 1, end: 2 }],
start: 1,
end: 2,
},
];

const expectedCues: ICuesGroup[] = [
{
cues: [{ element: createCueElement("hello"), start: 0, end: 1 }],
start: 0,
end: 1,
},
{
cues: [{ element: createCueElement("bye"), start: 1, end: 2 }],
start: 1,
end: 2,
},
];

textTrackCuesStore["_cuesBuffer"] = currentCues;
textTrackCuesStore.insert(
[{ element: createCueElement("hello"), start: 0, end: 1 }],
0,
1
);
expect(textTrackCuesStore["_cuesBuffer"]).toEqual(expectedCues);
});

it("inserting between two cues", () => {
// ours: |AAAAA|
// the current one: |BBBBB| |BBBBB|
// Result: |BBBBB|AAAAA|BBBBB|
const textTrackCuesStore = new TextTrackCuesStore();
const currentCues: ICuesGroup[] = [
{
cues: [{ element: createCueElement("hello"), start: 0, end: 1 }],
start: 0,
end: 1,
},
{
cues: [{ element: createCueElement("hello again"), start: 2, end: 3 }],
start: 2,
end: 3,
},
];

const expectedCues: ICuesGroup[] = [
{
cues: [{ element: createCueElement("hello"), start: 0, end: 1 }],
start: 0,
end: 1,
},
{
cues: [{ element: createCueElement("bye"), start: 1, end: 2 }],
start: 1,
end: 2,
},
{
cues: [{ element: createCueElement("hello again"), start: 2, end: 3 }],
start: 2,
end: 3,
},
];

textTrackCuesStore["_cuesBuffer"] = currentCues;
textTrackCuesStore.insert(
[{ element: createCueElement("bye"), start: 1, end: 2 }],
1,
2
);
expect(textTrackCuesStore["_cuesBuffer"]).toEqual(expectedCues);
});

it("replacing current cues", () => {
// ours: |AAAAA|
// the current one: |BBBBB|
// Result: |AAAAA|
const textTrackCuesStore = new TextTrackCuesStore();
const currentCues: ICuesGroup[] = [
{
cues: [{ element: createCueElement("hello"), start: 0, end: 1 }],
start: 0,
end: 1,
},
];

const expectedCues: ICuesGroup[] = [
{
cues: [{ element: createCueElement("hi"), start: 0, end: 1 }],
start: 0,
end: 1,
},
];

textTrackCuesStore["_cuesBuffer"] = currentCues;
textTrackCuesStore.insert(
[{ element: createCueElement("hi"), start: 0, end: 1 }],
0,
1
);
expect(textTrackCuesStore["_cuesBuffer"]).toEqual(expectedCues);
});

it("inserting cues that partially replace existing cues", () => {
// ours: |AAAAA|
// the current one: |BBBBBBBB|
// Result: |AAAAABBB|
const textTrackCuesStore = new TextTrackCuesStore();
const currentCues: ICuesGroup[] = [
{
cues: [{ element: createCueElement("how are you?"), start: 0, end: 2 }],
start: 0,
end: 2,
},
];

const expectedCues: ICuesGroup[] = [
{
cues: [{ element: createCueElement("hi"), start: 0, end: 1 }],
start: 0,
end: 1,
},
{
cues: [{ element: createCueElement("how are you?"), start: 0, end: 2 }],
start: 1,
end: 2,
},
];

textTrackCuesStore["_cuesBuffer"] = currentCues;
textTrackCuesStore.insert(
[{ element: createCueElement("hi"), start: 0, end: 1 }],
0,
1
);
expect(textTrackCuesStore["_cuesBuffer"]).toEqual(expectedCues);
});
it("inserting cues that replace existing cues and go beyond", () => {
// ours: |AAAAAAA|
// the current one: |BBBB|...
// Result: |AAAAAAA|
const textTrackCuesStore = new TextTrackCuesStore();
const currentCues: ICuesGroup[] = [
{
cues: [{ element: createCueElement("hi"), start: 0, end: 1 }],
start: 0,
end: 1,
},
];

const expectedCues: ICuesGroup[] = [
{
cues: [{ element: createCueElement("how are you?"), start: 0, end: 2 }],
start: 0,
end: 2,
},
];

textTrackCuesStore["_cuesBuffer"] = currentCues;
textTrackCuesStore.insert(
[{ element: createCueElement("how are you?"), start: 0, end: 2 }],
0,
2
);
expect(textTrackCuesStore["_cuesBuffer"]).toEqual(expectedCues);
});

it("inserting after previous one with parsing approximation", () => {
// ours: |AAAAA|
// the current one: |BBBBB|
// Result: |BBBBB|AAAAA|
const textTrackCuesStore = new TextTrackCuesStore();
const currentCues: ICuesGroup[] = [
{
cues: [{ element: createCueElement("hi"), start: 0, end: 1.0001 }],
start: 0,
end: 1.0001,
},
];

const expectedCues: ICuesGroup[] = [
{
cues: [{ element: createCueElement("hi"), start: 0, end: 1.0001 }],
start: 0,
end: 1,
},
{
cues: [{ element: createCueElement("how are you?"), start: 1, end: 2 }],
start: 1,
end: 2,
},
];

textTrackCuesStore["_cuesBuffer"] = currentCues;
textTrackCuesStore.insert(
[{ element: createCueElement("how are you?"), start: 1, end: 2 }],
1,
2
);
expect(textTrackCuesStore["_cuesBuffer"]).toEqual(expectedCues);
});

/* eslint-disable-next-line max-len */
it("inserting cues that replace existing cues and go beyond with parsing approximation", () => {
// ours: |AAAAAAA|
// the current one: |BBBB|...
// Result: |AAAAAAA|
const textTrackCuesStore = new TextTrackCuesStore();
const currentCues: ICuesGroup[] = [
{
cues: [{ element: createCueElement("hi"), start: 9.8, end: 10.001 }],
start: 9.8,
end: 10.001,
},
];

const expectedCues: ICuesGroup[] = [
{
cues: [{ element: createCueElement("hi"), start: 9.8, end: 10.001 }],
start: 9.8,
end: 10,
},
{
cues: [{ element: createCueElement("hi"), start: 10, end: 12 }],
start: 10,
end: 12,
},
];

textTrackCuesStore["_cuesBuffer"] = currentCues;
textTrackCuesStore.insert(
[{ element: createCueElement("hi"), start: 10, end: 12 }],
10,
12
);
expect(textTrackCuesStore["_cuesBuffer"]).toEqual(expectedCues);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
getCuesAfter,
getCuesBefore,
removeCuesInfosBetween,
areCuesStartNearlyEqual,
} from "../utils";

describe("HTML Text buffer utils - getCuesBefore", () => {
Expand Down Expand Up @@ -341,3 +342,59 @@ describe("HTML Text buffer utils - removeCuesInfosBetween", () => {
]);
});
});

describe("HTML areCuesStartNearlyEqual", () => {
it("Case 1: should be false", () => {
// * [0, 2] and [2, 4] start are NOT equals
const element = document.createElement("div");
const cues = [{ start: 1, end: 2, element }];
const cueInfo1 = { start: 0, end: 2, cues };
const cueInfo2 = { start: 2, end: 4, cues };

expect(areCuesStartNearlyEqual(cueInfo1, cueInfo2)).toBe(false);
});
it("Case 2: should be true", () => {
// * [0, 2] and [0, 4] start are equals
const element = document.createElement("div");
const cues = [{ start: 1, end: 2, element }];
const cueInfo1 = { start: 0, end: 2, cues };
const cueInfo2 = { start: 0, end: 4, cues };
expect(areCuesStartNearlyEqual(cueInfo1, cueInfo2)).toBe(true);
});

it("Case 3: should be false", () => {
// * [0, 0.1] and [0.101, 2] start are NOT equals
const element = document.createElement("div");
const cues = [{ start: 1, end: 2, element }];
const cueInfo1 = { start: 0, end: 0.1, cues };
const cueInfo2 = { start: 0.101, end: 2, cues };
expect(areCuesStartNearlyEqual(cueInfo1, cueInfo2)).toBe(false);
});

it("Case 4: should be true", () => {
// * [0, 2] and [0.01, 4] start are equals
const element = document.createElement("div");
const cues = [{ start: 1, end: 2, element }];
const cueInfo1 = { start: 0, end: 2, cues };
const cueInfo2 = { start: 0.01, end: 4, cues };
expect(areCuesStartNearlyEqual(cueInfo1, cueInfo2)).toBe(true);
});

it("Case 5: should be false", () => {
// * [0, 100] and [1, 200] start are NOT equals
const element = document.createElement("div");
const cues = [{ start: 1, end: 2, element }];
const cueInfo1 = { start: 0, end: 100, cues };
const cueInfo2 = { start: 2, end: 200, cues };
expect(areCuesStartNearlyEqual(cueInfo1, cueInfo2)).toBe(false);
});

it("Case 6: should be true", () => {
// * [0, 4] and [0.01, 3.99] start should be equals
const element = document.createElement("div");
const cues = [{ start: 0, end: 4, element }];
const cueInfo1 = { start: 0, end: 4, cues };
const cueInfo2 = { start: 0.01, end: 3.99, cues };
expect(areCuesStartNearlyEqual(cueInfo1, cueInfo2)).toBe(true);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
getCuesAfter,
getCuesBefore,
removeCuesInfosBetween,
areCuesStartNearlyEqual,
} from "./utils";

/**
Expand Down Expand Up @@ -245,7 +246,7 @@ export default class TextTrackCuesStore {
for (let cueIdx = 0; cueIdx < cuesBuffer.length; cueIdx++) {
let cuesInfos = cuesBuffer[cueIdx];
if (start < cuesInfos.end) {
if (areNearlyEqual(start, cuesInfos.start, relativeDelta)) {
if (areCuesStartNearlyEqual(cuesInfosToInsert, cuesInfos)) {
if (areNearlyEqual(end, cuesInfos.end, relativeDelta)) {
// exact same segment
// ours: |AAAAA|
Expand Down
Loading