o
    DDin(                  	   @   sf  d dl Z d dlmZ d dl mZ d dlmZmZmZmZm	Z	m
Z
mZ d dlmZ d dlZd dlmZ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 d dlmZ eddG dd dZG dd deZ 	d!dej!dej!de	e" ddfddZ#dedee"gej$f fddZ%dedee"gej&f fddZ'G dd deZ(eddG dd  d ej!Z)dS )"    N)	ExitStack)	dataclass)AnyCallableIterableListOptionalSequenceType)patch)CodegenStatevisit_required)CSTNodeT)CSTTransformerCSTVisitorT)	CodeRangePositionProvider)PositionProvidingCodegenState)UnitTestT)frozenc                   @   s0   e Zd ZU eej ed< eed< ed ed< dS )_CSTCodegenPatchTargettypename.Nold_codegenN)	__name__
__module____qualname__r
   cstCSTNode__annotations__strr    r"   r"   Q/var/www/Datamplify/venv/lib/python3.10/site-packages/libcst/_nodes/tests/base.pyr      s   
 r   c                   @   s   e Zd ZdS )_NOOPVisitorN)r   r   r   r"   r"   r"   r#   r$      s    r$   abmsgreturnc                 C   s<   |  |s|du rdnd| }td| d|| dS )z+
    For use with addTypeEqualityFunc.
    N 
z
is not deeply equal to 
)deep_equalsAssertionError)r%   r&   r'   suffixr"   r"   r#   _cst_node_equality_func    s   
r.   configc                        dt dtjf fdd}|S )Ncoder(   c                       t j| t jdi  dS Nr/   r"   )r   parse_expressionPartialParserConfigr1   r4   r"   r#   inner,      z"parse_expression_as.<locals>.inner)r!   r   BaseExpressionr/   r8   r"   r4   r#   parse_expression_as+      r<   c                     r0   )Nr1   r(   c                    r2   r3   )r   parse_statementr6   r7   r4   r"   r#   r8   3   r9   z!parse_statement_as.<locals>.inner)r!   r   BaseStatementr;   r"   r4   r#   parse_statement_as2   r=   r@   c                   @   s,  e Zd ZdddZ		d dededeeegef  dee ddf
d	d
Z	deg e
jf deddfddZdeg e
jf deddfddZ	d!de
jdedee ddfddZde
jddfddZde
jdee
j fddZde
jddfddZde
jddfddZdedeege
jf deddfddZdS )"CSTNodeTestr(   Nc                 C   sB   t j D ]}t|trt|t jr| |t q| t	t d S N)
r   __dict__values
isinstancer   
issubclassr   addTypeEqualityFuncr.   DummyIndentedBlock)selfvr"   r"   r#   setUp;   s
   zCSTNodeTest.setUpnoder1   parserexpected_positionc                 C   sr   |   | ||| |d ur||}| || |}t|tr(|j}t|ts | | | | | | d S rB   )	validate_types_deep_CSTNodeTest__assert_codegenassertEqualrE   rH   child+_CSTNodeTest__assert_children_match_codegen*_CSTNodeTest__assert_children_match_fields+_CSTNodeTest__assert_visit_returns_identity)rI   rL   r1   rM   rN   parsed_nodeunwrapped_noder"   r"   r#   validate_nodeE   s   



zCSTNodeTest.validate_nodeget_nodeexpected_rec                 C   s:   |  tj| |  W d    d S 1 sw   Y  d S rB   )assertRaisesRegexr   CSTValidationErrorrI   rY   rZ   r"   r"   r#   assert_invalid\   s   "zCSTNodeTest.assert_invalidc                 C   s<   |  t| |   W d    d S 1 sw   Y  d S rB   )r[   	TypeErrorvalidate_types_shallowr]   r"   r"   r#   assert_invalid_typesb   s   "z CSTNodeTest.assert_invalid_typesexpectedc                 C   s`   t g }| ||| |dur.t }t|j|j|d}|| | |j	| | dS dS )zN
        Verifies that the given node's `_codegen` method is correct.
        N)default_indentdefault_newlineprovider)
r   ModulerQ   code_for_noder   r   rc   rd   _codegen	_computed)rI   rL   rb   rN   modulere   stater"   r"   r#   __assert_codegenh   s   
	
zCSTNodeTest.__assert_codegenc                 C   s$   |j }| |}| j||dd d S )NzThe list of children we got from `node.children` differs from the children that were visited by `node._codegen`. This is probably due to a mismatch between _visit_and_replace_children and _codegen_impl.r'   )children*_CSTNodeTest__derive_children_from_codegenassertSequenceEqual)rI   rL   rn   codegen_childrenr"   r"   r#   __assert_children_match_codegen   s   

z+CSTNodeTest.__assert_children_match_codegenc                    s   dd t j D }g  g dtdtd f fdd}t %}|D ]}|td|j d	|| q"t 	g 
| W d
    S 1 sGw   Y   S )a  
        Patches all subclasses of `CSTNode` exported by the `cst` module to track which
        `_codegen` methods get called, generating a list of children.

        Because all children must be rendered out into lexical order, this should be
        equivalent to `node.children`.

        `node.children` uses `_visit_and_replace_children` under the hood, not
        `_codegen`, so this helps us verify that both of those two method's behaviors
        are in sync.
        c                 S   s@   g | ]\}}t |trt|tjrt|d rt|||jdqS )rh   )r   r   r   )rE   r   rF   r   r   hasattrr   rh   ).0krJ   r"   r"   r#   
<listcomp>   s    
z>CSTNodeTest.__derive_children_from_codegen.<locals>.<listcomp>targetr(   r   c                    s&   dt dtdtdd f fdd}|S )NrI   argskwargsr(   c                    sl   d}t dksd | ur t dkr |  |  d}j| g|R i | |r4  d S d S )NFr      T)lenappendr   pop)rI   rx   ry   
should_pop)rn   codegen_stackrw   r"   r#   _codegen_impl   s   

z`CSTNodeTest.__derive_children_from_codegen.<locals>._get_codegen_override.<locals>._codegen_impl)r   r   )rw   r   rn   r   )rw   r#   _get_codegen_override   s   "zICSTNodeTest.__derive_children_from_codegen.<locals>._get_codegen_overridezlibcst.z	._codegenN)r   rC   itemsr   r   r   enter_contextr   r   rf   rg   )rI   rL   patch_targetsr   patch_stacktr"   r   r#   __derive_children_from_codegen   s(   
z*CSTNodeTest.__derive_children_from_codegenc                 C   s   dd |j D }t|}t }|D ]%}t||j}t|tjr(|	t
| qt|tr7|dd |D  q| j||dd dS )a  
        We expect `node.children` to match everything we can extract from the node's
        fields, but maybe in a different order. This asserts that those things match.

        If you want to verify order as well, use `assert_children_ordered`.
        c                 S   s   h | ]}t |qS r"   )id)rt   rR   r"   r"   r#   	<setcomp>   s    z=CSTNodeTest.__assert_children_match_fields.<locals>.<setcomp>c                 s   s$    | ]}t |tjrt|V  qd S rB   )rE   r   r   r   )rt   elr"   r"   r#   	<genexpr>   s    
z=CSTNodeTest.__assert_children_match_fields.<locals>.<genexpr>zA`node.children` doesn't match what we found through introspectionrm   N)rn   dataclassesfieldssetgetattrr   rE   r   r   addr   r   updateassertSetEqual)rI   rL   node_children_idsr   field_child_idsfvaluer"   r"   r#   __assert_children_match_fields   s"   



z*CSTNodeTest.__assert_children_match_fieldsc                 C   s   |  ||t  dS )z
        When visit is called with a visitor that acts as a no-op, the visit method
        should return the same node it started with.
        N)rQ   visitr$   )rI   rL   r"   r"   r#   __assert_visit_returns_identity   s   z+CSTNodeTest.__assert_visit_returns_identityexpect_successc                 C   sJ   |s|  tj || W d    d S 1 sw   Y  d S || d S rB   )assertRaisesr   ParserSyntaxError)rI   r1   rM   r   r"   r"   r#   assert_parses   s
   
"zCSTNodeTest.assert_parses)r(   N)NNrB   )r   r   r   rK   r   r!   r   r   r   rX   r   r   r^   ra   rP   rS   r	   ro   rT   rU   boolr   r"   r"   r"   r#   rA   :   sp    






9
rA   c                   @   sH   e Zd ZU dZeed< ejed< deddfddZ	d	e
dd fd
dZdS )rH   z
    A stripped-down version of cst.IndentedBlock that only sets/clears the indentation
    state for the purpose of testing cst.IndentWhitespace in isolation.
    r   rR   rk   r(   Nc                 C   sX   | | j |j| | j| jd | j| W d    n1 s!w   Y  |  d S )N)
start_nodeend_node)increase_indentr   record_syntactic_positionrR   rh   decrease_indent)rI   rk   r"   r"   r#   r     s   
z DummyIndentedBlock._codegen_implvisitorc                 C   s   t | jt| d| j|dS )NrR   )r   rR   )rH   r   r   rR   )rI   r   r"   r"   r#   _visit_and_replace_children  s   z.DummyIndentedBlock._visit_and_replace_children)r   r   r   __doc__r!   r    r   r   r   r   r   r   r"   r"   r"   r#   rH      s   
 
rH   rB   )*r   
contextlibr   r   typingr   r   r   r   r   r	   r
   unittest.mockr   libcstr   libcst._nodes.internalr   r   libcst._typesr   libcst._visitorsr   r   libcst.metadatar   r   !libcst.metadata.position_providerr   libcst.testing.utilsr   r   r$   r   r!   r.   r:   r<   r?   r@   rA   rH   r"   r"   r"   r#   <module>   s>   $
 C