
_'                 @   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 Gd d   d e j j  Z d d   Z Gd d   d e  Z Gd 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 d d d   f d d  Z d d   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                sQ  | 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 r | j d } t |  }
 d j d |
 j p | d	 |
 j p | d
 |	 j d   } |
 j	 } |
 j
 r%t |
 j
 t  rd n d } | | |
 j
 7} | |  _ t t |   j | | | |  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}schemenetlocpathr      ??)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-5gj8f0j9/flask/flask/testing.pyr   /   s.    
						zEnvironBuilder.__init__c             K   s    | j  d |  j  t | |  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)__name__
__module____qualname____doc__r   r(   r%   r%   )r$   r&   r
      s   #r
   c              O   s    t  j t d   t |  |   S)zCreate a :class:`flask.testing.EnvironBuilder`.

    .. deprecated: 1.1
        Will be removed in 2.0. Construct
        ``flask.testing.EnvironBuilder`` directly instead.
    z"make_test_environ_builder()" is deprecated and will be removed in 2.0. Construct "flask.testing.EnvironBuilder" directly instead.)warningswarnDeprecationWarningr
   )r    r!   r%   r%   r&   make_test_environ_builderb   s    
r1   c                   sd   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
   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                s9   t  t |   j | |   d d d d t j i |  _ d  S)NZREMOTE_ADDRz	127.0.0.1ZHTTP_USER_AGENTz	werkzeug/)r   r2   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 r t d   t j |  z	 | VWd t j   X| j   }	 | j |  s | j | | |	  |	 j | j
 j  }
 |  j  j | j
 j |
  Wd QRXd 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   r6   Zouter_reqctxcr:   sessrespheadersr%   r%   r&   session_transaction   s,    					
	zFlaskClient.session_transactionc             O   sR  | 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 <n_ |  j | j d i   d <| j d	 |  j  t |  j | |  } z | j
   } Wd  | j   Xt j |  | d | d | d | S)
Nas_tupleFbufferedfollow_redirectsr   r   zflask._preserve_contextr6   r5   )r=   lenr   r3   testr
   dictr5   copyupdateZget_environpreserve_contextr'   r8   closer   open)r   r    r!   rE   rF   rG   r?   Zbuilderr%   r%   r&   rO      s.    zFlaskClient.openc             C   s"   |  j  r t d   d |  _  |  S)NzCannot nest client invocationsT)rM   r7   )r   r%   r%   r&   	__enter__   s    		zFlaskClient.__enter__c             C   s@   d |  _  x0 t j } | d  k	 r7 | j r7 | j   q Pq Wd  S)NF)rM   r   r9   Z	preservedr=   )r   exc_type	exc_valuetbr9   r%   r%   r&   __exit__   s    		zFlaskClient.__exit__)r*   r+   r,   r-   rM   r   r   rD   rO   rP   rT   r%   r%   )r$   r&   r2   s   s   5&r2   c                   s@   e  Z d  Z d Z   f d d   Z d d   f d d  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 |   d  S)N)r   r   rU   r   )r   r   r!   )r$   r%   r&   r     s    	zFlaskCliRunner.__init__Nc                s_   | d k r   j  j } d | k rC t d   f d d    | d <t t    j | | |  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)   Z
create_appc                  s     j  S)N)r   r%   )r   r%   r&   <lambda>  s    z'FlaskCliRunner.invoke.<locals>.<lambda>)r   clir   r   rU   invoke)r   rW   r    r!   )r$   )r   r&   rX     s
    zFlaskCliRunner.invoke)r*   r+   r,   r-   r   rX   r%   r%   )r$   r&   rU      s   rU   )r-   r.   
contextlibr   Zwerkzeug.testr3   Zclick.testingr   r   Zwerkzeug.urlsr    r   rW   r   jsonr	   r(   rI   r
   r1   r2   rU   r%   r%   r%   r&   <module>   s   I