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);