@neurodevs/node-lsl 20.0.0 → 22.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/README.md +6 -6
- package/build/__tests__/AbstractPackageTest.d.ts +2 -1
- package/build/__tests__/AbstractPackageTest.js +9 -7
- package/build/__tests__/AbstractPackageTest.js.map +1 -1
- package/build/__tests__/impl/{BleDeviceController.test.d.ts → BleGattController.test.d.ts} +3 -3
- package/build/__tests__/impl/{BleDeviceController.test.js → BleGattController.test.js} +65 -65
- package/build/__tests__/impl/BleGattController.test.js.map +1 -0
- package/build/__tests__/impl/BleObserverController.test.d.ts +22 -0
- package/build/__tests__/impl/BleObserverController.test.js +112 -0
- package/build/__tests__/impl/BleObserverController.test.js.map +1 -0
- package/build/__tests__/impl/{LslEventMarkerEmitter.test.d.ts → LslEventMarkerOutlet.test.d.ts} +3 -3
- package/build/__tests__/impl/{LslEventMarkerEmitter.test.js → LslEventMarkerOutlet.test.js} +35 -36
- package/build/__tests__/impl/LslEventMarkerOutlet.test.js.map +1 -0
- package/build/__tests__/impl/LslJsonOutlet.test.d.ts +14 -0
- package/build/__tests__/impl/LslJsonOutlet.test.js +118 -0
- package/build/__tests__/impl/LslJsonOutlet.test.js.map +1 -0
- package/build/__tests__/impl/LslStreamInfo.test.js +0 -1
- package/build/__tests__/impl/LslStreamInfo.test.js.map +1 -1
- package/build/__tests__/impl/LslStreamInlet.test.js +0 -1
- package/build/__tests__/impl/LslStreamInlet.test.js.map +1 -1
- package/build/__tests__/impl/LslStreamOutlet.test.js +0 -1
- package/build/__tests__/impl/LslStreamOutlet.test.js.map +1 -1
- package/build/__tests__/impl/LslWebSocketBridge.test.js +0 -1
- package/build/__tests__/impl/LslWebSocketBridge.test.js.map +1 -1
- package/build/__tests__/impl/UsbDeviceController.test.js.map +1 -1
- package/build/impl/{LslEventMarkerEmitter.d.ts → LslEventMarkerOutlet.d.ts} +6 -6
- package/build/impl/{LslEventMarkerEmitter.js → LslEventMarkerOutlet.js} +2 -2
- package/build/impl/LslEventMarkerOutlet.js.map +1 -0
- package/build/impl/LslJsonOutlet.d.ts +33 -0
- package/build/impl/LslJsonOutlet.js +44 -0
- package/build/impl/LslJsonOutlet.js.map +1 -0
- package/build/impl/LslStreamOutlet.d.ts +3 -4
- package/build/impl/controllers/{BleDeviceController.d.ts → BleGattController.d.ts} +10 -10
- package/build/impl/controllers/{BleDeviceController.js → BleGattController.js} +18 -18
- package/build/impl/controllers/BleGattController.js.map +1 -0
- package/build/impl/controllers/BleObserverController.d.ts +24 -0
- package/build/impl/controllers/BleObserverController.js +49 -0
- package/build/impl/controllers/BleObserverController.js.map +1 -0
- package/build/impl/controllers/UsbDeviceController.d.ts +9 -9
- package/build/impl/controllers/UsbDeviceController.js +7 -7
- package/build/impl/controllers/UsbDeviceController.js.map +1 -1
- package/build/index.d.ts +24 -16
- package/build/index.js +29 -19
- package/build/index.js.map +1 -1
- package/build/scripts/runEventMarkerOutlet.js +12 -0
- package/build/scripts/runEventMarkerOutlet.js.map +1 -0
- package/build/scripts/runMuse.js +2 -2
- package/build/scripts/runMuse.js.map +1 -1
- package/build/testDoubles/{BleController/FakeBleController.d.ts → BleGatt/FakeBleGatt.d.ts} +6 -6
- package/build/testDoubles/{BleController/FakeBleController.js → BleGatt/FakeBleGatt.js} +8 -8
- package/build/testDoubles/BleGatt/FakeBleGatt.js.map +1 -0
- package/build/testDoubles/{BleController/SpyBleController.d.ts → BleGatt/SpyBleGatt.d.ts} +4 -4
- package/build/testDoubles/{BleController/SpyBleController.js → BleGatt/SpyBleGatt.js} +3 -3
- package/build/testDoubles/BleGatt/SpyBleGatt.js.map +1 -0
- package/build/testDoubles/BleObserver/FakeBleObserver.d.ts +10 -0
- package/build/testDoubles/BleObserver/FakeBleObserver.js +20 -0
- package/build/testDoubles/BleObserver/FakeBleObserver.js.map +1 -0
- package/build/testDoubles/{LslEmitter/FakeLslEmitter.d.ts → EventMarkerOutlet/FakeEventMarkerOutlet.d.ts} +2 -2
- package/build/testDoubles/{LslEmitter/FakeLslEmitter.js → EventMarkerOutlet/FakeEventMarkerOutlet.js} +7 -7
- package/build/testDoubles/EventMarkerOutlet/FakeEventMarkerOutlet.js.map +1 -0
- package/build/testDoubles/{LslEmitter/SpyLslEmitter.d.ts → EventMarkerOutlet/SpyEventMarkerOutlet.d.ts} +3 -3
- package/build/testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.js +23 -0
- package/build/testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.js.map +1 -0
- package/build/testDoubles/{LslEmitter/ThrowingLslEmitter.d.ts → EventMarkerOutlet/ThrowingEventMarkerOutlet.d.ts} +2 -2
- package/build/testDoubles/{LslEmitter/ThrowingLslEmitter.js → EventMarkerOutlet/ThrowingEventMarkerOutlet.js} +2 -2
- package/build/testDoubles/EventMarkerOutlet/ThrowingEventMarkerOutlet.js.map +1 -0
- package/build/testDoubles/JsonOutlet/FakeJsonOutlet.d.ts +10 -0
- package/build/testDoubles/JsonOutlet/FakeJsonOutlet.js +20 -0
- package/build/testDoubles/JsonOutlet/FakeJsonOutlet.js.map +1 -0
- package/build/testDoubles/UsbDevice/FakeUsbDevice.d.ts +12 -0
- package/build/testDoubles/UsbDevice/FakeUsbDevice.js +25 -0
- package/build/testDoubles/UsbDevice/FakeUsbDevice.js.map +1 -0
- package/package.json +3 -3
- package/src/__tests__/AbstractPackageTest.ts +9 -7
- package/src/__tests__/impl/{BleDeviceController.test.ts → BleGattController.test.ts} +43 -43
- package/src/__tests__/impl/BleObserverController.test.ts +158 -0
- package/src/__tests__/impl/{LslEventMarkerEmitter.test.ts → LslEventMarkerOutlet.test.ts} +20 -19
- package/src/__tests__/impl/LslJsonOutlet.test.ts +135 -0
- package/src/__tests__/impl/LslStreamInfo.test.ts +0 -1
- package/src/__tests__/impl/LslStreamInlet.test.ts +0 -1
- package/src/__tests__/impl/LslStreamOutlet.test.ts +0 -1
- package/src/__tests__/impl/LslWebSocketBridge.test.ts +0 -1
- package/src/__tests__/impl/UsbDeviceController.test.ts +2 -2
- package/src/impl/{LslEventMarkerEmitter.ts → LslEventMarkerOutlet.ts} +8 -6
- package/src/impl/LslJsonOutlet.ts +87 -0
- package/src/impl/LslStreamOutlet.ts +7 -5
- package/src/impl/controllers/{BleDeviceController.ts → BleGattController.ts} +23 -28
- package/src/impl/controllers/BleObserverController.ts +85 -0
- package/src/impl/controllers/UsbDeviceController.ts +14 -16
- package/src/index.ts +40 -24
- package/src/scripts/{runLslEmitter.ts → runEventMarkerOutlet.ts} +5 -5
- package/src/scripts/runMuse.ts +2 -2
- package/src/testDoubles/{BleController/FakeBleController.ts → BleGatt/FakeBleGatt.ts} +14 -14
- package/src/testDoubles/{BleController/SpyBleController.ts → BleGatt/SpyBleGatt.ts} +5 -5
- package/src/testDoubles/BleObserver/FakeBleObserver.ts +28 -0
- package/src/testDoubles/{LslEmitter/FakeLslEmitter.ts → EventMarkerOutlet/FakeEventMarkerOutlet.ts} +8 -8
- package/src/testDoubles/{LslEmitter/SpyLslEmitter.ts → EventMarkerOutlet/SpyEventMarkerOutlet.ts} +7 -7
- package/src/testDoubles/{LslEmitter/ThrowingLslEmitter.ts → EventMarkerOutlet/ThrowingEventMarkerOutlet.ts} +3 -3
- package/src/testDoubles/JsonOutlet/FakeJsonOutlet.ts +25 -0
- package/src/testDoubles/UsbDevice/FakeUsbDevice.ts +34 -0
- package/build/__tests__/impl/BleDeviceController.test.js.map +0 -1
- package/build/__tests__/impl/LslEventMarkerEmitter.test.js.map +0 -1
- package/build/impl/LslEventMarkerEmitter.js.map +0 -1
- package/build/impl/controllers/BleDeviceController.js.map +0 -1
- package/build/scripts/runLslEmitter.js +0 -12
- package/build/scripts/runLslEmitter.js.map +0 -1
- package/build/testDoubles/BleController/FakeBleController.js.map +0 -1
- package/build/testDoubles/BleController/SpyBleController.js.map +0 -1
- package/build/testDoubles/LslEmitter/FakeLslEmitter.js.map +0 -1
- package/build/testDoubles/LslEmitter/SpyLslEmitter.js +0 -23
- package/build/testDoubles/LslEmitter/SpyLslEmitter.js.map +0 -1
- package/build/testDoubles/LslEmitter/ThrowingLslEmitter.js.map +0 -1
- package/build/testDoubles/UsbController/FakeUsbController.d.ts +0 -12
- package/build/testDoubles/UsbController/FakeUsbController.js +0 -25
- package/build/testDoubles/UsbController/FakeUsbController.js.map +0 -1
- package/src/testDoubles/UsbController/FakeUsbController.ts +0 -34
- /package/build/scripts/{runLslEmitter.d.ts → runEventMarkerOutlet.d.ts} +0 -0
|
@@ -3,14 +3,14 @@ import { randomInt } from 'node:crypto'
|
|
|
3
3
|
import { test, assert } from '@neurodevs/node-tdd'
|
|
4
4
|
import { FakeLibndx, NativePeripheral } from '@neurodevs/ndx-native'
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import SpyBleGatt from '../../testDoubles/BleGatt/SpyBleGatt.js'
|
|
7
7
|
import AbstractPackageTest from '../AbstractPackageTest.js'
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
} from '../../impl/controllers/
|
|
8
|
+
import BleGattController, {
|
|
9
|
+
BleGattOptions,
|
|
10
|
+
} from '../../impl/controllers/BleGattController.js'
|
|
11
11
|
|
|
12
|
-
export default class
|
|
13
|
-
private static instance:
|
|
12
|
+
export default class BleGattControllerTest extends AbstractPackageTest {
|
|
13
|
+
private static instance: SpyBleGatt
|
|
14
14
|
|
|
15
15
|
private static readonly uuid = this.generateId()
|
|
16
16
|
private static readonly namePrefix = this.generateId()
|
|
@@ -56,7 +56,7 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
56
56
|
|
|
57
57
|
protected static async beforeAll() {
|
|
58
58
|
assert.isEqual(
|
|
59
|
-
|
|
59
|
+
BleGattController.waitAfterMs,
|
|
60
60
|
1000,
|
|
61
61
|
'Set incorrect waitAfterMs!'
|
|
62
62
|
)
|
|
@@ -65,12 +65,12 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
65
65
|
protected static async beforeEach() {
|
|
66
66
|
await super.beforeEach()
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
68
|
+
BleGattController.waitAfterMs = 0
|
|
69
|
+
BleGattController.Class = SpyBleGatt
|
|
70
70
|
|
|
71
71
|
this.wasConnected = false
|
|
72
72
|
|
|
73
|
-
this.instance = this.
|
|
73
|
+
this.instance = this.BleGattController()
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
@test()
|
|
@@ -83,17 +83,17 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
83
83
|
await this.connect()
|
|
84
84
|
|
|
85
85
|
assert.isEqualDeep(
|
|
86
|
-
FakeLibndx.
|
|
86
|
+
FakeLibndx.callsToCreateBleGattBackend[0],
|
|
87
87
|
{
|
|
88
88
|
deviceUuid: this.uuid,
|
|
89
89
|
},
|
|
90
|
-
'Did not call
|
|
90
|
+
'Did not call createBleGattBackend!'
|
|
91
91
|
)
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
@test()
|
|
95
95
|
protected static async discoversUuidWhenDeviceUuidNotProvided() {
|
|
96
|
-
const instance = await this.
|
|
96
|
+
const instance = await this.BleGattControllerWithPrefix()
|
|
97
97
|
|
|
98
98
|
await this.connectWithDiscovery(instance)
|
|
99
99
|
|
|
@@ -124,12 +124,12 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
124
124
|
|
|
125
125
|
@test()
|
|
126
126
|
protected static async usesDiscoveredUuidToCreateBleBackend() {
|
|
127
|
-
const instance = await this.
|
|
127
|
+
const instance = await this.BleGattControllerWithPrefix()
|
|
128
128
|
|
|
129
129
|
await this.connectWithDiscovery(instance)
|
|
130
130
|
|
|
131
131
|
assert.isEqualDeep(
|
|
132
|
-
FakeLibndx.
|
|
132
|
+
FakeLibndx.callsToCreateBleGattBackend[0],
|
|
133
133
|
{
|
|
134
134
|
deviceUuid: this.discoveredUuid,
|
|
135
135
|
},
|
|
@@ -139,12 +139,12 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
139
139
|
|
|
140
140
|
@test()
|
|
141
141
|
protected static async usesDiscoveredUuidToStartBleBackend() {
|
|
142
|
-
const instance = await this.
|
|
142
|
+
const instance = await this.BleGattControllerWithPrefix()
|
|
143
143
|
|
|
144
144
|
await this.connectWithDiscovery(instance)
|
|
145
145
|
|
|
146
146
|
assert.isEqual(
|
|
147
|
-
FakeLibndx.
|
|
147
|
+
FakeLibndx.callsToStartBleGattBackend[0]?.deviceUuid,
|
|
148
148
|
this.discoveredUuid,
|
|
149
149
|
'Did not start BLE backend with the discovered uuid!'
|
|
150
150
|
)
|
|
@@ -152,7 +152,7 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
152
152
|
|
|
153
153
|
@test()
|
|
154
154
|
protected static async exposesDiscoveredUuid() {
|
|
155
|
-
const instance = await this.
|
|
155
|
+
const instance = await this.BleGattControllerWithPrefix()
|
|
156
156
|
|
|
157
157
|
await this.connectWithDiscovery(instance)
|
|
158
158
|
|
|
@@ -189,18 +189,18 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
189
189
|
protected static async connectCallsLibndxStartBleBackend() {
|
|
190
190
|
await this.connect()
|
|
191
191
|
|
|
192
|
-
const call = FakeLibndx.
|
|
192
|
+
const call = FakeLibndx.callsToStartBleGattBackend[0]
|
|
193
193
|
|
|
194
194
|
assert.isEqual(
|
|
195
195
|
call.deviceUuid,
|
|
196
196
|
this.uuid,
|
|
197
|
-
'Did not call
|
|
197
|
+
'Did not call startBleGattBackend with correct deviceUuid!'
|
|
198
198
|
)
|
|
199
199
|
|
|
200
200
|
assert.isEqual(
|
|
201
201
|
call.charCallbacks.length,
|
|
202
202
|
2,
|
|
203
|
-
'Did not call
|
|
203
|
+
'Did not call startBleGattBackend with charCallbacks!'
|
|
204
204
|
)
|
|
205
205
|
|
|
206
206
|
let i = 0
|
|
@@ -228,7 +228,7 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
228
228
|
@test()
|
|
229
229
|
protected static async startBleBackendThrowsOn400() {
|
|
230
230
|
//@ts-ignore
|
|
231
|
-
this.instance.
|
|
231
|
+
this.instance.createBleGattBackend = () => {}
|
|
232
232
|
|
|
233
233
|
this.setFake400Error()
|
|
234
234
|
|
|
@@ -242,7 +242,7 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
242
242
|
@test()
|
|
243
243
|
protected static async startBleBackendThrowsOn500() {
|
|
244
244
|
//@ts-ignore
|
|
245
|
-
this.instance.
|
|
245
|
+
this.instance.createBleGattBackend = () => {}
|
|
246
246
|
|
|
247
247
|
this.setFake500Error()
|
|
248
248
|
|
|
@@ -266,7 +266,7 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
266
266
|
@test()
|
|
267
267
|
protected static async waitsAfterOnConnectedToDiscoverServices() {
|
|
268
268
|
const waitAfterMs = 20
|
|
269
|
-
|
|
269
|
+
BleGattController.waitAfterMs = waitAfterMs
|
|
270
270
|
|
|
271
271
|
await this.connect()
|
|
272
272
|
|
|
@@ -281,13 +281,13 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
281
281
|
await this.writeCharacteristic()
|
|
282
282
|
|
|
283
283
|
assert.isEqualDeep(
|
|
284
|
-
FakeLibndx.
|
|
284
|
+
FakeLibndx.callsToWriteBleGattChar[0],
|
|
285
285
|
{
|
|
286
286
|
deviceUuid: this.uuid,
|
|
287
287
|
charUuid: this.charUuid,
|
|
288
288
|
value: this.charValueToWrite,
|
|
289
289
|
},
|
|
290
|
-
'Did not call
|
|
290
|
+
'Did not call writeBleGattChar as expected!'
|
|
291
291
|
)
|
|
292
292
|
}
|
|
293
293
|
|
|
@@ -318,12 +318,12 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
318
318
|
await this.subscribeCharacteristics()
|
|
319
319
|
|
|
320
320
|
assert.isEqualDeep(
|
|
321
|
-
FakeLibndx.
|
|
321
|
+
FakeLibndx.callsToRegisterBleGattCharCallbacks[0],
|
|
322
322
|
{
|
|
323
323
|
deviceUuid: this.uuid,
|
|
324
324
|
charCallbacks: this.extraCharCallbacks,
|
|
325
325
|
},
|
|
326
|
-
'Did not call
|
|
326
|
+
'Did not call registerBleGattCharCallbacks as expected!'
|
|
327
327
|
)
|
|
328
328
|
}
|
|
329
329
|
|
|
@@ -354,7 +354,7 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
354
354
|
await this.connect()
|
|
355
355
|
|
|
356
356
|
const { deviceUuid, intervalMs } =
|
|
357
|
-
FakeLibndx.
|
|
357
|
+
FakeLibndx.callsToStartBleGattRssiPolling[0]
|
|
358
358
|
|
|
359
359
|
assert.isEqualDeep(
|
|
360
360
|
{ deviceUuid, intervalMs },
|
|
@@ -362,7 +362,7 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
362
362
|
deviceUuid: this.uuid,
|
|
363
363
|
intervalMs: this.rssiIntervalMs,
|
|
364
364
|
},
|
|
365
|
-
'Did not call
|
|
365
|
+
'Did not call startBleGattRssiPolling as expected!'
|
|
366
366
|
)
|
|
367
367
|
}
|
|
368
368
|
|
|
@@ -371,11 +371,11 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
371
371
|
await this.disconnect()
|
|
372
372
|
|
|
373
373
|
assert.isEqualDeep(
|
|
374
|
-
FakeLibndx.
|
|
374
|
+
FakeLibndx.callsToStopBleGattBackend[0],
|
|
375
375
|
{
|
|
376
376
|
deviceUuid: this.uuid,
|
|
377
377
|
},
|
|
378
|
-
'Did not call
|
|
378
|
+
'Did not call stopBleGattBackend!'
|
|
379
379
|
)
|
|
380
380
|
}
|
|
381
381
|
|
|
@@ -446,20 +446,22 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
446
446
|
private static async connect() {
|
|
447
447
|
const promise = this.instance.connect()
|
|
448
448
|
|
|
449
|
-
const startCall = FakeLibndx.
|
|
449
|
+
const startCall = FakeLibndx.callsToStartBleGattBackend[0]
|
|
450
450
|
startCall?.onConnected(this.nativePeripheral)
|
|
451
451
|
|
|
452
452
|
await promise
|
|
453
453
|
}
|
|
454
454
|
|
|
455
|
-
private static async connectWithDiscovery(instance:
|
|
455
|
+
private static async connectWithDiscovery(instance: SpyBleGatt) {
|
|
456
456
|
const promise = instance.connect()
|
|
457
457
|
|
|
458
458
|
FakeLibndx.callsToDiscoverBleUuid[0]?.onDiscovered(this.discoveredUuid)
|
|
459
459
|
|
|
460
|
-
await this.waitForCall(() => FakeLibndx.
|
|
460
|
+
await this.waitForCall(() => FakeLibndx.callsToStartBleGattBackend[0])
|
|
461
461
|
|
|
462
|
-
FakeLibndx.
|
|
462
|
+
FakeLibndx.callsToStartBleGattBackend[0]?.onConnected(
|
|
463
|
+
this.nativePeripheral
|
|
464
|
+
)
|
|
463
465
|
|
|
464
466
|
await promise
|
|
465
467
|
}
|
|
@@ -512,20 +514,18 @@ export default class BleDeviceControllerTest extends AbstractPackageTest {
|
|
|
512
514
|
}
|
|
513
515
|
}
|
|
514
516
|
|
|
515
|
-
private static
|
|
516
|
-
|
|
517
|
-
) {
|
|
518
|
-
return BleDeviceController.Create({
|
|
517
|
+
private static BleGattController(options?: Partial<BleGattOptions>) {
|
|
518
|
+
return BleGattController.Create({
|
|
519
519
|
deviceUuid: this.uuid,
|
|
520
520
|
charCallbacks: this.charCallbacks,
|
|
521
521
|
onConnected: this.onConnected,
|
|
522
522
|
rssiIntervalMs: this.rssiIntervalMs,
|
|
523
523
|
...options,
|
|
524
|
-
}) as
|
|
524
|
+
}) as SpyBleGatt
|
|
525
525
|
}
|
|
526
526
|
|
|
527
|
-
private static
|
|
528
|
-
return this.
|
|
527
|
+
private static BleGattControllerWithPrefix() {
|
|
528
|
+
return this.BleGattController({
|
|
529
529
|
deviceNamePrefix: this.namePrefix,
|
|
530
530
|
deviceUuid: undefined,
|
|
531
531
|
})
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { test, assert } from '@neurodevs/node-tdd'
|
|
2
|
+
|
|
3
|
+
import BleObserverController, {
|
|
4
|
+
BleObserver,
|
|
5
|
+
} from '../../impl/controllers/BleObserverController.js'
|
|
6
|
+
import AbstractPackageTest from '../AbstractPackageTest.js'
|
|
7
|
+
import { FakeLibndx } from '@neurodevs/ndx-native'
|
|
8
|
+
|
|
9
|
+
export default class BleObserverControllerTest extends AbstractPackageTest {
|
|
10
|
+
private static instance: BleObserver
|
|
11
|
+
private static passedAdvertisements: PassedAdvertisement[]
|
|
12
|
+
|
|
13
|
+
private static readonly fakeError = this.generateId()
|
|
14
|
+
|
|
15
|
+
private static readonly data = Buffer.from([0x01, 0x02, 0x03])
|
|
16
|
+
private static readonly length = 3
|
|
17
|
+
private static readonly timestampSec = 1234.5
|
|
18
|
+
|
|
19
|
+
protected static async beforeEach() {
|
|
20
|
+
await super.beforeEach()
|
|
21
|
+
|
|
22
|
+
this.passedAdvertisements = []
|
|
23
|
+
|
|
24
|
+
this.instance = this.BleObserverController()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@test()
|
|
28
|
+
protected static async createsInstance() {
|
|
29
|
+
assert.isTruthy(this.instance, 'Failed to create instance!')
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@test()
|
|
33
|
+
protected static async startObservingCreatesBleObserverBackend() {
|
|
34
|
+
await this.startObserving()
|
|
35
|
+
|
|
36
|
+
assert.isEqualDeep(FakeLibndx.callsToCreateBleObserver[0], {
|
|
37
|
+
deviceUuid: this.deviceUuid,
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@test()
|
|
42
|
+
protected static async startObservingStartsBleObserverBackend() {
|
|
43
|
+
await this.startObserving()
|
|
44
|
+
|
|
45
|
+
const { deviceUuid, onAdvertisement } =
|
|
46
|
+
FakeLibndx.callsToStartBleObserver[0]
|
|
47
|
+
|
|
48
|
+
assert.isEqual(
|
|
49
|
+
deviceUuid,
|
|
50
|
+
this.deviceUuid,
|
|
51
|
+
'Did not pass deviceUuid to startBleObserverBackend!'
|
|
52
|
+
)
|
|
53
|
+
assert.isFunction(
|
|
54
|
+
onAdvertisement,
|
|
55
|
+
'Did not pass onAdvertisement to startBleObserverBackend!'
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@test()
|
|
60
|
+
protected static async passesExpectedArgsToOnAdvertisement() {
|
|
61
|
+
await this.startObserving()
|
|
62
|
+
|
|
63
|
+
FakeLibndx.callsToStartBleObserver[0]?.onAdvertisement(
|
|
64
|
+
this.data,
|
|
65
|
+
this.length,
|
|
66
|
+
this.timestampSec
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
assert.isEqualDeep(
|
|
70
|
+
this.passedAdvertisements[0],
|
|
71
|
+
{
|
|
72
|
+
data: this.data,
|
|
73
|
+
length: this.length,
|
|
74
|
+
timestampSec: this.timestampSec,
|
|
75
|
+
},
|
|
76
|
+
'Did not pass expected args to onAdvertisement!'
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@test()
|
|
81
|
+
protected static async stopObservingStopsBleObserverBackend() {
|
|
82
|
+
await this.stopObserving()
|
|
83
|
+
|
|
84
|
+
assert.isEqualDeep(FakeLibndx.callsToStopBleObserver[0], {
|
|
85
|
+
deviceUuid: this.deviceUuid,
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@test()
|
|
90
|
+
protected static async createBleObserverBackendThrowsOnError() {
|
|
91
|
+
this.setFakeErrorResult()
|
|
92
|
+
|
|
93
|
+
//@ts-ignore
|
|
94
|
+
this.instance.startBleObserverBackend = () => {}
|
|
95
|
+
|
|
96
|
+
await assert.doesThrowAsync(
|
|
97
|
+
async () => await this.startObserving(),
|
|
98
|
+
this.fakeError,
|
|
99
|
+
'Did not throw error!'
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@test()
|
|
104
|
+
protected static async startObservingThrowsOnError() {
|
|
105
|
+
this.setFakeErrorResult()
|
|
106
|
+
|
|
107
|
+
await assert.doesThrowAsync(
|
|
108
|
+
async () => await this.startObserving(),
|
|
109
|
+
this.fakeError,
|
|
110
|
+
'Did not throw error!'
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@test()
|
|
115
|
+
protected static async stopObservingThrowsOnError() {
|
|
116
|
+
this.setFakeErrorResult()
|
|
117
|
+
|
|
118
|
+
await assert.doesThrowAsync(
|
|
119
|
+
async () => await this.stopObserving(),
|
|
120
|
+
this.fakeError,
|
|
121
|
+
'Did not throw error!'
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private static setFakeErrorResult() {
|
|
126
|
+
FakeLibndx.fakeResult = {
|
|
127
|
+
status: 400,
|
|
128
|
+
error: this.fakeError,
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private static async startObserving() {
|
|
133
|
+
await this.instance.startObserving()
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
private static async stopObserving() {
|
|
137
|
+
await this.instance.stopObserving()
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private static BleObserverController() {
|
|
141
|
+
return BleObserverController.Create({
|
|
142
|
+
deviceUuid: this.deviceUuid,
|
|
143
|
+
onAdvertisement: (
|
|
144
|
+
data: Buffer,
|
|
145
|
+
length: number,
|
|
146
|
+
timestampSec: number
|
|
147
|
+
) => {
|
|
148
|
+
this.passedAdvertisements.push({ data, length, timestampSec })
|
|
149
|
+
},
|
|
150
|
+
})
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
type PassedAdvertisement = {
|
|
155
|
+
data: Buffer
|
|
156
|
+
length: number
|
|
157
|
+
timestampSec: number
|
|
158
|
+
}
|
|
@@ -2,26 +2,25 @@ import { randomInt } from 'node:crypto'
|
|
|
2
2
|
|
|
3
3
|
import { assert, test } from '@neurodevs/node-tdd'
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import LslEventMarkerOutlet, {
|
|
6
6
|
EmitOptions,
|
|
7
|
-
} from '../../impl/
|
|
7
|
+
} from '../../impl/LslEventMarkerOutlet.js'
|
|
8
8
|
import { LslOutletOptions } from '../../impl/LslStreamOutlet.js'
|
|
9
|
-
import
|
|
9
|
+
import SpyEventMarkerOutlet from '../../testDoubles/EventMarkerOutlet/SpyEventMarkerOutlet.js'
|
|
10
10
|
import generateRandomOutletOptions from '../../testDoubles/generateRandomOutletOptions.js'
|
|
11
11
|
import FakeLslOutlet from '../../testDoubles/LslOutlet/FakeLslOutlet.js'
|
|
12
12
|
import AbstractPackageTest from '../AbstractPackageTest.js'
|
|
13
13
|
|
|
14
|
-
export default class
|
|
15
|
-
private static instance:
|
|
14
|
+
export default class EventMarkerOutletTest extends AbstractPackageTest {
|
|
15
|
+
private static instance: SpyEventMarkerOutlet
|
|
16
16
|
|
|
17
17
|
protected static async beforeEach() {
|
|
18
18
|
await super.beforeEach()
|
|
19
19
|
|
|
20
|
-
this.setFakeLiblsl()
|
|
21
20
|
this.setFakeLslOutlet()
|
|
22
|
-
this.
|
|
21
|
+
this.setSpyEventMarkerOutlet()
|
|
23
22
|
|
|
24
|
-
this.instance = await this.
|
|
23
|
+
this.instance = await this.LslEventMarkerOutlet()
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
private static readonly markerName = this.generateId()
|
|
@@ -68,7 +67,7 @@ export default class EventMarkerEmitterTest extends AbstractPackageTest {
|
|
|
68
67
|
@test()
|
|
69
68
|
protected static async canOverrideDefaultOptions() {
|
|
70
69
|
const options = generateRandomOutletOptions()
|
|
71
|
-
await this.
|
|
70
|
+
await this.LslEventMarkerOutlet(options)
|
|
72
71
|
|
|
73
72
|
assert.isEqualDeep(FakeLslOutlet.callsToConstructor[1], options)
|
|
74
73
|
}
|
|
@@ -86,7 +85,7 @@ export default class EventMarkerEmitterTest extends AbstractPackageTest {
|
|
|
86
85
|
'Pushed the wrong marker!'
|
|
87
86
|
)
|
|
88
87
|
|
|
89
|
-
assert.isEqual(this.instance.
|
|
88
|
+
assert.isEqual(this.instance.totalWaitAfterMs, marker.waitAfterMs)
|
|
90
89
|
}
|
|
91
90
|
|
|
92
91
|
@test()
|
|
@@ -96,7 +95,7 @@ export default class EventMarkerEmitterTest extends AbstractPackageTest {
|
|
|
96
95
|
assert.isEqual(FakeLslOutlet.callsToPushSample.length, 2)
|
|
97
96
|
|
|
98
97
|
assert.isEqual(
|
|
99
|
-
this.instance.
|
|
98
|
+
this.instance.totalWaitAfterMs,
|
|
100
99
|
markers[0].waitAfterMs + markers[1].waitAfterMs
|
|
101
100
|
)
|
|
102
101
|
}
|
|
@@ -104,7 +103,7 @@ export default class EventMarkerEmitterTest extends AbstractPackageTest {
|
|
|
104
103
|
@test('interrupts on first marker', 1)
|
|
105
104
|
@test('interrupts on second marker', 2)
|
|
106
105
|
@test('interrupts on third marker', 3)
|
|
107
|
-
protected static async
|
|
106
|
+
protected static async outletIsInterruptable(bailIdx: number) {
|
|
108
107
|
let hitCount = 0
|
|
109
108
|
|
|
110
109
|
this.streamOutlet.pushSample = () => {
|
|
@@ -170,7 +169,7 @@ export default class EventMarkerEmitterTest extends AbstractPackageTest {
|
|
|
170
169
|
|
|
171
170
|
@test()
|
|
172
171
|
protected static async emitWaitsForMsIfPassed() {
|
|
173
|
-
|
|
172
|
+
SpyEventMarkerOutlet.shouldCallWaitOnSuper = true
|
|
174
173
|
|
|
175
174
|
const waitAfterMs = 10
|
|
176
175
|
|
|
@@ -217,7 +216,7 @@ export default class EventMarkerEmitterTest extends AbstractPackageTest {
|
|
|
217
216
|
|
|
218
217
|
@test()
|
|
219
218
|
protected static async sourceIdIsUniqueAcrossInstances() {
|
|
220
|
-
const instance = await this.
|
|
219
|
+
const instance = await this.LslEventMarkerOutlet()
|
|
221
220
|
|
|
222
221
|
assert.isNotEqual(
|
|
223
222
|
instance['outlet'].sourceId,
|
|
@@ -237,7 +236,7 @@ export default class EventMarkerEmitterTest extends AbstractPackageTest {
|
|
|
237
236
|
|
|
238
237
|
@test()
|
|
239
238
|
protected static async emitManyThrowsIfCalledWhileAlreadyRunning() {
|
|
240
|
-
void
|
|
239
|
+
void EventMarkerOutletTest.emitManyOnce()
|
|
241
240
|
|
|
242
241
|
await assert.doesThrowAsync(async () => {
|
|
243
242
|
await this.emitManyFor(5, 1)
|
|
@@ -306,13 +305,15 @@ export default class EventMarkerEmitterTest extends AbstractPackageTest {
|
|
|
306
305
|
}
|
|
307
306
|
|
|
308
307
|
private static async setupOutlet() {
|
|
309
|
-
|
|
310
|
-
this.instance = await this.
|
|
308
|
+
LslEventMarkerOutlet.Class = LslEventMarkerOutlet as any
|
|
309
|
+
this.instance = await this.LslEventMarkerOutlet()
|
|
311
310
|
}
|
|
312
311
|
|
|
313
|
-
private static async
|
|
312
|
+
private static async LslEventMarkerOutlet(
|
|
314
313
|
options?: Partial<LslOutletOptions>
|
|
315
314
|
) {
|
|
316
|
-
return (await
|
|
315
|
+
return (await LslEventMarkerOutlet.Create(
|
|
316
|
+
options
|
|
317
|
+
)) as SpyEventMarkerOutlet
|
|
317
318
|
}
|
|
318
319
|
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { test, assert } from '@neurodevs/node-tdd'
|
|
2
|
+
|
|
3
|
+
import LslJsonOutlet, {
|
|
4
|
+
JsonOutlet,
|
|
5
|
+
JsonOutletOptions,
|
|
6
|
+
} from '../../impl/LslJsonOutlet.js'
|
|
7
|
+
import FakeLslOutlet from '../../testDoubles/LslOutlet/FakeLslOutlet.js'
|
|
8
|
+
import AbstractPackageTest from '../AbstractPackageTest.js'
|
|
9
|
+
|
|
10
|
+
export default class LslJsonOutletTest extends AbstractPackageTest {
|
|
11
|
+
private static instance: JsonOutlet
|
|
12
|
+
|
|
13
|
+
protected static async beforeEach() {
|
|
14
|
+
await super.beforeEach()
|
|
15
|
+
|
|
16
|
+
this.setFakeLslOutlet()
|
|
17
|
+
|
|
18
|
+
LslJsonOutlet.backupIdCounter = 0
|
|
19
|
+
|
|
20
|
+
this.instance = await this.LslJsonOutlet()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@test()
|
|
24
|
+
protected static async createsInstance() {
|
|
25
|
+
assert.isTruthy(this.instance, 'Failed to create instance!')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@test()
|
|
29
|
+
protected static async loadsWithJsonSpecificOptionsOnce() {
|
|
30
|
+
assert.isEqualDeep(FakeLslOutlet.callsToConstructor[0], {
|
|
31
|
+
name: `JSON (json-1)`,
|
|
32
|
+
type: 'JSON',
|
|
33
|
+
sourceId: 'json-1',
|
|
34
|
+
channelNames: ['JSON'],
|
|
35
|
+
channelFormat: 'string',
|
|
36
|
+
sampleRateHz: 0,
|
|
37
|
+
chunkSize: 1,
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@test()
|
|
42
|
+
protected static async loadsWithJsonSpecificOptionsTwice() {
|
|
43
|
+
await this.LslJsonOutlet()
|
|
44
|
+
|
|
45
|
+
assert.isEqualDeep(FakeLslOutlet.callsToConstructor[1], {
|
|
46
|
+
name: `JSON (json-2)`,
|
|
47
|
+
type: 'JSON',
|
|
48
|
+
sourceId: 'json-2',
|
|
49
|
+
channelNames: ['JSON'],
|
|
50
|
+
channelFormat: 'string',
|
|
51
|
+
sampleRateHz: 0,
|
|
52
|
+
chunkSize: 1,
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@test()
|
|
57
|
+
protected static async canOverrideDefaultOptions() {
|
|
58
|
+
const channelName = this.generateId()
|
|
59
|
+
|
|
60
|
+
await this.LslJsonOutlet({
|
|
61
|
+
name: this.name_,
|
|
62
|
+
type: this.type,
|
|
63
|
+
sourceId: this.sourceId,
|
|
64
|
+
channelName,
|
|
65
|
+
sampleRateHz: this.sampleRateHz,
|
|
66
|
+
chunkSize: this.chunkSize,
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
assert.isEqualDeep(FakeLslOutlet.callsToConstructor[1], {
|
|
70
|
+
name: this.name_,
|
|
71
|
+
type: this.type,
|
|
72
|
+
sourceId: this.sourceId,
|
|
73
|
+
channelNames: [channelName],
|
|
74
|
+
channelFormat: 'string',
|
|
75
|
+
sampleRateHz: this.sampleRateHz,
|
|
76
|
+
chunkSize: this.chunkSize,
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@test()
|
|
81
|
+
protected static async pushJsonSerializesAndPushesToLslOutlet() {
|
|
82
|
+
const data = { [this.generateId()]: this.generateId() }
|
|
83
|
+
|
|
84
|
+
this.instance.pushJson(data)
|
|
85
|
+
|
|
86
|
+
assert.isEqualDeep(FakeLslOutlet.callsToPushSample[0]?.sample, [
|
|
87
|
+
JSON.stringify(data),
|
|
88
|
+
])
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@test()
|
|
92
|
+
protected static async destroyCallsDestroyOnLslOutlet() {
|
|
93
|
+
this.instance.destroy()
|
|
94
|
+
|
|
95
|
+
assert.isEqual(
|
|
96
|
+
FakeLslOutlet.numCallsToDestroy,
|
|
97
|
+
1,
|
|
98
|
+
'Did not call destroy on outlet!'
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@test()
|
|
103
|
+
protected static async pushJsonThrowsIfPayloadExceedsMaxBytesPerSample() {
|
|
104
|
+
const maxBytesPerSample = 10
|
|
105
|
+
|
|
106
|
+
const instance = await this.LslJsonOutlet({ maxBytesPerSample })
|
|
107
|
+
const data = { [this.generateId()]: this.generateId() }
|
|
108
|
+
|
|
109
|
+
assert.doesThrow(
|
|
110
|
+
() => instance.pushJson(data),
|
|
111
|
+
`Payload of ${JSON.stringify(data).length} bytes exceeds maxBytesPerSample of ${maxBytesPerSample}!`
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
@test()
|
|
116
|
+
protected static async countsUtf8BytesNotCharacters() {
|
|
117
|
+
const data = { emoji: '😀😀😀' }
|
|
118
|
+
|
|
119
|
+
const json = JSON.stringify(data)
|
|
120
|
+
const totalBytes = Buffer.byteLength(json)
|
|
121
|
+
|
|
122
|
+
const maxBytesPerSample = json.length
|
|
123
|
+
|
|
124
|
+
const instance = await this.LslJsonOutlet({ maxBytesPerSample })
|
|
125
|
+
|
|
126
|
+
assert.doesThrow(
|
|
127
|
+
() => instance.pushJson(data),
|
|
128
|
+
`Payload of ${totalBytes} bytes exceeds maxBytesPerSample of ${maxBytesPerSample}!`
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private static LslJsonOutlet(options?: JsonOutletOptions) {
|
|
133
|
+
return LslJsonOutlet.Create(options)
|
|
134
|
+
}
|
|
135
|
+
}
|