diff --git a/tests/reference-integrity.test.mjs b/tests/reference-integrity.test.mjs index 25fcf86..98e0ae5 100644 --- a/tests/reference-integrity.test.mjs +++ b/tests/reference-integrity.test.mjs @@ -79,3 +79,41 @@ test('alle ${CLAUDE_PLUGIN_ROOT}-stier finnes paa disk', () => { } assert.deepEqual(missing, [], 'doede referanser funnet'); }); + +// 1.8.0 (En kanon): kanon-konsolideringen legger til NYE krysslenker mellom +// referansefiler (Steps 3/4/6/10/11). Denne casen fanger doede *relative* +// .md-lenker i skills/-treet - komplementaert til ${CLAUDE_PLUGIN_ROOT}- +// invariantene over. Kilder: SKILL.md (backtick `references/x.md` / `x.md`) +// + sibling-krysslenker (`x.md`) inni references/. Alle forventes aa peke +// paa en fil i references/ paa disk. +const REF_REL = join('skills', 'okr-offentlig-sektor', 'references'); +const REL_MD_RE = /`(?:references\/)?([a-z0-9-]+\.md)`/g; + +function collectSkillRelativeRefs() { + const refs = []; + const sources = [join('skills', 'okr-offentlig-sektor', 'SKILL.md')]; + for (const name of readdirSync(join(ROOT, REF_REL))) { + if (name.endsWith('.md')) sources.push(join(REF_REL, name)); + } + for (const file of sources) { + const body = readFileSync(join(ROOT, file), 'utf8'); + for (const m of body.matchAll(REL_MD_RE)) { + refs.push({ file, rel: join(REF_REL, m[1]) }); + } + } + return refs; +} + +test('SKILL.md + referansefil-krysslenker resolverer paa disk (relative .md)', () => { + const refs = collectSkillRelativeRefs(); + assert.ok(refs.length >= 15, `fant bare ${refs.length} relative refs (regex broken?)`); + const missing = []; + for (const { file, rel } of refs) { + try { + assertResolvable(rel); + } catch (e) { + missing.push(`${file} -> ${rel} (${e.message})`); + } + } + assert.deepEqual(missing, [], 'doede relative referanser i skills/-treet'); +});