51 lines
2.2 KiB
TypeScript
51 lines
2.2 KiB
TypeScript
import { test, expect } from "bun:test";
|
|
import { assignTab } from "../../src/pipeline/tab.ts";
|
|
import { GUITAR_STANDARD, BASS_STANDARD } from "../../src/core/types.ts";
|
|
import type { ScoreNote } from "../../src/core/types.ts";
|
|
|
|
const sn = (tick: number, dur: number, pitch: number): ScoreNote => ({ tick, dur, pitch });
|
|
|
|
test("chord gets playable, injective tab", () => {
|
|
const chordC = [48, 52, 55, 60, 64].map((p) => sn(0, 960, p));
|
|
const a = assignTab(chordC, GUITAR_STANDARD);
|
|
expect(a.dropped).toBe(0);
|
|
for (const n of a.notes) expect(GUITAR_STANDARD[n.string! - 1]! + n.fret!).toBe(n.pitch);
|
|
expect(new Set(a.notes.map((n) => n.string)).size).toBe(5);
|
|
expect(Math.max(...a.notes.map((n) => n.fret!))).toBeLessThanOrEqual(3);
|
|
});
|
|
|
|
test("drops unplayable notes", () => {
|
|
expect(assignTab([sn(0, 960, 30)], GUITAR_STANDARD)).toEqual({ notes: [], dropped: 1 });
|
|
expect(assignTab([sn(0, 960, 90)], GUITAR_STANDARD)).toEqual({ notes: [], dropped: 1 });
|
|
});
|
|
|
|
test("keeps highest notes when chord exceeds string count", () => {
|
|
const a = assignTab([40, 45, 50, 55, 59, 64, 67].map((p) => sn(0, 960, p)), GUITAR_STANDARD);
|
|
expect(a.dropped).toBe(1);
|
|
expect(a.notes.map((n) => n.pitch).sort()).toEqual([45, 50, 55, 59, 64, 67]);
|
|
});
|
|
|
|
test("a scale run stays in a low, smoothly moving position", () => {
|
|
const run = [60, 62, 64, 65, 67, 69, 71, 72].map((p, i) => sn(i * 240, 240, p));
|
|
const a = assignTab(run, GUITAR_STANDARD);
|
|
expect(a.dropped).toBe(0);
|
|
const frets = a.notes.map((n) => n.fret!);
|
|
expect(Math.max(...frets)).toBeLessThanOrEqual(9);
|
|
for (let i = 1; i < frets.length; i++) expect(Math.abs(frets[i]! - frets[i - 1]!)).toBeLessThanOrEqual(4);
|
|
});
|
|
|
|
test("bass notes are valid and respect maxFret", () => {
|
|
const a = assignTab([28, 33, 38, 43, 80].map((p, i) => sn(i * 240, 240, p)), BASS_STANDARD, 20);
|
|
for (const n of a.notes) {
|
|
expect(BASS_STANDARD[n.string! - 1]! + n.fret!).toBe(n.pitch);
|
|
expect(n.fret!).toBeLessThanOrEqual(20);
|
|
}
|
|
expect(a.dropped).toBe(1);
|
|
});
|
|
|
|
test("two notes that only fit the low E string: one dropped", () => {
|
|
const a = assignTab([sn(0, 240, 40), sn(0, 240, 41)], GUITAR_STANDARD, 20);
|
|
expect(a.notes.length).toBe(1);
|
|
expect(a.dropped).toBe(1);
|
|
});
|