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 209 210 211 212 213 214 215 216 217 218
|
"""Tests for the plugin module."""
from __future__ import annotations
import functools
from typing import Literal
import pytest
from mkdocs.config.defaults import MkDocsConfig
from mkdocs.theme import Theme
from mkdocs_autorefs import AutorefsConfig, AutorefsPlugin, fix_refs
from tests.helpers import create_page
def test_url_registration() -> None:
"""Check that URLs can be registered, then obtained."""
plugin = AutorefsPlugin()
plugin.register_anchor(identifier="foo", page=create_page("foo1.html"), primary=True)
plugin.register_url(identifier="bar", url="https://example.org/bar.html")
assert plugin.get_item_url("foo") == ("foo1.html#foo", None)
assert plugin.get_item_url("bar") == ("https://example.org/bar.html", None)
with pytest.raises(KeyError):
plugin.get_item_url("baz")
def test_url_registration_with_from_url() -> None:
"""Check that URLs can be registered, then obtained, relative to a page."""
plugin = AutorefsPlugin()
plugin.register_anchor(identifier="foo", page=create_page("foo1.html"), primary=True)
plugin.register_url(identifier="bar", url="https://example.org/bar.html")
assert plugin.get_item_url("foo", from_url="a/b.html") == ("../foo1.html#foo", None)
assert plugin.get_item_url("bar", from_url="a/b.html") == ("https://example.org/bar.html", None)
with pytest.raises(KeyError):
plugin.get_item_url("baz", from_url="a/b.html")
# YORE: Bump 2: Remove block.
def test_url_registration_with_fallback() -> None:
"""Check that URLs can be registered, then obtained through a fallback."""
plugin = AutorefsPlugin()
plugin.register_anchor(identifier="foo", page=create_page("foo1.html"), primary=True)
plugin.register_url(identifier="bar", url="https://example.org/bar.html")
# URL map will be updated with baz -> foo1.html#foo
assert plugin.get_item_url("baz", fallback=lambda _: ("foo",)) == ("foo1.html#foo", None)
# as expected, baz is now known as foo1.html#foo
assert plugin.get_item_url("baz", fallback=lambda _: ("bar",)) == ("foo1.html#foo", None)
# unknown identifiers correctly fallback: qux -> https://example.org/bar.html
assert plugin.get_item_url("qux", fallback=lambda _: ("bar",)) == ("https://example.org/bar.html", None)
with pytest.raises(KeyError):
plugin.get_item_url("foobar", fallback=lambda _: ("baaaa",))
with pytest.raises(KeyError):
plugin.get_item_url("foobar", fallback=lambda _: ())
def test_dont_make_relative_urls_relative_again() -> None:
"""Check that URLs are not made relative more than once."""
plugin = AutorefsPlugin()
plugin.register_anchor(identifier="foo.bar.baz", page=create_page("foo/bar/baz.html"), primary=True)
for _ in range(2):
assert plugin.get_item_url("foo.bar.baz", from_url="baz/bar/foo.html") == (
"../../foo/bar/baz.html#foo.bar.baz",
None,
)
@pytest.mark.parametrize(
("base", "urls", "expected"),
[
# One URL is closest.
("", ["x/#b", "#b"], "#b"),
# Several URLs are equally close.
("a/b", ["x/#e", "a/c/#e", "a/d/#e"], "a/c/#e"),
("a/b/", ["x/#e", "a/d/#e", "a/c/#e"], "a/d/#e"),
# Two close URLs, one is shorter (closer).
("a/b", ["x/#e", "a/c/#e", "a/c/d/#e"], "a/c/#e"),
("a/b/", ["x/#e", "a/c/d/#e", "a/c/#e"], "a/c/#e"),
# Deeper-nested URLs.
("a/b/c", ["x/#e", "a/#e", "a/b/#e", "a/b/c/#e", "a/b/c/d/#e"], "a/b/c/#e"),
("a/b/c/", ["x/#e", "a/#e", "a/b/#e", "a/b/c/d/#e", "a/b/c/#e"], "a/b/c/#e"),
# No closest URL, use first one even if longer distance.
("a", ["b/c/#d", "c/#d"], "b/c/#d"),
("a/", ["c/#d", "b/c/#d"], "c/#d"),
],
)
def test_find_closest_url(base: str, urls: list[str], expected: str) -> None:
"""Find closest URLs given a list of URLs."""
assert AutorefsPlugin._get_closest_url(base, urls, "test") == expected
def test_register_secondary_url() -> None:
"""Test registering secondary URLs."""
plugin = AutorefsPlugin()
plugin.register_anchor(identifier="foo", page=create_page("foo.html"), primary=False)
assert plugin._secondary_url_map == {"foo": ["foo.html#foo"]}
@pytest.mark.parametrize("primary", [True, False])
def test_warn_multiple_urls(caplog: pytest.LogCaptureFixture, primary: bool) -> None:
"""Warn when multiple URLs are found for the same identifier."""
plugin = AutorefsPlugin()
plugin.config = AutorefsConfig()
plugin.register_anchor(identifier="foo", page=create_page("foo.html"), primary=primary)
plugin.register_anchor(identifier="foo", page=create_page("bar.html"), primary=primary)
url_mapper = functools.partial(plugin.get_item_url, from_url="/hello")
# YORE: Bump 2: Replace `, _legacy_refs=False` with `` within line.
fix_refs('<autoref identifier="foo">Foo</autoref>', url_mapper, _legacy_refs=False)
qualifier = "primary" if primary else "secondary"
assert (f"Multiple {qualifier} URLs found for 'foo': ['foo.html#foo', 'bar.html#foo']" in caplog.text) is primary
@pytest.mark.parametrize("primary", [True, False])
def test_use_closest_url(caplog: pytest.LogCaptureFixture, primary: bool) -> None:
"""Use the closest URL when multiple URLs are found for the same identifier."""
plugin = AutorefsPlugin()
plugin.config = AutorefsConfig()
plugin.config.resolve_closest = True
plugin.register_anchor(identifier="foo", page=create_page("foo.html"), primary=primary)
plugin.register_anchor(identifier="foo", page=create_page("bar.html"), primary=primary)
url_mapper = functools.partial(plugin.get_item_url, from_url="/hello")
# YORE: Bump 2: Replace `, _legacy_refs=False` with `` within line.
fix_refs('<autoref identifier="foo">Foo</autoref>', url_mapper, _legacy_refs=False)
qualifier = "primary" if primary else "secondary"
assert f"Multiple {qualifier} URLs found for 'foo': ['foo.html#foo', 'bar.html#foo']" not in caplog.text
def test_on_config_hook() -> None:
"""Check that the `on_config` hook runs without issue."""
plugin = AutorefsPlugin()
plugin.config = AutorefsConfig()
plugin.on_config(config=MkDocsConfig())
def test_auto_link_titles_external() -> None:
"""Check that `link_titles` are made external when automatic and Material is detected."""
plugin = AutorefsPlugin()
plugin.config = AutorefsConfig()
plugin.config.link_titles = "auto"
config = MkDocsConfig()
config.theme = Theme(name="material", features=["navigation.instant.preview"])
plugin.on_config(config=config)
assert plugin._link_titles == "external"
def test_auto_link_titles() -> None:
"""Check that `link_titles` are made true when automatic and Material is not detected."""
plugin = AutorefsPlugin()
plugin.config = AutorefsConfig()
plugin.config.link_titles = "auto"
config = MkDocsConfig()
config.theme = Theme(name="material", features=[])
plugin.on_config(config=config)
assert plugin._link_titles is True
config.theme = Theme("mkdocs")
plugin.on_config(config=config)
assert plugin._link_titles is True
config.theme = Theme("readthedocs")
plugin.on_config(config=config)
assert plugin._link_titles is True
@pytest.mark.parametrize("link_titles", ["external", True, False])
def test_explicit_link_titles(link_titles: bool | Literal["external"]) -> None:
"""Check that explicit `link_titles` are kept unchanged."""
plugin = AutorefsPlugin()
plugin.config = AutorefsConfig()
plugin.config.link_titles = link_titles
plugin.on_config(config=MkDocsConfig())
assert plugin._link_titles is link_titles
def test_auto_strip_title_tags_false() -> None:
"""Check that `strip_title_tags` is made false when Material is detected."""
plugin = AutorefsPlugin()
plugin.config = AutorefsConfig()
plugin.config.strip_title_tags = "auto"
config = MkDocsConfig()
config.theme = Theme(name="material", features=["content.tooltips"])
plugin.on_config(config=config)
assert plugin._strip_title_tags is False
def test_auto_strip_title_tags_true() -> None:
"""Check that `strip_title_tags` are made true when automatic and Material is not detected."""
plugin = AutorefsPlugin()
plugin.config = AutorefsConfig()
plugin.config.strip_title_tags = "auto"
config = MkDocsConfig()
config.theme = Theme(name="material", features=[])
plugin.on_config(config=config)
assert plugin._strip_title_tags is True
config.theme = Theme("mkdocs")
plugin.on_config(config=config)
assert plugin._strip_title_tags is True
config.theme = Theme("readthedocs")
plugin.on_config(config=config)
assert plugin._strip_title_tags is True
@pytest.mark.parametrize("strip_title_tags", [True, False])
def test_explicit_strip_tags(strip_title_tags: bool) -> None:
"""Check that explicit `_strip_title_tags` are kept unchanged."""
plugin = AutorefsPlugin()
plugin.config = AutorefsConfig()
plugin.config.strip_title_tags = strip_title_tags
plugin.on_config(config=MkDocsConfig())
assert plugin._strip_title_tags is strip_title_tags
|