update at 2026-02-14 10:55:14
This commit is contained in:
@@ -2,7 +2,10 @@
|
|||||||
* 统一清洗文本,避免空格导致节点重复。
|
* 统一清洗文本,避免空格导致节点重复。
|
||||||
*/
|
*/
|
||||||
function normalizeText(value) {
|
function normalizeText(value) {
|
||||||
return String(value || '').trim();
|
if (value === null || value === undefined) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return String(value).trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -236,7 +239,7 @@ function parseXlsxBuffer(buffer) {
|
|||||||
const rows = xlsx.utils.sheet_to_json(sheet, {
|
const rows = xlsx.utils.sheet_to_json(sheet, {
|
||||||
header: 1,
|
header: 1,
|
||||||
raw: false,
|
raw: false,
|
||||||
defval: ''
|
blankrows: false
|
||||||
});
|
});
|
||||||
return toRawTable(rows);
|
return toRawTable(rows);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ export function parseXlsxBuffer(buffer: ArrayBuffer): RawTable {
|
|||||||
const rows = XLSX.utils.sheet_to_json<unknown[]>(sheet, {
|
const rows = XLSX.utils.sheet_to_json<unknown[]>(sheet, {
|
||||||
header: 1,
|
header: 1,
|
||||||
raw: false,
|
raw: false,
|
||||||
defval: ''
|
blankrows: false
|
||||||
});
|
});
|
||||||
|
|
||||||
return toRawTable(rows);
|
return toRawTable(rows);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { readFileSync } from 'node:fs';
|
import { readFileSync } from 'node:fs';
|
||||||
import { resolve } from 'node:path';
|
import { resolve } from 'node:path';
|
||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import * as XLSX from 'xlsx';
|
||||||
import { buildSankeyData, parseCsvText, parseXlsxBuffer } from '../src/core';
|
import { buildSankeyData, parseCsvText, parseXlsxBuffer } from '../src/core';
|
||||||
|
|
||||||
describe('core parser & sankey', () => {
|
describe('core parser & sankey', () => {
|
||||||
@@ -45,6 +46,38 @@ describe('core parser & sankey', () => {
|
|||||||
expect(table.rows.length).toBeGreaterThan(0);
|
expect(table.rows.length).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('xlsx !ref 范围虚高时,不应错误膨胀行列数量', () => {
|
||||||
|
const sheet = XLSX.utils.aoa_to_sheet([
|
||||||
|
['source', 'target', 'value'],
|
||||||
|
['A', 'B', 1]
|
||||||
|
]);
|
||||||
|
sheet['!ref'] = 'A1:H20';
|
||||||
|
const workbook = XLSX.utils.book_new();
|
||||||
|
XLSX.utils.book_append_sheet(workbook, sheet, 'S1');
|
||||||
|
const buffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'buffer' });
|
||||||
|
const table = parseXlsxBuffer(
|
||||||
|
buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength)
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(table.headers).toEqual(['source', 'target', 'value']);
|
||||||
|
expect(table.rows).toEqual([['A', 'B', '1']]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('xlsx 中 0 值应被正确保留', () => {
|
||||||
|
const sheet = XLSX.utils.aoa_to_sheet([
|
||||||
|
['source', 'target', 'value'],
|
||||||
|
['A', 'B', 0]
|
||||||
|
]);
|
||||||
|
const workbook = XLSX.utils.book_new();
|
||||||
|
XLSX.utils.book_append_sheet(workbook, sheet, 'S1');
|
||||||
|
const buffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'buffer' });
|
||||||
|
const table = parseXlsxBuffer(
|
||||||
|
buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength)
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(table.rows).toEqual([['A', 'B', '0']]);
|
||||||
|
});
|
||||||
|
|
||||||
it('源数据非法时,告警包含单元格内容和位置', () => {
|
it('源数据非法时,告警包含单元格内容和位置', () => {
|
||||||
const table = {
|
const table = {
|
||||||
headers: ['source', 'value', 'target'],
|
headers: ['source', 'value', 'target'],
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { readFileSync } from 'node:fs';
|
|||||||
import { createRequire } from 'node:module';
|
import { createRequire } from 'node:module';
|
||||||
import { resolve } from 'node:path';
|
import { resolve } from 'node:path';
|
||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import * as XLSX from 'xlsx';
|
||||||
|
|
||||||
const require = createRequire(import.meta.url);
|
const require = createRequire(import.meta.url);
|
||||||
const { parseTableByFileName, parseXlsxBuffer } = require('../miniapp/utils/sankey.js') as {
|
const { parseTableByFileName, parseXlsxBuffer } = require('../miniapp/utils/sankey.js') as {
|
||||||
@@ -41,4 +42,36 @@ describe('miniapp utils sankey', () => {
|
|||||||
expect(table.headers.length).toBeGreaterThan(1);
|
expect(table.headers.length).toBeGreaterThan(1);
|
||||||
expect(table.rows.length).toBeGreaterThan(0);
|
expect(table.rows.length).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('xlsx !ref 范围虚高时,不应错误膨胀行列数量', () => {
|
||||||
|
const sheet = XLSX.utils.aoa_to_sheet([
|
||||||
|
['source', 'target', 'value'],
|
||||||
|
['A', 'B', 1]
|
||||||
|
]);
|
||||||
|
sheet['!ref'] = 'A1:H20';
|
||||||
|
const workbook = XLSX.utils.book_new();
|
||||||
|
XLSX.utils.book_append_sheet(workbook, sheet, 'S1');
|
||||||
|
const buffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'buffer' });
|
||||||
|
const arrayBuffer = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
||||||
|
|
||||||
|
const table = parseXlsxBuffer(arrayBuffer);
|
||||||
|
|
||||||
|
expect(table.headers).toEqual(['source', 'target', 'value']);
|
||||||
|
expect(table.rows).toEqual([['A', 'B', '1']]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('xlsx 中 0 值应被正确保留', () => {
|
||||||
|
const sheet = XLSX.utils.aoa_to_sheet([
|
||||||
|
['source', 'target', 'value'],
|
||||||
|
['A', 'B', 0]
|
||||||
|
]);
|
||||||
|
const workbook = XLSX.utils.book_new();
|
||||||
|
XLSX.utils.book_append_sheet(workbook, sheet, 'S1');
|
||||||
|
const buffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'buffer' });
|
||||||
|
const arrayBuffer = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
||||||
|
|
||||||
|
const table = parseXlsxBuffer(arrayBuffer);
|
||||||
|
|
||||||
|
expect(table.rows).toEqual([['A', 'B', '0']]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user