6 lines
1.7 KiB
JavaScript
6 lines
1.7 KiB
JavaScript
import test from 'node:test';import assert from 'node:assert/strict';import {CasualAudio} from '../audio.mjs';import {CasualAudio as OriginalAudio} from '../../campaign-50/audio.mjs';
|
|
function host(){const events=[];class Audio{constructor(){this.currentTime=1;this.state='running';this.destination={};}createOscillator(){let type;return {set type(v){type=v;},frequency:{setValueAtTime(f,t){events.push({f,t,type});}},connect(){},disconnect(){},start(){},stop(){}};}createGain(){return {gain:{setValueAtTime(){},linearRampToValueAtTime(){},exponentialRampToValueAtTime(){}},connect(){},disconnect(){}};}}return {AudioContext:Audio,events};}const storage={getItem(){return null},setItem(){}};
|
|
test('every movement is one semitone higher, including rapid moves; undo/restart follow step index',()=>{const h=host(),a=new CasualAudio(h,storage,'sound');for(let step=1;step<=20;step++)a.play('move',0,step);assert.equal(h.events.length,20);assert.equal(h.events[0].f,523);for(let i=1;i<20;i++)assert.ok(Math.abs(h.events[i].f/h.events[i-1].f-Math.pow(2,1/12))<1e-10);a.play('move',0,7);assert.equal(h.events.at(-1).f,h.events[6].f);a.play('move',0,1);assert.equal(h.events.at(-1).f,523);assert.ok(h.events.every(e=>e.type==='sine'));});
|
|
test('other five cues retain exact frequency and timing arrays',()=>{for(const kind of ['correct','error','undo','restart','complete']){const h=host(),old=host();new CasualAudio(h,storage,'s').play(kind);new OriginalAudio(old,storage,'s').play(kind);assert.deepEqual(h.events,old.events,kind);}});
|
|
test('silent/unsupported audio never blocks play',()=>{const h=host(),a=new CasualAudio(h,storage,'s');a.toggle();a.play('move',0,5);assert.equal(h.events.length,0);assert.doesNotThrow(()=>new CasualAudio({},storage,'s').play('move'));});
|