1 var tape = require('tape')
2 , crypto = require('crypto')
4 , hash = require('hash_file')
5 , BufferList = require('../')
8 ('hex utf8 utf-8 ascii binary base64'
9 + (process.browser ? '' : ' ucs2 ucs-2 utf16le utf-16le')).split(' ')
11 tape('single bytes from single buffer', function (t) {
12 var bl = new BufferList()
13 bl.append(new Buffer('abcd'))
17 t.equal(bl.get(0), 97)
18 t.equal(bl.get(1), 98)
19 t.equal(bl.get(2), 99)
20 t.equal(bl.get(3), 100)
25 tape('single bytes from multiple buffers', function (t) {
26 var bl = new BufferList()
27 bl.append(new Buffer('abcd'))
28 bl.append(new Buffer('efg'))
29 bl.append(new Buffer('hi'))
30 bl.append(new Buffer('j'))
32 t.equal(bl.length, 10)
34 t.equal(bl.get(0), 97)
35 t.equal(bl.get(1), 98)
36 t.equal(bl.get(2), 99)
37 t.equal(bl.get(3), 100)
38 t.equal(bl.get(4), 101)
39 t.equal(bl.get(5), 102)
40 t.equal(bl.get(6), 103)
41 t.equal(bl.get(7), 104)
42 t.equal(bl.get(8), 105)
43 t.equal(bl.get(9), 106)
47 tape('multi bytes from single buffer', function (t) {
48 var bl = new BufferList()
49 bl.append(new Buffer('abcd'))
53 t.equal(bl.slice(0, 4).toString('ascii'), 'abcd')
54 t.equal(bl.slice(0, 3).toString('ascii'), 'abc')
55 t.equal(bl.slice(1, 4).toString('ascii'), 'bcd')
60 tape('multiple bytes from multiple buffers', function (t) {
61 var bl = new BufferList()
63 bl.append(new Buffer('abcd'))
64 bl.append(new Buffer('efg'))
65 bl.append(new Buffer('hi'))
66 bl.append(new Buffer('j'))
68 t.equal(bl.length, 10)
70 t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')
71 t.equal(bl.slice(3, 10).toString('ascii'), 'defghij')
72 t.equal(bl.slice(3, 6).toString('ascii'), 'def')
73 t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')
74 t.equal(bl.slice(5, 10).toString('ascii'), 'fghij')
79 tape('multiple bytes from multiple buffer lists', function (t) {
80 var bl = new BufferList()
82 bl.append(new BufferList([ new Buffer('abcd'), new Buffer('efg') ]))
83 bl.append(new BufferList([ new Buffer('hi'), new Buffer('j') ]))
85 t.equal(bl.length, 10)
87 t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')
89 t.equal(bl.slice(3, 10).toString('ascii'), 'defghij')
90 t.equal(bl.slice(3, 6).toString('ascii'), 'def')
91 t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')
92 t.equal(bl.slice(5, 10).toString('ascii'), 'fghij')
97 // same data as previous test, just using nested constructors
98 tape('multiple bytes from crazy nested buffer lists', function (t) {
99 var bl = new BufferList()
101 bl.append(new BufferList([
103 new BufferList(new Buffer('abc'))
105 , new BufferList(new Buffer('efg'))
107 , new BufferList([ new Buffer('hi') ])
108 , new BufferList(new Buffer('j'))
111 t.equal(bl.length, 10)
113 t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')
115 t.equal(bl.slice(3, 10).toString('ascii'), 'defghij')
116 t.equal(bl.slice(3, 6).toString('ascii'), 'def')
117 t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')
118 t.equal(bl.slice(5, 10).toString('ascii'), 'fghij')
123 tape('append accepts arrays of Buffers', function (t) {
124 var bl = new BufferList()
125 bl.append(new Buffer('abc'))
126 bl.append([ new Buffer('def') ])
127 bl.append([ new Buffer('ghi'), new Buffer('jkl') ])
128 bl.append([ new Buffer('mnop'), new Buffer('qrstu'), new Buffer('vwxyz') ])
129 t.equal(bl.length, 26)
130 t.equal(bl.slice().toString('ascii'), 'abcdefghijklmnopqrstuvwxyz')
134 tape('append accepts arrays of BufferLists', function (t) {
135 var bl = new BufferList()
136 bl.append(new Buffer('abc'))
137 bl.append([ new BufferList('def') ])
138 bl.append(new BufferList([ new Buffer('ghi'), new BufferList('jkl') ]))
139 bl.append([ new Buffer('mnop'), new BufferList([ new Buffer('qrstu'), new Buffer('vwxyz') ]) ])
140 t.equal(bl.length, 26)
141 t.equal(bl.slice().toString('ascii'), 'abcdefghijklmnopqrstuvwxyz')
145 tape('append chainable', function (t) {
146 var bl = new BufferList()
147 t.ok(bl.append(new Buffer('abcd')) === bl)
148 t.ok(bl.append([ new Buffer('abcd') ]) === bl)
149 t.ok(bl.append(new BufferList(new Buffer('abcd'))) === bl)
150 t.ok(bl.append([ new BufferList(new Buffer('abcd')) ]) === bl)
154 tape('append chainable (test results)', function (t) {
155 var bl = new BufferList('abc')
156 .append([ new BufferList('def') ])
157 .append(new BufferList([ new Buffer('ghi'), new BufferList('jkl') ]))
158 .append([ new Buffer('mnop'), new BufferList([ new Buffer('qrstu'), new Buffer('vwxyz') ]) ])
160 t.equal(bl.length, 26)
161 t.equal(bl.slice().toString('ascii'), 'abcdefghijklmnopqrstuvwxyz')
165 tape('consuming from multiple buffers', function (t) {
166 var bl = new BufferList()
168 bl.append(new Buffer('abcd'))
169 bl.append(new Buffer('efg'))
170 bl.append(new Buffer('hi'))
171 bl.append(new Buffer('j'))
173 t.equal(bl.length, 10)
175 t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')
178 t.equal(bl.length, 7)
179 t.equal(bl.slice(0, 7).toString('ascii'), 'defghij')
182 t.equal(bl.length, 5)
183 t.equal(bl.slice(0, 5).toString('ascii'), 'fghij')
186 t.equal(bl.length, 4)
187 t.equal(bl.slice(0, 4).toString('ascii'), 'ghij')
190 t.equal(bl.length, 3)
191 t.equal(bl.slice(0, 3).toString('ascii'), 'hij')
194 t.equal(bl.length, 1)
195 t.equal(bl.slice(0, 1).toString('ascii'), 'j')
200 tape('complete consumption', function (t) {
201 var bl = new BufferList()
203 bl.append(new Buffer('a'))
204 bl.append(new Buffer('b'))
208 t.equal(bl.length, 0)
209 t.equal(bl._bufs.length, 0)
214 tape('test readUInt8 / readInt8', function (t) {
215 var buf1 = new Buffer(1)
216 , buf2 = new Buffer(3)
217 , buf3 = new Buffer(3)
218 , bl = new BufferList()
229 t.equal(bl.readUInt8(2), 0x3)
230 t.equal(bl.readInt8(2), 0x3)
231 t.equal(bl.readUInt8(3), 0x4)
232 t.equal(bl.readInt8(3), 0x4)
233 t.equal(bl.readUInt8(4), 0x23)
234 t.equal(bl.readInt8(4), 0x23)
235 t.equal(bl.readUInt8(5), 0x42)
236 t.equal(bl.readInt8(5), 0x42)
240 tape('test readUInt16LE / readUInt16BE / readInt16LE / readInt16BE', function (t) {
241 var buf1 = new Buffer(1)
242 , buf2 = new Buffer(3)
243 , buf3 = new Buffer(3)
244 , bl = new BufferList()
255 t.equal(bl.readUInt16BE(2), 0x0304)
256 t.equal(bl.readUInt16LE(2), 0x0403)
257 t.equal(bl.readInt16BE(2), 0x0304)
258 t.equal(bl.readInt16LE(2), 0x0403)
259 t.equal(bl.readUInt16BE(3), 0x0423)
260 t.equal(bl.readUInt16LE(3), 0x2304)
261 t.equal(bl.readInt16BE(3), 0x0423)
262 t.equal(bl.readInt16LE(3), 0x2304)
263 t.equal(bl.readUInt16BE(4), 0x2342)
264 t.equal(bl.readUInt16LE(4), 0x4223)
265 t.equal(bl.readInt16BE(4), 0x2342)
266 t.equal(bl.readInt16LE(4), 0x4223)
270 tape('test readUInt32LE / readUInt32BE / readInt32LE / readInt32BE', function (t) {
271 var buf1 = new Buffer(1)
272 , buf2 = new Buffer(3)
273 , buf3 = new Buffer(3)
274 , bl = new BufferList()
285 t.equal(bl.readUInt32BE(2), 0x03042342)
286 t.equal(bl.readUInt32LE(2), 0x42230403)
287 t.equal(bl.readInt32BE(2), 0x03042342)
288 t.equal(bl.readInt32LE(2), 0x42230403)
292 tape('test readFloatLE / readFloatBE', function (t) {
293 var buf1 = new Buffer(1)
294 , buf2 = new Buffer(3)
295 , buf3 = new Buffer(3)
296 , bl = new BufferList()
307 t.equal(bl.readFloatLE(2), 0x01)
311 tape('test readDoubleLE / readDoubleBE', function (t) {
312 var buf1 = new Buffer(1)
313 , buf2 = new Buffer(3)
314 , buf3 = new Buffer(10)
315 , bl = new BufferList()
330 t.equal(bl.readDoubleLE(2), 0.3333333333333333)
334 tape('test toString', function (t) {
335 var bl = new BufferList()
337 bl.append(new Buffer('abcd'))
338 bl.append(new Buffer('efg'))
339 bl.append(new Buffer('hi'))
340 bl.append(new Buffer('j'))
342 t.equal(bl.toString('ascii', 0, 10), 'abcdefghij')
343 t.equal(bl.toString('ascii', 3, 10), 'defghij')
344 t.equal(bl.toString('ascii', 3, 6), 'def')
345 t.equal(bl.toString('ascii', 3, 8), 'defgh')
346 t.equal(bl.toString('ascii', 5, 10), 'fghij')
351 tape('test toString encoding', function (t) {
352 var bl = new BufferList()
353 , b = new Buffer('abcdefghij\xff\x00')
355 bl.append(new Buffer('abcd'))
356 bl.append(new Buffer('efg'))
357 bl.append(new Buffer('hi'))
358 bl.append(new Buffer('j'))
359 bl.append(new Buffer('\xff\x00'))
361 encodings.forEach(function (enc) {
362 t.equal(bl.toString(enc), b.toString(enc), enc)
368 !process.browser && tape('test stream', function (t) {
369 var random = crypto.randomBytes(65534)
370 , rndhash = hash(random, 'md5')
371 , md5sum = crypto.createHash('md5')
372 , bl = new BufferList(function (err, buf) {
373 t.ok(Buffer.isBuffer(buf))
375 t.equal(rndhash, hash(bl.slice(), 'md5'))
376 t.equal(rndhash, hash(buf, 'md5'))
378 bl.pipe(fs.createWriteStream('/tmp/bl_test_rnd_out.dat'))
379 .on('close', function () {
380 var s = fs.createReadStream('/tmp/bl_test_rnd_out.dat')
381 s.on('data', md5sum.update.bind(md5sum))
382 s.on('end', function() {
383 t.equal(rndhash, md5sum.digest('hex'), 'woohoo! correct hash!')
390 fs.writeFileSync('/tmp/bl_test_rnd.dat', random)
391 fs.createReadStream('/tmp/bl_test_rnd.dat').pipe(bl)
394 tape('instantiation with Buffer', function (t) {
395 var buf = crypto.randomBytes(1024)
396 , buf2 = crypto.randomBytes(1024)
397 , b = BufferList(buf)
399 t.equal(buf.toString('hex'), b.slice().toString('hex'), 'same buffer')
400 b = BufferList([ buf, buf2 ])
401 t.equal(b.slice().toString('hex'), Buffer.concat([ buf, buf2 ]).toString('hex'), 'same buffer')
405 tape('test String appendage', function (t) {
406 var bl = new BufferList()
407 , b = new Buffer('abcdefghij\xff\x00')
413 bl.append('\xff\x00')
415 encodings.forEach(function (enc) {
416 t.equal(bl.toString(enc), b.toString(enc))
422 tape('test Number appendage', function (t) {
423 var bl = new BufferList()
424 , b = new Buffer('1234567890')
431 encodings.forEach(function (enc) {
432 t.equal(bl.toString(enc), b.toString(enc))
438 tape('write nothing, should get empty buffer', function (t) {
440 BufferList(function (err, data) {
441 t.notOk(err, 'no error')
442 t.ok(Buffer.isBuffer(data), 'got a buffer')
443 t.equal(0, data.length, 'got a zero-length buffer')
448 tape('unicode string', function (t) {
452 , exp = inp1 + ' and ' + inp2
457 t.equal(exp, bl.toString())
458 t.equal(new Buffer(exp).toString('hex'), bl.toString('hex'))
461 tape('should emit finish', function (t) {
462 var source = BufferList()
463 , dest = BufferList()
465 source.write('hello')
468 dest.on('finish', function () {
469 t.equal(dest.toString('utf8'), 'hello')
474 tape('basic copy', function (t) {
475 var buf = crypto.randomBytes(1024)
476 , buf2 = new Buffer(1024)
477 , b = BufferList(buf)
480 t.equal(b.slice().toString('hex'), buf2.toString('hex'), 'same buffer')
484 tape('copy after many appends', function (t) {
485 var buf = crypto.randomBytes(512)
486 , buf2 = new Buffer(1024)
487 , b = BufferList(buf)
491 t.equal(b.slice().toString('hex'), buf2.toString('hex'), 'same buffer')
495 tape('copy at a precise position', function (t) {
496 var buf = crypto.randomBytes(1004)
497 , buf2 = new Buffer(1024)
498 , b = BufferList(buf)
501 t.equal(b.slice().toString('hex'), buf2.slice(20).toString('hex'), 'same buffer')
505 tape('copy starting from a precise location', function (t) {
506 var buf = crypto.randomBytes(10)
507 , buf2 = new Buffer(5)
508 , b = BufferList(buf)
511 t.equal(b.slice(5).toString('hex'), buf2.toString('hex'), 'same buffer')
515 tape('copy in an interval', function (t) {
516 var rnd = crypto.randomBytes(10)
517 , b = BufferList(rnd) // put the random bytes there
518 , actual = new Buffer(3)
519 , expected = new Buffer(3)
521 rnd.copy(expected, 0, 5, 8)
522 b.copy(actual, 0, 5, 8)
524 t.equal(actual.toString('hex'), expected.toString('hex'), 'same buffer')
528 tape('copy an interval between two buffers', function (t) {
529 var buf = crypto.randomBytes(10)
530 , buf2 = new Buffer(10)
531 , b = BufferList(buf)
534 b.copy(buf2, 0, 5, 15)
536 t.equal(b.slice(5, 15).toString('hex'), buf2.toString('hex'), 'same buffer')
540 tape('duplicate', function (t) {
543 var bl = new BufferList('abcdefghij\xff\x00')
544 , dup = bl.duplicate()
546 t.equal(bl.prototype, dup.prototype)
547 t.equal(bl.toString('hex'), dup.toString('hex'))
550 tape('destroy no pipe', function (t) {
553 var bl = new BufferList('alsdkfja;lsdkfja;lsdk')
556 t.equal(bl._bufs.length, 0)
557 t.equal(bl.length, 0)
560 !process.browser && tape('destroy with pipe before read end', function (t) {
563 var bl = new BufferList()
564 fs.createReadStream(__dirname + '/test.js')
569 t.equal(bl._bufs.length, 0)
570 t.equal(bl.length, 0)
574 !process.browser && tape('destroy with pipe before read end with race', function (t) {
577 var bl = new BufferList()
578 fs.createReadStream(__dirname + '/test.js')
581 setTimeout(function () {
583 setTimeout(function () {
584 t.equal(bl._bufs.length, 0)
585 t.equal(bl.length, 0)
590 !process.browser && tape('destroy with pipe after read end', function (t) {
593 var bl = new BufferList()
594 fs.createReadStream(__dirname + '/test.js')
601 t.equal(bl._bufs.length, 0)
602 t.equal(bl.length, 0)
606 !process.browser && tape('destroy with pipe while writing to a destination', function (t) {
609 var bl = new BufferList()
610 , ds = new BufferList()
612 fs.createReadStream(__dirname + '/test.js')
619 setTimeout(function () {
622 t.equals(bl._bufs.length, 0)
623 t.equals(bl.length, 0)
627 t.equals(bl._bufs.length, 0)
628 t.equals(bl.length, 0)
634 !process.browser && tape('handle error', function (t) {
636 fs.createReadStream('/does/not/exist').pipe(BufferList(function (err, data) {
637 t.ok(err instanceof Error, 'has error')
638 t.notOk(data, 'no data')