U
    W[`                     @   sL  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	 ddl
mZ ddlmZ ddlmZ dd	lmZ dd
lm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eZG dd deZG dd deZG dd de Z!G dd de Z"G dd deZ#G dd deZ$G dd deZ%G dd deZ&G d d! d!eZ'dS )"z!
Tests for L{twisted.trial.util}
    )divisionabsolute_importN)implementer)NativeStringIO)filepath)IProcessTransport)defer)DelayedCall)Failure)SynchronousTestCase)util)DirtyReactorAggregateError_JanitorexcInfoOrFailureToExcInfoacquireAttributec                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )MktempTestszm
    Tests for L{TestCase.mktemp}, a helper function for creating temporary file
    or directory names.
    c                 C   s:   |   }tj|tjdd }| |dddg dS )z
        The path name returned by C{mktemp} is directly beneath a directory
        which identifies the test method which created the name.
        Nztwisted.trial.test.test_utilr   	test_name)mktempospathdirnamesplitsepassertEqual)selfnamedirs r   >/usr/lib/python3/dist-packages/twisted/trial/test/test_util.pyr   #   s     zMktempTests.test_namec                 C   s   |   }| ||    dS )zF
        Repeated calls to C{mktemp} return different values.
        N)r   ZassertNotEqual)r   r   r   r   r   test_unique.   s    zMktempTests.test_uniquec                 C   s<   |   }tj|}| tj| | tj| dS )zS
        The directory part of the path name returned by C{mktemp} exists.
        N)r   r   r   r   
assertTrueexistsassertFalse)r   r   r   r   r   r   test_created6   s    zMktempTests.test_createdc                 C   s(   t j|  }| |t   dS )zZ
        The path returned by C{mktemp} is beneath the current working directory.
        N)r   r   abspathr   r!   
startswithgetcwd)r   r   r   r   r   test_location@   s    zMktempTests.test_locationN)__name__
__module____qualname____doc__r   r    r$   r(   r   r   r   r   r      s
   
r   c                   @   sX   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d ZdS )RunSequentiallyTestsz
    Sometimes it is useful to be able to run an arbitrary list of callables,
    one after the other.

    When some of those callables can return Deferreds, things become complex.
    c                 O   s(   g }| |j ||d f|| dS )ze
        Call the given assertion function against the current result of a
        Deferred.
        r   N)ZaddCallbackappend)r   ZdeferredZassertFunctionargskwargsresultr   r   r   assertDeferredResultQ   s    z)RunSequentiallyTests.assertDeferredResultc                 C   s   t g }| || jg  dS )z
        When asked to run an empty list of callables, runSequentially returns a
        successful Deferred that fires an empty list.
        N)r   _runSequentiallyr2   r   r   dr   r   r   test_emptyListZ   s    
z#RunSequentiallyTests.test_emptyListc                 C   s,   t dd g}| || jtjdfg dS )z
        When given a callable that succeeds without returning a Deferred,
        include the return value in the results list, tagged with a SUCCESS
        flag.
        c                   S   s   d S Nr   r   r   r   r   <lambda>i       zDRunSequentiallyTests.test_singleSynchronousSuccess.<locals>.<lambda>Nr   r3   r2   r   r   SUCCESSr4   r   r   r   test_singleSynchronousSuccessc   s    z2RunSequentiallyTests.test_singleSynchronousSuccessc                    s0   t  fddg} fdd} || dS )z
        When given a callable that raises an exception, include a Failure for
        that exception in the results list, tagged with a FAILURE flag.
        c                      s
     dS Nfoofailr   r   r   r   r8   r   r9   zDRunSequentiallyTests.test_singleSynchronousFailure.<locals>.<lambda>c                    s8   | \\}}|  j  | d  |tj d S r=   )trapfailureExceptionr   getErrorMessager   FAILUREresultsflagr@   rA   r   r   checks   s    
zARunSequentiallyTests.test_singleSynchronousFailure.<locals>.checkNr   r3   r2   r   r5   rI   r   rA   r   test_singleSynchronousFailurem   s    z2RunSequentiallyTests.test_singleSynchronousFailurec                 C   s,   t dd g}| || jtjdfg dS )z
        When given a callable that returns a successful Deferred, include the
        result of the Deferred in the results list, tagged with a SUCCESS flag.
        c                   S   s
   t d S r7   )r   Zsucceedr   r   r   r   r8      r9   zERunSequentiallyTests.test_singleAsynchronousSuccess.<locals>.<lambda>Nr:   r4   r   r   r   test_singleAsynchronousSuccess{   s    z3RunSequentiallyTests.test_singleAsynchronousSuccessc                    s,   t dd g} fdd} || dS )z
        When given a callable that returns a failing Deferred, include the
        failure the results list, tagged with a FAILURE flag.
        c                   S   s   t tdS r=   )r   r@   
ValueErrorr   r   r   r   r8      r9   zERunSequentiallyTests.test_singleAsynchronousFailure.<locals>.<lambda>c                    s6   | \\}}| t  | d  |tj d S r=   )rB   rN   r   rD   r   rE   rF   rA   r   r   rI      s    

zBRunSequentiallyTests.test_singleAsynchronousFailure.<locals>.checkNrJ   rK   r   rA   r   test_singleAsynchronousFailure   s    z3RunSequentiallyTests.test_singleAsynchronousFailurec                    sd   g g fdd t  fdd fddg | dg d d | dd	g dS )
zf
        Check that the callables are called in the given order, one after the
        other.
        c                    s    t  }|   | |S r7   )r   ZDeferredr.   )valuer5   )	deferredslogr   r   r.      s    

z@RunSequentiallyTests.test_callablesCalledInOrder.<locals>.appendc                      s    dS r=   r   r   r.   r   r   r8      r9   zBRunSequentiallyTests.test_callablesCalledInOrder.<locals>.<lambda>c                      s    dS Nbarr   r   rS   r   r   r8      r9   r>   r   NrU   )r   r3   r   callbackrA   r   )r.   rQ   rR   r   test_callablesCalledInOrder   s    
z0RunSequentiallyTests.test_callablesCalledInOrderc                    s6   t  fdddd g} fdd} || dS )z
        If one of the callables raises an error, then runSequentially continues
        to run the remaining callables.
        c                      s
     dS r=   r?   r   rA   r   r   r8      r9   z?RunSequentiallyTests.test_continuesAfterError.<locals>.<lambda>c                   S   s   dS rT   r   r   r   r   r   r8      r9   c                    sX   | \\}}\}}|  j  |tj  | d  |tj  |d d S )Nr>   rU   )rB   rC   r   r   rE   rD   r;   )rG   flag1r@   Zflag2r1   rA   r   r   rI      s    z<RunSequentiallyTests.test_continuesAfterError.<locals>.checkNrJ   rK   r   rA   r   test_continuesAfterError   s    z-RunSequentiallyTests.test_continuesAfterErrorc                    s:   t j fdddd gdd} fdd} || dS )	z
        If the C{stopOnFirstError} option is passed to C{runSequentially}, then
        no further callables are called after the first exception is raised.
        c                      s
     dS r=   r?   r   rA   r   r   r8      r9   z<RunSequentiallyTests.test_stopOnFirstError.<locals>.<lambda>c                   S   s   dS rT   r   r   r   r   r   r8      r9   T)ZstopOnFirstErrorc                    s8   | \\}}|  j  |tj  | d d S r=   )rB   rC   r   r   rE   rD   )rG   rX   r@   rA   r   r   rI      s    
z9RunSequentiallyTests.test_stopOnFirstError.<locals>.checkNrJ   rK   r   rA   r   test_stopOnFirstError   s
    z*RunSequentiallyTests.test_stopOnFirstErrorN)r)   r*   r+   r,   r2   r6   r<   rL   rM   rO   rW   rY   rZ   r   r   r   r   r-   I   s   		
	r-   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	DirtyReactorAggregateErrorTestsz6
    Tests for the L{DirtyReactorAggregateError}.
    c                 C   s    t ddg}| t|d dS )z5
        Delayed calls are formatted nicely.
        ZFoorU   zhReactor was unclean.
DelayedCalls: (set twisted.internet.base.DelayedCall.debug = True to debug)
Foo
barNr   r   strr   errorr   r   r   test_formatDelayedCall   s    
z6DirtyReactorAggregateErrorTests.test_formatDelayedCallc                 C   s"   t g ddg}| t|d dS )z3
        Selectables are formatted nicely.
        zselectable 1zselectable 2z;Reactor was unclean.
Selectables:
selectable 1
selectable 2Nr\   r^   r   r   r   test_formatSelectables   s    
z6DirtyReactorAggregateErrorTests.test_formatSelectablesc                 C   s&   t ddgddg}| t|d dS )zR
        Both delayed calls and selectables can appear in the same error.
        ZbleckZBoozoZSel1ZSel2zReactor was unclean.
DelayedCalls: (set twisted.internet.base.DelayedCall.debug = True to debug)
bleck
Boozo
Selectables:
Sel1
Sel2Nr\   r^   r   r   r   %test_formatDelayedCallsAndSelectables   s    
zEDirtyReactorAggregateErrorTests.test_formatDelayedCallsAndSelectablesN)r)   r*   r+   r,   r`   ra   rb   r   r   r   r   r[      s   r[   c                   @   s4   e Zd ZdZdddZdddZdd Zd	d
 ZdS )StubReactora~  
    A reactor stub which contains enough functionality to be used with the
    L{_Janitor}.

    @ivar iterations: A list of the arguments passed to L{iterate}.
    @ivar removeAllCalled: Number of times that L{removeAll} was called.
    @ivar selectables: The value that will be returned from L{removeAll}.
    @ivar delayedCalls: The value to return from L{getDelayedCalls}.
    Nc                 C   s$   || _ g | _d| _|sg }|| _dS )z
        @param delayedCalls: See L{StubReactor.delayedCalls}.
        @param selectables: See L{StubReactor.selectables}.
        r   N)delayedCalls
iterationsremoveAllCalledselectables)r   rd   rg   r   r   r   __init__  s    zStubReactor.__init__c                 C   s   | j | dS )z/
        Increment C{self.iterations}.
        N)re   r.   )r   Ztimeoutr   r   r   iterate  s    zStubReactor.iteratec                 C   s   | j S )z.
        Return C{self.delayedCalls}.
        )rd   rA   r   r   r   getDelayedCalls  s    zStubReactor.getDelayedCallsc                 C   s   |  j d7  _ | jS )zS
        Increment C{self.removeAllCalled} and return C{self.selectables}.
           )rf   rg   rA   r   r   r   	removeAll!  s    zStubReactor.removeAll)N)N)r)   r*   r+   r,   rh   ri   rj   rl   r   r   r   r   rc      s
   


rc   c                   @   s    e Zd ZdZdd Zdd ZdS )StubErrorReporterz
    A subset of L{twisted.trial.itrial.IReporter} which records L{addError}
    calls.

    @ivar errors: List of two-tuples of (test, error) which were passed to
        L{addError}.
    c                 C   s
   g | _ d S r7   )errorsrA   r   r   r   rh   3  s    zStubErrorReporter.__init__c                 C   s   | j ||f dS )z6
        Record parameters in C{self.errors}.
        N)rn   r.   )r   testr_   r   r   r   addError7  s    zStubErrorReporter.addErrorN)r)   r*   r+   r,   rh   rp   r   r   r   r   rm   *  s   rm   c                   @   sh   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d Zdd Zdd ZdS )JanitorTestsz 
    Tests for L{_Janitor}!
    c                 C   s4   t g }tdd|d}|  | |jddg dS )a  
        During pending-call cleanup, the reactor will be spun twice with an
        instant timeout. This is not a requirement, it is only a test for
        current behavior. Hopefully Trial will eventually not do this kind of
        reactor stuff.
        Nreactorr   )rc   r   _cleanPendingr   re   r   rs   janr   r   r   test_cleanPendingSpinsReactorD  s    z*JanitorTests.test_cleanPendingSpinsReactorc                 C   sV   dd }g }t d|di |jdd }t|g}tdd|d}|  | ||g dS )	zW
        During pending-call cleanup, the janitor cancels pending timed calls.
        c                   S   s   dS )NZLulzr   r   r   r   r   funcU  s    z8JanitorTests.test_cleanPendingCancelsCalls.<locals>.func,  r   c                 S   s   d S r7   r   xr   r   r   r8   Y  r9   z<JanitorTests.test_cleanPendingCancelsCalls.<locals>.<lambda>Nrr   )r	   r.   rc   r   rt   r   )r   rx   Z	cancelleddelayedCallrs   rv   r   r   r   test_cleanPendingCancelsCallsQ  s    
 
z*JanitorTests.test_cleanPendingCancelsCallsc              	   C   s`   t ddd di dd dd dd d}t|}t|g}tdd|d	}| }| ||g dS )
aK  
        The Janitor produces string representations of delayed calls from the
        delayed call cleanup method. It gets the string representations
        *before* cancelling the calls; this is important because cancelling the
        call removes critical debugging information from the string
        representation.
        ry   c                   S   s   d S r7   r   r   r   r   r   r8   h  r9   zIJanitorTests.test_cleanPendingReturnsDelayedCallStrings.<locals>.<lambda>r   c                 S   s   d S r7   r   rz   r   r   r   r8   i  r9   c                   S   s   dS Nr   r   r   r   r   r   r8   j  r9   ZsecondsNrr   )r	   r]   rc   r   rt   r   )r   r|   delayedCallStringrs   rv   Zstringsr   r   r   *test_cleanPendingReturnsDelayedCallStrings`  s     
z7JanitorTests.test_cleanPendingReturnsDelayedCallStringsc                 C   s0   t g }tdd|d}|  | |jd dS )zM
        The Janitor will remove selectables during reactor cleanup.
        Nrr   rk   )rc   r   _cleanReactorr   rf   ru   r   r   r   #test_cleanReactorRemovesSelectablesr  s    z0JanitorTests.test_cleanReactorRemovesSelectablesc                 C   sT   t tG dd dt}| }tg |g}tdd|d}|  | |jdg dS )zI
        The Janitor will kill processes during reactor cleanup.
        c                   @   s    e Zd ZdZdd Zdd ZdS )zJJanitorTests.test_cleanReactorKillsProcesses.<locals>.StubProcessTransportz
            A stub L{IProcessTransport} provider which records signals.
            @ivar signals: The signals passed to L{signalProcess}.
            c                 S   s
   g | _ d S r7   )signalsrA   r   r   r   rh     s    zSJanitorTests.test_cleanReactorKillsProcesses.<locals>.StubProcessTransport.__init__c                 S   s   | j | dS )zF
                Append C{signal} to C{self.signals}.
                N)r   r.   )r   signalr   r   r   signalProcess  s    zXJanitorTests.test_cleanReactorKillsProcesses.<locals>.StubProcessTransport.signalProcessN)r)   r*   r+   r,   rh   r   r   r   r   r   StubProcessTransport  s   r   Nrr   ZKILL)r   r   objectrc   r   r   r   r   )r   r   Zptrs   rv   r   r   r   test_cleanReactorKillsProcesses|  s    z,JanitorTests.test_cleanReactorKillsProcessesc                 C   sB   G dd dt }tg | g}tdd|d}| | dg dS )z
        The Janitor returns string representations of the selectables that it
        cleaned up from the reactor cleanup method.
        c                   @   s   e Zd ZdZdd ZdS )zJJanitorTests.test_cleanReactorReturnsSelectableStrings.<locals>.Selectablezl
            A stub Selectable which only has an interesting string
            representation.
            c                 S   s   dS )N(SELECTABLE!)r   rA   r   r   r   __repr__  s    zSJanitorTests.test_cleanReactorReturnsSelectableStrings.<locals>.Selectable.__repr__N)r)   r*   r+   r,   r   r   r   r   r   
Selectable  s   r   Nrr   r   )r   rc   r   r   r   )r   r   rs   rv   r   r   r   )test_cleanReactorReturnsSelectableStrings  s    z6JanitorTests.test_cleanReactorReturnsSelectableStringsc                 C   sB   t g }t }t }t|||d}| |  | |jg  dS )z
        The post-case cleanup method will return True and not call C{addError}
        on the result if there are no pending calls.
        rr   N)rc   r   rm   r   r!   postCaseCleanupr   rn   r   rs   ro   reporterrv   r   r   r   test_postCaseCleanupNoErrors  s    z)JanitorTests.test_postCaseCleanupNoErrorsc              	   C   s   t ddd di dd dd dd d}t|}t|gg }t }t }t|||d}| |  | t	|j
d	 | |j
d
 d	 jj|g dS )z
        The post-case cleanup method will return False and call C{addError} on
        the result with a L{DirtyReactorAggregateError} Failure if there are
        pending calls.
        ry   c                   S   s   d S r7   r   r   r   r   r   r8     r9   z=JanitorTests.test_postCaseCleanupWithErrors.<locals>.<lambda>r   c                 S   s   d S r7   r   rz   r   r   r   r8     r9   c                   S   s   dS r~   r   r   r   r   r   r8     r9   r   rr   rk   r   N)r	   r]   rc   r   rm   r   r#   r   r   lenrn   rP   rd   r   r|   r   rs   ro   r   rv   r   r   r   test_postCaseCleanupWithErrors  s     z+JanitorTests.test_postCaseCleanupWithErrorsc                 C   s<   t g }t }t }t|||d}|  | |jg  dS )z
        The post-class cleanup method will not call C{addError} on the result
        if there are no pending calls or selectables.
        rr   N)rc   r   rm   r   postClassCleanupr   rn   r   r   r   r   test_postClassCleanupNoErrors  s    z*JanitorTests.test_postClassCleanupNoErrorsc              	   C   s   t ddd di dd dd dd d}t|}t|gg }t }t }t|||d}|  | t|j	d	 | |j	d
 d	 j
j|g dS )z
        The post-class cleanup method call C{addError} on the result with a
        L{DirtyReactorAggregateError} Failure if there are pending calls.
        ry   c                   S   s   d S r7   r   r   r   r   r   r8     r9   zIJanitorTests.test_postClassCleanupWithPendingCallErrors.<locals>.<lambda>r   c                 S   s   d S r7   r   rz   r   r   r   r8     r9   c                   S   s   dS r~   r   r   r   r   r   r8     r9   r   rr   rk   r   N)r	   r]   rc   r   rm   r   r   r   r   rn   rP   rd   r   r   r   r   *test_postClassCleanupWithPendingCallErrors  s     z7JanitorTests.test_postClassCleanupWithPendingCallErrorsc                 C   sh   d}t g |g}t }t }t|||d}|  | t|jd | |jd d jj	t
|g dS )z
        The post-class cleanup method call C{addError} on the result with a
        L{DirtyReactorAggregateError} Failure if there are selectables.
        zSELECTABLE HERErr   rk   r   N)rc   r   rm   r   r   r   r   rn   rP   rg   repr)r   Z
selectablers   ro   r   rv   r   r   r   )test_postClassCleanupWithSelectableErrors  s    z6JanitorTests.test_postClassCleanupWithSelectableErrorsN)r)   r*   r+   r,   rw   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   rq   ?  s   
rq   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	RemoveSafelyTestsz*
    Tests for L{util._removeSafely}.
    c                 C   s8   |   d}t| t|}| tjtj	| dS )z
        If a path doesn't contain a node named C{"_trial_marker"}, that path is
        not removed by L{util._removeSafely} and a L{util._NoTrialMarker}
        exception is raised instead.
        utf-8N)
r   encoder   mkdirr   FilePathassertRaisesr   Z_NoTrialMarker_removeSafely)r   	directorydirPathr   r   r   test_removeSafelyNoTrialMarker  s    

z0RemoveSafelyTests.test_removeSafelyNoTrialMarkerc                 C   sp   dd }t  }| td| |  d}t| t|}|	d
  ||_t| | d|  dS )z
        If an L{OSError} is raised while removing a path in
        L{util._removeSafely}, an attempt is made to move the path to a new
        name.
        c                   S   s
   t  dS )
            Raise an C{OSError} to emulate the branch of L{util._removeSafely}
            in which path removal fails.
            NOSErrorr   r   r   r   dummyRemove  s    zORemoveSafelyTests.test_removeSafelyRemoveFailsMoveSucceeds.<locals>.dummyRemovestdoutr      _trial_markercould not remove FilePathN)r   patchsysr   r   r   r   r   r   childtouchremover   r   assertIngetvalue)r   r   outr   r   r   r   r   (test_removeSafelyRemoveFailsMoveSucceeds  s    


z:RemoveSafelyTests.test_removeSafelyRemoveFailsMoveSucceedsc                 C   s   dd }dd }t  }| td| |  d}t| t|}|	d
  ||_||_| ttj|}| t|d | d	|  d
S )z
        If an L{OSError} is raised while removing a path in
        L{util._removeSafely}, an attempt is made to move the path to a new
        name. If that attempt fails, the L{OSError} is re-raised.
        c                   S   s   t ddS )r   zpath removal failedNr   r   r   r   r   r   .  s    zLRemoveSafelyTests.test_removeSafelyRemoveFailsMoveFails.<locals>.dummyRemovec                 S   s   t ddS )z
            Raise an C{OSError} to emulate the branch of L{util._removeSafely}
            in which path movement fails.
            path movement failedNr   )r   r   r   r   dummyMoveTo5  s    zLRemoveSafelyTests.test_removeSafelyRemoveFailsMoveFails.<locals>.dummyMoveTor   r   r   r   r   N)r   r   r   r   r   r   r   r   r   r   r   r   ZmoveTor   r   r   r   r   r]   r   r   )r   r   r   r   r   r   r_   r   r   r   %test_removeSafelyRemoveFailsMoveFails(  s    

z7RemoveSafelyTests.test_removeSafelyRemoveFailsMoveFailsN)r)   r*   r+   r,   r   r   r   r   r   r   r   r     s   r   c                   @   s    e Zd ZdZdd Zdd ZdS )ExcInfoTestsz1
    Tests for L{excInfoOrFailureToExcInfo}.
    c                 C   s$   t t ddf}| |t|k dS )z
        L{excInfoOrFailureToExcInfo} returns exactly what it is passed, if it is
        passed a tuple like the one returned by L{sys.exc_info}.
        r>   N)rN   r!   r   )r   infor   r   r   test_excInfoT  s    zExcInfoTests.test_excInfoc                 C   s@   zdd  W n   t  }Y nX | |j|j|jft| dS )z
        When called with a L{Failure} instance, L{excInfoOrFailureToExcInfo}
        returns a tuple like the one returned by L{sys.exc_info}, with the
        elements taken from the type, value, and traceback of the failure.
        rk   r   N)r
   r   typerP   tbr   )r   fr   r   r   test_failure]  s
    zExcInfoTests.test_failureN)r)   r*   r+   r,   r   r   r   r   r   r   r   P  s   	r   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )AcquireAttributeTestsz(
    Tests for L{acquireAttribute}.
    c                 C   s*   t   | _}| |t| t  gdk dS )z
        The value returned by L{acquireAttribute} is the value of the requested
        attribute on the first object in the list passed in which has that
        attribute.
        rP   Nr   rP   r!   r   r   rP   r   r   r   test_foundOnEarlierObjecto  s    z/AcquireAttributeTests.test_foundOnEarlierObjectc                 C   s*   t   | _}| |tt  | gdk dS )z
        The same as L{test_foundOnEarlierObject}, but for the case where the 2nd
        element in the object list has the attribute and the first does not.
        rP   Nr   r   r   r   r   test_foundOnLaterObjecty  s    z-AcquireAttributeTests.test_foundOnLaterObjectc                 C   s   |  ttt gd dS )z
        If none of the objects passed in the list to L{acquireAttribute} have
        the requested attribute, L{AttributeError} is raised.
        r>   N)r   AttributeErrorr   r   rA   r   r   r   test_notFoundException  s    z,AcquireAttributeTests.test_notFoundExceptionc                 C   s$   t  }| |tt  gd|k dS )z
        If none of the objects passed in the list to L{acquireAttribute} have
        the requested attribute and a default value is given, the default value
        is returned.
        r>   N)r   r!   r   )r   defaultr   r   r   test_notFoundDefault  s    z*AcquireAttributeTests.test_notFoundDefaultN)r)   r*   r+   r,   r   r   r   r   r   r   r   r   r   k  s
   
	r   c                   @   sX   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d ZdS )ListToPhraseTestsz
    Input is transformed into a string representation of the list,
    with each item separated by delimiter (defaulting to a comma) and the final
    two being separated by a final delimiter.
    c                 C   s$   g }d}t |d}| || dS )zB
        If things is empty, an empty string is returned.
         andNr   _listToPhraser   r   sampleZexpectedr1   r   r   r   
test_empty  s    zListToPhraseTests.test_emptyc                 C   s&   dg}d}t |d}| || dS )z;
        With a single item, the item is returned.
        Oner   Nr   r   r   r   r   test_oneWord  s    zListToPhraseTests.test_oneWordc                 C   s(   ddg}d}t |d}| || dS )zA
        Two words are separated by the final delimiter.
        r   TwozOne and Twor   Nr   r   r   r   r   test_twoWords  s    zListToPhraseTests.test_twoWordsc                 C   s*   dddg}d}t |d}| || dS )zY
        With more than two words, the first two are separated by the delimiter.
        r   r   ThreezOne, Two, and Threer   Nr   r   r   r   r   test_threeWords  s    
z!ListToPhraseTests.test_threeWordsc                 C   s0   ddddg}d}t j|ddd}| || d	S )
zW
        If a delimiter is specified, it is used instead of the default comma.
        r   r   r   ZFourzOne; Two; Three; or Fourorz; )Z	delimiterNr   r   r   r   r   test_fourWords  s    z ListToPhraseTests.test_fourWordsc                 C   s*   dddg}d}t |d}| || dS )zS
        If something in things is not a string, it is converted into one.
        rk      Zthreez1, 2, and threer   Nr   r   r   r   r   test_notString  s    
z ListToPhraseTests.test_notStringc                 C   s*   d}|  ttj|d}| t|d dS )z?
        If things is a string, a TypeError is raised.
        zOne, two, threer    Things must be a list or a tupleNr   	TypeErrorr   r   r   r]   r   r   r_   r   r   r   test_stringTypeError  s    z&ListToPhraseTests.test_stringTypeErrorc                 C   s4   t dddg}| ttj|d}| t|d dS )zB
        If things is an iterator, a TypeError is raised.
        rk   r      r   r   N)iterr   r   r   r   r   r]   r   r   r   r   test_iteratorTypeError  s    z(ListToPhraseTests.test_iteratorTypeErrorc                 C   s.   dd }|  ttj|d}| t|d dS )zB
        If things is a generator, a TypeError is raised.
        c                  s   s   t dD ]
} | V  qd S )Nr   )range)ir   r   r   r     s    z9ListToPhraseTests.test_generatorTypeError.<locals>.sampler   r   Nr   r   r   r   r   test_generatorTypeError  s    z)ListToPhraseTests.test_generatorTypeErrorN)r)   r*   r+   r,   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s   





		r   )(r,   Z
__future__r   r   r   r   Zzope.interfacer   Ztwisted.python.compatr   Ztwisted.pythonr   Ztwisted.internet.interfacesr   Ztwisted.internetr   Ztwisted.internet.baser	   Ztwisted.python.failurer
   Ztwisted.trial.unittestr   Ztwisted.trialr   Ztwisted.trial.utilr   r   r   r   r   r-   r[   r   rc   rm   rq   r   r   r   r   r   r   r   r   <module>   s0   + 1/ =U*