basic-test.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. var tape = require('tape')
  2. , crypto = require('crypto')
  3. , fs = require('fs')
  4. , hash = require('hash_file')
  5. , BufferList = require('../')
  6. , encodings =
  7. ('hex utf8 utf-8 ascii binary base64'
  8. + (process.browser ? '' : ' ucs2 ucs-2 utf16le utf-16le')).split(' ')
  9. tape('single bytes from single buffer', function (t) {
  10. var bl = new BufferList()
  11. bl.append(new Buffer('abcd'))
  12. t.equal(bl.length, 4)
  13. t.equal(bl.get(0), 97)
  14. t.equal(bl.get(1), 98)
  15. t.equal(bl.get(2), 99)
  16. t.equal(bl.get(3), 100)
  17. t.end()
  18. })
  19. tape('single bytes from multiple buffers', function (t) {
  20. var bl = new BufferList()
  21. bl.append(new Buffer('abcd'))
  22. bl.append(new Buffer('efg'))
  23. bl.append(new Buffer('hi'))
  24. bl.append(new Buffer('j'))
  25. t.equal(bl.length, 10)
  26. t.equal(bl.get(0), 97)
  27. t.equal(bl.get(1), 98)
  28. t.equal(bl.get(2), 99)
  29. t.equal(bl.get(3), 100)
  30. t.equal(bl.get(4), 101)
  31. t.equal(bl.get(5), 102)
  32. t.equal(bl.get(6), 103)
  33. t.equal(bl.get(7), 104)
  34. t.equal(bl.get(8), 105)
  35. t.equal(bl.get(9), 106)
  36. t.end()
  37. })
  38. tape('multi bytes from single buffer', function (t) {
  39. var bl = new BufferList()
  40. bl.append(new Buffer('abcd'))
  41. t.equal(bl.length, 4)
  42. t.equal(bl.slice(0, 4).toString('ascii'), 'abcd')
  43. t.equal(bl.slice(0, 3).toString('ascii'), 'abc')
  44. t.equal(bl.slice(1, 4).toString('ascii'), 'bcd')
  45. t.end()
  46. })
  47. tape('multiple bytes from multiple buffers', function (t) {
  48. var bl = new BufferList()
  49. bl.append(new Buffer('abcd'))
  50. bl.append(new Buffer('efg'))
  51. bl.append(new Buffer('hi'))
  52. bl.append(new Buffer('j'))
  53. t.equal(bl.length, 10)
  54. t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')
  55. t.equal(bl.slice(3, 10).toString('ascii'), 'defghij')
  56. t.equal(bl.slice(3, 6).toString('ascii'), 'def')
  57. t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')
  58. t.equal(bl.slice(5, 10).toString('ascii'), 'fghij')
  59. t.end()
  60. })
  61. tape('multiple bytes from multiple buffer lists', function (t) {
  62. var bl = new BufferList()
  63. bl.append(new BufferList([new Buffer('abcd'), new Buffer('efg')]))
  64. bl.append(new BufferList([new Buffer('hi'), new Buffer('j')]))
  65. t.equal(bl.length, 10)
  66. t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')
  67. t.equal(bl.slice(3, 10).toString('ascii'), 'defghij')
  68. t.equal(bl.slice(3, 6).toString('ascii'), 'def')
  69. t.equal(bl.slice(3, 8).toString('ascii'), 'defgh')
  70. t.equal(bl.slice(5, 10).toString('ascii'), 'fghij')
  71. t.end()
  72. })
  73. tape('consuming from multiple buffers', function (t) {
  74. var bl = new BufferList()
  75. bl.append(new Buffer('abcd'))
  76. bl.append(new Buffer('efg'))
  77. bl.append(new Buffer('hi'))
  78. bl.append(new Buffer('j'))
  79. t.equal(bl.length, 10)
  80. t.equal(bl.slice(0, 10).toString('ascii'), 'abcdefghij')
  81. bl.consume(3)
  82. t.equal(bl.length, 7)
  83. t.equal(bl.slice(0, 7).toString('ascii'), 'defghij')
  84. bl.consume(2)
  85. t.equal(bl.length, 5)
  86. t.equal(bl.slice(0, 5).toString('ascii'), 'fghij')
  87. bl.consume(1)
  88. t.equal(bl.length, 4)
  89. t.equal(bl.slice(0, 4).toString('ascii'), 'ghij')
  90. bl.consume(1)
  91. t.equal(bl.length, 3)
  92. t.equal(bl.slice(0, 3).toString('ascii'), 'hij')
  93. bl.consume(2)
  94. t.equal(bl.length, 1)
  95. t.equal(bl.slice(0, 1).toString('ascii'), 'j')
  96. t.end()
  97. })
  98. tape('test readUInt8 / readInt8', function (t) {
  99. var buf1 = new Buffer(1)
  100. , buf2 = new Buffer(3)
  101. , buf3 = new Buffer(3)
  102. , bl = new BufferList()
  103. buf2[1] = 0x3
  104. buf2[2] = 0x4
  105. buf3[0] = 0x23
  106. buf3[1] = 0x42
  107. bl.append(buf1)
  108. bl.append(buf2)
  109. bl.append(buf3)
  110. t.equal(bl.readUInt8(2), 0x3)
  111. t.equal(bl.readInt8(2), 0x3)
  112. t.equal(bl.readUInt8(3), 0x4)
  113. t.equal(bl.readInt8(3), 0x4)
  114. t.equal(bl.readUInt8(4), 0x23)
  115. t.equal(bl.readInt8(4), 0x23)
  116. t.equal(bl.readUInt8(5), 0x42)
  117. t.equal(bl.readInt8(5), 0x42)
  118. t.end()
  119. })
  120. tape('test readUInt16LE / readUInt16BE / readInt16LE / readInt16BE', function (t) {
  121. var buf1 = new Buffer(1)
  122. , buf2 = new Buffer(3)
  123. , buf3 = new Buffer(3)
  124. , bl = new BufferList()
  125. buf2[1] = 0x3
  126. buf2[2] = 0x4
  127. buf3[0] = 0x23
  128. buf3[1] = 0x42
  129. bl.append(buf1)
  130. bl.append(buf2)
  131. bl.append(buf3)
  132. t.equal(bl.readUInt16BE(2), 0x0304)
  133. t.equal(bl.readUInt16LE(2), 0x0403)
  134. t.equal(bl.readInt16BE(2), 0x0304)
  135. t.equal(bl.readInt16LE(2), 0x0403)
  136. t.equal(bl.readUInt16BE(3), 0x0423)
  137. t.equal(bl.readUInt16LE(3), 0x2304)
  138. t.equal(bl.readInt16BE(3), 0x0423)
  139. t.equal(bl.readInt16LE(3), 0x2304)
  140. t.equal(bl.readUInt16BE(4), 0x2342)
  141. t.equal(bl.readUInt16LE(4), 0x4223)
  142. t.equal(bl.readInt16BE(4), 0x2342)
  143. t.equal(bl.readInt16LE(4), 0x4223)
  144. t.end()
  145. })
  146. tape('test readUInt32LE / readUInt32BE / readInt32LE / readInt32BE', function (t) {
  147. var buf1 = new Buffer(1)
  148. , buf2 = new Buffer(3)
  149. , buf3 = new Buffer(3)
  150. , bl = new BufferList()
  151. buf2[1] = 0x3
  152. buf2[2] = 0x4
  153. buf3[0] = 0x23
  154. buf3[1] = 0x42
  155. bl.append(buf1)
  156. bl.append(buf2)
  157. bl.append(buf3)
  158. t.equal(bl.readUInt32BE(2), 0x03042342)
  159. t.equal(bl.readUInt32LE(2), 0x42230403)
  160. t.equal(bl.readInt32BE(2), 0x03042342)
  161. t.equal(bl.readInt32LE(2), 0x42230403)
  162. t.end()
  163. })
  164. tape('test readFloatLE / readFloatBE', function (t) {
  165. var buf1 = new Buffer(1)
  166. , buf2 = new Buffer(3)
  167. , buf3 = new Buffer(3)
  168. , bl = new BufferList()
  169. buf2[1] = 0x00
  170. buf2[2] = 0x00
  171. buf3[0] = 0x80
  172. buf3[1] = 0x3f
  173. bl.append(buf1)
  174. bl.append(buf2)
  175. bl.append(buf3)
  176. t.equal(bl.readFloatLE(2), 0x01)
  177. t.end()
  178. })
  179. tape('test readDoubleLE / readDoubleBE', function (t) {
  180. var buf1 = new Buffer(1)
  181. , buf2 = new Buffer(3)
  182. , buf3 = new Buffer(10)
  183. , bl = new BufferList()
  184. buf2[1] = 0x55
  185. buf2[2] = 0x55
  186. buf3[0] = 0x55
  187. buf3[1] = 0x55
  188. buf3[2] = 0x55
  189. buf3[3] = 0x55
  190. buf3[4] = 0xd5
  191. buf3[5] = 0x3f
  192. bl.append(buf1)
  193. bl.append(buf2)
  194. bl.append(buf3)
  195. t.equal(bl.readDoubleLE(2), 0.3333333333333333)
  196. t.end()
  197. })
  198. tape('test toString', function (t) {
  199. var bl = new BufferList()
  200. bl.append(new Buffer('abcd'))
  201. bl.append(new Buffer('efg'))
  202. bl.append(new Buffer('hi'))
  203. bl.append(new Buffer('j'))
  204. t.equal(bl.toString('ascii', 0, 10), 'abcdefghij')
  205. t.equal(bl.toString('ascii', 3, 10), 'defghij')
  206. t.equal(bl.toString('ascii', 3, 6), 'def')
  207. t.equal(bl.toString('ascii', 3, 8), 'defgh')
  208. t.equal(bl.toString('ascii', 5, 10), 'fghij')
  209. t.end()
  210. })
  211. tape('test toString encoding', function (t) {
  212. var bl = new BufferList()
  213. , b = new Buffer('abcdefghij\xff\x00')
  214. bl.append(new Buffer('abcd'))
  215. bl.append(new Buffer('efg'))
  216. bl.append(new Buffer('hi'))
  217. bl.append(new Buffer('j'))
  218. bl.append(new Buffer('\xff\x00'))
  219. encodings.forEach(function (enc) {
  220. t.equal(bl.toString(enc), b.toString(enc), enc)
  221. })
  222. t.end()
  223. })
  224. !process.browser && tape('test stream', function (t) {
  225. var random = crypto.randomBytes(65534)
  226. , rndhash = hash(random, 'md5')
  227. , md5sum = crypto.createHash('md5')
  228. , bl = new BufferList(function (err, buf) {
  229. t.ok(Buffer.isBuffer(buf))
  230. t.ok(err === null)
  231. t.equal(rndhash, hash(bl.slice(), 'md5'))
  232. t.equal(rndhash, hash(buf, 'md5'))
  233. bl.pipe(fs.createWriteStream('/tmp/bl_test_rnd_out.dat'))
  234. .on('close', function () {
  235. var s = fs.createReadStream('/tmp/bl_test_rnd_out.dat')
  236. s.on('data', md5sum.update.bind(md5sum))
  237. s.on('end', function() {
  238. t.equal(rndhash, md5sum.digest('hex'), 'woohoo! correct hash!')
  239. t.end()
  240. })
  241. })
  242. })
  243. fs.writeFileSync('/tmp/bl_test_rnd.dat', random)
  244. fs.createReadStream('/tmp/bl_test_rnd.dat').pipe(bl)
  245. })
  246. tape('instantiation with Buffer', function (t) {
  247. var buf = crypto.randomBytes(1024)
  248. , buf2 = crypto.randomBytes(1024)
  249. , b = BufferList(buf)
  250. t.equal(buf.toString('hex'), b.slice().toString('hex'), 'same buffer')
  251. b = BufferList([ buf, buf2 ])
  252. t.equal(b.slice().toString('hex'), Buffer.concat([ buf, buf2 ]).toString('hex'), 'same buffer')
  253. t.end()
  254. })
  255. tape('test String appendage', function (t) {
  256. var bl = new BufferList()
  257. , b = new Buffer('abcdefghij\xff\x00')
  258. bl.append('abcd')
  259. bl.append('efg')
  260. bl.append('hi')
  261. bl.append('j')
  262. bl.append('\xff\x00')
  263. encodings.forEach(function (enc) {
  264. t.equal(bl.toString(enc), b.toString(enc))
  265. })
  266. t.end()
  267. })
  268. tape('test Number appendage', function (t) {
  269. var bl = new BufferList()
  270. , b = new Buffer('1234567890')
  271. bl.append(1234)
  272. bl.append(567)
  273. bl.append(89)
  274. bl.append(0)
  275. encodings.forEach(function (enc) {
  276. t.equal(bl.toString(enc), b.toString(enc))
  277. })
  278. t.end()
  279. })
  280. tape('write nothing, should get empty buffer', function (t) {
  281. t.plan(3)
  282. BufferList(function (err, data) {
  283. t.notOk(err, 'no error')
  284. t.ok(Buffer.isBuffer(data), 'got a buffer')
  285. t.equal(0, data.length, 'got a zero-length buffer')
  286. t.end()
  287. }).end()
  288. })
  289. tape('unicode string', function (t) {
  290. t.plan(2)
  291. var inp1 = '\u2600'
  292. , inp2 = '\u2603'
  293. , exp = inp1 + ' and ' + inp2
  294. , bl = BufferList()
  295. bl.write(inp1)
  296. bl.write(' and ')
  297. bl.write(inp2)
  298. t.equal(exp, bl.toString())
  299. t.equal(new Buffer(exp).toString('hex'), bl.toString('hex'))
  300. })
  301. tape('should emit finish', function (t) {
  302. var source = BufferList()
  303. , dest = BufferList()
  304. source.write('hello')
  305. source.pipe(dest)
  306. dest.on('finish', function () {
  307. t.equal(dest.toString('utf8'), 'hello')
  308. t.end()
  309. })
  310. })
  311. tape('basic copy', function (t) {
  312. var buf = crypto.randomBytes(1024)
  313. , buf2 = new Buffer(1024)
  314. , b = BufferList(buf)
  315. b.copy(buf2)
  316. t.equal(b.slice().toString('hex'), buf2.toString('hex'), 'same buffer')
  317. t.end()
  318. })
  319. tape('copy after many appends', function (t) {
  320. var buf = crypto.randomBytes(512)
  321. , buf2 = new Buffer(1024)
  322. , b = BufferList(buf)
  323. b.append(buf)
  324. b.copy(buf2)
  325. t.equal(b.slice().toString('hex'), buf2.toString('hex'), 'same buffer')
  326. t.end()
  327. })
  328. tape('copy at a precise position', function (t) {
  329. var buf = crypto.randomBytes(1004)
  330. , buf2 = new Buffer(1024)
  331. , b = BufferList(buf)
  332. b.copy(buf2, 20)
  333. t.equal(b.slice().toString('hex'), buf2.slice(20).toString('hex'), 'same buffer')
  334. t.end()
  335. })
  336. tape('copy starting from a precise location', function (t) {
  337. var buf = crypto.randomBytes(10)
  338. , buf2 = new Buffer(5)
  339. , b = BufferList(buf)
  340. b.copy(buf2, 0, 5)
  341. t.equal(b.slice(5).toString('hex'), buf2.toString('hex'), 'same buffer')
  342. t.end()
  343. })
  344. tape('copy in an interval', function (t) {
  345. var rnd = crypto.randomBytes(10)
  346. , b = BufferList(rnd) // put the random bytes there
  347. , actual = new Buffer(3)
  348. , expected = new Buffer(3)
  349. rnd.copy(expected, 0, 5, 8)
  350. b.copy(actual, 0, 5, 8)
  351. t.equal(actual.toString('hex'), expected.toString('hex'), 'same buffer')
  352. t.end()
  353. })
  354. tape('copy an interval between two buffers', function (t) {
  355. var buf = crypto.randomBytes(10)
  356. , buf2 = new Buffer(10)
  357. , b = BufferList(buf)
  358. b.append(buf)
  359. b.copy(buf2, 0, 5, 15)
  360. t.equal(b.slice(5, 15).toString('hex'), buf2.toString('hex'), 'same buffer')
  361. t.end()
  362. })
  363. tape('duplicate', function (t) {
  364. t.plan(2)
  365. var bl = new BufferList('abcdefghij\xff\x00')
  366. , dup = bl.duplicate()
  367. t.equal(bl.prototype, dup.prototype)
  368. t.equal(bl.toString('hex'), dup.toString('hex'))
  369. })
  370. tape('destroy no pipe', function (t) {
  371. t.plan(2)
  372. var bl = new BufferList('alsdkfja;lsdkfja;lsdk')
  373. bl.destroy()
  374. t.equal(bl._bufs.length, 0)
  375. t.equal(bl.length, 0)
  376. })
  377. !process.browser && tape('destroy with pipe before read end', function (t) {
  378. t.plan(2)
  379. var bl = new BufferList()
  380. fs.createReadStream(__dirname + '/sauce.js')
  381. .pipe(bl)
  382. bl.destroy()
  383. t.equal(bl._bufs.length, 0)
  384. t.equal(bl.length, 0)
  385. })
  386. !process.browser && tape('destroy with pipe before read end with race', function (t) {
  387. t.plan(2)
  388. var bl = new BufferList()
  389. fs.createReadStream(__dirname + '/sauce.js')
  390. .pipe(bl)
  391. setTimeout(function () {
  392. bl.destroy()
  393. setTimeout(function () {
  394. t.equal(bl._bufs.length, 0)
  395. t.equal(bl.length, 0)
  396. }, 500)
  397. }, 500)
  398. })
  399. !process.browser && tape('destroy with pipe after read end', function (t) {
  400. t.plan(2)
  401. var bl = new BufferList()
  402. fs.createReadStream(__dirname + '/sauce.js')
  403. .on('end', onEnd)
  404. .pipe(bl)
  405. function onEnd () {
  406. bl.destroy()
  407. t.equal(bl._bufs.length, 0)
  408. t.equal(bl.length, 0)
  409. }
  410. })
  411. !process.browser && tape('destroy with pipe while writing to a destination', function (t) {
  412. t.plan(4)
  413. var bl = new BufferList()
  414. , ds = new BufferList()
  415. fs.createReadStream(__dirname + '/sauce.js')
  416. .on('end', onEnd)
  417. .pipe(bl)
  418. function onEnd () {
  419. bl.pipe(ds)
  420. setTimeout(function () {
  421. bl.destroy()
  422. t.equals(bl._bufs.length, 0)
  423. t.equals(bl.length, 0)
  424. ds.destroy()
  425. t.equals(bl._bufs.length, 0)
  426. t.equals(bl.length, 0)
  427. }, 100)
  428. }
  429. })
  430. !process.browser && tape('handle error', function (t) {
  431. t.plan(2)
  432. fs.createReadStream('/does/not/exist').pipe(BufferList(function (err, data) {
  433. t.ok(err instanceof Error, 'has error')
  434. t.notOk(data, 'no data')
  435. }))
  436. })