U
    ¹êW[*9  ã                   @   s’   d Z ddlmZmZ ddlZddlZddlmZ ddlm	Z	m
Z
 ddlmZ ddlmZmZ ddlmZmZmZ g ZeejƒG d	d
„ d
eƒƒZdS )zP
Things likely to be used by writers of unit tests.

Maintainer: Jonathan Lange
é    )ÚdivisionÚabsolute_importN)Úimplementer)ÚdeferÚutils)Úfailure)ÚitrialÚutil)ÚFailTestÚSkipTestÚSynchronousTestCasec                       sæ   e Zd ZdZd3‡ fdd„	Zdd„ Ze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$„ Zd%d&„ Zd'd(„ Zd)d*„ Z‡ fd+d,„Zd-d.„ Zd/d0„ Zefd1d2„Z‡  ZS )4ÚTestCasea=  
    A unit test. The atom of the unit testing universe.

    This class extends L{SynchronousTestCase} which extends C{unittest.TestCase}
    from the standard library. The main feature is the ability to return
    C{Deferred}s from tests and fixture methods and to have the suite wait for
    those C{Deferred}s to fire.  Also provides new assertions such as
    L{assertFailure}.

    @ivar timeout: A real number of seconds. If set, the test will
    raise an error if it takes longer than C{timeout} seconds.
    If not set, util.DEFAULT_TIMEOUT_DURATION is used.
    ÚrunTestc                    s   t t| ƒ |¡ dS )aŸ  
        Construct an asynchronous test case for C{methodName}.

        @param methodName: The name of a method on C{self}. This method should
        be a unit test. That is, it should be a short method that calls some of
        the assert* methods. If C{methodName} is unspecified,
        L{SynchronousTestCase.runTest} will be used as the test method. This is
        mostly useful for testing Trial.
        N)Úsuperr   Ú__init__)ÚselfÚ
methodName©Ú	__class__© ú:/usr/lib/python3/dist-packages/twisted/trial/_asynctest.pyr   .   s    
zTestCase.__init__c                    s&   ‡fdd„}‡ ‡fdd„}|  ||¡S )zÖ
        Fail if C{deferred} does not errback with one of C{expectedFailures}.
        Returns the original Deferred with callbacks added. You will need
        to return this Deferred from your test case.
        c                    s   ˆ   d| f ¡‚d S )Nz&did not catch an error, instead got %r)ÚfailureException)Úignore©r   r   r   Ú_cbA   s    ÿz#TestCase.assertFailure.<locals>._cbc                    s.   | j ˆ Ž r| jS dˆ t| ƒf }ˆ |¡‚d S )Nz
Expected: %r
Got:
%s)ÚcheckÚvalueÚstrr   )r   Úoutput©ÚexpectedFailuresr   r   r   Ú_ebE   s    

ÿz#TestCase.assertFailure.<locals>._eb)ÚaddCallbacks)r   Zdeferredr    r   r!   r   r   r   ÚassertFailure;   s    zTestCase.assertFailurec                    s    ddl m‰ ˆ ¡ ‰‡‡‡‡‡fdd„}t |tjtd¡}tˆˆƒ}t	 
|¡rhtd|f ƒ}t |¡S t tjˆ ¡ |¡}ˆ ˆ||¡‰ | ‡ fdd„¡ |S )	Nr   ©Úreactorc                    sŒ   t  dˆˆ ˆf ¡}t |¡}z|  |¡ W nZ t jk
r†   ˆ ¡  dˆ_ˆ ¡ }|d k	rv| 	|¡rvˆ 
ˆ||¡ nˆ ˆ|¡ Y nX d S )Nz %r (%s) still running at %s secsT)r   ÚTimeoutErrorr   ÚFailureZerrbackZAlreadyCalledErrorÚcrashÚ	_timedOutÚgetTodoÚexpectedÚaddExpectedFailureÚaddError)ÚdÚeÚfÚtodo)r   r%   Úresultr   Útimeoutr   r   Ú	onTimeoutS   s    ÿ
z TestCase._run.<locals>.onTimeout©Úcategoryz7%r is a generator function and therefore will never runc                    s   ˆ   ¡ rˆ  ¡ p| S ©N)ZactiveZcancel)Úx)Úcallr   r   Ú<lambda>r   ó    zTestCase._run.<locals>.<lambda>)Útwisted.internetr%   Ú
getTimeoutr   ÚsuppressWarningsr	   ÚsuppressÚDeprecationWarningÚgetattrÚinspectZisgeneratorfunctionÚ	TypeErrorr   ZfailZmaybeDeferredZrunWithWarningsSuppressedÚ_getSuppressZ	callLaterÚaddBoth)r   r   r2   r4   ÚmethodÚexcr.   r   )r9   r   r%   r2   r   r3   r   Ú_runP   s.     
ÿ

ÿÿ
  ÿzTestCase._runc                 O   s   | j ||ŽS r7   )Úrun)r   ÚargsÚkwargsr   r   r   Ú__call__v   s    zTestCase.__call__c                 C   s*   |   d|¡}|j| j| j|f|fd |S )NÚsetUp©ZcallbackArgsZerrbackArgs)rH   r"   ÚdeferTestMethodÚ_ebDeferSetUp©r   Úignoredr2   r.   r   r   r   Ú
deferSetUpz   s    þzTestCase.deferSetUpc                 C   sN   |  t¡r$| | |  | j|j¡¡ n| | |¡ |  t¡rB| ¡  |  	d |¡S r7   )
r   r   ÚaddSkipÚ_getSkipReasonrM   r   r-   ÚKeyboardInterruptÚstopÚdeferRunCleanups©r   r   r2   r   r   r   rP   ‚   s    

zTestCase._ebDeferSetUpc                 C   sH   |   | j|¡}|j| j| j|f|fd | | j|¡ | | j|¡ |S )NrN   )rH   Ú_testMethodNamer"   Ú_cbDeferTestMethodÚ_ebDeferTestMethodrE   rX   ÚdeferTearDownrQ   r   r   r   rO   Œ   s    þzTestCase.deferTestMethodc                 C   s(   |   ¡ d k	r| | |   ¡ ¡ nd| _|S )NT)r*   ZaddUnexpectedSuccessÚ_passed)r   rR   r2   r   r   r   r[   –   s    zTestCase._cbDeferTestMethodc                 C   s    |   ¡ }|d k	r*| |¡r*| | ||¡ nr| | jt¡rF| | |¡ nV| t¡rf| | |¡ | 	¡  n6| t
¡r| | |  t| | jƒ|j¡¡ n| | |¡ d S r7   )r*   r+   r,   r   r   r
   Z
addFailurerV   r-   rW   r   rT   rU   rA   rZ   r   )r   r0   r2   r1   r   r   r   r\   ž   s    


þzTestCase._ebDeferTestMethodc                 C   s   |   d|¡}| | j|¡ |S )NZtearDown)rH   Z
addErrbackÚ_ebDeferTearDownrQ   r   r   r   r]   ¯   s    zTestCase.deferTearDownc                 C   s(   |  | |¡ | t¡r| ¡  d| _d S ©NF)r-   r   rV   rW   r^   rY   r   r   r   r_   µ   s    
zTestCase._ebDeferTearDownc                 C   s   |   ¡ }| | j|¡ |S )zd
        Run any scheduled cleanups and report errors (if any to the result
        object.
        )Ú_runCleanupsZaddCallbackÚ_cbDeferRunCleanupsrQ   r   r   r   rX   ¼   s    zTestCase.deferRunCleanupsc                 C   s@   |D ]6\}}|t jkr| | |¡ | t¡r4| ¡  d| _qd S r`   )r   ÚFAILUREr-   r   rV   rW   r^   )r   ZcleanupResultsr2   ÚflagZtestFailurer   r   r   rb   Æ   s    

zTestCase._cbDeferRunCleanupsc                 C   sˆ   zt  | |¡ ¡ }|sd| _W n"   | | t ¡ ¡ d| _Y nX | j ¡ D ]}| | |¡ d| _qL|  	¡  |  
¡  | jr„| | ¡ d S r`   )r	   Ú_JanitorZpostCaseCleanupr^   r-   r   r'   Z	_observerZ	getErrorsZflushLoggedErrorsZ_removeObserverZ
addSuccess)r   r2   ZcleanÚerrorr   r   r   Ú_cleanUpÏ   s    
zTestCase._cleanUpc                 C   s6   zt  | |¡ ¡  W n   | | t ¡ ¡ Y nX d S r7   )r	   re   ZpostClassCleanupr-   r   r'   )r   r2   r   r   r   Ú_classCleanUpà   s    zTestCase._classCleanUpc                    s   ‡ ‡fdd„}|S )z•
        Create a method which wraps the reactor method C{name}. The new
        method issues a deprecation warning and calls the original.
        c                     s(   t jdˆ ˆ f dtd ˆjˆ  | |ŽS )Nz{reactor.%s cannot be used inside unit tests. In the future, using %s will fail the test and may crash or hang the test run.é   )Ú
stacklevelr6   )ÚwarningsÚwarnr@   Ú_reactorMethods)ÚaÚkw©Únamer   r   r   Ú_ì   s    ý üz&TestCase._makeReactorMethod.<locals>._r   )r   rq   rr   r   rp   r   Ú_makeReactorMethodç   s    zTestCase._makeReactorMethodc                 C   s6   i | _ dD ]&}t||ƒ| j |< t|||  |¡ƒ q
dS )zó
        Deprecate C{iterate}, C{crash} and C{stop} on C{reactor}. That is,
        each method is wrapped in a function that issues a deprecation
        warning, then calls the original.

        @param reactor: The Twisted reactor.
        )r(   ZiteraterW   N)rm   rA   Úsetattrrs   )r   r%   rq   r   r   r   Ú_deprecateReactorö   s    zTestCase._deprecateReactorc                 C   s*   | j  ¡ D ]\}}t|||ƒ q
i | _ dS )z•
        Restore the deprecated reactor methods. Undoes what
        L{_deprecateReactor} did.

        @param reactor: The Twisted reactor.
        N)rm   Úitemsrt   )r   r%   rq   rF   r   r   r   Ú_undeprecateReactor  s    zTestCase._undeprecateReactorc                 C   sH   dd„ }g }t | jƒdkr>| j ¡ \}}}| ||||ƒ¡ qt |¡S )z‹
        Run the cleanups added with L{addCleanup} in order.

        @return: A C{Deferred} that fires when all cleanups are run.
        c                    s   ‡ ‡‡fdd„S )Nc                      s
   ˆˆ ˆŽS r7   r   r   ©rJ   r0   rK   r   r   r:     r;   z>TestCase._runCleanups.<locals>._makeFunction.<locals>.<lambda>r   )r0   rJ   rK   r   rx   r   Ú_makeFunction  s    z,TestCase._runCleanups.<locals>._makeFunctionr   )ÚlenZ	_cleanupsÚpopÚappendr	   Z_runSequentially)r   ry   Z	callablesr0   rJ   rK   r   r   r   ra     s    zTestCase._runCleanupsc              	   C   sd   ddl m} |  |¡ d| _z6|  d|¡}z|  |¡ W 5 |  |¡ |  |¡ X W 5 |  |¡ X dS )zÛ
        Really run C{setUp}, the test method, and C{tearDown}.  Any of these may
        return L{defer.Deferred}s. After they complete, do some reactor cleanup.

        @param result: A L{TestResult} object.
        r   r$   FN)	r<   r%   ru   r)   rw   rS   rg   rh   Ú_wait)r   r2   r%   r.   r   r   r   Ú_runFixturesAndTest  s    

zTestCase._runFixturesAndTestc                    s   t t| ƒj|f|ž|ŽS )a	  
        Extend the base cleanup feature with support for cleanup functions which
        return Deferreds.

        If the function C{f} returns a Deferred, C{TestCase} will wait until the
        Deferred has fired before proceeding to the next function.
        )r   r   Ú
addCleanup)r   r0   rJ   rK   r   r   r   r   4  s    zTestCase.addCleanupc                 C   s   |   ¡ S r7   )rD   r   r   r   r   ÚgetSuppress?  s    zTestCase.getSuppressc              	   C   sN   t  | jdt j¡}z
t|ƒW S  ttfk
rH   tjdt	d t j Y S X dS )ae  
        Returns the timeout value set on this test. Checks on the instance
        first, then the class, then the module, then packages. As soon as it
        finds something with a C{timeout} attribute, returns that. Returns
        L{util.DEFAULT_TIMEOUT_DURATION} if it cannot find anything. See
        L{TestCase} docstring for more details.
        r3   z)'timeout' attribute needs to be a number.r5   N)
r	   ZacquireAttributeZ_parentsZDEFAULT_TIMEOUT_DURATIONÚfloatÚ
ValueErrorrC   rk   rl   r@   )r   r3   r   r   r   r=   C  s    
ÿ
ÿzTestCase.getTimeoutc                    sâ   |rt dƒ‚ddlm‰  g ‰‡fdd„}‡ ‡fdd„}t |tjdtd	¡}‡ fd
d„}t |tjdtd	¡}| d¡ zV| 
|¡ ˆrW ¢DdS | 
|¡ |ˆ _zˆ  ¡  W 5 ˆ `X ˆs¾| jrÆW ¢dS tƒ ‚W 5 d‰| 	¡  X dS )zJTake a Deferred that only ever callbacks. Block until it happens.
        z_wait is not reentrantr   r$   c                    s   ˆ d k	rˆ   | ¡ d S r7   )r|   )Úany)Úresultsr   r   r|   a  s    zTestCase._wait.<locals>.appendc                    s   ˆd k	rˆ   ¡  d S r7   ©r(   )Zign©r%   r„   r   r   r(   d  s    zTestCase._wait.<locals>.crashzreactor\.crash cannot be used.*)Úmessager6   c                      s   ˆ   ¡  d S r7   r…   r   r$   r   r   rW   j  s    zTestCase._wait.<locals>.stopN)ÚRuntimeErrorr<   r%   r   r>   r	   r?   r@   r|   r{   rE   rW   rI   r)   rV   )r   r.   Úrunningr|   r(   rW   r   r†   r   r}   Y  sD     ÿÿ ÿÿ




zTestCase._wait)r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r#   ZfailUnlessFailurerH   rL   rS   rP   rO   r[   r\   r]   r_   rX   rb   rg   rh   rs   ru   rw   ra   r~   r   r€   r=   Ú_wait_is_runningr}   Ú__classcell__r   r   r   r   r      s4   &


	r   )r   Z
__future__r   r   rB   rk   Zzope.interfacer   r<   r   r   Ztwisted.pythonr   Ztwisted.trialr   r	   Ztwisted.trial._synctestr
   r   r   rŽ   Z	ITestCaser   r   r   r   r   Ú<module>   s   