From 9cce9b572ef78271fe6b1784dcb60c8e2c1ba5ae Mon Sep 17 00:00:00 2001 From: Marcel Mraz Date: Fri, 2 May 2025 16:27:00 +0200 Subject: [PATCH] Test appstate delta stability, remove console.log --- excalidraw-app/App.tsx | 3 - packages/element/tests/delta.test.tsx | 143 +++++++++++++++++++++++++ packages/excalidraw/components/App.tsx | 5 +- 3 files changed, 144 insertions(+), 7 deletions(-) create mode 100644 packages/element/tests/delta.test.tsx diff --git a/excalidraw-app/App.tsx b/excalidraw-app/App.tsx index 1f3d9954d2..bb62a0e96c 100644 --- a/excalidraw-app/App.tsx +++ b/excalidraw-app/App.tsx @@ -807,9 +807,6 @@ const ExcalidrawWrapper = () => { { - console.log(increment); - }} initialData={initialStatePromiseRef.current.promise} isCollaborating={isCollaborating} onPointerUpdate={collabAPI?.onPointerUpdate} diff --git a/packages/element/tests/delta.test.tsx b/packages/element/tests/delta.test.tsx new file mode 100644 index 0000000000..48e925c309 --- /dev/null +++ b/packages/element/tests/delta.test.tsx @@ -0,0 +1,143 @@ +import type { ObservedAppState } from "@excalidraw/excalidraw/types"; +import type { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; + +import { AppStateDelta } from "../src/delta"; + +describe("AppStateDelta", () => { + describe("ensure stable delta properties order", () => { + it("should maintain stable order for root properties", () => { + const name = "untitled scene"; + const selectedLinearElementId = "id1" as LinearElementEditor["elementId"]; + + const commonAppState = { + viewBackgroundColor: "#ffffff", + selectedElementIds: {}, + selectedGroupIds: {}, + editingGroupId: null, + croppingElementId: null, + editingLinearElementId: null, + }; + + const prevAppState1: ObservedAppState = { + ...commonAppState, + name: "", + selectedLinearElementId: null, + }; + + const nextAppState1: ObservedAppState = { + ...commonAppState, + name, + selectedLinearElementId, + }; + + const prevAppState2: ObservedAppState = { + selectedLinearElementId: null, + name: "", + ...commonAppState, + }; + + const nextAppState2: ObservedAppState = { + selectedLinearElementId, + name, + ...commonAppState, + }; + + const delta1 = AppStateDelta.calculate(prevAppState1, nextAppState1); + const delta2 = AppStateDelta.calculate(prevAppState2, nextAppState2); + + expect(JSON.stringify(delta1)).toBe(JSON.stringify(delta2)); + }); + + it("should maintain stable order for selectedElementIds", () => { + const commonAppState = { + name: "", + viewBackgroundColor: "#ffffff", + selectedGroupIds: {}, + editingGroupId: null, + croppingElementId: null, + selectedLinearElementId: null, + editingLinearElementId: null, + }; + + const prevAppState1: ObservedAppState = { + ...commonAppState, + selectedElementIds: { id5: true, id2: true, id4: true }, + }; + + const nextAppState1: ObservedAppState = { + ...commonAppState, + selectedElementIds: { + id1: true, + id2: true, + id3: true, + }, + }; + + const prevAppState2: ObservedAppState = { + ...commonAppState, + selectedElementIds: { id4: true, id2: true, id5: true }, + }; + + const nextAppState2: ObservedAppState = { + ...commonAppState, + selectedElementIds: { + id3: true, + id2: true, + id1: true, + }, + }; + + const delta1 = AppStateDelta.calculate(prevAppState1, nextAppState1); + const delta2 = AppStateDelta.calculate(prevAppState2, nextAppState2); + + expect(JSON.stringify(delta1)).toBe(JSON.stringify(delta2)); + }); + + it("should maintain stable order for selectedGroupIds", () => { + const commonAppState = { + name: "", + viewBackgroundColor: "#ffffff", + selectedElementIds: {}, + editingGroupId: null, + croppingElementId: null, + selectedLinearElementId: null, + editingLinearElementId: null, + }; + + const prevAppState1: ObservedAppState = { + ...commonAppState, + selectedGroupIds: { id5: false, id2: true, id4: true, id0: true }, + }; + + const nextAppState1: ObservedAppState = { + ...commonAppState, + selectedGroupIds: { + id0: true, + id1: true, + id2: false, + id3: true, + }, + }; + + const prevAppState2: ObservedAppState = { + ...commonAppState, + selectedGroupIds: { id0: true, id4: true, id2: true, id5: false }, + }; + + const nextAppState2: ObservedAppState = { + ...commonAppState, + selectedGroupIds: { + id3: true, + id2: false, + id1: true, + id0: true, + }, + }; + + const delta1 = AppStateDelta.calculate(prevAppState1, nextAppState1); + const delta2 = AppStateDelta.calculate(prevAppState2, nextAppState2); + + expect(JSON.stringify(delta1)).toBe(JSON.stringify(delta2)); + }); + }); +}); diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index 5dfb1ba052..b342e2f995 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -304,10 +304,7 @@ import { isNonDeletedElement } from "@excalidraw/element"; import Scene from "@excalidraw/element/Scene"; -import { - Store, - CaptureUpdateAction, -} from "@excalidraw/element/store"; +import { Store, CaptureUpdateAction } from "@excalidraw/element/store"; import type { ElementUpdate } from "@excalidraw/element/mutateElement";