@design-core/core 0.0.5 → 0.0.7
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 +4 -0
- package/TODO.md +49 -6
- package/core/core/core.js +0 -3
- package/core/dimensions/alignedDimension.js +5 -4
- package/core/dimensions/angularDimension.js +6 -5
- package/core/dimensions/baseCircularDimension.js +3 -2
- package/core/dimensions/baseDimension.js +59 -93
- package/core/dimensions/baseLinearDimension.js +6 -5
- package/core/dimensions/diametricDimension.js +4 -3
- package/core/dimensions/dimension.js +21 -14
- package/core/dimensions/radialDimension.js +4 -3
- package/core/dimensions/rotatedDimension.js +12 -11
- package/core/entities/arc.js +112 -145
- package/core/entities/arctext.js +212 -174
- package/core/entities/basePolyline.js +33 -284
- package/core/entities/circle.js +77 -99
- package/core/entities/entity.js +114 -93
- package/core/entities/hatch.js +322 -249
- package/core/entities/insert.js +66 -81
- package/core/entities/line.js +21 -142
- package/core/entities/lwpolyline.js +16 -11
- package/core/entities/polyline.js +4 -4
- package/core/entities/rectangle.js +3 -1
- package/core/entities/solid.js +6 -15
- package/core/entities/text.js +188 -199
- package/core/lib/auxiliary/rubberBand.js +32 -0
- package/core/lib/auxiliary/selectionWindow.js +63 -0
- package/core/lib/auxiliary/snapPoint.js +113 -0
- package/core/lib/auxiliary/trackingLine.js +76 -0
- package/core/lib/canvas.js +228 -166
- package/core/lib/clipboard.js +7 -1
- package/core/lib/colour.js +16 -0
- package/core/lib/commandLine.js +1 -6
- package/core/lib/commandManager.js +18 -8
- package/core/lib/constants.js +28 -0
- package/core/lib/dxf/dxf.js +4 -3
- package/core/lib/entityManager.js +18 -11
- package/core/lib/inputManager.js +36 -13
- package/core/lib/intersect.js +25 -0
- package/core/lib/patterns.js +8 -1
- package/core/lib/plotOptions.js +67 -0
- package/core/lib/polylineUtils.js +75 -0
- package/core/lib/renderers/cairoRenderer.js +371 -0
- package/core/lib/renderers/canvasRenderer.js +315 -0
- package/core/lib/renderers/pdfRenderer.js +366 -0
- package/core/lib/renderers/rendererBase.js +284 -0
- package/core/lib/renderers/svgRenderer.js +343 -0
- package/core/lib/scene.js +27 -5
- package/core/lib/selectionManager.js +2 -2
- package/core/lib/settings.js +4 -2
- package/core/lib/snapping.js +4 -191
- package/core/lib/stateManager.js +30 -1
- package/core/lib/utils.js +21 -2
- package/core/properties/entityProperties.js +104 -0
- package/core/properties/property.js +106 -2
- package/core/properties/propertyManager.js +29 -13
- package/core/tables/block.js +4 -37
- package/core/tables/endblk.js +1 -1
- package/core/tables/layer.js +8 -0
- package/core/tables/styleManagerBase.js +3 -2
- package/core/tables/tableManagerBase.js +8 -3
- package/core/tools/chamfer.js +111 -137
- package/core/tools/chamferFilletBase.js +135 -34
- package/core/tools/copy.js +3 -3
- package/core/tools/explode.js +2 -2
- package/core/tools/extend.js +132 -19
- package/core/tools/fillet.js +86 -183
- package/core/tools/matchProp.js +2 -11
- package/core/tools/mirror.js +7 -6
- package/core/tools/move.js +3 -3
- package/core/tools/offset.js +3 -5
- package/core/tools/pasteclip.js +1 -1
- package/core/tools/rotate.js +6 -3
- package/core/tools/scale.js +1 -1
- package/core/tools/trim.js +265 -23
- package/core/tools/zoom.js +1 -1
- package/jest.config.js +6 -0
- package/package.json +5 -3
- package/test/dimensions/alignedDimension.test.js +14 -7
- package/test/dimensions/angularDimension.test.js +6 -6
- package/test/dimensions/baseDimension.test.js +69 -8
- package/test/dimensions/baseLinearDimension.test.js +62 -0
- package/test/dimensions/diametricDimension.test.js +6 -6
- package/test/dimensions/radialDimension.test.js +6 -6
- package/test/dimensions/rotatedDimension.test.js +14 -7
- package/test/entities/arc.test.js +80 -83
- package/test/entities/arctext.test.js +180 -53
- package/test/entities/basePolyline.test.js +129 -2
- package/test/entities/circle.test.js +57 -85
- package/test/entities/entity.test.js +42 -8
- package/test/entities/hatch.test.js +543 -70
- package/test/entities/insert.test.js +96 -1
- package/test/entities/line.test.js +15 -41
- package/test/entities/lwpolyline.test.js +104 -0
- package/test/entities/polyline.test.js +11 -0
- package/test/entities/rectangle.test.js +11 -0
- package/test/entities/solid.test.js +1 -1
- package/test/entities/text.test.js +294 -69
- package/test/integration/exportIntegration.reference.dxf +9 -9
- package/test/integration/exportIntegration.test.js +2 -2
- package/test/integration/intersectionIntegration.test.js +4 -5
- package/test/integration/pdfRendererIntegration.reference.pdf +17709 -0
- package/test/integration/pdfRendererIntegration.test.js +61 -0
- package/test/integration/svgRendererIntegration.reference.svg +3343 -0
- package/test/integration/svgRendererIntegration.test.js +61 -0
- package/test/integration/userInputIntegration.reference.dxf +1165 -105
- package/test/integration/userInputIntegration.test.js +239 -132
- package/test/lib/canvas.test.js +742 -123
- package/test/lib/constants.test.js +27 -0
- package/test/lib/entityManager.test.js +4 -4
- package/test/lib/inputManager.test.js +80 -19
- package/test/lib/intersect.test.js +83 -0
- package/test/lib/plotOptions.test.js +179 -0
- package/test/lib/rubberBand.test.js +84 -0
- package/test/lib/settings.test.js +5 -6
- package/test/lib/snapping.test.js +71 -129
- package/test/lib/stateManager.test.js +7 -7
- package/test/lib/utils.test.js +36 -2
- package/test/properties/entityProperties.test.js +132 -0
- package/test/properties/property.test.js +53 -0
- package/test/properties/propertyManager.test.js +3 -3
- package/test/renderers/canvasRenderer.test.js +317 -0
- package/test/renderers/pdfRenderer.test.js +271 -0
- package/test/renderers/rendererBase.test.js +213 -0
- package/test/renderers/svgRenderer.test.js +326 -0
- package/test/tables/block.test.js +31 -1
- package/test/tables/endblk.test.js +2 -2
- package/test/tables/layer.test.js +30 -0
- package/test/test-helpers/hatchGridRenderer.js +180 -0
- package/test/test-helpers/test-helpers.js +152 -0
- package/test/tools/chamfer.test.js +227 -5
- package/test/tools/chamferFilletBase.test.js +98 -9
- package/test/tools/copy.test.js +2 -2
- package/test/tools/explode.test.js +3 -3
- package/test/tools/extend.test.js +331 -0
- package/test/tools/fillet.test.js +296 -0
- package/test/tools/matchProp.test.js +5 -5
- package/test/tools/mirror.test.js +13 -13
- package/test/tools/offset.test.js +170 -3
- package/test/tools/pasteclip.test.js +5 -5
- package/test/tools/rotate.test.js +32 -2
- package/test/tools/scale.test.js +5 -5
- package/test/tools/trim.test.js +526 -0
- package/test/tools/zoom.test.js +7 -7
- package/core/lib/selectionWindow.js +0 -83
|
@@ -2,6 +2,8 @@ import { Core } from '../../core/core/core.js';
|
|
|
2
2
|
import { Insert } from '../../core/entities/insert.js';
|
|
3
3
|
import { Point } from '../../core/entities/point.js';
|
|
4
4
|
import { Line } from '../../core/entities/line.js';
|
|
5
|
+
import { Utils } from '../../core/lib/utils.js';
|
|
6
|
+
import { jest } from '@jest/globals';
|
|
5
7
|
|
|
6
8
|
import { File } from '../test-helpers/test-helpers.js';
|
|
7
9
|
|
|
@@ -85,7 +87,7 @@ AcDbBlockReference
|
|
|
85
87
|
expect(file.contents).toEqual(dxfString);
|
|
86
88
|
|
|
87
89
|
// create new entity from entity data to ensure all props are loaded
|
|
88
|
-
const newInsert = new Insert(insert);
|
|
90
|
+
const newInsert = new Insert({ handle: insert.getProperty('handle'), points: insert.points });
|
|
89
91
|
file = new File();
|
|
90
92
|
newInsert.dxf(file);
|
|
91
93
|
expect(file.contents).toEqual(dxfString);
|
|
@@ -98,3 +100,96 @@ test('Insert.snaps returns a node snap at points[0]', () => {
|
|
|
98
100
|
expect(nodeSnaps[0].snapPoint.x).toBe(5);
|
|
99
101
|
expect(nodeSnaps[0].snapPoint.y).toBe(10);
|
|
100
102
|
});
|
|
103
|
+
|
|
104
|
+
describe('Test Insert.draw', () => {
|
|
105
|
+
/**
|
|
106
|
+
* Create a minimal mock renderer with a jest spy for applyTransform.
|
|
107
|
+
* @return {Object} mock renderer
|
|
108
|
+
*/
|
|
109
|
+
function makeMockCtx() {
|
|
110
|
+
return {
|
|
111
|
+
applyTransform: jest.fn(),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
test('draw() returns the block items array', () => {
|
|
116
|
+
const ins = new Insert({ points: [new Point(0, 0)] });
|
|
117
|
+
const line = new Line({ points: [new Point(0, 0), new Point(1, 1)] });
|
|
118
|
+
ins.block.addItem(line);
|
|
119
|
+
|
|
120
|
+
const result = ins.draw(makeMockCtx());
|
|
121
|
+
expect(result).toBe(ins.block.items);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('draw() returns empty array when block has no items', () => {
|
|
125
|
+
const ins = new Insert({ points: [new Point(0, 0)] });
|
|
126
|
+
const result = ins.draw(makeMockCtx());
|
|
127
|
+
expect(result).toEqual([]);
|
|
128
|
+
expect(result).toBe(ins.block.items);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test('draw() calls renderer.applyTransform with the insert point coordinates', () => {
|
|
132
|
+
const ins = new Insert({ points: [new Point(50, 75)] });
|
|
133
|
+
const ctx = makeMockCtx();
|
|
134
|
+
ins.draw(ctx);
|
|
135
|
+
expect(ctx.applyTransform).toHaveBeenCalledWith(expect.objectContaining({ x: 50, y: 75 }));
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test('draw() calls renderer.applyTransform with rotation converted to radians', () => {
|
|
139
|
+
const ins = new Insert({ points: [new Point(0, 0)], rotation: 90 });
|
|
140
|
+
const ctx = makeMockCtx();
|
|
141
|
+
ins.draw(ctx);
|
|
142
|
+
expect(ctx.applyTransform).toHaveBeenCalledWith(expect.objectContaining({ rotation: Utils.degrees2radians(90) }));
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('draw() calls renderer.applyTransform with rotation 0 when rotation is 0', () => {
|
|
146
|
+
const ins = new Insert({ points: [new Point(0, 0)] });
|
|
147
|
+
const ctx = makeMockCtx();
|
|
148
|
+
ins.draw(ctx);
|
|
149
|
+
expect(ctx.applyTransform).toHaveBeenCalledWith(expect.objectContaining({ rotation: 0 }));
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
test('draw() calls renderer.applyTransform exactly once', () => {
|
|
153
|
+
const ins = new Insert({ points: [new Point(10, 20)], rotation: 45 });
|
|
154
|
+
const ctx = makeMockCtx();
|
|
155
|
+
ins.draw(ctx);
|
|
156
|
+
expect(ctx.applyTransform).toHaveBeenCalledTimes(1);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test('draw() returns same items reference regardless of scale', () => {
|
|
160
|
+
const ins = new Insert({ points: [new Point(0, 0)] });
|
|
161
|
+
const line = new Line({ points: [new Point(0, 0), new Point(1, 1)] });
|
|
162
|
+
ins.block.addItem(line);
|
|
163
|
+
expect(ins.draw(makeMockCtx())).toBe(ins.block.items);
|
|
164
|
+
expect(ins.draw(makeMockCtx())).toBe(ins.block.items);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
describe('Insert.fromDxf', () => {
|
|
169
|
+
test('maps group code 2 to blockName', () => {
|
|
170
|
+
const data = Insert.fromDxf({ points: [new Point(0, 0)], 2: 'MYBLOCK' });
|
|
171
|
+
expect(data.blockName).toBe('MYBLOCK');
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test('maps group code 50 to rotation', () => {
|
|
175
|
+
const data = Insert.fromDxf({ points: [new Point(0, 0)], 50: 45 });
|
|
176
|
+
expect(data.rotation).toBe(45);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
test('preserves other properties unchanged', () => {
|
|
180
|
+
const data = Insert.fromDxf({ points: [new Point(1, 2)], layer: 'TEST', 2: 'BLK' });
|
|
181
|
+
expect(data.layer).toBe('TEST');
|
|
182
|
+
expect(data.points[0].x).toBe(1);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test('result with rotation is equivalent to direct construction', () => {
|
|
186
|
+
const pt = new Point(5, 10);
|
|
187
|
+
const i1 = new Insert(Insert.fromDxf({ points: [pt], 50: 90 }));
|
|
188
|
+
const i2 = new Insert({ points: [pt], rotation: 90 });
|
|
189
|
+
expect(i1.getProperty('rotation')).toBeCloseTo(i2.getProperty('rotation'));
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test('unimplemented codes do not throw', () => {
|
|
193
|
+
expect(() => Insert.fromDxf({ points: [new Point()], 41: 2, 42: 2, 43: 2, 44: 5, 45: 5, 70: 2, 71: 3 })).not.toThrow();
|
|
194
|
+
});
|
|
195
|
+
});
|
|
@@ -2,7 +2,6 @@ import { Line } from '../../core/entities/line.js';
|
|
|
2
2
|
import { Point } from '../../core/entities/point.js';
|
|
3
3
|
import { Core } from '../../core/core/core.js';
|
|
4
4
|
import { DesignCore } from '../../core/designCore.js';
|
|
5
|
-
import { AddState, RemoveState } from '../../core/lib/stateManager.js';
|
|
6
5
|
import { File, withMockInput } from '../test-helpers/test-helpers.js';
|
|
7
6
|
|
|
8
7
|
// initialise core
|
|
@@ -110,13 +109,13 @@ ByLayer
|
|
|
110
109
|
31
|
|
111
110
|
0.0
|
|
112
111
|
39
|
|
113
|
-
|
|
112
|
+
1
|
|
114
113
|
`;
|
|
115
114
|
|
|
116
115
|
expect(file.contents).toEqual(dxfString);
|
|
117
116
|
|
|
118
117
|
// create new entity from entity data to ensure all props are loaded
|
|
119
|
-
const newLine = new Line(line);
|
|
118
|
+
const newLine = new Line({ handle: line.getProperty('handle'), points: line.points });
|
|
120
119
|
file = new File();
|
|
121
120
|
newLine.dxf(file);
|
|
122
121
|
expect(file.contents).toEqual(dxfString);
|
|
@@ -135,45 +134,19 @@ test('Test Line.toPolylinePoints', () => {
|
|
|
135
134
|
});
|
|
136
135
|
|
|
137
136
|
|
|
138
|
-
test('Test Line.
|
|
139
|
-
const line = new Line({ points: [new Point(0, 0), new Point(
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const changes = line.trim([i1, i2]);
|
|
149
|
-
|
|
150
|
-
expect(Array.isArray(changes)).toBe(true);
|
|
151
|
-
expect(changes.length).toBeGreaterThanOrEqual(2);
|
|
152
|
-
expect(changes[0]).toBeInstanceOf(AddState);
|
|
153
|
-
expect(changes[1]).toBeInstanceOf(AddState);
|
|
154
|
-
expect(changes[2]).toBeInstanceOf(RemoveState);
|
|
155
|
-
|
|
156
|
-
// Verify trimmed lines have unique handles (not the original)
|
|
157
|
-
expect(changes[0].entity.handle).toBeUndefined();
|
|
158
|
-
expect(changes[1].entity.handle).toBeUndefined();
|
|
137
|
+
test('Test Line.draw calls renderer.drawShape with toPolylinePoints', () => {
|
|
138
|
+
const line = new Line({ points: [new Point(0, 0), new Point(10, 5)] });
|
|
139
|
+
let capturedPoints;
|
|
140
|
+
const mockRenderer = {
|
|
141
|
+
drawShape(points) {
|
|
142
|
+
capturedPoints = points;
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
line.draw(mockRenderer);
|
|
146
|
+
expect(capturedPoints).toEqual(line.toPolylinePoints());
|
|
159
147
|
});
|
|
160
148
|
|
|
161
149
|
|
|
162
|
-
test('Test Line.trim returns empty array when provided with empty intersection list', () => {
|
|
163
|
-
const line = new Line({ points: [new Point(0, 0), new Point(100, 0)] });
|
|
164
|
-
|
|
165
|
-
expect(line.trim([])).toEqual([]);
|
|
166
|
-
expect(line.trim()).toEqual([]);
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
test('Test Line.extend returns empty array when provided with empty intersection list', () => {
|
|
171
|
-
const line = new Line({ points: [new Point(0, 0), new Point(100, 0)] });
|
|
172
|
-
|
|
173
|
-
expect(line.extend([])).toEqual([]);
|
|
174
|
-
expect(line.extend()).toEqual([]);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
150
|
test('Line.execute handles Close option', async () => {
|
|
178
151
|
const pt1 = new Point(0, 0);
|
|
179
152
|
const pt2 = new Point(10, 0);
|
|
@@ -183,11 +156,12 @@ test('Line.execute handles Close option', async () => {
|
|
|
183
156
|
const line = new Line({});
|
|
184
157
|
await line.execute();
|
|
185
158
|
|
|
186
|
-
|
|
159
|
+
// this.points accumulates all confirmed input points (not the closing segment,
|
|
160
|
+
// which is committed as a separate entity)
|
|
161
|
+
expect(line.points.length).toBe(3);
|
|
187
162
|
expect(line.points[0]).toBe(pt1);
|
|
188
163
|
expect(line.points[1]).toBe(pt2);
|
|
189
164
|
expect(line.points[2]).toBe(pt3);
|
|
190
|
-
expect(line.points[3]).toBe(pt1);
|
|
191
165
|
}, { extraMethods: { actionCommand: () => {} } });
|
|
192
166
|
});
|
|
193
167
|
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { jest } from '@jest/globals';
|
|
2
|
+
import { Lwpolyline } from '../../core/entities/lwpolyline.js';
|
|
3
|
+
import { Polyline } from '../../core/entities/polyline.js';
|
|
4
|
+
import { Point } from '../../core/entities/point.js';
|
|
5
|
+
import { Core } from '../../core/core/core.js';
|
|
6
|
+
|
|
7
|
+
// initialise core
|
|
8
|
+
new Core();
|
|
9
|
+
|
|
10
|
+
// ─── constructor returns a Polyline ──────────────────────────────────────────
|
|
11
|
+
|
|
12
|
+
test('Lwpolyline constructor returns a Polyline instance', () => {
|
|
13
|
+
const result = new Lwpolyline({ points: [new Point(0, 0), new Point(10, 0)] });
|
|
14
|
+
expect(result).toBeInstanceOf(Polyline);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('Lwpolyline with no data returns a Polyline instance', () => {
|
|
18
|
+
const result = new Lwpolyline();
|
|
19
|
+
expect(result).toBeInstanceOf(Polyline);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// ─── group code 90 vertex count validation ───────────────────────────────────
|
|
23
|
+
|
|
24
|
+
test('Lwpolyline logs no error when group code 90 matches points.length', () => {
|
|
25
|
+
const spy = jest.spyOn(console, 'log').mockImplementation(() => {});
|
|
26
|
+
new Lwpolyline({ 90: 2, points: [new Point(0, 0), new Point(10, 0)] });
|
|
27
|
+
const errorCalls = spy.mock.calls.filter(([msg]) => msg.startsWith('Error:'));
|
|
28
|
+
expect(errorCalls).toHaveLength(0);
|
|
29
|
+
spy.mockRestore();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('Lwpolyline logs error when group code 90 count does not match points.length', () => {
|
|
33
|
+
const spy = jest.spyOn(console, 'log').mockImplementation(() => {});
|
|
34
|
+
new Lwpolyline({ 90: 3, points: [new Point(0, 0), new Point(10, 0)] });
|
|
35
|
+
const errorCalls = spy.mock.calls.filter(([msg]) => msg.startsWith('Error:'));
|
|
36
|
+
expect(errorCalls).toHaveLength(1);
|
|
37
|
+
expect(errorCalls[0][0]).toMatch(/specifies 3 vertices/);
|
|
38
|
+
expect(errorCalls[0][0]).toMatch(/2 were parsed/);
|
|
39
|
+
spy.mockRestore();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('Lwpolyline logs error when group code 90 present but points is undefined', () => {
|
|
43
|
+
const spy = jest.spyOn(console, 'log').mockImplementation(() => {});
|
|
44
|
+
new Lwpolyline({ 90: 2 });
|
|
45
|
+
const errorCalls = spy.mock.calls.filter(([msg]) => msg.startsWith('Error:'));
|
|
46
|
+
expect(errorCalls).toHaveLength(1);
|
|
47
|
+
expect(errorCalls[0][0]).toMatch(/points array is missing or invalid/);
|
|
48
|
+
spy.mockRestore();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('Lwpolyline logs error when group code 90 present but points is not an array', () => {
|
|
52
|
+
const spy = jest.spyOn(console, 'log').mockImplementation(() => {});
|
|
53
|
+
new Lwpolyline({ 90: 1, points: 'bad' });
|
|
54
|
+
const errorCalls = spy.mock.calls.filter(([msg]) => msg.startsWith('Error:'));
|
|
55
|
+
expect(errorCalls).toHaveLength(1);
|
|
56
|
+
expect(errorCalls[0][0]).toMatch(/points array is missing or invalid/);
|
|
57
|
+
spy.mockRestore();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('Lwpolyline does not throw when group code 90 present but points is undefined', () => {
|
|
61
|
+
expect(() => new Lwpolyline({ 90: 2 })).not.toThrow();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// ─── closed-polyline deduplication ───────────────────────────────────────────
|
|
65
|
+
|
|
66
|
+
test('Lwpolyline removes duplicate closing point and sets closed flag', () => {
|
|
67
|
+
const pts = [
|
|
68
|
+
new Point(0, 0), new Point(10, 0), new Point(10, 10), new Point(0, 0),
|
|
69
|
+
];
|
|
70
|
+
const result = new Lwpolyline({ points: pts });
|
|
71
|
+
expect(result.points).toHaveLength(3);
|
|
72
|
+
expect(result.flags.hasFlag(1)).toBe(true);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('Lwpolyline preserves existing flags when setting closed bit', () => {
|
|
76
|
+
const pts = [
|
|
77
|
+
new Point(0, 0), new Point(10, 0), new Point(10, 10), new Point(0, 0),
|
|
78
|
+
];
|
|
79
|
+
// pass flag bit 2 (arbitrary extra flag)
|
|
80
|
+
const result = new Lwpolyline({ points: pts, 70: 2 });
|
|
81
|
+
const flagVal = result.flags.getFlagValue();
|
|
82
|
+
expect(flagVal & 1).toBe(1); // closed bit set
|
|
83
|
+
expect(flagVal & 2).toBe(2); // original bit preserved
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('Lwpolyline does not remove point when fewer than 4 points with matching ends', () => {
|
|
87
|
+
const pts = [new Point(0, 0), new Point(10, 0), new Point(0, 0)];
|
|
88
|
+
const result = new Lwpolyline({ points: pts });
|
|
89
|
+
expect(result.points).toHaveLength(3);
|
|
90
|
+
expect(result.flags.hasFlag(1)).toBe(false);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test('Lwpolyline does not modify open polyline', () => {
|
|
94
|
+
const pts = [new Point(0, 0), new Point(10, 0), new Point(10, 10), new Point(5, 5)];
|
|
95
|
+
const result = new Lwpolyline({ points: pts });
|
|
96
|
+
expect(result.points).toHaveLength(4);
|
|
97
|
+
expect(result.flags.hasFlag(1)).toBe(false);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// ─── register ────────────────────────────────────────────────────────────────
|
|
101
|
+
|
|
102
|
+
test('Lwpolyline.register returns command object', () => {
|
|
103
|
+
expect(Lwpolyline.register()).toEqual({ command: 'Lwpolyline' });
|
|
104
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Polyline } from '../../core/entities/polyline.js';
|
|
2
|
+
import { Core } from '../../core/core/core.js';
|
|
3
|
+
|
|
4
|
+
// initialise core
|
|
5
|
+
new Core();
|
|
6
|
+
|
|
7
|
+
// ─── register ────────────────────────────────────────────────────────────────
|
|
8
|
+
|
|
9
|
+
test('Polyline.register returns correct command object', () => {
|
|
10
|
+
expect(Polyline.register()).toEqual({ command: 'Polyline', shortcut: 'PL', type: 'Entity' });
|
|
11
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Rectangle } from '../../core/entities/rectangle.js';
|
|
2
|
+
import { Core } from '../../core/core/core.js';
|
|
3
|
+
|
|
4
|
+
// initialise core
|
|
5
|
+
new Core();
|
|
6
|
+
|
|
7
|
+
// ─── register ────────────────────────────────────────────────────────────────
|
|
8
|
+
|
|
9
|
+
test('Rectangle.register returns correct command object', () => {
|
|
10
|
+
expect(Rectangle.register()).toEqual({ command: 'Rectangle', shortcut: 'REC', type: 'Entity' });
|
|
11
|
+
});
|
|
@@ -59,7 +59,7 @@ AcDbTrace
|
|
|
59
59
|
expect(file.contents).toEqual(dxfString);
|
|
60
60
|
|
|
61
61
|
// create new entity from entity data to ensure all props are loaded
|
|
62
|
-
const newSolid = new Solid(solid);
|
|
62
|
+
const newSolid = new Solid({ handle: solid.getProperty('handle'), points: solid.points });
|
|
63
63
|
file = new File();
|
|
64
64
|
newSolid.dxf(file);
|
|
65
65
|
expect(file.contents).toEqual(dxfString);
|