a
    ijS                     @   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mZm	Z	 ddl
Z
ddlmZ ddlmZ eeddh d 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ddZG dd dZG d d! d!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)AnyDict)saxutils)_pretty_print_reporter    >   	   
      c                 C   s   i | ]}t |d |dqS )z\x02x)chr).0i r   W/home/ghrups/robot-bench/.venv/lib/python3.9/site-packages/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_attr9   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u 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_timestampO   s
    	r)    c                 C   sh   | d|| f  |D ]B}t|dkr|d dur|d du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    	
r4   )objreturnc                 C   s:   z
t | W S  ty4   dt| jt| jf  Y S 0 dS )z-Returns a string representation of an object.z<unprintable %s.%s object>N)str	Exceptiontype
__module____name__)r5   r   r   r   	_safe_strs   s    
r<   c                   @   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idr7   &_CLASS_OR_MODULE_LEVEL_TEST_DESC_REGEXmatchgroupunittestutilZstrclass	__class__
isinstancecase_SubTest	test_case
startswithr.   rsplitr   namefull_class_name)selfrD   Z	test_descrG   rR   rS   
class_namepartsr   r   r   __init__   s*    


z_TestCaseResult.__init__c                 C   s
   || _ d S N)r@   rT   Ztime_in_secsr   r   r   set_run_time   s    z_TestCaseResult.set_run_timec                 C   s
   || _ d S rX   rA   rY   r   r   r   set_start_time   s    z_TestCaseResult.set_start_timec                 C   s   | j du 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run	completedZnotrun
suppressedrR   %sstatusresulttime%.3f	classnamer(   Ztestcasez  z  </testcase>
)	rB   rR   r@   rS   r)   rA   r4   _print_testcase_detailsr-   )rT   r1   ra   rb   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>
)rC   r   r<   r7   r!   r-   )rT   r1   erroroutcomeZexception_typemessage	error_msgr   r   r   rf      s    
z'_TestCaseResult._print_testcase_detailsN)	r;   r:   __qualname____doc__rW   rZ   r\   rg   rf   r   r   r   r   r=   ~   s   %r=   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 )Nr>   )suitesfailure_countserror_countsoverall_start_timeoverall_end_time_testsuites_propertiesrT   r   r   r   rW      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_ErrorHolderr?   r>   r   failurer,   rh   )r9   rD   r;   rS   rQ   rL   rI   rM   rN   rO   _setup_test_suitero   appendrC   rp   rq   )rT   test_case_result
suite_namerh   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|| t|	dd dD ]}|| q|
d q|
d d S )Nc                 s   s   | ]}t |V  qd S rX   )r.   r   xr   r   r   	<genexpr>	      z5_TestSuiteResult.print_xml_summary.<locals>.<genexpr>)rR   r*   Ztestsz%dfailuresrC   rc   rd   r(   Z
testsuitesz    <properties>
z1      <property name="%s" value="%s"></property>
z    </properties>
c                 s   s   | ]}|j |j V  qd S rX   )rA   r@   r|   r   r   r   r~     r   c                 s   s   | ]}|j V  qd S rX   r[   r|   r   r   r   r~     r   rR   r`   Z	testsuitec                 S   s   | j S rX   )rR   )tr   r   r   <lambda>.  r   z4_TestSuiteResult.print_xml_summary.<locals>.<lambda>)keyz</testsuite>
z</testsuites>
)sumro   valuesrp   rq   rs   rr   r)   r4   rt   r-   sortedr   r   r7   maxminr.   rg   )rT   r1   Zoverall_test_countZoverall_failuresZoverall_errorsZoverall_attributesrR   valuerz   suiteZsuite_end_timeZsuite_start_timer   rC   Zsuite_attributesry   r   r   r   rg     sH    












z"_TestSuiteResult.print_xml_summaryc                 C   s0   || j v 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   )ro   rp   rq   )rT   rz   r   r   r   rw   3  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)rs   rT   Ztimestamp_in_secsr   r   r   set_end_time?  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)rr   r   r   r   r   r\   G  s    z_TestSuiteResult.set_start_timeN)
r;   r:   rl   rm   rW   r{   rg   rw   r   r\   r   r   r   r   rn      s   +rn   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                    sF   t  ||| || _i | _|  | _|r2|| j_|| _t	 | _
d S rX   )superrW   
xml_streampending_test_case_results_TEST_SUITE_RESULT_CLASSr   rt   time_getter	threadingRLock_pending_test_case_results_lock)rT   r   r1   descriptions	verbosityr   testsuites_propertiesrK   r   r   rW   Y  s    
z_TextAndXMLTestResult.__init__c                    s   |   | _t | d S rX   )r   rA   r   	startTestrT   rD   r   r   r   r   f  s    
z_TextAndXMLTestResult.startTestc                    s   | j  t | | |}|sR| p0t|}tjd|  W d    d S t	| dd d u rl| 
 | _t|}| 
 | j }|| || j | j| | j|= W d    n1 s0    Y  d S )NzNo pending test case: %s
rA   )r   r   stopTestget_pending_test_case_resultrE   r7   sysstderrr-   getattrr   rA   rZ   r\   r   r{   r   )rT   rD   rb   	test_nametest_idr@   r   r   r   r   j  s    


z_TextAndXMLTestResult.stopTestc                    s   | j |   t   d S rX   )r   r\   r   r   startTestRunru   r   r   r   r   }  s    z"_TextAndXMLTestResult.startTestRunc                 C   s   | j |   | jp | jD ]N}| j| }t| dd d ur`| j j| j }|| |	| j | j 
| q| j  W d    n1 s0    Y  d S )NrA   )r   r   r   r   r   r   rs   rA   rZ   r\   r{   clear)rT   r   rb   r@   r   r   r   stopTestRun  s    


z!_TextAndXMLTestResult.stopTestRunc                    s"   |r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   _exc_info_to_stringjoin	tracebackformat_exception)rT   errrD   r   r   r   r     s    z)_TextAndXMLTestResult._exc_info_to_stringc                 C   sr   | j X t|}|| jvr*| || j|< |r@| j| j| |rP|| j| _W d   n1 sd0    Y  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   rE   r   _TEST_CASE_RESULT_CLASSrC   rx   rB   )rT   rD   error_summaryrB   r   r   r   r   add_pending_test_case_result  s    

z2_TextAndXMLTestResult.add_pending_test_case_resultc                 C   s:   | j   t|}| j|= W d    n1 s,0    Y  d S rX   )r   rE   r   rT   rD   r   r   r   r   delete_pending_test_case_result  s    z5_TextAndXMLTestResult.delete_pending_test_case_resultc                 C   s   t |}| j|d S rX   )rE   r   getr   r   r   r   r     s    z2_TextAndXMLTestResult.get_pending_test_case_resultc                    s   t  | | | d S rX   )r   
addSuccessr   r   r   r   r   r     s    z _TextAndXMLTestResult.addSuccessc                    s>   t  || d|d |d | j||df}| j||d d S )Nrh   r   r,   rD   r   )r   addErrorr   r   rT   rD   r   r   r   r   r   r     s
    z_TextAndXMLTestResult.addErrorc                    s>   t  || d|d |d | j||df}| j||d d S )Nrv   r   r,   r   r   )r   
addFailurer   r   r   r   r   r   r     s
    z _TextAndXMLTestResult.addFailurec                    s    t  || | j||d d S )N)rB   )r   addSkipr   )rT   rD   reasonr   r   r   r     s    z_TextAndXMLTestResult.addSkipc                    sB   t  || tt|dd r4|d| j||d | | d S )NrecordPropertyZEXPECTED_FAILUREr   )r   addExpectedFailurecallabler   r   r   r   )rT   rD   r   r   r   r   r     s    z(_TextAndXMLTestResult.addExpectedFailurec                    s>   t  | | pt|}dddd| f}| j||d d S )Nrh   r*   z,Test case %s should have failed, but passed.r   )r   addUnexpectedSuccessrE   r7   r   )rT   rD   r   r   r   r   r   r     s    z*_TextAndXMLTestResult.addUnexpectedSuccessc                    s~   t  ||| |d urht|d |jrHd|d |d | j||df}qld|d |d | j||df}nd }| j||d d S )Nr   rv   r,   r   rh   r   )r   
addSubTest
issubclassZfailureExceptionr   r   )rT   rD   Zsubtestr   r   r   r   r   r     s    z _TextAndXMLTestResult.addSubTestc                    s(   t    | jd | j| j d S )Nz<?xml version="1.0"?>
)r   printErrorsr   r-   r   rg   ru   r   r   r   r      s    
z!_TextAndXMLTestResult.printErrors)N)NN)r;   r:   rl   rm   rn   r   r=   r   
_time_copyrW   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   r   r   r   P  s.     
 r   c                       sd   e Zd ZU dZeZdZi Zee	e	f e
d< 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.
  Nrt   c                    s$   t  j|i | |du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   rW   _xml_stream)rT   r   argskwargsr   r   r   rW     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                    s6   | j d u rt  S | j| j | j| j| j| jdS d S )N)r   )r   r   _makeResult_TEST_RESULT_CLASSr1   r   r   rt   ru   r   r   r   r   0  s    

z TextAndXMLTestRunner._makeResultc                 C   s   || j |< d S rX   )rt   )r   r   r   r   r   r   set_testsuites_property8  s    z,TextAndXMLTestRunner.set_testsuites_property)N)r;   r:   rl   rm   r   r   r   rt   r   r   __annotations__rW   classmethodr   r   r   r   r   r   r   r   r     s   

r   )r*   )%rm   r#   rer   r   rc   r   typingr   r   rI   Zxml.saxr   Zabsl.testingr   setrangeZ_bad_control_character_codesr   r   updatecompilerF   r   r!   r)   r4   r   objectr7   r<   r=   rn   ZTextTestResultr   ZTextTestRunnerr   r   r   r   r   <module>   sD   


hj 7