3
üZð]¢'  ã               @   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ê   |p
|p
| s*|d k	t |p|ƒks*tdƒ‚|d krÆ|jjdƒp@d}|jd }	|r\dj||ƒ}|d krn|jd }t|ƒ}
dj|
jp‚||
jpŠ||	jdƒd	�}|
j	}|
j
rÆt|
j
tƒr´d
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__© ú./tmp/pip-build-w1as9q70/flask/flask/testing.pyr   /   s.    


zEnvironBuilder.__init__c             K   s   |j d| jƒ t|f|ŽS )z³Serialize ``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 jtdƒƒ t| |ŽS )z±Create 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    r2   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   r3   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}|jdi ƒ}| j j|ƒ tj}|j||Ž�Š}|j}|j	||j
ƒ}|dkrhtdƒ‚tj|ƒ z
|V  W dtjƒ  X |jƒ }	|j|ƒs¨|j|||	ƒ |	j|j
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Ú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   r7   Zouter_reqctxÚcr;   ÚsessÚrespÚheadersr%   r%   r&   Úsession_transaction‹   s,    





zFlaskClient.session_transactionc             O   sô   |j ddƒ}|j ddƒ}|j ddƒ}| r–t|ƒdkr–t|d tjjtfƒr–| jjƒ }t|d tjjƒr||j	|d j
ƒ ƒ n|j	|d ƒ | j|d< nJ| j|jdi ƒd< |jd	| jƒ t| jf|ž|Ž}z|j
ƒ }W d |jƒ  X tj| ||||d
�S )NÚas_tupleFÚbufferedÚfollow_redirectsr   r   zflask._preserve_contextr7   r6   )rF   rG   rH   )r>   Úlenr   r4   Útestr
   Údictr6   ÚcopyÚupdateZget_environÚpreserve_contextr'   r9   Úcloser   Úopen)r   r    r!   rF   rG   rH   r@   Zbuilderr%   r%   r&   rP   À   s.    

zFlaskClient.openc             C   s   | j rtdƒ‚d| _ | S )NzCannot nest client invocationsT)rN   r8   )r   r%   r%   r&   Ú	__enter__æ   s    zFlaskClient.__enter__c             C   s0   d| _ x$tj}|d k	r&|jr&|jƒ  qP qW d S )NF)rN   r   r:   Z	preservedr>   )r   Úexc_typeÚ	exc_valueÚtbr:   r%   r%   r&   Ú__exit__ì   s    
zFlaskClient.__exit__)r*   r+   r,   r-   rN   r   r   rE   rP   rQ   rU   r.   r%   r%   )r$   r&   r3   s   s   5&r3   c                   s.   e Zd ZdZ‡ fdd„Zd‡ fdd„	Z‡  ZS )ÚFlaskCliRunnerz®A :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   rV   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 )N)r   r%   )r   r%   r&   Ú<lambda>  s    z'FlaskCliRunner.invoke.<locals>.<lambda>)Z
create_app)r   Úclir   r   rV   Úinvoke)r   rX   r    r!   )r$   )r   r&   rY     s
    zFlaskCliRunner.invoke)NN)r*   r+   r,   r-   r   rY   r.   r%   r%   )r$   r&   rV   ü   s   rV   )r-   r/   Ú
contextlibr   Zwerkzeug.testr4   Zclick.testingr   r   Zwerkzeug.urlsr   Ú r   rX   r   Újsonr	   r(   rJ   r
   r2   r3   rV   r%   r%   r%   r&   Ú<module>   s   I 
