AK-21/Graphite-Industrial-Intelligence
0
1'use strict'2 3const tape = require('tape')4const crypto = require('crypto')5const fs = require('fs')6const path = require('path')7const BufferList = require('../')8const { Buffer } = require('buffer')9 10const encodings =11 ('hex utf8 utf-8 ascii binary base64' +12 (process.browser ? '' : ' ucs2 ucs-2 utf16le utf-16le')).split(' ')13 14require('./indexOf')15require('./isBufferList')16require('./convert')17 18tape('single bytes from single buffer', function (t) {19 const bl = new BufferList()20 21 bl.append(Buffer.from('abcd'))22 23 t.equal(bl.length, 4)24 t.equal(bl.get(-1), undefined)25 t.equal(bl.get(0), 97)26 t.equal(bl.get(1), 98)27 t.equal(bl.get(2), 99)28 t.equal(bl.get(3), 100)29 t.equal(bl.get(4), undefined)30 31 t.end()32})33 34tape('single bytes from multiple buffers', function (t) {35 const bl = new BufferList()36 37 bl.append(Buffer.from('abcd'))38 bl.append(Buffer.from('efg'))39 bl.append(Buffer.from('hi'))40 bl.append(Buffer.from('j'))41 42 t.equal(bl.length, 10)43 44 t.equal(bl.get(0), 97)45 t.equal(bl.get(1), 98)46 t.equal(bl.get(2), 99)47 t.equal(bl.get(3), 100)48 t.equal(bl.get(4), 101)49 t.equal(bl.get(5), 102)50 t.equal(bl.get(6), 103)51 t.equal(bl.get(7), 104)52 t.equal(bl.get(8), 105)53 t.equal(bl.get(9), 106)54 55 t.end()56})57 58tape('multi bytes from single buffer', function (t) {59 const bl = new BufferList()60 61 bl.append(Buffer.from('abcd'))62 63 t.equal(bl.length, 4)64 65 t.equal(bl.slice(0, 4).toString('ascii'), 'abcd')66 t.equal(bl.slice(0, 3).toString('ascii'), 'abc')67 t.equal(bl.slice(1, 4).toString('ascii'), 'bcd')68 t.equal(bl.slice(-4, -1).toString('ascii'), 'abc')69 70 t.end()71})72 73tape('multi bytes from single buffer (negative indexes)', function (t) {74 const bl = new BufferList()75 76 bl.append(Buffer.from('buffer'))77 78 t.equal(bl.length, 6)79 80 t.equal(bl.slice(-6, -1).toString('ascii'), 'buffe')81 t.equal(bl.slice(-6, -2).toString('ascii'), 'buff')82 t.equal(bl.slice(-5, -2).toString('ascii'), 'uff')83 84 t.end()85})86 87tape('multiple bytes from multiple buffers', function (t) {88 const bl = new BufferList()89 90 bl.append(Buffer.from('abcd'))91 bl.append(Buffer.from('efg'))92 bl.append(Buffer.from('hi'))93 bl.append(Buffer.from('j'))94 95 t.equal(bl.length, 10)96 97 t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')98 t.equal(bl.slice(3, 10).toString('ascii'), 'defghij')99 t.equal(bl.slice(3, 6).toString('ascii'), 'def')100 t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')101 t.equal(bl.slice(5, 10).toString('ascii'), 'fghij')102 t.equal(bl.slice(-7, -4).toString('ascii'), 'def')103 104 t.end()105})106 107tape('multiple bytes from multiple buffer lists', function (t) {108 const bl = new BufferList()109 110 bl.append(new BufferList([Buffer.from('abcd'), Buffer.from('efg')]))111 bl.append(new BufferList([Buffer.from('hi'), Buffer.from('j')]))112 113 t.equal(bl.length, 10)114 115 t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')116 117 t.equal(bl.slice(3, 10).toString('ascii'), 'defghij')118 t.equal(bl.slice(3, 6).toString('ascii'), 'def')119 t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')120 t.equal(bl.slice(5, 10).toString('ascii'), 'fghij')121 122 t.end()123})124 125// same data as previous test, just using nested constructors126tape('multiple bytes from crazy nested buffer lists', function (t) {127 const bl = new BufferList()128 129 bl.append(new BufferList([130 new BufferList([131 new BufferList(Buffer.from('abc')),132 Buffer.from('d'),133 new BufferList(Buffer.from('efg'))134 ]),135 new BufferList([Buffer.from('hi')]),136 new BufferList(Buffer.from('j'))137 ]))138 139 t.equal(bl.length, 10)140 141 t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')142 143 t.equal(bl.slice(3, 10).toString('ascii'), 'defghij')144 t.equal(bl.slice(3, 6).toString('ascii'), 'def')145 t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')146 t.equal(bl.slice(5, 10).toString('ascii'), 'fghij')147 148 t.end()149})150 151tape('append accepts arrays of Buffers', function (t) {152 const bl = new BufferList()153 154 bl.append(Buffer.from('abc'))155 bl.append([Buffer.from('def')])156 bl.append([Buffer.from('ghi'), Buffer.from('jkl')])157 bl.append([Buffer.from('mnop'), Buffer.from('qrstu'), Buffer.from('vwxyz')])158 t.equal(bl.length, 26)159 t.equal(bl.slice().toString('ascii'), 'abcdefghijklmnopqrstuvwxyz')160 161 t.end()162})163 164tape('append accepts arrays of Uint8Arrays', function (t) {165 const bl = new BufferList()166 167 bl.append(new Uint8Array([97, 98, 99]))168 bl.append([Uint8Array.from([100, 101, 102])])169 bl.append([new Uint8Array([103, 104, 105]), new Uint8Array([106, 107, 108])])170 bl.append([new Uint8Array([109, 110, 111, 112]), new Uint8Array([113, 114, 115, 116, 117]), new Uint8Array([118, 119, 120, 121, 122])])171 t.equal(bl.length, 26)172 t.equal(bl.slice().toString('ascii'), 'abcdefghijklmnopqrstuvwxyz')173 174 t.end()175})176 177tape('append accepts arrays of BufferLists', function (t) {178 const bl = new BufferList()179 180 bl.append(Buffer.from('abc'))181 bl.append([new BufferList('def')])182 bl.append(new BufferList([Buffer.from('ghi'), new BufferList('jkl')]))183 bl.append([Buffer.from('mnop'), new BufferList([Buffer.from('qrstu'), Buffer.from('vwxyz')])])184 t.equal(bl.length, 26)185 t.equal(bl.slice().toString('ascii'), 'abcdefghijklmnopqrstuvwxyz')186 187 t.end()188})189 190tape('append chainable', function (t) {191 const bl = new BufferList()192 193 t.ok(bl.append(Buffer.from('abcd')) === bl)194 t.ok(bl.append([Buffer.from('abcd')]) === bl)195 t.ok(bl.append(new BufferList(Buffer.from('abcd'))) === bl)196 t.ok(bl.append([new BufferList(Buffer.from('abcd'))]) === bl)197 198 t.end()199})200 201tape('append chainable (test results)', function (t) {202 const bl = new BufferList('abc')203 .append([new BufferList('def')])204 .append(new BufferList([Buffer.from('ghi'), new BufferList('jkl')]))205 .append([Buffer.from('mnop'), new BufferList([Buffer.from('qrstu'), Buffer.from('vwxyz')])])206 207 t.equal(bl.length, 26)208 t.equal(bl.slice().toString('ascii'), 'abcdefghijklmnopqrstuvwxyz')209 210 t.end()211})212 213tape('consuming from multiple buffers', function (t) {214 const bl = new BufferList()215 216 bl.append(Buffer.from('abcd'))217 bl.append(Buffer.from('efg'))218 bl.append(Buffer.from('hi'))219 bl.append(Buffer.from('j'))220 221 t.equal(bl.length, 10)222 223 t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')224 225 bl.consume(3)226 t.equal(bl.length, 7)227 t.equal(bl.slice(0, 7).toString('ascii'), 'defghij')228 229 bl.consume(2)230 t.equal(bl.length, 5)231 t.equal(bl.slice(0, 5).toString('ascii'), 'fghij')232 233 bl.consume(1)234 t.equal(bl.length, 4)235 t.equal(bl.slice(0, 4).toString('ascii'), 'ghij')236 237 bl.consume(1)238 t.equal(bl.length, 3)239 t.equal(bl.slice(0, 3).toString('ascii'), 'hij')240 241 bl.consume(2)242 t.equal(bl.length, 1)243 t.equal(bl.slice(0, 1).toString('ascii'), 'j')244 245 t.end()246})247 248tape('complete consumption', function (t) {249 const bl = new BufferList()250 251 bl.append(Buffer.from('a'))252 bl.append(Buffer.from('b'))253 254 bl.consume(2)255 256 t.equal(bl.length, 0)257 t.equal(bl._bufs.length, 0)258 259 t.end()260})261 262tape('test readUInt8 / readInt8', function (t) {263 const buf1 = Buffer.alloc(1)264 const buf2 = Buffer.alloc(3)265 const buf3 = Buffer.alloc(3)266 const bl = new BufferList()267 268 buf1[0] = 0x1269 buf2[1] = 0x3270 buf2[2] = 0x4271 buf3[0] = 0x23272 buf3[1] = 0x42273 274 bl.append(buf1)275 bl.append(buf2)276 bl.append(buf3)277 278 t.equal(bl.readUInt8(), 0x1)279 t.equal(bl.readUInt8(2), 0x3)280 t.equal(bl.readInt8(2), 0x3)281 t.equal(bl.readUInt8(3), 0x4)282 t.equal(bl.readInt8(3), 0x4)283 t.equal(bl.readUInt8(4), 0x23)284 t.equal(bl.readInt8(4), 0x23)285 t.equal(bl.readUInt8(5), 0x42)286 t.equal(bl.readInt8(5), 0x42)287 288 t.end()289})290 291tape('test readUInt16LE / readUInt16BE / readInt16LE / readInt16BE', function (t) {292 const buf1 = Buffer.alloc(1)293 const buf2 = Buffer.alloc(3)294 const buf3 = Buffer.alloc(3)295 const bl = new BufferList()296 297 buf1[0] = 0x1298 buf2[1] = 0x3299 buf2[2] = 0x4300 buf3[0] = 0x23301 buf3[1] = 0x42302 303 bl.append(buf1)304 bl.append(buf2)305 bl.append(buf3)306 307 t.equal(bl.readUInt16BE(), 0x0100)308 t.equal(bl.readUInt16LE(), 0x0001)309 t.equal(bl.readUInt16BE(2), 0x0304)310 t.equal(bl.readUInt16LE(2), 0x0403)311 t.equal(bl.readInt16BE(2), 0x0304)312 t.equal(bl.readInt16LE(2), 0x0403)313 t.equal(bl.readUInt16BE(3), 0x0423)314 t.equal(bl.readUInt16LE(3), 0x2304)315 t.equal(bl.readInt16BE(3), 0x0423)316 t.equal(bl.readInt16LE(3), 0x2304)317 t.equal(bl.readUInt16BE(4), 0x2342)318 t.equal(bl.readUInt16LE(4), 0x4223)319 t.equal(bl.readInt16BE(4), 0x2342)320 t.equal(bl.readInt16LE(4), 0x4223)321 322 t.end()323})324 325tape('test readUInt32LE / readUInt32BE / readInt32LE / readInt32BE', function (t) {326 const buf1 = Buffer.alloc(1)327 const buf2 = Buffer.alloc(3)328 const buf3 = Buffer.alloc(3)329 const bl = new BufferList()330 331 buf1[0] = 0x1332 buf2[1] = 0x3333 buf2[2] = 0x4334 buf3[0] = 0x23335 buf3[1] = 0x42336 337 bl.append(buf1)338 bl.append(buf2)339 bl.append(buf3)340 341 t.equal(bl.readUInt32BE(), 0x01000304)342 t.equal(bl.readUInt32LE(), 0x04030001)343 t.equal(bl.readUInt32BE(2), 0x03042342)344 t.equal(bl.readUInt32LE(2), 0x42230403)345 t.equal(bl.readInt32BE(2), 0x03042342)346 t.equal(bl.readInt32LE(2), 0x42230403)347 348 t.end()349})350 351tape('test readUIntLE / readUIntBE / readIntLE / readIntBE', function (t) {352 const buf1 = Buffer.alloc(1)353 const buf2 = Buffer.alloc(3)354 const buf3 = Buffer.alloc(3)355 const bl = new BufferList()356 357 buf2[0] = 0x2358 buf2[1] = 0x3359 buf2[2] = 0x4360 buf3[0] = 0x23361 buf3[1] = 0x42362 buf3[2] = 0x61363 364 bl.append(buf1)365 bl.append(buf2)366 bl.append(buf3)367 368 t.equal(bl.readUIntBE(1, 1), 0x02)369 t.equal(bl.readUIntBE(1, 2), 0x0203)370 t.equal(bl.readUIntBE(1, 3), 0x020304)371 t.equal(bl.readUIntBE(1, 4), 0x02030423)372 t.equal(bl.readUIntBE(1, 5), 0x0203042342)373 t.equal(bl.readUIntBE(1, 6), 0x020304234261)374 t.equal(bl.readUIntLE(1, 1), 0x02)375 t.equal(bl.readUIntLE(1, 2), 0x0302)376 t.equal(bl.readUIntLE(1, 3), 0x040302)377 t.equal(bl.readUIntLE(1, 4), 0x23040302)378 t.equal(bl.readUIntLE(1, 5), 0x4223040302)379 t.equal(bl.readUIntLE(1, 6), 0x614223040302)380 t.equal(bl.readIntBE(1, 1), 0x02)381 t.equal(bl.readIntBE(1, 2), 0x0203)382 t.equal(bl.readIntBE(1, 3), 0x020304)383 t.equal(bl.readIntBE(1, 4), 0x02030423)384 t.equal(bl.readIntBE(1, 5), 0x0203042342)385 t.equal(bl.readIntBE(1, 6), 0x020304234261)386 t.equal(bl.readIntLE(1, 1), 0x02)387 t.equal(bl.readIntLE(1, 2), 0x0302)388 t.equal(bl.readIntLE(1, 3), 0x040302)389 t.equal(bl.readIntLE(1, 4), 0x23040302)390 t.equal(bl.readIntLE(1, 5), 0x4223040302)391 t.equal(bl.readIntLE(1, 6), 0x614223040302)392 393 t.end()394})395 396tape('test readFloatLE / readFloatBE', function (t) {397 const buf1 = Buffer.alloc(1)398 const buf2 = Buffer.alloc(3)399 const buf3 = Buffer.alloc(3)400 const bl = new BufferList()401 402 buf1[0] = 0x01403 buf2[1] = 0x00404 buf2[2] = 0x00405 buf3[0] = 0x80406 buf3[1] = 0x3f407 408 bl.append(buf1)409 bl.append(buf2)410 bl.append(buf3)411 412 const canonical = Buffer.concat([buf1, buf2, buf3])413 t.equal(bl.readFloatLE(), canonical.readFloatLE())414 t.equal(bl.readFloatBE(), canonical.readFloatBE())415 t.equal(bl.readFloatLE(2), canonical.readFloatLE(2))416 t.equal(bl.readFloatBE(2), canonical.readFloatBE(2))417 418 t.end()419})420 421tape('test readDoubleLE / readDoubleBE', function (t) {422 const buf1 = Buffer.alloc(1)423 const buf2 = Buffer.alloc(3)424 const buf3 = Buffer.alloc(10)425 const bl = new BufferList()426 427 buf1[0] = 0x01428 buf2[1] = 0x55429 buf2[2] = 0x55430 buf3[0] = 0x55431 buf3[1] = 0x55432 buf3[2] = 0x55433 buf3[3] = 0x55434 buf3[4] = 0xd5435 buf3[5] = 0x3f436 437 bl.append(buf1)438 bl.append(buf2)439 bl.append(buf3)440 441 const canonical = Buffer.concat([buf1, buf2, buf3])442 t.equal(bl.readDoubleBE(), canonical.readDoubleBE())443 t.equal(bl.readDoubleLE(), canonical.readDoubleLE())444 t.equal(bl.readDoubleBE(2), canonical.readDoubleBE(2))445 t.equal(bl.readDoubleLE(2), canonical.readDoubleLE(2))446 447 t.end()448})449 450tape('test toString', function (t) {451 const bl = new BufferList()452 453 bl.append(Buffer.from('abcd'))454 bl.append(Buffer.from('efg'))455 bl.append(Buffer.from('hi'))456 bl.append(Buffer.from('j'))457 458 t.equal(bl.toString('ascii', 0, 10), 'abcdefghij')459 t.equal(bl.toString('ascii', 3, 10), 'defghij')460 t.equal(bl.toString('ascii', 3, 6), 'def')461 t.equal(bl.toString('ascii', 3, 8), 'defgh')462 t.equal(bl.toString('ascii', 5, 10), 'fghij')463 464 t.end()465})466 467tape('test toString encoding', function (t) {468 const bl = new BufferList()469 const b = Buffer.from('abcdefghij\xff\x00')470 471 bl.append(Buffer.from('abcd'))472 bl.append(Buffer.from('efg'))473 bl.append(Buffer.from('hi'))474 bl.append(Buffer.from('j'))475 bl.append(Buffer.from('\xff\x00'))476 477 encodings.forEach(function (enc) {478 t.equal(bl.toString(enc), b.toString(enc), enc)479 })480 481 t.end()482})483 484tape('uninitialized memory', function (t) {485 const secret = crypto.randomBytes(256)486 for (let i = 0; i < 1e6; i++) {487 const clone = Buffer.from(secret)488 const bl = new BufferList()489 bl.append(Buffer.from('a'))490 bl.consume(-1024)491 const buf = bl.slice(1)492 if (buf.indexOf(clone) !== -1) {493 t.fail(`Match (at ${i})`)494 break495 }496 }497 t.end()498})499 500!process.browser && tape('test stream', function (t) {501 const random = crypto.randomBytes(65534)502 503 const bl = new BufferList((err, buf) => {504 t.ok(Buffer.isBuffer(buf))505 t.ok(err === null)506 t.ok(random.equals(bl.slice()))507 t.ok(random.equals(buf.slice()))508 509 bl.pipe(fs.createWriteStream('/tmp/bl_test_rnd_out.dat'))510 .on('close', function () {511 const rndhash = crypto.createHash('md5').update(random).digest('hex')512 const md5sum = crypto.createHash('md5')513 const s = fs.createReadStream('/tmp/bl_test_rnd_out.dat')514 515 s.on('data', md5sum.update.bind(md5sum))516 s.on('end', function () {517 t.equal(rndhash, md5sum.digest('hex'), 'woohoo! correct hash!')518 t.end()519 })520 })521 })522 523 fs.writeFileSync('/tmp/bl_test_rnd.dat', random)524 fs.createReadStream('/tmp/bl_test_rnd.dat').pipe(bl)525})526 527tape('instantiation with Buffer', function (t) {528 const buf = crypto.randomBytes(1024)529 const buf2 = crypto.randomBytes(1024)530 let b = BufferList(buf)531 532 t.equal(buf.toString('hex'), b.slice().toString('hex'), 'same buffer')533 b = BufferList([buf, buf2])534 t.equal(b.slice().toString('hex'), Buffer.concat([buf, buf2]).toString('hex'), 'same buffer')535 536 t.end()537})538 539tape('test String appendage', function (t) {540 const bl = new BufferList()541 const b = Buffer.from('abcdefghij\xff\x00')542 543 bl.append('abcd')544 bl.append('efg')545 bl.append('hi')546 bl.append('j')547 bl.append('\xff\x00')548 549 encodings.forEach(function (enc) {550 t.equal(bl.toString(enc), b.toString(enc))551 })552 553 t.end()554})555 556tape('test Number appendage', function (t) {557 const bl = new BufferList()558 const b = Buffer.from('1234567890')559 560 bl.append(1234)561 bl.append(567)562 bl.append(89)563 bl.append(0)564 565 encodings.forEach(function (enc) {566 t.equal(bl.toString(enc), b.toString(enc))567 })568 569 t.end()570})571 572tape('write nothing, should get empty buffer', function (t) {573 t.plan(3)574 BufferList(function (err, data) {575 t.notOk(err, 'no error')576 t.ok(Buffer.isBuffer(data), 'got a buffer')577 t.equal(0, data.length, 'got a zero-length buffer')578 t.end()579 }).end()580})581 582tape('unicode string', function (t) {583 t.plan(2)584 585 const inp1 = '\u2600'586 const inp2 = '\u2603'587 const exp = inp1 + ' and ' + inp2588 const bl = BufferList()589 590 bl.write(inp1)591 bl.write(' and ')592 bl.write(inp2)593 t.equal(exp, bl.toString())594 t.equal(Buffer.from(exp).toString('hex'), bl.toString('hex'))595})596 597tape('should emit finish', function (t) {598 const source = BufferList()599 const dest = BufferList()600 601 source.write('hello')602 source.pipe(dest)603 604 dest.on('finish', function () {605 t.equal(dest.toString('utf8'), 'hello')606 t.end()607 })608})609 610tape('basic copy', function (t) {611 const buf = crypto.randomBytes(1024)612 const buf2 = Buffer.alloc(1024)613 const b = BufferList(buf)614 615 b.copy(buf2)616 t.equal(b.slice().toString('hex'), buf2.toString('hex'), 'same buffer')617 618 t.end()619})620 621tape('copy after many appends', function (t) {622 const buf = crypto.randomBytes(512)623 const buf2 = Buffer.alloc(1024)624 const b = BufferList(buf)625 626 b.append(buf)627 b.copy(buf2)628 t.equal(b.slice().toString('hex'), buf2.toString('hex'), 'same buffer')629 630 t.end()631})632 633tape('copy at a precise position', function (t) {634 const buf = crypto.randomBytes(1004)635 const buf2 = Buffer.alloc(1024)636 const b = BufferList(buf)637 638 b.copy(buf2, 20)639 t.equal(b.slice().toString('hex'), buf2.slice(20).toString('hex'), 'same buffer')640 641 t.end()642})643 644tape('copy starting from a precise location', function (t) {645 const buf = crypto.randomBytes(10)646 const buf2 = Buffer.alloc(5)647 const b = BufferList(buf)648 649 b.copy(buf2, 0, 5)650 t.equal(b.slice(5).toString('hex'), buf2.toString('hex'), 'same buffer')651 652 t.end()653})654 655tape('copy in an interval', function (t) {656 const rnd = crypto.randomBytes(10)657 const b = BufferList(rnd) // put the random bytes there658 const actual = Buffer.alloc(3)659 const expected = Buffer.alloc(3)660 661 rnd.copy(expected, 0, 5, 8)662 b.copy(actual, 0, 5, 8)663 664 t.equal(actual.toString('hex'), expected.toString('hex'), 'same buffer')665 666 t.end()667})668 669tape('copy an interval between two buffers', function (t) {670 const buf = crypto.randomBytes(10)671 const buf2 = Buffer.alloc(10)672 const b = BufferList(buf)673 674 b.append(buf)675 b.copy(buf2, 0, 5, 15)676 677 t.equal(b.slice(5, 15).toString('hex'), buf2.toString('hex'), 'same buffer')678 679 t.end()680})681 682tape('shallow slice across buffer boundaries', function (t) {683 const bl = new BufferList(['First', 'Second', 'Third'])684 685 t.equal(bl.shallowSlice(3, 13).toString(), 'stSecondTh')686 687 t.end()688})689 690tape('shallow slice within single buffer', function (t) {691 t.plan(2)692 693 const bl = new BufferList(['First', 'Second', 'Third'])694 695 t.equal(bl.shallowSlice(5, 10).toString(), 'Secon')696 t.equal(bl.shallowSlice(7, 10).toString(), 'con')697 698 t.end()699})700 701tape('shallow slice single buffer', function (t) {702 t.plan(3)703 704 const bl = new BufferList(['First', 'Second', 'Third'])705 706 t.equal(bl.shallowSlice(0, 5).toString(), 'First')707 t.equal(bl.shallowSlice(5, 11).toString(), 'Second')708 t.equal(bl.shallowSlice(11, 16).toString(), 'Third')709})710 711tape('shallow slice with negative or omitted indices', function (t) {712 t.plan(4)713 714 const bl = new BufferList(['First', 'Second', 'Third'])715 716 t.equal(bl.shallowSlice().toString(), 'FirstSecondThird')717 t.equal(bl.shallowSlice(5).toString(), 'SecondThird')718 t.equal(bl.shallowSlice(5, -3).toString(), 'SecondTh')719 t.equal(bl.shallowSlice(-8).toString(), 'ondThird')720})721 722tape('shallow slice does not make a copy', function (t) {723 t.plan(1)724 725 const buffers = [Buffer.from('First'), Buffer.from('Second'), Buffer.from('Third')]726 const bl = (new BufferList(buffers)).shallowSlice(5, -3)727 728 buffers[1].fill('h')729 buffers[2].fill('h')730 731 t.equal(bl.toString(), 'hhhhhhhh')732})733 734tape('shallow slice with 0 length', function (t) {735 t.plan(1)736 737 const buffers = [Buffer.from('First'), Buffer.from('Second'), Buffer.from('Third')]738 const bl = (new BufferList(buffers)).shallowSlice(0, 0)739 740 t.equal(bl.length, 0)741})742 743tape('shallow slice with 0 length from middle', function (t) {744 t.plan(1)745 746 const buffers = [Buffer.from('First'), Buffer.from('Second'), Buffer.from('Third')]747 const bl = (new BufferList(buffers)).shallowSlice(10, 10)748 749 t.equal(bl.length, 0)750})751 752tape('duplicate', function (t) {753 t.plan(2)754 755 const bl = new BufferList('abcdefghij\xff\x00')756 const dup = bl.duplicate()757 758 t.equal(bl.prototype, dup.prototype)759 t.equal(bl.toString('hex'), dup.toString('hex'))760})761 762tape('destroy no pipe', function (t) {763 t.plan(2)764 765 const bl = new BufferList('alsdkfja;lsdkfja;lsdk')766 767 bl.destroy()768 769 t.equal(bl._bufs.length, 0)770 t.equal(bl.length, 0)771})772 773tape('destroy with error', function (t) {774 t.plan(3)775 776 const bl = new BufferList('alsdkfja;lsdkfja;lsdk')777 const err = new Error('kaboom')778 779 bl.destroy(err)780 bl.on('error', function (_err) {781 t.equal(_err, err)782 })783 784 t.equal(bl._bufs.length, 0)785 t.equal(bl.length, 0)786})787 788!process.browser && tape('destroy with pipe before read end', function (t) {789 t.plan(2)790 791 const bl = new BufferList()792 fs.createReadStream(path.join(__dirname, '/test.js'))793 .pipe(bl)794 795 bl.destroy()796 797 t.equal(bl._bufs.length, 0)798 t.equal(bl.length, 0)799})800 801!process.browser && tape('destroy with pipe before read end with race', function (t) {802 t.plan(2)803 804 const bl = new BufferList()805 806 fs.createReadStream(path.join(__dirname, '/test.js'))807 .pipe(bl)808 809 setTimeout(function () {810 bl.destroy()811 setTimeout(function () {812 t.equal(bl._bufs.length, 0)813 t.equal(bl.length, 0)814 }, 500)815 }, 500)816})817 818!process.browser && tape('destroy with pipe after read end', function (t) {819 t.plan(2)820 821 const bl = new BufferList()822 823 fs.createReadStream(path.join(__dirname, '/test.js'))824 .on('end', onEnd)825 .pipe(bl)826 827 function onEnd () {828 bl.destroy()829 830 t.equal(bl._bufs.length, 0)831 t.equal(bl.length, 0)832 }833})834 835!process.browser && tape('destroy with pipe while writing to a destination', function (t) {836 t.plan(4)837 838 const bl = new BufferList()839 const ds = new BufferList()840 841 fs.createReadStream(path.join(__dirname, '/test.js'))842 .on('end', onEnd)843 .pipe(bl)844 845 function onEnd () {846 bl.pipe(ds)847 848 setTimeout(function () {849 bl.destroy()850 851 t.equals(bl._bufs.length, 0)852 t.equals(bl.length, 0)853 854 ds.destroy()855 856 t.equals(bl._bufs.length, 0)857 t.equals(bl.length, 0)858 }, 100)859 }860})861 862!process.browser && tape('handle error', function (t) {863 t.plan(2)864 865 fs.createReadStream('/does/not/exist').pipe(BufferList(function (err, data) {866 t.ok(err instanceof Error, 'has error')867 t.notOk(data, 'no data')868 }))869})870 