a
    b+                     @   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__ `/Users/vegardjervell/Documents/master/model/venv/lib/python3.9/site-packages/Cython/TestUtils.pyr      s    zNodeTypeWriter.__init__c                 C   s   | j sd}n0| j d }|d d u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_filer   r   r   r   setUp1   s    zCythonTest.setUpc                 C   s   | j t_ | jt_d S r*   )r+   r   r,   r   r   r   r   tearDown6   s    zCythonTest.tearDownc              	   C   s   t |ts|d}t |ts(|d}tt||D ]$\}\}}| ||d|||f  q6| 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: %s%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 r*   )r   writer   lines)r   treewriterr   r   r   codeToLinesF   s    
zCythonTest.codeToLinesc                 C   s   d | |S )Nr"   )r%   r?   )r   r=   r   r   r   codeToStringK   s    zCythonTest.codeToStringc              	   C   st   |  |}t|d}tt||D ]$\}\}}| ||d|||f  q&| t|t|dd||f  d S )Nr"   zLine %d:
Got: %s
Exp: %sr/   )r?   r   r2   r3   r4   r5   r6   r%   )r   r7   result_treeZresult_linesZexpected_linesr8   liner9   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   pathrA   r   r   r   assertNodeExistsY   s    zCythonTest.assertNodeExistsNc                 C   sV   |du ri }|du 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
startswithr6   replacer   )r   codepxdsrI   r   r   r   r   fragment]   s    
zCythonTest.fragmentc                 C   s   t |S r*   )r(   )r   r&   r   r   r   r(   i   s    zCythonTest.treetypesc              
   C   sV   z|  |  d|  W n8 |yP } z | t|| |W  Y d}~S d}~0 0 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
assertTruer0   )r   funcexc_typeer   r   r   should_faill   s    zCythonTest.should_failc              
   C   s@   z| W S  t y: } z| t| W Y d}~n
d}~0 0 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)	ExceptionrP   str)r   rR   excr   r   r   should_not_failw   s    zCythonTest.should_not_fail)NN)r   r   r    r-   r.   r:   r?   r@   rC   rF   rO   r(   rV   rU   rY   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   s0   |d u ri }|  ||j}|D ]}||}q|S r*   )rO   r&   )r   rI   ZpyxrN   r=   Tr   r   r   run_pipeline   s    
zTransformTest.run_pipeline)N)r   r   r    __doc__r\   r   r   r   r   rZ      s   rZ   c                   @   s   e Zd Zdd ZejZdS )TreeAssertVisitorc                 C   s   |j }d|v r>|d D ]&}t||d u rt|jd|  qd|v rv|d D ]&}t||d urNt|jd|  qN| | |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
   rD   r   errorposr   )r   r   r_   rE   r   r   r   visit_CompilerDirectivesNode   s"    
z.TreeAssertVisitor.visit_CompilerDirectivesNodeN)r   r   r    rb   r	   Zrecurse_to_childrenr   r   r   r   r   r^      s   r^   c           	      C   sN  |d u rt  }g }d }t| }z| }W |  n
|  0 ~z|D ]}|d d dkr| d dtjj	}tj
||}tjtj|sttj| |d ur|d  }}|  t|d}qH|d ur|| qH| rH| dsH| dvrH|| qHW |d ur@|  n|d ur>|  0 |d
|fS )N   z######/r'   )z"""z'''r#   )tempfilemkdtempopen	readlinesclosestriprL   osrE   sepr%   existsdirnamemakedirsr;   lstriprK   r   )	Z	tree_filedirheaderZcur_filefr<   rB   filenamerE   r   r   r   unpack_source_tree   s<    





rv   )N)
__future__r   rl   Zunittestrf   ZCompilerr   r   ZCompiler.TreeFragmentr   r   ZCompiler.Visitorr   r	   r
   r   r(   ZTestCaser)   rZ   r^   rv   r   r   r   r   <module>   s   
R"