a
    4ñ»jªð  ã                   @   sf  d Z ddlmZm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mZmZmZmZ ddlmZ ddlmZ e	jr”ddlZnddlZG dd	„ d	eeƒZG d
d„ deeƒZG dd„ deeƒZG dd„ deƒZG dd„ deƒZG dd„ deeƒZ G dd„ deeƒZ!G dd„ deƒZ"G dd„ deƒZ#G dd„ de	j$ƒZ%G dd„ de	j$ƒZ&dd„ Z'dS ) z¦
This module provides the model element class that represent a behave model:

* :class:`Feature`
* :class:`Scenario`
* :class:`ScenarioOutline`
* :class:`Step`
* ...
é    )Úabsolute_importÚwith_statementN)Úzip)ÚStatusÚBasicStatementÚTagAndStatusStatementÚTagStatementÚ
Replayable)ÚNoMatch)Útextc                       s”   e Zd ZdZdZd‡ fdd„	Z‡ fdd„Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
edd„ ƒZd dd„Zd!dd„Zdd„ Zdd„ Zd"dd„Zdd„ Z‡  ZS )#ÚFeaturea-	  A `feature`_ parsed from a *feature file*.

    The attributes are:

    .. attribute:: keyword

       This is the keyword as seen in the *feature file*. In English this will
       be "Feature".

    .. attribute:: name

       The name of the feature (the text after "Feature".)

    .. attribute:: description

       The description of the feature as seen in the *feature file*. This is
       stored as a list of text lines.

    .. attribute:: background

       The :class:`~behave.model.Background` for this feature, if any.

    .. attribute:: scenarios

       A list of :class:`~behave.model.Scenario` making up this feature.

    .. attribute:: tags

       A list of @tags (as :class:`~behave.model.Tag` which are basically
       glorified strings) attached to the feature.
       See :ref:`controlling things with tags`.

    .. attribute:: status

       Read-Only. A summary status of the feature's run. If read before the
       feature is fully tested it will return "untested" otherwise it will
       return one of:

       Status.untested
         The feature was has not been completely tested yet.
       Status.skipped
         One or more steps of this feature was passed over during testing.
       Status.passed
         The feature was tested successfully.
       Status.failed
         One or more steps of this feature failed.

       .. versionchanged:: 1.2.6
            Use Status enum class (was: string).

    .. attribute:: hook_failed

        Indicates if a hook failure occured while running this feature.

        .. versionadded:: 1.2.6

    .. attribute:: duration

       The time, in seconds, that it took to test this feature. If read before
       the feature is tested it will return 0.0.

    .. attribute:: filename

       The file name (or "<string>") of the *feature file* where the feature
       was found.

    .. attribute:: line

       The line number of the *feature file* where the feature was found.

    .. attribute:: language

       Indicates which spoken language (English, French, German, ..) was used
       for parsing the feature file and its keywords. The I18N language code
       indicates which language is used. This corresponds to the language tag
       at the beginning of the feature file.

       .. versionadded:: 1.2.6

    .. _`feature`: gherkin.html#features
    ÚfeatureNc
                    sd   |pg }t t| ƒ |||||¡ |p&g | _g | _|| _|	| _d | _d| _|r`|D ]}
|  	|
¡ qPd S ©NF)
Úsuperr   Ú__init__ÚdescriptionÚ	scenariosÚ
backgroundÚlanguageÚparserÚhook_failedÚadd_scenario)ÚselfÚfilenameÚlineÚkeywordÚnameÚtagsr   r   r   r   Úscenario©Ú	__class__© ú2E:\soccer\ml_env\Lib\site-packages\behave/model.pyr   u   s    
zFeature.__init__c                    s,   t t| ƒ ¡  d| _| jD ]}| ¡  qdS )z'Reset to clean state before a test run.FN)r   r   Úresetr   r   ©r   r   r   r!   r"   r#   „   s    
zFeature.resetc                 C   s   d| j t| jƒf S )Nz<Feature "%s": %d scenario(s)>)r   Úlenr   ©r   r!   r!   r"   Ú__repr__‹   s    ÿzFeature.__repr__c                 C   s
   t | jƒS ©N©Úiterr   r&   r!   r!   r"   Ú__iter__�   s    zFeature.__iter__c                 C   s   | |_ | j|_| j |¡ d S r(   )r   r   r   Úappendr$   r!   r!   r"   r   ’   s    zFeature.add_scenarioc                 C   s”   | j rtjS d}d}| jD ]d}|j}|tjkr8tj  S |tjkr^|dkrTtj  S tj  S |tjkrld}|tjkr|d7 }q|rŠtjS tjS dS )z»Compute the status of this feature based on its:
          * scenarios
          * scenario outlines
          * hook failures

        :return: Computed status (as string-enum).
        Tr   Fé   N)r   r   Úfailedr   ÚstatusÚuntestedÚskippedÚpassed)r   r1   Zpassed_countr   Úscenario_statusr!   r!   r"   Úcompute_status—   s&    








zFeature.compute_statusc                 C   s   d}| j D ]}||j7 }q
|S )Ng        )r   Úduration)r   Zfeature_durationr   r!   r!   r"   r5   ·   s    
zFeature.durationFc                 C   sH   g }| j D ]8}t|tƒr8|}|r*| |¡ | |j ¡ q
| |¡ q
|S )aÄ  
        Provides a flat list of all scenarios of this feature.
        A ScenarioOutline element adds its scenarios to this list.
        But the ScenarioOutline element itself is only added when specified.

        A flat scenario list is useful when all scenarios of a features
        should be processed.

        :param with_outlines: If ScenarioOutline items should be added, too.
        :return: List of all scenarios of this feature.
        )r   Ú
isinstanceÚScenarioOutliner,   Úextend)r   Zwith_outlinesZall_scenariosr   Úscenario_outliner!   r!   r"   Úwalk_scenarios¿   s    


zFeature.walk_scenariosc                 C   s    | j  }|r|r|  |j¡}|S )a¥  
        Determines if this Feature (and its scenarios) should run.
        Implements the run decision logic for a feature.
        The decision depends on:

          * if the Feature is marked as skipped
          * if the config.tags (tag expression) enable/disable this feature

        :param config:  Runner configuration to use (optional).
        :return: True, if scenario should run. False, otherwise.
        )Úshould_skipÚshould_run_with_tagsr   ©r   ÚconfigZanswerr!   r!   r"   Ú
should_runÖ   s    zFeature.should_runc                 C   s0   |  | j¡}|s,| D ]}| |¡rd} q,q|S )at  Determines if this feature should run when the tag expression is used.
        A feature should run if:
          * it should run according to its tags
          * any of its scenarios should run according to its tags

        :param tag_expression:  Runner/config environment tags to use.
        :return: True, if feature should run. False, otherwise (skip it).
        T)Úcheckr   r<   )r   Útag_expressionÚrun_featurer   r!   r!   r"   r<   ç   s    	
zFeature.should_run_with_tagsc                 C   s&   | j dd� | jtjks"| js"J ‚dS )z’Marks this feature (and all its scenarios and steps) as skipped.
        Note this function may be called before the feature is executed.
        T©Úrequire_not_executedN)Úskipr/   r   r1   r   r&   r!   r!   r"   Úmark_skippedø   s    zFeature.mark_skippedc                 C   sp   |rt  d¡}| d| j|¡ |  ¡  d| _|| _| jD ]}| ||¡ q8| js\|  	t
j¡ | j| jv slJ ‚dS )a}  Skip executing this feature or the remaining parts of it.
        Note that this feature may be already partly executed
        when this function is called.

        :param reason:  Optional reason why feature should be skipped (as string).
        :param require_not_executed: Optional, requires that feature is not
                        executed yet (default: false).
        ÚbehavezSKIP FEATURE %s: %sTN)ÚloggingÚ	getLoggerÚwarningr   Úclear_statusr;   Úskip_reasonr   rE   Ú
set_statusr   r1   r/   Úfinal_status©r   ÚreasonrD   Úloggerr   r!   r!   r"   rE   ÿ   s    	

zFeature.skipc           
      C   s  |   ¡  d| _|jjdd� | |j_t| jƒ|j_|j}|  |j	¡}d}d}|j	j
sª|rªd}| jD ]}| d|j|¡ qb| d|j| ¡ | jr–|d7 }| jp |j}|  ¡ }|s¶|j	jrê|jD ]}| | ¡ q¼| jrê|jD ]}| | j¡ qØ|�sJ| jD ]R}|j	j�r| |j	¡�s| ¡  qö| |¡}	|	rö|d7 }|j	j�sB|jrö �qJqö|   ¡  | j�sl|�sl|  tj¡ |�r¼| d	|j| ¡ | jD ]}| d
|j|¡ �qˆ| j�r¼|d7 }|  tj¡ z|j ¡  W n  t�yê   |  tj¡ Y n0 |�sü|j	j�r|jD ]}| ¡  �q|dk}	|	S )NFr   ©Z
layer_namer   TÚ
before_tagZbefore_featurer-   Zafter_featureÚ	after_tag)rK   r   ÚcontextÚ_pushr   Úsetr   Úabortedr?   r>   Údry_runÚrun_hookÚshow_skippedÚ
formattersr   r   r   Úshould_run_with_name_selectrF   ÚrunÚstoprM   r   r1   r.   Ú_popÚ	ExceptionÚeof)
r   ÚrunnerZskip_feature_untestedrB   Úfailed_countÚhooks_calledÚtagÚ	formatterr   r.   r!   r!   r"   r^     sn    





ÿ


zFeature.run)NNNNN)F)N)NF)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Útyper   r#   r'   r+   r   r4   Úpropertyr5   r:   r?   r<   rF   rE   r^   Ú__classcell__r!   r!   r   r"   r       s&   R   þ 



r   c                       sB   e Zd ZdZdZd‡ fdd„	Zdd„ Zdd	„ Zed
d„ ƒZ	‡  Z
S )Ú
BackgroundaO  A `background`_ parsed from a *feature file*.

    The attributes are:

    .. attribute:: keyword

       This is the keyword as seen in the *feature file*. In English this will
       typically be "Background".

    .. attribute:: name

       The name of the background (the text after "Background:".)

    .. attribute:: steps

       A list of :class:`~behave.model.Step` making up this background.

    .. attribute:: duration

       The time, in seconds, that it took to run this background. If read
       before the background is run it will return 0.0.

    .. attribute:: filename

       The file name (or "<string>") of the *feature file* where the background
       was found.

    .. attribute:: line

       The line number of the *feature file* where the background was found.

    .. _`background`: gherkin.html#backgrounds
    r   Nc                    s$   t t| ƒ ||||¡ |pg | _d S r(   )r   ro   r   Ústeps)r   r   r   r   r   rp   r   r!   r"   r   ˆ  s    zBackground.__init__c                 C   s
   d| j  S )Nz<Background "%s">©r   r&   r!   r!   r"   r'   Œ  s    zBackground.__repr__c                 C   s
   t | jƒS r(   )r*   rp   r&   r!   r!   r"   r+   �  s    zBackground.__iter__c                 C   s   d}| j D ]}||j7 }q
|S ©Nr   )rp   r5   )r   r5   Ústepr!   r!   r"   r5   ’  s    
zBackground.duration)N)rh   ri   rj   rk   rl   r   r'   r+   rm   r5   rn   r!   r!   r   r"   ro   d  s   !ro   c                       s²   e Zd ZdZdZdZd#‡ fdd„	Z‡ fdd„Zed	d
„ ƒZ	edd„ ƒZ
dd„ Zdd„ Zdd„ Zedd„ ƒZedd„ ƒZd$dd„Zdd„ Zdd„ Zdd„ Zd%dd „Zd!d"„ Z‡  ZS )&ÚScenarioaë  A `scenario`_ parsed from a *feature file*.

    The attributes are:

    .. attribute:: keyword

       This is the keyword as seen in the *feature file*. In English this will
       typically be "Scenario".

    .. attribute:: name

       The name of the scenario (the text after "Scenario:".)

    .. attribute:: description

       The description of the scenario as seen in the *feature file*.
       This is stored as a list of text lines.

    .. attribute:: feature

       The :class:`~behave.model.Feature` this scenario belongs to.

    .. attribute:: steps

       A list of :class:`~behave.model.Step` making up this scenario.

    .. attribute:: tags

       A list of @tags (as :class:`~behave.model.Tag` which are basically
       glorified strings) attached to the scenario.
       See :ref:`controlling things with tags`.

    .. attribute:: status

       Read-Only. A summary status of the scenario's run. If read before the
       scenario is fully tested it will return "untested" otherwise it will
       return one of:


       Status.untested
         The scenario was has not been completely tested yet.
       Status.skipped
         One or more steps of this scenario was passed over during testing.
       Status.passed
         The scenario was tested successfully.
       Status.failed
         One or more steps of this scenario failed.

       .. versionchanged:: 1.2.6
            Use Status enum class (was: string)

    .. attribute:: hook_failed

        Indicates if a hook failure occured while running this scenario.

        .. versionadded:: 1.2.6

    .. attribute:: duration

       The time, in seconds, that it took to test this scenario. If read before
       the scenario is tested it will return 0.0.

    .. attribute:: filename

       The file name (or "<string>") of the *feature file* where the scenario
       was found.

    .. attribute:: line

       The line number of the *feature file* where the scenario was found.


    .. _`scenario`: gherkin.html#scenarios
    r   FNc                    s\   |pg }t t| ƒ |||||¡ |p&g | _|p0g | _d | _d | _d| _d | _d | _	d| _
d S r   )r   rt   r   r   rp   r   r   r   Ú_background_stepsÚ_rowÚwas_dry_run)r   r   r   r   r   r   rp   r   r   r!   r"   r   é  s    

zScenario.__init__c                    s8   t t| ƒ ¡  d| _d| _d| _| jD ]}| ¡  q&dS )zfReset the internal data to reintroduce new-born state just after the
        ctor was called.
        FN)r   rt   r#   r   rv   rw   Ú	all_steps©r   rs   r   r!   r"   r#   ö  s    
zScenario.resetc                 C   s2   | j du r,g }| jr&dd„ | jjD ƒ}|| _ | j S )a7  Provide background steps if feature has a background.
        Lazy init that copies the background steps.

        Note that a copy of the background steps is needed to ensure
        that the background step status is specific to the scenario.

        :return:  List of background steps or empty list
        Nc                 S   s   g | ]}t   |¡‘qS r!   )Úcopy)Ú.0rs   r!   r!   r"   Ú
<listcomp>  ó    z-Scenario.background_steps.<locals>.<listcomp>)ru   r   rp   )r   rp   r!   r!   r"   Úbackground_steps  s    

zScenario.background_stepsc                 C   s(   | j durt | j| j¡S t| jƒS dS )zAReturns iterator to all steps, including background steps if any.N)r   Ú	itertoolsÚchainr~   rp   r*   r&   r!   r!   r"   rx     s    
zScenario.all_stepsc                 C   s
   d| j  S )Nz<Scenario "%s">rq   r&   r!   r!   r"   r'     s    zScenario.__repr__c                 C   s   | j S r(   )rx   r&   r!   r!   r"   r+      s    zScenario.__iter__c                 C   sv   | j rtjS | jD ]\}|jtjkr>| jr2tj  S tj  S q|jtjkr|jtjtj	tjfv sdJ ‚|j  S qtjS )zŠCompute the status of the scenario from its steps
        (and hook failures).

        :return: Computed status (as enum value).
        )
r   r   r.   rx   r/   Ú	undefinedrw   r0   r2   r1   ry   r!   r!   r"   r4   #  s    

zScenario.compute_statusc                 C   s   d}| j D ]}||j7 }q
|S rr   )rx   r5   )r   Zscenario_durationrs   r!   r!   r"   r5   ;  s    
zScenario.durationc                 C   s   | j }| jr| jj | j  }|S )zt
        Effective tags for this scenario:
          * own tags
          * tags inherited from its feature
        )r   r   )r   r   r!   r!   r"   Úeffective_tagsC  s    zScenario.effective_tagsc                 C   s*   | j  }|r&|r&|  |j¡o$|  |¡}|S )aÚ  
        Determines if this Scenario (or ScenarioOutline) should run.
        Implements the run decision logic for a scenario.
        The decision depends on:

          * if the Scenario is marked as skipped
          * if the config.tags (tag expression) enable/disable this scenario
          * if the scenario is selected by name

        :param config:  Runner configuration to use (optional).
        :return: True, if scenario should run. False, otherwise.
        )r;   r<   r   r]   r=   r!   r!   r"   r?   O  s    ÿzScenario.should_runc                 C   s   |  | j¡S )zì
        Determines if this scenario should run when the tag expression is used.

        :param tag_expression:  Runner/config environment tags to use.
        :return: True, if scenario should run. False, otherwise (skip it).
        )r@   r‚   )r   rA   r!   r!   r"   r<   b  s    zScenario.should_run_with_tagsc                 C   s   |j  p|j | j ¡S )úàDetermines if this scenario should run when it is selected by name.

        :param config:  Runner/config environment name regexp (if any).
        :return: True, if scenario should run. False, otherwise (skip it).
        )r   Zname_reÚsearch)r   r>   r!   r!   r"   r]   k  s    z$Scenario.should_run_with_name_selectc                 C   s2   | j dd� | jtjks.| js.J d| jj ƒ‚dS )z‰Marks this scenario (and all its steps) as skipped.
        Note that this method can be called before the scenario is executed.
        TrC   zOOPS: scenario.status=%sN)rE   r/   r   r1   r   r   r&   r!   r!   r"   rF   t  s    
ÿzScenario.mark_skippedc                 C   s®   |r(| j j}t d¡}| d|| j|¡ |  ¡  d| _|| _| j	D ]6}|j
tjtjfv }|rftj|_
qB|rBJ d|j
 ƒ‚qB| j oˆ| j }|rš|  tj¡ | j
| jv sªJ ‚dS )zùSkip from executing this scenario or the remaining parts of it.
        Note that the scenario may be already partly executed
        when this method is called.

        :param reason:  Optional reason why it should be skipped (as string).
        rG   zSKIP %s %s: %sTz$REQUIRE NOT-EXECUTED, but step is %sN)r    rh   rH   rI   rJ   r   rK   r;   rL   rx   r/   r   r0   r1   rp   r~   rM   rN   )r   rP   rD   Zscenario_typerQ   rs   Znot_executedZscenario_without_stepsr!   r!   r"   rE   |  s$    


ÿzScenario.skipc                 C   s  |   ¡  | j ¡  d| _d}|j}|  |j¡}|o:|jj }|oF|jj}|| _|j	j
dd� | |j	_t| jƒ|j	_d}|jjsÞ|rÞd}| jD ]}| d|j	|¡ qŒ| d|j	| ¡ | jr¼d}| jpÆ|j}|  ¡ }|oÜ|jj }|sì|jj�r|jD ]}	|	 | ¡ qò| ¡  |�s|jj�r>| D ]}
|jD ]}	|	 |
¡ �q(�q|�s4| jD ]è}
|�r¢|
 |¡�s”| j�or|
jtjk}d}|j	 dd¡ |  tj¡ n| j�r0d}nŽ|�s®|�r(tj|
_|�rÄtj|
_|j  |
¡}|�sìtj!|
_|j" #|
¡ n:|�r0|
jtjk�sJ ‚|jD ]}	|	 $|¡ |	 %|
¡ �q
ntj|
_�qJ|   ¡  |�sV| j&�sV|  tj¡ |�r¢| d|j	| ¡ | jD ]}| d	|j	|¡ �qr| j�r¢|  tj¡ d}z|j	 '¡  W n$ t(�yÔ   |  tj¡ d}Y n0 |jj)�pê| jtjk}|�rü|j*j| _| +¡  |S )
NFr   rR   TrS   Zbefore_scenarior.   Zafter_scenariorT   ),rK   Úcapturedr#   r   rX   r?   r>   rY   rw   rU   rV   r   rW   r‚   r   rZ   r[   r\   Zsetup_capturers   rx   r^   Úcontinue_after_failed_stepr/   r   r.   Ú_set_root_attributerM   r;   r1   r0   Ústep_registryÚ
find_matchr�   Úundefined_stepsr,   ÚmatchÚresultrp   r`   ra   ZjunitÚcapture_controllerZteardown_capture)r   rc   r.   Zskip_scenario_untestedZrun_scenarioZ	run_stepsZdry_run_scenariore   rf   rg   rs   Zfound_step_matchÚstore_capturedr!   r!   r"   r^   ˜  sš    





ÿ




zScenario.run)NNN)N)NF)rh   ri   rj   rk   rl   r†   r   r#   rm   r~   rx   r'   r+   r4   r5   r‚   r?   r<   r]   rF   rE   r^   rn   r!   r!   r   r"   rt   š  s0   K  ÿ




		
rt   c                   @   sT   e Zd ZdZdd„ Zeddd„ƒZddd„Zedd	d
„ƒZ	eddd„ƒZ
dd„ ZdS )ÚScenarioOutlineBuilderzmHelper class to use a ScenarioOutline as a template and
    build its scenarios (as template instances).
    c                 C   s
   || _ d S r(   )Úannotation_schema)r   r�   r!   r!   r"   r     s    zScenarioOutlineBuilder.__init__Nc                 C   sh   d| v rd| v s| S d}||fD ]B}|s*q |  ¡ D ].\}}|rPd|v rPd|v rPq2|  d| |¡} q2q | S )a  Render a text template with placeholders, ala "Hello <name>".

        :param row:     As placeholder provider (dict-like).
        :param params:  As additional placeholder provider (as dict).
        :return: Rendered text, known placeholders are substituted w/ values.
        ú<ú>Fú<%s>)ÚitemsÚreplace)r   ÚrowÚparamsZsafe_valuesZplaceholdersr   Úvaluer!   r!   r"   Úrender_template  s    z&ScenarioOutlineBuilder.render_templatec           
      C   s¦   |du ri }|j pd|d< | d|j¡ | d|j¡ | d|j¡ |  |j ||¡}||d< |  |||¡}G dd„ dtƒ}|||jƒ}||j|jƒ}	| jj|||	d	�S )
a  Build a scenario name for an example row of this scenario outline.
        Placeholders for row data are replaced by values.

        SCHEMA: "{outline_name} -*- {examples.name}@{row.id}"

        :param outline_name:    ScenarioOutline's name (as template).
        :param example:         Examples object.
        :param row:             Row of this example.
        :param params:          Additional placeholders for example/row.
        :return: Computed name for the scenario representing example/row.
        NÚ úexamples.nameúexamples.indexú	row.indexúrow.idc                   @   s   e Zd Zdd„ ZdS )z7ScenarioOutlineBuilder.make_scenario_name.<locals>.Datac                 S   s   || _ || _|| _d S r(   )r   ÚindexÚid©r   r   rŸ   r!   r!   r"   r   C  s    z@ScenarioOutlineBuilder.make_scenario_name.<locals>.Data.__init__N)rh   ri   rj   r   r!   r!   r!   r"   ÚDataB  s   r¢   )r   Úexamplesr–   )r   Ú
setdefaultrŸ   r    r™   Úobjectr�   Úformat)
r   Zoutline_nameÚexampler–   r—   Zexamples_nameÚscenario_namer¢   Zexample_dataZrow_datar!   r!   r"   Úmake_scenario_name*  s    ÿz)ScenarioOutlineBuilder.make_scenario_namec                 C   sb   |sg S g }|D ]L}d|v r2d|v r2|   |||¡}d|v sd|v rDqtj|dd�}| |¡ q|S )Nr‘   r’   T)Úunescape)r™   ÚTagÚ	make_namer,   )ÚclsZoutline_tagsr–   r—   r   rf   Znew_tagr!   r!   r"   Úmake_row_tagsM  s    z$ScenarioOutlineBuilder.make_row_tagsc           	      C   s„   t  |¡}|  |j||¡|_|jr2|  |j|¡|_|jr€| ¡ D ]>\}}|jD ].}t|jƒD ]\}}| 	d| |¡|j|< q\qNq@|S )Nr“   )
rz   Údeepcopyr™   r   r   Útabler”   Ú	enumerateÚcellsr•   )	r­   Úoutline_stepr–   r—   Únew_stepr   r˜   ÚiÚcellr!   r!   r"   Úmake_step_for_row]  s    

z(ScenarioOutlineBuilder.make_step_for_rowc              	   C   s(  dddddœ}g }t |jƒD �]\}}|d |_|j|d< t|jƒ|d< t |jƒD ]Î\}}|d |_d|j|jf |_|j|d< t|jƒ|d< |  |j|||¡}|  |j	||¡}	|	 
|j	¡ g }
|jD ]}|  |||¡}|
 |¡ qÆ|j}t|j||j||	|
ƒ}|j|_|j|_||_| |¡ qRq|S )	z8Build scenarios for a ScenarioOutline from its examples.N)r›   rœ   r�   rž   r-   r›   rœ   z%d.%drž   r�   )r±   r£   rŸ   r   Ú_textr°   r    r©   r®   r   r8   rp   r·   r,   r   rt   r   r   r   r   rv   )r   r9   r—   r   Zexample_indexr§   Z	row_indexr–   r¨   Zrow_tagsZ	new_stepsr³   r´   Zscenario_liner   r!   r!   r"   Úbuild_scenariosk  sD    ü



ÿ
þz&ScenarioOutlineBuilder.build_scenarios)NN)N)N)N)rh   ri   rj   rk   r   Ústaticmethodr™   r©   Úclassmethodr®   r·   r¹   r!   r!   r!   r"   r�     s   
#r�   c                       s�   e Zd ZdZdZdZd‡ fdd„	Z‡ fdd„Zed	d
„ ƒZ	dd„ Z
dd„ Zdd„ Zedd„ ƒZdd„ Zdd„ Zdd„ Zddd„Zdd„ Z‡  ZS ) r7   aí  A `scenario outline`_ parsed from a *feature file*.

    A scenario outline extends the existing :class:`~behave.model.Scenario`
    class with the addition of the :class:`~behave.model.Examples` tables of
    data from the *feature file*.

    The attributes are:

    .. attribute:: keyword

       This is the keyword as seen in the *feature file*. In English this will
       typically be "Scenario Outline".

    .. attribute:: name

       The name of the scenario (the text after "Scenario Outline:".)

    .. attribute:: description

       The description of the `scenario outline`_ as seen in the *feature file*.
       This is stored as a list of text lines.

    .. attribute:: feature

       The :class:`~behave.model.Feature` this scenario outline belongs to.

    .. attribute:: steps

       A list of :class:`~behave.model.Step` making up this scenario outline.

    .. attribute:: examples

       A list of :class:`~behave.model.Examples` used by this scenario outline.

    .. attribute:: tags

       A list of @tags (as :class:`~behave.model.Tag` which are basically
       glorified strings) attached to the scenario.
       See :ref:`controlling things with tags`.

    .. attribute:: status

       Read-Only. A summary status of the scenario outlines's run. If read
       before the scenario is fully tested it will return "untested" otherwise
       it will return one of:

       Status.untested
         The scenario was has not been completely tested yet.
       Status.skipped
         One or more scenarios of this outline was passed over during testing.
       Status.passed
         The scenario was tested successfully.
       Status.failed
         One or more scenarios of this outline failed.

        .. versionchanged:: 1.2.6
            Use Status enum class (was: string)

    .. attribute:: duration

       The time, in seconds, that it took to test the scenarios of this
       outline. If read before the scenarios are tested it will return 0.0.

    .. attribute:: filename

       The file name (or "<string>") of the *feature file* where the scenario
       was found.

    .. attribute:: line

       The line number of the *feature file* where the scenario was found.

    .. _`scenario outline`: gherkin.html#scenario-outlines
    r9   z#{name} -- @{row.id} {examples.name}Nc	           	   	      s0   t t| ƒ |||||||¡ |p"g | _g | _d S r(   )r   r7   r   r£   Ú
_scenarios)	r   r   r   r   r   r   rp   r£   r   r   r!   r"   r   â  s
    ÿ
zScenarioOutline.__init__c                    s&   t t| ƒ ¡  | jD ]}| ¡  qdS )z4Reset runtime temporary data like before a test run.N)r   r7   r#   r¼   r$   r   r!   r"   r#   é  s    
zScenarioOutline.resetc                 C   s(   | j r| j S t| jƒ}| | ¡| _ | j S )zbReturn the scenarios with the steps altered to take the values from
        the examples.
        )r¼   r�   r�   r¹   )r   Úbuilderr!   r!   r"   r   ï  s
    
zScenarioOutline.scenariosc                 C   s
   d| j  S )Nz<ScenarioOutline "%s">rq   r&   r!   r!   r"   r'   ü  s    zScenarioOutline.__repr__c                 C   s
   t | jƒS r(   r)   r&   r!   r!   r"   r+   ÿ  s    zScenarioOutline.__iter__c                 C   sb   d}| j D ]4}|j}|tjtjfv r,|  S |tjkr
|d7 }q
|dkr\|t| j ƒkr\tjS tjS )Nr   r-   )r¼   r/   r   r.   r0   r1   r%   r2   )r   Zskipped_countr   r3   r!   r!   r"   r4     s    


zScenarioOutline.compute_statusc                 C   s   d}| j D ]}||j7 }q
|S rr   )r¼   r5   )r   Zoutline_durationr   r!   r!   r"   r5     s    
zScenarioOutline.durationc                 C   s0   |  | j¡rdS | jD ]}| |¡r dS qdS )a  Determines if this scenario outline (or one of its scenarios)
        should run when the tag expression is used.

        :param tag_expression:  Runner/config environment tags to use.
        :return: True, if scenario should run. False, otherwise (skip it).
        TF)r@   r‚   r   r<   )r   rA   r   r!   r!   r"   r<     s    

z$ScenarioOutline.should_run_with_tagsc                 C   s*   |j s
dS | jD ]}| |¡r dS qdS )rƒ   TF)r   r   r]   )r   r>   r   r!   r!   r"   r]   '  s    

z+ScenarioOutline.should_run_with_name_selectc                 C   s    | j dd� | jtjksJ ‚dS )z«Marks this scenario outline (and all its scenarios/steps) as skipped.
        Note that this method may be called before the scenario outline
        is executed.
        TrC   N)rE   r/   r   r1   r&   r!   r!   r"   rF   7  s    zScenarioOutline.mark_skippedFc                 C   sj   |rt  d¡}| d| j|¡ |  ¡  d| _| jD ]}| ||¡ q2| jsV|  t	j
¡ | j| jv sfJ ‚dS )a  Skip from executing this scenario outline or its remaining parts.
        Note that the scenario outline may be already partly executed
        when this method is called.

        :param reason:  Optional reason why it should be skipped (as string).
        rG   zSKIP ScenarioOutline %s: %sTN)rH   rI   rJ   r   rK   r;   r   rE   rM   r   r1   r/   rN   rO   r!   r!   r"   rE   ?  s    

zScenarioOutline.skipc                 C   sf   |   ¡  d}| jD ]<}|j d|j¡ | |¡}|r|d7 }|jjsJ|jr qPq|j dd ¡ |dkS )Nr   Zactive_outliner-   )	rK   r   rU   r‡   rv   r^   r>   r_   rX   )r   rc   rd   r   r.   r!   r!   r"   r^   S  s    

zScenarioOutline.run)NNNN)NF)rh   ri   rj   rk   rl   r�   r   r#   rm   r   r'   r+   r4   r5   r<   r]   rF   rE   r^   rn   r!   r!   r   r"   r7   ”  s&   J  ÿ


r7   c                       s&   e Zd ZdZdZd‡ fdd„	Z‡  ZS )ÚExamplesaÑ  A table parsed from a `scenario outline`_ in a *feature file*.

    The attributes are:

    .. attribute:: keyword

       This is the keyword as seen in the *feature file*. In English this will
       typically be "Example".

    .. attribute:: name

       The name of the example (the text after "Example:".)

    .. attribute:: table

       An instance  of :class:`~behave.model.Table` that came with the example
       in the *feature file*.

    .. attribute:: filename

       The file name (or "<string>") of the *feature file* where the example
       was found.

    .. attribute:: line

       The line number of the *feature file* where the example was found.

    .. _`examples`: gherkin.html#examples
    r£   Nc                    s(   t t| ƒ |||||¡ || _d | _d S r(   )r   r¾   r   r°   rŸ   )r   r   r   r   r   r   r°   r   r!   r"   r   ƒ  s    zExamples.__init__)NN)rh   ri   rj   rk   rl   r   rn   r!   r!   r   r"   r¾   c  s   r¾   c                       s\   e Zd ZdZdZd‡ fdd„	Z‡ fdd„Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
ddd„Z‡  ZS )ÚStepaj  A single `step`_ parsed from a *feature file*.

    The attributes are:

    .. attribute:: keyword

       This is the keyword as seen in the *feature file*. In English this will
       typically be "Given", "When", "Then" or a number of other words.

    .. attribute:: name

       The name of the step (the text after "Given" etc.)

    .. attribute:: step_type

       The type of step as determined by the keyword. If the keyword is "and"
       then the previous keyword in the *feature file* will determine this
       step's step_type.

    .. attribute:: text

       An instance of :class:`~behave.model.Text` that came with the step
       in the *feature file*.

    .. attribute:: table

       An instance of :class:`~behave.model.Table` that came with the step
       in the *feature file*.

    .. attribute:: status

       Read-Only. A summary status of the step's run. If read before the
       step is tested it will return "untested" otherwise it will
       return one of:

       Status.untested
         This step was not run (yet).
       Status.skipped
         This step was skipped during testing.
       Status.passed
         The step was tested successfully.
       Status.failed
         The step failed.
       Status.undefined
         The step has no matching step implementation.

       .. versionchanged::
            Use Status enum class (was: string).

    .. attribute:: hook_failed

        Indicates if a hook failure occured while running this step.

        .. versionadded:: 1.2.6

    .. attribute:: duration

       The time, in seconds, that it took to test this step. If read before the
       step is tested it will return 0.0.

    .. attribute:: error_message

       If the step failed then this will hold any error information, as a
       single string. It will otherwise be None.

       .. versionchanged:: 1.2.6 (moved to base class)

    .. attribute:: filename

       The file name (or "<string>") of the *feature file* where the step was
       found.

    .. attribute:: line

       The line number of the *feature file* where the step was found.

    .. _`step`: gherkin.html#steps
    rs   Nc                    s@   t t| ƒ ||||¡ || _|| _|| _tj| _d| _	d| _
d S )NFr   )r   r¿   r   Ú	step_typer   r°   r   r0   r/   r   r5   )r   r   r   r   rÀ   r   r   r°   r   r!   r"   r   Ú  s    zStep.__init__c                    s&   t t| ƒ ¡  tj| _d| _d| _dS )z8Reset temporary runtime data to reach clean state again.Fr   N)r   r¿   r#   r   r0   r/   r   r5   r&   r   r!   r"   r#   å  s    z
Step.resetc                 C   s   d| j | jf S )Nz	<%s "%s">©rÀ   r   r&   r!   r!   r"   r'   í  s    zStep.__repr__c                 C   s   | j | jf|j |jfkS r(   rÁ   ©r   Úotherr!   r!   r"   Ú__eq__ð  s    zStep.__eq__c                 C   s   t | jƒt | jƒ S r(   )ÚhashrÀ   r   r&   r!   r!   r"   Ú__hash__ó  s    zStep.__hash__c                 C   s(   ddl }|jdtdd� | }t ||¡S )aK  Clone a new step from this one, used for ScenarioOutline.
        Replace ScenarioOutline placeholders w/ values.

        :param table_row:  Placeholder data for example row.
        :return: Cloned, adapted step object.

        .. note:: Deprecating
            Use 'ScenarioOutlineBuilder.make_step_for_row()' instead.
        r   Nz1Use 'ScenarioOutline.make_step_for_row()' insteadé   )Ú
stacklevel)ÚwarningsÚwarnÚPendingDeprecationWarningr�   r·   )r   Z	table_rowrÉ   r³   r!   r!   r"   Ú
set_valuesö  s    
ÿzStep.set_valuesFTc              
   C   sÀ  |   ¡  |j | ¡}|d u rj|j | ¡ |sD|jD ]}| tƒ ¡ q2tj	| _
|sf|jD ]}| | ¡ qVdS d}d}|sŒ|jD ]}| |¡ q||r˜| ¡  d}| d|j| ¡ | jr¶d}t ¡ }	|�sÞz8| j|j_| j|j_| |j¡ | j
tjkrútj| _
W nà t�y> }
 z(d|_d}tj| _
|  |
¡ W Y d }
~
n¨d }
~
0  t�yš }
 zDtj| _
|  |
¡ |
j�rzt|
ƒ}d| }ntt ¡ ƒ}W Y d }
~
nLd }
~
0  t�yÜ }
 z*tj| _
tt ¡ ƒ}|  |
¡ W Y d }
~
n
d }
~
0 0 t ¡ |	 | _ | d|j| ¡ | j�rtj| _
|�r| !¡  d}| j
tjk�p.|}| j
tjk�rˆt"|t#j$ƒ�sPJ ‚|�r||j%j&| _&| j& '¡ }|�r||d| 7 }|| _(d}n|�rž|�rž|j%j&| _&|�s¼|jD ]}| | ¡ �qª|S )	NFTrš   Zbefore_stepz%ABORTED: By user (KeyboardInterrupt).zAssertion Failed: Z
after_stepÚ
))r#   rˆ   r‰   rŠ   r,   r\   r‹   r
   r   r�   r/   rŒ   Zstart_capturerZ   rU   r   Útimer   r°   r^   r0   r2   ÚKeyboardInterruptrX   r.   Zstore_exception_contextÚAssertionErrorÚargsr¸   Ú	tracebackÚ
format_excra   r5   Zstop_capturer6   ÚsixÚ	text_typer�   r…   Zmake_reportÚerror_message)r   rc   ÚquietÚcapturer‹   rg   Z
keep_goingÚerrorZskip_step_untestedÚstartÚeÚmessageZstore_captured_alwaysrŽ   Zerror2r!   r!   r"   r^     sŒ    






  



zStep.run)NN)FT)rh   ri   rj   rk   rl   r   r#   r'   rÄ   rÆ   rÌ   r^   rn   r!   r!   r   r"   r¿   ‰  s   N  ÿr¿   c                   @   sš   e Zd ZdZdZd%dd„Zd&dd„Zd'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S )(ÚTablea>  A `table`_ extracted from a *feature file*.

    Table instance data is accessible using a number of methods:

    **iteration**
      Iterating over the Table will yield the :class:`~behave.model.Row`
      instances from the .rows attribute.

    **indexed access**
      Individual rows may be accessed directly by index on the Table instance;
      table[0] gives the first non-heading row and table[-1] gives the last
      row.

    The attributes are:

    .. attribute:: headings

       The headings of the table as a list of strings.

    .. attribute:: rows

       An list of instances of :class:`~behave.model.Row` that make up the body
       of the table in the *feature file*.

    Tables are also comparable, for what that's worth. Headings and row data
    are compared.

    .. _`table`: gherkin.html#table
    r°   Nc                 C   s:   t  | ¡ || _|| _g | _|r6|D ]}|  ||¡ q$d S r(   )r	   r   Úheadingsr   ÚrowsÚadd_row)r   rÞ   r   rß   r–   r!   r!   r"   r   ˆ  s    
zTable.__init__c                 C   s   | j  t| j||ƒ¡ d S r(   )rß   r,   ÚRowrÞ   )r   r–   r   r!   r!   r"   rà   ‘  s    zTable.add_rowrš   c           	      C   sÀ   |   |¡rJ ‚|du r(|gt| jƒ }nt|tƒs:t|ƒ}t|ƒt| jƒk rrt| jƒt|ƒ }|g| }| |¡ t| jƒ}| j |¡ t| j|ƒD ]&\}}t|j	ƒ|ks®J ‚|j	 |¡ q”|S )a  Adds a new column to this table.
        Uses :param:`default_value` for new cells (if :param:`values` are
        not provided). param:`values` are extended with :param:`default_value`
        if values list is smaller than the number of table rows.

        :param column_name: Name of new column (as string).
        :param values: Optional list of cell values in new column.
        :param default_value: Default value for cell (if values not provided).
        :returns: Index of new column (as number).
        N)
Ú
has_columnr%   rß   r6   Úlistr8   rÞ   r,   r   r²   )	r   Úcolumn_nameÚvaluesÚdefault_valueZ	more_sizeZmore_valuesZnew_column_indexr–   r˜   r!   r!   r"   Ú
add_column”  s    



zTable.add_columnc                 C   sŠ   t |tƒs8z|  |¡}W n ty6   td| ƒ‚Y n0 t |tƒsFJ ‚|t| jƒk sXJ ‚| j|= | jD ]}|t|jƒk s|J ‚|j|= qfd S )Nzcolumn=%s is unknown)	r6   ÚintÚget_column_indexÚ
ValueErrorÚKeyErrorr%   rÞ   rß   r²   )r   rä   Úcolumn_indexr–   r!   r!   r"   Úremove_column±  s    

zTable.remove_columnc                 C   s   |D ]}|   |¡ qd S r(   )rí   ©r   Zcolumn_namesrä   r!   r!   r"   Úremove_columns¿  s    zTable.remove_columnsc                 C   s
   || j v S r(   )rÞ   ©r   rä   r!   r!   r"   râ   Ã  s    zTable.has_columnc                 C   s   | j  |¡S r(   )rÞ   rŸ   rð   r!   r!   r"   ré   Æ  s    zTable.get_column_indexc                 C   s4   |   |¡s*d | j¡}d||f }t|ƒ‚|  |¡S )zéRequire that a column exists in the table.
        Raise an AssertionError if the column does not exist.

        :param column_name: Name of new column (as string).
        :return: Index of column (as number) if it exists.
        z, z REQUIRE COLUMN: %s (columns: %s))râ   ÚjoinrÞ   rÐ   ré   )r   rä   ÚcolumnsÚmsgr!   r!   r"   Úrequire_columnÉ  s
    
zTable.require_columnc                 C   s   |D ]}|   |¡ qd S r(   )rô   rî   r!   r!   r"   Úrequire_columnsÖ  s    zTable.require_columnsc                 C   s"   |   |¡r|  |¡S |  |¡S dS )zÜEnsures that a column with the given name exists.
        If the column does not exist, the column is added.

        :param column_name: Name of column (as string).
        :return: Index of column (as number).
        N)râ   ré   rç   rð   r!   r!   r"   Úensure_column_existsÚ  s    

zTable.ensure_column_existsc                 C   s   dt | jƒt | jƒf S )Nz<Table: %dx%d>)r%   rÞ   rß   r&   r!   r!   r"   r'   æ  s    zTable.__repr__c                 C   sn   t |tƒrB| j|jkrdS t| j|jƒD ]\}}||kr( dS q(n(|}t| j|ƒD ]\}}||krR dS qRdS )NFT)r6   rÝ   rÞ   r   rß   )r   rÃ   Zmy_rowZ	their_rowZ
other_rowsr!   r!   r"   rÄ   é  s    

zTable.__eq__c                 C   s   |   |¡ S r(   ©rÄ   rÂ   r!   r!   r"   Ú__ne__ø  s    zTable.__ne__c                 C   s
   t | jƒS r(   )r*   rß   r&   r!   r!   r"   r+   û  s    zTable.__iter__c                 C   s
   | j | S r(   )rß   )r   rŸ   r!   r!   r"   Ú__getitem__þ  s    zTable.__getitem__c                 C   s   | |ksJ ‚t ‚dS )a@  Assert that this table's cells are the same as the supplied "data".

        The data passed in must be a list of lists giving:

            [
                [row 1],
                [row 2],
                [row 3],
            ]

        If the cells do not match then a useful AssertionError will be raised.
        N)ÚNotImplementedError)r   Údatar!   r!   r"   Úassert_equals  s    zTable.assert_equals)NN)N)Nrš   )rh   ri   rj   rk   rl   r   rà   rç   rí   rï   râ   ré   rô   rõ   rö   r'   rÄ   rø   r+   rù   rü   r!   r!   r!   r"   rÝ   h  s$   
	

rÝ   c                   @   sd   e Zd ZdZd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„ ZdS )rá   aS  One row of a `table`_ parsed from a *feature file*.

    Row data is accessible using a number of methods:

    **iteration**
      Iterating over the Row will yield the individual cells as strings.

    **named access**
      Individual cells may be accessed by heading name; row["name"] would give
      the cell value for the column with heading "name".

    **indexed access**
      Individual cells may be accessed directly by index on the Row instance;
      row[0] gives the first cell and row[-1] gives the last cell.

    The attributes are:

    .. attribute:: cells

       The list of strings that form the cells of this row.

    .. attribute:: headings

       The headings of the table as a list of strings.

    Rows are also comparable, for what that's worth. Only the cells are
    compared.

    .. _`table`: gherkin.html#table
    Nc                 C   s6   || _ || _|D ]}t|tjƒsJ ‚q|| _|| _d S r(   )rÞ   Úcommentsr6   rÔ   rÕ   r²   r   )r   rÞ   r²   r   rý   Úcr!   r!   r"   r   1  s    zRow.__init__c                 C   sJ   z| j  |¡}W n. ty>   t|tƒr.|}ntd| ƒ‚Y n0 | j| S )Nz"%s" is not a row heading)rÞ   rŸ   rê   r6   rè   rë   r²   r¡   r!   r!   r"   rù   9  s    
zRow.__getitem__c                 C   s   d| j f S )Nz<Row %r>©r²   r&   r!   r!   r"   r'   C  s    zRow.__repr__c                 C   s   | j |j kS r(   rÿ   rÂ   r!   r!   r"   rÄ   F  s    z
Row.__eq__c                 C   s   |   |¡ S r(   r÷   rÂ   r!   r!   r"   rø   I  s    z
Row.__ne__c                 C   s
   t | jƒS r(   )r%   r²   r&   r!   r!   r"   Ú__len__L  s    zRow.__len__c                 C   s
   t | jƒS r(   )r*   r²   r&   r!   r!   r"   r+   O  s    zRow.__iter__c                 C   s   t | j| jƒS r(   )r   rÞ   r²   r&   r!   r!   r"   r”   R  s    z	Row.itemsc                 C   s&   z
| | W S  t y    | Y S 0 d S r(   )rë   )r   ÚkeyÚdefaultr!   r!   r"   ÚgetU  s    
zRow.getc                 C   s   ddl m} ||  ¡ ƒS )z…Converts the row and its cell data into a dictionary.
        :return: Row data as dictionary (without comments, line info).
        r   )ÚOrderedDict)Zbehave.compat.collectionsr  r”   )r   r  r!   r!   r"   Úas_dict[  s    zRow.as_dict)NN)N)rh   ri   rj   rk   r   rù   r'   rÄ   rø   r   r+   r”   r  r  r!   r!   r!   r"   rá     s   


rá   c                   @   s.   e Zd ZdZdZdZdd„ Zed
dd	„ƒZdS )r«   a  Tags appear may be associated with Features or Scenarios.

    They're a subclass of regular strings (unicode pre-Python 3) with an
    additional ``line`` number attribute (where the tag was seen in the source
    feature file.

    See :ref:`controlling things with tags`.
    z._-=:)ú'ú"r‘   r’   c                 C   s   t j | |¡}||_|S r(   )rÔ   rÕ   Ú__new__r   )r­   r   r   Úor!   r!   r"   r  o  s    zTag.__new__FNc                 C   sŒ   t |tjƒsJ ‚|du r| j}|r6| dd¡ dd¡}g }|D ]B}| ¡ sV|rb||v rb| |¡ q>| ¡ rv| d¡ q>|| jv r>q>d 	|¡S )aW  Translate text into a "valid tag" without whitespace, etc.
        Translation rules are:
          * alnum chars => same, kept
          * space chars => "_"
          * other chars => deleted

        Preserve following characters (in addition to alnums, like: A-z, 0-9):
          * dots        => "." (support: dotted-names, active-tag name schema)
          * minus       => "-" (support: dashed-names)
          * underscore  => "_"
          * equal       => "=" (support: active-tag name schema)
          * colon       => ":" (support: active-tag name schema or similar)

        :param text: Unicode text as input for name.
        :param unescape: Optional flag to unescape some chars (default: false)
        :param allowed_chars: Optional string with additional preserved chars.
        :return: Unicode name that can be used as tag.
        Nz\tú	z\nrÍ   Ú_rš   )
r6   rÔ   rÕ   Úallowed_charsr•   Úisalnumr,   ÚisspaceÚquoting_charsrñ   )r­   r   rª   r  ÚcharsÚcharr!   r!   r"   r¬   t  s    
zTag.make_name)FN)	rh   ri   rj   rk   r  r  r  r»   r¬   r!   r!   r!   r"   r«   c  s   r«   c                       s<   e Zd ZdZddd„Zdd„ Zd‡ fd	d
„	Zdd„ Z‡  ZS )ÚTextzâStore multiline text from a Step definition.

    The attributes are:

    .. attribute:: value

       The actual text parsed from the *feature file*.

    .. attribute:: content_type

       Currently only "text/plain".
    ú
text/plainr   c                 C   s>   t |tjƒsJ ‚t |tjƒs J ‚tj | |¡}||_||_|S r(   )r6   rÔ   rÕ   r  Úcontent_typer   )r­   r˜   r  r   r	  r!   r!   r"   r  «  s    zText.__new__c                 C   s    t |  ¡ ƒ}| j| j| d fS )Nr-   )r%   Ú
splitlinesr   )r   Ú
line_countr!   r!   r"   Ú
line_range³  s    zText.line_rangeéÿÿÿÿc                    s    t tt | ƒ |||¡| j| jƒS r(   )r  r   r•   r  r   )r   ÚoldÚnewÚcountr   r!   r"   r•   ·  s    ÿzText.replacec                 C   sX   | |krdS g }t  |  ¡ | ¡ ¡D ]}| |¡ q$dg|dd…  }td |¡ƒ‚dS )z†Assert that my text is identical to the "expected" text.

        A nice context diff will be displayed if they do not match.
        TzText does not match:é   NrÍ   )ÚdifflibZunified_diffr  r,   rÐ   rñ   )r   ÚexpectedÚdiffr   r!   r!   r"   rü   »  s    
ÿzText.assert_equals)r  r   )r  )	rh   ri   rj   rk   r  r  r•   rü   rn   r!   r!   r   r"   r  ž  s
   
r  c                 C   s   | D ]}|  ¡  qdS )zŠReset the test run information stored in model elements.

    :param model_elements:  List of model elements (Feature, Scenario, ...)
    N)r#   )Zmodel_elementsZmodel_elementr!   r!   r"   Úreset_modelÎ  s    r   )(rk   Ú
__future__r   r   rz   r  rH   r   rÎ   rÔ   Z	six.movesr   Zbehave.model_corer   r   r   r   r	   Zbehave.matchersr
   Zbehave.textutilr   r¸   ÚPY2Z
traceback2rÒ   r   ro   rt   r¥   r�   r7   r¾   r¿   rÝ   rá   rÕ   r«   r  r   r!   r!   r!   r"   Ú<module>   sD   

  F6  u  P& ` +Q;0