import { describe, it, expect, beforeEach, afterEach } from 'vitest' import { DiagramController } from '@diagram/controller' // Headless controller (no DOM host / Paper) exercises the graph-level logic. let ctrl: DiagramController beforeEach(() => { ctrl = new DiagramController(null) }) afterEach(() => { ctrl.dispose() }) describe('node lifecycle', () => { it('adds a node and selects it', () => { const node = ctrl.addNode('pump', 100, 100) expect(ctrl.graph.getElements().length).toBe(1) expect(ctrl.getSelection().map((c) => c.id)).toContain(node.id) }) it('edits properties through applyValues', () => { const node = ctrl.addNode('valve', 40, 40) ctrl.applyValues(node.id as string, { ...(node.get('values') as object), title: 'V-9', opening: 50 }) expect(node.attr('label/text')).toBe('V-9') expect((node.get('values') as Record).opening).toBe(50) }) it('deletes the selection', () => { const node = ctrl.addNode('tank', 40, 40) ctrl.select(node.id as string, false) ctrl.deleteSelected() expect(ctrl.graph.getElements().length).toBe(0) }) }) describe('undo / redo', () => { it('reverts and reapplies an add', () => { ctrl.addNode('pump', 0, 0) expect(ctrl.graph.getElements().length).toBe(1) ctrl.undo() expect(ctrl.graph.getElements().length).toBe(0) ctrl.redo() expect(ctrl.graph.getElements().length).toBe(1) }) }) describe('copy / paste', () => { it('duplicates selected nodes', () => { const node = ctrl.addNode('valve', 60, 60) ctrl.select(node.id as string, false) ctrl.duplicateSelected() expect(ctrl.graph.getElements().length).toBe(2) }) }) describe('flow', () => { it('solves and animates a seeded network, then stops', () => { ctrl.seedSample() const sol = ctrl.runFlow() expect(sol.edges.size).toBeGreaterThan(0) expect(sol.maxMagnitude).toBeGreaterThan(0) expect(ctrl.isFlowing()).toBe(true) ctrl.stopFlow() expect(ctrl.isFlowing()).toBe(false) }) }) describe('serialization', () => { it('round-trips the whole diagram including settings', () => { ctrl.seedSample() ctrl.setSettings({ jumpover: false, colorScheme: 'colorblind' }) const json = ctrl.toJSON() const nElements = ctrl.graph.getElements().length const ctrl2 = new DiagramController(null) ctrl2.loadJSON(json) expect(ctrl2.graph.getElements().length).toBe(nElements) expect(ctrl2.settings.colorScheme).toBe('colorblind') expect(ctrl2.settings.jumpover).toBe(false) ctrl2.dispose() }) })