@design-core/core 0.0.1 → 0.0.3
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/.eslintrc.json +14 -7
- package/.github/workflows/DesignCoreQA.yml +3 -1
- package/README.md +11 -4
- package/TODO.md +19 -0
- package/core/core/core.js +49 -42
- package/core/designCore.js +61 -2
- package/core/dimensions/alignedDimension.js +142 -0
- package/core/dimensions/angularDimension.js +550 -0
- package/core/dimensions/baseCircularDimension.js +244 -0
- package/core/dimensions/baseDimension.js +558 -0
- package/core/dimensions/baseLinearDimension.js +371 -0
- package/core/dimensions/diametricDimension.js +82 -0
- package/core/dimensions/dimension.js +298 -0
- package/core/dimensions/linearDimension.js +29 -0
- package/core/dimensions/radialDimension.js +78 -0
- package/core/dimensions/rotatedDimension.js +167 -0
- package/core/entities/arc.js +314 -60
- package/core/entities/arctext.js +642 -0
- package/core/entities/basePolyline.js +553 -94
- package/core/entities/circle.js +181 -54
- package/core/entities/entity.js +154 -74
- package/core/entities/hatch.js +807 -0
- package/core/entities/insert.js +200 -39
- package/core/entities/line.js +196 -134
- package/core/entities/lwpolyline.js +21 -44
- package/core/entities/point.js +194 -29
- package/core/entities/polyline.js +54 -7
- package/core/entities/rectangle.js +43 -13
- package/core/entities/solid.js +43 -6
- package/core/entities/text.js +324 -181
- package/core/lib/boundingBox.js +73 -13
- package/core/lib/canvas.js +256 -65
- package/core/lib/clipboard.js +198 -0
- package/core/lib/colour.js +144 -0
- package/core/lib/colours.js +367 -301
- package/core/lib/commandLine.js +16 -28
- package/core/lib/commandManager.js +115 -58
- package/core/lib/constants.js +23 -0
- package/core/lib/dxf/dxf.js +249 -34
- package/core/lib/dxf/dxfFile.js +23 -38
- package/core/lib/dxf/dxfIterator.js +17 -5
- package/core/lib/dxf/dxfRead.js +23 -7
- package/core/lib/dxf/dxfWrite.js +39 -129
- package/core/lib/dxf/handleManager.js +97 -0
- package/core/lib/dxf/sections/blocks.js +16 -2
- package/core/lib/dxf/sections/entities.js +17 -3
- package/core/lib/dxf/sections/header.js +10 -1
- package/core/lib/dxf/sections/objects.js +36 -0
- package/core/lib/dxf/sections/section.js +43 -5
- package/core/lib/dxf/sections/tables.js +17 -3
- package/core/lib/entityManager.js +178 -0
- package/core/lib/fileio.js +14 -4
- package/core/lib/headers.js +229 -0
- package/core/lib/input.js +46 -0
- package/core/lib/inputManager.js +199 -194
- package/core/lib/intersect.js +341 -468
- package/core/lib/logging.js +25 -1
- package/core/lib/matrix.js +6 -8
- package/core/lib/mouse.js +24 -79
- package/core/lib/patterns.js +690 -0
- package/core/lib/promptOptions.js +133 -0
- package/core/lib/scene.js +71 -174
- package/core/lib/selectionManager.js +74 -48
- package/core/lib/selectionWindow.js +24 -10
- package/core/lib/settings.js +18 -11
- package/core/lib/snapping.js +129 -21
- package/core/lib/stateManager.js +288 -0
- package/core/lib/strings.js +57 -5
- package/core/lib/utils.js +95 -11
- package/core/objects/dictionary.js +43 -0
- package/core/objects/dictionaryManager.js +80 -0
- package/core/properties/dimType.js +117 -0
- package/core/properties/flags.js +66 -0
- package/core/properties/property.js +26 -0
- package/core/properties/propertyManager.js +65 -19
- package/core/tables/appId.js +31 -0
- package/core/tables/appIdManager.js +44 -0
- package/core/tables/block.js +323 -0
- package/core/tables/blockManager.js +48 -0
- package/core/tables/blockRecord.js +29 -0
- package/core/tables/blockRecordManager.js +37 -0
- package/core/tables/dimStyle.js +627 -0
- package/core/tables/dimStyleManager.js +187 -0
- package/core/tables/endblk.js +28 -0
- package/core/tables/layer.js +219 -0
- package/core/tables/layerManager.js +47 -0
- package/core/tables/ltype.js +85 -0
- package/core/tables/ltypeManager.js +65 -0
- package/core/tables/style.js +145 -0
- package/core/tables/styleManager.js +55 -0
- package/core/tables/styleManagerBase.js +110 -0
- package/core/tables/tableManagerBase.js +354 -0
- package/core/tables/ucs.js +28 -0
- package/core/tables/ucsManager.js +44 -0
- package/core/tables/view.js +28 -0
- package/core/tables/viewManager.js +44 -0
- package/core/tables/vport.js +70 -0
- package/core/tables/vportManager.js +65 -0
- package/core/tools/chamfer.js +343 -0
- package/core/tools/chamferFilletBase.js +162 -0
- package/core/tools/copy.js +68 -40
- package/core/tools/copybase.js +65 -0
- package/core/tools/copyclip.js +59 -0
- package/core/tools/cornerEntity.js +138 -0
- package/core/tools/cutclip.js +72 -0
- package/core/tools/distance.js +37 -9
- package/core/tools/erase.js +43 -13
- package/core/tools/explode.js +117 -0
- package/core/tools/extend.js +71 -32
- package/core/tools/fillet.js +336 -0
- package/core/tools/identify.js +33 -6
- package/core/tools/matchProp.js +106 -0
- package/core/tools/mirror.js +141 -0
- package/core/tools/move.js +65 -32
- package/core/tools/offset.js +321 -0
- package/core/tools/pan.js +54 -0
- package/core/tools/pasteclip.js +93 -0
- package/core/tools/purge.js +90 -0
- package/core/tools/rotate.js +105 -70
- package/core/tools/scale.js +166 -0
- package/core/tools/tool.js +14 -4
- package/core/tools/trim.js +71 -32
- package/core/tools/zoom.js +152 -0
- package/package.json +3 -305
- package/test/dimensions/alignedDimension.test.js +211 -0
- package/test/dimensions/angularDimension.test.js +243 -0
- package/test/dimensions/baseDimension.test.js +239 -0
- package/test/dimensions/diametricDimension.test.js +203 -0
- package/test/dimensions/dimension.test.js +102 -0
- package/test/dimensions/radialDimension.test.js +203 -0
- package/test/dimensions/rotatedDimension.test.js +224 -0
- package/test/entities/arc.test.js +463 -41
- package/test/entities/arctext.test.js +329 -0
- package/test/entities/basePolyline.test.js +459 -10
- package/test/entities/circle.test.js +312 -7
- package/test/entities/entity.test.js +28 -9
- package/test/entities/hatch.test.js +606 -0
- package/test/entities/insert.test.js +90 -0
- package/test/entities/line.test.js +182 -6
- package/test/entities/point.test.js +375 -37
- package/test/entities/solid.test.js +156 -0
- package/test/entities/text.test.js +533 -7
- package/test/integration/exportIntegration.reference.dxf +1706 -0
- package/test/integration/exportIntegration.test.js +186 -0
- package/test/integration/importExportIntegration.test.js +126 -0
- package/test/integration/intersectionIntegration.test.js +880 -0
- package/test/integration/userInputIntegration.reference.dxf +1410 -0
- package/test/integration/userInputIntegration.test.js +269 -0
- package/test/lib/boundingBox.test.js +26 -2
- package/test/lib/canvas.test.js +613 -5
- package/test/lib/clipboard.test.js +70 -0
- package/test/lib/colour.test.js +114 -0
- package/test/lib/colours.test.js +63 -18
- package/test/lib/commandLine.test.js +159 -22
- package/test/lib/commandManager.test.js +4 -4
- package/test/lib/constants.test.js +9 -0
- package/test/lib/dxf/dxfFile.test.js +6 -2
- package/test/lib/dxf/dxfIterator.test.js +1 -1
- package/test/lib/dxf/dxfWrite.test.js +173 -0
- package/test/lib/dxf/handleManager.test.js +137 -0
- package/test/lib/dxf/sections/blocks.test.js +5 -5
- package/test/lib/dxf/sections/entities.test.js +4 -4
- package/test/lib/dxf/sections/header.test.js +18 -4
- package/test/lib/dxf/sections/objects.test.js +132 -0
- package/test/lib/dxf/sections/section.test.js +29 -29
- package/test/lib/dxf/sections/tables.test.js +3 -3
- package/test/lib/entityManager.test.js +163 -0
- package/test/lib/headers.test.js +233 -0
- package/test/lib/inputManager.test.js +1144 -5
- package/test/lib/intersect.test.js +454 -331
- package/test/lib/logging.test.js +1 -1
- package/test/lib/matrix.test.js +1 -1
- package/test/lib/mouse.test.js +327 -4
- package/test/lib/patterns.test.js +105 -0
- package/test/lib/promptOptions.test.js +179 -0
- package/test/lib/scene.test.js +16 -52
- package/test/lib/selectionManager.test.js +17 -5
- package/test/lib/settings.test.js +111 -5
- package/test/lib/snapping.test.js +142 -4
- package/test/lib/stateManager.test.js +155 -0
- package/test/lib/utils.test.js +81 -1
- package/test/objects/dictionary.test.js +81 -0
- package/test/objects/dictionaryManager.test.js +34 -0
- package/test/properties/dimType.test.js +62 -0
- package/test/properties/flags.test.js +164 -0
- package/test/properties/property.test.js +13 -0
- package/test/properties/propertyManager.test.js +10 -11
- package/test/tables/appId.test.js +46 -0
- package/test/tables/appIdManager.test.js +72 -0
- package/test/tables/block.test.js +157 -0
- package/test/tables/blockManager.test.js +52 -0
- package/test/tables/blockRecord.test.js +39 -0
- package/test/tables/blockRecordManager.test.js +60 -0
- package/test/tables/dimstyle.test.js +72 -0
- package/test/tables/endblk.test.js +30 -0
- package/test/tables/layer.test.js +95 -0
- package/test/tables/layerManager.test.js +172 -0
- package/test/{styles → tables}/ltype.test.js +7 -7
- package/test/{styles → tables}/ltypeManager.test.js +2 -2
- package/test/tables/style.test.js +44 -0
- package/test/tables/stylemanagerbase.test.js +220 -0
- package/test/tables/tableManagerBase.test.js +194 -0
- package/test/tables/ucs.test.js +37 -0
- package/test/tables/ucsManager.test.js +48 -0
- package/test/tables/view.test.js +37 -0
- package/test/tables/viewManager.test.js +48 -0
- package/test/tables/vport.test.js +117 -0
- package/test/tables/vportManager.test.js +54 -0
- package/test/test-helpers/test-helpers.js +66 -0
- package/test/tools/chamfer.test.js +970 -0
- package/test/tools/chamferFilletBase.test.js +446 -0
- package/test/tools/copy.test.js +22 -14
- package/test/tools/copybase.test.js +93 -0
- package/test/tools/copyclip.test.js +92 -0
- package/test/tools/cornerEntity.test.js +201 -0
- package/test/tools/cutclip.test.js +94 -0
- package/test/tools/distance.test.js +140 -18
- package/test/tools/erase.test.js +12 -12
- package/test/tools/explode.test.js +45 -0
- package/test/tools/extend.test.js +326 -44
- package/test/tools/fillet.test.js +831 -0
- package/test/tools/identify.test.js +115 -16
- package/test/tools/matchProp.test.js +84 -0
- package/test/tools/mirror.test.js +475 -0
- package/test/tools/move.test.js +75 -19
- package/test/tools/offset.test.js +748 -0
- package/test/tools/pan.test.js +72 -0
- package/test/tools/pasteclip.test.js +100 -0
- package/test/tools/purge.test.js +89 -0
- package/test/tools/rotate.test.js +89 -23
- package/test/tools/scale.test.js +529 -0
- package/test/tools/trim.test.js +419 -84
- package/test/tools/zoom.test.js +504 -0
- package/core/entities/alignedDimension.js +0 -279
- package/core/entities/angularDimension.js +0 -194
- package/core/entities/baseDimension.js +0 -227
- package/core/entities/block.js +0 -247
- package/core/entities/diametricDimension.js +0 -133
- package/core/entities/dimension.js +0 -202
- package/core/entities/radialDimension.js +0 -126
- package/core/styles/dimStyle.js +0 -719
- package/core/styles/dimStyleManager.js +0 -47
- package/core/styles/layer.js +0 -133
- package/core/styles/layerManager.js +0 -40
- package/core/styles/ltype.js +0 -86
- package/core/styles/ltypeManager.js +0 -50
- package/core/styles/style.js +0 -158
- package/core/styles/styleManager.js +0 -43
- package/core/styles/styleManagerBase.js +0 -299
- package/test/entities/block.test.js +0 -22
- package/test/styles/dimstyle.test.js +0 -19
- package/test/styles/layerManager.test.js +0 -150
- package/test/styles/style.test.js +0 -33
- package/test/styles/stylemanagerbase.test.js +0 -219
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
import { Core } from '../../core/core/core.js';
|
|
2
|
+
import { DesignCore } from '../../core/designCore.js';
|
|
3
|
+
import { Point } from '../../core/entities/point.js';
|
|
4
|
+
import { Zoom } from '../../core/tools/zoom.js';
|
|
5
|
+
import { expect, jest } from '@jest/globals';
|
|
6
|
+
import { withMockInput } from '../test-helpers/test-helpers.js';
|
|
7
|
+
|
|
8
|
+
const core = new Core();
|
|
9
|
+
|
|
10
|
+
test('Test Zoom.register', () => {
|
|
11
|
+
const command = Zoom.register();
|
|
12
|
+
expect(command.command).toBe('Zoom');
|
|
13
|
+
expect(command.shortcut).toBe('Z');
|
|
14
|
+
expect(command.type).toBeUndefined();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('Test Zoom.action - Window mode', () => {
|
|
18
|
+
// Set canvas dimensions for zoom calculations
|
|
19
|
+
core.canvas.width = 800;
|
|
20
|
+
core.canvas.height = 600;
|
|
21
|
+
|
|
22
|
+
// Set initial scale
|
|
23
|
+
core.canvas.matrix.scale(1, 1);
|
|
24
|
+
|
|
25
|
+
const initialScale = core.canvas.getScale();
|
|
26
|
+
|
|
27
|
+
const zoom = new Zoom();
|
|
28
|
+
zoom.mode = 'Window';
|
|
29
|
+
|
|
30
|
+
// Set two points for window zoom
|
|
31
|
+
zoom.points.push(new Point(0, 0));
|
|
32
|
+
zoom.points.push(new Point(100, 100));
|
|
33
|
+
|
|
34
|
+
// Perform zoom
|
|
35
|
+
zoom.action();
|
|
36
|
+
|
|
37
|
+
// Verify scale has changed (should be different from initial)
|
|
38
|
+
const finalScale = core.canvas.getScale();
|
|
39
|
+
expect(finalScale).not.toBe(initialScale);
|
|
40
|
+
expect(finalScale).toBeGreaterThan(0);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('Test Zoom.action - Window mode with reversed points', () => {
|
|
44
|
+
// Set canvas dimensions
|
|
45
|
+
core.canvas.width = 800;
|
|
46
|
+
core.canvas.height = 600;
|
|
47
|
+
core.canvas.matrix.scale(1, 1);
|
|
48
|
+
|
|
49
|
+
const initialScale = core.canvas.getScale();
|
|
50
|
+
|
|
51
|
+
const zoom = new Zoom();
|
|
52
|
+
zoom.mode = 'Window';
|
|
53
|
+
|
|
54
|
+
// Points in reverse order (should still work)
|
|
55
|
+
zoom.points.push(new Point(100, 100));
|
|
56
|
+
zoom.points.push(new Point(0, 0));
|
|
57
|
+
|
|
58
|
+
zoom.action();
|
|
59
|
+
|
|
60
|
+
const finalScale = core.canvas.getScale();
|
|
61
|
+
expect(finalScale).not.toBe(initialScale);
|
|
62
|
+
expect(finalScale).toBeGreaterThan(0);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test('Test Zoom.action - Window mode with single point (should not zoom)', () => {
|
|
66
|
+
core.canvas.width = 800;
|
|
67
|
+
core.canvas.height = 600;
|
|
68
|
+
core.canvas.matrix.scale(1, 1);
|
|
69
|
+
|
|
70
|
+
const initialScale = core.canvas.getScale();
|
|
71
|
+
|
|
72
|
+
const zoom = new Zoom();
|
|
73
|
+
zoom.mode = 'Window';
|
|
74
|
+
|
|
75
|
+
// Only one point - action should not zoom
|
|
76
|
+
zoom.points.push(new Point(0, 0));
|
|
77
|
+
|
|
78
|
+
zoom.action();
|
|
79
|
+
|
|
80
|
+
// Scale should remain the same
|
|
81
|
+
const finalScale = core.canvas.getScale();
|
|
82
|
+
expect(finalScale).toBe(initialScale);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
test('Test Zoom.action - All mode (calls zoomExtents)', () => {
|
|
86
|
+
// Add items to scene so extents exist
|
|
87
|
+
DesignCore.Scene.addItem('Line', { points: [new Point(10, 10), new Point(100, 100)] });
|
|
88
|
+
DesignCore.Scene.addItem('Circle', { points: [new Point(50, 50), new Point(60, 60)] });
|
|
89
|
+
|
|
90
|
+
core.canvas.width = 800;
|
|
91
|
+
core.canvas.height = 600;
|
|
92
|
+
core.canvas.matrix.scale(1, 1);
|
|
93
|
+
|
|
94
|
+
const initialScale = core.canvas.getScale();
|
|
95
|
+
|
|
96
|
+
// zoomExtents should change the scale
|
|
97
|
+
core.canvas.zoomExtents();
|
|
98
|
+
|
|
99
|
+
const finalScale = core.canvas.getScale();
|
|
100
|
+
expect(finalScale).not.toBe(initialScale);
|
|
101
|
+
expect(finalScale).toBeGreaterThan(0);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('Test Zoom.preview - Window mode with one point', () => {
|
|
105
|
+
const zoom = new Zoom();
|
|
106
|
+
zoom.mode = 'Window';
|
|
107
|
+
zoom.points.push(new Point(10, 10));
|
|
108
|
+
|
|
109
|
+
// Mock mouse position
|
|
110
|
+
core.mouse.mouseMoved(50, 50);
|
|
111
|
+
|
|
112
|
+
const initialTempItemsCount = DesignCore.Scene.tempEntities.count();
|
|
113
|
+
|
|
114
|
+
zoom.preview();
|
|
115
|
+
|
|
116
|
+
// Should have added a polyline (rectangle preview)
|
|
117
|
+
expect(DesignCore.Scene.tempEntities.count()).toBe(initialTempItemsCount + 1);
|
|
118
|
+
|
|
119
|
+
// Verify it's a polyline
|
|
120
|
+
const tempItem = DesignCore.Scene.tempEntities.get(DesignCore.Scene.tempEntities.count() - 1);
|
|
121
|
+
expect(tempItem.type).toBe('Polyline');
|
|
122
|
+
expect(tempItem.points.length).toBe(4); // Rectangle has 4 points (closed flag set)
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('Test Zoom.preview - Window mode with no points (should not preview)', () => {
|
|
126
|
+
const zoom = new Zoom();
|
|
127
|
+
zoom.mode = 'Window';
|
|
128
|
+
|
|
129
|
+
const initialTempItemsCount = DesignCore.Scene.tempEntities.count();
|
|
130
|
+
|
|
131
|
+
zoom.preview();
|
|
132
|
+
|
|
133
|
+
// Should not add anything
|
|
134
|
+
expect(DesignCore.Scene.tempEntities.count()).toBe(initialTempItemsCount);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test('Test Zoom.preview - All mode (should not preview)', () => {
|
|
138
|
+
const zoom = new Zoom();
|
|
139
|
+
zoom.mode = 'All';
|
|
140
|
+
zoom.points.push(new Point(10, 10));
|
|
141
|
+
|
|
142
|
+
const initialTempItemsCount = DesignCore.Scene.tempEntities.count();
|
|
143
|
+
|
|
144
|
+
zoom.preview();
|
|
145
|
+
|
|
146
|
+
// Should not add anything for All/Extents modes
|
|
147
|
+
expect(DesignCore.Scene.tempEntities.count()).toBe(initialTempItemsCount);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test('Test Canvas.zoomToWindow - valid window', () => {
|
|
151
|
+
core.canvas.width = 800;
|
|
152
|
+
core.canvas.height = 600;
|
|
153
|
+
core.canvas.matrix.scale(1, 1);
|
|
154
|
+
|
|
155
|
+
const initialScale = core.canvas.getScale();
|
|
156
|
+
|
|
157
|
+
const pt1 = new Point(0, 0);
|
|
158
|
+
const pt2 = new Point(100, 100);
|
|
159
|
+
|
|
160
|
+
core.canvas.zoomToWindow(pt1, pt2);
|
|
161
|
+
|
|
162
|
+
const finalScale = core.canvas.getScale();
|
|
163
|
+
expect(finalScale).not.toBe(initialScale);
|
|
164
|
+
expect(finalScale).toBeGreaterThan(0);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test('Test Canvas.zoomToWindow - reversed points', () => {
|
|
168
|
+
core.canvas.width = 800;
|
|
169
|
+
core.canvas.height = 600;
|
|
170
|
+
core.canvas.matrix.scale(1, 1);
|
|
171
|
+
|
|
172
|
+
const initialScale = core.canvas.getScale();
|
|
173
|
+
|
|
174
|
+
// Points in reverse order
|
|
175
|
+
const pt1 = new Point(100, 100);
|
|
176
|
+
const pt2 = new Point(0, 0);
|
|
177
|
+
|
|
178
|
+
core.canvas.zoomToWindow(pt1, pt2);
|
|
179
|
+
|
|
180
|
+
const finalScale = core.canvas.getScale();
|
|
181
|
+
expect(finalScale).not.toBe(initialScale);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test('Test Canvas.zoomToWindow - zero width (should not zoom)', () => {
|
|
185
|
+
core.canvas.width = 800;
|
|
186
|
+
core.canvas.height = 600;
|
|
187
|
+
core.canvas.matrix.scale(1, 1);
|
|
188
|
+
|
|
189
|
+
const initialScale = core.canvas.getScale();
|
|
190
|
+
|
|
191
|
+
// Points with same x coordinate (zero width)
|
|
192
|
+
const pt1 = new Point(50, 0);
|
|
193
|
+
const pt2 = new Point(50, 100);
|
|
194
|
+
|
|
195
|
+
core.canvas.zoomToWindow(pt1, pt2);
|
|
196
|
+
|
|
197
|
+
// Should not change scale
|
|
198
|
+
const finalScale = core.canvas.getScale();
|
|
199
|
+
expect(finalScale).toBe(initialScale);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test('Test Canvas.zoomToWindow - zero height (should not zoom)', () => {
|
|
203
|
+
core.canvas.width = 800;
|
|
204
|
+
core.canvas.height = 600;
|
|
205
|
+
core.canvas.matrix.scale(1, 1);
|
|
206
|
+
|
|
207
|
+
const initialScale = core.canvas.getScale();
|
|
208
|
+
|
|
209
|
+
// Points with same y coordinate (zero height)
|
|
210
|
+
const pt1 = new Point(0, 50);
|
|
211
|
+
const pt2 = new Point(100, 50);
|
|
212
|
+
|
|
213
|
+
core.canvas.zoomToWindow(pt1, pt2);
|
|
214
|
+
|
|
215
|
+
// Should not change scale
|
|
216
|
+
const finalScale = core.canvas.getScale();
|
|
217
|
+
expect(finalScale).toBe(initialScale);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
test('Test Canvas.zoomToWindow - same point (should not zoom)', () => {
|
|
221
|
+
core.canvas.width = 800;
|
|
222
|
+
core.canvas.height = 600;
|
|
223
|
+
core.canvas.matrix.scale(1, 1);
|
|
224
|
+
|
|
225
|
+
const initialScale = core.canvas.getScale();
|
|
226
|
+
|
|
227
|
+
// Same point
|
|
228
|
+
const pt1 = new Point(50, 50);
|
|
229
|
+
const pt2 = new Point(50, 50);
|
|
230
|
+
|
|
231
|
+
core.canvas.zoomToWindow(pt1, pt2);
|
|
232
|
+
|
|
233
|
+
// Should not change scale
|
|
234
|
+
const finalScale = core.canvas.getScale();
|
|
235
|
+
expect(finalScale).toBe(initialScale);
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
test('Test Zoom.action - Object mode', () => {
|
|
239
|
+
// Add an object to the scene
|
|
240
|
+
const obj = DesignCore.Scene.addItem('Circle', { points: [new Point(20, 20), new Point(40, 40)] });
|
|
241
|
+
|
|
242
|
+
core.canvas.width = 800;
|
|
243
|
+
core.canvas.height = 600;
|
|
244
|
+
core.canvas.matrix.scale(1, 1);
|
|
245
|
+
|
|
246
|
+
const initialScale = core.canvas.getScale();
|
|
247
|
+
|
|
248
|
+
const zoom = new Zoom();
|
|
249
|
+
zoom.mode = 'Object';
|
|
250
|
+
|
|
251
|
+
// Select the object for zoom
|
|
252
|
+
DesignCore.Scene.selectionManager.addToSelectionSet(obj);
|
|
253
|
+
|
|
254
|
+
// Perform zoom to object
|
|
255
|
+
zoom.action();
|
|
256
|
+
|
|
257
|
+
const finalScale = core.canvas.getScale();
|
|
258
|
+
expect(finalScale).not.toBe(initialScale);
|
|
259
|
+
expect(finalScale).toBeGreaterThan(0);
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
// ─── constructor / mode defaults ──────────────────────────────────────────────
|
|
263
|
+
|
|
264
|
+
test('Zoom constructor defaults mode to Window', () => {
|
|
265
|
+
const zoom = new Zoom();
|
|
266
|
+
expect(zoom.mode).toBe('Window');
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
test('Zoom.modes contains All, Extents, Window, Object', () => {
|
|
270
|
+
const zoom = new Zoom();
|
|
271
|
+
expect(zoom.modes.ALL).toBe('All');
|
|
272
|
+
expect(zoom.modes.EXTENTS).toBe('Extents');
|
|
273
|
+
expect(zoom.modes.WINDOW).toBe('Window');
|
|
274
|
+
expect(zoom.modes.OBJECT).toBe('Object');
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// ─── action: Extents mode ─────────────────────────────────────────────────────
|
|
278
|
+
|
|
279
|
+
test('Zoom.action - Extents mode calls zoomExtents', () => {
|
|
280
|
+
core.canvas.width = 800;
|
|
281
|
+
core.canvas.height = 600;
|
|
282
|
+
core.canvas.matrix.scale(1, 1);
|
|
283
|
+
core.scene.clear();
|
|
284
|
+
core.scene.addItem('Line', { points: [new Point(10, 10), new Point(50, 50)] });
|
|
285
|
+
|
|
286
|
+
const initialScale = core.canvas.getScale();
|
|
287
|
+
|
|
288
|
+
const zoom = new Zoom();
|
|
289
|
+
zoom.mode = 'Extents';
|
|
290
|
+
zoom.action();
|
|
291
|
+
|
|
292
|
+
const finalScale = core.canvas.getScale();
|
|
293
|
+
expect(finalScale).not.toBe(initialScale);
|
|
294
|
+
expect(finalScale).toBeGreaterThan(0);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// ─── action: Object mode with empty selection ─────────────────────────────────
|
|
298
|
+
|
|
299
|
+
test('Zoom.action - Object mode with empty selection does not zoom', () => {
|
|
300
|
+
core.canvas.width = 800;
|
|
301
|
+
core.canvas.height = 600;
|
|
302
|
+
core.canvas.matrix.scale(1, 1);
|
|
303
|
+
core.scene.selectionManager.reset();
|
|
304
|
+
|
|
305
|
+
const initialScale = core.canvas.getScale();
|
|
306
|
+
|
|
307
|
+
const zoom = new Zoom();
|
|
308
|
+
zoom.mode = 'Object';
|
|
309
|
+
zoom.action();
|
|
310
|
+
|
|
311
|
+
// Selection is empty — should return early without changing scale
|
|
312
|
+
expect(core.canvas.getScale()).toBe(initialScale);
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
// ─── execute ──────────────────────────────────────────────────────────────────
|
|
316
|
+
|
|
317
|
+
test('Zoom.execute returns early when first input is undefined', async () => {
|
|
318
|
+
const executeCommandSpy = jest.fn();
|
|
319
|
+
|
|
320
|
+
await withMockInput(
|
|
321
|
+
core.scene,
|
|
322
|
+
[],
|
|
323
|
+
async () => {
|
|
324
|
+
const zoom = new Zoom();
|
|
325
|
+
await zoom.execute();
|
|
326
|
+
},
|
|
327
|
+
{ extraMethods: { executeCommand: executeCommandSpy } },
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
expect(executeCommandSpy).not.toHaveBeenCalled();
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
test('Zoom.execute Window mode: first input is a Point, collects second point, calls executeCommand', async () => {
|
|
334
|
+
const executeCommandSpy = jest.fn();
|
|
335
|
+
|
|
336
|
+
await withMockInput(
|
|
337
|
+
core.scene,
|
|
338
|
+
[new Point(0, 0), new Point(100, 100)],
|
|
339
|
+
async () => {
|
|
340
|
+
const zoom = new Zoom();
|
|
341
|
+
await zoom.execute();
|
|
342
|
+
},
|
|
343
|
+
{ extraMethods: { executeCommand: executeCommandSpy } },
|
|
344
|
+
);
|
|
345
|
+
|
|
346
|
+
expect(executeCommandSpy).toHaveBeenCalled();
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
test('Zoom.execute Window mode: returns early when second point is undefined', async () => {
|
|
350
|
+
const executeCommandSpy = jest.fn();
|
|
351
|
+
|
|
352
|
+
await withMockInput(
|
|
353
|
+
core.scene,
|
|
354
|
+
[new Point(0, 0)],
|
|
355
|
+
async () => {
|
|
356
|
+
const zoom = new Zoom();
|
|
357
|
+
await zoom.execute();
|
|
358
|
+
},
|
|
359
|
+
{ extraMethods: { executeCommand: executeCommandSpy } },
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
expect(executeCommandSpy).not.toHaveBeenCalled();
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
test('Zoom.execute Window mode: string input prompts for first point then second, calls executeCommand', async () => {
|
|
366
|
+
const executeCommandSpy = jest.fn();
|
|
367
|
+
|
|
368
|
+
await withMockInput(
|
|
369
|
+
core.scene,
|
|
370
|
+
['Window', new Point(0, 0), new Point(100, 100)],
|
|
371
|
+
async () => {
|
|
372
|
+
const zoom = new Zoom();
|
|
373
|
+
await zoom.execute();
|
|
374
|
+
},
|
|
375
|
+
{ extraMethods: { executeCommand: executeCommandSpy } },
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
expect(executeCommandSpy).toHaveBeenCalled();
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
test('Zoom.execute Window mode: returns early when prompted first point is undefined', async () => {
|
|
382
|
+
const executeCommandSpy = jest.fn();
|
|
383
|
+
|
|
384
|
+
await withMockInput(
|
|
385
|
+
core.scene,
|
|
386
|
+
['Window'],
|
|
387
|
+
async () => {
|
|
388
|
+
const zoom = new Zoom();
|
|
389
|
+
await zoom.execute();
|
|
390
|
+
},
|
|
391
|
+
{ extraMethods: { executeCommand: executeCommandSpy } },
|
|
392
|
+
);
|
|
393
|
+
|
|
394
|
+
expect(executeCommandSpy).not.toHaveBeenCalled();
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
test('Zoom.execute Window mode: returns early when prompted second point is undefined after string branch', async () => {
|
|
398
|
+
const executeCommandSpy = jest.fn();
|
|
399
|
+
|
|
400
|
+
await withMockInput(
|
|
401
|
+
core.scene,
|
|
402
|
+
['Window', new Point(0, 0)],
|
|
403
|
+
async () => {
|
|
404
|
+
const zoom = new Zoom();
|
|
405
|
+
await zoom.execute();
|
|
406
|
+
},
|
|
407
|
+
{ extraMethods: { executeCommand: executeCommandSpy } },
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
expect(executeCommandSpy).not.toHaveBeenCalled();
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
test('Zoom.execute All mode: calls executeCommand without extra point prompts', async () => {
|
|
414
|
+
const executeCommandSpy = jest.fn();
|
|
415
|
+
|
|
416
|
+
await withMockInput(
|
|
417
|
+
core.scene,
|
|
418
|
+
['All'],
|
|
419
|
+
async () => {
|
|
420
|
+
const zoom = new Zoom();
|
|
421
|
+
await zoom.execute();
|
|
422
|
+
},
|
|
423
|
+
{ extraMethods: { executeCommand: executeCommandSpy } },
|
|
424
|
+
);
|
|
425
|
+
|
|
426
|
+
expect(executeCommandSpy).toHaveBeenCalled();
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
test('Zoom.execute Extents mode: calls executeCommand without extra point prompts', async () => {
|
|
430
|
+
const executeCommandSpy = jest.fn();
|
|
431
|
+
|
|
432
|
+
await withMockInput(
|
|
433
|
+
core.scene,
|
|
434
|
+
['Extents'],
|
|
435
|
+
async () => {
|
|
436
|
+
const zoom = new Zoom();
|
|
437
|
+
await zoom.execute();
|
|
438
|
+
},
|
|
439
|
+
{ extraMethods: { executeCommand: executeCommandSpy } },
|
|
440
|
+
);
|
|
441
|
+
|
|
442
|
+
expect(executeCommandSpy).toHaveBeenCalled();
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
test('Zoom.execute Object mode: with existing selection calls executeCommand without prompting', async () => {
|
|
446
|
+
core.scene.clear();
|
|
447
|
+
const idx = core.scene.addItem('Line', { points: [new Point(0, 0), new Point(10, 10)] });
|
|
448
|
+
core.scene.selectionManager.reset();
|
|
449
|
+
core.scene.selectionManager.addToSelectionSet(idx);
|
|
450
|
+
|
|
451
|
+
const executeCommandSpy = jest.fn();
|
|
452
|
+
|
|
453
|
+
await withMockInput(
|
|
454
|
+
core.scene,
|
|
455
|
+
['Object'],
|
|
456
|
+
async () => {
|
|
457
|
+
const zoom = new Zoom();
|
|
458
|
+
await zoom.execute();
|
|
459
|
+
},
|
|
460
|
+
{ extraMethods: { executeCommand: executeCommandSpy } },
|
|
461
|
+
);
|
|
462
|
+
|
|
463
|
+
expect(executeCommandSpy).toHaveBeenCalled();
|
|
464
|
+
core.scene.selectionManager.reset();
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
test('Zoom.execute Object mode: without selection prompts for selection set, returns early when undefined', async () => {
|
|
468
|
+
core.scene.selectionManager.reset();
|
|
469
|
+
|
|
470
|
+
const executeCommandSpy = jest.fn();
|
|
471
|
+
|
|
472
|
+
await withMockInput(
|
|
473
|
+
core.scene,
|
|
474
|
+
['Object'],
|
|
475
|
+
async () => {
|
|
476
|
+
const zoom = new Zoom();
|
|
477
|
+
await zoom.execute();
|
|
478
|
+
},
|
|
479
|
+
{ extraMethods: { executeCommand: executeCommandSpy } },
|
|
480
|
+
);
|
|
481
|
+
|
|
482
|
+
expect(executeCommandSpy).not.toHaveBeenCalled();
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
test('Zoom.execute stores collected window points for action', async () => {
|
|
486
|
+
let capturedZoom;
|
|
487
|
+
const executeCommandSpy = jest.fn();
|
|
488
|
+
|
|
489
|
+
await withMockInput(
|
|
490
|
+
core.scene,
|
|
491
|
+
[new Point(5, 10), new Point(50, 80)],
|
|
492
|
+
async () => {
|
|
493
|
+
capturedZoom = new Zoom();
|
|
494
|
+
await capturedZoom.execute();
|
|
495
|
+
},
|
|
496
|
+
{ extraMethods: { executeCommand: executeCommandSpy } },
|
|
497
|
+
);
|
|
498
|
+
|
|
499
|
+
expect(capturedZoom.points).toHaveLength(2);
|
|
500
|
+
expect(capturedZoom.points[0].x).toBe(5);
|
|
501
|
+
expect(capturedZoom.points[0].y).toBe(10);
|
|
502
|
+
expect(capturedZoom.points[1].x).toBe(50);
|
|
503
|
+
expect(capturedZoom.points[1].y).toBe(80);
|
|
504
|
+
});
|