@stoprocent/noble 1.19.0 → 2.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/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 +579 -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 +381 -1085
- 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,293 @@ 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.
|
|
344
|
-
|
|
345
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral uuid connected!');
|
|
275
|
+
noble._onConnect('uuid', true);
|
|
346
276
|
|
|
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.
|
|
376
|
+
noble._onStateChange(state);
|
|
422
377
|
|
|
423
|
-
|
|
424
|
-
|
|
378
|
+
expect(noble.state).toBe(state);
|
|
379
|
+
expect(callback).toHaveBeenCalledWith(state);
|
|
380
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
425
381
|
});
|
|
426
382
|
|
|
427
|
-
|
|
383
|
+
test('should change address', () => {
|
|
428
384
|
const address = 'newAddress';
|
|
429
|
-
noble.
|
|
385
|
+
noble._onAddressChange(address);
|
|
430
386
|
|
|
431
|
-
|
|
387
|
+
expect(noble.address).toBe(address);
|
|
432
388
|
});
|
|
433
389
|
|
|
434
|
-
|
|
435
|
-
const callback =
|
|
390
|
+
test('should emit scanParametersSet event', () => {
|
|
391
|
+
const callback = jest.fn();
|
|
436
392
|
noble.on('scanParametersSet', callback);
|
|
437
393
|
|
|
438
|
-
noble.
|
|
394
|
+
noble._onScanParametersSet();
|
|
439
395
|
|
|
440
|
-
|
|
396
|
+
expect(callback).toHaveBeenCalled();
|
|
397
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
441
398
|
});
|
|
442
399
|
|
|
443
|
-
|
|
444
|
-
const callback =
|
|
400
|
+
test('should emit scanStart event', () => {
|
|
401
|
+
const callback = jest.fn();
|
|
445
402
|
noble.on('scanStart', callback);
|
|
446
403
|
|
|
447
|
-
noble.
|
|
404
|
+
noble._onScanStart('filterDuplicates');
|
|
448
405
|
|
|
449
|
-
|
|
406
|
+
expect(callback).toHaveBeenCalledWith('filterDuplicates');
|
|
407
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
450
408
|
});
|
|
451
409
|
|
|
452
|
-
|
|
453
|
-
const callback =
|
|
410
|
+
test('should emit scanStop event', () => {
|
|
411
|
+
const callback = jest.fn();
|
|
454
412
|
noble.on('scanStop', callback);
|
|
455
413
|
|
|
456
|
-
noble.
|
|
414
|
+
noble._onScanStop();
|
|
457
415
|
|
|
458
|
-
|
|
416
|
+
expect(callback).toHaveBeenCalled();
|
|
417
|
+
expect(callback).toHaveBeenCalledTimes(1);
|
|
459
418
|
});
|
|
460
419
|
|
|
461
420
|
describe('reset', () => {
|
|
462
|
-
|
|
463
|
-
mockBindings.reset = sinon.spy();
|
|
464
|
-
});
|
|
465
|
-
|
|
466
|
-
afterEach(() => {
|
|
467
|
-
sinon.reset();
|
|
468
|
-
});
|
|
469
|
-
|
|
470
|
-
it('should reset', () => {
|
|
421
|
+
test('should reset', () => {
|
|
471
422
|
noble.reset();
|
|
472
|
-
|
|
423
|
+
expect(mockBindings.reset).toHaveBeenCalled();
|
|
424
|
+
expect(mockBindings.reset).toHaveBeenCalledTimes(1);
|
|
473
425
|
});
|
|
474
426
|
});
|
|
475
427
|
|
|
476
428
|
describe('disconnect', () => {
|
|
477
|
-
|
|
478
|
-
mockBindings.disconnect = sinon.spy();
|
|
479
|
-
});
|
|
480
|
-
|
|
481
|
-
afterEach(() => {
|
|
482
|
-
sinon.reset();
|
|
483
|
-
});
|
|
484
|
-
|
|
485
|
-
it('should disconnect', () => {
|
|
429
|
+
test('should disconnect', () => {
|
|
486
430
|
noble.disconnect('peripheralUuid');
|
|
487
|
-
|
|
431
|
+
expect(mockBindings.disconnect).toHaveBeenCalledWith('peripheralUuid');
|
|
432
|
+
expect(mockBindings.disconnect).toHaveBeenCalledTimes(1);
|
|
488
433
|
});
|
|
489
434
|
});
|
|
490
435
|
|
|
491
436
|
describe('onDisconnect', () => {
|
|
492
|
-
|
|
493
|
-
const emit =
|
|
494
|
-
noble._peripherals
|
|
495
|
-
uuid: { emit }
|
|
496
|
-
};
|
|
437
|
+
test('should emit disconnect on existing peripheral', () => {
|
|
438
|
+
const emit = jest.fn();
|
|
439
|
+
noble._peripherals.set('uuid', { emit });
|
|
497
440
|
|
|
498
|
-
const warningCallback =
|
|
441
|
+
const warningCallback = jest.fn();
|
|
499
442
|
|
|
500
443
|
noble.on('warning', warningCallback);
|
|
501
|
-
noble.
|
|
444
|
+
noble._onDisconnect('uuid', false);
|
|
502
445
|
|
|
503
|
-
|
|
504
|
-
|
|
446
|
+
expect(emit).toHaveBeenCalledWith('disconnect', false);
|
|
447
|
+
expect(emit).toHaveBeenCalledTimes(1);
|
|
448
|
+
expect(warningCallback).not.toHaveBeenCalled();
|
|
505
449
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
450
|
+
const peripheral = noble._peripherals.get('uuid');
|
|
451
|
+
expect(peripheral).toHaveProperty('emit', emit);
|
|
452
|
+
expect(peripheral).toHaveProperty('state', 'disconnected');
|
|
509
453
|
});
|
|
510
454
|
|
|
511
|
-
|
|
512
|
-
const warningCallback =
|
|
455
|
+
test('should emit warning on missing peripheral', () => {
|
|
456
|
+
const warningCallback = jest.fn();
|
|
513
457
|
|
|
514
458
|
noble.on('warning', warningCallback);
|
|
515
|
-
noble.
|
|
516
|
-
|
|
517
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral uuid disconnected!');
|
|
459
|
+
noble._onDisconnect('uuid', true);
|
|
518
460
|
|
|
519
|
-
|
|
461
|
+
expect(warningCallback).toHaveBeenCalledWith('unknown peripheral uuid disconnected!');
|
|
462
|
+
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
463
|
+
expect(noble._peripherals.size).toBe(0);
|
|
520
464
|
});
|
|
521
465
|
});
|
|
522
466
|
|
|
523
467
|
describe('onDiscover', () => {
|
|
524
|
-
|
|
525
|
-
mockBindings.disconnect = sinon.spy();
|
|
526
|
-
});
|
|
527
|
-
|
|
528
|
-
afterEach(() => {
|
|
529
|
-
sinon.reset();
|
|
530
|
-
});
|
|
531
|
-
|
|
532
|
-
it('should add new peripheral', () => {
|
|
468
|
+
test('should add new peripheral', () => {
|
|
533
469
|
const uuid = 'uuid';
|
|
534
470
|
const address = 'address';
|
|
535
471
|
const addressType = 'addressType';
|
|
@@ -537,10 +473,10 @@ describe('noble', () => {
|
|
|
537
473
|
const advertisement = [];
|
|
538
474
|
const rssi = 'rssi';
|
|
539
475
|
|
|
540
|
-
const eventCallback =
|
|
476
|
+
const eventCallback = jest.fn();
|
|
541
477
|
noble.on('discover', eventCallback);
|
|
542
478
|
|
|
543
|
-
noble.
|
|
479
|
+
noble._onDiscover(
|
|
544
480
|
uuid,
|
|
545
481
|
address,
|
|
546
482
|
addressType,
|
|
@@ -550,25 +486,27 @@ describe('noble', () => {
|
|
|
550
486
|
);
|
|
551
487
|
|
|
552
488
|
// Check new peripheral
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
489
|
+
expect(noble._peripherals.has(uuid)).toBe(true);
|
|
490
|
+
expect(noble._discoveredPeripherals.has(uuid)).toBe(true);
|
|
491
|
+
|
|
492
|
+
const peripheral = noble._peripherals.get(uuid);
|
|
493
|
+
expect(peripheral._noble).toBe(noble);
|
|
494
|
+
expect(peripheral.id).toBe(uuid);
|
|
495
|
+
expect(peripheral.address).toBe(address);
|
|
496
|
+
expect(peripheral.addressType).toBe(addressType);
|
|
497
|
+
expect(peripheral.connectable).toBe(connectable);
|
|
498
|
+
expect(peripheral.advertisement).toBe(advertisement);
|
|
499
|
+
expect(peripheral.rssi).toBe(rssi);
|
|
500
|
+
|
|
501
|
+
expect(noble._services[uuid]).toEqual({});
|
|
502
|
+
expect(noble._characteristics[uuid]).toEqual({});
|
|
503
|
+
expect(noble._descriptors[uuid]).toEqual({});
|
|
504
|
+
|
|
505
|
+
expect(eventCallback).toHaveBeenCalledWith(peripheral);
|
|
506
|
+
expect(eventCallback).toHaveBeenCalledTimes(1);
|
|
569
507
|
});
|
|
570
508
|
|
|
571
|
-
|
|
509
|
+
test('should update existing peripheral', () => {
|
|
572
510
|
const uuid = 'uuid';
|
|
573
511
|
const address = 'address';
|
|
574
512
|
const addressType = 'addressType';
|
|
@@ -577,7 +515,7 @@ describe('noble', () => {
|
|
|
577
515
|
const rssi = 'rssi';
|
|
578
516
|
|
|
579
517
|
// init peripheral
|
|
580
|
-
noble._peripherals
|
|
518
|
+
noble._peripherals.set(uuid, new Peripheral(
|
|
581
519
|
noble,
|
|
582
520
|
uuid,
|
|
583
521
|
'originalAddress',
|
|
@@ -585,12 +523,12 @@ describe('noble', () => {
|
|
|
585
523
|
'originalConnectable',
|
|
586
524
|
['adv1'],
|
|
587
525
|
'originalRssi'
|
|
588
|
-
);
|
|
526
|
+
));
|
|
589
527
|
|
|
590
|
-
const eventCallback =
|
|
528
|
+
const eventCallback = jest.fn();
|
|
591
529
|
noble.on('discover', eventCallback);
|
|
592
530
|
|
|
593
|
-
noble.
|
|
531
|
+
noble._onDiscover(
|
|
594
532
|
uuid,
|
|
595
533
|
address,
|
|
596
534
|
addressType,
|
|
@@ -599,26 +537,28 @@ describe('noble', () => {
|
|
|
599
537
|
rssi
|
|
600
538
|
);
|
|
601
539
|
|
|
602
|
-
// Check
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
540
|
+
// Check updated peripheral
|
|
541
|
+
expect(noble._peripherals.has(uuid)).toBe(true);
|
|
542
|
+
expect(noble._discoveredPeripherals.has(uuid)).toBe(true);
|
|
543
|
+
|
|
544
|
+
const peripheral = noble._peripherals.get(uuid);
|
|
545
|
+
expect(peripheral._noble).toBe(noble);
|
|
546
|
+
expect(peripheral.id).toBe(uuid);
|
|
547
|
+
expect(peripheral.address).toBe('originalAddress');
|
|
548
|
+
expect(peripheral.addressType).toBe('originalAddressType');
|
|
549
|
+
expect(peripheral.connectable).toBe(connectable);
|
|
550
|
+
expect(peripheral.advertisement).toEqual(['adv1', 'adv2', 'adv3']);
|
|
551
|
+
expect(peripheral.rssi).toBe(rssi);
|
|
552
|
+
|
|
553
|
+
expect(Object.keys(noble._services)).toHaveLength(0);
|
|
554
|
+
expect(Object.keys(noble._characteristics)).toHaveLength(0);
|
|
555
|
+
expect(Object.keys(noble._descriptors)).toHaveLength(0);
|
|
556
|
+
|
|
557
|
+
expect(eventCallback).toHaveBeenCalledWith(peripheral);
|
|
558
|
+
expect(eventCallback).toHaveBeenCalledTimes(1);
|
|
619
559
|
});
|
|
620
560
|
|
|
621
|
-
|
|
561
|
+
test('should emit on duplicate', () => {
|
|
622
562
|
const uuid = 'uuid';
|
|
623
563
|
const address = 'address';
|
|
624
564
|
const addressType = 'addressType';
|
|
@@ -627,13 +567,13 @@ describe('noble', () => {
|
|
|
627
567
|
const rssi = 'rssi';
|
|
628
568
|
|
|
629
569
|
// register peripheral
|
|
630
|
-
noble.
|
|
570
|
+
noble._discoveredPeripherals.add(uuid);
|
|
631
571
|
noble._allowDuplicates = true;
|
|
632
572
|
|
|
633
|
-
const eventCallback =
|
|
573
|
+
const eventCallback = jest.fn();
|
|
634
574
|
noble.on('discover', eventCallback);
|
|
635
575
|
|
|
636
|
-
noble.
|
|
576
|
+
noble._onDiscover(
|
|
637
577
|
uuid,
|
|
638
578
|
address,
|
|
639
579
|
addressType,
|
|
@@ -642,10 +582,11 @@ describe('noble', () => {
|
|
|
642
582
|
rssi
|
|
643
583
|
);
|
|
644
584
|
|
|
645
|
-
|
|
585
|
+
expect(eventCallback).toHaveBeenCalledWith(noble._peripherals.get(uuid));
|
|
586
|
+
expect(eventCallback).toHaveBeenCalledTimes(1);
|
|
646
587
|
});
|
|
647
588
|
|
|
648
|
-
|
|
589
|
+
test('should not emit on duplicate', () => {
|
|
649
590
|
const uuid = 'uuid';
|
|
650
591
|
const address = 'address';
|
|
651
592
|
const addressType = 'addressType';
|
|
@@ -654,12 +595,13 @@ describe('noble', () => {
|
|
|
654
595
|
const rssi = 'rssi';
|
|
655
596
|
|
|
656
597
|
// register peripheral
|
|
657
|
-
noble.
|
|
598
|
+
noble._discoveredPeripherals.add(uuid);
|
|
599
|
+
noble._allowDuplicates = false;
|
|
658
600
|
|
|
659
|
-
const eventCallback =
|
|
601
|
+
const eventCallback = jest.fn();
|
|
660
602
|
noble.on('discover', eventCallback);
|
|
661
603
|
|
|
662
|
-
noble.
|
|
604
|
+
noble._onDiscover(
|
|
663
605
|
uuid,
|
|
664
606
|
address,
|
|
665
607
|
addressType,
|
|
@@ -668,10 +610,10 @@ describe('noble', () => {
|
|
|
668
610
|
rssi
|
|
669
611
|
);
|
|
670
612
|
|
|
671
|
-
|
|
613
|
+
expect(eventCallback).not.toHaveBeenCalled();
|
|
672
614
|
});
|
|
673
615
|
|
|
674
|
-
|
|
616
|
+
test('should emit on new peripheral (even if duplicates are disallowed)', () => {
|
|
675
617
|
const uuid = 'uuid';
|
|
676
618
|
const address = 'address';
|
|
677
619
|
const addressType = 'addressType';
|
|
@@ -679,10 +621,10 @@ describe('noble', () => {
|
|
|
679
621
|
const advertisement = ['adv1', 'adv2', 'adv3'];
|
|
680
622
|
const rssi = 'rssi';
|
|
681
623
|
|
|
682
|
-
const eventCallback =
|
|
624
|
+
const eventCallback = jest.fn();
|
|
683
625
|
noble.on('discover', eventCallback);
|
|
684
626
|
|
|
685
|
-
noble.
|
|
627
|
+
noble._onDiscover(
|
|
686
628
|
uuid,
|
|
687
629
|
address,
|
|
688
630
|
addressType,
|
|
@@ -691,69 +633,57 @@ describe('noble', () => {
|
|
|
691
633
|
rssi
|
|
692
634
|
);
|
|
693
635
|
|
|
694
|
-
|
|
636
|
+
expect(eventCallback).toHaveBeenCalledWith(noble._peripherals.get(uuid));
|
|
637
|
+
expect(eventCallback).toHaveBeenCalledTimes(1);
|
|
695
638
|
});
|
|
696
639
|
});
|
|
697
640
|
|
|
698
641
|
describe('updateRssi', () => {
|
|
699
|
-
|
|
700
|
-
mockBindings.updateRssi = sinon.spy();
|
|
701
|
-
});
|
|
702
|
-
|
|
703
|
-
afterEach(() => {
|
|
704
|
-
sinon.reset();
|
|
705
|
-
});
|
|
706
|
-
|
|
707
|
-
it('should updateRssi', () => {
|
|
642
|
+
test('should updateRssi', () => {
|
|
708
643
|
noble.updateRssi('peripheralUuid');
|
|
709
|
-
|
|
644
|
+
expect(mockBindings.updateRssi).toHaveBeenCalledWith('peripheralUuid');
|
|
645
|
+
expect(mockBindings.updateRssi).toHaveBeenCalledTimes(1);
|
|
710
646
|
});
|
|
711
647
|
});
|
|
712
648
|
|
|
713
649
|
describe('onRssiUpdate', () => {
|
|
714
|
-
|
|
715
|
-
const emit =
|
|
716
|
-
noble._peripherals
|
|
717
|
-
uuid: { emit }
|
|
718
|
-
};
|
|
650
|
+
test('should emit rssiUpdate on existing peripheral', () => {
|
|
651
|
+
const emit = jest.fn();
|
|
652
|
+
noble._peripherals.set('uuid', { emit });
|
|
719
653
|
|
|
720
|
-
|
|
654
|
+
noble._onRssiUpdate('uuid', 3);
|
|
721
655
|
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
assert.calledOnceWithExactly(emit, 'rssiUpdate', 3);
|
|
726
|
-
assert.notCalled(warningCallback);
|
|
656
|
+
expect(emit).toHaveBeenCalledWith('rssiUpdate', 3, undefined);
|
|
657
|
+
expect(emit).toHaveBeenCalledTimes(1);
|
|
727
658
|
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
659
|
+
const peripheral = noble._peripherals.get('uuid');
|
|
660
|
+
expect(peripheral).toHaveProperty('emit', emit);
|
|
661
|
+
expect(peripheral).toHaveProperty('rssi', 3);
|
|
731
662
|
});
|
|
732
663
|
|
|
733
|
-
|
|
734
|
-
const warningCallback =
|
|
664
|
+
test('should emit warning on missing peripheral', () => {
|
|
665
|
+
const warningCallback = jest.fn();
|
|
735
666
|
|
|
736
667
|
noble.on('warning', warningCallback);
|
|
737
|
-
noble.
|
|
668
|
+
noble._onRssiUpdate('uuid', 4);
|
|
738
669
|
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
670
|
+
expect(warningCallback).toHaveBeenCalledWith('unknown peripheral uuid RSSI update!');
|
|
671
|
+
expect(warningCallback).toHaveBeenCalledTimes(1);
|
|
672
|
+
expect(noble._peripherals.size).toBe(0);
|
|
742
673
|
});
|
|
743
674
|
});
|
|
744
675
|
|
|
745
|
-
|
|
746
|
-
noble.addService =
|
|
676
|
+
test('should add multiple services', () => {
|
|
677
|
+
noble.addService = jest.fn().mockImplementation((peripheralUuid, service) => service);
|
|
747
678
|
|
|
748
679
|
const peripheralUuid = 'peripheralUuid';
|
|
749
680
|
const services = ['service1', 'service2'];
|
|
750
681
|
const result = noble.addServices(peripheralUuid, services);
|
|
751
682
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
should(result).deepEqual(services);
|
|
683
|
+
expect(noble.addService).toHaveBeenCalledTimes(2);
|
|
684
|
+
expect(noble.addService).toHaveBeenNthCalledWith(1, peripheralUuid, 'service1');
|
|
685
|
+
expect(noble.addService).toHaveBeenNthCalledWith(2, peripheralUuid, 'service2');
|
|
686
|
+
expect(result).toEqual(services);
|
|
757
687
|
});
|
|
758
688
|
|
|
759
689
|
describe('addService', () => {
|
|
@@ -764,58 +694,59 @@ describe('noble', () => {
|
|
|
764
694
|
const peripheral = {};
|
|
765
695
|
|
|
766
696
|
beforeEach(() => {
|
|
767
|
-
noble._peripherals
|
|
697
|
+
noble._peripherals.set(peripheralUuid, peripheral);
|
|
768
698
|
noble._services = { [peripheralUuid]: {} };
|
|
769
699
|
noble._characteristics = { [peripheralUuid]: {} };
|
|
770
700
|
noble._descriptors = { [peripheralUuid]: {} };
|
|
771
701
|
});
|
|
772
702
|
|
|
773
|
-
|
|
774
|
-
noble._bindings.addService =
|
|
703
|
+
test('should add service to lower layer', () => {
|
|
704
|
+
noble._bindings.addService = jest.fn();
|
|
775
705
|
|
|
776
706
|
const result = noble.addService(peripheralUuid, service);
|
|
777
707
|
|
|
778
|
-
|
|
708
|
+
expect(noble._bindings.addService).toHaveBeenCalledWith(peripheralUuid, service);
|
|
709
|
+
expect(noble._bindings.addService).toHaveBeenCalledTimes(1);
|
|
779
710
|
|
|
780
711
|
const expectedService = new Service(noble, peripheralUuid, service.uuid);
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
712
|
+
expect(result).toEqual(expectedService);
|
|
713
|
+
expect(peripheral.services).toEqual([expectedService]);
|
|
714
|
+
expect(noble._services).toEqual({
|
|
784
715
|
[peripheralUuid]: {
|
|
785
716
|
[service.uuid]: expectedService
|
|
786
717
|
}
|
|
787
718
|
});
|
|
788
|
-
|
|
719
|
+
expect(noble._characteristics).toEqual({
|
|
789
720
|
[peripheralUuid]: {
|
|
790
721
|
[service.uuid]: {}
|
|
791
722
|
}
|
|
792
723
|
});
|
|
793
|
-
|
|
724
|
+
expect(noble._descriptors).toEqual({
|
|
794
725
|
[peripheralUuid]: {
|
|
795
726
|
[service.uuid]: {}
|
|
796
727
|
}
|
|
797
728
|
});
|
|
798
729
|
});
|
|
799
730
|
|
|
800
|
-
|
|
731
|
+
test('should add service only to noble', () => {
|
|
801
732
|
peripheral.services = [];
|
|
802
733
|
|
|
803
734
|
const result = noble.addService(peripheralUuid, service);
|
|
804
735
|
|
|
805
736
|
const expectedService = new Service(noble, peripheralUuid, service.uuid);
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
737
|
+
expect(result).toEqual(expectedService);
|
|
738
|
+
expect(peripheral.services).toEqual([expectedService]);
|
|
739
|
+
expect(noble._services).toEqual({
|
|
809
740
|
[peripheralUuid]: {
|
|
810
741
|
[service.uuid]: expectedService
|
|
811
742
|
}
|
|
812
743
|
});
|
|
813
|
-
|
|
744
|
+
expect(noble._characteristics).toEqual({
|
|
814
745
|
[peripheralUuid]: {
|
|
815
746
|
[service.uuid]: {}
|
|
816
747
|
}
|
|
817
748
|
});
|
|
818
|
-
|
|
749
|
+
expect(noble._descriptors).toEqual({
|
|
819
750
|
[peripheralUuid]: {
|
|
820
751
|
[service.uuid]: {}
|
|
821
752
|
}
|
|
@@ -827,740 +758,105 @@ describe('noble', () => {
|
|
|
827
758
|
const peripheralUuid = 'peripheralUuid';
|
|
828
759
|
const services = ['service1', 'service2'];
|
|
829
760
|
|
|
830
|
-
|
|
831
|
-
const callback =
|
|
761
|
+
test('should not emit servicesDiscovered', () => {
|
|
762
|
+
const callback = jest.fn();
|
|
832
763
|
noble.on('servicesDiscovered', callback);
|
|
833
764
|
|
|
834
|
-
noble.
|
|
765
|
+
noble._onServicesDiscovered(peripheralUuid, services);
|
|
835
766
|
|
|
836
|
-
|
|
767
|
+
expect(callback).not.toHaveBeenCalled();
|
|
837
768
|
});
|
|
838
769
|
|
|
839
|
-
|
|
840
|
-
const emit =
|
|
841
|
-
noble._peripherals
|
|
770
|
+
test('should emit servicesDiscovered', () => {
|
|
771
|
+
const emit = jest.fn();
|
|
772
|
+
noble._peripherals.set(peripheralUuid, { uuid: 'peripheral', emit });
|
|
842
773
|
|
|
843
|
-
noble.
|
|
774
|
+
noble._onServicesDiscovered(peripheralUuid, services);
|
|
844
775
|
|
|
845
|
-
|
|
776
|
+
expect(emit).toHaveBeenCalledWith('servicesDiscovered', { uuid: 'peripheral', emit }, services);
|
|
777
|
+
expect(emit).toHaveBeenCalledTimes(1);
|
|
846
778
|
});
|
|
847
779
|
});
|
|
848
780
|
|
|
849
|
-
|
|
850
|
-
noble._bindings.discoverServices =
|
|
781
|
+
test('discoverServices - should delegate to bindings', () => {
|
|
782
|
+
noble._bindings.discoverServices = jest.fn();
|
|
851
783
|
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
|
-
});
|
|
784
|
+
expect(noble._bindings.discoverServices).toHaveBeenCalledWith('peripheral', 'uuids');
|
|
785
|
+
expect(noble._bindings.discoverServices).toHaveBeenCalledTimes(1);
|
|
899
786
|
});
|
|
900
787
|
|
|
901
|
-
describe('
|
|
902
|
-
|
|
903
|
-
|
|
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');
|
|
1014
|
-
});
|
|
1015
|
-
|
|
1016
|
-
describe('onCharacteristicsDiscover', () => {
|
|
1017
|
-
it('should emit warning', () => {
|
|
1018
|
-
const warningCallback = sinon.spy();
|
|
1019
|
-
|
|
1020
|
-
const peripheralUuid = 'peripheralUuid';
|
|
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
|
-
}
|
|
788
|
+
describe('onMtu', () => {
|
|
789
|
+
test('should update peripheral mtu when set before already', () => {
|
|
790
|
+
const peripheral = {
|
|
791
|
+
mtu: 234,
|
|
792
|
+
emit: jest.fn()
|
|
1093
793
|
};
|
|
1094
|
-
noble.onRead('peripheralUuid', 'serviceUuid', 'characteristicUuid', 'data', 'isNotification');
|
|
1095
|
-
|
|
1096
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral peripheralUuid, serviceUuid, characteristicUuid read!');
|
|
1097
|
-
});
|
|
1098
794
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
const emit = sinon.spy();
|
|
795
|
+
noble._peripherals.set('uuid', peripheral);
|
|
796
|
+
noble._onMtu('uuid', 123);
|
|
1102
797
|
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
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');
|
|
798
|
+
expect(peripheral.mtu).toBe(123);
|
|
799
|
+
expect(peripheral.emit).toHaveBeenCalledWith('mtu', 123);
|
|
800
|
+
expect(peripheral.emit).toHaveBeenCalledTimes(1);
|
|
1120
801
|
});
|
|
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
802
|
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
}
|
|
803
|
+
test('should update peripheral mtu too when empty', () => {
|
|
804
|
+
const peripheral = {
|
|
805
|
+
mtu: null,
|
|
806
|
+
emit: jest.fn()
|
|
1139
807
|
};
|
|
1140
|
-
noble.onWrite('peripheralUuid', 'serviceUuid', 'characteristicUuid');
|
|
1141
|
-
|
|
1142
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral peripheralUuid, serviceUuid, characteristicUuid write!');
|
|
1143
|
-
});
|
|
1144
808
|
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
const emit = sinon.spy();
|
|
809
|
+
noble._peripherals.set('uuid', peripheral);
|
|
810
|
+
noble._onMtu('uuid', 123);
|
|
1148
811
|
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
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');
|
|
812
|
+
expect(peripheral.mtu).toBe(123);
|
|
813
|
+
expect(peripheral.emit).toHaveBeenCalledWith('mtu', 123);
|
|
814
|
+
expect(peripheral.emit).toHaveBeenCalledTimes(1);
|
|
1164
815
|
});
|
|
1165
816
|
});
|
|
1166
817
|
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
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
|
-
}
|
|
818
|
+
describe('state change handling', () => {
|
|
819
|
+
test('should disconnect peripherals when state changes to poweredOff', () => {
|
|
820
|
+
// Setup a connected peripheral
|
|
821
|
+
const peripheral = {
|
|
822
|
+
id: 'test-peripheral',
|
|
823
|
+
state: 'connected',
|
|
824
|
+
emit: jest.fn()
|
|
1203
825
|
};
|
|
1204
|
-
noble.
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
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 = {
|
|
1421
|
-
};
|
|
1422
|
-
noble.onHandleRead('peripheralUuid', 'nameOfHandle', 'data');
|
|
1423
|
-
|
|
1424
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral peripheralUuid handle read!');
|
|
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');
|
|
1439
|
-
|
|
1440
|
-
assert.notCalled(warningCallback);
|
|
1441
|
-
assert.calledOnceWithExactly(emit, 'handleReadnameOfHandle', 'data');
|
|
1442
|
-
});
|
|
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
|
-
|
|
1451
|
-
describe('onHandleWrite', () => {
|
|
1452
|
-
it('should emit warning', () => {
|
|
1453
|
-
const warningCallback = sinon.spy();
|
|
1454
|
-
noble.on('warning', warningCallback);
|
|
1455
|
-
|
|
1456
|
-
noble._peripherals = {
|
|
1457
|
-
};
|
|
1458
|
-
noble.onHandleWrite('peripheralUuid', 'nameOfHandle');
|
|
1459
|
-
|
|
1460
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral peripheralUuid handle write!');
|
|
1461
|
-
});
|
|
1462
|
-
|
|
1463
|
-
it('should emit handleRead', () => {
|
|
1464
|
-
const warningCallback = sinon.spy();
|
|
1465
|
-
const emit = sinon.spy();
|
|
1466
|
-
|
|
1467
|
-
noble.on('warning', warningCallback);
|
|
1468
|
-
|
|
1469
|
-
noble._peripherals = {
|
|
1470
|
-
peripheralUuid: {
|
|
1471
|
-
emit
|
|
1472
|
-
}
|
|
1473
|
-
};
|
|
1474
|
-
noble.onHandleWrite('peripheralUuid', 'nameOfHandle');
|
|
1475
|
-
|
|
1476
|
-
assert.notCalled(warningCallback);
|
|
1477
|
-
assert.calledOnceWithExactly(emit, 'handleWritenameOfHandle');
|
|
1478
|
-
});
|
|
1479
|
-
});
|
|
1480
|
-
|
|
1481
|
-
describe('onHandleNotify', () => {
|
|
1482
|
-
it('should emit warning', () => {
|
|
1483
|
-
const warningCallback = sinon.spy();
|
|
1484
|
-
noble.on('warning', warningCallback);
|
|
1485
|
-
|
|
1486
|
-
noble._peripherals = {
|
|
1487
|
-
};
|
|
1488
|
-
noble.onHandleNotify('peripheralUuid', 'nameOfHandle', 'data');
|
|
1489
|
-
|
|
1490
|
-
assert.calledOnceWithExactly(warningCallback, 'unknown peripheral peripheralUuid handle notify!');
|
|
1491
|
-
});
|
|
1492
|
-
|
|
1493
|
-
it('should emit handleNotify', () => {
|
|
1494
|
-
const warningCallback = sinon.spy();
|
|
1495
|
-
const emit = sinon.spy();
|
|
1496
|
-
|
|
1497
|
-
noble.on('warning', warningCallback);
|
|
1498
|
-
|
|
1499
|
-
noble._peripherals = {
|
|
1500
|
-
peripheralUuid: {
|
|
1501
|
-
emit
|
|
1502
|
-
}
|
|
1503
|
-
};
|
|
1504
|
-
noble.onHandleNotify('peripheralUuid', 'nameOfHandle', 'data');
|
|
1505
|
-
|
|
1506
|
-
assert.notCalled(warningCallback);
|
|
1507
|
-
assert.calledOnceWithExactly(emit, 'handleNotify', 'nameOfHandle', 'data');
|
|
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 } }
|
|
826
|
+
noble._peripherals.set('test-peripheral', peripheral);
|
|
827
|
+
noble._state = 'poweredOn';
|
|
828
|
+
|
|
829
|
+
// Mock the _onDisconnect method to verify it's called
|
|
830
|
+
const originalOnDisconnect = noble._onDisconnect;
|
|
831
|
+
noble._onDisconnect = jest.fn();
|
|
832
|
+
|
|
833
|
+
// Trigger state change to poweredOff
|
|
834
|
+
noble._onStateChange('poweredOff');
|
|
835
|
+
|
|
836
|
+
// Check if _onDisconnect was called for the peripheral
|
|
837
|
+
expect(noble._onDisconnect).toHaveBeenCalledWith('test-peripheral', 'cleanup');
|
|
838
|
+
|
|
839
|
+
// Restore original method
|
|
840
|
+
noble._onDisconnect = originalOnDisconnect;
|
|
841
|
+
});
|
|
842
|
+
|
|
843
|
+
test('should update peripheral state when cleaned up during poweredOff', () => {
|
|
844
|
+
// Setup a connected peripheral
|
|
845
|
+
const peripheral = {
|
|
846
|
+
id: 'test-peripheral',
|
|
847
|
+
state: 'connected',
|
|
848
|
+
emit: jest.fn()
|
|
1538
849
|
};
|
|
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
|
-
});
|
|
850
|
+
noble._peripherals.set('test-peripheral', peripheral);
|
|
851
|
+
|
|
852
|
+
// Call the cleanup method directly
|
|
853
|
+
noble._cleanupPeriperals('test-peripheral');
|
|
854
|
+
|
|
855
|
+
// Verify peripheral emitted disconnect event
|
|
856
|
+
expect(peripheral.emit).toHaveBeenCalledWith('disconnect', 'cleanup');
|
|
857
|
+
|
|
858
|
+
// Verify peripheral state was updated
|
|
859
|
+
expect(peripheral.state).toBe('disconnected');
|
|
860
|
+
});
|
|
861
|
+
});
|
|
862
|
+
});
|