test_compat

tests/test_compat.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import importlib
import tempfile
from urllib.parse import urlsplit

import pytest
from werkzeug import urls as werkzeug_urls

from lektor_ng.compat import _CompatURL


@pytest.mark.parametrize(
    "name, expected_value, replacement",
    [
        (
            "TemporaryDirectory",
            tempfile.TemporaryDirectory,
            "tempfile.TemporaryDirectory",
        ),
        ("importlib_metadata", importlib.metadata, "importlib.metadata"),
    ],
)
def test_deprecated_attr(name, expected_value, replacement):
    lektor_compat = importlib.import_module("lektor_ng.compat")
    with pytest.deprecated_call(match=f"use {replacement} instead") as warnings:
        value = getattr(lektor_compat, name)
    assert value is expected_value
    assert warnings[0].filename == __file__


def test_missing_attr():
    lektor_compat = importlib.import_module("lektor_ng.compat")
    with pytest.raises(AttributeError):
        _ = lektor_compat.MISSING


def make_CompatURL(url: str) -> _CompatURL:
    return _CompatURL._make(urlsplit(url))


URL_MAKERS = [
    pytest.param(make_CompatURL, id="_CompatURL"),
    pytest.param(
        getattr(werkzeug_urls, "url_parse", None),
        id="werkzeug.urls.URL",
        marks=pytest.mark.skipif(
            not hasattr(werkzeug_urls, "url_parse"),
            reason="werkzeug.urls.url_parse is not available",
        ),
    ),
]


@pytest.fixture(params=URL_MAKERS)
def make_url(request):
    return request.param


pytestmark = pytest.mark.filterwarnings("ignore:'werkzeug:DeprecationWarning")


def test_compatURL_replace(make_url):
    url = make_url("http://example.org/foo")
    assert str(url.replace(scheme="https", path="bar")) == "https://example.org/bar"


def test_compatURL_host(make_url):
    assert make_url("http://bücher.example/foo").host == "bücher.example"


@pytest.mark.parametrize(
    "url, expected",
    [
        ("http:/foo", [None]),
        ("http://bücher.example/foo", ["xn--bcher-kva.example"]),
        # werkzeug < 2.3 strips non-ascii
        ("http://bad\uffff.example.org", ["bad\uffff.example.org", "bad.example.org"]),
    ],
)
def test_compatURL_ascii_host(url, expected, make_url):
    assert make_url(url).ascii_host in expected


def test_compatURL_auth(make_url):
    assert make_url("http://u:p@example.org/").auth == "u:p"


@pytest.mark.parametrize(
    "url, expected",
    [
        ("http://example.org/", None),
        ("http://a%20user@example.org/", "a user"),
        ("http://%C3%BCser:pw@example.org/", "üser"),
        ("http://%FCser:pw@example.org/", "üser"),  # latin1
    ],
)
def test_compatURL_username(url, expected, make_url):
    assert make_url(url).username == expected


def test_compatURL_raw_username(make_url):
    assert make_url("http://a%20user:p@example.org/").raw_username == "a%20user"


@pytest.mark.parametrize(
    "url, expected",
    [
        ("http://user@example.org/", None),
        ("http://user:pass%20word@example.org/", "pass word"),
    ],
)
def test_compatURL_password(url, expected, make_url):
    assert make_url(url).password == expected


def test_compatURL_raw_password(make_url):
    assert make_url("http://u:pass%20word@example.org/").raw_password == "pass%20word"


def test_compatURL_decode_query(make_url):
    args = make_url("?a=b&c").decode_query()
    assert args["a"] == "b"
    assert args["c"] == ""


def test_compatURL_join(make_url):
    base = make_url("http://example.org/top/index.html")
    assert str(base.join("sibling.html")) == "http://example.org/top/sibling.html"


def test_compatURL_join_tuple(make_url):
    base = make_url("http://example.org/top/index.html")
    url = ("", "", "sibling.html", "q", "f")
    assert str(base.join(url)) == "http://example.org/top/sibling.html?q#f"


def test_compatURL_to_url(make_url):
    strval = "http://example.org/foo?q#a"
    url = make_url(strval)
    assert url.to_url() == strval
    assert str(url) == strval


@pytest.mark.filterwarnings("ignore:(?i).*werkzeug:DeprecationWarning")
def test_compatURL_to_uri_tuple(make_url):
    uri_tuple = make_url("http://example.org/fü/").to_uri_tuple()
    assert uri_tuple == ("http", "example.org", "/f%C3%BC/", "", "")


@pytest.mark.filterwarnings("ignore:(?i).*werkzeug:DeprecationWarning")
def test_compatURL_to_iri_tuple(make_url):
    iri_tuple = make_url("http://example.org/f%C3%BC/").to_iri_tuple()
    assert iri_tuple == ("http", "example.org", "/fü/", "", "")