test tonal methods + move mod to util

This commit is contained in:
Felix Roos 2022-02-28 22:52:09 +01:00
parent 020c1d5589
commit df21c81bfa
5 changed files with 129 additions and 54 deletions

39
test/tonal.test.mjs Normal file
View file

@ -0,0 +1,39 @@
import { strict as assert } from 'assert';
import { scaleTranspose, scaleOffset } from '../repl/src/tonal.mjs';
describe('scaleOffset', () => {
it('should transpose positive numbers', () => {
const c3Minor = ['C3', 'D3', 'Eb3', 'F3', 'G3', 'Ab3', 'Bb3', 'C4', 'D4', 'Eb4', 'F4', 'G4', 'Ab4', 'Bb4'];
c3Minor.forEach((n, i) => {
assert.equal(scaleOffset('C minor', i), n);
});
const gMinor = ['G3', 'A3', 'Bb3', 'C4', 'D4', 'Eb4', 'F4', 'G4', 'A4', 'Bb4', 'C5', 'D5', 'Eb5', 'F5', 'G5'];
gMinor.forEach((n, i) => {
assert.equal(scaleOffset('G minor', i), n);
});
});
it('should transpose negative numbers', () => {
const c3MinorDown = ['C3', 'Bb2', 'Ab2', 'G2', 'F2', 'Eb2', 'D2', 'C2'];
c3MinorDown.forEach((n, i) => {
assert.equal(scaleOffset('C minor', -i), n);
});
});
it('should transpose scales with octave', () => {
const c4Minor = ['C4', 'D4', 'Eb4', 'F4', 'G4', 'Ab4', 'Bb4', 'C5', 'D5', 'Eb5', 'F5', 'G5', 'Ab5', 'Bb5'];
c4Minor.forEach((n, i) => {
assert.equal(scaleOffset('C4 minor', i), n);
});
});
});
describe('scaleTranspose', () => {
it('should transpose inside scale', () => {
scaleTranspose('C minor', 0, 'C3');
scaleTranspose('C minor', 1, 'D3');
scaleTranspose('C minor', -1, 'Bb2');
scaleTranspose('C minor', 8, 'C4');
scaleTranspose('C4 minor', 8, 'C5');
});
});
// TODO: test tonal Pattern methods

View file

@ -1,18 +1,18 @@
import { strict as assert } from 'assert';
import { isNote, tokenizeNote, toMidi } from '../util.mjs';
import { isNote, tokenizeNote, toMidi, mod } from '../util.mjs';
describe('isNote', () => {
it('should recognize notes without accidentals', function () {
it('should recognize notes without accidentals', () => {
'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 () {
it('should recognize notes with accidentals', () => {
'C#3 D##3 Eb3 Fbb3 Bb5'.split(' ').forEach((note) => {
assert.equal(isNote(note), true);
});
});
it('should not recognize invalid notes', function () {
it('should not recognize invalid notes', () => {
assert.equal(isNote('H5'), false);
assert.equal(isNote('C'), false);
assert.equal(isNote('X'), false);
@ -21,32 +21,38 @@ describe('isNote', () => {
});
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 without accidentals', () => {
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 tokenize notes with accidentals', () => {
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 () {
it('should tokenize notes without octave', () => {
assert.deepStrictEqual(tokenizeNote('C'), ['C', '', undefined]);
assert.deepStrictEqual(tokenizeNote('C#'), ['C', '#', undefined]);
assert.deepStrictEqual(tokenizeNote('Bb'), ['B', 'b', undefined]);
assert.deepStrictEqual(tokenizeNote('Bbb'), ['B', 'bb', undefined]);
});
it('should not tokenize invalid notes', () => {
assert.deepStrictEqual(tokenizeNote('X'), []);
assert.deepStrictEqual(tokenizeNote('asfasf'), []);
assert.deepStrictEqual(tokenizeNote(123), []);
});
});
describe('toMidi', () => {
it('should turn notes into midi', function () {
it('should turn notes into midi', () => {
assert.equal(toMidi('A4'), 69);
assert.equal(toMidi('C4'), 60);
assert.equal(toMidi('Db4'), 61);
@ -58,3 +64,22 @@ describe('toMidi', () => {
assert.equal(toMidi('C##3'), 50);
});
});
describe('mod', () => {
it('should work like regular modulo with positive numbers', () => {
assert.equal(mod(0, 3), 0);
assert.equal(mod(1, 3), 1);
assert.equal(mod(2, 3), 2);
assert.equal(mod(3, 3), 0);
assert.equal(mod(4, 3), 1);
assert.equal(mod(4, 2), 0);
});
it('should work with negative numbers', () => {
assert.equal(mod(-1, 3), 2);
assert.equal(mod(-2, 3), 1);
assert.equal(mod(-3, 3), 0);
assert.equal(mod(-4, 3), 2);
assert.equal(mod(-5, 3), 1);
assert.equal(mod(-3, 2), 1);
});
});