Files
hls.js/tests/unit/controller/base-stream-controller.ts
renovate[bot]GitHubrenovate[bot] <29139614+renovate[bot]@users.noreply.github.com>Tom Jenkinson
359197f20b chore(deps): update dependency prettier to v3 (#5646)
* chore(deps): update dependency prettier to v3

* run prettier

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Tom Jenkinson <tom@tjenkinson.me>
2023-08-22 11:24:59 +01:00

107 lines
3.2 KiB
TypeScript

import Hls from '../../../src/hls';
import { hlsDefaultConfig } from '../../../src/config';
import BaseStreamController from '../../../src/controller/stream-controller';
import KeyLoader from '../../../src/loader/key-loader';
import { TimeRangesMock } from '../../mocks/time-ranges.mock';
import type { BufferInfo } from '../../../src/utils/buffer-helper';
import type { LevelDetails } from '../../../src/loader/level-details';
import type { Fragment, Part } from '../../../src/loader/fragment';
import chai from 'chai';
import sinonChai from 'sinon-chai';
chai.use(sinonChai);
const expect = chai.expect;
type BaseStreamControllerTestable = Omit<
BaseStreamController,
'media' | '_streamEnded'
> & {
media: HTMLMediaElement | null;
_streamEnded: (bufferInfo: BufferInfo, levelDetails: LevelDetails) => boolean;
};
describe('BaseStreamController', function () {
let hls: Hls;
let baseStreamController: BaseStreamControllerTestable;
let bufferInfo: BufferInfo;
let levelDetails: LevelDetails;
let fragmentTracker;
let media;
beforeEach(function () {
hls = new Hls({});
fragmentTracker = {
state: null,
getState() {
return this.state;
},
isEndListAppended() {
return true;
},
};
baseStreamController = new BaseStreamController(
hls,
fragmentTracker,
new KeyLoader(hlsDefaultConfig),
) as unknown as BaseStreamControllerTestable;
bufferInfo = {
len: 1,
nextStart: 0,
start: 0,
end: 1,
};
levelDetails = {
endSN: 0,
live: false,
get fragments() {
const frags: Fragment[] = [];
for (let i = 0; i < this.endSN; i++) {
frags.push({ sn: i, type: 'main' } as unknown as Fragment);
}
return frags;
},
} as unknown as LevelDetails;
media = {
duration: 0,
buffered: new TimeRangesMock(),
} as unknown as HTMLMediaElement;
baseStreamController.media = media;
});
describe('_streamEnded', function () {
it('returns false if the stream is live', function () {
levelDetails.live = true;
expect(baseStreamController._streamEnded(bufferInfo, levelDetails)).to.be
.false;
});
it('returns false if there is subsequently buffered range', function () {
levelDetails.endSN = 10;
bufferInfo.nextStart = 100;
expect(baseStreamController._streamEnded(bufferInfo, levelDetails)).to.be
.false;
});
it('returns true if parts are buffered for low latency content', function () {
media.buffered = new TimeRangesMock([0, 1]);
levelDetails.endSN = 10;
levelDetails.partList = [{ start: 0, duration: 1 } as unknown as Part];
expect(baseStreamController._streamEnded(bufferInfo, levelDetails)).to.be
.true;
});
it('depends on fragment-tracker to determine if last fragment is buffered', function () {
media.buffered = new TimeRangesMock([0, 1]);
levelDetails.endSN = 10;
expect(baseStreamController._streamEnded(bufferInfo, levelDetails)).to.be
.true;
fragmentTracker.isEndListAppended = () => false;
expect(baseStreamController._streamEnded(bufferInfo, levelDetails)).to.be
.false;
});
});
});