Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-16 08:16:23

0001 #!/usr/bin/env python3
0002 """Self-tests for check_deprecated_docs.py.
0003 
0004 Guards the doc-block association heuristic (the only non-trivial part): walking
0005 up from a ``[[deprecated]]`` past declaration-prefix lines to the Doxygen block,
0006 and stopping at statement boundaries so an unrelated comment above is not
0007 mis-attributed.
0008 
0009 Run directly (``python3 CI/public_api/test_check_deprecated_docs.py``); non-zero exit on
0010 failure. Also collectable by pytest.
0011 """
0012 
0013 from __future__ import annotations
0014 
0015 import sys
0016 import tempfile
0017 from pathlib import Path
0018 
0019 HERE = Path(__file__).resolve().parent
0020 sys.path.insert(0, str(HERE))
0021 
0022 import check_deprecated_docs as cdd  # noqa: E402
0023 
0024 
0025 def _reasons(text: str) -> list[str]:
0026     """Run the checker over a single synthetic header, return violation reasons."""
0027     with tempfile.TemporaryDirectory() as d:
0028         repo = Path(d)
0029         hdr = repo / "Core" / "include" / "Acts" / "T.hpp"
0030         hdr.parent.mkdir(parents=True)
0031         hdr.write_text(text)
0032         vios = cdd.find_violations(repo, ["Core/include"])
0033         return [v["reason"] for v in vios]
0034 
0035 
0036 # --- doc_block_for association ---------------------------------------------
0037 
0038 
0039 def test_paired_simple_block():
0040     text = (
0041         "/// Does a thing.\n"
0042         "/// @deprecated Use bar() instead\n"
0043         '[[deprecated("Use bar() instead")]] void foo();\n'
0044     )
0045     assert _reasons(text) == [], "an adjacent @deprecated block should pair"
0046 
0047 
0048 def test_template_line_between_doc_and_attribute():
0049     text = (
0050         "/// Does a thing.\n"
0051         "/// @deprecated gone soon\n"
0052         "template <typename T>\n"
0053         '[[deprecated("gone soon")]] void foo();\n'
0054     )
0055     assert _reasons(text) == [], "template head between block and attr must be skipped"
0056 
0057 
0058 def test_backslash_command_form_accepted():
0059     text = "/// \\deprecated old\n[[deprecated]] void foo();\n"
0060     assert _reasons(text) == []
0061 
0062 
0063 def test_doc_block_without_command_is_violation():
0064     text = "/// Does a thing.\n[[deprecated]] void foo();\n"
0065     assert _reasons(text) == ["no-deprecated-tag"]
0066 
0067 
0068 def test_no_doc_block_is_violation():
0069     text = "int x = 0;\n\n[[deprecated]] void foo();\n"
0070     assert _reasons(text) == ["no-doc-block"]
0071 
0072 
0073 def test_previous_statement_not_mistaken_for_doc():
0074     # A @deprecated on the *previous* entity must not satisfy this one.
0075     text = (
0076         "/// @deprecated old one\n"
0077         '[[deprecated("old one")]] void a();\n'
0078         "\n"
0079         "[[deprecated]] void b();\n"
0080     )
0081     assert _reasons(text) == ["no-doc-block"], "b() is undocumented"
0082 
0083 
0084 def test_gnu_deprecated_attribute_recognised():
0085     text = "/// no tag here\n[[gnu::deprecated]] void foo();\n"
0086     assert _reasons(text) == ["no-deprecated-tag"]
0087 
0088 
0089 def test_copydoc_block_with_explicit_command_pairs():
0090     text = (
0091         "/// @copydoc Base::foo() const\n"
0092         "/// @deprecated Use the 2D overload instead\n"
0093         '[[deprecated("Use the 2D overload instead")]] void foo() const;\n'
0094     )
0095     assert _reasons(text) == []
0096 
0097 
0098 def _main() -> int:
0099     failures = 0
0100     for name, fn in sorted(globals().items()):
0101         if name.startswith("test_") and callable(fn):
0102             try:
0103                 fn()
0104                 print(f"ok   {name}")
0105             except AssertionError as e:
0106                 failures += 1
0107                 print(f"FAIL {name}: {e}")
0108     print(f"\n{failures} failure(s)")
0109     return 1 if failures else 0
0110 
0111 
0112 if __name__ == "__main__":
0113     sys.exit(_main())