1import { describe, expect, it } from 'vitest'; 2import { position, starting } from './lyrics.mjs'; 3 4const lyric = { text: 'It breaks.', seconds: 1.5, syllables: [['It ', 0.1], ['breaks.', 0.6]] }; 5 6describe('position', () => { 7 it('waits before the first syllable, then says which is sung and how far to the next', () => { 8 expect(position(lyric, 50)).toMatchObject({ index: -1, over: false }); 9 expect(position(lyric, 100).index).toBe(0); 10 expect(position(lyric, 100).progress).toBeCloseTo(0); 11 expect(position(lyric, 350).progress).toBeCloseTo(0.5); 12 expect(position(lyric, 600).index).toBe(1); 13 }); 14 it('runs the last syllable to the clip\'s end, then is over', () => { 15 expect(position(lyric, 1050)).toMatchObject({ index: 1, over: false }); 16 expect(position(lyric, 1050).progress).toBeCloseTo(0.5); 17 expect(position(lyric, 1500)).toMatchObject({ index: 1, progress: 1, over: true }); 18 }); 19}); 20 21describe('starting', () => { 22 const hap = (value, begin, end = begin + 1) => ({ value, whole: { begin, end } }); 23 const words = { ck1a: lyric, ck1b: lyric }; 24 it('keeps the haps of sounds that have words, once they have begun, keyed by sound and cycle', () => { 25 const haps = [hap({ s: 'ck1a' }, 8), hap({ s: 'bd' }, 8), hap({ s: 'ck1b' }, 10), hap({ note: 60 }, 8)]; 26 expect(starting(haps, 8.25, words)).toEqual([{ key: 'ck1a@8', sound: 'ck1a', since: 0.25, rate: 1, cut: 1, held: null }]); 27 }); 28 it('says how fast the clip plays and how much of it', () => { 29 const [fast] = starting([hap({ s: 'ck1a', speed: 1.25, end: 0.5 }, 0)], 0, words); 30 expect(fast).toMatchObject({ rate: 1.25, cut: 0.5, held: null }); 31 const [clipped] = starting([hap({ s: 'ck1a', clip: 1 }, 0, 0.25)], 0, words); 32 expect(clipped.held).toBe(0.25); 33 }); 34 it('starts nothing for a slice of a clip, one played backwards, or another file of the sound', () => { 35 const haps = [hap({ s: 'ck1a', begin: 0.25, end: 0.5 }, 0), hap({ s: 'ck1a', speed: -1 }, 0), hap({ s: 'ck1a', n: 3 }, 0)]; 36 expect(starting(haps, 0.5, words)).toEqual([]); 37 }); 38 it('is not fooled by a sound named like an object\'s own method', () => { 39 expect(starting([hap({ s: 'toString' }, 0)], 1, { ck1a: lyric })).toEqual([]); 40 }); 41});