
    h                     8   S r SSKJr  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
Jr  SSKJr  SSKJr  SSKJr  S	 rS
 r " S S5      r " S S\5      rSS jrS S jr     S!S\S\S\S\S\S\S\4S jjr " S S\5      r " S S\5      r " S S\5      rg)"zHelpers for writing unit tests.    )Iterable)BytesION)TestCase)Configtobytes)	XMLWriterc                    [        5       nSn[        U [        5      (       a  X -  nOw[        U [        5      (       a  U[	        U S5      -  nOR[        U [
        5      (       a  USR                  S U  5       5      -  nO![        S[        U 5      R                  -  5      eUS-  nUR                  R                  US5        UR                  S   $ )	a)  Parses a snippet of XML.

Input can be either a single string (unicode or UTF-8 bytes), or a
a sequence of strings.

The result is in the same format that would be returned by
XMLReader, but the parser imposes no constraints on the root
element so it can be called on small snippets of TTX files.
s   <root>utf-8    c              3   :   #    U  H  n[        US 5      v   M     g7f)r   Nr   ).0ss     J/var/www/html/env/lib/python3.13/site-packages/fontTools/misc/testTools.py	<genexpr>parseXML.<locals>.<genexpr>"   s     @Z7++Zs   z0expected string or sequence of strings; found %rs   </root>      )TestXMLReader_
isinstancebytesstrr   r   join	TypeErrortype__name__parserParseroot)
xmlSnippetreaderxmls      r   parseXMLr#      s     F
C*e$$	J	$	$wz7++	J	)	)sxx@Z@@@>:''(
 	
 :C
MMQ;;q>r   c                    [        UR                  5       5       Vs/ s H  n[        U[        5      (       a  M  UPM     nnU H  u  pVnUR	                  XVXp5        M     [        US5      (       a  UR                  5         U$ s  snf )NpopulateDefaults)r#   stripr   r   fromXMLhasattrr%   )font	parseIntor    e
parsed_xmlnameattrscontents           r   parseXmlIntor0   -   st    %j&6&6&89T9AsAS!9JT *W$w5 !+y,--""$ Us
   BBc                   `    \ rS rSrS 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g)FakeFont6   c                     Xl         [        U5       VVs0 s H  u  p#X2_M	     snnU l        SU l        0 U l        [        5       U l        g s  snnf )NF)glyphOrder_	enumeratereverseGlyphOrderDict_lazytablesr   cfg)selfglyphsigs       r   __init__FakeFont.__init__7   sG    !8A&8I&J8Iqt8I&J#	8 'Ks   A
c                     XR                   ;   $ Nr9   r;   tags     r   __contains__FakeFont.__contains__>   s    kk!!r   c                      U R                   U   $ rB   rC   rD   s     r   __getitem__FakeFont.__getitem__A   s    {{3r   c                      X R                   U'   g rB   rC   )r;   rE   tables      r   __setitem__FakeFont.__setitem__D   s     Cr   Nc                 8    U R                   R                  X5      $ rB   )r9   get)r;   rE   defaults      r   rP   FakeFont.getG   s    {{s,,r   c                      U R                   U   $ rB   r7   r;   r-   s     r   
getGlyphIDFakeFont.getGlyphIDJ   s    **400r   c                 N    U Vs/ s H  o R                  U5      PM     sn$ s  snf rB   )rV   r;   lstgids      r   getGlyphIDManyFakeFont.getGlyphIDManyM   s!    034$444   "c                 \    U[        U R                  5      :  a  U R                  U   $ SU-  $ )Nz	glyph%.5d)lenr5   )r;   glyphIDs     r   getGlyphNameFakeFont.getGlyphNameP   s1    S))**##G,,((r   c                 N    U Vs/ s H  o R                  U5      PM     sn$ s  snf rB   )rb   rY   s      r   getGlyphNameManyFakeFont.getGlyphNameManyV   s#    256#3!!#&#666r^   c                     U R                   $ rB   )r5   r;   s    r   getGlyphOrderFakeFont.getGlyphOrderY       r   c                     U R                   $ rB   rT   rh   s    r   getReverseGlyphMapFakeFont.getReverseGlyphMap\   s    ***r   c                 4    [        U R                  5       5      $ rB   )sortedri   rh   s    r   getGlyphNamesFakeFont.getGlyphNames_   s    d((*++r   )r:   r5   r8   r7   r9   rB   )r   
__module____qualname____firstlineno__r?   rF   rI   rM   rP   rV   r\   rb   re   ri   rm   rq   __static_attributes__ r   r   r2   r2   6   s>    " !-15)7 +,r   r2   c                   ,    \ rS rSrS rS rS rS rSrg)r   c   c                     SSK Jn  U" 5       U l        U R                  U R                  l        U R
                  U R                  l        U R                  U R                  l        S U l	        / U l
        g )Nr   )ParserCreate)xml.parsers.expatr{   r   startElement_StartElementHandlerendElement_EndElementHandleraddCharacterData_CharacterDataHandlerr   stack)r;   r{   s     r   r?   TestXMLReader_.__init__d   sR    2"n*.*<*<'(,(8(8%+/+A+A(	
r   c                     X/ 4nU R                   (       a"  U R                   S   S   R                  U5        OX0l        U R                   R                  U5        g Nr   )r   appendr   )r;   r-   r.   elements       r   r}   TestXMLReader_.startElement_n   sE    #::JJrN1$$W-I

'"r   c                 8    U R                   R                  5         g rB   )r   poprU   s     r   r   TestXMLReader_.endElement_v   s    

r   c                 F    U R                   S   S   R                  U5        g r   )r   r   )r;   datas     r   r    TestXMLReader_.addCharacterData_y   s    

2q  &r   )r   r   r   N)	r   rs   rt   ru   r?   r}   r   r   rv   rw   r   r   r   r   c   s    #'r   r   c                     [        [        5       U S9nUR                  R                  S5        UR                  R	                  5         U$ )N)
newlinestrr   )r	   r   fileseektruncate)r   writers     r   makeXMLWriterr   }   s7    wyZ8F
KKQ
KKMr   c                     [        5       nU " X!5        UR                  R                  5       R                  S5      nUR	                  S5      (       d   eUR                  5       $ )zCall the passed toXML function and return the written content as a
list of lines (unicode strings).
Result is stripped of XML declaration and OS-specific newline characters.
r   
)r   r   getvaluedecodeendswith
splitlines)functtFontr   r"   s       r   getXMLr      sR    
 _F
++


 
'
'
0C<<>>r   stringttLibVersioncheckSumAdjustmentmodifiedcreatedsfntVersionreturnc                 <   U(       a  [         R                  " SSU 5      n U(       a  [         R                  " SSU 5      n U(       a  [         R                  " SSU 5      n U(       a  [         R                  " SSU 5      n U(       a  [         R                  " SSU 5      n U $ )zJStrip stuff like ttLibVersion, checksums, timestamps, etc. from TTX dumps.z ttLibVersion="[^"]+" z sfntVersion="[^"]+"z#<checkSumAdjustment value="[^"]+"/>z<modified value="[^"]+"/>z<created value="[^"]+"/>)resub)r   r   r   r   r   r   s         r   stripVariableItemsFromTTXr      sw     /V<.F;=r6J3R@2B?Mr   c                   6    \ rS rSrSrS rS rS rS rS r	Sr
g	)
MockFont   zUA font-like object that automatically adds any looked up glyphname
to its glyphOrder.c                 f   ^  S/T l          " U 4S jS[        5      nU" SS05      T l        ST l        g )Nz.notdefc                   "   > \ rS rSrU 4S jrSrg))MockFont.__init__.<locals>.AllocatingDict   c                 \   > TR                   R                  U5        [        U 5      nX U'   U$ rB   )_glyphOrderr   r`   )reverseDictkeyr[   r;   s      r   __missing__5MockFont.__init__.<locals>.AllocatingDict.__missing__   s.      '',+&#&C 
r   rw   N)r   rs   rt   ru   r   rv   rh   s   r   AllocatingDictr      s     r   r   r   F)r   dict_reverseGlyphOrderr8   )r;   r   s   ` r   r?   MockFont.__init__   s3    %;	T 	 #1)Q"@	r   c                 $    U R                   U   nU$ rB   r   )r;   glyphr[   s      r   rV   MockFont.getGlyphID   s    %%e,
r   c                     U R                   $ rB   r   rh   s    r   rm   MockFont.getReverseGlyphMap   s    &&&r   c                      U R                   U   $ rB   r   )r;   r[   s     r   rb   MockFont.getGlyphName   s    $$r   c                     U R                   $ rB   r   rh   s    r   ri   MockFont.getGlyphOrder   rk   r   )r   r   r8   N)r   rs   rt   ru   __doc__r?   rV   rm   rb   ri   rv   rw   r   r   r   r      s     '% r   r   c                       \ rS rSrS rSrg)r      c                 v    [         R                  " X5        [        U S5      (       d  U R                  U l        g g )NassertRaisesRegex)	_TestCaser?   r(   assertRaisesRegexpr   )r;   
methodNames     r   r?   TestCase.__init__   s3    4, t011%)%<%<D" 2r   )r   N)r   rs   rt   ru   r?   rv   rw   r   r   r   r      s    =r   r   c                   2    \ rS rSrS rS rS rS rS rSr	g)	DataFilesHandler   c                      S U l         SU l        g )Nr   )tempdirnum_tempfilesrh   s    r   setUpDataFilesHandler.setUp   s    r   c                 h    U R                   (       a!  [        R                  " U R                   5        g g rB   )r   shutilrmtreerh   s    r   tearDownDataFilesHandler.tearDown   s    <<MM$,,' r   c                     [         R                  R                  [        R                  U R
                     R                  5      n[         R                  R                  USU5      $ )Nr   )ospathdirnamesysmodulesrs   __file__r   )r;   testfilefolders      r   getpathDataFilesHandler.getpath   s>    T__!=!F!FGww||FFH55r   c                 \    U R                   (       d  [        R                  " 5       U l         g g rB   )r   tempfilemkdtemprh   s    r   temp_dirDataFilesHandler.temp_dir   s    ||#++-DL r   c                     U R                  5         [        R                  R                  U R                  U5      n[
        R                  " X5        U$ rB   )r   r   r   r   r   r   copy2)r;   	font_path	file_nametemppaths       r   	temp_fontDataFilesHandler.temp_font   s4    77<<i8Y)r   )r   r   N)
r   rs   rt   ru   r   r   r   r   r   rv   rw   r   r   r   r      s    (6.r   r   )r   rB   )TTTTF)r   collections.abcr   ior   r   r   r   r   r   unittestr   r   fontTools.configr   fontTools.misc.textToolsr   fontTools.misc.xmlWriterr	   r#   r0   r2   objectr   r   r   r   boolr   r   r   rw   r   r   <module>r      s    % $  	 	  
  * # , .:*, *,Z'V '4
 #  	
   	2 v  >=y =x r   