fix: avoid unresolved reference false-positive for autorefs

This commit fixes validation reporting false unresolved-reference errors for Markdown links that are successfully resolved by autorefs. Validation now runs after pages render, so it uses the autorefs results from the current build state and emits one complete issue report for that state.

**Validation implementation summary:**

- Page rendering now returns the identifiers that autorefs resolved, alongside rendered output.
- Validation combines those resolutions with the source-page references and anchors; a reference resolved by autorefs is no longer reported as unresolved.
- The workflow tracks a generation for page content and navigation, so it waits for matching render results from every page before creating issues. This prevents validation from using stale render data or printing duplicate reports during incremental updates.
- Reference collection now follows the configured documentation directory, and tests cover reporting after rendering and a subsequent clean rebuild.

Signed-off-by: Timothée Mazzucotelli <dev@pawamoy.fr>
This commit is contained in:
Timothée Mazzucotelli
2026-08-13 12:11:48 +00:00
committed by GitHub
parent 21824d2aec
commit db4f8ef5dc
7 changed files with 486 additions and 50 deletions
+76
View File
@@ -0,0 +1,76 @@
# Copyright (c) 2025-2026 Zensical and contributors
# SPDX-License-Identifier: MIT
# All contributions are certified under the DCO
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
from __future__ import annotations
from typing import TYPE_CHECKING
import zensical
if TYPE_CHECKING:
from pathlib import Path
import pytest
def test_validation_reports_issues_after_rendering(
tmp_path: Path, capfd: pytest.CaptureFixture[str]
) -> None:
"""Validation reports source and autoref issues after page rendering."""
docs = tmp_path / "docs"
docs.mkdir()
(docs / "index.md").write_text(
"# Hello\n\n[normal](missing.md)\n\n[autoref][missing-id]\n",
encoding="utf-8",
)
(docs / "other.md").write_text("# Other\n", encoding="utf-8")
(tmp_path / "watched.md").write_text(
"# Watched support file\n", encoding="utf-8"
)
config = tmp_path / "zensical.toml"
config.write_text(
"""
[project]
site_name = "Test"
watch = ["watched.md"]
[project.validation]
unresolved_references = true
""".lstrip(),
encoding="utf-8",
)
zensical.build(str(config), {"clean": True, "strict": False})
captured = capfd.readouterr()
assert "page does not exist" in captured.err
assert "unresolved link reference" in captured.err
assert "2 issues found" in captured.err
assert captured.err.count("2 issues found") == 1
(docs / "index.md").write_text("# Hello\n", encoding="utf-8")
zensical.build(str(config), {"clean": True, "strict": False})
captured = capfd.readouterr()
assert "No issues found" in captured.err
assert "2 issues found" not in captured.err