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?
    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