smart-buffer.test.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. var SmartBuffer = require('../lib/smart-buffer.js');
  2. var assert = require('chai').assert;
  3. describe('Constructing a SmartBuffer', function () {
  4. describe('Constructing with an existing Buffer', function () {
  5. var buff = new Buffer([0xAA, 0xBB, 0xCC, 0xDD, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99]);
  6. var reader = new SmartBuffer(buff);
  7. it('should have the exact same internal Buffer when constructed with a Buffer', function () {
  8. assert.strictEqual(reader.buff, buff);
  9. });
  10. it('should return a buffer with the same content', function () {
  11. assert.deepEqual(reader.toBuffer(), buff);
  12. });
  13. });
  14. describe('Constructing with an existing Buffer and setting the encoding', function () {
  15. var buff = new Buffer([0xAA, 0xBB, 0xCC, 0xDD, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99]);
  16. var reader = new SmartBuffer(buff, 'ascii');
  17. it('should have the exact same internal Buffer', function () {
  18. assert.strictEqual(reader.buff, buff);
  19. });
  20. it('should have the same encoding that was set', function () {
  21. assert.strictEqual(reader.encoding, 'ascii');
  22. });
  23. });
  24. describe('Constructing with a specified size', function () {
  25. var size = 128;
  26. var reader = new SmartBuffer(size);
  27. it('should have an internal Buffer with the same length as the size defined in the constructor', function () {
  28. assert.strictEqual(reader.buff.length, size);
  29. });
  30. });
  31. describe('Constructing with a specified encoding', function () {
  32. var encoding = 'utf8';
  33. it('should have an internal encoding with the encoding given to the constructor (1st argument)', function () {
  34. var reader = new SmartBuffer(encoding);
  35. assert.strictEqual(reader.encoding, encoding);
  36. });
  37. it('should have an internal encoding with the encoding given to the constructor (2nd argument)', function () {
  38. var reader = new SmartBuffer(1024, encoding);
  39. assert.strictEqual(reader.encoding, encoding);
  40. });
  41. });
  42. describe('Constructing with invalid parameters', function () {
  43. it('should throw an exception when given an invalid number size', function () {
  44. assert.throws(function () {
  45. var reader = new SmartBuffer(-100);
  46. }, Error);
  47. });
  48. it('should throw an exception when give a invalid encoding', function () {
  49. assert.throws(function () {
  50. var reader = new SmartBuffer('invalid');
  51. }, Error);
  52. assert.throws(function () {
  53. var reader = new SmartBuffer(1024, 'invalid');
  54. }, Error);
  55. });
  56. it('should throw and exception when given an object that is not a Buffer', function () {
  57. assert.throws(function () {
  58. var reader = new SmartBuffer(null);
  59. }, TypeError);
  60. });
  61. });
  62. });
  63. describe('Reading/Writing To/From SmartBuffer', function () {
  64. /**
  65. * Technically, if one of these works, they all should. But they're all here anyways.
  66. */
  67. describe('Numeric Values', function () {
  68. var reader = new SmartBuffer();
  69. reader.writeInt8(0x44);
  70. reader.writeUInt8(0xFF);
  71. reader.writeInt16BE(0x6699);
  72. reader.writeInt16LE(0x6699);
  73. reader.writeUInt16BE(0xFFDD);
  74. reader.writeUInt16LE(0xFFDD);
  75. reader.writeInt32BE(0x77889900);
  76. reader.writeInt32LE(0x77889900);
  77. reader.writeUInt32BE(0xFFDDCCBB);
  78. reader.writeUInt32LE(0xFFDDCCBB);
  79. reader.writeFloatBE(1.234);
  80. reader.writeFloatLE(1.234);
  81. reader.writeDoubleBE(1.234567890);
  82. reader.writeDoubleLE(1.234567890);
  83. it('should equal the correct values that were written above', function () {
  84. assert.strictEqual(reader.readInt8(), 0x44);
  85. assert.strictEqual(reader.readUInt8(), 0xFF);
  86. assert.strictEqual(reader.readInt16BE(), 0x6699);
  87. assert.strictEqual(reader.readInt16LE(), 0x6699);
  88. assert.strictEqual(reader.readUInt16BE(), 0xFFDD);
  89. assert.strictEqual(reader.readUInt16LE(), 0xFFDD);
  90. assert.strictEqual(reader.readInt32BE(), 0x77889900);
  91. assert.strictEqual(reader.readInt32LE(), 0x77889900);
  92. assert.strictEqual(reader.readUInt32BE(), 0xFFDDCCBB);
  93. assert.strictEqual(reader.readUInt32LE(), 0xFFDDCCBB);
  94. assert.closeTo(reader.readFloatBE(), 1.234, 0.001);
  95. assert.closeTo(reader.readFloatLE(), 1.234, 0.001);
  96. assert.closeTo(reader.readDoubleBE(), 1.234567890, 0.001);
  97. assert.closeTo(reader.readDoubleLE(), 1.234567890, 0.001);
  98. });
  99. });
  100. describe('Basic String Values', function () {
  101. var reader = new SmartBuffer();
  102. reader.writeStringNT('hello');
  103. reader.writeString('world');
  104. reader.writeStringNT('✎✏✎✏✎✏');
  105. it('should equal the correct strings that were written above', function () {
  106. assert.strictEqual(reader.readStringNT(), 'hello');
  107. assert.strictEqual(reader.readString(5), 'world');
  108. assert.strictEqual(reader.readStringNT(), '✎✏✎✏✎✏');
  109. });
  110. });
  111. describe('Mixed Encoding Strings', function () {
  112. var reader = new SmartBuffer('ascii');
  113. reader.writeStringNT('some ascii text');
  114. reader.writeStringNT('ѕσмє υтƒ8 тєχт', 'utf8');
  115. it('should equal the correct strings that were written above', function () {
  116. assert.strictEqual(reader.readStringNT(), 'some ascii text');
  117. assert.strictEqual(reader.readStringNT('utf8'), 'ѕσмє υтƒ8 тєχт');
  118. });
  119. });
  120. describe('Null/non-null terminating strings', function () {
  121. var reader = new SmartBuffer();
  122. reader.writeString('hello\0test\0bleh');
  123. it('should equal hello', function () {
  124. assert.strictEqual(reader.readStringNT(), 'hello');
  125. });
  126. it('should equal: test', function () {
  127. assert.strictEqual(reader.readString(4), 'test');
  128. });
  129. it('should have a length of zero', function () {
  130. assert.strictEqual(reader.readStringNT().length, 0);
  131. });
  132. it('should equal: bleh', function () {
  133. assert.strictEqual(reader.readStringNT(), 'bleh');
  134. });
  135. });
  136. describe('Reading string without specifying length', function () {
  137. var str = 'hello123';
  138. var writer = new SmartBuffer();
  139. writer.writeString(str);
  140. var reader = new SmartBuffer(writer.toBuffer());
  141. assert.strictEqual(reader.readString(), str);
  142. });
  143. describe('Write string as specific position', function () {
  144. var str = 'hello123';
  145. var writer = new SmartBuffer();
  146. writer.writeString(str, 10);
  147. var reader = new SmartBuffer(writer.toBuffer());
  148. reader.skipTo(10);
  149. it('Should read the correct string from the original position it was written to.', function () {
  150. assert.strictEqual(reader.readString(), str);
  151. });
  152. });
  153. describe('Buffer Values', function () {
  154. describe('Writing buffer to position 0', function () {
  155. var buff = new SmartBuffer();
  156. var frontBuff = new Buffer([1, 2, 3, 4, 5, 6]);
  157. buff.writeStringNT('hello');
  158. buff.writeBuffer(frontBuff, 0);
  159. it('should write the buffer to the front of the smart buffer instance', function () {
  160. var readBuff = buff.readBuffer(frontBuff.length);
  161. assert.deepEqual(readBuff, frontBuff);
  162. });
  163. });
  164. describe('Writing null terminated buffer to position 0', function () {
  165. var buff = new SmartBuffer();
  166. var frontBuff = new Buffer([1, 2, 3, 4, 5, 6]);
  167. buff.writeStringNT('hello');
  168. buff.writeBufferNT(frontBuff, 0);
  169. console.log(buff);
  170. it('should write the buffer to the front of the smart buffer instance', function () {
  171. var readBuff = buff.readBufferNT();
  172. console.log(readBuff);
  173. assert.deepEqual(readBuff, frontBuff);
  174. });
  175. });
  176. describe('Explicit lengths', function () {
  177. var buff = new Buffer([0x01, 0x02, 0x04, 0x08, 0x16, 0x32, 0x64]);
  178. var reader = new SmartBuffer();
  179. reader.writeBuffer(buff);
  180. it('should equal the buffer that was written above.', function () {
  181. assert.deepEqual(reader.readBuffer(7), buff);
  182. });
  183. });
  184. describe('Implicit lengths', function () {
  185. var buff = new Buffer([0x01, 0x02, 0x04, 0x08, 0x16, 0x32, 0x64]);
  186. var reader = new SmartBuffer();
  187. reader.writeBuffer(buff);
  188. it('should equal the buffer that was written above.', function () {
  189. assert.deepEqual(reader.readBuffer(), buff);
  190. });
  191. });
  192. describe('Null Terminated Buffer Reading', function () {
  193. var buff = new SmartBuffer();
  194. buff.writeBuffer(new Buffer([0x01, 0x02, 0x03, 0x04, 0x00, 0x01, 0x02, 0x03]));
  195. var read1 = buff.readBufferNT();
  196. var read2 = buff.readBufferNT();
  197. it('Should return a length of 4 for the four bytes before the first null in the buffer.', function () {
  198. assert.equal(read1.length, 4);
  199. });
  200. it('Should return a length of 3 for the three bytes after the first null in the buffer after reading to end.', function () {
  201. assert.equal(read2.length, 3);
  202. });
  203. });
  204. describe('Null Terminated Buffer Writing', function () {
  205. var buff = new SmartBuffer();
  206. buff.writeBufferNT(new Buffer([0x01, 0x02, 0x03, 0x04]));
  207. var read1 = buff.readBufferNT();
  208. it('Should read the correct null terminated buffer data.', function () {
  209. assert.equal(read1.length, 4);
  210. });
  211. })
  212. });
  213. describe('Inserting values into specific positions', function () {
  214. var reader = new SmartBuffer();
  215. reader.writeUInt16LE(0x0060);
  216. reader.writeStringNT('something');
  217. reader.writeUInt32LE(8485934);
  218. reader.writeUInt16LE(6699);
  219. reader.writeStringNT('else');
  220. reader.writeUInt16LE(reader.length - 2, 2);
  221. it('should equal the size of the remaining data in the buffer', function () {
  222. reader.readUInt16LE();
  223. var size = reader.readUInt16LE();
  224. assert.strictEqual(reader.remaining(), size);
  225. });
  226. });
  227. describe('Adding more data to the buffer than the internal buffer currently allows.', function () {
  228. it('Should automatically adjust internal buffer size when needed', function () {
  229. var writer = new SmartBuffer();
  230. var largeBuff = new Buffer(10000);
  231. writer.writeBuffer(largeBuff);
  232. assert.strictEqual(writer.length, largeBuff.length);
  233. });
  234. });
  235. });
  236. describe('Skipping around data', function () {
  237. var writer = new SmartBuffer();
  238. writer.writeStringNT('hello');
  239. writer.writeUInt16LE(6699);
  240. writer.writeStringNT('world!');
  241. it('Should equal the UInt16 that was written above', function () {
  242. var reader = new SmartBuffer(writer.toBuffer());
  243. reader.skip(6);
  244. assert.strictEqual(reader.readUInt16LE(), 6699);
  245. reader.skipTo(0);
  246. assert.strictEqual(reader.readStringNT(), 'hello');
  247. reader.rewind(6);
  248. assert.strictEqual(reader.readStringNT(), 'hello');
  249. });
  250. it('Should throw an error when attempting to skip more bytes than actually exist.', function () {
  251. var reader = new SmartBuffer(writer.toBuffer());
  252. assert.throws(function () {
  253. reader.skip(10000);
  254. });
  255. });
  256. it('Should throw an error when attempting to skip to a position that does not exist.', function () {
  257. var reader = new SmartBuffer(writer.toBuffer());
  258. assert.throws(function () {
  259. reader.skipTo(10000);
  260. });
  261. });
  262. it('Should throw an error when attempting to rewind past the start of the buffer.', function () {
  263. var buff = new SmartBuffer();
  264. assert.throws(function () {
  265. buff.rewind(10000);
  266. });
  267. });
  268. });
  269. describe('Automatic internal buffer resizing', function () {
  270. var writer;
  271. it('Should not throw an error when adding data that is larger than current buffer size (internal resize algo fails)', function () {
  272. var str = 'String larger than one byte';
  273. writer = new SmartBuffer(1);
  274. writer.writeString(str);
  275. assert.strictEqual(writer.buff.length, str.length);
  276. });
  277. it('Should not throw an error when adding data that is larger than current buffer size (internal resize algo succeeds)', function () {
  278. writer = new SmartBuffer(100);
  279. var buff = new Buffer(105);
  280. writer.writeBuffer(buff);
  281. // Test internal array growth algo.
  282. assert.strictEqual(writer.buff.length, (100 * 3 / 2 + 1));
  283. });
  284. });
  285. describe('Clearing the buffer', function () {
  286. var writer = new SmartBuffer();
  287. writer.writeString('somedata');
  288. it('Should contain some data.', function () {
  289. assert.notStrictEqual(writer.length, 0);
  290. });
  291. it('Should contain zero data after being cleared.', function () {
  292. writer.clear();
  293. assert.strictEqual(writer.length, 0);
  294. });
  295. });
  296. describe('Displaying the buffer as a string', function () {
  297. var buff = new Buffer([1, 2, 3, 4]);
  298. var sbuff = new SmartBuffer(buff);
  299. var str = buff.toString();
  300. var str64 = buff.toString('base64');
  301. it('Should return a valid string representing the internal buffer', function () {
  302. assert.strictEqual(str, sbuff.toString());
  303. });
  304. it('Should return a valid base64 string representing the internal buffer', function () {
  305. assert.strictEqual(str64, sbuff.toString('base64'));
  306. });
  307. });
  308. describe('Destroying the buffer', function () {
  309. var writer = new SmartBuffer();
  310. writer.writeString('hello123');
  311. writer.destroy();
  312. it('Should have a length of zero when buffer is destroyed', function () {
  313. assert.strictEqual(0, writer.length);
  314. });
  315. it('Should have no internal buff property when buffer is destroyed', function () {
  316. assert.notProperty(writer, 'buff');
  317. });
  318. });