repo-mailbox/tests/tracked-terms.test.mjs
Kjell Tore Guttormsen 1f17b67ed7
chore: remove dead references to a retired repository
Two tracked lines named a repository that no longer exists: a CLAUDE.md
paragraph on nested-repo admission and a board-selftest section-31
comment. Both are reworded without the name; behaviour is unchanged.

tests/tracked-terms.test.mjs is the check: it fails when any tracked
path or line matches a term in the untracked
tests/excluded-terms.local.md (covered by *.local.md), verifies every
term against a known-positive sample first, and skips loudly when the
list is absent. Red on 4fd1955 with 2 hits, green after.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 15:13:58 +02:00

75 lines
3.1 KiB
JavaScript

// No tracked file may carry a term from a LOCAL, untracked term list - not in
// its content and not in its path. The list itself is deliberately kept out of
// the repository (tests/excluded-terms.local.md, covered by `*.local.md` in
// .gitignore): a check that spelled its own pattern out would be a tracked file
// carrying exactly what it forbids.
//
// Absent list = SKIPPED, loudly, never passed: a check that could not run must
// not read as a check that found nothing.
//
// Format: one case-insensitive regex per line; `#` lines and blank lines are
// ignored; `sample: <text>` lines are known-positive controls. Every sample
// must match some term and every term must be matched by some sample, so a
// term that can no longer find anything fails here instead of passing vacuously.
import { test } from 'node:test';
import assert from 'node:assert';
import { execFileSync } from 'node:child_process';
import { existsSync, readFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
const root = join(dirname(fileURLToPath(import.meta.url)), '..');
const listFile = join(root, 'tests', 'excluded-terms.local.md');
// Named exceptions: tracked path -> reason. Empty on purpose; an entry needs a
// stated reason, never a silent widening.
const EXEMPT = new Map();
function loadList() {
const terms = [];
const samples = [];
for (const raw of readFileSync(listFile, 'utf8').split('\n')) {
const line = raw.trim();
if (line === '' || line.startsWith('#')) continue;
if (line.startsWith('sample:')) samples.push(line.slice('sample:'.length).trim());
else terms.push(new RegExp(line, 'i'));
}
return { terms, samples };
}
function hitsIn(text, terms) {
return terms.filter((re) => re.test(text)).map((re) => re.source);
}
test('no tracked file carries a term from the local term list', (t) => {
if (!existsSync(listFile)) {
t.skip(`SKIPPED, not passed: ${listFile} is absent, so nothing was checked`);
return;
}
const { terms, samples } = loadList();
assert.ok(terms.length > 0, 'term list holds no terms');
// Known-positive controls, before anything depends on the matcher.
for (const s of samples) {
assert.ok(hitsIn(s, terms).length > 0, `control sample matches no term: ${s}`);
}
for (const re of terms) {
assert.ok(samples.some((s) => re.test(s)), `term /${re.source}/ has no matching sample`);
}
const files = execFileSync('git', ['ls-files', '-z'], { cwd: root, encoding: 'utf8' })
.split('\0')
.filter((p) => p !== '' && !EXEMPT.has(p));
assert.ok(files.length > 0, 'git ls-files listed no tracked files');
const found = [];
for (const path of files) {
for (const term of hitsIn(path, terms)) found.push(`${path} (path): /${term}/`);
const lines = readFileSync(join(root, path), 'latin1').split('\n');
lines.forEach((line, i) => {
for (const term of hitsIn(line, terms)) found.push(`${path}:${i + 1}: /${term}/`);
});
}
t.diagnostic(`scanned ${files.length} tracked files against ${terms.length} terms`);
assert.deepStrictEqual(found, [], `${found.length} hit(s):\n${found.join('\n')}`);
});