U
    P|jn<  ã                   @  sÈ   U d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	 ddl
mZ ddlmZmZ ddlmZ dd	lmZ dd
lmZmZ ddlmZmZmZ edƒZg Zded< e	ejƒG dd„ deƒƒZdS )z4
Things likely to be used by writers of unit tests.
é    )ÚannotationsN)ÚCallableÚList)Úimplementer)Ú	ParamSpec)ÚdeferÚutils)Ú_T)Úfailure)ÚitrialÚutil)ÚFailTestÚSkipTestÚSynchronousTestCaseÚ_Pz
List[None]Ú_wait_is_runningc                      sÚ   e Zd ZdZd1‡ fdd„	Zddddœdd	„ZeZd
d„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zejdd„ ƒZdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%d&d'd(œ‡ fd)d*„Zd+d,„ Zd-d.„ Zefd/d0„Z‡  ZS )2Ú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 ƒ  |¡ ddlm} || _d| _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.
        r   ©ÚreactorFN)ÚsuperÚ__init__Útwisted.internetr   Ú_twistedPrivateSchedulerÚ_twistedPrivateNeedsTearDown)ÚselfÚ
methodNamer   ©Ú	__class__© ú</tmp/pip-unpacked-wheel-audpp6lv/twisted/trial/_asynctest.pyr   1   s    
zTestCase.__init__zdefer.Deferred[_T]ztype[BaseException])ÚdeferredÚexpectedFailuresÚreturnc                   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| ›�¡‚d S )Nz$did not catch an error, instead got )ÚfailureException)Úignore©r   r   r    Ú_cbR   s    ÿz#TestCase.assertFailure.<locals>._cbc                   s.   | j ˆ Ž r| jS d ˆ t| ƒ¡}ˆ |¡‚d S )Nz
Expected: {!r}
Got:
{})ÚcheckÚvalueÚformatÚstrr$   )r
   Úoutput©r"   r   r   r    Ú_ebW   s    
 ÿz#TestCase.assertFailure.<locals>._eb)ZaddCallbacks)r   r!   r"   r'   r.   r   r-   r    ÚassertFailureI   s    		zTestCase.assertFailurec                   sŠ   ˆ  ¡ ‰‡‡‡‡fdd„}t |tjtd�¡}t |¡rPtd 	|¡ƒ}t
 |¡S t
 tjˆ ¡ |¡}ˆj ˆ||¡‰ | ‡ fdd„¡ |S )Nc                   s–   t  ˆ›dˆ › dˆ› d�¡}t |¡}z|  |¡ W n\ t jk
r�   ˆj ¡  dˆ_ˆ 	¡ }|d k	r€| 
|¡r€ˆ ˆ||¡ nˆ ˆ|¡ Y nX d S )Nz (z) still running at z secsT)r   ÚTimeoutErrorr
   ÚFailureZerrbackZAlreadyCalledErrorr   ÚcrashÚ	_timedOutÚgetTodoÚexpectedÚaddExpectedFailureÚaddError)ÚdÚeÚfÚtodo)ÚfuncDescriptionÚresultr   Útimeoutr   r    Ú	onTimeoutg   s    ÿ

z TestCase._run.<locals>.onTimeout©Úcategoryz9{!r} is a generator function and therefore will never runc                   s   ˆ   ¡ rˆ  ¡ p| S ©N)ÚactiveÚcancel)Úx)Úcallr   r    Ú<lambda>‰   ó    zTestCase._run.<locals>.<lambda>)Ú
getTimeoutr   ÚsuppressWarningsr   ÚsuppressÚDeprecationWarningÚinspectÚisgeneratorfunctionÚ	TypeErrorr*   r   ZfailZmaybeDeferredZrunWithWarningsSuppressedÚ_getSuppressr   Z	callLaterÚaddBoth)r   Úfuncr<   r=   r?   Úexcr8   r   )rF   r<   r=   r   r>   r    Ú_rund   s&     
ÿ
ÿ
  ÿzTestCase._runc                 O  s   | j ||ŽS rB   )Úrun)r   ÚargsÚkwargsr   r   r    Ú__call__Œ   s    zTestCase.__call__c              	   Ã  sJ   z,z|  |¡I d H  W 5 |  |¡I d H  X W 5 | j rD|  |¡I d H  X d S rB   )r   Ú_deferTearDownÚ_deferRunCleanupsÚ_deferSetUpAndRun©r   r=   r   r   r    Ú_deferSetUp�   s    zTestCase._deferSetUpc              
   Ã  s^  z|   | jd|¡I dH  W n¶ tk
rX } z | | |  | j|¡¡ W Y ¢dS d}~X Y nz tk
r˜ } z$| | t |¡¡ | 	¡  W Y ¢dS d}~X Y n: t
k
rÐ } z| | t |¡¡ W Y ¢dS d}~X Y nX d| _zH|   t| | jƒ| j|¡I dH  |  ¡ dk	�r| | |  ¡ ¡ nd| _W n8 t
k
�rX } z|  t |¡|¡ ‚ W 5 d}~X Y nX dS )zc
        Execute the setUp and run part of a test. Teardown and cleanups are not executed.
        ÚsetUpNT)rT   r^   r   ÚaddSkipÚ_getSkipReasonÚKeyboardInterruptr7   r
   r1   ÚstopÚBaseExceptionr   ÚgetattrÚ_testMethodNamer4   ZaddUnexpectedSuccessÚ_passedÚ_ebDeferTestMethod©r   r=   r9   r   r   r    r[   ™   s2    
  ÿ

zTestCase._deferSetUpAndRunc                 C  s    |   ¡ }|d k	r*| |¡r*| | ||¡ nr| | jt¡rF| | |¡ nV| t¡rf| | |¡ | 	¡  n6| t
¡r�| | |  t| | jƒ|j¡¡ n| | |¡ d S rB   )r4   r5   r6   r(   r$   r   Z
addFailurera   r7   rb   r   r_   r`   rd   re   r)   )r   r:   r=   r;   r   r   r    rg   ¸   s    


 ÿzTestCase._ebDeferTestMethodc              
   Ã  sš   z|   | jd|¡I d H  W nz tk
r\ } z$| | t |¡¡ | ¡  d| _W 5 d }~X Y n: tk
r” } z| | t |¡¡ d| _W 5 d }~X Y nX d S )NÚtearDownF)	rT   ri   ra   r7   r
   r1   rb   rf   rc   rh   r   r   r    rY   È   s    zTestCase._deferTearDownc                 #  s�   g }t | jƒdkrp| j ¡ \‰‰ ‰z(|  ‡ ‡‡fdd„dˆj› �|¡V  W q tk
rl   | t ¡ ¡ Y qX q|D ]}| 	| |¡ d| _
qtdS )zf
        Run any scheduled cleanups and report errors (if any) to the result.
        object.
        r   c                     s
   ˆˆ ˆŽS rB   r   r   ©rV   rR   rW   r   r    rG   Þ   rH   z,TestCase._deferRunCleanups.<locals>.<lambda>zcleanup function FN)ÚlenÚ	_cleanupsÚpoprT   Ú__name__Ú	ExceptionÚappendr
   r1   r7   rf   )r   r=   Zfailuresr:   r   rj   r    rZ   Ó   s    
ý
zTestCase._deferRunCleanupsc                 C  s�   zt  | |¡ ¡ }|sd| _W n* tk
rH   | | t ¡ ¡ d| _Y nX | j 	¡ D ]}| | |¡ d| _qT|  
¡  |  ¡  | jrŒ| | ¡ d S )NF)r   Ú_JanitorZpostCaseCleanuprf   rc   r7   r
   r1   Z	_observerZ	getErrorsZflushLoggedErrorsZ_removeObserverZ
addSuccess)r   r=   ÚcleanÚerrorr   r   r    Ú_cleanUpé   s    
zTestCase._cleanUpc                 C  s>   zt  | |¡ ¡  W n$ tk
r8   | | t ¡ ¡ Y nX d S rB   )r   rq   ZpostClassCleanuprc   r7   r
   r1   r\   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.é   )Ú
stacklevelrA   )ÚwarningsÚwarnrL   Ú_reactorMethods)ÚaÚkw©Únamer   r   r    Ú_  s    þûz&TestCase._makeReactorMethod.<locals>._r   )r   r~   r   r   r}   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.
        )r2   Ziteraterb   N)rz   rd   Úsetattrr€   )r   r   r~   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)rz   Úitemsr�   )r   r   r~   Úmethodr   r   r    Ú_undeprecateReactor  s    zTestCase._undeprecateReactorc              	   C  sj   ddl m} |  |¡ d| _z<tj |  |¡¡}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   r‚   r3   r…   r   ZDeferredZfromCoroutiner]   rt   ru   Ú_wait)r   r=   r   r8   r   r   r    Ú_runFixturesAndTest)  s    

zTestCase._runFixturesAndTestzCallable[_P, object]z_P.argsz	_P.kwargsÚNone)r:   rV   rW   r#   c                   s   t ƒ j|f|ž|ŽS )ar  
        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.

        If the function takes more than C{timeout} settings, then the test will
        raise an error.
        )r   Ú
addCleanup)r   r:   rV   rW   r   r   r    r‰   @  s    zTestCase.addCleanupc                 C  s   |   ¡ S rB   )rP   r&   r   r   r    ÚgetSuppressO  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.
        r>   z)'timeout' attribute needs to be a number.r@   N)
r   ZacquireAttributeÚ_parentsZDEFAULT_TIMEOUT_DURATIONÚfloatÚ
ValueErrorrO   rx   ry   rL   )r   r>   r   r   r    rI   R  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| 
|¡ ˆr�W ¢DdS | 
|¡ |ˆ _zˆ  ¡  W 5 ˆ `X ˆs¾| jrÆW ¢dS tƒ ‚W 5 d‰| 	¡  X dS )zATake a Deferred that only ever callbacks. Block until it happens.z_wait is not reentrantr   r   c                   s   ˆ d k	rˆ   | ¡ d S rB   )rp   )Úany)Úresultsr   r    rp   r  s    zTestCase._wait.<locals>.appendc                   s   ˆd k	rˆ   ¡  d S rB   ©r2   )Zign©r   r�   r   r    r2   v  s    zTestCase._wait.<locals>.crashzreactor\.crash cannot be used.*)ÚmessagerA   c                     s   ˆ   ¡  d S rB   r�   r   r   r   r    rb   �  s    zTestCase._wait.<locals>.stopN)ÚRuntimeErrorr   r   r   rJ   r   rK   rL   rp   rm   rQ   rb   rU   r3   ra   )r   r8   Zrunningrp   r2   rb   r   r‘   r    r†   i  sH     ÿþ ÿþ




zTestCase._wait)r   )rn   Ú
__module__Ú__qualname__Ú__doc__r   r/   ZfailUnlessFailurerT   rX   r]   r[   rg   rY   r   ZinlineCallbacksrZ   rt   ru   r€   r‚   r…   r‡   r‰   rŠ   rI   r   r†   Ú__classcell__r   r   r   r    r   !   s,   (

r   )r–   Ú
__future__r   rM   rx   Útypingr   r   Zzope.interfacer   Ztyping_extensionsr   r   r   r   Ztwisted.internet.deferr	   Ztwisted.pythonr
   Ztwisted.trialr   r   Ztwisted.trial._synctestr   r   r   r   r   Ú__annotations__Z	ITestCaser   r   r   r   r    Ú<module>   s   