@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.
Files changed (112) hide show
  1. package/.editorconfig +11 -0
  2. package/.eslintrc.js +25 -0
  3. package/.github/FUNDING.yml +2 -0
  4. package/.github/workflows/fediverse-action.yml +16 -0
  5. package/.github/workflows/nodepackage.yml +77 -0
  6. package/.github/workflows/npm-publish.yml +26 -0
  7. package/.github/workflows/prebuild.yml +65 -0
  8. package/.nycrc.json +4 -0
  9. package/CHANGELOG.md +119 -0
  10. package/LICENSE +20 -0
  11. package/MAINTAINERS.md +1 -0
  12. package/README.md +833 -0
  13. package/assets/noble-logo.png +0 -0
  14. package/assets/noble-logo.svg +13 -0
  15. package/binding.gyp +19 -0
  16. package/codecov.yml +5 -0
  17. package/examples/advertisement-discovery.js +65 -0
  18. package/examples/cache-gatt-discovery.js +198 -0
  19. package/examples/cache-gatt-reconnect.js +164 -0
  20. package/examples/echo.js +104 -0
  21. package/examples/enter-exit.js +78 -0
  22. package/examples/peripheral-explorer-async.js +133 -0
  23. package/examples/peripheral-explorer.js +225 -0
  24. package/examples/pizza/README.md +15 -0
  25. package/examples/pizza/central.js +194 -0
  26. package/examples/pizza/pizza.js +60 -0
  27. package/index.d.ts +203 -0
  28. package/index.js +6 -0
  29. package/lib/characteristic.js +161 -0
  30. package/lib/characteristics.json +449 -0
  31. package/lib/descriptor.js +72 -0
  32. package/lib/descriptors.json +47 -0
  33. package/lib/distributed/bindings.js +326 -0
  34. package/lib/hci-socket/acl-stream.js +60 -0
  35. package/lib/hci-socket/bindings.js +788 -0
  36. package/lib/hci-socket/crypto.js +74 -0
  37. package/lib/hci-socket/gap.js +432 -0
  38. package/lib/hci-socket/gatt.js +809 -0
  39. package/lib/hci-socket/hci-status.json +71 -0
  40. package/lib/hci-socket/hci.js +1264 -0
  41. package/lib/hci-socket/signaling.js +76 -0
  42. package/lib/hci-socket/smp.js +140 -0
  43. package/lib/hci-uart/bindings.js +569 -0
  44. package/lib/hci-uart/hci-serial-parser.js +70 -0
  45. package/lib/hci-uart/hci.js +1336 -0
  46. package/lib/mac/binding.gyp +26 -0
  47. package/lib/mac/bindings.js +11 -0
  48. package/lib/mac/src/ble_manager.h +41 -0
  49. package/lib/mac/src/ble_manager.mm +435 -0
  50. package/lib/mac/src/callbacks.cc +222 -0
  51. package/lib/mac/src/callbacks.h +84 -0
  52. package/lib/mac/src/napi_objc.h +12 -0
  53. package/lib/mac/src/napi_objc.mm +50 -0
  54. package/lib/mac/src/noble_mac.h +34 -0
  55. package/lib/mac/src/noble_mac.mm +264 -0
  56. package/lib/mac/src/objc_cpp.h +26 -0
  57. package/lib/mac/src/objc_cpp.mm +126 -0
  58. package/lib/mac/src/peripheral.h +23 -0
  59. package/lib/manufacture.js +48 -0
  60. package/lib/noble.js +593 -0
  61. package/lib/peripheral.js +219 -0
  62. package/lib/resolve-bindings-web.js +9 -0
  63. package/lib/resolve-bindings.js +44 -0
  64. package/lib/service.js +72 -0
  65. package/lib/services.json +92 -0
  66. package/lib/webbluetooth/bindings.js +368 -0
  67. package/lib/websocket/bindings.js +321 -0
  68. package/lib/win/binding.gyp +23 -0
  69. package/lib/win/bindings.js +11 -0
  70. package/lib/win/src/ble_manager.cc +802 -0
  71. package/lib/win/src/ble_manager.h +77 -0
  72. package/lib/win/src/callbacks.cc +274 -0
  73. package/lib/win/src/callbacks.h +33 -0
  74. package/lib/win/src/napi_winrt.cc +76 -0
  75. package/lib/win/src/napi_winrt.h +12 -0
  76. package/lib/win/src/noble_winrt.cc +308 -0
  77. package/lib/win/src/noble_winrt.h +34 -0
  78. package/lib/win/src/notify_map.cc +62 -0
  79. package/lib/win/src/notify_map.h +50 -0
  80. package/lib/win/src/peripheral.h +23 -0
  81. package/lib/win/src/peripheral_winrt.cc +296 -0
  82. package/lib/win/src/peripheral_winrt.h +82 -0
  83. package/lib/win/src/radio_watcher.cc +125 -0
  84. package/lib/win/src/radio_watcher.h +61 -0
  85. package/lib/win/src/winrt_cpp.cc +82 -0
  86. package/lib/win/src/winrt_cpp.h +11 -0
  87. package/lib/win/src/winrt_guid.cc +12 -0
  88. package/lib/win/src/winrt_guid.h +13 -0
  89. package/misc/nrf52840dk.hex +6921 -0
  90. package/misc/prj.conf +43 -0
  91. package/package.json +96 -0
  92. package/test/lib/characteristic.test.js +791 -0
  93. package/test/lib/descriptor.test.js +249 -0
  94. package/test/lib/distributed/bindings.test.js +918 -0
  95. package/test/lib/hci-socket/acl-stream.test.js +188 -0
  96. package/test/lib/hci-socket/bindings.test.js +1756 -0
  97. package/test/lib/hci-socket/crypto.test.js +55 -0
  98. package/test/lib/hci-socket/gap.test.js +1089 -0
  99. package/test/lib/hci-socket/gatt.test.js +2392 -0
  100. package/test/lib/hci-socket/hci.test.js +1891 -0
  101. package/test/lib/hci-socket/signaling.test.js +94 -0
  102. package/test/lib/hci-socket/smp.test.js +268 -0
  103. package/test/lib/manufacture.test.js +77 -0
  104. package/test/lib/peripheral.test.js +623 -0
  105. package/test/lib/resolve-bindings.test.js +102 -0
  106. package/test/lib/service.test.js +195 -0
  107. package/test/lib/webbluetooth/bindings.test.js +190 -0
  108. package/test/lib/websocket/bindings.test.js +456 -0
  109. package/test/noble.test.js +1565 -0
  110. package/test.js +131 -0
  111. package/with-bindings.js +5 -0
  112. 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
+ });