@yh-ui/flow 1.0.1 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/bpmn-engine.test.cjs +357 -0
- package/dist/__tests__/bpmn-engine.test.d.ts +1 -0
- package/dist/__tests__/bpmn-engine.test.mjs +406 -0
- package/dist/__tests__/bpmn-utils.test.cjs +268 -0
- package/dist/__tests__/bpmn-utils.test.d.ts +1 -0
- package/dist/__tests__/bpmn-utils.test.mjs +227 -0
- package/dist/__tests__/bpmn-xml.test.cjs +150 -0
- package/dist/__tests__/bpmn-xml.test.d.ts +1 -0
- package/dist/__tests__/bpmn-xml.test.mjs +112 -0
- package/dist/__tests__/collaboration.test.cjs +487 -0
- package/dist/__tests__/collaboration.test.d.ts +1 -0
- package/dist/__tests__/collaboration.test.mjs +424 -0
- package/dist/__tests__/edge-types.test.cjs +275 -0
- package/dist/__tests__/edge-types.test.d.ts +1 -0
- package/dist/__tests__/edge-types.test.mjs +234 -0
- package/dist/__tests__/edge-utils.test.cjs +375 -0
- package/dist/__tests__/edge-utils.test.d.ts +1 -0
- package/dist/__tests__/edge-utils.test.mjs +376 -0
- package/dist/__tests__/events-types.test.cjs +184 -0
- package/dist/__tests__/events-types.test.d.ts +1 -0
- package/dist/__tests__/events-types.test.mjs +184 -0
- package/dist/__tests__/export-image-plugin.test.cjs +142 -0
- package/dist/__tests__/export-image-plugin.test.d.ts +1 -0
- package/dist/__tests__/export-image-plugin.test.mjs +118 -0
- package/dist/__tests__/export.test.cjs +237 -0
- package/dist/__tests__/export.test.d.ts +1 -0
- package/dist/__tests__/export.test.mjs +171 -0
- package/dist/__tests__/flow-context.test.cjs +16 -0
- package/dist/__tests__/flow-context.test.d.ts +1 -0
- package/dist/__tests__/flow-context.test.mjs +16 -0
- package/dist/__tests__/flow-props.test.cjs +94 -0
- package/dist/__tests__/flow-props.test.d.ts +1 -0
- package/dist/__tests__/flow-props.test.mjs +92 -0
- package/dist/__tests__/layout-plugin.test.cjs +233 -0
- package/dist/__tests__/layout-plugin.test.d.ts +1 -0
- package/dist/__tests__/layout-plugin.test.mjs +215 -0
- package/dist/__tests__/node-types.test.cjs +368 -0
- package/dist/__tests__/node-types.test.d.ts +1 -0
- package/dist/__tests__/node-types.test.mjs +292 -0
- package/dist/__tests__/performance.test.cjs +313 -0
- package/dist/__tests__/performance.test.d.ts +1 -0
- package/dist/__tests__/performance.test.mjs +218 -0
- package/dist/__tests__/plugin-advanced.test.cjs +301 -0
- package/dist/__tests__/plugin-advanced.test.d.ts +1 -0
- package/dist/__tests__/plugin-advanced.test.mjs +225 -0
- package/dist/__tests__/plugins.test.cjs +412 -0
- package/dist/__tests__/plugins.test.d.ts +1 -0
- package/dist/__tests__/plugins.test.mjs +402 -0
- package/dist/__tests__/screenshot-capture.test.cjs +183 -0
- package/dist/__tests__/screenshot-capture.test.d.ts +1 -0
- package/dist/__tests__/screenshot-capture.test.mjs +124 -0
- package/dist/__tests__/screenshot.test.cjs +74 -0
- package/dist/__tests__/screenshot.test.d.ts +1 -0
- package/dist/__tests__/screenshot.test.mjs +69 -0
- package/dist/__tests__/theme.test.cjs +185 -0
- package/dist/__tests__/theme.test.d.ts +1 -0
- package/dist/__tests__/theme.test.mjs +191 -0
- package/dist/__tests__/transform.test.cjs +376 -50
- package/dist/__tests__/transform.test.mjs +229 -28
- package/dist/__tests__/useAlignment.test.cjs +37 -0
- package/dist/__tests__/useAlignment.test.mjs +20 -0
- package/dist/__tests__/useNodeDistribution.test.cjs +643 -0
- package/dist/__tests__/useNodeDistribution.test.d.ts +1 -0
- package/dist/__tests__/useNodeDistribution.test.mjs +297 -0
- package/dist/__tests__/viewport-types.test.cjs +324 -0
- package/dist/__tests__/viewport-types.test.d.ts +1 -0
- package/dist/__tests__/viewport-types.test.mjs +207 -0
- package/dist/utils/bpmn.cjs +27 -16
- package/dist/utils/bpmn.mjs +27 -19
- package/package.json +3 -3
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { ref } from "vue";
|
|
3
|
+
import { PluginManager, createPlugin, withHooks } from "../plugins/plugin.mjs";
|
|
4
|
+
function createMockFlowInstance() {
|
|
5
|
+
const nodes = ref([]);
|
|
6
|
+
const edges = ref([]);
|
|
7
|
+
const viewport = ref({ x: 0, y: 0, zoom: 1 });
|
|
8
|
+
const draggingNodeId = ref(null);
|
|
9
|
+
return {
|
|
10
|
+
nodes,
|
|
11
|
+
edges,
|
|
12
|
+
viewport,
|
|
13
|
+
draggingNodeId,
|
|
14
|
+
addNode: vi.fn(),
|
|
15
|
+
removeNode: vi.fn(),
|
|
16
|
+
updateNode: vi.fn(),
|
|
17
|
+
getNode: vi.fn(),
|
|
18
|
+
addEdge: vi.fn(),
|
|
19
|
+
removeEdge: vi.fn(),
|
|
20
|
+
updateEdge: vi.fn(),
|
|
21
|
+
getEdge: vi.fn(),
|
|
22
|
+
setViewport: vi.fn(),
|
|
23
|
+
fitView: vi.fn(),
|
|
24
|
+
zoomIn: vi.fn(),
|
|
25
|
+
zoomOut: vi.fn(),
|
|
26
|
+
centerView: vi.fn(),
|
|
27
|
+
selectNode: vi.fn(),
|
|
28
|
+
selectEdge: vi.fn(),
|
|
29
|
+
clearSelection: vi.fn(),
|
|
30
|
+
getNodes: vi.fn(() => nodes.value),
|
|
31
|
+
getEdges: vi.fn(() => edges.value),
|
|
32
|
+
getViewport: vi.fn(() => viewport.value),
|
|
33
|
+
screenToCanvas: vi.fn(),
|
|
34
|
+
canvasToScreen: vi.fn(),
|
|
35
|
+
on: vi.fn(),
|
|
36
|
+
off: vi.fn(),
|
|
37
|
+
emit: vi.fn(),
|
|
38
|
+
isValidConnection: vi.fn(() => true),
|
|
39
|
+
$el: void 0,
|
|
40
|
+
usePlugin: vi.fn(),
|
|
41
|
+
removePlugin: vi.fn()
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
describe("flow/plugins/plugin - withHooks", () => {
|
|
45
|
+
let consoleLogSpy;
|
|
46
|
+
let consoleWarnSpy;
|
|
47
|
+
let consoleErrorSpy;
|
|
48
|
+
beforeEach(() => {
|
|
49
|
+
consoleLogSpy = vi.spyOn(console, "log").mockImplementation(() => {
|
|
50
|
+
});
|
|
51
|
+
consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {
|
|
52
|
+
});
|
|
53
|
+
consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
afterEach(() => {
|
|
57
|
+
consoleLogSpy.mockRestore();
|
|
58
|
+
consoleWarnSpy.mockRestore();
|
|
59
|
+
consoleErrorSpy.mockRestore();
|
|
60
|
+
});
|
|
61
|
+
describe("PluginManager - edge cases", () => {
|
|
62
|
+
it("should warn when unregistering non-existent plugin", () => {
|
|
63
|
+
const pm = new PluginManager();
|
|
64
|
+
pm.unregister("non-existent");
|
|
65
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith("[YhFlow] Plugin non-existent not found");
|
|
66
|
+
});
|
|
67
|
+
it("should warn when registering without init and no options", () => {
|
|
68
|
+
const pm = new PluginManager();
|
|
69
|
+
const install = vi.fn();
|
|
70
|
+
pm.register({ id: "n", name: "N", install });
|
|
71
|
+
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
72
|
+
"[YhFlow] PluginManager not initialized, call init() first or provide flow instance"
|
|
73
|
+
);
|
|
74
|
+
expect(install).not.toHaveBeenCalled();
|
|
75
|
+
});
|
|
76
|
+
it("should register with options as flow instance fallback", () => {
|
|
77
|
+
const pm = new PluginManager();
|
|
78
|
+
const flow = createMockFlowInstance();
|
|
79
|
+
const install = vi.fn();
|
|
80
|
+
pm.register({ id: "fallback", name: "Fallback", install }, flow);
|
|
81
|
+
expect(install).toHaveBeenCalledWith(flow, flow);
|
|
82
|
+
});
|
|
83
|
+
it("should log when plugin is registered", () => {
|
|
84
|
+
const pm = new PluginManager();
|
|
85
|
+
const flow = createMockFlowInstance();
|
|
86
|
+
pm.init(flow);
|
|
87
|
+
pm.register({ id: "log-test", name: "LogTest", install: vi.fn() });
|
|
88
|
+
expect(consoleLogSpy).toHaveBeenCalledWith("[YhFlow] Plugin LogTest (log-test) registered");
|
|
89
|
+
});
|
|
90
|
+
it("should log when plugin is unregistered", () => {
|
|
91
|
+
const pm = new PluginManager();
|
|
92
|
+
const flow = createMockFlowInstance();
|
|
93
|
+
pm.init(flow);
|
|
94
|
+
pm.register({ id: "ul", name: "UL", install: vi.fn() });
|
|
95
|
+
pm.unregister("ul");
|
|
96
|
+
expect(consoleLogSpy).toHaveBeenCalledWith("[YhFlow] Plugin UL (ul) unregistered");
|
|
97
|
+
});
|
|
98
|
+
it("should not call destroy if plugin has no destroy method", () => {
|
|
99
|
+
const pm = new PluginManager();
|
|
100
|
+
const flow = createMockFlowInstance();
|
|
101
|
+
pm.init(flow);
|
|
102
|
+
pm.register({ id: "no-destroy", name: "NoDestroy", install: vi.fn() });
|
|
103
|
+
expect(() => pm.unregister("no-destroy")).not.toThrow();
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
describe("withHooks", () => {
|
|
107
|
+
it("should wrap plugin with onInit hook", () => {
|
|
108
|
+
const pm = new PluginManager();
|
|
109
|
+
const flow = createMockFlowInstance();
|
|
110
|
+
pm.init(flow);
|
|
111
|
+
const onInit = vi.fn();
|
|
112
|
+
const install = vi.fn();
|
|
113
|
+
const hooks = { onInit };
|
|
114
|
+
const basePlugin = createPlugin({ id: "hooks-test", name: "HooksTest" }, install);
|
|
115
|
+
const hookedPlugin = withHooks(basePlugin, hooks);
|
|
116
|
+
hookedPlugin.install(flow);
|
|
117
|
+
expect(onInit).toHaveBeenCalled();
|
|
118
|
+
});
|
|
119
|
+
it("should register onViewportChange hook", () => {
|
|
120
|
+
const flow = createMockFlowInstance();
|
|
121
|
+
const onViewportChange = vi.fn();
|
|
122
|
+
const basePlugin = createPlugin({ id: "vp-hook", name: "VpHook" }, vi.fn());
|
|
123
|
+
const hookedPlugin = withHooks(basePlugin, { onViewportChange });
|
|
124
|
+
hookedPlugin.install(flow);
|
|
125
|
+
const onHandler = flow.on.mock.calls.find(
|
|
126
|
+
(call) => call[0] === "viewport:change"
|
|
127
|
+
);
|
|
128
|
+
expect(onHandler).toBeDefined();
|
|
129
|
+
const handler = onHandler[1];
|
|
130
|
+
handler({ transform: { x: 100, y: 200, zoom: 2 } });
|
|
131
|
+
expect(onViewportChange).toHaveBeenCalledWith({ x: 100, y: 200, zoom: 2 });
|
|
132
|
+
});
|
|
133
|
+
it("should register onNodesChange hook", () => {
|
|
134
|
+
const flow = createMockFlowInstance();
|
|
135
|
+
const onNodesChange = vi.fn();
|
|
136
|
+
const basePlugin = createPlugin({ id: "nodes-hook", name: "NodesHook" }, vi.fn());
|
|
137
|
+
const hookedPlugin = withHooks(basePlugin, { onNodesChange });
|
|
138
|
+
hookedPlugin.install(flow);
|
|
139
|
+
const onHandler = flow.on.mock.calls.find(
|
|
140
|
+
(call) => call[0] === "node:selected"
|
|
141
|
+
);
|
|
142
|
+
expect(onHandler).toBeDefined();
|
|
143
|
+
});
|
|
144
|
+
it("should register onEdgesChange hook", () => {
|
|
145
|
+
const flow = createMockFlowInstance();
|
|
146
|
+
const onEdgesChange = vi.fn();
|
|
147
|
+
const basePlugin = createPlugin({ id: "edges-hook", name: "EdgesHook" }, vi.fn());
|
|
148
|
+
const hookedPlugin = withHooks(basePlugin, { onEdgesChange });
|
|
149
|
+
hookedPlugin.install(flow);
|
|
150
|
+
const onHandler = flow.on.mock.calls.find(
|
|
151
|
+
(call) => call[0] === "edge:selected"
|
|
152
|
+
);
|
|
153
|
+
expect(onHandler).toBeDefined();
|
|
154
|
+
});
|
|
155
|
+
it("should call onDestroy when hooked plugin is destroyed", () => {
|
|
156
|
+
const flow = createMockFlowInstance();
|
|
157
|
+
const onDestroy = vi.fn();
|
|
158
|
+
const baseDestroy = vi.fn();
|
|
159
|
+
const basePlugin = createPlugin({ id: "destroy-hook", name: "DestroyHook" }, vi.fn());
|
|
160
|
+
basePlugin.destroy = baseDestroy;
|
|
161
|
+
const hookedPlugin = withHooks(basePlugin, { onDestroy });
|
|
162
|
+
hookedPlugin.destroy();
|
|
163
|
+
expect(onDestroy).toHaveBeenCalled();
|
|
164
|
+
expect(baseDestroy).toHaveBeenCalled();
|
|
165
|
+
});
|
|
166
|
+
it("should only register hooks that are provided", () => {
|
|
167
|
+
const flow = createMockFlowInstance();
|
|
168
|
+
const onInit = vi.fn();
|
|
169
|
+
const hooks = { onInit };
|
|
170
|
+
const basePlugin = createPlugin({ id: "partial-hooks", name: "PartialHooks" }, vi.fn());
|
|
171
|
+
const hookedPlugin = withHooks(basePlugin, hooks);
|
|
172
|
+
hookedPlugin.install(flow);
|
|
173
|
+
expect(onInit).toHaveBeenCalled();
|
|
174
|
+
});
|
|
175
|
+
it("should keep plugin metadata from base plugin", () => {
|
|
176
|
+
const basePlugin = createPlugin(
|
|
177
|
+
{ id: "meta", name: "Meta", version: "1.0.0", description: "Test plugin" },
|
|
178
|
+
vi.fn()
|
|
179
|
+
);
|
|
180
|
+
const hookedPlugin = withHooks(basePlugin, {});
|
|
181
|
+
expect(hookedPlugin.id).toBe("meta");
|
|
182
|
+
expect(hookedPlugin.name).toBe("Meta");
|
|
183
|
+
expect(hookedPlugin.version).toBe("1.0.0");
|
|
184
|
+
expect(hookedPlugin.description).toBe("Test plugin");
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
describe("createPlugin", () => {
|
|
188
|
+
it("should create plugin with default enabled true", () => {
|
|
189
|
+
const installFn = vi.fn();
|
|
190
|
+
const plugin = createPlugin({ id: "default-enabled", name: "DefaultEnabled" }, installFn);
|
|
191
|
+
expect(plugin.enabled).toBe(true);
|
|
192
|
+
});
|
|
193
|
+
it("should create plugin with explicit enabled false", () => {
|
|
194
|
+
const installFn = vi.fn();
|
|
195
|
+
const plugin = createPlugin(
|
|
196
|
+
{ id: "explicit-disabled", name: "ExplicitDisabled", enabled: false },
|
|
197
|
+
installFn
|
|
198
|
+
);
|
|
199
|
+
expect(plugin.enabled).toBe(false);
|
|
200
|
+
plugin.install(createMockFlowInstance());
|
|
201
|
+
expect(installFn).not.toHaveBeenCalled();
|
|
202
|
+
});
|
|
203
|
+
it("should pass options to install function", () => {
|
|
204
|
+
const installFn = vi.fn();
|
|
205
|
+
const plugin = createPlugin(
|
|
206
|
+
{ id: "opts-pass", name: "OptsPass", version: "2.0.0" },
|
|
207
|
+
installFn
|
|
208
|
+
);
|
|
209
|
+
const flow = createMockFlowInstance();
|
|
210
|
+
plugin.install(flow, { customOption: true });
|
|
211
|
+
expect(installFn).toHaveBeenCalledWith(flow, { id: "opts-pass", name: "OptsPass", version: "2.0.0" });
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
describe("getPlugins", () => {
|
|
215
|
+
it("should return all registered plugins", () => {
|
|
216
|
+
const pm = new PluginManager();
|
|
217
|
+
const flow = createMockFlowInstance();
|
|
218
|
+
pm.init(flow);
|
|
219
|
+
pm.register({ id: "p1", name: "P1", install: vi.fn() });
|
|
220
|
+
pm.register({ id: "p2", name: "P2", install: vi.fn() });
|
|
221
|
+
const plugins = pm.getPlugins();
|
|
222
|
+
expect(plugins).toHaveLength(2);
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
});
|
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _vitest = require("vitest");
|
|
4
|
+
var _vue = require("vue");
|
|
5
|
+
var _controls = require("../plugins/plugins/controls.cjs");
|
|
6
|
+
var _grid = require("../plugins/plugins/grid.cjs");
|
|
7
|
+
var _keyboard = require("../plugins/plugins/keyboard.cjs");
|
|
8
|
+
var _minimap = require("../plugins/plugins/minimap.cjs");
|
|
9
|
+
var _snap = require("../plugins/plugins/snap.cjs");
|
|
10
|
+
function createMockFlowInstance() {
|
|
11
|
+
const nodes = (0, _vue.ref)([]);
|
|
12
|
+
const edges = (0, _vue.ref)([]);
|
|
13
|
+
const viewport = (0, _vue.ref)({
|
|
14
|
+
x: 0,
|
|
15
|
+
y: 0,
|
|
16
|
+
zoom: 1
|
|
17
|
+
});
|
|
18
|
+
const draggingNodeId = (0, _vue.ref)(null);
|
|
19
|
+
return {
|
|
20
|
+
nodes,
|
|
21
|
+
edges,
|
|
22
|
+
viewport,
|
|
23
|
+
draggingNodeId,
|
|
24
|
+
addNode: _vitest.vi.fn(),
|
|
25
|
+
removeNode: _vitest.vi.fn(),
|
|
26
|
+
updateNode: _vitest.vi.fn(),
|
|
27
|
+
getNode: _vitest.vi.fn(),
|
|
28
|
+
addEdge: _vitest.vi.fn(),
|
|
29
|
+
removeEdge: _vitest.vi.fn(),
|
|
30
|
+
updateEdge: _vitest.vi.fn(),
|
|
31
|
+
getEdge: _vitest.vi.fn(),
|
|
32
|
+
setViewport: _vitest.vi.fn(),
|
|
33
|
+
fitView: _vitest.vi.fn(),
|
|
34
|
+
zoomIn: _vitest.vi.fn(),
|
|
35
|
+
zoomOut: _vitest.vi.fn(),
|
|
36
|
+
centerView: _vitest.vi.fn(),
|
|
37
|
+
selectNode: _vitest.vi.fn(),
|
|
38
|
+
selectEdge: _vitest.vi.fn(),
|
|
39
|
+
clearSelection: _vitest.vi.fn(),
|
|
40
|
+
getNodes: _vitest.vi.fn(() => nodes.value),
|
|
41
|
+
getEdges: _vitest.vi.fn(() => edges.value),
|
|
42
|
+
getViewport: _vitest.vi.fn(() => viewport.value),
|
|
43
|
+
screenToCanvas: _vitest.vi.fn(),
|
|
44
|
+
canvasToScreen: _vitest.vi.fn(),
|
|
45
|
+
on: _vitest.vi.fn(),
|
|
46
|
+
off: _vitest.vi.fn(),
|
|
47
|
+
emit: _vitest.vi.fn(),
|
|
48
|
+
isValidConnection: _vitest.vi.fn(() => true),
|
|
49
|
+
$el: void 0,
|
|
50
|
+
usePlugin: _vitest.vi.fn(),
|
|
51
|
+
removePlugin: _vitest.vi.fn()
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
(0, _vitest.describe)("flow/plugins/plugins/controls", () => {
|
|
55
|
+
let consoleLogSpy;
|
|
56
|
+
(0, _vitest.beforeEach)(() => {
|
|
57
|
+
consoleLogSpy = _vitest.vi.spyOn(console, "log").mockImplementation(() => {});
|
|
58
|
+
});
|
|
59
|
+
(0, _vitest.afterEach)(() => {
|
|
60
|
+
consoleLogSpy.mockRestore();
|
|
61
|
+
});
|
|
62
|
+
(0, _vitest.describe)("createControlsPlugin", () => {
|
|
63
|
+
(0, _vitest.it)("should create plugin with correct id and name", () => {
|
|
64
|
+
const plugin = (0, _controls.createControlsPlugin)();
|
|
65
|
+
(0, _vitest.expect)(plugin.id).toBe("controls");
|
|
66
|
+
(0, _vitest.expect)(plugin.name).toBe("Controls");
|
|
67
|
+
(0, _vitest.expect)(plugin.version).toBe("1.0.0");
|
|
68
|
+
(0, _vitest.expect)(plugin.description).toBe("Displays a set of controls for zooming and fitting the view");
|
|
69
|
+
});
|
|
70
|
+
(0, _vitest.it)("should have a component", () => {
|
|
71
|
+
const plugin = (0, _controls.createControlsPlugin)();
|
|
72
|
+
(0, _vitest.expect)(plugin.component).toBeDefined();
|
|
73
|
+
});
|
|
74
|
+
(0, _vitest.it)("should install with default options", () => {
|
|
75
|
+
const flow = createMockFlowInstance();
|
|
76
|
+
const plugin = (0, _controls.createControlsPlugin)();
|
|
77
|
+
plugin.install(flow);
|
|
78
|
+
(0, _vitest.expect)(consoleLogSpy).toHaveBeenCalledWith("[Controls Plugin] Installed");
|
|
79
|
+
});
|
|
80
|
+
(0, _vitest.it)("should merge custom options", () => {
|
|
81
|
+
const plugin = (0, _controls.createControlsPlugin)({
|
|
82
|
+
enabled: true,
|
|
83
|
+
position: "top-right",
|
|
84
|
+
showZoom: true,
|
|
85
|
+
showFitView: false,
|
|
86
|
+
showInteractive: false
|
|
87
|
+
});
|
|
88
|
+
(0, _vitest.expect)(plugin.componentProps).toEqual({
|
|
89
|
+
position: "top-right",
|
|
90
|
+
showZoom: true,
|
|
91
|
+
showFitView: false,
|
|
92
|
+
showInteractive: false
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
(0, _vitest.it)("should use default position when not provided", () => {
|
|
96
|
+
const plugin = (0, _controls.createControlsPlugin)();
|
|
97
|
+
(0, _vitest.expect)(plugin.componentProps?.position).toBe("bottom-left");
|
|
98
|
+
});
|
|
99
|
+
(0, _vitest.it)("should use default show options", () => {
|
|
100
|
+
const plugin = (0, _controls.createControlsPlugin)();
|
|
101
|
+
(0, _vitest.expect)(plugin.componentProps?.showZoom).toBe(true);
|
|
102
|
+
(0, _vitest.expect)(plugin.componentProps?.showFitView).toBe(true);
|
|
103
|
+
(0, _vitest.expect)(plugin.componentProps?.showInteractive).toBe(true);
|
|
104
|
+
});
|
|
105
|
+
(0, _vitest.it)("should support all position options", () => {
|
|
106
|
+
const positions = ["top-left", "top-right", "bottom-left", "bottom-right"];
|
|
107
|
+
for (const pos of positions) {
|
|
108
|
+
const plugin = (0, _controls.createControlsPlugin)({
|
|
109
|
+
position: pos
|
|
110
|
+
});
|
|
111
|
+
(0, _vitest.expect)(plugin.componentProps?.position).toBe(pos);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
(0, _vitest.describe)("flow/plugins/plugins/grid", () => {
|
|
117
|
+
let consoleLogSpy;
|
|
118
|
+
(0, _vitest.beforeEach)(() => {
|
|
119
|
+
consoleLogSpy = _vitest.vi.spyOn(console, "log").mockImplementation(() => {});
|
|
120
|
+
});
|
|
121
|
+
(0, _vitest.afterEach)(() => {
|
|
122
|
+
consoleLogSpy.mockRestore();
|
|
123
|
+
});
|
|
124
|
+
(0, _vitest.describe)("createGridPlugin", () => {
|
|
125
|
+
(0, _vitest.it)("should create plugin with correct id and name", () => {
|
|
126
|
+
const plugin = (0, _grid.createGridPlugin)();
|
|
127
|
+
(0, _vitest.expect)(plugin.id).toBe("grid");
|
|
128
|
+
(0, _vitest.expect)(plugin.name).toBe("Grid");
|
|
129
|
+
(0, _vitest.expect)(plugin.version).toBe("1.0.0");
|
|
130
|
+
(0, _vitest.expect)(plugin.description).toBe("Displays a grid or dots background");
|
|
131
|
+
});
|
|
132
|
+
(0, _vitest.it)("should have a component", () => {
|
|
133
|
+
const plugin = (0, _grid.createGridPlugin)();
|
|
134
|
+
(0, _vitest.expect)(plugin.component).toBeDefined();
|
|
135
|
+
});
|
|
136
|
+
(0, _vitest.it)("should install with default options", () => {
|
|
137
|
+
const flow = createMockFlowInstance();
|
|
138
|
+
const plugin = (0, _grid.createGridPlugin)();
|
|
139
|
+
plugin.install(flow);
|
|
140
|
+
(0, _vitest.expect)(consoleLogSpy).toHaveBeenCalledWith("[Grid Plugin] Installed");
|
|
141
|
+
});
|
|
142
|
+
(0, _vitest.it)("should merge custom options", () => {
|
|
143
|
+
const plugin = (0, _grid.createGridPlugin)({
|
|
144
|
+
enabled: true,
|
|
145
|
+
type: "grid",
|
|
146
|
+
color: "#ff0000",
|
|
147
|
+
gap: 30
|
|
148
|
+
});
|
|
149
|
+
(0, _vitest.expect)(plugin.componentProps).toEqual({
|
|
150
|
+
type: "grid",
|
|
151
|
+
color: "#ff0000",
|
|
152
|
+
gap: 30
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
(0, _vitest.it)("should use default type dots", () => {
|
|
156
|
+
const plugin = (0, _grid.createGridPlugin)();
|
|
157
|
+
(0, _vitest.expect)(plugin.componentProps?.type).toBe("dots");
|
|
158
|
+
});
|
|
159
|
+
(0, _vitest.it)("should use default gap", () => {
|
|
160
|
+
const plugin = (0, _grid.createGridPlugin)();
|
|
161
|
+
(0, _vitest.expect)(plugin.componentProps?.gap).toBe(20);
|
|
162
|
+
});
|
|
163
|
+
(0, _vitest.it)("should use default color", () => {
|
|
164
|
+
const plugin = (0, _grid.createGridPlugin)();
|
|
165
|
+
(0, _vitest.expect)(plugin.componentProps?.color).toBe("#e5e5e5");
|
|
166
|
+
});
|
|
167
|
+
(0, _vitest.it)("should support grid type", () => {
|
|
168
|
+
const plugin = (0, _grid.createGridPlugin)({
|
|
169
|
+
type: "grid"
|
|
170
|
+
});
|
|
171
|
+
(0, _vitest.expect)(plugin.componentProps?.type).toBe("grid");
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
(0, _vitest.describe)("flow/plugins/plugins/keyboard", () => {
|
|
176
|
+
let consoleLogSpy;
|
|
177
|
+
(0, _vitest.beforeEach)(() => {
|
|
178
|
+
consoleLogSpy = _vitest.vi.spyOn(console, "log").mockImplementation(() => {});
|
|
179
|
+
});
|
|
180
|
+
(0, _vitest.afterEach)(() => {
|
|
181
|
+
consoleLogSpy.mockRestore();
|
|
182
|
+
});
|
|
183
|
+
(0, _vitest.describe)("createKeyboardPlugin", () => {
|
|
184
|
+
(0, _vitest.it)("should create plugin with correct id and name", () => {
|
|
185
|
+
const plugin = (0, _keyboard.createKeyboardPlugin)();
|
|
186
|
+
(0, _vitest.expect)(plugin.id).toBe("keyboard");
|
|
187
|
+
(0, _vitest.expect)(plugin.name).toBe("Keyboard");
|
|
188
|
+
});
|
|
189
|
+
(0, _vitest.it)("should install with default options", () => {
|
|
190
|
+
const flow = createMockFlowInstance();
|
|
191
|
+
const plugin = (0, _keyboard.createKeyboardPlugin)();
|
|
192
|
+
plugin.install(flow);
|
|
193
|
+
(0, _vitest.expect)(consoleLogSpy).toHaveBeenCalledWith("Keyboard plugin installed", {
|
|
194
|
+
enabled: true,
|
|
195
|
+
delete: true,
|
|
196
|
+
backspace: true,
|
|
197
|
+
ctrlZ: true,
|
|
198
|
+
ctrlY: true,
|
|
199
|
+
escape: true
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
(0, _vitest.it)("should merge custom options", () => {
|
|
203
|
+
const plugin = (0, _keyboard.createKeyboardPlugin)({
|
|
204
|
+
enabled: false,
|
|
205
|
+
delete: false,
|
|
206
|
+
backspace: false,
|
|
207
|
+
ctrlZ: false,
|
|
208
|
+
ctrlY: false,
|
|
209
|
+
escape: false
|
|
210
|
+
});
|
|
211
|
+
plugin.install(createMockFlowInstance());
|
|
212
|
+
(0, _vitest.expect)(consoleLogSpy).toHaveBeenCalledWith("Keyboard plugin installed", {
|
|
213
|
+
enabled: false,
|
|
214
|
+
delete: false,
|
|
215
|
+
backspace: false,
|
|
216
|
+
ctrlZ: false,
|
|
217
|
+
ctrlY: false,
|
|
218
|
+
escape: false
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
(0, _vitest.it)("should accept partial options", () => {
|
|
222
|
+
const plugin = (0, _keyboard.createKeyboardPlugin)({
|
|
223
|
+
delete: false
|
|
224
|
+
});
|
|
225
|
+
(0, _vitest.expect)(plugin.id).toBe("keyboard");
|
|
226
|
+
});
|
|
227
|
+
(0, _vitest.it)("should override individual options", () => {
|
|
228
|
+
const plugin = (0, _keyboard.createKeyboardPlugin)({
|
|
229
|
+
ctrlZ: false,
|
|
230
|
+
ctrlY: false
|
|
231
|
+
});
|
|
232
|
+
plugin.install(createMockFlowInstance());
|
|
233
|
+
(0, _vitest.expect)(consoleLogSpy).toHaveBeenCalledWith("Keyboard plugin installed", {
|
|
234
|
+
enabled: true,
|
|
235
|
+
delete: true,
|
|
236
|
+
backspace: true,
|
|
237
|
+
ctrlZ: false,
|
|
238
|
+
ctrlY: false,
|
|
239
|
+
escape: true
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
(0, _vitest.describe)("flow/plugins/plugins/minimap", () => {
|
|
245
|
+
let consoleLogSpy;
|
|
246
|
+
(0, _vitest.beforeEach)(() => {
|
|
247
|
+
consoleLogSpy = _vitest.vi.spyOn(console, "log").mockImplementation(() => {});
|
|
248
|
+
});
|
|
249
|
+
(0, _vitest.afterEach)(() => {
|
|
250
|
+
consoleLogSpy.mockRestore();
|
|
251
|
+
});
|
|
252
|
+
(0, _vitest.describe)("createMiniMapPlugin", () => {
|
|
253
|
+
(0, _vitest.it)("should create plugin with correct id and name", () => {
|
|
254
|
+
const plugin = (0, _minimap.createMiniMapPlugin)();
|
|
255
|
+
(0, _vitest.expect)(plugin.id).toBe("minimap");
|
|
256
|
+
(0, _vitest.expect)(plugin.name).toBe("Minimap");
|
|
257
|
+
(0, _vitest.expect)(plugin.version).toBe("1.0.0");
|
|
258
|
+
(0, _vitest.expect)(plugin.description).toBe("Displays a minimap for navigation");
|
|
259
|
+
});
|
|
260
|
+
(0, _vitest.it)("should have a component", () => {
|
|
261
|
+
const plugin = (0, _minimap.createMiniMapPlugin)();
|
|
262
|
+
(0, _vitest.expect)(plugin.component).toBeDefined();
|
|
263
|
+
});
|
|
264
|
+
(0, _vitest.it)("should install with default options", () => {
|
|
265
|
+
const flow = createMockFlowInstance();
|
|
266
|
+
const plugin = (0, _minimap.createMiniMapPlugin)();
|
|
267
|
+
plugin.install(flow);
|
|
268
|
+
(0, _vitest.expect)(consoleLogSpy).toHaveBeenCalled();
|
|
269
|
+
});
|
|
270
|
+
(0, _vitest.it)("should use default position bottom-right", () => {
|
|
271
|
+
const plugin = (0, _minimap.createMiniMapPlugin)();
|
|
272
|
+
(0, _vitest.expect)(plugin.componentProps?.position).toBe("bottom-right");
|
|
273
|
+
});
|
|
274
|
+
(0, _vitest.it)("should use default dimensions", () => {
|
|
275
|
+
const plugin = (0, _minimap.createMiniMapPlugin)();
|
|
276
|
+
(0, _vitest.expect)(plugin.componentProps?.width).toBe(200);
|
|
277
|
+
(0, _vitest.expect)(plugin.componentProps?.height).toBe(150);
|
|
278
|
+
});
|
|
279
|
+
(0, _vitest.it)("should use default mask colors", () => {
|
|
280
|
+
const plugin = (0, _minimap.createMiniMapPlugin)();
|
|
281
|
+
(0, _vitest.expect)(plugin.componentProps?.maskColor).toBe("rgba(240, 240, 240, 0.6)");
|
|
282
|
+
(0, _vitest.expect)(plugin.componentProps?.maskStrokeColor).toBe("#ddd");
|
|
283
|
+
(0, _vitest.expect)(plugin.componentProps?.maskStrokeWidth).toBe(1);
|
|
284
|
+
});
|
|
285
|
+
(0, _vitest.it)("should use default pannable and zoomable", () => {
|
|
286
|
+
const plugin = (0, _minimap.createMiniMapPlugin)();
|
|
287
|
+
(0, _vitest.expect)(plugin.componentProps?.pannable).toBe(true);
|
|
288
|
+
(0, _vitest.expect)(plugin.componentProps?.zoomable).toBe(true);
|
|
289
|
+
});
|
|
290
|
+
(0, _vitest.it)("should support custom position", () => {
|
|
291
|
+
const positions = ["top-left", "top-right", "bottom-left", "bottom-right"];
|
|
292
|
+
for (const pos of positions) {
|
|
293
|
+
const plugin = (0, _minimap.createMiniMapPlugin)({
|
|
294
|
+
position: pos
|
|
295
|
+
});
|
|
296
|
+
(0, _vitest.expect)(plugin.componentProps?.position).toBe(pos);
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
(0, _vitest.it)("should support custom dimensions", () => {
|
|
300
|
+
const plugin = (0, _minimap.createMiniMapPlugin)({
|
|
301
|
+
width: 300,
|
|
302
|
+
height: 200
|
|
303
|
+
});
|
|
304
|
+
(0, _vitest.expect)(plugin.componentProps?.width).toBe(300);
|
|
305
|
+
(0, _vitest.expect)(plugin.componentProps?.height).toBe(200);
|
|
306
|
+
});
|
|
307
|
+
(0, _vitest.it)("should support custom node color functions", () => {
|
|
308
|
+
const customNodeColor = node => "#ff0000";
|
|
309
|
+
const customNodeStrokeColor = node => "#00ff00";
|
|
310
|
+
const plugin = (0, _minimap.createMiniMapPlugin)({
|
|
311
|
+
nodeColor: customNodeColor,
|
|
312
|
+
nodeStrokeColor: customNodeStrokeColor
|
|
313
|
+
});
|
|
314
|
+
(0, _vitest.expect)(plugin.componentProps?.nodeColor).toBe(customNodeColor);
|
|
315
|
+
(0, _vitest.expect)(plugin.componentProps?.nodeStrokeColor).toBe(customNodeStrokeColor);
|
|
316
|
+
});
|
|
317
|
+
(0, _vitest.it)("should support interactive option", () => {
|
|
318
|
+
const pluginEnabled = (0, _minimap.createMiniMapPlugin)({
|
|
319
|
+
interactive: true
|
|
320
|
+
});
|
|
321
|
+
const pluginDisabled = (0, _minimap.createMiniMapPlugin)({
|
|
322
|
+
interactive: false
|
|
323
|
+
});
|
|
324
|
+
(0, _vitest.expect)(pluginEnabled.componentProps?.interactive).toBe(true);
|
|
325
|
+
(0, _vitest.expect)(pluginDisabled.componentProps?.interactive).toBe(false);
|
|
326
|
+
});
|
|
327
|
+
(0, _vitest.it)("should support layout controls options", () => {
|
|
328
|
+
const plugin = (0, _minimap.createMiniMapPlugin)({
|
|
329
|
+
showLayoutControls: true,
|
|
330
|
+
layoutType: "dagre",
|
|
331
|
+
layoutDirection: "LR"
|
|
332
|
+
});
|
|
333
|
+
(0, _vitest.expect)(plugin.componentProps?.showLayoutControls).toBe(true);
|
|
334
|
+
(0, _vitest.expect)(plugin.componentProps?.layoutType).toBe("dagre");
|
|
335
|
+
(0, _vitest.expect)(plugin.componentProps?.layoutDirection).toBe("LR");
|
|
336
|
+
});
|
|
337
|
+
(0, _vitest.it)("should support all layout directions", () => {
|
|
338
|
+
const directions = ["TB", "BT", "LR", "RL"];
|
|
339
|
+
for (const dir of directions) {
|
|
340
|
+
const plugin = (0, _minimap.createMiniMapPlugin)({
|
|
341
|
+
layoutDirection: dir
|
|
342
|
+
});
|
|
343
|
+
(0, _vitest.expect)(plugin.componentProps?.layoutDirection).toBe(dir);
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
(0, _vitest.it)("should support all layout types", () => {
|
|
347
|
+
const types = ["dagre", "elk", "force", "grid", "none"];
|
|
348
|
+
for (const type of types) {
|
|
349
|
+
const plugin = (0, _minimap.createMiniMapPlugin)({
|
|
350
|
+
layoutType: type
|
|
351
|
+
});
|
|
352
|
+
(0, _vitest.expect)(plugin.componentProps?.layoutType).toBe(type);
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
(0, _vitest.describe)("flow/plugins/plugins/snap", () => {
|
|
358
|
+
let consoleLogSpy;
|
|
359
|
+
(0, _vitest.beforeEach)(() => {
|
|
360
|
+
consoleLogSpy = _vitest.vi.spyOn(console, "log").mockImplementation(() => {});
|
|
361
|
+
});
|
|
362
|
+
(0, _vitest.afterEach)(() => {
|
|
363
|
+
consoleLogSpy.mockRestore();
|
|
364
|
+
});
|
|
365
|
+
(0, _vitest.describe)("createSnapPlugin", () => {
|
|
366
|
+
(0, _vitest.it)("should create plugin with correct id and name", () => {
|
|
367
|
+
const plugin = (0, _snap.createSnapPlugin)();
|
|
368
|
+
(0, _vitest.expect)(plugin.id).toBe("snap");
|
|
369
|
+
(0, _vitest.expect)(plugin.name).toBe("Snap");
|
|
370
|
+
(0, _vitest.expect)(plugin.version).toBe("1.0.0");
|
|
371
|
+
(0, _vitest.expect)(plugin.description).toBe("Enables grid snapping and alignment lines");
|
|
372
|
+
});
|
|
373
|
+
(0, _vitest.it)("should have a component when showAlignmentLines is true", () => {
|
|
374
|
+
const plugin = (0, _snap.createSnapPlugin)({
|
|
375
|
+
showAlignmentLines: true
|
|
376
|
+
});
|
|
377
|
+
(0, _vitest.expect)(plugin.component).toBeDefined();
|
|
378
|
+
});
|
|
379
|
+
(0, _vitest.it)("should not have a component when showAlignmentLines is false", () => {
|
|
380
|
+
const plugin = (0, _snap.createSnapPlugin)({
|
|
381
|
+
showAlignmentLines: false
|
|
382
|
+
});
|
|
383
|
+
(0, _vitest.expect)(plugin.component).toBeUndefined();
|
|
384
|
+
});
|
|
385
|
+
(0, _vitest.it)("should install with default options", () => {
|
|
386
|
+
const flow = createMockFlowInstance();
|
|
387
|
+
const plugin = (0, _snap.createSnapPlugin)();
|
|
388
|
+
plugin.install(flow);
|
|
389
|
+
(0, _vitest.expect)(consoleLogSpy).toHaveBeenCalled();
|
|
390
|
+
});
|
|
391
|
+
(0, _vitest.it)("should not install when enabled is false", () => {
|
|
392
|
+
const flow = createMockFlowInstance();
|
|
393
|
+
const plugin = (0, _snap.createSnapPlugin)({
|
|
394
|
+
enabled: false
|
|
395
|
+
});
|
|
396
|
+
plugin.install(flow);
|
|
397
|
+
(0, _vitest.expect)(consoleLogSpy).not.toHaveBeenCalled();
|
|
398
|
+
});
|
|
399
|
+
(0, _vitest.it)("should use default snap options", () => {
|
|
400
|
+
const plugin = (0, _snap.createSnapPlugin)();
|
|
401
|
+
(0, _vitest.expect)(plugin.componentProps?.snapThreshold).toBe(10);
|
|
402
|
+
});
|
|
403
|
+
(0, _vitest.it)("should support custom snap options", () => {
|
|
404
|
+
const plugin = (0, _snap.createSnapPlugin)({
|
|
405
|
+
snapToGrid: true,
|
|
406
|
+
gridSize: 20,
|
|
407
|
+
snapThreshold: 15
|
|
408
|
+
});
|
|
409
|
+
(0, _vitest.expect)(plugin.componentProps?.snapThreshold).toBe(15);
|
|
410
|
+
});
|
|
411
|
+
});
|
|
412
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|