158 lines
3.8 KiB
TypeScript
158 lines
3.8 KiB
TypeScript
import { vi } from 'vitest';
|
|
|
|
/**
|
|
* Mock implementation of Tone.js for testing
|
|
* This provides consistent, deterministic behavior for audio-related tests
|
|
*/
|
|
|
|
// Mock Sampler class
|
|
export const MockSampler = vi.fn().mockImplementation(() => ({
|
|
triggerAttackRelease: vi.fn(),
|
|
triggerAttack: vi.fn(),
|
|
triggerRelease: vi.fn(),
|
|
dispose: vi.fn(),
|
|
loaded: true,
|
|
attack: 0,
|
|
release: 0.1,
|
|
curve: 'exponential',
|
|
output: {},
|
|
volume: {
|
|
value: -12
|
|
},
|
|
connect: vi.fn(),
|
|
disconnect: vi.fn(),
|
|
toDestination: vi.fn()
|
|
}));
|
|
|
|
export const MockBufferSource = vi.fn().mockImplementation((options?: { playbackRate?: number }) => {
|
|
const instance = {
|
|
playbackRate: {
|
|
value: options?.playbackRate ?? 1,
|
|
setValueAtTime: vi.fn(),
|
|
},
|
|
connect: vi.fn(() => instance),
|
|
start: vi.fn(() => instance),
|
|
stop: vi.fn(() => instance),
|
|
onended: undefined as (() => void) | undefined,
|
|
};
|
|
return instance;
|
|
});
|
|
|
|
// Mock Transport object
|
|
export const MockTransport = {
|
|
start: vi.fn(),
|
|
stop: vi.fn(),
|
|
pause: vi.fn(),
|
|
position: 0,
|
|
bpm: {
|
|
value: 120,
|
|
rampTo: vi.fn()
|
|
},
|
|
timeSignature: [4, 4],
|
|
state: 'stopped',
|
|
scheduleOnce: vi.fn(),
|
|
scheduleRepeat: vi.fn(),
|
|
schedule: vi.fn().mockReturnValue(1),
|
|
cancel: vi.fn(),
|
|
clear: vi.fn()
|
|
,
|
|
setLoopPoints: vi.fn(),
|
|
loop: false,
|
|
PPQ: 192,
|
|
getTicksAtTime: vi.fn().mockImplementation((time: number) => time * 192)
|
|
};
|
|
|
|
export const MockLoop = vi.fn().mockImplementation((callback: (time: number) => void, interval: string) => ({
|
|
callback,
|
|
interval,
|
|
start: vi.fn(),
|
|
dispose: vi.fn()
|
|
}));
|
|
|
|
// Mock Destination
|
|
export const MockDestination = {
|
|
volume: {
|
|
value: -12
|
|
},
|
|
mute: false,
|
|
connect: vi.fn(),
|
|
disconnect: vi.fn()
|
|
};
|
|
|
|
// Mock ToneAudioBuffer
|
|
export const MockToneAudioBuffer = vi.fn().mockImplementation(() => ({
|
|
loaded: true,
|
|
dispose: vi.fn(),
|
|
get: vi.fn(),
|
|
set: vi.fn(),
|
|
load: vi.fn().mockResolvedValue(undefined)
|
|
}));
|
|
|
|
// Mock Gain node
|
|
export const MockGain = vi.fn().mockImplementation(() => ({
|
|
gain: {
|
|
value: 1,
|
|
setValueAtTime: vi.fn(),
|
|
linearRampToValueAtTime: vi.fn(),
|
|
exponentialRampToValueAtTime: vi.fn()
|
|
},
|
|
connect: vi.fn(),
|
|
disconnect: vi.fn(),
|
|
dispose: vi.fn()
|
|
}));
|
|
|
|
// Mock Meter
|
|
export const MockMeter = vi.fn().mockImplementation(() => ({
|
|
getValue: vi.fn().mockReturnValue(-Infinity),
|
|
connect: vi.fn(),
|
|
disconnect: vi.fn(),
|
|
dispose: vi.fn()
|
|
}));
|
|
|
|
// Complete Tone.js mock
|
|
export const ToneMock = {
|
|
Sampler: MockSampler,
|
|
BufferSource: MockBufferSource,
|
|
ToneBufferSource: MockBufferSource,
|
|
Loop: MockLoop,
|
|
Transport: MockTransport,
|
|
Destination: MockDestination,
|
|
ToneAudioBuffer: MockToneAudioBuffer,
|
|
Gain: MockGain,
|
|
Meter: MockMeter,
|
|
|
|
// Context management
|
|
start: vi.fn().mockResolvedValue(undefined),
|
|
getContext: vi.fn().mockReturnValue({
|
|
state: 'running',
|
|
resume: vi.fn().mockResolvedValue(undefined),
|
|
suspend: vi.fn().mockResolvedValue(undefined),
|
|
close: vi.fn().mockResolvedValue(undefined),
|
|
lookAhead: 0.05,
|
|
setTimeout: vi.fn().mockImplementation((fn: () => void, timeoutSeconds: number) => {
|
|
return window.setTimeout(fn, timeoutSeconds * 1000);
|
|
}),
|
|
clearTimeout: vi.fn().mockImplementation((id: number) => {
|
|
window.clearTimeout(id);
|
|
})
|
|
}),
|
|
|
|
// Time utilities
|
|
Time: vi.fn().mockImplementation((time) => ({
|
|
toSeconds: vi.fn().mockReturnValue(parseFloat(time) || 0),
|
|
valueOf: vi.fn().mockReturnValue(parseFloat(time) || 0)
|
|
})),
|
|
|
|
// Frequency utilities
|
|
Frequency: vi.fn().mockImplementation((freq) => ({
|
|
toFrequency: vi.fn().mockReturnValue(parseFloat(freq) || 440),
|
|
valueOf: vi.fn().mockReturnValue(parseFloat(freq) || 440)
|
|
})),
|
|
now: vi.fn().mockImplementation(() => Date.now() / 1000)
|
|
};
|
|
|
|
// Setup the global mock
|
|
export const setupToneMocks = () => {
|
|
vi.doMock('tone', () => ToneMock);
|
|
};
|