/// import { DataProcessor, AggregateResult } from '../src/core/dataProcessor'; describe('DataProcessor Algorithm & Performance Validation', () => { // 1. 정합성 테스트 (Correctness) test('Should correctly aggregate data by key path', () => { const testData = [ { category: 'A', value: 10 }, { category: 'B', value: 20 }, { category: 'A', value: 30 }, { category: 'C', value: 40 }, ]; const result = DataProcessor.aggregate(testData, 'category'); expect(result.length).toBe(3); expect(result.find((r: AggregateResult) => r.key === 'A')?.count).toBe(2); expect(result.find((r: AggregateResult) => r.key === 'B')?.count).toBe(1); }); // 2. 예외 처리 테스트 (Robustness) test('Should handle invalid or missing key paths gracefully', () => { const testData = [ { id: 1, info: { type: 'X' } }, { id: 2 }, // info.type 없음 { id: 3, info: null }, // info.type 접근 불가 ]; const result = DataProcessor.aggregate(testData, 'info.type'); expect(result.length).toBe(1); expect(result[0].key).toBe('X'); }); test('Should reject unsafe or malformed key paths', () => { expect(() => DataProcessor.aggregate([{ a: 1 }], '')).toThrow(TypeError); expect(() => DataProcessor.aggregate([{ a: 1 }], 'a..b')).toThrow(TypeError); expect(() => DataProcessor.aggregate([{ a: 1 }], '__proto__.polluted')).toThrow(TypeError); }); test('Should support aggregation without retaining source values', () => { const result = DataProcessor.aggregate([ { category: 'A', value: 10 }, { category: 'A', value: 20 }, ], 'category', { collectValues: false }); expect(result).toHaveLength(1); expect(result[0].count).toBe(2); expect(result[0].values).toEqual([]); }); // 3. 성능 벤치마크 (O(N) vs O(N^2) 검증) test('O(N) Efficiency Benchmark', () => { const generateData = (n: number) => { return Array.from({ length: n }, (_, i) => ({ id: i, group: `group_${i % 100}` })); }; const smallN = 1000; const largeN = 100000; // 100배 증가 // Small dataset test const smallData = generateData(smallN); const startSmall = performance.now(); DataProcessor.aggregate(smallData, 'group'); const endSmall = performance.now(); const durationSmall = endSmall - startSmall; // Large dataset test const largeData = generateData(largeN); const startLarge = performance.now(); DataProcessor.aggregate(largeData, 'group'); const endLarge = performance.now(); const durationLarge = endLarge - startLarge; console.log(`[Benchmark] N=${smallN}: ${durationSmall.toFixed(4)}ms`); console.log(`[Benchmark] N=${largeN}: ${durationLarge.toFixed(4)}ms`); console.log(`[Benchmark] Scale Factor (N x 100): ${(durationLarge / durationSmall).toFixed(2)}x time`); // O(N^2)이었다면 10,000배 이상의 시간이 걸려야 하지만, // O(N)인 경우 약 100배 내외의 증가폭을 보여야 합니다. expect(durationLarge / durationSmall).toBeLessThan(500); }); });