UNPKG

murmuraba

Version:

Real-time audio noise reduction with advanced chunked processing for web applications

168 lines (167 loc) 4.84 kB
/** * Main test utilities export file * Import everything from here for a clean, organized test setup */ import { describe, afterEach, expect } from 'vitest'; // Re-export all utilities export * from './audio-context-utils'; export * from './console-utils'; export * from './factories'; export * from './custom-matchers'; // Import for side effects (auto-setup custom matchers) import './custom-matchers'; import { vi } from 'vitest'; import { setupAudioContextMock } from './audio-context-utils'; import { useConsoleMocks } from './console-utils'; /** * Setup complete test environment with all common mocks */ export function setupTestEnvironment(options = {}) { const env = { audioContext: null, consoleMocks: null, cleanup: () => { }, }; // Setup console mocks const getConsoleMocks = useConsoleMocks(options.console); env.consoleMocks = getConsoleMocks; // Setup AudioContext mock const audioMock = setupAudioContextMock(options.audio); env.audioContext = audioMock.context; // Setup WASM mocks if needed if (options.wasm) { env.wasmModule = setupWASMMocks(options.wasm); } // Setup fetch mock if needed if (options.fetch) { setupFetchMock(); } // Setup timers if needed if (options.timers) { vi.useFakeTimers(); } // Cleanup function env.cleanup = () => { audioMock.restore(); vi.clearAllMocks(); if (options.timers) { vi.useRealTimers(); } }; return env; } /** * Setup WASM module mocks */ function setupWASMMocks(options = {}) { const { rnnoiseState = 12345, vadProbability = 0.7 } = options; const mockModule = { _rnnoise_create: vi.fn().mockReturnValue(rnnoiseState), _rnnoise_destroy: vi.fn(), _rnnoise_process_frame: vi.fn().mockReturnValue(vadProbability), _malloc: vi.fn((size) => size), _free: vi.fn(), HEAPF32: new Float32Array(10000), HEAP32: new Int32Array(10000), HEAPU8: new Uint8Array(10000), HEAPU32: new Uint32Array(10000), }; // Mock the loader vi.doMock('../../utils/rnnoise-loader', () => ({ loadRNNoiseModule: vi.fn().mockResolvedValue(mockModule), })); return mockModule; } /** * Setup fetch mock for blob and WASM operations */ function setupFetchMock() { global.fetch = vi.fn().mockImplementation((url) => { if (url.startsWith('blob:')) { return Promise.resolve({ ok: true, blob: vi.fn().mockResolvedValue(new Blob(['mock audio data'], { type: 'audio/webm' })), arrayBuffer: vi.fn().mockResolvedValue(new ArrayBuffer(1024)), }); } if (url.includes('.wasm')) { const mockWasm = new ArrayBuffer(8); new Uint8Array(mockWasm).set([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]); return Promise.resolve({ ok: true, arrayBuffer: vi.fn().mockResolvedValue(mockWasm), }); } return Promise.reject(new Error(`Fetch not mocked for URL: ${url}`)); }); } /** * Helper to wait for async operations */ export async function waitForAsync(ms = 0) { return new Promise(resolve => setTimeout(resolve, ms)); } /** * Helper to flush all promises */ export async function flushPromises() { return new Promise(resolve => setImmediate(resolve)); } /** * Create a deferred promise for testing async operations */ export function createDeferred() { let resolve; let reject; const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); return { promise, resolve: resolve, reject: reject, }; } /** * Mock performance.now for consistent timing tests */ export function mockPerformanceNow(sequence) { let index = 0; vi.spyOn(performance, 'now').mockImplementation(() => { const value = sequence[index % sequence.length]; index++; return value; }); } /** * Helper for testing error scenarios */ export async function expectAsyncError(fn, errorPattern) { try { await fn(); throw new Error('Expected function to throw'); } catch (error) { if (errorPattern) { if (typeof errorPattern === 'string') { expect(error.message).toContain(errorPattern); } else { expect(error.message).toMatch(errorPattern); } } } } /** * Create a test suite with common setup */ export function createTestSuite(name, options = {}, tests) { describe(name, () => { const env = setupTestEnvironment(options); afterEach(() => { env.cleanup(); }); tests(env); }); }