U
    ˆjß1  ã                   @   sÜ   d Z ddlZddlmZmZmZmZmZmZm	Z	m
Z
 ddl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 dd
lmZ ddlmZ ddlmZ ddlmZ ejee ee ddœdd„Z G dd„ dejƒZ!dS )z+
Test cases for L{twisted.logger._global}.
é    N)ÚIOÚAnyÚListÚOptionalÚTextIOÚTupleÚTypeÚcast)ÚFailure)Úunittesté   )ÚtextFileLogObserver)ÚMORE_THAN_ONCE_WARNINGÚLogBeginner)ÚILogObserverÚLogEvent)ÚLogLevel)ÚLogger)ÚLogPublisher)ÚnextLine)ÚtestÚactualEventsÚexpectedEventsÚreturnc                    sr   t |ƒt |ƒkr|  ||¡ tƒ ‰ |D ]}ˆ t| ¡ ƒO ‰ q&ttdœ‡ fdd„‰‡fdd„|D ƒ}|  ||¡ dS )a7  
    Compare two sequences of log events, examining only the the keys which are
    present in both.

    @param test: a test case doing the comparison
    @param actualEvents: A list of log events that were emitted by a logger.
    @param expectedEvents: A list of log events that were expected by a test.
    )Úeventr   c                    s,   |   ¡ }|  ¡ D ]}|ˆ kr| |¡ q|S ©N)ÚcopyÚkeysÚpop)r   r   Úkey)ÚallMergedKeys© úC/tmp/pip-unpacked-wheel-j5h_c8_q/twisted/logger/test/test_global.pyÚsimplify*   s
    zcompareEvents.<locals>.simplifyc                    s   g | ]}ˆ |ƒ‘qS r!   r!   ©Ú.0r   )r#   r!   r"   Ú
<listcomp>1   s     z!compareEvents.<locals>.<listcomp>N)ÚlenÚassertEqualÚsetr   r   )r   r   r   r   ZsimplifiedActualr!   )r    r#   r"   ÚcompareEvents   s    r*   c                   @   sØ   e Zd ZdZddœdd„Zddœdd„Zddœdd	„Zeedd
œdd„Z	ddœdd„Z
ddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd „ZdS )!ÚLogBeginnerTestsz#
    Tests for L{LogBeginner}.
    N©r   c                 C   sZ   t ƒ | _t ¡ | _G dd„ dƒ}G dd„ dƒ}|ƒ | _|ƒ | _t| j| j| j| jƒ| _d S )Nc                   @   s   e Zd Zeƒ Zeƒ ZdS )z&LogBeginnerTests.setUp.<locals>.NotSysN)Ú__name__Ú
__module__Ú__qualname__ÚobjectÚstdoutÚstderrr!   r!   r!   r"   ÚNotSys>   s   r3   c                	   @   sF   e Zd Zddœdd„Zdeee eeee	e
  ee ddœdd„ZdS )	z+LogBeginnerTests.setUp.<locals>.NotWarningsNr,   c                 S   s
   g | _ d S r   )Úwarnings)Úselfr!   r!   r"   Ú__init__C   s    üz4LogBeginnerTests.setUp.<locals>.NotWarnings.__init__)ÚmessageÚcategoryÚfilenameÚlinenoÚfileÚliner   c                 S   s   | j  ||||||f¡ dS )a  
                Emulate warnings.showwarning.

                @param message: A warning message to emit.
                @param category: A warning category to associate with
                    C{message}.
                @param filename: A file name for the source code file issuing
                    the warning.
                @param lineno: A line number in the source file where the
                    warning was issued.
                @param file: A file to write the warning message to.  If
                    L{None}, write to L{sys.stderr}.
                @param line: A line of source code to include with the warning
                    message. If L{None}, attempt to read the line from
                    C{filename} and C{lineno}.
                N)r4   Úappend)r5   r7   r8   r9   r:   r;   r<   r!   r!   r"   ÚshowwarningJ   s    z7LogBeginnerTests.setUp.<locals>.NotWarnings.showwarning)NN)r-   r.   r/   r6   Ústrr   ÚWarningÚintr   r   r   r>   r!   r!   r!   r"   ÚNotWarningsB   s     ù
ørB   )	r   Ú	publisherÚioÚStringIOÚerrorStreamÚ	sysModuleÚwarningsModuler   Úbeginner)r5   r3   rB   r!   r!   r"   ÚsetUp:   s    
#   ÿzLogBeginnerTests.setUpc                    sr   t ddd�}g ‰ g ‰tt‡ fdd„ƒ}tt‡fdd„ƒ}| j ||f¡ |  |¡ |  |gˆ ¡ |  |gˆ¡ dS )z?
        Test that C{beginLoggingTo()} adds observers.
        é   r   ©ZfooÚbarc                    s
   ˆ   | ¡S r   ©r=   ©Úe©Úevents1r!   r"   Ú<lambda>t   ó    zBLogBeginnerTests.test_beginLoggingToAddObservers.<locals>.<lambda>c                    s
   ˆ   | ¡S r   rN   rO   ©Úevents2r!   r"   rS   u   rT   N)Údictr	   r   rI   ÚbeginLoggingTorC   r(   ©r5   r   Zo1Zo2r!   ©rR   rV   r"   Útest_beginLoggingToAddObserversk   s    
z0LogBeginnerTests.test_beginLoggingToAddObserversc                    sr   t ddd�}g ‰ g ‰tt‡ fdd„ƒ}tt‡fdd„ƒ}|  |¡ | j ||f¡ |  |gˆ ¡ |  |gˆ¡ dS )z\
        Test that events are buffered until C{beginLoggingTo()} is
        called.
        rK   r   rL   c                    s
   ˆ   | ¡S r   rN   rO   rQ   r!   r"   rS   ‡   rT   zDLogBeginnerTests.test_beginLoggingToBufferedEvents.<locals>.<lambda>c                    s
   ˆ   | ¡S r   rN   rO   rU   r!   r"   rS   ˆ   rT   N)rW   r	   r   rC   rI   rX   r(   rY   r!   rZ   r"   Ú!test_beginLoggingToBufferedEvents}   s    
z2LogBeginnerTests.test_beginLoggingToBufferedEvents)ÚlimitrI   r   c                 C   sf   t |d ƒD ]}|  t|d�¡ qg }| tt|jƒg¡ |  tt d|d ƒƒtdd„ |D ƒƒ¡ dS )a´  
        Verify that when more than C{limit} events are logged to L{LogBeginner},
        only the last C{limit} are replayed by L{LogBeginner.beginLoggingTo}.

        @param limit: The maximum number of events the log beginner should
            buffer.
        @param beginner: The L{LogBeginner} against which to verify.

        @raise: C{self.failureException} if the wrong events are replayed by
            C{beginner}.
        rK   )Úcountc                 s   s   | ]}|d  V  qdS )r^   Nr!   r$   r!   r!   r"   Ú	<genexpr>¢   s     z4LogBeginnerTests._bufferLimitTest.<locals>.<genexpr>N)	ÚrangerC   rW   rX   r	   r   r=   r(   Úlist)r5   r]   rI   r^   Úeventsr!   r!   r"   Ú_bufferLimitTest�   s    þz!LogBeginnerTests._bufferLimitTestc                 C   s   t j}|  || j¡ dS )zˆ
        Up to C{LogBeginner._DEFAULT_BUFFER_SIZE} log events are buffered for
        replay by L{LogBeginner.beginLoggingTo}.
        N)r   Z_DEFAULT_BUFFER_SIZErc   rI   )r5   r]   r!   r!   r"   Útest_defaultBufferLimit¥   s    z(LogBeginnerTests.test_defaultBufferLimitc                 C   s.   d}t | j| j| j| j|d�}|  ||¡ dS )zŠ
        The size of the L{LogBeginner} event buffer can be overridden with the
        C{initialBufferSize} initilizer argument.
        é   )ZinitialBufferSizeN)r   rC   rF   rG   rH   rc   )r5   r]   rI   r!   r!   r"   Útest_overrideBufferLimit­   s    ûz)LogBeginnerTests.test_overrideBufferLimitc              	   C   s$  g }g }t  ¡ }t|ƒ}|  tdd�¡ tƒ \}}| j tt	|j
ƒ|g¡ |  tdd�¡ tƒ \}}| j tt	|j
ƒ|g¡ |  tdd�¡ tttj||||d�}	d| _t| |tdd�tdd�|	tdd�gƒ t| ||	tdd�gƒ | ¡ }
|  d|› d|› d	�|
¡ |  d|› d|› d	�|
¡ dS )
z¿
        When invoked twice, L{LogBeginner.beginLoggingTo} will emit a log
        message warning the user that they previously began logging, and add
        the new log observers.
        Z	prebuffer)r   Z
postbufferZpostwarn)Z
log_formatZ	log_levelZfileNowZlineNowZfileThenZlineThenNú<ú:ú>)rD   rE   r   rC   rW   r   rI   rX   r	   r   r=   r   r   ÚwarnZmaxDiffr*   ÚgetvalueÚassertIn)r5   rR   rV   Z
fileHandleZtextObserverZfirstFilenameZ	firstLineZsecondFilenameZ
secondLineÚwarningÚoutputr!   r!   r"   Útest_beginLoggingToTwice¼   sB    

ú	üý
z)LogBeginnerTests.test_beginLoggingToTwicec                 C   s:   t | jd�}| d¡ |jddd� |  | j ¡ d¡ dS )zP
        Critical messages will be written as text to the error stream.
        ©Zobserverzignore thisza critical {message}r7   )r7   za critical message
N)r   rC   ÚinfoÚcriticalr(   rF   rk   ©r5   Úlogr!   r!   r"   Útest_criticalLoggingç   s    
z%LogBeginnerTests.test_criticalLoggingc                 C   s8   t | jd�}| j d¡ | d¡ |  | j ¡ d¡ dS )z†
        Once logging has begun with C{beginLoggingTo}, critical messages are no
        longer written to the output stream.
        rp   r!   zanother critical messageÚ N)r   rC   rI   rX   rr   r(   rF   rk   rs   r!   r!   r"   Útest_criticalLoggingStopsð   s    
z*LogBeginnerTests.test_criticalLoggingStopsc                 C   s€   g }| j  tt|jƒg¡ tdtt| jjƒd� t	| |t
ddd�gƒ |dd…= tdtt| jjƒd� t	| |t
ddd�gƒ dS )z¿
        L{LogBeginner.beginLoggingTo} will re-direct the standard output and
        error streams by setting the C{stdio} and C{stderr} attributes on its
        sys module object.
        zHello, world.©r;   r1   )Zlog_namespaceÚlog_ioNzError, world.r2   )rI   rX   r	   r   r=   Úprintr   rG   r1   r*   rW   r2   )r5   rb   r!   r!   r"   Ú%test_beginLoggingToRedirectStandardIOú   s      ÿ
  ÿz6LogBeginnerTests.test_beginLoggingToRedirectStandardIOc                 C   sD   | j j}| j j}| jjddd� |  | j j|¡ |  | j j|¡ dS )z�
        L{LogBeginner.beginLoggingTo} will leave the existing stdout/stderr in
        place if it has been told not to replace them.
        r!   F)ZredirectStandardION)rG   r1   r2   rI   rX   ZassertIs)r5   ZoldOutZoldErrr!   r!   r"   Útest_beginLoggingToDontRedirect  s
    z0LogBeginnerTests.test_beginLoggingToDontRedirectc                 C   s¶   t  t  ¡ d¡}t  t  ¡ d¡}|| j_|| j_g }| j tt	|j
ƒg¡ tt| jjƒ}tt| jjƒ}|  |jd¡ |  |jd¡ | d¡ | d¡ t| |tdd�tdd�gƒ dS )	zö
        When L{LogBeginner.beginLoggingTo} redirects stdout/stderr streams, the
        replacement streams will preserve the encoding of the replaced streams,
        to minimally disrupt any application relying on a specific encoding.
        z	shift-JISÚbig5s   —›
s   ¼ü
u   æ�Ž)ry   u   ç‘©N)rD   ÚTextIOWrapperÚBytesIOrG   r1   r2   rI   rX   r	   r   r=   r   r(   ÚencodingÚwriter*   rW   )r5   ZweirdZweirderrrb   r1   r2   r!   r!   r"   Ú$test_beginLoggingToPreservesEncoding  s    

z5LogBeginnerTests.test_beginLoggingToPreservesEncodingc              
   C   s²   | j  dttd¡ g }| j tt|jƒg¡ | j  dttd¡ t	 
¡ }| j jdttd|d� |  | j jdttdddfdttd|dfg¡ t| |tdtjd	 tj tdd
�gƒ dS )z‚
        L{LogBeginner.beginLoggingTo} will redirect the warnings of its
        warnings module into the logging system.
        z	a messagerK   zanother messager   zyet anotherre   rx   NÚ.)rm   r8   r9   r:   )rH   r>   ÚDeprecationWarningÚ__file__rI   rX   r	   r   r=   rD   rE   r(   r4   r*   rW   r.   r-   )r5   rb   Úfr!   r!   r"   Útest_warningsModule/  sL       ÿ    ÿþþÿþøÿýz$LogBeginnerTests.test_warningsModulec                 C   sX   t tdƒƒ}t| jd�}|jd|d� | j ¡ }|  d|¡ |  d|¡ |  d|¡ dS )zR
        The string resulting from a logged failure contains a traceback.
        z,this is not the behavior you are looking forrp   z	a failure)ÚfailureÚ	TracebackN)r
   Ú	Exceptionr   rC   rˆ   rF   rk   rl   )r5   r†   rt   Úmsgr!   r!   r"   Útest_failuresAppendTracebacksV  s    
z.LogBeginnerTests.test_failuresAppendTracebacks)r-   r.   r/   Ú__doc__rJ   r[   r\   rA   r   rc   rd   rf   ro   ru   rw   r{   r|   r‚   r‡   rŒ   r!   r!   r!   r"   r+   5   s   1+	
'r+   )"r�   rD   Útypingr   r   r   r   r   r   r   r	   Ztwisted.python.failurer
   Ztwisted.trialr   Ú_filer   Z_globalr   r   Z_interfacesr   r   Z_levelsr   Z_loggerr   Z	_observerr   Ztest.test_stdlibr   ZTestCaser*   r+   r!   r!   r!   r"   Ú<module>   s"   (ü