o
    Zh6                     @   s  d Z ddlZddlm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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mZ ddlmZ ddlmZ ddlmZ ej dkrjej!nej"Z#e#de$de%e$ de%e$ fddZ&dd Z'de'_(dd Z)dd Z*d:ddZ+d;d d!Z,	"	d<d#d$Z-G d%d& d&ej.Z/d'Z0d(d) Z1eZ2e3e4d"Z5d*Z6G d+d, d,e7Z8d-Z9G d.d/ d/e8Z:e	d0d1 Z;e	d2d3 Z<d4d5 Z=d=d6d7Z>d=d8d9Z?dS )>zWGeneric testing tools.

Authors
-------
- Fernando Perez <Fernando.Perez@berkeley.edu>
    N)Path)contextmanager)StringIO)PopenPIPE)patch)Config)get_output_error_code)list_strings)temp_pyfileTee)	py3compat   )
decorators)skipdoctestwin32	startPathfilesreturnc                    s0   t |tsJ tj| d   fdd|D S )a  Make full paths for all the listed files, based on startPath.

    Only the base part of startPath is kept, since this routine is typically
    used with a script's ``__file__`` variable as startPath. The base of startPath
    is then prepended to all the listed files, forming the output list.

    Parameters
    ----------
    startPath : string
      Initial path to use as the base for the results.  This path is split
      using os.path.split() and only its first component is kept.

    files : list
      One or more files.

    Examples
    --------

    >>> full_path('/foo/bar.py',['a.txt','b.txt'])
    ['/foo/a.txt', '/foo/b.txt']

    >>> full_path('/foo',['a.txt','b.txt'])
    ['/a.txt', '/b.txt']

    r   c                    s   g | ]	}t j |qS  )ospathjoin).0fbaser   L/var/www/html/lang_env/lib/python3.10/site-packages/IPython/testing/tools.py
<listcomp>C   s    zfull_path.<locals>.<listcomp>)
isinstancelistr   r   split)r   r   r   r   r   	full_path&   s   r"   c                 C   s   t d| t j}|rt|d}d}||fS t d| t j}|r.d}t|d}||fS t d| t j}|rJt|d}t|d}||fS dS )a  Parse the output of a test run and return errors, failures.

    Parameters
    ----------
    txt : str
      Text output of a test run, assumed to contain a line of one of the
      following forms::

        'FAILED (errors=1)'
        'FAILED (failures=1)'
        'FAILED (errors=1, failures=1)'

    Returns
    -------
    nerr, nfail
      number of errors and failures.
    z^FAILED \(errors=(\d+)\)r   r   z^FAILED \(failures=(\d+)\)z(^FAILED \(errors=(\d+), failures=(\d+)\)   )r   r   )research	MULTILINEintgroup)txtZerr_mZnerrZnfailZfail_mZboth_mr   r   r   parse_test_outputF   s$   r*   Fc                   C   s   g dS )zEReturn a valid default argv for creating testing instances of ipython)z--quickz--colors=NoColorz--no-term-titlez--no-bannerz--autocall=0r   r   r   r   r   default_argvt   s   r+   c                  C   sN   t  } d| j_d| j_d| j_tjddd}t|j	| j
_|  d| j
_| S )z6Return a config object with good defaults for testing.ZNoColorFr   ztest_hist.sqliteF)suffixdeletei'  )r   TerminalInteractiveShellcolorsZ TerminalTerminalInteractiveShellZ
term_titleZautocalltempfileNamedTemporaryFiler   nameZHistoryManagerZ	hist_filecloseZdb_cache_size)configr   r   r   r   default_config}   s   r6   c                 C   s   t jddg}| rd|}|S )aW  
    Return appropriate IPython command line name. By default, this will return
    a list that can be used with subprocess.Popen, for example, but passing
    `as_string=True` allows for returning the IPython command as a string.

    Parameters
    ----------
    as_string: bool
        Flag to allow to return the command as a string.
    z-mZIPython )sys
executabler   )	as_stringipython_cmdr   r   r   get_ipython_cmd   s   
r<   r   c                 C   s   d}|du rg }t  | }tjt}t }tj|| }|| d|g }tj }	d|	d< |		dd |	
 D ]\}
}t|tsFt|
| q8t|ttt|	d}|jtd|p[dd	\}}t|t|}}|rttd
d|}||fS )a  Utility to call 'ipython filename'.

    Starts IPython with a minimal and safe configuration to make startup as fast
    as possible.

    Note that this starts IPython in a subprocess!

    Parameters
    ----------
    fname : str, Path
      Name of file to be executed (should have .py or .ipy extension).

    options : optional, list
      Extra command-line flags to be passed to IPython.

    commands : optional, list
      Commands to send in on stdin

    Returns
    -------
    ``(stdout, stderr)`` of ipython subprocess.
    TNz--ignoreZPYTHONWARNINGSZPYCHARM_HOSTED)stdoutstderrstdinenv
)inputz\x1b\[[^h]+h )r+   r   r   dirname__file__r<   r   environcopypopitemsr   strprintr   r   communicater   encodedecoder$   sub)fnameoptionscommands__tracebackhide__ZcmdargsZtest_dirr;   Z
full_fnameZfull_cmdrA   kvpouterrr   r   r   ipexec   s*   



 rZ   rD   c                 C   s   d}t | ||\}}|r+|r#d|  d|  ks"J ntd| |f d|  d|  ks?J dS )a9  Utility to call 'ipython filename' and validate output/error.

    This function raises an AssertionError if the validation fails.

    Note that this starts IPython in a subprocess!

    Parameters
    ----------
    fname : str, Path
      Name of the file to be executed (should have .py or .ipy extension).

    expected_out : str
      Expected stdout of the process.

    expected_err : optional, str
      Expected stderr of the process.

    options : optional, list
      Extra command-line flags to be passed to IPython.

    Returns
    -------
    None
    TrB   z"Running file %r produced error: %rN)rZ   r   strip
splitlines
ValueError)rQ   Zexpected_outZexpected_errrR   rS   rT   rX   rY   r   r   r   ipexec_validate   s   

r^   c                   @   s2   e Zd ZdZdddZdd Zdd Zd	d
 ZdS )TempFileMixinzcUtility class to create temporary Python/IPython files.

    Meant as a mixin class for test cases..pyc                 C   s0   t ||}t| dsg | _| j| || _dS )zMake a valid python temp file.tmpsN)r   hasattrra   appendrQ   )selfsrcextrQ   r   r   r   mktmp
  s
   


zTempFileMixin.mktmpc                 C   s6   t | dr| jD ]}zt| W q   Y qd S d S )Nra   )rb   ra   r   unlink)rd   rQ   r   r   r   tearDown  s   

zTempFileMixin.tearDownc                 C   s   | S Nr   rd   r   r   r   	__enter__   s   zTempFileMixin.__enter__c                 C   s   |    d S rj   )ri   )rd   exc_type	exc_value	tracebackr   r   r   __exit__#  s   zTempFileMixin.__exit__N)r`   )__name__
__module____qualname____doc__rg   ri   rl   rp   r   r   r   r   r_     s    
r_   z8Testing {0}

In:
  {1!r}
Expected:
  {2!r}
Got:
  {3!r}
c                 C   sN   d}t | dt | dd}|D ]\}}| |}||ks$J t||||qdS )a  Utility function for the common case of checking a function with a
    sequence of input/output pairs.

    Parameters
    ----------
    func : callable
      The function to be tested. Should accept a single argument.
    pairs : iterable
      A list of (input, expected_output) tuples.

    Returns
    -------
    None. Raises an AssertionError if any output does not match the expected
    value.
    T	func_namerq   z	<unknown>N)getattrpair_fail_msgformat)funcpairsrT   r3   inpexpectedrX   r   r   r   check_pairs.  s   r}   zEDid not find {0!r} in printed output (on {1}):
-------
{2!s}
-------
c                   @   s*   e Zd ZdZdddZdd Zdd	 Zd
S )AssertPrintszContext manager for testing that code prints certain text.

    Examples
    --------
    >>> with AssertPrints("abc", suppress=False):
    ...     print("abcd")
    ...     print("def")
    ...
    abcd
    def
    r>   Tc                 C   s0   || _ t| j ttfr| j g| _ || _|| _d S rj   )sr   rK   _re_typechannelsuppress)rd   r   r   r   r   r   r   __init__\  s
   

zAssertPrints.__init__c                 C   sN   t t| j| _t | _t| j| jd| _tt| j| j	r!| j d S | j d S )N)r   )
rv   r8   r   orig_stream
MyStringIObufferr   teesetattrr   rk   r   r   r   rl   c  s   &zAssertPrints.__enter__c                 C   s   d}zP|d urW | j   dS | j   tt| j| j | j }| j	D ]&}t
|tr<||s;J t|j| j|q$||v sJJ t|| j|q$W | j   dS | j   w NTF)r   r4   flushr   r8   r   r   r   getvaluer   r   r   r%   notprinted_msgrx   patternrd   etypevaluero   rT   Zprintedr   r   r   r   rp   i  s   



"zAssertPrints.__exit__N)r>   T)rq   rr   rs   rt   r   rl   rp   r   r   r   r   r~   P  s
    
r~   z>Found {0!r} in printed output (on {1}):
-------
{2!s}
-------
c                   @   s   e Zd ZdZdd ZdS )AssertNotPrintszcContext manager for checking that certain output *isn't* produced.

    Counterpart of AssertPrintsc                 C   s   d}zU|d ur| j   W | j   dS | j   tt| j| j | j }| j	D ]&}t
|trA||r@J t|j| j|q)||vsOJ t|| j|q)W | j   dS | j   w r   )r   r4   r   r   r8   r   r   r   r   r   r   r   r%   printed_msgrx   r   r   r   r   r   rp     s&   





zAssertNotPrints.__exit__N)rq   rr   rs   rt   rp   r   r   r   r   r     s    r   c                  c   s:    ddl m}  | j}dd | _z	d V  W || _d S || _w )Nr   )warnc                  _   s   d S rj   r   )akwr   r   r   <lambda>  s    zmute_warn.<locals>.<lambda>)IPython.utilsr   )r   Z	save_warnr   r   r   	mute_warn  s   
r   c              	   c   s8    t | ddd  zdV  W t|  dS t|  w )zGCreate an empty, named, temporary file for the duration of the context.wzutf-8)encodingN)openr4   r   rh   )r3   r   r   r   make_tempfile  s
   r   c                    s    t |  d fdd	}td|S )a  Temporarily replace the input() function to return the given values

    Use as a context manager:

    with fake_input(['result1', 'result2']):
        ...

    Values are returned in order. If input() is called again after the last value
    was used, EOFError is raised.
    rD   c              
      s.   zt  W S  ty } ztd|d }~ww )NzNo more inputs given)nextStopIterationEOFError)prompteitr   r   
mock_input  s   

zfake_input.<locals>.mock_inputzbuiltins.inputNrD   )iterr   )Zinputsr   r   r   r   
fake_input  s   
r   c                 C   X   t  | dg }t|\}}}|dksJ |d|vsJ d|v s"J d|v s(J ||fS )z)test that `ipython [subcommand] -h` worksz-hr   	TracebackOptions
--help-allr<   r	   
subcommandcmdrX   rY   rcr   r   r   help_output_test     r   c                 C   r   )z1test that `ipython [subcommand] --help-all` worksr   r   r   r   Classr   r   r   r   r   help_all_output_test  r   r   r,   )Nr   )rD   Nr   r   )@rt   r   pathlibr   r$   r8   r1   Zunittest
contextlibr   ior   
subprocessr   r   Zunittest.mockr   Ztraitlets.config.loaderr   ZIPython.utils.processr	   ZIPython.utils.textr
   ZIPython.utils.ior   r   r   r   rD   r   decr   platformZskip_doctestZ	null_decoZdoctest_decorK   r    r"   r*   Z__test__r+   r6   r<   rZ   r^   ZTestCaser_   rw   r}   r   typecompiler   r   objectr~   r   r   r   r   r   r   r   r   r   r   r   <module>   s\     +	

:
/",
	

