U
    ‰ª/eà  ã                   @   sä   d Z ddl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
Z
ddlZddlmZ ddlmZ ddlmZmZmZmZ G d	d
„ d
ƒZG dd„ deƒZG dd„ deƒZG dd„ dejƒZdd„ Zdd„ Zedkràe ¡  dS )z* Tests for zmq shell / display publisher. é    N)ÚQueue)ÚThread)Ú	MagicMock)ÚSession)ÚInt)ÚInteractiveShellÚKernelMagicsÚZMQDisplayPublisherÚZMQInteractiveShellc                   @   s   e Zd ZdZdZdd„ ZdS )ÚNoReturnDisplayHookz¢
    A dummy DisplayHook which allows us to monitor
    the number of times an object is called, but which
    does *not* return a message when it is called.
    r   c                 C   s   |  j d7  _ d S )Né   )Ú
call_count©ÚselfÚobj© r   úB/tmp/pip-unpacked-wheel-g43y689f/ipykernel/tests/test_zmq_shell.pyÚ__call__#   s    zNoReturnDisplayHook.__call__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r      s   r   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )ÚReturnDisplayHookz’
    A dummy DisplayHook with the same counting ability
    as its base class, but which also returns the same
    message when it is called.
    c                    s   t ƒ  |¡ |S ©N)Úsuperr   r   ©Ú	__class__r   r   r   .   s    zReturnDisplayHook.__call__)r   r   r   r   r   Ú__classcell__r   r   r   r   r   '   s   r   c                       s(   e Zd ZdZedƒZ‡ fdd„Z‡  ZS )ÚCounterSessionz
    This is a simple subclass to allow us to count
    the calls made to the session object by the display
    publisher.
    r   c                    s    |  j d7  _ tƒ j||Ž dS )zu
        A trivial override to just augment the existing call
        with an increment to the send counter.
        r   N)Ú
send_countr   Úsend)r   ÚargsÚkwargsr   r   r   r    <   s    zCounterSession.send)r   r   r   r   r   r   r    r   r   r   r   r   r   3   s   r   c                   @   sP   e Zd Z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 )ÚZMQDisplayPublisherTestsz6
    Tests the ZMQDisplayPublisher in zmqshell.py
    c                 C   s8   t  ¡ | _| j t j¡| _tƒ | _t| j| jd| _d S )N)ÚsessionÚ
pub_socket)	ÚzmqÚContextÚcontextÚsocketÚPUBr   r$   r	   Údisp_pub©r   r   r   r   ÚsetUpJ   s    
zZMQDisplayPublisherTests.setUpc                 C   s"   | j  ¡  | j ¡  | j ¡  dS )z¿
        We need to close the socket in order to proceed with the
        tests.
        TODO - There is still an open file handler to '/dev/null',
        presumably created by zmq.
        N)r+   Zclear_outputr)   Úcloser(   Ztermr,   r   r   r   ÚtearDownQ   s    

z!ZMQDisplayPublisherTests.tearDownc                 C   s(   | j j| jkst‚| j j| jks$t‚dS )z
        Since there's no explicit constructor, here we confirm
        that keyword args get assigned correctly, and override
        the defaults.
        N)r+   r$   ÚAssertionErrorr%   r)   r,   r   r   r   Útest_display_publisher_creation\   s    z8ZMQDisplayPublisherTests.test_display_publisher_creationc                    sx   ˆj jg kst‚dd„ }ˆj  |¡ ˆj j|gks6t‚tƒ ‰ ‡ ‡fdd„}t|d}| ¡  ˆ jdd}|g kstt‚dS )	z„
        Confirms that the thread_local attribute is correctly
        initialised with an empty list for the display hooks
        c                 S   s   | S r   r   )Úmsgr   r   r   Úhookl   s    z>ZMQDisplayPublisherTests.test_thread_local_hooks.<locals>.hookc                      s   ˆ   ˆjj¡ d S r   )Úputr+   Ú_hooksr   ©Úqr   r   r   Úset_thread_hookst   s    zJZMQDisplayPublisherTests.test_thread_local_hooks.<locals>.set_thread_hooks)Útargeté
   )ÚtimeoutN)r+   r5   r0   Úregister_hookr   r   ÚstartÚget)r   r3   r8   ÚtZthread_hooksr   r6   r   Útest_thread_local_hookse   s    
z0ZMQDisplayPublisherTests.test_thread_local_hooksc                 C   s:   t dd}| jjdkst‚| j |¡ | jjdks6t‚dS )zc
        Publish should prepare the message and eventually call
        `send` by default.
        r   ©Úar   N)Údictr$   r   r0   r+   Úpublish)r   Údatar   r   r   Útest_publish|   s    
z%ZMQDisplayPublisherTests.test_publishc                 C   sh   t dd}tƒ }| j |¡ |jdks*t‚| jjdks:t‚| j |¡ |jdksTt‚| jjdksdt‚dS )zé
        If a hook is installed, and on calling the object
        it does *not* return a message, then we assume that
        the message has been consumed, and should not be
        processed (`sent`) in the normal manner.
        r   rA   r   N)	rC   r   r+   r<   r   r0   r$   r   rD   ©r   rE   r3   r   r   r   Útest_display_hook_halts_send†   s    
z5ZMQDisplayPublisherTests.test_display_hook_halts_sendc                 C   sh   t dd}tƒ }| j |¡ |jdks*t‚| jjdks:t‚| j |¡ |jdksTt‚| jjdksdt‚dS )zã
        If a hook is installed and on calling the object
        it returns a new message, then we assume that this
        is just a message transformation, and the message
        should be sent in the usual manner.
        r   rA   r   N)	rC   r   r+   r<   r   r0   r$   r   rD   rG   r   r   r   Ú#test_display_hook_return_calls_send™   s    
z<ZMQDisplayPublisherTests.test_display_hook_return_calls_sendc                 C   s¾   t dd}tƒ }| j |¡ |jdks*t‚| jjdks:t‚| j |¡ |jdksTt‚| jjdksdt‚| j 	|¡}| j |¡ |  
|¡ |jdks”t‚| jjdks¤t‚| j 	|¡}|  |¡ dS )z`
        Once a hook is unregistered, it should not be called
        during `publish`.
        r   rA   r   N)rC   r   r+   r<   r   r0   r$   r   rD   Zunregister_hookÚ
assertTrueZassertFalse)r   rE   r3   ÚfirstÚsecondr   r   r   Útest_unregister_hook¬   s    

z-ZMQDisplayPublisherTests.test_unregister_hookN)r   r   r   r   r-   r/   r1   r@   rF   rH   rI   rM   r   r   r   r   r#   E   s   	
r#   c                 C   s˜   t  ¡ }| t j¡}tƒ }d|jd< t|ƒ}| d }| dd¡ | t	|ƒ¡ | 
g ¡ | t	|ƒ¡ tjdkrz| d¡ | d¡ | ¡  | ¡  d S )Nr   Úhiztest.txtÚutf8ÚposixÚlsÚ10)r&   r'   r)   r*   r   Zuser_nsr   Ú
write_textZeditÚstrÚclearZlessÚosÚnameZmanZautosaver.   Údestroy)Ztmp_pathr(   r)   ÚshellZmagicsZtmp_filer   r   r   Útest_magicsÕ   s    




rZ   c              	   C   s    t ƒ }t t¡ | d¡ W 5 Q R X t ¡   t dt¡ t	ƒ |_
|j W 5 Q R X | |_| d¡ | ¡ d kstt‚tjdkrŠ| d¡ n
| d¡ | ¡  d S )NZtkÚignorerN   rP   rQ   Údir)r
   ÚpytestZraisesÚRuntimeErrorZ
enable_guiÚwarningsÚcatch_warningsÚsimplefilterÚDeprecationWarningr   Zdata_pub_classZdata_pubÚkernelZset_next_inputZ
get_parentr0   rV   rW   Zsystem_pipedZask_exit)rc   rY   r   r   r   Útest_zmq_interactive_shellé   s    



rd   Ú__main__)r   rV   Zunittestr_   Úqueuer   Ú	threadingr   Zunittest.mockr   r]   r&   Zjupyter_client.sessionr   Z	traitletsr   Zipykernel.zmqshellr   r   r	   r
   r   r   r   ZTestCaser#   rZ   rd   r   Úmainr   r   r   r   Ú<module>   s(    