**New component:** - nexus/components/symbolic-debugger.js — Real-time debug overlay showing: - Active symbols with truth values (green=true, red=false) - FSM states for all registered agents - Reasoning paths with timestamps - Knowledge graph stats + mini visualization - Performance metrics (facts, rules, heap) **Features:** - Toggle with Ctrl+Shift+G - Auto-refresh every second when visible - Draggable overlay - Manual refresh button **Tests:** - tests/test_symbolic_debugger.js — 10 tests, all passing **Documentation:** - docs/symbolic-debugger.md — Usage guide Closes #871
96 lines
3.0 KiB
JavaScript
96 lines
3.0 KiB
JavaScript
/**
|
|
* Tests for SymbolicDebugger component (issue #871)
|
|
*/
|
|
|
|
import { SymbolicDebugger } from '../nexus/components/symbolic-debugger.js';
|
|
import { SymbolicEngine, AgentFSM, KnowledgeGraph } from '../nexus/symbolic-engine.js';
|
|
|
|
// Mock DOM for Node.js testing
|
|
if (typeof document === 'undefined') {
|
|
const mockElements = new Map();
|
|
|
|
global.document = {
|
|
createElement: (tag) => {
|
|
const el = {
|
|
tagName: tag,
|
|
style: {},
|
|
innerHTML: '',
|
|
children: [],
|
|
appendChild: function(child) { this.children.push(child); return child; },
|
|
prepend: function(child) { this.children.unshift(child); return child; },
|
|
querySelector: () => null,
|
|
querySelectorAll: () => [],
|
|
addEventListener: () => {},
|
|
setAttribute: () => {},
|
|
getAttribute: () => null,
|
|
};
|
|
return el;
|
|
},
|
|
body: {
|
|
appendChild: (el) => {
|
|
mockElements.set(el.id, el);
|
|
return el;
|
|
}
|
|
},
|
|
addEventListener: () => {},
|
|
getElementById: (id) => mockElements.get(id) || {
|
|
style: {},
|
|
innerHTML: '',
|
|
onclick: null,
|
|
addEventListener: () => {},
|
|
},
|
|
};
|
|
global.window = { SymbolicDebugger: null };
|
|
}
|
|
|
|
function assert(condition, message) {
|
|
if (!condition) {
|
|
console.error(`❌ FAILED: ${message}`);
|
|
process.exit(1);
|
|
}
|
|
console.log(`✔ PASSED: ${message}`);
|
|
}
|
|
|
|
console.log('--- Running Symbolic Debugger Tests ---');
|
|
|
|
// Test 1: Module exports
|
|
assert(typeof SymbolicDebugger === 'object', 'SymbolicDebugger exports an object');
|
|
assert(typeof SymbolicDebugger.init === 'function', 'SymbolicDebugger has init method');
|
|
assert(typeof SymbolicDebugger.show === 'function', 'SymbolicDebugger has show method');
|
|
assert(typeof SymbolicDebugger.hide === 'function', 'SymbolicDebugger has hide method');
|
|
assert(typeof SymbolicDebugger.toggle === 'function', 'SymbolicDebugger has toggle method');
|
|
assert(typeof SymbolicDebugger.update === 'function', 'SymbolicDebugger has update method');
|
|
|
|
// Test 2: Initial state
|
|
assert(SymbolicDebugger.isVisible() === false, 'Debugger starts hidden');
|
|
|
|
// Test 3: Engine integration (mock)
|
|
const mockEngine = {
|
|
facts: new Map([['energy', 75], ['stable', true]]),
|
|
rules: [{ condition: () => true, action: () => 'test' }],
|
|
reasoningLog: [
|
|
{ timestamp: Date.now(), rule: 'TestRule', outcome: 'TestOutcome' }
|
|
]
|
|
};
|
|
|
|
SymbolicDebugger.init({ engine: mockEngine });
|
|
assert(true, 'Debugger initializes with engine');
|
|
|
|
// Test 4: FSM integration
|
|
const mockFSM = { state: 'IDLE', transitions: { IDLE: [] } };
|
|
SymbolicDebugger.init({ engine: mockEngine, fsmRegistry: new Map([['Agent1', mockFSM]]) });
|
|
assert(true, 'Debugger initializes with FSM registry');
|
|
|
|
// Test 5: Knowledge Graph integration
|
|
const mockKG = {
|
|
nodes: new Map([
|
|
['A', { id: 'A', type: 'Agent' }],
|
|
['B', { id: 'B', type: 'Location' }]
|
|
]),
|
|
edges: [{ from: 'A', to: 'B', relation: 'AT' }]
|
|
};
|
|
SymbolicDebugger.init({ engine: mockEngine, knowledgeGraph: mockKG });
|
|
assert(true, 'Debugger initializes with Knowledge Graph');
|
|
|
|
console.log('--- All Symbolic Debugger Tests Passed ---');
|