
;^c           @   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	 d d l
 m Z d d l m Z d d l m Z d d l m Z m Z e j d	  Z e j d
  Z d   Z d   Z d   Z d   Z d   Z d e f d     YZ d e f d     YZ d S(   sU  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/

iN(   t   StringIO(   t   time(   t   saxutils(   t   Plugin(   t   SkipTest(   t   force_unicodet   format_exceptions   [\000-\010\013\014\016-\037]s   ^(.*?)(\(.*\))$c         C   s   t  j d |   S(   s)   Replaces invalid XML characters with '?'.t   ?(   t   CONTROL_CHARACTERSt   sub(   t   value(    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt   xml_safe>   s    c         C   s   t  |   j d d  S(   s)   Escape a string for an XML CDATA section.s   ]]>s   ]]>]]&gt;<![CDATA[(   R   t   replace(   t   cdata(    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt   escape_cdataB   s    c         C   sa   t  j |   } | rM | j   \ } } | j d d  \ } } | | | g S|  j d d  Sd  S(   Nt   .i   (   t   TEST_IDt   matcht   groupst   rsplit(   t   idvalt   mt   namet   fargst   headt   tail(    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt   id_splitF   s    c         C   s}   t  j |   r |  j } n |  j j } t  j |   } | ru | j } | j d  rg | t d  } n  d | | f S| Sd S(   s   Returns a nice name for class object or class instance.

        >>> nice_classname(Exception()) # doctest: +ELLIPSIS
        '...Exception'
        >>> nice_classname(Exception) # doctest: +ELLIPSIS
        '...Exception'

    s   org.python.core.s   %s.%sN(   t   inspectt   isclasst   __name__t	   __class__t	   getmodulet
   startswitht   len(   t   objt   cls_namet   modR   (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt   nice_classnameO   s    		c         C   s   |  d } | d k r# |  d } nU y t |  } WnB t k
 rw y t |  } Wqx t k
 rs | j d } qx Xn Xt | d  } t |  S(   s   Return the exception's message.i   i    s   UTF-8N(   t   Nonet   strt   UnicodeEncodeErrort   unicodet   UnicodeErrort   argsR   R   (   t   exc_infot   exct   result(    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt   exc_messagef   s    
t   Teec           B   s5   e  Z d    Z d   Z d   Z d   Z d   Z RS(   c         G   s   | |  _  | |  _ d  S(   N(   t	   _encodingt   _streams(   t   selft   encodingR+   (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt   __init__z   s    	c         C   s7   t  | |  j  } x |  j D] } | j |  q Wd  S(   N(   R   R1   R2   t   write(   R3   t   datat   s(    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyR6   ~   s    c         C   s"   x | D] } |  j  |  q Wd  S(   N(   R6   (   R3   t   linest   line(    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt
   writelines   s    c         C   s"   x |  j  D] } | j   q
 Wd  S(   N(   R2   t   flush(   R3   R8   (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyR<      s    c         C   s   t  S(   N(   t   False(   R3   (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt   isatty   s    (   R   t
   __module__R5   R6   R;   R<   R>   (    (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyR0   y   s
   				t   Xunitc           B   s   e  Z d  Z d Z d Z d Z d Z d   Z d   Z	 d   Z
 d   Z d   Z d	   Z d
   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d d  Z d d d  Z d d  Z RS(   sC   This plugin provides test results in the standard XUnit XML format.t   xuniti  s   UTF-8c         C   s2   t  t |   j   g  |  _ d  |  _ d  |  _ d  S(   N(   t   superR@   R5   t   _capture_stackR&   t   _currentStdoutt   _currentStderr(   R3   (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyR5      s    		c         C   s,   t  |  d  r" t   |  j } n d } | S(   Nt   _timerg        (   t   hasattrR   RF   (   R3   t   taken(    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt
   _timeTaken   s    c         C   s   t  |  } t j |  S(   s.   Escape an XML attribute. Value can be unicode.(   R   R   t	   quoteattr(   R3   t   attr(    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt
   _quoteattr   s    c         C   s   t  j |  | |  | j d d d d d d d d | j d	 d
  d d | j d d d d d d d d | j d d  d d d S(   s%   Sets additional command line options.s   --xunit-filet   actiont   storet   destt
   xunit_filet   metavart   FILEt   defaultt   NOSE_XUNIT_FILEs   nosetests.xmlt   helpsr   Path to xml file to store the xunit report in. Default is nosetests.xml in the working directory [NOSE_XUNIT_FILE]s   --xunit-testsuite-namet   xunit_testsuite_namet   PACKAGEt   NOSE_XUNIT_TESTSUITE_NAMEt	   nosetestssb   Name of the testsuite in the xunit xml, generated by plugin. Default test suite name is nosetests.N(   R   t   optionst
   add_optiont   get(   R3   t   parsert   env(    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyRZ      s    c         C   s~   t  j |  | |  | |  _ |  j rz i d d 6d d 6d d 6d d 6|  _ g  |  _ t j j | j	  |  _
 | j |  _ n  d S(   s   Configures the xunit plugin.i    t   errorst   failurest   passest   skippedN(   R   t	   configuret   configt   enabledt   statst	   errorlistt   ost   patht   realpathRP   t   error_report_file_nameRV   (   R3   RZ   Rd   (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyRc      s    		
	c         C   s&  t  j |  j d |  j d  |  _ |  j |  j d <|  j |  j d <|  j d |  j d |  j d |  j d |  j d	 <|  j j d
 |  j  |  j j d j g  |  j	 D] } t
 | |  j  ^ q   |  j j d  |  j j   |  j j d k r"| j d d  | j d |  j j  n  d S(   sm   Writes an Xunit-formatted XML file

        The file includes a report of test errors and failures.

        t   wR   R4   t   testsuite_nameR_   R`   Ra   Rb   t   totalu   <?xml version="1.0" encoding="%(encoding)s"?><testsuite name="%(testsuite_name)s" tests="%(total)d" errors="%(errors)d" failures="%(failures)d" skip="%(skipped)d">u    u   </testsuite>i   t   -iF   s   XML: %sN(   t   codecst   openRk   R4   t   error_report_fileRf   RV   R6   t   joinRg   R   t   closeRd   t	   verbosityt   writelnR   (   R3   t   streamt   e(    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt   report   s    5	)c         C   st   |  j  j t j t j f  t   |  _ t   |  _ t |  j	 |  j t j  t _ t |  j	 |  j t j  t _ d  S(   N(
   RC   t   appendt   syst   stdoutt   stderrR    RD   RE   R0   R4   (   R3   (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt   _startCapture   s
    c         C   s   |  j    d  S(   N(   R~   (   R3   t   context(    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt   startContext   s    c         C   s   |  j    d  S(   N(   t   _endCapture(   R3   R   (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt   stopContext   s    c         C   s   t    |  _ |  j   d S(   s+   Initializes a timer before starting a test.N(   R   RF   R~   (   R3   t   test(    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt
   beforeTest   s    c         C   s+   |  j  r' |  j  j   \ t _ t _ n  d  S(   N(   RC   t   popR{   R|   R}   (   R3   (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyR      s    	c         C   s    |  j    d  |  _ d  |  _ d  S(   N(   R   R&   RD   RE   (   R3   R   (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt	   afterTest   s    
	c         C   s   x |  j  r |  j   q Wd  S(   N(   RC   R   (   R3   R   (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt   finalize   s    c         C   s3   |  j  r/ |  j  j   } | r/ d t |  Sn  d S(   Ns'   <system-out><![CDATA[%s]]></system-out>t    (   RD   t   getvalueR   (   R3   R
   (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt   _getCapturedStdout  s    	c         C   s3   |  j  r/ |  j  j   } | r/ d t |  Sn  d S(   Ns'   <system-err><![CDATA[%s]]></system-err>R   (   RE   R   R   (   R3   R
   (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt   _getCapturedStderr  s    	c         C   s#  |  j    } t | d t  r; d } |  j d c d 7<n d } |  j d c d 7<t | |  j  } | j   } |  j j d i	 |  j	 t
 |  d  d 6|  j	 t
 |  d  d	 6| d
 6| d 6|  j	 t | d   d 6|  j	 t |   d 6t |  d 6|  j   d 6|  j   d 6 d S(   s*   Add error output to Xunit report.
        i    Rb   i   t   errorR_   u   <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>t   clsiR   RH   t   typet   errtypet   messaget   tbt	   systemoutt	   systemerrN(   RI   t
   issubclassR   Rf   R   R4   t   idRg   Rz   RL   R   R%   R/   R   R   R   (   R3   R   t   errt   captRH   R   R   R   (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt   addError  s&    	c         C   s   |  j    } t | |  j  } |  j d c d 7<| j   } |  j j d i |  j t |  d  d 6|  j t |  d  d 6| d 6|  j t	 | d   d	 6|  j t
 |   d
 6t |  d 6|  j   d 6|  j   d 6 d S(   s,   Add failure output to Xunit report.
        R`   i   u   <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>i    R   iR   RH   R   R   R   R   R   N(   RI   R   R4   Rf   R   Rg   Rz   RL   R   R%   R/   R   R   R   (   R3   R   R   R   t   tb_infoRH   R   R   (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt
   addFailure1  s    	c         C   s   |  j    } |  j d c d 7<| j   } |  j j d i |  j t |  d  d 6|  j t |  d  d 6| d 6|  j   d	 6|  j   d
 6 d S(   s,   Add success output to Xunit report.
        Ra   i   sb   <testcase classname=%(cls)s name=%(name)s time="%(taken).3f">%(systemout)s%(systemerr)s</testcase>i    R   iR   RH   R   R   N(	   RI   Rf   R   Rg   Rz   RL   R   R   R   (   R3   R   R   RH   R   (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt
   addSuccessG  s    	N(   R   R?   t   __doc__R   t   scoreR4   R&   Rr   R5   RI   RL   RZ   Rc   Ry   R~   R   R   R   R   R   R   R   R   R   R   R   (    (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyR@      s.   		
													(   R   Rp   t   doctestRh   R{   t	   tracebackt   reR   R    R   t   xml.saxR   t   nose.plugins.baseR   t   nose.excR   t   nose.pyversionR   R   t   compileR   R   R   R   R   R%   R/   t   objectR0   R@   (    (    (    s4   /tmp/pip-unpacked-wheel-IhimZu/nose/plugins/xunit.pyt   <module>)   s,   						