@neurodevs/node-lsl 17.1.1 → 18.1.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/.claude/settings.local.json +10 -0
- package/.vscode/launch.json +54 -57
- package/.vscode/settings.json +61 -66
- package/.vscode/tasks.json +98 -129
- package/README.md +20 -44
- package/build/__tests__/AbstractPackageTest.d.ts +7 -5
- package/build/__tests__/AbstractPackageTest.js +22 -15
- package/build/__tests__/AbstractPackageTest.js.map +1 -1
- package/build/__tests__/impl/BleDeviceController.test.d.ts +54 -0
- package/build/__tests__/impl/BleDeviceController.test.js +333 -0
- package/build/__tests__/impl/BleDeviceController.test.js.map +1 -0
- package/build/__tests__/impl/LslEventMarkerEmitter.test.d.ts +34 -0
- package/build/__tests__/impl/LslEventMarkerEmitter.test.js +243 -0
- package/build/__tests__/impl/LslEventMarkerEmitter.test.js.map +1 -0
- package/build/__tests__/impl/LslStreamInfo.test.d.ts +0 -3
- package/build/__tests__/impl/LslStreamInfo.test.js +2 -27
- package/build/__tests__/impl/LslStreamInfo.test.js.map +1 -1
- package/build/__tests__/impl/LslStreamInlet.test.d.ts +20 -8
- package/build/__tests__/impl/LslStreamInlet.test.js +224 -69
- package/build/__tests__/impl/LslStreamInlet.test.js.map +1 -1
- package/build/__tests__/impl/LslStreamOutlet.test.d.ts +3 -7
- package/build/__tests__/impl/LslStreamOutlet.test.js +40 -50
- package/build/__tests__/impl/LslStreamOutlet.test.js.map +1 -1
- package/build/__tests__/impl/LslWebSocketBridge.test.js +19 -20
- package/build/__tests__/impl/LslWebSocketBridge.test.js.map +1 -1
- package/build/assertions.d.ts +1 -1
- package/build/assertions.js.map +1 -1
- package/build/impl/LslEventMarkerEmitter.d.ts +35 -0
- package/build/impl/LslEventMarkerEmitter.js +86 -0
- package/build/impl/LslEventMarkerEmitter.js.map +1 -0
- package/build/impl/LslStreamInfo.d.ts +4 -8
- package/build/impl/LslStreamInfo.js +8 -21
- package/build/impl/LslStreamInfo.js.map +1 -1
- package/build/impl/LslStreamInlet.d.ts +31 -50
- package/build/impl/LslStreamInlet.js +79 -149
- package/build/impl/LslStreamInlet.js.map +1 -1
- package/build/impl/LslStreamOutlet.d.ts +15 -18
- package/build/impl/LslStreamOutlet.js +39 -47
- package/build/impl/LslStreamOutlet.js.map +1 -1
- package/build/impl/LslWebSocketBridge.d.ts +4 -5
- package/build/impl/LslWebSocketBridge.js +10 -10
- package/build/impl/LslWebSocketBridge.js.map +1 -1
- package/build/impl/controllers/BleDeviceController.d.ts +58 -0
- package/build/impl/controllers/BleDeviceController.js +145 -0
- package/build/impl/controllers/BleDeviceController.js.map +1 -0
- package/build/impl/workers/inlet/LslStreamInlet.worker.d.ts +22 -0
- package/build/impl/workers/inlet/LslStreamInlet.worker.js +42 -0
- package/build/impl/workers/inlet/LslStreamInlet.worker.js.map +1 -0
- package/build/impl/workers/inlet/StreamInletWorker.d.ts +73 -0
- package/build/impl/workers/inlet/StreamInletWorker.js +253 -0
- package/build/impl/workers/inlet/StreamInletWorker.js.map +1 -0
- package/build/impl/workers/outlet/LslStreamOutlet.worker.d.ts +32 -0
- package/build/impl/workers/outlet/LslStreamOutlet.worker.js +82 -0
- package/build/impl/workers/outlet/LslStreamOutlet.worker.js.map +1 -0
- package/build/index.d.ts +14 -14
- package/build/index.js +16 -16
- package/build/index.js.map +1 -1
- package/build/scripts/discoverMuse.js +40 -0
- package/build/scripts/discoverMuse.js.map +1 -0
- package/build/scripts/finalizeHandles.d.ts +2 -0
- package/build/scripts/finalizeHandles.js +48 -0
- package/build/scripts/finalizeHandles.js.map +1 -0
- package/build/scripts/runLslEventMarkerEmitter.d.ts +1 -0
- package/build/scripts/runLslEventMarkerEmitter.js +11 -0
- package/build/scripts/runLslEventMarkerEmitter.js.map +1 -0
- package/build/scripts/runMuse.d.ts +1 -0
- package/build/scripts/runMuse.js +40 -0
- package/build/scripts/runMuse.js.map +1 -0
- package/build/scripts/runOutletToInlet.js +7 -6
- package/build/scripts/runOutletToInlet.js.map +1 -1
- package/build/scripts/testDestroyOutlet.d.ts +1 -0
- package/build/scripts/testDestroyOutlet.js +4 -0
- package/build/scripts/testDestroyOutlet.js.map +1 -0
- package/build/testDoubles/BleController/FakeBleController.d.ts +24 -0
- package/build/testDoubles/BleController/FakeBleController.js +42 -0
- package/build/testDoubles/BleController/FakeBleController.js.map +1 -0
- package/build/testDoubles/BleController/SpyBleController.d.ts +14 -0
- package/build/testDoubles/BleController/SpyBleController.js +48 -0
- package/build/testDoubles/BleController/SpyBleController.js.map +1 -0
- package/build/testDoubles/EventMarkerEmitter/FakeEventMarkerEmitter.d.ts +17 -0
- package/build/testDoubles/EventMarkerEmitter/FakeEventMarkerEmitter.js +30 -0
- package/build/testDoubles/EventMarkerEmitter/FakeEventMarkerEmitter.js.map +1 -0
- package/build/testDoubles/EventMarkerEmitter/SpyEventMarkerEmitter.d.ts +10 -0
- package/build/testDoubles/EventMarkerEmitter/SpyEventMarkerEmitter.js +23 -0
- package/build/testDoubles/EventMarkerEmitter/SpyEventMarkerEmitter.js.map +1 -0
- package/build/testDoubles/EventMarkerEmitter/ThrowingEventMarkerEmitter.d.ts +9 -0
- package/build/testDoubles/EventMarkerEmitter/ThrowingEventMarkerEmitter.js +19 -0
- package/build/testDoubles/EventMarkerEmitter/ThrowingEventMarkerEmitter.js.map +1 -0
- package/build/testDoubles/StreamInfo/FakeStreamInfo.d.ts +3 -3
- package/build/testDoubles/StreamInfo/FakeStreamInfo.js +3 -3
- package/build/testDoubles/StreamInfo/FakeStreamInfo.js.map +1 -1
- package/build/testDoubles/StreamInlet/FakeStreamInlet.d.ts +8 -10
- package/build/testDoubles/StreamInlet/FakeStreamInlet.js +6 -7
- package/build/testDoubles/StreamInlet/FakeStreamInlet.js.map +1 -1
- package/build/testDoubles/StreamInlet/SpyStreamInlet.d.ts +2 -5
- package/build/testDoubles/StreamInlet/SpyStreamInlet.js +2 -8
- package/build/testDoubles/StreamInlet/SpyStreamInlet.js.map +1 -1
- package/build/testDoubles/StreamOutlet/FakeStreamOutlet.d.ts +7 -9
- package/build/testDoubles/StreamOutlet/FakeStreamOutlet.js +8 -8
- package/build/testDoubles/StreamOutlet/FakeStreamOutlet.js.map +1 -1
- package/build/testDoubles/WebSocketBridge/FakeWebSocketBridge.d.ts +1 -1
- package/build/testDoubles/WebSocketBridge/FakeWebSocketBridge.js +1 -1
- package/build/testDoubles/WebSocketBridge/FakeWebSocketBridge.js.map +1 -1
- package/build/testDoubles/WorkerThreads/FakeWorker.d.ts +27 -0
- package/build/testDoubles/WorkerThreads/FakeWorker.js +67 -0
- package/build/testDoubles/WorkerThreads/FakeWorker.js.map +1 -0
- package/build/testDoubles/generateRandomOutletOptions.js +1 -1
- package/build/testDoubles/generateRandomOutletOptions.js.map +1 -1
- package/build/validations.js +0 -2
- package/build/validations.js.map +1 -1
- package/eslint.config.js +3 -0
- package/package.json +27 -49
- package/prettier.config.js +3 -0
- package/src/__tests__/AbstractPackageTest.ts +38 -21
- package/src/__tests__/impl/BleDeviceController.test.ts +492 -0
- package/src/__tests__/impl/LslEventMarkerEmitter.test.ts +323 -0
- package/src/__tests__/impl/LslStreamInfo.test.ts +3 -40
- package/src/__tests__/impl/LslStreamInlet.test.ts +344 -97
- package/src/__tests__/impl/LslStreamOutlet.test.ts +65 -73
- package/src/__tests__/impl/LslWebSocketBridge.test.ts +22 -21
- package/src/assertions.ts +2 -1
- package/src/impl/LslEventMarkerEmitter.ts +133 -0
- package/src/impl/LslStreamInfo.ts +17 -29
- package/src/impl/LslStreamInlet.ts +102 -215
- package/src/impl/LslStreamOutlet.ts +54 -78
- package/src/impl/LslWebSocketBridge.ts +14 -14
- package/src/impl/controllers/BleDeviceController.ts +223 -0
- package/src/impl/workers/inlet/LslStreamInlet.worker.ts +74 -0
- package/src/impl/workers/inlet/StreamInletWorker.ts +348 -0
- package/src/impl/workers/outlet/LslStreamOutlet.worker.ts +144 -0
- package/src/index.ts +16 -16
- package/src/scripts/discoverMuse.ts +50 -0
- package/src/scripts/finalizeHandles.ts +63 -0
- package/src/scripts/runLslEventMarkerEmitter.ts +15 -0
- package/src/scripts/runMuse.ts +50 -0
- package/src/scripts/runOutletToInlet.ts +10 -8
- package/src/scripts/testDestroyOutlet.ts +5 -0
- package/src/testDoubles/BleController/FakeBleController.ts +70 -0
- package/src/testDoubles/BleController/SpyBleController.ts +61 -0
- package/src/testDoubles/EventMarkerEmitter/FakeEventMarkerEmitter.ts +46 -0
- package/src/testDoubles/EventMarkerEmitter/SpyEventMarkerEmitter.ts +31 -0
- package/src/testDoubles/EventMarkerEmitter/ThrowingEventMarkerEmitter.ts +29 -0
- package/src/testDoubles/StreamInfo/FakeStreamInfo.ts +4 -4
- package/src/testDoubles/StreamInlet/FakeStreamInlet.ts +11 -17
- package/src/testDoubles/StreamInlet/SpyStreamInlet.ts +3 -16
- package/src/testDoubles/StreamOutlet/FakeStreamOutlet.ts +15 -15
- package/src/testDoubles/WebSocketBridge/FakeWebSocketBridge.ts +1 -1
- package/src/testDoubles/WorkerThreads/FakeWorker.ts +99 -0
- package/src/testDoubles/generateRandomOutletOptions.ts +2 -1
- package/src/validations.ts +0 -2
- package/tsconfig.json +23 -27
- package/build/.spruce/settings.json +0 -11
- package/build/__tests__/impl/LiblslAdapter.test.d.ts +0 -79
- package/build/__tests__/impl/LiblslAdapter.test.js +0 -688
- package/build/__tests__/impl/LiblslAdapter.test.js.map +0 -1
- package/build/__tests__/impl/LslEventMarkerOutlet.test.d.ts +0 -21
- package/build/__tests__/impl/LslEventMarkerOutlet.test.js +0 -160
- package/build/__tests__/impl/LslEventMarkerOutlet.test.js.map +0 -1
- package/build/handleError.d.ts +0 -8
- package/build/handleError.js +0 -25
- package/build/handleError.js.map +0 -1
- package/build/impl/LiblslAdapter.d.ts +0 -154
- package/build/impl/LiblslAdapter.js +0 -317
- package/build/impl/LiblslAdapter.js.map +0 -1
- package/build/impl/LslEventMarkerOutlet.d.ts +0 -28
- package/build/impl/LslEventMarkerOutlet.js +0 -63
- package/build/impl/LslEventMarkerOutlet.js.map +0 -1
- package/build/scripts/runLslEventMarkerOutlet.js +0 -18
- package/build/scripts/runLslEventMarkerOutlet.js.map +0 -1
- package/build/testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.d.ts +0 -13
- package/build/testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.js +0 -26
- package/build/testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.js.map +0 -1
- package/build/testDoubles/EventMarkerOutlet/MockEventMarkerOutlet.d.ts +0 -17
- package/build/testDoubles/EventMarkerOutlet/MockEventMarkerOutlet.js +0 -46
- package/build/testDoubles/EventMarkerOutlet/MockEventMarkerOutlet.js.map +0 -1
- package/build/testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.d.ts +0 -9
- package/build/testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.js +0 -19
- package/build/testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.js.map +0 -1
- package/build/testDoubles/EventMarkerOutlet/ThrowingEventMarkerOutlet.d.ts +0 -9
- package/build/testDoubles/EventMarkerOutlet/ThrowingEventMarkerOutlet.js +0 -19
- package/build/testDoubles/EventMarkerOutlet/ThrowingEventMarkerOutlet.js.map +0 -1
- package/build/testDoubles/Liblsl/FakeLiblsl.d.ts +0 -50
- package/build/testDoubles/Liblsl/FakeLiblsl.js +0 -126
- package/build/testDoubles/Liblsl/FakeLiblsl.js.map +0 -1
- package/eslint.config.mjs +0 -3
- package/src/.spruce/settings.json +0 -11
- package/src/__tests__/impl/LiblslAdapter.test.ts +0 -817
- package/src/__tests__/impl/LslEventMarkerOutlet.test.ts +0 -195
- package/src/handleError.ts +0 -24
- package/src/impl/LiblslAdapter.ts +0 -543
- package/src/impl/LslEventMarkerOutlet.ts +0 -97
- package/src/scripts/runLslEventMarkerOutlet.ts +0 -23
- package/src/testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.ts +0 -36
- package/src/testDoubles/EventMarkerOutlet/MockEventMarkerOutlet.ts +0 -75
- package/src/testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.ts +0 -24
- package/src/testDoubles/EventMarkerOutlet/ThrowingEventMarkerOutlet.ts +0 -28
- package/src/testDoubles/Liblsl/FakeLiblsl.ts +0 -182
- /package/build/scripts/{runLslEventMarkerOutlet.d.ts → discoverMuse.d.ts} +0 -0
|
@@ -1,18 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FakeLiblsl,
|
|
3
|
+
FakeLibndx,
|
|
4
|
+
InfoHandle,
|
|
5
|
+
LiblslAdapter,
|
|
6
|
+
LibndxAdapter,
|
|
7
|
+
} from '@neurodevs/ndx-native'
|
|
1
8
|
import AbstractModuleTest from '@neurodevs/node-tdd'
|
|
2
9
|
import WebSocket, { Server } from 'ws'
|
|
3
10
|
|
|
4
|
-
import
|
|
5
|
-
import LslEventMarkerOutlet from '../impl/LslEventMarkerOutlet.js'
|
|
6
|
-
import LslStreamInfo from '../impl/LslStreamInfo.js'
|
|
7
|
-
import LslStreamInlet, {
|
|
8
|
-
OnDataCallback,
|
|
9
|
-
StreamInletOptions,
|
|
10
|
-
} from '../impl/LslStreamInlet.js'
|
|
11
|
-
import LslStreamOutlet from '../impl/LslStreamOutlet.js'
|
|
12
|
-
import LslWebSocketBridge from '../impl/LslWebSocketBridge.js'
|
|
13
|
-
|
|
14
|
-
import SpyEventMarkerOutlet from '../testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.js'
|
|
15
|
-
import FakeLiblsl from '../testDoubles/Liblsl/FakeLiblsl.js'
|
|
11
|
+
import SpyEventMarkerEmitter from '../testDoubles/EventMarkerEmitter/SpyEventMarkerEmitter.js'
|
|
16
12
|
import FakeStreamInfo from '../testDoubles/StreamInfo/FakeStreamInfo.js'
|
|
17
13
|
import SpyStreamInfo from '../testDoubles/StreamInfo/SpyStreamInfo.js'
|
|
18
14
|
import FakeStreamInlet from '../testDoubles/StreamInlet/FakeStreamInlet.js'
|
|
@@ -22,8 +18,19 @@ import SpyLslWebSocketBridge from '../testDoubles/WebSocketBridge/SpyLslWebSocke
|
|
|
22
18
|
import FakeWebSocket from '../testDoubles/WebSockets/FakeWebSocket.js'
|
|
23
19
|
import FakeWebSocketServer from '../testDoubles/WebSockets/FakeWebSocketServer.js'
|
|
24
20
|
|
|
21
|
+
import LslWebSocketBridge from '../impl/LslWebSocketBridge.js'
|
|
22
|
+
import BleDeviceController from '../impl/controllers/BleDeviceController.js'
|
|
23
|
+
import LslEventMarkerEmitter from '../impl/LslEventMarkerEmitter.js'
|
|
24
|
+
import LslStreamInfo from '../impl/LslStreamInfo.js'
|
|
25
|
+
import LslStreamInlet, {
|
|
26
|
+
OnDataCallback,
|
|
27
|
+
StreamInletOptions,
|
|
28
|
+
} from '../impl/LslStreamInlet.js'
|
|
29
|
+
import LslStreamOutlet from '../impl/LslStreamOutlet.js'
|
|
30
|
+
|
|
25
31
|
export default class AbstractPackageTest extends AbstractModuleTest {
|
|
26
32
|
protected static fakeLiblsl: FakeLiblsl
|
|
33
|
+
protected static fakeLibndx: FakeLibndx
|
|
27
34
|
|
|
28
35
|
protected static async beforeEach() {
|
|
29
36
|
await super.beforeEach()
|
|
@@ -34,6 +41,17 @@ export default class AbstractPackageTest extends AbstractModuleTest {
|
|
|
34
41
|
LiblslAdapter.setInstance(this.fakeLiblsl)
|
|
35
42
|
|
|
36
43
|
FakeLiblsl.fakeErrorCode = 0
|
|
44
|
+
FakeLiblsl.fakeInfoHandles = [{} as InfoHandle]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
protected static setFakeLibndx() {
|
|
48
|
+
this.fakeLibndx = new FakeLibndx()
|
|
49
|
+
LibndxAdapter.setInstance(this.fakeLibndx)
|
|
50
|
+
|
|
51
|
+
FakeLibndx.resetTestDouble()
|
|
52
|
+
FakeLibndx.fakeResult = { status: 200 }
|
|
53
|
+
|
|
54
|
+
BleDeviceController.ndx = this.fakeLibndx
|
|
37
55
|
}
|
|
38
56
|
|
|
39
57
|
protected static setSpyStreamInfo() {
|
|
@@ -60,8 +78,8 @@ export default class AbstractPackageTest extends AbstractModuleTest {
|
|
|
60
78
|
FakeStreamOutlet.resetTestDouble()
|
|
61
79
|
}
|
|
62
80
|
|
|
63
|
-
protected static
|
|
64
|
-
|
|
81
|
+
protected static setSpyEventMarkerEmitter() {
|
|
82
|
+
LslEventMarkerEmitter.Class = SpyEventMarkerEmitter
|
|
65
83
|
}
|
|
66
84
|
|
|
67
85
|
protected static setSpyLslWebSocketBridge() {
|
|
@@ -78,7 +96,8 @@ export default class AbstractPackageTest extends AbstractModuleTest {
|
|
|
78
96
|
FakeWebSocketServer.resetTestDouble()
|
|
79
97
|
}
|
|
80
98
|
|
|
81
|
-
protected static readonly
|
|
99
|
+
protected static readonly fakeStreamInfo = new FakeStreamInfo()
|
|
100
|
+
|
|
82
101
|
protected static readonly name_ = this.generateId()
|
|
83
102
|
protected static readonly type = this.generateId()
|
|
84
103
|
protected static readonly sourceId = this.generateId()
|
|
@@ -90,9 +109,7 @@ export default class AbstractPackageTest extends AbstractModuleTest {
|
|
|
90
109
|
this.generateId(),
|
|
91
110
|
]
|
|
92
111
|
|
|
93
|
-
protected static
|
|
94
|
-
return this.channelNames.length
|
|
95
|
-
}
|
|
112
|
+
protected static readonly channelCount = this.channelNames.length
|
|
96
113
|
|
|
97
114
|
protected static readonly chunkSize = 2
|
|
98
115
|
protected static readonly sampleRateHz = Math.floor(Math.random() * 100)
|
|
@@ -102,12 +119,12 @@ export default class AbstractPackageTest extends AbstractModuleTest {
|
|
|
102
119
|
options: Partial<StreamInletOptions>,
|
|
103
120
|
onData: OnDataCallback
|
|
104
121
|
) {
|
|
105
|
-
const defaultOptions = {
|
|
106
|
-
|
|
122
|
+
const defaultOptions: StreamInletOptions = {
|
|
123
|
+
sourceId: this.sourceId,
|
|
107
124
|
chunkSize: this.chunkSize,
|
|
108
125
|
maxBufferedMs: this.maxBufferedMs,
|
|
109
126
|
...options,
|
|
110
|
-
}
|
|
127
|
+
}
|
|
111
128
|
|
|
112
129
|
return LslStreamInlet.Create(defaultOptions, onData)
|
|
113
130
|
}
|
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
import { randomInt } from 'node:crypto'
|
|
2
|
+
|
|
3
|
+
import { test, assert } from '@neurodevs/node-tdd'
|
|
4
|
+
import { FakeLibndx, NativePeripheral } from '@neurodevs/ndx-native'
|
|
5
|
+
|
|
6
|
+
import SpyBleController from '../../testDoubles/BleController/SpyBleController.js'
|
|
7
|
+
import AbstractPackageTest from '../AbstractPackageTest.js'
|
|
8
|
+
import BleDeviceController, {
|
|
9
|
+
BleControllerOptions,
|
|
10
|
+
} from '../../impl/controllers/BleDeviceController.js'
|
|
11
|
+
|
|
12
|
+
export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
13
|
+
private static instance: SpyBleController
|
|
14
|
+
|
|
15
|
+
private static readonly uuid = this.generateId()
|
|
16
|
+
private static readonly namePrefix = this.generateId()
|
|
17
|
+
private static readonly discoveredUuid = this.generateId()
|
|
18
|
+
private static readonly charUuid = this.generateId()
|
|
19
|
+
private static readonly charValueToWrite = this.generateId()
|
|
20
|
+
private static readonly rssiIntervalMs = randomInt(1, 5)
|
|
21
|
+
private static readonly fakeError = this.generateId()
|
|
22
|
+
private static readonly fake400Error = `400 error: ${this.fakeError}`
|
|
23
|
+
private static readonly fake500Error = `500 error: ${this.fakeError}`
|
|
24
|
+
|
|
25
|
+
private static readonly charCallbacks = [
|
|
26
|
+
{
|
|
27
|
+
charUuid: this.generateId(),
|
|
28
|
+
charName: this.generateId(),
|
|
29
|
+
onData: async () => {},
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
charUuid: this.generateId(),
|
|
33
|
+
charName: this.generateId(),
|
|
34
|
+
onData: async () => {},
|
|
35
|
+
},
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
private static onConnected = (_peripheral: NativePeripheral) => {
|
|
39
|
+
this.wasConnected = true
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private static wasConnected: boolean
|
|
43
|
+
|
|
44
|
+
private static nativePeripheral: NativePeripheral = {
|
|
45
|
+
uuid: this.generateId(),
|
|
46
|
+
name: this.generateId(),
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
protected static async beforeAll() {
|
|
50
|
+
assert.isEqual(
|
|
51
|
+
BleDeviceController.waitAfterMs,
|
|
52
|
+
1000,
|
|
53
|
+
'Set incorrect waitAfterMs!'
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
protected static async beforeEach() {
|
|
58
|
+
await super.beforeEach()
|
|
59
|
+
|
|
60
|
+
BleDeviceController.waitAfterMs = 0
|
|
61
|
+
|
|
62
|
+
this.setFakeLibndx()
|
|
63
|
+
BleDeviceController.Class = SpyBleController
|
|
64
|
+
|
|
65
|
+
this.wasConnected = false
|
|
66
|
+
|
|
67
|
+
this.instance = await this.BleController()
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@test()
|
|
71
|
+
protected static async createsInstance() {
|
|
72
|
+
assert.isTruthy(this.instance, 'Failed to create instance!')
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@test()
|
|
76
|
+
protected static async connectCallsLibndxCreateBleBackend() {
|
|
77
|
+
await this.connect()
|
|
78
|
+
|
|
79
|
+
assert.isEqualDeep(
|
|
80
|
+
FakeLibndx.callsToCreateBleBackend[0],
|
|
81
|
+
{
|
|
82
|
+
deviceUuid: this.uuid,
|
|
83
|
+
},
|
|
84
|
+
'Did not call createBleBackend!'
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@test()
|
|
89
|
+
protected static async discoversUuidWhenDeviceUuidNotProvided() {
|
|
90
|
+
const instance = await this.BleControllerWithPrefix()
|
|
91
|
+
|
|
92
|
+
await this.connectWithDiscovery(instance)
|
|
93
|
+
|
|
94
|
+
const call = FakeLibndx.callsToDiscoverBleUuid[0]
|
|
95
|
+
|
|
96
|
+
assert.isEqual(
|
|
97
|
+
call?.namePrefix,
|
|
98
|
+
this.namePrefix,
|
|
99
|
+
'Did not call discoverBleUuid with deviceNamePrefix!'
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
assert.isFunction(
|
|
103
|
+
call?.onDiscovered,
|
|
104
|
+
'Did not pass an onDiscovered callback to discoverBleUuid!'
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@test()
|
|
109
|
+
protected static async doesNotDiscoverUuidWhenDeviceUuidProvided() {
|
|
110
|
+
await this.connect()
|
|
111
|
+
|
|
112
|
+
assert.isEqual(
|
|
113
|
+
FakeLibndx.callsToDiscoverBleUuid.length,
|
|
114
|
+
0,
|
|
115
|
+
'Should not call discoverBleUuid when deviceUuid is provided!'
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@test()
|
|
120
|
+
protected static async usesDiscoveredUuidToCreateBleBackend() {
|
|
121
|
+
const instance = await this.BleControllerWithPrefix()
|
|
122
|
+
|
|
123
|
+
await this.connectWithDiscovery(instance)
|
|
124
|
+
|
|
125
|
+
assert.isEqualDeep(
|
|
126
|
+
FakeLibndx.callsToCreateBleBackend[0],
|
|
127
|
+
{
|
|
128
|
+
deviceUuid: this.discoveredUuid,
|
|
129
|
+
},
|
|
130
|
+
'Did not create BLE backend with the discovered uuid!'
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@test()
|
|
135
|
+
protected static async usesDiscoveredUuidToStartBleBackend() {
|
|
136
|
+
const instance = await this.BleControllerWithPrefix()
|
|
137
|
+
|
|
138
|
+
await this.connectWithDiscovery(instance)
|
|
139
|
+
|
|
140
|
+
assert.isEqual(
|
|
141
|
+
FakeLibndx.callsToStartBleBackend[0]?.deviceUuid,
|
|
142
|
+
this.discoveredUuid,
|
|
143
|
+
'Did not start BLE backend with the discovered uuid!'
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
@test()
|
|
148
|
+
protected static async exposesDiscoveredUuid() {
|
|
149
|
+
const instance = await this.BleControllerWithPrefix()
|
|
150
|
+
|
|
151
|
+
await this.connectWithDiscovery(instance)
|
|
152
|
+
|
|
153
|
+
assert.isEqual(
|
|
154
|
+
instance.uuid,
|
|
155
|
+
this.discoveredUuid,
|
|
156
|
+
'Did not expose the discovered uuid!'
|
|
157
|
+
)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
@test()
|
|
161
|
+
protected static async createBleBackendThrowsOn400() {
|
|
162
|
+
this.setFake400Error()
|
|
163
|
+
|
|
164
|
+
await assert.doesThrowAsync(
|
|
165
|
+
async () => await this.instance.connect(),
|
|
166
|
+
this.fake400Error,
|
|
167
|
+
'Did not throw error!'
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
@test()
|
|
172
|
+
protected static async createBleBackendThrowsOn500() {
|
|
173
|
+
this.setFake500Error()
|
|
174
|
+
|
|
175
|
+
await assert.doesThrowAsync(
|
|
176
|
+
async () => await this.instance.connect(),
|
|
177
|
+
this.fake500Error,
|
|
178
|
+
'Did not throw error!'
|
|
179
|
+
)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@test()
|
|
183
|
+
protected static async connectCallsLibndxStartBleBackend() {
|
|
184
|
+
await this.connect()
|
|
185
|
+
|
|
186
|
+
const call = FakeLibndx.callsToStartBleBackend[0]
|
|
187
|
+
|
|
188
|
+
assert.isEqual(
|
|
189
|
+
call.deviceUuid,
|
|
190
|
+
this.uuid,
|
|
191
|
+
'Did not call startBleBackend with correct deviceUuid!'
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
assert.isEqual(
|
|
195
|
+
call.charCallbacks.length,
|
|
196
|
+
2,
|
|
197
|
+
'Did not call startBleBackend with charCallbacks!'
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
let i = 0
|
|
201
|
+
for (const charCallback of call.charCallbacks) {
|
|
202
|
+
assert.isEqual(
|
|
203
|
+
charCallback.charUuid,
|
|
204
|
+
this.charCallbacks[i].charUuid,
|
|
205
|
+
'Incorrect charUuid!'
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
assert.isEqual(
|
|
209
|
+
charCallback.charName,
|
|
210
|
+
this.charCallbacks[i].charName,
|
|
211
|
+
'Incorrect charName!'
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
assert.isFunction(
|
|
215
|
+
charCallback.onData,
|
|
216
|
+
'Callback is not a function!'
|
|
217
|
+
)
|
|
218
|
+
i++
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
@test()
|
|
223
|
+
protected static async startBleBackendThrowsOn400() {
|
|
224
|
+
//@ts-ignore
|
|
225
|
+
this.instance.createBleBackend = () => {}
|
|
226
|
+
|
|
227
|
+
this.setFake400Error()
|
|
228
|
+
|
|
229
|
+
await assert.doesThrowAsync(
|
|
230
|
+
async () => await this.instance.connect(),
|
|
231
|
+
this.fake400Error,
|
|
232
|
+
'Did not throw error!'
|
|
233
|
+
)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
@test()
|
|
237
|
+
protected static async startBleBackendThrowsOn500() {
|
|
238
|
+
//@ts-ignore
|
|
239
|
+
this.instance.createBleBackend = () => {}
|
|
240
|
+
|
|
241
|
+
this.setFake500Error()
|
|
242
|
+
|
|
243
|
+
await assert.doesThrowAsync(
|
|
244
|
+
async () => await this.instance.connect(),
|
|
245
|
+
this.fake500Error,
|
|
246
|
+
'Did not throw error!'
|
|
247
|
+
)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
@test()
|
|
251
|
+
protected static async connectWaitsForOnConnectedEvent() {
|
|
252
|
+
await this.connect()
|
|
253
|
+
|
|
254
|
+
assert.isTruthy(
|
|
255
|
+
this.wasConnected,
|
|
256
|
+
'Did not wait for onConnected event!'
|
|
257
|
+
)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
@test()
|
|
261
|
+
protected static async waitsAfterOnConnectedToDiscoverServices() {
|
|
262
|
+
const waitAfterMs = 20
|
|
263
|
+
BleDeviceController.waitAfterMs = waitAfterMs
|
|
264
|
+
|
|
265
|
+
const t0 = Date.now()
|
|
266
|
+
await this.connect()
|
|
267
|
+
const t1 = Date.now()
|
|
268
|
+
|
|
269
|
+
assert.isAbove(
|
|
270
|
+
t1 - t0,
|
|
271
|
+
100 + waitAfterMs * 0.8,
|
|
272
|
+
'Did not wait after on connected!'
|
|
273
|
+
)
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
@test()
|
|
277
|
+
protected static async writeCharacteristicCallsLibndxBinding() {
|
|
278
|
+
await this.writeCharacteristic()
|
|
279
|
+
|
|
280
|
+
assert.isEqualDeep(
|
|
281
|
+
FakeLibndx.callsToWriteBleCharacteristic[0],
|
|
282
|
+
{
|
|
283
|
+
deviceUuid: this.uuid,
|
|
284
|
+
charUuid: this.charUuid,
|
|
285
|
+
value: this.charValueToWrite,
|
|
286
|
+
},
|
|
287
|
+
'Did not call writeBleCharacteristic as expected!'
|
|
288
|
+
)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
@test()
|
|
292
|
+
protected static async writeCharacteristicThrowsOn400() {
|
|
293
|
+
this.setFake400Error()
|
|
294
|
+
|
|
295
|
+
await assert.doesThrowAsync(
|
|
296
|
+
async () => await this.writeCharacteristic(),
|
|
297
|
+
this.fake400Error,
|
|
298
|
+
'Did not throw error!'
|
|
299
|
+
)
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
@test()
|
|
303
|
+
protected static async writeCharacteristicThrowsOn500() {
|
|
304
|
+
this.setFake500Error()
|
|
305
|
+
|
|
306
|
+
await assert.doesThrowAsync(
|
|
307
|
+
async () => await this.writeCharacteristic(),
|
|
308
|
+
this.fake500Error,
|
|
309
|
+
'Did not throw error!'
|
|
310
|
+
)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
@test()
|
|
314
|
+
protected static async callsSetBleRssiInterval() {
|
|
315
|
+
await this.connect()
|
|
316
|
+
|
|
317
|
+
const { deviceUuid, intervalMs } =
|
|
318
|
+
FakeLibndx.callsToSetBleRssiInterval[0]
|
|
319
|
+
|
|
320
|
+
assert.isEqualDeep(
|
|
321
|
+
{ deviceUuid, intervalMs },
|
|
322
|
+
{
|
|
323
|
+
deviceUuid: this.uuid,
|
|
324
|
+
intervalMs: this.rssiIntervalMs,
|
|
325
|
+
},
|
|
326
|
+
'Did not call setBleRssiInterval as expected!'
|
|
327
|
+
)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
@test()
|
|
331
|
+
protected static async disconnectCallsLibndxStopBleBackend() {
|
|
332
|
+
await this.disconnect()
|
|
333
|
+
|
|
334
|
+
assert.isEqualDeep(
|
|
335
|
+
FakeLibndx.callsToStopBleBackend[0],
|
|
336
|
+
{
|
|
337
|
+
deviceUuid: this.uuid,
|
|
338
|
+
},
|
|
339
|
+
'Did not call stopBleBackend!'
|
|
340
|
+
)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
@test()
|
|
344
|
+
protected static async disconnectThrowsOn400() {
|
|
345
|
+
this.setFake400Error()
|
|
346
|
+
|
|
347
|
+
await assert.doesThrowAsync(
|
|
348
|
+
async () => await this.disconnect(),
|
|
349
|
+
this.fake400Error,
|
|
350
|
+
'Did not throw error!'
|
|
351
|
+
)
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
@test()
|
|
355
|
+
protected static async disconnectThrowsOn500() {
|
|
356
|
+
this.setFake500Error()
|
|
357
|
+
|
|
358
|
+
await assert.doesThrowAsync(
|
|
359
|
+
async () => await this.disconnect(),
|
|
360
|
+
this.fake500Error,
|
|
361
|
+
'Did not throw error!'
|
|
362
|
+
)
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
@test()
|
|
366
|
+
protected static async disconnectResetsConnectedFlag() {
|
|
367
|
+
await this.connect()
|
|
368
|
+
await this.disconnect()
|
|
369
|
+
|
|
370
|
+
assert.isFalse(
|
|
371
|
+
this.instance.getConnected(),
|
|
372
|
+
'Did not reset connected flag on disconnect!'
|
|
373
|
+
)
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
@test()
|
|
377
|
+
protected static async exposesPeriperalName() {
|
|
378
|
+
await this.connect()
|
|
379
|
+
|
|
380
|
+
assert.isEqual(
|
|
381
|
+
this.instance.name,
|
|
382
|
+
this.nativePeripheral.name,
|
|
383
|
+
'Did not set peripheral name!'
|
|
384
|
+
)
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
@test()
|
|
388
|
+
protected static async returnsNAIfNameNotAvailable() {
|
|
389
|
+
assert.isEqual(
|
|
390
|
+
this.instance.name,
|
|
391
|
+
'N/A',
|
|
392
|
+
'Did not set default name to N/A!'
|
|
393
|
+
)
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
@test()
|
|
397
|
+
protected static async throwsWithUnknownErrorIfNoError() {
|
|
398
|
+
this.setFake500ErrorWithoutError()
|
|
399
|
+
|
|
400
|
+
await assert.doesThrowAsync(
|
|
401
|
+
async () => await this.connect(),
|
|
402
|
+
'Unknown error',
|
|
403
|
+
'Did not throw error!'
|
|
404
|
+
)
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
private static async connect() {
|
|
408
|
+
const promise = this.instance.connect()
|
|
409
|
+
|
|
410
|
+
const startCall = FakeLibndx.callsToStartBleBackend[0]
|
|
411
|
+
startCall?.onConnected(this.nativePeripheral)
|
|
412
|
+
|
|
413
|
+
await promise
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
private static async connectWithDiscovery(instance: SpyBleController) {
|
|
417
|
+
const promise = instance.connect()
|
|
418
|
+
|
|
419
|
+
FakeLibndx.callsToDiscoverBleUuid[0]?.onDiscovered(this.discoveredUuid)
|
|
420
|
+
|
|
421
|
+
await this.waitForCall(() => FakeLibndx.callsToStartBleBackend[0])
|
|
422
|
+
|
|
423
|
+
FakeLibndx.callsToStartBleBackend[0]?.onConnected(this.nativePeripheral)
|
|
424
|
+
|
|
425
|
+
await promise
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
private static async waitForCall<T>(getCall: () => T) {
|
|
429
|
+
await new Promise<void>((resolve) => {
|
|
430
|
+
const check = () => {
|
|
431
|
+
if (getCall()) {
|
|
432
|
+
resolve()
|
|
433
|
+
} else {
|
|
434
|
+
setTimeout(check, 10)
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
check()
|
|
438
|
+
})
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
private static async writeCharacteristic() {
|
|
442
|
+
await this.instance.writeCharacteristic(
|
|
443
|
+
this.charUuid,
|
|
444
|
+
this.charValueToWrite
|
|
445
|
+
)
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
private static async disconnect() {
|
|
449
|
+
await this.instance.disconnect()
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
private static setFake400Error() {
|
|
453
|
+
FakeLibndx.fakeResult = {
|
|
454
|
+
status: 400,
|
|
455
|
+
error: this.fakeError,
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
private static setFake500Error() {
|
|
460
|
+
FakeLibndx.fakeResult = {
|
|
461
|
+
status: 500,
|
|
462
|
+
error: this.fakeError,
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
private static setFake500ErrorWithoutError() {
|
|
467
|
+
FakeLibndx.fakeResult = {
|
|
468
|
+
status: 500,
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
private static async BleController(
|
|
473
|
+
options?: Partial<BleControllerOptions>
|
|
474
|
+
) {
|
|
475
|
+
return (await BleDeviceController.Create({
|
|
476
|
+
deviceUuid: this.uuid,
|
|
477
|
+
charCallbacks: this.charCallbacks,
|
|
478
|
+
onConnected: this.onConnected,
|
|
479
|
+
rssiIntervalMs: this.rssiIntervalMs,
|
|
480
|
+
...options,
|
|
481
|
+
})) as SpyBleController
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
private static async BleControllerWithPrefix() {
|
|
485
|
+
return (await BleDeviceController.Create({
|
|
486
|
+
deviceNamePrefix: this.namePrefix,
|
|
487
|
+
charCallbacks: this.charCallbacks,
|
|
488
|
+
onConnected: this.onConnected,
|
|
489
|
+
rssiIntervalMs: this.rssiIntervalMs,
|
|
490
|
+
} as unknown as BleControllerOptions)) as SpyBleController
|
|
491
|
+
}
|
|
492
|
+
}
|