105 lines
3.3 KiB
TypeScript
105 lines
3.3 KiB
TypeScript
import {
|
|
addSensorPoint,
|
|
createSchemeEditorState,
|
|
deleteSensorPoint,
|
|
isSchemeDirty,
|
|
redoSchemeEdit,
|
|
replaceSensorPoint,
|
|
resetSchemeEdit,
|
|
summarizeChanges,
|
|
undoSchemeEdit,
|
|
} from "./schemeEditor";
|
|
import type { SensorPlacementScheme, SensorPoint } from "./types";
|
|
|
|
const point = (node_id: string): SensorPoint => ({
|
|
node_id,
|
|
project_x: Number(node_id.slice(1)) * 10,
|
|
project_y: Number(node_id.slice(1)) * 20,
|
|
map_x: 13500000 + Number(node_id.slice(1)) * 10,
|
|
map_y: 3600000 + Number(node_id.slice(1)) * 20,
|
|
longitude: 121,
|
|
latitude: 31,
|
|
elevation: 5,
|
|
});
|
|
|
|
const scheme: SensorPlacementScheme = {
|
|
id: 1,
|
|
scheme_name: "测试方案",
|
|
sensor_number: 2,
|
|
min_diameter: 300,
|
|
username: "alice",
|
|
create_time: "2026-07-30T08:00:00+08:00",
|
|
sensor_location: ["J1", "J2"],
|
|
sensor_points: [point("J1"), point("J2")],
|
|
can_edit: true,
|
|
};
|
|
|
|
describe("scheme editor", () => {
|
|
it("adds unique nodes and can undo", () => {
|
|
const initial = createSchemeEditorState(scheme);
|
|
const added = addSensorPoint(initial, point("J3"));
|
|
|
|
expect(added.points.map((item) => item.node_id)).toEqual(["J1", "J2", "J3"]);
|
|
expect(added.statuses.J3).toBe("added");
|
|
expect(isSchemeDirty(added)).toBe(true);
|
|
expect(undoSchemeEdit(added).points).toEqual(initial.points);
|
|
});
|
|
|
|
it("can redo an undone edit and clears redo history after a new edit", () => {
|
|
const initial = createSchemeEditorState(scheme);
|
|
const added = addSensorPoint(initial, point("J3"));
|
|
const undone = undoSchemeEdit(added);
|
|
const redone = redoSchemeEdit(undone);
|
|
|
|
expect(redone.points.map((item) => item.node_id)).toEqual([
|
|
"J1",
|
|
"J2",
|
|
"J3",
|
|
]);
|
|
expect(redone.history).toHaveLength(1);
|
|
expect(redone.future).toEqual([]);
|
|
|
|
const editedAfterUndo = replaceSensorPoint(undone, "J1", point("J4"));
|
|
expect(editedAfterUndo.future).toEqual([]);
|
|
});
|
|
|
|
it("replaces a node without changing row order", () => {
|
|
const initial = createSchemeEditorState(scheme);
|
|
const replaced = replaceSensorPoint(initial, "J1", point("J3"));
|
|
|
|
expect(replaced.points.map((item) => item.node_id)).toEqual(["J3", "J2"]);
|
|
expect(replaced.statuses.J3).toBe("replaced");
|
|
expect(summarizeChanges(replaced)).toEqual({
|
|
added: 0,
|
|
removed: 0,
|
|
replaced: 1,
|
|
});
|
|
});
|
|
|
|
it("keeps an added status when replacing a newly added node", () => {
|
|
const added = addSensorPoint(createSchemeEditorState(scheme), point("J3"));
|
|
const replaced = replaceSensorPoint(added, "J3", point("J4"));
|
|
|
|
expect(replaced.statuses.J3).toBeUndefined();
|
|
expect(replaced.statuses.J4).toBe("added");
|
|
});
|
|
|
|
it("rejects duplicate replacements and deleting the final row", () => {
|
|
const initial = createSchemeEditorState(scheme);
|
|
expect(replaceSensorPoint(initial, "J1", point("J2"))).toBe(initial);
|
|
|
|
const oneLeft = deleteSensorPoint(initial, "J1");
|
|
expect(deleteSensorPoint(oneLeft, "J2")).toBe(oneLeft);
|
|
});
|
|
|
|
it("resets to the loaded baseline", () => {
|
|
const edited = addSensorPoint(createSchemeEditorState(scheme), point("J3"));
|
|
const reset = resetSchemeEdit(edited);
|
|
|
|
expect(reset.points.map((item) => item.node_id)).toEqual(["J1", "J2"]);
|
|
expect(isSchemeDirty(reset)).toBe(false);
|
|
expect(reset.history).toEqual([]);
|
|
expect(reset.future).toEqual([]);
|
|
});
|
|
});
|