Files
leistungsbilanz-ts/tests/circuit-structure-projection.test.ts
2026-07-30 20:27:17 +02:00

145 lines
3.7 KiB
TypeScript

import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { buildCircuitStructureProjection } from "../src/frontend/utils/circuit-structure-projection.js";
import type {
CircuitTreeCircuitDto,
CircuitTreeComponentDto,
CircuitTreeSectionDto,
} from "../src/frontend/types.js";
function component(
id: string,
placement: CircuitTreeComponentDto["placement"],
sortOrder: number,
sectionId?: string
): CircuitTreeComponentDto {
return {
id,
circuitListId: "list-1",
sectionId,
equipmentIdentifier: `-${id}`,
name: id,
role:
placement === "header"
? "main_switch"
: placement === "footer"
? "auxiliary"
: "group_residual_current_protection",
placement,
sortOrder,
};
}
function circuit(
id: string,
sectionId: string
): CircuitTreeCircuitDto {
return {
id,
circuitListId: "list-1",
sectionId,
equipmentIdentifier: `-${id}`,
sortOrder: 10,
isReserve: true,
circuitTotalPower: 0,
deviceRows: [],
};
}
function section(
id: string,
sortOrder: number
): CircuitTreeSectionDto {
return {
id,
key: id,
displayName: id,
prefix: "-1F1.",
sortOrder,
category: "lighting",
groupNumber: sortOrder / 10,
sectionTotalPower: 0,
components: [
component(`${id}-rcd-late`, "group", 20, id),
component(`${id}-rcd-first`, "group", 10, id),
],
circuits: [circuit(`${id}-circuit`, id)],
};
}
describe("circuit structure projection", () => {
it("projects fixed header, complete groups and auxiliary footer in stable order", () => {
const rows = buildCircuitStructureProjection({
headerComponents: [
component("surge", "header", 20),
component("main", "header", 10),
],
sections: [section("group-2", 20), section("group-1", 10)],
footerComponents: [
component("actor-2", "footer", 20),
component("actor-1", "footer", 10),
],
});
assert.deepEqual(
rows.map((row) => row.rowKey),
[
"header-component:main",
"header-component:surge",
"group:group-1",
"group-component:group-1-rcd-first",
"group-component:group-1-rcd-late",
"circuit-block:group-1-circuit",
"group-placeholder:group-1",
"group:group-2",
"group-component:group-2-rcd-first",
"group-component:group-2-rcd-late",
"circuit-block:group-2-circuit",
"group-placeholder:group-2",
"footer-component:actor-1",
"footer-component:actor-2",
]
);
});
it("keeps structural rows around an empty group", () => {
const empty = section("group-empty", 10);
empty.components = [];
empty.circuits = [];
assert.deepEqual(
buildCircuitStructureProjection({
headerComponents: [],
sections: [empty],
footerComponents: [],
}).map((row) => row.rowType),
["groupHeader", "groupPlaceholder"]
);
});
it("keeps circuit device rows inside their circuit block", () => {
const grouped = section("group-1", 10);
grouped.circuits[0].deviceRows = [
{
id: "device-1",
sortOrder: 10,
name: "Leuchte",
displayName: "Leuchte",
quantity: 1,
powerPerUnit: 0.1,
simultaneityFactor: 1,
rowTotalPower: 0.1,
},
];
const block = buildCircuitStructureProjection({
headerComponents: [],
sections: [grouped],
footerComponents: [],
}).find((row) => row.rowType === "circuitBlock");
assert.equal(
block?.rowType === "circuitBlock"
? block.circuit.deviceRows[0].id
: null,
"device-1"
);
});
});