142 lines
8.6 KiB
TypeScript
142 lines
8.6 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
||
import { groupInvestigationCharts } from "./investigation-chart-groups";
|
||
import type { InvestigationChart } from "../hooks/use-investigation-presentation";
|
||
|
||
const comparison = (id: string, metric = "压力", unit = "m", date = "2026-07-16"): InvestigationChart => ({
|
||
action: "open_chart", chart_id: `chart_tc_${id}`, evidence_refs: [`evidence:${id}`],
|
||
chart: { title: `${id} ${metric}七日同时刻对照(${unit})`, chart_type: "time_comparison",
|
||
x_axis_name: "时间", y_axis_name: `${metric}(${unit})`, x_data: ["07:45", "08:00"],
|
||
series: [
|
||
{ name: `${id} 当前 ${date}`, type: "line", data: [30, 25], sample_times: [`${date}T07:45:00+08:00`, `${date}T08:00:00+08:00`] },
|
||
{ name: `${id} 2026-07-09`, type: "scatter", data: [null, 32], sample_times: [null, "2026-07-09T08:00:00+08:00"] }
|
||
] }
|
||
});
|
||
|
||
const legacyComparison = (id: string, metric = "压力", unit = "m", date = "2026-07-16") => {
|
||
const command = comparison(id, metric, unit, date);
|
||
command.chart.title = `${id} ${metric}三小时趋势与七天同期对照(${unit})`;
|
||
command.chart.series[0].name = `${id} ${date.slice(5)}(${unit})`;
|
||
command.chart.series[1].name = "07-09";
|
||
return command;
|
||
};
|
||
|
||
describe("investigation comparison groups", () => {
|
||
it("groups all four bound devices even when titles differ and one device has no observations", () => {
|
||
const ids = ["486033", "542017", "541061", "524529"];
|
||
const charts = ids.map((id, index) => {
|
||
const command = comparison(id, "流量", "m3/h");
|
||
command.chart.title = `不同的标题 ${index}`;
|
||
command.chart.scada = { role: "comparison", metric: "flow", unit: "m3/h",
|
||
window_start: "2026-07-16T05:00:00+08:00", window_end: "2026-07-16T08:00:00+08:00" };
|
||
command.chart.series.forEach((series, offset) => {
|
||
series.device_id = id;
|
||
series.day_offset = offset;
|
||
series.name = offset ? "历史" : "当前";
|
||
if (id === "524529") { series.data = [null, null]; series.sample_times = [null, null]; }
|
||
});
|
||
return command;
|
||
});
|
||
const groups = groupInvestigationCharts(charts);
|
||
expect(groups).toHaveLength(1);
|
||
expect(groups[0].items.map((item) => item.label)).toEqual(ids);
|
||
expect(groups[0].id).toBe(groupInvestigationCharts([charts[3]])[0].id);
|
||
expect(groups[0].items[3].command).toBe(charts[3]);
|
||
charts[3].chart.scada!.unit = "m³/h";
|
||
charts[3].chart.scada!.window_start = "2026-07-15T21:00:00Z";
|
||
charts[3].chart.scada!.window_end = "2026-07-16T00:00:00Z";
|
||
expect(groupInvestigationCharts(charts)).toHaveLength(1);
|
||
});
|
||
|
||
it("groups pressure objects and pipe flow objects separately without changing data or evidence", () => {
|
||
const charts = [comparison("170486"), comparison("175618"), comparison("542017", "管流", "m³/h"), comparison("486033", "管流", "m³/h")];
|
||
const groups = groupInvestigationCharts(charts);
|
||
expect(groups).toHaveLength(2);
|
||
expect(groups[0].items.map((item) => item.label)).toEqual(["170486", "175618"]);
|
||
expect(groups[1].items.map((item) => item.label)).toEqual(["542017", "486033"]);
|
||
expect(groups[0].title).toBe("压力七日同时刻对照(m)");
|
||
expect(groups[0].items[1].command).toBe(charts[1]);
|
||
expect(charts[1].chart.series[1].data).toEqual([null, 32]);
|
||
});
|
||
|
||
it("groups saved pressure and flow charts whose titles put the metric before the object ID", () => {
|
||
const charts = [["170486", "压力", "m"], ["175618", "压力", "m"], ["541061", "流量", "m³/h"], ["542017", "流量", "m³/h"]].map(([id, metric, unit]) => {
|
||
const command = comparison(id, metric, unit);
|
||
command.chart.title = `${metric}测点 ${id} 当前曲线与前七天同期对比(${unit})`;
|
||
return command;
|
||
});
|
||
const groups = groupInvestigationCharts(charts);
|
||
expect(groups.map((group) => ({ title: group.title, objects: group.items.map((item) => item.label) }))).toEqual([
|
||
{ title: "压力当前曲线与前七天同期对比(m)", objects: ["170486", "175618"] },
|
||
{ title: "流量当前曲线与前七天同期对比(m³/h)", objects: ["541061", "542017"] }
|
||
]);
|
||
});
|
||
|
||
it("recognizes the same explicit object comparison in all three saved title formats", () => {
|
||
const charts = [comparison("170486"), comparison("175618"), comparison("159673")];
|
||
charts[0].chart.title = "170486 压力三小时与历史对照(m)";
|
||
charts[1].chart.title = "测点 175618 压力三小时与历史对照(m)";
|
||
charts[2].chart.title = "压力测点 159673 三小时与历史对照(m)";
|
||
const groups = groupInvestigationCharts(charts);
|
||
expect(groups).toHaveLength(1);
|
||
expect(groups[0].title).toBe("压力三小时与历史对照(m)");
|
||
expect(groups[0].items.map((item) => item.label)).toEqual(["170486", "175618", "159673"]);
|
||
});
|
||
|
||
it("groups saved date-only historical labels without rewriting commands, readings or evidence", () => {
|
||
const charts = [legacyComparison("170486"), legacyComparison("175618")];
|
||
charts[1].chart.series[1].data[1] = 0;
|
||
const original = structuredClone(charts);
|
||
const groups = groupInvestigationCharts(charts);
|
||
expect(groups).toHaveLength(1);
|
||
expect(groups[0].items.map((item) => item.label)).toEqual(["170486", "175618"]);
|
||
groups[0].items.forEach((item, index) => {
|
||
expect(item.command).toBe(charts[index]);
|
||
expect(item.command.chart.series).toBe(charts[index].chart.series);
|
||
expect(item.command.chart.series[1].sample_times).toBe(charts[index].chart.series[1].sample_times);
|
||
expect(item.command.evidence_refs).toBe(charts[index].evidence_refs);
|
||
});
|
||
expect(charts).toEqual(original);
|
||
});
|
||
|
||
it("keeps legacy comparisons with different units, windows or current dates separate", () => {
|
||
const shifted = legacyComparison("175618");
|
||
shifted.chart.x_data = ["08:00", "08:15"];
|
||
shifted.chart.series[0].sample_times = ["2026-07-16T08:00:00+08:00", "2026-07-16T08:15:00+08:00"];
|
||
shifted.chart.series[1].sample_times = [null, "2026-07-09T08:15:00+08:00"];
|
||
const charts = [legacyComparison("170486"), legacyComparison("P2", "压力", "MPa"), shifted, legacyComparison("P3", "压力", "m", "2026-07-17")];
|
||
expect(groupInvestigationCharts(charts)).toHaveLength(charts.length);
|
||
});
|
||
|
||
it("leaves ambiguous or mixed-object legacy charts and unproven historical dates separate", () => {
|
||
const ambiguous = legacyComparison("P2"); ambiguous.chart.title = "压力测点历史对照";
|
||
const foreign = legacyComparison("P3"); foreign.chart.series[1].name = "P4 07-09";
|
||
const mixed = legacyComparison("P4"); mixed.chart.series.push({ ...mixed.chart.series[0], name: "P5 当前 2026-07-16" });
|
||
const missing = legacyComparison("P5"); delete missing.chart.series[1].sample_times;
|
||
const mismatched = legacyComparison("P6"); mismatched.chart.series[1].sample_times = [null, "2026-07-10T08:00:00+08:00"];
|
||
const empty = legacyComparison("P7"); empty.chart.series[1].data = [null, null]; empty.chart.series[1].sample_times = [null, null];
|
||
const sameDateInUtc8 = legacyComparison("P8"); sameDateInUtc8.chart.series[1].sample_times = [null, "2026-07-09T00:00:00Z"];
|
||
const charts = [legacyComparison("170486"), ambiguous, foreign, mixed, missing, mismatched, empty, sameDateInUtc8];
|
||
const groups = groupInvestigationCharts(charts);
|
||
expect(groups).toHaveLength(charts.length - 1);
|
||
expect(groups[0].items.map((item) => item.label)).toEqual(["170486", "P8"]);
|
||
});
|
||
|
||
it("keeps incompatible units, sampling windows, comparison dates and ordinary trends separate", () => {
|
||
const base = comparison("170486");
|
||
const window = comparison("175618"); window.chart.x_data = ["08:00", "08:15"];
|
||
const trend = comparison("159673"); trend.chart.series = [trend.chart.series[0]];
|
||
expect(groupInvestigationCharts([base, comparison("P2", "压力", "MPa"), comparison("P3", "压力", "m", "2026-07-17"), window, trend])).toHaveLength(5);
|
||
const noTimes = [comparison("P4"), comparison("P5", "压力", "m", "2026-07-17")];
|
||
for (const command of noTimes) for (const series of command.chart.series) delete series.sample_times;
|
||
expect(groupInvestigationCharts(noTimes)).toHaveLength(2);
|
||
});
|
||
|
||
it("keeps group identity stable as objects arrive or are closed and leaves ambiguous titles alone", () => {
|
||
const first = comparison("170486"), second = comparison("175618");
|
||
expect(groupInvestigationCharts([first])[0].id).toBe(groupInvestigationCharts([second, first])[0].id);
|
||
const ambiguous = comparison("159673"); ambiguous.chart.title = "压力同期对照";
|
||
expect(groupInvestigationCharts([first, ambiguous])).toHaveLength(2);
|
||
expect(groupInvestigationCharts([])).toEqual([]);
|
||
});
|
||
});
|