Skip to content

Nothing checks that links inside a doc resolve — only reachability from docs/README.md #656

Description

@pal-tamas

DocsIndexTests guards that every doc under docs/ is reachable from docs/README.md, and GuidesTests guards GuideCatalog parity both ways. Neither checks that a link written inside a doc points at something that exists.

Two real misses, both caught by a person reading rather than by a test

  1. A dead anchor. docs/sqlite.md linked [Where OPFS fits](#rasksqlitebrowser--keeping-a-browser-database) while "Where OPFS fits" was bold text, not a heading — so it had no anchor and the link silently landed the reader at the top of the section. Nothing looked broken, which is the worst kind of broken link.
  2. A link to a file that does not exist yet. docs/sync.md (feat(sync): add Rask.Sync, the merge engine offline-first sync rests on #654) cross-linked object-storage.md, which lives in the still-unmerged feat(objectstore): add Rask.ObjectStore, an S3 and Azure Blob client with no cloud SDK #653. Had the merge order gone the other way it would have shipped a 404. I removed the links rather than make the doc depend on merge order, which is a workaround, not a fix — the next person writing a doc across two PRs has no reason to think of it.

Both are the same class: the docs are the product's front door and these are exactly the failures a reader hits first.

What a guard would need to cover

  • Relative *.md links resolve to a file that exists. Note these are rewritten at render time to SPA routes (Markdown.RewriteLinks/guides/{leaf}), so the check belongs on the source text, and a link to a doc that exists but is not in GuideCatalog renders as a route that 404s — worth failing on too.
  • In-page anchors (#…) resolve to a heading in the target document, including cross-document other.md#section. This is the one that caught nobody, because a wrong anchor still navigates.
  • Ignore external http(s) links: those need the network and would make the suite flaky for no benefit.

Where it belongs

Alongside DocsIndexTests in Rask.Example.Shared.Tests, which already enumerates docs/**/*.md on disk and already owns the reachability half. It is the same walk with a different assertion.

One interaction worth knowing: until the docs/ entry lands in the pre-commit filter (#652), a docs-only commit skips these tests entirely — so this guard and that filter fix are worth having together, or the new check will not run for precisely the commits that most need it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions