fix(docs): page help buttons open the right topic + wiring guard

The Federation and Runs help buttons opened the architecture doc:
federation.md/runs.md existed as assets but had no _DocEntry, so
showFaiDoc resolved the unknown slug to _kDocs.first. Register both
(onWelcome: false, so they don't clutter the newcomer grid but are
reachable), split the Welcome grid onto the curated subset, and make
the unknown-slug fallback assert in debug instead of silently opening
the wrong topic.

Guard (no-bugfix-without-a-guard): doc_help_wiring_test.dart scans
lib/ for every showFaiDoc('slug') call and asserts each has a
registered entry AND both assets/docs/<slug>[_de].md files. Exposes
kKnownDocSlugs for the test.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
flemming-it 2026-07-20 02:00:56 +02:00
parent 588f437395
commit 5a3f00bb2c
7 changed files with 226 additions and 6 deletions

View file

@ -0,0 +1,70 @@
// Doc-help wiring guard a page help button must open the RIGHT
// topic. Every `showFaiDoc(context, '<slug>')` call in lib/ needs:
//
// 1. a registered _DocEntry (exposed as kKnownDocSlugs), and
// 2. the backing assets assets/docs/<slug>.md + <slug>_de.md.
//
// Without this, a slug with no entry silently fell back to the
// first doc ('architecture'): the Federation and Runs help buttons
// opened the architecture sheet even though federation.md/runs.md
// existed the author wrote the docs, set the icon, but never
// wired the catalog, and nothing caught it. This test catches that
// whole class (per the no-bugfix-without-a-guard rule).
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:chain_studio/pages/welcome.dart' show kKnownDocSlugs;
void main() {
final callSlugs = _showFaiDocSlugsInLib();
test('lib/ actually calls showFaiDoc somewhere (sanity)', () {
expect(
callSlugs,
isNotEmpty,
reason: 'no showFaiDoc calls found — did the scan regex go stale?',
);
});
test('every showFaiDoc slug is registered in the doc catalog', () {
final unregistered = callSlugs.difference(kKnownDocSlugs);
expect(
unregistered,
isEmpty,
reason:
'These slugs are opened by a help button but have no _DocEntry, '
'so they silently fall back to the wrong topic. Register them in '
'_kDocs (lib/pages/welcome.dart): $unregistered',
);
});
test('every registered doc slug has both locale assets', () {
final missing = <String>[];
for (final slug in kKnownDocSlugs) {
for (final path in ['assets/docs/$slug.md', 'assets/docs/${slug}_de.md']) {
if (!File(path).existsSync()) missing.add(path);
}
}
expect(
missing,
isEmpty,
reason: 'Registered doc slugs missing their markdown assets: $missing',
);
});
}
/// Scan lib/ for `showFaiDoc(context, 'slug')` and collect the slugs.
Set<String> _showFaiDocSlugsInLib() {
final re = RegExp(r'''showFaiDoc\(\s*context\s*,\s*['"]([a-z0-9_-]+)['"]''');
final slugs = <String>{};
final dir = Directory('lib');
for (final f in dir.listSync(recursive: true).whereType<File>()) {
if (!f.path.endsWith('.dart')) continue;
for (final m in re.allMatches(f.readAsStringSync())) {
slugs.add(m.group(1)!);
}
}
return slugs;
}