123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407 |
- /* eslint-disable @typescript-eslint/no-unused-expressions */
- import { MusicSheetReader } from "../../../src/MusicalScore/ScoreIO/MusicSheetReader";
- import { MusicSheet } from "../../../src/MusicalScore/MusicSheet";
- import { IXmlElement } from "../../../src/Common/FileIO/Xml";
- import { KeyInstruction } from "../../../src/MusicalScore/VoiceData/Instructions/KeyInstruction";
- import { KeyEnum as KeyModeEnum } from "../../../src/MusicalScore/VoiceData/Instructions/KeyInstruction";
- import { VexFlowConverter } from "../../../src/MusicalScore/Graphical/VexFlow/VexFlowConverter";
- import chai from "chai";
- import { AbstractNotationInstruction } from "../../../src/MusicalScore/VoiceData/Instructions/AbstractNotationInstruction";
- import { RhythmInstruction, RhythmSymbolEnum } from "../../../src/MusicalScore/VoiceData/Instructions/RhythmInstruction";
- let reader: MusicSheetReader;
- let parser: DOMParser;
- describe("MusicXML parser for element 'key'", () => {
- before((): void => {
- reader = new MusicSheetReader();
- parser = new DOMParser();
- });
- describe("for group traditional keys", () => {
- it("enforces single occurrence of element 'fifths'", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getIllegalMusicXmlWithTwoFifthsElements().getFirstSourceMeasure().getKeyInstruction(0);
- // TODO Make sure we detect the multiple fifths and react properly // [it seems like we do this, test passes. ssch]
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.none);
- done();
- });
- it("reads key signature with no optional 'mode' element present", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(0, undefined).getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(0);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.none);
- done();
- });
- describe("major keys", () => {
- it("reads key signature C-major", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(0, "major").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(0);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
- done();
- });
- it("reads key signature G-major", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(1, "major").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(1);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
- done();
- });
- it("reads key signature D-major", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(2, "major").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(2);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
- done();
- });
- it("reads key signature A-major", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(3, "major").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(3);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
- done();
- });
- it("reads key signature E-major", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(4, "major").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(4);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
- done();
- });
- it("reads key signature B-major", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(5, "major").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(5);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
- done();
- });
- it("reads key signature F#-major", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(6, "major").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(6);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
- done();
- });
- it("reads key signature C#-major", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(7, "major").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(7);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
- done();
- });
- it("reads key signature G#-major", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(8, "major").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(8);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
- done();
- });
- it("reads key signature F-major", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(-1, "major").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(-1);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
- done();
- });
- it("reads key signature Bb-major", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(-2, "major").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(-2);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
- done();
- });
- it("reads key signature Eb-major", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(-3, "major").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(-3);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
- done();
- });
- it("reads key signature Ab-major", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(-4, "major").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(-4);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
- done();
- });
- it("reads key signature Db-major", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(-5, "major").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(-5);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
- done();
- });
- it("reads key signature Gb-major", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(-6, "major").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(-6);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
- done();
- });
- it("reads key signature Fb-major", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(-8, "major").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(-8);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.major);
- done();
- });
- });
- describe("minor keys", () => {
- it("reads key signature a-minor", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(0, "minor").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(0);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
- done();
- });
- it("reads key signature e-minor", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(1, "minor").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(1);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
- done();
- });
- it("reads key signature b-minor", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(2, "minor").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(2);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
- done();
- });
- it("reads key signature f#-minor", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(3, "minor").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(3);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
- done();
- });
- it("reads key signature c#-minor", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(4, "minor").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(4);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
- done();
- });
- it("reads key signature g#-minor", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(5, "minor").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(5);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
- done();
- });
- it("reads key signature d#-minor", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(6, "minor").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(6);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
- done();
- });
- it("reads key signature a#-minor", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(7, "minor").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(7);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
- done();
- });
- it("reads key signature d-minor", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(-1, "minor").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(-1);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
- done();
- });
- it("reads key signature g-minor", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(-2, "minor").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(-2);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
- done();
- });
- it("reads key signature c-minor", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(-3, "minor").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(-3);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
- done();
- });
- it("reads key signature f-minor", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(-4, "minor").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(-4);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
- done();
- });
- it("reads key signature bb-minor", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(-5, "minor").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(-5);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
- done();
- });
- it("reads key signature eb-minor", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(-6, "minor").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(-6);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
- done();
- });
- it("reads key signature ab-minor", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(-7, "minor").getFirstSourceMeasure().getKeyInstruction(0);
- chai.expect(keyInstruction.Key).to.equal(-7);
- chai.expect(keyInstruction.Mode).to.equal(KeyModeEnum.minor);
- done();
- });
- });
- });
- });
- describe("VexFlowConverter for element 'key'", () => {
- before((): void => {
- reader = new MusicSheetReader();
- parser = new DOMParser();
- });
- it("gives key signature G-major with no optional 'mode' element present", (done: Mocha.Done) => {
- const keyInstruction: KeyInstruction = getMusicSheetWithKey(1, "").getFirstSourceMeasure().getKeyInstruction(0);
- const vexflowKeySignature: string = VexFlowConverter.keySignature(keyInstruction);
- const isGMajorOrEminor: boolean = ["G", "E"].indexOf(vexflowKeySignature.charAt(0)) !== -1;
- chai.expect(isGMajorOrEminor).to.equal(true);
- done();
- });
- });
- // not key tests, but if we outsource this, we need to make getMusicSheetWithKey() accessible from other test files.
- describe("InstrumentReader for element 'time'", () => {
- before((): void => {
- reader = new MusicSheetReader();
- parser = new DOMParser();
- });
- it("gives common time RythmSymbolEnum from xml", (done: Mocha.Done) => {
- const instructions: AbstractNotationInstruction[] =
- getMusicSheetWithKey(1, "major", "common").getFirstSourceMeasure().FirstInstructionsStaffEntries[0].Instructions;
- for (const instruction of instructions) {
- if (instruction instanceof RhythmInstruction) {
- chai.expect(instruction.SymbolEnum).to.equal(RhythmSymbolEnum.COMMON);
- }
- }
- done();
- });
- it("gives alla breve/cut time RythmSymbolEnum from xml", (done: Mocha.Done) => {
- const instructions: AbstractNotationInstruction[] =
- getMusicSheetWithKey(1, "major", "cut").getFirstSourceMeasure().FirstInstructionsStaffEntries[0].Instructions;
- for (const instruction of instructions) {
- if (instruction instanceof RhythmInstruction) {
- chai.expect(instruction.SymbolEnum).to.equal(RhythmSymbolEnum.CUT);
- }
- }
- done();
- });
- });
- function getMusicSheetWithKey(fifths: number = undefined, mode: string = undefined, timeSymbol: string = ""): MusicSheet {
- const doc: Document = parser.parseFromString(getMusicXmlWithKey(fifths, mode, timeSymbol), "text/xml");
- chai.expect(doc).to.not.be.undefined;
- const score: IXmlElement = new IXmlElement(doc.getElementsByTagName("score-partwise")[0]);
- chai.expect(score).to.not.be.undefined;
- return reader.createMusicSheet(score, "template.xml");
- }
- function getMusicXmlWithKey(fifths: number = undefined, mode: string = undefined, timeSymbol: string = ""): string {
- const modeElement: string = mode ? `<mode>${mode}</mode>` : "";
- const fifthsElement: string = fifths ? `<fifths>${fifths}</fifths>` : "";
- const timeSymbolAttribute: string = timeSymbol ? `symbol="${timeSymbol}"` : "";
- return `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
- <!DOCTYPE score-partwise PUBLIC
- "-//Recordare//DTD MusicXML 3.0 Partwise//EN"
- "http://www.musicxml.org/dtds/partwise.dtd">
- <score-partwise version="3.0">
- <part-list>
- <score-part id="P1">
- <part-name>Music</part-name>
- </score-part>
- </part-list>
- <part id="P1">
- <measure number="1">
- <attributes>
- <divisions>1</divisions>
- <key>
- ${fifthsElement}
- ${modeElement}
- </key>
- <time ${timeSymbolAttribute}>
- <beats>4</beats>
- <beat-type>4</beat-type>
- </time>
- <clef>
- <sign>G</sign>
- <line>2</line>
- </clef>
- </attributes>
- <note>
- <pitch>
- <step>C</step>
- <octave>4</octave>
- </pitch>
- <duration>4</duration>
- <type>whole</type>
- </note>
- </measure>
- </part>
- </score-partwise>`;
- }
- function getIllegalMusicXmlWithTwoFifthsElements(): MusicSheet {
- const doc: Document = parser.parseFromString(
- `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
- <!DOCTYPE score-partwise PUBLIC
- "-//Recordare//DTD MusicXML 3.0 Partwise//EN"
- "http://www.musicxml.org/dtds/partwise.dtd">
- <score-partwise version="3.0">
- <part-list>
- <score-part id="P1">
- <part-name>Music</part-name>
- </score-part>
- </part-list>
- <part id="P1">
- <measure number="1">
- <attributes>
- <divisions>1</divisions>
- <key>
- <fifths>1</fifths>
- <fifths>2</fifths>
- <fifths>3</fifths>
- </key>
- <time>
- <beats>4</beats>
- <beat-type>4</beat-type>
- </time>
- <clef>
- <sign>G</sign>
- <line>2</line>
- </clef>
- </attributes>
- <note>
- <pitch>
- <step>C</step>
- <octave>4</octave>
- </pitch>
- <duration>4</duration>
- <type>whole</type>
- </note>
- </measure>
- </part>
- </score-partwise>`,
- "text/xml"
- );
- chai.expect(doc).to.not.be.undefined;
- const score: IXmlElement = new IXmlElement(doc.getElementsByTagName("score-partwise")[0]);
- chai.expect(score).to.not.be.undefined;
- return reader.createMusicSheet(score, "template.xml");
- }
|