import { readFileSync } from 'node:fs'; import { resolve } from 'node:path'; import { describe, expect, it } from 'vitest'; import { buildSankeyData, parseCsvText, parseXlsxBuffer } from '../src/core'; describe('core parser & sankey', () => { it('可以解析 CSV 并生成列名与数据行', () => { const table = parseCsvText('A,B,C\n1,2,3\n4,5,6'); expect(table.headers).toEqual(['A', 'B', 'C']); expect(table.rows).toEqual([ ['1', '2', '3'], ['4', '5', '6'] ]); }); it('支持合并单元格语义向下补全并聚合', () => { const table = { headers: ['站点', '值', '目标', '模型'], rows: [ ['宁波北欧10', '2582', '嘉兴四级算力池', '小模型'], ['宁波北欧12', '2610', '', ''], ['宁波鄞中15', '507', '嘉兴四级算力池', '小模型'] ] }; const result = buildSankeyData(table, { sourceDataColumn: 1, sourceDescriptionColumns: [0, 1], targetDescriptionColumns: [2, 3], delimiter: '-' }); expect(result.meta.droppedRows).toBe(0); expect(result.links).toHaveLength(3); expect(result.links[1].target).toBe('嘉兴四级算力池-小模型'); }); it('可以解析 data/example0.xlsx', () => { const filePath = resolve(process.cwd(), 'data/example0.xlsx'); const fileBuffer = readFileSync(filePath); const table = parseXlsxBuffer(fileBuffer.buffer.slice(fileBuffer.byteOffset, fileBuffer.byteOffset + fileBuffer.byteLength)); expect(table.headers.length).toBeGreaterThan(1); expect(table.rows.length).toBeGreaterThan(0); }); });