a
    ñ»j"+  ã                   @   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mZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZmZ e d	¡Ze d
¡Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZG dd„ deƒZG dd„ deƒZdS )aO  This plugin provides test results in the standard XUnit XML format.
It's designed for the `Jenkins`_ (previously Hudson) continuous build
system, but will probably work for anything else that understands an
XUnit-formatted XML representation of test results.

Add this shell command to your builder:

    nosetests --with-xunit

And by default a file named nosetests.xml will be written to the
working directory.

In a Jenkins builder, tick the box named "Publish JUnit test result report"
under the Post-build Actions and enter this value for Test report XMLs:

    **/nosetests.xml

If you need to change the name or location of the file, you can set the
``--xunit-file`` option.

If you need to change the name of the test suite, you can set the
``--xunit-testsuite-name`` option.

Here is an abbreviated version of what an XML test report might look like:

    <?xml version="1.0" encoding="UTF-8"?>
    <testsuite name="nosetests" tests="1" errors="1" failures="0" skip="0">
        <testcase classname="path_to_test_suite.TestSomething"
                  name="test_it" time="0">
            <error type="exceptions.TypeError" message="oops, wrong type">
            Traceback (most recent call last):
            ...
            TypeError: oops, wrong type
            </error>
        </testcase>
    </testsuite>

.. _Jenkins: http://jenkins-ci.org/
é    N)ÚStringIO)Útime)Úsaxutils)ÚPlugin)ÚSkipTest)Úforce_unicodeÚformat_exceptionz[\000-\010\013\014\016-\037]z^(.*?)(\(.*\))$c                 C   s   t  d| ¡S )z)Replaces invalid XML characters with '?'.ú?)ÚCONTROL_CHARACTERSÚsub)Úvalue© r   ú8E:\soccer\ml_env\Lib\site-packages\nose/plugins/xunit.pyÚxml_safe9   s    r   c                 C   s   t | ƒ dd¡S )z)Escape a string for an XML CDATA section.z]]>z]]>]]&gt;<![CDATA[)r   Úreplace)Úcdatar   r   r   Úescape_cdata>   s    r   c                 C   sF   t  | ¡}|r6| ¡ \}}| dd¡\}}||| gS |  dd¡S d S )NÚ.é   )ÚTEST_IDÚmatchÚgroupsÚrsplit)ZidvalÚmÚnameZfargsÚheadÚtailr   r   r   Úid_splitC   s    
r   c                 C   s\   t  | ¡r| j}n| jj}t  | ¡}|rT|j}| d¡rH|tdƒd… }d||f S |S dS )z7Returns a nice name for class object or class instance.zorg.python.core.Nz%s.%s)ÚinspectÚisclassÚ__name__Ú	__class__Ú	getmoduleÚ
startswithÚlen)ÚobjÚcls_nameÚmodr   r   r   r   Únice_classnameM   s    


r(   c                 C   s4   | d }|du r| d }nt |ƒ}t|dƒ}t|ƒS )zReturn the exception's message.r   Nr   úUTF-8)Ústrr   r   )Úexc_infoÚexcÚresultr   r   r   Úexc_message^   s    

r.   c                   @   s4   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ ZdS )ÚTeec                 G   s   || _ || _d S ©N)ÚencodingÚ_streams)Úselfr1   Úargsr   r   r   Ú__init__k   s    zTee.__init__c                 C   s&   t || jƒ}| jD ]}| |¡ qd S r0   )r   r1   r2   Úwrite)r3   ÚdataÚsr   r   r   r6   o   s    
z	Tee.writec                 C   s   |D ]}|   |¡ qd S r0   )r6   )r3   ÚlinesÚliner   r   r   Ú
writelinest   s    zTee.writelinesc                 C   s   | j D ]}| ¡  qd S r0   )r2   Úflush)r3   r8   r   r   r   r<   x   s    
z	Tee.flushc                 C   s   dS )NFr   ©r3   r   r   r   Úisatty|   s    z
Tee.isattyN)r    Ú
__module__Ú__qualname__r5   r6   r;   r<   r>   r   r   r   r   r/   j   s
   r/   c                       s¾   e Zd ZdZdZdZdZdZ‡ fdd„Zdd	„ Z	d
d„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd*d$d%„Zd+d&d'„Zd,d(d)„Z‡  ZS )-ÚXunitzCThis plugin provides test results in the standard XUnit XML format.ZxunitiÜ  r)   Nc                    s$   t t| ƒ ¡  g | _d | _d | _d S r0   )ÚsuperrA   r5   Ú_capture_stackÚ_currentStdoutÚ_currentStderrr=   ©r!   r   r   r5   ‡   s    zXunit.__init__c                 C   s    t | dƒrtƒ | j }nd}|S )NÚ_timerg        )Úhasattrr   rG   )r3   Útakenr   r   r   Ú
_timeTaken�   s    
zXunit._timeTakenc                 C   s   t |ƒ}t |¡S )z.Escape an XML attribute. Value can be unicode.)r   r   Z	quoteattr)r3   Úattrr   r   r   Ú
_quoteattr–   s    zXunit._quoteattrc              	   C   sN   t  | ||¡ |jdddd| dd¡dd� |jd	dd
d| dd¡dd� dS )z%Sets additional command line options.z--xunit-fileÚstoreÚ
xunit_fileÚFILEZNOSE_XUNIT_FILEznosetests.xmlzrPath to xml file to store the xunit report in. Default is nosetests.xml in the working directory [NOSE_XUNIT_FILE])ÚactionÚdestÚmetavarÚdefaultÚhelpz--xunit-testsuite-nameÚxunit_testsuite_nameZPACKAGEZNOSE_XUNIT_TESTSUITE_NAMEZ	nosetestszbName of the testsuite in the xunit xml, generated by plugin. Default test suite name is nosetests.N)r   ÚoptionsÚ
add_optionÚget)r3   ÚparserÚenvr   r   r   rV   ›   s    
ü	
ûzXunit.optionsc                 C   sL   t  | ||¡ || _| jrHdddddœ| _g | _tj |j	¡| _
|j| _dS )zConfigures the xunit plugin.r   )ÚerrorsÚfailuresÚpassesÚskippedN)r   Ú	configureÚconfigÚenabledÚstatsÚ	errorlistÚosÚpathÚrealpathrN   Úerror_report_file_namerU   )r3   rV   r`   r   r   r   r_   °   s    ÿzXunit.configurec                    sÒ   t  ˆ jdˆ jd¡ˆ _ˆ jˆ jd< ˆ jˆ jd< ˆ jd ˆ jd  ˆ jd  ˆ jd  ˆ jd	< ˆ j d
ˆ j ¡ ˆ j d ‡ fdd„ˆ j	D ƒ¡¡ ˆ j d¡ ˆ j 
¡  ˆ jjdkrÎ| d¡ | dˆ jj ¡ dS )zcWrites an Xunit-formatted XML file.
        The file includes a report of test errors and failures.Úwr   r1   Ztestsuite_namer[   r\   r]   r^   Útotalz£<?xml version="1.0" encoding="%(encoding)s"?><testsuite name="%(testsuite_name)s" tests="%(total)d" errors="%(errors)d" failures="%(failures)d" skip="%(skipped)d">Ú c                    s   g | ]}t |ˆ jƒ‘qS r   )r   r1   )Ú.0Úer=   r   r   Ú
<listcomp>Ì   ó    z Xunit.report.<locals>.<listcomp>z</testsuite>r   zF----------------------------------------------------------------------zXML: %sN)ÚcodecsÚopenrg   r1   Úerror_report_filerb   rU   r6   Újoinrc   Úcloser`   Ú	verbosityÚwritelnr   )r3   Ústreamr   r=   r   Úreport¼   s.    ÿÿÿ
ýÿÿ

zXunit.reportc                 C   sP   | j  tjtjf¡ tƒ | _tƒ | _t| j	| jtjƒt_t| j	| jtjƒt_d S r0   )
rC   ÚappendÚsysÚstdoutÚstderrr   rD   rE   r/   r1   r=   r   r   r   Ú_startCaptureÔ   s
    zXunit._startCapturec                 C   s   |   ¡  d S r0   )r|   ©r3   Úcontextr   r   r   ÚstartContextÛ   s    zXunit.startContextc                 C   s   |   ¡  d S r0   )Ú_endCapturer}   r   r   r   ÚstopContextÞ   s    zXunit.stopContextc                 C   s   t ƒ | _|  ¡  dS )z+Initializes a timer before starting a test.N)r   rG   r|   ©r3   Útestr   r   r   Ú
beforeTestá   s    zXunit.beforeTestc                 C   s   | j r| j  ¡ \t_t_d S r0   )rC   Úpopry   rz   r{   r=   r   r   r   r€   æ   s    zXunit._endCapturec                 C   s   |   ¡  d | _d | _d S r0   )r€   rD   rE   r‚   r   r   r   Ú	afterTestê   s    zXunit.afterTestc                 C   s   | j r|  ¡  q d S r0   )rC   r€   r‚   r   r   r   Úfinalizeï   s    zXunit.finalizec                 C   s$   | j r | j  ¡ }|r dt|ƒ S dS )Nz'<system-out><![CDATA[%s]]></system-out>rj   )rD   Úgetvaluer   ©r3   r   r   r   r   Ú_getCapturedStdoutó   s    
ÿÿzXunit._getCapturedStdoutc                 C   s$   | j r | j  ¡ }|r dt|ƒ S dS )Nz'<system-err><![CDATA[%s]]></system-err>rj   )rE   rˆ   r   r‰   r   r   r   Ú_getCapturedStderrý   s    
ÿÿzXunit._getCapturedStderrc                 C   sÀ   |   ¡ }t|d tƒr.d}| jd  d7  < nd}| jd  d7  < t|| jƒ}| ¡ }| j d|  	t
|ƒd ¡|  	t
|ƒd ¡|||  	t|d ƒ¡|  	t|ƒ¡t|ƒ|  ¡ |  ¡ dœ	 ¡ d	S )
z!Add error output to Xunit report.r   r^   r   Úerrorr[   z®<testcase classname=%(cls)s name=%(name)s time="%(taken).3f"><%(type)s type=%(errtype)s message=%(message)s><![CDATA[%(tb)s]]></%(type)s>%(systemout)s%(systemerr)s</testcase>éÿÿÿÿ)	Úclsr   rI   ÚtypeÚerrtypeÚmessageÚtbÚ	systemoutÚ	systemerrN)rJ   Ú
issubclassr   rb   r   r1   Úidrc   rx   rL   r   r(   r.   r   rŠ   r‹   )r3   rƒ   ÚerrÚcaptrI   r�   r’   r–   r   r   r   ÚaddError  s,    øýÿzXunit.addErrorc                 C   s”   |   ¡ }t|| jƒ}| jd  d7  < | ¡ }| j d|  t|ƒd ¡|  t|ƒd ¡||  t	|d ƒ¡|  t
|ƒ¡t|ƒ|  ¡ |  ¡ dœ ¡ dS )z#Add failure output to Xunit report.r\   r   z¬<testcase classname=%(cls)s name=%(name)s time="%(taken).3f"><failure type=%(errtype)s message=%(message)s><![CDATA[%(tb)s]]></failure>%(systemout)s%(systemerr)s</testcase>r   r�   )rŽ   r   rI   r�   r‘   r’   r“   r”   N)rJ   r   r1   rb   r–   rc   rx   rL   r   r(   r.   r   rŠ   r‹   )r3   rƒ   r—   r˜   Ztb_inforI   r’   r–   r   r   r   Ú
addFailure!  s"    ùýÿzXunit.addFailurec              	   C   sf   |   ¡ }| jd  d7  < | ¡ }| j d|  t|ƒd ¡|  t|ƒd ¡||  ¡ |  ¡ dœ ¡ dS )z#Add success output to Xunit report.r]   r   zb<testcase classname=%(cls)s name=%(name)s time="%(taken).3f">%(systemout)s%(systemerr)s</testcase>r   r�   )rŽ   r   rI   r“   r”   N)	rJ   rb   r–   rc   rx   rL   r   rŠ   r‹   )r3   rƒ   r˜   rI   r–   r   r   r   Ú
addSuccess5  s    üþÿzXunit.addSuccess)N)NN)N)r    r?   r@   Ú__doc__r   Zscorer1   rq   r5   rJ   rL   rV   r_   rw   r|   r   r�   r„   r€   r†   r‡   rŠ   r‹   r™   rš   r›   Ú__classcell__r   r   rF   r   rA   €   s.   	



rA   )rœ   ro   rd   ry   Úrer   Úior   r   Zxml.saxr   Znose.plugins.baser   Znose.excr   Znose.pyversionr   r   Úcompiler
   r   r   r   r   r(   r.   Úobjectr/   rA   r   r   r   r   Ú<module>   s(   '


