@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,186 @@
|
|
|
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 { Line } from '../../core/entities/line.js';
|
|
5
|
+
import { Circle } from '../../core/entities/circle.js';
|
|
6
|
+
import { Arc } from '../../core/entities/arc.js';
|
|
7
|
+
import { Text } from '../../core/entities/text.js';
|
|
8
|
+
import { Polyline } from '../../core/entities/polyline.js';
|
|
9
|
+
import { Lwpolyline } from '../../core/entities/lwpolyline.js';
|
|
10
|
+
// import { Solid } from '../../core/entities/solid.js';
|
|
11
|
+
import { Hatch } from '../../core/entities/hatch.js';
|
|
12
|
+
import { Insert } from '../../core/entities/insert.js';
|
|
13
|
+
// import { ArcAlignedText } from '../../core/entities/arctext.js';
|
|
14
|
+
import { BasePolyline } from '../../core/entities/basePolyline.js';
|
|
15
|
+
|
|
16
|
+
import { readFileSync } from 'fs';
|
|
17
|
+
import { fileURLToPath } from 'url';
|
|
18
|
+
import { dirname, join } from 'path';
|
|
19
|
+
|
|
20
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
21
|
+
const __dirname = dirname(__filename);
|
|
22
|
+
|
|
23
|
+
let core;
|
|
24
|
+
|
|
25
|
+
beforeAll(() => {
|
|
26
|
+
core = new Core();
|
|
27
|
+
|
|
28
|
+
// Entities are arranged in a 3x3 grid of 100x100 cells:
|
|
29
|
+
//
|
|
30
|
+
// Row 2 (y=200-300): | Hatch | Insert |
|
|
31
|
+
// Row 1 (y=100-200): | Text | Polyline | Lwpolyline |
|
|
32
|
+
// Row 0 (y=0-100): | Line | Circle | Arc |
|
|
33
|
+
|
|
34
|
+
// Add layers for each entity type
|
|
35
|
+
DesignCore.LayerManager.addItem({ name: 'LINE_LAYER' });
|
|
36
|
+
DesignCore.LayerManager.addItem({ name: 'CIRCLE_LAYER' });
|
|
37
|
+
DesignCore.LayerManager.addItem({ name: 'ARC_LAYER' });
|
|
38
|
+
DesignCore.LayerManager.addItem({ name: 'TEXT_LAYER' });
|
|
39
|
+
DesignCore.LayerManager.addItem({ name: 'POLYLINE_LAYER' });
|
|
40
|
+
DesignCore.LayerManager.addItem({ name: 'LWPOLYLINE_LAYER' });
|
|
41
|
+
// DesignCore.LayerManager.addItem({ name: 'SOLID_LAYER' });
|
|
42
|
+
DesignCore.LayerManager.addItem({ name: 'HATCH_LAYER' });
|
|
43
|
+
DesignCore.LayerManager.addItem({ name: 'INSERT_LAYER' });
|
|
44
|
+
// DesignCore.LayerManager.addItem({ name: 'ARCTEXT_LAYER' });
|
|
45
|
+
|
|
46
|
+
// Row 0, Col 0: Line
|
|
47
|
+
const line = new Line({
|
|
48
|
+
points: [new Point(20, 25), new Point(80, 85)],
|
|
49
|
+
layer: 'LINE_LAYER',
|
|
50
|
+
});
|
|
51
|
+
core.scene.entities.add(line);
|
|
52
|
+
core.scene.entities.add(new Text({ points: [new Point(15, 5)], string: 'Line', height: 4 }));
|
|
53
|
+
|
|
54
|
+
// Row 0, Col 1: Circle
|
|
55
|
+
const circle = new Circle({
|
|
56
|
+
points: [new Point(150, 55)],
|
|
57
|
+
radius: 25,
|
|
58
|
+
layer: 'CIRCLE_LAYER',
|
|
59
|
+
});
|
|
60
|
+
core.scene.entities.add(circle);
|
|
61
|
+
core.scene.entities.add(new Text({ points: [new Point(115, 5)], string: 'Circle', height: 4 }));
|
|
62
|
+
|
|
63
|
+
// Row 0, Col 2: Arc
|
|
64
|
+
const arc = new Arc({
|
|
65
|
+
points: [new Point(250, 55)],
|
|
66
|
+
radius: 25,
|
|
67
|
+
startAngle: 0,
|
|
68
|
+
endAngle: 270,
|
|
69
|
+
layer: 'ARC_LAYER',
|
|
70
|
+
});
|
|
71
|
+
core.scene.entities.add(arc);
|
|
72
|
+
core.scene.entities.add(new Text({ points: [new Point(215, 5)], string: 'Arc', height: 4 }));
|
|
73
|
+
|
|
74
|
+
// Row 1, Col 0: Text
|
|
75
|
+
const text = new Text({
|
|
76
|
+
points: [new Point(25, 150)],
|
|
77
|
+
string: 'Hello',
|
|
78
|
+
height: 8,
|
|
79
|
+
layer: 'TEXT_LAYER',
|
|
80
|
+
});
|
|
81
|
+
core.scene.entities.add(text);
|
|
82
|
+
core.scene.entities.add(new Text({ points: [new Point(15, 105)], string: 'Text', height: 4 }));
|
|
83
|
+
|
|
84
|
+
// Row 1, Col 1: Polyline
|
|
85
|
+
const polyline = new Polyline({
|
|
86
|
+
points: [new Point(130, 130), new Point(170, 130), new Point(170, 175), new Point(130, 175)],
|
|
87
|
+
layer: 'POLYLINE_LAYER',
|
|
88
|
+
});
|
|
89
|
+
core.scene.entities.add(polyline);
|
|
90
|
+
core.scene.entities.add(new Text({ points: [new Point(115, 105)], string: 'Polyline', height: 4 }));
|
|
91
|
+
|
|
92
|
+
// Row 1, Col 2: Lwpolyline
|
|
93
|
+
const lwpolyline = new Lwpolyline({
|
|
94
|
+
points: [new Point(230, 130), new Point(270, 130), new Point(270, 175), new Point(230, 175)],
|
|
95
|
+
layer: 'LWPOLYLINE_LAYER',
|
|
96
|
+
});
|
|
97
|
+
core.scene.entities.add(lwpolyline);
|
|
98
|
+
core.scene.entities.add(new Text({ points: [new Point(215, 105)], string: 'Lwpolyline', height: 4 }));
|
|
99
|
+
|
|
100
|
+
// Solid - not registered as a command, cannot be imported
|
|
101
|
+
// const solid = new Solid({
|
|
102
|
+
// points: [new Point(20, 225), new Point(80, 225), new Point(50, 280)],
|
|
103
|
+
// layer: 'SOLID_LAYER',
|
|
104
|
+
// });
|
|
105
|
+
// core.scene.entities.add(solid);
|
|
106
|
+
// core.scene.entities.add(new Text({ points: [new Point(15, 205)], string: 'Solid', height: 4 }));
|
|
107
|
+
|
|
108
|
+
// Row 2, Col 0: Hatch
|
|
109
|
+
const boundary = new BasePolyline({
|
|
110
|
+
points: [new Point(25, 230), new Point(75, 230), new Point(75, 280), new Point(25, 280)],
|
|
111
|
+
});
|
|
112
|
+
const hatch = new Hatch({
|
|
113
|
+
patternName: 'ANSI31',
|
|
114
|
+
layer: 'HATCH_LAYER',
|
|
115
|
+
});
|
|
116
|
+
hatch.childEntities = [boundary];
|
|
117
|
+
core.scene.entities.add(hatch);
|
|
118
|
+
core.scene.entities.add(new Text({ points: [new Point(15, 205)], string: 'Hatch', height: 4 }));
|
|
119
|
+
|
|
120
|
+
// Row 2, Col 1: Insert
|
|
121
|
+
const blockLine = new Line({ points: [new Point(0, 0), new Point(40, 40)] });
|
|
122
|
+
blockLine.handle = DesignCore.HandleManager.next();
|
|
123
|
+
const block = DesignCore.Scene.blockManager.addItem({
|
|
124
|
+
name: 'TEST_BLOCK',
|
|
125
|
+
items: [blockLine],
|
|
126
|
+
});
|
|
127
|
+
const insert = new Insert({
|
|
128
|
+
points: [new Point(130, 235)],
|
|
129
|
+
layer: 'INSERT_LAYER',
|
|
130
|
+
});
|
|
131
|
+
insert.block = block;
|
|
132
|
+
core.scene.entities.add(insert);
|
|
133
|
+
core.scene.entities.add(new Text({ points: [new Point(115, 205)], string: 'Insert', height: 4 }));
|
|
134
|
+
|
|
135
|
+
// ArcAlignedText - omitted
|
|
136
|
+
// const arctext = new ArcAlignedText({
|
|
137
|
+
// points: [new Point(250, 255)],
|
|
138
|
+
// radius: 25,
|
|
139
|
+
// string: 'ArcText',
|
|
140
|
+
// height: 5,
|
|
141
|
+
// startAngle: 0,
|
|
142
|
+
// endAngle: 180,
|
|
143
|
+
// layer: 'ARCTEXT_LAYER',
|
|
144
|
+
// });
|
|
145
|
+
// core.scene.entities.add(arctext);
|
|
146
|
+
// core.scene.entities.add(new Text({ points: [new Point(215, 205)], string: 'ArcText', height: 4 }));
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
let dxfOutput;
|
|
150
|
+
|
|
151
|
+
beforeAll(() => {
|
|
152
|
+
dxfOutput = core.saveFile('R2018');
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test('Test DXF output contains all entities', () => {
|
|
156
|
+
expect(dxfOutput).toContain('LINE');
|
|
157
|
+
expect(dxfOutput).toContain('CIRCLE');
|
|
158
|
+
expect(dxfOutput).toContain('ARC');
|
|
159
|
+
expect(dxfOutput).toContain('TEXT');
|
|
160
|
+
expect(dxfOutput).toContain('POLYLINE');
|
|
161
|
+
expect(dxfOutput).toContain('LWPOLYLINE');
|
|
162
|
+
// expect(dxfOutput).toContain('SOLID');
|
|
163
|
+
expect(dxfOutput).toContain('HATCH');
|
|
164
|
+
expect(dxfOutput).toContain('INSERT');
|
|
165
|
+
// expect(dxfOutput).toContain('ARCALIGNEDTEXT');
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
test('Test DXF output contains all layers', () => {
|
|
169
|
+
expect(dxfOutput).toContain('LINE_LAYER');
|
|
170
|
+
expect(dxfOutput).toContain('CIRCLE_LAYER');
|
|
171
|
+
expect(dxfOutput).toContain('ARC_LAYER');
|
|
172
|
+
expect(dxfOutput).toContain('TEXT_LAYER');
|
|
173
|
+
expect(dxfOutput).toContain('POLYLINE_LAYER');
|
|
174
|
+
expect(dxfOutput).toContain('LWPOLYLINE_LAYER');
|
|
175
|
+
// expect(dxfOutput).toContain('SOLID_LAYER');
|
|
176
|
+
expect(dxfOutput).toContain('HATCH_LAYER');
|
|
177
|
+
expect(dxfOutput).toContain('INSERT_LAYER');
|
|
178
|
+
// expect(dxfOutput).toContain('ARCTEXT_LAYER');
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
test('Test DXF output matches reference file', () => {
|
|
182
|
+
const referencePath = join(__dirname, 'exportIntegration.reference.dxf');
|
|
183
|
+
const reference = readFileSync(referencePath, 'utf8');
|
|
184
|
+
|
|
185
|
+
expect(dxfOutput).toBe(reference);
|
|
186
|
+
});
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Core } from '../../core/core/core.js';
|
|
2
|
+
import { DXF } from '../../core/lib/dxf/dxf.js';
|
|
3
|
+
|
|
4
|
+
import { readFileSync } from 'fs';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { dirname, join } from 'path';
|
|
7
|
+
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Strip handle values from a DXF string so that comparison
|
|
13
|
+
* is insensitive to handle allocation order.
|
|
14
|
+
* Only group codes that contain hex handles are stripped.
|
|
15
|
+
* Values are validated as hex before stripping.
|
|
16
|
+
* @param {string} dxfString
|
|
17
|
+
* @return {{stripped: string, invalidHandles: Array<{line: number, code: number, value: string}>}}
|
|
18
|
+
*/
|
|
19
|
+
function stripHandles(dxfString) {
|
|
20
|
+
const lines = dxfString.split('\n');
|
|
21
|
+
const invalidHandles = [];
|
|
22
|
+
let inDimStyle = false;
|
|
23
|
+
|
|
24
|
+
// DXF lines alternate: group code, value, group code, value...
|
|
25
|
+
for (let i = 0; i < lines.length - 1; i += 2) {
|
|
26
|
+
const code = parseInt(lines[i].trim(), 10);
|
|
27
|
+
if (isNaN(code)) continue;
|
|
28
|
+
|
|
29
|
+
const value = lines[i + 1].trim();
|
|
30
|
+
|
|
31
|
+
// Track DIMSTYLE context - groupcode 5 is an arrowhead
|
|
32
|
+
// block name in DIMSTYLE, not a handle (DIMSTYLE uses 105)
|
|
33
|
+
if (code === 0) {
|
|
34
|
+
inDimStyle = value === 'DIMSTYLE';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Groupcode 5 = entity/table handle (except in DIMSTYLE)
|
|
38
|
+
// Groupcode 105 = dimstyle handle
|
|
39
|
+
// Groupcode 350 = dictionary entry handle
|
|
40
|
+
// Groupcode 390 = plotStyleHandle
|
|
41
|
+
const isHandleCode = (code === 5 && !inDimStyle) ||
|
|
42
|
+
code === 105 || code === 350 || code === 390;
|
|
43
|
+
|
|
44
|
+
if (isHandleCode) {
|
|
45
|
+
if (/^[0-9A-Fa-f]+$/.test(value)) {
|
|
46
|
+
lines[i + 1] = '0';
|
|
47
|
+
} else {
|
|
48
|
+
invalidHandles.push({ line: i + 2, code, value });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return { stripped: lines.join('\n'), invalidHandles };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
test('Test DXF round-trip: read reference and re-output matches', () => {
|
|
57
|
+
const core = new Core();
|
|
58
|
+
|
|
59
|
+
const referencePath = join(__dirname, 'exportIntegration.reference.dxf');
|
|
60
|
+
const reference = readFileSync(referencePath, 'utf8');
|
|
61
|
+
|
|
62
|
+
// Load the reference DXF
|
|
63
|
+
const dxf = new DXF();
|
|
64
|
+
dxf.loadDxf(reference);
|
|
65
|
+
|
|
66
|
+
// Output a new DXF
|
|
67
|
+
const output = core.saveFile('R2018');
|
|
68
|
+
|
|
69
|
+
const strippedOutput = stripHandles(output);
|
|
70
|
+
const strippedReference = stripHandles(reference);
|
|
71
|
+
|
|
72
|
+
expect(strippedOutput.invalidHandles).toEqual([]);
|
|
73
|
+
expect(strippedReference.invalidHandles).toEqual([]);
|
|
74
|
+
expect(strippedOutput.stripped).toBe(strippedReference.stripped);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('Test DXF output has no duplicate handles', () => {
|
|
78
|
+
const core = new Core();
|
|
79
|
+
|
|
80
|
+
const referencePath = join(__dirname, 'exportIntegration.reference.dxf');
|
|
81
|
+
const reference = readFileSync(referencePath, 'utf8');
|
|
82
|
+
|
|
83
|
+
// Load the reference DXF
|
|
84
|
+
const dxf = new DXF();
|
|
85
|
+
dxf.loadDxf(reference);
|
|
86
|
+
|
|
87
|
+
// Output a new DXF
|
|
88
|
+
const output = core.saveFile('R2018');
|
|
89
|
+
const lines = output.split('\n');
|
|
90
|
+
|
|
91
|
+
const handles = new Map();
|
|
92
|
+
let inDimStyle = false;
|
|
93
|
+
let isHandseed = false;
|
|
94
|
+
|
|
95
|
+
for (let i = 0; i < lines.length - 1; i += 2) {
|
|
96
|
+
const code = parseInt(lines[i].trim(), 10);
|
|
97
|
+
if (isNaN(code)) continue;
|
|
98
|
+
|
|
99
|
+
const value = lines[i + 1].trim();
|
|
100
|
+
|
|
101
|
+
if (code === 0) {
|
|
102
|
+
inDimStyle = value === 'DIMSTYLE';
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// $HANDSEED uses groupcode 5 for its value, not as a handle
|
|
106
|
+
if (code === 9 && value === '$HANDSEED') {
|
|
107
|
+
isHandseed = true;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Only check groupcode 5 handles (entity/table handles)
|
|
112
|
+
// Skip DIMSTYLE where code 5 is arrowhead block name
|
|
113
|
+
// Skip $HANDSEED value
|
|
114
|
+
if (code === 5 && !inDimStyle && !isHandseed && /^[0-9A-Fa-f]+$/.test(value)) {
|
|
115
|
+
const lineNum = i + 2;
|
|
116
|
+
if (handles.has(value)) {
|
|
117
|
+
fail(`Duplicate handle ${value} at line ${lineNum} (first seen at line ${handles.get(value)})`);
|
|
118
|
+
}
|
|
119
|
+
handles.set(value, lineNum);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
isHandseed = false;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
expect(handles.size).toBeGreaterThan(0);
|
|
126
|
+
});
|