fix(okr): okf-index saner title/desc + escape klammer + skip innboks/dot (SC index-integritet)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012HzGPGJ81k1BkUC6UvgX4Y
This commit is contained in:
parent
3b45be70be
commit
dec8a13952
2 changed files with 88 additions and 4 deletions
|
|
@ -65,6 +65,16 @@ function allDirs(root) {
|
|||
return out;
|
||||
}
|
||||
|
||||
// Byte-snapshot av alle index.md under root (for idempotens-sammenligning).
|
||||
function snapshotIndexes(root) {
|
||||
return allDirs(root)
|
||||
.map((d) => join(d, 'index.md'))
|
||||
.filter((p) => existsSync(p))
|
||||
.sort()
|
||||
.map((p) => `${p}\n${readFileSync(p, 'utf8')}`)
|
||||
.join('\n=====\n');
|
||||
}
|
||||
|
||||
// --- okf-index ---
|
||||
|
||||
test('okf-index: genererer index.md per nivaa (hver katalog) i temp-kopi', () => {
|
||||
|
|
@ -254,3 +264,49 @@ test('okf-check: raa filer i innboks/ og .cache/ ignoreres av walk (ingen falsk
|
|||
rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
// --- okf-index herding (Step 9): saner title/desc + skip innboks/dot ---
|
||||
|
||||
test('okf-index: tittel/beskrivelse med ]/) + lenke saneres -> 2x byte-identisk + round-trip-trygg', () => {
|
||||
const dir = tmpRoot();
|
||||
try {
|
||||
mkdirSync(join(dir, 'dokumenter'), { recursive: true });
|
||||
writeFileSync(join(dir, 'index.md'), '# Bundle\n\nokf_version: kb-layout-2026-06\n');
|
||||
writeFileSync(
|
||||
join(dir, 'dokumenter', 'kr.md'),
|
||||
'---\ntype: OKR\ntitle: "KR1 [resultat] (maal) [lenke](http://x)"\n'
|
||||
+ 'description: "Status (delvis) [ref](http://y)"\n---\n# KR\n',
|
||||
);
|
||||
generateIndexes(dir);
|
||||
const run1 = snapshotIndexes(dir);
|
||||
generateIndexes(dir);
|
||||
const run2 = snapshotIndexes(dir);
|
||||
assert.equal(run1, run2, 'generateIndexes skal vaere byte-idempotent');
|
||||
const idx = readFileSync(join(dir, 'dokumenter', 'index.md'), 'utf8');
|
||||
const entry = idx.split('\n').find((l) => l.startsWith('* '));
|
||||
assert.ok(entry, 'kr.md skal ha en entry');
|
||||
assert.match(entry, /^\* \[[^\]]*\]\([^)]+\)/, 'entry skal vaere round-trip-trygg OKF-form');
|
||||
assert.ok(!entry.includes('http'), 'injisert lenke skal vaere noytralisert');
|
||||
} finally {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test('okf-index: innboks/ + dot-katalog -> ingen egen index.md OG ikke listet i rot-index', () => {
|
||||
const dir = tmpRoot();
|
||||
try {
|
||||
cpSync(REALISTIC, dir, { recursive: true });
|
||||
mkdirSync(join(dir, 'innboks'), { recursive: true });
|
||||
mkdirSync(join(dir, '.cache'), { recursive: true });
|
||||
writeFileSync(join(dir, 'innboks', 'raa.md'), '# Raa\n');
|
||||
writeFileSync(join(dir, '.cache', 'c.md'), '# Cache\n');
|
||||
generateIndexes(dir);
|
||||
assert.ok(!existsSync(join(dir, 'innboks', 'index.md')), 'innboks/ skal ikke faa index.md');
|
||||
assert.ok(!existsSync(join(dir, '.cache', 'index.md')), 'dot-katalog skal ikke faa index.md');
|
||||
const root = readFileSync(join(dir, 'index.md'), 'utf8');
|
||||
assert.ok(!root.includes('innboks/index.md'), 'rot-index skal ikke liste innboks/ som peker');
|
||||
assert.ok(!root.includes('.cache/index.md'), 'rot-index skal ikke liste dot-katalog som peker');
|
||||
} finally {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue