B
    ;=[$                 @   s   d 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	m
Z
 ddlmZ ddlmZ dd	lmZ dddZG dd de	ZG dd deZdS )u   
    flask.testing
    ~~~~~~~~~~~~~

    Implements test support helpers.  This module is lazily imported
    and usually not used in production environments.

    :copyright: © 2010 by the Pallets team.
    :license: BSD, see LICENSE for more details.
    N)contextmanager)	CliRunner)
ScriptInfo)ClientEnvironBuilder)_request_ctx_stack)dumps)	url_parse/c          	   O   s(  |s|s|r(|dk	t |p|ks(td|dkr| jdp>d}| jd }|rZd||}|dkrl| jd }t|}	dj|	jp||	jp||d	d
}|	j	}|	j
rt|	j
trdnd}
||
|	j
 7 }d|krd|kstd|   t|d|d< W dQ R X d|krd|d< t||f||S )a  Create a :class:`~werkzeug.test.EnvironBuilder`, taking some
    defaults from the application.

    :param app: The Flask application to configure the environment from.
    :param path: URL path being requested.
    :param base_url: Base URL where the app is being served, which
        ``path`` is relative to. If not given, built from
        :data:`PREFERRED_URL_SCHEME`, ``subdomain``,
        :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`.
    :param subdomain: Subdomain name to append to :data:`SERVER_NAME`.
    :param url_scheme: Scheme to use instead of
        :data:`PREFERRED_URL_SCHEME`.
    :param json: If given, this is serialized as JSON and passed as
        ``data``. Also defaults ``content_type`` to
        ``application/json``.
    :param args: other positional arguments passed to
        :class:`~werkzeug.test.EnvironBuilder`.
    :param kwargs: other keyword arguments passed to
        :class:`~werkzeug.test.EnvironBuilder`.
    Nz8Cannot pass "subdomain" or "url_scheme" with "base_url".ZSERVER_NAMEZ	localhostZAPPLICATION_ROOTz{0}.{1}ZPREFERRED_URL_SCHEMEz{scheme}://{netloc}/{path}r
   )schemenetlocpath   ??Zjsondataz-Client cannot provide both 'json' and 'data'.Zcontent_typezapplication/json)boolAssertionErrorZconfiggetformatr	   r   r   lstripr   Zquery
isinstancebytesZapp_context
json_dumpspopr   )appr   Zbase_urlZ	subdomainZ
url_schemeargskwargsZ	http_hostZapp_rootZurlsep r   ,lib/python3.7/site-packages/flask/testing.pymake_test_environ_builder   s6    





r    c                   sH   e Zd ZdZdZ fddZedd Zdd Zd	d
 Z	dd Z
  ZS )FlaskClientaD  Works like a regular Werkzeug test client but has some knowledge about
    how Flask works to defer the cleanup of the request context stack to the
    end of a ``with`` body when used in a ``with`` statement.  For general
    information about how to use this class refer to
    :class:`werkzeug.test.Client`.

    .. versionchanged:: 0.12
       `app.test_client()` includes preset default environment, which can be
       set after instantiation of the `app.test_client()` object in
       `client.environ_base`.

    Basic usage is outlined in the :ref:`testing` chapter.
    Fc                s(   t t| j|| ddtj d| _d S )Nz	127.0.0.1z	werkzeug/)ZREMOTE_ADDRZHTTP_USER_AGENT)superr!   __init__werkzeug__version__environ_base)selfr   r   )	__class__r   r   r#   l   s    zFlaskClient.__init__c          	   o   s   | j dkrtd| j}|di }| j | tj}|j||}|j}|	||j
}|dkrhtdt| z
|V  W dt  X | }	||s||||	 |	|j
j}
| j |j
j|
 W dQ R X dS )a  When used in combination with a ``with`` statement this opens a
        session transaction.  This can be used to modify the session that
        the test client uses.  Once the ``with`` block is left the session is
        stored back.

        ::

            with client.session_transaction() as session:
                session['value'] = 42

        Internally this is implemented by going through a temporary test
        request context and since session handling could depend on
        request variables this function accepts the same arguments as
        :meth:`~flask.Flask.test_request_context` which are directly
        passed through.
        Nz:Session transactions only make sense with cookies enabled.environ_overridesz?Session backend did not open a session. Check the configuration)Z
cookie_jarRuntimeErrorapplication
setdefaultZinject_wsgir   topZtest_request_contextsession_interfaceZopen_sessionZrequestpushr   Zresponse_classZis_null_sessionZsave_sessionZget_wsgi_headersenvironZextract_wsgi)r'   r   r   r   r)   Zouter_reqctxcr.   ZsessZrespZheadersr   r   r   session_transactions   s(    





zFlaskClient.session_transactionc             O   s   | dd}| dd}| dd}|st|dkrt|d ttfr| j }t|d trr||d   n||d  | j	|d< nJ| j	|
di d< |
d	| j t| jf||}z| }W d |  X tj| ||||d
S )Nas_tupleFbufferedfollow_redirects   r   zflask._preserve_contextr)   r&   )r3   r4   r5   )r   lenr   r   dictr&   copyupdateZget_environpreserve_contextr,   r    r+   closer   open)r'   r   r   r3   r4   r5   r0   Zbuilderr   r   r   r=      s,    

zFlaskClient.openc             C   s   | j rtdd| _ | S )NzCannot nest client invocationsT)r;   r*   )r'   r   r   r   	__enter__   s    zFlaskClient.__enter__c             C   s&   d| _ tj}|d k	r"|jr"|  d S )NF)r;   r   r-   Z	preservedr   )r'   exc_type	exc_valuetbr-   r   r   r   __exit__   s    zFlaskClient.__exit__)__name__
__module____qualname____doc__r;   r#   r   r2   r=   r>   rB   __classcell__r   r   )r(   r   r!   [   s   3%r!   c                   s.   e Zd ZdZ fddZd fdd	Z  ZS )FlaskCliRunnerzA :class:`~click.testing.CliRunner` for testing a Flask app's
    CLI commands. Typically created using
    :meth:`~flask.Flask.test_cli_runner`. See :ref:`testing-cli`.
    c                s   || _ tt| jf | d S )N)r   r"   rH   r#   )r'   r   r   )r(   r   r   r#      s    zFlaskCliRunner.__init__Nc                sD   |dkr j j}d|kr.t fddd|d< tt j||f|S )ac  Invokes a CLI command in an isolated environment. See
        :meth:`CliRunner.invoke <click.testing.CliRunner.invoke>` for
        full method documentation. See :ref:`testing-cli` for examples.

        If the ``obj`` argument is not given, passes an instance of
        :class:`~flask.cli.ScriptInfo` that knows how to load the Flask
        app being tested.

        :param cli: Command object to invoke. Default is the app's
            :attr:`~flask.app.Flask.cli` group.
        :param args: List of strings to invoke the command with.

        :return: a :class:`~click.testing.Result` object.
        Nobjc                  s    j S )N)r   r   )r'   r   r   <lambda>   s    z'FlaskCliRunner.invoke.<locals>.<lambda>)Z
create_app)r   clir   r"   rH   invoke)r'   rK   r   r   )r(   )r'   r   rL      s
    zFlaskCliRunner.invoke)NN)rC   rD   rE   rF   r#   rL   rG   r   r   )r(   r   rH      s   rH   )r
   NNN)rF   r$   
contextlibr   Zclick.testingr   Z	flask.clir   Zwerkzeug.testr   r   Zflaskr   Z
flask.jsonr   r   Zwerkzeug.urlsr	   r    r!   rH   r   r   r   r   <module>   s   
B 