
    rh                       S SK Jr  S SKrS SKrS SKrS SKrS SKrS SKrS SKJ	r	J
r  S SKJr  S SKJr  S SKJr  S SKJr  S SKJr  S S	KJr  S S
KJr  S SKJr  S SKJr  S SKJr  S SKJr  S SKJr  S SKJr  S SKJr  S SKJr  S SKJr  S SKJr  S SKJr  S SKJr  S SK J!r!  S SK J"r"  S SK#J$r$J%r%J&r&J'r'  S SK(J)r)  S!S jr* " S S\RV                  5      r, " S S\RV                  5      r-\.S :X  a  S SKr\R^                  " \,5        gg)"    )annotationsN)ElementTree
fromstring)articulations)chord)common)	converter)corpus)defaults)duration)dynamics)expressions)harmony)
instrument)layout)meter)note)repeat)spanner)stream)style)tempo)helpers)testPrimitive)GeneralObjectExporterScoreExporterMusicXMLWarningMusicXMLExportException)MeasureParserc                2    [         R                  " SSU 5      $ )zW
Collapse all whitespace (say, in some XML) to a single space,
for ease of comparison.
z\s+ )resub)txts    X/home/james-whalen/.local/lib/python3.13/site-packages/music21/musicxml/test_m21ToXml.pystripInnerSpacesr&   )   s    
 66&#s##    c                      \ rS rSrS rS)S jrS rS rS rS r	S r
S	 rS
 rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS r S r!S  r"S! r#S" r$S# r%S$ r&S% r'S& r(S'r)g()*Test1   c                ^    [        5       nUR                  U5      nUR                  S5      nU$ )Nutf-8)r   parsedecode)selfobjgexbytesOutbytesOutUnicodes        r%   getXmlTest.getXml3   s+    #%99S>"//'2r'   c                    U(       a  [        5       nUR                  U5      n[        U5      nX$l        UR	                  5       n[
        R                  " U5        U$ )z(
Return a <score-partwise> ElementTree.
)r   fromGeneralObjectr   makeNotationr-   r   indent)r/   r0   r8   r1   SXmxScores         r%   getET
Test.getET9   sJ     ')C'',C3&((*wr'   c                   [         R                  " 5       n[         R                  " 5       nSUl        UR	                  [
        R                  " SS95        UR	                  U5        SnUS-  nU R                  [        5       nUR                  5         S S S 5        U R                  [        WR                  5      U5        g ! , (       d  f       N4= f)NzOffstage Trumpetg      `?quarterLengthz)In part (Offstage Trumpet), measure (1): z9Cannot convert "2048th" duration to MusicXML (too short).)r   ScorePartpartNameinsertr   NoteassertRaisesr   writeassertEqualstr	exception)r/   spmsgerrors        r%   testExceptionMessageTest.testExceptionMessageG   s    LLNKKM'
	(45	9JJ675GGI 8U__-s3 87s   C
Cc                   [         R                  " S5      n[        UR                  5       R                  5      nUS   nUS   n[
        R                  " X4/5      nUR                  SU5        US   nUS   nUS   n[
        R                  " XgU/5      n	UR                  SU	5        US   n
US	   n[
        R                  " X/5      nUR                  SU5        U R                  U R                  U5      R                  S
5      S5        g )Nz*tinynotation: 4/4 c4 d e f g a b c' b a g2r                          z<slur )r	   r-   listrecursenotesr   SlurrD   rH   r4   count)r/   rL   	listNotescdsl1fgasl2c2g2sl3s                r%   testSpannersWriteTest.testSpannersWriteT   s    OOHI**+	aLaLllA6"	caLaLaLllA!9%	cq\r]llB8$	cQ--h7;r'   c                   [         R                  " 5       n[         R                  " 5       nUR                  SU5        [         R                  " 5       nUR                  SU5        [         R
                  " 5       nUR                  SU5        [        R                  " SSS9n[        R                  " 5       n[        R                  " 5       nUR                  SU5        UR                  SU5        UR                  SU5        [        R                  " XV5      n[        R                  " Xg5      n	UR                  X45        U R                  U5      n
U R                  [!        S5      [!        U
5      5        g )Nr   CrU   r?      as  <measure implicit="no" number="0">
                       <attributes>
                           <divisions>10080</divisions>
                       </attributes>
                       <note>
                           <pitch>
                               <step>C</step>
                               <octave>4</octave>
                           </pitch>
                           <duration>40320</duration>
                           <type>whole</type>
                       </note>
                       <backup>
                           <duration>40320</duration>
                       </backup>
                       <direction placement="below">
                           <direction-type>
                               <wedge number="1" spread="0" type="crescendo" />
                           </direction-type>
                       </direction>
                       <forward>
                           <duration>20160</duration>
                       </forward>
                       <direction placement="below">
                           <direction-type>
                               <wedge number="2" spread="15" type="diminuendo" />
                           </direction-type>
                       </direction>
                       <direction placement="below">
                           <direction-type>
                               <wedge number="1" spread="15" type="stop" />
                           </direction-type>
                       </direction>
                       <forward>
                           <duration>20160</duration>
                       </forward>
                       <direction placement="below">
                           <direction-type>
                               <wedge number="2" spread="0" type="stop" />
                           </direction-type>
                       </direction>
                   </measure>)r   rA   rB   rD   MeasureVoicer   rE   r   SpannerAnchorr   	Crescendo
Diminuendoappendr4   assertInr&   )r/   scorepartmeasurevoicensa1sa2crescdimxmlOuts              r%   testSpannerAnchorsTest.testSpannerAnchorsh   s   {{}Q.."Awq% IIc+##%##%QQQ""1*!!#+e\"U#)!*"V V$Y-	
r'   c                `   [         R                  " 5       S-  S-  n[        R                  " US-  5      nU R	                  [        UR                  5      S5        U R                  UR                  S   [        R                  5        U R	                  [        UR                  S   R                  5      S5        U R	                  [        UR                  S   R                  5      S5        U R                  UR                  S   R                  S   [        R                  5        UR                  SS9  U R	                  [        UR                  S   R                  5      S5        U R                  U5      nUR                  S5      S   nU R!                  [#        S	5      [#        U5      5        g
)z
Test that spanners are gathered on the PartStaffs that need them.

Multi-staff instruments are separated on import into distinct PartStaff
objects, where usually all the spanners will remain on the first object.
musicxmllilypondTestSuitez43e-Multistaff-ClefDynamics.xmlrR   r   TinPlacez
</backup>
a   <direction placement="below">
                        <direction-type>
                            <wedge number="1" spread="0" type="crescendo" />
                        </direction-type>
                        <staff>2</staff>
                    </direction>N)r   getSourceFilePathr	   r-   rH   lenspannersassertIsInstancer   
StaffGrouppartsr   rq   r8   r4   splitrt   r&   )r/   xmlDirrK   r~   xmlAfterFirstBackups        r%   testSpannersWritePartStaffs Test.testSpannersWritePartStaffs   sT    ))+j8;NNOOF%FFG 	QZZ!,ajjmV->->? 	QWWQZ00115QWWQZ00115aggaj11!4h6H6HI 	
t$QWWQZ00115 Q$ll=9!<$% 01		
r'   c                   [         R                  " 5       n[        R                  " U/5      n[        R                  " U/5      nU R                  U5      nU R                  SU5        [         R                  " 5       n[        R                  " U/5      nUR                  SU5        U R                  U5      nU R                  SU5        U R                  SU5        SUl	        U R                  U5      nU R                  SU5        U R                  SU5        SUl	        U R                  U5      nU R                  SU5        g )	Nz<voice>1</voice>r   z<voice>2</voice>   z<voice>234</voice>z<voice>235</voice>helloz<voice>hello</voice>)
r   rE   r   ro   rn   r4   assertNotInrD   rt   id)r/   ry   v1mr~   n2v2s          r%   testLowVoiceNumbersTest.testLowVoiceNumbers   s    IIK\\1#NNB4 Q+V4YY[\\2$	BQ(&1(&1Q*F3*F3Q,f5r'   c                   [         R                  " 5       n[        R                  " U/5      n[        R                  " U/5      n[         R                  " 5       n[        R                  " U/5      n[        R                  " U/5      n[        R
                  " X6/5      n[         R                  " 5       n[        R                  " U/5      n	[        R                  " U	/5      n
[         R                  " 5       n[        R                  " U/5      n[        R                  " U/5      n[        R
                  " X/5      n[         R                  " 5       n[        R                  " U/5      n[        R                  " U/5      n[         R                  " 5       n[        R                  " U/5      n[        R                  " U/5      n[        R
                  " UU/5      n[        R                  " X~U/5      n[        R                  " X~U/5      nUR                  SU5        U R                  USS9nUR                  S5      nU HK  nUR                  S5      nUR                  S5      nU R                  UR                  UR                  5        MM     g )Nr   Fr8   zpart/measure/noterx   staff)r   rE   r   ro   rn   	PartStaffrA   r   r   rD   r<   findallfindrH   text)r/   n1_1v1_1m1_1n1_2v1_2m1_2ps1n2_1v2_1m2_1n2_2v2_2m2_2ps2n3_1v3_1m3_1n3_2v3_2m3_2ps3rK   
staffGrouptreemxNotesmxNoterx   r   s                                r%   (testVoiceNumberOffsetsThreeStaffsInGroup-Test.testVoiceNumberOffsetsThreeStaffsInGroup   s   yy{||TF#~~tf%yy{||TF#~~tf%|,yy{||TF#~~tf%yy{||TF#~~tf%|,yy{||TF#~~tf%yy{||TF#~~tf%d|,LL#C)&&#7
	Jzz!%z0,,23FKK(EKK(EUZZ4	 r'   c                \   [         R                  " 5       S-  S-  nUS-  n[        R                  " U5      nU[        R
                     R                  5       nU R                  U5      nU R                  SU5        U R                  SU5        U R                  SU5        U R                  U5      nUR                  S5      nUS   nU R                  UR                  S	5      S
5        U R                  [        U5      S5        U R                  US   R                  S5        U R                  US   R                  S5        US   n	U R                  [        U	5      S5        U	 V
s/ s H  oR                  PM     nn
U R                  U/ SQ5        U R                  U	R                  S5      R                   S5        U R                  U	R                  S5      S   R                   S5        U R                  U	R                  S5      S   R                   S5        U R                  U	R                  S5      S   R                   S5        U R                  U	R                  S5      S   R                   S5        US   nU R                  [        U5      S5        U V
s/ s H  oR                  PM     nn
U R                  U/ SQ5        U R#                  UR                  S5      R                   5        U R                  UR                  S5      S   R                   S5        U R                  UR                  S5      S   R                   S5        U R                  UR                  S5      S   R                   S5        U R                  UR                  S5      S   R                   S5        g s  sn
f s  sn
f )Nr   r   z!61l-Lyrics-Elisions-Syllables.xmlz<lyric name="1" number="1">z<syllabic>begin</syllabic>z<text>a</text>zpart/measure/note/lyricr   number1rm   syllabicrR   r   rV   )r   r   elisionr   r   r   r!   middlebr_   r`   ende)r   r   r	   r-   r   NotRestfirstr4   rt   r<   r   rH   getr   tagr   r   assertIsNone)r/   r   fprK   n1r~   r   mxLyricsly0ly1childtagsly2s                r%   testCompositeLyricsTest.testCompositeLyrics  s   ))+j8;NN99OOBt||_""$R3V<2F;&/zz!}<< 9:qk*C0S1%QZ0QV, qkS1%'*+se		s+RS),1137Z0388(CV,Q/44c:Z0388(CV,Q/44c:qkS1%'*+se		s+RS#((9-223Z0388(CV,Q/44c:Z0388%@V,Q/44c:! , ,s   $N$N)c                   [         R                  " SSSSS9nU R                  U5      nUR                  S5      nU R	                  [        U5      S5        US   nUR                  S5      nUR                  S	5      nU R	                  UR                  S5        U R	                  UR                  S
5      R                  S5        U R	                  UR                  S5      R                  S5        U R	                  UR                  S5      R                  S5        U R	                  UR                  S5      R                  S5        [        5       nUR                  U5      nU R	                  UR                  SS9UR                  SS95        U R	                  UR                  SS9UR                  SS95        U R	                  UR                  5       UR                  5       5        g)z
This test checks for the issue in 1756 where a chord symbol imported
with both inversion and bass would not have them both set.

There were multiple bugs fixed, so important to check.
FzA-rR   minor)rootbass	inversionkindzpart/measure/harmonyr   r   z	root-stepr   r   r   zbass/bass-stepAzbass/bass-alterz-1F)r   N)r   ChordSymbolr<   r   rH   r   r   r   r   xmlToChordSymbolr   r   r   )	r/   explicitFm6et
harmonyEls	harmonyElr   rootStepmpcss	            r%   #testExportChordSymbolWithInversions(Test.testExportChordSymbolWithInversions5  s    ))sQXYZZ$ZZ 67
Z!,qM	~~f%99[),/44g>4993?(89>>D(9:??F _  +))u)5rwwEw7JK))u)5rwwEw7JK..0",,.Ar'   c                   [         R                  " 5       n[         R                  " 5       n[         R                  " 5       nUR	                  [
        R                  " S5      5        UR                  [        R                  " S5      S5        UR	                  U5        [         R                  " 5       nUR	                  [
        R                  " 5       5        UR                  [        R                  " S5      S5        UR	                  [
        R                  " S5      5        UR                  [        R                  " S5      S5        UR	                  U5        UR	                  U5        U R                  SU R                  U5      R                  S5      5        U R                  SU R                  U5      R                  S5      5        U R                  SU R                  U5      R                  S5      5        [         R                  " 5       n[         R                  " 5       n[         R                  " 5       nUR	                  [
        R                  " 5       5        UR                  [        R                  " S5      S5        UR	                  [
        R                  " S5      5        UR                  [        R                  " S5      S5        UR	                  U5        [         R                  " 5       nUR	                  [
        R                  " S	5      5        UR                  [        R                  " S5      S5        UR	                  [
        R                  " S5      5        UR                  [        R                  " S5      S5        UR	                  U5        UR	                  U5        U R                  SU R                  U5      R                  S5      5        U R                  SU R                  U5      R                  S
5      5        g )Nrl   rU   rm   rT   z<harmonyrR   z<kind text="N.C.">none</kind>z<root-step text="">zNo Chordz!<kind text="No Chord">none</kind>)r   rA   rB   rn   rs   r   r   repeatAppendr   rE   NoChordrH   r4   r]   )r/   rK   rL   r   s       r%   testExportNCTest.testExportNCQ  s   LLNKKMNN	$$S)*	tyy~q)	NN	"#	tyy~q)	$$S)*	tyy~q)		DKKN00<=DKKN001PQRDKKN001FGHLLNKKMNN	"#	tyy~q)	$$S)*	tyy~q)	NN	,-	tyy~q)	$$S)*	tyy~q)		DKKN001PQRDKKN001TUVr'   c                    [         R                  " S5      n[        R                  " U/5      n[	        U5      nUR                  5         U Vs/ s H  oDR                  S:X  d  M  UPM     nnU R                  XQR                  S S 5        g s  snf )Nztinynotation: 4/4 c1 d1r   rR   )	r	   r-   r   rA   r   setPartsAndRefStreamoffsetassertSequenceEqualelements)r/   rL   scsxr   measuresAtOffsetZeros         r%   testSetPartsAndRefStreamMeasure$Test.testSetPartsAndRefStreamMeasurew  sr    OO56\\1#2
!+,>1aA1>  !5zz"1~F  ?s   B$Bc                4   [         R                  " 5       nUR                  [        R                  " S5      5        UR                  [
        R                  " 5       5        UR                  [
        R                  " 5       5        [        U5      nU R                  [        5       n[        UR                  5       R                  S5      5      nSSS5        U R                  [        U5      R                  S5      S   [!        WR"                  5      5        U R                  S[!        UR"                  5      5        U R%                  [        U5      [!        UR"                  5      5        U R'                  WR)                  S5      / 5        g! , (       d  f       N= f)z6
Badly nested streams should warn but output no gaps.
1/4r,   Nz 0xr   z/ is not well-formed; see isWellFormedNotation()
.//forward)r   rA   rs   r   TimeSignaturer   rE   r   assertWarnsr   et_fromstringr-   r.   rt   reprr   rI   warningr   r   r   )r/   rK   r1   cmr   s        r%   testFromScoreNoPartsTest.testFromScoreNoParts  s    LLN	$$U+,		#A&o." !3!3G!<=D /d1gmmE*1-s2::?GRZZY 	a#bjj/2 	  l!;R@ /.s   #)F		
Fc                    [         R                  " 5       nUR                  [        R                  " 5       5        [        U5      nUR                  5       nU R                  UR                  S5      5        g )N
.//measure)	r   rA   rs   r   rE   r   r-   assertIsNotNoner   )r/   rK   
scExporterr   s       r%   testFromScoreNoMeasuresTest.testFromScoreNoMeasures  sN    LLN	"1%
!TYY|45r'   c                   [         R                  " [        R                  " 5       [        R
                  " S5      /5      n[         R                  " U5      nSUl        [         R                  " [         R                  " [        R                  " 5       [        R
                  " 5       /5      5      n[         R                  " X#/5      nU R                  UR                  S5        [        U5      n[        UR                  5       R                  S5      5      nU R                  [        UR!                  S5      5      S5        U R                  UR#                  S5      R$                  S5        SUl        [        U5      n[        UR                  5       R                  S5      5      nU R                  [        UR!                  S5      5      S5        U R                  UR#                  S5      R$                  S5        g	)
z0
A score with mixed sounding and written parts.
rl   Tunknownr,   z.//transposerR   z.//stepDN)r   rn   r   Clarinetr   rE   rB   atSoundingPitchBassoonrA   rH   r   r   r-   r.   r   r   r   r   )r/   r   p1p2rK   r1   r   s          r%   testFromSoundingPitchTest.testFromSoundingPitch  sZ    NNJ//1499S>BC[[^![[););)=tyy{(KLMLL""**I6#A&SYY[//89T\\.9:A>9-22C8 #A&SYY[//89T\\.9:A>9-22C8r'   c                v   [         R                  " [         R                  " [        R                  " 5       [
        R                  " SS9/5      [         R                  " [        R                  " 5       [
        R                  " SS9/5      [         R                  " [        R                  " 5       [
        R                  " SS9/5      /5      n[         R                  " [         R                  " [        R                  " 5       [
        R                  " SS9/5      [         R                  " [        R                  " 5       [
        R                  " SS9/5      [         R                  " [        R                  " 5       [
        R                  " SS9/5      /5      n[         R                  " X/5      n[        U5      nUR                  5       nU R                  [        UR                  S5      5      S5        U R                  [        UR                  S5      5      S5        U R                  UR                  S5      R                  S5      UR                  S5      R                  S5      5        U R!                  UR                  S5      R                  S5      UR                  S5      S   R                  S5      5        g	)
aJ  
This is a score for two woodwind players both doubling on
flute and oboe. They both switch to flute and then back to oboe.
There are six m21 instruments to represent this, but the
<score-instrument> tags need just four, since no
musicXML <part> needs two oboes in it, etc., unless
there is a patch change/MIDI instrument change.
wholetype.//score-instrumentrU   .//measure/note/instrumentrW   r   rX   N)r   rB   rn   r   Oboer   rE   FluterA   r   r-   rH   r   r   r   r   assertNotEqual)r/   r  r  rK   scExr   s         r%   testMultipleInstrumentsTest.testMultipleInstruments  s    [[NNJOO-tyyg/FGHNNJ,,.		w0GHINNJOO-tyyg/FGH
 
 [[NNJOO-tyyg/FGHNNJ,,.		w0GHINNJOO-tyyg/FGH
 
 LL""Qzz|T\\*?@A1ET\\*FGH!L#89==dC#?@DDTJ	LDII&;<@@F LL)EFrJNNtT	Vr'   c                H   [         R                  " [         R                  " [        R                  " 5       [
        R                  " SS9/5      [         R                  " [        R                  " 5       [
        R                  " SS9/5      [         R                  " [        R                  " 5       [
        R                  " SS9/5      /5      n[         R                  " [         R                  " [        R                  " 5       [
        R                  " SS9/5      [         R                  " [
        R                  " SS9/5      [         R                  " [
        R                  " SS9/5      /5      n[        R                  " X/5      n[         R                  " XU/5      n[        U5      nUR                  5       nU R                  UR!                  S5       Vs1 s H  owR"                  iM     sn1 Sk5        U R                  [%        UR!                  S5      5      S5        g s  snf )Nr  r  z.//instrument-name>   Pianoro   Electric OrganElectric Pianor  rW   )r   r   rn   r   ElectricPianor   rE   ElectricOrganr   Vocalistr   r   rA   r   r-   rH   r   r   r   )r/   r   r   sgrK   r  r   els           r%   testMultipleInstrumentsPiano!Test.testMultipleInstrumentsPiano  s}   NNJ446		w8OPQNNJ446		w8OPQNNJ,,.		w0GHI 
 
 NNJ//1499'3JKLNNDII7345NNDII7345 
 
 z*LL#B(Qzz|#||,@ABAWWABB	

 	T\\*FGH!L Cs   Hc                   [         R                  " SSS9nUR                  [        R                  " SS95        [         R
                  " U5      n[        U5      nUR                  5       nUR                  S5       HB  nU R                  SUR                  ;   5        U R                  UR                  S5      S5        MD     g)	zZCheck that id of measure are exported
as attributes of the <measure> eelement in MusicXML
testrR   )r   r   r  r  r  r   N)r   rn   rs   r   rE   rA   r   r-   r   
assertTrueattribrH   r   )r/   rw   rK   r  r   measure_xmls         r%   testExportIdOfMeasureTest.testExportIdOfMeasure  s     ..F15tyyg./LL!Qzz|<<5KOODK$6$667[__T2F; 6r'   c                   [         R                  " 5       nSUl        [        R                  " S5      nUR                  S5      R                  U5        [        R                  " U5      n[        U5      nUR	                  5       nUR                  S5      S   nUR                  S5      S   nU R                  UR                  S5      UR                  S5      5        g )N*   ztinyNotation: c1rR   r  r   z.//midi-instrumentr   )r   
InstrumentmidiProgramr	   r-   rw   rD   r   rA   r   r   rH   r   )r/   irK   r   r  r   mxScoreInstrumentmxMidiInstruments           r%   testMidiInstrumentNoNameTest.testMidiInstrumentNoName  s    !!#OO./			!A\\!_"2&
! LL)>?B<<(<=a@*..t46F6J6J46PQr'   c                    [         R                  " [        R                  5      nU R	                  U5      nUR                  S5      nU R                  U Vs/ s H  oDR                  PM     sn/ SQ5        g s  snf )Nz.//ornaments/accidental-mark)naturalsharpzthree-quarters-flat)r	   r-   r   notations32ar<   r   rH   r   )r/   rK   xaccidentalMarksaccMarks        r%   testOrnamentAccidentalsTest.testOrnamentAccidentals   sZ    OOM667JJqM))$BC)89g\\97	
9s   A6c                $   [         R                  " [        R                  5      nU R	                  U5      nUR                  S5      nU R                  U Vs/ s H  oDR                  S5      PM     sn/ SQ5        UR                  5       nUR                  SS9  U R	                  U5      nUR                  S5      nU R                  U Vs/ s H  oDR                  S5      PM     sn/ SQ5        SUR                  S   R                  [        R                  5      R                  5       l        U R	                  U5      nUR                  S5      nU R                  U Vs/ s H  oDR                  S5      PM     sn/ SQ5        g s  snf s  snf s  snf )N	.//endingr   )1,2rE  3rF  Tr   r   ) rG  rF  rF  )r	   r-   r   multiDigitEndingr<   r   rH   r   templater8   r   getElementsByClassr   RepeatBracketr   r   )r/   rK   r>  endingsr   rI  s         r%   testMultiDigitEndingsWriteTest.testMultiDigitEndingsWrite	  s7    OOM::;JJqM))K(7;7a%%/7;=UV ::<d+JJx ))K(7;7a%%/7;=UV OP
%%g&;&;<BBDKJJqM))K(7;7a%%/7;=OP < < <s   F
FFc           	     r   [         R                  " [        R                  5      nU R	                  U5      nUR                  S5      nU R                  U Vs/ s H  oDR                  S5      PM     sn/ SQ5        S S /SS /S S /S S/SS /S S /S S/S S /S.nUR                  S5      nU R                  [        U5      S5        U GHX  nUR                  S5      nU R                  US	9   [        XX   S
   S L5      n	[        XX   S   S L5      n
SnSnUR                  S5      n[        U5       H  u  pUR                  S5      S:X  aB  SnS nUR                  S5      nUb  UR                  S5      nU R                  UXX   S
   5        M\  UR                  S5      S:X  d  Ms  SnS nUR                  S5      nUb  UR                  S5      nU R                  UXX   S   5        M     U	(       a  U R                  U5        U
(       a  U R                  U5        S S S 5        GM[     g s  snf ! , (       d  f       GMs  = f)NrD  r   )r   r   2rP  startstop)r   rP  rF  45678r     )measureNumberr   rR   Fz
.//barlinelocationleftTendingr  right)r	   r-   r   multiMeasureEndingr<   r   rH   r   r   subTestbool	enumerater   r,  )r/   rK   r>  rL  r   expectedEndingsmeasuresrw   
measNumberexpectLeftBarlineexpectRightBarlinegotLeftBarlinegotRightBarlinebarlinesr5  barlineleftEndingType
leftEndingrightEndingTyperightEndings                       r%   testMultiMeasureEndingsWrite!Test.testMultiMeasureEndingsWrite!  s    $ OOM<<=JJqM))K(7;7a%%/7;=QR 44

 99\*X*G X.JJ7$()DQ)Gt)S$T!%)/*Ea*HPT*T%U"!&"'"??<8"+H"5JA{{:.&8)-)-%,\\(%;
%1-7^^F-CN((9TUV9WX Z0G;*.*.&-ll8&<&2.9oof.EO((/:UVW:XY #6  %OON3%OOO45 87   <" 87s   H!'B4H&A4H&&
H6	c                   [         R                  " S5      n[        R                  " 5       nSUl        [        R
                  " 5       n[        R                  " SS9nSUl        UR                  S5      R                  X#U/5        U R                  U5      nUR                  S5       H#  nU R                  UR                  S5      5        M%     UR                  S	5      nU R                  UR!                  S
5      S5        g)z<
Transfer element offset after calling getTextExpression().
ztinynotation: 4/4 c1FLangsam)r   aboverR   z.//directionr   zpart/measure/direction	placementN)r	   r-   r   Coda	useSymbolFiner   MetronomeMarkrt  rw   
storeAtEndr<   r   r   r   rH   r   )r/   rK   r_   rb   mmr   	directionmxDirections           r%   testTextExpressionOffsetTest.testTextExpressionOffsetc  s    
 OO23KKMKKM  i0			!r
+zz!}n5IinnX67 6 ii 895w?r'   c                   [         R                  " S5      nU[        R                     R	                  5       nSUl        U R                  UR                  S5        U R                  U5      nU R                  [        UR                  S5      5      S5        UR                  S5      nU R                  UR                  S5      S5        U R                  UR                  S5      5        g )	Nztinynotation: 9/8 r1g      @auto.//restrR   rw   yesz.//note/type)r	   r-   r   Restr   r@   rH   fullMeasurer<   r   r   r   r   r   )r/   rK   rr   rests        r%   testFullMeasureRestTest.testFullMeasureRestx  s    OO23diiL /zz!} 	T\\)45q9yy#),e4$))N34r'   c                   [         R                  " 5       n[        R                  " 5       nUR                  R	                  U5        [        R
                  " 5       nUR                  R	                  U5        U R                  UR                  S5        [        U5      n[        UR                  5       R                  S5      5      nU R                  UR                  S5      5        U R                  UR                  S5      5        g )Nr   r,   z	.//stringz.//other-technical)r   rE   r   StringIndicationrs   HammerOnrH   r   r   r   r-   r.   r   r   )r/   ry   rd   hr1   r   s         r%   testArticulationSpecialCases!Test.testArticulationSpecialCases  s    IIK**,	q!""$ 	
q! 	1%#A&SYY[//89$))K01$))$89:r'   c                   [         R                  " [        R                  " S5      /5      nSU[         R                     R                  5       l        SU[         R                     R                  5       l        [        5       R                  U5      nU R                  U5      nU R                  [        UR                  S5      5      S5        SU[         R                     R                  5       l        [        5       R                  U5      nU R                  U5      nU R                  [        UR                  S5      5      S5        g )NztinyNotation: 4/4 c4       @g      ?r  r   rR   )r   rA   r	   r-   rn   r   paddingLeftpaddingRightr   r7   r<   rH   r   r   )r/   rK   r   s      r%   testMeasurePaddingTest.testMeasurePadding  s    LL)//*@ABC03&..!-14&..!.!#55a8zz!}T\\)45q903&..!-!#55a8zz!}T\\)45q9r'   c                @   [         R                  " S5      R                  S   n[        R                  " S5      UR                  S5      l        UR                  5       R                  [        R                  5      R                  5       nUR                  S[        R                  " S5      5        UR                  SS9  UR                  5       nU R                  U5      nU R                  UR                  S	5      5        U R!                  UR                  S
5      5        g)a6  
Instrument tags were causing forward motion in some cases.
From Chapter 14, Key Signatures

This is a transposed score.  Instruments were being extended in duration
in the toSoundingPitch and not having their durations restored afterwards
leading to Instrument objects being split if the duration was complex
zbach/bwv57.8z#Altoz6/8   r   z2/4Tr   z.//noter   N)r
   r-   r   r   r   rw   timeSignatureflattengetElementsNotOfClassr   rD   makeMeasuresr8   r<   r,  r   assertFalse)r/   altonewAltonewAltoFixedr   s        r%   #test_instrumentDoesNotCreateForward(Test.test_instrumentDoesNotCreateForward  s     ||N+11':(-(;(;E(BQ%,,.66u7J7JKRRTq%--e45T*++-zz,'Y/0l34r'   c                   [         R                  " 5       nUR                  [        R                  " 5       5        UR                  [        R                  " 5       5        UR                  [        R                  " 5       5        UR                  [        R                  " 5       5        [
        R                  " 5       n[        R                  " 5       n[        R                  " 5       nUR                  SU5        UR                  SU5        UR                  X45        UR                  U5        [         R                  " 5       nUR                  U5        [         R                  " 5       nUR                  U5        U R                  U5      nSnSn	UR                  5        HB  n
U
R                  S:X  d  M  U
nUR                  5        H  n
U
R                  S:X  d  M  U
n	  O     O   U R!                  U5        U R!                  U	5        [#        U	R$                  5      nSnUR'                  S5       H  n
U
R)                  S5      nUc  M  [#        UR$                  5      n[*        R,                  " [.        R0                  " X5      5      nU
R                  S	:X  a  [*        R,                  " X-
  5      nM  [*        R,                  " X-   5      nM     U R3                  US
5        g)z
Write to MusicXML from a Measure containing SpannerAnchors was not positioning
the current time offset correctly before starting the next written measure.
Now the next measure is positioned at the correct offset.
g      ?g      ?Nrw   	divisionsrS   *r   backupg      @)r   rn   rs   r   rE   r   rq   r   rp   rD   addSpannedElementsrB   rA   r<   iterr   r  intr   r   r   r   opFrac	fractionsFractionrH   )r/   m1r|   startAnchor	endAnchorrL   rK   r   measEldivisionsElr'  divisionsIntcurrOffsetQLdurdurIntdurQLs                   r%   5test_writeFromSpannerAnchorsGetsMeasureEndOffsetRight:Test.test_writeFromSpannerAnchorsGetsMeasureEndOffsetRight  s    ^^
		$))+
		$))+
		$))+
		$))+""$++-))+	
		#{#
		#y!  8
		%KKM	LLN	zz!} ))+Bvv" ++-Bvv,&( (   	V$[);++,..%B''*%CSXXi&8&8&NO66X%#)==1E#FL#)==1E#FL & 	s+r'   c                T   [         R                  " 5       nUR                  [        R                  " S5      5        UR                  [
        R                  " 5       5        UR                  S[        R                  " SS5      5        [         R                  " U/5      n[         R                  " U/5      nU R                  USS9nU R                  UR                  S5      5        U R                  [!        UR                  S5      S	   R"                  5      [$        R&                  5        g
)z
A metronome mark at an offset exceeding the bar duration was causing
<forward> tags, i.e. hidden rests. Prefer <offset> instead.
r   rm   slow(   Fr   r   z.//direction/offsetr   N)r   rn   rs   r   r   r   r  rD   r   rx  rB   rA   r<   r  r   rH   r  r   r   divisionsPerQuarter)r/   r   rL   rK   r   s        r%   -testOutOfBoundsExpressionDoesNotCreateForward2Test.testOutOfBoundsExpressionDoesNotCreateForward  s    
 NN	$$U+,		E''34KKLL!zz!%z0l3423A6;;<((	*r'   c           
        SSSS.SSS.SSS.SSS.SSS.S	SSS.4n[         R                  " [        R                  5      nU R	                  U5      nUR                  S
5      n[        UR                  S5      5       HO  u  pVU R                  US9   X    H*  nU R                  UR                  US5      X   U   5        M,     S S S 5        MQ     [        U5      nSSSS.SSS.SSS.SSS.SSS.SSS.S	SSS.4n	[         R                  " [        R                  5      nU R	                  U5      nUR                  S
5      n[        UR                  S5      5       HQ  u  pVU R                  X-   S9   X    H*  nU R                  UR                  US5      X   U   5        M,     S S S 5        MS     g ! , (       d  f       GMD  = f! , (       d  f       Mx  = f)NrQ  r  r   )r  liner   change)r  r  discontinueresumerR  rv   z.//pedal)pedal_indexrG  )r  signr   )r	   r-   r   
pedalLinesr<   r   ra  r   r_  rH   r   r   pedalSymLines)
r/   expectedResults1rK   r>  mxPartr5  mxPedalkstartIdxexpectedResults2s
             r%   
testPedalsTest.testPedals  s      !
 &
 !
 !
 -
8 OOM445JJqM#FNN:$>?JA!,),A$$W[[B%79I9LQ9OP - -, @
 '(   !
 !
 &
 !
 !
 5
B OOM778JJqM#FNN:$>?JA(,7),A$$W[[B%79I9LQ9OP - 87 @U -,V 87s   3F113G1
G	
G	c                >   Sn[         R                  " [        R                  5      nU R	                  U5      nUR                  S5      nUR                  S5      n[        UR                  S5      5       GH  u  pgU R                  US9   S nS n	UR                  S5      n
U
b"  U
R                  S5      nU
R                  S5      n	X   R                  S5      (       aa  U R                  U5        UR                  S	5      nS
 H.  nX   R                  U5      (       d  M  U R                  X5        M0      S S S 5        M  X   R                  S5      (       a  U R                  U	5        U	R                  S5      nX   S:X  a  U R                  U5         S S S 5        GM(  S H.  nX   R                  U5      (       d  M  U R                  X5        M0      S S S 5        GMh  U R                  U	5        U R                  U5        S S S 5        GM     g ! , (       d  f       GM  = f)N)
arpeggiater  r  arpeggiate upr  r  r  r  r  arpeggiate downr  r  r  r  r  znon-arpeggiate bottomrG  znon-arpeggiate topr  r  r  rv   rw   r   
note_index	notationsnon-arpeggiater  r  )topbottomr{  )updown)r	   r-   r   arpeggio32dr<   r   ra  r   r_  
startswithr  r   endswithrH   r   )r/   expectedResultsrK   r>  r  	mxMeasurer5  r   nonArparpr  
nonArpTypewhichEndarpDirectionr{  s                  r%   testArpeggiosTest.testArpeggiosR  s   
. OOM556JJqMKK	*	"9#4#4V#<=IA+"KK4	(&^^,<=F#..6C"%001ABB((0!'F!3J$5*-66x@@ ,,ZB %6  ,+ #%00>>((-#&77;#7L&)\9)),7 ' ,+( &4	*-66yAA ,,\E &4 / ,+0 !!#&!!&)3 ,+ >++s,   	BHH=AHH;H"H
H	c                   Sn[         R                  " [        R                  5      nU R	                  U5      nUR                  S5      nUR                  S5      n[        UR                  S5      5       Hn  u  pgU R                  US9   S nS n	UR                  S5      n
U
b  U
R                  S5      nUb  UR                  S5      n	U R                  XU   5        S S S 5        Mp     g ! , (       d  f       M  = f)	N)NNNr   r   r   NNNr   r   r   rv   rw   r   r  r  r  r   )r	   r-   r   multiStaffArpeggiosr<   r   ra  r   r_  r   rH   )r/   expectedNumberrK   r>  r  r  r  r   r  arpNumr  s              r%   testArpeggioMarkSpannersTest.testArpeggioMarkSpanners  s    
( OOM==>JJqMKK	*	"+I,=,=f,E"FJ4"KK4	(#..6C? WWX.F  
)CD 54 #G44s   AC''
C6	c                2   [         R                  " / SQ5      n[        R                  " S5      n[        R
                  " X/SS9n[        R                  " 5       nUR                  U5        [        R                  " U/5      n[        R                  " 5       nUR                  U5        [        R                  " U/5      n[        R                  " XW/5      n[        R                  " XXW/5      n	U R                  U	5      n
U
R                  S5      nUR                  S5      n[        UR!                  S5      5       H  u  pU R#                  US9   S nS	nUR                  S
5      nUbP  UR                  S5      nUS;   a  Ub  U R%                  SU< S35        US;   a  Uc  U R%                  SU< S35        OUS;   a  U R%                  SU< S35        Ub#  UR'                  S5      nU R)                  US5        S S S 5        M     g ! , (       d  f       M  = f)N)C3E3G3D4znon-arpeggio)arpeggioTyperv   rw   r   r  rX   r  r  )rR   rm   znote_index=z should not have non-arpeggiate)r   rT   z should have non-arpeggiatez should have notationsr   r   )r   Chordr   rE   r   ArpeggioMarkSpannerr   rn   rs   r   r   r   rA   r<   r   ra  r   r_  failr   rH   )r/   c1r   amr  r  m2r  slrK   r>  r  r  r  r   r  r  r  s                     r%   %testArpeggioMarkSpannersNonArpeggiate*Test.testArpeggioMarkSpannersNonArpeggiate  s   [[+,YYt_,,bXNS^^
		"rd#^^
		"rd#x(LL"")*JJqMKK	*	"+I,=,=f,E"FJ4"KK4	(#..)9:C!V+		[ZM1P"QR!V+		[ZM1L"MN6)II-CDE? WWX.F$$VS1 54 #G44s   B+H
H	c                  ^  SSU 4S jjjn[         R                  " S5      n[         R                  " S5      n[        R                  " 5       nUR	                  SU5        UR	                  SU5        U" USSS9  [
        R                  " S	S
9nUR	                  SU5        U" USSS9  UR                  U5        UR                  U5        U" USSS9  [
        R                  " SS
9nUR	                  SU5        U" USSS9  UR                  U5        UR	                  SU5        U" USSS9  SUl	        SUl
        SUl        U" USSS9  g )NFc                  > [         R                  " U 5      n [        R                  " U 5        [        R
                  " U /5      n[        R                  " U/5      nTR                  USS9nTR                  [        UR                  S5      5      U5        TR                  [        UR                  S5      5      U5        g )NFr   r   z	.//offset)copydeepcopyr   realizeChordSymbolDurationsr   rB   rA   r<   assertIsr`  r   )rz  
forwardTag	offsetTagrL   rK   r   r/   s         r%   realizeDurationsAndAssertTagsWTest.testExportChordSymbolsWithRealizedDurations.<locals>.realizeDurationsAndAssertTags  s    r"B//3RD!AaS!A::ae:4DMM$t||L9:JGMM$t||K899Er'   C7F7r   rm   T)r  r  halfr  r  )FF)rz  zstream.Measure)r   r   r   rn   rD   r   r  removerE   writeAsChordr   r@   )r/   r  cs1cs2r   r1r   s   `      r%   +testExportChordSymbolsWithRealizedDurations0Test.testExportChordSymbolsWithRealizedDurations  s'   	F 	F !!$'!!$'NN	C	C%aDEJ YYF#	B%aEUK 	
	%aDEJ YYG$	B%aETJ 	
	C%aEUK  	%aEUKr'   c                   [         R                  " 5       n[        R                  " SS9n[        R
                  " SSS5      nUR                  R                  U5        SUR                  l        [        R                  " SS5      Ul
        UR                  US5        UR                  US/5        UR                  US	5        UR                  S
[        R                  " S5      5        UR!                  SSSSS9  U R#                  U[        R$                     R'                  5       R                  S5        [)        5       nU R+                  UR-                  U5      5      nU R/                  [1        UR3                  S5      5      S5        g)zF
Express hidden rests with inexpressible durations as <forward> tags.
eighthr  r  rU   F   i  r  rW   r   z4/4T)r   fillGaps	hideReststimeRangeFromBarDurationg{Gzd?r   rR   N)r   rn   r   rE   r   TupletappendTupletlinkedr  r  r@   r   repeatInsertrD   r   r   	makeRests
assertLessr  r   r   r<   r7   rH   r   r   )r/   r   	septuplet
tuplet_objr1   r   s         r%   3test_inexpressible_hidden_rests_become_forward_tags8Test.test_inexpressible_hidden_rests_become_forward_tags  s)    NN II8,	__Q84
''
3$)	!"+"4"4S#">		y!$	y3%(	y!$	E''./	D44Z^_$))**,::FC#%zz#//23 	T\\,78!<r'   c                   SSK Jn  U" SS5      nSUR                  l        U" SS5      nSUR                  l        [        R
                  " 5       nUR                  SU5        UR                  SU5        U R                  UR                  5        [        5       R                  U5      R                  S	5      nU R                  S
U5        U R                  SU5        SUl        SUl        [        5       R                  U5      R                  S	5      nU R                  SU5        U R                  S
U5        U R                  SU5        U R                  SU5        U R                  SU5        SUR                  l        SUR                  l        [        5       R                  U5      R                  S	5      nU R                  SU5        U R                  S
U5        g )Nr   )RomanNumeralIrl   r  VrS   r  r,   z	<forward>z<chordFz<numeralz<offsetz<rest)music21.romanr   r   r  r   rn   rD   r,  r	  r   r-   r.   r   rt   r@   )r/   r   rn1rn2r   r~   s         r%   test_roman_musicxml_two_kinds"Test.test_roman_musicxml_two_kinds  s}   . 3$"3$"NN	c	c 	(()&(..q188Af-h'  &(..q188Aj&)k6*6*F+&)%("%("&(..q188Agv&f-r'   c                r   [         R                  " S5      nUR                  5       R                  R	                  5       n[
        R                  " 5       UR
                  l        SUR
                  R                  l        [        5       R                  U5      R                  S5      nU R                  SU5        g )NztinyNotation: 2/4 c2redr,   z<stem color="#FF0000">up</stem>)r	   r-   rZ   r[   r   r   Style	stemStylecolorr   r.   rt   )r/   one_note_tune	half_noter~   s       r%   !test_stem_style_without_direction&Test.test_stem_style_without_direction@  s    !(>?!))+11779	$)KKM	!*/	!!'&(..}=DDWM7@r'    N)T)*__name__
__module____qualname____firstlineno__r4   r<   rO   ri   r   r   r   r   r   r   r   r   r  r  r  r  r(  r/  r8  rA  rM  ro  r}  r  r  r  r  r  r  r  r  r  r  r  r  r&  r/  __static_attributes__r1  r'   r%   r)   r)   1   s    4<(B
J$
L6*$5L%;NB8$WLGA*69*V:M.<R
Q0@5D@*5;(:5&4,l*$NQ`7*r"EH#2L-L^=4 .DAr'   r)   c                      \ rS rSrSrS rSrg)TestExternaliI  Tc                
   [         R                  " S5      n[        U5      nUR                  5       n[        R                  " U5        [
        R                  " 5       nUR                  UR                  5       5        [        U5      nUR                  USSS9  UR                  5       nUR                  5         UR                  S5      nUR                  S5      nU R                  (       a  [        U5        [
        R                  " USS9 nUR!                  5       n	S S S 5        [#        [$        R&                  " UR)                  5       W	R)                  5       5      5      n
[+        U
5       Ho  u  pUR-                  S5      (       d.  UR-                  S5      (       d  UR-                  S	5      (       d  MI  S
U;   a  MQ  U R                  (       d  Md  [        U5        Mq     SS KnUR1                  U5        g ! , (       d  f       N= f)Ncpebachr,   F)encodingxml_declarationr   )r;  -?+zid=r   )r
   r-   r   r   r9   ioBytesIOrG   	xmlHeaderr   getvaluecloser.   showprintopenreadrY   difflibndiff
splitlinesra  r  osr  )r/   r   r:   r;   sior   vr   rb   r   differr5  lrL  s                 r%   
testSimpleTestExternal.testSimpleL  s^    LL# 1((*wjjl		",,.!!
w>LLN		HHW WWZ 99"IWWR'*aB +gmmALLNBMMODEf%DA||C  ALL$5$5c9J9JA:999!H & 	
		" +*s   G44
Hr1  N)r2  r3  r4  r5  rE  rQ  r6  r1  r'   r%   r8  r8  I  s    D,r'   r8  __main__)r$   rI   )0
__future__r   r  rI  r  r@  r"   unittestxml.etree.ElementTreer   r   r   music21r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   music21.musicxmlr   r   music21.musicxml.m21ToXmlr   r   r   r   music21.musicxml.xmlToM21r   r&   TestCaser)   r8  r2  mainTestr1  r'   r%   <module>r]     s    "    	 	  "                   $ *  4$UA8 UAp /8$$ /d zT r'   