1import importlib.resources
2from xml.etree import ElementTree
3
4from absl.testing import absltest, parameterized
5
6from sphinxdocs.tests import sphinx_stardoc
7
8
9class SphinxOutputTest(parameterized.TestCase):
10    def setUp(self):
11        super().setUp()
12        self._docs = {}
13        self._xmls = {}
14
15    def assert_xref(self, doc, *, text, href):
16        match = self._doc_element(doc).find(f".//*[.='{text}']")
17        if not match:
18            self.fail(f"No element found with {text=}")
19        actual = match.attrib.get("href", "<UNSET>")
20        self.assertEqual(
21            href,
22            actual,
23            msg=f"Unexpected href for {text=}: "
24            + ElementTree.tostring(match).decode("utf8"),
25        )
26
27    def _read_doc(self, doc):
28        doc += ".html"
29        if doc not in self._docs:
30            self._docs[doc] = (
31                importlib.resources.files(sphinx_stardoc)
32                .joinpath("docs/_build/html")
33                .joinpath(doc)
34                .read_text()
35            )
36        return self._docs[doc]
37
38    def _doc_element(self, doc):
39        xml = self._read_doc(doc)
40        if doc not in self._xmls:
41            self._xmls[doc] = ElementTree.fromstring(xml)
42        return self._xmls[doc]
43
44    @parameterized.named_parameters(
45        # fmt: off
46        ("short_func", "myfunc", "function.html#myfunc"),
47        ("short_func_arg", "myfunc.arg1", "function.html#myfunc.arg1"),
48        ("short_rule", "my_rule", "rule.html#my_rule"),
49        ("short_rule_attr", "my_rule.ra1", "rule.html#my_rule.ra1"),
50        ("short_provider", "LangInfo", "provider.html#LangInfo"),
51        ("short_tag_class", "myext.mytag", "module_extension.html#myext.mytag"),
52        ("full_norepo_func", "//lang:function.bzl%myfunc", "function.html#myfunc"),
53        ("full_norepo_func_arg", "//lang:function.bzl%myfunc.arg1", "function.html#myfunc.arg1"),
54        ("full_norepo_rule", "//lang:rule.bzl%my_rule", "rule.html#my_rule"),
55        ("full_norepo_rule_attr", "//lang:rule.bzl%my_rule.ra1", "rule.html#my_rule.ra1"),
56        ("full_norepo_provider", "//lang:provider.bzl%LangInfo", "provider.html#LangInfo"),
57        ("full_norepo_aspect", "//lang:aspect.bzl%myaspect", "aspect.html#myaspect"),
58        ("full_norepo_target", "//lang:relativetarget", "target.html#relativetarget"),
59        ("full_repo_func", "@testrepo//lang:function.bzl%myfunc", "function.html#myfunc"),
60        ("full_repo_func_arg", "@testrepo//lang:function.bzl%myfunc.arg1", "function.html#myfunc.arg1"),
61        ("full_repo_rule", "@testrepo//lang:rule.bzl%my_rule", "rule.html#my_rule"),
62        ("full_repo_rule_attr", "@testrepo//lang:rule.bzl%my_rule.ra1", "rule.html#my_rule.ra1"),
63        ("full_repo_provider", "@testrepo//lang:provider.bzl%LangInfo", "provider.html#LangInfo"),
64        ("full_repo_aspect", "@testrepo//lang:aspect.bzl%myaspect", "aspect.html#myaspect"),
65        ("full_repo_target", "@testrepo//lang:relativetarget", "target.html#relativetarget"),
66        # fmt: on
67    )
68    def test_xrefs(self, text, href):
69        self.assert_xref("xrefs", text=text, href=href)
70
71
72if __name__ == "__main__":
73    absltest.main()
74