Convert make_test_environ_builder into class (fixes #3207)
This commit is contained in:
parent
91e53da054
commit
976dfedaa9
4 changed files with 99 additions and 48 deletions
|
|
@ -2359,9 +2359,9 @@ class Flask(_PackageBoundObject):
|
||||||
:param kwargs: other keyword arguments passed to
|
:param kwargs: other keyword arguments passed to
|
||||||
:class:`~werkzeug.test.EnvironBuilder`.
|
:class:`~werkzeug.test.EnvironBuilder`.
|
||||||
"""
|
"""
|
||||||
from flask.testing import make_test_environ_builder
|
from flask.testing import EnvironBuilder
|
||||||
|
|
||||||
builder = make_test_environ_builder(self, *args, **kwargs)
|
builder = EnvironBuilder(self, *args, **kwargs)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return self.request_context(builder.get_environ())
|
return self.request_context(builder.get_environ())
|
||||||
|
|
|
||||||
108
flask/testing.py
108
flask/testing.py
|
|
@ -9,8 +9,9 @@
|
||||||
:copyright: © 2010 by the Pallets team.
|
:copyright: © 2010 by the Pallets team.
|
||||||
:license: BSD, see LICENSE for more details.
|
:license: BSD, see LICENSE for more details.
|
||||||
"""
|
"""
|
||||||
|
import warnings
|
||||||
import werkzeug
|
import werkzeug
|
||||||
|
import werkzeug.test
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
from click.testing import CliRunner
|
from click.testing import CliRunner
|
||||||
|
|
@ -21,11 +22,9 @@ from flask.json import dumps as json_dumps
|
||||||
from werkzeug.urls import url_parse
|
from werkzeug.urls import url_parse
|
||||||
|
|
||||||
|
|
||||||
def make_test_environ_builder(
|
class EnvironBuilder(werkzeug.test.EnvironBuilder):
|
||||||
app, path="/", base_url=None, subdomain=None, url_scheme=None, *args, **kwargs
|
"""An :class:`~werkzeug.test.EnvironBuilder`, that takes defaults from the
|
||||||
):
|
application.
|
||||||
"""Create a :class:`~werkzeug.test.EnvironBuilder`, taking some
|
|
||||||
defaults from the application.
|
|
||||||
|
|
||||||
:param app: The Flask application to configure the environment from.
|
:param app: The Flask application to configure the environment from.
|
||||||
:param path: URL path being requested.
|
:param path: URL path being requested.
|
||||||
|
|
@ -45,41 +44,72 @@ def make_test_environ_builder(
|
||||||
:class:`~werkzeug.test.EnvironBuilder`.
|
:class:`~werkzeug.test.EnvironBuilder`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
assert not (base_url or subdomain or url_scheme) or (base_url is not None) != bool(
|
def __init__(
|
||||||
subdomain or url_scheme
|
self,
|
||||||
), 'Cannot pass "subdomain" or "url_scheme" with "base_url".'
|
app,
|
||||||
|
path="/",
|
||||||
|
base_url=None,
|
||||||
|
subdomain=None,
|
||||||
|
url_scheme=None,
|
||||||
|
*args,
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
assert not (base_url or subdomain or url_scheme) or (
|
||||||
|
base_url is not None
|
||||||
|
) != bool(
|
||||||
|
subdomain or url_scheme
|
||||||
|
), 'Cannot pass "subdomain" or "url_scheme" with "base_url".'
|
||||||
|
|
||||||
if base_url is None:
|
if base_url is None:
|
||||||
http_host = app.config.get("SERVER_NAME") or "localhost"
|
http_host = app.config.get("SERVER_NAME") or "localhost"
|
||||||
app_root = app.config["APPLICATION_ROOT"]
|
app_root = app.config["APPLICATION_ROOT"]
|
||||||
|
|
||||||
if subdomain:
|
if subdomain:
|
||||||
http_host = "{0}.{1}".format(subdomain, http_host)
|
http_host = "{0}.{1}".format(subdomain, http_host)
|
||||||
|
|
||||||
if url_scheme is None:
|
if url_scheme is None:
|
||||||
url_scheme = app.config["PREFERRED_URL_SCHEME"]
|
url_scheme = app.config["PREFERRED_URL_SCHEME"]
|
||||||
|
|
||||||
url = url_parse(path)
|
url = url_parse(path)
|
||||||
base_url = "{scheme}://{netloc}/{path}".format(
|
base_url = "{scheme}://{netloc}/{path}".format(
|
||||||
scheme=url.scheme or url_scheme,
|
scheme=url.scheme or url_scheme,
|
||||||
netloc=url.netloc or http_host,
|
netloc=url.netloc or http_host,
|
||||||
path=app_root.lstrip("/"),
|
path=app_root.lstrip("/"),
|
||||||
|
)
|
||||||
|
path = url.path
|
||||||
|
|
||||||
|
if url.query:
|
||||||
|
sep = b"?" if isinstance(url.query, bytes) else "?"
|
||||||
|
path += sep + url.query
|
||||||
|
|
||||||
|
if "json" in kwargs:
|
||||||
|
assert "data" not in kwargs, "Client cannot provide both 'json' and 'data'."
|
||||||
|
kwargs["data"] = self.json_dumps(kwargs.pop("json"), app=app)
|
||||||
|
|
||||||
|
if "content_type" not in kwargs:
|
||||||
|
kwargs["content_type"] = "application/json"
|
||||||
|
|
||||||
|
super(EnvironBuilder, self).__init__(path, base_url, *args, **kwargs)
|
||||||
|
self.app = app
|
||||||
|
|
||||||
|
json_dumps = staticmethod(json_dumps)
|
||||||
|
|
||||||
|
|
||||||
|
def make_test_environ_builder(*args, **kwargs):
|
||||||
|
"""Create a :class:`flask.testing.EnvironBuilder`.
|
||||||
|
|
||||||
|
.. deprecated: 1.1
|
||||||
|
Will be removed in 1.2. Construct ``flask.testing.EnvironBuilder``
|
||||||
|
directly instead.
|
||||||
|
"""
|
||||||
|
warnings.warn(
|
||||||
|
DeprecationWarning(
|
||||||
|
'"make_test_environ_builder()" is deprecated and will be removed '
|
||||||
|
'in 1.2. Construct "flask.testing.EnvironBuilder" directly '
|
||||||
|
"instead."
|
||||||
)
|
)
|
||||||
path = url.path
|
)
|
||||||
|
return EnvironBuilder(*args, **kwargs)
|
||||||
if url.query:
|
|
||||||
sep = b"?" if isinstance(url.query, bytes) else "?"
|
|
||||||
path += sep + url.query
|
|
||||||
|
|
||||||
# TODO use EnvironBuilder.json_dumps once we require Werkzeug 0.15
|
|
||||||
if "json" in kwargs:
|
|
||||||
assert "data" not in kwargs, "Client cannot provide both 'json' and 'data'."
|
|
||||||
kwargs["data"] = json_dumps(kwargs.pop("json"), app=app)
|
|
||||||
|
|
||||||
if "content_type" not in kwargs:
|
|
||||||
kwargs["content_type"] = "application/json"
|
|
||||||
|
|
||||||
return EnvironBuilder(path, base_url, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class FlaskClient(Client):
|
class FlaskClient(Client):
|
||||||
|
|
@ -167,11 +197,11 @@ class FlaskClient(Client):
|
||||||
if (
|
if (
|
||||||
not kwargs
|
not kwargs
|
||||||
and len(args) == 1
|
and len(args) == 1
|
||||||
and isinstance(args[0], (EnvironBuilder, dict))
|
and isinstance(args[0], (werkzeug.test.EnvironBuilder, dict))
|
||||||
):
|
):
|
||||||
environ = self.environ_base.copy()
|
environ = self.environ_base.copy()
|
||||||
|
|
||||||
if isinstance(args[0], EnvironBuilder):
|
if isinstance(args[0], werkzeug.test.EnvironBuilder):
|
||||||
environ.update(args[0].get_environ())
|
environ.update(args[0].get_environ())
|
||||||
else:
|
else:
|
||||||
environ.update(args[0])
|
environ.update(args[0])
|
||||||
|
|
@ -182,7 +212,7 @@ class FlaskClient(Client):
|
||||||
"flask._preserve_context"
|
"flask._preserve_context"
|
||||||
] = self.preserve_context
|
] = self.preserve_context
|
||||||
kwargs.setdefault("environ_base", self.environ_base)
|
kwargs.setdefault("environ_base", self.environ_base)
|
||||||
builder = make_test_environ_builder(self.application, *args, **kwargs)
|
builder = EnvironBuilder(self.application, *args, **kwargs)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
environ = builder.get_environ()
|
environ = builder.get_environ()
|
||||||
|
|
|
||||||
|
|
@ -243,9 +243,9 @@ def test_bad_environ_raises_bad_request():
|
||||||
# because werkzeug enforces latin1 on Python 2.
|
# because werkzeug enforces latin1 on Python 2.
|
||||||
# However it works when actually passed to the server.
|
# However it works when actually passed to the server.
|
||||||
|
|
||||||
from flask.testing import make_test_environ_builder
|
from flask.testing import EnvironBuilder
|
||||||
|
|
||||||
builder = make_test_environ_builder(app)
|
builder = EnvironBuilder(app)
|
||||||
environ = builder.get_environ()
|
environ = builder.get_environ()
|
||||||
|
|
||||||
# use a non-printable character in the Host - this is key to this test
|
# use a non-printable character in the Host - this is key to this test
|
||||||
|
|
@ -267,9 +267,9 @@ def test_environ_for_valid_idna_completes():
|
||||||
# because werkzeug enforces latin1 on Python 2.
|
# because werkzeug enforces latin1 on Python 2.
|
||||||
# However it works when actually passed to the server.
|
# However it works when actually passed to the server.
|
||||||
|
|
||||||
from flask.testing import make_test_environ_builder
|
from flask.testing import EnvironBuilder
|
||||||
|
|
||||||
builder = make_test_environ_builder(app)
|
builder = EnvironBuilder(app)
|
||||||
environ = builder.get_environ()
|
environ = builder.get_environ()
|
||||||
|
|
||||||
# these characters are all IDNA-compatible
|
# these characters are all IDNA-compatible
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ from flask import appcontext_popped
|
||||||
from flask._compat import text_type
|
from flask._compat import text_type
|
||||||
from flask.cli import ScriptInfo
|
from flask.cli import ScriptInfo
|
||||||
from flask.json import jsonify
|
from flask.json import jsonify
|
||||||
from flask.testing import make_test_environ_builder, FlaskCliRunner
|
from flask.testing import make_test_environ_builder, FlaskCliRunner, EnvironBuilder
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import blinker
|
import blinker
|
||||||
|
|
@ -88,7 +88,7 @@ def test_client_open_environ(app, client, request):
|
||||||
def index():
|
def index():
|
||||||
return flask.request.remote_addr
|
return flask.request.remote_addr
|
||||||
|
|
||||||
builder = make_test_environ_builder(app, path="/index", method="GET")
|
builder = EnvironBuilder(app, path="/index", method="GET")
|
||||||
request.addfinalizer(builder.close)
|
request.addfinalizer(builder.close)
|
||||||
|
|
||||||
rv = client.open(builder)
|
rv = client.open(builder)
|
||||||
|
|
@ -113,13 +113,34 @@ def test_specify_url_scheme(app, client):
|
||||||
|
|
||||||
|
|
||||||
def test_path_is_url(app):
|
def test_path_is_url(app):
|
||||||
eb = make_test_environ_builder(app, "https://example.com/")
|
eb = EnvironBuilder(app, "https://example.com/")
|
||||||
assert eb.url_scheme == "https"
|
assert eb.url_scheme == "https"
|
||||||
assert eb.host == "example.com"
|
assert eb.host == "example.com"
|
||||||
assert eb.script_root == ""
|
assert eb.script_root == ""
|
||||||
assert eb.path == "/"
|
assert eb.path == "/"
|
||||||
|
|
||||||
|
|
||||||
|
def test_make_test_environ_builder(app):
|
||||||
|
with pytest.deprecated_call():
|
||||||
|
eb = make_test_environ_builder(app, "https://example.com/")
|
||||||
|
assert eb.url_scheme == "https"
|
||||||
|
assert eb.host == "example.com"
|
||||||
|
assert eb.script_root == ""
|
||||||
|
assert eb.path == "/"
|
||||||
|
|
||||||
|
|
||||||
|
def test_environbuilder_json_dumps(app):
|
||||||
|
"""EnvironBuilder.json_dumps() takes settings from the app."""
|
||||||
|
app.config["JSON_AS_ASCII"] = False
|
||||||
|
eb = EnvironBuilder(app, json=u"\u20ac")
|
||||||
|
assert eb.input_stream.read().decode("utf8") == u'"\u20ac"'
|
||||||
|
|
||||||
|
|
||||||
|
def test_environbuilder_json_dumps_static():
|
||||||
|
"""EnvironBuilder.json_dumps() can be called as a static method."""
|
||||||
|
assert EnvironBuilder.json_dumps(u"\u20ac") == u'"\\u20ac"'
|
||||||
|
|
||||||
|
|
||||||
def test_blueprint_with_subdomain():
|
def test_blueprint_with_subdomain():
|
||||||
app = flask.Flask(__name__, subdomain_matching=True)
|
app = flask.Flask(__name__, subdomain_matching=True)
|
||||||
app.config["SERVER_NAME"] = "example.com:1234"
|
app.config["SERVER_NAME"] = "example.com:1234"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue