pict-section-flow 1.4.0 → 2.0.1

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.
Files changed (164) hide show
  1. package/package.json +7 -2
  2. package/source/Pict-Section-Flow.js +20 -14
  3. package/source/providers/PictProvider-Flow-Background.js +303 -0
  4. package/source/providers/PictProvider-Flow-CSS.js +73 -7
  5. package/source/providers/PictProvider-Flow-Geometry.js +11 -421
  6. package/source/providers/PictProvider-Flow-Icons.js +12 -0
  7. package/source/providers/PictProvider-Flow-Layouts.js +107 -0
  8. package/source/services/PictService-Flow-ConnectionRenderer.js +1 -1
  9. package/source/services/PictService-Flow-CursorManager.js +113 -0
  10. package/source/services/PictService-Flow-InteractionManager.js +439 -59
  11. package/source/services/PictService-Flow-Layout.js +21 -16
  12. package/source/services/PictService-Flow-PathGenerator.js +30 -417
  13. package/source/services/PictService-Flow-RenderManager.js +23 -3
  14. package/source/services/PictService-Flow-ViewportManager.js +102 -0
  15. package/source/views/PictView-Flow-FloatingToolbar.js +5 -1
  16. package/source/views/PictView-Flow-Node.js +29 -0
  17. package/source/views/PictView-Flow-Toolbar.js +50 -3
  18. package/source/views/PictView-Flow.js +591 -2
  19. package/.claude/launch.json +0 -11
  20. package/docs/.nojekyll +0 -0
  21. package/docs/Architecture.md +0 -163
  22. package/docs/Custom-Styling.md +0 -275
  23. package/docs/Data_Model.md +0 -149
  24. package/docs/Event_System.md +0 -156
  25. package/docs/Getting_Started.md +0 -237
  26. package/docs/Implementation_Reference.md +0 -528
  27. package/docs/Layout_Persistence.md +0 -117
  28. package/docs/README.md +0 -103
  29. package/docs/Theme_Integration.md +0 -150
  30. package/docs/_brand.json +0 -18
  31. package/docs/_cover.md +0 -17
  32. package/docs/_playground.json +0 -24
  33. package/docs/_sidebar.md +0 -57
  34. package/docs/_topbar.md +0 -8
  35. package/docs/_version.json +0 -7
  36. package/docs/api/PictFlowCard.md +0 -216
  37. package/docs/api/PictFlowCardPropertiesPanel.md +0 -235
  38. package/docs/api/addConnection.md +0 -101
  39. package/docs/api/addNode.md +0 -137
  40. package/docs/api/autoLayout.md +0 -77
  41. package/docs/api/getFlowData.md +0 -112
  42. package/docs/api/marshalToView.md +0 -95
  43. package/docs/api/openPanel.md +0 -128
  44. package/docs/api/registerHandler.md +0 -174
  45. package/docs/api/registerNodeType.md +0 -142
  46. package/docs/api/removeConnection.md +0 -57
  47. package/docs/api/removeNode.md +0 -80
  48. package/docs/api/saveLayout.md +0 -152
  49. package/docs/api/screenToSVGCoords.md +0 -68
  50. package/docs/api/selectNode.md +0 -116
  51. package/docs/api/setTheme.md +0 -168
  52. package/docs/api/setZoom.md +0 -97
  53. package/docs/api/toggleFullscreen.md +0 -68
  54. package/docs/card-help/EACH.md +0 -19
  55. package/docs/card-help/FREAD.md +0 -24
  56. package/docs/card-help/FWRITE.md +0 -24
  57. package/docs/card-help/GET.md +0 -22
  58. package/docs/card-help/ITE.md +0 -23
  59. package/docs/card-help/LOG.md +0 -23
  60. package/docs/card-help/NOTE.md +0 -17
  61. package/docs/card-help/PREV.md +0 -18
  62. package/docs/card-help/SET.md +0 -27
  63. package/docs/card-help/SPKL.md +0 -22
  64. package/docs/card-help/STAT.md +0 -23
  65. package/docs/card-help/SW.md +0 -25
  66. package/docs/diagrams/architecture-at-a-glance.excalidraw +0 -4270
  67. package/docs/diagrams/architecture-at-a-glance.mmd +0 -30
  68. package/docs/diagrams/architecture-at-a-glance.svg +0 -2
  69. package/docs/diagrams/data-flow.excalidraw +0 -1451
  70. package/docs/diagrams/data-flow.mmd +0 -17
  71. package/docs/diagrams/data-flow.svg +0 -2
  72. package/docs/diagrams/high-level-design.excalidraw +0 -5767
  73. package/docs/diagrams/high-level-design.mmd +0 -86
  74. package/docs/diagrams/high-level-design.svg +0 -2
  75. package/docs/diagrams/relationships.excalidraw +0 -3852
  76. package/docs/diagrams/relationships.mmd +0 -9
  77. package/docs/diagrams/relationships.svg +0 -2
  78. package/docs/diagrams/service-initialization-sequence.excalidraw +0 -1466
  79. package/docs/diagrams/service-initialization-sequence.mmd +0 -19
  80. package/docs/diagrams/service-initialization-sequence.svg +0 -2
  81. package/docs/diagrams/svg-layer-structure.excalidraw +0 -1060
  82. package/docs/diagrams/svg-layer-structure.mmd +0 -18
  83. package/docs/diagrams/svg-layer-structure.svg +0 -2
  84. package/docs/examples/README.md +0 -9
  85. package/docs/examples/simple_cards/README.md +0 -677
  86. package/docs/examples/simple_cards/css/flowexample.css +0 -65
  87. package/docs/examples/simple_cards/index.html +0 -32
  88. package/docs/examples/simple_cards/js/pict.min.js +0 -12
  89. package/docs/examples/simple_cards/pict-section-flow-example-simple-cards.compatible.min.js +0 -1
  90. package/docs/index.html +0 -38
  91. package/docs/playground/app.json +0 -6
  92. package/docs/playground/appdata.json +0 -85
  93. package/docs/playground/application.js +0 -23
  94. package/docs/playground/pict.json +0 -17
  95. package/docs/playground/runtime/pict-application.min.js +0 -2
  96. package/docs/playground/runtime/pict-section-flow.min.js +0 -2
  97. package/docs/playground/runtime/pict-section-modal.min.js +0 -2
  98. package/docs/playground/runtime/pict.min.js +0 -12
  99. package/docs/retold-catalog.json +0 -244
  100. package/docs/retold-keyword-index.json +0 -26028
  101. package/example_applications/simple_cards/css/flowexample.css +0 -65
  102. package/example_applications/simple_cards/html/index.html +0 -32
  103. package/example_applications/simple_cards/package.json +0 -52
  104. package/example_applications/simple_cards/source/Pict-Application-FlowExample-Configuration.json +0 -15
  105. package/example_applications/simple_cards/source/Pict-Application-FlowExample.js +0 -539
  106. package/example_applications/simple_cards/source/card-help-content.js +0 -16
  107. package/example_applications/simple_cards/source/cards/FlowCard-Comment.js +0 -38
  108. package/example_applications/simple_cards/source/cards/FlowCard-DataPreview.js +0 -44
  109. package/example_applications/simple_cards/source/cards/FlowCard-Each.js +0 -38
  110. package/example_applications/simple_cards/source/cards/FlowCard-FileRead.js +0 -56
  111. package/example_applications/simple_cards/source/cards/FlowCard-FileWrite.js +0 -50
  112. package/example_applications/simple_cards/source/cards/FlowCard-GetValue.js +0 -37
  113. package/example_applications/simple_cards/source/cards/FlowCard-IfThenElse.js +0 -49
  114. package/example_applications/simple_cards/source/cards/FlowCard-LogValues.js +0 -55
  115. package/example_applications/simple_cards/source/cards/FlowCard-SetValue.js +0 -97
  116. package/example_applications/simple_cards/source/cards/FlowCard-Sparkline.js +0 -100
  117. package/example_applications/simple_cards/source/cards/FlowCard-StatusMonitor.js +0 -46
  118. package/example_applications/simple_cards/source/cards/FlowCard-Switch.js +0 -39
  119. package/example_applications/simple_cards/source/providers/PictRouter-FlowExample-Configuration.json +0 -22
  120. package/example_applications/simple_cards/source/sample-flows.js +0 -410
  121. package/example_applications/simple_cards/source/views/PictView-FlowExample-About.js +0 -184
  122. package/example_applications/simple_cards/source/views/PictView-FlowExample-BottomBar.js +0 -77
  123. package/example_applications/simple_cards/source/views/PictView-FlowExample-Documentation.js +0 -325
  124. package/example_applications/simple_cards/source/views/PictView-FlowExample-FileWriteInfo.js +0 -59
  125. package/example_applications/simple_cards/source/views/PictView-FlowExample-Layout.js +0 -90
  126. package/example_applications/simple_cards/source/views/PictView-FlowExample-MainWorkspace.js +0 -453
  127. package/example_applications/simple_cards/source/views/PictView-FlowExample-TopBar.js +0 -95
  128. package/scripts/generate-card-help.js +0 -214
  129. package/source/providers/edges/Edge-Bezier.js +0 -41
  130. package/source/providers/edges/Edge-Orthogonal.js +0 -37
  131. package/source/providers/edges/Edge-OrthogonalSnap.js +0 -72
  132. package/source/providers/edges/Edge-Perimeter-Linear.js +0 -31
  133. package/source/providers/edges/Edge-Perimeter-Orthogonal.js +0 -39
  134. package/source/providers/edges/Edge-Perimeter.js +0 -48
  135. package/source/providers/edges/Edge-PerimeterMath.js +0 -92
  136. package/source/providers/edges/Edge-Straight.js +0 -24
  137. package/source/providers/layouts/Layout-Circular.js +0 -203
  138. package/source/providers/layouts/Layout-Coerce.js +0 -40
  139. package/source/providers/layouts/Layout-Columnar.js +0 -134
  140. package/source/providers/layouts/Layout-Custom.js +0 -27
  141. package/source/providers/layouts/Layout-ForcedFromCenter.js +0 -256
  142. package/source/providers/layouts/Layout-Grid.js +0 -134
  143. package/source/providers/layouts/Layout-Layered.js +0 -155
  144. package/source/providers/layouts/Layout-Rank.js +0 -141
  145. package/source/providers/layouts/Layout-Staggered.js +0 -131
  146. package/source/providers/layouts/Layout-Tabular.js +0 -94
  147. package/test/CardPalette_tests.js +0 -43
  148. package/test/ConnectionHandleManager_tests.js +0 -717
  149. package/test/ConnectionRenderer_tests.js +0 -591
  150. package/test/ConnectionStyle_tests.js +0 -90
  151. package/test/DataManager_tests.js +0 -859
  152. package/test/Geometry_tests.js +0 -767
  153. package/test/InteractionManager_tests.js +0 -279
  154. package/test/Layout_tests.js +0 -1604
  155. package/test/NodeView_tests.js +0 -66
  156. package/test/PanelManager_tests.js +0 -172
  157. package/test/PathGenerator_tests.js +0 -978
  158. package/test/PortRenderer_tests.js +0 -376
  159. package/test/RenderManager_tests.js +0 -756
  160. package/test/Renderer_tests.js +0 -133
  161. package/test/SelectionManager_tests.js +0 -185
  162. package/test/StylePresets_tests.js +0 -153
  163. package/test/ToolbarExtraButtons_tests.js +0 -138
  164. package/test/UndirectedConnections_tests.js +0 -70
@@ -1,859 +0,0 @@
1
- const libFable = require('fable');
2
- const libChai = require('chai');
3
- const libExpect = libChai.expect;
4
-
5
- const libDataManager = require('../source/services/PictService-Flow-DataManager.js');
6
-
7
- suite
8
- (
9
- 'PictService-Flow-DataManager',
10
- function ()
11
- {
12
- let _Fable;
13
- let _DataManager;
14
- let _MockFlowView;
15
-
16
- setup
17
- (
18
- function ()
19
- {
20
- _Fable = new libFable({});
21
-
22
- _MockFlowView =
23
- {
24
- fable: _Fable,
25
- pict: null,
26
- log: _Fable.log,
27
- options:
28
- {
29
- DefaultNodeType: 'generic',
30
- DefaultNodeWidth: 160,
31
- DefaultNodeHeight: 80,
32
- FlowDataAddress: null
33
- },
34
- Bundle: {},
35
- initialRenderComplete: false,
36
- _FlowData:
37
- {
38
- Nodes: [],
39
- Connections: [],
40
- OpenPanels: [],
41
- SavedLayouts: [],
42
- ViewState:
43
- {
44
- PanX: 0,
45
- PanY: 0,
46
- Zoom: 1,
47
- SelectedNodeHash: null,
48
- SelectedConnectionHash: null,
49
- SelectedTetherHash: null
50
- }
51
- },
52
- _NodeTypeProvider:
53
- {
54
- getNodeType: function (pType)
55
- {
56
- if (pType === 'action')
57
- {
58
- return {
59
- Label: 'Action',
60
- DefaultWidth: 200,
61
- DefaultHeight: 100,
62
- DefaultPorts:
63
- [
64
- { Hash: 'p-in', Direction: 'input', Side: 'left', Label: 'In' },
65
- { Hash: 'p-out', Direction: 'output', Side: 'right', Label: 'Out' },
66
- { Hash: 'p-err', Direction: 'output', Side: 'bottom', Label: 'Error', PortType: 'error' }
67
- ]
68
- };
69
- }
70
- return null;
71
- }
72
- },
73
- _LayoutProvider:
74
- {
75
- loadPersistedLayouts: function () {}
76
- },
77
- _EventHandlerProvider:
78
- {
79
- fireEvent: function () {}
80
- },
81
- renderFlow: function () {},
82
- closePanelForNode: function (pNodeHash)
83
- {
84
- _MockFlowView._FlowData.OpenPanels = _MockFlowView._FlowData.OpenPanels.filter(
85
- (pPanel) => pPanel.NodeHash !== pNodeHash
86
- );
87
- },
88
- marshalFromView: function () {}
89
- };
90
-
91
- _DataManager = new libDataManager(_Fable, { FlowView: _MockFlowView }, 'DM-Test');
92
- }
93
- );
94
-
95
- // ---- Constructor ----
96
-
97
- suite
98
- (
99
- 'Constructor',
100
- function ()
101
- {
102
- test
103
- (
104
- 'should instantiate with correct serviceType',
105
- function (fDone)
106
- {
107
- libExpect(_DataManager).to.be.an('object');
108
- libExpect(_DataManager.serviceType).to.equal('PictServiceFlowDataManager');
109
- fDone();
110
- }
111
- );
112
-
113
- test
114
- (
115
- 'should store FlowView reference from options',
116
- function (fDone)
117
- {
118
- libExpect(_DataManager._FlowView).to.equal(_MockFlowView);
119
- fDone();
120
- }
121
- );
122
-
123
- test
124
- (
125
- 'should handle missing FlowView in options',
126
- function (fDone)
127
- {
128
- let tmpManager = new libDataManager(_Fable, {}, 'NoView');
129
- libExpect(tmpManager._FlowView).to.be.null;
130
- fDone();
131
- }
132
- );
133
- }
134
- );
135
-
136
- // ---- getFlowData ----
137
-
138
- suite
139
- (
140
- 'getFlowData',
141
- function ()
142
- {
143
- test
144
- (
145
- 'should return a deep clone of the flow data',
146
- function (fDone)
147
- {
148
- _MockFlowView._FlowData.Nodes.push({ Hash: 'node-1', X: 10, Y: 20 });
149
- let tmpResult = _DataManager.getFlowData();
150
-
151
- libExpect(tmpResult.Nodes).to.have.length(1);
152
- libExpect(tmpResult.Nodes[0].Hash).to.equal('node-1');
153
-
154
- // Verify it's a clone, not a reference
155
- tmpResult.Nodes[0].X = 999;
156
- libExpect(_MockFlowView._FlowData.Nodes[0].X).to.equal(10);
157
- fDone();
158
- }
159
- );
160
-
161
- test
162
- (
163
- 'should return empty object when no FlowView',
164
- function (fDone)
165
- {
166
- let tmpManager = new libDataManager(_Fable, {}, 'NoView');
167
- let tmpResult = tmpManager.getFlowData();
168
- libExpect(tmpResult).to.deep.equal({});
169
- fDone();
170
- }
171
- );
172
- }
173
- );
174
-
175
- // ---- setFlowData ----
176
-
177
- suite
178
- (
179
- 'setFlowData',
180
- function ()
181
- {
182
- test
183
- (
184
- 'should set flow data with validated structure',
185
- function (fDone)
186
- {
187
- let tmpData =
188
- {
189
- Nodes: [{ Hash: 'n1', X: 50, Y: 50 }],
190
- Connections: [{ Hash: 'c1', SourceNodeHash: 'n1', TargetNodeHash: 'n2' }],
191
- ViewState: { PanX: 100, PanY: 200, Zoom: 2 }
192
- };
193
-
194
- _DataManager.setFlowData(tmpData);
195
-
196
- libExpect(_MockFlowView._FlowData.Nodes).to.have.length(1);
197
- libExpect(_MockFlowView._FlowData.Connections).to.have.length(1);
198
- libExpect(_MockFlowView._FlowData.ViewState.PanX).to.equal(100);
199
- libExpect(_MockFlowView._FlowData.ViewState.Zoom).to.equal(2);
200
- fDone();
201
- }
202
- );
203
-
204
- test
205
- (
206
- 'should provide defaults for missing arrays',
207
- function (fDone)
208
- {
209
- _DataManager.setFlowData({ ViewState: { PanX: 10 } });
210
-
211
- libExpect(_MockFlowView._FlowData.Nodes).to.be.an('array').that.is.empty;
212
- libExpect(_MockFlowView._FlowData.Connections).to.be.an('array').that.is.empty;
213
- libExpect(_MockFlowView._FlowData.OpenPanels).to.be.an('array').that.is.empty;
214
- libExpect(_MockFlowView._FlowData.SavedLayouts).to.be.an('array').that.is.empty;
215
- fDone();
216
- }
217
- );
218
-
219
- test
220
- (
221
- 'should provide default ViewState when missing',
222
- function (fDone)
223
- {
224
- _DataManager.setFlowData({ Nodes: [] });
225
-
226
- libExpect(_MockFlowView._FlowData.ViewState.PanX).to.equal(0);
227
- libExpect(_MockFlowView._FlowData.ViewState.PanY).to.equal(0);
228
- libExpect(_MockFlowView._FlowData.ViewState.Zoom).to.equal(1);
229
- libExpect(_MockFlowView._FlowData.ViewState.SelectedNodeHash).to.be.null;
230
- fDone();
231
- }
232
- );
233
-
234
- test
235
- (
236
- 'should reject null data',
237
- function (fDone)
238
- {
239
- let tmpOriginalNodes = _MockFlowView._FlowData.Nodes;
240
- _DataManager.setFlowData(null);
241
- // Should not have changed
242
- libExpect(_MockFlowView._FlowData.Nodes).to.equal(tmpOriginalNodes);
243
- fDone();
244
- }
245
- );
246
-
247
- test
248
- (
249
- 'should reject non-object data',
250
- function (fDone)
251
- {
252
- let tmpOriginalNodes = _MockFlowView._FlowData.Nodes;
253
- _DataManager.setFlowData('invalid');
254
- libExpect(_MockFlowView._FlowData.Nodes).to.equal(tmpOriginalNodes);
255
- fDone();
256
- }
257
- );
258
-
259
- test
260
- (
261
- 'should call renderFlow when initialRenderComplete is true',
262
- function (fDone)
263
- {
264
- let tmpRenderCalled = false;
265
- _MockFlowView.renderFlow = function () { tmpRenderCalled = true; };
266
- _MockFlowView.initialRenderComplete = true;
267
-
268
- _DataManager.setFlowData({ Nodes: [] });
269
-
270
- libExpect(tmpRenderCalled).to.be.true;
271
- fDone();
272
- }
273
- );
274
-
275
- test
276
- (
277
- 'should not call renderFlow when initialRenderComplete is false',
278
- function (fDone)
279
- {
280
- let tmpRenderCalled = false;
281
- _MockFlowView.renderFlow = function () { tmpRenderCalled = true; };
282
- _MockFlowView.initialRenderComplete = false;
283
-
284
- _DataManager.setFlowData({ Nodes: [] });
285
-
286
- libExpect(tmpRenderCalled).to.be.false;
287
- fDone();
288
- }
289
- );
290
-
291
- test
292
- (
293
- 'should call loadPersistedLayouts when LayoutProvider exists',
294
- function (fDone)
295
- {
296
- let tmpLoadCalled = false;
297
- _MockFlowView._LayoutProvider.loadPersistedLayouts = function () { tmpLoadCalled = true; };
298
-
299
- _DataManager.setFlowData({ Nodes: [] });
300
-
301
- libExpect(tmpLoadCalled).to.be.true;
302
- fDone();
303
- }
304
- );
305
- }
306
- );
307
-
308
- // ---- addNode ----
309
-
310
- suite
311
- (
312
- 'addNode',
313
- function ()
314
- {
315
- test
316
- (
317
- 'should add a node with generated hash',
318
- function (fDone)
319
- {
320
- let tmpNode = _DataManager.addNode('generic', 200, 300, 'Test Node');
321
-
322
- libExpect(tmpNode).to.be.an('object');
323
- libExpect(tmpNode.Hash).to.be.a('string').that.includes('node-');
324
- libExpect(tmpNode.X).to.equal(200);
325
- libExpect(tmpNode.Y).to.equal(300);
326
- libExpect(tmpNode.Title).to.equal('Test Node');
327
- libExpect(_MockFlowView._FlowData.Nodes).to.have.length(1);
328
- fDone();
329
- }
330
- );
331
-
332
- test
333
- (
334
- 'should use node type config for defaults',
335
- function (fDone)
336
- {
337
- let tmpNode = _DataManager.addNode('action', 100, 100);
338
-
339
- libExpect(tmpNode.Width).to.equal(200);
340
- libExpect(tmpNode.Height).to.equal(100);
341
- libExpect(tmpNode.Title).to.equal('Action');
342
- libExpect(tmpNode.Ports).to.have.length(3);
343
- fDone();
344
- }
345
- );
346
-
347
- test
348
- (
349
- 'should use option defaults when type config is null',
350
- function (fDone)
351
- {
352
- let tmpNode = _DataManager.addNode('unknown', 100, 100, 'My Node');
353
-
354
- libExpect(tmpNode.Width).to.equal(160);
355
- libExpect(tmpNode.Height).to.equal(80);
356
- libExpect(tmpNode.Title).to.equal('My Node');
357
- // Default ports (2 generic)
358
- libExpect(tmpNode.Ports).to.have.length(2);
359
- fDone();
360
- }
361
- );
362
-
363
- test
364
- (
365
- 'should use DefaultNodeType when type is null',
366
- function (fDone)
367
- {
368
- let tmpNode = _DataManager.addNode(null, 100, 100, 'Fallback');
369
-
370
- libExpect(tmpNode.Type).to.equal('generic');
371
- fDone();
372
- }
373
- );
374
-
375
- test
376
- (
377
- 'should default position to 100,100 when not provided',
378
- function (fDone)
379
- {
380
- let tmpNode = _DataManager.addNode('generic', 0, 0);
381
-
382
- // 0 is falsy, so it should fall back to 100
383
- // (This tests the || operator behavior)
384
- libExpect(tmpNode.X).to.equal(100);
385
- libExpect(tmpNode.Y).to.equal(100);
386
- fDone();
387
- }
388
- );
389
-
390
- test
391
- (
392
- 'should ensure all ports have unique hashes',
393
- function (fDone)
394
- {
395
- let tmpNode = _DataManager.addNode('action', 100, 100);
396
- let tmpHashes = tmpNode.Ports.map((p) => p.Hash);
397
- let tmpUnique = new Set(tmpHashes);
398
- libExpect(tmpUnique.size).to.equal(tmpHashes.length);
399
- fDone();
400
- }
401
- );
402
-
403
- test
404
- (
405
- 'should call renderFlow and marshalFromView',
406
- function (fDone)
407
- {
408
- let tmpRenderCalled = false;
409
- let tmpMarshalCalled = false;
410
- _MockFlowView.renderFlow = function () { tmpRenderCalled = true; };
411
- _DataManager.marshalFromView = function () { tmpMarshalCalled = true; };
412
-
413
- _DataManager.addNode('generic', 100, 100);
414
-
415
- libExpect(tmpRenderCalled).to.be.true;
416
- libExpect(tmpMarshalCalled).to.be.true;
417
- fDone();
418
- }
419
- );
420
-
421
- test
422
- (
423
- 'should fire onNodeAdded and onFlowChanged events',
424
- function (fDone)
425
- {
426
- let tmpEvents = [];
427
- _MockFlowView._EventHandlerProvider.fireEvent = function (pEvent) { tmpEvents.push(pEvent); };
428
-
429
- _DataManager.addNode('generic', 100, 100);
430
-
431
- libExpect(tmpEvents).to.include('onNodeAdded');
432
- libExpect(tmpEvents).to.include('onFlowChanged');
433
- fDone();
434
- }
435
- );
436
-
437
- test
438
- (
439
- 'should return null when no FlowView',
440
- function (fDone)
441
- {
442
- let tmpManager = new libDataManager(_Fable, {}, 'NoView');
443
- let tmpResult = tmpManager.addNode('generic', 100, 100);
444
- libExpect(tmpResult).to.be.null;
445
- fDone();
446
- }
447
- );
448
-
449
- test
450
- (
451
- 'should include custom data when provided',
452
- function (fDone)
453
- {
454
- let tmpNode = _DataManager.addNode('generic', 100, 100, 'Test', { foo: 'bar' });
455
- libExpect(tmpNode.Data).to.deep.equal({ foo: 'bar' });
456
- fDone();
457
- }
458
- );
459
- }
460
- );
461
-
462
- // ---- removeNode ----
463
-
464
- suite
465
- (
466
- 'removeNode',
467
- function ()
468
- {
469
- test
470
- (
471
- 'should remove a node by hash',
472
- function (fDone)
473
- {
474
- let tmpNode = _DataManager.addNode('generic', 100, 100, 'ToRemove');
475
- libExpect(_MockFlowView._FlowData.Nodes).to.have.length(1);
476
-
477
- let tmpResult = _DataManager.removeNode(tmpNode.Hash);
478
- libExpect(tmpResult).to.be.true;
479
- libExpect(_MockFlowView._FlowData.Nodes).to.have.length(0);
480
- fDone();
481
- }
482
- );
483
-
484
- test
485
- (
486
- 'should return false for non-existent node',
487
- function (fDone)
488
- {
489
- let tmpResult = _DataManager.removeNode('non-existent');
490
- libExpect(tmpResult).to.be.false;
491
- fDone();
492
- }
493
- );
494
-
495
- test
496
- (
497
- 'should cascade-delete connections involving the node',
498
- function (fDone)
499
- {
500
- // Set up two nodes with a connection
501
- _MockFlowView._FlowData.Nodes = [
502
- { Hash: 'n1', Ports: [{ Hash: 'p1', Direction: 'output' }] },
503
- { Hash: 'n2', Ports: [{ Hash: 'p2', Direction: 'input' }] }
504
- ];
505
- _MockFlowView._FlowData.Connections = [
506
- { Hash: 'c1', SourceNodeHash: 'n1', SourcePortHash: 'p1', TargetNodeHash: 'n2', TargetPortHash: 'p2' }
507
- ];
508
-
509
- _DataManager.removeNode('n1');
510
-
511
- libExpect(_MockFlowView._FlowData.Connections).to.have.length(0);
512
- fDone();
513
- }
514
- );
515
-
516
- test
517
- (
518
- 'should close open panels for the node',
519
- function (fDone)
520
- {
521
- _MockFlowView._FlowData.Nodes = [{ Hash: 'n1' }];
522
- _MockFlowView._FlowData.OpenPanels = [{ Hash: 'panel-1', NodeHash: 'n1' }];
523
-
524
- _DataManager.removeNode('n1');
525
-
526
- libExpect(_MockFlowView._FlowData.OpenPanels).to.have.length(0);
527
- fDone();
528
- }
529
- );
530
-
531
- test
532
- (
533
- 'should clear selection if removed node was selected',
534
- function (fDone)
535
- {
536
- _MockFlowView._FlowData.Nodes = [{ Hash: 'n1' }];
537
- _MockFlowView._FlowData.ViewState.SelectedNodeHash = 'n1';
538
-
539
- _DataManager.removeNode('n1');
540
-
541
- libExpect(_MockFlowView._FlowData.ViewState.SelectedNodeHash).to.be.null;
542
- fDone();
543
- }
544
- );
545
-
546
- test
547
- (
548
- 'should fire onNodeRemoved and onFlowChanged events',
549
- function (fDone)
550
- {
551
- _MockFlowView._FlowData.Nodes = [{ Hash: 'n1' }];
552
- let tmpEvents = [];
553
- _MockFlowView._EventHandlerProvider.fireEvent = function (pEvent) { tmpEvents.push(pEvent); };
554
-
555
- _DataManager.removeNode('n1');
556
-
557
- libExpect(tmpEvents).to.include('onNodeRemoved');
558
- libExpect(tmpEvents).to.include('onFlowChanged');
559
- fDone();
560
- }
561
- );
562
-
563
- test
564
- (
565
- 'should return false when no FlowView',
566
- function (fDone)
567
- {
568
- let tmpManager = new libDataManager(_Fable, {}, 'NoView');
569
- let tmpResult = tmpManager.removeNode('n1');
570
- libExpect(tmpResult).to.be.false;
571
- fDone();
572
- }
573
- );
574
- }
575
- );
576
-
577
- // ---- addConnection ----
578
-
579
- suite
580
- (
581
- 'addConnection',
582
- function ()
583
- {
584
- setup
585
- (
586
- function ()
587
- {
588
- // Set up two nodes with ports
589
- _MockFlowView._FlowData.Nodes = [
590
- {
591
- Hash: 'n1',
592
- Ports: [
593
- { Hash: 'p-out-1', Direction: 'output', Side: 'right', Label: 'Out' }
594
- ]
595
- },
596
- {
597
- Hash: 'n2',
598
- Ports: [
599
- { Hash: 'p-in-2', Direction: 'input', Side: 'left', Label: 'In' }
600
- ]
601
- }
602
- ];
603
- _MockFlowView._FlowData.Connections = [];
604
- }
605
- );
606
-
607
- test
608
- (
609
- 'should create a connection between valid nodes/ports',
610
- function (fDone)
611
- {
612
- let tmpConn = _DataManager.addConnection('n1', 'p-out-1', 'n2', 'p-in-2');
613
-
614
- libExpect(tmpConn).to.be.an('object');
615
- libExpect(tmpConn.Hash).to.be.a('string').that.includes('conn-');
616
- libExpect(tmpConn.SourceNodeHash).to.equal('n1');
617
- libExpect(tmpConn.TargetNodeHash).to.equal('n2');
618
- libExpect(_MockFlowView._FlowData.Connections).to.have.length(1);
619
- fDone();
620
- }
621
- );
622
-
623
- test
624
- (
625
- 'should return false for missing source node',
626
- function (fDone)
627
- {
628
- let tmpResult = _DataManager.addConnection('non-existent', 'p-out-1', 'n2', 'p-in-2');
629
- libExpect(tmpResult).to.be.false;
630
- fDone();
631
- }
632
- );
633
-
634
- test
635
- (
636
- 'should return false for missing target node',
637
- function (fDone)
638
- {
639
- let tmpResult = _DataManager.addConnection('n1', 'p-out-1', 'non-existent', 'p-in-2');
640
- libExpect(tmpResult).to.be.false;
641
- fDone();
642
- }
643
- );
644
-
645
- test
646
- (
647
- 'should return false for missing source port',
648
- function (fDone)
649
- {
650
- let tmpResult = _DataManager.addConnection('n1', 'bad-port', 'n2', 'p-in-2');
651
- libExpect(tmpResult).to.be.false;
652
- fDone();
653
- }
654
- );
655
-
656
- test
657
- (
658
- 'should return false for missing target port',
659
- function (fDone)
660
- {
661
- let tmpResult = _DataManager.addConnection('n1', 'p-out-1', 'n2', 'bad-port');
662
- libExpect(tmpResult).to.be.false;
663
- fDone();
664
- }
665
- );
666
-
667
- test
668
- (
669
- 'should prevent self-connections',
670
- function (fDone)
671
- {
672
- _MockFlowView._FlowData.Nodes[0].Ports.push(
673
- { Hash: 'p-in-1', Direction: 'input', Side: 'left', Label: 'In' }
674
- );
675
-
676
- let tmpResult = _DataManager.addConnection('n1', 'p-out-1', 'n1', 'p-in-1');
677
- libExpect(tmpResult).to.be.false;
678
- fDone();
679
- }
680
- );
681
-
682
- test
683
- (
684
- 'should prevent duplicate connections',
685
- function (fDone)
686
- {
687
- _DataManager.addConnection('n1', 'p-out-1', 'n2', 'p-in-2');
688
- let tmpResult = _DataManager.addConnection('n1', 'p-out-1', 'n2', 'p-in-2');
689
-
690
- libExpect(tmpResult).to.be.false;
691
- libExpect(_MockFlowView._FlowData.Connections).to.have.length(1);
692
- fDone();
693
- }
694
- );
695
-
696
- test
697
- (
698
- 'should include custom data when provided',
699
- function (fDone)
700
- {
701
- let tmpConn = _DataManager.addConnection('n1', 'p-out-1', 'n2', 'p-in-2', { LineMode: 'bezier' });
702
- libExpect(tmpConn.Data).to.deep.equal({ LineMode: 'bezier' });
703
- fDone();
704
- }
705
- );
706
-
707
- test
708
- (
709
- 'should fire onConnectionCreated and onFlowChanged events',
710
- function (fDone)
711
- {
712
- let tmpEvents = [];
713
- _MockFlowView._EventHandlerProvider.fireEvent = function (pEvent) { tmpEvents.push(pEvent); };
714
-
715
- _DataManager.addConnection('n1', 'p-out-1', 'n2', 'p-in-2');
716
-
717
- libExpect(tmpEvents).to.include('onConnectionCreated');
718
- libExpect(tmpEvents).to.include('onFlowChanged');
719
- fDone();
720
- }
721
- );
722
-
723
- test
724
- (
725
- 'should return false when no FlowView',
726
- function (fDone)
727
- {
728
- let tmpManager = new libDataManager(_Fable, {}, 'NoView');
729
- let tmpResult = tmpManager.addConnection('n1', 'p1', 'n2', 'p2');
730
- libExpect(tmpResult).to.be.false;
731
- fDone();
732
- }
733
- );
734
- }
735
- );
736
-
737
- // ---- removeConnection ----
738
-
739
- suite
740
- (
741
- 'removeConnection',
742
- function ()
743
- {
744
- test
745
- (
746
- 'should remove a connection by hash',
747
- function (fDone)
748
- {
749
- _MockFlowView._FlowData.Nodes = [
750
- { Hash: 'n1', Ports: [{ Hash: 'p1', Direction: 'output' }] },
751
- { Hash: 'n2', Ports: [{ Hash: 'p2', Direction: 'input' }] }
752
- ];
753
-
754
- let tmpConn = _DataManager.addConnection('n1', 'p1', 'n2', 'p2');
755
- libExpect(_MockFlowView._FlowData.Connections).to.have.length(1);
756
-
757
- let tmpResult = _DataManager.removeConnection(tmpConn.Hash);
758
- libExpect(tmpResult).to.be.true;
759
- libExpect(_MockFlowView._FlowData.Connections).to.have.length(0);
760
- fDone();
761
- }
762
- );
763
-
764
- test
765
- (
766
- 'should return false for non-existent connection',
767
- function (fDone)
768
- {
769
- let tmpResult = _DataManager.removeConnection('non-existent');
770
- libExpect(tmpResult).to.be.false;
771
- fDone();
772
- }
773
- );
774
-
775
- test
776
- (
777
- 'should clear selection if removed connection was selected',
778
- function (fDone)
779
- {
780
- _MockFlowView._FlowData.Connections = [
781
- { Hash: 'c1', SourceNodeHash: 'n1', TargetNodeHash: 'n2' }
782
- ];
783
- _MockFlowView._FlowData.ViewState.SelectedConnectionHash = 'c1';
784
-
785
- _DataManager.removeConnection('c1');
786
-
787
- libExpect(_MockFlowView._FlowData.ViewState.SelectedConnectionHash).to.be.null;
788
- fDone();
789
- }
790
- );
791
-
792
- test
793
- (
794
- 'should fire onConnectionRemoved and onFlowChanged events',
795
- function (fDone)
796
- {
797
- _MockFlowView._FlowData.Connections = [
798
- { Hash: 'c1', SourceNodeHash: 'n1', TargetNodeHash: 'n2' }
799
- ];
800
- let tmpEvents = [];
801
- _MockFlowView._EventHandlerProvider.fireEvent = function (pEvent) { tmpEvents.push(pEvent); };
802
-
803
- _DataManager.removeConnection('c1');
804
-
805
- libExpect(tmpEvents).to.include('onConnectionRemoved');
806
- libExpect(tmpEvents).to.include('onFlowChanged');
807
- fDone();
808
- }
809
- );
810
-
811
- test
812
- (
813
- 'should return false when no FlowView',
814
- function (fDone)
815
- {
816
- let tmpManager = new libDataManager(_Fable, {}, 'NoView');
817
- let tmpResult = tmpManager.removeConnection('c1');
818
- libExpect(tmpResult).to.be.false;
819
- fDone();
820
- }
821
- );
822
- }
823
- );
824
-
825
- // ---- marshalToView / marshalFromView ----
826
-
827
- suite
828
- (
829
- 'marshalToView and marshalFromView',
830
- function ()
831
- {
832
- test
833
- (
834
- 'should be no-ops when FlowDataAddress is not set',
835
- function (fDone)
836
- {
837
- // marshalToView with no FlowDataAddress should not crash
838
- _DataManager.marshalToView();
839
- // marshalFromView with no FlowDataAddress should not crash
840
- _DataManager.marshalFromView();
841
- fDone();
842
- }
843
- );
844
-
845
- test
846
- (
847
- 'should be no-ops when no FlowView',
848
- function (fDone)
849
- {
850
- let tmpManager = new libDataManager(_Fable, {}, 'NoView');
851
- tmpManager.marshalToView();
852
- tmpManager.marshalFromView();
853
- fDone();
854
- }
855
- );
856
- }
857
- );
858
- }
859
- );