import chai = require ( "chai" ) ; import { OpenSheetMusicDisplay } from "../../../src/OpenSheetMusicDisplay/OpenSheetMusicDisplay" ; import { TestUtils } from "../../Util/TestUtils" ; import { VoiceEntry , Instrument , Note , Staff , Voice , GraphicalStaffEntry , GraphicalNote , Fraction , Pitch , AccidentalEnum , DrawingParametersEnum , IOSMDOptions } from "../../../src" ; describe ( "OpenSheetMusicDisplay Main Export" , ( ) => { let container1 ; it ( "no container" , ( done ) => { chai . expect ( ( ) => { return new OpenSheetMusicDisplay ( undefined ) ; } ) . to . throw ( /container/ ) ; done ( ) ; } ) ; it ( "container" , ( done ) => { const div = TestUtils . getDivElement ( document ) ; chai . expect ( ( ) => { return new OpenSheetMusicDisplay ( div ) ; } ) . to . not . throw ( Error ) ; done ( ) ; } ) ; it ( "multiple instances" , ( ) => { const musicSheetFragmentContainer = TestUtils . getDivElement ( document ) ; const fullMusicSheetContainer = TestUtils . getDivElement ( document ) ; const musicSheetFragmentOptions = { drawComposer : false , drawCredits : false , drawFingerings : false , drawHiddenNotes : false , drawLyricist : false , drawPartAbbreviations : false , drawPartNames : false , drawSubtitle : false , drawTitle : false , drawUpToMeasureNumber : 1 , drawingParameters : DrawingParametersEnum . compact } ; const fullMusicSheetOptions = { drawUpToMeasureNumber : 10 } ; const musicSheetFragment = new OpenSheetMusicDisplay ( musicSheetFragmentContainer , musicSheetFragmentOptions ) ; const fullMusicSheet = new OpenSheetMusicDisplay ( fullMusicSheetContainer , fullMusicSheetOptions ) ; const musicSheet = TestUtils . getScore ( "MuzioClementi_SonatinaOpus36No1_Part1.xml" ) ; const musicSheetXML = new XMLSerializer ( ) . serializeToString ( musicSheet ) ; return musicSheetFragment . load ( musicSheetXML ) . then ( ( ) => { musicSheetFragment . render ( ) ; return fullMusicSheet . load ( musicSheetXML ) ; } ) . then ( ( ) => { fullMusicSheet . render ( ) ; chai . expect ( musicSheetFragment . Sheet . Rules . RenderComposer ) . to . equal ( musicSheetFragmentOptions . drawComposer ) ; chai . expect ( musicSheetFragment . Sheet . Rules . RenderFingerings ) . to . equal ( musicSheetFragmentOptions . drawFingerings ) ; chai . expect ( musicSheetFragment . Sheet . Rules . RenderLyricist ) . to . equal ( musicSheetFragmentOptions . drawLyricist ) ; chai . expect ( musicSheetFragment . Sheet . Rules . RenderPartAbbreviations ) . to . equal ( musicSheetFragmentOptions . drawPartAbbreviations ) ; chai . expect ( musicSheetFragment . Sheet . Rules . RenderPartNames ) . to . equal ( musicSheetFragmentOptions . drawPartNames ) ; chai . expect ( musicSheetFragment . Sheet . Rules . RenderSubtitle ) . to . equal ( musicSheetFragmentOptions . drawSubtitle ) ; chai . expect ( musicSheetFragment . Sheet . Rules . RenderTitle ) . to . equal ( musicSheetFragmentOptions . drawTitle ) ; chai . expect ( musicSheetFragment . Sheet . Rules . MaxMeasureToDrawIndex ) . to . equal ( musicSheetFragmentOptions . drawUpToMeasureNumber - 1 ) ; chai . expect ( fullMusicSheet . Sheet . Rules . RenderComposer ) . to . not . equal ( musicSheetFragmentOptions . drawComposer ) ; chai . expect ( fullMusicSheet . Sheet . Rules . RenderFingerings ) . to . not . equal ( musicSheetFragmentOptions . drawFingerings ) ; chai . expect ( fullMusicSheet . Sheet . Rules . RenderLyricist ) . to . not . equal ( musicSheetFragmentOptions . drawLyricist ) ; chai . expect ( fullMusicSheet . Sheet . Rules . RenderPartAbbreviations ) . to . not . equal ( musicSheetFragmentOptions . drawPartAbbreviations ) ; chai . expect ( fullMusicSheet . Sheet . Rules . RenderPartNames ) . to . not . equal ( musicSheetFragmentOptions . drawPartNames ) ; chai . expect ( fullMusicSheet . Sheet . Rules . RenderSubtitle ) . to . not . equal ( musicSheetFragmentOptions . drawSubtitle ) ; chai . expect ( fullMusicSheet . Sheet . Rules . RenderTitle ) . to . not . equal ( musicSheetFragmentOptions . drawTitle ) ; chai . expect ( fullMusicSheet . Sheet . Rules . MaxMeasureToDrawIndex ) . to . equal ( fullMusicSheetOptions . drawUpToMeasureNumber - 1 ) ; } ) ; } ) ; it ( "load MXL from string" , ( done ) => { const mxl = TestUtils . getMXL ( "Mozart_Clarinet_Quintet_Excerpt.mxl" ) ; const div = TestUtils . getDivElement ( document ) ; const opensheetmusicdisplay = TestUtils . createOpenSheetMusicDisplay ( div ) ; opensheetmusicdisplay . load ( mxl ) . then ( ( _ ) => { opensheetmusicdisplay . render ( ) ; done ( ) ; } , done ) ; } ) ; it ( "load invalid MXL from string" , ( done ) => { const mxl = "\x50\x4b\x03\x04" ; const div = TestUtils . getDivElement ( document ) ; const opensheetmusicdisplay = TestUtils . createOpenSheetMusicDisplay ( div ) ; opensheetmusicdisplay . load ( mxl ) . then ( ( _ ) => { done ( new Error ( "Corrupted MXL appears to be loaded correctly" ) ) ; } , ( exc ) => { if ( exc . message . toLowerCase ( ) . match ( /invalid/ ) ) { done ( ) ; } else { done ( new Error ( "Unexpected error: " + exc . message ) ) ; } } ) ; } ) ; it ( "load XML string" , ( done ) => { const score = TestUtils . getScore ( "MuzioClementi_SonatinaOpus36No1_Part1.xml" ) ; const xml = new XMLSerializer ( ) . serializeToString ( score ) ; const div = TestUtils . getDivElement ( document ) ; const opensheetmusicdisplay = TestUtils . createOpenSheetMusicDisplay ( div ) ; opensheetmusicdisplay . load ( xml ) . then ( ( _ ) => { opensheetmusicdisplay . render ( ) ; done ( ) ; } , done ) ; } ) ; it ( "load XML Document" , ( done ) => { const score = TestUtils . getScore ( "MuzioClementi_SonatinaOpus36No1_Part1.xml" ) ; const div = TestUtils . getDivElement ( document ) ; const opensheetmusicdisplay = TestUtils . createOpenSheetMusicDisplay ( div ) ; opensheetmusicdisplay . load ( score ) . then ( ( _ ) => { opensheetmusicdisplay . render ( ) ; done ( ) ; } , done ) ; } ) ; it . skip ( "Timeout from server" , ( done ) => { const score = "https://httpstat.us/408" ; const div = TestUtils . getDivElement ( document ) ; const opensheetmusicdisplay = TestUtils . createOpenSheetMusicDisplay ( div ) ; opensheetmusicdisplay . load ( score ) . then ( ( _ ) => { done ( new Error ( "Unexpected response from server" ) ) ; } , ( exc ) => { done ( ) ; } ) ; } ) ; it ( "load MXL Document by URL" , ( done ) => { const url = "base/test/data/Mozart_Clarinet_Quintet_Excerpt.mxl" ; const div = TestUtils . getDivElement ( document ) ; const opensheetmusicdisplay = TestUtils . createOpenSheetMusicDisplay ( div ) ; opensheetmusicdisplay . load ( url ) . then ( ( _ ) => { opensheetmusicdisplay . render ( ) ; done ( ) ; } , done ) ; } ) ; it ( "load something invalid by URL" , ( done ) => { const url = "https://www.google.com" ; const div = TestUtils . getDivElement ( document ) ; const opensheetmusicdisplay = TestUtils . createOpenSheetMusicDisplay ( div ) ; opensheetmusicdisplay . load ( url ) . then ( ( _ ) => { done ( new Error ( "Invalid URL appears to be loaded correctly" ) ) ; } , ( exc ) => { if ( exc . message . toLowerCase ( ) . match ( /opensheetmusicdisplay.*invalid/ ) ) { done ( ) ; } else { done ( new Error ( "Unexpected error: " + exc . message ) ) ; } } ) ; } ) . timeout ( 5000 ) ; it ( "load invalid URL" , ( done ) => { const url = "https://www.afjkhfjkauu2ui3z2uiu.com" ; const div = TestUtils . getDivElement ( document ) ; const opensheetmusicdisplay = TestUtils . createOpenSheetMusicDisplay ( div ) ; opensheetmusicdisplay . load ( url ) . then ( ( _ ) => { done ( new Error ( "Invalid URL appears to be loaded correctly" ) ) ; } , ( exc ) => { if ( exc . message . toLowerCase ( ) . match ( /url/ ) ) { done ( ) ; } else { done ( new Error ( "Unexpected error: " + exc . message ) ) ; } } ) ; } ) . timeout ( 5000 ) ; it ( "load invalid XML string" , ( done ) => { const xml = "<?xml" ; const div = TestUtils . getDivElement ( document ) ; const opensheetmusicdisplay = TestUtils . createOpenSheetMusicDisplay ( div ) ; opensheetmusicdisplay . load ( xml ) . then ( ( _ ) => { done ( new Error ( "Corrupted XML appears to be loaded correctly" ) ) ; } , ( exc ) => { if ( exc . message . toLowerCase ( ) . match ( /partwise/ ) ) { done ( ) ; } else { done ( new Error ( "Unexpected error: " + exc . message ) ) ; } } ) ; } ) ; it ( "render without loading" , ( done ) => { const div = TestUtils . getDivElement ( document ) ; const opensheetmusicdisplay = TestUtils . createOpenSheetMusicDisplay ( div ) ; chai . expect ( ( ) => { return opensheetmusicdisplay . render ( ) ; } ) . to . throw ( /load/ ) ; done ( ) ; } ) ; before ( ( ) : void => { container1 = TestUtils . getDivElement ( document ) ; } ) ; after ( ( ) : void => { document . body . removeChild ( container1 ) ; } ) ; it ( "test width 500" , ( done ) => { const div = container1 ; div . style . width = "500px" ; const opensheetmusicdisplay = TestUtils . createOpenSheetMusicDisplay ( div ) ; const score = TestUtils . getScore ( "MuzioClementi_SonatinaOpus36No1_Part1.xml" ) ; opensheetmusicdisplay . load ( score ) . then ( ( _ ) => { opensheetmusicdisplay . render ( ) ; chai . expect ( div . offsetWidth ) . to . equal ( 500 ) ; done ( ) ; } , done ) . catch ( done ) ; } ) ; it ( "test width 200" , ( done ) => { const div = container1 ; div . style . width = "200px" ; const opensheetmusicdisplay = TestUtils . createOpenSheetMusicDisplay ( div ) ; const score = TestUtils . getScore ( "MuzioClementi_SonatinaOpus36No1_Part1.xml" ) ; opensheetmusicdisplay . load ( score ) . then ( ( _ ) => { opensheetmusicdisplay . render ( ) ; chai . expect ( div . offsetWidth ) . to . equal ( 200 ) ; done ( ) ; } , done ) . catch ( done ) ; } ) ; describe ( "cursor with hidden instrument" , ( ) => { let osmd ; beforeEach ( ( ) => { const div = TestUtils . getDivElement ( document ) ; osmd = TestUtils . createOpenSheetMusicDisplay ( div ) ; const score = TestUtils . getScore ( "MuzioClementi_SonatinaOpus36No1_Part1.xml" ) ; return osmd . load ( score ) . then ( ( ) => { osmd . render ( ) ; } ) ; } ) ; it ( "should move cursor after instrument is hidden" , ( ) => { osmd . Sheet . Instruments [ 1 ] . Visible = false ; osmd . render ( ) ; osmd . cursors [ 0 ] . show ( ) ; for ( let i = 0 ; i < 100 ; i ++ ) { osmd . cursors [ 0 ] . next ( ) ; } chai . expect ( osmd . cursors [ 0 ] . NotesUnderCursor ( ) [ 0 ] . halfTone ) . to . equal ( 60 ) ; } ) ; } ) ; describe ( "cursor" , ( ) => { let opensheetmusicdisplay ; beforeEach ( ( done ) => { const div = container1 ; opensheetmusicdisplay = TestUtils . createOpenSheetMusicDisplay ( div ) ; const score = TestUtils . getScore ( "MuzioClementi_SonatinaOpus36No1_Part1.xml" ) ; opensheetmusicdisplay . load ( score ) . then ( ( _ ) => { opensheetmusicdisplay . render ( ) ; opensheetmusicdisplay . cursors [ 0 ] . show ( ) ; done ( ) ; } , done ) . catch ( done ) ; } ) ; describe ( "get AllVoicesUnderCursor" , ( ) => { it ( "retrieves all voices under cursor" , ( ) => { const voiceEntries = opensheetmusicdisplay . cursors [ 0 ] . VoicesUnderCursor ( ) ; chai . expect ( voiceEntries . length ) . to . equal ( 2 ) ; } ) ; } ) ; describe ( "VoicesUnderCursor" , ( ) => { it ( "retrieves voices for a specific instrument under cursor" , ( ) => { const voiceEntries = opensheetmusicdisplay . cursors [ 0 ] . VoicesUnderCursor ( ) ; chai . expect ( voiceEntries . length ) . to . equal ( 2 ) ; } ) ; it ( "retrieves all voices under cursor when instrument not specified" , ( ) => { const instrument = opensheetmusicdisplay . Sheet . Instruments [ 1 ] ; const voiceEntries = opensheetmusicdisplay . cursors [ 0 ] . VoicesUnderCursor ( instrument ) ; chai . expect ( voiceEntries . length ) . to . equal ( 1 ) ; } ) ; } ) ; describe ( "NotesUnderCursor" , ( ) => { it ( "gets notes for a specific instrument under cursor" , ( ) => { const instrument = opensheetmusicdisplay . Sheet . Instruments [ 0 ] ; const notes = opensheetmusicdisplay . cursors [ 0 ] . NotesUnderCursor ( instrument ) ; chai . expect ( notes . length ) . to . equal ( 1 ) ; } ) ; it ( "gets all notes under cursor when instrument unspecified" , ( ) => { const notes = opensheetmusicdisplay . cursors [ 0 ] . NotesUnderCursor ( ) ; chai . expect ( notes . length ) . to . equal ( 2 ) ; } ) ; } ) ; describe ( "updateGraphic" , ( ) => { it ( "updates the graphical sheet with mutations on the music sheet" , ( ) => { const staff = opensheetmusicdisplay . Sheet . Staves [ 0 ] ; const voice = staff . Voices [ 0 ] ; const voiceEntry = voice . VoiceEntries [ 0 ] ; const numNotesBefore = voiceEntry . Notes . length ; { const graphicalStaffEntry = opensheetmusicdisplay . GraphicSheet . getStaffEntry ( 0 ) ; const graphicalNotes = graphicalStaffEntry . findVoiceEntryGraphicalNotes ( voiceEntry ) ; chai . expect ( graphicalNotes . length ) . to . equal ( numNotesBefore ) ; } const newNote = new Note ( voiceEntry , voiceEntry . ParentSourceStaffEntry , new Fraction ( 1 ) , new Pitch ( 11 , 2 , AccidentalEnum . NATURAL ) , voiceEntry . ParentSourceStaffEntry . VerticalContainerParent . ParentMeasure ) ; voiceEntry . Notes . push ( newNote ) ; opensheetmusicdisplay . updateGraphic ( ) ; { const graphicalStaffEntry = opensheetmusicdisplay . GraphicSheet . getStaffEntry ( 0 ) ; const graphicalNotes = graphicalStaffEntry . findVoiceEntryGraphicalNotes ( voiceEntry ) ; chai . expect ( graphicalNotes . length ) . to . equal ( numNotesBefore + 1 ) ; } } ) ; } ) ; } ) ; } ) ;