o
    q+WZ°5  ã                   @   s†  d dl mZ d dlZd dlZd dlZd dlmZmZ d dlZddl	m
Z
 ddlmZ dd	„ Zd
d„ Zdd„ Zeeƒ  dƒG dd„ deƒƒZejG dd„ deƒƒZdd„ Zdd„ Zeeƒ  dƒG dd„ deƒƒZeeƒ  dƒeeƒ  dƒG dd„ deƒƒƒZeeƒ  dƒG dd„ deƒƒZG dd„ deƒZG d d!„ d!eƒZG d"d#„ d#eƒZeeƒ  dƒeeƒ  dƒeeƒ  d$ƒG d%d&„ d&eƒƒƒƒZdS )'é    )Úprint_functionN)ÚTestCaseÚskipIfé   )ÚMethodicalMachineé   )ÚisTwistedInstalledc                   C   s$   zt dƒ W dS  ty   Y dS w )z2
    Is the graphviz Python module installed?
    ÚgraphvizFT)Ú
__import__ÚImportError© r   r   ú>/usr/lib/python3/dist-packages/automat/_test/test_visualize.pyÚisGraphvizModuleInstalled   s   
ýÿr   c               	   C   sB   t  ¡ \} }t  |¡ ztjd| dd� W t  | ¡ S t  | ¡ w )z+
    Are the graphviz tools installed?
    ÚdotT)ÚstdinÚshell)ÚosÚpipeÚcloseÚ
subprocessÚcall)ÚrÚwr   r   r   ÚisGraphvizInstalled   s
   
r   c                     s,   t ƒ ‰ G ‡ fdd„dtƒ} | ƒ }| ¡  ˆ S )zG
    Create a sample L{MethodicalMachine} with some sample states.
    c                       s`   e Zd Z” jdd�dd„ ƒZ”  ¡ dd„ ƒZ”  ¡ dd„ ƒZ”  ¡ d	d
„ ƒZ	e 
eee	g¡ dS )z#sampleMachine.<locals>.SampleObjectT)Úinitialc                 S   ó   dS )zinitial stateNr   ©Úselfr   r   r   Úbegin.   ó    z)sampleMachine.<locals>.SampleObject.beginc                 S   r   )z	end stateNr   r   r   r   r   Úend1   r   z'sampleMachine.<locals>.SampleObject.endc                 S   r   )zsample inputNr   r   r   r   r   Úgo4   r   z&sampleMachine.<locals>.SampleObject.goc                 S   r   )zsample outputNr   r   r   r   r   Úout7   r   z'sampleMachine.<locals>.SampleObject.outN)Ú__name__Ú
__module__Ú__qualname__Ústater   r    Úinputr!   Úoutputr"   Úuponr   ©Úmmr   r   ÚSampleObject-   s    




r,   )r   Úobjectr!   )r,   Úsor   r*   r   ÚsampleMachine(   s
   r/   z!Graphviz module is not installed.c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚElementMakerTestszL
    L{elementMaker} generates HTML representing the specified element.
    c                 C   s   ddl m} || _d S )Nr   )ÚelementMaker)Ú
_visualizer1   )r   r1   r   r   r   ÚsetUpF   s   
zElementMakerTests.setUpc              	   C   ó"   d}|   || jddddd�¡ dS )zK
        L{elementMaker} orders HTML attributes lexicographically.
        z<div a="1" b="2" c="3"></div>ÚdivÚ2Ú1Ú3©ÚbÚaÚcN©ÚassertEqualr1   ©r   Úexpectedr   r   r   Útest_sortsAttrsJ   s   ýÿz!ElementMakerTests.test_sortsAttrsc              	   C   r4   )z¡
        L{elementMaker} quotes HTML attributes according to DOT's quoting rule.

        See U{http://www.graphviz.org/doc/info/lang.html}, footnote 1.
        z-<div a="1" b="a \" quote" c="a string"></div>r5   z	a " quoter   za stringr9   Nr=   r?   r   r   r   Útest_quotesAttrsU   s   ýÿz"ElementMakerTests.test_quotesAttrsc                 C   s   d}|   ||  d¡¡ dS )zN
        L{elementMaker} should render an element with no attributes.
        z<div ></div>r5   Nr=   r?   r   r   r   Útest_noAttrsb   s   zElementMakerTests.test_noAttrsN)r#   r$   r%   Ú__doc__r3   rA   rB   rC   r   r   r   r   r0   @   s    r0   c                   @   s(   e Zd ZdZe ¡ Ze ¡ Ze ¡ ZdS )ÚHTMLElementz2Holds an HTML element, as created by elementMaker.N)	r#   r$   r%   rD   ÚattrÚibÚnameÚchildrenÚ
attributesr   r   r   r   rE   j   s
    rE   c                    s.   ˆ | ƒr| gS t | ƒrg S ‡ fdd„| jD ƒS )zk
    Recursively collect all elements in an L{HTMLElement} tree that
    match the optional predicate.
    c                    s    g | ]}t |ˆ ƒD ]}|‘q	qS r   )ÚfindElements)Ú.0ÚchildÚresult©Ú	predicater   r   Ú
<listcomp>|   s    þ
þz findElements.<locals>.<listcomp>)ÚisLeafrI   )ÚelementrP   r   rO   r   rK   r   s   
ÿrK   c                 C   s   t | tƒ S )z2
    This HTML element is actually leaf node.
    )Ú
isinstancerE   ©rS   r   r   r   rR   �   s   rR   c                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )ÚTableMakerTestszÚ
    Tests that ensure L{tableMaker} generates HTML tables usable as
    labels in DOT graphs.

    For more information, read the "HTML-Like Labels" section of
    U{http://www.graphviz.org/doc/info/shapes.html}.
    c                 O   s   t |||d�S )N)rH   rI   rJ   )rE   )r   rH   rI   rJ   r   r   r   ÚfakeElementMaker’   s   z TableMakerTests.fakeElementMakerc                 C   s.   ddl m} d| _d| _tj|| jd�| _d S )Nr   )Ú
tableMakerúinput labelzthe port)Ú_E)r2   rX   Ú
inputLabelÚportÚ	functoolsÚpartialrW   )r   rX   r   r   r   r3   •   s   ÿzTableMakerTests.setUpc                    s’   ‡ fdd„}g dgfD ];}ˆ j ˆ j|ˆ jd�}ˆ  t|jƒd¡ |jd }t||ƒ}ˆ  t|ƒd¡ ˆ  |d jd¡ ˆ  t|t	ƒˆ jg¡ qdS )	zÍ
        The table returned by L{tableMaker} always contains the input
        symbol label in its first row, and that row contains one cell
        with a port attribute set to the provided port.
        c                    s   t | ƒ o| j d¡ˆ jkS )Nr\   )rR   rJ   Úgetr\   rU   r   r   r   ÚhasPort¤   s   
ÿz3TableMakerTests.test_inputLabelRow.<locals>.hasPortzan output label©r\   r   r   ÚtdN)
rX   r[   r\   ÚassertGreaterÚlenrI   rK   r>   rH   rR   )r   r`   ÚoutputLabelsÚtableÚinputLabelRowÚportCandidatesr   r   r   Útest_inputLabelRow�   s   
ÿ

ÿöz"TableMakerTests.test_inputLabelRowc                 C   s>   | j dd| jd�}|  t|jƒd¡ |j\}|  d|j¡ dS )z�
        L{tableMaker} does not add a colspan attribute to the input
        label's cell or a second row if there no output labels.
        rY   r   ra   r   ÚcolspanN)rX   r\   r>   rd   rI   ÚassertNotInrJ   )r   rf   rg   r   r   r   Útest_noOutputLabelsµ   s   z#TableMakerTests.test_noOutputLabelsc                 C   sh   | j | jd| jd�}|  t|jƒd¡ |j\}}dd„ }|  tt||ƒƒd¡ |  t|tƒddg¡ d	S )
z¹
        L{tableMaker} adds a colspan attribute to the input label's cell
        equal to the number of output labels and a second row that
        contains the output labels.
        )úoutput label 1úoutput label 2ra   r   c                 S   s$   t | ƒ o| jdko| j d¡dkS )Nrb   rj   r6   )rR   rH   rJ   r_   rU   r   r   r   ÚhasCorrectColspanÌ   s
   
ÿþz@TableMakerTests.test_withOutputLabels.<locals>.hasCorrectColspanr   rm   rn   N)rX   r[   r\   r>   rd   rI   rK   rR   )r   rf   ÚinputRowÚ	outputRowro   r   r   r   Útest_withOutputLabels¿   s   
þ
ÿ
ÿz%TableMakerTests.test_withOutputLabelsN)	r#   r$   r%   rD   rW   r3   ri   rl   rr   r   r   r   r   rV   ˆ   s    
rV   z!Graphviz tools are not installed.c                   @   ó   e Zd ZdZdd„ ZdS )ÚIntegrationTestsz[
    Tests which make sure Graphviz can understand the output produced by
    Automat.
    c                 C   sF   t jdt jt jd�}| d tƒ  ¡ ¡ d¡¡\}}|  |j	d¡ dS )z8
        L{graphviz} emits valid graphviz data.
        r   )r   ÚstdoutÚ zutf-8r   N)
r   ÚPopenÚPIPEÚcommunicateÚjoinr/   Ú	asDigraphÚencoder>   Ú
returncode)r   Úpr"   Úerrr   r   r   Útest_validGraphvizß   s   
ÿÿz#IntegrationTests.test_validGraphvizN)r#   r$   r%   rD   r€   r   r   r   r   rt   ×   s    rt   c                   @   rs   )Ú
SpotCheckszj
    Tests to make sure that the output contains salient features of the machine
    being generated.
    c                 C   sD   d  tƒ  ¡ ¡}|  d|¡ |  d|¡ |  d|¡ |  d|¡ dS )z�
        The output of L{graphviz} should contain the names of the states,
        inputs, outputs in the state machine.
        rv   r   r    r!   r"   N)rz   r/   r{   ÚassertIn)r   Úgvoutr   r   r   Útest_containsMachineFeaturesñ   s
   z'SpotChecks.test_containsMachineFeaturesN)r#   r$   r%   rD   r„   r   r   r   r   r�   ê   s    r�   c                   @   ó    e Zd ZdZdd„ Zdd„ ZdS )ÚRecordsDigraphActionsz/
    Records calls made to L{FakeDigraph}.
    c                 C   s   |   ¡  d S ©N)Úresetr   r   r   r   Ú__init__  s   zRecordsDigraphActions.__init__c                 C   s   g | _ g | _d S r‡   )ÚrenderCallsÚ	saveCallsr   r   r   r   rˆ     s   
zRecordsDigraphActions.resetN)r#   r$   r%   rD   r‰   rˆ   r   r   r   r   r†   ý   ó    r†   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚFakeDigraphzZ
    A fake L{graphviz.Digraph}.  Instantiate it with a
    L{RecordsDigraphActions}.
    c                 C   ó
   || _ d S r‡   )Ú	_recorder)r   Úrecorderr   r   r   r‰     ó   
zFakeDigraph.__init__c                 K   ó   | j j |¡ d S r‡   )r�   rŠ   Úappend©r   Úkwargsr   r   r   Úrender  ó   zFakeDigraph.renderc                 K   r’   r‡   )r�   r‹   r“   r”   r   r   r   Úsave  r—   zFakeDigraph.saveN)r#   r$   r%   rD   r‰   r–   r˜   r   r   r   r   r�   
  s
    r�   c                   @   r…   )ÚFakeMethodicalMachinezL
    A fake L{MethodicalMachine}.  Instantiate it with a L{FakeDigraph}
    c                 C   rŽ   r‡   ©Ú_digraph)r   Údigraphr   r   r   r‰     r‘   zFakeMethodicalMachine.__init__c                 C   s   | j S r‡   rš   r   r   r   r   r{   "  s   zFakeMethodicalMachine.asDigraphN)r#   r$   r%   rD   r‰   r{   r   r   r   r   r™     rŒ   r™   zTwisted is not installed.c                   @   sh   e Zd Zdd„ Zdd„ Zdd„ Z					ddd	„Zd
d„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ ZdS )ÚVisualizeToolTestsc                 C   s2   t ƒ | _t| jƒ| _d| _dg| _g | _d| _d S )Nz	tool-testÚignoredz	fake.fqpn)r†   ÚdigraphRecorderr�   ÚfakeDigraphÚfakePrognameÚfakeSysPathÚcollectedOutputÚfakeFQPNr   r   r   r   r3   +  s   
zVisualizeToolTests.setUpc                 G   s   | j  d |¡¡ d S )Nú )r£   r“   rz   )r   Úargsr   r   r   ÚcollectPrints4  s   z VisualizeToolTests.collectPrintsc                 c   s   � |t | jƒfV  d S r‡   )r™   r    )r   Úfqpnr   r   r   ÚfakeFindMachines7  s   €z#VisualizeToolTests.fakeFindMachinesNc                 C   s>   ddl m} ||p| j|p| jg|p| j|p| j|p| jd�S )Nr   )Útool)Ú	_prognameÚ_argvÚ_syspathÚ_findMachinesÚ_print)r2   rª   r¡   r¤   r¢   r©   r§   )r   ÚprognameÚargvÚsyspathÚfindMachinesÚprintrª   r   r   r   rª   :  s   
ûzVisualizeToolTests.toolc                 C   s&   | j | jgd� |  | jd d¡ dS )z‰
        L{tool} adds '' to sys.path to ensure
        L{automat._discover.findMachines} searches the current
        directory.
        ©r±   r   rv   N)rª   r¤   r>   r¢   r   r   r   r   Útest_checksCurrentDirectoryH  s   z.VisualizeToolTests.test_checksCurrentDirectoryc                 C   s@   | j | jdgd� |  | j¡ | j | jdgd� |  | j¡ dS )z6
        Passing -q/--quiet hides all output.
        z--quietrµ   z-qN)rª   r¤   ÚassertFalser£   r   r   r   r   Útest_quietHidesOutputQ  s   z(VisualizeToolTests.test_quietHidesOutputc                 C   s�   dD ]C}| j  ¡  g | _| j| j|dgd� |  tdd„ | jD ƒƒ¡ |  t| j j	ƒd¡ | j j	\}|  d 
| j¡|d ¡ |  | j j¡ qd	S )
ze
        Passing an empty string for --image-directory/-i disables
        rendering images.
        )ú--image-directoryz-irv   rµ   c                 s   ó   � | ]}d |v V  qdS ©ÚimageNr   ©rL   Úliner   r   r   Ú	<genexpr>d  ó   € ÿz6VisualizeToolTests.test_onlySaveDot.<locals>.<genexpr>r   ú{}.dotÚfilenameN)rŸ   rˆ   r£   rª   r¤   r·   Úanyr>   rd   r‹   ÚformatrŠ   ©r   Úargr   r   r   r   Útest_onlySaveDotZ  s   

ÿ
ÿóz#VisualizeToolTests.test_onlySaveDotc                 C   sž   dD ]J}| j  ¡  g | _| j| j|dgd� |  tdd„ | jD ƒƒ¡ |  t| j j	ƒd¡ | j j	\}|  d 
| j¡|d ¡ |  |d	 ¡ |  | j j¡ qd
S )zc
        Passing an empty string for --dot-directory/-d disables saving dot
        files.
        )ú--dot-directoryz-drv   rµ   c                 s   rº   ©r   Nr   r½   r   r   r   r¿   x  rÀ   z8VisualizeToolTests.test_saveOnlyImage.<locals>.<genexpr>r   rÁ   rÂ   ÚcleanupN)rŸ   rˆ   r£   rª   r¤   r·   rÃ   r>   rd   rŠ   rÄ   Ú
assertTruer‹   rÅ   r   r   r   Útest_saveOnlyImagen  s   

ÿ
ÿòz%VisualizeToolTests.test_saveOnlyImagec                 C   sÂ   d}d}| j | jd|d|gd� |  tdd„ | jD ƒƒ¡ |  tdd„ | jD ƒƒ¡ |  t| jjƒd	¡ | jj\}|  |d
 |¡ |  |d ¡ |  t| jj	ƒd	¡ | jj	\}|  |d
 |¡ dS )z’
        Passing different directories to --image-directory and --dot-directory
        writes images and dot files to those directories.
        r¼   r   r¹   rÈ   rµ   c                 s   rº   r»   r   r½   r   r   r   r¿   Ž  rÀ   zQVisualizeToolTests.test_saveDotAndImagesInDifferentDirectories.<locals>.<genexpr>c                 s   rº   rÉ   r   r½   r   r   r   r¿   �  rÀ   r   Ú	directoryrÊ   N)
rª   r¤   rË   rÃ   r£   r>   rd   rŸ   rŠ   r‹   )r   ÚimageDirectoryÚdotDirectoryÚ
renderCallÚsaveCallr   r   r   Ú+test_saveDotAndImagesInDifferentDirectoriesƒ  s&   þ
ÿ
ÿ

z>VisualizeToolTests.test_saveDotAndImagesInDifferentDirectoriesc                 C   sˆ   d}| j | jd|d|gd� |  tdd„ | jD ƒƒ¡ |  t| jjƒd¡ | jj\}|  |d |¡ |  	|d	 ¡ |  	t| jj
ƒ¡ d
S )z�
        Passing the same directory to --image-directory and --dot-directory
        writes images and dot files to that one directory.
        ÚimagesAndDotr¹   rÈ   rµ   c                 s   rº   )zimage and dotNr   r½   r   r   r   r¿   ¦  rÀ   zJVisualizeToolTests.test_saveDotAndImagesInSameDirectory.<locals>.<genexpr>r   rÍ   rÊ   N)rª   r¤   rË   rÃ   r£   r>   rd   rŸ   rŠ   r·   r‹   )r   rÍ   rÐ   r   r   r   Ú$test_saveDotAndImagesInSameDirectoryœ  s   þ
ÿ
z7VisualizeToolTests.test_saveDotAndImagesInSameDirectory)NNNNN)r#   r$   r%   r3   r§   r©   rª   r¶   r¸   rÇ   rÌ   rÒ   rÔ   r   r   r   r   r�   &  s     	
û		r�   )Ú
__future__r   r]   r   r   Úunittestr   r   rF   Ú_methodicalr   Útest_discoverr   r   r   r/   r0   Úsr-   rE   rK   rR   rV   rt   r�   r†   r�   r™   r�   r   r   r   r   Ú<module>   s>    )N