Skip to content

Commit

Permalink
Merge pull request #1518 from NiklasMM/fix/1510_lint-middleware-pytho…
Browse files Browse the repository at this point in the history
…n3-compatibility

Make LintMiddleware Python 3 compatible and add tests
  • Loading branch information
davidism authored May 12, 2019
2 parents d590cc7 + e00c7c2 commit 777500b
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Unreleased
- Fix the filename format string in
:class:`~middleware.profiler.ProfilerMiddleware` to correctly handle
float values. (:issue:`1511`)
- Update :class:`~middleware.lint.LintMiddleware` to work on Python 3.
(:issue:`1510`)


Version 0.15.2
Expand Down
10 changes: 8 additions & 2 deletions src/werkzeug/middleware/lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
"""
from warnings import warn

from .._compat import implements_iterator
from .._compat import PY2
from .._compat import string_types
from ..datastructures import Headers
from ..http import is_entity_header
Expand Down Expand Up @@ -124,18 +126,22 @@ def __call__(self, s):
self._chunks.append(len(s))


@implements_iterator
class GuardedIterator(object):
def __init__(self, iterator, headers_set, chunks):
self._iterator = iterator
self._next = iter(iterator).next
if PY2:
self._next = iter(iterator).next
else:
self._next = iter(iterator).__next__
self.closed = False
self.headers_set = headers_set
self.chunks = chunks

def __iter__(self):
return self

def next(self):
def __next__(self):
if self.closed:
warn("Iterated over closed 'app_iter'.", WSGIWarning, stacklevel=2)

Expand Down
87 changes: 87 additions & 0 deletions tests/middleware/test_lint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# -*- coding: utf-8 -*-
import pytest

from werkzeug.middleware.lint import HTTPWarning
from werkzeug.middleware.lint import LintMiddleware
from werkzeug.middleware.lint import WSGIWarning
from werkzeug.test import create_environ
from werkzeug.test import run_wsgi_app


def dummy_application(environ, start_response):
start_response("200 OK", [("Content-Type", "text/plain")])
return ["Foo"]


def test_lint_middleware():
""" Test lint middleware runs for a dummy applications without warnings """
app = LintMiddleware(dummy_application)

environ = create_environ("/test")
app_iter, status, headers = run_wsgi_app(app, environ, buffered=True)
assert status == "200 OK"


@pytest.mark.parametrize(
"key, value, message",
[
("wsgi.version", (0, 7), "Environ is not a WSGI 1.0 environ."),
("SCRIPT_NAME", "test", "'SCRIPT_NAME' does not start with a slash:"),
("PATH_INFO", "test", "'PATH_INFO' does not start with a slash:"),
],
)
def test_lint_middleware_check_environ(key, value, message):
app = LintMiddleware(dummy_application)

environ = create_environ("/test")
environ[key] = value
with pytest.warns(WSGIWarning, match=message):
app_iter, status, headers = run_wsgi_app(app, environ, buffered=True)
assert status == "200 OK"


def test_lint_middleware_invalid_status():
def my_dummy_application(environ, start_response):
start_response("20 OK", [("Content-Type", "text/plain")])
return ["Foo"]

app = LintMiddleware(my_dummy_application)

environ = create_environ("/test")
with pytest.warns(WSGIWarning) as record:
run_wsgi_app(app, environ, buffered=True)

# Returning status 20 should raise three different warnings
assert len(record) == 3


@pytest.mark.parametrize(
"headers, message",
[
(tuple([("Content-Type", "text/plain")]), "header list is not a list"),
(["fo"], "Headers must tuple 2-item tuples"),
([("status", "foo")], "The status header is not supported"),
],
)
def test_lint_middleware_http_headers(headers, message):
def my_dummy_application(environ, start_response):
start_response("200 OK", headers)
return ["Foo"]

app = LintMiddleware(my_dummy_application)

environ = create_environ("/test")
with pytest.warns(WSGIWarning, match=message):
run_wsgi_app(app, environ, buffered=True)


def test_lint_middleware_invalid_location():
def my_dummy_application(environ, start_response):
start_response("200 OK", [("location", "foo")])
return ["Foo"]

app = LintMiddleware(my_dummy_application)

environ = create_environ("/test")
with pytest.warns(HTTPWarning, match="absolute URLs required for location header"):
run_wsgi_app(app, environ, buffered=True)

0 comments on commit 777500b

Please sign in to comment.