@neurodevs/node-lsl 8.0.11 → 10.0.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/build/__tests__/behavioral/LslOutlet.test.d.ts +4 -2
- package/build/__tests__/behavioral/LslOutlet.test.js +66 -46
- package/build/__tests__/behavioral/LslOutlet.test.js.map +1 -1
- package/build/__tests__/behavioral/TimeMarkerOutlet.test.js +12 -12
- package/build/__tests__/behavioral/TimeMarkerOutlet.test.js.map +1 -1
- package/build/__tests__/support/generateRandomOutletOptions.d.ts +1 -1
- package/build/implementations/LslOutlet.d.ts +22 -3
- package/build/implementations/LslOutlet.js +10 -4
- package/build/implementations/LslOutlet.js.map +1 -1
- package/build/implementations/TimeMarkerOutlet.d.ts +8 -3
- package/build/implementations/TimeMarkerOutlet.js +1 -1
- package/build/implementations/TimeMarkerOutlet.js.map +1 -1
- package/build/index.d.ts +5 -5
- package/build/index.js +8 -8
- package/build/index.js.map +1 -1
- package/build/nodeLsl.types.d.ts +0 -21
- package/build/testDoubles/{SpyImplementsTimeMarkerOutlet.d.ts → FakeTimeMarkerOutlet.d.ts} +4 -3
- package/build/testDoubles/{SpyImplementsTimeMarkerOutlet.js → FakeTimeMarkerOutlet.js} +4 -4
- package/build/testDoubles/FakeTimeMarkerOutlet.js.map +1 -0
- package/build/testDoubles/{SpyExtendsTimeMarkerOutlet.d.ts → SpyTimeMarkerOutlet.d.ts} +3 -3
- package/build/testDoubles/{SpyExtendsTimeMarkerOutlet.js → SpyTimeMarkerOutlet.js} +4 -4
- package/build/testDoubles/SpyTimeMarkerOutlet.js.map +1 -0
- package/package.json +1 -1
- package/src/__tests__/behavioral/LslOutlet.test.ts +82 -54
- package/src/__tests__/behavioral/TimeMarkerOutlet.test.ts +15 -15
- package/src/__tests__/support/generateRandomOutletOptions.ts +1 -1
- package/src/implementations/LslOutlet.ts +34 -7
- package/src/implementations/TimeMarkerOutlet.ts +12 -8
- package/src/index.ts +6 -6
- package/src/nodeLsl.types.ts +0 -27
- package/src/testDoubles/{SpyImplementsTimeMarkerOutlet.ts → FakeTimeMarkerOutlet.ts} +4 -3
- package/src/testDoubles/{SpyExtendsTimeMarkerOutlet.ts → SpyTimeMarkerOutlet.ts} +4 -4
- package/build/testDoubles/SpyExtendsTimeMarkerOutlet.js.map +0 -1
- package/build/testDoubles/SpyImplementsTimeMarkerOutlet.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
class
|
|
3
|
+
class FakeTimeMarkerOutlet {
|
|
4
4
|
constructor() {
|
|
5
5
|
this.pushMarkersCalls = [];
|
|
6
6
|
this.pushSampleCalls = [];
|
|
@@ -19,12 +19,12 @@ class SpyImplementsTimeMarkerOutlet {
|
|
|
19
19
|
destroy() {
|
|
20
20
|
this.numDestroyCalls++;
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
resetTestDouble() {
|
|
23
23
|
this.pushMarkersCalls = [];
|
|
24
24
|
this.pushSampleCalls = [];
|
|
25
25
|
this.numStopCalls = 0;
|
|
26
26
|
this.numDestroyCalls = 0;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
exports.default =
|
|
30
|
-
//# sourceMappingURL=
|
|
29
|
+
exports.default = FakeTimeMarkerOutlet;
|
|
30
|
+
//# sourceMappingURL=FakeTimeMarkerOutlet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FakeTimeMarkerOutlet.js","sourceRoot":"","sources":["../../src/testDoubles/FakeTimeMarkerOutlet.ts"],"names":[],"mappings":";;AAGA,MAAqB,oBAAoB;IAMrC;QACI,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAA;QAC1B,IAAI,CAAC,eAAe,GAAG,EAAE,CAAA;QACzB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAA;QACrB,IAAI,CAAC,eAAe,GAAG,CAAC,CAAA;IAC5B,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,OAAyB;QAC9C,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACvC,CAAC;IAEM,UAAU,CAAC,MAAgB;QAC9B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACrC,CAAC;IAEM,IAAI;QACP,IAAI,CAAC,YAAY,EAAE,CAAA;IACvB,CAAC;IAEM,OAAO;QACV,IAAI,CAAC,eAAe,EAAE,CAAA;IAC1B,CAAC;IAEM,eAAe;QAClB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAA;QAC1B,IAAI,CAAC,eAAe,GAAG,EAAE,CAAA;QACzB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAA;QACrB,IAAI,CAAC,eAAe,GAAG,CAAC,CAAA;IAC5B,CAAC;CACJ;AAnCD,uCAmCC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { LslOutletOptions } from '../implementations/LslOutlet';
|
|
1
2
|
import TimeMarkerOutletImpl from '../implementations/TimeMarkerOutlet';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
spyOptions: LslOutletOptions;
|
|
3
|
+
export default class SpyTimeMarkerOutlet extends TimeMarkerOutletImpl {
|
|
4
|
+
passedOptions: LslOutletOptions;
|
|
5
5
|
totalWaitTimeMs: number;
|
|
6
6
|
constructor(options: LslOutletOptions);
|
|
7
7
|
wait(durationMs: number): Promise<void>;
|
|
@@ -4,10 +4,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const TimeMarkerOutlet_1 = __importDefault(require("../implementations/TimeMarkerOutlet"));
|
|
7
|
-
class
|
|
7
|
+
class SpyTimeMarkerOutlet extends TimeMarkerOutlet_1.default {
|
|
8
8
|
constructor(options) {
|
|
9
9
|
super(options);
|
|
10
|
-
this.
|
|
10
|
+
this.passedOptions = options;
|
|
11
11
|
this.totalWaitTimeMs = 0;
|
|
12
12
|
}
|
|
13
13
|
async wait(durationMs) {
|
|
@@ -15,5 +15,5 @@ class SpyExtendsTimeMarkerOutlet extends TimeMarkerOutlet_1.default {
|
|
|
15
15
|
return Promise.resolve();
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
exports.default =
|
|
19
|
-
//# sourceMappingURL=
|
|
18
|
+
exports.default = SpyTimeMarkerOutlet;
|
|
19
|
+
//# sourceMappingURL=SpyTimeMarkerOutlet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpyTimeMarkerOutlet.js","sourceRoot":"","sources":["../../src/testDoubles/SpyTimeMarkerOutlet.ts"],"names":[],"mappings":";;;;;AACA,2FAAsE;AAEtE,MAAqB,mBAAoB,SAAQ,0BAAoB;IAIjE,YAAmB,OAAyB;QACxC,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,aAAa,GAAG,OAAO,CAAA;QAC5B,IAAI,CAAC,eAAe,GAAG,CAAC,CAAA;IAC5B,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,UAAkB;QAChC,IAAI,CAAC,eAAe,IAAI,UAAU,CAAA;QAClC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;IAC5B,CAAC;CACJ;AAdD,sCAcC"}
|
package/package.json
CHANGED
|
@@ -5,8 +5,10 @@ import AbstractSpruceTest, {
|
|
|
5
5
|
generateId,
|
|
6
6
|
} from '@sprucelabs/test-utils'
|
|
7
7
|
import LiblslImpl from '../../implementations/Liblsl'
|
|
8
|
-
import
|
|
9
|
-
|
|
8
|
+
import LslOutletImpl, {
|
|
9
|
+
LslOutletOptions,
|
|
10
|
+
} from '../../implementations/LslOutlet'
|
|
11
|
+
import { LslSample } from '../../nodeLsl.types'
|
|
10
12
|
import FakeLiblsl from '../../testDoubles/FakeLiblsl'
|
|
11
13
|
import {
|
|
12
14
|
TEST_CHANNEL_FORMATS_MAP,
|
|
@@ -23,19 +25,22 @@ export default class LslOutletTest extends AbstractSpruceTest {
|
|
|
23
25
|
|
|
24
26
|
protected static async beforeEach() {
|
|
25
27
|
await super.beforeEach()
|
|
26
|
-
delete
|
|
28
|
+
delete LslOutletImpl.Class
|
|
27
29
|
this.randomOutletOptions = generateRandomOutletOptions()
|
|
28
30
|
|
|
29
31
|
const channelFormat = this.randomOutletOptions.channelFormat
|
|
30
32
|
this.channelFormatIdx = TEST_CHANNEL_FORMATS_MAP[channelFormat]
|
|
31
33
|
this.fakeLiblsl = new FakeLiblsl()
|
|
34
|
+
|
|
32
35
|
LiblslImpl.setInstance(this.fakeLiblsl)
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
@test()
|
|
36
|
-
protected static async
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
protected static async throwsWithMissingRequiredParams() {
|
|
40
|
+
const err = await assert.doesThrowAsync(
|
|
41
|
+
//@ts-ignore
|
|
42
|
+
async () => await LslOutletImpl.Create()
|
|
43
|
+
)
|
|
39
44
|
errorAssert.assertError(err, 'MISSING_PARAMETERS', {
|
|
40
45
|
parameters: [
|
|
41
46
|
'name',
|
|
@@ -54,45 +59,51 @@ export default class LslOutletTest extends AbstractSpruceTest {
|
|
|
54
59
|
|
|
55
60
|
@test()
|
|
56
61
|
protected static async throwsWithInvalidChannelNames() {
|
|
57
|
-
this.assertThrowsInvalidChannelNames(0)
|
|
62
|
+
await this.assertThrowsInvalidChannelNames(0)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@test()
|
|
66
|
+
protected static async allowsZeroSampleRate() {
|
|
67
|
+
await this.Outlet({ sampleRate: 0 })
|
|
58
68
|
}
|
|
59
69
|
|
|
60
70
|
@test()
|
|
61
71
|
protected static async throwsWithInvalidSampleRate() {
|
|
62
|
-
this.
|
|
63
|
-
this.assertThrowsInvalidSampleRate(-1)
|
|
64
|
-
this.assertThrowsInvalidSampleRate(-1.5)
|
|
72
|
+
await this.assertThrowsInvalidSampleRate(-1)
|
|
73
|
+
await this.assertThrowsInvalidSampleRate(-1.5)
|
|
65
74
|
}
|
|
66
75
|
|
|
67
76
|
@test()
|
|
68
77
|
protected static async throwsWithInvalidChannelFormat() {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
78
|
+
await this.assertDoesThrowInvalidParameters(
|
|
79
|
+
//@ts-ignore
|
|
80
|
+
{ channelFormat: generateId() },
|
|
81
|
+
['channelFormat']
|
|
82
|
+
)
|
|
73
83
|
}
|
|
74
84
|
|
|
75
85
|
@test()
|
|
76
86
|
protected static async throwsWithInvalidChunkSize() {
|
|
77
|
-
this.Outlet({ chunkSize: 0 })
|
|
78
|
-
this.assertThrowsInvalidChunkSize(-1)
|
|
79
|
-
this.assertThrowsInvalidChunkSize(-1.5)
|
|
80
|
-
this.assertThrowsInvalidChunkSize(1.5)
|
|
87
|
+
await this.Outlet({ chunkSize: 0 })
|
|
88
|
+
await this.assertThrowsInvalidChunkSize(-1)
|
|
89
|
+
await this.assertThrowsInvalidChunkSize(-1.5)
|
|
90
|
+
await this.assertThrowsInvalidChunkSize(1.5)
|
|
81
91
|
}
|
|
82
92
|
|
|
83
93
|
@test()
|
|
84
94
|
protected static async throwsWithInvalidMaxBuffered() {
|
|
85
|
-
this.Outlet({ maxBuffered: 0 })
|
|
86
|
-
this.assertThrowsInvalidMaxBuffered(-1)
|
|
87
|
-
this.assertThrowsInvalidMaxBuffered(-1.5)
|
|
88
|
-
this.assertThrowsInvalidMaxBuffered(1.5)
|
|
95
|
+
await this.Outlet({ maxBuffered: 0 })
|
|
96
|
+
await this.assertThrowsInvalidMaxBuffered(-1)
|
|
97
|
+
await this.assertThrowsInvalidMaxBuffered(-1.5)
|
|
98
|
+
await this.assertThrowsInvalidMaxBuffered(1.5)
|
|
89
99
|
}
|
|
90
100
|
|
|
91
101
|
@test()
|
|
92
102
|
protected static async throwsWithUnsupportedType() {
|
|
93
103
|
for (let unsupportedType of TEST_UNSUPPORTED_CHANNEL_FORMATS) {
|
|
94
|
-
assert.
|
|
95
|
-
() =>
|
|
104
|
+
await assert.doesThrowAsync(
|
|
105
|
+
async () =>
|
|
106
|
+
await this.Outlet({ channelFormat: unsupportedType }),
|
|
96
107
|
`This method currently does not support the ${unsupportedType} type! Please implement it.`
|
|
97
108
|
)
|
|
98
109
|
}
|
|
@@ -101,14 +112,14 @@ export default class LslOutletTest extends AbstractSpruceTest {
|
|
|
101
112
|
@test()
|
|
102
113
|
protected static async supportsAllKnownChannelFormats() {
|
|
103
114
|
for (const format of TEST_SUPPORTED_CHANNEL_FORMATS) {
|
|
104
|
-
this.Outlet({ channelFormat: format as TestChannelFormat })
|
|
115
|
+
await this.Outlet({ channelFormat: format as TestChannelFormat })
|
|
105
116
|
}
|
|
106
117
|
}
|
|
107
118
|
|
|
108
119
|
@test('pushing [1, 2] sample sends to LSL', [1.0, 2.0])
|
|
109
120
|
@test('pushing [1] sample sends to LSL', [1.0])
|
|
110
121
|
protected static async canPushFloatSampleToLsl(sample: LslSample) {
|
|
111
|
-
const outlet = this.FloatOutlet()
|
|
122
|
+
const outlet = await this.FloatOutlet()
|
|
112
123
|
outlet.pushSample(sample)
|
|
113
124
|
|
|
114
125
|
assert.isEqual(
|
|
@@ -132,7 +143,7 @@ export default class LslOutletTest extends AbstractSpruceTest {
|
|
|
132
143
|
@test()
|
|
133
144
|
protected static async canPushStringSampleToLsl() {
|
|
134
145
|
const sample = [generateId()]
|
|
135
|
-
const outlet = this.StringOutlet()
|
|
146
|
+
const outlet = await this.StringOutlet()
|
|
136
147
|
|
|
137
148
|
outlet.pushSample(sample)
|
|
138
149
|
|
|
@@ -151,7 +162,7 @@ export default class LslOutletTest extends AbstractSpruceTest {
|
|
|
151
162
|
|
|
152
163
|
@test()
|
|
153
164
|
protected static async pushingStringTwiceGivesDifferentTimestamps() {
|
|
154
|
-
const outlet = this.StringOutlet()
|
|
165
|
+
const outlet = await this.StringOutlet()
|
|
155
166
|
const sample = [generateId()]
|
|
156
167
|
|
|
157
168
|
outlet.pushSample(sample)
|
|
@@ -170,7 +181,7 @@ export default class LslOutletTest extends AbstractSpruceTest {
|
|
|
170
181
|
|
|
171
182
|
@test()
|
|
172
183
|
protected static async constructionCreatesStreamInfo() {
|
|
173
|
-
this.Outlet()
|
|
184
|
+
await this.Outlet()
|
|
174
185
|
|
|
175
186
|
const { ...options } = this.randomOutletOptions as any
|
|
176
187
|
|
|
@@ -190,8 +201,8 @@ export default class LslOutletTest extends AbstractSpruceTest {
|
|
|
190
201
|
|
|
191
202
|
@test()
|
|
192
203
|
protected static async canOverrideClassInstantiatedInFactory() {
|
|
193
|
-
|
|
194
|
-
const instance = this.Outlet()
|
|
204
|
+
LslOutletImpl.Class = CheckingOutlet
|
|
205
|
+
const instance = await this.Outlet()
|
|
195
206
|
|
|
196
207
|
assert.isInstanceOf(instance, CheckingOutlet)
|
|
197
208
|
}
|
|
@@ -202,7 +213,7 @@ export default class LslOutletTest extends AbstractSpruceTest {
|
|
|
202
213
|
const type = generateId()
|
|
203
214
|
const unit = generateId()
|
|
204
215
|
|
|
205
|
-
this.Outlet({ channelNames: labels, type, unit })
|
|
216
|
+
await this.Outlet({ channelNames: labels, type, unit })
|
|
206
217
|
|
|
207
218
|
assert.isEqualDeep(
|
|
208
219
|
this.fakeLiblsl.lastAppendChannelsToStreamInfoOptions,
|
|
@@ -219,7 +230,7 @@ export default class LslOutletTest extends AbstractSpruceTest {
|
|
|
219
230
|
|
|
220
231
|
@test()
|
|
221
232
|
protected static async canDestroyOutlet() {
|
|
222
|
-
const outlet = this.Outlet()
|
|
233
|
+
const outlet = await this.Outlet()
|
|
223
234
|
outlet.destroy()
|
|
224
235
|
|
|
225
236
|
assert.isEqual(this.fakeLiblsl.destroyOutletHitCount, 1)
|
|
@@ -227,7 +238,7 @@ export default class LslOutletTest extends AbstractSpruceTest {
|
|
|
227
238
|
|
|
228
239
|
@test()
|
|
229
240
|
protected static async pushSampleShouldNotCreateMultipleOutlets() {
|
|
230
|
-
const outlet = this.FloatOutlet()
|
|
241
|
+
const outlet = await this.FloatOutlet()
|
|
231
242
|
outlet.pushSample([1.0])
|
|
232
243
|
outlet.pushSample([2.0])
|
|
233
244
|
outlet.pushSample([3.0])
|
|
@@ -235,52 +246,69 @@ export default class LslOutletTest extends AbstractSpruceTest {
|
|
|
235
246
|
assert.isEqual(this.fakeLiblsl.createStreamInfoHitCount, 1)
|
|
236
247
|
}
|
|
237
248
|
|
|
238
|
-
|
|
239
|
-
|
|
249
|
+
@test()
|
|
250
|
+
protected static async waitsForTenMsAfterConstructionBeforeReturning() {
|
|
251
|
+
const startMs = Date.now()
|
|
252
|
+
await this.Outlet({ waitAfterConstructionMs: 10 })
|
|
253
|
+
const endMs = Date.now()
|
|
254
|
+
|
|
255
|
+
assert.isAbove(endMs - startMs, 10)
|
|
240
256
|
}
|
|
241
257
|
|
|
242
|
-
private static
|
|
243
|
-
this.assertDoesThrowInvalidParameters({
|
|
258
|
+
private static async assertThrowsInvalidMaxBuffered(maxBuffered: number) {
|
|
259
|
+
await this.assertDoesThrowInvalidParameters({ maxBuffered }, [
|
|
260
|
+
'maxBuffered',
|
|
261
|
+
])
|
|
244
262
|
}
|
|
245
263
|
|
|
246
|
-
private static
|
|
247
|
-
this.assertDoesThrowInvalidParameters({
|
|
264
|
+
private static async assertThrowsInvalidChunkSize(chunkSize: number) {
|
|
265
|
+
await this.assertDoesThrowInvalidParameters({ chunkSize }, [
|
|
266
|
+
'chunkSize',
|
|
267
|
+
])
|
|
248
268
|
}
|
|
249
269
|
|
|
250
|
-
private static
|
|
251
|
-
this.assertDoesThrowInvalidParameters(
|
|
270
|
+
private static async assertThrowsInvalidSampleRate(sampleRate: number) {
|
|
271
|
+
await this.assertDoesThrowInvalidParameters({ sampleRate }, [
|
|
272
|
+
'sampleRate',
|
|
273
|
+
])
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
private static async assertThrowsInvalidChannelNames(count: number) {
|
|
277
|
+
await this.assertDoesThrowInvalidParameters(
|
|
252
278
|
{ channelNames: new Array(count).fill(generateId()) },
|
|
253
279
|
['channelNames']
|
|
254
280
|
)
|
|
255
281
|
}
|
|
256
282
|
|
|
257
|
-
private static assertDoesThrowInvalidParameters(
|
|
283
|
+
private static async assertDoesThrowInvalidParameters(
|
|
258
284
|
options: Partial<LslOutletOptions>,
|
|
259
285
|
parameters: string[]
|
|
260
286
|
) {
|
|
261
|
-
const err = assert.
|
|
287
|
+
const err = await assert.doesThrowAsync(
|
|
288
|
+
async () => await this.Outlet(options)
|
|
289
|
+
)
|
|
262
290
|
errorAssert.assertError(err, 'INVALID_PARAMETERS', {
|
|
263
291
|
parameters,
|
|
264
292
|
})
|
|
265
293
|
}
|
|
266
294
|
|
|
267
|
-
private static
|
|
268
|
-
return
|
|
269
|
-
...this.randomOutletOptions,
|
|
270
|
-
...options,
|
|
271
|
-
})
|
|
295
|
+
private static async StringOutlet() {
|
|
296
|
+
return await this.Outlet({ channelFormat: 'string' })
|
|
272
297
|
}
|
|
273
298
|
|
|
274
|
-
private static
|
|
275
|
-
return this.Outlet({ channelFormat: '
|
|
299
|
+
private static async FloatOutlet() {
|
|
300
|
+
return await this.Outlet({ channelFormat: 'float32' })
|
|
276
301
|
}
|
|
277
302
|
|
|
278
|
-
private static
|
|
279
|
-
return
|
|
303
|
+
private static async Outlet(options?: Partial<LslOutletOptions>) {
|
|
304
|
+
return await LslOutletImpl.Create({
|
|
305
|
+
...this.randomOutletOptions,
|
|
306
|
+
...options,
|
|
307
|
+
})
|
|
280
308
|
}
|
|
281
309
|
}
|
|
282
310
|
|
|
283
|
-
class CheckingOutlet extends
|
|
311
|
+
class CheckingOutlet extends LslOutletImpl {
|
|
284
312
|
public constructor(options: LslOutletOptions) {
|
|
285
313
|
super(options)
|
|
286
314
|
}
|
|
@@ -5,27 +5,27 @@ import AbstractSpruceTest, {
|
|
|
5
5
|
test,
|
|
6
6
|
} from '@sprucelabs/test-utils'
|
|
7
7
|
import LiblslImpl from '../../implementations/Liblsl'
|
|
8
|
+
import { LslOutletOptions } from '../../implementations/LslOutlet'
|
|
8
9
|
import TimeMarkerOutletImpl from '../../implementations/TimeMarkerOutlet'
|
|
9
|
-
import { LslOutletOptions } from '../../nodeLsl.types'
|
|
10
10
|
import FakeLiblsl from '../../testDoubles/FakeLiblsl'
|
|
11
|
-
import
|
|
11
|
+
import SpyTimeMarkerOutlet from '../../testDoubles/SpyTimeMarkerOutlet'
|
|
12
12
|
import generateRandomOutletOptions from '../support/generateRandomOutletOptions'
|
|
13
13
|
|
|
14
14
|
export default class TimeMarkerOutletTest extends AbstractSpruceTest {
|
|
15
15
|
private static fakeLiblsl: FakeLiblsl
|
|
16
|
-
private static outlet:
|
|
16
|
+
private static outlet: SpyTimeMarkerOutlet
|
|
17
17
|
|
|
18
18
|
protected static async beforeEach() {
|
|
19
19
|
await super.beforeEach()
|
|
20
|
-
TimeMarkerOutletImpl.Class =
|
|
20
|
+
TimeMarkerOutletImpl.Class = SpyTimeMarkerOutlet
|
|
21
21
|
this.fakeLiblsl = new FakeLiblsl()
|
|
22
22
|
LiblslImpl.setInstance(this.fakeLiblsl)
|
|
23
|
-
this.outlet = this.Outlet()
|
|
23
|
+
this.outlet = await this.Outlet()
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
@test()
|
|
27
27
|
protected static async loadsWithTimeMarkerSpecificOptions() {
|
|
28
|
-
assert.isEqualDeep(this.outlet.
|
|
28
|
+
assert.isEqualDeep(this.outlet.passedOptions, {
|
|
29
29
|
name: 'Time markers',
|
|
30
30
|
type: 'Markers',
|
|
31
31
|
channelNames: ['Markers'],
|
|
@@ -42,8 +42,8 @@ export default class TimeMarkerOutletTest extends AbstractSpruceTest {
|
|
|
42
42
|
@test()
|
|
43
43
|
protected static async canOverrideDefaultOptions() {
|
|
44
44
|
const options = generateRandomOutletOptions()
|
|
45
|
-
const outlet = this.Outlet(options)
|
|
46
|
-
assert.isEqualDeep(outlet.
|
|
45
|
+
const outlet = await this.Outlet(options)
|
|
46
|
+
assert.isEqualDeep(outlet.passedOptions, options)
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
@test()
|
|
@@ -101,7 +101,7 @@ export default class TimeMarkerOutletTest extends AbstractSpruceTest {
|
|
|
101
101
|
|
|
102
102
|
@test()
|
|
103
103
|
protected static async doesNotWaitIfStopped() {
|
|
104
|
-
this.setupTimeMarkerImpl()
|
|
104
|
+
await this.setupTimeMarkerImpl()
|
|
105
105
|
|
|
106
106
|
const startMs = Date.now()
|
|
107
107
|
const promise = this.pushTotalMarkers(2, 1000)
|
|
@@ -114,7 +114,7 @@ export default class TimeMarkerOutletTest extends AbstractSpruceTest {
|
|
|
114
114
|
|
|
115
115
|
@test()
|
|
116
116
|
protected static async clearsTheTimeoutOnStop() {
|
|
117
|
-
this.setupTimeMarkerImpl()
|
|
117
|
+
await this.setupTimeMarkerImpl()
|
|
118
118
|
|
|
119
119
|
const promise = this.pushTotalMarkers(2, 100)
|
|
120
120
|
|
|
@@ -126,9 +126,9 @@ export default class TimeMarkerOutletTest extends AbstractSpruceTest {
|
|
|
126
126
|
await this.wait(100)
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
private static setupTimeMarkerImpl() {
|
|
129
|
+
private static async setupTimeMarkerImpl() {
|
|
130
130
|
TimeMarkerOutletImpl.Class = TimeMarkerOutletImpl as any
|
|
131
|
-
this.outlet = this.Outlet()
|
|
131
|
+
this.outlet = await this.Outlet()
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
private static async pushTotalMarkers(total: number, durationMs?: number) {
|
|
@@ -148,9 +148,9 @@ export default class TimeMarkerOutletTest extends AbstractSpruceTest {
|
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
private static Outlet(options?: Partial<LslOutletOptions>) {
|
|
152
|
-
return TimeMarkerOutletImpl.
|
|
151
|
+
private static async Outlet(options?: Partial<LslOutletOptions>) {
|
|
152
|
+
return (await TimeMarkerOutletImpl.Create(
|
|
153
153
|
options
|
|
154
|
-
) as
|
|
154
|
+
)) as SpyTimeMarkerOutlet
|
|
155
155
|
}
|
|
156
156
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { randomInt } from 'crypto'
|
|
2
2
|
import { generateId } from '@sprucelabs/test-utils'
|
|
3
|
-
import { LslOutletOptions } from '../../
|
|
3
|
+
import { LslOutletOptions } from '../../implementations/LslOutlet'
|
|
4
4
|
import { TEST_SUPPORTED_CHANNEL_FORMATS } from './consts'
|
|
5
5
|
|
|
6
6
|
export default function generateRandomOutletOptions() {
|
|
@@ -8,8 +8,6 @@ import {
|
|
|
8
8
|
} from '../assertions'
|
|
9
9
|
import { CHANNEL_FORMATS_MAP } from '../consts'
|
|
10
10
|
import {
|
|
11
|
-
LslOutlet,
|
|
12
|
-
LslOutletOptions,
|
|
13
11
|
ChannelFormat,
|
|
14
12
|
BoundOutlet,
|
|
15
13
|
BoundStreamInfo,
|
|
@@ -19,16 +17,13 @@ import {
|
|
|
19
17
|
import LiblslImpl from './Liblsl'
|
|
20
18
|
|
|
21
19
|
export default class LslOutletImpl implements LslOutlet {
|
|
22
|
-
public static Class?:
|
|
20
|
+
public static Class?: LslOutletConstructor
|
|
21
|
+
|
|
23
22
|
private options: LslOutletOptions
|
|
24
23
|
private streamInfo: BoundStreamInfo
|
|
25
24
|
private outlet: BoundOutlet
|
|
26
25
|
private pushSampleByType: (options: any) => void
|
|
27
26
|
|
|
28
|
-
public static Outlet(options: LslOutletOptions) {
|
|
29
|
-
return new (this.Class ?? this)(options)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
27
|
protected constructor(options: LslOutletOptions) {
|
|
33
28
|
const { sampleRate, channelFormat } = assertOptions(options, [
|
|
34
29
|
'name',
|
|
@@ -84,6 +79,17 @@ export default class LslOutletImpl implements LslOutlet {
|
|
|
84
79
|
this.pushSampleByType = this.lsl[pushMethod].bind(this.lsl)
|
|
85
80
|
}
|
|
86
81
|
|
|
82
|
+
public static async Create(options: LslOutletOptions) {
|
|
83
|
+
const { waitAfterConstructionMs = 10 } = options ?? {}
|
|
84
|
+
const instance = new (this.Class ?? this)(options)
|
|
85
|
+
await this.wait(waitAfterConstructionMs)
|
|
86
|
+
return instance
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private static wait(waitMs: number) {
|
|
90
|
+
return new Promise((resolve) => setTimeout(resolve, waitMs))
|
|
91
|
+
}
|
|
92
|
+
|
|
87
93
|
public destroy() {
|
|
88
94
|
this.lsl.destroyOutlet({ outlet: this.outlet })
|
|
89
95
|
}
|
|
@@ -122,3 +128,24 @@ export default class LslOutletImpl implements LslOutlet {
|
|
|
122
128
|
return LiblslImpl.getInstance()
|
|
123
129
|
}
|
|
124
130
|
}
|
|
131
|
+
|
|
132
|
+
export interface LslOutlet {
|
|
133
|
+
destroy(): void
|
|
134
|
+
pushSample(sample: LslSample): void
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export type LslOutletConstructor = new (options: LslOutletOptions) => LslOutlet
|
|
138
|
+
|
|
139
|
+
export interface LslOutletOptions {
|
|
140
|
+
name: string
|
|
141
|
+
type: string
|
|
142
|
+
channelNames: string[]
|
|
143
|
+
sampleRate: number
|
|
144
|
+
channelFormat: ChannelFormat
|
|
145
|
+
sourceId: string
|
|
146
|
+
manufacturer: string
|
|
147
|
+
unit: string
|
|
148
|
+
chunkSize: number
|
|
149
|
+
maxBuffered: number
|
|
150
|
+
waitAfterConstructionMs?: number
|
|
151
|
+
}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
LslOutletOptions,
|
|
4
|
-
DurationMarker,
|
|
5
|
-
TimeMarkerOutletConstructor,
|
|
6
|
-
} from '../nodeLsl.types'
|
|
7
|
-
import LslOutletImpl from './LslOutlet'
|
|
1
|
+
import { DurationMarker } from '../nodeLsl.types'
|
|
2
|
+
import LslOutletImpl, { LslOutlet, LslOutletOptions } from './LslOutlet'
|
|
8
3
|
|
|
9
4
|
export default class TimeMarkerOutletImpl
|
|
10
5
|
extends LslOutletImpl
|
|
@@ -16,7 +11,7 @@ export default class TimeMarkerOutletImpl
|
|
|
16
11
|
private waitResolve?: () => void
|
|
17
12
|
private timeout?: any
|
|
18
13
|
|
|
19
|
-
public static
|
|
14
|
+
public static async Create(options?: Partial<LslOutletOptions>) {
|
|
20
15
|
const defaultOptions = {
|
|
21
16
|
name: 'Time markers',
|
|
22
17
|
type: 'Markers',
|
|
@@ -65,3 +60,12 @@ export default class TimeMarkerOutletImpl
|
|
|
65
60
|
this.isPlaying = false
|
|
66
61
|
}
|
|
67
62
|
}
|
|
63
|
+
|
|
64
|
+
export interface TimeMarkerOutlet extends LslOutlet {
|
|
65
|
+
pushMarkers(markers: DurationMarker[]): Promise<void>
|
|
66
|
+
stop(): void
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export type TimeMarkerOutletConstructor = new (
|
|
70
|
+
options: LslOutletOptions
|
|
71
|
+
) => TimeMarkerOutlet
|
package/src/index.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export * from './nodeLsl.types'
|
|
2
|
+
|
|
1
3
|
export { default as LiblslImpl } from './implementations/Liblsl'
|
|
2
4
|
export * from './implementations/Liblsl'
|
|
3
5
|
|
|
@@ -10,15 +12,13 @@ export * from './implementations/TimeMarkerOutlet'
|
|
|
10
12
|
export { default as FakeLiblsl } from './testDoubles/FakeLiblsl'
|
|
11
13
|
export * from './testDoubles/FakeLiblsl'
|
|
12
14
|
|
|
13
|
-
export { default as
|
|
14
|
-
export * from './testDoubles/
|
|
15
|
-
|
|
16
|
-
export { default as SpyImplementsTimeMarkerOutlet } from './testDoubles/SpyImplementsTimeMarkerOutlet'
|
|
17
|
-
export * from './testDoubles/SpyImplementsTimeMarkerOutlet'
|
|
15
|
+
export { default as FakeTimeMarkerOutlet } from './testDoubles/FakeTimeMarkerOutlet'
|
|
16
|
+
export * from './testDoubles/FakeTimeMarkerOutlet'
|
|
18
17
|
|
|
19
18
|
export { default as MockTimeMarkerOutlet } from './testDoubles/MockTimeMarkerOutlet'
|
|
20
19
|
export * from './testDoubles/MockTimeMarkerOutlet'
|
|
21
20
|
|
|
22
|
-
export
|
|
21
|
+
export { default as SpyTimeMarkerOutlet } from './testDoubles/SpyTimeMarkerOutlet'
|
|
22
|
+
export * from './testDoubles/SpyTimeMarkerOutlet'
|
|
23
23
|
|
|
24
24
|
export { default as generateRandomOutletOptions } from './__tests__/support/generateRandomOutletOptions'
|
package/src/nodeLsl.types.ts
CHANGED
|
@@ -1,35 +1,8 @@
|
|
|
1
1
|
import { FuncObj, FieldType } from 'ffi-rs'
|
|
2
2
|
import { CHANNEL_FORMATS } from './consts'
|
|
3
3
|
|
|
4
|
-
export interface LslOutlet {
|
|
5
|
-
destroy(): void
|
|
6
|
-
pushSample(sample: LslSample): void
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface LslOutletOptions {
|
|
10
|
-
name: string
|
|
11
|
-
type: string
|
|
12
|
-
channelNames: string[]
|
|
13
|
-
sampleRate: number
|
|
14
|
-
channelFormat: ChannelFormat
|
|
15
|
-
sourceId: string
|
|
16
|
-
manufacturer: string
|
|
17
|
-
unit: string
|
|
18
|
-
chunkSize: number
|
|
19
|
-
maxBuffered: number
|
|
20
|
-
}
|
|
21
|
-
|
|
22
4
|
export type ChannelFormat = (typeof CHANNEL_FORMATS)[number]
|
|
23
5
|
|
|
24
|
-
export interface TimeMarkerOutlet extends LslOutlet {
|
|
25
|
-
pushMarkers(markers: DurationMarker[]): Promise<void>
|
|
26
|
-
stop(): void
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export type TimeMarkerOutletConstructor = new (
|
|
30
|
-
options: LslOutletOptions
|
|
31
|
-
) => TimeMarkerOutlet
|
|
32
|
-
|
|
33
6
|
export interface DurationMarker {
|
|
34
7
|
name: string
|
|
35
8
|
durationMs: number
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TimeMarkerOutlet } from '../implementations/TimeMarkerOutlet'
|
|
2
|
+
import { DurationMarker } from '../nodeLsl.types'
|
|
2
3
|
|
|
3
|
-
export default class
|
|
4
|
+
export default class FakeTimeMarkerOutlet implements TimeMarkerOutlet {
|
|
4
5
|
public pushMarkersCalls: DurationMarker[][]
|
|
5
6
|
public pushSampleCalls: string[][]
|
|
6
7
|
public numStopCalls: number
|
|
@@ -29,7 +30,7 @@ export default class SpyImplementsTimeMarkerOutlet implements TimeMarkerOutlet {
|
|
|
29
30
|
this.numDestroyCalls++
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
public
|
|
33
|
+
public resetTestDouble() {
|
|
33
34
|
this.pushMarkersCalls = []
|
|
34
35
|
this.pushSampleCalls = []
|
|
35
36
|
this.numStopCalls = 0
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
import { LslOutletOptions } from '../implementations/LslOutlet'
|
|
1
2
|
import TimeMarkerOutletImpl from '../implementations/TimeMarkerOutlet'
|
|
2
|
-
import { LslOutletOptions } from '../nodeLsl.types'
|
|
3
3
|
|
|
4
|
-
export default class
|
|
5
|
-
public
|
|
4
|
+
export default class SpyTimeMarkerOutlet extends TimeMarkerOutletImpl {
|
|
5
|
+
public passedOptions: LslOutletOptions
|
|
6
6
|
public totalWaitTimeMs: number
|
|
7
7
|
|
|
8
8
|
public constructor(options: LslOutletOptions) {
|
|
9
9
|
super(options)
|
|
10
|
-
this.
|
|
10
|
+
this.passedOptions = options
|
|
11
11
|
this.totalWaitTimeMs = 0
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SpyExtendsTimeMarkerOutlet.js","sourceRoot":"","sources":["../../src/testDoubles/SpyExtendsTimeMarkerOutlet.ts"],"names":[],"mappings":";;;;;AAAA,2FAAsE;AAGtE,MAAqB,0BAA2B,SAAQ,0BAAoB;IAIxE,YAAmB,OAAyB;QACxC,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,UAAU,GAAG,OAAO,CAAA;QACzB,IAAI,CAAC,eAAe,GAAG,CAAC,CAAA;IAC5B,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,UAAkB;QAChC,IAAI,CAAC,eAAe,IAAI,UAAU,CAAA;QAClC,OAAO,OAAO,CAAC,OAAO,EAAE,CAAA;IAC5B,CAAC;CACJ;AAdD,6CAcC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"SpyImplementsTimeMarkerOutlet.js","sourceRoot":"","sources":["../../src/testDoubles/SpyImplementsTimeMarkerOutlet.ts"],"names":[],"mappings":";;AAEA,MAAqB,6BAA6B;IAM9C;QACI,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAA;QAC1B,IAAI,CAAC,eAAe,GAAG,EAAE,CAAA;QACzB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAA;QACrB,IAAI,CAAC,eAAe,GAAG,CAAC,CAAA;IAC5B,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,OAAyB;QAC9C,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACvC,CAAC;IAEM,UAAU,CAAC,MAAgB;QAC9B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACrC,CAAC;IAEM,IAAI;QACP,IAAI,CAAC,YAAY,EAAE,CAAA;IACvB,CAAC;IAEM,OAAO;QACV,IAAI,CAAC,eAAe,EAAE,CAAA;IAC1B,CAAC;IAEM,QAAQ;QACX,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAA;QAC1B,IAAI,CAAC,eAAe,GAAG,EAAE,CAAA;QACzB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAA;QACrB,IAAI,CAAC,eAAe,GAAG,CAAC,CAAA;IAC5B,CAAC;CACJ;AAnCD,gDAmCC"}
|