@design-core/core 0.0.7 → 51.1.0
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/.github/workflows/DesignCoreQA.yml +3 -0
- package/core/designCore.js +1 -1
- package/core/dimensions/alignedDimension.js +7 -7
- package/core/dimensions/angularDimension.js +32 -32
- package/core/dimensions/{baseCircularDimension.js → circularDimensionBase.js} +19 -19
- package/core/dimensions/diametricDimension.js +10 -10
- package/core/dimensions/dimension.js +42 -42
- package/core/dimensions/{baseDimension.js → dimensionBase.js} +17 -17
- package/core/dimensions/{baseLinearDimension.js → linearDimensionBase.js} +9 -9
- package/core/dimensions/radialDimension.js +8 -8
- package/core/dimensions/rotatedDimension.js +8 -8
- package/core/entities/arc.js +22 -22
- package/core/entities/arctext.js +13 -13
- package/core/entities/circle.js +7 -7
- package/core/entities/hatch.js +210 -40
- package/core/entities/insert.js +11 -6
- package/core/entities/point.js +19 -19
- package/core/entities/polyline.js +3 -3
- package/core/entities/{basePolyline.js → polylineBase.js} +18 -18
- package/core/entities/text.js +4 -4
- package/core/lib/boundingBox.js +11 -11
- package/core/lib/canvas.js +13 -6
- package/core/lib/clipboard.js +2 -2
- package/core/lib/dxf/dxf.js +11 -11
- package/core/lib/dxf/dxfIterator.js +2 -2
- package/core/lib/entityManager.js +19 -19
- package/core/lib/inputManager.js +1 -1
- package/core/lib/matrix.js +1 -1
- package/core/lib/patterns.js +1 -1
- package/core/lib/polylineUtils.js +9 -9
- package/core/lib/renderers/cairoRenderer.js +5 -5
- package/core/lib/renderers/canvasRenderer.js +4 -4
- package/core/lib/renderers/pdfRenderer.js +7 -7
- package/core/lib/renderers/rendererBase.js +1 -1
- package/core/lib/scene.js +1 -1
- package/core/lib/selectionManager.js +18 -18
- package/core/lib/utils.js +5 -5
- package/core/properties/entityProperties.js +2 -1
- package/core/properties/flags.js +12 -0
- package/core/properties/property.js +8 -3
- package/core/properties/propertyManager.js +52 -37
- package/core/tables/block.js +50 -46
- package/core/tables/dimStyle.js +5 -5
- package/core/tables/ltypeManager.js +1 -1
- package/core/tables/vport.js +2 -2
- package/core/tools/chamfer.js +6 -6
- package/core/tools/chamferFilletBase.js +4 -4
- package/core/tools/copy.js +8 -8
- package/core/tools/copybase.js +3 -3
- package/core/tools/copyclip.js +3 -3
- package/core/tools/cornerEntity.js +2 -2
- package/core/tools/cutclip.js +3 -3
- package/core/tools/explode.js +6 -6
- package/core/tools/extend.js +13 -13
- package/core/tools/fillet.js +6 -6
- package/core/tools/matchProp.js +1 -1
- package/core/tools/mirror.js +11 -11
- package/core/tools/move.js +5 -5
- package/core/tools/offset.js +29 -29
- package/core/tools/purge.js +10 -10
- package/core/tools/rotate.js +16 -16
- package/core/tools/scale.js +6 -6
- package/core/tools/trim.js +15 -15
- package/cspell.json +323 -0
- package/package.json +1 -1
- package/test/dimensions/alignedDimension.test.js +3 -3
- package/test/dimensions/angularDimension.test.js +7 -7
- package/test/dimensions/diametricDimension.test.js +9 -9
- package/test/dimensions/dimension.test.js +12 -12
- package/test/dimensions/{baseDimension.test.js → dimensionBase.test.js} +12 -12
- package/test/dimensions/{baseLinearDimension.test.js → linearDimensionBase.test.js} +7 -7
- package/test/dimensions/radialDimension.test.js +9 -9
- package/test/dimensions/rotatedDimension.test.js +4 -4
- package/test/entities/arc.test.js +10 -10
- package/test/entities/arctext.test.js +6 -6
- package/test/entities/circle.test.js +18 -18
- package/test/entities/hatch.test.js +362 -39
- package/test/entities/insert.test.js +9 -9
- package/test/entities/point.test.js +3 -3
- package/test/entities/{basePolyline.test.js → polylineBase.test.js} +131 -62
- package/test/entities/text.test.js +19 -19
- package/test/integration/exportIntegration.test.js +3 -3
- package/test/integration/userInputIntegration.test.js +5 -5
- package/test/lib/boundingBox.test.js +3 -3
- package/test/lib/canvas.test.js +9 -9
- package/test/lib/clipboard.test.js +73 -0
- package/test/lib/inputManager.test.js +4 -4
- package/test/lib/scene.test.js +9 -9
- package/test/lib/selectionManager.test.js +3 -3
- package/test/lib/snapping.test.js +1 -1
- package/test/properties/flags.test.js +24 -0
- package/test/properties/propertyManager.test.js +93 -22
- package/test/renderers/pdfRenderer.test.js +2 -2
- package/test/tables/block.test.js +63 -14
- package/test/tables/layerManager.test.js +2 -2
- package/test/test-helpers/hatchGridRenderer.js +3 -3
- package/test/test-helpers/test-helpers.js +6 -6
- package/test/tools/chamfer.test.js +60 -60
- package/test/tools/chamferFilletBase.test.js +36 -36
- package/test/tools/copy.test.js +6 -6
- package/test/tools/copybase.test.js +2 -2
- package/test/tools/copyclip.test.js +2 -2
- package/test/tools/cornerEntity.test.js +8 -8
- package/test/tools/cutclip.test.js +2 -2
- package/test/tools/erase.test.js +6 -6
- package/test/tools/explode.test.js +2 -2
- package/test/tools/extend.test.js +84 -84
- package/test/tools/fillet.test.js +62 -62
- package/test/tools/matchProp.test.js +6 -6
- package/test/tools/mirror.test.js +26 -26
- package/test/tools/move.test.js +7 -7
- package/test/tools/offset.test.js +65 -65
- package/test/tools/purge.test.js +4 -4
- package/test/tools/rotate.test.js +10 -10
- package/test/tools/scale.test.js +28 -28
- package/test/tools/trim.test.js +109 -109
- package/test/tools/zoom.test.js +15 -17
|
@@ -24,9 +24,9 @@ test.each(inputScenarios)('Trim.execute handles $desc', async (scenario) => {
|
|
|
24
24
|
// clear all scene entities
|
|
25
25
|
core.scene.clear();
|
|
26
26
|
// create line
|
|
27
|
-
core.scene.
|
|
27
|
+
core.scene.addEntity('Line', { points: [new Point(), new Point(10, 0)] });
|
|
28
28
|
// create circle
|
|
29
|
-
core.scene.
|
|
29
|
+
core.scene.addEntity('Circle', { points: [new Point(), new Point(10, 0)] });
|
|
30
30
|
// select line
|
|
31
31
|
core.scene.selectionManager.selectionSet.selectionSet.push(0);
|
|
32
32
|
|
|
@@ -35,7 +35,7 @@ test.each(inputScenarios)('Trim.execute handles $desc', async (scenario) => {
|
|
|
35
35
|
await extend.execute();
|
|
36
36
|
|
|
37
37
|
expect(extend.selectedBoundaryItems[0]).toEqual(core.scene.entities.get(0));
|
|
38
|
-
expect(extend.
|
|
38
|
+
expect(extend.selectedEntity).toBe(core.scene.entities.get(1));
|
|
39
39
|
expect(actionSpy).toHaveBeenCalled();
|
|
40
40
|
}, { extraMethods: { actionCommand: () => actionSpy() } });
|
|
41
41
|
});
|
|
@@ -63,12 +63,12 @@ test('Test Extend.action', () => {
|
|
|
63
63
|
// clear all scene entities
|
|
64
64
|
core.scene.clear();
|
|
65
65
|
// Add items to scene
|
|
66
|
-
core.scene.
|
|
67
|
-
core.scene.
|
|
66
|
+
core.scene.addEntity('Line', { points: [lineOneStart, lineOneEnd] });
|
|
67
|
+
core.scene.addEntity('Line', { points: [lineTwoStart, lineTwoEnd] });
|
|
68
68
|
// Select boundary item
|
|
69
69
|
extend.selectedBoundaryItems = [core.scene.entities.get(0)];
|
|
70
70
|
// select item to trim
|
|
71
|
-
extend.
|
|
71
|
+
extend.selectedEntity = core.scene.entities.get(1);
|
|
72
72
|
// set mouse location - required for Extend
|
|
73
73
|
core.mouse.setPosFromScenePoint(new Point(40, 50));
|
|
74
74
|
// Perform Extend
|
|
@@ -95,12 +95,12 @@ test('Test Extend.action', () => {
|
|
|
95
95
|
// clear scene items
|
|
96
96
|
core.scene.clear();
|
|
97
97
|
// Add items to scene
|
|
98
|
-
core.scene.
|
|
99
|
-
core.scene.
|
|
98
|
+
core.scene.addEntity('Line', { points: [lineTwoStart, lineTwoEnd] });
|
|
99
|
+
core.scene.addEntity('Line', { points: [lineThreeStart, lineThreeEnd] });
|
|
100
100
|
// Select boundary item
|
|
101
101
|
extend.selectedBoundaryItems = [core.scene.entities.get(0)];
|
|
102
102
|
// select item to extend
|
|
103
|
-
extend.
|
|
103
|
+
extend.selectedEntity = core.scene.entities.get(1);
|
|
104
104
|
// set mouse location - required for Extend
|
|
105
105
|
core.mouse.setPosFromScenePoint(new Point(0, 20));
|
|
106
106
|
// Perform Extend
|
|
@@ -126,12 +126,12 @@ test('Test Extend.action', () => {
|
|
|
126
126
|
// clear scene items
|
|
127
127
|
core.scene.clear();
|
|
128
128
|
// Add items to scene
|
|
129
|
-
core.scene.
|
|
130
|
-
core.scene.
|
|
129
|
+
core.scene.addEntity('Line', { points: [lineOneStart, lineOneEnd] });
|
|
130
|
+
core.scene.addEntity('Line', { points: [crossingLineStart, crossingLineEnd] });
|
|
131
131
|
// Select boundary item
|
|
132
132
|
extend.selectedBoundaryItems = [core.scene.entities.get(0)];
|
|
133
133
|
// select item to extend
|
|
134
|
-
extend.
|
|
134
|
+
extend.selectedEntity = core.scene.entities.get(1);
|
|
135
135
|
// set mouse location - required for Extend
|
|
136
136
|
core.mouse.setPosFromScenePoint(new Point(35, 35));
|
|
137
137
|
// Perform Extend
|
|
@@ -158,8 +158,8 @@ test('Test Extend.action line - endpoint coincident with intersection', () => {
|
|
|
158
158
|
const extend = new Extend();
|
|
159
159
|
core.scene.clear();
|
|
160
160
|
|
|
161
|
-
core.scene.
|
|
162
|
-
core.scene.
|
|
161
|
+
core.scene.addEntity('Line', { points: [new Point(0, 50), new Point(25, 50)] });
|
|
162
|
+
core.scene.addEntity('Lwpolyline', { points: [
|
|
163
163
|
new Point(50, 0), new Point(50, 100), new Point(100, 100),
|
|
164
164
|
new Point(100, 0), new Point(150, 0), new Point(150, 100),
|
|
165
165
|
new Point(200, 100), new Point(200, 0),
|
|
@@ -171,7 +171,7 @@ test('Test Extend.action line - endpoint coincident with intersection', () => {
|
|
|
171
171
|
const expected = [50, 100, 150, 200];
|
|
172
172
|
for (const ex of expected) {
|
|
173
173
|
extend.selectedBoundaryItems = [boundary];
|
|
174
|
-
extend.
|
|
174
|
+
extend.selectedEntity = line;
|
|
175
175
|
core.mouse.setPosFromScenePoint(new Point(line.points[1].x - 5, 50));
|
|
176
176
|
extend.action();
|
|
177
177
|
expect(line.points[1].x).toBe(ex);
|
|
@@ -188,11 +188,11 @@ test('Test Extend.action polyline - endpoint coincident with intersection', () =
|
|
|
188
188
|
const extend = new Extend();
|
|
189
189
|
core.scene.clear();
|
|
190
190
|
|
|
191
|
-
core.scene.
|
|
192
|
-
core.scene.
|
|
191
|
+
core.scene.addEntity('Lwpolyline', { points: [new Point(0, 0), new Point(50, 50)] });
|
|
192
|
+
core.scene.addEntity('Line', { points: [new Point(100, 0), new Point(100, 100)] });
|
|
193
193
|
|
|
194
194
|
extend.selectedBoundaryItems = [core.scene.entities.get(1)];
|
|
195
|
-
extend.
|
|
195
|
+
extend.selectedEntity = core.scene.entities.get(0);
|
|
196
196
|
core.mouse.setPosFromScenePoint(new Point(45, 45));
|
|
197
197
|
extend.action();
|
|
198
198
|
|
|
@@ -210,11 +210,11 @@ test('Test Extend.action polyline - 2-point polyline extend start', () => {
|
|
|
210
210
|
const extend = new Extend();
|
|
211
211
|
core.scene.clear();
|
|
212
212
|
|
|
213
|
-
core.scene.
|
|
214
|
-
core.scene.
|
|
213
|
+
core.scene.addEntity('Lwpolyline', { points: [new Point(50, 0), new Point(100, 0)] });
|
|
214
|
+
core.scene.addEntity('Line', { points: [new Point(0, -50), new Point(0, 50)] });
|
|
215
215
|
|
|
216
216
|
extend.selectedBoundaryItems = [core.scene.entities.get(1)];
|
|
217
|
-
extend.
|
|
217
|
+
extend.selectedEntity = core.scene.entities.get(0);
|
|
218
218
|
core.mouse.setPosFromScenePoint(new Point(55, 0));
|
|
219
219
|
extend.action();
|
|
220
220
|
|
|
@@ -234,11 +234,11 @@ test('Test Extend.action polyline - extend end segment', () => {
|
|
|
234
234
|
const extend = new Extend();
|
|
235
235
|
core.scene.clear();
|
|
236
236
|
|
|
237
|
-
core.scene.
|
|
238
|
-
core.scene.
|
|
237
|
+
core.scene.addEntity('Lwpolyline', { points: [new Point(0, 0), new Point(50, 0), new Point(75, 0)] });
|
|
238
|
+
core.scene.addEntity('Line', { points: [new Point(100, -50), new Point(100, 50)] });
|
|
239
239
|
|
|
240
240
|
extend.selectedBoundaryItems = [core.scene.entities.get(1)];
|
|
241
|
-
extend.
|
|
241
|
+
extend.selectedEntity = core.scene.entities.get(0);
|
|
242
242
|
core.mouse.setPosFromScenePoint(new Point(80, 0));
|
|
243
243
|
extend.action();
|
|
244
244
|
|
|
@@ -261,11 +261,11 @@ test('Test Extend.action polyline - extend start segment', () => {
|
|
|
261
261
|
const extend = new Extend();
|
|
262
262
|
core.scene.clear();
|
|
263
263
|
|
|
264
|
-
core.scene.
|
|
265
|
-
core.scene.
|
|
264
|
+
core.scene.addEntity('Lwpolyline', { points: [new Point(25, 0), new Point(50, 0), new Point(100, 0)] });
|
|
265
|
+
core.scene.addEntity('Line', { points: [new Point(0, -50), new Point(0, 50)] });
|
|
266
266
|
|
|
267
267
|
extend.selectedBoundaryItems = [core.scene.entities.get(1)];
|
|
268
|
-
extend.
|
|
268
|
+
extend.selectedEntity = core.scene.entities.get(0);
|
|
269
269
|
core.mouse.setPosFromScenePoint(new Point(20, 0));
|
|
270
270
|
extend.action();
|
|
271
271
|
|
|
@@ -288,11 +288,11 @@ test('Test Extend.action polyline - reject arc end segment', () => {
|
|
|
288
288
|
const extend = new Extend();
|
|
289
289
|
core.scene.clear();
|
|
290
290
|
|
|
291
|
-
core.scene.
|
|
292
|
-
core.scene.
|
|
291
|
+
core.scene.addEntity('Lwpolyline', { points: [new Point(0, 0), new Point(50, 0, 1), new Point(100, 0)] });
|
|
292
|
+
core.scene.addEntity('Line', { points: [new Point(125, -50), new Point(125, 50)] });
|
|
293
293
|
|
|
294
294
|
extend.selectedBoundaryItems = [core.scene.entities.get(1)];
|
|
295
|
-
extend.
|
|
295
|
+
extend.selectedEntity = core.scene.entities.get(0);
|
|
296
296
|
core.mouse.setPosFromScenePoint(new Point(100, 0));
|
|
297
297
|
extend.action();
|
|
298
298
|
|
|
@@ -316,11 +316,11 @@ test('Test Extend.action polyline - reject intersection behind endpoint', () =>
|
|
|
316
316
|
const extend = new Extend();
|
|
317
317
|
core.scene.clear();
|
|
318
318
|
|
|
319
|
-
core.scene.
|
|
320
|
-
core.scene.
|
|
319
|
+
core.scene.addEntity('Lwpolyline', { points: [new Point(50, 0), new Point(75, 0), new Point(100, 0)] });
|
|
320
|
+
core.scene.addEntity('Line', { points: [new Point(25, -50), new Point(25, 50)] });
|
|
321
321
|
|
|
322
322
|
extend.selectedBoundaryItems = [core.scene.entities.get(1)];
|
|
323
|
-
extend.
|
|
323
|
+
extend.selectedEntity = core.scene.entities.get(0);
|
|
324
324
|
core.mouse.setPosFromScenePoint(new Point(95, 0));
|
|
325
325
|
extend.action();
|
|
326
326
|
|
|
@@ -339,11 +339,11 @@ test('Test Extend.action polyline - reject shortening intersection', () => {
|
|
|
339
339
|
const extend = new Extend();
|
|
340
340
|
core.scene.clear();
|
|
341
341
|
|
|
342
|
-
core.scene.
|
|
343
|
-
core.scene.
|
|
342
|
+
core.scene.addEntity('Lwpolyline', { points: [new Point(0, 0), new Point(50, 0), new Point(100, 0)] });
|
|
343
|
+
core.scene.addEntity('Line', { points: [new Point(75, -50), new Point(75, 50)] });
|
|
344
344
|
|
|
345
345
|
extend.selectedBoundaryItems = [core.scene.entities.get(1)];
|
|
346
|
-
extend.
|
|
346
|
+
extend.selectedEntity = core.scene.entities.get(0);
|
|
347
347
|
core.mouse.setPosFromScenePoint(new Point(95, 0));
|
|
348
348
|
extend.action();
|
|
349
349
|
|
|
@@ -362,11 +362,11 @@ test('Test Extend.action polyline - extend with arc start segment', () => {
|
|
|
362
362
|
const extend = new Extend();
|
|
363
363
|
core.scene.clear();
|
|
364
364
|
|
|
365
|
-
core.scene.
|
|
366
|
-
core.scene.
|
|
365
|
+
core.scene.addEntity('Lwpolyline', { points: [new Point(0, 0, 1), new Point(50, 0), new Point(100, 0)] });
|
|
366
|
+
core.scene.addEntity('Line', { points: [new Point(125, -50), new Point(125, 50)] });
|
|
367
367
|
|
|
368
368
|
extend.selectedBoundaryItems = [core.scene.entities.get(1)];
|
|
369
|
-
extend.
|
|
369
|
+
extend.selectedEntity = core.scene.entities.get(0);
|
|
370
370
|
core.mouse.setPosFromScenePoint(new Point(110, 0));
|
|
371
371
|
extend.action();
|
|
372
372
|
|
|
@@ -383,11 +383,11 @@ test('Test Extend.action polyline - no intersections', () => {
|
|
|
383
383
|
const extend = new Extend();
|
|
384
384
|
core.scene.clear();
|
|
385
385
|
|
|
386
|
-
core.scene.
|
|
387
|
-
core.scene.
|
|
386
|
+
core.scene.addEntity('Lwpolyline', { points: [new Point(0, 0), new Point(50, 0)] });
|
|
387
|
+
core.scene.addEntity('Line', { points: [new Point(0, 50), new Point(100, 50)] });
|
|
388
388
|
|
|
389
389
|
extend.selectedBoundaryItems = [core.scene.entities.get(1)];
|
|
390
|
-
extend.
|
|
390
|
+
extend.selectedEntity = core.scene.entities.get(0);
|
|
391
391
|
core.mouse.setPosFromScenePoint(new Point(45, 0));
|
|
392
392
|
extend.action();
|
|
393
393
|
|
|
@@ -410,7 +410,7 @@ test('Extend.preview does not throw', () => {
|
|
|
410
410
|
|
|
411
411
|
test('Extend.preview returns early when no boundary items set', () => {
|
|
412
412
|
core.scene.clear();
|
|
413
|
-
core.scene.
|
|
413
|
+
core.scene.addEntity('Line', { points: [new Point(100, -10), new Point(100, 10)] });
|
|
414
414
|
DesignCore.Scene.previewEntities.clear();
|
|
415
415
|
|
|
416
416
|
const extend = new Extend();
|
|
@@ -422,8 +422,8 @@ test('Extend.preview returns early when no boundary items set', () => {
|
|
|
422
422
|
|
|
423
423
|
test('Extend.preview returns early when findClosestItem returns undefined', () => {
|
|
424
424
|
core.scene.clear();
|
|
425
|
-
core.scene.
|
|
426
|
-
core.scene.
|
|
425
|
+
core.scene.addEntity('Line', { points: [new Point(100, -10), new Point(100, 10)] });
|
|
426
|
+
core.scene.addEntity('Line', { points: [new Point(0, 0), new Point(50, 0)] });
|
|
427
427
|
DesignCore.Scene.previewEntities.clear();
|
|
428
428
|
|
|
429
429
|
const extend = new Extend();
|
|
@@ -439,8 +439,8 @@ test('Extend.preview returns early when findClosestItem returns undefined', () =
|
|
|
439
439
|
test('Extend.preview returns early when hovered entity does not implement extend', () => {
|
|
440
440
|
// Circle does not override Entity.extend() — preview must not emit a notification.
|
|
441
441
|
core.scene.clear();
|
|
442
|
-
core.scene.
|
|
443
|
-
core.scene.
|
|
442
|
+
core.scene.addEntity('Line', { points: [new Point(100, -10), new Point(100, 10)] }); // boundary
|
|
443
|
+
core.scene.addEntity('Circle', { points: [new Point(0, 0), new Point(5, 0)] }); // unsupported
|
|
444
444
|
DesignCore.Scene.previewEntities.clear();
|
|
445
445
|
|
|
446
446
|
const notifySpy = jest.spyOn(core, 'notify');
|
|
@@ -460,8 +460,8 @@ test('Extend.preview returns early when hovered entity does not implement extend
|
|
|
460
460
|
test('Extend.preview returns early when hovered entity has no valid extension', () => {
|
|
461
461
|
// Hovered line is parallel to the boundary — no intersection ahead of its endpoint.
|
|
462
462
|
core.scene.clear();
|
|
463
|
-
core.scene.
|
|
464
|
-
core.scene.
|
|
463
|
+
core.scene.addEntity('Line', { points: [new Point(0, 50), new Point(100, 50)] }); // boundary (horizontal)
|
|
464
|
+
core.scene.addEntity('Line', { points: [new Point(0, 0), new Point(50, 0)] }); // hovered (parallel, y=0)
|
|
465
465
|
DesignCore.Scene.previewEntities.clear();
|
|
466
466
|
|
|
467
467
|
const extend = new Extend();
|
|
@@ -479,8 +479,8 @@ test('Extend.preview populates previewEntities when entity can be extended', ()
|
|
|
479
479
|
// Vertical boundary at x=100; short horizontal line from (0,0) to (50,0).
|
|
480
480
|
// Mouse near end (45,0) → end extends to (100,0).
|
|
481
481
|
core.scene.clear();
|
|
482
|
-
core.scene.
|
|
483
|
-
core.scene.
|
|
482
|
+
core.scene.addEntity('Line', { points: [new Point(100, -10), new Point(100, 10)] }); // boundary
|
|
483
|
+
core.scene.addEntity('Line', { points: [new Point(0, 0), new Point(50, 0)] }); // hovered
|
|
484
484
|
DesignCore.Scene.previewEntities.clear();
|
|
485
485
|
|
|
486
486
|
const extend = new Extend();
|
|
@@ -502,7 +502,7 @@ test('Extend.preview populates previewEntities when entity can be extended', ()
|
|
|
502
502
|
test('Extend.execute returns early when boundary input is undefined', async () => {
|
|
503
503
|
core.scene.clear();
|
|
504
504
|
core.scene.selectionManager.reset();
|
|
505
|
-
core.scene.
|
|
505
|
+
core.scene.addEntity('Line', { points: [new Point(), new Point(10, 0)] });
|
|
506
506
|
|
|
507
507
|
await withMockInput(core.scene, [undefined], async () => {
|
|
508
508
|
const extend = new Extend();
|
|
@@ -514,8 +514,8 @@ test('Extend.execute returns early when boundary input is undefined', async () =
|
|
|
514
514
|
test('Extend.execute exits selection loop when selection input is undefined', async () => {
|
|
515
515
|
core.scene.clear();
|
|
516
516
|
core.scene.selectionManager.reset();
|
|
517
|
-
core.scene.
|
|
518
|
-
core.scene.
|
|
517
|
+
core.scene.addEntity('Line', { points: [new Point(100, -10), new Point(100, 10)] });
|
|
518
|
+
core.scene.addEntity('Line', { points: [new Point(0, 0), new Point(50, 0)] });
|
|
519
519
|
core.scene.selectionManager.selectionSet.selectionSet.push(0);
|
|
520
520
|
|
|
521
521
|
const executeCommandSpy = jest.fn();
|
|
@@ -530,9 +530,9 @@ test('Extend.execute exits selection loop when selection input is undefined', as
|
|
|
530
530
|
test('Extend.execute calls actionCommand once per extend selection', async () => {
|
|
531
531
|
core.scene.clear();
|
|
532
532
|
core.scene.selectionManager.reset();
|
|
533
|
-
core.scene.
|
|
534
|
-
core.scene.
|
|
535
|
-
core.scene.
|
|
533
|
+
core.scene.addEntity('Line', { points: [new Point(100, -10), new Point(100, 10)] });
|
|
534
|
+
core.scene.addEntity('Line', { points: [new Point(0, 0), new Point(50, 0)] });
|
|
535
|
+
core.scene.addEntity('Line', { points: [new Point(0, 5), new Point(50, 5)] });
|
|
536
536
|
core.scene.selectionManager.selectionSet.selectionSet.push(0);
|
|
537
537
|
|
|
538
538
|
const actionSpy = jest.fn();
|
|
@@ -548,11 +548,11 @@ test('Extend.execute calls actionCommand once per extend selection', async () =>
|
|
|
548
548
|
);
|
|
549
549
|
});
|
|
550
550
|
|
|
551
|
-
test('Extend.action does nothing when
|
|
551
|
+
test('Extend.action does nothing when selectedEntity is null', () => {
|
|
552
552
|
core.scene.clear();
|
|
553
|
-
core.scene.
|
|
553
|
+
core.scene.addEntity('Line', { points: [new Point(), new Point(10, 0)] });
|
|
554
554
|
const extend = new Extend();
|
|
555
|
-
extend.
|
|
555
|
+
extend.selectedEntity = null;
|
|
556
556
|
extend.selectedBoundaryItems = [core.scene.entities.get(0)];
|
|
557
557
|
|
|
558
558
|
expect(() => extend.action()).not.toThrow();
|
|
@@ -560,24 +560,24 @@ test('Extend.action does nothing when selectedItem is null', () => {
|
|
|
560
560
|
|
|
561
561
|
test('Extend.action does nothing when selectedBoundaryItems is empty', () => {
|
|
562
562
|
core.scene.clear();
|
|
563
|
-
core.scene.
|
|
563
|
+
core.scene.addEntity('Line', { points: [new Point(), new Point(10, 0)] });
|
|
564
564
|
const extend = new Extend();
|
|
565
|
-
extend.
|
|
565
|
+
extend.selectedEntity = core.scene.entities.get(0);
|
|
566
566
|
extend.selectedBoundaryItems = [];
|
|
567
567
|
|
|
568
568
|
expect(() => extend.action()).not.toThrow();
|
|
569
|
-
expect(extend.
|
|
569
|
+
expect(extend.selectedEntity).toBeNull();
|
|
570
570
|
});
|
|
571
571
|
|
|
572
572
|
test('Extend.action notifies NOEXTEND when selected entity lacks fromPolylinePoints', () => {
|
|
573
573
|
// Use a stub entity that has toPolylinePoints but no fromPolylinePoints.
|
|
574
574
|
// action() must notify and not throw.
|
|
575
575
|
core.scene.clear();
|
|
576
|
-
core.scene.
|
|
576
|
+
core.scene.addEntity('Line', { points: [new Point(100, -10), new Point(100, 10)] }); // boundary
|
|
577
577
|
|
|
578
578
|
const extend = new Extend();
|
|
579
579
|
extend.selectedBoundaryItems = [core.scene.entities.get(0)];
|
|
580
|
-
extend.
|
|
580
|
+
extend.selectedEntity = {
|
|
581
581
|
type: 'FakeEntity',
|
|
582
582
|
toPolylinePoints: () => [new Point(0, 0), new Point(50, 0)],
|
|
583
583
|
// deliberately no fromPolylinePoints
|
|
@@ -588,30 +588,30 @@ test('Extend.action notifies NOEXTEND when selected entity lacks fromPolylinePoi
|
|
|
588
588
|
extend.action();
|
|
589
589
|
|
|
590
590
|
expect(notifySpy).toHaveBeenCalledWith(expect.stringContaining(Strings.Message.NOEXTEND));
|
|
591
|
-
expect(extend.
|
|
591
|
+
expect(extend.selectedEntity).toBeNull();
|
|
592
592
|
notifySpy.mockRestore();
|
|
593
593
|
});
|
|
594
594
|
|
|
595
595
|
test('Extend.action notifies NOEXTEND when selected entity is a closed polyline', () => {
|
|
596
596
|
// Closed polylines have no open endpoints — extend must notify and leave the entity unchanged.
|
|
597
597
|
core.scene.clear();
|
|
598
|
-
core.scene.
|
|
598
|
+
core.scene.addEntity('Line', { points: [new Point(200, -10), new Point(200, 10)] }); // boundary
|
|
599
599
|
// Closed square: flag bit 1 set
|
|
600
|
-
core.scene.
|
|
600
|
+
core.scene.addEntity('Lwpolyline', {
|
|
601
601
|
points: [new Point(0, 0), new Point(100, 0), new Point(100, 100), new Point(0, 100)],
|
|
602
602
|
flags: 1,
|
|
603
603
|
});
|
|
604
604
|
|
|
605
605
|
const extend = new Extend();
|
|
606
606
|
extend.selectedBoundaryItems = [core.scene.entities.get(0)];
|
|
607
|
-
extend.
|
|
607
|
+
extend.selectedEntity = core.scene.entities.get(1);
|
|
608
608
|
core.mouse.setPosFromScenePoint(new Point(95, 0));
|
|
609
609
|
|
|
610
610
|
const notifySpy = jest.spyOn(core, 'notify').mockImplementation(() => {});
|
|
611
611
|
extend.action();
|
|
612
612
|
|
|
613
613
|
expect(notifySpy).toHaveBeenCalledWith(expect.stringContaining(Strings.Message.NOEXTEND));
|
|
614
|
-
expect(extend.
|
|
614
|
+
expect(extend.selectedEntity).toBeNull();
|
|
615
615
|
notifySpy.mockRestore();
|
|
616
616
|
});
|
|
617
617
|
|
|
@@ -619,7 +619,7 @@ test('Extend.preview silently skips entity that lacks fromPolylinePoints', () =>
|
|
|
619
619
|
// Stub entity implements toPolylinePoints but not fromPolylinePoints.
|
|
620
620
|
// preview() must return early without calling notify.
|
|
621
621
|
core.scene.clear();
|
|
622
|
-
core.scene.
|
|
622
|
+
core.scene.addEntity('Line', { points: [new Point(100, -10), new Point(100, 10)] }); // boundary
|
|
623
623
|
DesignCore.Scene.previewEntities.clear();
|
|
624
624
|
|
|
625
625
|
const stubEntity = {
|
|
@@ -648,30 +648,30 @@ test('Extend.preview silently skips entity that lacks fromPolylinePoints', () =>
|
|
|
648
648
|
test('Extend.action notifies when no intersection found (parallel lines)', () => {
|
|
649
649
|
core.scene.clear();
|
|
650
650
|
// Two parallel horizontal lines — no intersection possible
|
|
651
|
-
core.scene.
|
|
652
|
-
core.scene.
|
|
651
|
+
core.scene.addEntity('Line', { points: [new Point(0, 0), new Point(100, 0)] });
|
|
652
|
+
core.scene.addEntity('Line', { points: [new Point(0, 50), new Point(50, 50)] });
|
|
653
653
|
|
|
654
654
|
const extend = new Extend();
|
|
655
655
|
extend.selectedBoundaryItems = [core.scene.entities.get(0)];
|
|
656
|
-
extend.
|
|
656
|
+
extend.selectedEntity = core.scene.entities.get(1);
|
|
657
657
|
core.mouse.setPosFromScenePoint(new Point(40, 50));
|
|
658
658
|
|
|
659
659
|
const notifySpy = jest.spyOn(core, 'notify').mockImplementation(() => {});
|
|
660
660
|
extend.action();
|
|
661
661
|
|
|
662
662
|
expect(notifySpy).toHaveBeenCalledWith(expect.stringContaining(Strings.Message.NOEXTEND));
|
|
663
|
-
expect(extend.
|
|
663
|
+
expect(extend.selectedEntity).toBeNull();
|
|
664
664
|
notifySpy.mockRestore();
|
|
665
665
|
});
|
|
666
666
|
|
|
667
667
|
test('Extend.action notifies when boundary item equals selected item', () => {
|
|
668
668
|
core.scene.clear();
|
|
669
|
-
core.scene.
|
|
669
|
+
core.scene.addEntity('Line', { points: [new Point(0, 0), new Point(50, 0)] });
|
|
670
670
|
const entity = core.scene.entities.get(0);
|
|
671
671
|
|
|
672
672
|
const extend = new Extend();
|
|
673
673
|
extend.selectedBoundaryItems = [entity];
|
|
674
|
-
extend.
|
|
674
|
+
extend.selectedEntity = entity;
|
|
675
675
|
core.mouse.setPosFromScenePoint(new Point(40, 0));
|
|
676
676
|
|
|
677
677
|
const notifySpy = jest.spyOn(core, 'notify').mockImplementation(() => {});
|
|
@@ -686,12 +686,12 @@ test('Extend.action extends the start of a line', () => {
|
|
|
686
686
|
// Boundary: vertical line at x=0
|
|
687
687
|
// Mouse near the start (50,50) → extend start back to x=0
|
|
688
688
|
core.scene.clear();
|
|
689
|
-
core.scene.
|
|
690
|
-
core.scene.
|
|
689
|
+
core.scene.addEntity('Line', { points: [new Point(0, 0), new Point(0, 100)] });
|
|
690
|
+
core.scene.addEntity('Line', { points: [new Point(50, 50), new Point(100, 50)] });
|
|
691
691
|
|
|
692
692
|
const extend = new Extend();
|
|
693
693
|
extend.selectedBoundaryItems = [core.scene.entities.get(0)];
|
|
694
|
-
extend.
|
|
694
|
+
extend.selectedEntity = core.scene.entities.get(1);
|
|
695
695
|
core.mouse.setPosFromScenePoint(new Point(55, 50));
|
|
696
696
|
extend.action();
|
|
697
697
|
|
|
@@ -705,22 +705,22 @@ test('Extend.action notifies NOEXTEND when end segment of an Arc is curved', ()
|
|
|
705
705
|
// A standalone Arc always has a non-zero bulge on its single segment.
|
|
706
706
|
// #extendEntity must reject the extension and notify because endSegmentBulge !== 0.
|
|
707
707
|
core.scene.clear();
|
|
708
|
-
core.scene.
|
|
708
|
+
core.scene.addEntity('Arc', {
|
|
709
709
|
points: [new Point(0, 0), new Point(10, 0), new Point(0, 10)],
|
|
710
710
|
direction: 1,
|
|
711
711
|
});
|
|
712
712
|
// Vertical boundary at x=5 — intersects the CCW quarter-arc
|
|
713
|
-
core.scene.
|
|
713
|
+
core.scene.addEntity('Line', { points: [new Point(5, -20), new Point(5, 20)] });
|
|
714
714
|
|
|
715
715
|
const extend = new Extend();
|
|
716
716
|
extend.selectedBoundaryItems = [core.scene.entities.get(1)];
|
|
717
|
-
extend.
|
|
717
|
+
extend.selectedEntity = core.scene.entities.get(0);
|
|
718
718
|
core.mouse.setPosFromScenePoint(new Point(9, 1)); // near arc start (10,0)
|
|
719
719
|
|
|
720
720
|
const notifySpy = jest.spyOn(core, 'notify').mockImplementation(() => {});
|
|
721
721
|
extend.action();
|
|
722
722
|
|
|
723
723
|
expect(notifySpy).toHaveBeenCalledWith(expect.stringContaining(Strings.Message.NOEXTEND));
|
|
724
|
-
expect(extend.
|
|
724
|
+
expect(extend.selectedEntity).toBeNull();
|
|
725
725
|
notifySpy.mockRestore();
|
|
726
726
|
});
|