test: update coverage and snapshots for per-track schemaState

This commit is contained in:
Ryan Di
2026-03-25 18:04:22 +11:00
parent 16cf593978
commit b871d4ceb3
19 changed files with 2623 additions and 581 deletions
+40 -21
View File
@@ -84,10 +84,15 @@ describe("collaboration", () => {
const frameWithFutureFields = {
...frame,
schemaVersion: 2,
schemaState: {
tracks: {
...frame.schemaState.tracks,
"host.myapp.frame": 1,
},
},
futureField: "keep-me",
} as typeof frame & {
schemaVersion: number;
schemaState: { tracks: Record<string, number> };
futureField: string;
};
@@ -98,7 +103,9 @@ describe("collaboration", () => {
await waitFor(() => {
expect((h.elements[0] as any).futureField).toBe("keep-me");
expect((h.elements[0] as any).schemaVersion).toBe(2);
expect((h.elements[0] as any).schemaState).toEqual(
frameWithFutureFields.schemaState,
);
expect(h.elements[0].backgroundColor).toBe("#ff0000");
});
@@ -119,7 +126,9 @@ describe("collaboration", () => {
}),
);
expect((reconciled[0] as any).futureField).toBe("keep-me");
expect((reconciled[0] as any).schemaVersion).toBe(2);
expect((reconciled[0] as any).schemaState).toEqual(
frameWithFutureFields.schemaState,
);
});
it("should preserve future element fields on local edits before broadcast", async () => {
@@ -136,10 +145,15 @@ describe("collaboration", () => {
const rectWithFutureFields = {
...rect,
schemaVersion: 2,
schemaState: {
tracks: {
...rect.schemaState.tracks,
"host.myapp.rect": 1,
},
},
futureField: { value: "keep-me" },
} as typeof rect & {
schemaVersion: number;
schemaState: { tracks: Record<string, number> };
futureField: { value: string };
};
@@ -156,7 +170,9 @@ describe("collaboration", () => {
await waitFor(() => {
expect((h.elements[0] as any).futureField).toEqual({ value: "keep-me" });
expect((h.elements[0] as any).schemaVersion).toBe(2);
expect((h.elements[0] as any).schemaState).toEqual(
rectWithFutureFields.schemaState,
);
expect(h.elements[0]).toEqual(expect.objectContaining({ x: 200 }));
});
});
@@ -175,14 +191,18 @@ describe("collaboration", () => {
}
});
// eslint-disable-next-line dot-notation
expect(h.store["scheduledMicroActions"].length).toBe(0);
expect(durableIncrements.length).toBe(0);
expect(ephemeralIncrements.length).toBe(0);
// Ensure this test starts from a deterministic scene regardless of previous
// test state restored from persistence.
API.updateScene({
elements: [],
captureUpdate: CaptureUpdateAction.NEVER,
});
const durableBaseline = durableIncrements.length;
const ephemeralBaseline = ephemeralIncrements.length;
const rectProps = {
type: "rectangle",
id: "A",
height: 200,
width: 100,
x: 0,
@@ -197,8 +217,7 @@ describe("collaboration", () => {
});
await waitFor(() => {
// expect(commitSpy).toHaveBeenCalledTimes(1);
expect(durableIncrements.length).toBe(1);
expect(durableIncrements.length).toBe(durableBaseline + 1);
});
// simulate two batched remote updates
@@ -222,13 +241,13 @@ describe("collaboration", () => {
// altough the updates get batched,
// we expect two ephemeral increments for each update,
// and each such update should have the expected change
expect(ephemeralIncrements.length).toBe(2);
expect(ephemeralIncrements[0].change.elements.A).toEqual(
expect.objectContaining({ x: 100 }),
);
expect(ephemeralIncrements[1].change.elements.A).toEqual(
expect.objectContaining({ x: 200 }),
);
expect(ephemeralIncrements.length).toBe(ephemeralBaseline + 2);
expect(
ephemeralIncrements[ephemeralBaseline].change.elements[rect.id],
).toEqual(expect.objectContaining({ x: 100 }));
expect(
ephemeralIncrements[ephemeralBaseline + 1].change.elements[rect.id],
).toEqual(expect.objectContaining({ x: 200 }));
// eslint-disable-next-line dot-notation
expect(h.store["scheduledMicroActions"].length).toBe(0);
});
@@ -27,7 +27,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing s
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#66a80f",
"strokeStyle": "solid",
@@ -65,7 +67,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing s
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#9c36b5",
"strokeStyle": "solid",
@@ -118,7 +122,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing s
],
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": {
@@ -180,7 +186,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing s
],
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": {
@@ -227,7 +235,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing s
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -271,7 +281,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing t
"originalText": "HEYYYYY",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#c2255c",
"strokeStyle": "solid",
@@ -318,7 +330,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing t
"originalText": "Whats up ?",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -379,7 +393,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing t
],
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": {
@@ -427,7 +443,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to existing t
"originalText": "HELLO WORLD!!",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -488,7 +506,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to shapes whe
],
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": {
@@ -536,7 +556,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to shapes whe
"originalText": "HELLO WORLD!!",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -577,7 +599,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to shapes whe
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -615,7 +639,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to shapes whe
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -673,7 +699,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to text when
],
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": {
@@ -721,7 +749,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to text when
"originalText": "HELLO WORLD!!",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -768,7 +798,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to text when
"originalText": "HEYYYYY",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -815,7 +847,9 @@ exports[`Test Transform > Test arrow bindings > should bind arrows to text when
"originalText": "WHATS UP ?",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -851,7 +885,9 @@ exports[`Test Transform > should not allow duplicate ids 1`] = `
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -897,7 +933,9 @@ exports[`Test Transform > should transform linear elements 1`] = `
],
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": null,
@@ -945,7 +983,9 @@ exports[`Test Transform > should transform linear elements 2`] = `
],
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": "dot",
"startBinding": null,
@@ -993,7 +1033,9 @@ exports[`Test Transform > should transform linear elements 3`] = `
"polygon": false,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": null,
@@ -1041,7 +1083,9 @@ exports[`Test Transform > should transform linear elements 4`] = `
"polygon": false,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": null,
@@ -1076,7 +1120,9 @@ exports[`Test Transform > should transform regular shapes 1`] = `
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1109,7 +1155,9 @@ exports[`Test Transform > should transform regular shapes 2`] = `
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1142,7 +1190,9 @@ exports[`Test Transform > should transform regular shapes 3`] = `
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1175,7 +1225,9 @@ exports[`Test Transform > should transform regular shapes 4`] = `
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1208,7 +1260,9 @@ exports[`Test Transform > should transform regular shapes 5`] = `
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "dotted",
@@ -1241,7 +1295,9 @@ exports[`Test Transform > should transform regular shapes 6`] = `
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1971c2",
"strokeStyle": "dashed",
@@ -1280,7 +1336,9 @@ exports[`Test Transform > should transform text element 1`] = `
"originalText": "HELLO WORLD!",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1322,7 +1380,9 @@ exports[`Test Transform > should transform text element 2`] = `
"originalText": "STYLED HELLO WORLD!",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#5f3dc4",
"strokeStyle": "solid",
@@ -1369,7 +1429,9 @@ exports[`Test Transform > should transform the elements correctly when linear el
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1409,7 +1471,9 @@ exports[`Test Transform > should transform the elements correctly when linear el
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1453,7 +1517,9 @@ exports[`Test Transform > should transform the elements correctly when linear el
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1501,7 +1567,9 @@ exports[`Test Transform > should transform the elements correctly when linear el
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1561,7 +1629,9 @@ exports[`Test Transform > should transform the elements correctly when linear el
"roundness": {
"type": 2,
},
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": {
@@ -1626,7 +1696,9 @@ exports[`Test Transform > should transform the elements correctly when linear el
"roundness": {
"type": 2,
},
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": {
@@ -1676,7 +1748,9 @@ exports[`Test Transform > should transform the elements correctly when linear el
"originalText": "B",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1720,7 +1794,9 @@ exports[`Test Transform > should transform the elements correctly when linear el
"originalText": "A",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1764,7 +1840,9 @@ exports[`Test Transform > should transform the elements correctly when linear el
"originalText": "Alice",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1808,7 +1886,9 @@ exports[`Test Transform > should transform the elements correctly when linear el
"originalText": "Bob",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1850,7 +1930,9 @@ exports[`Test Transform > should transform the elements correctly when linear el
"originalText": "How are you?",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1892,7 +1974,9 @@ exports[`Test Transform > should transform the elements correctly when linear el
"originalText": "Friendship",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1946,7 +2030,9 @@ exports[`Test Transform > should transform to labelled arrows when label provide
],
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": null,
@@ -1999,7 +2085,9 @@ exports[`Test Transform > should transform to labelled arrows when label provide
],
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": null,
@@ -2052,7 +2140,9 @@ exports[`Test Transform > should transform to labelled arrows when label provide
],
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": null,
@@ -2105,7 +2195,9 @@ exports[`Test Transform > should transform to labelled arrows when label provide
],
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": null,
@@ -2146,7 +2238,9 @@ exports[`Test Transform > should transform to labelled arrows when label provide
"originalText": "LABELED ARROW",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -2188,7 +2282,9 @@ exports[`Test Transform > should transform to labelled arrows when label provide
"originalText": "STYLED LABELED ARROW",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#099268",
"strokeStyle": "solid",
@@ -2230,7 +2326,9 @@ exports[`Test Transform > should transform to labelled arrows when label provide
"originalText": "ANOTHER STYLED LABELLED ARROW",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1098ad",
"strokeStyle": "solid",
@@ -2273,7 +2371,9 @@ exports[`Test Transform > should transform to labelled arrows when label provide
"originalText": "ANOTHER STYLED LABELLED ARROW",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#099268",
"strokeStyle": "solid",
@@ -2315,7 +2415,9 @@ exports[`Test Transform > should transform to text containers when label provide
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -2353,7 +2455,9 @@ exports[`Test Transform > should transform to text containers when label provide
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -2391,7 +2495,9 @@ exports[`Test Transform > should transform to text containers when label provide
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -2429,7 +2535,9 @@ exports[`Test Transform > should transform to text containers when label provide
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -2467,7 +2575,9 @@ exports[`Test Transform > should transform to text containers when label provide
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#c2255c",
"strokeStyle": "solid",
@@ -2505,7 +2615,9 @@ exports[`Test Transform > should transform to text containers when label provide
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#f08c00",
"strokeStyle": "solid",
@@ -2544,7 +2656,9 @@ exports[`Test Transform > should transform to text containers when label provide
"originalText": "RECTANGLE TEXT CONTAINER",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -2586,7 +2700,9 @@ exports[`Test Transform > should transform to text containers when label provide
"originalText": "ELLIPSE TEXT CONTAINER",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -2630,7 +2746,9 @@ exports[`Test Transform > should transform to text containers when label provide
TEXT CONTAINER",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -2674,7 +2792,9 @@ exports[`Test Transform > should transform to text containers when label provide
"originalText": "STYLED DIAMOND TEXT CONTAINER",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#099268",
"strokeStyle": "solid",
@@ -2717,7 +2837,9 @@ exports[`Test Transform > should transform to text containers when label provide
"originalText": "TOP LEFT ALIGNED RECTANGLE TEXT CONTAINER",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#c2255c",
"strokeStyle": "solid",
@@ -2761,7 +2883,9 @@ exports[`Test Transform > should transform to text containers when label provide
"originalText": "STYLED ELLIPSE TEXT CONTAINER",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#c2255c",
"strokeStyle": "solid",
@@ -6,6 +6,10 @@ import {
FONT_FAMILY,
STROKE_WIDTH,
} from "@excalidraw/common";
import {
CORE_FRAME_SCHEMA_TRACK,
CORE_SUPPORTED_TRACKS,
} from "@excalidraw/element";
import { Excalidraw } from "../index";
import { API } from "../tests/helpers/api";
@@ -196,6 +200,7 @@ describe("element locking", () => {
it("should not update text background when changing background in mixed frame selection", () => {
const frame = API.createElement({
type: "frame",
schemaState: { tracks: {} },
});
const text = API.createElement({
type: "text",
@@ -215,6 +220,9 @@ describe("element locking", () => {
expect(API.getElement(text).backgroundColor).toBe(
COLOR_PALETTE.transparent,
);
expect(
API.getElement(frame).schemaState.tracks[CORE_FRAME_SCHEMA_TRACK],
).toBe(CORE_SUPPORTED_TRACKS[CORE_FRAME_SCHEMA_TRACK]);
});
it("should not update frame stroke width when changing stroke width in mixed selection", () => {
+8 -9
View File
@@ -4,7 +4,6 @@ import {
parseDataTransferEvent,
serializeAsClipboardJSON,
} from "./clipboard";
import { SCHEMA_VERSIONS } from "./data/schema";
import { API } from "./tests/helpers/api";
describe("parseClipboard()", () => {
@@ -59,7 +58,7 @@ describe("parseClipboard()", () => {
expect.objectContaining({
id: rect.id,
type: rect.type,
schemaVersion: SCHEMA_VERSIONS.latest,
schemaState: rect.schemaState,
}),
]);
});
@@ -84,7 +83,7 @@ describe("parseClipboard()", () => {
expect.objectContaining({
id: rect.id,
type: rect.type,
schemaVersion: SCHEMA_VERSIONS.latest,
schemaState: rect.schemaState,
}),
]);
// -------------------------------------------------------------------------
@@ -102,7 +101,7 @@ describe("parseClipboard()", () => {
expect.objectContaining({
id: rect.id,
type: rect.type,
schemaVersion: SCHEMA_VERSIONS.latest,
schemaState: rect.schemaState,
}),
]);
// -------------------------------------------------------------------------
@@ -127,15 +126,15 @@ describe("parseClipboard()", () => {
expect(clipboardData.elements?.[0]).toEqual(
expect.objectContaining({
id: rect.id,
schemaVersion: SCHEMA_VERSIONS.latest,
schemaState: rect.schemaState,
}),
);
});
it("should not upcast legacy elements to latest schema on clipboard serialize", async () => {
const rect = API.createElement({ type: "rectangle" });
const legacyRect = { ...rect } as typeof rect & { schemaVersion?: number };
delete legacyRect.schemaVersion;
const legacyRect = { ...(rect as any) };
delete legacyRect.schemaState;
const clipboardPayload = JSON.parse(
serializeAsClipboardJSON({
@@ -143,7 +142,7 @@ describe("parseClipboard()", () => {
files: null,
}),
);
expect(clipboardPayload.elements[0]).not.toHaveProperty("schemaVersion");
expect(clipboardPayload.elements[0]).not.toHaveProperty("schemaState");
const clipboardData = await parseClipboard(
await parseDataTransferEvent(
@@ -155,7 +154,7 @@ describe("parseClipboard()", () => {
),
);
expect(clipboardData.elements?.[0]).not.toHaveProperty("schemaVersion");
expect(clipboardData.elements?.[0]).not.toHaveProperty("schemaState");
});
it("should parse <image> `src` urls out of text/html", async () => {
+146 -53
View File
@@ -3,11 +3,13 @@ import { DEFAULT_ELEMENT_PROPS } from "@excalidraw/common";
import { API } from "../tests/helpers/api";
import {
CORE_FRAME_SCHEMA_TRACK,
type SchemaMigration,
CORE_SUPPORTED_TRACKS,
migrateElements,
resolveSchemaVersion,
resolveTrackVersion,
SCHEMA_INITIAL_TRACK_VERSION,
SCHEMA_MIGRATIONS,
SCHEMA_VERSIONS,
validateSchemaMigrations,
} from "./schema";
@@ -18,7 +20,7 @@ describe("schema migration", () => {
type: "frame",
backgroundColor: "#ffc9c9",
}),
schemaVersion: undefined,
schemaState: { tracks: {} },
};
const migrated = migrateElements([frame])!;
@@ -26,23 +28,31 @@ describe("schema migration", () => {
expect(migrated[0].backgroundColor).toBe(
DEFAULT_ELEMENT_PROPS.backgroundColor,
);
expect(migrated[0].schemaVersion).toBe(SCHEMA_VERSIONS.latest);
expect(migrated[0].schemaState.tracks[CORE_FRAME_SCHEMA_TRACK]).toBe(
CORE_SUPPORTED_TRACKS[CORE_FRAME_SCHEMA_TRACK],
);
});
it("should keep latest-schema frame backgrounds unchanged", () => {
const frame = API.createElement({
type: "frame",
backgroundColor: "#ffc9c9",
});
const latestFrame = {
...frame,
schemaVersion: SCHEMA_VERSIONS.latest,
} as typeof frame & { schemaVersion: number };
it("should keep latest-track frame backgrounds unchanged", () => {
const frame = {
...API.createElement({
type: "frame",
backgroundColor: "#ffc9c9",
}),
schemaState: {
tracks: {
[CORE_FRAME_SCHEMA_TRACK]:
CORE_SUPPORTED_TRACKS[CORE_FRAME_SCHEMA_TRACK],
},
},
};
const migrated = migrateElements([latestFrame])!;
const migrated = migrateElements([frame])!;
expect(migrated[0].backgroundColor).toBe("#ffc9c9");
expect(migrated[0].schemaVersion).toBe(SCHEMA_VERSIONS.latest);
expect(migrated[0].schemaState.tracks[CORE_FRAME_SCHEMA_TRACK]).toBe(
CORE_SUPPORTED_TRACKS[CORE_FRAME_SCHEMA_TRACK],
);
});
it("should normalize legacy frame backgrounds", () => {
@@ -51,7 +61,11 @@ describe("schema migration", () => {
type: "frame",
backgroundColor: "#a5d8ff",
}),
schemaVersion: undefined,
schemaState: {
tracks: {
[CORE_FRAME_SCHEMA_TRACK]: SCHEMA_INITIAL_TRACK_VERSION,
},
},
};
const migrated = migrateElements([frame])!;
@@ -60,10 +74,10 @@ describe("schema migration", () => {
);
});
it("should resolve invalid schema versions to initial", () => {
expect(resolveSchemaVersion(undefined)).toBe(SCHEMA_VERSIONS.initial);
expect(resolveSchemaVersion(0)).toBe(SCHEMA_VERSIONS.initial);
expect(resolveSchemaVersion(2)).toBe(2);
it("should resolve invalid track versions to initial", () => {
expect(resolveTrackVersion(undefined)).toBe(SCHEMA_INITIAL_TRACK_VERSION);
expect(resolveTrackVersion(0)).toBe(SCHEMA_INITIAL_TRACK_VERSION);
expect(resolveTrackVersion(2)).toBe(2);
});
it("should have a valid migration registry configuration", () => {
@@ -73,16 +87,34 @@ describe("schema migration", () => {
it("should reject invalid migration metadata", () => {
const invalidMigrations: SchemaMigration[] = [
{
version: 2.1,
id: "",
namespace: "core",
track: CORE_FRAME_SCHEMA_TRACK,
toVersion: 2.1,
title: "",
description: " ",
apply: (elements) => elements,
targetTypes: [],
apply: (element) => element,
},
{
version: 2.1,
id: "dup",
namespace: "core",
track: CORE_FRAME_SCHEMA_TRACK,
toVersion: 2.1,
title: "duplicate",
description: "duplicate version",
apply: (elements) => elements,
targetTypes: ["frame"],
apply: (element) => element,
},
{
id: "dup",
namespace: "core",
track: CORE_FRAME_SCHEMA_TRACK,
toVersion: 3,
title: "duplicate id",
description: "duplicate id",
targetTypes: ["frame"],
apply: (element) => element,
},
];
@@ -92,34 +124,62 @@ describe("schema migration", () => {
expect(errors.join("\n")).toContain("integer version");
expect(errors.join("\n")).toContain("title must be non-empty");
expect(errors.join("\n")).toContain("non-empty description");
expect(errors.join("\n")).toContain("Duplicate schema migration version");
expect(errors.join("\n")).toContain("Duplicate schema migration id");
expect(errors.join("\n")).toContain("at least one target type");
});
it("should reject versions at or below initial", () => {
const errors = validateSchemaMigrations([
{
version: SCHEMA_VERSIONS.initial,
id: "invalid-start",
namespace: "core",
track: CORE_FRAME_SCHEMA_TRACK,
toVersion: SCHEMA_INITIAL_TRACK_VERSION,
title: "invalid start",
description: "bad version",
apply: (elements) => elements,
targetTypes: ["frame"],
apply: (element) => element,
},
]);
expect(errors.join("\n")).toContain("greater than schema initial version");
expect(errors.join("\n")).toContain("must be greater than 1");
});
it("should reject latest-version mismatch", () => {
it("should reject core track/version mismatch", () => {
const errors = validateSchemaMigrations([
{
version: SCHEMA_VERSIONS.latest + 1,
id: "frame-v3",
namespace: "core",
track: CORE_FRAME_SCHEMA_TRACK,
toVersion: CORE_SUPPORTED_TRACKS[CORE_FRAME_SCHEMA_TRACK] + 1,
title: "future migration",
description: "future migration for test",
apply: (elements) => elements,
targetTypes: ["frame"],
apply: (element) => element,
},
]);
expect(errors.join("\n")).toContain(
"SCHEMA_VERSIONS.latest (2) must match last migration version",
`Core supported track "${CORE_FRAME_SCHEMA_TRACK}" (${CORE_SUPPORTED_TRACKS[CORE_FRAME_SCHEMA_TRACK]}) must match last migration version`,
);
});
it("should reject undeclared core tracks", () => {
const errors = validateSchemaMigrations([
{
id: "unknown-core-track",
namespace: "core",
track: "excalidraw.shape.unknown",
toVersion: 2,
title: "unknown core track",
description: "should require supported-track declaration",
targetTypes: ["rectangle"],
apply: (element) => element,
},
]);
expect(errors.join("\n")).toContain(
"must be declared in CORE_SUPPORTED_TRACKS",
);
});
@@ -129,7 +189,7 @@ describe("schema migration", () => {
type: "frame",
backgroundColor: "#a5d8ff",
}),
schemaVersion: undefined,
schemaState: { tracks: {} },
};
const withTempField = {
...frame,
@@ -147,15 +207,20 @@ describe("schema migration", () => {
);
});
it("should use per-element schema hints", () => {
it("should use per-element track hints", () => {
const frame = API.createElement({
type: "frame",
backgroundColor: "#ff0000",
});
const frameFromModernSource = {
...frame,
schemaVersion: SCHEMA_VERSIONS.latest,
} as typeof frame & { schemaVersion: number };
schemaState: {
tracks: {
[CORE_FRAME_SCHEMA_TRACK]:
CORE_SUPPORTED_TRACKS[CORE_FRAME_SCHEMA_TRACK],
},
},
};
const migrated = migrateElements([frameFromModernSource])!;
@@ -168,18 +233,23 @@ describe("schema migration", () => {
type: "frame",
backgroundColor: "#ff0000",
}),
schemaVersion: undefined,
schemaState: { tracks: {} },
};
const modernFrame = API.createElement({
type: "frame",
backgroundColor: "#00ff00",
});
const modernFrameWithHint = {
const modernFrameWithTrack = {
...modernFrame,
schemaVersion: SCHEMA_VERSIONS.latest,
} as typeof modernFrame & { schemaVersion: number };
schemaState: {
tracks: {
[CORE_FRAME_SCHEMA_TRACK]:
CORE_SUPPORTED_TRACKS[CORE_FRAME_SCHEMA_TRACK],
},
},
};
const migrated = migrateElements([legacyFrame, modernFrameWithHint])!;
const migrated = migrateElements([legacyFrame, modernFrameWithTrack])!;
expect(migrated[0].backgroundColor).toBe(
DEFAULT_ELEMENT_PROPS.backgroundColor,
@@ -187,20 +257,43 @@ describe("schema migration", () => {
expect(migrated[1].backgroundColor).toBe("#00ff00");
});
it("should stamp schemaVersion to latest after migration", () => {
const rect = API.createElement({ type: "rectangle" });
const migrated = migrateElements([rect])!;
expect(migrated[0].schemaVersion).toBe(SCHEMA_VERSIONS.latest);
it("should preserve higher-than-supported track versions", () => {
const frame = API.createElement({
type: "frame",
backgroundColor: "#ff0000",
});
const futureFrame = {
...frame,
schemaState: {
tracks: {
[CORE_FRAME_SCHEMA_TRACK]:
CORE_SUPPORTED_TRACKS[CORE_FRAME_SCHEMA_TRACK] + 1,
},
},
};
const migrated = migrateElements([futureFrame])!;
expect(migrated[0].schemaState.tracks[CORE_FRAME_SCHEMA_TRACK]).toBe(
CORE_SUPPORTED_TRACKS[CORE_FRAME_SCHEMA_TRACK] + 1,
);
expect(migrated[0].backgroundColor).toBe("#ff0000");
});
it("should preserve higher-than-latest schema versions", () => {
const rect = API.createElement({ type: "rectangle" });
const futureRect = {
...rect,
schemaVersion: SCHEMA_VERSIONS.latest + 1,
} as typeof rect & { schemaVersion: number };
it("should normalize invalid schema state and preserve unknown tracks", () => {
const rect = {
...API.createElement({ type: "rectangle" }),
schemaState: {
tracks: {
"host.myapp.card": 4,
[CORE_FRAME_SCHEMA_TRACK]: 0,
},
},
};
const migrated = migrateElements([futureRect])!;
expect(migrated[0].schemaVersion).toBe(SCHEMA_VERSIONS.latest + 1);
const migrated = migrateElements([rect])!;
expect(migrated[0].schemaState.tracks[CORE_FRAME_SCHEMA_TRACK]).toBe(
SCHEMA_INITIAL_TRACK_VERSION,
);
expect(migrated[0].schemaState.tracks["host.myapp.card"]).toBe(4);
});
});
@@ -1020,7 +1020,9 @@ exports[`contextMenu element > right-clicking on a group should select whole gro
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1055,7 +1057,9 @@ exports[`contextMenu element > right-clicking on a group should select whole gro
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1218,7 +1222,9 @@ exports[`contextMenu element > selecting 'Add to library' in context menu adds e
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1274,7 +1280,9 @@ exports[`contextMenu element > selecting 'Add to library' in context menu adds e
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -1435,7 +1443,9 @@ exports[`contextMenu element > selecting 'Bring forward' in context menu brings
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1014066025,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1468,7 +1478,9 @@ exports[`contextMenu element > selecting 'Bring forward' in context menu brings
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1524,7 +1536,9 @@ exports[`contextMenu element > selecting 'Bring forward' in context menu brings
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -1579,7 +1593,9 @@ exports[`contextMenu element > selecting 'Bring forward' in context menu brings
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -1621,10 +1637,16 @@ exports[`contextMenu element > selecting 'Bring forward' in context menu brings
"id0": {
"deleted": {
"index": "a2",
"schemaState": {
"tracks": {},
},
"version": 4,
},
"inserted": {
"index": "a0",
"schemaState": {
"tracks": {},
},
"version": 3,
},
},
@@ -1773,7 +1795,9 @@ exports[`contextMenu element > selecting 'Bring to front' in context menu brings
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1014066025,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1806,7 +1830,9 @@ exports[`contextMenu element > selecting 'Bring to front' in context menu brings
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1862,7 +1888,9 @@ exports[`contextMenu element > selecting 'Bring to front' in context menu brings
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -1917,7 +1945,9 @@ exports[`contextMenu element > selecting 'Bring to front' in context menu brings
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -1959,10 +1989,16 @@ exports[`contextMenu element > selecting 'Bring to front' in context menu brings
"id0": {
"deleted": {
"index": "a2",
"schemaState": {
"tracks": {},
},
"version": 4,
},
"inserted": {
"index": "a0",
"schemaState": {
"tracks": {},
},
"version": 3,
},
},
@@ -2113,7 +2149,9 @@ exports[`contextMenu element > selecting 'Copy styles' in context menu copies st
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -2169,7 +2207,9 @@ exports[`contextMenu element > selecting 'Copy styles' in context menu copies st
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -2328,7 +2368,9 @@ exports[`contextMenu element > selecting 'Delete' in context menu deletes elemen
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -2384,7 +2426,9 @@ exports[`contextMenu element > selecting 'Delete' in context menu deletes elemen
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -2422,10 +2466,16 @@ exports[`contextMenu element > selecting 'Delete' in context menu deletes elemen
"id0": {
"deleted": {
"isDeleted": true,
"schemaState": {
"tracks": {},
},
"version": 4,
},
"inserted": {
"isDeleted": false,
"schemaState": {
"tracks": {},
},
"version": 3,
},
},
@@ -2576,7 +2626,9 @@ exports[`contextMenu element > selecting 'Duplicate' in context menu duplicates
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -2609,7 +2661,9 @@ exports[`contextMenu element > selecting 'Duplicate' in context menu duplicates
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1014066025,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -2665,7 +2719,9 @@ exports[`contextMenu element > selecting 'Duplicate' in context menu duplicates
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -2720,7 +2776,9 @@ exports[`contextMenu element > selecting 'Duplicate' in context menu duplicates
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -2888,7 +2946,9 @@ exports[`contextMenu element > selecting 'Group selection' in context menu group
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -2923,7 +2983,9 @@ exports[`contextMenu element > selecting 'Group selection' in context menu group
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1014066025,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -2979,7 +3041,9 @@ exports[`contextMenu element > selecting 'Group selection' in context menu group
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -3034,7 +3098,9 @@ exports[`contextMenu element > selecting 'Group selection' in context menu group
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -3096,10 +3162,16 @@ exports[`contextMenu element > selecting 'Group selection' in context menu group
"groupIds": [
"id9",
],
"schemaState": {
"tracks": {},
},
"version": 4,
},
"inserted": {
"groupIds": [],
"schemaState": {
"tracks": {},
},
"version": 3,
},
},
@@ -3108,10 +3180,16 @@ exports[`contextMenu element > selecting 'Group selection' in context menu group
"groupIds": [
"id9",
],
"schemaState": {
"tracks": {},
},
"version": 4,
},
"inserted": {
"groupIds": [],
"schemaState": {
"tracks": {},
},
"version": 3,
},
},
@@ -3262,7 +3340,9 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
"opacity": 60,
"roughness": 2,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#e03131",
"strokeStyle": "dotted",
@@ -3295,7 +3375,9 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
"opacity": 60,
"roughness": 2,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1898319239,
"strokeColor": "#e03131",
"strokeStyle": "dotted",
@@ -3351,7 +3433,9 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -3406,7 +3490,9 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -3439,10 +3525,16 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
"updated": {
"id3": {
"deleted": {
"schemaState": {
"tracks": {},
},
"strokeColor": "#e03131",
"version": 4,
},
"inserted": {
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"version": 3,
},
@@ -3465,10 +3557,16 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
"id3": {
"deleted": {
"backgroundColor": "#a5d8ff",
"schemaState": {
"tracks": {},
},
"version": 5,
},
"inserted": {
"backgroundColor": "transparent",
"schemaState": {
"tracks": {},
},
"version": 4,
},
},
@@ -3490,10 +3588,16 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
"id3": {
"deleted": {
"fillStyle": "cross-hatch",
"schemaState": {
"tracks": {},
},
"version": 6,
},
"inserted": {
"fillStyle": "solid",
"schemaState": {
"tracks": {},
},
"version": 5,
},
},
@@ -3514,10 +3618,16 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
"updated": {
"id3": {
"deleted": {
"schemaState": {
"tracks": {},
},
"strokeStyle": "dotted",
"version": 7,
},
"inserted": {
"schemaState": {
"tracks": {},
},
"strokeStyle": "solid",
"version": 6,
},
@@ -3540,10 +3650,16 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
"id3": {
"deleted": {
"roughness": 2,
"schemaState": {
"tracks": {},
},
"version": 8,
},
"inserted": {
"roughness": 1,
"schemaState": {
"tracks": {},
},
"version": 7,
},
},
@@ -3565,10 +3681,16 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
"id3": {
"deleted": {
"opacity": 60,
"schemaState": {
"tracks": {},
},
"version": 9,
},
"inserted": {
"opacity": 100,
"schemaState": {
"tracks": {},
},
"version": 8,
},
},
@@ -3601,6 +3723,9 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
"fillStyle": "cross-hatch",
"opacity": 60,
"roughness": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#e03131",
"strokeStyle": "dotted",
"version": 4,
@@ -3610,6 +3735,9 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
"fillStyle": "solid",
"opacity": 100,
"roughness": 1,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"version": 3,
@@ -3760,7 +3888,9 @@ exports[`contextMenu element > selecting 'Send backward' in context menu sends e
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 238820263,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -3793,7 +3923,9 @@ exports[`contextMenu element > selecting 'Send backward' in context menu sends e
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -3849,7 +3981,9 @@ exports[`contextMenu element > selecting 'Send backward' in context menu sends e
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -3904,7 +4038,9 @@ exports[`contextMenu element > selecting 'Send backward' in context menu sends e
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -3938,10 +4074,16 @@ exports[`contextMenu element > selecting 'Send backward' in context menu sends e
"id3": {
"deleted": {
"index": "Zz",
"schemaState": {
"tracks": {},
},
"version": 4,
},
"inserted": {
"index": "a1",
"schemaState": {
"tracks": {},
},
"version": 3,
},
},
@@ -4090,7 +4232,9 @@ exports[`contextMenu element > selecting 'Send to back' in context menu sends el
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1014066025,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -4123,7 +4267,9 @@ exports[`contextMenu element > selecting 'Send to back' in context menu sends el
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -4179,7 +4325,9 @@ exports[`contextMenu element > selecting 'Send to back' in context menu sends el
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -4234,7 +4382,9 @@ exports[`contextMenu element > selecting 'Send to back' in context menu sends el
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -4268,10 +4418,16 @@ exports[`contextMenu element > selecting 'Send to back' in context menu sends el
"id3": {
"deleted": {
"index": "Zz",
"schemaState": {
"tracks": {},
},
"version": 4,
},
"inserted": {
"index": "a1",
"schemaState": {
"tracks": {},
},
"version": 3,
},
},
@@ -4423,7 +4579,9 @@ exports[`contextMenu element > selecting 'Ungroup selection' in context menu ung
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -4456,7 +4614,9 @@ exports[`contextMenu element > selecting 'Ungroup selection' in context menu ung
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 238820263,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -4512,7 +4672,9 @@ exports[`contextMenu element > selecting 'Ungroup selection' in context menu ung
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -4567,7 +4729,9 @@ exports[`contextMenu element > selecting 'Ungroup selection' in context menu ung
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -4629,10 +4793,16 @@ exports[`contextMenu element > selecting 'Ungroup selection' in context menu ung
"groupIds": [
"id9",
],
"schemaState": {
"tracks": {},
},
"version": 4,
},
"inserted": {
"groupIds": [],
"schemaState": {
"tracks": {},
},
"version": 3,
},
},
@@ -4641,10 +4811,16 @@ exports[`contextMenu element > selecting 'Ungroup selection' in context menu ung
"groupIds": [
"id9",
],
"schemaState": {
"tracks": {},
},
"version": 4,
},
"inserted": {
"groupIds": [],
"schemaState": {
"tracks": {},
},
"version": 3,
},
},
@@ -4672,24 +4848,36 @@ exports[`contextMenu element > selecting 'Ungroup selection' in context menu ung
"id0": {
"deleted": {
"groupIds": [],
"schemaState": {
"tracks": {},
},
"version": 5,
},
"inserted": {
"groupIds": [
"id9",
],
"schemaState": {
"tracks": {},
},
"version": 4,
},
},
"id3": {
"deleted": {
"groupIds": [],
"schemaState": {
"tracks": {},
},
"version": 5,
},
"inserted": {
"groupIds": [
"id9",
],
"schemaState": {
"tracks": {},
},
"version": 4,
},
},
@@ -5715,7 +5903,9 @@ exports[`contextMenu element > shows 'Group selection' in context menu for multi
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -5748,7 +5938,9 @@ exports[`contextMenu element > shows 'Group selection' in context menu for multi
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 400692809,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -5804,7 +5996,9 @@ exports[`contextMenu element > shows 'Group selection' in context menu for multi
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -5859,7 +6053,9 @@ exports[`contextMenu element > shows 'Group selection' in context menu for multi
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -6943,7 +7139,9 @@ exports[`contextMenu element > shows 'Ungroup selection' in context menu for gro
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -6978,7 +7176,9 @@ exports[`contextMenu element > shows 'Ungroup selection' in context menu for gro
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 238820263,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -7034,7 +7234,9 @@ exports[`contextMenu element > shows 'Ungroup selection' in context menu for gro
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -7089,7 +7291,9 @@ exports[`contextMenu element > shows 'Ungroup selection' in context menu for gro
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -7173,10 +7377,16 @@ exports[`contextMenu element > shows 'Ungroup selection' in context menu for gro
"groupIds": [
"id12",
],
"schemaState": {
"tracks": {},
},
"version": 4,
},
"inserted": {
"groupIds": [],
"schemaState": {
"tracks": {},
},
"version": 3,
},
},
@@ -7185,10 +7395,16 @@ exports[`contextMenu element > shows 'Ungroup selection' in context menu for gro
"groupIds": [
"id12",
],
"schemaState": {
"tracks": {},
},
"version": 4,
},
"inserted": {
"groupIds": [],
"schemaState": {
"tracks": {},
},
"version": 3,
},
},
@@ -9878,7 +10094,9 @@ exports[`contextMenu element > shows context menu for element > [end of test] el
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -9911,7 +10129,9 @@ exports[`contextMenu element > shows context menu for element > [end of test] el
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -9944,7 +10164,9 @@ exports[`contextMenu element > shows context menu for element > [end of test] el
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -10006,7 +10228,9 @@ exports[`contextMenu element > shows context menu for element > [end of test] un
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
"strokeWidth": 2,
@@ -35,7 +35,9 @@ exports[`Test dragCreate > add element to the scene when pointer dragging long e
"roundness": {
"type": 2,
},
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"startArrowhead": null,
"startBinding": null,
@@ -72,7 +74,9 @@ exports[`Test dragCreate > add element to the scene when pointer dragging long e
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -107,7 +111,9 @@ exports[`Test dragCreate > add element to the scene when pointer dragging long e
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -153,7 +159,9 @@ exports[`Test dragCreate > add element to the scene when pointer dragging long e
"polygon": false,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"startArrowhead": null,
"startBinding": null,
@@ -190,7 +198,9 @@ exports[`Test dragCreate > add element to the scene when pointer dragging long e
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -1,7 +1,7 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`export > export svg-embedded scene > svg-embdedded scene export output 1`] = `
"<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" width="36" height="36"><!-- svg-source:excalidraw --><metadata><!-- payload-type:application/vnd.excalidraw+json --><!-- payload-version:2 --><!-- payload-start -->eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nHVTwW7bMFxmvfcrXGb3WqxOiu6QW7t1WFx1MDAwZu2hXHUwMDE51sPQg2oxNlx1MDAxMUVcdTAwMTIkuklcdTAwMTZcdTAwMDTYZ/S2X9wnjFI8K3K7XHUwMDA0MKBHUnx8fNqdXHUwMDE0RUlbXHUwMDBi5awoYVNcdTAwMGKF0ol1eVx1MDAxNvBcdTAwMTdwXHUwMDFljebQNJ696VxcXHUwMDFkM1tcIjs7P1eGXHUwMDBiWuNpdlFV1aFcYlx1MDAxNKxAk+e0XHUwMDFmfC6KXfxyXHUwMDA0ZSi9imlcdTAwMTH415dgQ1x03TBUXHKnbXZao6SWkcnHXHUwMDAxalx1MDAwMZuWckzoRkFW6MmZJXwyyrjQ8XRcdTAwMDLhn5o+i3rZONNpOeSQXHUwMDEz2lvheJiUt0Cl5rSNt7NcdTAwMWWsVjnq8dhTnI7w/1Vx06bV4INgk1x1MDAwMTVW1Ehh+EmVplxiXGbtrYzaPiVOTqzgNoirO6VcdTAwMDZcdTAwMTi1hM1cdTAwMTiMI/bdsoBcdTAwMDeQXHUwMDE5g7T8hPm6hZX4ntviOPve6DpcdTAwMTdcdTAwMWX9Z3ZcdTAwMDTFy1x1MDAxN0J5SJJcdTAwMDcqN8ktXHUwMDE5nc5KQSNGXG71cpzHXHUwMDBlXFy+c3d0XHUwMDE0a/3n9+uvo+VcdTAwMTlNc/xcdTAwMTlcYk6rXGb9XCJWqILal9lcdTAwMTVXXG6bMGepYHFkXHUwMDAyXHUwMDFllpCdP4TJ2Fx1MDAxNK35PoFcdTAwMWHc25VcdTAwMTiHXHJqob69S090ZFx1MDAxZcBcdTAwMWZcYpLr4Hhy+Dr4/MP0Mlx1MDAwNvb8jS4ohbVzYr04enht7Fx1MDAxNJSjUVx1MDAwZlx1MDAxOIFNY0bozki40eJZjXUsX1x1MDAxMNbXb1x1MDAxZsbpXCL+euL9XG7uOkU451XXxD5cYvvcXHUwMDA1fvvIj19ccvTQ/i+oli93In0=<!-- payload-end --></metadata><defs><style class="style-fonts">
"<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36" width="36" height="36"><!-- svg-source:excalidraw --><metadata><!-- payload-type:application/vnd.excalidraw+json --><!-- payload-version:2 --><!-- payload-start -->eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nHVTwW7bMFxmve8rXGb3OrROhu6QW7t1WFx1MDAwZt1hXHUwMDE5sMOwg2oxNmFFXHUwMDEyJLpJXHUwMDE2XHUwMDA06Gfstl/sJ5RSXFwrcrtcdTAwMThcYqBHinzke9q/K4qSdlx1MDAxNspFUcK2XHUwMDE2XG6lXHUwMDEzm/J9wFx1MDAxZsB5NJpD83j2pnd1zGyJ7OLiQlx1MDAxOb7QXHUwMDFhT4tcdTAwMGZVVVx1MDAxZC+BgjVo8pz2i89FsY//XHUwMDFjQVx1MDAxOa5exbRcYrz0JdhSQrdcZlXjaZedNiipZWT2cYRawKalXHUwMDFjXHUwMDEzulGQXfTkTFx1MDAwN5+MMi50PJtB+FLTe1F3jTO9lmNcdTAwMGU5ob1cdTAwMTWOh0l5K1RqSbtYnffB2yonPX5cdTAwMGVcdTAwMTTnXHUwMDEz/H+3uGnTavBhYbNcdTAwMTE1VtRIYfhZlaZcYlxm7a2Mu/2dODmxhtuwXFzdKzXCqCVsp2BcdTAwMWNx6JZcdTAwMDU8gMxcdTAwMTgk8Vx1MDAxM+brXHUwMDE21mJJgsIkL8JcdTAwMTZxV3VcdTAwMTdq7lx1MDAwZlx1MDAwM3iYXHUwMDE2+mZ0nWuC/jObhWLflVBcdTAwMWWSXHUwMDFhgeVNMlLGtLdS0ISsQt1N89ic3Vx1MDAxYrWj2ViGp39/XHUwMDFmT3Q1mpb4J1x1MDAxMJxXXHUwMDE5+kWsUVx1MDAwNSEus1x1MDAxMldcbpuwnFLB6sRcdTAwMWY8LCE/ijFMxqZozfVcdTAwMDRqcK/VMlx1MDAwZVx1MDAxYtRC/XiTnujJfFx1MDAwN38kSK6H08nh6/hcdTAwMDTO55cxXHUwMDEwVIhcdTAwMDYphbW5XmxcIpSTUY9cdTAwMTiBTWNG6M5IuNHiXk33WD4gbK5fv5mzVfxccsRcdTAwMDdcdO56RbhkqWtiXHUwMDFmjC6JXHUwMDBlXHRcdTAwMGZcblx1MDAwNujwXGZOizVKIn0=<!-- payload-end --></metadata><defs><style class="style-fonts">
</style></defs><rect x="0" y="0" width="36" height="36" fill="#ffffff"></rect><g transform="translate(10 10) rotate(0 8 8)" data-id="A"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, sans-serif, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">😀</text></g></svg>"
`;
File diff suppressed because it is too large Load Diff
@@ -18,7 +18,9 @@ exports[`duplicate element on move when ALT is clicked > rectangle 5`] = `
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -51,7 +53,9 @@ exports[`duplicate element on move when ALT is clicked > rectangle 6`] = `
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1505387817,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -84,7 +88,9 @@ exports[`move element > rectangle 5`] = `
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -122,7 +128,9 @@ exports[`move element > rectangles with binding arrow 5`] = `
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -160,7 +168,9 @@ exports[`move element > rectangles with binding arrow 6`] = `
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1116226695,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -216,7 +226,9 @@ exports[`move element > rectangles with binding arrow 7`] = `
"roundness": {
"type": 2,
},
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 23633383,
"startArrowhead": null,
"startBinding": {
@@ -37,7 +37,9 @@ exports[`multi point mode in linear elements > arrow 3`] = `
"roundness": {
"type": 2,
},
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"startArrowhead": null,
"startBinding": null,
@@ -89,7 +91,9 @@ exports[`multi point mode in linear elements > line 3`] = `
"polygon": false,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"startArrowhead": null,
"startBinding": null,
File diff suppressed because it is too large Load Diff
@@ -33,7 +33,9 @@ exports[`select single element on the scene > arrow 1`] = `
"roundness": {
"type": 2,
},
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"startArrowhead": null,
"startBinding": null,
@@ -81,7 +83,9 @@ exports[`select single element on the scene > arrow escape 1`] = `
"polygon": false,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"startArrowhead": null,
"startBinding": null,
@@ -116,7 +120,9 @@ exports[`select single element on the scene > diamond 1`] = `
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -149,7 +155,9 @@ exports[`select single element on the scene > ellipse 1`] = `
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -182,7 +190,9 @@ exports[`select single element on the scene > rectangle 1`] = `
"opacity": 100,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": 1278240551,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -31,7 +31,9 @@ exports[`repairing bindings > should strip arrow binding if repair throws 1`] =
],
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": null,
@@ -79,7 +81,9 @@ exports[`restoreElements > should restore arrow element correctly 1`] = `
],
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": null,
@@ -120,7 +124,9 @@ exports[`restoreElements > should restore correctly with rectangle, ellipse and
"roundness": {
"type": 3,
},
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "red",
"strokeStyle": "dashed",
@@ -159,7 +165,9 @@ exports[`restoreElements > should restore correctly with rectangle, ellipse and
"roundness": {
"type": 3,
},
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "red",
"strokeStyle": "dashed",
@@ -198,7 +206,9 @@ exports[`restoreElements > should restore correctly with rectangle, ellipse and
"roundness": {
"type": 3,
},
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "red",
"strokeStyle": "dashed",
@@ -242,7 +252,9 @@ exports[`restoreElements > should restore freedraw element correctly 1`] = `
"pressures": [],
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"simulatePressure": true,
"strokeColor": "#1e1e1e",
@@ -289,7 +301,9 @@ exports[`restoreElements > should restore line and draw elements correctly 1`] =
"polygon": false,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": null,
@@ -337,7 +351,9 @@ exports[`restoreElements > should restore line and draw elements correctly 2`] =
"polygon": false,
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"startArrowhead": null,
"startBinding": null,
@@ -378,7 +394,9 @@ exports[`restoreElements > should restore text element correctly passing value f
"originalText": "text",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -421,7 +439,9 @@ exports[`restoreElements > should restore text element correctly with unknown fo
"originalText": "",
"roughness": 1,
"roundness": null,
"schemaVersion": 2,
"schemaState": {
"tracks": {},
},
"seed": Any<Number>,
"strokeColor": "#1e1e1e",
"strokeStyle": "solid",
@@ -132,8 +132,8 @@ describe("restoreElements", () => {
});
const legacyFrame = {
...frame,
schemaVersion: undefined,
} as typeof frame & { schemaVersion?: number };
schemaState: { tracks: {} },
};
const restoredLibraryItems = restore.restoreLibraryItems(
[
+3
View File
@@ -24,6 +24,9 @@ const elementBase: Omit<ExcalidrawElement, "type"> = {
index: null,
seed: 1041657908,
version: 120,
schemaState: {
tracks: {},
},
versionNonce: 1188004276,
isDeleted: false,
boundElements: null,
+3
View File
@@ -188,6 +188,7 @@ export class API {
roundness?: ExcalidrawGenericElement["roundness"];
roughness?: ExcalidrawGenericElement["roughness"];
opacity?: ExcalidrawGenericElement["opacity"];
schemaState?: ExcalidrawGenericElement["schemaState"];
// text props
text?: T extends "text" ? ExcalidrawTextElement["text"] : never;
fontSize?: T extends "text" ? ExcalidrawTextElement["fontSize"] : never;
@@ -246,6 +247,7 @@ export class API {
| "groupIds"
| "link"
| "updated"
| "schemaState"
> = {
seed: 1,
x,
@@ -276,6 +278,7 @@ export class API {
opacity: rest.opacity ?? appState.currentItemOpacity,
boundElements: rest.boundElements ?? null,
locked: rest.locked ?? false,
...(rest.schemaState ? { schemaState: rest.schemaState } : {}),
};
switch (type) {
case "rectangle":
+3
View File
@@ -359,6 +359,7 @@ describe("Basic lasso selection tests", () => {
...e,
angle: e.angle as Radians,
index: null,
schemaState: { tracks: {} },
} as ExcalidrawElement),
);
@@ -1044,6 +1045,7 @@ describe("Special cases", () => {
...e,
index: null,
angle: e.angle as Radians,
schemaState: { tracks: {} },
})) as ExcalidrawElement[];
h.elements = elements;
@@ -1763,6 +1765,7 @@ describe("Special cases", () => {
...e,
index: null,
angle: e.angle as Radians,
schemaState: { tracks: {} },
})) as ExcalidrawElement[];
h.elements = elements;
@@ -240,7 +240,7 @@ exports[`exportToSvg > with elements that have a link 1`] = `
`;
exports[`exportToSvg > with exportEmbedScene 1`] = `
"<!-- svg-source:excalidraw --><metadata><!-- payload-type:application/vnd.excalidraw+json --><!-- payload-version:2 --><!-- payload-start -->eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1WW2vbMFx1MDAxOH3vrzDaa1llJ2nSvGXrLoWxwTIorOxBtT7bwrLkSnIuXHUwMDBi+e+T5MVyvLLnNYtcdTAwMDOG7350dD6c3UVcdTAwMTQhs61cdTAwMDHNI1x1MDAwNJuUcEZcdTAwMTVZo0vnX4HSTFxuXHUwMDFiSrytZaNSn1lcdTAwMThTz6+uuLRcdTAwMDWF1GY+wlx1MDAxOLdFwKFcdTAwMDJhtE17sHZcdTAwMTTt/NtGXHUwMDE4daWre/X0ZZGVTNDkKa2mn25cdTAwMTdcdTAwMWa++1KftLE543jc2Vs3fTTt7DWjprC+XHUwMDE4485XXHUwMDAwy1x1MDAwYjNwXHUwMDEykXOHNXi0UbKEt5JL5YC8wv5cdKNcdTAwMWZJWuZKNoKGnHhCyGNcdTAwMTZyMsb50mx5y1x1MDAwMkmLRlx1MDAwMVx1MDAxYUy4P0BcdTAwMWP4uzotLcuhyo7MXHUwMDBiXHUwMDAxWlx1MDAxZtXImqTMbFx1MDAwN6dy+Oo76tn9XHUwMDExUClSwZ2jVzSc91x1MDAxYlx1MDAwYvq78VHAclx1MDAwZo5oRHrH11x1MDAwMNRPXHUwMDFix9eT6VxynnWRoIM4wUPvZym8JuJ4NsN4nEyvw1x1MDAxOH1r1WB824xwXHKBaofsXVDKXHUwMDExuqampC1cbmxwJsphnlVf+Uzvg5opI5VcdTAwMTRcdTAwMTR5//7yrMV/XYvx6WpcdTAwMTE4Z7WGl6HFXHUwMDE43O//1mJyulo0sDG9i5PCLNlPXHUwMDE36Z3Bed+TinHH8yS0cKW2hVQsZ4Lw6LjXwf3t72nOWnCWO+JcdTAwMTCHrFx1MDAxN7LcXHUwMDE5Zv9TdGEj61x1MDAxME0tKsJcdTAwMDSoP6/U8lx1MDAwMFx1MDAxZju5v05cdTAwMDJm0lx1MDAxOPlcdTAwMTV0e0TPyHlcdF/IXHUwMDEyjs5L2C1hXHUwMDAwfkpLaN9eKIjU9dJYYm24XUm0YrB+84zoM/+4L6lfYSd6cLe021/sf1x1MDAwMVSoRdMifQ==<!-- payload-end --></metadata><defs><style class="style-fonts">
"<!-- svg-source:excalidraw --><metadata><!-- payload-type:application/vnd.excalidraw+json --><!-- payload-version:2 --><!-- payload-start -->eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1WW2/TMFx1MDAxNH7fr4jCK2JJ2q6lb4VxmYRAokiTmPbgxSeJVcfObKdcdTAwMTeq/nd8nDZOwsRcdTAwMDNPXGaaSpF8rt/5/Fx1MDAxZKX7iyBcYs2ugnBcdTAwMWWEsE1cdGdUkU34XHUwMDEy7WtQmklhXYk7a1mr1EVcdTAwMTbGVPPLSy5tQiG1mY+iKGqSgENcdMJoXHUwMDFidmfPQbB3b+thXHUwMDE0U9e36vHLXCJbMUGTx7ScfrpefPjuUl3Q1saM43F73mH30bQ9b1x1MDAxODWFtcVR1NpcbmB5YVx1MDAwNkZcInKOWL1FXHUwMDFiJVfwVnKpXHUwMDEwyIvIPb71XHUwMDAzSVe5krWgPiaeXHUwMDEw8pD5mIxxvjQ73rBA0qJWXHUwMDEwXHUwMDBlOtyeIFx1MDAwZextnpaWZZ9lW+aFXHUwMDAwrXs5slwiKTO7wVSIr7qhjt17j0qRXHUwMDEybpBeUXPeLSzosXDPYblcdTAwMDckOiSd8TVcdTAwMDB13cbx1WT6Opq1XHUwMDFlr4M46dCZXHUwMDE2UJKlIVx1MDAwNoc63TLKSVlcIrHn/nA0XHUwMDFlhqU+S+GEXHUwMDE0x7NZXHUwMDE0jZPplcemr62EjMOSXHUwMDExrsHfXHUwMDBmjvPOy6s3Ul1R0iR5XG45XHUwMDEzq2GclezqidqnXHUwMDE1oIyUUtDwolx1MDAwM/ss4L9YwPFZwD1cdTAwMDFcdTAwMDPnrNLwPFx1MDAwNFx1MDAxY1x1MDAwM/7+b1x1MDAwMSdnXHUwMDAx91x1MDAwNGxgazq3LYVZslx1MDAxZujpXGaO1vekZFx1MDAxYy9n4ktgqi0hXHUwMDE1y5kgPOjXOpm//T5cZk9cdTAwMGLOcmQ75JB1XFyWO8PsX57WbWTlvalFRZhcdTAwMDD1q1x1MDAwZSxcdTAwMGbwsd2RV4nHTGojv4JuRnSMnDf3mWzu6Ly5XHLmP91cXFx1MDAwZvxf2lxc+3bqXG5JVfVvOFxcM9i8eWJTMvfgN9vdNm5cblx1MDAxY0Vw+Fx0stl5kyJ9<!-- payload-end --></metadata><defs><style class="style-fonts">
@font-face { font-family: Excalifont; src: url(data:font/woff2;base64,d09GMgABAAAAAAf0AA4AAAAADbQAAAegAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbgjgcNAZgAHwRCAqPYItcCxoAATYCJAMwBCAFgxgHIBujClGUblKX7Edh3Pg8OJbt5MlDFPwWk6FmJ08terdayeDx9O8Fa5eunTJ1ykAUGuAvgOF5bPfuH0nXrvQrNkFoNlERBLIQDd/mj2kP7fdg8avL4M/sm4cbu4L2i1VQVjShz/+90/YE3IJFmOC+f0Z1Xhs3bVxiJZZGa1IgY5sHCJ2EM2iBndkLWsZvFxCAhRBGCknKEOQenHCpmE2fVQTl1atzWyjvzs3aQPnWd20PJQZeG3mQp1lnLimFBAhOKFIQSrGa+vOB69gLCRkjLr4NIjd5rXiz8hhu+LIe9DZCgkJjmZEy34MkhXNBJ8GhNMMnJUgmSYA0AowAwT2zRor05iZAeN/80c4UkYlgSTOaKgOQCUOSE5F+z6+DXqndDTk4CEHP2v3/aKw7lXQXgAUAQP5+kgIpTYMHT9MEjIyWxJ5V5jAzgnrNtNBKWx101tXee86rA5O1f1fiIzEtJsS4GBMjYlikIhEvwwXDjYgiApUFdjgCFAA1m2GorwgdA5a6fzxxX0ei+Eqw6MspHfbmte7eLSh2FSEREgnySedVN+VfsbKAVQygCrGALXgDQoSA0kZqfB2OiyyaZolc/i3tnXswySlmifL9eo1ReyWQcYadAK/DD9c80uaI4pamykJM2hp/MF2uj+teZm9LiRlrltgBlcVYlWVWf+WPTpVJj40Kz9Gvi5p21Zcov8bKEL+5Uirz+j2Hjzr+99zosad2XtbpfsbKgyIQ3RJHxrTH1ysQQAjTUaii13B+OTtxrFoLubjpMYtit2uul6DdSPvKaQl/9FkppthYCXEvjoEdStVVjti2fUQf34q9YjychmIsxCAjKkj0GW4mIhlX1snPOEVRVq4UMRQwkzJNhK143IsBOlghz9meJAGf4apbAmYRMj2hsj5X1OGDPuIKXoOyN8yIMYbeusXTa9f4a+1UvYG9FgQxzoQBUoSPD5/ezAuQIP8s8IyVrUGrwSxC95WPAdlx3EkkQq5yNjcaKAAZ4LEHheIMvgHV3fe6X41/6rzCiMBwSxrnvl9RcR0gK5fy4jDVigBySy99iwlppT9aTlWIMSMKBx9WkbupSbZXNC/CKUC6z53jA0mS7340zruutV7xYguW6p/01tYHOQZQ7ptAagFiLAzFWqyWUwN8/eNGSyn2elPguvF9At0XUNlNv4t202nq+EnkKvdW6aLVlJUxhpXYUqMsn5svp9eoTpvKKf6BY8QwAkaJWYSggEuximEYiCVE0TjN5ojkVoznAP0GytsVT1SesrOn/s8LsMpVpXtSc6To4sT6XIl1q0jH96rd5/g5vmi35+y6eeYPNqjBGHtX0nKFGywfPr19aO9Gh/Q1sWZGuqckOoOJmlK2pSPTSgm/46h389ap+VmOnxsPdspP82Xyy2l7u6i2908pVjRkDbEddOKOprOPJ/94eJ59fi6jDtB6VbzuwXb5puJcqcKnUeM72fFnIlssAv/Z6uMq2s1Jd8qpd7DZo538w5PG7cHm2TU2TD41PjYiaUSikYspa/kjJ84AdgqXsT226/L+fW6j99QmJZlWN99tfcdbUPO17tLu8+gVw73h3OfmurdS9BCa5twNfokJhx7/agK3fHC9rXVewbT0kZG9vXqRBOtS6xGOZ5dC3pwleZIyidL1le+xC3btOlwJkXqGESosoDUG2TqcuE/6OcolnOykkpKdD+5l7+JODWBpAycPke+STDMRWidsWCLvfQJbKM7JpnkLG1WV73qjg6eZ1EMVF1NgG5rTaZF2r7tJNs2VzabNrTQfhSOtgxRxRLP5mldJB6/b6R5LWk9ss9nNUGyTTx8iytdCS9xlAlvtN/1hTrYObLVe5T8zLWNk2oko/bq0dv1cvjXrGC5k+pfYm+L1MtXCFsSzKDTY/dhu66JJWqlfkIxw7T5ufjDBa4pCy7ObPC0cojzlZMlCh2VjKwfX8qy5cpyRt1hp6DeKs/UZjc6zfGxC0rJHl1IUtIm2p7Tg+6VKn8vbfWR9fHljiebwTXPXTQ13HmoSbMssDsa32NnSfmmoH92xuU/E7U2qS8vWYFD9D73VJodqvWU8l7tB+b9ZdPiXvC2qoboerfoamG78+oOX7uWn1/WJy87rJPSHcVmUO7sN0ypzcG5zdfzU8k/NSh5OCbHvUSJlOk2xGrkmubA+nV7YtUCdoJk2vZ/dNSvrAkFnE0toKlC7rHllSrrOzt4Yb91LaLga9TtY+etg/uCpE8rVr604yv7YaE2x450wAACIfUvVNvFrrWXyNylLvwSAR70CtQDwePGbPuLQ/32Y10wCAClKi8AXKzralCj+/e0Dwri9RW2ArkwEqBW+cYJzghDkKyuPEB0FElKG8DIXEQkASS4s/2PSN2DGs1Bi6eh9EhVoZDAH0NblyEbw9tsoChtttEDDbQxvDTZWKm+YcYcDOj01qtdWK8110F5XIQq+nMJuwnpSopmb7KJVWbUgQqhwkyQxlOd76aglFYEKoxAJ8OeFkYPjBPTuQejsbXStQgY5klp1cr1LoQHSUa8StKqVbKnrXAqNAgg8wm1EB6RBL7ejLWnSmSI9hGJQZdAW2trTXRJoBsJm6M5VNQlFM3yJ/7EAAAA=); }
@font-face { font-family: Excalifont; src: url(data:font/woff2;base64,d09GMgABAAAAAAHcAA0AAAAAA9gAAAGMAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGx4cNAZgAAQRCAoAKgsEAAE2AiQDBAQgBYMYByAbHQPIrgp4MjSeIQLqpl4jnPFQwveqm205gmrZevZ2/8kKGaJ6ictBuCwMMnsKo8hC4RwaLBrJ7dXaFrFk0Re1e/Dk3t9wCUVrYAiZkgiZ5rGDVFdY04wBF4APOCzXHr/ljrNIDqLAY/slkQf0SyjxLNBaAq8Z1AJqYW5j0GjbckRLQhoJCgwYoyfY3q33QS5DrSAwYB4hFruNve4WoN2On4P29GEFWsC+nVM/UvSlVwIcsWycI/5gbqfUhE/9Q2P7UppTOAVeIR4TYIocELVKIEACZJgXCJ5GXl0o+esbFP3g+763DcDPx6/60MrnBaBPAsGPUDRC/8+FGIqGUSBA+NIJOwTWe13HRCIrgEvfRhj1RjLiE42eG7I5DIpVNuqkNNhxwaItTI2srRz4dfHGjhZoO0O8nb2pilFYQKhenFaycLUxsYcoAQRyoRBEnPvcgfysPq+npClt8UxLyvHWjaudqbGJA+TCckNECBGBGFforuTs0M4CUMbCAvp+P4in4o864XECREBtFQAAAAA=); }
@font-face { font-family: Nunito; src: url(data:font/woff2;base64,d09GMgABAAAAAAIsAA4AAAAABLQAAAHYAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGx4cLgZgP1NUQVREAAQRCAoAKgsEAAE2AiQDBAQgBYQkByAb5wPIrgp4Mt6IIcJZFNCfWmZY6KzqazTt6AiVHCFawzJ7V0CQBKoSQQEpFKrCVxiSFbqqqsaTevKs/q7s6uBYmujMyA9wxb6a7XnEOcNnDLgG4nW8PoPzHzYpS2uqp51pL3eB/xZoxIllCQc80B9o4j/4xMbxQB+j+SC3hsm6JmI8RMaHj+aJApW6ZbkXlg4vXSE5FECg0og6LzxP9pOarug4tF1RLpbHeZqLX0pIt2mfy3pNG6eyGaRIjrnrr/gv2c//yGdjpJ/7DuJLin5eIZRLaObBMM/NpYpuXJ8z3SE088mEFANcCARESfwChCioAwESsVxBgeyxp6+vZ3Xzv8uz7Ae8tRk+p6RUTPOR7BmlEgh+STsAimNuKibilyluhBNe5/wCACSBKrcykVfgyb+RYcK/TGq9yMyCt3bOskSnR1FqTLMSVBsMGLQVltDKKw2IYA+wcGxHJCINY9mDOCaN4IZEo1ChY4xNg8DaB0RxDqnbMNjXJJRzF9iInqahtm67M8dOHFvXaYbn+wrGxKG3YZI+2V4CW58ovdfV1tFHXFJJiPH7T1FAJxEgYo5BKkA5iDIVQluOqZYWhQapGF6TAFhaFAAoTBIZsCFHi/0oV3gpVKwbAA==); }