@shopware-ag/dive 1.16.3 → 1.16.4
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/build/dive.cjs +58 -30
- package/build/dive.cjs.map +1 -1
- package/build/dive.d.cts +4 -2
- package/build/dive.d.ts +4 -2
- package/build/dive.js +58 -31
- package/build/dive.js.map +1 -1
- package/package.json +1 -1
- package/src/com/Communication.ts +5 -0
- package/src/com/__test__/Communication.test.ts +7 -1
- package/src/com/types/COMGeometry.ts +3 -1
- package/src/com/types/COMGeometryType.ts +9 -0
- package/src/com/types/index.ts +2 -0
- package/src/io/IO.ts +19 -42
- package/src/io/__test__/IO.test.ts +32 -15
- package/src/primitive/Primitive.ts +8 -4
- package/src/primitive/__test__/Primitive.test.ts +17 -2
- package/src/renderer/__test__/Renderer.test.ts +3 -2
- package/src/scene/root/Root.ts +20 -0
- package/src/scene/root/__test__/Root.test.ts +54 -1
- package/src/toolbox/BaseTool.ts +11 -3
- package/src/toolbox/Toolbox.ts +1 -1
- package/src/toolbox/__test__/BaseTool.test.ts +37 -1
- package/src/toolbox/__test__/Toolbox.test.ts +18 -18
package/package.json
CHANGED
package/src/com/Communication.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DIVECommunication } from '../Communication';
|
|
2
2
|
import '../types';
|
|
3
|
-
import '../actions';
|
|
3
|
+
import { type Actions } from '../actions';
|
|
4
4
|
import '../actions/camera/movecamera';
|
|
5
5
|
import '../actions/camera/resetcamera';
|
|
6
6
|
import '../actions/camera/setcameralayer';
|
|
@@ -933,4 +933,10 @@ describe('dive/communication/DIVECommunication', () => {
|
|
|
933
933
|
});
|
|
934
934
|
expect(result).toBe(url);
|
|
935
935
|
});
|
|
936
|
+
|
|
937
|
+
it('should warn of action is of invalid type ', () => {
|
|
938
|
+
jest.spyOn(console, 'warn').mockImplementationOnce(() => {});
|
|
939
|
+
testCom.PerformAction('INVALID_ACTION' as keyof Actions, {});
|
|
940
|
+
expect(console.warn).toHaveBeenCalledTimes(1);
|
|
941
|
+
});
|
|
936
942
|
});
|
package/src/com/types/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { type COMGeometry } from './COMGeometry';
|
|
|
7
7
|
import { type COMMaterial } from './COMMaterial';
|
|
8
8
|
import { type COMGroup } from './COMGroup';
|
|
9
9
|
import { type COMEntityType } from './COMEntityType';
|
|
10
|
+
import { type COMGeometryType } from './COMGeometryType';
|
|
10
11
|
|
|
11
12
|
export type {
|
|
12
13
|
COMEntity,
|
|
@@ -18,4 +19,5 @@ export type {
|
|
|
18
19
|
COMMaterial,
|
|
19
20
|
COMGroup,
|
|
20
21
|
COMEntityType,
|
|
22
|
+
COMGeometryType,
|
|
21
23
|
};
|
package/src/io/IO.ts
CHANGED
|
@@ -18,63 +18,40 @@ export class DIVEIO {
|
|
|
18
18
|
type: FileType,
|
|
19
19
|
url: string,
|
|
20
20
|
): Promise<DIVESceneFileType[FileType] | null> {
|
|
21
|
-
return this._importFromURL(type, url)
|
|
22
|
-
|
|
23
|
-
.catch((error) => {
|
|
24
|
-
console.error(error);
|
|
25
|
-
|
|
26
|
-
return null;
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
public Export<FileType extends keyof DIVESceneFileType>(
|
|
31
|
-
type: FileType,
|
|
32
|
-
): Promise<string | null> {
|
|
33
|
-
return this._exportToURL(type)
|
|
34
|
-
|
|
35
|
-
.catch((error) => {
|
|
36
|
-
console.error(error);
|
|
37
|
-
|
|
38
|
-
return null;
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
private _importFromURL<FileType extends keyof DIVESceneFileType>(
|
|
43
|
-
type: FileType,
|
|
44
|
-
url: string,
|
|
45
|
-
): Promise<DIVESceneFileType[FileType]> {
|
|
46
21
|
switch (type) {
|
|
47
22
|
case 'glb': {
|
|
48
|
-
return this._gltfIO.Import(url)
|
|
23
|
+
return this._gltfIO.Import(url).catch((error) => {
|
|
24
|
+
console.error(error);
|
|
25
|
+
return null;
|
|
26
|
+
});
|
|
49
27
|
}
|
|
50
28
|
|
|
51
29
|
default: {
|
|
52
|
-
|
|
30
|
+
console.error('DIVEIO.Import: Unsupported file type: ' + type);
|
|
31
|
+
return Promise.reject();
|
|
53
32
|
}
|
|
54
33
|
}
|
|
55
34
|
}
|
|
56
35
|
|
|
57
|
-
|
|
36
|
+
public Export<FileType extends keyof DIVESceneFileType>(
|
|
58
37
|
type: FileType,
|
|
59
|
-
): Promise<string> {
|
|
38
|
+
): Promise<string | null> {
|
|
60
39
|
switch (type) {
|
|
61
40
|
case 'glb': {
|
|
62
|
-
return
|
|
63
|
-
this.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
reject(error);
|
|
72
|
-
});
|
|
73
|
-
});
|
|
41
|
+
return this._gltfIO
|
|
42
|
+
.Export(this._scene, true, true)
|
|
43
|
+
.then((data) => {
|
|
44
|
+
return this._createBlobURL(data);
|
|
45
|
+
})
|
|
46
|
+
.catch((error) => {
|
|
47
|
+
console.error(error);
|
|
48
|
+
return null;
|
|
49
|
+
});
|
|
74
50
|
}
|
|
75
51
|
|
|
76
52
|
default: {
|
|
77
|
-
|
|
53
|
+
console.error('DIVEIO.Export: Unsupported file type: ' + type);
|
|
54
|
+
return Promise.reject();
|
|
78
55
|
}
|
|
79
56
|
}
|
|
80
57
|
}
|
|
@@ -58,15 +58,24 @@ describe('dive/io/DIVEIO', () => {
|
|
|
58
58
|
expect(result).toStrictEqual(mockGLTF);
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
-
it('should
|
|
61
|
+
it('should handle rejection from gltf io import', async () => {
|
|
62
62
|
jest.spyOn(console, 'error').mockImplementationOnce(() => {});
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
'unsupported file type' as 'glb',
|
|
66
|
-
'test.glb',
|
|
63
|
+
jest.spyOn(testIO['_gltfIO'], 'Import').mockRejectedValueOnce(
|
|
64
|
+
'THIS_IS_A_TEST_ERROR',
|
|
67
65
|
);
|
|
68
66
|
|
|
69
|
-
expect(
|
|
67
|
+
expect(testIO.Import('glb', 'test.glb')).resolves.toEqual(null);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should reject when importing with unsupported file type', async () => {
|
|
71
|
+
const spy = jest
|
|
72
|
+
.spyOn(console, 'error')
|
|
73
|
+
.mockImplementationOnce(() => {});
|
|
74
|
+
|
|
75
|
+
expect(
|
|
76
|
+
testIO.Import('THIS_IS_NOT_A_VALID_FILE_TYPE' as 'glb', 'test.glb'),
|
|
77
|
+
).rejects.not.toBeDefined();
|
|
78
|
+
expect(spy).toHaveBeenCalled();
|
|
70
79
|
});
|
|
71
80
|
|
|
72
81
|
it('should export to URL', async () => {
|
|
@@ -80,20 +89,28 @@ describe('dive/io/DIVEIO', () => {
|
|
|
80
89
|
|
|
81
90
|
const result = await testIO.Export('glb');
|
|
82
91
|
expect(result).toBeDefined();
|
|
92
|
+
expect(console.error).not.toHaveBeenCalled();
|
|
83
93
|
});
|
|
84
94
|
|
|
85
|
-
it('should handle rejection from gltf io', async () => {
|
|
86
|
-
|
|
87
|
-
|
|
95
|
+
it('should handle rejection from gltf io export', async () => {
|
|
96
|
+
const spy = jest
|
|
97
|
+
.spyOn(console, 'error')
|
|
98
|
+
.mockImplementationOnce(() => {});
|
|
99
|
+
jest.spyOn(testIO['_gltfIO'], 'Export').mockRejectedValueOnce(
|
|
100
|
+
'THIS_IS_A_TEST_ERROR',
|
|
101
|
+
);
|
|
88
102
|
|
|
89
|
-
|
|
90
|
-
expect(result).toBeDefined();
|
|
103
|
+
expect(testIO.Export('glb')).resolves.toEqual(null);
|
|
91
104
|
});
|
|
92
105
|
|
|
93
106
|
it('should reject when exporting with unsupported file type', async () => {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
107
|
+
const spy = jest
|
|
108
|
+
.spyOn(console, 'error')
|
|
109
|
+
.mockImplementationOnce(() => {});
|
|
110
|
+
|
|
111
|
+
expect(
|
|
112
|
+
testIO.Export('THIS_IS_NOT_A_VALID_FILE_TYPE' as 'glb'),
|
|
113
|
+
).rejects.not.toBeDefined();
|
|
114
|
+
expect(spy).toHaveBeenCalled();
|
|
98
115
|
});
|
|
99
116
|
});
|
|
@@ -43,7 +43,10 @@ export class DIVEPrimitive extends DIVENode {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
public SetGeometry(geometry: COMGeometry): void {
|
|
46
|
-
|
|
46
|
+
const geo = this.assembleGeometry(geometry);
|
|
47
|
+
if (!geo) return;
|
|
48
|
+
|
|
49
|
+
this._mesh.geometry = geo;
|
|
47
50
|
this._boundingBox.setFromObject(this._mesh);
|
|
48
51
|
}
|
|
49
52
|
|
|
@@ -168,7 +171,7 @@ export class DIVEPrimitive extends DIVENode {
|
|
|
168
171
|
}
|
|
169
172
|
}
|
|
170
173
|
|
|
171
|
-
private assembleGeometry(geometry: COMGeometry): BufferGeometry {
|
|
174
|
+
private assembleGeometry(geometry: COMGeometry): BufferGeometry | null {
|
|
172
175
|
switch (geometry.name.toLowerCase()) {
|
|
173
176
|
case 'cylinder':
|
|
174
177
|
return this.createCylinderGeometry(geometry);
|
|
@@ -176,6 +179,7 @@ export class DIVEPrimitive extends DIVENode {
|
|
|
176
179
|
return this.createSphereGeometry(geometry);
|
|
177
180
|
case 'pyramid':
|
|
178
181
|
return this.createPyramidGeometry(geometry);
|
|
182
|
+
case 'cube':
|
|
179
183
|
case 'box':
|
|
180
184
|
return this.createBoxGeometry(geometry);
|
|
181
185
|
case 'cone':
|
|
@@ -186,10 +190,10 @@ export class DIVEPrimitive extends DIVENode {
|
|
|
186
190
|
return this.createPlaneGeometry(geometry);
|
|
187
191
|
default: {
|
|
188
192
|
console.warn(
|
|
189
|
-
'DIVEPrimitive: Invalid geometry type:',
|
|
193
|
+
'DIVEPrimitive.assembleGeometry: Invalid geometry type:',
|
|
190
194
|
geometry.name.toLowerCase(),
|
|
191
195
|
);
|
|
192
|
-
return
|
|
196
|
+
return null;
|
|
193
197
|
}
|
|
194
198
|
}
|
|
195
199
|
}
|
|
@@ -8,7 +8,11 @@ import {
|
|
|
8
8
|
type MeshStandardMaterial,
|
|
9
9
|
} from 'three';
|
|
10
10
|
import type { DIVEScene } from '../../scene/Scene';
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
type COMMaterial,
|
|
13
|
+
type COMGeometry,
|
|
14
|
+
type COMGeometryType,
|
|
15
|
+
} from '../../com/types';
|
|
12
16
|
|
|
13
17
|
const intersectObjectsMock = jest.fn();
|
|
14
18
|
|
|
@@ -219,10 +223,21 @@ describe('dive/primitive/DIVEPrimitive', () => {
|
|
|
219
223
|
});
|
|
220
224
|
|
|
221
225
|
it('should set geometry', () => {
|
|
226
|
+
jest.spyOn(console, 'warn');
|
|
227
|
+
const geometry = {
|
|
228
|
+
name: 'cube' as COMGeometryType,
|
|
229
|
+
} as COMGeometry;
|
|
230
|
+
expect(() => primitive.SetGeometry(geometry)).not.toThrow();
|
|
231
|
+
expect(console.warn).not.toHaveBeenCalled();
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it('should warn when geometry is invalid', () => {
|
|
235
|
+
jest.spyOn(console, 'warn').mockImplementation(() => {});
|
|
222
236
|
const geometry = {
|
|
223
|
-
name: '
|
|
237
|
+
name: 'INVALID' as COMGeometryType,
|
|
224
238
|
} as COMGeometry;
|
|
225
239
|
expect(() => primitive.SetGeometry(geometry)).not.toThrow();
|
|
240
|
+
expect(console.warn).toHaveBeenCalled();
|
|
226
241
|
});
|
|
227
242
|
|
|
228
243
|
it('should place on floor', () => {
|
|
@@ -10,7 +10,6 @@ const test_uuid = 'test-uuid';
|
|
|
10
10
|
|
|
11
11
|
const mock_render = jest.fn();
|
|
12
12
|
const mock_setSize = jest.fn();
|
|
13
|
-
const mock_setAnimationLoop = jest.fn();
|
|
14
13
|
|
|
15
14
|
jest.mock('three', () => {
|
|
16
15
|
return {
|
|
@@ -27,7 +26,9 @@ jest.mock('three', () => {
|
|
|
27
26
|
this.setSize = mock_setSize;
|
|
28
27
|
this.setPixelRatio = jest.fn();
|
|
29
28
|
this.render = mock_render;
|
|
30
|
-
this.setAnimationLoop =
|
|
29
|
+
this.setAnimationLoop = jest.fn((callback: (() => void) | null) => {
|
|
30
|
+
if (callback) callback();
|
|
31
|
+
});
|
|
31
32
|
this.shadowMap = {
|
|
32
33
|
enabled: false,
|
|
33
34
|
};
|
package/src/scene/root/Root.ts
CHANGED
|
@@ -81,6 +81,11 @@ export class DIVERoot extends Object3D {
|
|
|
81
81
|
this.updateGroup(object);
|
|
82
82
|
break;
|
|
83
83
|
}
|
|
84
|
+
default: {
|
|
85
|
+
console.warn(
|
|
86
|
+
`DIVERoot.AddSceneObject: Unknown entity type: ${object.entityType}`,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
84
89
|
}
|
|
85
90
|
}
|
|
86
91
|
|
|
@@ -107,6 +112,11 @@ export class DIVERoot extends Object3D {
|
|
|
107
112
|
this.updateGroup(object);
|
|
108
113
|
break;
|
|
109
114
|
}
|
|
115
|
+
default: {
|
|
116
|
+
console.warn(
|
|
117
|
+
`DIVERoot.UpdateSceneObject: Unknown entity type: ${object.entityType}`,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
110
120
|
}
|
|
111
121
|
}
|
|
112
122
|
|
|
@@ -133,6 +143,11 @@ export class DIVERoot extends Object3D {
|
|
|
133
143
|
this.deleteGroup(object);
|
|
134
144
|
break;
|
|
135
145
|
}
|
|
146
|
+
default: {
|
|
147
|
+
console.warn(
|
|
148
|
+
`DIVERoot.DeleteSceneObject: Unknown entity type: ${object.entityType}`,
|
|
149
|
+
);
|
|
150
|
+
}
|
|
136
151
|
}
|
|
137
152
|
}
|
|
138
153
|
|
|
@@ -147,6 +162,11 @@ export class DIVERoot extends Object3D {
|
|
|
147
162
|
this.placeOnFloor(object);
|
|
148
163
|
break;
|
|
149
164
|
}
|
|
165
|
+
default: {
|
|
166
|
+
console.warn(
|
|
167
|
+
`DIVERoot.PlaceOnFloor: Unknown entity type: ${object.entityType}`,
|
|
168
|
+
);
|
|
169
|
+
}
|
|
150
170
|
}
|
|
151
171
|
}
|
|
152
172
|
|
|
@@ -6,7 +6,8 @@ import {
|
|
|
6
6
|
type COMPov,
|
|
7
7
|
type COMEntity,
|
|
8
8
|
type COMGeometry,
|
|
9
|
-
COMGroup,
|
|
9
|
+
type COMGroup,
|
|
10
|
+
type COMEntityType,
|
|
10
11
|
} from '../../../com/types';
|
|
11
12
|
import { type DIVEScene } from '../../Scene';
|
|
12
13
|
import { DIVECommunication } from '../../../com/Communication';
|
|
@@ -928,4 +929,56 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
928
929
|
} as COMPrimitive),
|
|
929
930
|
).not.toThrow();
|
|
930
931
|
});
|
|
932
|
+
|
|
933
|
+
it('should warn if entity type is invalid while adding object', () => {
|
|
934
|
+
const spy = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
|
935
|
+
expect(() =>
|
|
936
|
+
root.AddSceneObject({
|
|
937
|
+
id: 'id',
|
|
938
|
+
name: 'entity',
|
|
939
|
+
entityType: 'INVALID' as COMEntityType,
|
|
940
|
+
visible: true,
|
|
941
|
+
} as COMEntity),
|
|
942
|
+
).not.toThrow();
|
|
943
|
+
expect(spy).toHaveBeenCalled();
|
|
944
|
+
});
|
|
945
|
+
|
|
946
|
+
it('should warn if entity type is invalid while updating object', () => {
|
|
947
|
+
const spy = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
|
948
|
+
expect(() =>
|
|
949
|
+
root.UpdateSceneObject({
|
|
950
|
+
id: 'id',
|
|
951
|
+
name: 'entity',
|
|
952
|
+
entityType: 'INVALID' as COMEntityType,
|
|
953
|
+
visible: true,
|
|
954
|
+
} as COMEntity),
|
|
955
|
+
).not.toThrow();
|
|
956
|
+
expect(spy).toHaveBeenCalled();
|
|
957
|
+
});
|
|
958
|
+
|
|
959
|
+
it('should warn if entity type is invalid while deleting object', () => {
|
|
960
|
+
const spy = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
|
961
|
+
expect(() =>
|
|
962
|
+
root.DeleteSceneObject({
|
|
963
|
+
id: 'id',
|
|
964
|
+
name: 'entity',
|
|
965
|
+
entityType: 'INVALID' as COMEntityType,
|
|
966
|
+
visible: true,
|
|
967
|
+
} as COMEntity),
|
|
968
|
+
).not.toThrow();
|
|
969
|
+
expect(spy).toHaveBeenCalled();
|
|
970
|
+
});
|
|
971
|
+
|
|
972
|
+
it('should warn if entity type is invalid while placing on floor', () => {
|
|
973
|
+
const spy = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
|
974
|
+
expect(() =>
|
|
975
|
+
root.PlaceOnFloor({
|
|
976
|
+
id: 'id',
|
|
977
|
+
name: 'entity',
|
|
978
|
+
entityType: 'INVALID' as COMEntityType,
|
|
979
|
+
visible: true,
|
|
980
|
+
} as COMEntity),
|
|
981
|
+
).not.toThrow();
|
|
982
|
+
expect(spy).toHaveBeenCalled();
|
|
983
|
+
});
|
|
931
984
|
});
|
package/src/toolbox/BaseTool.ts
CHANGED
|
@@ -95,15 +95,23 @@ export abstract class DIVEBaseTool {
|
|
|
95
95
|
|
|
96
96
|
public onPointerDown(e: PointerEvent): void {
|
|
97
97
|
switch (e.button) {
|
|
98
|
-
case 0:
|
|
98
|
+
case 0: {
|
|
99
99
|
this._pointerPrimaryDown = true;
|
|
100
100
|
break;
|
|
101
|
-
|
|
101
|
+
}
|
|
102
|
+
case 1: {
|
|
102
103
|
this._pointerMiddleDown = true;
|
|
103
104
|
break;
|
|
104
|
-
|
|
105
|
+
}
|
|
106
|
+
case 2: {
|
|
105
107
|
this._pointerSecondaryDown = true;
|
|
106
108
|
break;
|
|
109
|
+
}
|
|
110
|
+
default: {
|
|
111
|
+
console.warn(
|
|
112
|
+
'DIVEBaseTool.onPointerDown: Unknown button: ' + e.button,
|
|
113
|
+
);
|
|
114
|
+
}
|
|
107
115
|
}
|
|
108
116
|
|
|
109
117
|
this._lastPointerDown.copy(this._pointer);
|
package/src/toolbox/Toolbox.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DIVEBaseTool } from '../BaseTool';
|
|
2
2
|
import type DIVEOrbitControls from '../../controls/OrbitControls';
|
|
3
3
|
import type { DIVEScene } from '../../scene/Scene';
|
|
4
|
-
import { type Object3D, type Vector3 } from 'three';
|
|
4
|
+
import { type Intersection, type Object3D, type Vector3 } from 'three';
|
|
5
5
|
import { type DIVEHoverable } from '../../interface/Hoverable';
|
|
6
6
|
import { type DIVEDraggable } from '../../interface/Draggable';
|
|
7
7
|
|
|
@@ -60,8 +60,36 @@ describe('dive/toolbox/DIVEBaseTool', () => {
|
|
|
60
60
|
|
|
61
61
|
it('should raycast', () => {
|
|
62
62
|
const toolBox = new abstractWrapper(mockScene, mockController);
|
|
63
|
+
const spy = jest
|
|
64
|
+
.spyOn(toolBox['_raycaster'], 'intersectObjects')
|
|
65
|
+
.mockImplementationOnce(() => {
|
|
66
|
+
return [
|
|
67
|
+
{
|
|
68
|
+
object: {
|
|
69
|
+
visible: true,
|
|
70
|
+
},
|
|
71
|
+
} as unknown as Intersection,
|
|
72
|
+
];
|
|
73
|
+
});
|
|
63
74
|
expect(() => toolBox['raycast']()).not.toThrow();
|
|
75
|
+
expect(spy).toHaveBeenCalled();
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should raycast with selection of objects', () => {
|
|
79
|
+
const toolBox = new abstractWrapper(mockScene, mockController);
|
|
80
|
+
const spy = jest
|
|
81
|
+
.spyOn(toolBox['_raycaster'], 'intersectObjects')
|
|
82
|
+
.mockImplementationOnce(() => {
|
|
83
|
+
return [
|
|
84
|
+
{
|
|
85
|
+
object: {
|
|
86
|
+
visible: true,
|
|
87
|
+
},
|
|
88
|
+
} as unknown as Intersection,
|
|
89
|
+
];
|
|
90
|
+
});
|
|
64
91
|
expect(() => toolBox['raycast']([])).not.toThrow();
|
|
92
|
+
expect(spy).toHaveBeenCalled();
|
|
65
93
|
});
|
|
66
94
|
|
|
67
95
|
it('should return correct pointerAnyDown', () => {
|
|
@@ -96,13 +124,21 @@ describe('dive/toolbox/DIVEBaseTool', () => {
|
|
|
96
124
|
expect(() =>
|
|
97
125
|
toolBox.onPointerDown({ button: 0 } as PointerEvent),
|
|
98
126
|
).not.toThrow();
|
|
127
|
+
|
|
99
128
|
expect(() =>
|
|
100
129
|
toolBox.onPointerDown({ button: 1 } as PointerEvent),
|
|
101
130
|
).not.toThrow();
|
|
131
|
+
|
|
102
132
|
expect(() =>
|
|
103
133
|
toolBox.onPointerDown({ button: 2 } as PointerEvent),
|
|
104
134
|
).not.toThrow();
|
|
105
135
|
|
|
136
|
+
const spy = jest.spyOn(console, 'warn').mockImplementation();
|
|
137
|
+
expect(() =>
|
|
138
|
+
toolBox.onPointerDown({ button: 666 } as PointerEvent),
|
|
139
|
+
).not.toThrow();
|
|
140
|
+
expect(spy).toHaveBeenCalled();
|
|
141
|
+
|
|
106
142
|
toolBox['_intersects'] = [
|
|
107
143
|
{
|
|
108
144
|
distance: 1,
|
|
@@ -6,21 +6,6 @@ import type { DIVEScene } from '../../scene/Scene';
|
|
|
6
6
|
* @jest-environment jsdom
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
const mock_addEventListener = jest.fn();
|
|
10
|
-
const mock_removeEventListener = jest.fn();
|
|
11
|
-
|
|
12
|
-
const mock_Canvas = {
|
|
13
|
-
width: 0,
|
|
14
|
-
height: 0,
|
|
15
|
-
addEventListener: mock_addEventListener,
|
|
16
|
-
getContext: jest.fn(),
|
|
17
|
-
removeEventListener: mock_removeEventListener,
|
|
18
|
-
clientWidth: 0,
|
|
19
|
-
clientHeight: 0,
|
|
20
|
-
offsetLeft: 0,
|
|
21
|
-
offsetTop: 0,
|
|
22
|
-
};
|
|
23
|
-
|
|
24
9
|
jest.mock('../select/SelectTool.ts', () => {
|
|
25
10
|
return {
|
|
26
11
|
DIVESelectTool: jest.fn(function () {
|
|
@@ -38,7 +23,21 @@ jest.mock('../select/SelectTool.ts', () => {
|
|
|
38
23
|
});
|
|
39
24
|
|
|
40
25
|
const mockController = {
|
|
41
|
-
domElement:
|
|
26
|
+
domElement: {
|
|
27
|
+
width: 0,
|
|
28
|
+
height: 0,
|
|
29
|
+
addEventListener: jest.fn((type, callback) => {
|
|
30
|
+
callback();
|
|
31
|
+
}),
|
|
32
|
+
getContext: jest.fn(),
|
|
33
|
+
removeEventListener: jest.fn((type, callback) => {
|
|
34
|
+
callback();
|
|
35
|
+
}),
|
|
36
|
+
clientWidth: 0,
|
|
37
|
+
clientHeight: 0,
|
|
38
|
+
offsetLeft: 0,
|
|
39
|
+
offsetTop: 0,
|
|
40
|
+
},
|
|
42
41
|
object: {},
|
|
43
42
|
} as unknown as DIVEOrbitControls;
|
|
44
43
|
|
|
@@ -55,14 +54,15 @@ describe('dive/toolbox/DIVEToolBox', () => {
|
|
|
55
54
|
it('should dispose', () => {
|
|
56
55
|
const toolBox = new DIVEToolbox({} as DIVEScene, mockController);
|
|
57
56
|
toolBox.Dispose();
|
|
58
|
-
expect(mock_removeEventListener).toHaveBeenCalled();
|
|
59
57
|
});
|
|
60
58
|
|
|
61
59
|
it('should throw with incorrect tool', () => {
|
|
60
|
+
const spy = jest.spyOn(console, 'warn').mockImplementation();
|
|
62
61
|
const toolBox = new DIVEToolbox({} as DIVEScene, mockController);
|
|
63
62
|
expect(() =>
|
|
64
63
|
toolBox.UseTool('not a real tool' as unknown as ToolType),
|
|
65
|
-
).toThrow();
|
|
64
|
+
).not.toThrow();
|
|
65
|
+
expect(spy).toHaveBeenCalled();
|
|
66
66
|
});
|
|
67
67
|
|
|
68
68
|
it('should use no tool', () => {
|