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 ; let parser ; 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 ) => { const keyInstruction = getIllegalMusicXmlWithTwoFifthsElements ( ) . getFirstSourceMeasure ( ) . getKeyInstruction ( 0 ) ; chai . expect ( keyInstruction . Mode ) . to . equal ( KeyModeEnum . none ) ; done ( ) ; } ) ; it ( "reads key signature with no optional 'mode' element present" , ( done ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const 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 ) => { const keyInstruction = getMusicSheetWithKey ( 1 , "" ) . getFirstSourceMeasure ( ) . getKeyInstruction ( 0 ) ; const vexflowKeySignature = VexFlowConverter . keySignature ( keyInstruction ) ; const isGMajorOrEminor = [ "G" , "E" ] . indexOf ( vexflowKeySignature . charAt ( 0 ) ) !== - 1 ; chai . expect ( isGMajorOrEminor ) . to . equal ( true ) ; done ( ) ; } ) ; } ) ; describe ( "InstrumentReader for element 'time'" , ( ) => { before ( ( ) : void => { reader = new MusicSheetReader ( ) ; parser = new DOMParser ( ) ; } ) ; it ( "gives common time RythmSymbolEnum from xml" , ( done ) => { const instructions = 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 ) => { const instructions = 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 = undefined , mode = undefined , timeSymbol = "" ) { const doc = parser . parseFromString ( getMusicXmlWithKey ( fifths , mode , timeSymbol ) , "text/xml" ) ; chai . expect ( doc ) . to . not . be . undefined ; const score = new IXmlElement ( doc . getElementsByTagName ( "score-partwise" ) [ 0 ] ) ; chai . expect ( score ) . to . not . be . undefined ; return reader . createMusicSheet ( score , "template.xml" ) ; } function getMusicXmlWithKey ( fifths = undefined , mode = undefined , timeSymbol = "" ) { const modeElement = mode ? `<mode>${ mode }</mode>` : "" ; const fifthsElement = fifths ? `<fifths>${ fifths }</fifths>` : "" ; const timeSymbolAttribute = 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 ( ) { const doc = 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 = new IXmlElement ( doc . getElementsByTagName ( "score-partwise" ) [ 0 ] ) ; chai . expect ( score ) . to . not . be . undefined ; return reader . createMusicSheet ( score , "template.xml" ) ; }