Files
glchat/web/tests/fakeAudio.ts
T

64 lines
1.8 KiB
TypeScript
Raw Normal View History

import { vi } from 'vitest';
/**
* Подставной `Audio` для тестов саундборда: в jsdom `play()` не реализован,
* поэтому звук подменяется целиком. Экземпляры собираются в массив — по ним
* проверяют, что звук скачали, проиграли или остановили.
*/
export class FakeAudio {
src: string;
volume = 1;
currentTime = 0;
paused = true;
playCalls = 0;
pauseCalls = 0;
/** Считаем и нативные, и «событийные» подписки: `ended` глушит звук. */
readonly listeners = new Map<string, Set<() => void>>();
constructor(src = '') {
this.src = src;
}
addEventListener(type: string, handler: () => void): void {
const set = this.listeners.get(type) ?? new Set<() => void>();
set.add(handler);
this.listeners.set(type, set);
}
removeEventListener(type: string, handler: () => void): void {
this.listeners.get(type)?.delete(handler);
}
play(): Promise<void> {
this.playCalls += 1;
this.paused = false;
return Promise.resolve();
}
pause(): void {
this.pauseCalls += 1;
this.paused = true;
}
/** Сообщить о конце звука: движок снимает элемент с учёта. */
emit(type: string): void {
for (const handler of [...(this.listeners.get(type) ?? [])]) {
handler();
}
}
}
/** Ставит подставной `Audio` и возвращает список созданных элементов. */
export function installFakeAudio(): FakeAudio[] {
const instances: FakeAudio[] = [];
class StubAudio extends FakeAudio {
constructor(src = '') {
super(src);
instances.push(this);
}
}
vi.stubGlobal('Audio', StubAudio);
return instances;
}