B
    \aF                 @   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 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 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 d
dlmZ d
dl	mZ d
dl	mZ dd Zejdd Zdd Zdd Zdd Zdd Z ejdJd"d#Z!d$d% Z"d a#d&d' Z$dKd(d)Z%dLd*d+Z&dMd,d-Z'dNd.d/Z(dOd0d1Z)dPd2d3Z*dQd4d5Z+dRd6d7Z,dSd8d9Z-dTd:d;Z.dUd<d=Z/dVd>d?Z0d@dA Z1dBdC Z2G dDdE dEe3Z4G dFdG dGe3Z5G dHdI dIe3Z6dS )W    )absolute_importN   )	assertsql)config)mock)util)db_spec)fail   )exc)orm)pool)schema)types)default)url)compat)	decoratorc              O   s   t tj| f|S )a  Context manager which expects one or more warnings.

    With no arguments, squelches all SAWarnings emitted via
    sqlalchemy.util.warn and sqlalchemy.util.warn_limited.   Otherwise
    pass string expressions that will match selected warnings via regex;
    all non-matching warnings are sent through.

    The expect version **asserts** that the warnings were in fact seen.

    Note that the test suite sets SAWarning warnings to raise exceptions.

    )_expect_warningssa_excZ	SAWarning)messageskw r   <lib/python3.7/site-packages/sqlalchemy/testing/assertions.pyexpect_warnings    s    r   c          	   o   sF   t | }t| tjr&|tjs&dV  nt|| dV  W dQ R X dS )zContext manager which expects one or more warnings on specific
    dialects.

    The expect version **asserts** that the warnings were in fact seen.

    N)r   
isinstancer   string_typesr   Z_currentr   )dbr   r   specr   r   r   expect_warnings_on0   s
    r   c                 s   t  fdd}|S )zDecorator form of expect_warnings().

    Note that emits_warning does **not** assert that the warnings
    were in fact seen.

    c          	      s$   t  ddi | ||S Q R X d S )Nassert_F)r   )fnargsr   )r   r   r   decorateI   s    zemits_warning.<locals>.decorate)r   )r   r#   r   )r   r   emits_warningA   s    r$   c              O   s   t tj| f|S )N)r   r   ZSADeprecationWarning)r   r   r   r   r   expect_deprecatedQ   s    r%   c                s   t  fdd}|S )aV  Mark a test as emitting a warning on a specific dialect.

    With no arguments, squelches all SAWarning failures.  Or pass one or more
    strings; these will be matched to the root of the warning description by
    warnings.filterwarnings().

    Note that emits_warning_on does **not** assert that the warnings
    were in fact seen.

    c          	      s*   t  fddi | ||S Q R X d S )Nr    F)r   )r!   r"   r   )r   r   r   r   r#   a   s    z"emits_warning_on.<locals>.decorate)r   )r   r   r#   r   )r   r   r   emits_warning_onU   s    r&   c                 s   t  fdd}|S )a+  Mark a test as immune from fatal deprecation warnings.

    With no arguments, squelches all SADeprecationWarning failures.
    Or pass one or more strings; these will be matched to the root
    of the warning description by warnings.filterwarnings().

    As a special case, you may pass a function name prefixed with //
    and it will be re-written as needed to match the standard warning
    verbiage emitted by the sqlalchemy.util.deprecated decorator.

    Note that uses_deprecated does **not** assert that the warnings
    were in fact seen.

    c          	      s$   t  ddi | ||S Q R X d S )Nr    F)r%   )r!   r"   r   )r   r   r   r#   y   s    z!uses_deprecated.<locals>.decorate)r   )r   r#   r   )r   r   uses_deprecatedi   s    r'   TFc          	   #   s   rdd |D n|t tj fdd}td| d V  W d Q R X |r|rftjsrtddfdd	D  d S )
Nc             S   s    g | ]}t |t jt jB qS r   )recompileIS).0msgr   r   r   
<listcomp>   s    z$_expect_warnings.<locals>.<listcomp>c                s   t |  r| }t|} n|r&|d }nd }|r8t| sH| f||S sPd S xBD ]*}rh|| stsV|| krV| P qVW | f|| d S )Nr   )r   str
issubclassmatchdiscard)r-   argr   Z	exceptionZfilter_)exc_clsfilters	real_warnregexseenr   r   our_warn   s     




z"_expect_warnings.<locals>.our_warnzwarnings.warnzWarnings were not seen: %sz, c             3   s    | ]}d  r|j n| V  qdS )z%rN)pattern)r,   s)r7   r   r   	<genexpr>   s    z#_expect_warnings.<locals>.<genexpr>)	setwarningswarnr   patchr   py3kAssertionErrorjoin)r4   r   r7   r    Zpy2konlyr9   r   )r4   r5   r6   r7   r8   r   r      s    r   c               C   s
   t   dS )zCheck things that have to be finalized at the end of a test suite.

    Hardcoded at the moment, a modular system can be built here
    to support things like PG prepared transactions, tables all
    dropped, etc.

    N)!_assert_no_stray_pool_connectionsr   r   r   r   global_cleanup_assertions   s    rE   c              C   sz   t   tjr0td7 atdttj  t   tjr^ttj} tj  dat	
d|   ntdkrvdsrtddad S )Nr   z2Encountered a stray connection in test cleanup: %sr   z8Stray connection refused to leave after gc.collect(): %s
   Fz*Encountered more than 10 stray connections)testutilZlazy_gcr   Z_refs_STRAY_CONNECTION_FAILURESprintr/   Z
gc_collectclearr>   r?   rB   )errr   r   r   rD      s     

rD   c             C   s$   t || s t|pd| |f d S )Nz%r !~ %r)r(   r1   rB   )abr-   r   r   r   eq_regex   s    rN   c             C   s    | |kst |pd| |f dS )z.Assert a == b, with repr messaging on failure.z%r != %rN)rB   )rL   rM   r-   r   r   r   eq_   s    rO   c             C   s    | |kst |pd| |f dS )z.Assert a != b, with repr messaging on failure.z%r == %rN)rB   )rL   rM   r-   r   r   r   ne_   s    rP   c             C   s    | |kst |pd| |f dS )z.Assert a <= b, with repr messaging on failure.z%r != %rN)rB   )rL   rM   r-   r   r   r   le_   s    rQ   c             C   s   t | d|d d S )NT)r-   )is_)rL   r-   r   r   r   is_true   s    rS   c             C   s   t | d|d d S )NF)r-   )rR   )rL   r-   r   r   r   is_false   s    rT   c             C   s    | |kst |pd| |f dS )z.Assert a is b, with repr messaging on failure.z%r is not %rN)rB   )rL   rM   r-   r   r   r   rR     s    rR   c             C   s    | |k	st |pd| |f dS )z2Assert a is not b, with repr messaging on failure.z%r is %rN)rB   )rL   rM   r-   r   r   r   is_not_  s    rU   c             C   s    | |kst |pd| |f dS )z.Assert a in b, with repr messaging on failure.z%r not in %rN)rB   )rL   rM   r-   r   r   r   in_  s    rV   c             C   s    | |kst |pd| |f dS )z2Assert a in not b, with repr messaging on failure.z%r is in %rN)rB   )rL   rM   r-   r   r   r   not_in_  s    rW   c             C   s"   |  |st|pd| |f dS )z>Assert a.startswith(fragment), with repr messaging on failure.z%r does not start with %rN)
startswithrB   )rL   Zfragmentr-   r   r   r   startswith_  s    rY   c             C   sX   t dd| } t dd| } t dd|}t dd|}| |ksTt|pPd| |f d S )Nz^\s+?|\n z {2,} z%r != %r)r(   subrB   )rL   rM   r-   r   r   r   eq_ignore_whitespace  s
    r]   c             O   s<   y||| d}W n | k
r*   d}Y nX |s8t dd S )NFTz#Callable did not raise an exception)rB   )
except_cls	callable_r"   r   Zsuccessr   r   r   assert_raises'  s    

r`   c          
   O   s|   y||| dst dW n\ | k
rv } z>t|t|tjsRt d||f tt|d W d d }~X Y nX d S )NFz#Callable did not raise an exceptionz%r !~ %szutf-8)rB   r(   searchr   	text_typeUNICODErI   encode)r^   r-   r_   r"   kwargser   r   r   assert_raises_message2  s    

rg   c            	   @   s   e Zd ZdddZdS )AssertsCompiledSQLNFc          	      s0  |rt  }np|	rd }nf|d kr,t| dd }|d kr>tjj}n@|dkrPt  }n.|dkrbt  }nt|tj	r~t
|  }i }i }|r||d< |d k	rt||d< |
rd|d< t|tjr| }d|j_|j}nDt|tjjrtj|d }|  |jd	 d
 d	 }W d Q R X |r(||d< |jf d|i|}tt|di }tjr|ddd}tdt | | d ntdt |d |  t!"ddt |}t#||d|||f  |d k	rt#|$|| |d k	r|$| t#t% fdd|j&D | |d k	r,t#|j'| d S )NZ__dialect__r   Zdefault_enhancedschema_translate_mapZcolumn_keysTliteral_bindsZ_execute_stmtr   r   compile_kwargsdialectparamszutf-8asciiignorez
SQL String:
z[\n\t]rZ   z%r != %r on dialect %rc                s   g | ]} | qS r   r   )r,   x)pr   r   r.     s    z5AssertsCompiledSQL.assert_compile.<locals>.<listcomp>)(r   ZDefaultDialectgetattrr   r   rl   ZStrCompileDialectr   r   r   r   ZURLZget_dialectlistr   ZQueryZ_compile_contextZ	statementZ
use_labelsZpersistenceZBulkUDr   r@   objectZexec_Z
mock_callsr)   reprrA   rd   decoderI   rb   r(   r\   rO   Zconstruct_paramstupleZpositiontupZprefetch)selfZclauseresultrm   Zcheckparamsrl   ZcheckpositionalZcheck_prefetchZuse_default_dialectZallow_dialect_selectrj   ri   r   rk   contextZ	stmt_mockcZ	param_strZccr   )rq   r   assert_compile?  sd    








z!AssertsCompiledSQL.assert_compile)	NNNNNFFFN)__name__
__module____qualname__r|   r   r   r   r   rh   >  s           rh   c               @   s   e Zd ZdddZdd ZdS )ComparesTablesFc             C   sP  t |jt |jkstxt|j|jD ]\}}t|j|j ||j|j ksRtt|j|j t|j|j |rd}t|j	t	|j	st||j	|j	f n| 
|| t|j	tjrt|j	j|j	j tdd |jD dd |jD  |jr(t|jtjs(tq(W t |jt |jks"tx(|jD ]}|jj|j d k	s*tq*W d S )Nz)Type '%s' doesn't correspond to type '%s'c             S   s   h | ]}|j jqS r   )columnname)r,   fr   r   r   	<setcomp>  s    z5ComparesTables.assert_tables_equal.<locals>.<setcomp>c             S   s   h | ]}|j jqS r   )r   r   )r,   r   r   r   r   r     s    )lenr{   rB   ziprO   r   Zprimary_keyZnullabler   typeassert_types_basesqltypesStringlengthZforeign_keysZserver_defaultr   ZFetchedValuecolumns)rx   tableZreflected_tableZstrict_typesr{   Zreflected_cr-   r   r   r   assert_tables_equal  s.    z"ComparesTables.assert_tables_equalc             C   s*   |j |j s&td|j|j |j f d S )Nz7On column %r, type '%s' doesn't correspond to type '%s')r   Z_compare_type_affinityrB   r   )rx   Zc1Zc2r   r   r   r     s    z ComparesTables.assert_types_baseN)F)r}   r~   r   r   r   r   r   r   r   r     s   
!r   c               @   sl   e Zd Zd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ejdd Zdd Zd	S )AssertsExecutionResultsc             G   s&   t |}tt| | ||| d S )N)rs   rI   ru   assert_list)rx   ry   class_Zobjectsr   r   r   assert_result  s    z%AssertsExecutionResults.assert_resultc             C   sP   |  t|t|kd|j  x,tdt|D ]}| ||| ||  q.W d S )Nz9result list is not the same size as test list, for class r   )r    r   r}   range
assert_row)rx   ry   r   Zlist_ir   r   r   r     s
    z#AssertsExecutionResults.assert_listc          	   C   s   |  |j|kdt|  x| D ]\}}t|trt|d trb| t|||d |d  q| 	|d t|||d  q$|  t|||kd|t|||f  q$W d S )Nzitem class is not r   r   z'attribute %s value %s does not match %s)
r    	__class__ru   itemsr   rw   rs   r   rr   r   )rx   r   ZrowobjZdesckeyvaluer   r   r   r     s    
z"AssertsExecutionResults.assert_rowc       	         s   G dd dt t|}fdd|D }x4tfdd|D ]}tdt|jjf  qBW t|t|krtdt|t|f  t   fd	d
}xF|D ]>}x8|D ]}|||r|	| P qW tdjt
|f  qW dS )zAs assert_result, but the order of objects is not considered.

        The algorithm is very expensive but not a big deal for the small
        numbers of rows that the test suite manipulates.
        c               @   s   e Zd Zdd ZdS )zFAssertsExecutionResults.assert_unordered_result.<locals>.immutabledictc             S   s   t | S )N)id)rx   r   r   r   __hash__  s    zOAssertsExecutionResults.assert_unordered_result.<locals>.immutabledict.__hash__N)r}   r~   r   r   r   r   r   r   immutabledict  s   r   c                s   h | ]} |qS r   r   )r,   rf   )r   r   r   r     s    zBAssertsExecutionResults.assert_unordered_result.<locals>.<setcomp>c                s
   t |  S )N)r   )o)clsr   r   <lambda>  s    zAAssertsExecutionResults.assert_unordered_result.<locals>.<lambda>z#Unexpected type "%s", expected "%s"z+Unexpected object count "%s", expected "%s"c          	      st   xn|  D ]b\}}t|trXy$jt| ||d f|d   W ql tk
rT   dS X q
t| | |kr
dS q
W dS )Nr   r   FT)r   r   rw   assert_unordered_resultrr   rB   )objr   r   r   )NOVALUErx   r   r   _compare_item  s    
 zFAssertsExecutionResults.assert_unordered_result.<locals>._compare_itemz2Expected %s instance with attributes %s not found.T)dictr   ZIdentitySetZitertools_filterfalser	   r   r}   r   rt   removeru   )	rx   ry   r   ZexpectedfoundZwrongr   Zexpected_itemZ
found_itemr   )r   r   r   rx   r   r     s.    




z/AssertsExecutionResults.assert_unordered_resultNc             C   s   |d krddl m} t|S )Nr   )r   )rZ   r   r   Zassert_engine)rx   r   r   r   r   sql_execution_asserter  s    z.AssertsExecutionResults.sql_execution_asserterc          	   G   s*   |  |}| }W d Q R X |j|  |S )N)r   r    )rx   r   r_   rulesasserterry   r   r   r   assert_sql_execution  s    
z,AssertsExecutionResults.assert_sql_executionc             C   s\   g }xD|D ]<}t |tr2tjdd | D  }n
tj| }|| q
W | j||f| S )Nc             S   s   g | ]\}}t ||qS r   )r   CompiledSQL)r,   kvr   r   r   r.   )  s    z6AssertsExecutionResults.assert_sql.<locals>.<listcomp>)r   r   r   ZAllOfr   r   appendr   )rx   r   r_   r   ZnewrulesZruleZnewruler   r   r   
assert_sql#  s    


z"AssertsExecutionResults.assert_sqlc             C   s   |  ||t| d S )N)r   r   CountStatements)rx   r   r_   countr   r   r   assert_sql_count1  s    z(AssertsExecutionResults.assert_sql_countc       
         s    fddt ||D }g }x |D ]\}}}||  q"W z| S x:t ||D ],\}	\}}}|d d d  |	t| qRW X d S )Nc                s    g | ]\}}  |||fqS r   )r   )r,   r   r   )rx   r   r   r.   8  s   zEAssertsExecutionResults.assert_multiple_sql_count.<locals>.<listcomp>)r   r   	__enter____exit__r    r   r   )
rx   Zdbsr_   ZcountsZrecsZ	assertersZctxr   r   r   r   )rx   r   assert_multiple_sql_count6  s    
z1AssertsExecutionResults.assert_multiple_sql_countc          	   g   s*   |  |}d V  W d Q R X |j|  d S )N)r   r    )rx   r   r   r   r   r   r   assert_executionE  s    z(AssertsExecutionResults.assert_executionc             C   s   |  |t|S )N)r   r   r   )rx   r   r   r   r   r   assert_statement_countK  s    z.AssertsExecutionResults.assert_statement_count)N)r}   r~   r   r   r   r   r   r   r   r   r   r   
contextlibcontextmanagerr   r   r   r   r   r   r     s   
8
r   )TTF)N)N)N)N)N)N)N)N)N)N)N)N)7Z
__future__r   r   r(   r>   rZ   r   r   r   r   rG   Z
exclusionsr   r	   r   r   r   r   r   r   r   Zenginer   r   r   r   r   r   r   r$   r%   r&   r'   r   rE   rH   rD   rN   rO   rP   rQ   rS   rT   rR   rU   rV   rW   rY   r]   r`   rg   rt   rh   r   r   r   r   r   r   <module>   s^   ,*











	W)