mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
77 lines
3.6 KiB
JavaScript
77 lines
3.6 KiB
JavaScript
// W2b acceptance tests: the semantic twin runs in the SPA with the reference
|
|
// project's honesty rules preserved, the cursor pipeline fills it without
|
|
// refetch storms, and the step badges stay in sync with the STEPS list.
|
|
// Run: node --test tests/scaffold/w2b.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: the twin layer is ported with provenance and fixture-proven', () => {
|
|
const files = [
|
|
'src/twin/render-model.ts',
|
|
'src/twin/twin-view-model.ts',
|
|
'src/twin/strings.ts',
|
|
'src/twin/presentation-profile.ts',
|
|
'src/twin/mini-understanding.ts',
|
|
'src/twin/hop-plan.ts',
|
|
'src/core/step-badge-decorator.ts',
|
|
];
|
|
for (const f of files) {
|
|
assert.ok(existsSync(join(ROOT, f)), `${f} fehlt`);
|
|
assert.ok(read(f).includes('CodeAtlasIDE'), `${f} braucht die Herkunftsnotiz`);
|
|
}
|
|
assert.ok(existsSync(join(ROOT, 'src/twin/render-model.test.ts')),
|
|
'render-model-Verhaltenstests fehlen');
|
|
const rm = read('src/twin/render-model.test.ts');
|
|
for (const marker of ['Nobody wrote that description', 'confidence', 'validateUser']) {
|
|
assert.ok(rm.includes(marker), `render-model-Test muss ${marker} pruefen`);
|
|
}
|
|
const fixtures = read('src/twin/render-model.test.ts') + (existsSync(join(ROOT, 'src/twin/__fixtures__/create-user-ir.json')) ? 'FIXTURE_OK' : '');
|
|
assert.ok(fixtures.includes('FIXTURE_OK'), 'create-user-ir.json-Fixture fehlt');
|
|
const s = JSON.parse(read('verification/w1/scaffold.json'));
|
|
assert.ok(s.unitTests >= 220, `Unit-Suite muss >= 220 Tests fahren, war ${s.unitTests}`);
|
|
assert.equal(s.unitExit, 0);
|
|
});
|
|
|
|
test('AC2/AC3/AC4: the live twin proof holds', () => {
|
|
const t = JSON.parse(read('verification/w2/twin.json'));
|
|
assert.ok(t.sectionsPopulated >= 5, `>= 5 Sections erwartet, war ${t.sectionsPopulated}`);
|
|
assert.equal(t.stepsCount, 6);
|
|
assert.equal(t.stepsOrdered, true);
|
|
assert.equal(t.firstStep, 'validateUser');
|
|
assert.equal(t.envReadShown, 'DB_URL');
|
|
assert.equal(t.throwShown, 'ValidationError');
|
|
assert.equal(t.missingTestsHonest, true,
|
|
'createUser muss die ehrliche Kein-Test-Aussage zeigen');
|
|
assert.equal(t.depthProseNoQualifiedNames, true);
|
|
assert.equal(t.depthDenseShowsConfidence, true);
|
|
assert.ok(t.badgeCount >= 3, `>= 3 Gutter-Badges erwartet, war ${t.badgeCount}`);
|
|
assert.equal(t.caretSyncNoRefetch, true, 'Caret-Sync darf keinen Refetch ausloesen');
|
|
assert.equal(t.followNavigatesEditor, true, 'Step-Klick muss den Editor bewegen');
|
|
assert.equal(t.evidenceVisible, true);
|
|
assert.ok(t.port >= 4240, `Port >= 4240 erwartet, war ${t.port}`);
|
|
assert.equal(t.leftoverProcesses, 0);
|
|
});
|
|
|
|
test('AC5: the twin click path ran under the net deny gate', () => {
|
|
const nd = JSON.parse(read('verification/w2/netdeny-w2b.json'));
|
|
assert.equal(nd.outboundViolations, 0);
|
|
assert.ok(nd.samples >= 10, `>= 10 Samples erwartet, war ${nd.samples}`);
|
|
assert.ok(/smoke-w2b/.test(nd.command));
|
|
});
|
|
|
|
test('AC6: wiring', () => {
|
|
const pkg = JSON.parse(read('package.json'));
|
|
assert.ok(pkg.scripts?.['smoke:w2b'], 'Script smoke:w2b fehlt');
|
|
assert.ok(existsSync(join(ROOT, 'tools/smoke-w2b.mjs')), 'tools/smoke-w2b.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}`);
|
|
}
|
|
});
|