@stoprocent/noble 1.19.1 → 2.0.1
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 +393 -650
- package/examples/advertisement-discovery.js +57 -48
- package/examples/connect-address.js +59 -34
- package/examples/echo.js +59 -69
- package/examples/enter-exit.js +55 -49
- package/examples/multiple-bindings.js +53 -0
- package/examples/peripheral-explorer-async.js +39 -21
- package/examples/peripheral-explorer.ts +52 -0
- package/index.d.ts +249 -209
- package/index.js +4 -1
- package/jest.config.js +4 -0
- package/lib/characteristic.js +153 -127
- package/lib/{win/src/callbacks.h → common/include/Emit.h} +17 -14
- package/lib/common/include/Peripheral.h +31 -0
- package/lib/common/include/ThreadSafeCallback.h +95 -0
- package/lib/{win/src/callbacks.cc → common/src/Emit.cc} +111 -68
- package/lib/descriptor.js +57 -54
- package/lib/hci-socket/acl-stream.js +2 -4
- package/lib/hci-socket/bindings.js +96 -73
- package/lib/hci-socket/gap.js +2 -3
- package/lib/hci-socket/gatt.js +2 -5
- package/lib/hci-socket/hci.js +19 -7
- package/lib/hci-socket/signaling.js +2 -3
- package/lib/hci-socket/smp.js +2 -3
- package/lib/hci-socket/vs.js +1 -0
- package/lib/mac/binding.gyp +5 -7
- package/lib/mac/bindings.js +1 -3
- package/lib/mac/src/ble_manager.h +1 -8
- package/lib/mac/src/ble_manager.mm +87 -44
- package/lib/mac/src/napi_objc.h +1 -0
- package/lib/mac/src/napi_objc.mm +0 -6
- package/lib/mac/src/noble_mac.h +5 -3
- package/lib/mac/src/noble_mac.mm +99 -57
- package/lib/mac/src/objc_cpp.h +3 -2
- package/lib/mac/src/objc_cpp.mm +0 -6
- package/lib/noble.js +583 -488
- package/lib/peripheral.js +171 -174
- package/lib/resolve-bindings.js +37 -30
- package/lib/service.js +58 -55
- package/lib/win/binding.gyp +4 -11
- package/lib/win/bindings.js +1 -3
- package/lib/win/src/ble_manager.cc +291 -166
- package/lib/win/src/ble_manager.h +11 -13
- package/lib/win/src/napi_winrt.cc +1 -7
- package/lib/win/src/napi_winrt.h +1 -1
- package/lib/win/src/noble_winrt.cc +88 -61
- package/lib/win/src/noble_winrt.h +5 -3
- package/lib/win/src/notify_map.cc +0 -7
- package/lib/win/src/notify_map.h +1 -8
- package/lib/win/src/peripheral_winrt.cc +29 -11
- package/lib/win/src/peripheral_winrt.h +1 -1
- package/lib/win/src/radio_watcher.cc +79 -69
- package/lib/win/src/radio_watcher.h +30 -11
- package/lib/win/src/winrt_cpp.cc +1 -1
- package/lib/win/src/winrt_cpp.h +3 -0
- package/package.json +14 -17
- package/prebuilds/darwin-x64+arm64/@stoprocent+noble.node +0 -0
- package/prebuilds/win32-ia32/@stoprocent+noble.node +0 -0
- package/prebuilds/win32-x64/@stoprocent+noble.node +0 -0
- package/test/lib/characteristic.test.js +202 -322
- package/test/lib/descriptor.test.js +62 -95
- package/test/lib/hci-socket/acl-stream.test.js +112 -108
- package/test/lib/hci-socket/bindings.test.js +576 -365
- package/test/lib/hci-socket/hci.test.js +442 -473
- package/test/lib/hci-socket/signaling.test.js +45 -48
- package/test/lib/hci-socket/smp.test.js +144 -142
- package/test/lib/hci-socket/vs.test.js +193 -18
- package/test/lib/peripheral.test.js +492 -322
- package/test/lib/resolve-bindings.test.js +207 -82
- package/test/lib/service.test.js +79 -88
- package/test/noble.test.js +426 -1088
- package/.editorconfig +0 -11
- package/.nycrc.json +0 -4
- package/codecov.yml +0 -5
- package/examples/cache-gatt-discovery.js +0 -198
- package/examples/cache-gatt-reconnect.js +0 -164
- package/examples/ext-advertisement-discovery.js +0 -65
- package/examples/peripheral-explorer.js +0 -225
- package/examples/pizza/central.js +0 -194
- package/examples/pizza/pizza.js +0 -60
- package/examples/test/test.custom.js +0 -131
- package/examples/uart-bind-params.js +0 -28
- package/lib/distributed/bindings.js +0 -326
- package/lib/mac/src/callbacks.cc +0 -222
- package/lib/mac/src/callbacks.h +0 -84
- package/lib/mac/src/peripheral.h +0 -23
- package/lib/resolve-bindings-web.js +0 -9
- package/lib/webbluetooth/bindings.js +0 -368
- package/lib/websocket/bindings.js +0 -321
- package/lib/win/src/peripheral.h +0 -23
- package/test/lib/distributed/bindings.test.js +0 -918
- package/test/lib/webbluetooth/bindings.test.js +0 -190
- package/test/lib/websocket/bindings.test.js +0 -456
- package/test/mocha.setup.js +0 -0
- package/with-bindings.js +0 -5
- package/with-custom-binding.js +0 -6
- package/ws-slave.js +0 -404
package/test/noble.test.js
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
const should = require('should');
|
|
2
|
-
const sinon = require('sinon');
|
|
3
|
-
|
|
4
|
-
const { assert } = sinon;
|
|
5
|
-
|
|
6
1
|
const Noble = require('../lib/noble');
|
|
7
2
|
const Peripheral = require('../lib/peripheral');
|
|
8
3
|
const Service = require('../lib/service');
|
|
@@ -18,73 +13,43 @@ describe('noble', () => {
|
|
|
18
13
|
|
|
19
14
|
beforeEach(() => {
|
|
20
15
|
mockBindings = {
|
|
21
|
-
|
|
22
|
-
on: ()
|
|
16
|
+
start: jest.fn(),
|
|
17
|
+
on: jest.fn(),
|
|
18
|
+
startScanning: jest.fn(),
|
|
19
|
+
stopScanning: jest.fn(),
|
|
20
|
+
connect: jest.fn(),
|
|
21
|
+
disconnect: jest.fn(),
|
|
22
|
+
updateRssi: jest.fn(),
|
|
23
|
+
discoverServices: jest.fn(),
|
|
24
|
+
discoverIncludedServices: jest.fn(),
|
|
25
|
+
discoverCharacteristics: jest.fn(),
|
|
26
|
+
read: jest.fn(),
|
|
27
|
+
write: jest.fn(),
|
|
28
|
+
broadcast: jest.fn(),
|
|
29
|
+
notify: jest.fn(),
|
|
30
|
+
discoverDescriptors: jest.fn(),
|
|
31
|
+
readValue: jest.fn(),
|
|
32
|
+
writeValue: jest.fn(),
|
|
33
|
+
readHandle: jest.fn(),
|
|
34
|
+
writeHandle: jest.fn(),
|
|
35
|
+
reset: jest.fn(),
|
|
36
|
+
setScanParameters: jest.fn(),
|
|
37
|
+
cancelConnect: jest.fn(),
|
|
38
|
+
addressToId: jest.fn()
|
|
23
39
|
};
|
|
24
40
|
|
|
25
41
|
noble = new Noble(mockBindings);
|
|
42
|
+
noble.removeAllListeners('warning');
|
|
43
|
+
noble._peripherals = new Map();
|
|
26
44
|
});
|
|
27
45
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
afterEach(() => {
|
|
34
|
-
sinon.reset();
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('should emit warning due to serviceUuids', () => {
|
|
38
|
-
const callback = sinon.spy();
|
|
39
|
-
const eventCallback = sinon.spy();
|
|
40
|
-
const expectedAllowDuplicates = true;
|
|
41
|
-
noble.on('warning', eventCallback);
|
|
42
|
-
|
|
43
|
-
noble.startScanning(callback, expectedAllowDuplicates);
|
|
44
|
-
noble.emit('stateChange', 'poweredOn');
|
|
45
|
-
// Check for single callback
|
|
46
|
-
noble.emit('stateChange', 'poweredOn');
|
|
47
|
-
noble.emit('scanStart');
|
|
48
|
-
// Check for single callback
|
|
49
|
-
noble.emit('scanStart');
|
|
50
|
-
|
|
51
|
-
assert.calledOnceWithExactly(
|
|
52
|
-
mockBindings.startScanning,
|
|
53
|
-
callback,
|
|
54
|
-
expectedAllowDuplicates
|
|
55
|
-
);
|
|
56
|
-
assert.calledOnceWithExactly(
|
|
57
|
-
eventCallback,
|
|
58
|
-
'calling startScanning(callback) is deprecated'
|
|
59
|
-
);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('should emit warning due to allowDuplicates', () => {
|
|
63
|
-
const callback = sinon.spy();
|
|
64
|
-
const eventCallback = sinon.spy();
|
|
65
|
-
const expectedServiceUuids = [1, 2, 3];
|
|
66
|
-
noble.on('warning', eventCallback);
|
|
67
|
-
|
|
68
|
-
noble.startScanning(expectedServiceUuids, callback);
|
|
69
|
-
noble.emit('stateChange', 'poweredOn');
|
|
70
|
-
// Check for single callback
|
|
71
|
-
noble.emit('stateChange', 'poweredOn');
|
|
72
|
-
noble.emit('scanStart');
|
|
73
|
-
// Check for single callback
|
|
74
|
-
noble.emit('scanStart');
|
|
75
|
-
|
|
76
|
-
assert.calledOnceWithExactly(
|
|
77
|
-
mockBindings.startScanning,
|
|
78
|
-
expectedServiceUuids,
|
|
79
|
-
callback
|
|
80
|
-
);
|
|
81
|
-
assert.calledOnceWithExactly(
|
|
82
|
-
eventCallback,
|
|
83
|
-
'calling startScanning(serviceUuids, callback) is deprecated'
|
|
84
|
-
);
|
|
85
|
-
});
|
|
46
|
+
afterEach(() => {
|
|
47
|
+
jest.clearAllMocks();
|
|
48
|
+
});
|
|
86
49
|
|
|
87
|
-
|
|
50
|
+
describe('startScanning', () => {
|
|
51
|
+
|
|
52
|
+
test('should delegate to binding', () => {
|
|
88
53
|
const expectedServiceUuids = [1, 2, 3];
|
|
89
54
|
const expectedAllowDuplicates = true;
|
|
90
55
|
|
|
@@ -96,17 +61,17 @@ describe('noble', () => {
|
|
|
96
61
|
// Check for single callback
|
|
97
62
|
noble.emit('scanStart');
|
|
98
63
|
|
|
99
|
-
|
|
100
|
-
mockBindings.startScanning,
|
|
64
|
+
expect(mockBindings.startScanning).toHaveBeenCalledWith(
|
|
101
65
|
expectedServiceUuids,
|
|
102
66
|
expectedAllowDuplicates
|
|
103
67
|
);
|
|
68
|
+
expect(mockBindings.startScanning).toHaveBeenCalledTimes(1);
|
|
104
69
|
});
|
|
105
70
|
|
|
106
|
-
|
|
71
|
+
test('should delegate to callback', async () => {
|
|
107
72
|
const expectedServiceUuids = [1, 2, 3];
|
|
108
73
|
const expectedAllowDuplicates = true;
|
|
109
|
-
const callback =
|
|
74
|
+
const callback = jest.fn();
|
|
110
75
|
|
|
111
76
|
noble.startScanning(
|
|
112
77
|
expectedServiceUuids,
|
|
@@ -120,31 +85,32 @@ describe('noble', () => {
|
|
|
120
85
|
// Check for single callback
|
|
121
86
|
noble.emit('scanStart');
|
|
122
87
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
88
|
+
expect(callback).toHaveBeenCalledWith(null, undefined);
|
|
89
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
90
|
+
expect(mockBindings.startScanning).toHaveBeenCalledWith(
|
|
126
91
|
expectedServiceUuids,
|
|
127
92
|
expectedAllowDuplicates
|
|
128
93
|
);
|
|
94
|
+
expect(mockBindings.startScanning).toHaveBeenCalledTimes(1);
|
|
129
95
|
});
|
|
130
96
|
|
|
131
|
-
|
|
132
|
-
noble.
|
|
97
|
+
test('should delegate to callback, already initialized', async () => {
|
|
98
|
+
noble._initialized = true;
|
|
133
99
|
noble._state = 'poweredOn';
|
|
134
100
|
|
|
135
101
|
noble.startScanning();
|
|
136
102
|
|
|
137
|
-
|
|
138
|
-
mockBindings.startScanning,
|
|
103
|
+
expect(mockBindings.startScanning).toHaveBeenCalledWith(
|
|
139
104
|
undefined,
|
|
140
105
|
undefined
|
|
141
106
|
);
|
|
107
|
+
expect(mockBindings.startScanning).toHaveBeenCalledTimes(1);
|
|
142
108
|
});
|
|
143
109
|
|
|
144
|
-
|
|
110
|
+
test('should delegate to callback with filter', async () => {
|
|
145
111
|
const expectedServiceUuids = [1, 2, 3];
|
|
146
112
|
const expectedAllowDuplicates = true;
|
|
147
|
-
const callback =
|
|
113
|
+
const callback = jest.fn();
|
|
148
114
|
|
|
149
115
|
noble.startScanning(
|
|
150
116
|
expectedServiceUuids,
|
|
@@ -156,16 +122,17 @@ describe('noble', () => {
|
|
|
156
122
|
noble.emit('stateChange', 'poweredOn');
|
|
157
123
|
noble.emit('scanStart', 'filter');
|
|
158
124
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
125
|
+
expect(callback).toHaveBeenCalledWith(null, 'filter');
|
|
126
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
127
|
+
expect(mockBindings.startScanning).toHaveBeenCalledWith(
|
|
162
128
|
expectedServiceUuids,
|
|
163
129
|
expectedAllowDuplicates
|
|
164
130
|
);
|
|
131
|
+
expect(mockBindings.startScanning).toHaveBeenCalledTimes(1);
|
|
165
132
|
});
|
|
166
133
|
|
|
167
|
-
|
|
168
|
-
|
|
134
|
+
test('should throw an error if not powered on', async () => {
|
|
135
|
+
expect(() => {
|
|
169
136
|
noble.startScanning();
|
|
170
137
|
noble.emit('stateChange', 'poweredOff');
|
|
171
138
|
// Check for single callback
|
|
@@ -173,27 +140,14 @@ describe('noble', () => {
|
|
|
173
140
|
noble.emit('scanStart');
|
|
174
141
|
// Check for single callback
|
|
175
142
|
noble.emit('scanStart');
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
should(e.message).equal(
|
|
180
|
-
'Could not start scanning, state is poweredOff (not poweredOn)'
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
assert.notCalled(mockBindings.startScanning);
|
|
143
|
+
}).toThrow('Could not start scanning, state is poweredOff (not poweredOn)');
|
|
144
|
+
|
|
145
|
+
expect(mockBindings.startScanning).not.toHaveBeenCalled();
|
|
184
146
|
});
|
|
185
147
|
});
|
|
186
148
|
|
|
187
149
|
describe('startScanningAsync', () => {
|
|
188
|
-
|
|
189
|
-
mockBindings.startScanning = sinon.spy();
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
afterEach(() => {
|
|
193
|
-
sinon.reset();
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
it('should delegate to binding', async () => {
|
|
150
|
+
test('should delegate to binding', async () => {
|
|
197
151
|
const expectedServiceUuids = [1, 2, 3];
|
|
198
152
|
const expectedAllowDuplicates = true;
|
|
199
153
|
|
|
@@ -208,15 +162,15 @@ describe('noble', () => {
|
|
|
208
162
|
// Check for single callback
|
|
209
163
|
noble.emit('scanStart');
|
|
210
164
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
mockBindings.startScanning,
|
|
165
|
+
await expect(promise).resolves.toBeUndefined();
|
|
166
|
+
expect(mockBindings.startScanning).toHaveBeenCalledWith(
|
|
214
167
|
expectedServiceUuids,
|
|
215
168
|
expectedAllowDuplicates
|
|
216
169
|
);
|
|
170
|
+
expect(mockBindings.startScanning).toHaveBeenCalledTimes(1);
|
|
217
171
|
});
|
|
218
172
|
|
|
219
|
-
|
|
173
|
+
test('should throw an error if not powered on', async () => {
|
|
220
174
|
const promise = noble.startScanningAsync();
|
|
221
175
|
noble.emit('stateChange', 'poweredOff');
|
|
222
176
|
// Check for single callback
|
|
@@ -225,311 +179,335 @@ describe('noble', () => {
|
|
|
225
179
|
// Check for single callback
|
|
226
180
|
noble.emit('scanStart');
|
|
227
181
|
|
|
228
|
-
|
|
182
|
+
await expect(promise).rejects.toThrow(
|
|
229
183
|
'Could not start scanning, state is poweredOff (not poweredOn)'
|
|
230
184
|
);
|
|
231
|
-
|
|
185
|
+
expect(mockBindings.startScanning).not.toHaveBeenCalled();
|
|
232
186
|
});
|
|
233
187
|
});
|
|
234
188
|
|
|
235
189
|
describe('stopScanning', () => {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
afterEach(() => {
|
|
241
|
-
sinon.reset();
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
it('should no callback', async () => {
|
|
245
|
-
noble.initialized = true;
|
|
190
|
+
test('should no callback', async () => {
|
|
191
|
+
noble._initialized = true;
|
|
246
192
|
noble.stopScanning();
|
|
247
|
-
|
|
193
|
+
expect(mockBindings.stopScanning).toHaveBeenCalled();
|
|
194
|
+
expect(mockBindings.stopScanning).toHaveBeenCalledTimes(1);
|
|
248
195
|
});
|
|
249
196
|
});
|
|
250
197
|
|
|
251
198
|
describe('stopScanningAsync', () => {
|
|
252
|
-
|
|
253
|
-
mockBindings.stopScanning = sinon.spy();
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
afterEach(() => {
|
|
257
|
-
sinon.reset();
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
it('should not delegate to binding (not initialized)', async () => {
|
|
199
|
+
test('should not delegate to binding (not initialized)', async () => {
|
|
261
200
|
const promise = noble.stopScanningAsync();
|
|
262
201
|
noble.emit('scanStop');
|
|
263
202
|
|
|
264
|
-
|
|
265
|
-
|
|
203
|
+
await expect(promise).rejects.toThrow('Bindings are not initialized');
|
|
204
|
+
expect(mockBindings.stopScanning).not.toHaveBeenCalled();
|
|
266
205
|
});
|
|
267
206
|
|
|
268
|
-
|
|
269
|
-
noble.
|
|
207
|
+
test('should delegate to binding (initilazed)', async () => {
|
|
208
|
+
noble._initialized = true;
|
|
270
209
|
const promise = noble.stopScanningAsync();
|
|
271
210
|
noble.emit('scanStop');
|
|
272
211
|
|
|
273
|
-
|
|
274
|
-
|
|
212
|
+
await expect(promise).resolves.toBeUndefined();
|
|
213
|
+
expect(mockBindings.stopScanning).toHaveBeenCalled();
|
|
214
|
+
expect(mockBindings.stopScanning).toHaveBeenCalledTimes(1);
|
|
275
215
|
});
|
|
276
216
|
});
|
|
277
217
|
|
|
278
218
|
describe('connect', () => {
|
|
279
|
-
|
|
280
|
-
mockBindings.connect = sinon.spy();
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
afterEach(() => {
|
|
284
|
-
sinon.reset();
|
|
285
|
-
});
|
|
286
|
-
it('should delegate to binding', () => {
|
|
219
|
+
test('should delegate to binding', () => {
|
|
287
220
|
const peripheralUuid = 'peripheral-uuid';
|
|
288
221
|
const parameters = {};
|
|
289
222
|
|
|
223
|
+
mockBindings.addressToId = jest.fn().mockReturnValue(peripheralUuid);
|
|
290
224
|
noble.connect(peripheralUuid, parameters);
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
mockBindings.connect,
|
|
225
|
+
|
|
226
|
+
expect(mockBindings.connect).toHaveBeenCalledWith(
|
|
294
227
|
peripheralUuid,
|
|
295
228
|
parameters
|
|
296
229
|
);
|
|
230
|
+
expect(mockBindings.connect).toHaveBeenCalledTimes(1);
|
|
297
231
|
});
|
|
298
232
|
});
|
|
299
233
|
|
|
300
234
|
describe('onConnect', () => {
|
|
301
|
-
|
|
302
|
-
const emit =
|
|
303
|
-
noble._peripherals
|
|
304
|
-
uuid: { emit }
|
|
305
|
-
};
|
|
235
|
+
test('should emit connected on existing peripheral', () => {
|
|
236
|
+
const emit = jest.fn();
|
|
237
|
+
noble._peripherals.set('uuid', { emit });
|
|
306
238
|
|
|
307
|
-
const warningCallback =
|
|
239
|
+
const warningCallback = jest.fn();
|
|
308
240
|
|
|
309
241
|
noble.on('warning', warningCallback);
|
|
310
|
-
noble.
|
|
242
|
+
noble._onConnect('uuid', false);
|
|
311
243
|
|
|
312
|
-
|
|
313
|
-
|
|
244
|
+
expect(emit).toHaveBeenCalledWith('connect', false);
|
|
245
|
+
expect(emit).toHaveBeenCalledTimes(1);
|
|
246
|
+
expect(warningCallback).not.toHaveBeenCalled();
|
|
314
247
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
248
|
+
const peripheral = noble._peripherals.get('uuid');
|
|
249
|
+
expect(peripheral).toHaveProperty('emit', emit);
|
|
250
|
+
expect(peripheral).toHaveProperty('state', 'connected');
|
|
318
251
|
});
|
|
319
252
|
|
|
320
|
-
|
|
321
|
-
const emit =
|
|
322
|
-
noble._peripherals
|
|
323
|
-
uuid: { emit }
|
|
324
|
-
};
|
|
253
|
+
test('should emit error on existing peripheral', () => {
|
|
254
|
+
const emit = jest.fn();
|
|
255
|
+
noble._peripherals.set('uuid', { emit });
|
|
325
256
|
|
|
326
|
-
const warningCallback =
|
|
257
|
+
const warningCallback = jest.fn();
|
|
327
258
|
|
|
328
259
|
noble.on('warning', warningCallback);
|
|
329
|
-
noble.
|
|
260
|
+
noble._onConnect('uuid', true);
|
|
330
261
|
|
|
331
|
-
|
|
332
|
-
|
|
262
|
+
expect(emit).toHaveBeenCalledWith('connect', true);
|
|
263
|
+
expect(emit).toHaveBeenCalledTimes(1);
|
|
264
|
+
expect(warningCallback).not.toHaveBeenCalled();
|
|
333
265
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
266
|
+
const peripheral = noble._peripherals.get('uuid');
|
|
267
|
+
expect(peripheral).toHaveProperty('emit', emit);
|
|
268
|
+
expect(peripheral).toHaveProperty('state', 'error');
|
|
337
269
|
});
|
|
338
270
|
|
|
339
|
-
|
|
340
|
-
const warningCallback =
|
|
271
|
+
test('should emit warning on missing peripheral', () => {
|
|
272
|
+
const warningCallback = jest.fn();
|
|
341
273
|
|
|
342
274
|
noble.on('warning', warningCallback);
|
|
343
|
-
noble.
|
|
275
|
+
noble._onConnect('uuid', true);
|
|
344
276
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
277
|
+
expect(warningCallback).toHaveBeenCalledWith('unknown peripheral uuid connected!');
|
|
278
|
+
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
279
|
+
expect(noble._peripherals.size).toBe(0);
|
|
348
280
|
});
|
|
349
281
|
});
|
|
350
282
|
|
|
351
283
|
describe('setScanParameters', () => {
|
|
352
|
-
|
|
353
|
-
mockBindings.setScanParameters = sinon.spy();
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
afterEach(() => {
|
|
357
|
-
sinon.reset();
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
it('should delegate to binding', async () => {
|
|
284
|
+
test('should delegate to binding', async () => {
|
|
361
285
|
const interval = 'interval';
|
|
362
286
|
const window = 'window';
|
|
363
287
|
|
|
364
288
|
noble.setScanParameters(interval, window);
|
|
365
289
|
noble.emit('scanParametersSet');
|
|
366
290
|
|
|
367
|
-
|
|
368
|
-
mockBindings.setScanParameters,
|
|
291
|
+
expect(mockBindings.setScanParameters).toHaveBeenCalledWith(
|
|
369
292
|
interval,
|
|
370
293
|
window
|
|
371
294
|
);
|
|
295
|
+
expect(mockBindings.setScanParameters).toHaveBeenCalledTimes(1);
|
|
372
296
|
});
|
|
373
297
|
|
|
374
|
-
|
|
298
|
+
test('should delegate to callback too', async () => {
|
|
375
299
|
const interval = 'interval';
|
|
376
300
|
const window = 'window';
|
|
377
|
-
const callback =
|
|
301
|
+
const callback = jest.fn();
|
|
378
302
|
|
|
379
303
|
noble.setScanParameters(interval, window, callback);
|
|
380
304
|
noble.emit('scanParametersSet');
|
|
381
305
|
// Check for single callback
|
|
382
306
|
noble.emit('scanParametersSet');
|
|
383
307
|
|
|
384
|
-
|
|
385
|
-
mockBindings.setScanParameters,
|
|
308
|
+
expect(mockBindings.setScanParameters).toHaveBeenCalledWith(
|
|
386
309
|
interval,
|
|
387
310
|
window
|
|
388
311
|
);
|
|
389
|
-
|
|
312
|
+
expect(mockBindings.setScanParameters).toHaveBeenCalledTimes(1);
|
|
313
|
+
expect(callback).toHaveBeenCalled();
|
|
314
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
390
315
|
});
|
|
391
316
|
});
|
|
392
317
|
|
|
393
318
|
describe('cancelConnect', () => {
|
|
394
|
-
|
|
395
|
-
mockBindings.cancelConnect = sinon.spy();
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
afterEach(() => {
|
|
399
|
-
sinon.reset();
|
|
400
|
-
});
|
|
401
|
-
|
|
402
|
-
it('should delegate to binding', () => {
|
|
319
|
+
test('should delegate to binding', () => {
|
|
403
320
|
const peripheralUuid = 'peripheral-uuid';
|
|
404
321
|
const parameters = {};
|
|
405
322
|
|
|
323
|
+
mockBindings.addressToId = jest.fn().mockReturnValue(peripheralUuid);
|
|
406
324
|
noble.cancelConnect(peripheralUuid, parameters);
|
|
407
325
|
|
|
408
|
-
|
|
409
|
-
mockBindings.cancelConnect,
|
|
326
|
+
expect(mockBindings.cancelConnect).toHaveBeenCalledWith(
|
|
410
327
|
peripheralUuid,
|
|
411
328
|
parameters
|
|
412
329
|
);
|
|
330
|
+
expect(mockBindings.cancelConnect).toHaveBeenCalledTimes(1);
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
test('should update peripheral state when cancelConnect is called during connection', () => {
|
|
334
|
+
// Setup a peripheral in connecting state
|
|
335
|
+
const peripheral = {
|
|
336
|
+
id: 'test-peripheral',
|
|
337
|
+
state: 'connecting',
|
|
338
|
+
emit: jest.fn()
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
noble._peripherals.set('test-peripheral', peripheral);
|
|
342
|
+
|
|
343
|
+
// Mock addressToId to return the peripheral id
|
|
344
|
+
mockBindings.addressToId = jest.fn().mockReturnValue('test-peripheral');
|
|
345
|
+
|
|
346
|
+
// Spy on noble's emit method
|
|
347
|
+
const emitSpy = jest.spyOn(noble, 'emit');
|
|
348
|
+
|
|
349
|
+
// Call cancelConnect
|
|
350
|
+
noble.cancelConnect('test-peripheral');
|
|
351
|
+
|
|
352
|
+
// Verify cancelConnect was called with correct parameters
|
|
353
|
+
expect(mockBindings.cancelConnect).toHaveBeenCalledWith(
|
|
354
|
+
'test-peripheral',
|
|
355
|
+
undefined
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
// Verify peripheral state was updated to disconnected
|
|
359
|
+
expect(peripheral.state).toBe('disconnected');
|
|
360
|
+
|
|
361
|
+
// Verify connect event was emitted with error
|
|
362
|
+
expect(emitSpy).toHaveBeenCalledWith(
|
|
363
|
+
'connect:test-peripheral',
|
|
364
|
+
expect.objectContaining({
|
|
365
|
+
message: 'connection canceled!'
|
|
366
|
+
})
|
|
367
|
+
);
|
|
413
368
|
});
|
|
414
369
|
});
|
|
415
370
|
|
|
416
|
-
|
|
417
|
-
const callback =
|
|
371
|
+
test('should emit state', () => {
|
|
372
|
+
const callback = jest.fn();
|
|
418
373
|
noble.on('stateChange', callback);
|
|
419
374
|
|
|
420
375
|
const state = 'newState';
|
|
421
|
-
noble.
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
376
|
+
noble._onStateChange(state);
|
|
377
|
+
|
|
378
|
+
expect(noble.state).toBe(state);
|
|
379
|
+
expect(callback).toHaveBeenCalledWith(state);
|
|
380
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
describe('waitForPoweredOnAsync', () => {
|
|
384
|
+
test('should resolve when state changes to poweredOn', async () => {
|
|
385
|
+
// Set initial state to something other than poweredOn
|
|
386
|
+
noble._state = 'poweredOff';
|
|
387
|
+
|
|
388
|
+
// Create promise but don't await it yet
|
|
389
|
+
const promise = noble.waitForPoweredOnAsync();
|
|
390
|
+
|
|
391
|
+
// Emit state change event to poweredOn
|
|
392
|
+
noble.emit('stateChange', 'poweredOn');
|
|
393
|
+
|
|
394
|
+
// Now await the promise - it should resolve
|
|
395
|
+
await expect(promise).resolves.toBeUndefined();
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
test('should resolve immediately if state is already poweredOn', async () => {
|
|
399
|
+
// Set initial state to poweredOn
|
|
400
|
+
noble._state = 'poweredOn';
|
|
401
|
+
|
|
402
|
+
// Multiple concurrent calls should resolve immediately
|
|
403
|
+
const promise1 = noble.waitForPoweredOnAsync();
|
|
404
|
+
const promise2 = noble.waitForPoweredOnAsync();
|
|
405
|
+
const promise3 = noble.waitForPoweredOnAsync();
|
|
406
|
+
|
|
407
|
+
// Both promises should resolve
|
|
408
|
+
await expect(promise1).resolves.toBeUndefined();
|
|
409
|
+
await expect(promise2).resolves.toBeUndefined();
|
|
410
|
+
await expect(promise3).resolves.toBeUndefined();
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
test('should reject if timeout occurs before state changes to poweredOn', async () => {
|
|
414
|
+
// Set initial state to something other than poweredOn
|
|
415
|
+
noble._state = 'poweredOff';
|
|
416
|
+
|
|
417
|
+
// Set a very short timeout
|
|
418
|
+
const promise = noble.waitForPoweredOnAsync(10);
|
|
419
|
+
|
|
420
|
+
// Promise should reject after timeout
|
|
421
|
+
await expect(promise).rejects.toThrow('Timeout waiting for Noble to be powered on');
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
test('should change address', () => {
|
|
428
426
|
const address = 'newAddress';
|
|
429
|
-
noble.
|
|
427
|
+
noble._onAddressChange(address);
|
|
430
428
|
|
|
431
|
-
|
|
429
|
+
expect(noble.address).toBe(address);
|
|
432
430
|
});
|
|
433
431
|
|
|
434
|
-
|
|
435
|
-
const callback =
|
|
432
|
+
test('should emit scanParametersSet event', () => {
|
|
433
|
+
const callback = jest.fn();
|
|
436
434
|
noble.on('scanParametersSet', callback);
|
|
437
435
|
|
|
438
|
-
noble.
|
|
436
|
+
noble._onScanParametersSet();
|
|
439
437
|
|
|
440
|
-
|
|
438
|
+
expect(callback).toHaveBeenCalled();
|
|
439
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
441
440
|
});
|
|
442
441
|
|
|
443
|
-
|
|
444
|
-
const callback =
|
|
442
|
+
test('should emit scanStart event', () => {
|
|
443
|
+
const callback = jest.fn();
|
|
445
444
|
noble.on('scanStart', callback);
|
|
446
445
|
|
|
447
|
-
noble.
|
|
446
|
+
noble._onScanStart('filterDuplicates');
|
|
448
447
|
|
|
449
|
-
|
|
448
|
+
expect(callback).toHaveBeenCalledWith('filterDuplicates');
|
|
449
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
450
450
|
});
|
|
451
451
|
|
|
452
|
-
|
|
453
|
-
const callback =
|
|
452
|
+
test('should emit scanStop event', () => {
|
|
453
|
+
const callback = jest.fn();
|
|
454
454
|
noble.on('scanStop', callback);
|
|
455
455
|
|
|
456
|
-
noble.
|
|
456
|
+
noble._onScanStop();
|
|
457
457
|
|
|
458
|
-
|
|
458
|
+
expect(callback).toHaveBeenCalled();
|
|
459
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
459
460
|
});
|
|
460
461
|
|
|
461
462
|
describe('reset', () => {
|
|
462
|
-
|
|
463
|
-
mockBindings.reset = sinon.spy();
|
|
464
|
-
});
|
|
465
|
-
|
|
466
|
-
afterEach(() => {
|
|
467
|
-
sinon.reset();
|
|
468
|
-
});
|
|
469
|
-
|
|
470
|
-
it('should reset', () => {
|
|
463
|
+
test('should reset', () => {
|
|
471
464
|
noble.reset();
|
|
472
|
-
|
|
465
|
+
expect(mockBindings.reset).toHaveBeenCalled();
|
|
466
|
+
expect(mockBindings.reset).toHaveBeenCalledTimes(1);
|
|
473
467
|
});
|
|
474
468
|
});
|
|
475
469
|
|
|
476
470
|
describe('disconnect', () => {
|
|
477
|
-
|
|
478
|
-
mockBindings.disconnect = sinon.spy();
|
|
479
|
-
});
|
|
480
|
-
|
|
481
|
-
afterEach(() => {
|
|
482
|
-
sinon.reset();
|
|
483
|
-
});
|
|
484
|
-
|
|
485
|
-
it('should disconnect', () => {
|
|
471
|
+
test('should disconnect', () => {
|
|
486
472
|
noble.disconnect('peripheralUuid');
|
|
487
|
-
|
|
473
|
+
expect(mockBindings.disconnect).toHaveBeenCalledWith('peripheralUuid');
|
|
474
|
+
expect(mockBindings.disconnect).toHaveBeenCalledTimes(1);
|
|
488
475
|
});
|
|
489
476
|
});
|
|
490
477
|
|
|
491
478
|
describe('onDisconnect', () => {
|
|
492
|
-
|
|
493
|
-
const emit =
|
|
494
|
-
noble._peripherals
|
|
495
|
-
uuid: { emit }
|
|
496
|
-
};
|
|
479
|
+
test('should emit disconnect on existing peripheral', () => {
|
|
480
|
+
const emit = jest.fn();
|
|
481
|
+
noble._peripherals.set('uuid', { emit });
|
|
497
482
|
|
|
498
|
-
const warningCallback =
|
|
483
|
+
const warningCallback = jest.fn();
|
|
499
484
|
|
|
500
485
|
noble.on('warning', warningCallback);
|
|
501
|
-
noble.
|
|
486
|
+
noble._onDisconnect('uuid', false);
|
|
502
487
|
|
|
503
|
-
|
|
504
|
-
|
|
488
|
+
expect(emit).toHaveBeenCalledWith('disconnect', false);
|
|
489
|
+
expect(emit).toHaveBeenCalledTimes(1);
|
|
490
|
+
expect(warningCallback).not.toHaveBeenCalled();
|
|
505
491
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
492
|
+
const peripheral = noble._peripherals.get('uuid');
|
|
493
|
+
expect(peripheral).toHaveProperty('emit', emit);
|
|
494
|
+
expect(peripheral).toHaveProperty('state', 'disconnected');
|
|
509
495
|
});
|
|
510
496
|
|
|
511
|
-
|
|
512
|
-
const warningCallback =
|
|
497
|
+
test('should emit warning on missing peripheral', () => {
|
|
498
|
+
const warningCallback = jest.fn();
|
|
513
499
|
|
|
514
500
|
noble.on('warning', warningCallback);
|
|
515
|
-
noble.
|
|
501
|
+
noble._onDisconnect('uuid', true);
|
|
516
502
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
503
|
+
expect(warningCallback).toHaveBeenCalledWith('unknown peripheral uuid disconnected!');
|
|
504
|
+
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
505
|
+
expect(noble._peripherals.size).toBe(0);
|
|
520
506
|
});
|
|
521
507
|
});
|
|
522
508
|
|
|
523
509
|
describe('onDiscover', () => {
|
|
524
|
-
|
|
525
|
-
mockBindings.disconnect = sinon.spy();
|
|
526
|
-
});
|
|
527
|
-
|
|
528
|
-
afterEach(() => {
|
|
529
|
-
sinon.reset();
|
|
530
|
-
});
|
|
531
|
-
|
|
532
|
-
it('should add new peripheral', () => {
|
|
510
|
+
test('should add new peripheral', () => {
|
|
533
511
|
const uuid = 'uuid';
|
|
534
512
|
const address = 'address';
|
|
535
513
|
const addressType = 'addressType';
|
|
@@ -537,10 +515,10 @@ describe('noble', () => {
|
|
|
537
515
|
const advertisement = [];
|
|
538
516
|
const rssi = 'rssi';
|
|
539
517
|
|
|
540
|
-
const eventCallback =
|
|
518
|
+
const eventCallback = jest.fn();
|
|
541
519
|
noble.on('discover', eventCallback);
|
|
542
520
|
|
|
543
|
-
noble.
|
|
521
|
+
noble._onDiscover(
|
|
544
522
|
uuid,
|
|
545
523
|
address,
|
|
546
524
|
addressType,
|
|
@@ -550,25 +528,27 @@ describe('noble', () => {
|
|
|
550
528
|
);
|
|
551
529
|
|
|
552
530
|
// Check new peripheral
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
531
|
+
expect(noble._peripherals.has(uuid)).toBe(true);
|
|
532
|
+
expect(noble._discoveredPeripherals.has(uuid)).toBe(true);
|
|
533
|
+
|
|
534
|
+
const peripheral = noble._peripherals.get(uuid);
|
|
535
|
+
expect(peripheral._noble).toBe(noble);
|
|
536
|
+
expect(peripheral.id).toBe(uuid);
|
|
537
|
+
expect(peripheral.address).toBe(address);
|
|
538
|
+
expect(peripheral.addressType).toBe(addressType);
|
|
539
|
+
expect(peripheral.connectable).toBe(connectable);
|
|
540
|
+
expect(peripheral.advertisement).toBe(advertisement);
|
|
541
|
+
expect(peripheral.rssi).toBe(rssi);
|
|
542
|
+
|
|
543
|
+
expect(noble._services[uuid]).toEqual({});
|
|
544
|
+
expect(noble._characteristics[uuid]).toEqual({});
|
|
545
|
+
expect(noble._descriptors[uuid]).toEqual({});
|
|
546
|
+
|
|
547
|
+
expect(eventCallback).toHaveBeenCalledWith(peripheral);
|
|
548
|
+
expect(eventCallback).toHaveBeenCalledTimes(1);
|
|
569
549
|
});
|
|
570
550
|
|
|
571
|
-
|
|
551
|
+
test('should update existing peripheral', () => {
|
|
572
552
|
const uuid = 'uuid';
|
|
573
553
|
const address = 'address';
|
|
574
554
|
const addressType = 'addressType';
|
|
@@ -577,7 +557,7 @@ describe('noble', () => {
|
|
|
577
557
|
const rssi = 'rssi';
|
|
578
558
|
|
|
579
559
|
// init peripheral
|
|
580
|
-
noble._peripherals
|
|
560
|
+
noble._peripherals.set(uuid, new Peripheral(
|
|
581
561
|
noble,
|
|
582
562
|
uuid,
|
|
583
563
|
'originalAddress',
|
|
@@ -585,12 +565,12 @@ describe('noble', () => {
|
|
|
585
565
|
'originalConnectable',
|
|
586
566
|
['adv1'],
|
|
587
567
|
'originalRssi'
|
|
588
|
-
);
|
|
568
|
+
));
|
|
589
569
|
|
|
590
|
-
const eventCallback =
|
|
570
|
+
const eventCallback = jest.fn();
|
|
591
571
|
noble.on('discover', eventCallback);
|
|
592
572
|
|
|
593
|
-
noble.
|
|
573
|
+
noble._onDiscover(
|
|
594
574
|
uuid,
|
|
595
575
|
address,
|
|
596
576
|
addressType,
|
|
@@ -599,26 +579,28 @@ describe('noble', () => {
|
|
|
599
579
|
rssi
|
|
600
580
|
);
|
|
601
581
|
|
|
602
|
-
// Check
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
582
|
+
// Check updated peripheral
|
|
583
|
+
expect(noble._peripherals.has(uuid)).toBe(true);
|
|
584
|
+
expect(noble._discoveredPeripherals.has(uuid)).toBe(true);
|
|
585
|
+
|
|
586
|
+
const peripheral = noble._peripherals.get(uuid);
|
|
587
|
+
expect(peripheral._noble).toBe(noble);
|
|
588
|
+
expect(peripheral.id).toBe(uuid);
|
|
589
|
+
expect(peripheral.address).toBe('originalAddress');
|
|
590
|
+
expect(peripheral.addressType).toBe('originalAddressType');
|
|
591
|
+
expect(peripheral.connectable).toBe(connectable);
|
|
592
|
+
expect(peripheral.advertisement).toEqual(['adv1', 'adv2', 'adv3']);
|
|
593
|
+
expect(peripheral.rssi).toBe(rssi);
|
|
594
|
+
|
|
595
|
+
expect(Object.keys(noble._services)).toHaveLength(0);
|
|
596
|
+
expect(Object.keys(noble._characteristics)).toHaveLength(0);
|
|
597
|
+
expect(Object.keys(noble._descriptors)).toHaveLength(0);
|
|
598
|
+
|
|
599
|
+
expect(eventCallback).toHaveBeenCalledWith(peripheral);
|
|
600
|
+
expect(eventCallback).toHaveBeenCalledTimes(1);
|
|
619
601
|
});
|
|
620
602
|
|
|
621
|
-
|
|
603
|
+
test('should emit on duplicate', () => {
|
|
622
604
|
const uuid = 'uuid';
|
|
623
605
|
const address = 'address';
|
|
624
606
|
const addressType = 'addressType';
|
|
@@ -627,13 +609,13 @@ describe('noble', () => {
|
|
|
627
609
|
const rssi = 'rssi';
|
|
628
610
|
|
|
629
611
|
// register peripheral
|
|
630
|
-
noble.
|
|
612
|
+
noble._discoveredPeripherals.add(uuid);
|
|
631
613
|
noble._allowDuplicates = true;
|
|
632
614
|
|
|
633
|
-
const eventCallback =
|
|
615
|
+
const eventCallback = jest.fn();
|
|
634
616
|
noble.on('discover', eventCallback);
|
|
635
617
|
|
|
636
|
-
noble.
|
|
618
|
+
noble._onDiscover(
|
|
637
619
|
uuid,
|
|
638
620
|
address,
|
|
639
621
|
addressType,
|
|
@@ -642,10 +624,11 @@ describe('noble', () => {
|
|
|
642
624
|
rssi
|
|
643
625
|
);
|
|
644
626
|
|
|
645
|
-
|
|
627
|
+
expect(eventCallback).toHaveBeenCalledWith(noble._peripherals.get(uuid));
|
|
628
|
+
expect(eventCallback).toHaveBeenCalledTimes(1);
|
|
646
629
|
});
|
|
647
630
|
|
|
648
|
-
|
|
631
|
+
test('should not emit on duplicate', () => {
|
|
649
632
|
const uuid = 'uuid';
|
|
650
633
|
const address = 'address';
|
|
651
634
|
const addressType = 'addressType';
|
|
@@ -654,12 +637,13 @@ describe('noble', () => {
|
|
|
654
637
|
const rssi = 'rssi';
|
|
655
638
|
|
|
656
639
|
// register peripheral
|
|
657
|
-
noble.
|
|
640
|
+
noble._discoveredPeripherals.add(uuid);
|
|
641
|
+
noble._allowDuplicates = false;
|
|
658
642
|
|
|
659
|
-
const eventCallback =
|
|
643
|
+
const eventCallback = jest.fn();
|
|
660
644
|
noble.on('discover', eventCallback);
|
|
661
645
|
|
|
662
|
-
noble.
|
|
646
|
+
noble._onDiscover(
|
|
663
647
|
uuid,
|
|
664
648
|
address,
|
|
665
649
|
addressType,
|
|
@@ -668,10 +652,10 @@ describe('noble', () => {
|
|
|
668
652
|
rssi
|
|
669
653
|
);
|
|
670
654
|
|
|
671
|
-
|
|
655
|
+
expect(eventCallback).not.toHaveBeenCalled();
|
|
672
656
|
});
|
|
673
657
|
|
|
674
|
-
|
|
658
|
+
test('should emit on new peripheral (even if duplicates are disallowed)', () => {
|
|
675
659
|
const uuid = 'uuid';
|
|
676
660
|
const address = 'address';
|
|
677
661
|
const addressType = 'addressType';
|
|
@@ -679,10 +663,10 @@ describe('noble', () => {
|
|
|
679
663
|
const advertisement = ['adv1', 'adv2', 'adv3'];
|
|
680
664
|
const rssi = 'rssi';
|
|
681
665
|
|
|
682
|
-
const eventCallback =
|
|
666
|
+
const eventCallback = jest.fn();
|
|
683
667
|
noble.on('discover', eventCallback);
|
|
684
668
|
|
|
685
|
-
noble.
|
|
669
|
+
noble._onDiscover(
|
|
686
670
|
uuid,
|
|
687
671
|
address,
|
|
688
672
|
addressType,
|
|
@@ -691,69 +675,57 @@ describe('noble', () => {
|
|
|
691
675
|
rssi
|
|
692
676
|
);
|
|
693
677
|
|
|
694
|
-
|
|
678
|
+
expect(eventCallback).toHaveBeenCalledWith(noble._peripherals.get(uuid));
|
|
679
|
+
expect(eventCallback).toHaveBeenCalledTimes(1);
|
|
695
680
|
});
|
|
696
681
|
});
|
|
697
682
|
|
|
698
683
|
describe('updateRssi', () => {
|
|
699
|
-
|
|
700
|
-
mockBindings.updateRssi = sinon.spy();
|
|
701
|
-
});
|
|
702
|
-
|
|
703
|
-
afterEach(() => {
|
|
704
|
-
sinon.reset();
|
|
705
|
-
});
|
|
706
|
-
|
|
707
|
-
it('should updateRssi', () => {
|
|
684
|
+
test('should updateRssi', () => {
|
|
708
685
|
noble.updateRssi('peripheralUuid');
|
|
709
|
-
|
|
686
|
+
expect(mockBindings.updateRssi).toHaveBeenCalledWith('peripheralUuid');
|
|
687
|
+
expect(mockBindings.updateRssi).toHaveBeenCalledTimes(1);
|
|
710
688
|
});
|
|
711
689
|
});
|
|
712
690
|
|
|
713
691
|
describe('onRssiUpdate', () => {
|
|
714
|
-
|
|
715
|
-
const emit =
|
|
716
|
-
noble._peripherals
|
|
717
|
-
uuid: { emit }
|
|
718
|
-
};
|
|
719
|
-
|
|
720
|
-
const warningCallback = sinon.spy();
|
|
692
|
+
test('should emit rssiUpdate on existing peripheral', () => {
|
|
693
|
+
const emit = jest.fn();
|
|
694
|
+
noble._peripherals.set('uuid', { emit });
|
|
721
695
|
|
|
722
|
-
noble.
|
|
723
|
-
noble.onRssiUpdate('uuid', 3);
|
|
696
|
+
noble._onRssiUpdate('uuid', 3);
|
|
724
697
|
|
|
725
|
-
|
|
726
|
-
|
|
698
|
+
expect(emit).toHaveBeenCalledWith('rssiUpdate', 3, undefined);
|
|
699
|
+
expect(emit).toHaveBeenCalledTimes(1);
|
|
727
700
|
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
701
|
+
const peripheral = noble._peripherals.get('uuid');
|
|
702
|
+
expect(peripheral).toHaveProperty('emit', emit);
|
|
703
|
+
expect(peripheral).toHaveProperty('rssi', 3);
|
|
731
704
|
});
|
|
732
705
|
|
|
733
|
-
|
|
734
|
-
const warningCallback =
|
|
706
|
+
test('should emit warning on missing peripheral', () => {
|
|
707
|
+
const warningCallback = jest.fn();
|
|
735
708
|
|
|
736
709
|
noble.on('warning', warningCallback);
|
|
737
|
-
noble.
|
|
710
|
+
noble._onRssiUpdate('uuid', 4);
|
|
738
711
|
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
712
|
+
expect(warningCallback).toHaveBeenCalledWith('unknown peripheral uuid RSSI update!');
|
|
713
|
+
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
714
|
+
expect(noble._peripherals.size).toBe(0);
|
|
742
715
|
});
|
|
743
716
|
});
|
|
744
717
|
|
|
745
|
-
|
|
746
|
-
noble.addService =
|
|
718
|
+
test('should add multiple services', () => {
|
|
719
|
+
noble.addService = jest.fn().mockImplementation((peripheralUuid, service) => service);
|
|
747
720
|
|
|
748
721
|
const peripheralUuid = 'peripheralUuid';
|
|
749
722
|
const services = ['service1', 'service2'];
|
|
750
723
|
const result = noble.addServices(peripheralUuid, services);
|
|
751
724
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
should(result).deepEqual(services);
|
|
725
|
+
expect(noble.addService).toHaveBeenCalledTimes(2);
|
|
726
|
+
expect(noble.addService).toHaveBeenNthCalledWith(1, peripheralUuid, 'service1');
|
|
727
|
+
expect(noble.addService).toHaveBeenNthCalledWith(2, peripheralUuid, 'service2');
|
|
728
|
+
expect(result).toEqual(services);
|
|
757
729
|
});
|
|
758
730
|
|
|
759
731
|
describe('addService', () => {
|
|
@@ -764,58 +736,59 @@ describe('noble', () => {
|
|
|
764
736
|
const peripheral = {};
|
|
765
737
|
|
|
766
738
|
beforeEach(() => {
|
|
767
|
-
noble._peripherals
|
|
739
|
+
noble._peripherals.set(peripheralUuid, peripheral);
|
|
768
740
|
noble._services = { [peripheralUuid]: {} };
|
|
769
741
|
noble._characteristics = { [peripheralUuid]: {} };
|
|
770
742
|
noble._descriptors = { [peripheralUuid]: {} };
|
|
771
743
|
});
|
|
772
744
|
|
|
773
|
-
|
|
774
|
-
noble._bindings.addService =
|
|
745
|
+
test('should add service to lower layer', () => {
|
|
746
|
+
noble._bindings.addService = jest.fn();
|
|
775
747
|
|
|
776
748
|
const result = noble.addService(peripheralUuid, service);
|
|
777
749
|
|
|
778
|
-
|
|
750
|
+
expect(noble._bindings.addService).toHaveBeenCalledWith(peripheralUuid, service);
|
|
751
|
+
expect(noble._bindings.addService).toHaveBeenCalledTimes(1);
|
|
779
752
|
|
|
780
753
|
const expectedService = new Service(noble, peripheralUuid, service.uuid);
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
754
|
+
expect(result).toEqual(expectedService);
|
|
755
|
+
expect(peripheral.services).toEqual([expectedService]);
|
|
756
|
+
expect(noble._services).toEqual({
|
|
784
757
|
[peripheralUuid]: {
|
|
785
758
|
[service.uuid]: expectedService
|
|
786
759
|
}
|
|
787
760
|
});
|
|
788
|
-
|
|
761
|
+
expect(noble._characteristics).toEqual({
|
|
789
762
|
[peripheralUuid]: {
|
|
790
763
|
[service.uuid]: {}
|
|
791
764
|
}
|
|
792
765
|
});
|
|
793
|
-
|
|
766
|
+
expect(noble._descriptors).toEqual({
|
|
794
767
|
[peripheralUuid]: {
|
|
795
768
|
[service.uuid]: {}
|
|
796
769
|
}
|
|
797
770
|
});
|
|
798
771
|
});
|
|
799
772
|
|
|
800
|
-
|
|
773
|
+
test('should add service only to noble', () => {
|
|
801
774
|
peripheral.services = [];
|
|
802
775
|
|
|
803
776
|
const result = noble.addService(peripheralUuid, service);
|
|
804
777
|
|
|
805
778
|
const expectedService = new Service(noble, peripheralUuid, service.uuid);
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
779
|
+
expect(result).toEqual(expectedService);
|
|
780
|
+
expect(peripheral.services).toEqual([expectedService]);
|
|
781
|
+
expect(noble._services).toEqual({
|
|
809
782
|
[peripheralUuid]: {
|
|
810
783
|
[service.uuid]: expectedService
|
|
811
784
|
}
|
|
812
785
|
});
|
|
813
|
-
|
|
786
|
+
expect(noble._characteristics).toEqual({
|
|
814
787
|
[peripheralUuid]: {
|
|
815
788
|
[service.uuid]: {}
|
|
816
789
|
}
|
|
817
790
|
});
|
|
818
|
-
|
|
791
|
+
expect(noble._descriptors).toEqual({
|
|
819
792
|
[peripheralUuid]: {
|
|
820
793
|
[service.uuid]: {}
|
|
821
794
|
}
|
|
@@ -827,740 +800,105 @@ describe('noble', () => {
|
|
|
827
800
|
const peripheralUuid = 'peripheralUuid';
|
|
828
801
|
const services = ['service1', 'service2'];
|
|
829
802
|
|
|
830
|
-
|
|
831
|
-
const callback =
|
|
803
|
+
test('should not emit servicesDiscovered', () => {
|
|
804
|
+
const callback = jest.fn();
|
|
832
805
|
noble.on('servicesDiscovered', callback);
|
|
833
806
|
|
|
834
|
-
noble.
|
|
807
|
+
noble._onServicesDiscovered(peripheralUuid, services);
|
|
835
808
|
|
|
836
|
-
|
|
809
|
+
expect(callback).not.toHaveBeenCalled();
|
|
837
810
|
});
|
|
838
811
|
|
|
839
|
-
|
|
840
|
-
const emit =
|
|
841
|
-
noble._peripherals
|
|
812
|
+
test('should emit servicesDiscovered', () => {
|
|
813
|
+
const emit = jest.fn();
|
|
814
|
+
noble._peripherals.set(peripheralUuid, { uuid: 'peripheral', emit });
|
|
842
815
|
|
|
843
|
-
noble.
|
|
816
|
+
noble._onServicesDiscovered(peripheralUuid, services);
|
|
844
817
|
|
|
845
|
-
|
|
818
|
+
expect(emit).toHaveBeenCalledWith('servicesDiscovered', { uuid: 'peripheral', emit }, services);
|
|
819
|
+
expect(emit).toHaveBeenCalledTimes(1);
|
|
846
820
|
});
|
|
847
821
|
});
|
|
848
822
|
|
|
849
|
-
|
|
850
|
-
noble._bindings.discoverServices =
|
|
823
|
+
test('discoverServices - should delegate to bindings', () => {
|
|
824
|
+
noble._bindings.discoverServices = jest.fn();
|
|
851
825
|
noble.discoverServices('peripheral', 'uuids');
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
describe('onServicesDiscover', () => {
|
|
856
|
-
it('should emit warning', () => {
|
|
857
|
-
const warningCallback = sinon.spy();
|
|
858
|
-
|
|
859
|
-
noble.on('warning', warningCallback);
|
|
860
|
-
|
|
861
|
-
noble.onServicesDiscover('pUuid', ['service1', 'service2']);
|
|
862
|
-
|
|
863
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral pUuid services discover!');
|
|
864
|
-
});
|
|
865
|
-
|
|
866
|
-
it('should emit servicesDiscover and store services', () => {
|
|
867
|
-
const warningCallback = sinon.spy();
|
|
868
|
-
const discoverCallback = sinon.spy();
|
|
869
|
-
|
|
870
|
-
const peripheralUuid = 'peripheralUuid';
|
|
871
|
-
|
|
872
|
-
noble._peripherals = { [peripheralUuid]: { emit: discoverCallback } };
|
|
873
|
-
noble._services = { [peripheralUuid]: {} };
|
|
874
|
-
noble._characteristics = { [peripheralUuid]: {} };
|
|
875
|
-
noble._descriptors = { [peripheralUuid]: {} };
|
|
876
|
-
|
|
877
|
-
noble.on('warning', warningCallback);
|
|
878
|
-
|
|
879
|
-
noble.onServicesDiscover(peripheralUuid, ['service1', 'service2']);
|
|
880
|
-
|
|
881
|
-
const services = [new Service(noble, peripheralUuid, 'service1'), new Service(noble, peripheralUuid, 'service2')];
|
|
882
|
-
|
|
883
|
-
assert.calledOnceWithExactly(discoverCallback, 'servicesDiscover', services);
|
|
884
|
-
assert.notCalled(warningCallback);
|
|
885
|
-
|
|
886
|
-
should(noble._peripherals).deepEqual({
|
|
887
|
-
[peripheralUuid]: { services, emit: discoverCallback }
|
|
888
|
-
});
|
|
889
|
-
should(noble._services).deepEqual({
|
|
890
|
-
[peripheralUuid]: { service1: services[0], service2: services[1] }
|
|
891
|
-
});
|
|
892
|
-
should(noble._characteristics).deepEqual({
|
|
893
|
-
[peripheralUuid]: { service1: {}, service2: {} }
|
|
894
|
-
});
|
|
895
|
-
should(noble._descriptors).deepEqual({
|
|
896
|
-
[peripheralUuid]: { service1: {}, service2: {} }
|
|
897
|
-
});
|
|
898
|
-
});
|
|
899
|
-
});
|
|
900
|
-
|
|
901
|
-
describe('discoverIncludedServices', () => {
|
|
902
|
-
beforeEach(() => {
|
|
903
|
-
mockBindings.discoverIncludedServices = sinon.spy();
|
|
904
|
-
});
|
|
905
|
-
|
|
906
|
-
afterEach(() => {
|
|
907
|
-
sinon.reset();
|
|
908
|
-
});
|
|
909
|
-
|
|
910
|
-
it('should disconnect', () => {
|
|
911
|
-
noble.discoverIncludedServices('peripheralUuid', 'serviceUuid', 'serviceUuids');
|
|
912
|
-
assert.calledOnceWithExactly(mockBindings.discoverIncludedServices, 'peripheralUuid', 'serviceUuid', 'serviceUuids');
|
|
913
|
-
});
|
|
914
|
-
});
|
|
915
|
-
|
|
916
|
-
describe('addCharacteristics', () => {
|
|
917
|
-
const peripheralUuid = 'peripheralUuid';
|
|
918
|
-
const serviceUuid = 'serviceUuid';
|
|
919
|
-
const characteristic1 = {
|
|
920
|
-
uuid: 'characteristic1',
|
|
921
|
-
properties: 'properties1'
|
|
922
|
-
};
|
|
923
|
-
const characteristic2 = {
|
|
924
|
-
uuid: 'characteristic2',
|
|
925
|
-
properties: 'properties2'
|
|
926
|
-
};
|
|
927
|
-
const characteristics = [characteristic1, characteristic2];
|
|
928
|
-
|
|
929
|
-
beforeEach(() => {
|
|
930
|
-
noble._services = { [peripheralUuid]: { [serviceUuid]: {} } };
|
|
931
|
-
noble._characteristics = { [peripheralUuid]: { [serviceUuid]: {} } };
|
|
932
|
-
noble._descriptors = { [peripheralUuid]: { [serviceUuid]: {} } };
|
|
933
|
-
});
|
|
934
|
-
|
|
935
|
-
it('should delegate to bindings', () => {
|
|
936
|
-
const warningCallback = sinon.spy();
|
|
937
|
-
|
|
938
|
-
noble._bindings.addCharacteristics = sinon.spy();
|
|
939
|
-
noble.on('warning', warningCallback);
|
|
940
|
-
|
|
941
|
-
const result = noble.addCharacteristics(peripheralUuid, serviceUuid, characteristics);
|
|
942
|
-
|
|
943
|
-
assert.notCalled(warningCallback);
|
|
944
|
-
assert.calledOnceWithExactly(noble._bindings.addCharacteristics, peripheralUuid, serviceUuid, characteristics);
|
|
945
|
-
|
|
946
|
-
const expectedCharacteristics = [
|
|
947
|
-
new Characteristic(noble, peripheralUuid, serviceUuid, 'characteristic1', 'properties1'),
|
|
948
|
-
new Characteristic(noble, peripheralUuid, serviceUuid, 'characteristic2', 'properties2')
|
|
949
|
-
];
|
|
950
|
-
should(result).deepEqual(expectedCharacteristics);
|
|
951
|
-
should(noble._services).deepEqual({ [peripheralUuid]: { [serviceUuid]: { characteristics: expectedCharacteristics } } });
|
|
952
|
-
should(noble._characteristics).deepEqual({ [peripheralUuid]: { [serviceUuid]: { characteristic1: expectedCharacteristics[0], characteristic2: expectedCharacteristics[1] } } });
|
|
953
|
-
should(noble._descriptors).deepEqual({ [peripheralUuid]: { [serviceUuid]: { characteristic1: {}, characteristic2: {} } } });
|
|
954
|
-
});
|
|
955
|
-
|
|
956
|
-
it('should not delegate to bindings', () => {
|
|
957
|
-
const warningCallback = sinon.spy();
|
|
958
|
-
|
|
959
|
-
noble.on('warning', warningCallback);
|
|
960
|
-
|
|
961
|
-
const result = noble.addCharacteristics(peripheralUuid, serviceUuid, characteristics);
|
|
962
|
-
|
|
963
|
-
assert.notCalled(warningCallback);
|
|
964
|
-
|
|
965
|
-
const expectedCharacteristics = [
|
|
966
|
-
new Characteristic(noble, peripheralUuid, serviceUuid, 'characteristic1', 'properties1'),
|
|
967
|
-
new Characteristic(noble, peripheralUuid, serviceUuid, 'characteristic2', 'properties2')
|
|
968
|
-
];
|
|
969
|
-
should(result).deepEqual(expectedCharacteristics);
|
|
970
|
-
should(noble._services).deepEqual({ [peripheralUuid]: { [serviceUuid]: { characteristics: expectedCharacteristics } } });
|
|
971
|
-
should(noble._characteristics).deepEqual({ [peripheralUuid]: { [serviceUuid]: { characteristic1: expectedCharacteristics[0], characteristic2: expectedCharacteristics[1] } } });
|
|
972
|
-
should(noble._descriptors).deepEqual({ [peripheralUuid]: { [serviceUuid]: { characteristic1: {}, characteristic2: {} } } });
|
|
973
|
-
});
|
|
974
|
-
|
|
975
|
-
it('should emit warning', () => {
|
|
976
|
-
const warningCallback = sinon.spy();
|
|
977
|
-
|
|
978
|
-
noble.on('warning', warningCallback);
|
|
979
|
-
|
|
980
|
-
noble._services = { peripheralUuid: {} };
|
|
981
|
-
const result = noble.addCharacteristics(peripheralUuid, serviceUuid, characteristics);
|
|
982
|
-
|
|
983
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown service peripheralUuid, serviceUuid characteristics discover!');
|
|
984
|
-
|
|
985
|
-
should(result).equal(undefined);
|
|
986
|
-
should(noble._services).deepEqual({ [peripheralUuid]: { } });
|
|
987
|
-
should(noble._characteristics).deepEqual({ [peripheralUuid]: { [serviceUuid]: { } } });
|
|
988
|
-
should(noble._descriptors).deepEqual({ [peripheralUuid]: { [serviceUuid]: { } } });
|
|
989
|
-
});
|
|
990
|
-
});
|
|
991
|
-
|
|
992
|
-
it('onCharacteristicsDiscovered - should emit event', () => {
|
|
993
|
-
const emit = sinon.spy();
|
|
994
|
-
|
|
995
|
-
noble._services = {
|
|
996
|
-
peripheralUuid: {
|
|
997
|
-
serviceUuid: {
|
|
998
|
-
emit
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
};
|
|
1002
|
-
|
|
1003
|
-
noble.onCharacteristicsDiscovered('peripheralUuid', 'serviceUuid', 'characteristics');
|
|
1004
|
-
|
|
1005
|
-
assert.calledOnceWithExactly(emit, 'characteristicsDiscovered', 'characteristics');
|
|
1006
|
-
});
|
|
1007
|
-
|
|
1008
|
-
it('discoverCharacteristics - should delegate', () => {
|
|
1009
|
-
noble._bindings.discoverCharacteristics = sinon.spy();
|
|
1010
|
-
|
|
1011
|
-
noble.discoverCharacteristics('peripheralUuid', 'serviceUuid', 'characteristicUuids');
|
|
1012
|
-
|
|
1013
|
-
assert.calledOnceWithExactly(noble._bindings.discoverCharacteristics, 'peripheralUuid', 'serviceUuid', 'characteristicUuids');
|
|
826
|
+
expect(noble._bindings.discoverServices).toHaveBeenCalledWith('peripheral', 'uuids');
|
|
827
|
+
expect(noble._bindings.discoverServices).toHaveBeenCalledTimes(1);
|
|
1014
828
|
});
|
|
1015
829
|
|
|
1016
|
-
describe('
|
|
1017
|
-
|
|
1018
|
-
const
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
const serviceUuid = 'serviceUuid';
|
|
1022
|
-
const characteristics = ['characteristic1', 'characteristic2'];
|
|
1023
|
-
|
|
1024
|
-
noble.on('warning', warningCallback);
|
|
1025
|
-
|
|
1026
|
-
noble._services[peripheralUuid] = {};
|
|
1027
|
-
noble.onCharacteristicsDiscover(peripheralUuid, serviceUuid, characteristics);
|
|
1028
|
-
|
|
1029
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral peripheralUuid, serviceUuid characteristics discover!');
|
|
1030
|
-
});
|
|
1031
|
-
|
|
1032
|
-
it('should emit characteristicsDiscover and store characteristics', () => {
|
|
1033
|
-
const warningCallback = sinon.spy();
|
|
1034
|
-
const emit = sinon.spy();
|
|
1035
|
-
|
|
1036
|
-
const peripheralUuid = 'peripheralUuid';
|
|
1037
|
-
const serviceUuid = 'serviceUuid';
|
|
1038
|
-
const characteristics = [
|
|
1039
|
-
{ uuid: 'characteristic1', properties: 'properties1' },
|
|
1040
|
-
{ uuid: 'characteristic2', properties: 'properties2' }
|
|
1041
|
-
];
|
|
1042
|
-
|
|
1043
|
-
noble._services = { [peripheralUuid]: { [serviceUuid]: { emit } } };
|
|
1044
|
-
noble._characteristics = { [peripheralUuid]: { [serviceUuid]: {} } };
|
|
1045
|
-
noble._descriptors = { [peripheralUuid]: { [serviceUuid]: {} } };
|
|
1046
|
-
|
|
1047
|
-
noble.on('warning', warningCallback);
|
|
1048
|
-
|
|
1049
|
-
noble.onCharacteristicsDiscover(peripheralUuid, serviceUuid, characteristics);
|
|
1050
|
-
|
|
1051
|
-
const expectedCharacteristics = [
|
|
1052
|
-
new Characteristic(noble, peripheralUuid, serviceUuid, characteristics[0].uuid, characteristics[0].properties),
|
|
1053
|
-
new Characteristic(noble, peripheralUuid, serviceUuid, characteristics[1].uuid, characteristics[1].properties)
|
|
1054
|
-
];
|
|
1055
|
-
|
|
1056
|
-
assert.calledOnceWithExactly(emit, 'characteristicsDiscover', expectedCharacteristics);
|
|
1057
|
-
assert.notCalled(warningCallback);
|
|
1058
|
-
|
|
1059
|
-
should(noble._services).deepEqual({
|
|
1060
|
-
[peripheralUuid]: {
|
|
1061
|
-
[serviceUuid]: {
|
|
1062
|
-
emit, characteristics: expectedCharacteristics
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
});
|
|
1066
|
-
should(noble._characteristics).deepEqual({
|
|
1067
|
-
[peripheralUuid]: {
|
|
1068
|
-
[serviceUuid]: { characteristic1: expectedCharacteristics[0], characteristic2: expectedCharacteristics[1] }
|
|
1069
|
-
}
|
|
1070
|
-
});
|
|
1071
|
-
should(noble._descriptors).deepEqual({
|
|
1072
|
-
[peripheralUuid]: { [serviceUuid]: { characteristic1: {}, characteristic2: {} } }
|
|
1073
|
-
});
|
|
1074
|
-
});
|
|
1075
|
-
});
|
|
1076
|
-
|
|
1077
|
-
it('read - should delegate to bindings', () => {
|
|
1078
|
-
noble._bindings.read = sinon.spy();
|
|
1079
|
-
noble.read('peripheralUuid', 'serviceUuid', 'characteristicUuid');
|
|
1080
|
-
assert.calledOnceWithExactly(noble._bindings.read, 'peripheralUuid', 'serviceUuid', 'characteristicUuid');
|
|
1081
|
-
});
|
|
1082
|
-
|
|
1083
|
-
describe('onRead', () => {
|
|
1084
|
-
it('should emit warning', () => {
|
|
1085
|
-
const warningCallback = sinon.spy();
|
|
1086
|
-
noble.on('warning', warningCallback);
|
|
1087
|
-
|
|
1088
|
-
noble._characteristics = {
|
|
1089
|
-
peripheralUuid: {
|
|
1090
|
-
serviceUuid: {
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
1093
|
-
};
|
|
1094
|
-
noble.onRead('peripheralUuid', 'serviceUuid', 'characteristicUuid', 'data', 'isNotification');
|
|
1095
|
-
|
|
1096
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral peripheralUuid, serviceUuid, characteristicUuid read!');
|
|
1097
|
-
});
|
|
1098
|
-
|
|
1099
|
-
it('should emit data and read', () => {
|
|
1100
|
-
const warningCallback = sinon.spy();
|
|
1101
|
-
const emit = sinon.spy();
|
|
1102
|
-
|
|
1103
|
-
noble.on('warning', warningCallback);
|
|
1104
|
-
|
|
1105
|
-
noble._characteristics = {
|
|
1106
|
-
peripheralUuid: {
|
|
1107
|
-
serviceUuid: {
|
|
1108
|
-
characteristicUuid: {
|
|
1109
|
-
emit
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
1113
|
-
};
|
|
1114
|
-
noble.onRead('peripheralUuid', 'serviceUuid', 'characteristicUuid', 'dataArg', 'isNotification');
|
|
1115
|
-
|
|
1116
|
-
assert.notCalled(warningCallback);
|
|
1117
|
-
assert.callCount(emit, 2);
|
|
1118
|
-
assert.calledWithExactly(emit, 'data', 'dataArg', 'isNotification');
|
|
1119
|
-
assert.calledWithExactly(emit, 'read', 'dataArg', 'isNotification');
|
|
1120
|
-
});
|
|
1121
|
-
});
|
|
1122
|
-
|
|
1123
|
-
it('write - should delegate to bindings', () => {
|
|
1124
|
-
noble._bindings.write = sinon.spy();
|
|
1125
|
-
noble.write('peripheralUuid', 'serviceUuid', 'characteristicUuid', 'dataArg', 'isNotification');
|
|
1126
|
-
assert.calledOnceWithExactly(noble._bindings.write, 'peripheralUuid', 'serviceUuid', 'characteristicUuid', 'dataArg', 'isNotification');
|
|
1127
|
-
});
|
|
1128
|
-
|
|
1129
|
-
describe('onWrite', () => {
|
|
1130
|
-
it('should emit warning', () => {
|
|
1131
|
-
const warningCallback = sinon.spy();
|
|
1132
|
-
noble.on('warning', warningCallback);
|
|
1133
|
-
|
|
1134
|
-
noble._characteristics = {
|
|
1135
|
-
peripheralUuid: {
|
|
1136
|
-
serviceUuid: {
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
1139
|
-
};
|
|
1140
|
-
noble.onWrite('peripheralUuid', 'serviceUuid', 'characteristicUuid');
|
|
1141
|
-
|
|
1142
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral peripheralUuid, serviceUuid, characteristicUuid write!');
|
|
1143
|
-
});
|
|
1144
|
-
|
|
1145
|
-
it('should emit write', () => {
|
|
1146
|
-
const warningCallback = sinon.spy();
|
|
1147
|
-
const emit = sinon.spy();
|
|
1148
|
-
|
|
1149
|
-
noble.on('warning', warningCallback);
|
|
1150
|
-
|
|
1151
|
-
noble._characteristics = {
|
|
1152
|
-
peripheralUuid: {
|
|
1153
|
-
serviceUuid: {
|
|
1154
|
-
characteristicUuid: {
|
|
1155
|
-
emit
|
|
1156
|
-
}
|
|
1157
|
-
}
|
|
1158
|
-
}
|
|
1159
|
-
};
|
|
1160
|
-
noble.onWrite('peripheralUuid', 'serviceUuid', 'characteristicUuid');
|
|
1161
|
-
|
|
1162
|
-
assert.notCalled(warningCallback);
|
|
1163
|
-
assert.calledOnceWithExactly(emit, 'write');
|
|
1164
|
-
});
|
|
1165
|
-
});
|
|
1166
|
-
|
|
1167
|
-
it('broadcast - should delegate to bindings', () => {
|
|
1168
|
-
noble._bindings.broadcast = sinon.spy();
|
|
1169
|
-
noble.broadcast('peripheralUuid', 'serviceUuid', 'characteristicUuid', 'broadcast');
|
|
1170
|
-
assert.calledOnceWithExactly(noble._bindings.broadcast, 'peripheralUuid', 'serviceUuid', 'characteristicUuid', 'broadcast');
|
|
1171
|
-
});
|
|
1172
|
-
|
|
1173
|
-
describe('onBroadcast', () => {
|
|
1174
|
-
it('should emit warning', () => {
|
|
1175
|
-
const warningCallback = sinon.spy();
|
|
1176
|
-
noble.on('warning', warningCallback);
|
|
1177
|
-
|
|
1178
|
-
noble._characteristics = {
|
|
1179
|
-
peripheralUuid: {
|
|
1180
|
-
serviceUuid: {
|
|
1181
|
-
}
|
|
1182
|
-
}
|
|
1183
|
-
};
|
|
1184
|
-
noble.onBroadcast('peripheralUuid', 'serviceUuid', 'characteristicUuid', 'state');
|
|
1185
|
-
|
|
1186
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral peripheralUuid, serviceUuid, characteristicUuid broadcast!');
|
|
1187
|
-
});
|
|
1188
|
-
|
|
1189
|
-
it('should emit broadcast', () => {
|
|
1190
|
-
const warningCallback = sinon.spy();
|
|
1191
|
-
const emit = sinon.spy();
|
|
1192
|
-
|
|
1193
|
-
noble.on('warning', warningCallback);
|
|
1194
|
-
|
|
1195
|
-
noble._characteristics = {
|
|
1196
|
-
peripheralUuid: {
|
|
1197
|
-
serviceUuid: {
|
|
1198
|
-
characteristicUuid: {
|
|
1199
|
-
emit
|
|
1200
|
-
}
|
|
1201
|
-
}
|
|
1202
|
-
}
|
|
1203
|
-
};
|
|
1204
|
-
noble.onBroadcast('peripheralUuid', 'serviceUuid', 'characteristicUuid', 'state');
|
|
1205
|
-
|
|
1206
|
-
assert.notCalled(warningCallback);
|
|
1207
|
-
assert.calledOnceWithExactly(emit, 'broadcast', 'state');
|
|
1208
|
-
});
|
|
1209
|
-
});
|
|
1210
|
-
|
|
1211
|
-
it('notify - should delegate to bindings', () => {
|
|
1212
|
-
noble._bindings.notify = sinon.spy();
|
|
1213
|
-
noble.notify('peripheralUuid', 'serviceUuid', 'characteristicUuid', 'notify');
|
|
1214
|
-
assert.calledOnceWithExactly(noble._bindings.notify, 'peripheralUuid', 'serviceUuid', 'characteristicUuid', 'notify');
|
|
1215
|
-
});
|
|
1216
|
-
|
|
1217
|
-
describe('onNotify', () => {
|
|
1218
|
-
it('should emit warning', () => {
|
|
1219
|
-
const warningCallback = sinon.spy();
|
|
1220
|
-
noble.on('warning', warningCallback);
|
|
1221
|
-
|
|
1222
|
-
noble._characteristics = {
|
|
1223
|
-
peripheralUuid: {
|
|
1224
|
-
serviceUuid: {
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1227
|
-
};
|
|
1228
|
-
noble.onNotify('peripheralUuid', 'serviceUuid', 'characteristicUuid', 'state');
|
|
1229
|
-
|
|
1230
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral peripheralUuid, serviceUuid, characteristicUuid notify!');
|
|
1231
|
-
});
|
|
1232
|
-
|
|
1233
|
-
it('should emit notify', () => {
|
|
1234
|
-
const warningCallback = sinon.spy();
|
|
1235
|
-
const emit = sinon.spy();
|
|
1236
|
-
|
|
1237
|
-
noble.on('warning', warningCallback);
|
|
1238
|
-
|
|
1239
|
-
noble._characteristics = {
|
|
1240
|
-
peripheralUuid: {
|
|
1241
|
-
serviceUuid: {
|
|
1242
|
-
characteristicUuid: {
|
|
1243
|
-
emit
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
};
|
|
1248
|
-
noble.onNotify('peripheralUuid', 'serviceUuid', 'characteristicUuid', 'state');
|
|
1249
|
-
|
|
1250
|
-
assert.notCalled(warningCallback);
|
|
1251
|
-
assert.calledOnceWithExactly(emit, 'notify', 'state');
|
|
1252
|
-
});
|
|
1253
|
-
});
|
|
1254
|
-
|
|
1255
|
-
it('discoverDescriptors - should delegate', () => {
|
|
1256
|
-
noble._bindings.discoverDescriptors = sinon.spy();
|
|
1257
|
-
|
|
1258
|
-
noble.discoverDescriptors('peripheralUuid', 'serviceUuid', 'characteristicUuid');
|
|
1259
|
-
|
|
1260
|
-
assert.calledOnceWithExactly(noble._bindings.discoverDescriptors, 'peripheralUuid', 'serviceUuid', 'characteristicUuid');
|
|
1261
|
-
});
|
|
1262
|
-
|
|
1263
|
-
describe('onDescriptorsDiscover', () => {
|
|
1264
|
-
it('should emit warning', () => {
|
|
1265
|
-
const warningCallback = sinon.spy();
|
|
1266
|
-
|
|
1267
|
-
const peripheralUuid = 'peripheralUuid';
|
|
1268
|
-
const serviceUuid = 'serviceUuid';
|
|
1269
|
-
const characteristicUuid = 'characteristicUuid';
|
|
1270
|
-
const descriptors = ['descriptor1', 'descriptor2'];
|
|
1271
|
-
|
|
1272
|
-
noble.on('warning', warningCallback);
|
|
1273
|
-
|
|
1274
|
-
noble._characteristics[peripheralUuid] = {
|
|
1275
|
-
[serviceUuid]: {}
|
|
1276
|
-
};
|
|
1277
|
-
noble.onDescriptorsDiscover(peripheralUuid, serviceUuid, characteristicUuid, descriptors);
|
|
1278
|
-
|
|
1279
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral peripheralUuid, serviceUuid, characteristicUuid descriptors discover!');
|
|
1280
|
-
});
|
|
1281
|
-
|
|
1282
|
-
it('should emit characteristicsDiscover and store characteristics', () => {
|
|
1283
|
-
const warningCallback = sinon.spy();
|
|
1284
|
-
const emit = sinon.spy();
|
|
1285
|
-
|
|
1286
|
-
const peripheralUuid = 'peripheralUuid';
|
|
1287
|
-
const serviceUuid = 'serviceUuid';
|
|
1288
|
-
const characteristicUuid = 'characteristicUuid';
|
|
1289
|
-
const descriptors = ['descriptor1', 'descriptor2'];
|
|
1290
|
-
|
|
1291
|
-
noble._characteristics = { [peripheralUuid]: { [serviceUuid]: { [characteristicUuid]: { emit } } } };
|
|
1292
|
-
noble._descriptors = { [peripheralUuid]: { [serviceUuid]: { [characteristicUuid]: {} } } };
|
|
1293
|
-
|
|
1294
|
-
noble.on('warning', warningCallback);
|
|
1295
|
-
|
|
1296
|
-
noble.onDescriptorsDiscover(peripheralUuid, serviceUuid, characteristicUuid, descriptors);
|
|
1297
|
-
|
|
1298
|
-
const expectedDescriptors = [
|
|
1299
|
-
new Descriptor(noble, peripheralUuid, serviceUuid, characteristicUuid, descriptors[0]),
|
|
1300
|
-
new Descriptor(noble, peripheralUuid, serviceUuid, characteristicUuid, descriptors[1])
|
|
1301
|
-
];
|
|
1302
|
-
|
|
1303
|
-
assert.calledOnceWithExactly(emit, 'descriptorsDiscover', expectedDescriptors);
|
|
1304
|
-
assert.notCalled(warningCallback);
|
|
1305
|
-
|
|
1306
|
-
should(noble._characteristics).deepEqual({
|
|
1307
|
-
[peripheralUuid]: { [serviceUuid]: { [characteristicUuid]: { emit, descriptors: expectedDescriptors } } }
|
|
1308
|
-
});
|
|
1309
|
-
should(noble._descriptors).deepEqual({
|
|
1310
|
-
[peripheralUuid]: { [serviceUuid]: { [characteristicUuid]: { descriptor1: expectedDescriptors[0], descriptor2: expectedDescriptors[1] } } }
|
|
1311
|
-
});
|
|
1312
|
-
});
|
|
1313
|
-
});
|
|
1314
|
-
|
|
1315
|
-
it('readValue - should delegate to bindings', () => {
|
|
1316
|
-
noble._bindings.readValue = sinon.spy();
|
|
1317
|
-
noble.readValue('peripheralUuid', 'serviceUuid', 'characteristicUuid', 'descriptorUuid');
|
|
1318
|
-
assert.calledOnceWithExactly(noble._bindings.readValue, 'peripheralUuid', 'serviceUuid', 'characteristicUuid', 'descriptorUuid');
|
|
1319
|
-
});
|
|
1320
|
-
|
|
1321
|
-
describe('onValueRead', () => {
|
|
1322
|
-
it('should emit warning', () => {
|
|
1323
|
-
const warningCallback = sinon.spy();
|
|
1324
|
-
noble.on('warning', warningCallback);
|
|
1325
|
-
|
|
1326
|
-
noble._descriptors = {
|
|
1327
|
-
peripheralUuid: {
|
|
1328
|
-
serviceUuid: {
|
|
1329
|
-
characteristicUuid: {}
|
|
1330
|
-
}
|
|
1331
|
-
}
|
|
1332
|
-
};
|
|
1333
|
-
noble.onValueRead('peripheralUuid', 'serviceUuid', 'characteristicUuid', 'descriptorUuid', 'data');
|
|
1334
|
-
|
|
1335
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral peripheralUuid, serviceUuid, characteristicUuid, descriptorUuid value read!');
|
|
1336
|
-
});
|
|
1337
|
-
|
|
1338
|
-
it('should emit valueRead', () => {
|
|
1339
|
-
const warningCallback = sinon.spy();
|
|
1340
|
-
const emit = sinon.spy();
|
|
1341
|
-
|
|
1342
|
-
noble.on('warning', warningCallback);
|
|
1343
|
-
|
|
1344
|
-
noble._descriptors = {
|
|
1345
|
-
peripheralUuid: {
|
|
1346
|
-
serviceUuid: {
|
|
1347
|
-
characteristicUuid: {
|
|
1348
|
-
descriptorUuid: {
|
|
1349
|
-
emit
|
|
1350
|
-
}
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
1353
|
-
}
|
|
1354
|
-
};
|
|
1355
|
-
noble.onValueRead('peripheralUuid', 'serviceUuid', 'characteristicUuid', 'descriptorUuid', 'data');
|
|
1356
|
-
|
|
1357
|
-
assert.notCalled(warningCallback);
|
|
1358
|
-
assert.calledOnceWithExactly(emit, 'valueRead', 'data');
|
|
1359
|
-
});
|
|
1360
|
-
});
|
|
1361
|
-
|
|
1362
|
-
it('writeValue - should delegate to bindings', () => {
|
|
1363
|
-
noble._bindings.writeValue = sinon.spy();
|
|
1364
|
-
noble.writeValue('peripheralUuid', 'serviceUuid', 'characteristicUuid', 'descriptorUuid', 'data');
|
|
1365
|
-
assert.calledOnceWithExactly(noble._bindings.writeValue, 'peripheralUuid', 'serviceUuid', 'characteristicUuid', 'descriptorUuid', 'data');
|
|
1366
|
-
});
|
|
1367
|
-
|
|
1368
|
-
describe('onValueWrite', () => {
|
|
1369
|
-
it('should emit warning', () => {
|
|
1370
|
-
const warningCallback = sinon.spy();
|
|
1371
|
-
noble.on('warning', warningCallback);
|
|
1372
|
-
|
|
1373
|
-
noble._descriptors = {
|
|
1374
|
-
peripheralUuid: {
|
|
1375
|
-
serviceUuid: {
|
|
1376
|
-
characteristicUuid: {}
|
|
1377
|
-
}
|
|
1378
|
-
}
|
|
1379
|
-
};
|
|
1380
|
-
noble.onValueWrite('peripheralUuid', 'serviceUuid', 'characteristicUuid', 'descriptorUuid');
|
|
1381
|
-
|
|
1382
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral peripheralUuid, serviceUuid, characteristicUuid, descriptorUuid value write!');
|
|
1383
|
-
});
|
|
1384
|
-
|
|
1385
|
-
it('should emit valueWrite', () => {
|
|
1386
|
-
const warningCallback = sinon.spy();
|
|
1387
|
-
const emit = sinon.spy();
|
|
1388
|
-
|
|
1389
|
-
noble.on('warning', warningCallback);
|
|
1390
|
-
|
|
1391
|
-
noble._descriptors = {
|
|
1392
|
-
peripheralUuid: {
|
|
1393
|
-
serviceUuid: {
|
|
1394
|
-
characteristicUuid: {
|
|
1395
|
-
descriptorUuid: {
|
|
1396
|
-
emit
|
|
1397
|
-
}
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
};
|
|
1402
|
-
noble.onValueWrite('peripheralUuid', 'serviceUuid', 'characteristicUuid', 'descriptorUuid');
|
|
1403
|
-
|
|
1404
|
-
assert.notCalled(warningCallback);
|
|
1405
|
-
assert.calledOnceWithExactly(emit, 'valueWrite');
|
|
1406
|
-
});
|
|
1407
|
-
});
|
|
1408
|
-
|
|
1409
|
-
it('readHandle - should delegate to bindings', () => {
|
|
1410
|
-
noble._bindings.readHandle = sinon.spy();
|
|
1411
|
-
noble.readHandle('peripheralUuid', 'handle');
|
|
1412
|
-
assert.calledOnceWithExactly(noble._bindings.readHandle, 'peripheralUuid', 'handle');
|
|
1413
|
-
});
|
|
1414
|
-
|
|
1415
|
-
describe('onHandleRead', () => {
|
|
1416
|
-
it('should emit warning', () => {
|
|
1417
|
-
const warningCallback = sinon.spy();
|
|
1418
|
-
noble.on('warning', warningCallback);
|
|
1419
|
-
|
|
1420
|
-
noble._peripherals = {
|
|
830
|
+
describe('onMtu', () => {
|
|
831
|
+
test('should update peripheral mtu when set before already', () => {
|
|
832
|
+
const peripheral = {
|
|
833
|
+
mtu: 234,
|
|
834
|
+
emit: jest.fn()
|
|
1421
835
|
};
|
|
1422
|
-
noble.onHandleRead('peripheralUuid', 'nameOfHandle', 'data');
|
|
1423
836
|
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
it('should emit handleWrite', () => {
|
|
1428
|
-
const warningCallback = sinon.spy();
|
|
1429
|
-
const emit = sinon.spy();
|
|
1430
|
-
|
|
1431
|
-
noble.on('warning', warningCallback);
|
|
1432
|
-
|
|
1433
|
-
noble._peripherals = {
|
|
1434
|
-
peripheralUuid: {
|
|
1435
|
-
emit
|
|
1436
|
-
}
|
|
1437
|
-
};
|
|
1438
|
-
noble.onHandleRead('peripheralUuid', 'nameOfHandle', 'data');
|
|
837
|
+
noble._peripherals.set('uuid', peripheral);
|
|
838
|
+
noble._onMtu('uuid', 123);
|
|
1439
839
|
|
|
1440
|
-
|
|
1441
|
-
|
|
840
|
+
expect(peripheral.mtu).toBe(123);
|
|
841
|
+
expect(peripheral.emit).toHaveBeenCalledWith('mtu', 123);
|
|
842
|
+
expect(peripheral.emit).toHaveBeenCalledTimes(1);
|
|
1442
843
|
});
|
|
1443
|
-
});
|
|
1444
|
-
|
|
1445
|
-
it('writeHandle - should delegate to bindings', () => {
|
|
1446
|
-
noble._bindings.writeHandle = sinon.spy();
|
|
1447
|
-
noble.writeHandle('peripheralUuid', 'handle', 'data', 'withoutResponse');
|
|
1448
|
-
assert.calledOnceWithExactly(noble._bindings.writeHandle, 'peripheralUuid', 'handle', 'data', 'withoutResponse');
|
|
1449
|
-
});
|
|
1450
844
|
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
noble._peripherals = {
|
|
845
|
+
test('should update peripheral mtu too when empty', () => {
|
|
846
|
+
const peripheral = {
|
|
847
|
+
mtu: null,
|
|
848
|
+
emit: jest.fn()
|
|
1457
849
|
};
|
|
1458
|
-
noble.onHandleWrite('peripheralUuid', 'nameOfHandle');
|
|
1459
|
-
|
|
1460
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral peripheralUuid handle write!');
|
|
1461
|
-
});
|
|
1462
850
|
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
const emit = sinon.spy();
|
|
851
|
+
noble._peripherals.set('uuid', peripheral);
|
|
852
|
+
noble._onMtu('uuid', 123);
|
|
1466
853
|
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
peripheralUuid: {
|
|
1471
|
-
emit
|
|
1472
|
-
}
|
|
1473
|
-
};
|
|
1474
|
-
noble.onHandleWrite('peripheralUuid', 'nameOfHandle');
|
|
1475
|
-
|
|
1476
|
-
assert.notCalled(warningCallback);
|
|
1477
|
-
assert.calledOnceWithExactly(emit, 'handleWritenameOfHandle');
|
|
854
|
+
expect(peripheral.mtu).toBe(123);
|
|
855
|
+
expect(peripheral.emit).toHaveBeenCalledWith('mtu', 123);
|
|
856
|
+
expect(peripheral.emit).toHaveBeenCalledTimes(1);
|
|
1478
857
|
});
|
|
1479
858
|
});
|
|
1480
859
|
|
|
1481
|
-
describe('
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
860
|
+
describe('state change handling', () => {
|
|
861
|
+
test('should disconnect peripherals when state changes to poweredOff', () => {
|
|
862
|
+
// Setup a connected peripheral
|
|
863
|
+
const peripheral = {
|
|
864
|
+
id: 'test-peripheral',
|
|
865
|
+
state: 'connected',
|
|
866
|
+
emit: jest.fn()
|
|
1487
867
|
};
|
|
1488
|
-
noble.
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
noble.
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
it('onMtu - should update peripheral mtu when set before already', () => {
|
|
1512
|
-
const peripheral = {
|
|
1513
|
-
mtu: 234
|
|
1514
|
-
};
|
|
1515
|
-
|
|
1516
|
-
noble._peripherals = { uuid: peripheral };
|
|
1517
|
-
noble.onMtu('uuid', 123);
|
|
1518
|
-
|
|
1519
|
-
should(peripheral).deepEqual({ mtu: 123 });
|
|
1520
|
-
});
|
|
1521
|
-
|
|
1522
|
-
it('onMtu - should update peripheral mtu too when empty', () => {
|
|
1523
|
-
const peripheral = {
|
|
1524
|
-
mtu: null
|
|
1525
|
-
};
|
|
1526
|
-
|
|
1527
|
-
noble._peripherals = { uuid: peripheral };
|
|
1528
|
-
noble.onMtu('uuid', 123);
|
|
1529
|
-
|
|
1530
|
-
should(peripheral).deepEqual({ mtu: 123 });
|
|
1531
|
-
});
|
|
1532
|
-
|
|
1533
|
-
describe('onIncludedServicesDiscover', () => {
|
|
1534
|
-
it('should emit connected on existing peripheral', () => {
|
|
1535
|
-
const emit = sinon.spy();
|
|
1536
|
-
noble._services = {
|
|
1537
|
-
uuid: { serviceUuid: { emit } }
|
|
868
|
+
noble._peripherals.set('test-peripheral', peripheral);
|
|
869
|
+
noble._state = 'poweredOn';
|
|
870
|
+
|
|
871
|
+
// Mock the _onDisconnect method to verify it's called
|
|
872
|
+
const originalOnDisconnect = noble._onDisconnect;
|
|
873
|
+
noble._onDisconnect = jest.fn();
|
|
874
|
+
|
|
875
|
+
// Trigger state change to poweredOff
|
|
876
|
+
noble._onStateChange('poweredOff');
|
|
877
|
+
|
|
878
|
+
// Check if _onDisconnect was called for the peripheral
|
|
879
|
+
expect(noble._onDisconnect).toHaveBeenCalledWith('test-peripheral', 'cleanup');
|
|
880
|
+
|
|
881
|
+
// Restore original method
|
|
882
|
+
noble._onDisconnect = originalOnDisconnect;
|
|
883
|
+
});
|
|
884
|
+
|
|
885
|
+
test('should update peripheral state when cleaned up during poweredOff', () => {
|
|
886
|
+
// Setup a connected peripheral
|
|
887
|
+
const peripheral = {
|
|
888
|
+
id: 'test-peripheral',
|
|
889
|
+
state: 'connected',
|
|
890
|
+
emit: jest.fn()
|
|
1538
891
|
};
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
noble.
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
it('should emit warning on missing peripheral', () => {
|
|
1554
|
-
noble._services = { uuid: {} };
|
|
1555
|
-
|
|
1556
|
-
const warningCallback = sinon.spy();
|
|
1557
|
-
|
|
1558
|
-
noble.on('warning', warningCallback);
|
|
1559
|
-
noble.onIncludedServicesDiscover('uuid', 'serviceUuid', 'serviceUuids');
|
|
1560
|
-
|
|
1561
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral uuid, serviceUuid included services discover!');
|
|
1562
|
-
|
|
1563
|
-
should(noble._services).deepEqual({ uuid: {} });
|
|
1564
|
-
});
|
|
1565
|
-
});
|
|
1566
|
-
});
|
|
892
|
+
noble._peripherals.set('test-peripheral', peripheral);
|
|
893
|
+
|
|
894
|
+
// Call the cleanup method directly
|
|
895
|
+
noble._cleanupPeriperals('test-peripheral');
|
|
896
|
+
|
|
897
|
+
// Verify peripheral emitted disconnect event
|
|
898
|
+
expect(peripheral.emit).toHaveBeenCalledWith('disconnect', 'cleanup');
|
|
899
|
+
|
|
900
|
+
// Verify peripheral state was updated
|
|
901
|
+
expect(peripheral.state).toBe('disconnected');
|
|
902
|
+
});
|
|
903
|
+
});
|
|
904
|
+
});
|