U
    'Q^'                     @   s   d Z ddlZddlm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 G dd dejjZdd ZG dd deZG dd deZdS )z
    flask.testing
    ~~~~~~~~~~~~~

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

    :copyright: 2010 Pallets
    :license: BSD-3-Clause
    N)contextmanager)	CliRunner)Client)	url_parse   )_request_ctx_stack)
ScriptInfo)dumpsc                       s*   e Zd ZdZd fdd	Zdd Z  ZS )	EnvironBuildera  An :class:`~werkzeug.test.EnvironBuilder`, that takes 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`.
    /Nc                    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 }|| _tt| j||f|| d S )Nz8Cannot pass "subdomain" or "url_scheme" with "base_url".ZSERVER_NAME	localhostZAPPLICATION_ROOTz{0}.{1}ZPREFERRED_URL_SCHEMEz{scheme}://{netloc}/{path}r   )schemenetlocpath   ??)boolAssertionErrorconfiggetformatr   r   r   lstripr   query
isinstancebytesappsuperr
   __init__)selfr   r   base_urlZ	subdomainZ
url_schemeargskwargsZ	http_hostZapp_rooturlsep	__class__ 0/tmp/pip-install-bd4o36v9/Flask/flask/testing.pyr   /   s6    


zEnvironBuilder.__init__c                 K   s   | d| j t|f|S )zSerialize ``obj`` to a JSON-formatted string.

        The serialization will be configured according to the config associated
        with this EnvironBuilder's ``app``.
        r   )
setdefaultr   
json_dumps)r   objr!   r&   r&   r'   r)   X   s    zEnvironBuilder.json_dumps)r   NNN)__name__
__module____qualname____doc__r   r)   __classcell__r&   r&   r$   r'   r
      s       )r
   c                  O   s   t td t| |S )zCreate a :class:`flask.testing.EnvironBuilder`.

    .. deprecated: 1.1
        Will be removed in 1.2. Construct ``flask.testing.EnvironBuilder``
        directly instead.
    z"make_test_environ_builder()" is deprecated and will be removed in 1.2. Construct "flask.testing.EnvironBuilder" directly instead.)warningswarnDeprecationWarningr
   )r    r!   r&   r&   r'   make_test_environ_builderb   s    r3   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)r   r4   r   werkzeug__version__environ_base)r   r    r!   r$   r&   r'   r      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 5 t  X | }	||s||||	 |	|j
j}
| j |j
j|
 W 5 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applicationr(   Zinject_wsgir   topZtest_request_contextsession_interfaceZopen_sessionrequestpushpopresponse_classZis_null_sessionZsave_sessionZget_wsgi_headersenvironZextract_wsgi)r   r    r!   r   r8   Zouter_reqctxcr<   sessrespheadersr&   r&   r'   session_transaction   s0    




zFlaskClient.session_transactionc                 O   s   | dd}| dd}| dd}|st|dkrt|d tjjtfr| j }t|d tjjrz|	|d 
  n|	|d  | j|d< nJ| j|di d< |d	| j t| jf||}z|
 }W 5 |  X tj| ||||d
S )Nas_tupleFbufferedfollow_redirectsr   r   zflask._preserve_contextr8   r7   )rG   rH   rI   )r?   lenr   r5   testr
   dictr7   copyupdateZget_environpreserve_contextr(   r:   closer   open)r   r    r!   rG   rH   rI   rA   builderr&   r&   r'   rQ      s<    



zFlaskClient.openc                 C   s   | j rtdd| _ | S )NzCannot nest client invocationsT)rO   r9   r   r&   r&   r'   	__enter__   s    zFlaskClient.__enter__c                 C   s,   d| _ tj}|d k	r(|jr(|  qq(qd S )NF)rO   r   r;   Z	preservedr?   )r   exc_type	exc_valuetbr;   r&   r&   r'   __exit__   s
    
zFlaskClient.__exit__)r+   r,   r-   r.   rO   r   r   rF   rQ   rT   rX   r/   r&   r&   r$   r'   r4   s   s   
4&r4   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   rY   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.
        Nr*   c                      s    j S rZ   )r   r&   rS   r&   r'   <lambda>      z'FlaskCliRunner.invoke.<locals>.<lambda>)Z
create_app)r   clir   r   rY   invoke)r   r]   r    r!   r$   rS   r'   r^     s
    zFlaskCliRunner.invoke)NN)r+   r,   r-   r.   r   r^   r/   r&   r&   r$   r'   rY      s   rY   )r.   r0   
contextlibr   Zwerkzeug.testr5   Zclick.testingr   r   Zwerkzeug.urlsr    r   r]   r   jsonr	   r)   rK   r
   r3   r4   rY   r&   r&   r&   r'   <module>   s   
I 
