test(engine): pin inspectRepo's multi-file loading through the real I/O path
Closes a real gap the order (20260818T132719Z) correctly identified even
though its diagnosis was wrong: every LINK-FILE-URL test fed `files` to
checkInternalLinks by hand, so nothing pinned that inspectRepo's own loading
loop (`tracked.filter(p => p.endsWith('.md'))`) actually reaches files other
than README.md. A future narrowing of that filter back to README-only would
have kept all 247 tests green.
Two new tests go through inspectRepo itself (git init + git add in a temp
dir, no commit — avoids the gitleaks pre-commit hook and unnecessary git
config). Verified red-then-green: temporarily replaced the loading loop with
an empty one, confirmed the leak-detection test failed with the exact
"did not fire" message, reverted, confirmed all 249 pass.
This crosses the file's stated "pure classifiers only, inspectRepo is
exercised live" boundary deliberately and narrowly, for the one behaviour an
external report specifically asked to see pinned through the ordinary
loading path rather than by feeding `files` directly.
This commit is contained in:
parent
5fe1743105
commit
1ee6cc28c6
1 changed files with 56 additions and 1 deletions
|
|
@ -7,7 +7,10 @@
|
|||
// They are the reason this gate has three outcomes instead of a boolean.
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { readFileSync, mkdtempSync, writeFileSync, mkdirSync, rmSync } from 'node:fs';
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
import {
|
||||
countCodepoints,
|
||||
normalizeRepoRef,
|
||||
|
|
@ -47,6 +50,7 @@ import {
|
|||
checkVerifyCommand,
|
||||
countTestFiles,
|
||||
codeLines,
|
||||
inspectRepo,
|
||||
} from './repo-standard-check.mjs';
|
||||
|
||||
const REGISTER = {
|
||||
|
|
@ -811,6 +815,57 @@ test('other schemes stay somebody else\'s to resolve', () => {
|
|||
assert.equal(checkInternalLinks({ files, present: ['README.md'] }).some((x) => x.code === 'LINK-FILE-URL'), false);
|
||||
});
|
||||
|
||||
// ------------------------------------------------- I/O shell: file loading
|
||||
//
|
||||
// Every test above feeds `files` to checkInternalLinks directly — deliberate,
|
||||
// per the file header: the I/O shell is exercised live, not unit-tested. One
|
||||
// exception, here: an order (`.claude`, 2026-08-18) diagnosed the file://
|
||||
// rule as dead because it believed inspectRepo only ever loads README.md —
|
||||
// wrong (git blame: every tracked .md file, since 2026-07-27, 816ba97) — but
|
||||
// its point about the TEST SUITE stood: feeding `files` by hand is exactly
|
||||
// the shortcut that would let every test above stay green while a real
|
||||
// narrowing of inspectRepo's `.filter((p) => p.endsWith('.md'))` silently
|
||||
// killed the rule in production. These two go through the real loading path.
|
||||
function tempGitRepo(files) {
|
||||
const dir = mkdtempSync(join(tmpdir(), 'repo-standard-io-'));
|
||||
execFileSync('git', ['init', '-q'], { cwd: dir });
|
||||
for (const [name, content] of Object.entries(files)) {
|
||||
const path = join(dir, name);
|
||||
mkdirSync(join(path, '..'), { recursive: true });
|
||||
writeFileSync(path, content);
|
||||
}
|
||||
execFileSync('git', ['add', '-A'], { cwd: dir });
|
||||
return dir;
|
||||
}
|
||||
|
||||
test('inspectRepo scans a file: leak in a non-README markdown file through the ordinary loading path', () => {
|
||||
const dir = tempGitRepo({
|
||||
'README.md': '# test\n',
|
||||
'docs/plan.md': '[notes](file:///Users/ktg/repos/x/notes.md)\n',
|
||||
});
|
||||
try {
|
||||
const result = inspectRepo(dir, 'llm-ingestion-pipeline-security', REGISTER, null, null, true);
|
||||
const hit = result.findings.find((f) => f.code === 'LINK-FILE-URL');
|
||||
assert.ok(hit, 'LINK-FILE-URL did not fire for a leak outside README.md');
|
||||
assert.match(hit.msg, /docs\/plan\.md:1/);
|
||||
} finally {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test('inspectRepo raises nothing when no file: leak exists anywhere', () => {
|
||||
const dir = tempGitRepo({
|
||||
'README.md': '# test\n',
|
||||
'docs/plan.md': 'no links here\n',
|
||||
});
|
||||
try {
|
||||
const result = inspectRepo(dir, 'llm-ingestion-pipeline-security', REGISTER, null, null, true);
|
||||
assert.equal(result.findings.some((f) => f.code === 'LINK-FILE-URL'), false);
|
||||
} finally {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
// -------------------------------------------------------------- tag integrity
|
||||
|
||||
// A lightweight tag is a branch-like ref: it can be moved to a different commit
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue