UNPKG

satie

Version:

A sheet music renderer for the web

199 lines (198 loc) 10.7 kB
/** * 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/>. */ "use strict"; /** * @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]); }); }); });