Coverage for tests/test_plugin.py: 100.00%
61 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-10 16:33 +0100
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-10 16:33 +0100
1"""Tests for the plugin module."""
3from __future__ import annotations
4import functools
6import pytest
8from mkdocs_autorefs.plugin import AutorefsPlugin, AutorefsConfig
9from mkdocs_autorefs.references import fix_refs
12def test_url_registration() -> None:
13 """Check that URLs can be registered, then obtained."""
14 plugin = AutorefsPlugin()
15 plugin.register_anchor(identifier="foo", page="foo1.html", primary=True)
16 plugin.register_url(identifier="bar", url="https://example.org/bar.html")
18 assert plugin.get_item_url("foo") == "foo1.html#foo"
19 assert plugin.get_item_url("bar") == "https://example.org/bar.html"
20 with pytest.raises(KeyError):
21 plugin.get_item_url("baz")
24def test_url_registration_with_from_url() -> None:
25 """Check that URLs can be registered, then obtained, relative to a page."""
26 plugin = AutorefsPlugin()
27 plugin.register_anchor(identifier="foo", page="foo1.html", primary=True)
28 plugin.register_url(identifier="bar", url="https://example.org/bar.html")
30 assert plugin.get_item_url("foo", from_url="a/b.html") == "../foo1.html#foo"
31 assert plugin.get_item_url("bar", from_url="a/b.html") == "https://example.org/bar.html"
32 with pytest.raises(KeyError):
33 plugin.get_item_url("baz", from_url="a/b.html")
36def test_url_registration_with_fallback() -> None:
37 """Check that URLs can be registered, then obtained through a fallback."""
38 plugin = AutorefsPlugin()
39 plugin.register_anchor(identifier="foo", page="foo1.html", primary=True)
40 plugin.register_url(identifier="bar", url="https://example.org/bar.html")
42 # URL map will be updated with baz -> foo1.html#foo
43 assert plugin.get_item_url("baz", fallback=lambda _: ("foo",)) == "foo1.html#foo"
44 # as expected, baz is now known as foo1.html#foo
45 assert plugin.get_item_url("baz", fallback=lambda _: ("bar",)) == "foo1.html#foo"
46 # unknown identifiers correctly fallback: qux -> https://example.org/bar.html
47 assert plugin.get_item_url("qux", fallback=lambda _: ("bar",)) == "https://example.org/bar.html"
49 with pytest.raises(KeyError):
50 plugin.get_item_url("foobar", fallback=lambda _: ("baaaa",))
51 with pytest.raises(KeyError):
52 plugin.get_item_url("foobar", fallback=lambda _: ())
55def test_dont_make_relative_urls_relative_again() -> None:
56 """Check that URLs are not made relative more than once."""
57 plugin = AutorefsPlugin()
58 plugin.register_anchor(identifier="foo.bar.baz", page="foo/bar/baz.html", primary=True)
60 for _ in range(2):
61 assert (
62 plugin.get_item_url("hello", from_url="baz/bar/foo.html", fallback=lambda _: ("foo.bar.baz",))
63 == "../../foo/bar/baz.html#foo.bar.baz"
64 )
67@pytest.mark.parametrize(
68 ("base", "urls", "expected"),
69 [
70 # One URL is closest.
71 ("", ["x/#b", "#b"], "#b"),
72 # Several URLs are equally close.
73 ("a/b", ["x/#e", "a/c/#e", "a/d/#e"], "a/c/#e"),
74 ("a/b/", ["x/#e", "a/d/#e", "a/c/#e"], "a/d/#e"),
75 # Two close URLs, one is shorter (closer).
76 ("a/b", ["x/#e", "a/c/#e", "a/c/d/#e"], "a/c/#e"),
77 ("a/b/", ["x/#e", "a/c/d/#e", "a/c/#e"], "a/c/#e"),
78 # Deeper-nested URLs.
79 ("a/b/c", ["x/#e", "a/#e", "a/b/#e", "a/b/c/#e", "a/b/c/d/#e"], "a/b/c/#e"),
80 ("a/b/c/", ["x/#e", "a/#e", "a/b/#e", "a/b/c/d/#e", "a/b/c/#e"], "a/b/c/#e"),
81 # No closest URL, use first one even if longer distance.
82 ("a", ["b/c/#d", "c/#d"], "b/c/#d"),
83 ("a/", ["c/#d", "b/c/#d"], "c/#d"),
84 ],
85)
86def test_find_closest_url(base: str, urls: list[str], expected: str) -> None:
87 """Find closest URLs given a list of URLs."""
88 assert AutorefsPlugin._get_closest_url(base, urls, "test") == expected
91def test_register_secondary_url() -> None:
92 """Test registering secondary URLs."""
93 plugin = AutorefsPlugin()
94 plugin.register_anchor(identifier="foo", page="foo.html", primary=False)
95 assert plugin._secondary_url_map == {"foo": ["foo.html#foo"]}
98def test_warn_multiple_urls(caplog: pytest.LogCaptureFixture) -> None:
99 """Warn when multiple URLs are found for the same identifier."""
100 plugin = AutorefsPlugin()
101 plugin.config = AutorefsConfig()
102 plugin.register_anchor(identifier="foo", page="foo.html", primary=True)
103 plugin.register_anchor(identifier="foo", page="bar.html", primary=True)
104 url_mapper = functools.partial(plugin.get_item_url, from_url="/hello")
105 fix_refs('<autoref identifier="foo">Foo</autoref>', url_mapper, _legacy_refs=False)
106 assert "Multiple primary URLs found for 'foo': ['foo.html#foo', 'bar.html#foo']" in caplog.text
109def test_use_closest_url(caplog: pytest.LogCaptureFixture) -> None:
110 """Use the closest URL when multiple URLs are found for the same identifier."""
111 plugin = AutorefsPlugin()
112 plugin.config = AutorefsConfig()
113 plugin.config.resolve_closest = True
114 plugin.register_anchor(identifier="foo", page="foo.html", primary=True)
115 plugin.register_anchor(identifier="foo", page="bar.html", primary=True)
116 url_mapper = functools.partial(plugin.get_item_url, from_url="/hello")
117 fix_refs('<autoref identifier="foo">Foo</autoref>', url_mapper, _legacy_refs=False)
118 assert "Multiple primary URLs found for 'foo': ['foo.html#foo', 'bar.html#foo']" not in caplog.text