@stoprocent/noble 1.9.2-16
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/.editorconfig +11 -0
- package/.eslintrc.js +25 -0
- package/.github/FUNDING.yml +2 -0
- package/.github/workflows/fediverse-action.yml +16 -0
- package/.github/workflows/nodepackage.yml +77 -0
- package/.github/workflows/npm-publish.yml +26 -0
- package/.github/workflows/prebuild.yml +65 -0
- package/.nycrc.json +4 -0
- package/CHANGELOG.md +119 -0
- package/LICENSE +20 -0
- package/MAINTAINERS.md +1 -0
- package/README.md +833 -0
- package/assets/noble-logo.png +0 -0
- package/assets/noble-logo.svg +13 -0
- package/binding.gyp +19 -0
- package/codecov.yml +5 -0
- package/examples/advertisement-discovery.js +65 -0
- package/examples/cache-gatt-discovery.js +198 -0
- package/examples/cache-gatt-reconnect.js +164 -0
- package/examples/echo.js +104 -0
- package/examples/enter-exit.js +78 -0
- package/examples/peripheral-explorer-async.js +133 -0
- package/examples/peripheral-explorer.js +225 -0
- package/examples/pizza/README.md +15 -0
- package/examples/pizza/central.js +194 -0
- package/examples/pizza/pizza.js +60 -0
- package/index.d.ts +203 -0
- package/index.js +6 -0
- package/lib/characteristic.js +161 -0
- package/lib/characteristics.json +449 -0
- package/lib/descriptor.js +72 -0
- package/lib/descriptors.json +47 -0
- package/lib/distributed/bindings.js +326 -0
- package/lib/hci-socket/acl-stream.js +60 -0
- package/lib/hci-socket/bindings.js +788 -0
- package/lib/hci-socket/crypto.js +74 -0
- package/lib/hci-socket/gap.js +432 -0
- package/lib/hci-socket/gatt.js +809 -0
- package/lib/hci-socket/hci-status.json +71 -0
- package/lib/hci-socket/hci.js +1264 -0
- package/lib/hci-socket/signaling.js +76 -0
- package/lib/hci-socket/smp.js +140 -0
- package/lib/hci-uart/bindings.js +569 -0
- package/lib/hci-uart/hci-serial-parser.js +70 -0
- package/lib/hci-uart/hci.js +1336 -0
- package/lib/mac/binding.gyp +26 -0
- package/lib/mac/bindings.js +11 -0
- package/lib/mac/src/ble_manager.h +41 -0
- package/lib/mac/src/ble_manager.mm +435 -0
- package/lib/mac/src/callbacks.cc +222 -0
- package/lib/mac/src/callbacks.h +84 -0
- package/lib/mac/src/napi_objc.h +12 -0
- package/lib/mac/src/napi_objc.mm +50 -0
- package/lib/mac/src/noble_mac.h +34 -0
- package/lib/mac/src/noble_mac.mm +264 -0
- package/lib/mac/src/objc_cpp.h +26 -0
- package/lib/mac/src/objc_cpp.mm +126 -0
- package/lib/mac/src/peripheral.h +23 -0
- package/lib/manufacture.js +48 -0
- package/lib/noble.js +593 -0
- package/lib/peripheral.js +219 -0
- package/lib/resolve-bindings-web.js +9 -0
- package/lib/resolve-bindings.js +44 -0
- package/lib/service.js +72 -0
- package/lib/services.json +92 -0
- package/lib/webbluetooth/bindings.js +368 -0
- package/lib/websocket/bindings.js +321 -0
- package/lib/win/binding.gyp +23 -0
- package/lib/win/bindings.js +11 -0
- package/lib/win/src/ble_manager.cc +802 -0
- package/lib/win/src/ble_manager.h +77 -0
- package/lib/win/src/callbacks.cc +274 -0
- package/lib/win/src/callbacks.h +33 -0
- package/lib/win/src/napi_winrt.cc +76 -0
- package/lib/win/src/napi_winrt.h +12 -0
- package/lib/win/src/noble_winrt.cc +308 -0
- package/lib/win/src/noble_winrt.h +34 -0
- package/lib/win/src/notify_map.cc +62 -0
- package/lib/win/src/notify_map.h +50 -0
- package/lib/win/src/peripheral.h +23 -0
- package/lib/win/src/peripheral_winrt.cc +296 -0
- package/lib/win/src/peripheral_winrt.h +82 -0
- package/lib/win/src/radio_watcher.cc +125 -0
- package/lib/win/src/radio_watcher.h +61 -0
- package/lib/win/src/winrt_cpp.cc +82 -0
- package/lib/win/src/winrt_cpp.h +11 -0
- package/lib/win/src/winrt_guid.cc +12 -0
- package/lib/win/src/winrt_guid.h +13 -0
- package/misc/nrf52840dk.hex +6921 -0
- package/misc/prj.conf +43 -0
- package/package.json +96 -0
- package/test/lib/characteristic.test.js +791 -0
- package/test/lib/descriptor.test.js +249 -0
- package/test/lib/distributed/bindings.test.js +918 -0
- package/test/lib/hci-socket/acl-stream.test.js +188 -0
- package/test/lib/hci-socket/bindings.test.js +1756 -0
- package/test/lib/hci-socket/crypto.test.js +55 -0
- package/test/lib/hci-socket/gap.test.js +1089 -0
- package/test/lib/hci-socket/gatt.test.js +2392 -0
- package/test/lib/hci-socket/hci.test.js +1891 -0
- package/test/lib/hci-socket/signaling.test.js +94 -0
- package/test/lib/hci-socket/smp.test.js +268 -0
- package/test/lib/manufacture.test.js +77 -0
- package/test/lib/peripheral.test.js +623 -0
- package/test/lib/resolve-bindings.test.js +102 -0
- package/test/lib/service.test.js +195 -0
- package/test/lib/webbluetooth/bindings.test.js +190 -0
- package/test/lib/websocket/bindings.test.js +456 -0
- package/test/noble.test.js +1565 -0
- package/test.js +131 -0
- package/with-bindings.js +5 -0
- package/ws-slave.js +404 -0
|
@@ -0,0 +1,791 @@
|
|
|
1
|
+
const sinon = require('sinon');
|
|
2
|
+
const should = require('should');
|
|
3
|
+
|
|
4
|
+
const { assert } = sinon;
|
|
5
|
+
|
|
6
|
+
const Characteristic = require('../../lib/characteristic');
|
|
7
|
+
|
|
8
|
+
describe('characteristic', () => {
|
|
9
|
+
let mockNoble = null;
|
|
10
|
+
const mockPeripheralId = 'mock-peripheral-id';
|
|
11
|
+
const mockServiceUuid = 'mock-service-uuid';
|
|
12
|
+
const mockUuid = 'mock-uuid';
|
|
13
|
+
const mockProperties = ['mock-property-1', 'mock-property-2'];
|
|
14
|
+
|
|
15
|
+
let characteristic = null;
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
mockNoble = {};
|
|
19
|
+
|
|
20
|
+
characteristic = new Characteristic(
|
|
21
|
+
mockNoble,
|
|
22
|
+
mockPeripheralId,
|
|
23
|
+
mockServiceUuid,
|
|
24
|
+
mockUuid,
|
|
25
|
+
mockProperties
|
|
26
|
+
);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should have a uuid', () => {
|
|
30
|
+
should(characteristic.uuid).equal(mockUuid);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should lookup name and type by uuid', () => {
|
|
34
|
+
characteristic = new Characteristic(
|
|
35
|
+
mockNoble,
|
|
36
|
+
mockPeripheralId,
|
|
37
|
+
mockServiceUuid,
|
|
38
|
+
'2a00',
|
|
39
|
+
mockProperties
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
should(characteristic.name).equal('Device Name');
|
|
43
|
+
should(characteristic.type).equal(
|
|
44
|
+
'org.bluetooth.characteristic.gap.device_name'
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should have properties', () => {
|
|
49
|
+
should(characteristic.properties).equal(mockProperties);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
describe('toString', () => {
|
|
53
|
+
it('should be uuid, name, type, properties', () => {
|
|
54
|
+
should(characteristic.toString()).equal(
|
|
55
|
+
'{"uuid":"mock-uuid","name":null,"type":null,"properties":["mock-property-1","mock-property-2"]}'
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
describe('read', () => {
|
|
61
|
+
beforeEach(() => {
|
|
62
|
+
mockNoble.read = sinon.spy();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
afterEach(() => {
|
|
66
|
+
sinon.reset();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('should delegate to noble', () => {
|
|
70
|
+
characteristic.read();
|
|
71
|
+
assert.calledOnceWithExactly(
|
|
72
|
+
mockNoble.read,
|
|
73
|
+
mockPeripheralId,
|
|
74
|
+
mockServiceUuid,
|
|
75
|
+
mockUuid
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('should callback without data', () => {
|
|
80
|
+
const callback = sinon.spy();
|
|
81
|
+
|
|
82
|
+
characteristic.read(callback);
|
|
83
|
+
characteristic.emit('read');
|
|
84
|
+
// Check for single callback
|
|
85
|
+
characteristic.emit('read');
|
|
86
|
+
|
|
87
|
+
assert.calledOnceWithExactly(callback, null, undefined);
|
|
88
|
+
assert.calledOnceWithExactly(
|
|
89
|
+
mockNoble.read,
|
|
90
|
+
mockPeripheralId,
|
|
91
|
+
mockServiceUuid,
|
|
92
|
+
mockUuid
|
|
93
|
+
);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('should callback with data', () => {
|
|
97
|
+
const callback = sinon.spy();
|
|
98
|
+
const data = 'data';
|
|
99
|
+
|
|
100
|
+
characteristic.read(callback);
|
|
101
|
+
characteristic.emit('read', data);
|
|
102
|
+
// Check for single callback
|
|
103
|
+
characteristic.emit('read', data);
|
|
104
|
+
|
|
105
|
+
assert.calledOnceWithExactly(callback, null, data);
|
|
106
|
+
assert.calledOnceWithExactly(
|
|
107
|
+
mockNoble.read,
|
|
108
|
+
mockPeripheralId,
|
|
109
|
+
mockServiceUuid,
|
|
110
|
+
mockUuid
|
|
111
|
+
);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should not callback as it is notification', () => {
|
|
115
|
+
const callback = sinon.spy();
|
|
116
|
+
const data = 'data';
|
|
117
|
+
|
|
118
|
+
characteristic.read(callback);
|
|
119
|
+
characteristic.emit('read', data, true);
|
|
120
|
+
// Check for single callback
|
|
121
|
+
characteristic.emit('read', data, true);
|
|
122
|
+
|
|
123
|
+
assert.notCalled(callback);
|
|
124
|
+
assert.calledOnceWithExactly(
|
|
125
|
+
mockNoble.read,
|
|
126
|
+
mockPeripheralId,
|
|
127
|
+
mockServiceUuid,
|
|
128
|
+
mockUuid
|
|
129
|
+
);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
describe('readAsync', () => {
|
|
134
|
+
beforeEach(() => {
|
|
135
|
+
mockNoble.read = sinon.spy();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
afterEach(() => {
|
|
139
|
+
sinon.reset();
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('should delegate to noble', async () => {
|
|
143
|
+
const promise = characteristic.readAsync();
|
|
144
|
+
characteristic.emit('read');
|
|
145
|
+
// Check for single callback
|
|
146
|
+
characteristic.emit('read');
|
|
147
|
+
|
|
148
|
+
should(promise).resolvedWith(undefined);
|
|
149
|
+
assert.calledOnceWithExactly(
|
|
150
|
+
mockNoble.read,
|
|
151
|
+
mockPeripheralId,
|
|
152
|
+
mockServiceUuid,
|
|
153
|
+
mockUuid
|
|
154
|
+
);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('should returns without data', async () => {
|
|
158
|
+
const promise = characteristic.readAsync();
|
|
159
|
+
characteristic.emit('read');
|
|
160
|
+
// Check for single callback
|
|
161
|
+
characteristic.emit('read');
|
|
162
|
+
|
|
163
|
+
should(promise).resolvedWith(undefined);
|
|
164
|
+
assert.calledOnceWithExactly(
|
|
165
|
+
mockNoble.read,
|
|
166
|
+
mockPeripheralId,
|
|
167
|
+
mockServiceUuid,
|
|
168
|
+
mockUuid
|
|
169
|
+
);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('should callback with data', async () => {
|
|
173
|
+
const data = 'data';
|
|
174
|
+
|
|
175
|
+
const promise = characteristic.readAsync();
|
|
176
|
+
characteristic.emit('read', data);
|
|
177
|
+
// Check for single callback
|
|
178
|
+
characteristic.emit('read', data);
|
|
179
|
+
|
|
180
|
+
should(promise).resolvedWith(data);
|
|
181
|
+
assert.calledOnceWithExactly(
|
|
182
|
+
mockNoble.read,
|
|
183
|
+
mockPeripheralId,
|
|
184
|
+
mockServiceUuid,
|
|
185
|
+
mockUuid
|
|
186
|
+
);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// This shows that async notification never ends
|
|
190
|
+
it.skip('should not callback as it is notification', async () => {
|
|
191
|
+
const data = 'data';
|
|
192
|
+
|
|
193
|
+
const promise = characteristic.readAsync();
|
|
194
|
+
characteristic.emit('read', data, true);
|
|
195
|
+
// Check for single callback
|
|
196
|
+
characteristic.emit('read', data, true);
|
|
197
|
+
|
|
198
|
+
should(promise).resolvedWith(undefined);
|
|
199
|
+
assert.calledOnceWithExactly(
|
|
200
|
+
mockNoble.read,
|
|
201
|
+
mockPeripheralId,
|
|
202
|
+
mockServiceUuid,
|
|
203
|
+
mockUuid
|
|
204
|
+
);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
describe('write', () => {
|
|
209
|
+
let processTitle = null;
|
|
210
|
+
beforeEach(() => {
|
|
211
|
+
mockNoble.write = sinon.spy();
|
|
212
|
+
processTitle = process.title;
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
afterEach(() => {
|
|
216
|
+
sinon.reset();
|
|
217
|
+
process.title = processTitle;
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it('should only accept data as a buffer', () => {
|
|
221
|
+
should(() => characteristic.write({})).throw(
|
|
222
|
+
'data must be a Buffer or Uint8Array or Uint16Array or Uint32Array'
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
assert.notCalled(mockNoble.write);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it('should accept any kind of data as process is browser', () => {
|
|
229
|
+
process.title = 'browser';
|
|
230
|
+
|
|
231
|
+
const mockData = {};
|
|
232
|
+
characteristic.write(mockData);
|
|
233
|
+
|
|
234
|
+
assert.calledOnceWithExactly(
|
|
235
|
+
mockNoble.write,
|
|
236
|
+
mockPeripheralId,
|
|
237
|
+
mockServiceUuid,
|
|
238
|
+
mockUuid,
|
|
239
|
+
mockData,
|
|
240
|
+
undefined
|
|
241
|
+
);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it('should delegate to noble, withoutResponse false', () => {
|
|
245
|
+
const mockData = Buffer.alloc(0);
|
|
246
|
+
characteristic.write(mockData, false);
|
|
247
|
+
|
|
248
|
+
assert.calledOnceWithExactly(
|
|
249
|
+
mockNoble.write,
|
|
250
|
+
mockPeripheralId,
|
|
251
|
+
mockServiceUuid,
|
|
252
|
+
mockUuid,
|
|
253
|
+
mockData,
|
|
254
|
+
false
|
|
255
|
+
);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it('should delegate to noble, withoutResponse true', () => {
|
|
259
|
+
const mockData = Buffer.alloc(0);
|
|
260
|
+
characteristic.write(mockData, true);
|
|
261
|
+
|
|
262
|
+
assert.calledOnceWithExactly(
|
|
263
|
+
mockNoble.write,
|
|
264
|
+
mockPeripheralId,
|
|
265
|
+
mockServiceUuid,
|
|
266
|
+
mockUuid,
|
|
267
|
+
mockData,
|
|
268
|
+
true
|
|
269
|
+
);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it('should callback', () => {
|
|
273
|
+
const mockData = Buffer.alloc(0);
|
|
274
|
+
const callback = sinon.spy();
|
|
275
|
+
|
|
276
|
+
characteristic.write(mockData, true, callback);
|
|
277
|
+
characteristic.emit('write');
|
|
278
|
+
// Check for single callback
|
|
279
|
+
characteristic.emit('write');
|
|
280
|
+
|
|
281
|
+
assert.calledOnceWithExactly(callback, null);
|
|
282
|
+
assert.calledOnceWithExactly(
|
|
283
|
+
mockNoble.write,
|
|
284
|
+
mockPeripheralId,
|
|
285
|
+
mockServiceUuid,
|
|
286
|
+
mockUuid,
|
|
287
|
+
mockData,
|
|
288
|
+
true
|
|
289
|
+
);
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
describe('writeAsync', () => {
|
|
294
|
+
beforeEach(() => {
|
|
295
|
+
mockNoble.write = sinon.spy();
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
afterEach(() => {
|
|
299
|
+
sinon.reset();
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
it('should only accept data as a buffer', async () => {
|
|
303
|
+
const promise = characteristic.writeAsync({});
|
|
304
|
+
should(promise).rejectedWith(
|
|
305
|
+
'data must be a Buffer or Uint8Array or Uint16Array or Uint32Array'
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
assert.notCalled(mockNoble.write);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it('should delegate to noble, withoutResponse false', async () => {
|
|
312
|
+
const mockData = Buffer.alloc(0);
|
|
313
|
+
const promise = characteristic.writeAsync(mockData, false);
|
|
314
|
+
characteristic.emit('write');
|
|
315
|
+
// Check for single callback
|
|
316
|
+
characteristic.emit('write');
|
|
317
|
+
|
|
318
|
+
should(promise).resolvedWith(undefined);
|
|
319
|
+
assert.calledOnceWithExactly(
|
|
320
|
+
mockNoble.write,
|
|
321
|
+
mockPeripheralId,
|
|
322
|
+
mockServiceUuid,
|
|
323
|
+
mockUuid,
|
|
324
|
+
mockData,
|
|
325
|
+
false
|
|
326
|
+
);
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
it('should delegate to noble, withoutResponse true', async () => {
|
|
330
|
+
const mockData = Buffer.alloc(0);
|
|
331
|
+
const promise = characteristic.writeAsync(mockData, true);
|
|
332
|
+
characteristic.emit('write');
|
|
333
|
+
// Check for single callback
|
|
334
|
+
characteristic.emit('write');
|
|
335
|
+
|
|
336
|
+
should(promise).resolvedWith(undefined);
|
|
337
|
+
assert.calledOnceWithExactly(
|
|
338
|
+
mockNoble.write,
|
|
339
|
+
mockPeripheralId,
|
|
340
|
+
mockServiceUuid,
|
|
341
|
+
mockUuid,
|
|
342
|
+
mockData,
|
|
343
|
+
true
|
|
344
|
+
);
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
it('should resolve', async () => {
|
|
348
|
+
const mockData = Buffer.alloc(0);
|
|
349
|
+
const promise = characteristic.writeAsync(mockData, true);
|
|
350
|
+
characteristic.emit('write');
|
|
351
|
+
// Check for single callback
|
|
352
|
+
characteristic.emit('write');
|
|
353
|
+
|
|
354
|
+
should(promise).resolvedWith(undefined);
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
describe('broadcast', () => {
|
|
359
|
+
beforeEach(() => {
|
|
360
|
+
mockNoble.broadcast = sinon.spy();
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
afterEach(() => {
|
|
364
|
+
sinon.reset();
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
it('should delegate to noble, true', () => {
|
|
368
|
+
characteristic.broadcast(true);
|
|
369
|
+
|
|
370
|
+
assert.calledOnceWithExactly(
|
|
371
|
+
mockNoble.broadcast,
|
|
372
|
+
mockPeripheralId,
|
|
373
|
+
mockServiceUuid,
|
|
374
|
+
mockUuid,
|
|
375
|
+
true
|
|
376
|
+
);
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
it('should delegate to noble, false', () => {
|
|
380
|
+
characteristic.broadcast(false);
|
|
381
|
+
|
|
382
|
+
assert.calledOnceWithExactly(
|
|
383
|
+
mockNoble.broadcast,
|
|
384
|
+
mockPeripheralId,
|
|
385
|
+
mockServiceUuid,
|
|
386
|
+
mockUuid,
|
|
387
|
+
false
|
|
388
|
+
);
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
it('should callback', () => {
|
|
392
|
+
const callback = sinon.spy();
|
|
393
|
+
|
|
394
|
+
characteristic.broadcast(true, callback);
|
|
395
|
+
characteristic.emit('broadcast');
|
|
396
|
+
// Check for single callback
|
|
397
|
+
characteristic.emit('broadcast');
|
|
398
|
+
|
|
399
|
+
assert.calledOnceWithExactly(callback, null);
|
|
400
|
+
assert.calledOnceWithExactly(
|
|
401
|
+
mockNoble.broadcast,
|
|
402
|
+
mockPeripheralId,
|
|
403
|
+
mockServiceUuid,
|
|
404
|
+
mockUuid,
|
|
405
|
+
true
|
|
406
|
+
);
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
describe('broadcastAsync', () => {
|
|
411
|
+
beforeEach(() => {
|
|
412
|
+
mockNoble.broadcast = sinon.spy();
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
afterEach(() => {
|
|
416
|
+
sinon.reset();
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
it('should delegate to noble, true', async () => {
|
|
420
|
+
const promise = characteristic.broadcastAsync(true);
|
|
421
|
+
characteristic.emit('broadcast');
|
|
422
|
+
// Check for single callback
|
|
423
|
+
characteristic.emit('broadcast');
|
|
424
|
+
|
|
425
|
+
should(promise).resolvedWith(undefined);
|
|
426
|
+
assert.calledOnceWithExactly(
|
|
427
|
+
mockNoble.broadcast,
|
|
428
|
+
mockPeripheralId,
|
|
429
|
+
mockServiceUuid,
|
|
430
|
+
mockUuid,
|
|
431
|
+
true
|
|
432
|
+
);
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
it('should delegate to noble, false', async () => {
|
|
436
|
+
const promise = characteristic.broadcastAsync(false);
|
|
437
|
+
characteristic.emit('broadcast');
|
|
438
|
+
// Check for single callback
|
|
439
|
+
characteristic.emit('broadcast');
|
|
440
|
+
|
|
441
|
+
should(promise).resolvedWith(undefined);
|
|
442
|
+
assert.calledOnceWithExactly(
|
|
443
|
+
mockNoble.broadcast,
|
|
444
|
+
mockPeripheralId,
|
|
445
|
+
mockServiceUuid,
|
|
446
|
+
mockUuid,
|
|
447
|
+
false
|
|
448
|
+
);
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
it('should resolve', async () => {
|
|
452
|
+
const promise = characteristic.broadcastAsync(true);
|
|
453
|
+
characteristic.emit('broadcast');
|
|
454
|
+
// Check for single callback
|
|
455
|
+
characteristic.emit('broadcast');
|
|
456
|
+
|
|
457
|
+
should(promise).resolvedWith(undefined);
|
|
458
|
+
assert.calledOnceWithExactly(
|
|
459
|
+
mockNoble.broadcast,
|
|
460
|
+
mockPeripheralId,
|
|
461
|
+
mockServiceUuid,
|
|
462
|
+
mockUuid,
|
|
463
|
+
true
|
|
464
|
+
);
|
|
465
|
+
});
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
describe('notify', () => {
|
|
469
|
+
beforeEach(() => {
|
|
470
|
+
mockNoble.notify = sinon.spy();
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
afterEach(() => {
|
|
474
|
+
sinon.reset();
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
it('should delegate to noble, true', () => {
|
|
478
|
+
characteristic.notify(true);
|
|
479
|
+
|
|
480
|
+
assert.calledOnceWithExactly(
|
|
481
|
+
mockNoble.notify,
|
|
482
|
+
mockPeripheralId,
|
|
483
|
+
mockServiceUuid,
|
|
484
|
+
mockUuid,
|
|
485
|
+
true
|
|
486
|
+
);
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
it('should delegate to noble, false', () => {
|
|
490
|
+
characteristic.notify(false);
|
|
491
|
+
|
|
492
|
+
assert.calledOnceWithExactly(
|
|
493
|
+
mockNoble.notify,
|
|
494
|
+
mockPeripheralId,
|
|
495
|
+
mockServiceUuid,
|
|
496
|
+
mockUuid,
|
|
497
|
+
false
|
|
498
|
+
);
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
it('should callback', () => {
|
|
502
|
+
const callback = sinon.spy();
|
|
503
|
+
|
|
504
|
+
characteristic.notify(true, callback);
|
|
505
|
+
characteristic.emit('notify');
|
|
506
|
+
// Check for single callback
|
|
507
|
+
characteristic.emit('notify');
|
|
508
|
+
|
|
509
|
+
assert.calledOnceWithExactly(callback, null);
|
|
510
|
+
assert.calledOnceWithExactly(
|
|
511
|
+
mockNoble.notify,
|
|
512
|
+
mockPeripheralId,
|
|
513
|
+
mockServiceUuid,
|
|
514
|
+
mockUuid,
|
|
515
|
+
true
|
|
516
|
+
);
|
|
517
|
+
});
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
describe('notifyAsync', () => {
|
|
521
|
+
beforeEach(() => {
|
|
522
|
+
mockNoble.notify = sinon.spy();
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
afterEach(() => {
|
|
526
|
+
sinon.reset();
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
it('should delegate to noble, true', async () => {
|
|
530
|
+
const promise = characteristic.notifyAsync(true);
|
|
531
|
+
characteristic.emit('notify');
|
|
532
|
+
// Check for single callback
|
|
533
|
+
characteristic.emit('notify');
|
|
534
|
+
|
|
535
|
+
should(promise).resolvedWith(undefined);
|
|
536
|
+
assert.calledOnceWithExactly(
|
|
537
|
+
mockNoble.notify,
|
|
538
|
+
mockPeripheralId,
|
|
539
|
+
mockServiceUuid,
|
|
540
|
+
mockUuid,
|
|
541
|
+
true
|
|
542
|
+
);
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
it('should delegate to noble, false', async () => {
|
|
546
|
+
const promise = characteristic.notifyAsync(false);
|
|
547
|
+
characteristic.emit('notify');
|
|
548
|
+
// Check for single callback
|
|
549
|
+
characteristic.emit('notify');
|
|
550
|
+
|
|
551
|
+
should(promise).resolvedWith(undefined);
|
|
552
|
+
assert.calledOnceWithExactly(
|
|
553
|
+
mockNoble.notify,
|
|
554
|
+
mockPeripheralId,
|
|
555
|
+
mockServiceUuid,
|
|
556
|
+
mockUuid,
|
|
557
|
+
false
|
|
558
|
+
);
|
|
559
|
+
});
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
describe('subscribe', () => {
|
|
563
|
+
beforeEach(() => {
|
|
564
|
+
mockNoble.notify = sinon.spy();
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
afterEach(() => {
|
|
568
|
+
sinon.reset();
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
it('should delegate to noble notify, true', () => {
|
|
572
|
+
characteristic.subscribe();
|
|
573
|
+
|
|
574
|
+
assert.calledOnceWithExactly(
|
|
575
|
+
mockNoble.notify,
|
|
576
|
+
mockPeripheralId,
|
|
577
|
+
mockServiceUuid,
|
|
578
|
+
mockUuid,
|
|
579
|
+
true
|
|
580
|
+
);
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
it('should callback', () => {
|
|
584
|
+
const callback = sinon.spy();
|
|
585
|
+
|
|
586
|
+
characteristic.subscribe(callback);
|
|
587
|
+
characteristic.emit('notify');
|
|
588
|
+
// Check for single callback
|
|
589
|
+
characteristic.emit('notify');
|
|
590
|
+
|
|
591
|
+
assert.calledOnceWithExactly(callback, null);
|
|
592
|
+
assert.calledOnceWithExactly(
|
|
593
|
+
mockNoble.notify,
|
|
594
|
+
mockPeripheralId,
|
|
595
|
+
mockServiceUuid,
|
|
596
|
+
mockUuid,
|
|
597
|
+
true
|
|
598
|
+
);
|
|
599
|
+
});
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
describe('subscribeAsync', () => {
|
|
603
|
+
beforeEach(() => {
|
|
604
|
+
mockNoble.notify = sinon.spy();
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
afterEach(() => {
|
|
608
|
+
sinon.reset();
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
it('should delegate to noble notify, true', async () => {
|
|
612
|
+
const promise = characteristic.subscribeAsync();
|
|
613
|
+
characteristic.emit('notify');
|
|
614
|
+
// Check for single callback
|
|
615
|
+
characteristic.emit('notify');
|
|
616
|
+
|
|
617
|
+
should(promise).resolvedWith(undefined);
|
|
618
|
+
assert.calledOnceWithExactly(
|
|
619
|
+
mockNoble.notify,
|
|
620
|
+
mockPeripheralId,
|
|
621
|
+
mockServiceUuid,
|
|
622
|
+
mockUuid,
|
|
623
|
+
true
|
|
624
|
+
);
|
|
625
|
+
});
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
describe('unsubscribe', () => {
|
|
629
|
+
beforeEach(() => {
|
|
630
|
+
mockNoble.notify = sinon.spy();
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
afterEach(() => {
|
|
634
|
+
sinon.reset();
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
it('should delegate to noble notify, false', () => {
|
|
638
|
+
characteristic.unsubscribe();
|
|
639
|
+
|
|
640
|
+
assert.calledOnceWithExactly(
|
|
641
|
+
mockNoble.notify,
|
|
642
|
+
mockPeripheralId,
|
|
643
|
+
mockServiceUuid,
|
|
644
|
+
mockUuid,
|
|
645
|
+
false
|
|
646
|
+
);
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
it('should callback', () => {
|
|
650
|
+
const callback = sinon.spy();
|
|
651
|
+
|
|
652
|
+
characteristic.unsubscribe(callback);
|
|
653
|
+
characteristic.emit('notify');
|
|
654
|
+
// Check for single callback
|
|
655
|
+
characteristic.emit('notify');
|
|
656
|
+
|
|
657
|
+
assert.calledOnceWithExactly(callback, null);
|
|
658
|
+
assert.calledOnceWithExactly(
|
|
659
|
+
mockNoble.notify,
|
|
660
|
+
mockPeripheralId,
|
|
661
|
+
mockServiceUuid,
|
|
662
|
+
mockUuid,
|
|
663
|
+
false
|
|
664
|
+
);
|
|
665
|
+
});
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
describe('unsubscribeAsync', () => {
|
|
669
|
+
beforeEach(() => {
|
|
670
|
+
mockNoble.notify = sinon.spy();
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
afterEach(() => {
|
|
674
|
+
sinon.reset();
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
it('should delegate to noble notify, false', async () => {
|
|
678
|
+
const promise = characteristic.unsubscribeAsync();
|
|
679
|
+
characteristic.emit('notify');
|
|
680
|
+
// Check for single callback
|
|
681
|
+
characteristic.emit('notify');
|
|
682
|
+
|
|
683
|
+
should(promise).resolvedWith(undefined);
|
|
684
|
+
assert.calledOnceWithExactly(
|
|
685
|
+
mockNoble.notify,
|
|
686
|
+
mockPeripheralId,
|
|
687
|
+
mockServiceUuid,
|
|
688
|
+
mockUuid,
|
|
689
|
+
false
|
|
690
|
+
);
|
|
691
|
+
});
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
describe('discoverDescriptors', () => {
|
|
695
|
+
beforeEach(() => {
|
|
696
|
+
mockNoble.discoverDescriptors = sinon.spy();
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
afterEach(() => {
|
|
700
|
+
sinon.reset();
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
it('should delegate to noble', () => {
|
|
704
|
+
characteristic.discoverDescriptors();
|
|
705
|
+
|
|
706
|
+
assert.calledOnceWithExactly(
|
|
707
|
+
mockNoble.discoverDescriptors,
|
|
708
|
+
mockPeripheralId,
|
|
709
|
+
mockServiceUuid,
|
|
710
|
+
mockUuid
|
|
711
|
+
);
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
it('should callback, undefined descriptors', () => {
|
|
715
|
+
const callback = sinon.spy();
|
|
716
|
+
|
|
717
|
+
characteristic.discoverDescriptors(callback);
|
|
718
|
+
characteristic.emit('descriptorsDiscover');
|
|
719
|
+
// Check for single callback
|
|
720
|
+
characteristic.emit('descriptorsDiscover');
|
|
721
|
+
|
|
722
|
+
assert.calledOnceWithExactly(callback, null, undefined);
|
|
723
|
+
assert.calledOnceWithExactly(
|
|
724
|
+
mockNoble.discoverDescriptors,
|
|
725
|
+
mockPeripheralId,
|
|
726
|
+
mockServiceUuid,
|
|
727
|
+
mockUuid
|
|
728
|
+
);
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
it('should callback with descriptors', () => {
|
|
732
|
+
const callback = sinon.spy();
|
|
733
|
+
const descriptors = 'descriptors';
|
|
734
|
+
|
|
735
|
+
characteristic.discoverDescriptors(callback);
|
|
736
|
+
characteristic.emit('descriptorsDiscover', descriptors);
|
|
737
|
+
// Check for single callback
|
|
738
|
+
characteristic.emit('descriptorsDiscover', descriptors);
|
|
739
|
+
|
|
740
|
+
assert.calledOnceWithExactly(callback, null, descriptors);
|
|
741
|
+
assert.calledOnceWithExactly(
|
|
742
|
+
mockNoble.discoverDescriptors,
|
|
743
|
+
mockPeripheralId,
|
|
744
|
+
mockServiceUuid,
|
|
745
|
+
mockUuid
|
|
746
|
+
);
|
|
747
|
+
});
|
|
748
|
+
});
|
|
749
|
+
|
|
750
|
+
describe('discoverDescriptorsAsync', () => {
|
|
751
|
+
beforeEach(() => {
|
|
752
|
+
mockNoble.discoverDescriptors = sinon.spy();
|
|
753
|
+
});
|
|
754
|
+
|
|
755
|
+
afterEach(() => {
|
|
756
|
+
sinon.reset();
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
it('should delegate to noble', async () => {
|
|
760
|
+
const promise = characteristic.discoverDescriptorsAsync();
|
|
761
|
+
characteristic.emit('descriptorsDiscover');
|
|
762
|
+
// Check for single callback
|
|
763
|
+
characteristic.emit('descriptorsDiscover');
|
|
764
|
+
|
|
765
|
+
should(promise).resolvedWith(null, undefined);
|
|
766
|
+
assert.calledOnceWithExactly(
|
|
767
|
+
mockNoble.discoverDescriptors,
|
|
768
|
+
mockPeripheralId,
|
|
769
|
+
mockServiceUuid,
|
|
770
|
+
mockUuid
|
|
771
|
+
);
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
it('should resolve with descriptors', async () => {
|
|
775
|
+
const descriptors = 'descriptors';
|
|
776
|
+
|
|
777
|
+
const promise = characteristic.discoverDescriptorsAsync();
|
|
778
|
+
characteristic.emit('descriptorsDiscover', descriptors);
|
|
779
|
+
// Check for single callback
|
|
780
|
+
characteristic.emit('descriptorsDiscover', descriptors);
|
|
781
|
+
|
|
782
|
+
should(promise).resolvedWith(null, descriptors);
|
|
783
|
+
assert.calledOnceWithExactly(
|
|
784
|
+
mockNoble.discoverDescriptors,
|
|
785
|
+
mockPeripheralId,
|
|
786
|
+
mockServiceUuid,
|
|
787
|
+
mockUuid
|
|
788
|
+
);
|
|
789
|
+
});
|
|
790
|
+
});
|
|
791
|
+
});
|