rx-player
Version:
Canal+ HTML5 Video Player
153 lines (145 loc) • 5.53 kB
text/typescript
import SharedReference from "../../utils/reference";
import type { CancellationSignal } from "../../utils/task_canceller";
import { makeMockedClass } from "../../utils/test-utils";
import type CorePlaybackObserver from "../core_playback_observer";
import type MediaElementPlaybackObserver from "../media_element_playback_observer";
import type { IReadOnlyPlaybackObserver } from "../types";
import type ObservationPosition from "../utils/observation_position";
/**
* Construct a class implementing the `MediaElementPlaybackObserver` interface.
* @class DummyMediaElementPlaybackObserver
*/
export const DummyMediaElementPlaybackObserver =
makeMockedClass<MediaElementPlaybackObserver>(
{
attachMediaElement: notImplemented("attachMediaElement"),
getCurrentTime: notImplemented("getCurrentTime"),
getIsPaused: notImplemented("getIsPaused"),
getPendingSeekInformation: notImplemented("getPendingSeekInformation"),
getPlaybackRate: notImplemented("getPlaybackRate"),
getReadyState: notImplemented("getReadyState"),
getReference: notImplemented("getReference"),
stop: notImplemented("stop"),
blockSeeking: notImplemented("blockSeeking"),
unblockSeeking: notImplemented("unblockSeeking"),
isSeekingBlocked: notImplemented("isSeekingBlocked"),
setCurrentTime: notImplemented("setCurrentTime"),
setPlaybackRate: notImplemented("setPlaybackRate"),
listen: notImplemented("listen"),
deriveReadOnlyObserver: notImplemented("deriveReadOnlyObserver"),
},
{},
);
/**
* Construct a class implementing the `CorePlaybackObserver` interface.
* @class DummyCorePlaybackObserver
*/
export const DummyCorePlaybackObserver = makeMockedClass<CorePlaybackObserver>(
{
getCurrentTime: notImplemented("getCurrentTime"),
getIsPaused: notImplemented("getIsPaused"),
getPlaybackRate: notImplemented("getPlaybackRate"),
getReadyState: notImplemented("getReadyState"),
getReference: notImplemented("getReference"),
setPlaybackRate: notImplemented("setPlaybackRate"),
listen: notImplemented("listen"),
deriveReadOnlyObserver: notImplemented("deriveReadOnlyObserver"),
},
{},
);
/**
* Object facilitation the usage of a IReadOnlyPlaybackObserver`.
* /!\ Do not forget to call `reset` when done to ensure no memory leak.
*/
export interface IMockedReadOnlyPlaybackObserver<TObservationData> {
/**
* The `IReadOnlyPlaybackObserver` itself.
*/
observer: IReadOnlyPlaybackObserver<TObservationData>;
/**
* Allows to trigger new observations through `observer`.
*/
emit: (data: TObservationData) => void;
/**
* Reset `observer` to its initial observation, also removing all observation
* listener it potentially had.
*
* Intended to be called between each test to clean-up.
*/
reset: () => void;
}
/**
* Allows to create any `IReadOnlyPlaybackObserver` with TypeScript typechecking
* and to obtain a function to emit new observations.
* @param {Object} initialData - The initial observation emitted.
* @returns {Object} res
* @returns {IReadOnlyPlaybackObserver} res.observer - The
* `IReadOnlyPlaybackObserver` instance.
* @returns {Function} res.emit - A function allowing to emit new observations.
* @returns {Function} res.reset - Reset the playback observer to its initial
* state, also removing all its listeners. Call this between tests.
*/
export function makeReadyOnlyPlaybackObserver<TObservationData>(
initialData: TObservationData,
): IMockedReadOnlyPlaybackObserver<TObservationData> {
let ref = new SharedReference<TObservationData>(initialData);
const ret = {
observer: makeObserver(),
emit: (data: TObservationData) => {
ref.setValue(data);
},
reset: () => {
ref.finish();
ref = new SharedReference<TObservationData>(initialData);
},
};
return ret;
function makeObserver(): IReadOnlyPlaybackObserver<TObservationData> {
const klass = makeMockedClass<IReadOnlyPlaybackObserver<TObservationData>>(
{
getCurrentTime: notImplemented("getCurrentTime"),
getIsPaused: notImplemented("getIsPaused"),
getPlaybackRate: notImplemented("getPlaybackRate"),
getReadyState: notImplemented("getReadyState"),
getReference: () => ref,
listen(
cb: (observation: TObservationData, stopListening: () => void) => void,
params: {
includeLastObservation?: boolean | undefined;
clearSignal: CancellationSignal;
},
) {
if (params.clearSignal.isCancelled()) {
return;
}
ref.onUpdate(cb, {
clearSignal: params.clearSignal,
emitCurrentValue: params.includeLastObservation,
});
},
deriveReadOnlyObserver: notImplemented("deriveReadOnlyObserver"),
},
{},
);
return new klass();
}
}
/**
* Construct a class implementing the `ObservationPosition` interface.
* @class DummyObservationPosition
*/
export const DummyObservationPosition = makeMockedClass<ObservationPosition>(
{
serialize: notImplemented("serialize"),
getPolled: notImplemented("getPolled"),
getWanted: notImplemented("getWanted"),
forceWantedPosition: notImplemented("forceWantedPosition"),
isAwaitingFuturePosition: notImplemented("isAwaitingFuturePosition"),
},
{},
);
function notImplemented(name: string): () => never {
return () => {
throw new Error(`${name} not implemented`);
};
}