@design-core/core 52.0.0 → 52.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/tables/dimStyleManager.js +2 -0
- package/core/tables/styleManagerBase.js +17 -3
- package/core/tables/tableManagerBase.js +24 -2
- package/package.json +1 -1
- package/test/dimensions/diametricDimension.test.js +1 -0
- package/test/dimensions/radialDimension.test.js +1 -0
- package/test/integration/exportIntegration.test.js +1 -0
- package/test/integration/userInputIntegration.test.js +1 -0
- package/test/tables/dimStyleManager.test.js +90 -0
- package/test/tables/tableManagerBase.test.js +167 -0
- package/test/tools/purge.test.js +3 -1
|
@@ -23,12 +23,17 @@ export class StyleManagerBase extends TableManagerBase {
|
|
|
23
23
|
* @param {boolean} showWarning
|
|
24
24
|
*/
|
|
25
25
|
deleteStyle(itemIndex, showWarning = true) {
|
|
26
|
-
//
|
|
27
|
-
const deletedItem = this.deleteItem(itemIndex, showWarning);
|
|
26
|
+
// deleteItem returns the spliced array, or undefined when nothing was deleted
|
|
27
|
+
const deletedItem = this.deleteItem(itemIndex, showWarning)?.[0];
|
|
28
28
|
|
|
29
29
|
if (deletedItem) {
|
|
30
30
|
// delete all item using the selected style
|
|
31
31
|
this.deleteStyleFromScene(deletedItem.name);
|
|
32
|
+
|
|
33
|
+
// the current style no longer exists, fall back to the first available style
|
|
34
|
+
if (this.currentstyle?.toUpperCase() === deletedItem.name.toUpperCase()) {
|
|
35
|
+
this.currentstyle = this.items[0]?.name;
|
|
36
|
+
}
|
|
32
37
|
}
|
|
33
38
|
}
|
|
34
39
|
|
|
@@ -37,10 +42,19 @@ export class StyleManagerBase extends TableManagerBase {
|
|
|
37
42
|
* @param {string} style
|
|
38
43
|
*/
|
|
39
44
|
deleteStyleFromScene(style) {
|
|
45
|
+
if (typeof style !== 'string') {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const target = style.toUpperCase();
|
|
40
50
|
const selectionSet = [];
|
|
41
51
|
|
|
42
52
|
for (let i = 0; i < DesignCore.Scene.entities.count(); i++) {
|
|
43
|
-
|
|
53
|
+
const entity = DesignCore.Scene.entities.get(i);
|
|
54
|
+
// entities without the property (e.g. a line has no dimensionStyle) are not dependent
|
|
55
|
+
const value = entity.getProperty?.(this.itemProperty) ?? entity[this.itemProperty];
|
|
56
|
+
|
|
57
|
+
if (typeof value === 'string' && value.toUpperCase() === target) {
|
|
44
58
|
selectionSet.push(i);
|
|
45
59
|
}
|
|
46
60
|
}
|
|
@@ -307,9 +307,24 @@ export class TableManagerBase {
|
|
|
307
307
|
* @param {string} newItemName
|
|
308
308
|
*/
|
|
309
309
|
updateSceneItem(oldItemName, newItemName) {
|
|
310
|
+
const target = typeof oldItemName === 'string' ? oldItemName.toUpperCase() : undefined;
|
|
311
|
+
if (target === undefined) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
310
315
|
for (let i = 0; i < DesignCore.Scene.entities.count(); i++) {
|
|
311
|
-
|
|
312
|
-
|
|
316
|
+
const entity = DesignCore.Scene.entities.get(i);
|
|
317
|
+
const isProperty = entity.properties?.has(this.itemProperty) ?? false;
|
|
318
|
+
const value = isProperty ? entity.getProperty(this.itemProperty) : entity[this.itemProperty];
|
|
319
|
+
|
|
320
|
+
if (typeof value !== 'string' || value.toUpperCase() !== target) {
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (isProperty) {
|
|
325
|
+
entity.setProperty(this.itemProperty, newItemName);
|
|
326
|
+
} else {
|
|
327
|
+
entity[this.itemProperty] = newItemName;
|
|
313
328
|
}
|
|
314
329
|
}
|
|
315
330
|
}
|
|
@@ -344,7 +359,14 @@ export class TableManagerBase {
|
|
|
344
359
|
/** Purge unused items */
|
|
345
360
|
purge() {
|
|
346
361
|
const itemsToPurge = [];
|
|
362
|
+
// only style managers have a current style
|
|
363
|
+
const currentStyle = this.getCstyle?.()?.toUpperCase();
|
|
364
|
+
|
|
347
365
|
this.items.forEach((item, index) => {
|
|
366
|
+
if (item.name.toUpperCase() === currentStyle) {
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
|
|
348
370
|
const searchTerm = this.itemProperty === 'block' ? item : item.name;
|
|
349
371
|
const items = DesignCore.Scene.entities.find('ANY', this.itemProperty, searchTerm);
|
|
350
372
|
if (items.length === 0) {
|
package/package.json
CHANGED
|
@@ -95,6 +95,7 @@ async function executeToolWithInputs(tool, selectionIndices, inputs) {
|
|
|
95
95
|
|
|
96
96
|
beforeAll(async () => {
|
|
97
97
|
core = new Core();
|
|
98
|
+
core.dimStyleManager.setCstyle('STANDARD');
|
|
98
99
|
|
|
99
100
|
// =====================================================================
|
|
100
101
|
// Phase 1: Showcase entities (idx 0–7)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Core } from '../../core/core/core.js';
|
|
2
|
+
import { Point } from '../../core/entities/point.js';
|
|
3
|
+
|
|
4
|
+
const core = new Core();
|
|
5
|
+
const dimStyleManager = core.dimStyleManager;
|
|
6
|
+
|
|
7
|
+
const dimensionData = (dimensionStyle) => ({
|
|
8
|
+
points: [new Point(), new Point(10, 0), new Point(5, 5)],
|
|
9
|
+
dimensionStyle: dimensionStyle,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
while (core.scene.entities.count() > 0) {
|
|
14
|
+
core.scene.entities.remove(0);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('Test DimStyleManager.deleteStyle removes only dimensions using the style', () => {
|
|
19
|
+
dimStyleManager.addItem({ name: 'CUSTOM' });
|
|
20
|
+
|
|
21
|
+
core.scene.addEntity('Line', { points: [new Point(), new Point(10, 10)] });
|
|
22
|
+
core.scene.addEntity('Circle', { points: [new Point()], radius: 5 });
|
|
23
|
+
core.scene.addEntity('RotatedDimension', dimensionData('CUSTOM'));
|
|
24
|
+
core.scene.addEntity('RotatedDimension', dimensionData('STANDARD'));
|
|
25
|
+
expect(core.scene.entities.count()).toBe(4);
|
|
26
|
+
|
|
27
|
+
dimStyleManager.deleteStyle(dimStyleManager.getItemIndex('CUSTOM'));
|
|
28
|
+
|
|
29
|
+
expect(dimStyleManager.itemExists('CUSTOM')).toBe(false);
|
|
30
|
+
const types = core.scene.entities.get(0).type + ',' + core.scene.entities.get(1).type + ',' + core.scene.entities.get(2).type;
|
|
31
|
+
expect(core.scene.entities.count()).toBe(3);
|
|
32
|
+
expect(types).toBe('Line,Circle,RotatedDimension');
|
|
33
|
+
expect(core.scene.entities.get(2).getProperty('dimensionStyle')).toBe('STANDARD');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test('Test DimStyleManager.deleteStyle matches style names case-insensitively', () => {
|
|
37
|
+
dimStyleManager.addItem({ name: 'MixedCase' });
|
|
38
|
+
core.scene.addEntity('RotatedDimension', dimensionData('MIXEDCASE'));
|
|
39
|
+
|
|
40
|
+
dimStyleManager.deleteStyle(dimStyleManager.getItemIndex('MixedCase'));
|
|
41
|
+
|
|
42
|
+
expect(core.scene.entities.count()).toBe(0);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('Test DimStyleManager.deleteStyle resets the current style when it is deleted', () => {
|
|
46
|
+
dimStyleManager.addItem({ name: 'CURRENT' });
|
|
47
|
+
dimStyleManager.setCstyle('CURRENT');
|
|
48
|
+
|
|
49
|
+
dimStyleManager.deleteStyle(dimStyleManager.getItemIndex('CURRENT'));
|
|
50
|
+
|
|
51
|
+
expect(dimStyleManager.getCstyle()).toBe(dimStyleManager.getItems()[0].name);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('Test DimStyleManager.deleteStyle keeps indelible styles and their dimensions', () => {
|
|
55
|
+
core.scene.addEntity('RotatedDimension', dimensionData('STANDARD'));
|
|
56
|
+
|
|
57
|
+
dimStyleManager.deleteStyle(dimStyleManager.getItemIndex('STANDARD'), false);
|
|
58
|
+
|
|
59
|
+
expect(dimStyleManager.itemExists('STANDARD')).toBe(true);
|
|
60
|
+
expect(core.scene.entities.count()).toBe(1);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('Test DimStyleManager.renameStyle updates dimensions through the property API', () => {
|
|
64
|
+
dimStyleManager.addItem({ name: 'OLDNAME' });
|
|
65
|
+
core.scene.addEntity('Line', { points: [new Point(), new Point(10, 10)] });
|
|
66
|
+
core.scene.addEntity('RotatedDimension', dimensionData('OLDNAME'));
|
|
67
|
+
core.scene.addEntity('RotatedDimension', dimensionData('STANDARD'));
|
|
68
|
+
|
|
69
|
+
dimStyleManager.renameStyle(dimStyleManager.getItemIndex('OLDNAME'), 'NEWNAME');
|
|
70
|
+
|
|
71
|
+
const dimension = core.scene.entities.get(1);
|
|
72
|
+
expect(dimension.getProperty('dimensionStyle')).toBe('NEWNAME');
|
|
73
|
+
expect(Object.hasOwn(dimension, 'dimensionStyle')).toBe(false);
|
|
74
|
+
expect(core.scene.entities.get(2).getProperty('dimensionStyle')).toBe('STANDARD');
|
|
75
|
+
expect(dimension.getDimensionStyle()?.name).toBe('NEWNAME');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test('Test DimStyleManager defaults to the ISO-25 current style', () => {
|
|
79
|
+
expect(new Core().dimStyleManager.getCstyle()).toBe('ISO-25');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('Test DimStyleManager.purge keeps the current style', () => {
|
|
83
|
+
dimStyleManager.setCstyle('ISO-25');
|
|
84
|
+
|
|
85
|
+
dimStyleManager.purge();
|
|
86
|
+
|
|
87
|
+
expect(dimStyleManager.itemExists('ISO-25')).toBe(true);
|
|
88
|
+
expect(dimStyleManager.getCstyle()).toBe('ISO-25');
|
|
89
|
+
expect(dimStyleManager.itemExists('ANNOTATIVE')).toBe(false);
|
|
90
|
+
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Core } from '../../core/core/core.js';
|
|
2
2
|
import { TableManagerBase } from '../../core/tables/tableManagerBase.js';
|
|
3
|
+
import { DesignCore } from '../../core/designCore.js';
|
|
4
|
+
import { Point } from '../../core/entities/point.js';
|
|
3
5
|
|
|
4
6
|
// initialise core
|
|
5
7
|
new Core();
|
|
@@ -192,3 +194,168 @@ test('Test tableManagerBase.updateItem', () => {
|
|
|
192
194
|
tableManagerBase.updateItem(0, 'textHeight', 20);
|
|
193
195
|
expect(tableManagerBase.getItemByIndex(0).textHeight).toBe(20);
|
|
194
196
|
});
|
|
197
|
+
|
|
198
|
+
describe('tableManagerBase deleteItem return contract', () => {
|
|
199
|
+
beforeEach(() => {
|
|
200
|
+
tableManagerBase.items = [{ name: 'itemOne' }, { name: 'Standard' }];
|
|
201
|
+
tableManagerBase.indelibleItems = ['Standard'];
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test('returns the spliced array containing the deleted item', () => {
|
|
205
|
+
const deleted = tableManagerBase.deleteItem(0);
|
|
206
|
+
|
|
207
|
+
expect(Array.isArray(deleted)).toBe(true);
|
|
208
|
+
expect(deleted).toEqual([{ name: 'itemOne' }]);
|
|
209
|
+
expect(tableManagerBase.itemExists('itemOne')).toBe(false);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
test('returns undefined for an invalid index', () => {
|
|
213
|
+
expect(tableManagerBase.deleteItem(10)).toBeUndefined();
|
|
214
|
+
expect(tableManagerBase.itemCount()).toBe(2);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
test('returns undefined and keeps indelible items, ignoring case', () => {
|
|
218
|
+
tableManagerBase.indelibleItems = ['STANDARD'];
|
|
219
|
+
|
|
220
|
+
expect(tableManagerBase.deleteItem(1, false)).toBeUndefined();
|
|
221
|
+
expect(tableManagerBase.itemExists('Standard')).toBe(true);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
test('invalidates the name lookup cache', () => {
|
|
225
|
+
expect(tableManagerBase.getItemByName('itemOne')).toBeDefined();
|
|
226
|
+
|
|
227
|
+
tableManagerBase.deleteItem(0);
|
|
228
|
+
|
|
229
|
+
expect(tableManagerBase.getItemByName('itemOne')).toBeUndefined();
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
describe('tableManagerBase lookups', () => {
|
|
234
|
+
beforeEach(() => {
|
|
235
|
+
tableManagerBase.items = [{ name: 'itemOne' }, { name: 'itemTwo' }];
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
test('getItemIndex is case-insensitive and returns -1 when missing', () => {
|
|
239
|
+
expect(tableManagerBase.getItemIndex('ITEMTWO')).toBe(1);
|
|
240
|
+
expect(tableManagerBase.getItemIndex('missing')).toBe(-1);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
test('itemExists and getItemByName are case-insensitive', () => {
|
|
244
|
+
expect(tableManagerBase.itemExists('ITEMONE')).toBe(true);
|
|
245
|
+
expect(tableManagerBase.getItemByName('itemone').name).toBe('itemOne');
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
test('getItemByName cache is refreshed after addItem and rename', () => {
|
|
249
|
+
expect(tableManagerBase.getItemByName('itemOne')).toBeDefined();
|
|
250
|
+
|
|
251
|
+
tableManagerBase.addItem({ name: 'itemThree' });
|
|
252
|
+
expect(tableManagerBase.getItemByName('itemThree')).toBeDefined();
|
|
253
|
+
|
|
254
|
+
tableManagerBase.renameItem(0, 'itemRenamed');
|
|
255
|
+
expect(tableManagerBase.getItemByName('itemOne')).toBeUndefined();
|
|
256
|
+
expect(tableManagerBase.getItemByName('itemRenamed')).toBeDefined();
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
test('clearItems removes all items', () => {
|
|
260
|
+
tableManagerBase.clearItems();
|
|
261
|
+
|
|
262
|
+
expect(tableManagerBase.itemCount()).toBe(0);
|
|
263
|
+
expect(tableManagerBase.getItemByName('itemOne')).toBeUndefined();
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
test('addItem returns the existing item when not overwriting', () => {
|
|
267
|
+
const existing = tableManagerBase.getItemByName('itemOne');
|
|
268
|
+
|
|
269
|
+
expect(tableManagerBase.addItem({ name: 'ITEMONE' })).toBe(existing);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
describe('tableManagerBase renameItem', () => {
|
|
274
|
+
beforeEach(() => {
|
|
275
|
+
tableManagerBase.items = [{ name: 'itemOne' }, { name: 'itemTwo' }, { name: 'Standard' }];
|
|
276
|
+
tableManagerBase.indelibleItems = ['Standard'];
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
test('returns the new name', () => {
|
|
280
|
+
expect(tableManagerBase.renameItem(0, 'renamed')).toBe('renamed');
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
test('returns undefined when the name is unchanged apart from case', () => {
|
|
284
|
+
expect(tableManagerBase.renameItem(0, 'ITEMONE')).toBeUndefined();
|
|
285
|
+
expect(tableManagerBase.getItemByIndex(0).name).toBe('itemOne');
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
test('cannot rename an indelible item', () => {
|
|
289
|
+
expect(tableManagerBase.renameItem(2, 'other')).toBeUndefined();
|
|
290
|
+
expect(tableManagerBase.getItemByIndex(2).name).toBe('Standard');
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
test('makes a clashing name unique', () => {
|
|
294
|
+
expect(tableManagerBase.renameItem(0, 'itemTwo')).toBe('itemTwo_1');
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
describe('tableManagerBase scene references', () => {
|
|
299
|
+
const originalProperty = tableManagerBase.itemProperty;
|
|
300
|
+
|
|
301
|
+
const addLine = (layer) => {
|
|
302
|
+
const line = DesignCore.Scene.addEntity('Line', { points: [new Point(), new Point(10, 10)], layer: layer });
|
|
303
|
+
return line;
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
beforeEach(() => {
|
|
307
|
+
tableManagerBase.itemProperty = 'layer';
|
|
308
|
+
tableManagerBase.items = [{ name: 'itemOne' }, { name: 'itemTwo' }];
|
|
309
|
+
tableManagerBase.indelibleItems = [];
|
|
310
|
+
while (DesignCore.Scene.entities.count() > 0) {
|
|
311
|
+
DesignCore.Scene.entities.remove(0);
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
afterAll(() => {
|
|
316
|
+
tableManagerBase.itemProperty = originalProperty;
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
test('updateSceneItem renames references through the property API', () => {
|
|
320
|
+
addLine('itemOne');
|
|
321
|
+
addLine('itemTwo');
|
|
322
|
+
|
|
323
|
+
tableManagerBase.updateSceneItem('itemOne', 'renamed');
|
|
324
|
+
|
|
325
|
+
expect(DesignCore.Scene.entities.get(0).getProperty('layer')).toBe('renamed');
|
|
326
|
+
expect(DesignCore.Scene.entities.get(1).getProperty('layer')).toBe('itemTwo');
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
test('updateSceneItem matches names case-insensitively', () => {
|
|
330
|
+
addLine('ITEMONE');
|
|
331
|
+
|
|
332
|
+
tableManagerBase.updateSceneItem('itemOne', 'renamed');
|
|
333
|
+
|
|
334
|
+
expect(DesignCore.Scene.entities.get(0).getProperty('layer')).toBe('renamed');
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
test('updateSceneItem ignores an undefined name', () => {
|
|
338
|
+
addLine('itemOne');
|
|
339
|
+
|
|
340
|
+
tableManagerBase.updateSceneItem(undefined, 'renamed');
|
|
341
|
+
|
|
342
|
+
expect(DesignCore.Scene.entities.get(0).getProperty('layer')).toBe('itemOne');
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
test('renameItem updates dependent entities', () => {
|
|
346
|
+
addLine('itemOne');
|
|
347
|
+
|
|
348
|
+
tableManagerBase.renameItem(0, 'renamed');
|
|
349
|
+
|
|
350
|
+
expect(DesignCore.Scene.entities.get(0).getProperty('layer')).toBe('renamed');
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
test('purge removes only unused items', () => {
|
|
354
|
+
addLine('itemOne');
|
|
355
|
+
|
|
356
|
+
tableManagerBase.purge();
|
|
357
|
+
|
|
358
|
+
expect(tableManagerBase.itemExists('itemOne')).toBe(true);
|
|
359
|
+
expect(tableManagerBase.itemExists('itemTwo')).toBe(false);
|
|
360
|
+
});
|
|
361
|
+
});
|
package/test/tools/purge.test.js
CHANGED
|
@@ -46,7 +46,9 @@ test('Test purge.action', () => {
|
|
|
46
46
|
expect(dimStyleManager.itemCount()).toBe(4);
|
|
47
47
|
purge.option = 'Dimstyles';
|
|
48
48
|
purge.action();
|
|
49
|
-
|
|
49
|
+
// STANDARD is indelible and ISO-25 is the current style
|
|
50
|
+
expect(dimStyleManager.itemCount()).toBe(2);
|
|
51
|
+
expect(dimStyleManager.itemExists('ISO-25')).toBe(true);
|
|
50
52
|
|
|
51
53
|
expect(layerManager.itemCount()).toBe(4);
|
|
52
54
|
purge.option = 'Layers';
|