Files
KGStudio/src/test/mocks/tone.ts
T

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);
};