test: add deterministic resilience matrix
This commit is contained in:
@@ -103,8 +103,8 @@ export function createAudioController(options: AudioControllerOptions): AudioCon
|
||||
if (!graph) return;
|
||||
try {
|
||||
await graph.resume();
|
||||
} catch {
|
||||
if (firstStart) await fail();
|
||||
} catch (error) {
|
||||
if (firstStart || (error instanceof Error && error.name === 'InvalidStateError')) await fail();
|
||||
else {
|
||||
desired = 'suspended';
|
||||
resumeIntent = 'user-required';
|
||||
|
||||
@@ -1,12 +1,44 @@
|
||||
import type { AudioContextLifecycleState, AudioGraph } from '@/audio/types';
|
||||
import { isTestFault, recordTestFaultEvent } from '@/testing/fault-hooks';
|
||||
|
||||
declare const __PORTFOLIO_TEST_BUILD__: boolean;
|
||||
const TEST_BUILD = typeof __PORTFOLIO_TEST_BUILD__ !== 'undefined' && __PORTFOLIO_TEST_BUILD__;
|
||||
|
||||
type AudioContextFactory = () => AudioContext;
|
||||
|
||||
export function createBrowserSynthEngine(): AudioGraph {
|
||||
if (TEST_BUILD && isTestFault('F10-audio-start-rejection')) {
|
||||
recordTestFaultEvent('audio-start-rejected');
|
||||
throw new DOMException('Injected audio start rejection', 'NotAllowedError');
|
||||
}
|
||||
const AudioContextConstructor = window.AudioContext
|
||||
?? (window as typeof window & { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;
|
||||
if (!AudioContextConstructor) throw new Error('Web Audio is unavailable');
|
||||
return createSynthEngine(() => new AudioContextConstructor());
|
||||
const graph = createSynthEngine(() => new AudioContextConstructor());
|
||||
if (!TEST_BUILD) return graph;
|
||||
let resumeCount = 0;
|
||||
return {
|
||||
...graph,
|
||||
async resume() {
|
||||
resumeCount += 1;
|
||||
if (isTestFault('F11-audio-resume-rejection') && resumeCount > 1) {
|
||||
recordTestFaultEvent('audio-resume-rejected');
|
||||
throw new DOMException('Injected audio resume rejection', 'NotAllowedError');
|
||||
}
|
||||
if (isTestFault('F12-audio-graph-invalid') && resumeCount > 1) {
|
||||
recordTestFaultEvent('audio-graph-invalid');
|
||||
throw new DOMException('Injected invalid audio graph', 'InvalidStateError');
|
||||
}
|
||||
await graph.resume();
|
||||
},
|
||||
async suspend() {
|
||||
if (isTestFault('F13-audio-suspend-rejection')) {
|
||||
recordTestFaultEvent('audio-suspend-rejected');
|
||||
throw new DOMException('Injected audio suspend rejection', 'InvalidStateError');
|
||||
}
|
||||
await graph.suspend();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function createSynthEngine(createContext: AudioContextFactory): AudioGraph {
|
||||
|
||||
Reference in New Issue
Block a user