a
    4ñ»jàF  ã                   @   s`  d Z ddlm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mZmZ ddlmZ dd	lmZ dd
lmZ ddlmZmZmZ ddlmZ ddlZejr´ddlZnddlZddd„Z G dd„ dejƒZ!e"edƒ�r4ej#fdd„Z$dej#fdd„Z%ej&�re% e_#ej'd< nej�r4e$ e_#ej'd< G dd„ de(ƒZ)G dd„ de
ƒZ*dd„ Z+dS )a6  
This module provides a reporter with JUnit XML output.

Mapping of behave model elements to XML elements::

    feature     -> xml_element:testsuite
    scenario    -> xml_element:testcase

XML document structure::

    # -- XML elements:
    # CARDINALITY SUFFIX:
    #   ?   optional (zero or one)
    #   *   many0 (zero or more)
    #   +   many (one or more)
    testsuites := sequence<testsuite>
    testsuite:
        properties? : sequence<property>
        testcase* :
            error?      : text
            failure?    : text
            system-out  : text
            system-err  : text

    testsuite:
        @name       : TokenString
        @tests      : int
        @failures   : int
        @errors     : int
        @skipped    : int
        @time       : Decimal       # Duration in seconds
        # -- SINCE: behave-1.2.6
        @timestamp  : IsoDateTime
        @hostname   : string

    testcase:
        @name       : TokenString
        @classname  : TokenString
        @status     : string        # Status enum
        @time       : Decimal       # Elapsed seconds

    error:
        @message    : string
        @type       : string

    failure:
        @message    : string
        @type       : string

    # -- HINT: Not used
    property:
        @name  : TokenString
        @value : string

    type Status : Enum("passed", "failed", "skipped", "untested")

Note that a spec for JUnit XML output was not clearly defined.
Best sources are:

* `JUnit XML`_ (for PDF)
* JUnit XML (`ant spec 1`_, `ant spec 2`_)


.. _`JUnit XML`:  http://junitpdfreport.sourceforge.net/managedcontent/PdfTranslation
.. _`ant spec 1`: https://github.com/windyroad/JUnit-Schema
.. _`ant spec 2`: http://svn.apache.org/repos/asf/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java
é    )Úabsolute_importN)ÚElementTree)Údatetime)ÚReporter)ÚScenarioÚScenarioOutlineÚStep)ÚStatus)Úansi_escapes)ÚModelDescriptor)ÚindentÚmake_indentationÚtext)ÚUserDataNamespacec                 C   s   t  d¡}t | ¡|_|S )Nú![CDATA[)r   ÚElementr
   Zstrip_escapesr   )r   Úelement© r   ú;E:\soccer\ml_env\Lib\site-packages\behave/reporter/junit.pyÚCDATA\   s    
r   c                   @   s   e Zd Zdd„ ZdS )ÚElementTreeWithCDATAc                 C   s>   |j dkr&|j |¡}| d| ¡ ntj | ||||¡ dS )z'This method is for ElementTree <= 1.2.6r   z
<![CDATA[%s]]>
N)Útagr   ÚencodeÚwriter   Ú_write)ÚselfÚfileÚnodeÚencodingÚ
namespacesr   r   r   r   r   e   s    
ÿzElementTreeWithCDATA._writeN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   c   s   r   Ú
_serializec                 C   s:   |j dkr*| d|j |j |d¡f ƒ d S || ||||ƒS )Nr   z

<%s%s]]>
Úxmlcharrefreplace)r   r   r   )r   Úelemr   Úqnamesr   Úorigr   r   r   Ú_serialize_xml2q   s    
ÿr(   c                 C   sJ   |j dkr$| dj|j |jd�ƒ d S |r8|| ||||ƒS || |||ƒS d S )Nr   z
<{tag}{text}]]>
)r   r   )r   Úformatr   )r   r%   r&   r   Zshort_empty_elementsr'   r   r   r   Ú_serialize_xml3y   s    
ÿr*   Úxmlc                   @   s"   e Zd ZdZddd„Zdd„ ZdS )ÚFeatureReportDatazL
    Provides value object to collect JUnit report data from a Feature.
    Nc                 C   sH   |s|r|  dd¡}|| _|| _|| _g | _d| _d| _d| _d| _d S )Nú/Ú.r   )	ÚreplaceÚfeatureÚfilenameÚ	classnameÚ	testcasesÚcounts_testsÚcounts_errorsÚcounts_failedÚcounts_skipped)r   r0   r1   r2   r   r   r   Ú__init__“   s    zFeatureReportData.__init__c                 C   s"   g | _ d| _d| _d| _d| _d S )Nr   )r3   r4   r5   r6   r7   ©r   r   r   r   ÚresetŸ   s
    zFeatureReportData.reset)N)r    r!   r"   Ú__doc__r8   r:   r   r   r   r   r,   �   s   
r,   c                       sœ   e Zd ZdZdZdZdZdZdZdZ	dZ
dZ‡ fdd„Zdd„ Zd	d
„ Zedd„ ƒZdd„ Zedd„ ƒZdd„ Zedd„ ƒZdd„ Zdd„ Zdd„ Z‡  ZS )ÚJUnitReporterz5Generates JUnit-like XML test report for behave.
    zbehave.reporter.junitTFc                    s    t t| ƒ |¡ |  |j¡ d S ©N)Úsuperr<   r8   Úsetup_with_userdataÚuserdata)r   Úconfig©Ú	__class__r   r   r8   µ   s    zJUnitReporter.__init__c                 C   s€   t | j|ƒ}| d| j¡| _| d| j¡| _| d| j¡| _| d| j¡| _| d| j¡| _| d| j¡| _| d| j	¡| _	dS )	a   Setup JUnit reporter with userdata information.
        A user can now tweak the output format of this reporter.

        EXAMPLE:
        .. code-block:: ini

            # -- FILE: behave.ini
            [behave.userdata]
            behave.reporter.junit.show_hostname = false
        Úshow_hostnameÚshow_multilineÚshow_scenariosÚ	show_tagsÚshow_timingsÚshow_timestampÚshow_skipped_alwaysN)
r   Úuserdata_scopeZgetboolrD   rE   rF   rG   rH   rI   rJ   )r   r@   rA   r   r   r   r?   ¹   s    ÿz!JUnitReporter.setup_with_userdatac                 C   sx   d }| j jD ]*}|j |¡r|jt|ƒd d … } q8q|sL|j | j j¡}| dd¡d }| 	dd¡ 	dd¡}t
|ƒS )Né   r.   r   ú\r-   )rA   Úpathsr1   Ú
startswithÚlenÚlocationÚrelpathÚbase_dirÚrsplitr/   Ú_text)r   r0   r1   Úpathr   r   r   Úmake_feature_filenameÏ   s    z#JUnitReporter.make_feature_filenamec                 C   s   | j jp| jS r=   )rA   Úshow_skippedrJ   r9   r   r   r   rX   Ü   s    zJUnitReporter.show_skippedc                 C   sš  |j tjkr| jsd S |  |¡}|}t||ƒ}t ¡ }t 	d¡}|j
pH|}| dd||f ¡ |D ],}t|tƒr‚|}	|  |	|¡ qb|  ||¡ qb|jD ]}
| |
¡ q–| dt|jƒ¡ | dt|jƒ¡ | dt|jƒ¡ | dt|jƒ¡ | dtt|jd	ƒƒ¡ | j�r"| d
t| ¡ ƒ¡ | j�r<| dttƒ ƒ¡ tj | j j!¡�s\t "| j j!¡ t#|ƒ}| j j!}d| }tj $||¡}| %t& '|d¡d¡ d S )NZ	testsuiteÚnameú%s.%sZtestsÚerrorsZfailuresÚskippedÚtimeé   Ú	timestampÚhostnamezTESTS-%s.xmlÚwbzUTF-8)(Ústatusr	   r\   rX   rW   r,   r   Únowr   r   rY   ÚsetÚ
isinstancer   Ú_process_scenario_outlineÚ_process_scenarior3   ÚappendrU   r4   r5   r6   r7   ÚroundÚdurationrI   Ú	isoformatrD   ÚgethostnameÚosrV   ÚexistsrA   Zjunit_directoryÚmakedirsr   Újoinr   ÚcodecsÚopen)r   r0   Zfeature_filenamer2   Úreportrc   ZsuiteÚfeature_nameÚscenarioÚscenario_outlineÚtestcaseÚtreeZreport_dirnameZreport_basenameZreport_filenamer   r   r   r0   á   s@    





zJUnitReporter.featurec                 C   s:   |D ]0}t |tƒs"J d|jj ƒ‚|j| kr|  S qdS )aq  Helper function to find the first step that has the given
        step.status.

        EXAMPLE: Search for a failing step in a scenario (all steps).
            >>> scenario = ...
            >>> failed_step = select_step_with_status(Status.failed, scenario)
            >>> failed_step = select_step_with_status(Status.failed, scenario.all_steps)
            >>> assert failed_step.status == Status.failed

        EXAMPLE: Search only scenario steps, skip background steps.
            >>> failed_step = select_step_with_status(Status.failed, scenario.steps)

        :param status:  Step status to search for (as enum value).
        :param steps:   List of steps to search in (or scenario).
        :returns: Step object, if found.
        :returns: None, otherwise.

        .. versionchanged:: 1.2.6
            status: Use enum value instead of string (or string).
        zTYPE-MISMATCH: step.class=%sN)re   r   rC   r    rb   )rb   ZstepsÚstepr   r   r   Úselect_step_with_status  s    
ÿ

z%JUnitReporter.select_step_with_statusc                 C   s€   t |jjƒ}| jr |d|j 7 }d|j|jf }|d| 7 }| jr|tdƒ}|jrd|t	 
|j|¡7 }n|jr||t	 |j|¡7 }|S )Nz
 in %0.3fsz
%s %s ... z%s
é   )rU   rb   rY   rH   rj   ÚkeywordrE   r   r   r   Zdescribe_docstringÚtableZdescribe_table)r   ry   Zstatus_textr   Úprefixr   r   r   Údescribe_step2  s    zJUnitReporter.describe_stepc                 C   s   d}|rdd  |¡ }|S )NÚ ú@z @)rp   )ÚclsÚtagsr   r   r   r   Údescribe_tags@  s    zJUnitReporter.describe_tagsc                 C   sr   d}| j r$|jr$|d|  |j¡ 7 }|d|j|jf 7 }d}d}|D ]}||  |¡7 }qDtdƒ}|t||ƒ | S )zÝDescribe the scenario and the test status.
        NOTE: table, multiline text is missing in description.

        :param scenario:  Scenario that was tested.
        :return: Textual description of the scenario.
        z
@scenario.begin
z
  %s
z	  %s: %s
z`
@scenario.end
--------------------------------------------------------------------------------
r€   é   )rG   rƒ   r„   r|   rY   r   r   r   )r   ru   Zheader_lineZfooter_liner   ry   Zstep_indentationr   r   r   Údescribe_scenarioG  s    zJUnitReporter.describe_scenarioc                 C   sx  t |tƒsJ ‚t |tƒrJ ‚|jtjks.| jr<| jd7  _|j}|j	}|j
}|s\|  |¡}t d¡}| dd||f ¡ | d|j
pˆd¡ | d|jj
¡ | dtt|jd	ƒƒ¡ d
}d
}|jtjk�r$tjtjfD ]}	|  |	|¡}|rÖ qðqÖd}
|�r8t |jttd
ƒfƒ�r8|jtjtjfv �s(J ‚| jd7  _n| jd7  _d}
t |
¡}|�r®|  |¡ ¡ }d||jf }t|jƒ}| d|jjj¡ | d|¡ |t|jƒ7 }n\d}|j�rÄ|jjj}| d|¡ | d|j�pàd¡ t  !|j"¡}| #dd¡ td $|¡ƒ}| %t&|ƒ¡ | %|¡ n”|jtjtj'fv �r¸| j�r¸| j(d7  _(|  tj|¡}|�r¤| jd7  _t d¡}| dd¡ | dd|j
 ¡ | %|¡ nt d¡}| %|¡ t d¡}d}| j)�rØ|  *|¡}|j+j,�rút|j+j,ƒ}|d| 7 }| %t&|ƒ¡ | %|¡ |j+j-�rRt d¡}t|j+j-ƒ}d| }| %t&|ƒ¡ | %|¡ |jtjk�sh| j�rt|j. %|¡ d
S )aþ  Process a scenario and append information to JUnit report object.
        This corresponds to a JUnit testcase:

          * testcase.@classname = f(filename) +'.'+ feature.name
          * testcase.@name   = scenario.name
          * testcase.@status = scenario.status
          * testcase.@time   = scenario.duration

        Distinguishes now between failures and errors.
        Failures are AssertationErrors: expectation is violated/not met.
        Errors are unexpected RuntimeErrors (all other exceptions).

        If a failure/error occurs, the step, that caused the failure,
        and its location are provided now.

        :param scenario:  Scenario to process.
        :param report:    Context object to store/add info to (outgoing param).
        rL   rw   r2   rZ   rY   r€   rb   r]   r^   NÚfailureÚerrorz
Failing step: %s
Location: %s
ÚtypeÚmessageZUnknownErrorr   zTraceback:
Ú	undefinedzUndefined Step: %sr\   z
system-outz
Captured stdout:
%s
z
system-errz
Captured stderr:
%s
)/re   r   r   rb   r	   r\   rX   r4   r2   r0   rY   rW   r   r   rd   rU   ri   rj   Úfailedr‹   rz   Ú	exceptionÚAssertionErrorr‰   r6   r5   r   ÚrstriprQ   rC   r    Úerror_messageÚ	tracebackÚ	format_tbÚexc_tracebackÚinsertrp   rh   r   Zuntestedr7   rF   r†   ZcapturedÚstdoutÚstderrr3   )r   ru   rs   r2   r0   rt   Úcasery   Zfailing_steprb   Zelement_namer‡   Z	step_textr   rŠ   Zfailure_typeZtraceback_linesÚskipr•   Úoutputr–   r   r   r   rg   Y  sš    


ÿ

ÿ









zJUnitReporter._process_scenarioc                 C   s6   t |tƒsJ ‚|D ]}t |tƒs$J ‚|  ||¡ qd S r=   )re   r   r   rg   )r   rv   rs   ru   r   r   r   rf   Ì  s    z'JUnitReporter._process_scenario_outline)r    r!   r"   r;   rK   rH   rJ   rI   rD   rF   rG   rE   r8   r?   rW   ÚpropertyrX   r0   Ústaticmethodrz   r   Úclassmethodr„   r†   rg   rf   Ú__classcell__r   r   rB   r   r<   §   s.   
1

sr<   c                  C   s   ddl } |  ¡ S )z)Return hostname of local host (as string)r   N)Úsocketrl   )rž   r   r   r   rl   Õ  s    rl   )N),r;   Ú
__future__r   Úos.pathrm   rq   Z	xml.etreer   r   Zbehave.reporter.baser   Zbehave.modelr   r   r   Zbehave.model_corer	   Zbehave.formatterr
   Zbehave.model_describer   Zbehave.textutilr   r   r   rU   Zbehave.userdatar   ÚsixÚPY2Z
traceback2r‘   r   r   ÚhasattrZ_serialize_xmlr(   r*   ÚPY3r#   Úobjectr,   r<   rl   r   r   r   r   Ú<module>   sL   E

ÿ
	þ
ÿÿÿ  0