Skip to content

[#140] Add a test that the documentation links resolve - #141

Merged
SkowronskiAndrew merged 1 commit into
mainfrom
issue140-doc-link-test
Sep 15, 2026
Merged

SkowronskiAndrew merged 1 commit into
mainfrom
issue140-doc-link-test

Conversation

@SkowronskiAndrew

Copy link
Copy Markdown
Collaborator

Summary

Fixes #140.

Nothing checked the documentation links, so broken ones accumulated. Cleaning up the schema docs in
#120 turned up nine pre-existing breakages: source paths that had moved (SQLite/SQLiteWriter.cs,
SQLite/Handler/MeshHandler.cs, Parsers/Models/BuildLayout.cs), a link to an IWriter interface
that no longer exists, anchors left behind when the per-command pages were split out
(unitydatatool.md#dump), three links with the wrong relative depth, and one missing its URL scheme.
Those matter more since #118 put Documentation/ in the release zip: someone reading the docs offline
from the zip cannot fall back to searching GitHub when a link dies.

This adds a test that walks the repository's markdown, resolves every relative target and every
anchor, and fails with the full list.

A test rather than a new workflow or a third-party action, because test.yml already runs
dotnet test on Linux, macOS and Windows for every PR — so this needs no CI changes at all — and
because it doubles as the local tool via dotnet test --filter DocumentationLinks. AGENTS.md
already instructs agents to run the test suite, so agents get the check without being told about it.
The repo has no package.json or lint infrastructure, and introducing a Node or Rust toolchain for
one check would be disproportionate.

Internal links only. 345 of the repo's 426 links are internal, and all nine breakages above were
internal, so this covers the whole observed failure mode while staying deterministic and offline.
External URLs need the network and produce false failures from rate limits and bot blocking, which
must never stand between a change and a merge. External link rot can be handled later by a scheduled
job if it becomes a problem.

Changes

One new file, UnityDataTool.Tests/DocumentationLinkTests.cs. No production code and no CI changes.

  • AllInternalLinksResolve walks every *.md in the repo except bin, obj, .git and Library
    (Unity's package cache, which is third-party markdown we do not maintain), and reports every
    unresolved target and anchor as file:line missing target|anchor <link>.
  • Fenced code blocks and inline code spans are skipped, so documented example commands and SQL are
    not mistaken for links.
  • Paths are compared against the real directory entries rather than with File.Exists, which is
    case-insensitive on Windows and macOS. A wrong-case link like ../Analyzer/resources/Init.sql
    passes locally and breaks only for Linux users; this catches it everywhere.
  • Anchors follow GitHub's slug rules. Two details are easy to get wrong and are pinned by unit tests:
    • Repeated headings get -1 / -2 suffixes. command-archive.md already has five Quick Reference and five Example headings, so a naive implementation would reject a legitimate
      #example-2.
    • Spaces become hyphens one for one rather than being collapsed, which is why the heading
      ## dangling_refs / dangling_refs_view anchors as #dangling_refs--dangling_refs_view — an
      anchor this repo genuinely used, and the evidence that settled the rule.
  • The test locates the repository root by walking up for UnityDataTools.sln and reports
    inconclusive rather than failing if it cannot, so a run from a packaged location does not break.

Testing

  • dotnet build -c Release — clean, 0 warnings. dotnet format whitespace --verify-no-changes
    reports nothing for the new file.
  • dotnet test -c Release — full suite green: 802 passed, 0 failed. The 13 new tests are
    AllInternalLinksResolve, 11 slug cases and the repeated-heading case; the link walk takes ~90 ms.
  • Verified the test actually catches the bugs it is meant to, rather than passing vacuously. With
    a temporary fixture page it detected exactly the five breakage classes from Analyzer: Init.sql schema comments never reach the produced database #120 — stale relative
    path, dead anchor, wrong relative depth, missing URL scheme, and case mismatch (caught on Windows)
    — while correctly accepting a valid path, a valid anchor, a #example-2 dedup anchor, a link to a
    directory, and an unreachable external URL, and while ignoring links inside inline code and fenced
    blocks. The fixture was removed afterwards.
  • Writing the test found one genuine bug in its own first draft: blanking inline code before
    computing slugs dropped the code text, so ## How \analyze` represents thisslugged ashow-represents-this`. The slug unit tests exist because of that.

🤖 Generated with Claude Code

Nothing checked the documentation links, so broken ones accumulated: the schema
docs cleanup in #120 turned up nine pre-existing breakages, including source
paths that had moved, anchors left behind when the per-command pages were split
out, and a link missing its URL scheme. These matter more since #118 put
Documentation/ in the release zip, where a reader cannot fall back to searching
GitHub.

The test walks the repository's markdown, resolves every relative target and
every anchor, and fails with the full list. It needs no CI changes because
test.yml already runs dotnet test on Linux, macOS and Windows, and it doubles as
the local tool via --filter DocumentationLinks.

Internal links only. External URLs need the network and produce false failures
from rate limits and bot blocking, which must not block a merge.

Paths are compared against the real directory entries rather than with
File.Exists, so a wrong-case link is caught on Windows and macOS too instead of
only breaking for Linux users.

Anchors follow GitHub's slug rules, including the -1/-2 suffixes for repeated
headings (command-archive.md has five "Example" headings) and the one-for-one
space-to-hyphen conversion that makes "dangling_refs / dangling_refs_view"
anchor as "dangling_refs--dangling_refs_view". Those rules are pinned by unit
tests, since they are the fiddly part.
@SkowronskiAndrew
SkowronskiAndrew merged commit ee162e1 into main Sep 15, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Documentation quality - add checks to detect broken links

1 participant