mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
79 lines
4.0 KiB
JavaScript
79 lines
4.0 KiB
JavaScript
// W4b acceptance tests: the bug wizard tells static from observed with real
|
|
// ingested traces and shows divergence as two lists, and the change view
|
|
// shows the blast radius with the ported risk rules.
|
|
// Run: node --test tests/scaffold/w4b.test.mjs
|
|
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { readFileSync, existsSync } from 'node:fs';
|
|
import { join, dirname, resolve } from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');
|
|
const read = (p) => readFileSync(join(ROOT, p), 'utf8');
|
|
|
|
test('AC1: risk rules and impact model are ported, bug paths exist', () => {
|
|
const rules = read('src/impact/risk-rules.ts');
|
|
assert.ok(rules.includes('CodeAtlasIDE'), 'Herkunftsnotiz fehlt in risk-rules');
|
|
for (const marker of ['perSymbolRisk', 'overallRisk', 'transitiveLoopDepth',
|
|
'unguardedRecursion', 'isEntryPoint']) {
|
|
assert.ok(rules.includes(marker), `risk-rules-Marker ${marker} fehlt`);
|
|
}
|
|
const model = read('src/impact/impact-model.ts');
|
|
assert.ok(model.includes('CodeAtlasIDE'), 'Herkunftsnotiz fehlt in impact-model');
|
|
for (const marker of ['mapChangeImpact', 'summaryTiles', 'narrative']) {
|
|
assert.ok(model.includes(marker), `impact-model-Marker ${marker} fehlt`);
|
|
}
|
|
const paths = read('src/traces/bug-paths.ts');
|
|
assert.ok(/staticOnly/.test(paths) && /runtimeOnly/.test(paths),
|
|
'Divergenz muss als zwei Listen existieren');
|
|
assert.ok(/truncated/.test(paths), 'Ketten-Kappung muss sichtbar sein');
|
|
assert.ok(existsSync(join(ROOT, 'src/impact/risk-rules.test.ts')),
|
|
'risk-rules-Tests fehlen');
|
|
const s = JSON.parse(read('verification/w1/scaffold.json'));
|
|
assert.ok(s.unitTests >= 340, `Unit-Suite muss >= 340 Tests fahren, war ${s.unitTests}`);
|
|
});
|
|
|
|
test('AC2/AC4: the bug wizard proves static vs observed live', () => {
|
|
const b = JSON.parse(read('verification/w4/bugwizard.json'));
|
|
assert.ok(b.staticChains >= 1, 'mindestens eine statische Kette');
|
|
assert.equal(b.observedPathShown, true, 'der beobachtete Pfad muss sichtbar sein');
|
|
assert.equal(b.observedCount, 3, 'count 3 aus dem Ingest');
|
|
assert.equal(b.observedLabel, 'smoke-run');
|
|
assert.ok(b.staticOnlyCount >= 1, 'erwartet-nie-beobachtet darf nicht leer sein');
|
|
assert.ok(b.runtimeOnlyCount >= 1, 'beobachtet-nicht-im-Index darf nicht leer sein');
|
|
assert.equal(b.noTracesHonest, true, 'ohne Traces muss der Wizard es sagen und anleiten');
|
|
assert.equal(b.hopClickNavigates, true);
|
|
assert.ok(b.port >= 4270, `Port >= 4270 erwartet, war ${b.port}`);
|
|
assert.equal(b.leftoverProcesses, 0);
|
|
});
|
|
|
|
test('AC3/AC4: the blast radius proves itself live', () => {
|
|
const i = JSON.parse(read('verification/w4/impact.json'));
|
|
assert.ok(i.directCount >= 1);
|
|
assert.ok(i.downstreamCount >= 1);
|
|
assert.ok(typeof i.endpointNamed === 'string' && i.endpointNamed.length > 0);
|
|
assert.ok(['low', 'medium', 'high'].includes(i.badge), `Badge unbekannt: ${i.badge}`);
|
|
assert.ok(typeof i.badgeRulesExplained === 'string' && i.badgeRulesExplained.length > 10,
|
|
'die Badge-Begruendung muss die erfuellten Regeln nennen');
|
|
assert.equal(i.narrativeEvidenceOk, true, 'jede Behauptung braucht Evidence');
|
|
assert.equal(i.invalidRefNoEngineCall, true, 'kaputter Ref darf keinen Engine-Call ausloesen');
|
|
assert.ok(i.tilesShown >= 5, `>= 5 Kacheln erwartet, war ${i.tilesShown}`);
|
|
});
|
|
|
|
test('AC5: net deny over the w4b click path', () => {
|
|
const nd = JSON.parse(read('verification/w4/netdeny-w4b.json'));
|
|
assert.equal(nd.outboundViolations, 0);
|
|
assert.ok(nd.samples >= 10);
|
|
assert.ok(/smoke-w4b/.test(nd.command));
|
|
});
|
|
|
|
test('AC6: wiring', () => {
|
|
const pkg = JSON.parse(read('package.json'));
|
|
assert.ok(pkg.scripts?.['smoke:w4b'], 'Script smoke:w4b fehlt');
|
|
assert.ok(existsSync(join(ROOT, 'tools/smoke-w4b.mjs')), 'tools/smoke-w4b.mjs fehlt');
|
|
const all = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };
|
|
for (const [name, version] of Object.entries(all)) {
|
|
assert.ok(!/[\^~><|*x]/.test(version), `${name} muss exakt gepinnt sein, war ${version}`);
|
|
}
|
|
});
|