3
ho9                 @   sJ  d dl mZ d dlZd dlZd dlZd dl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 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eejejdddjdZeejejdddjdZdd Z G dd deZ!dd Z"d#dd Z#d$d!d"Z$dS )%    )absolute_importN)open)partial   )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| j  d| _g | _d S )Nr   )superr   __init___indentsresult)self)	__class__ b/var/www/html/CrowdFlow/Picklecon/ble_analysis_env/lib/python3.6/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jd| j d||jjf   |  jd7  _| j| |  jd8  _d S )	Nz(root)r      z%s[%d]   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  }|j|  dj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  d S )N)r   init_thread)r   r   r   r   setUp7   s    zCythonTest.setUpc             C   s   t j  d S )N)r   r*   )r   r   r   r   tearDown:   s    zCythonTest.tearDownc             C   s   t |ts|jd}t |ts(|jd}x6tt||D ]$\}\}}| j||d|||f  q8W | jt|t|ddj|dj|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jS )N)r   writer   lines)r   treewriterr   r   r   codeToLinesI   s    
zCythonTest.codeToLinesc             C   s   dj | j|S )Nr"   )r%   r<   )r   r:   r   r   r   codeToStringN   s    zCythonTest.codeToStringc             C   sx   | j |}t|jd}x6tt||D ]$\}\}}| j||d|||f  q(W | jt|t|ddj||f  d S )Nr"   zLine %d:
Got: %s
Exp: %sz%Unmatched lines. Got:
%s
Expected:
%s)r<   r	   r/   r0   r1   r2   r3   r%   )r   r4   result_treeZresult_linesZexpected_linesr5   liner6   r   r   r   
assertCodeQ   s    
zCythonTest.assertCodec             C   s   | j tj||d d|  d S )Nz"Path '%s' not found in result tree)ZassertNotEqualr   
find_first)r   pathr>   r   r   r   assertNodeExists\   s    zCythonTest.assertNodeExistsNc             C   sV   |dkri }|dkrg }| j  }|jdr:|tdd }|jdd}t||||dS )zNSimply create a tree fragment using the name of the test-case in parse errors.Nz	__main__.._)pipeline)id
startswithr3   replacer   )r   codepxdsrF   r   r   r   r   fragment`   s    
zCythonTest.fragmentc             C   s   t |S )N)r(   )r   r&   r   r   r   r(   l   s    zCythonTest.treetypesc             C   sN   y|  | j d|  W n0 |k
rH } z| jt|| |S d}~X 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_failo   s    zCythonTest.should_failc             C   s<   y| S  t k
r6 } z| jt| W Y dd}~X 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)	ExceptionrM   str)r   rO   excr   r   r   should_not_failz   s    zCythonTest.should_not_fail)NN)r   r   r    r+   r,   r7   r<   r=   r@   rC   rL   r(   rS   rR   rV   r   r   r   r   r)   5   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 ||j}x|D ]}||}q W |S )N)rL   r&   )r   rF   ZpyxrK   r:   Tr   r   r   run_pipeline   s    
zTransformTest.run_pipeline)N)r   r   r    __doc__rY   r   r   r   r   rW      s   rW   z\s+r#   zz
        /[*] (
            (?: [^*\n] | [*][^/] )*
            [\n]
            (?: [^*] | [*][^/] )*
        ) [*]/
    z\s\s+z
    (?:
        <pre class=["'][^"']*cython\s+line[^"']*["']\s*>
        (?:[^<]|<(?!/pre))+
        </pre>
    )|(?:
        <style[^>]*>
        (?:[^<]|<(?!/style))+
        </style>
    )
    c             C   s   d  }}| j dr6tjd| dd  dd\}} | j } | j dr~| dd  j } | j dr~tjd| dd  dd\}} | j } ||| fS )N/z(?<!\\)/r   )maxsplit:)rH   rer/   strip)patternstartendr   r   r   _parse_pattern   s    


rc   c                   sB   e Zd Z fddZdd Zdd Zdd Zd	d
 Zej	Z
  ZS )TreeAssertVisitorc                s$   t t| j  d | _g | _g | _d S )N)r   rd   r   _module_pos_c_patterns_c_antipatterns)r   )r   r   r   r      s    zTreeAssertVisitor.__init__c                sL   j j  dd fdd fdd fdd}|S )	Nc             S   s"   t j| d||rdnd|f  d S )NzPattern '%s' %s found in %swaszwas not)r   error)posr`   found	file_pathr   r   r   rM      s    
z7TreeAssertVisitor.create_c_file_validator.<locals>.failc                st   |r8t j||}|r&||j d  }n j|d| d |rpt j||}|r^|d |j  }n j|d| d |S )NF)rk   rl   )r^   searchrb   re   ra   )rl   contentra   rb   r/   )rM   r   r   r   extract_section   s    zBTreeAssertVisitor.create_c_file_validator.<locals>.extract_sectionc                s   xFD ]>}t |\}}}| |||}tj||sj|d| d qW xF D ]>}t |\}}}| |||}tj||rNj|d| d qNW d S )NF)rk   rl   T)rc   r^   rm   re   )rl   rn   r`   ra   rb   sectionZantipattern)antipatternsro   rM   patternsr   r   r   validate_file_content   s    

zHTreeAssertVisitor.create_c_file_validator.<locals>.validate_file_contentc                s   | j }p s| S t|dd}|j }W d Q R X t|}|| tjj|d d }tjj|rtjj|tjj|krt|dd}|j }W d Q R X t	|}|| d S )Nutf8)encodingr   z.html)
c_filer   read_strip_c_commentsosrB   splitextexistsgetmtime_strip_cython_code_from_html)r   rv   frn   Z	html_file)rq   rr   rs   r   r   validate_c_file  s    
$zBTreeAssertVisitor.create_c_file_validator.<locals>.validate_c_file)rf   rg   )r   r   r   )rq   ro   rM   rr   r   rs   r   create_c_file_validator   s    z)TreeAssertVisitor.create_c_file_validatorc             C   s   |j }d|krBx2|d D ]&}tj||d krtj|jd|  qW d|krx6|d D ]*}tj||}|d k	rTtj|jd|  qTW d|kr| jj|d  d|kr| jj|d  d 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 treeZtest_assert_c_code_hasZtest_fail_if_c_code_has)	
directivesr   rA   r   ri   rj   rf   extendrg   )r   r   r   rB   Z
first_noder   r   r   _check_directives  s$    z#TreeAssertVisitor._check_directivesc             C   s    |j | _| j| | j| |S )N)rj   re   r   r   )r   r   r   r   r   visit_ModuleNode*  s    

z"TreeAssertVisitor.visit_ModuleNodec             C   s   | j | | j| |S )N)r   r   )r   r   r   r   r   visit_CompilerDirectivesNode0  s    

z.TreeAssertVisitor.visit_CompilerDirectivesNode)r   r   r    r   r   r   r   r   r   Zrecurse_to_childrenr   r!   r   r   )r   r   rd      s   <rd   c             C   s  t jgt jtjj|dgt jtjj|dgd}|d kr@tj }g d  }}t| db}zDx<|D ]2}|d d dkr|j jdj j	dj
d	tjj}tjj||}	tjjtjj|	stjtjj|	 |d k	r|d  }
}|
j  t|	d
}qd|d k	r|j| qd|j rd|j jd rd|j dkrdtj|j	d}|sJqd|d |dd   }}y|j|| |  W qd tk
r   |j| Y qdX qdW W d |d k	r|j  X W d Q R X ||fS )Nz	cython.pyzcythonize.py)PYTHONZCYTHONZ	CYTHONIZErb   s   #####   #rt   r[   wb   """   '''r   r   )r   r   )sys
executablery   rB   r%   tempfilemkdtempr   r_   decoderI   sepr{   dirnamemakedirscloser8   lstriprH   shlexr/   r   KeyError)Z	tree_fileZworkdirZcython_rootZprogramsheaderZcur_filer~   r?   filenamerB   to_closecommandprogargsr   r   r   unpack_source_tree8  sB    
$

 
r   Fc          	   C   sh   t |trd}d}d}nd}d}d}|dkr0|}|r>tj|}t| |||d}|j| W dQ R X dS )zWrite some content (text or bytes) to the file
    at `file_path` without translating `'\n'` into `os.linesep`.

    The default encoding is `'utf-8'`.
    r   Nr'   r"   zutf-8)moderu   newline)r-   bytestextwrapdedentr   r8   )rl   rn   r   ru   r   r   default_encodingr~   r   r   r   
write_file`  s    

r   c             C   sl   t | |||d ytjj|}W n tk
r8   d}Y nX x,|dksT|tjj| krft | |||d q<W dS )z
    Write `content` to the file `file_path` without translating `'\n'`
    into `os.linesep` and make sure it is newer than the file `newer_than`.

    The default encoding is `'utf-8'` (same as for `write_file`).
    )r   ru   N)r   ry   rB   r|   OSError)rl   Z
newer_thanrn   r   ru   Z
other_timer   r   r   write_newer_file~  s    
r   )FN)FN)%
__future__r   ry   r^   Zunittestr   r   r   r   ior   	functoolsr   ZCompilerr   r   ZCompiler.TreeFragmentr   r	   ZCompiler.Visitorr
   r   r   r   r(   ZTestCaser)   rW   compilesubrx   r}   rc   rd   r   r   r   r   r   r   r   <module>   s>   
O&
h(
