blob: dac1861e0163ee48d05e6ddabfc05d2acf336d8e [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001var tape = require('tape')
2 , crypto = require('crypto')
3 , fs = require('fs')
4 , hash = require('hash_file')
5 , BufferList = require('../')
6 , Buffer = require('safe-buffer').Buffer
7
8 , encodings =
9 ('hex utf8 utf-8 ascii binary base64'
10 + (process.browser ? '' : ' ucs2 ucs-2 utf16le utf-16le')).split(' ')
11
12tape('single bytes from single buffer', function (t) {
13 var bl = new BufferList()
14 bl.append(Buffer.from('abcd'))
15
16 t.equal(bl.length, 4)
17
18 t.equal(bl.get(0), 97)
19 t.equal(bl.get(1), 98)
20 t.equal(bl.get(2), 99)
21 t.equal(bl.get(3), 100)
22
23 t.end()
24})
25
26tape('single bytes from multiple buffers', function (t) {
27 var bl = new BufferList()
28 bl.append(Buffer.from('abcd'))
29 bl.append(Buffer.from('efg'))
30 bl.append(Buffer.from('hi'))
31 bl.append(Buffer.from('j'))
32
33 t.equal(bl.length, 10)
34
35 t.equal(bl.get(0), 97)
36 t.equal(bl.get(1), 98)
37 t.equal(bl.get(2), 99)
38 t.equal(bl.get(3), 100)
39 t.equal(bl.get(4), 101)
40 t.equal(bl.get(5), 102)
41 t.equal(bl.get(6), 103)
42 t.equal(bl.get(7), 104)
43 t.equal(bl.get(8), 105)
44 t.equal(bl.get(9), 106)
45 t.end()
46})
47
48tape('multi bytes from single buffer', function (t) {
49 var bl = new BufferList()
50 bl.append(Buffer.from('abcd'))
51
52 t.equal(bl.length, 4)
53
54 t.equal(bl.slice(0, 4).toString('ascii'), 'abcd')
55 t.equal(bl.slice(0, 3).toString('ascii'), 'abc')
56 t.equal(bl.slice(1, 4).toString('ascii'), 'bcd')
57 t.equal(bl.slice(-4, -1).toString('ascii'), 'abc')
58
59 t.end()
60})
61
62tape('multi bytes from single buffer (negative indexes)', function (t) {
63 var bl = new BufferList()
64 bl.append(Buffer.from('buffer'))
65
66 t.equal(bl.length, 6)
67
68 t.equal(bl.slice(-6, -1).toString('ascii'), 'buffe')
69 t.equal(bl.slice(-6, -2).toString('ascii'), 'buff')
70 t.equal(bl.slice(-5, -2).toString('ascii'), 'uff')
71
72 t.end()
73})
74
75tape('multiple bytes from multiple buffers', function (t) {
76 var bl = new BufferList()
77
78 bl.append(Buffer.from('abcd'))
79 bl.append(Buffer.from('efg'))
80 bl.append(Buffer.from('hi'))
81 bl.append(Buffer.from('j'))
82
83 t.equal(bl.length, 10)
84
85 t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')
86 t.equal(bl.slice(3, 10).toString('ascii'), 'defghij')
87 t.equal(bl.slice(3, 6).toString('ascii'), 'def')
88 t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')
89 t.equal(bl.slice(5, 10).toString('ascii'), 'fghij')
90 t.equal(bl.slice(-7, -4).toString('ascii'), 'def')
91
92 t.end()
93})
94
95tape('multiple bytes from multiple buffer lists', function (t) {
96 var bl = new BufferList()
97
98 bl.append(new BufferList([ Buffer.from('abcd'), Buffer.from('efg') ]))
99 bl.append(new BufferList([ Buffer.from('hi'), Buffer.from('j') ]))
100
101 t.equal(bl.length, 10)
102
103 t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')
104
105 t.equal(bl.slice(3, 10).toString('ascii'), 'defghij')
106 t.equal(bl.slice(3, 6).toString('ascii'), 'def')
107 t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')
108 t.equal(bl.slice(5, 10).toString('ascii'), 'fghij')
109
110 t.end()
111})
112
113// same data as previous test, just using nested constructors
114tape('multiple bytes from crazy nested buffer lists', function (t) {
115 var bl = new BufferList()
116
117 bl.append(new BufferList([
118 new BufferList([
119 new BufferList(Buffer.from('abc'))
120 , Buffer.from('d')
121 , new BufferList(Buffer.from('efg'))
122 ])
123 , new BufferList([ Buffer.from('hi') ])
124 , new BufferList(Buffer.from('j'))
125 ]))
126
127 t.equal(bl.length, 10)
128
129 t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')
130
131 t.equal(bl.slice(3, 10).toString('ascii'), 'defghij')
132 t.equal(bl.slice(3, 6).toString('ascii'), 'def')
133 t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')
134 t.equal(bl.slice(5, 10).toString('ascii'), 'fghij')
135
136 t.end()
137})
138
139tape('append accepts arrays of Buffers', function (t) {
140 var bl = new BufferList()
141 bl.append(Buffer.from('abc'))
142 bl.append([ Buffer.from('def') ])
143 bl.append([ Buffer.from('ghi'), Buffer.from('jkl') ])
144 bl.append([ Buffer.from('mnop'), Buffer.from('qrstu'), Buffer.from('vwxyz') ])
145 t.equal(bl.length, 26)
146 t.equal(bl.slice().toString('ascii'), 'abcdefghijklmnopqrstuvwxyz')
147 t.end()
148})
149
150tape('append accepts arrays of BufferLists', function (t) {
151 var bl = new BufferList()
152 bl.append(Buffer.from('abc'))
153 bl.append([ new BufferList('def') ])
154 bl.append(new BufferList([ Buffer.from('ghi'), new BufferList('jkl') ]))
155 bl.append([ Buffer.from('mnop'), new BufferList([ Buffer.from('qrstu'), Buffer.from('vwxyz') ]) ])
156 t.equal(bl.length, 26)
157 t.equal(bl.slice().toString('ascii'), 'abcdefghijklmnopqrstuvwxyz')
158 t.end()
159})
160
161tape('append chainable', function (t) {
162 var bl = new BufferList()
163 t.ok(bl.append(Buffer.from('abcd')) === bl)
164 t.ok(bl.append([ Buffer.from('abcd') ]) === bl)
165 t.ok(bl.append(new BufferList(Buffer.from('abcd'))) === bl)
166 t.ok(bl.append([ new BufferList(Buffer.from('abcd')) ]) === bl)
167 t.end()
168})
169
170tape('append chainable (test results)', function (t) {
171 var bl = new BufferList('abc')
172 .append([ new BufferList('def') ])
173 .append(new BufferList([ Buffer.from('ghi'), new BufferList('jkl') ]))
174 .append([ Buffer.from('mnop'), new BufferList([ Buffer.from('qrstu'), Buffer.from('vwxyz') ]) ])
175
176 t.equal(bl.length, 26)
177 t.equal(bl.slice().toString('ascii'), 'abcdefghijklmnopqrstuvwxyz')
178 t.end()
179})
180
181tape('consuming from multiple buffers', function (t) {
182 var bl = new BufferList()
183
184 bl.append(Buffer.from('abcd'))
185 bl.append(Buffer.from('efg'))
186 bl.append(Buffer.from('hi'))
187 bl.append(Buffer.from('j'))
188
189 t.equal(bl.length, 10)
190
191 t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')
192
193 bl.consume(3)
194 t.equal(bl.length, 7)
195 t.equal(bl.slice(0, 7).toString('ascii'), 'defghij')
196
197 bl.consume(2)
198 t.equal(bl.length, 5)
199 t.equal(bl.slice(0, 5).toString('ascii'), 'fghij')
200
201 bl.consume(1)
202 t.equal(bl.length, 4)
203 t.equal(bl.slice(0, 4).toString('ascii'), 'ghij')
204
205 bl.consume(1)
206 t.equal(bl.length, 3)
207 t.equal(bl.slice(0, 3).toString('ascii'), 'hij')
208
209 bl.consume(2)
210 t.equal(bl.length, 1)
211 t.equal(bl.slice(0, 1).toString('ascii'), 'j')
212
213 t.end()
214})
215
216tape('complete consumption', function (t) {
217 var bl = new BufferList()
218
219 bl.append(Buffer.from('a'))
220 bl.append(Buffer.from('b'))
221
222 bl.consume(2)
223
224 t.equal(bl.length, 0)
225 t.equal(bl._bufs.length, 0)
226
227 t.end()
228})
229
230tape('test readUInt8 / readInt8', function (t) {
231 var buf1 = Buffer.alloc(1)
232 , buf2 = Buffer.alloc(3)
233 , buf3 = Buffer.alloc(3)
234 , bl = new BufferList()
235
236 buf2[1] = 0x3
237 buf2[2] = 0x4
238 buf3[0] = 0x23
239 buf3[1] = 0x42
240
241 bl.append(buf1)
242 bl.append(buf2)
243 bl.append(buf3)
244
245 t.equal(bl.readUInt8(2), 0x3)
246 t.equal(bl.readInt8(2), 0x3)
247 t.equal(bl.readUInt8(3), 0x4)
248 t.equal(bl.readInt8(3), 0x4)
249 t.equal(bl.readUInt8(4), 0x23)
250 t.equal(bl.readInt8(4), 0x23)
251 t.equal(bl.readUInt8(5), 0x42)
252 t.equal(bl.readInt8(5), 0x42)
253 t.end()
254})
255
256tape('test readUInt16LE / readUInt16BE / readInt16LE / readInt16BE', function (t) {
257 var buf1 = Buffer.alloc(1)
258 , buf2 = Buffer.alloc(3)
259 , buf3 = Buffer.alloc(3)
260 , bl = new BufferList()
261
262 buf2[1] = 0x3
263 buf2[2] = 0x4
264 buf3[0] = 0x23
265 buf3[1] = 0x42
266
267 bl.append(buf1)
268 bl.append(buf2)
269 bl.append(buf3)
270
271 t.equal(bl.readUInt16BE(2), 0x0304)
272 t.equal(bl.readUInt16LE(2), 0x0403)
273 t.equal(bl.readInt16BE(2), 0x0304)
274 t.equal(bl.readInt16LE(2), 0x0403)
275 t.equal(bl.readUInt16BE(3), 0x0423)
276 t.equal(bl.readUInt16LE(3), 0x2304)
277 t.equal(bl.readInt16BE(3), 0x0423)
278 t.equal(bl.readInt16LE(3), 0x2304)
279 t.equal(bl.readUInt16BE(4), 0x2342)
280 t.equal(bl.readUInt16LE(4), 0x4223)
281 t.equal(bl.readInt16BE(4), 0x2342)
282 t.equal(bl.readInt16LE(4), 0x4223)
283 t.end()
284})
285
286tape('test readUInt32LE / readUInt32BE / readInt32LE / readInt32BE', function (t) {
287 var buf1 = Buffer.alloc(1)
288 , buf2 = Buffer.alloc(3)
289 , buf3 = Buffer.alloc(3)
290 , bl = new BufferList()
291
292 buf2[1] = 0x3
293 buf2[2] = 0x4
294 buf3[0] = 0x23
295 buf3[1] = 0x42
296
297 bl.append(buf1)
298 bl.append(buf2)
299 bl.append(buf3)
300
301 t.equal(bl.readUInt32BE(2), 0x03042342)
302 t.equal(bl.readUInt32LE(2), 0x42230403)
303 t.equal(bl.readInt32BE(2), 0x03042342)
304 t.equal(bl.readInt32LE(2), 0x42230403)
305 t.end()
306})
307
308tape('test readFloatLE / readFloatBE', function (t) {
309 var buf1 = Buffer.alloc(1)
310 , buf2 = Buffer.alloc(3)
311 , buf3 = Buffer.alloc(3)
312 , bl = new BufferList()
313
314 buf2[1] = 0x00
315 buf2[2] = 0x00
316 buf3[0] = 0x80
317 buf3[1] = 0x3f
318
319 bl.append(buf1)
320 bl.append(buf2)
321 bl.append(buf3)
322
323 t.equal(bl.readFloatLE(2), 0x01)
324 t.end()
325})
326
327tape('test readDoubleLE / readDoubleBE', function (t) {
328 var buf1 = Buffer.alloc(1)
329 , buf2 = Buffer.alloc(3)
330 , buf3 = Buffer.alloc(10)
331 , bl = new BufferList()
332
333 buf2[1] = 0x55
334 buf2[2] = 0x55
335 buf3[0] = 0x55
336 buf3[1] = 0x55
337 buf3[2] = 0x55
338 buf3[3] = 0x55
339 buf3[4] = 0xd5
340 buf3[5] = 0x3f
341
342 bl.append(buf1)
343 bl.append(buf2)
344 bl.append(buf3)
345
346 t.equal(bl.readDoubleLE(2), 0.3333333333333333)
347 t.end()
348})
349
350tape('test toString', function (t) {
351 var bl = new BufferList()
352
353 bl.append(Buffer.from('abcd'))
354 bl.append(Buffer.from('efg'))
355 bl.append(Buffer.from('hi'))
356 bl.append(Buffer.from('j'))
357
358 t.equal(bl.toString('ascii', 0, 10), 'abcdefghij')
359 t.equal(bl.toString('ascii', 3, 10), 'defghij')
360 t.equal(bl.toString('ascii', 3, 6), 'def')
361 t.equal(bl.toString('ascii', 3, 8), 'defgh')
362 t.equal(bl.toString('ascii', 5, 10), 'fghij')
363
364 t.end()
365})
366
367tape('test toString encoding', function (t) {
368 var bl = new BufferList()
369 , b = Buffer.from('abcdefghij\xff\x00')
370
371 bl.append(Buffer.from('abcd'))
372 bl.append(Buffer.from('efg'))
373 bl.append(Buffer.from('hi'))
374 bl.append(Buffer.from('j'))
375 bl.append(Buffer.from('\xff\x00'))
376
377 encodings.forEach(function (enc) {
378 t.equal(bl.toString(enc), b.toString(enc), enc)
379 })
380
381 t.end()
382})
383
384tape('uninitialized memory', function (t) {
385 const secret = crypto.randomBytes(256)
386 for (let i = 0; i < 1e6; i++) {
387 const clone = Buffer.from(secret)
388 const bl = new BufferList()
389 bl.append(Buffer.from('a'))
390 bl.consume(-1024)
391 const buf = bl.slice(1)
392 if (buf.indexOf(clone) !== -1) {
393 t.fail(`Match (at ${i})`)
394 break
395 }
396 }
397 t.end()
398})
399
400!process.browser && tape('test stream', function (t) {
401 var random = crypto.randomBytes(65534)
402 , rndhash = hash(random, 'md5')
403 , md5sum = crypto.createHash('md5')
404 , bl = new BufferList(function (err, buf) {
405 t.ok(Buffer.isBuffer(buf))
406 t.ok(err === null)
407 t.equal(rndhash, hash(bl.slice(), 'md5'))
408 t.equal(rndhash, hash(buf, 'md5'))
409
410 bl.pipe(fs.createWriteStream('/tmp/bl_test_rnd_out.dat'))
411 .on('close', function () {
412 var s = fs.createReadStream('/tmp/bl_test_rnd_out.dat')
413 s.on('data', md5sum.update.bind(md5sum))
414 s.on('end', function() {
415 t.equal(rndhash, md5sum.digest('hex'), 'woohoo! correct hash!')
416 t.end()
417 })
418 })
419
420 })
421
422 fs.writeFileSync('/tmp/bl_test_rnd.dat', random)
423 fs.createReadStream('/tmp/bl_test_rnd.dat').pipe(bl)
424})
425
426tape('instantiation with Buffer', function (t) {
427 var buf = crypto.randomBytes(1024)
428 , buf2 = crypto.randomBytes(1024)
429 , b = BufferList(buf)
430
431 t.equal(buf.toString('hex'), b.slice().toString('hex'), 'same buffer')
432 b = BufferList([ buf, buf2 ])
433 t.equal(b.slice().toString('hex'), Buffer.concat([ buf, buf2 ]).toString('hex'), 'same buffer')
434 t.end()
435})
436
437tape('test String appendage', function (t) {
438 var bl = new BufferList()
439 , b = Buffer.from('abcdefghij\xff\x00')
440
441 bl.append('abcd')
442 bl.append('efg')
443 bl.append('hi')
444 bl.append('j')
445 bl.append('\xff\x00')
446
447 encodings.forEach(function (enc) {
448 t.equal(bl.toString(enc), b.toString(enc))
449 })
450
451 t.end()
452})
453
454tape('test Number appendage', function (t) {
455 var bl = new BufferList()
456 , b = Buffer.from('1234567890')
457
458 bl.append(1234)
459 bl.append(567)
460 bl.append(89)
461 bl.append(0)
462
463 encodings.forEach(function (enc) {
464 t.equal(bl.toString(enc), b.toString(enc))
465 })
466
467 t.end()
468})
469
470tape('write nothing, should get empty buffer', function (t) {
471 t.plan(3)
472 BufferList(function (err, data) {
473 t.notOk(err, 'no error')
474 t.ok(Buffer.isBuffer(data), 'got a buffer')
475 t.equal(0, data.length, 'got a zero-length buffer')
476 t.end()
477 }).end()
478})
479
480tape('unicode string', function (t) {
481 t.plan(2)
482 var inp1 = '\u2600'
483 , inp2 = '\u2603'
484 , exp = inp1 + ' and ' + inp2
485 , bl = BufferList()
486 bl.write(inp1)
487 bl.write(' and ')
488 bl.write(inp2)
489 t.equal(exp, bl.toString())
490 t.equal(Buffer.from(exp).toString('hex'), bl.toString('hex'))
491})
492
493tape('should emit finish', function (t) {
494 var source = BufferList()
495 , dest = BufferList()
496
497 source.write('hello')
498 source.pipe(dest)
499
500 dest.on('finish', function () {
501 t.equal(dest.toString('utf8'), 'hello')
502 t.end()
503 })
504})
505
506tape('basic copy', function (t) {
507 var buf = crypto.randomBytes(1024)
508 , buf2 = Buffer.alloc(1024)
509 , b = BufferList(buf)
510
511 b.copy(buf2)
512 t.equal(b.slice().toString('hex'), buf2.toString('hex'), 'same buffer')
513 t.end()
514})
515
516tape('copy after many appends', function (t) {
517 var buf = crypto.randomBytes(512)
518 , buf2 = Buffer.alloc(1024)
519 , b = BufferList(buf)
520
521 b.append(buf)
522 b.copy(buf2)
523 t.equal(b.slice().toString('hex'), buf2.toString('hex'), 'same buffer')
524 t.end()
525})
526
527tape('copy at a precise position', function (t) {
528 var buf = crypto.randomBytes(1004)
529 , buf2 = Buffer.alloc(1024)
530 , b = BufferList(buf)
531
532 b.copy(buf2, 20)
533 t.equal(b.slice().toString('hex'), buf2.slice(20).toString('hex'), 'same buffer')
534 t.end()
535})
536
537tape('copy starting from a precise location', function (t) {
538 var buf = crypto.randomBytes(10)
539 , buf2 = Buffer.alloc(5)
540 , b = BufferList(buf)
541
542 b.copy(buf2, 0, 5)
543 t.equal(b.slice(5).toString('hex'), buf2.toString('hex'), 'same buffer')
544 t.end()
545})
546
547tape('copy in an interval', function (t) {
548 var rnd = crypto.randomBytes(10)
549 , b = BufferList(rnd) // put the random bytes there
550 , actual = Buffer.alloc(3)
551 , expected = Buffer.alloc(3)
552
553 rnd.copy(expected, 0, 5, 8)
554 b.copy(actual, 0, 5, 8)
555
556 t.equal(actual.toString('hex'), expected.toString('hex'), 'same buffer')
557 t.end()
558})
559
560tape('copy an interval between two buffers', function (t) {
561 var buf = crypto.randomBytes(10)
562 , buf2 = Buffer.alloc(10)
563 , b = BufferList(buf)
564
565 b.append(buf)
566 b.copy(buf2, 0, 5, 15)
567
568 t.equal(b.slice(5, 15).toString('hex'), buf2.toString('hex'), 'same buffer')
569 t.end()
570})
571
572tape('shallow slice across buffer boundaries', function (t) {
573 var bl = new BufferList(['First', 'Second', 'Third'])
574
575 t.equal(bl.shallowSlice(3, 13).toString(), 'stSecondTh')
576 t.end()
577})
578
579tape('shallow slice within single buffer', function (t) {
580 t.plan(2)
581 var bl = new BufferList(['First', 'Second', 'Third'])
582
583 t.equal(bl.shallowSlice(5, 10).toString(), 'Secon')
584 t.equal(bl.shallowSlice(7, 10).toString(), 'con')
585 t.end()
586})
587
588tape('shallow slice single buffer', function (t) {
589 t.plan(3)
590 var bl = new BufferList(['First', 'Second', 'Third'])
591
592 t.equal(bl.shallowSlice(0, 5).toString(), 'First')
593 t.equal(bl.shallowSlice(5, 11).toString(), 'Second')
594 t.equal(bl.shallowSlice(11, 16).toString(), 'Third')
595})
596
597tape('shallow slice with negative or omitted indices', function (t) {
598 t.plan(4)
599 var bl = new BufferList(['First', 'Second', 'Third'])
600
601 t.equal(bl.shallowSlice().toString(), 'FirstSecondThird')
602 t.equal(bl.shallowSlice(5).toString(), 'SecondThird')
603 t.equal(bl.shallowSlice(5, -3).toString(), 'SecondTh')
604 t.equal(bl.shallowSlice(-8).toString(), 'ondThird')
605})
606
607tape('shallow slice does not make a copy', function (t) {
608 t.plan(1)
609 var buffers = [Buffer.from('First'), Buffer.from('Second'), Buffer.from('Third')]
610 var bl = (new BufferList(buffers)).shallowSlice(5, -3)
611
612 buffers[1].fill('h')
613 buffers[2].fill('h')
614
615 t.equal(bl.toString(), 'hhhhhhhh')
616})
617
618tape('duplicate', function (t) {
619 t.plan(2)
620
621 var bl = new BufferList('abcdefghij\xff\x00')
622 , dup = bl.duplicate()
623
624 t.equal(bl.prototype, dup.prototype)
625 t.equal(bl.toString('hex'), dup.toString('hex'))
626})
627
628tape('destroy no pipe', function (t) {
629 t.plan(2)
630
631 var bl = new BufferList('alsdkfja;lsdkfja;lsdk')
632 bl.destroy()
633
634 t.equal(bl._bufs.length, 0)
635 t.equal(bl.length, 0)
636})
637
638!process.browser && tape('destroy with pipe before read end', function (t) {
639 t.plan(2)
640
641 var bl = new BufferList()
642 fs.createReadStream(__dirname + '/test.js')
643 .pipe(bl)
644
645 bl.destroy()
646
647 t.equal(bl._bufs.length, 0)
648 t.equal(bl.length, 0)
649
650})
651
652!process.browser && tape('destroy with pipe before read end with race', function (t) {
653 t.plan(2)
654
655 var bl = new BufferList()
656 fs.createReadStream(__dirname + '/test.js')
657 .pipe(bl)
658
659 setTimeout(function () {
660 bl.destroy()
661 setTimeout(function () {
662 t.equal(bl._bufs.length, 0)
663 t.equal(bl.length, 0)
664 }, 500)
665 }, 500)
666})
667
668!process.browser && tape('destroy with pipe after read end', function (t) {
669 t.plan(2)
670
671 var bl = new BufferList()
672 fs.createReadStream(__dirname + '/test.js')
673 .on('end', onEnd)
674 .pipe(bl)
675
676 function onEnd () {
677 bl.destroy()
678
679 t.equal(bl._bufs.length, 0)
680 t.equal(bl.length, 0)
681 }
682})
683
684!process.browser && tape('destroy with pipe while writing to a destination', function (t) {
685 t.plan(4)
686
687 var bl = new BufferList()
688 , ds = new BufferList()
689
690 fs.createReadStream(__dirname + '/test.js')
691 .on('end', onEnd)
692 .pipe(bl)
693
694 function onEnd () {
695 bl.pipe(ds)
696
697 setTimeout(function () {
698 bl.destroy()
699
700 t.equals(bl._bufs.length, 0)
701 t.equals(bl.length, 0)
702
703 ds.destroy()
704
705 t.equals(bl._bufs.length, 0)
706 t.equals(bl.length, 0)
707
708 }, 100)
709 }
710})
711
712!process.browser && tape('handle error', function (t) {
713 t.plan(2)
714 fs.createReadStream('/does/not/exist').pipe(BufferList(function (err, data) {
715 t.ok(err instanceof Error, 'has error')
716 t.notOk(data, 'no data')
717 }))
718})