@design-core/core 0.0.2 → 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 +5 -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 -5
- 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,152 @@
|
|
|
1
|
+
import { Tool } from './tool.js';
|
|
2
|
+
import { Input, PromptOptions } from '../lib/inputManager.js';
|
|
3
|
+
import { Strings } from '../lib/strings.js';
|
|
4
|
+
import { Logging } from '../lib/logging.js';
|
|
5
|
+
import { Point } from '../entities/point.js';
|
|
6
|
+
|
|
7
|
+
import { DesignCore } from '../designCore.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Zoom Command Class
|
|
11
|
+
* Provides: All, Extents, Window
|
|
12
|
+
* @extends Tool
|
|
13
|
+
*/
|
|
14
|
+
export class Zoom extends Tool {
|
|
15
|
+
/** Create a Zoom command */
|
|
16
|
+
constructor() {
|
|
17
|
+
super();
|
|
18
|
+
this.modes = {
|
|
19
|
+
ALL: 'All',
|
|
20
|
+
EXTENTS: 'Extents',
|
|
21
|
+
WINDOW: 'Window',
|
|
22
|
+
OBJECT: 'Object',
|
|
23
|
+
};
|
|
24
|
+
this.mode = this.modes.WINDOW; // default to window mode
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Register the command
|
|
29
|
+
* @return {Object}
|
|
30
|
+
*/
|
|
31
|
+
static register() {
|
|
32
|
+
const command = { command: 'Zoom', shortcut: 'Z' };
|
|
33
|
+
return command;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Execute method
|
|
38
|
+
*/
|
|
39
|
+
async execute() {
|
|
40
|
+
try {
|
|
41
|
+
const op = new PromptOptions(Strings.Input.POINT, [Input.Type.POINT], [this.modes.ALL, this.modes.EXTENTS, this.modes.WINDOW, this.modes.OBJECT]);
|
|
42
|
+
const input = await DesignCore.Scene.inputManager.requestInput(op);
|
|
43
|
+
if (input === undefined) return;
|
|
44
|
+
|
|
45
|
+
if (Object.values(this.modes).includes(input)) {
|
|
46
|
+
// input matches one of the mode values
|
|
47
|
+
this.mode = input;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// default window mode
|
|
51
|
+
if (this.mode === this.modes.WINDOW) {
|
|
52
|
+
if (Input.getType(input) === Input.Type.POINT) {
|
|
53
|
+
this.points.push(input);
|
|
54
|
+
} else {
|
|
55
|
+
const p1op = new PromptOptions(Strings.Input.POINT, [Input.Type.POINT]);
|
|
56
|
+
const pt1 = await DesignCore.Scene.inputManager.requestInput(p1op);
|
|
57
|
+
if (pt1 === undefined) return;
|
|
58
|
+
this.points.push(pt1);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const p2op = new PromptOptions(Strings.Input.END, [Input.Type.POINT]);
|
|
62
|
+
const pt2 = await DesignCore.Scene.inputManager.requestInput(p2op);
|
|
63
|
+
if (pt2 === undefined) return;
|
|
64
|
+
this.points.push(pt2);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Zoom to objects in selection
|
|
68
|
+
if (this.mode === this.modes.OBJECT) {
|
|
69
|
+
const op = new PromptOptions(Strings.Input.SELECTIONSET, [Input.Type.SELECTIONSET]);
|
|
70
|
+
|
|
71
|
+
if (!DesignCore.Scene.selectionManager.selectionSet.selectionSet.length) {
|
|
72
|
+
const sel = await DesignCore.Scene.inputManager.requestInput(op);
|
|
73
|
+
if (sel === undefined) return;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
DesignCore.Scene.inputManager.executeCommand();
|
|
78
|
+
} catch (err) {
|
|
79
|
+
Logging.instance.error(`${this.type} - ${err}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Preview the command during execution
|
|
85
|
+
*/
|
|
86
|
+
preview() {
|
|
87
|
+
if (this.mode === this.modes.WINDOW && this.points.length === 1) {
|
|
88
|
+
const mousePoint = DesignCore.Mouse.pointOnScene();
|
|
89
|
+
const p1 = this.points[0];
|
|
90
|
+
const p2 = mousePoint;
|
|
91
|
+
|
|
92
|
+
const points = [
|
|
93
|
+
new Point(p1.x, p1.y),
|
|
94
|
+
new Point(p2.x, p1.y),
|
|
95
|
+
new Point(p2.x, p2.y),
|
|
96
|
+
new Point(p1.x, p2.y),
|
|
97
|
+
new Point(p1.x, p1.y),
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
DesignCore.Scene.tempEntities.create('Polyline', { points: points });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Perform the command
|
|
106
|
+
*/
|
|
107
|
+
action() {
|
|
108
|
+
// Zoom to window
|
|
109
|
+
if (this.mode === this.modes.WINDOW && this.points.length === 2) {
|
|
110
|
+
DesignCore.Canvas.zoomToWindow(this.points[0], this.points[1]);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Zoom Extents
|
|
114
|
+
if (this.mode === this.modes.ALL || this.mode === this.modes.EXTENTS) {
|
|
115
|
+
DesignCore.Canvas.zoomExtents();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Zoom to Object(s)
|
|
119
|
+
if (this.mode === this.modes.OBJECT) {
|
|
120
|
+
let xmin = Infinity;
|
|
121
|
+
let xmax = -Infinity;
|
|
122
|
+
let ymin = Infinity;
|
|
123
|
+
let ymax = -Infinity;
|
|
124
|
+
|
|
125
|
+
// return if nothing selection
|
|
126
|
+
if (DesignCore.Scene.selectionManager.selectionSet.selectionSet.length === 0) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
for (let i = 0; i <DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
|
|
131
|
+
const itemBoundingBox = DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]).boundingBox();
|
|
132
|
+
|
|
133
|
+
xmin = Math.min(xmin, itemBoundingBox.xMin);
|
|
134
|
+
xmax = Math.max(xmax, itemBoundingBox.xMax);
|
|
135
|
+
ymin = Math.min(ymin, itemBoundingBox.yMin);
|
|
136
|
+
ymax = Math.max(ymax, itemBoundingBox.yMax);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// if all values are zero return undefined
|
|
140
|
+
if (xmin === 0 && xmax === 0, ymin === 0, ymax === 0) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const Pt1 = new Point(xmin, ymin);
|
|
145
|
+
const Pt2 = new Point(xmax, ymax);
|
|
146
|
+
|
|
147
|
+
DesignCore.Canvas.zoomToWindow(Pt1, Pt2);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@design-core/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"eslint-plugin-import": "^2.26.0",
|
|
13
13
|
"eslint-plugin-n": "^15.3.0",
|
|
14
14
|
"eslint-plugin-promise": "^6.1.1",
|
|
15
|
-
"jest": "^29.
|
|
15
|
+
"jest": "^29.7.0"
|
|
16
16
|
},
|
|
17
17
|
"description": "2D CAD Library",
|
|
18
18
|
"exports": {
|
|
@@ -22,8 +22,6 @@
|
|
|
22
22
|
"directories": {
|
|
23
23
|
"test": "test"
|
|
24
24
|
},
|
|
25
|
-
"dependencies": {
|
|
26
|
-
},
|
|
27
25
|
"repository": {
|
|
28
26
|
"type": "git",
|
|
29
27
|
"url": "git+https://github.com/dubstar-04/Design-Core.git"
|
|
@@ -37,4 +35,4 @@
|
|
|
37
35
|
"url": "https://github.com/dubstar-04/Design-Core/issues"
|
|
38
36
|
},
|
|
39
37
|
"homepage": "https://github.com/dubstar-04/Design-Core#readme"
|
|
40
|
-
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { AlignedDimension } from '../../core/dimensions/alignedDimension.js';
|
|
2
|
+
import { Point } from '../../core/entities/point.js';
|
|
3
|
+
import { DesignCore } from '../../core/designCore.js';
|
|
4
|
+
import { Core } from '../../core/core/core.js';
|
|
5
|
+
import { Line } from '../../core/entities/line.js';
|
|
6
|
+
import { File, withMockInput } from '../test-helpers/test-helpers.js';
|
|
7
|
+
|
|
8
|
+
// initialise core
|
|
9
|
+
new Core();
|
|
10
|
+
|
|
11
|
+
// Test cases for user input
|
|
12
|
+
const scenarios = [
|
|
13
|
+
|
|
14
|
+
{ desc: 'Aligned dimension from point selection',
|
|
15
|
+
input: [new Point(), new Point(10, 0), new Point(5, 5)],
|
|
16
|
+
selectedItems: [],
|
|
17
|
+
expectedDimType: 1,
|
|
18
|
+
dimensionValue: 10,
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
test.each(scenarios)('Dimension.execute handles $desc', async (scenario) => {
|
|
23
|
+
const { input, selectedItems, expectedDimType, dimensionValue } = scenario;
|
|
24
|
+
|
|
25
|
+
await withMockInput(DesignCore.Scene, input, async () => {
|
|
26
|
+
const dim = new AlignedDimension();
|
|
27
|
+
await dim.execute();
|
|
28
|
+
|
|
29
|
+
expect(dim.dimType.getBaseDimType()).toBe(expectedDimType);
|
|
30
|
+
// get the text entities from the dimension block
|
|
31
|
+
const dimensionBlockEntities = dim.buildDimension();
|
|
32
|
+
expect(dimensionBlockEntities.length).toBe(7);
|
|
33
|
+
|
|
34
|
+
// check if the text value matches the expected dimension value
|
|
35
|
+
for (const entity of dimensionBlockEntities) {
|
|
36
|
+
if (entity.type === 'Text') {
|
|
37
|
+
expect(Number(entity.string)).toBeCloseTo(dimensionValue);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}, { selectedItems });
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('constructor sets default properties', () => {
|
|
44
|
+
const dim = new AlignedDimension();
|
|
45
|
+
expect(dim).toBeInstanceOf(AlignedDimension);
|
|
46
|
+
expect(dim.points).toBeDefined();
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
test('register returns command object', () => {
|
|
51
|
+
expect(AlignedDimension.register()).toEqual({ command: 'AlignedDimension', shortcut: 'DIMALI' });
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
describe('AlignedDimension.getPointsFromSelection', () => {
|
|
56
|
+
const scenarios = [
|
|
57
|
+
{
|
|
58
|
+
desc: 'horizontal line',
|
|
59
|
+
pt1: new Point(0, 0),
|
|
60
|
+
pt2: new Point(10, 0),
|
|
61
|
+
textPos: new Point(5, 5),
|
|
62
|
+
expected: {
|
|
63
|
+
text: { x: 5, y: 5 },
|
|
64
|
+
arrow: { x: 10, y: 5 },
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
desc: 'vertical line',
|
|
69
|
+
pt1: new Point(0, 0),
|
|
70
|
+
pt2: new Point(0, 10),
|
|
71
|
+
textPos: new Point(5, 5),
|
|
72
|
+
expected: {
|
|
73
|
+
text: { x: 5, y: 5 },
|
|
74
|
+
arrow: { x: 5, y: 10 },
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
desc: 'diagonal line',
|
|
79
|
+
pt1: new Point(0, 0),
|
|
80
|
+
pt2: new Point(10, 10),
|
|
81
|
+
textPos: new Point(5, 0),
|
|
82
|
+
expected: {
|
|
83
|
+
text: { x: 5, y: 0 },
|
|
84
|
+
arrow: { x: 12.5, y: 7.5 },
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
test.each(scenarios)('returns correct sequenced points for $desc', ({ pt1, pt2, textPos, expected }) => {
|
|
90
|
+
const line = new Line({ points: [pt1, pt2] });
|
|
91
|
+
const result = AlignedDimension.getPointsFromSelection([line], textPos);
|
|
92
|
+
expect(result).toHaveLength(4);
|
|
93
|
+
expect(result[0].sequence).toBe(13);
|
|
94
|
+
expect(result[1].sequence).toBe(14);
|
|
95
|
+
expect(result[2].sequence).toBe(11);
|
|
96
|
+
expect(result[3].sequence).toBe(10);
|
|
97
|
+
// check text position
|
|
98
|
+
expect(result[2].x).toBeCloseTo(expected.text.x);
|
|
99
|
+
expect(result[2].y).toBeCloseTo(expected.text.y);
|
|
100
|
+
// check arrow position
|
|
101
|
+
expect(result[3].x).toBeCloseTo(expected.arrow.x);
|
|
102
|
+
expect(result[3].y).toBeCloseTo(expected.arrow.y);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('AlignedDimension.preview runs without error and calls createTempItem', () => {
|
|
107
|
+
const origCreateTempItem = DesignCore.Scene.tempEntities.create;
|
|
108
|
+
const origPointOnScene = DesignCore.Mouse.pointOnScene;
|
|
109
|
+
// Manual mock for createTempItem
|
|
110
|
+
const createTempItemCalls = [];
|
|
111
|
+
DesignCore.Scene.tempEntities.create = function(type, obj) {
|
|
112
|
+
createTempItemCalls.push([type, obj]);
|
|
113
|
+
};
|
|
114
|
+
// Manual mock for pointOnScene
|
|
115
|
+
DesignCore.Mouse.pointOnScene = function() {
|
|
116
|
+
return new Point(5, 5);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// Test with 1 point (should call createTempItem with 'Line')
|
|
120
|
+
const dim1 = new AlignedDimension();
|
|
121
|
+
dim1.points = [new Point(0, 0)];
|
|
122
|
+
expect(() => dim1.preview()).not.toThrow();
|
|
123
|
+
expect(createTempItemCalls.some((call) => call[0] === 'Line')).toBe(true);
|
|
124
|
+
|
|
125
|
+
// Test with >1 point (should call createTempItem with this.type)
|
|
126
|
+
const dim2 = new AlignedDimension();
|
|
127
|
+
dim2.points = [new Point(0, 0), new Point(10, 0), new Point(5, 5)];
|
|
128
|
+
expect(() => dim2.preview()).not.toThrow();
|
|
129
|
+
expect(createTempItemCalls.some((call) => call[0] === dim2.type)).toBe(true);
|
|
130
|
+
|
|
131
|
+
// Restore
|
|
132
|
+
DesignCore.Scene.tempEntities.create = origCreateTempItem;
|
|
133
|
+
DesignCore.Mouse.pointOnScene = origPointOnScene;
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test('Test AlignedDimension.dxf', () => {
|
|
137
|
+
const points = [];
|
|
138
|
+
|
|
139
|
+
const Pt13 = new Point(0, 0);
|
|
140
|
+
Pt13.sequence = 13;
|
|
141
|
+
points.push(Pt13);
|
|
142
|
+
|
|
143
|
+
const Pt14 = new Point(10, 0);
|
|
144
|
+
Pt14.sequence = 14;
|
|
145
|
+
points.push(Pt14);
|
|
146
|
+
|
|
147
|
+
const Pt10 = new Point(5, 5);
|
|
148
|
+
Pt10.sequence = 10;
|
|
149
|
+
points.push(Pt10);
|
|
150
|
+
|
|
151
|
+
const Pt11 = new Point(5, 5);
|
|
152
|
+
Pt11.sequence = 11;
|
|
153
|
+
points.push(Pt11);
|
|
154
|
+
|
|
155
|
+
points.push(Pt10, Pt14, Pt13, Pt11);
|
|
156
|
+
|
|
157
|
+
const dimension = new AlignedDimension({ points: points, handle: '1' });
|
|
158
|
+
let file = new File();
|
|
159
|
+
dimension.dxf(file);
|
|
160
|
+
// console.log(file.contents);
|
|
161
|
+
|
|
162
|
+
const dxfString = `0
|
|
163
|
+
DIMENSION
|
|
164
|
+
5
|
|
165
|
+
1
|
|
166
|
+
100
|
|
167
|
+
AcDbEntity
|
|
168
|
+
100
|
|
169
|
+
AcDbDimension
|
|
170
|
+
8
|
|
171
|
+
0
|
|
172
|
+
10
|
|
173
|
+
5
|
|
174
|
+
20
|
|
175
|
+
5
|
|
176
|
+
30
|
|
177
|
+
0.0
|
|
178
|
+
11
|
|
179
|
+
5
|
|
180
|
+
21
|
|
181
|
+
5
|
|
182
|
+
31
|
|
183
|
+
0.0
|
|
184
|
+
70
|
|
185
|
+
1
|
|
186
|
+
3
|
|
187
|
+
STANDARD
|
|
188
|
+
100
|
|
189
|
+
AcDbAlignedDimension
|
|
190
|
+
13
|
|
191
|
+
0
|
|
192
|
+
23
|
|
193
|
+
0
|
|
194
|
+
33
|
|
195
|
+
0.0
|
|
196
|
+
14
|
|
197
|
+
10
|
|
198
|
+
24
|
|
199
|
+
0
|
|
200
|
+
34
|
|
201
|
+
0.0
|
|
202
|
+
`;
|
|
203
|
+
|
|
204
|
+
expect(file.contents).toEqual(dxfString);
|
|
205
|
+
|
|
206
|
+
// create new entity from entity data to ensure all props are loaded
|
|
207
|
+
const newDimension = new AlignedDimension(dimension);
|
|
208
|
+
file = new File();
|
|
209
|
+
newDimension.dxf(file);
|
|
210
|
+
expect(file.contents).toEqual(dxfString);
|
|
211
|
+
});
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
|
|
2
|
+
import { AngularDimension } from '../../core/dimensions/angularDimension.js';
|
|
3
|
+
import { Point } from '../../core/entities/point.js';
|
|
4
|
+
import { Line } from '../../core/entities/line.js';
|
|
5
|
+
import { Polyline } from '../../core/entities/polyline.js';
|
|
6
|
+
import { Core } from '../../core/core/core.js';
|
|
7
|
+
import { DesignCore } from '../../core/designCore.js';
|
|
8
|
+
import { SingleSelection } from '../../core/lib/selectionManager.js';
|
|
9
|
+
|
|
10
|
+
import { File, withMockInput } from '../test-helpers/test-helpers.js';
|
|
11
|
+
|
|
12
|
+
// initialise core
|
|
13
|
+
new Core();
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
// Test cases for user input
|
|
17
|
+
const scenarios = [
|
|
18
|
+
|
|
19
|
+
{ desc: 'Angular dimension from line selection - 45 degrees',
|
|
20
|
+
input: [new SingleSelection(0, new Point()), new SingleSelection(1, new Point()), new Point(5, 5)],
|
|
21
|
+
selectedItems: [new Line({ points: [new Point(0, 0), new Point(10, 0)] }), new Line({ points: [new Point(0, 0), new Point(10, 10)] })],
|
|
22
|
+
expectedDimType: 2,
|
|
23
|
+
dimensionValue: 45,
|
|
24
|
+
dimensionEntities: 5,
|
|
25
|
+
},
|
|
26
|
+
{ desc: 'Angular dimension from line selection - 135 degrees',
|
|
27
|
+
input: [new SingleSelection(0, new Point()), new SingleSelection(1, new Point()), new Point(-5, 5)],
|
|
28
|
+
selectedItems: [new Line({ points: [new Point(0, 0), new Point(10, 0)] }), new Line({ points: [new Point(0, 0), new Point(10, 10)] })],
|
|
29
|
+
expectedDimType: 2,
|
|
30
|
+
dimensionValue: 135,
|
|
31
|
+
dimensionEntities: 6,
|
|
32
|
+
},
|
|
33
|
+
{ desc: 'Angular dimension from line selection - 45 degrees',
|
|
34
|
+
input: [new SingleSelection(0, new Point()), new SingleSelection(1, new Point()), new Point(-5, -5)],
|
|
35
|
+
selectedItems: [new Line({ points: [new Point(0, 0), new Point(10, 0)] }), new Line({ points: [new Point(0, 0), new Point(10, 10)] })],
|
|
36
|
+
expectedDimType: 2,
|
|
37
|
+
dimensionValue: 45,
|
|
38
|
+
dimensionEntities: 7,
|
|
39
|
+
},
|
|
40
|
+
{ desc: 'Angular dimension from line selection - 135 degrees',
|
|
41
|
+
input: [new SingleSelection(0, new Point()), new SingleSelection(1, new Point()), new Point(5, -5)],
|
|
42
|
+
selectedItems: [new Line({ points: [new Point(0, 0), new Point(10, 0)] }), new Line({ points: [new Point(0, 0), new Point(10, 10)] })],
|
|
43
|
+
expectedDimType: 2,
|
|
44
|
+
dimensionValue: 135,
|
|
45
|
+
dimensionEntities: 6,
|
|
46
|
+
},
|
|
47
|
+
{ desc: 'Angular dimension from polyline selection - 45 degrees',
|
|
48
|
+
input: [new SingleSelection(0, new Point(5, 0)), new SingleSelection(1, new Point(5, 5)), new Point(5, 5)],
|
|
49
|
+
selectedItems: [new Polyline({ points: [new Point(0, 0), new Point(10, 0)] }), new Polyline({ points: [new Point(0, 0), new Point(10, 10)] })],
|
|
50
|
+
expectedDimType: 2,
|
|
51
|
+
dimensionValue: 45,
|
|
52
|
+
dimensionEntities: 5,
|
|
53
|
+
},
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
test.each(scenarios)('Dimension.execute handles $desc', async (scenario) => {
|
|
57
|
+
const { input, selectedItems, expectedDimType, dimensionValue, dimensionEntities } = scenario;
|
|
58
|
+
|
|
59
|
+
await withMockInput(DesignCore.Scene, input, async () => {
|
|
60
|
+
const dim = new AngularDimension();
|
|
61
|
+
await dim.execute();
|
|
62
|
+
|
|
63
|
+
expect(dim.dimType.getBaseDimType()).toBe(expectedDimType);
|
|
64
|
+
// get the text entities from the dimension block
|
|
65
|
+
const dimensionBlockEntities = dim.buildDimension();
|
|
66
|
+
expect(dimensionBlockEntities.length).toBe(dimensionEntities);
|
|
67
|
+
|
|
68
|
+
// check if the text value matches the expected dimension value
|
|
69
|
+
for (const entity of dimensionBlockEntities) {
|
|
70
|
+
if (entity.type === 'Text') {
|
|
71
|
+
// remove all non-numeric characters except . and -
|
|
72
|
+
const numbersOnly = entity.string.replace(/[^0-9.-]+/g, '');
|
|
73
|
+
expect(Number(numbersOnly)).toBeCloseTo(dimensionValue);
|
|
74
|
+
expect(entity.string).toContain('°');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}, { selectedItems });
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('constructor sets default properties', () => {
|
|
81
|
+
const dim = new AngularDimension();
|
|
82
|
+
expect(dim).toBeInstanceOf(AngularDimension);
|
|
83
|
+
expect(dim.points).toBeDefined();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('register returns command object', () => {
|
|
87
|
+
expect(AngularDimension.register()).toEqual({ command: 'AngularDimension', shortcut: 'DIMANG' });
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test('getPointsFromSelection returns correct sequenced points', () => {
|
|
91
|
+
const pt1 = new Point(0, 0);
|
|
92
|
+
const pt2 = new Point(10, 0);
|
|
93
|
+
const pt3 = new Point(10, 10);
|
|
94
|
+
const textPos = new Point(5, 5);
|
|
95
|
+
const line1 = new Line({ points: [pt1, pt2] });
|
|
96
|
+
const line2 = new Line({ points: [pt2, pt3] });
|
|
97
|
+
const result = AngularDimension.getPointsFromSelection([line1, line2], textPos);
|
|
98
|
+
expect(Array.isArray(result)).toBe(true);
|
|
99
|
+
expect(result.length).toBeGreaterThanOrEqual(4);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test('AngularDimension.preview runs without error and calls createTempItem', () => {
|
|
103
|
+
const origCreateTempItem = DesignCore.Scene.tempEntities.create;
|
|
104
|
+
const origPointOnScene = DesignCore.Mouse.pointOnScene;
|
|
105
|
+
// Manual mock for createTempItem
|
|
106
|
+
const createTempItemCalls = [];
|
|
107
|
+
DesignCore.Scene.tempEntities.create = function(type, obj) {
|
|
108
|
+
createTempItemCalls.push([type, obj]);
|
|
109
|
+
};
|
|
110
|
+
// Manual mock for pointOnScene
|
|
111
|
+
DesignCore.Mouse.pointOnScene = function() {
|
|
112
|
+
return new Point(5, 5);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
// Test with >4 point (should call createTempItem with this.type)
|
|
117
|
+
const dim2 = new AngularDimension();
|
|
118
|
+
|
|
119
|
+
dim2.points = [];
|
|
120
|
+
|
|
121
|
+
const Pt10 = new Point();
|
|
122
|
+
Pt10.sequence = 10;
|
|
123
|
+
dim2.points.push(Pt10);
|
|
124
|
+
|
|
125
|
+
const Pt13 = new Point();
|
|
126
|
+
Pt13.sequence = 13;
|
|
127
|
+
dim2.points.push(Pt13);
|
|
128
|
+
|
|
129
|
+
const Pt14 = new Point();
|
|
130
|
+
Pt14.sequence = 14;
|
|
131
|
+
dim2.points.push(Pt14);
|
|
132
|
+
|
|
133
|
+
const Pt15 = new Point();
|
|
134
|
+
Pt15.sequence = 15;
|
|
135
|
+
dim2.points.push(Pt15);
|
|
136
|
+
|
|
137
|
+
expect(() => dim2.preview()).not.toThrow();
|
|
138
|
+
expect(createTempItemCalls.some((call) => call[0] === dim2.type)).toBe(true);
|
|
139
|
+
|
|
140
|
+
// Restore
|
|
141
|
+
DesignCore.Scene.tempEntities.create = origCreateTempItem;
|
|
142
|
+
DesignCore.Mouse.pointOnScene = origPointOnScene;
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('Test AngularDimension.dxf', () => {
|
|
146
|
+
const points = [];
|
|
147
|
+
|
|
148
|
+
const Pt10 = new Point(5, 6);
|
|
149
|
+
Pt10.sequence = 10;
|
|
150
|
+
points.push(Pt10);
|
|
151
|
+
|
|
152
|
+
const Pt11 = new Point(7, 8);
|
|
153
|
+
Pt11.sequence = 11;
|
|
154
|
+
points.push(Pt11);
|
|
155
|
+
|
|
156
|
+
const Pt13 = new Point(9, 10);
|
|
157
|
+
Pt13.sequence = 13;
|
|
158
|
+
points.push(Pt13);
|
|
159
|
+
|
|
160
|
+
const Pt14 = new Point(11, 12);
|
|
161
|
+
Pt14.sequence = 14;
|
|
162
|
+
points.push(Pt14);
|
|
163
|
+
|
|
164
|
+
const Pt15 = new Point(13, 14);
|
|
165
|
+
Pt15.sequence = 15;
|
|
166
|
+
points.push(Pt15);
|
|
167
|
+
|
|
168
|
+
const Pt16 = new Point(15, 16);
|
|
169
|
+
Pt16.sequence = 16;
|
|
170
|
+
points.push(Pt16);
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
points.push(Pt10, Pt11, Pt13, Pt14, Pt15, Pt16);
|
|
174
|
+
|
|
175
|
+
const dimension = new AngularDimension({ points: points, handle: '1' });
|
|
176
|
+
let file = new File();
|
|
177
|
+
dimension.dxf(file);
|
|
178
|
+
// console.log(file.contents);
|
|
179
|
+
|
|
180
|
+
const dxfString = `0
|
|
181
|
+
DIMENSION
|
|
182
|
+
5
|
|
183
|
+
1
|
|
184
|
+
100
|
|
185
|
+
AcDbEntity
|
|
186
|
+
100
|
|
187
|
+
AcDbDimension
|
|
188
|
+
8
|
|
189
|
+
0
|
|
190
|
+
10
|
|
191
|
+
5
|
|
192
|
+
20
|
|
193
|
+
6
|
|
194
|
+
30
|
|
195
|
+
0.0
|
|
196
|
+
11
|
|
197
|
+
7
|
|
198
|
+
21
|
|
199
|
+
8
|
|
200
|
+
31
|
|
201
|
+
0.0
|
|
202
|
+
70
|
|
203
|
+
2
|
|
204
|
+
3
|
|
205
|
+
STANDARD
|
|
206
|
+
100
|
|
207
|
+
AcDb2LineAngularDimension
|
|
208
|
+
13
|
|
209
|
+
9
|
|
210
|
+
23
|
|
211
|
+
10
|
|
212
|
+
33
|
|
213
|
+
0.0
|
|
214
|
+
14
|
|
215
|
+
11
|
|
216
|
+
24
|
|
217
|
+
12
|
|
218
|
+
34
|
|
219
|
+
0.0
|
|
220
|
+
15
|
|
221
|
+
13
|
|
222
|
+
25
|
|
223
|
+
14
|
|
224
|
+
35
|
|
225
|
+
0.0
|
|
226
|
+
16
|
|
227
|
+
15
|
|
228
|
+
26
|
|
229
|
+
16
|
|
230
|
+
36
|
|
231
|
+
0.0
|
|
232
|
+
`;
|
|
233
|
+
|
|
234
|
+
expect(file.contents).toEqual(dxfString);
|
|
235
|
+
|
|
236
|
+
// create new entity from entity data to ensure all props are loaded
|
|
237
|
+
const newDimension = new AngularDimension(dimension);
|
|
238
|
+
file = new File();
|
|
239
|
+
newDimension.dxf(file);
|
|
240
|
+
expect(file.contents).toEqual(dxfString);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
|