
J9Qc           @   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 e j d	  Z e j d
  Z d   Z d   Z d   Z d   Z d   Z d   Z d e f d     YZ d e f d     YZ d S(   s  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.

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   UNICODE_STRINGSs   [\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(    (    s6   /sys/lib/python2.7/site-packages/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(    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt   escape_cdata?   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(    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt   id_splitC   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   (    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt   nice_classnameL   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 |  S(   s   Return the exception's message.i   i    N(   t   Nonet   strt   UnicodeEncodeErrort   unicodet   UnicodeErrort   argsR
   (   t   exc_infot   exct   result(    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt   exc_messagec   s    
c         C   sX   |  \ } } } t  | t  r> d j t j |   } | | Sd j t j |     Sd  S(   Nt    (   t
   isinstancet
   basestringt   joint	   tracebackt	   format_tbt   format_exception(   R+   t   ect   evt   tbt   tb_data(    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyR5   u   s
    t   Teec           B   s#   e  Z d    Z d   Z d   Z RS(   c         G   s   | |  _  d  S(   N(   t   _streams(   t   selfR*   (    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt   __init__   s    c         G   s%   x |  j  D] } | j |   q
 Wd  S(   N(   R;   t   write(   R<   R*   t   s(    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyR>      s    c         C   s"   x |  j  D] } | j   q
 Wd  S(   N(   R;   t   flush(   R<   R?   (    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyR@      s    (   R   t
   __module__R=   R>   R@   (    (    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyR:      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 d  Z d d d  Z d d  Z 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   superRB   R=   t   _capture_stackR%   t   _currentStdoutt   _currentStderr(   R<   (    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyR=      s    		c         C   s,   t  |  d  r" t   |  j } n d } | S(   Nt   _timerg        (   t   hasattrR   RH   (   R<   t   taken(    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt
   _timeTaken   s    c         C   sD   t  |  } t | t  r7 t r7 | j |  j  } n  t j |  S(   s.   Escape an XML attribute. Value can be unicode.(   R
   R0   R(   R   t   encodet   encodingR   t	   quoteattr(   R<   t   attr(    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt
   _quoteattr   s    c         C   sN   t  j |  | |  | 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]N(   R   t   optionst
   add_optiont   get(   R<   t   parsert   env(    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyRZ      s    c         C   s{   t  j |  | |  | |  _ |  j rw i d d 6d d 6d d 6d d 6|  _ g  |  _ t j | j d |  j	 d  |  _
 n  d S(	   s   Configures the xunit plugin.i    t   errorst   failurest   passest   skippedt   wR   N(   R   t	   configuret   configt   enabledt   statst	   errorlistt   codecst   openRT   RM   t   error_report_file(   R<   RZ   Re   (    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyRd      s    		
	c         C   s   |  j  |  j d <|  j d |  j d |  j d |  j d |  j d <|  j j d |  j  |  j j d j g  |  j D] } |  j |  ^ qu   |  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.

        RM   R_   R`   Ra   Rb   t   totalu   <?xml version="1.0" encoding="%(encoding)s"?><testsuite name="nosetests" tests="%(total)d" errors="%(errors)d" failures="%(failures)d" skip="%(skipped)d">u    u   </testsuite>i   t   -iF   s   XML: %sN(   RM   Rg   Rk   R>   R2   Rh   t   _forceUnicodet   closeRe   t	   verbosityt   writelnR   (   R<   t   streamt   e(    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt   report   s    5	&c         C   sh   |  j  j t j t j f  t   |  _ t   |  _ t |  j t j  t _ t |  j t j  t _ d  S(   N(	   RE   t   appendt   syst   stdoutt   stderrR    RF   RG   R:   (   R<   (    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt   _startCapture   s
    c         C   s   |  j    d  S(   N(   Ry   (   R<   t   context(    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt   startContext   s    c         C   s   t    |  _ |  j   d S(   s+   Initializes a timer before starting a test.N(   R   RH   Ry   (   R<   t   test(    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt
   beforeTest   s    c         C   s+   |  j  r' |  j  j   \ t _ t _ n  d  S(   N(   RE   t   popRv   Rw   Rx   (   R<   (    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt   _endCapture   s    	c         C   s    |  j    d  |  _ d  |  _ d  S(   N(   R   R%   RF   RG   (   R<   R|   (    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt	   afterTest   s    
	c         C   s   x |  j  r |  j   q Wd  S(   N(   RE   R   (   R<   R|   (    (    s6   /sys/lib/python2.7/site-packages/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>R/   (   RF   t   getvalueR   (   R<   R	   (    (    s6   /sys/lib/python2.7/site-packages/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/   (   RG   R   R   (   R<   R	   (    (    s6   /sys/lib/python2.7/site-packages/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 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_   s   <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   RJ   t   typet   errtypet   messageR8   t	   systemoutt	   systemerrN(   RK   t
   issubclassR   Rg   R5   t   idRh   Ru   RP   R   R$   R.   R   R   R   (   R<   R|   t   errt   captRJ   R   R8   R   (    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt   addError  s&    	c         C   s   |  j    } t |  } |  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   s   <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   RJ   R   R   R8   R   R   N(   RK   R5   Rg   R   Rh   Ru   RP   R   R$   R.   R   R   R   (   R<   R|   R   R   t   tb_infoRJ   R8   R   (    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt
   addFailure#  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   RJ   R   R   N(	   RK   Rg   R   Rh   Ru   RP   R   R   R   (   R<   R|   R   RJ   R   (    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt
   addSuccess8  s    	c         C   s4   t  s0 t | t  r0 | j |  j d  } q0 n  | S(   NR   (   R   R0   R&   t   decodeRM   (   R<   R?   (    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyRn   H  s    N(   R   RA   t   __doc__R   t   scoreRM   R%   Rk   R=   RK   RP   RZ   Rd   Rt   Ry   R{   R}   R   R   R   R   R   R   R   R   Rn   (    (    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyRB      s.   		
												(   R   Ri   t   doctestt   osRv   R3   t   reR   t	   cStringIOR    R   t   xml.saxR   t   nose.plugins.baseR   t   nose.excR   t   nose.pyversionR   t   compileR   R   R
   R   R   R$   R.   R5   t   objectR:   RB   (    (    (    s6   /sys/lib/python2.7/site-packages/nose/plugins/xunit.pyt   <module>&   s.   							