mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-27 05:28:41 +00:00
test util
This commit is contained in:
parent
ee2d32339f
commit
020c1d5589
60
test/util.test.mjs
Normal file
60
test/util.test.mjs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { strict as assert } from 'assert';
|
||||||
|
import { isNote, tokenizeNote, toMidi } from '../util.mjs';
|
||||||
|
|
||||||
|
describe('isNote', () => {
|
||||||
|
it('should recognize notes without accidentals', function () {
|
||||||
|
'C3 D3 E3 F3 G3 A3 B3 C4 D5 c5 d5 e5'.split(' ').forEach((note) => {
|
||||||
|
assert.equal(isNote(note), true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should recognize notes with accidentals', function () {
|
||||||
|
'C#3 D##3 Eb3 Fbb3 Bb5'.split(' ').forEach((note) => {
|
||||||
|
assert.equal(isNote(note), true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should not recognize invalid notes', function () {
|
||||||
|
assert.equal(isNote('H5'), false);
|
||||||
|
assert.equal(isNote('C'), false);
|
||||||
|
assert.equal(isNote('X'), false);
|
||||||
|
assert.equal(isNote(1), false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isNote', () => {
|
||||||
|
it('should tokenize notes without accidentals', function () {
|
||||||
|
assert.deepStrictEqual(tokenizeNote('C3'), ['C', '', '3']);
|
||||||
|
assert.deepStrictEqual(tokenizeNote('D3'), ['D', '', '3']);
|
||||||
|
assert.deepStrictEqual(tokenizeNote('E3'), ['E', '', '3']);
|
||||||
|
assert.deepStrictEqual(tokenizeNote('F3'), ['F', '', '3']);
|
||||||
|
assert.deepStrictEqual(tokenizeNote('G3'), ['G', '', '3']);
|
||||||
|
assert.deepStrictEqual(tokenizeNote('A3'), ['A', '', '3']);
|
||||||
|
assert.deepStrictEqual(tokenizeNote('B3'), ['B', '', '3']);
|
||||||
|
assert.deepStrictEqual(tokenizeNote('C4'), ['C', '', '4']);
|
||||||
|
assert.deepStrictEqual(tokenizeNote('D5'), ['D', '', '5']);
|
||||||
|
});
|
||||||
|
it('should tokenize notes with accidentals', function () {
|
||||||
|
assert.deepStrictEqual(tokenizeNote('C#3'), ['C', '#', '3']);
|
||||||
|
assert.deepStrictEqual(tokenizeNote('D##3'), ['D', '##', '3']);
|
||||||
|
assert.deepStrictEqual(tokenizeNote('Eb3'), ['E', 'b', '3']);
|
||||||
|
assert.deepStrictEqual(tokenizeNote('Fbb3'), ['F', 'bb', '3']);
|
||||||
|
assert.deepStrictEqual(tokenizeNote('Bb5'), ['B', 'b', '5']);
|
||||||
|
});
|
||||||
|
it('should note tokenize invalid notes', function () {
|
||||||
|
assert.deepStrictEqual(tokenizeNote('X'), []);
|
||||||
|
assert.deepStrictEqual(tokenizeNote('asfasf'), []);
|
||||||
|
assert.deepStrictEqual(tokenizeNote(123), []);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('toMidi', () => {
|
||||||
|
it('should turn notes into midi', function () {
|
||||||
|
assert.equal(toMidi('A4'), 69);
|
||||||
|
assert.equal(toMidi('C4'), 60);
|
||||||
|
assert.equal(toMidi('Db4'), 61);
|
||||||
|
assert.equal(toMidi('C3'), 48);
|
||||||
|
assert.equal(toMidi('Cb3'), 47);
|
||||||
|
assert.equal(toMidi('Cbb3'), 46);
|
||||||
|
assert.equal(toMidi('C#3'), 49);
|
||||||
|
assert.equal(toMidi('C#3'), 49);
|
||||||
|
assert.equal(toMidi('C##3'), 50);
|
||||||
|
});
|
||||||
|
});
|
||||||
13
util.mjs
13
util.mjs
@ -1,7 +1,16 @@
|
|||||||
export const isNote = (name) => /^[a-gA-G][#b]?[0-9]$/.test(name);
|
export const isNote = (name) => /^[a-gA-G][#b]*[0-9]$/.test(name);
|
||||||
export const tokenizeNote = (note) => note.match(/^([a-gA-G])([#b])?([0-9])?$/).slice(1);
|
export const tokenizeNote = (note) =>
|
||||||
|
typeof note === 'string'
|
||||||
|
? note
|
||||||
|
.match(/^([a-gA-G])([#b]*)([0-9])?$/)
|
||||||
|
?.slice(1)
|
||||||
|
?.map((x) => (x === undefined ? '' : x)) || []
|
||||||
|
: [];
|
||||||
export const toMidi = (note) => {
|
export const toMidi = (note) => {
|
||||||
const [pc, acc, oct] = tokenizeNote(note);
|
const [pc, acc, oct] = tokenizeNote(note);
|
||||||
|
if (!pc) {
|
||||||
|
throw new Error('not a note: "' + note + '"');
|
||||||
|
}
|
||||||
const chroma = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 }[pc.toLowerCase()];
|
const chroma = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 }[pc.toLowerCase()];
|
||||||
const offset = acc?.split('').reduce((o, char) => o + { '#': 1, b: -1 }[char], 0) || 0;
|
const offset = acc?.split('').reduce((o, char) => o + { '#': 1, b: -1 }[char], 0) || 0;
|
||||||
return (Number(oct) + 1) * 12 + chroma + offset;
|
return (Number(oct) + 1) * 12 + chroma + offset;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user