@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,137 @@
|
|
|
1
|
+
import { HandleManager } from '../../../core/lib/dxf/handleManager.js';
|
|
2
|
+
|
|
3
|
+
test('Test HandleManager.constructor', () => {
|
|
4
|
+
const handle = new HandleManager();
|
|
5
|
+
expect(handle.counter).toBe(10);
|
|
6
|
+
expect(handle.usedHandles.size).toBe(0);
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
test('Test HandleManager.next', () => {
|
|
10
|
+
const handle = new HandleManager();
|
|
11
|
+
expect(handle.next()).toBe('A');
|
|
12
|
+
expect(handle.next()).toBe('B');
|
|
13
|
+
expect(handle.next()).toBe('C');
|
|
14
|
+
expect(handle.counter).toBe(13);
|
|
15
|
+
// each allocated handle is tracked in usedHandles
|
|
16
|
+
expect(handle.usedHandles.has('A')).toBe(true);
|
|
17
|
+
expect(handle.usedHandles.has('B')).toBe(true);
|
|
18
|
+
expect(handle.usedHandles.has('C')).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('Test HandleManager.format', () => {
|
|
22
|
+
const handle = new HandleManager();
|
|
23
|
+
expect(handle.format(0)).toBe('0');
|
|
24
|
+
expect(handle.format(10)).toBe('A');
|
|
25
|
+
expect(handle.format(15)).toBe('F');
|
|
26
|
+
expect(handle.format(16)).toBe('10');
|
|
27
|
+
expect(handle.format(255)).toBe('FF');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('Test HandleManager.reset', () => {
|
|
31
|
+
const handle = new HandleManager();
|
|
32
|
+
handle.next();
|
|
33
|
+
handle.next();
|
|
34
|
+
expect(handle.counter).toBe(12);
|
|
35
|
+
handle.reset();
|
|
36
|
+
expect(handle.counter).toBe(10);
|
|
37
|
+
// usedHandles must also be cleared
|
|
38
|
+
expect(handle.usedHandles.size).toBe(0);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('Test HandleManager.handseed getter', () => {
|
|
42
|
+
const handle = new HandleManager();
|
|
43
|
+
expect(handle.handseed).toBe('A');
|
|
44
|
+
handle.next();
|
|
45
|
+
expect(handle.handseed).toBe('B');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('Test HandleManager.handseed setter', () => {
|
|
49
|
+
const handle = new HandleManager();
|
|
50
|
+
handle.handseed = 'FF';
|
|
51
|
+
expect(handle.counter).toBe(255);
|
|
52
|
+
expect(handle.next()).toBe('FF');
|
|
53
|
+
expect(handle.next()).toBe('100');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('Test HandleManager.handseed setter directly assigns counter, even below current value', () => {
|
|
57
|
+
const handle = new HandleManager();
|
|
58
|
+
// Advance the counter, then set handseed to a lower value.
|
|
59
|
+
// The setter performs a direct assignment with no lower-bound guard.
|
|
60
|
+
handle.next(); // counter → 11
|
|
61
|
+
handle.next(); // counter → 12
|
|
62
|
+
handle.handseed = '5'; // parseInt('5', 16) = 5
|
|
63
|
+
expect(handle.counter).toBe(5);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('Test HandleManager.checkHandle coerces numeric handle to string', () => {
|
|
67
|
+
const handle = new HandleManager();
|
|
68
|
+
handle.checkHandle(255);
|
|
69
|
+
// String(255) = '255', which is valid hex (0x255 = 597)
|
|
70
|
+
expect(handle.usedHandles.has('255')).toBe(true);
|
|
71
|
+
expect(handle.counter).toBe(598);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('Test HandleManager.checkHandle advances counter when handle >= counter', () => {
|
|
75
|
+
const handle = new HandleManager();
|
|
76
|
+
// counter starts at 10 (0xA); register 0x1F (31) — above counter
|
|
77
|
+
handle.checkHandle('1F');
|
|
78
|
+
expect(handle.usedHandles.has('1F')).toBe(true);
|
|
79
|
+
expect(handle.counter).toBe(32); // 0x1F + 1
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('Test HandleManager.checkHandle does not advance counter when handle < counter', () => {
|
|
83
|
+
const handle = new HandleManager();
|
|
84
|
+
handle.next(); // counter → 11 (0xB), 'A' allocated
|
|
85
|
+
const counterBefore = handle.counter;
|
|
86
|
+
// Register a handle lower than current counter
|
|
87
|
+
handle.checkHandle('5');
|
|
88
|
+
expect(handle.usedHandles.has('5')).toBe(true);
|
|
89
|
+
expect(handle.counter).toBe(counterBefore); // counter unchanged
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('Test HandleManager.checkHandle ignores undefined and null', () => {
|
|
93
|
+
const handle = new HandleManager();
|
|
94
|
+
const counterBefore = handle.counter;
|
|
95
|
+
handle.checkHandle(undefined);
|
|
96
|
+
handle.checkHandle(null);
|
|
97
|
+
expect(handle.counter).toBe(counterBefore);
|
|
98
|
+
expect(handle.usedHandles.size).toBe(0);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test('Test HandleManager.checkHandle ignores invalid hex strings', () => {
|
|
102
|
+
const handle = new HandleManager();
|
|
103
|
+
const counterBefore = handle.counter;
|
|
104
|
+
handle.checkHandle('XYZ');
|
|
105
|
+
handle.checkHandle('');
|
|
106
|
+
expect(handle.counter).toBe(counterBefore);
|
|
107
|
+
expect(handle.usedHandles.size).toBe(0);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test('Test HandleManager.releaseHandle removes handle from usedHandles', () => {
|
|
111
|
+
const handle = new HandleManager();
|
|
112
|
+
const h = handle.next(); // allocates 'A'
|
|
113
|
+
expect(handle.usedHandles.has('A')).toBe(true);
|
|
114
|
+
handle.releaseHandle(h);
|
|
115
|
+
expect(handle.usedHandles.has('A')).toBe(false);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test('Test HandleManager.releaseHandle ignores undefined and null', () => {
|
|
119
|
+
const handle = new HandleManager();
|
|
120
|
+
handle.next();
|
|
121
|
+
const sizeBefore = handle.usedHandles.size;
|
|
122
|
+
handle.releaseHandle(undefined);
|
|
123
|
+
handle.releaseHandle(null);
|
|
124
|
+
expect(handle.usedHandles.size).toBe(sizeBefore);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test('Test HandleManager.releaseHandle allows handle to be re-registered without duplicate error', () => {
|
|
128
|
+
const handle = new HandleManager();
|
|
129
|
+
const h = handle.next(); // allocates 'A'
|
|
130
|
+
handle.releaseHandle(h);
|
|
131
|
+
// After release the handle is gone, so checkHandle should re-register it cleanly
|
|
132
|
+
handle.checkHandle(h);
|
|
133
|
+
// The handle should be back in usedHandles with no duplicate detection
|
|
134
|
+
expect(handle.usedHandles.has('A')).toBe(true);
|
|
135
|
+
// Only one entry — no duplication
|
|
136
|
+
expect(handle.usedHandles.size).toBe(1);
|
|
137
|
+
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {Blocks} from '../../../../core/lib/dxf/sections/blocks.js';
|
|
2
|
-
import {DxfIterator} from '../../../../core/lib/dxf/dxfIterator.js';
|
|
1
|
+
import { Blocks } from '../../../../core/lib/dxf/sections/blocks.js';
|
|
2
|
+
import { DxfIterator } from '../../../../core/lib/dxf/dxfIterator.js';
|
|
3
3
|
|
|
4
4
|
const blockData =
|
|
5
|
-
`2
|
|
5
|
+
`2
|
|
6
6
|
BLOCKS
|
|
7
7
|
0
|
|
8
8
|
BLOCK
|
|
@@ -91,7 +91,7 @@ test('Test blocks.read', () => {
|
|
|
91
91
|
test('Test blocks.addTable', () => {
|
|
92
92
|
// block without data
|
|
93
93
|
const blockEntity = {};
|
|
94
|
-
const
|
|
94
|
+
const itemCount = blocks.blocks.length;
|
|
95
95
|
blocks.addBlock(blockEntity);
|
|
96
|
-
expect(blocks.blocks.length).toBe(
|
|
96
|
+
expect(blocks.blocks.length).toBe(itemCount);
|
|
97
97
|
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {Entities} from '../../../../core/lib/dxf/sections/entities.js';
|
|
2
|
-
import {DxfIterator} from '../../../../core/lib/dxf/dxfIterator.js';
|
|
1
|
+
import { Entities } from '../../../../core/lib/dxf/sections/entities.js';
|
|
2
|
+
import { DxfIterator } from '../../../../core/lib/dxf/dxfIterator.js';
|
|
3
3
|
|
|
4
4
|
const entityData =
|
|
5
|
-
`0
|
|
5
|
+
`0
|
|
6
6
|
ENTITIES
|
|
7
7
|
0
|
|
8
8
|
CIRCLE
|
|
@@ -119,7 +119,7 @@ test('Test Entities.read', () => {
|
|
|
119
119
|
|
|
120
120
|
test('Test Entities.addEntity', () => {
|
|
121
121
|
// entity without points
|
|
122
|
-
const circleEntity = {'0': 'CIRCLE', '40': 100, '8': '0'};
|
|
122
|
+
const circleEntity = { '0': 'CIRCLE', '40': 100, '8': '0' };
|
|
123
123
|
|
|
124
124
|
expect(() => {
|
|
125
125
|
entities.addEntity(circleEntity);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {Header} from '../../../../core/lib/dxf/sections/header.js';
|
|
2
|
-
import {DxfIterator} from '../../../../core/lib/dxf/dxfIterator.js';
|
|
1
|
+
import { Header } from '../../../../core/lib/dxf/sections/header.js';
|
|
2
|
+
import { DxfIterator } from '../../../../core/lib/dxf/dxfIterator.js';
|
|
3
3
|
|
|
4
4
|
const headerData =
|
|
5
|
-
`2
|
|
5
|
+
`2
|
|
6
6
|
HEADER
|
|
7
7
|
9
|
|
8
8
|
$ACADVER
|
|
@@ -32,7 +32,15 @@ $EXTMAX
|
|
|
32
32
|
300
|
|
33
33
|
30
|
|
34
34
|
0.0
|
|
35
|
+
9
|
|
36
|
+
$TEXTSTYLE
|
|
37
|
+
7
|
|
38
|
+
Standard
|
|
35
39
|
9
|
|
40
|
+
$CLAYER
|
|
41
|
+
8
|
|
42
|
+
0
|
|
43
|
+
0
|
|
36
44
|
ENDSEC
|
|
37
45
|
0
|
|
38
46
|
EOF`;
|
|
@@ -43,7 +51,7 @@ const header = new Header();
|
|
|
43
51
|
header.read(iterator);
|
|
44
52
|
|
|
45
53
|
test('Test Header.read', () => {
|
|
46
|
-
expect(Object.keys(header)).toHaveLength(
|
|
54
|
+
expect(Object.keys(header)).toHaveLength(6);
|
|
47
55
|
// check the entity type
|
|
48
56
|
expect(header).toHaveProperty('$ACADVER');
|
|
49
57
|
expect(header['$ACADVER']).toHaveProperty('1', 'AC1009');
|
|
@@ -59,4 +67,10 @@ test('Test Header.read', () => {
|
|
|
59
67
|
expect(header['$EXTMIN'].points[0]).toHaveProperty('x', 100);
|
|
60
68
|
expect(header['$EXTMIN'].points[0]).toHaveProperty('y', 100);
|
|
61
69
|
expect(header['$EXTMIN'].points[0]).toHaveProperty('z', 100);
|
|
70
|
+
|
|
71
|
+
expect(header).toHaveProperty('$TEXTSTYLE');
|
|
72
|
+
expect(header['$TEXTSTYLE']).toHaveProperty('7', 'Standard');
|
|
73
|
+
|
|
74
|
+
expect(header).toHaveProperty('$CLAYER');
|
|
75
|
+
expect(header['$CLAYER']).toHaveProperty('8', '0');
|
|
62
76
|
});
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { Objects } from '../../../../core/lib/dxf/sections/objects.js';
|
|
2
|
+
import { DxfIterator } from '../../../../core/lib/dxf/dxfIterator.js';
|
|
3
|
+
|
|
4
|
+
const objectData =
|
|
5
|
+
`0
|
|
6
|
+
OBJECTS
|
|
7
|
+
0
|
|
8
|
+
DICTIONARY
|
|
9
|
+
5
|
|
10
|
+
27
|
|
11
|
+
100
|
|
12
|
+
AcDbDictionary
|
|
13
|
+
281
|
|
14
|
+
1
|
|
15
|
+
3
|
|
16
|
+
ACAD_GROUP
|
|
17
|
+
350
|
|
18
|
+
26
|
|
19
|
+
0
|
|
20
|
+
DICTIONARY
|
|
21
|
+
5
|
|
22
|
+
26
|
|
23
|
+
100
|
|
24
|
+
AcDbDictionary
|
|
25
|
+
281
|
|
26
|
+
1
|
|
27
|
+
0
|
|
28
|
+
ENDSEC
|
|
29
|
+
0
|
|
30
|
+
EOF`;
|
|
31
|
+
|
|
32
|
+
const iterator = new DxfIterator();
|
|
33
|
+
iterator.loadFile(objectData);
|
|
34
|
+
const objects = new Objects();
|
|
35
|
+
|
|
36
|
+
test('Test Objects.read', () => {
|
|
37
|
+
const readObjects = objects.read(iterator);
|
|
38
|
+
|
|
39
|
+
expect(readObjects).toHaveLength(2);
|
|
40
|
+
|
|
41
|
+
const rootDictionary = readObjects[0];
|
|
42
|
+
const groupDictionary = readObjects[1];
|
|
43
|
+
|
|
44
|
+
// check the object types
|
|
45
|
+
expect(rootDictionary).toHaveProperty('0', 'DICTIONARY');
|
|
46
|
+
expect(groupDictionary).toHaveProperty('0', 'DICTIONARY');
|
|
47
|
+
|
|
48
|
+
// check handles
|
|
49
|
+
expect(rootDictionary).toHaveProperty('5', '27');
|
|
50
|
+
expect(groupDictionary).toHaveProperty('5', '26');
|
|
51
|
+
|
|
52
|
+
// check AcDbDictionary subclass marker
|
|
53
|
+
expect(rootDictionary).toHaveProperty('100', 'AcDbDictionary');
|
|
54
|
+
expect(groupDictionary).toHaveProperty('100', 'AcDbDictionary');
|
|
55
|
+
|
|
56
|
+
// check duplicate record cloning
|
|
57
|
+
expect(rootDictionary).toHaveProperty('281', 1);
|
|
58
|
+
expect(groupDictionary).toHaveProperty('281', 1);
|
|
59
|
+
|
|
60
|
+
// check root dictionary entries
|
|
61
|
+
expect(rootDictionary).toHaveProperty('3', 'ACAD_GROUP');
|
|
62
|
+
expect(rootDictionary).toHaveProperty('350', '26');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test('Test Objects.read with multiple entries', () => {
|
|
66
|
+
const multiEntryData =
|
|
67
|
+
`0
|
|
68
|
+
OBJECTS
|
|
69
|
+
0
|
|
70
|
+
DICTIONARY
|
|
71
|
+
5
|
|
72
|
+
C
|
|
73
|
+
100
|
|
74
|
+
AcDbDictionary
|
|
75
|
+
281
|
|
76
|
+
1
|
|
77
|
+
3
|
|
78
|
+
ACAD_GROUP
|
|
79
|
+
350
|
|
80
|
+
D
|
|
81
|
+
3
|
|
82
|
+
ACAD_LAYOUT
|
|
83
|
+
350
|
|
84
|
+
1A
|
|
85
|
+
3
|
|
86
|
+
ACAD_PLOTSTYLENAME
|
|
87
|
+
350
|
|
88
|
+
E
|
|
89
|
+
0
|
|
90
|
+
DICTIONARY
|
|
91
|
+
5
|
|
92
|
+
D
|
|
93
|
+
100
|
|
94
|
+
AcDbDictionary
|
|
95
|
+
281
|
|
96
|
+
1
|
|
97
|
+
0
|
|
98
|
+
ENDSEC
|
|
99
|
+
0
|
|
100
|
+
EOF`;
|
|
101
|
+
|
|
102
|
+
const iter = new DxfIterator();
|
|
103
|
+
iter.loadFile(multiEntryData);
|
|
104
|
+
const obj = new Objects();
|
|
105
|
+
const result = obj.read(iter);
|
|
106
|
+
|
|
107
|
+
expect(result).toHaveLength(2);
|
|
108
|
+
|
|
109
|
+
const rootDict = result[0];
|
|
110
|
+
|
|
111
|
+
// multiple group code 3 values should be arrayed
|
|
112
|
+
expect(rootDict[3]).toEqual(['ACAD_GROUP', 'ACAD_LAYOUT', 'ACAD_PLOTSTYLENAME']);
|
|
113
|
+
// multiple group code 350 values should be arrayed
|
|
114
|
+
expect(rootDict[350]).toEqual(['D', '1A', 'E']);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('Test Objects.read with empty section', () => {
|
|
118
|
+
const emptyData =
|
|
119
|
+
`0
|
|
120
|
+
OBJECTS
|
|
121
|
+
0
|
|
122
|
+
ENDSEC
|
|
123
|
+
0
|
|
124
|
+
EOF`;
|
|
125
|
+
|
|
126
|
+
const iter = new DxfIterator();
|
|
127
|
+
iter.loadFile(emptyData);
|
|
128
|
+
const obj = new Objects();
|
|
129
|
+
const result = obj.read(iter);
|
|
130
|
+
|
|
131
|
+
expect(result).toHaveLength(0);
|
|
132
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {Section} from '../../../../core/lib/dxf/sections/section.js';
|
|
2
|
-
import {DxfIterator} from '../../../../core/lib/dxf/dxfIterator.js';
|
|
1
|
+
import { Section } from '../../../../core/lib/dxf/sections/section.js';
|
|
2
|
+
import { DxfIterator } from '../../../../core/lib/dxf/dxfIterator.js';
|
|
3
3
|
|
|
4
4
|
const section = new Section();
|
|
5
5
|
|
|
@@ -29,7 +29,7 @@ test('Test Section.parseValue', () => {
|
|
|
29
29
|
|
|
30
30
|
test('Test Section.parseChild', () => {
|
|
31
31
|
const string =
|
|
32
|
-
`0
|
|
32
|
+
`0
|
|
33
33
|
CIRCLE
|
|
34
34
|
8
|
|
35
35
|
0
|
|
@@ -69,7 +69,7 @@ EOF`;
|
|
|
69
69
|
|
|
70
70
|
test('Test Section.parsePoint', () => {
|
|
71
71
|
const string =
|
|
72
|
-
`10
|
|
72
|
+
`10
|
|
73
73
|
500.0
|
|
74
74
|
20
|
|
75
75
|
500.0
|
|
@@ -125,69 +125,69 @@ test('Test Section.parseBoolean', () => {
|
|
|
125
125
|
|
|
126
126
|
test('Test Section.getGroupValue', () => {
|
|
127
127
|
// 0-9: String
|
|
128
|
-
expect(section.getGroupValue({'code': '1', 'value': '1'})).toBe('1');
|
|
128
|
+
expect(section.getGroupValue({ 'code': '1', 'value': '1' })).toBe('1');
|
|
129
129
|
// 10-39: Double precision 3D point value
|
|
130
130
|
// 40-59: Double precision floating-point value
|
|
131
|
-
expect(section.getGroupValue({'code': '10', 'value': ' 100.0'})).toBe(100.0);
|
|
131
|
+
expect(section.getGroupValue({ 'code': '10', 'value': ' 100.0' })).toBe(100.0);
|
|
132
132
|
// 60-79: 16-bit integer value
|
|
133
133
|
// 90-99: 32-bit integer value
|
|
134
|
-
expect(section.getGroupValue({'code': '60', 'value': ' 100.0'})).toBe(100);
|
|
134
|
+
expect(section.getGroupValue({ 'code': '60', 'value': ' 100.0' })).toBe(100);
|
|
135
135
|
// 100: String (255-character maximum; less for Unicode strings)
|
|
136
136
|
// 102: String (255-character maximum; less for Unicode strings)
|
|
137
137
|
// 105: String representing hexadecimal (hex) handle value
|
|
138
|
-
expect(section.getGroupValue({'code': '100', 'value': 'aabbccdd'})).toBe('aabbccdd');
|
|
138
|
+
expect(section.getGroupValue({ 'code': '100', 'value': 'aabbccdd' })).toBe('aabbccdd');
|
|
139
139
|
// 110-119: Double precision floating-point value
|
|
140
140
|
// 120-129: Double precision floating-point value
|
|
141
141
|
// 130-139: Double precision floating-point value
|
|
142
142
|
// 140-149: Double precision scalar floating-point value
|
|
143
|
-
expect(section.getGroupValue({'code': '110', 'value': ' 100.0'})).toBe(100.0);
|
|
143
|
+
expect(section.getGroupValue({ 'code': '110', 'value': ' 100.0' })).toBe(100.0);
|
|
144
144
|
// 160-169: 64-bit integer value
|
|
145
145
|
// 170-179: 16-bit integer value
|
|
146
|
-
expect(section.getGroupValue({'code': '160', 'value': ' 100.0'})).toBe(100);
|
|
146
|
+
expect(section.getGroupValue({ 'code': '160', 'value': ' 100.0' })).toBe(100);
|
|
147
147
|
// 210-239: Double-precision floating-point value
|
|
148
|
-
expect(section.getGroupValue({'code': '210', 'value': ' 100.0'})).toBe(100.0);
|
|
148
|
+
expect(section.getGroupValue({ 'code': '210', 'value': ' 100.0' })).toBe(100.0);
|
|
149
149
|
// 270-279: 16-bit integer value
|
|
150
150
|
// 280-289: 16-bit integer value
|
|
151
|
-
expect(section.getGroupValue({'code': '270', 'value': ' 100.0'})).toBe(100);
|
|
151
|
+
expect(section.getGroupValue({ 'code': '270', 'value': ' 100.0' })).toBe(100);
|
|
152
152
|
// 290-299: Boolean flag value
|
|
153
|
-
expect(section.getGroupValue({'code': '290', 'value': ' 0'})).toBe(false);
|
|
154
|
-
expect(section.getGroupValue({'code': '299', 'value': ' 1'})).toBe(true);
|
|
153
|
+
expect(section.getGroupValue({ 'code': '290', 'value': ' 0' })).toBe(false);
|
|
154
|
+
expect(section.getGroupValue({ 'code': '299', 'value': ' 1' })).toBe(true);
|
|
155
155
|
// 300-309: Arbitrary text string
|
|
156
156
|
// 330-369: String representing hex object IDs
|
|
157
|
-
expect(section.getGroupValue({'code': '300', 'value': 'aabbccdd'})).toBe('aabbccdd');
|
|
157
|
+
expect(section.getGroupValue({ 'code': '300', 'value': 'aabbccdd' })).toBe('aabbccdd');
|
|
158
158
|
// 370-379: 16-bit integer value
|
|
159
159
|
// 380-389: 16-bit integer value
|
|
160
|
-
expect(section.getGroupValue({'code': '370', 'value': ' 100.0'})).toBe(100);
|
|
160
|
+
expect(section.getGroupValue({ 'code': '370', 'value': ' 100.0' })).toBe(100);
|
|
161
161
|
// 390-399: String representing hex handle value
|
|
162
|
-
expect(section.getGroupValue({'code': '390', 'value': 'aabbccdd'})).toBe('aabbccdd');
|
|
162
|
+
expect(section.getGroupValue({ 'code': '390', 'value': 'aabbccdd' })).toBe('aabbccdd');
|
|
163
163
|
// 400-409: 16-bit integer value
|
|
164
|
-
expect(section.getGroupValue({'code': '400', 'value': ' 100.0'})).toBe(100);
|
|
164
|
+
expect(section.getGroupValue({ 'code': '400', 'value': ' 100.0' })).toBe(100);
|
|
165
165
|
// 410-419: String
|
|
166
|
-
expect(section.getGroupValue({'code': '410', 'value': 'aabbccdd'})).toBe('aabbccdd');
|
|
166
|
+
expect(section.getGroupValue({ 'code': '410', 'value': 'aabbccdd' })).toBe('aabbccdd');
|
|
167
167
|
// 420-429: 32-bit integer value
|
|
168
|
-
expect(section.getGroupValue({'code': '420', 'value': ' 100.0'})).toBe(100);
|
|
168
|
+
expect(section.getGroupValue({ 'code': '420', 'value': ' 100.0' })).toBe(100);
|
|
169
169
|
// 430-439: String
|
|
170
|
-
expect(section.getGroupValue({'code': '340', 'value': 'aabbccdd'})).toBe('aabbccdd');
|
|
170
|
+
expect(section.getGroupValue({ 'code': '340', 'value': 'aabbccdd' })).toBe('aabbccdd');
|
|
171
171
|
// 440-449: 32-bit integer value
|
|
172
172
|
// 450-459: Long
|
|
173
|
-
expect(section.getGroupValue({'code': '440', 'value': ' 100.0'})).toBe(100);
|
|
173
|
+
expect(section.getGroupValue({ 'code': '440', 'value': ' 100.0' })).toBe(100);
|
|
174
174
|
// 460-469: Double-precision floating-point value
|
|
175
|
-
expect(section.getGroupValue({'code': '460', 'value': ' 100.0'})).toBe(100.0);
|
|
175
|
+
expect(section.getGroupValue({ 'code': '460', 'value': ' 100.0' })).toBe(100.0);
|
|
176
176
|
// 470-479: String
|
|
177
177
|
// 480-481: String representing hex handle value
|
|
178
|
-
expect(section.getGroupValue({'code': '470', 'value': 'aabbccdd'})).toBe('aabbccdd');
|
|
178
|
+
expect(section.getGroupValue({ 'code': '470', 'value': 'aabbccdd' })).toBe('aabbccdd');
|
|
179
179
|
// 999: Comment (string)
|
|
180
|
-
expect(section.getGroupValue({'code': '999', 'value': 'comment'})).toBe('comment');
|
|
180
|
+
expect(section.getGroupValue({ 'code': '999', 'value': 'comment' })).toBe('comment');
|
|
181
181
|
// 1000-1009: String (same limits as indicated with 0-9 code range)
|
|
182
|
-
expect(section.getGroupValue({'code': '1000', 'value': 'aabbccdd'})).toBe('aabbccdd');
|
|
182
|
+
expect(section.getGroupValue({ 'code': '1000', 'value': 'aabbccdd' })).toBe('aabbccdd');
|
|
183
183
|
// 1010-1059: Double-precision floating-point value
|
|
184
|
-
expect(section.getGroupValue({'code': '1010', 'value': ' 100.0'})).toBe(100.0);
|
|
184
|
+
expect(section.getGroupValue({ 'code': '1010', 'value': ' 100.0' })).toBe(100.0);
|
|
185
185
|
// 1060-1070: 16-bit integer value
|
|
186
186
|
// 1071: 32-bit: integer value
|
|
187
|
-
expect(section.getGroupValue({'code': '1060', 'value': ' 100.0'})).toBe(100);
|
|
187
|
+
expect(section.getGroupValue({ 'code': '1060', 'value': ' 100.0' })).toBe(100);
|
|
188
188
|
|
|
189
189
|
// test for throw on invalid group code
|
|
190
190
|
expect(() => {
|
|
191
|
-
section.getGroupValue({'code': 'error', 'value': 'error'}); ;
|
|
191
|
+
section.getGroupValue({ 'code': 'error', 'value': 'error' }); ;
|
|
192
192
|
}).toThrow();
|
|
193
193
|
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {Tables} from '../../../../core/lib/dxf/sections/tables.js';
|
|
2
|
-
import {DxfIterator} from '../../../../core/lib/dxf/dxfIterator.js';
|
|
1
|
+
import { Tables } from '../../../../core/lib/dxf/sections/tables.js';
|
|
2
|
+
import { DxfIterator } from '../../../../core/lib/dxf/dxfIterator.js';
|
|
3
3
|
|
|
4
4
|
const tableData =
|
|
5
|
-
`0
|
|
5
|
+
`0
|
|
6
6
|
TABLES
|
|
7
7
|
0
|
|
8
8
|
TABLE
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { Core } from '../../core/core/core.js';
|
|
2
|
+
import { DesignCore } from '../../core/designCore.js';
|
|
3
|
+
import { Line } from '../../core/entities/line.js';
|
|
4
|
+
import { Circle } from '../../core/entities/circle.js';
|
|
5
|
+
import { Point } from '../../core/entities/point.js';
|
|
6
|
+
|
|
7
|
+
// initialise core (also activates DesignCore facade)
|
|
8
|
+
new Core();
|
|
9
|
+
|
|
10
|
+
describe('EntityManager', () => {
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
// reset scene entities before each test
|
|
13
|
+
DesignCore.Scene.clear();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('create adds a new entity with current layer', () => {
|
|
17
|
+
const mgr = DesignCore.Scene.entities;
|
|
18
|
+
const p1 = new Point(0, 0);
|
|
19
|
+
const p2 = new Point(10, 0);
|
|
20
|
+
|
|
21
|
+
mgr.create('Line', { points: [p1, p2] });
|
|
22
|
+
|
|
23
|
+
expect(mgr.count()).toBe(1);
|
|
24
|
+
const ent = mgr.get(0);
|
|
25
|
+
expect(ent).toBeInstanceOf(Line);
|
|
26
|
+
expect(ent.layer).toBe(DesignCore.LayerManager.getCstyle());
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('add/get/count manage entities correctly', () => {
|
|
30
|
+
const mgr = DesignCore.Scene.entities;
|
|
31
|
+
const line = new Line({ points: [new Point(0, 0), new Point(1, 1)] });
|
|
32
|
+
expect(mgr.count()).toBe(0);
|
|
33
|
+
mgr.add(line);
|
|
34
|
+
expect(mgr.count()).toBe(1);
|
|
35
|
+
expect(mgr.get(0)).toBe(line);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('replace swaps entity at index', () => {
|
|
39
|
+
const mgr = DesignCore.Scene.entities;
|
|
40
|
+
const line = new Line({ points: [new Point(0, 0), new Point(1, 1)] });
|
|
41
|
+
const circle = new Circle({ points: [new Point(5, 5)], radius: 2 });
|
|
42
|
+
mgr.add(line);
|
|
43
|
+
expect(mgr.get(0)).toBeInstanceOf(Line);
|
|
44
|
+
mgr.replace(0, circle);
|
|
45
|
+
expect(mgr.get(0)).toBe(circle);
|
|
46
|
+
expect(mgr.get(0)).toBeInstanceOf(Circle);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('remove deletes entity at index', () => {
|
|
50
|
+
const mgr = DesignCore.Scene.entities;
|
|
51
|
+
const l1 = new Line({ points: [new Point(0, 0), new Point(1, 0)] });
|
|
52
|
+
const l2 = new Line({ points: [new Point(0, 1), new Point(1, 1)] });
|
|
53
|
+
mgr.add(l1);
|
|
54
|
+
mgr.add(l2);
|
|
55
|
+
expect(mgr.count()).toBe(2);
|
|
56
|
+
mgr.remove(0);
|
|
57
|
+
expect(mgr.count()).toBe(1);
|
|
58
|
+
expect(mgr.get(0)).toBe(l2);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('remove releases the entity handle from HandleManager', () => {
|
|
62
|
+
const mgr = DesignCore.Scene.entities;
|
|
63
|
+
const line = new Line({ points: [new Point(0, 0), new Point(1, 0)] });
|
|
64
|
+
mgr.add(line);
|
|
65
|
+
const handle = line.handle;
|
|
66
|
+
expect(DesignCore.HandleManager.usedHandles.has(handle)).toBe(true);
|
|
67
|
+
mgr.remove(0);
|
|
68
|
+
expect(DesignCore.HandleManager.usedHandles.has(handle)).toBe(false);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('remove then re-add (undo) does not produce a duplicate handle', () => {
|
|
72
|
+
const mgr = DesignCore.Scene.entities;
|
|
73
|
+
const line = new Line({ points: [new Point(0, 0), new Point(1, 0)] });
|
|
74
|
+
mgr.add(line);
|
|
75
|
+
const handle = line.handle;
|
|
76
|
+
const sizeAfterAdd = DesignCore.HandleManager.usedHandles.size;
|
|
77
|
+
|
|
78
|
+
mgr.remove(0);
|
|
79
|
+
// After remove the handle must be released
|
|
80
|
+
expect(DesignCore.HandleManager.usedHandles.has(handle)).toBe(false);
|
|
81
|
+
expect(DesignCore.HandleManager.usedHandles.size).toBe(sizeAfterAdd - 1);
|
|
82
|
+
|
|
83
|
+
// Re-add the same entity (simulates undo of a delete)
|
|
84
|
+
mgr.add(line);
|
|
85
|
+
expect(line.handle).toBe(handle);
|
|
86
|
+
expect(DesignCore.HandleManager.usedHandles.has(handle)).toBe(true);
|
|
87
|
+
// Size must return to what it was after the first add, not grow by one.
|
|
88
|
+
// If checkHandle silently re-inserted without the prior releaseHandle, the
|
|
89
|
+
// Set would still show size = sizeAfterAdd (Sets deduplicate), but the
|
|
90
|
+
// error log would fire. Tracking size across remove → re-add catches the
|
|
91
|
+
// case where releaseHandle was not called and size never shrank.
|
|
92
|
+
expect(DesignCore.HandleManager.usedHandles.size).toBe(sizeAfterAdd);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
test('indexOf - test correct index is returned', () => {
|
|
97
|
+
const mgr = DesignCore.Scene.entities;
|
|
98
|
+
// Add two lines with the same data
|
|
99
|
+
const l1 = new Line({ points: [new Point(0, 0), new Point(10, 0)] });
|
|
100
|
+
const l2 = new Line({ points: [new Point(0, 0), new Point(10, 0)] });
|
|
101
|
+
mgr.add(l1);
|
|
102
|
+
mgr.add(l2);
|
|
103
|
+
expect(mgr.count()).toBe(2);
|
|
104
|
+
expect(mgr.indexOf(l1)).toBe(0);
|
|
105
|
+
expect(mgr.indexOf(l2)).toBe(1);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test('find returns indices matching type and property', () => {
|
|
109
|
+
const mgr = DesignCore.Scene.entities;
|
|
110
|
+
const l1 = new Line({ points: [new Point(0, 0), new Point(1, 0)], lineWidth: 5 });
|
|
111
|
+
const l2 = new Line({ points: [new Point(0, 1), new Point(1, 1)], lineWidth: 2 });
|
|
112
|
+
mgr.add(l1);
|
|
113
|
+
mgr.add(l2);
|
|
114
|
+
|
|
115
|
+
const found = mgr.find('Line', 'lineWidth', 5);
|
|
116
|
+
expect(found).toEqual([0]);
|
|
117
|
+
|
|
118
|
+
const anyFound = mgr.find('ANY', 'lineWidth', 2);
|
|
119
|
+
expect(anyFound).toEqual([1]);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test('findClosest returns index of nearest selectable entity', () => {
|
|
123
|
+
const mgr = DesignCore.Scene.entities;
|
|
124
|
+
// two horizontal lines at y=0 and y=10
|
|
125
|
+
const l1 = new Line({ points: [new Point(0, 0), new Point(100, 0)] });
|
|
126
|
+
const l2 = new Line({ points: [new Point(0, 10), new Point(100, 10)] });
|
|
127
|
+
mgr.add(l1);
|
|
128
|
+
mgr.add(l2);
|
|
129
|
+
|
|
130
|
+
// point closer to y=10 line
|
|
131
|
+
const p = new Point(50, 9.9);
|
|
132
|
+
const idx = mgr.findClosest(p);
|
|
133
|
+
expect(idx).toBe(1);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test('update applies setProperty for existing keys only', () => {
|
|
137
|
+
const mgr = DesignCore.Scene.entities;
|
|
138
|
+
const l = new Line({ points: [new Point(0, 0), new Point(1, 1)] });
|
|
139
|
+
mgr.add(l);
|
|
140
|
+
|
|
141
|
+
const newP1 = new Point(2, 2);
|
|
142
|
+
const newP2 = new Point(3, 3);
|
|
143
|
+
mgr.update(0, { points: [newP1, newP2], nonExistent: 123 });
|
|
144
|
+
|
|
145
|
+
expect(mgr.get(0).points[0].x).toBe(2);
|
|
146
|
+
expect(mgr.get(0).points[0].y).toBe(2);
|
|
147
|
+
expect(mgr.get(0).points[1].x).toBe(3);
|
|
148
|
+
expect(mgr.get(0).points[1].y).toBe(3);
|
|
149
|
+
// nonExistent should be ignored
|
|
150
|
+
expect(mgr.get(0).nonExistent).toBeUndefined();
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test('count and clear reflect entity storage size', () => {
|
|
154
|
+
const mgr = DesignCore.Scene.entities;
|
|
155
|
+
mgr.add(new Line({ points: [new Point(0, 0), new Point(1, 0)] }));
|
|
156
|
+
mgr.add(new Line({ points: [new Point(0, 1), new Point(1, 1)] }));
|
|
157
|
+
expect(mgr.count()).toBe(2);
|
|
158
|
+
mgr.clear();
|
|
159
|
+
expect(mgr.count()).toBe(0);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
|