U
    ڲg                     @   sB   d dl Z d dlZd dlZddlmZ ddlmZ G dd dZdS )    N   )guarantee_single_callable)timeoutc                   @   sP   e Zd ZdZdd ZdddZddd	Zd
d Zdd ZdddZ	dddZ
dS )ApplicationCommunicatorz}
    Runs an ASGI application in a test mode, allowing sending of
    messages to it and retrieval of messages it sends.
    c                 C   sN   t || _|| _t | _t | _t 	tj
| || jj| jj| _d S N)r   applicationscopeasyncioQueueinput_queueoutput_queuecontextvarsContextrunZcreate_taskgetputfuture)selfr   r    r   3/tmp/pip-unpacked-wheel-hay1n6u8/asgiref/testing.py__init__   s    


z ApplicationCommunicator.__init__r   c                    s   zXt|4 I dH 8 z| j I dH  | j   W n tjk
rD   Y nX W 5 Q I dH R X W 5 | j  s| j   z| j I dH  W n tjk
r   Y nX X dS )zV
        Waits for the application to stop itself and returns any exceptions.
        N)r   donecancelr	   CancelledErrorasync_timeoutresult)r   r   r   r   r   wait   s    

zApplicationCommunicator.waitTc                 C   s(   | j  s| j   n|r$| j   d S r   )r   r   r   r   )r   
exceptionsr   r   r   stop0   s    
zApplicationCommunicator.stopc                 C   s*   z| j dd W n tk
r$   Y nX d S )NF)r   )r   RuntimeError)r   r   r   r   __del__7   s    zApplicationCommunicator.__del__c                    s   | j |I dH  dS )z;
        Sends a single message to the application
        N)r   r   )r   messager   r   r   
send_input?   s    z"ApplicationCommunicator.send_inputc                    s   | j  r| j   zFt|4 I dH & | j I dH W  5 Q I dH R  W S Q I dH R X W np tjk
r } zP| j  r| j   n2| j   z| j I dH  W n tj	k
r   Y nX |W 5 d}~X Y nX dS )zX
        Receives a single message from the application, with optional timeout.
        N)
r   r   r   r   r   r   r	   TimeoutErrorr   r   )r   r   er   r   r   receive_outputF   s    

4

z&ApplicationCommunicator.receive_output皙?{Gz?c                    sB   t  }t  | |k r8| j s&dS t|I dH  q| j S )zO
        Checks that there is no message to receive in the given time.
        FN)time	monotonicr   emptyr	   sleep)r   r   intervalstartr   r   r   receive_nothing]   s    
z'ApplicationCommunicator.receive_nothingN)r   )T)r   )r&   r'   )__name__
__module____qualname____doc__r   r   r   r    r"   r%   r.   r   r   r   r   r   	   s   


r   )r	   r   r(   Zcompatibilityr   r   r   r   r   r   r   r   <module>   s
   