B
    d+                 @   s   d dl mZ d dlZd dlZd dlZddlmZ ddlmZ ddlm	Z	m
Z
 ddlmZmZ ddlmZ G d	d
 d
eZdd ZG dd dejZG dd deZG dd deZdddZdS )    )absolute_importN   )Errors)
CodeWriter)TreeFragmentstrip_common_indent)TreeVisitorVisitorTransform)TreePathc                   s$   e Zd Z fddZdd Z  ZS )NodeTypeWriterc                s   t t|   d| _g | _d S )Nr   )superr   __init___indentsresult)self)	__class__ ]/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/Cython/TestUtils.pyr      s    zNodeTypeWriter.__init__c             C   s   | j sd}n0| j d }|d d k	r4d|dd  }n|d }| jd| j d||jjf   |  jd7  _| | |  jd8  _d S )	Nz(root)   z%s[%d]r      z  z%s: %s)Zaccess_pathr   appendr   r   __name__visitchildren)r   nodenameZtipr   r   r   
visit_Node   s    

zNodeTypeWriter.visit_Node)r   
__module____qualname__r   r   __classcell__r   r   )r   r   r      s   r   c             C   s(   t  }||  ddg|j dg S )zReturns a string representing the tree by class names.
    There's a leading and trailing whitespace so that it can be
    compared by simple string comparison while still making test
    cases look ok.
 )r   visitjoinr   )rootwr   r   r   	treetypes%   s    
r&   c               @   sj   e 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dZ
dd ZefddZdd ZdS )
CythonTestc             C   s    t j| _t j| _d  t _t _d S )N)r   listing_file	echo_file)r   r   r   r   setUp1   s    zCythonTest.setUpc             C   s   | j t_ | jt_d S )N)r(   r   r)   )r   r   r   r   tearDown6   s    zCythonTest.tearDownc          	   C   s   t |ts|d}t |ts(|d}x6tt||D ]$\}\}}| ||d|||f  q8W | t|t|dd|d|f  dS )zHChecks that the given strings or lists of strings are equal line by liner    zLine %d:
Exp: %s
Got: %sz%Unmatched lines. Got:
%s
Expected:
%sN)
isinstancelistsplit	enumeratezipassertEquallenr#   )r   expectedr   idxexpected_lineZresult_liner   r   r   assertLines:   s    



zCythonTest.assertLinesc             C   s   t  }|| |jjS )N)r   writer   lines)r   treewriterr   r   r   codeToLinesF   s    
zCythonTest.codeToLinesc             C   s   d | |S )Nr    )r#   r;   )r   r9   r   r   r   codeToStringK   s    zCythonTest.codeToStringc          	   C   sx   |  |}t|d}x6tt||D ]$\}\}}| ||d|||f  q(W | t|t|dd||f  d S )Nr    zLine %d:
Got: %s
Exp: %sz%Unmatched lines. Got:
%s
Expected:
%s)r;   r   r.   r/   r0   r1   r2   r#   )r   r3   result_treeZresult_linesZexpected_linesr4   liner5   r   r   r   
assertCodeN   s    
zCythonTest.assertCodec             C   s   |  t||d d|  d S )Nz"Path '%s' not found in result tree)ZassertNotEqualr
   
find_first)r   pathr=   r   r   r   assertNodeExistsY   s    zCythonTest.assertNodeExistsNc             C   sV   |dkri }|dkrg }|   }|dr:|tdd }|dd}t||||dS )zNSimply create a tree fragment using the name of the test-case in parse errors.Nz	__main__.._)pipeline)id
startswithr2   replacer   )r   codepxdsrE   r   r   r   r   fragment]   s    
zCythonTest.fragmentc             C   s   t |S )N)r&   )r   r$   r   r   r   r&   i   s    zCythonTest.treetypesc          
   C   sP   y|  |  d|  W n2 |k
rJ } z| t|| |S d}~X Y nX dS )zCalls "func" and fails if it doesn't raise the right exception
        (any exception by default). Also returns the exception in question.
        z Expected an exception of type %rN)fail
assertTruer,   )r   funcexc_typeer   r   r   should_faill   s    zCythonTest.should_failc          
   C   s<   y| S  t k
r6 } z| t| W dd}~X Y nX dS )zCalls func and succeeds if and only if no exception is raised
        (i.e. converts exception raising into a failed testcase). Returns
        the return value of func.N)	ExceptionrL   str)r   rN   excr   r   r   should_not_failw   s    zCythonTest.should_not_fail)NN)r   r   r   r*   r+   r6   r;   r<   r?   rB   rK   r&   rR   rQ   rU   r   r   r   r   r'   /   s   
r'   c               @   s   e Zd ZdZdddZdS )TransformTesta.  
    Utility base class for transform unit tests. It is based around constructing
    test trees (either explicitly or by parsing a Cython code string); running
    the transform, serialize it using a customized Cython serializer (with
    special markup for nodes that cannot be represented in Cython),
    and do a string-comparison line-by-line of the result.

    To create a test case:
     - Call run_pipeline. The pipeline should at least contain the transform you
       are testing; pyx should be either a string (passed to the parser to
       create a post-parse tree) or a node representing input to pipeline.
       The result will be a transformed result.

     - Check that the tree is correct. If wanted, assertCode can be used, which
       takes a code string as expected, and a ModuleNode in result_tree
       (it serializes the ModuleNode to a string and compares line-by-line).

    All code strings are first stripped for whitespace lines and then common
    indentation.

    Plans: One could have a pxd dictionary parameter to run_pipeline.
    Nc             C   s4   |d kri }|  ||j}x|D ]}||}q W |S )N)rK   r$   )r   rE   pyxrJ   r9   Tr   r   r   run_pipeline   s    
zTransformTest.run_pipeline)N)r   r   r   __doc__rY   r   r   r   r   rV      s   rV   c               @   s   e Zd Zdd ZejZdS )TreeAssertVisitorc             C   s   |j }d|krBx2|d D ]&}t||d krt|jd|  qW d|kr~x2|d D ]&}t||d k	rTt|jd|  qTW | | |S )NZtest_assert_path_existsz+Expected path '%s' not found in result treeZtest_fail_if_path_existsz)Unexpected path '%s' found in result tree)
directivesr
   r@   r   errorposr   )r   r   r\   rA   r   r   r   visit_CompilerDirectivesNode   s    
z.TreeAssertVisitor.visit_CompilerDirectivesNodeN)r   r   r   r_   r	   Zrecurse_to_childrenr   r   r   r   r   r[      s   r[   c       	      C   s8  |d krt  }g }d }t| }z| }W d |  X ~zx|D ]}|d d dkr| d dtjj	}tj
||}tjtj|sttj| |d k	r|d  }}|  t|d}qB|d k	r|| qB| rB| dsB| dkrB|| qBW W d |d k	r(|  X |d
|fS )N   z######/r%   )z"""z'''r!   )tempfilemkdtempopen	readlinesclosestriprH   osrA   sepr#   existsdirnamemakedirsr7   lstriprG   r   )	Z	tree_filedirheaderZcur_filefr8   r>   filenamerA   r   r   r   unpack_source_tree   s8    




rs   )N)
__future__r   ri   Zunittestrc   ZCompilerr   r   ZCompiler.TreeFragmentr   r   ZCompiler.Visitorr   r	   r
   r   r&   ZTestCaser'   rV   r[   rs   r   r   r   r   <module>   s   
R"