Files
pocket-chords/app/app/lib/chord-voicing.test.ts

74 lines
2.2 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { getPianoNotes, getGuitarVoicing } from './chord-voicing';
describe('getPianoNotes', () => {
it('returns note names for a major chord', () => {
expect(getPianoNotes('C')).toEqual(['C', 'E', 'G']);
});
it('returns note names for Cmaj7', () => {
expect(getPianoNotes('Cmaj7')).toEqual(['C', 'E', 'G', 'B']);
});
it('returns note names for Am', () => {
expect(getPianoNotes('Am')).toEqual(['A', 'C', 'E']);
});
it('returns [] for unparseable chord', () => {
expect(getPianoNotes('???')).toEqual([]);
});
it('returns [] for empty string', () => {
expect(getPianoNotes('')).toEqual([]);
});
});
describe('getGuitarVoicing', () => {
it('returns voicing for E major (open position, baseFret=0)', () => {
const v = getGuitarVoicing('E');
expect(v).not.toBeNull();
expect(v!.baseFret).toBe(0);
expect(v!.frets).toEqual([0, 2, 2, 1, 0, 0]);
});
it('returns voicing for Am (open position, baseFret=0)', () => {
const v = getGuitarVoicing('Am');
expect(v).not.toBeNull();
expect(v!.baseFret).toBe(0);
expect(v!.frets).toEqual([null, 0, 2, 2, 1, 0]);
});
it('transposes Bm correctly (A-shape, shift=2)', () => {
const v = getGuitarVoicing('Bm');
expect(v).not.toBeNull();
// Am shifted up 2: [null,2,4,4,3,2], baseFret=2
expect(v!.baseFret).toBe(2);
expect(v!.frets).toEqual([null, 2, 4, 4, 3, 2]);
});
it('returns open G major voicing from named table', () => {
const v = getGuitarVoicing('G');
expect(v).not.toBeNull();
// Named open G: [3,2,0,0,0,3], baseFret=0
expect(v!.baseFret).toBe(0);
expect(v!.frets).toEqual([3, 2, 0, 0, 0, 3]);
});
it('falls back to transposition for F# major (not in named table)', () => {
const v = getGuitarVoicing('F#');
expect(v).not.toBeNull();
// E-shape shift=2: [2,4,4,3,2,2], baseFret=2
expect(v!.baseFret).toBe(2);
expect(v!.frets).toEqual([2, 4, 4, 3, 2, 2]);
});
it('returns null for unknown quality', () => {
// 'add9' is not in the voicing map
expect(getGuitarVoicing('Cadd9')).toBeNull();
});
it('returns null for unparseable chord', () => {
expect(getGuitarVoicing('???')).toBeNull();
});
});