const fs = require('fs'); const path = require('path'); const GraphStore = require('../graph.js'); const { buildSubsystems } = require('../subsystem.js'); const { buildFlowIndex, traceFlow } = require('../flow.js'); const { generateDependencyDiagram, generateFlowDiagram, generateContractDiagram } = require('../diagrams.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}`); } } const graph = GraphStore.loadSnapshot(SNAPSHOT); const subs = buildSubsystems(graph, { minTraffic: 3, crossCuttingThreshold: 0.6 }); const index = buildFlowIndex(graph, subs); console.log('=== 7E: Diagram Generator Tests ===\n'); // Test 1: Dependency diagram valid Mermaid console.log('Test 1: Dependency diagram'); const depDiag = generateDependencyDiagram(subs); assert(depDiag.startsWith('graph TD'), 'Starts with graph TD'); assert(depDiag.includes('gateway'), 'Contains gateway node'); assert(depDiag.includes('-->'), 'Contains edges'); assert(depDiag.includes('shared'), 'Contains shared class for cross-cutting'); assert(!depDiag.includes('undefined'), 'No undefined values'); // Test 2: Flow sequence diagram console.log('\nTest 2: Flow sequence diagram'); const flow = traceFlow('channels/telegram.ts:onTelegramMessage', index); const flowDiag = generateFlowDiagram(flow); assert(flowDiag.startsWith('sequenceDiagram'), 'Starts with sequenceDiagram'); assert(flowDiag.includes('participant channels'), 'Has channels participant'); assert(flowDiag.includes('->>'), 'Has message arrows'); assert(!flowDiag.includes('undefined'), 'No undefined values'); // Test 3: Contract class diagram console.log('\nTest 3: Contract class diagram'); const contracts = JSON.parse(fs.readFileSync(path.join(FIXTURE_DIR, 'expected-contracts.json'), 'utf8')); const contractDiag = generateContractDiagram(contracts.contracts); assert(contractDiag.startsWith('classDiagram'), 'Starts with classDiagram'); assert(contractDiag.includes('GatewayConfig'), 'Contains GatewayConfig'); assert(contractDiag.includes('BaseConfig <|-- GatewayConfig'), 'Contains extends relationship'); assert(contractDiag.includes('<>'), 'Contains enum'); assert(contractDiag.includes('LogLevel'), 'Contains LogLevel enum'); assert(!contractDiag.includes('undefined'), 'No undefined values'); // Test 4: Empty inputs console.log('\nTest 4: Edge cases'); const emptyDeps = generateDependencyDiagram({ subsystems: [], crossCutting: [], dependencyMatrix: {} }); assert(emptyDeps === 'graph TD\n classDef shared fill:#f9f,stroke:#333,stroke-dasharray: 5 5', 'Empty dep diagram is valid'); const emptyFlow = generateFlowDiagram({ flow: [], subsystemSequence: [], cyclesDetected: [] }); assert(emptyFlow === 'sequenceDiagram', 'Empty flow diagram is valid'); const emptyContracts = generateContractDiagram([]); assert(emptyContracts === 'classDiagram', 'Empty contract diagram is valid'); console.log(`\n=== Results: ${passed} passed, ${failed} failed ===`); process.exit(failed > 0 ? 1 : 0);