U
    UcnS                     @   s&  d Z ddlZddlZddlZddlZddlZddlZddlZddlm	Z	 ddl
mZ eedddddh Zd	d
 eD ZdddddddZee edZdd Zdd Zdd Zd%ddZejZeedrejZneZG dd deZG dd  d eZG d!d" d"ej Z!G d#d$ d$ej"Z#dS )&zGA Python test reporter that generates test reports in JUnit XML format.    N)saxutils)_pretty_print_reporter    	   
      c                 C   s   i | ]}t |d |qS )z\x{:02x})chrformat).0i r   =/tmp/pip-unpacked-wheel-yg88_g5m/absl/testing/xml_reporter.py
<dictcomp>    s     r   z&quot;z&apos;z&#xA;z&#x9;z&#xD;z&#x20;)"'
	 z^(\w+) \((\S+)\)$c                 C   s   t | tS )zEscapes xml attributes.)r   escape_escape_xml_attr_conversions)contentr   r   r   _escape_xml_attr7   s    r   c                 C   s*   t  D ]\}}| ||} q| ddS )a  Escapes a string to be used as XML CDATA.

  CDATA characters are treated strictly as character data, not as XML markup,
  but there are still certain restrictions on them.

  Args:
    s: the string to be escaped.
  Returns:
    An escaped version of the input string.
  z]]>z]] >)_control_character_conversionsitemsreplace)scharescapedr   r   r   _escape_cdata=   s    r   c                 C   s,   | dks| dk rdS t j j| t jjd S )zProduces an ISO8601 datetime.

  Args:
    timestamp: an Epoch based timestamp in seconds.

  Returns:
    A iso8601 format timestamp if the input is a valid timestamp, None otherwise
  Nr   )tz)datetimefromtimestamptimezoneutc	isoformat)	timestampr   r   r   _iso8601_timestampM   s    	 r'    c                 C   sh   | d|| f  |D ]B}t|dkr|d dk	r|d dk	r| d|d |d f  q| d dS )a+  Prints an XML header of an arbitrary element.

  Args:
    element: element name (testsuites, testsuite, testcase)
    attributes: 2-tuple list with (attributes, values) already escaped
    stream: output stream to write test report XML to
    indentation: indentation added to the element header
  z%s<%s   r   N   z %s="%s"z>
)writelen)element
attributesstreamindentation	attributer   r   r   _print_xml_element_header\   s    	
r2   	_some_strc                   @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )_TestCaseResultaj  Private helper for _TextAndXMLTestResult that represents a test result.

  Attributes:
    test: A TestCase instance of an individual test method.
    name: The name of the individual test method.
    full_class_name: The full name of the test class.
    run_time: The duration (in seconds) it took to run the test.
    start_time: Epoch relative timestamp of when test started (in seconds)
    errors: A list of error 4-tuples. Error tuple entries are
        1) a string identifier of either "failure" or "error"
        2) an exception_type
        3) an exception_message
        4) a string version of a sys.exc_info()-style tuple of values
           ('error', err[0], err[1], self._exc_info_to_string(err))
           If the length of errors is 0, then the test is either passed or
           skipped.
    skip_reason: A string explaining why the test was skipped.
  c                 C   s   d| _ d| _d | _g | _|| _| p,t|}t|}|rR|	d}|	d}nt
j|j}t|t
jjr~t
j|jj}||d r|t|d d  }|}n,|dd}|d }t|dkr|d nd}t|| _t|| _d S )Nr*   r)   .r   r(   )run_time
start_timeskip_reasonerrorstestidstr&_CLASS_OR_MODULE_LEVEL_TEST_DESC_REGEXmatchgroupunittestutilZstrclass	__class__
isinstancecase_SubTest	test_case
startswithr,   rsplitr   namefull_class_name)selfr;   Z	test_descr?   rJ   rK   
class_namepartsr   r   r   __init__   s*    


z_TestCaseResult.__init__c                 C   s
   || _ d S N)r7   rL   Ztime_in_secsr   r   r   set_run_time   s    z_TestCaseResult.set_run_timec                 C   s
   || _ d S rP   r8   rQ   r   r   r   set_start_time   s    z_TestCaseResult.set_start_timec                 C   s   | j dkrd}d}nd}d}dd| j fdd| fd	d| fd
d| j fd| jfdt| jfg}td||d | | |d dS )aQ  Prints an XML Summary of a TestCase.

    Status and result are populated as per JUnit XML test result reporter.
    A test that has been skipped will always have a skip reason,
    as every skip method in Python's unittest requires the reason arg to be
    passed.

    Args:
      stream: output stream to write test report XML to
    NrunZ	completedZnotrunZ
suppressedrJ   %sstatusresulttime%.3f	classnamer&   Ztestcasez  z  </testcase>
)	r9   rJ   r7   rK   r'   r8   r2   _print_testcase_detailsr+   )rL   r/   rW   rX   Ztest_case_attributesr   r   r   print_xml_summary   s    



z!_TestCaseResult.print_xml_summaryc              	   C   sT   | j D ]H}|\}}}}tt|}tt|}t|}|d|||||f  qd S )Nz1  <%s message="%s" type="%s"><![CDATA[%s]]></%s>
)r:   r   	_safe_strr=   r   r+   )rL   r/   errorZoutcomeZexception_typemessage	error_msgr   r   r   r\      s    
z'_TestCaseResult._print_testcase_detailsN)	__name__
__module____qualname____doc__rO   rR   rT   r]   r\   r   r   r   r   r4   w   s   %r4   c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )_TestSuiteResultz)Private helper for _TextAndXMLTestResult.c                 C   s(   i | _ i | _i | _d| _d| _i | _d S )Nr5   )suitesfailure_countserror_countsoverall_start_timeoverall_end_time_testsuites_propertiesrL   r   r   r   rO      s    z_TestSuiteResult.__init__c                 C   s   t |jj}|dkr$|jdd }t|jtjjrBt |jj	j}| 
| | j| | |jD ]J}|d dkr| j|  d7  <  qqb|d dkrb| j|  d7  <  qqbd S )NZ_ErrorHolderr6   r5   r   failurer*   r_   )typer;   rb   rK   rI   rD   rA   rE   rF   rG   _setup_test_suiterg   appendr:   rh   ri   )rL   test_case_result
suite_namer_   r   r   r   add_test_case_result   s    

z%_TestSuiteResult.add_test_case_resultc              	   C   s  t dd | j D }t | j }t | j }ddd| fdd| fdd| fdd	| j| j  fd
t| jfg}td|| | j	r|
d t| j	 D ]&\}}|
dt|tt|f  q|
d | jD ]}| j| }	tdd |	D }
tdd |	D }| j| }| j| }dd| fddt|	 fdd| fdd| fdd	|
|  fd
t|fg}td|| |	D ]}|| qv|
d q|
d d S )Nc                 s   s   | ]}t |V  qd S rP   )r,   r
   xr   r   r   	<genexpr>  s     z5_TestSuiteResult.print_xml_summary.<locals>.<genexpr>)rJ   r(   testsz%dfailuresr:   rY   rZ   r&   Z
testsuitesz    <properties>
z1      <property name="%s" value="%s"></property>
z    </properties>
c                 s   s   | ]}|j |j V  qd S rP   )r8   r7   ru   r   r   r   rw     s     c                 s   s   | ]}|j V  qd S rP   rS   ru   r   r   r   rw     s     rJ   rV   Z	testsuitez</testsuite>
z</testsuites>
)sumrg   valuesrh   ri   rk   rj   r'   r2   rl   r+   sortedr   r   r=   maxminr,   r]   )rL   r/   Zoverall_test_countZoverall_failuresZoverall_errorsZoverall_attributesrJ   valuers   suiteZsuite_end_timeZsuite_start_timery   r:   Zsuite_attributesrr   r   r   r   r]     sH    












z"_TestSuiteResult.print_xml_summaryc                 C   s0   || j krdS g | j |< d| j|< d| j|< dS )zAdds a test suite to the set of suites tracked by this test run.

    Args:
      suite_name: string, The name of the test suite being initialized.
    Nr   )rg   rh   ri   )rL   rs   r   r   r   rp   *  s
    


z"_TestSuiteResult._setup_test_suitec                 C   s
   || _ dS )zvSets the start timestamp of this test suite.

    Args:
      timestamp_in_secs: timestamp in seconds since epoch
    N)rk   rL   Ztimestamp_in_secsr   r   r   set_end_time6  s    z_TestSuiteResult.set_end_timec                 C   s
   || _ dS )ztSets the end timestamp of this test suite.

    Args:
      timestamp_in_secs: timestamp in seconds since epoch
    N)rj   r   r   r   r   rT   >  s    z_TestSuiteResult.set_start_timeN)
rb   rc   rd   re   rO   rt   r]   rp   r   rT   r   r   r   r   rf      s   )rf   c                       s   e Zd ZdZeZeZedf fdd	Z	 fddZ
 fddZ fd	d
Zdd Zd% fdd	Zd&ddZdd Zdd Z fddZ fddZ fddZ fddZ fddZ fdd Z fd!d"Z fd#d$Z  ZS )'_TextAndXMLTestResultzoPrivate TestResult class that produces both formatted text results and XML.

  Used by TextAndXMLTestRunner.
  Nc                    sJ   t t| ||| || _i | _|  | _|r6|| j_|| _t	
 | _d S rP   )superr   rO   
xml_streampending_test_case_results_TEST_SUITE_RESULT_CLASSr   rl   time_getter	threadingRLock_pending_test_case_results_lock)rL   r   r/   descriptions	verbosityr   testsuites_propertiesrC   r   r   rO   P  s    
z_TextAndXMLTestResult.__init__c                    s   |   | _tt| | d S rP   )r   r8   r   r   	startTestrL   r;   r   r   r   r   ]  s    
z_TextAndXMLTestResult.startTestc              	      s   | j  tt| | | |}|sT| p4t|}tj	d|  W 5 Q R  d S t|}| 
 | j }|| || j | j| | j|= W 5 Q R X d S )NzNo pending test case: %s
)r   r   r   stopTestget_pending_test_case_resultr<   r=   sysstderrr+   r   r8   rR   rT   r   rt   r   )rL   r;   rX   	test_nametest_idr7   r   r   r   r   a  s    

z_TextAndXMLTestResult.stopTestc                    s"   | j |   tt|   d S rP   )r   rT   r   r   r   startTestRunrm   r   r   r   r   q  s    z"_TextAndXMLTestResult.startTestRunc              	   C   s   | j |   | j` | jD ]H}| j| }t| drZ| j j| j }|| |	| j | j 
| q| j  W 5 Q R X d S )Nr8   )r   r   r   r   r   hasattrrk   r8   rR   rT   rt   clear)rL   r   rX   r7   r   r   r   stopTestRunu  s    



z!_TextAndXMLTestResult.stopTestRunc                    s&   |rt t| ||S dtj| S )aW  Converts a sys.exc_info()-style tuple of values into a string.

    This method must be overridden because the method signature in
    unittest.TestResult changed between Python 2.2 and 2.4.

    Args:
      err: A sys.exc_info() tuple of values for an error.
      test: The test method.

    Returns:
      A formatted exception string.
    r(   )r   r   _exc_info_to_stringjoin	tracebackformat_exception)rL   errr;   r   r   r   r     s    z)_TextAndXMLTestResult._exc_info_to_stringc              	   C   s^   | j N t|}|| jkr*| || j|< |r@| j| j| |rP|| j| _W 5 Q R X dS )a  Adds result information to a test case result which may still be running.

    If a result entry for the test already exists, add_pending_test_case_result
    will add error summary tuples and/or overwrite skip_reason for the result.
    If it does not yet exist, a result entry will be created.
    Note that a test result is considered to have been run and passed
    only if there are no errors or skip_reason.

    Args:
      test: A test method as defined by unittest
      error_summary: A 4-tuple with the following entries:
          1) a string identifier of either "failure" or "error"
          2) an exception_type
          3) an exception_message
          4) a string version of a sys.exc_info()-style tuple of values
             ('error', err[0], err[1], self._exc_info_to_string(err))
             If the length of errors is 0, then the test is either passed or
             skipped.
      skip_reason: a string explaining why the test was skipped
    N)r   r<   r   _TEST_CASE_RESULT_CLASSr:   rq   r9   )rL   r;   error_summaryr9   r   r   r   r   add_pending_test_case_result  s    

z2_TextAndXMLTestResult.add_pending_test_case_resultc              	   C   s&   | j  t|}| j|= W 5 Q R X d S rP   )r   r<   r   rL   r;   r   r   r   r   delete_pending_test_case_result  s    z5_TextAndXMLTestResult.delete_pending_test_case_resultc                 C   s   t |}| j|d S rP   )r<   r   getr   r   r   r   r     s    z2_TextAndXMLTestResult.get_pending_test_case_resultc                    s   t t| | | | d S rP   )r   r   
addSuccessr   r   r   r   r   r     s    z _TextAndXMLTestResult.addSuccessc                    sB   t t| || d|d |d | j||df}| j||d d S )Nr_   r   r*   r;   r   )r   r   addErrorr   r   rL   r;   r   r   r   r   r   r     s
    z_TextAndXMLTestResult.addErrorc                    sB   t t| || d|d |d | j||df}| j||d d S )Nrn   r   r*   r   r   )r   r   
addFailurer   r   r   r   r   r   r     s
    z _TextAndXMLTestResult.addFailurec                    s$   t t| || | j||d d S )N)r9   )r   r   addSkipr   )rL   r;   reasonr   r   r   r     s    z_TextAndXMLTestResult.addSkipc                    sF   t t| || tt|dd r8|d| j||d | | d S )NrecordPropertyZEXPECTED_FAILUREr   )r   r   addExpectedFailurecallablegetattrr   r   r   )rL   r;   r   r   r   r   r     s    z(_TextAndXMLTestResult.addExpectedFailurec                    sB   t t| | | pt|}dddd| f}| j||d d S )Nr_   r(   z,Test case %s should have failed, but passed.r   )r   r   addUnexpectedSuccessr<   r=   r   )rL   r;   r   r   r   r   r   r     s    z*_TextAndXMLTestResult.addUnexpectedSuccessc                    s   t t| ||| |d k	rlt|d |jrLd|d |d | j||df}qpd|d |d | j||df}nd }| j||d d S )Nr   rn   r*   r   r_   r   )r   r   
addSubTest
issubclassZfailureExceptionr   r   )rL   r;   Zsubtestr   r   r   r   r   r     s    z _TextAndXMLTestResult.addSubTestc                    s,   t t|   | jd | j| j d S )Nz<?xml version="1.0"?>
)r   r   printErrorsr   r+   r   r]   rm   r   r   r   r     s    z!_TextAndXMLTestResult.printErrors)N)NN)rb   rc   rd   re   rf   r   r4   r   
_time_copyrO   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   r   r   r   G  s0      
 r   c                       sR   e Zd ZdZeZdZi Zd fdd	Ze	dd Z
 fddZe	d	d
 Z  ZS )TextAndXMLTestRunnerzA test runner that produces both formatted text results and XML.

  It prints out the names of tests as they are run, errors as they
  occur, and a summary of the results at the end of the test run.
  Nc                    s$   t t| j|| |dk	r || _dS )a  Initialize a TextAndXMLTestRunner.

    Args:
      xml_stream: file-like or None; XML-formatted test results are output
          via this object's write() method.  If None (the default), the
          new instance behaves as described in the set_default_xml_stream method
          documentation below.
      *args: passed unmodified to unittest.TextTestRunner.__init__.
      **kwargs: passed unmodified to unittest.TextTestRunner.__init__.
    N)r   r   rO   _xml_stream)rL   r   argskwargsr   r   r   rO     s    zTextAndXMLTestRunner.__init__c                 C   s
   || _ dS )a  Sets the default XML stream for the class.

    Args:
      xml_stream: file-like or None; used for instances when xml_stream is None
          or not passed to their constructors.  If None is passed, instances
          created with xml_stream=None will act as ordinary TextTestRunner
          instances; this is the default state before any calls to this method
          have been made.
    N)r   )clsr   r   r   r   set_default_xml_stream  s    z+TextAndXMLTestRunner.set_default_xml_streamc                    s:   | j d krtt|  S | j| j | j| j| j| jdS d S )N)r   )	r   r   r   _makeResult_TEST_RESULT_CLASSr/   r   r   rl   rm   r   r   r   r   $  s    
   z TextAndXMLTestRunner._makeResultc                 C   s   || j |< d S rP   )rl   )r   keyr   r   r   r   set_testsuites_property,  s    z,TextAndXMLTestRunner.set_testsuites_property)N)rb   rc   rd   re   r   r   r   rl   rO   classmethodr   r   r   r   r   r   r   r   r     s   
r   )r(   )$re   r!   rer   r   rY   r   rA   Zxml.saxr   Zabsl.testingr   setrangeZ_bad_control_character_codesr   r   updatecompiler>   r   r   r'   r2   r   r   r3   r^   r=   objectr4   rf   ZTextTestResultr   ZTextTestRunnerr   r   r   r   r   <module>   sF   



hh 4