o
    q+WZ5                     @   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?
    Z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!   Zuponr   Zmmr   r   SampleObject-   s    




r)   )r   objectr    )r)   Z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)
_visualizer-   )r   r-   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assertEqualr-   r   Zexpectedr   r   r   test_sortsAttrsJ   s   z!ElementMakerTests.test_sortsAttrsc              	   C   r0   )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>r1   z	a " quoter   za stringr5   Nr9   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>r1   Nr9   r;   r   r   r   test_noAttrsb   s   zElementMakerTests.test_noAttrsN)r"   r#   r$   __doc__r/   r<   r=   r>   r   r   r   r   r,   @   s    r,   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$   r?   attrZibnamechildren
attributesr   r   r   r   r@   j   s
    r@   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>)isLeafrC   )elementrJ   r   rI   r   rE   r   s   
rE   c                 C   s   t | t S )z2
    This HTML element is actually leaf node.
    )
isinstancer@   rM   r   r   r   rL      s   rL   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)rB   rC   rD   )r@   )r   rB   rC   rD   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)Z_E)r.   rR   
inputLabelport	functoolspartialrQ   )r   rR   r   r   r   r/      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 )NrU   )rL   rD   getrU   rO   r   r   r   hasPort   s   
z3TableMakerTests.test_inputLabelRow.<locals>.hasPortzan output labelrU   r   r   tdN)
rR   rT   rU   ZassertGreaterlenrC   rE   r:   rB   rL   )r   rY   ZoutputLabelstableinputLabelRowZ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.
        rS   r   rZ   r   colspanN)rR   rU   r:   r\   rC   ZassertNotInrD   )r   r]   r^   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 2rZ   r   c                 S   s$   t |  o| jdko| jddkS )Nr[   r`   r2   )rL   rB   rD   rX   rO   r   r   r   hasCorrectColspan   s
   
z@TableMakerTests.test_withOutputLabels.<locals>.hasCorrectColspanr   rb   rc   N)rR   rT   rU   r:   r\   rC   rE   rL   )r   r]   ZinputRowZ	outputRowrd   r   r   r   test_withOutputLabels   s   


z%TableMakerTests.test_withOutputLabelsN)	r"   r#   r$   r?   rQ   r/   r_   ra   re   r   r   r   r   rP      s    
rP   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PIPEZcommunicatejoinr+   	asDigraphencoder:   
returncode)r   pr!   errr   r   r   test_validGraphviz   s   
z#IntegrationTests.test_validGraphvizN)r"   r#   r$   r?   rr   r   r   r   r   rg      s    rg   c                   @   rf   )
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.
        ri   r   r   r    r!   N)rl   r+   rm   ZassertIn)r   Zgvoutr   r   r   test_containsMachineFeatures   s
   z'SpotChecks.test_containsMachineFeaturesN)r"   r#   r$   r?   rt   r   r   r   r   rs      s    rs   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 rw   )renderCalls	saveCallsr   r   r   r   rx     s   
zRecordsDigraphActions.resetN)r"   r#   r$   r?   ry   rx   r   r   r   r   rv          rv   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 rw   )	_recorder)r   Zrecorderr   r   r   ry        
zFakeDigraph.__init__c                 K      | j j| d S rw   )r   rz   appendr   kwargsr   r   r   render     zFakeDigraph.renderc                 K   r   rw   )r   r{   r   r   r   r   r   save  r   zFakeDigraph.saveN)r"   r#   r$   r?   ry   r   r   r   r   r   r   r}   
  s
    r}   c                   @   ru   )FakeMethodicalMachinezL
    A fake L{MethodicalMachine}.  Instantiate it with a L{FakeDigraph}
    c                 C   r~   rw   Z_digraph)r   Zdigraphr   r   r   ry     r   zFakeMethodicalMachine.__init__c                 C   s   | j S rw   r   r   r   r   r   rm   "  s   zFakeMethodicalMachine.asDigraphN)r"   r#   r$   r?   ry   rm   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-testZignoredz	fake.fqpn)rv   digraphRecorderr}   fakeDigraphfakePrognamefakeSysPathcollectedOutputfakeFQPNr   r   r   r   r/   +  s   
zVisualizeToolTests.setUpc                 G   s   | j d| d S )N )r   r   rl   )r   argsr   r   r   collectPrints4  s   z VisualizeToolTests.collectPrintsc                 c   s    |t | jfV  d S rw   )r   r   )r   Z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)Z	_prognameZ_argvZ_syspathZ_findMachinesZ_print)r.   r   r   r   r   r   r   )r   ZprognameargvZsyspathZ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   ri   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-iri   r   c                 s       | ]}d |v V  qdS imageNr   rF   liner   r   r   	<genexpr>d      z6VisualizeToolTests.test_onlySaveDot.<locals>.<genexpr>r   {}.dotfilenameN)r   rx   r   r   r   r   anyr:   r\   r{   formatrz   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-dri   r   c                 s   r   r   Nr   r   r   r   r   r   x  r   z8VisualizeToolTests.test_saveOnlyImage.<locals>.<genexpr>r   r   r   cleanupN)r   rx   r   r   r   r   r   r:   r\   rz   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:   r\   r   rz   r{   )r   ZimageDirectoryZdotDirectory
renderCallZ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.
        Z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:   r\   r   rz   r   r{   )r   r   r   r   r   r   $test_saveDotAndImagesInSameDirectory  s   

z7VisualizeToolTests.test_saveDotAndImagesInSameDirectory)NNNNN)r"   r#   r$   r/   r   r   r   r   r   r   r   r   r   r   r   r   r   r   &  s     	
		r   )Z
__future__r   rV   r   r   Zunittestr   r   rA   Z_methodicalr   Ztest_discoverr   r   r   r+   r,   sr*   r@   rE   rL   rP   rg   rs   rv   r}   r   r   r   r   r   r   <module>   s>    )N