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 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
|
import copy
import pickle
import random
try:
from collections.abc import deque
except ImportError:
from collections import deque
from copy import copy as shallow_copy
import pytest
from markupsafe import Markup
from jinja2.utils import consume
from jinja2.utils import generate_lorem_ipsum
from jinja2.utils import LRUCache
from jinja2.utils import missing
from jinja2.utils import object_type_repr
from jinja2.utils import select_autoescape
from jinja2.utils import urlize
class TestLRUCache:
def test_simple(self):
d = LRUCache(3)
d["a"] = 1
d["b"] = 2
d["c"] = 3
d["a"]
d["d"] = 4
assert d.keys() == ["d", "a", "c"]
def test_values(self):
cache = LRUCache(3)
cache["b"] = 1
cache["a"] = 2
assert cache.values() == [2, 1]
def test_values_empty(self):
cache = LRUCache(2)
assert cache.values() == []
def test_pickleable(self):
cache = LRUCache(2)
cache["foo"] = 42
cache["bar"] = 23
cache["foo"]
for protocol in range(3):
copy = pickle.loads(pickle.dumps(cache, protocol))
assert copy.capacity == cache.capacity
assert copy._mapping == cache._mapping
assert copy._queue == cache._queue
@pytest.mark.parametrize("copy_func", [LRUCache.copy, shallow_copy])
def test_copy(self, copy_func):
cache = LRUCache(2)
cache["a"] = 1
cache["b"] = 2
copy = copy_func(cache)
assert copy._queue == cache._queue
copy["c"] = 3
assert copy._queue != cache._queue
assert copy.keys() == ["c", "b"]
def test_clear(self):
d = LRUCache(3)
d["a"] = 1
d["b"] = 2
d["c"] = 3
d.clear()
assert d.__getstate__() == {"capacity": 3, "_mapping": {}, "_queue": deque([])}
def test_repr(self):
d = LRUCache(3)
d["a"] = 1
d["b"] = 2
d["c"] = 3
# Sort the strings - mapping is unordered
assert sorted(repr(d)) == sorted("<LRUCache {'a': 1, 'b': 2, 'c': 3}>")
def test_items(self):
"""Test various items, keys, values and iterators of LRUCache."""
d = LRUCache(3)
d["a"] = 1
d["b"] = 2
d["c"] = 3
assert d.items() == [("c", 3), ("b", 2), ("a", 1)]
assert d.keys() == ["c", "b", "a"]
assert d.values() == [3, 2, 1]
assert list(reversed(d)) == ["a", "b", "c"]
# Change the cache a little
d["b"]
d["a"] = 4
assert d.items() == [("a", 4), ("b", 2), ("c", 3)]
assert d.keys() == ["a", "b", "c"]
assert d.values() == [4, 2, 3]
assert list(reversed(d)) == ["c", "b", "a"]
def test_setdefault(self):
d = LRUCache(3)
assert len(d) == 0
assert d.setdefault("a") is None
assert d.setdefault("a", 1) is None
assert len(d) == 1
assert d.setdefault("b", 2) == 2
assert len(d) == 2
class TestHelpers:
def test_object_type_repr(self):
class X:
pass
assert object_type_repr(42) == "int object"
assert object_type_repr([]) == "list object"
assert object_type_repr(X()) == "test_utils.X object"
assert object_type_repr(None) == "None"
assert object_type_repr(Ellipsis) == "Ellipsis"
def test_autoescape_select(self):
func = select_autoescape(
enabled_extensions=("html", ".htm"),
disabled_extensions=("txt",),
default_for_string="STRING",
default="NONE",
)
assert func(None) == "STRING"
assert func("unknown.foo") == "NONE"
assert func("foo.html")
assert func("foo.htm")
assert not func("foo.txt")
assert func("FOO.HTML")
assert not func("FOO.TXT")
class TestEscapeUrlizeTarget:
def test_escape_urlize_target(self):
url = "http://example.org"
target = "<script>"
assert urlize(url, target=target) == (
'<a href="http://example.org"'
' target="<script>">'
"http://example.org</a>"
)
def test_urlize_mail_mastodon(self):
fr = "nabijaczleweli@nabijaczleweli.xyz\n@eater@cijber.social\n"
to = (
'<a href="mailto:nabijaczleweli@nabijaczleweli.xyz">'
"nabijaczleweli@nabijaczleweli.xyz</a>\n@eater@cijber.social\n"
)
assert urlize(fr) == to
class TestLoremIpsum:
def test_lorem_ipsum_markup(self):
"""Test that output of lorem_ipsum is Markup by default."""
assert isinstance(generate_lorem_ipsum(), Markup)
def test_lorem_ipsum_html(self):
"""Test that output of lorem_ipsum is a string_type when not html."""
assert isinstance(generate_lorem_ipsum(html=False), str)
def test_lorem_ipsum_n(self):
"""Test that the n (number of lines) works as expected."""
assert generate_lorem_ipsum(n=0, html=False) == ""
for n in range(1, 50):
assert generate_lorem_ipsum(n=n, html=False).count("\n") == (n - 1) * 2
def test_lorem_ipsum_min(self):
"""Test that at least min words are in the output of each line"""
for _ in range(5):
m = random.randrange(20, 99)
for _ in range(10):
assert generate_lorem_ipsum(n=1, min=m, html=False).count(" ") >= m - 1
def test_lorem_ipsum_max(self):
"""Test that at least max words are in the output of each line"""
for _ in range(5):
m = random.randrange(21, 100)
for _ in range(10):
assert generate_lorem_ipsum(n=1, max=m, html=False).count(" ") < m - 1
def test_missing():
"""Test the repr of missing."""
assert repr(missing) == "missing"
def test_consume():
"""Test that consume consumes an iterator."""
x = iter([1, 2, 3, 4, 5])
consume(x)
with pytest.raises(StopIteration):
next(x)
@pytest.mark.parametrize("protocol", range(pickle.HIGHEST_PROTOCOL + 1))
def test_pickle_missing(protocol: int) -> None:
"""Test that missing can be pickled while remaining a singleton."""
assert pickle.loads(pickle.dumps(missing, protocol)) is missing
def test_copy_missing() -> None:
"""Test that missing can be copied while remaining a singleton."""
assert copy.copy(missing) is missing
|