Files
dev-intel-v2/test/test-subsystem.js

110 lines
5.2 KiB
JavaScript
Raw Permalink Normal View History

const fs = require('fs');
const path = require('path');
const GraphStore = require('../graph.js');
const { buildSubsystems } = require('../subsystem.js');
const FIXTURE_DIR = path.join(__dirname, 'fixtures/system-docs');
const SNAPSHOT = path.join(FIXTURE_DIR, 'snapshot.json');
let passed = 0;
let failed = 0;
function assert(condition, name) {
if (condition) { passed++; console.log(`${name}`); }
else { failed++; console.log(`${name}`); }
}
// Load graph and run subsystem aggregator
const graph = GraphStore.loadSnapshot(SNAPSHOT);
const result = buildSubsystems(graph, { minTraffic: 3, crossCuttingThreshold: 0.6 });
const expected = JSON.parse(fs.readFileSync(path.join(FIXTURE_DIR, 'expected-subsystems.json'), 'utf8'));
console.log('=== 7A: Subsystem Aggregator Tests ===\n');
// Test 1: Directory clustering — correct number of subsystems
console.log('Test 1: Directory clustering');
assert(result.subsystems.length === 5, `Found 5 subsystems (got ${result.subsystems.length})`);
const names = result.subsystems.map(s => s.name).sort();
assert(JSON.stringify(names) === JSON.stringify(['agents', 'channels', 'config', 'gateway', 'utils']),
`Subsystem names match: ${names.join(', ')}`);
// Test 2: File assignment accuracy
console.log('\nTest 2: File assignment accuracy');
let correctFiles = 0;
let totalFiles = 0;
for (const expSub of expected.subsystems) {
const actualSub = result.subsystems.find(s => s.name === expSub.name);
assert(!!actualSub, `Subsystem "${expSub.name}" exists`);
if (actualSub) {
for (const f of expSub.files) {
totalFiles++;
if (actualSub.files.includes(f)) correctFiles++;
else console.log(` MISSING: ${f} in ${expSub.name}`);
}
}
}
const accuracy = totalFiles > 0 ? (correctFiles / totalFiles * 100).toFixed(1) : 0;
assert(correctFiles / totalFiles >= 0.9, `File assignment accuracy ≥90% (${accuracy}%, ${correctFiles}/${totalFiles})`);
// Test 3: Cross-cutting detection
console.log('\nTest 3: Cross-cutting detection');
assert(result.crossCutting.includes('utils'), 'utils detected as cross-cutting');
assert(result.crossCutting.includes('config'), 'config detected as cross-cutting');
assert(!result.crossCutting.includes('gateway'), 'gateway is NOT cross-cutting');
assert(!result.crossCutting.includes('agents'), 'agents is NOT cross-cutting');
assert(!result.crossCutting.includes('channels'), 'channels is NOT cross-cutting');
// Verify kind field matches
for (const expSub of expected.subsystems) {
const actualSub = result.subsystems.find(s => s.name === expSub.name);
if (actualSub) {
assert(actualSub.kind === expSub.kind, `${expSub.name} kind="${actualSub.kind}" (expected "${expSub.kind}")`);
}
}
// Test 4: Dependency matrix — key edges exist
console.log('\nTest 4: Dependency matrix');
const dm = result.dependencyMatrix;
assert('gateway→agents' in dm, 'gateway→agents edge exists');
assert('agents→gateway' in dm, 'agents→gateway edge exists (circular dep)');
assert('channels→gateway' in dm, 'channels→gateway edge exists');
assert('gateway→config' in dm, 'gateway→config edge exists');
assert('agents→utils' in dm, 'agents→utils edge exists');
assert('channels→utils' in dm, 'channels→utils edge exists');
// Test 5: Empty subsystem handling (channels has only 2 files, no internal CALLS)
console.log('\nTest 5: Edge cases');
const channelsSub = result.subsystems.find(s => s.name === 'channels');
assert(channelsSub && channelsSub.files.length === 2, `channels has 2 files (got ${channelsSub?.files.length})`);
// Orphan file: config/schema.ts should still be in config subsystem
const configSub = result.subsystems.find(s => s.name === 'config');
assert(configSub && configSub.files.includes('config/schema.ts'), 'Orphan config/schema.ts assigned to config');
// Test 6: Public exports populated
console.log('\nTest 6: Public exports');
const gatewaySub = result.subsystems.find(s => s.name === 'gateway');
assert(gatewaySub.publicExports.includes('handleRequest'), 'gateway exports handleRequest');
assert(gatewaySub.publicExports.includes('loadSession'), 'gateway exports loadSession');
const agentsSub = result.subsystems.find(s => s.name === 'agents');
assert(agentsSub.publicExports.includes('runAgent'), 'agents exports runAgent');
// Test 7: Run on OpenClaw full snapshot (performance)
console.log('\nTest 7: OpenClaw full snapshot');
const fullSnap = path.join(__dirname, '..', 'snapshots', 'openclaw-full.json');
if (fs.existsSync(fullSnap)) {
const start = Date.now();
const fullGraph = GraphStore.loadSnapshot(fullSnap);
const fullResult = buildSubsystems(fullGraph);
const elapsed = Date.now() - start;
assert(fullResult.subsystems.length > 10, `OpenClaw has >10 subsystems (got ${fullResult.subsystems.length})`);
assert(elapsed < 5000, `Completed in <5s (${elapsed}ms)`);
assert(fullResult.crossCutting.length > 0, `Detected cross-cutting subsystems: ${fullResult.crossCutting.join(', ')}`);
console.log(` OpenClaw: ${fullResult.subsystems.length} subsystems, ${Object.keys(fullResult.dependencyMatrix).length} dep edges, ${elapsed}ms`);
} else {
console.log(' (skipped — openclaw-full.json not found)');
}
console.log(`\n=== Results: ${passed} passed, ${failed} failed ===`);
process.exit(failed > 0 ? 1 : 0);