satie
Version:
A sheet music renderer for the web
199 lines (198 loc) • 10.7 kB
JavaScript
/**
* This file is part of Satie music engraver <https://github.com/jnetterf/satie>.
* Copyright (C) Joshua Netterfield <joshua.ca> 2015 - present.
*
* Satie is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Satie is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Satie. If not, see <http://www.gnu.org/licenses/>.
*/
;
/**
* @file part of Satie test suite
*/
var private_chordUtil_1 = require("../private_chordUtil");
var musicxml_interfaces_1 = require("musicxml-interfaces");
var builders_1 = require("musicxml-interfaces/builders");
var chai_1 = require("chai");
var attributes_test_1 = require("./attributes_test");
describe("[engine/ichord.ts]", function () {
describe("hasAccidental", function () {
it("works with rests", function () {
var notes = [{
rest: {}
}];
var cursor = attributes_test_1.makeCursor(null, [notes]);
chai_1.expect(private_chordUtil_1.hasAccidental(notes, cursor)).to.eq(false);
});
});
var treble = builders_1.buildClef(function (clef) { return clef
.sign("G")
.line(2); });
var withRoot = function (root, octave) { return function (note) { return note
.pitch(function (pitch) { return pitch
.step(root)
.octave(octave); })
.duration(1)
.noteType(function (noteType) { return noteType
.duration(musicxml_interfaces_1.Count.Quarter); }); }; };
var noteC = builders_1.buildNote(withRoot("C", 4));
var noteD = builders_1.buildNote(withRoot("D", 4));
var noteG = builders_1.buildNote(withRoot("G", 5));
var noteA = builders_1.buildNote(withRoot("A", 5));
var noteCHigher = builders_1.buildNote(withRoot("C", 6));
var noteR = builders_1.buildNote(function (note) { return note
.rest({})
.noteType(function (noteType) { return noteType
.duration(musicxml_interfaces_1.Count.Half); }); });
describe("lineForClef", function () {
it("handles a null note", function () {
chai_1.expect(private_chordUtil_1.lineForClef(null, treble)).to.equal(3);
});
it("throws on a null clef", function () {
chai_1.expect(function () { return private_chordUtil_1.lineForClef(noteC, null); }).to.throw();
chai_1.expect(function () { return private_chordUtil_1.lineForClef(null, null); }).to.throw();
});
it("calculates middle C", function () {
var bass = builders_1.buildClef(function (clef) { return clef
.sign("F")
.line(4); });
chai_1.expect(private_chordUtil_1.lineForClef(noteC, treble)).to.equal(0);
chai_1.expect(private_chordUtil_1.lineForClef(noteC, bass)).to.equal(6);
});
it("calculates whole rest", function () {
var note = builders_1.buildNote(function (note) { return note
.rest({})
.noteType(function (noteType) { return noteType
.duration(musicxml_interfaces_1.Count.Whole); }); });
var clef2 = builders_1.buildClef(function (clef) { return clef
.sign("C")
.line(2); });
chai_1.expect(private_chordUtil_1.lineForClef(note, treble)).to.equal(4);
chai_1.expect(private_chordUtil_1.lineForClef(note, clef2)).to.equal(4);
});
it("calculates half rest", function () {
var clef = builders_1.buildClef(function (clef) { return clef
.sign("G")
.line(2); });
chai_1.expect(private_chordUtil_1.lineForClef(noteR, clef)).to.equal(3);
});
});
describe("linesForClef", function () {
it("doesn't choke on empty chord", function () {
chai_1.expect(private_chordUtil_1.linesForClef([], treble)).to.deep.equal([]);
});
it("throws on null clef", function () {
var note1 = builders_1.buildNote(function (note) { return note
.rest({})
.noteType(function (noteType) { return noteType
.duration(musicxml_interfaces_1.Count.Half); }); });
chai_1.expect(function () { return private_chordUtil_1.linesForClef([], null); }).to.throw();
chai_1.expect(function () { return private_chordUtil_1.linesForClef([note1], null); }).to.throw();
});
it("seems to work", function () {
var note1 = builders_1.buildNote(function (note) { return note
.rest({})
.noteType(function (noteType) { return noteType
.duration(musicxml_interfaces_1.Count.Half); }); });
chai_1.expect(private_chordUtil_1.linesForClef([note1, noteC], treble)).to.deep.equal([3, 0]);
});
});
describe("heightDeterminingLine", function () {
it("calculates single line", function () {
var note1 = builders_1.buildNote(function (note) { return note
.rest({})
.noteType(function (noteType) { return noteType
.duration(musicxml_interfaces_1.Count.Half); }); });
chai_1.expect(private_chordUtil_1.heightDeterminingLine([note1], 1, treble)).to.deep.equal(3);
chai_1.expect(private_chordUtil_1.heightDeterminingLine([note1], -1, treble)).to.deep.equal(3);
});
it("calculates inner line", function () {
var note2 = builders_1.buildNote(function (note) { return note
.pitch(function (pitch) { return pitch
.step("C")
.octave(5); })
.duration(1)
.noteType(function (noteType) { return noteType
.duration(musicxml_interfaces_1.Count.Quarter); }); });
chai_1.expect(private_chordUtil_1.heightDeterminingLine([noteC, note2], 1 /* Up */, treble)).to.equal(3.5);
chai_1.expect(private_chordUtil_1.heightDeterminingLine([note2, noteC], 1 /* Up */, treble)).to.equal(3.5);
chai_1.expect(private_chordUtil_1.heightDeterminingLine([noteC, note2], -1 /* Down */, treble)).to.equal(0);
chai_1.expect(private_chordUtil_1.heightDeterminingLine([note2, noteC], -1 /* Down */, treble)).to.equal(0);
});
it("throws on invalid direction", function () {
chai_1.expect(function () { return private_chordUtil_1.heightDeterminingLine([noteC], "1", treble); }).to.throw();
chai_1.expect(function () { return private_chordUtil_1.heightDeterminingLine([noteC], NaN, treble); }).to.throw();
chai_1.expect(function () { return private_chordUtil_1.heightDeterminingLine([noteC], 0.5, treble); }).to.throw();
chai_1.expect(function () { return private_chordUtil_1.heightDeterminingLine([noteC], 0, treble); }).to.throw();
});
});
describe("startingLine", function () {
it("calculates outer line for 3 notes", function () {
var note2 = builders_1.buildNote(function (note) { return note
.pitch(function (pitch) { return pitch
.step("C")
.octave(5); })
.duration(1)
.noteType(function (noteType) { return noteType
.duration(musicxml_interfaces_1.Count.Quarter); }); });
var note3 = builders_1.buildNote(function (note) { return note
.pitch(function (pitch) { return pitch
.step("G")
.octave(4); })
.duration(1)
.noteType(function (noteType) { return noteType
.duration(musicxml_interfaces_1.Count.Quarter); }); });
chai_1.expect(private_chordUtil_1.startingLine([noteC, note2, note3], -1 /* Down */, treble)).to.equal(3.5);
chai_1.expect(private_chordUtil_1.startingLine([note2, noteC, note3], -1 /* Down */, treble)).to.equal(3.5);
chai_1.expect(private_chordUtil_1.startingLine([noteC, note3, note2], 1 /* Up */, treble)).to.equal(0);
chai_1.expect(private_chordUtil_1.startingLine([noteC, note3, note2], 1 /* Up */, treble)).to.equal(0);
});
});
describe("onLedger", function () {
it("determines middle C to have a ledger", function () {
chai_1.expect(private_chordUtil_1.onLedger(noteC, treble)).to.be.true;
});
it("determines middle D to not have a ledger", function () {
chai_1.expect(private_chordUtil_1.onLedger(noteD, treble)).to.be.false;
});
it("determines high G to not have a ledger", function () {
chai_1.expect(private_chordUtil_1.onLedger(noteG, treble)).to.be.false;
});
it("determines high A to have a ledger", function () {
chai_1.expect(private_chordUtil_1.onLedger(noteA, treble)).to.be.true;
});
it("determintes rests to not have ledgers", function () {
chai_1.expect(private_chordUtil_1.onLedger(noteR, treble)).to.be.false;
var noteROdd = builders_1.buildNote(function (note) { return note
.rest(function (rest) { return rest
.displayStep("A")
.displayOctave(5); })
.noteType(function (type) { return type
.duration(musicxml_interfaces_1.Count.Half); }); });
chai_1.expect(private_chordUtil_1.onLedger(noteROdd, treble)).to.be.false;
});
});
describe("ledgerLines", function () {
it("throws if clef is missing", function () {
chai_1.expect(function () { return private_chordUtil_1.ledgerLines([noteC], null); }).to.throw();
});
it("calculates valid answers for single notes", function () {
chai_1.expect(private_chordUtil_1.ledgerLines([noteC], treble)).to.deep.equal([0]);
chai_1.expect(private_chordUtil_1.ledgerLines([noteD], treble)).to.deep.equal([]);
chai_1.expect(private_chordUtil_1.ledgerLines([noteG], treble)).to.deep.equal([]);
chai_1.expect(private_chordUtil_1.ledgerLines([noteA], treble)).to.deep.equal([6]);
});
it("does not double count", function () {
chai_1.expect(private_chordUtil_1.ledgerLines([noteA, noteCHigher], treble)).to.deep.equal([6, 7]);
});
});
});