vexflow
Version:
A JavaScript library for rendering music notation and guitar tablature.
70 lines (69 loc) • 3.17 kB
JavaScript
import { VexFlow } from '../src/vexflow.js';
import { VexFlowTests } from './vexflow_test_helpers.js';
import { Formatter } from '../src/formatter.js';
import { Stave } from '../src/stave.js';
import { Barline } from '../src/stavebarline.js';
import { StaveNote } from '../src/stavenote.js';
import { Voice } from '../src/voice.js';
import { MockTickable } from './mocks.js';
const VoiceTests = {
Start() {
QUnit.module('Voice');
QUnit.test('Strict Test', strict);
QUnit.test('Ignore Test', ignore);
VexFlowTests.runTests('Full Voice Mode Test', full);
},
};
const BEAT = (1 * VexFlow.RESOLUTION) / 4;
const createTickable = () => new MockTickable().setTicks(BEAT);
function strict(assert) {
assert.expect(8);
const tickables = [createTickable(), createTickable(), createTickable()];
const voice = new Voice(VexFlow.TIME4_4);
assert.equal(voice.getTotalTicks().value(), BEAT * 4, '4/4 Voice has 4 beats');
assert.equal(voice.getTicksUsed().value(), BEAT * 0, 'No beats in voice');
voice.addTickables(tickables);
assert.equal(voice.getTicksUsed().value(), BEAT * 3, 'Three beats in voice');
voice.addTickable(createTickable());
assert.equal(voice.getTicksUsed().value(), BEAT * 4, 'Four beats in voice');
assert.equal(voice.isComplete(), true, 'Voice is complete');
const numeratorBeforeException = voice.getTicksUsed().numerator;
assert.throws(() => voice.addTickable(createTickable()), /BadArgument/, '"Too many ticks" exception');
assert.equal(voice.getTicksUsed().numerator, numeratorBeforeException, 'Revert `ticksUsed` after a "Too many ticks" exception');
assert.equal(voice.getSmallestTickCount().value(), BEAT, 'Smallest tick count is BEAT');
}
function ignore(assert) {
const tickables = [
createTickable(),
createTickable(),
createTickable().setIgnoreTicks(true),
createTickable(),
createTickable().setIgnoreTicks(true),
createTickable(),
];
const voice = new Voice(VexFlow.TIME4_4);
voice.addTickables(tickables);
assert.ok(true, 'all pass');
}
function full(options, contextBuilder) {
const ctx = contextBuilder(options.elementId, 550, 200);
const stave = new Stave(10, 50, 500).addClef('treble').addTimeSignature('4/4').setEndBarType(Barline.type.END);
const notes = [
new StaveNote({ keys: ['c/4'], duration: '4' }),
new StaveNote({ keys: ['d/4'], duration: '4' }),
new StaveNote({ keys: ['r/4'], duration: '4r' }),
];
notes.forEach((note) => note.setStave(stave));
const voice = new Voice(VexFlow.TIME4_4).setMode(Voice.Mode.FULL).addTickables(notes);
new Formatter().joinVoices([voice]).formatToStave([voice], stave);
stave.setContext(ctx).drawWithStyle();
voice.draw(ctx);
const bb = voice.getBoundingBox();
if (bb) {
ctx.rect(bb.getX(), bb.getY(), bb.getW(), bb.getH());
}
ctx.stroke();
options.assert.throws(() => voice.addTickable(new StaveNote({ keys: ['c/4'], duration: '2' })), /BadArgument/, 'Voice cannot exceed full amount of ticks');
}
VexFlowTests.register(VoiceTests);
export { VoiceTests };