U
    
W[1U                     @   sT  d Z ddlmZmZ ddlZddlmZ ddlmZ ddl	m
Z
mZmZ ddlmZmZmZ ddlmZ G d	d
 d
eZG dd deZdd ZG dd dejZG dd dejZG dd dejZG dd dejZG dd dejZG dd deZdd ZG dd dejZ G dd  d ejZ!G d!d" d"ejZ"G d#d$ d$e Z#d%Z$d&Z%dS )'z*
Test cases for twisted.python._shellcomp
    )divisionabsolute_importN)BytesIO)unittest)
_shellcompusagereflect)Completions	CompleterCompleteFilesCompleteListc                   @   s   e Zd ZdZdd ZdS )ZshScriptTestMetaz*
    Metaclass of ZshScriptTestMixin.
    c                 C   sH   dd }d|kr8|d D ]\}}|||}||d| < qt | |||S )Nc                    s    fdd}|S )Nc                    s   t |  S )N)test_genZshFunctionselfcmdNameoptionsFQPN D/usr/lib/python3/dist-packages/twisted/python/test/test_shellcomp.pyrunTest   s    z<ZshScriptTestMeta.__new__.<locals>.makeTest.<locals>.runTestr   )r   r   r   r   r   r   makeTest   s    z+ZshScriptTestMeta.__new__.<locals>.makeTestZgenerateForZtest_genZshFunction_)type__new__)clsnamebasesZattrsr   r   r   testr   r   r   r      s    
zZshScriptTestMeta.__new__N)__name__
__module____qualname____doc__r   r   r   r   r   r      s   r   c                   @   s   e Zd ZdZeZdS )ZshScriptTestMixina  
    Integration test helper to show that C{usage.Options} classes can have zsh
    completion functions generated for them without raising errors.

    In your subclasses set a class variable like so:

    #            | cmd name | Fully Qualified Python Name of Options class |
    #
    generateFor = [('conch',  'twisted.conch.scripts.conch.ClientOptions'),
                   ('twistd', 'twisted.scripts.twistd.ServerOptions'),
                   ]

    Each package that contains Twisted scripts should contain one TestCase
    subclass which also inherits from this mixin, and contains a C{generateFor}
    list appropriate for the scripts in that package.
    N)r   r    r!   r"   r   Z__metaclass__r   r   r   r   r#   )   s   r#   c           
      C   s  t  }| tjd| zt| }W n2 tk
rX } ztd|f W 5 d}~X Y nX z|	dddg W nB t
k
r } ztd|fW 5 d}~X Y n tk
r   Y nX | d |d	 | d
t|d
 |d	 |  t|dr|jD ]\}}}}	z|	|dddg W nF t
k
rT } ztd|fW 5 d}~X Y n  tk
rh   Y nX | d |d	 | d
t|d
 |d	 |  q |   dS )aI  
    Generate completion functions for given twisted command - no errors
    should be raised

    @type cmdName: C{str}
    @param cmdName: The name of the command-line utility e.g. 'twistd'

    @type optionsFQPN: C{str}
    @param optionsFQPN: The Fully Qualified Python Name of the C{Options}
        class to be tested.
    _shellCompFilez0Couldn't import or instantiate Options class: %sN --_shell-completionzsh:2z&ImportError calling parseOptions(): %szSystemExit not raisedr      subCommandszzsh:3z4ImportError calling parseOptions() on subcommand: %s)r   patchr   Optionsr   ZnamedAny	Exceptionr   ZSkipTestparseOptionsImportError
SystemExitZfailseekassertEquallenreadtruncatehasattrr)   ZflushWarnings)
r   r   r   
outputFileoecmdZshortparserdocr   r   r   r   >   sJ    







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d Zdd Zdd Zdd ZdS )ZshTestsz'
    Tests for zsh completion code
    c                 C   s   t  }t|dt }tjj }|t jj | 	|j| | 	|j
ttjj
 | 	|jtjj tjj }|t jj | 	|j| | 	|jtjj dS )zi
        Are `compData' attributes you can place on Options classes
        picked up correctly?
        aceN)FighterAceExtendedOptionsr   ZshArgumentsGeneratorr   FighterAceOptionscompDatadescriptionscopyupdater1   multiUsesetmutuallyExclusive
optActionsextraActions)r   optsagrB   rH   r   r   r   test_accumulateMetadata   s"    
z ZshTests.test_accumulateMetadatac                 C   s   G dd dt }| }t|dt }tdddddd	d
gtddddddd	d
gtdddddd	d
gtdddddd	d
gtdddddddgd}| |j| dS )z
        Exercise a corner-case of ZshArgumentsGenerator.makeExcludesDict()
        where the long option name already exists in the `excludes` dict being
        built.
        c                   @   s.   e Zd ZdddggZedddddggdZdS )	zGZshTests.test_mutuallyExclusiveCornerCase.<locals>.OddFighterAceOptionsanatraNz0Select the Anatra DS as your dogfighter aircraftfokkeralbatrosspadbristolrG   )r   r    r!   optFlagsr	   rA   r   r   r   r   OddFighterAceOptions   s    rT   r=   rM   brQ   frN   srP   arO   )rO   rM   rQ   rN   rP   N)r>   r   r?   r   rF   r1   Zexcludes)r   rT   rJ   rK   Zexpectedr   r   r    test_mutuallyExclusiveCornerCase   s>    

  
   
  
  
  z)ZshTests.test_mutuallyExclusiveCornerCasec                 C   sR   t  }t|dt }| d|j | d|j | d|j | d|j dS )z
        We pick up options that are only defined by having an
        appropriately named method on your Options class,
        e.g. def opt_foo(self, foo)
        r=   Znocrash
difficultyN)r>   r   r?   r   ZassertInZflagNameToDefinitionZallOptionsNameToDefinitionZparamNameToDefinition)r   rJ   rK   r   r   r    test_accumulateAdditionalOptions   s    z)ZshTests.test_accumulateAdditionalOptionsc                 C   sT   G dd dt }| ttj| dt  G dd dt }| ttj| dt  dS )z\
        Using a parameter/flag name that doesn't exist
        will raise an error
        c                   @   s   e Zd ZeddidZdS )z0ZshTests.test_verifyZshNames.<locals>.TmpOptionsZdetaillN)rH   r   r    r!   r	   rA   r   r   r   r   
TmpOptions   s   r]   r=   c                   @   s   e Zd ZedgdZdS )z1ZshTests.test_verifyZshNames.<locals>.TmpOptions2)ZfooZbarrR   Nr\   r   r   r   r   TmpOptions2   s   r^   N)r>   assertRaises
ValueErrorr   r?   r   )r   r]   r^   r   r   r   test_verifyZshNames   s    
  
  zZshTests.test_verifyZshNamesc                 C   sT   t  }| tjd| | tdddddg t }| t|j | 	t
|  dS )zt
        Generate a completion function, and test the textual output
        against a known correct output
        r$   argvsillyr%   r&   r'   N)r   r*   r   r+   sysSimpleProgOptionsr_   r/   r-   r1   testOutput1getvaluer   r6   rJ   r   r   r   test_zshCode   s    zZshTests.test_zshCodec                 C   sT   t  }| tjd| | tdddddg t }| t|j | 	t
|  dS )z
        Generate a completion function with subcommands,
        and test the textual output against a known correct output
        r$   rb   Zsilly2r%   r&   r'   N)r   r*   r   r+   rd   SimpleProgWithSubcommandsr_   r/   r-   r1   testOutput2rg   rh   r   r   r   test_zshCodeWithSubs   s    zZshTests.test_zshCodeWithSubsc              
   C   s\   t  }| tjd| t }| t|jddddddg |d | 	d	t
|d	 d
S )zx
        Completion still happens even if a command-line is given
        that would normally throw UsageError.
        r$   --fokkerserver--unknown-optionz--unknown-option2r&   zsh:5r   r(   Nr   r*   r   r+   r@   r_   r/   r-   r0   r1   r2   r3   rh   r   r   r   test_incompleteCommandLine  s    
 
z#ZshTests.test_incompleteCommandLinec              
   C   sn   t  }| tjd| t }| t|jddddddg |d | 	d	t
|d	 |d |  d
S )z
        Completion still happens even if a command-line is given
        that would normally throw UsageError.

        The existence of --unknown-option prior to the subcommand
        will break subcommand detection... but we complete anyway
        r$   rm   ro   rn   --list-serverr&   rp   r   r(   N)r   r*   r   r+   r@   r_   r/   r-   r0   r1   r2   r3   r4   rh   r   r   r    test_incompleteCommandLine_case2  s    
  

z)ZshTests.test_incompleteCommandLine_case2c              	   C   sZ   t  }| tjd| t }| t|jdddddg |d | 	dt
|d d	S )
z
        Completion still happens even if a command-line is given
        that would normally throw UsageError.

        Break subcommand detection in a different way by providing
        an invalid subcommand name.
        r$   rm   zunknown-subcommandrs   r&   zzsh:4r   r(   Nrq   rh   r   r   r    test_incompleteCommandLine_case3*  s    
  
z)ZshTests.test_incompleteCommandLine_case3c                 C   sV   t  }| tjd| t }| t|jdddg |d | 	dt
|d dS )z
        Ensure the optimization which skips building the subcommand list
        under certain conditions isn't broken.
        r$   z--albar&   r'   r   r(   Nrq   rh   r   r   r   test_skipSubcommandList>  s    

z ZshTests.test_skipSubcommandListc                 C   s.   t  }t|dd}|d}| |d dS )zY
        Test corner case fetching an option description from a method docstring
        r=   Nrc   )r@   r   r?   getDescriptionr1   )r   rJ   argGendescrr   r   r   test_poorlyDescribedOptMethodN  s    
z&ZshTests.test_poorlyDescribedOptMethodc                 C   sF   G dd dt j}t }| }| |d| | t|jdddg dS )zu
        A C{Completer} with repeat=True may only be used as the
        last item in the extraActions list.
        c                   @   s(   e Zd Zejejdde gdZdS )z2ZshTests.test_brokenActions.<locals>.BrokenActionsT)repeat)rI   N)r   r    r!   r   r	   r
   rA   r   r   r   r   BrokenActionsa  s
   
r|   r$   r%   r&   r'   N)r   r+   r   r*   r_   r`   r-   )r   r|   r6   rJ   r   r   r   test_brokenActions\  s    
zZshTests.test_brokenActionsc                 C   sN   G dd dt j}| }t|dd}| |dd | |dd dS )	z~
        opt_* methods on Options classes should not override the
        data provided in optFlags or optParameters.
        c                   @   s6   e Zd ZdddggZddddggZdd	 Zd
d ZdS )z5ZshTests.test_optMethodsDontOverride.<locals>.OptionsflagrV   A flagparampNA paramc                 S   s   dS z junk description Nr   r   r   r   r   opt_flagw  s    z>ZshTests.test_optMethodsDontOverride.<locals>.Options.opt_flagc                 S   s   dS r   r   )r   r   r   r   r   	opt_paramz  s    z?ZshTests.test_optMethodsDontOverride.<locals>.Options.opt_param)r   r    r!   rS   optParametersr   r   r   r   r   r   r+   s  s   r+   r=   Nr~   r   r   r   )r   r+   r   r?   r1   rw   )r   r+   rJ   rx   r   r   r   test_optMethodsDontOverriden  s
    
z$ZshTests.test_optMethodsDontOverrideN)r   r    r!   r"   rL   rY   r[   ra   ri   rl   rr   rt   ru   rv   rz   r}   r   r   r   r   r   r<      s   "r<   c                   @   s   e Zd Zdd ZdS )EscapeTestsc                 C   s2   t j}d}| ||d d}| ||d dS )z5
        Verify _shellcomp.escape() function
        $z'$'zA--'$"\`--Bz"A--'\$\"\\\`--B"N)r   escaper1   )r   Zescr   r   r   r   test_escape  s
    zEscapeTests.test_escapeN)r   r    r!   r   r   r   r   r   r     s   r   c                   @   s   e Zd ZdZdd ZdS )CompleterNotImplementedTestsz
    Test that using an unknown shell constant with SubcommandAction
    raises NotImplementedError

    The other Completer() subclasses are tested in test_usage.py
    c                 C   s   t  }| t|jdd dS )zM
        Using an unknown shellType should raise NotImplementedError
        NZbad_shell_type)r   ZSubcommandActionr_   NotImplementedErrorZ
_shellCode)r   actionr   r   r   test_unknownShell  s
    
 z.CompleterNotImplementedTests.test_unknownShellN)r   r    r!   r"   r   r   r   r   r   r     s   r   c                   @   s*   e Zd ZdZdddggZddddggZdS )FighterAceServerOptionsz4
    Options for FighterAce 'server' subcommand
    zlist-serverNz3List this server with the online FighterAce networkzpackets-per-secondz+Number of update packets to send per secondZ20)r   r    r!   r"   rS   r   r   r   r   r   r     s    r   c                	   @   s   e Zd ZdZdddgdddgdd	d
gdddgdddgdddgdddggZddddgddddggZdded ggZed!d"d#dgddddggde	d$gie
d%d&gd'Zd(d) ZdS )*r@   zB
    Command-line options for an imaginary `Fighter Ace` game
    rN   rV   z2Select the Fokker Dr.I as your dogfighter aircraftrO   rX   z5Select the Albatros D-III as your dogfighter aircraftrP   rW   z1Select the SPAD S.VII as your dogfighter aircraftrQ   rU   z4Select the Bristol Scout as your dogfighter aircraftphysicsr   z$Enable secret Twisted physics engineZjamjz6Enable a small chance that your machine guns will jam!verbosev1Verbose logging (may be specified more than once)z
pilot-nameNzWhat's your name, Ace?zManfred von Richthofendetaildz*Select the level of rendering detail (1-5)3rn   zStart FighterAce game-server.zTwisted-PhysicszRendering detail level)r   r   Z12345zsaved game file to loadry   rB   rE   rG   rH   rI   c                 C   s   dS ) Nr   r   r   r   r   	opt_silly  s    zFighterAceOptions.opt_silly)r   r    r!   r"   rS   r   r   r)   r	   r   r   rA   r   r   r   r   r   r@     s\    
r@   c                   @   sT   e Zd ZdZdddggZddddggZeddided	d
idZdd Z	dd Z
dS )r>   z
    Extend the options and zsh metadata provided by FighterAceOptions.
    _shellcomp must accumulate options and metadata from all classes in the
    hiearchy so this is important to test.
    z	no-stallsNz+Turn off the ability to stall your aircraftzreality-levelz)Select the level of physics reality (1-5)5zCan't stall your planezPhysics reality levelr   )rB   rH   c                 C   s   dS )z8
        Select that you can't crash your plane
        Nr   r   r   r   r   opt_nocrash  s    z%FighterAceExtendedOptions.opt_nocrashc                 C   s   dS )z+
        How tough are you? (1-10)
        Nr   )r   rZ   r   r   r   opt_difficulty  s    z(FighterAceExtendedOptions.opt_difficulty)r   r    r!   r"   rS   r   r	   r
   rA   r   r   r   r   r   r   r>     s     r>   c                   C   s   t dddgddS )N12r   zAccuracy'`?r   r   r   r   r   r   _accuracyAction  s    r   c                
   @   s   e Zd ZdZdddgdddgdd	d
ggZddddgddddggZeddddgddggedddddgddede	ddgdZ
dd ZdS ) re   z>
    Command-line options for a `Silly` imaginary program
    colorczTurn on color outputZgraygzTurn on gray-scale outputr   r   r   optimizationNr   z&Select the level of optimization (1-5)accuracyrX   r   z"Select the level of accuracy (1-3)zColor onzOptimization level)r   r   r   r   4zOptimization?r   )r   r   zoutput filer   c                 C   s   dS )zM
        usage.Options does not recognize single-letter opt_ methods
        Nr   r   r   r   r   opt_X   s    zSimpleProgOptions.opt_X)r   r    r!   r"   rS   r   r	   r   r   r   rA   r   r   r   r   r   re     s8   
re   c                   @   s   e Zd ZdddggZdS )SimpleProgSub1sub-optrW   zSub Opt OneNr   r    r!   rS   r   r   r   r   r   '  s   r   c                   @   s   e Zd ZdddggZdS )SimpleProgSub2r   rW   zSub Opt TwoNr   r   r   r   r   r   ,  s   r   c                   @   sH   e Zd ZdgddggZdgddgddd	ggZd
dedgddedggZdS )rj   zsome-optionzother-optionr7   z
some-paramzother-paramr   zanother-paramPzYet Another ParamZsub1NzSub Command 1Zsub2zSub Command 2)r   r    r!   rS   r   r   r   r)   r   r   r   r   rj   1  s   

rj   s  #compdef silly

_arguments -s -A "-*" \
':output file (*):_files -g "*"' \
"(--accuracy)-a[Select the level of accuracy (1-3)]:Accuracy'\`?:(1 2 3)" \
"(-a)--accuracy=[Select the level of accuracy (1-3)]:Accuracy'\`?:(1 2 3)" \
'(--color --gray -g)-c[Color on]' \
'(--gray -c -g)--color[Color on]' \
'(--color --gray -c)-g[Turn on gray-scale output]' \
'(--color -c -g)--gray[Turn on gray-scale output]' \
'--help[Display this help and exit.]' \
'--optimization=[Optimization level]:Optimization?:(1 2 3 4 5)' \
'*-v[Verbose logging (may be specified more than once)]' \
'*--verbose[Verbose logging (may be specified more than once)]' \
'--version[Display Twisted version and exit.]' \
&& return 0
s  #compdef silly2

_arguments -s -A "-*" \
'*::subcmd:->subcmd' \
':output file (*):_files -g "*"' \
"(--accuracy)-a[Select the level of accuracy (1-3)]:Accuracy'\`?:(1 2 3)" \
"(-a)--accuracy=[Select the level of accuracy (1-3)]:Accuracy'\`?:(1 2 3)" \
'(--another-param)-P[another-param]:another-param:_files' \
'(-P)--another-param=[another-param]:another-param:_files' \
'(--color --gray -g)-c[Color on]' \
'(--gray -c -g)--color[Color on]' \
'(--color --gray -c)-g[Turn on gray-scale output]' \
'(--color -c -g)--gray[Turn on gray-scale output]' \
'--help[Display this help and exit.]' \
'--optimization=[Optimization level]:Optimization?:(1 2 3 4 5)' \
'(--other-option)-o[other-option]' \
'(-o)--other-option[other-option]' \
'(--other-param)-p[other-param]:other-param:_files' \
'(-p)--other-param=[other-param]:other-param:_files' \
'--some-option[some-option]' \
'--some-param=[some-param]:some-param:_files' \
'*-v[Verbose logging (may be specified more than once)]' \
'*--verbose[Verbose logging (may be specified more than once)]' \
'--version[Display Twisted version and exit.]' \
&& return 0
local _zsh_subcmds_array
_zsh_subcmds_array=(
"sub1:Sub Command 1"
"sub2:Sub Command 2"
)

_describe "sub-command" _zsh_subcmds_array
)&r"   Z
__future__r   r   rd   ior   Ztwisted.trialr   Ztwisted.pythonr   r   r   Ztwisted.python.usager	   r
   r   r   r   r   objectr#   r   ZTestCaser<   r   r   r+   r   r@   r>   r   re   r   r   rj   rf   rk   r   r   r   r   <module>   s2   D  /#