/** * Stresstest – 50.000 Elemente: SpatialIndex Query-Performance, * HistoryManager Memory, Undo/Redo Performance. */ import { describe, it, expect } from 'vitest'; import { SpatialIndex } from '../src/canvas/SpatialIndex'; import { HistoryManager } from '../src/history/HistoryManager'; import type { CADElement, CADLayer } from '../src/types/cad.types'; const N = 50_000; function generateElements(count: number): CADElement[] { const elements: CADElement[] = []; for (let i = 0; i < count; i++) { elements.push({ id: `elem-${i}`, type: 'rect', layerId: 'layer-1', x: (i % 1000) * 1.5, y: Math.floor(i / 1000) * 1.5, width: 1, height: 1, properties: {}, }); } return elements; } function makeLayer(): CADLayer { return { id: 'layer-1', name: 'Layer 1', visible: true, locked: false, color: '#ffffff', lineType: 'solid', transparency: 0, sortOrder: 0, parentId: null, }; } describe('Stresstest: 50.000 Elemente', () => { it('should bulk-insert 50k elements into SpatialIndex in under 2s', () => { const elements = generateElements(N); const index = new SpatialIndex(); const start = performance.now(); index.bulkInsert(elements); const elapsed = performance.now() - start; console.log(`SpatialIndex bulkInsert: ${elapsed.toFixed(1)}ms for ${N} elements`); expect(elapsed).toBeLessThan(2000); }); it('should search SpatialIndex with 50k elements in under 10ms', () => { const elements = generateElements(N); const index = new SpatialIndex(); index.bulkInsert(elements); // Search a region in the middle const start = performance.now(); const results = index.search({ minX: 750, minY: 37.5, maxX: 1500, maxY: 75 }); const elapsed = performance.now() - start; console.log(`SpatialIndex search: ${elapsed.toFixed(2)}ms, found ${results.length} elements`); expect(elapsed).toBeLessThan(50); expect(results.length).toBeGreaterThan(0); }); it('should search a small point region with 50k elements in under 5ms', () => { const elements = generateElements(N); const index = new SpatialIndex(); index.bulkInsert(elements); const start = performance.now(); const results = index.search({ minX: 750, minY: 37.5, maxX: 751, maxY: 38.5 }); const elapsed = performance.now() - start; console.log(`SpatialIndex point search: ${elapsed.toFixed(3)}ms, found ${results.length} elements`); expect(elapsed).toBeLessThan(10); }); it('should clear and re-insert 50k elements in under 2s', () => { const elements = generateElements(N); const index = new SpatialIndex(); index.bulkInsert(elements); // Modify 100 elements for (let i = 0; i < 100; i++) { elements[i].x += 5000; } const start = performance.now(); index.clear(); index.bulkInsert(elements); const elapsed = performance.now() - start; console.log(`SpatialIndex clear+reinsert: ${elapsed.toFixed(1)}ms after 100 modifications`); expect(elapsed).toBeLessThan(2000); }); it('should handle HistoryManager with 50k elements snapshot', () => { const elements = generateElements(N); const layers = [makeLayer()]; const history = new HistoryManager({ maxStackSize: 50 }); const start = performance.now(); history.initialize({ elements, layers, blocks: [], groups: [], bgConfig: null, }); const elapsed = performance.now() - start; console.log(`HistoryManager initialize: ${elapsed.toFixed(1)}ms for ${N} elements`); expect(elapsed).toBeLessThan(1000); }); it('should push 10 history snapshots with 50k elements each', () => { const elements = generateElements(N); const layers = [makeLayer()]; const history = new HistoryManager({ maxStackSize: 50 }); history.initialize({ elements, layers, blocks: [], groups: [], bgConfig: null, }); const start = performance.now(); for (let i = 0; i < 10; i++) { // Slightly modify elements each snapshot elements[i * 100].x += 1; history.pushSnapshot({ elements: [...elements], layers, blocks: [], groups: [], bgConfig: null, label: `Step ${i + 1}`, }); } const elapsed = performance.now() - start; console.log(`HistoryManager 10 snapshots: ${elapsed.toFixed(1)}ms for ${N} elements each`); expect(elapsed).toBeLessThan(5000); expect(history.getHistory().length).toBe(11); // initial + 10 }); it('should undo/redo with 50k elements in under 100ms', () => { const elements = generateElements(N); const layers = [makeLayer()]; const history = new HistoryManager({ maxStackSize: 50 }); history.initialize({ elements, layers, blocks: [], groups: [], bgConfig: null, }); history.pushSnapshot({ elements: [...elements], layers, blocks: [], groups: [], bgConfig: null, label: 'Step 1', }); const undoStart = performance.now(); const undoSnap = history.undo(); const undoTime = performance.now() - undoStart; console.log(`Undo: ${undoTime.toFixed(2)}ms for ${N} elements`); expect(undoSnap).not.toBeNull(); expect(undoTime).toBeLessThan(100); const redoStart = performance.now(); const redoSnap = history.redo(); const redoTime = performance.now() - redoStart; console.log(`Redo: ${redoTime.toFixed(2)}ms for ${N} elements`); expect(redoSnap).not.toBeNull(); expect(redoTime).toBeLessThan(100); }); });