test-multipart.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. var Dicer = require('..');
  2. var assert = require('assert'),
  3. fs = require('fs'),
  4. path = require('path'),
  5. inspect = require('util').inspect;
  6. var FIXTURES_ROOT = __dirname + '/fixtures/';
  7. var t = 0,
  8. group = path.basename(__filename, '.js') + '/';
  9. var tests = [
  10. { source: 'nested',
  11. opts: { boundary: 'AaB03x' },
  12. chsize: 32,
  13. nparts: 2,
  14. what: 'One nested multipart'
  15. },
  16. { source: 'many',
  17. opts: { boundary: '----WebKitFormBoundaryWLHCs9qmcJJoyjKR' },
  18. chsize: 16,
  19. nparts: 7,
  20. what: 'Many parts'
  21. },
  22. { source: 'many-wrongboundary',
  23. opts: { boundary: 'LOLOLOL' },
  24. chsize: 8,
  25. nparts: 0,
  26. dicerError: true,
  27. what: 'Many parts, wrong boundary'
  28. },
  29. { source: 'many-noend',
  30. opts: { boundary: '----WebKitFormBoundaryWLHCs9qmcJJoyjKR' },
  31. chsize: 16,
  32. nparts: 7,
  33. npartErrors: 1,
  34. dicerError: true,
  35. what: 'Many parts, end boundary missing, 1 file open'
  36. },
  37. { source: 'nested-full',
  38. opts: { boundary: 'AaB03x', headerFirst: true },
  39. chsize: 32,
  40. nparts: 2,
  41. what: 'One nested multipart with preceding header'
  42. },
  43. { source: 'nested-full',
  44. opts: { headerFirst: true },
  45. chsize: 32,
  46. nparts: 2,
  47. setBoundary: 'AaB03x',
  48. what: 'One nested multipart with preceding header, using setBoundary'
  49. },
  50. ];
  51. function next() {
  52. if (t === tests.length)
  53. return;
  54. var v = tests[t],
  55. fixtureBase = FIXTURES_ROOT + v.source,
  56. n = 0,
  57. buffer = new Buffer(v.chsize),
  58. state = { parts: [], preamble: undefined };
  59. var dicer = new Dicer(v.opts),
  60. error,
  61. partErrors = 0,
  62. finishes = 0;
  63. dicer.on('preamble', function(p) {
  64. var preamble = {
  65. body: undefined,
  66. bodylen: 0,
  67. error: undefined,
  68. header: undefined
  69. };
  70. p.on('header', function(h) {
  71. preamble.header = h;
  72. if (v.setBoundary)
  73. dicer.setBoundary(v.setBoundary);
  74. }).on('data', function(data) {
  75. // make a copy because we are using readSync which re-uses a buffer ...
  76. var copy = new Buffer(data.length);
  77. data.copy(copy);
  78. data = copy;
  79. if (!preamble.body)
  80. preamble.body = [ data ];
  81. else
  82. preamble.body.push(data);
  83. preamble.bodylen += data.length;
  84. }).on('error', function(err) {
  85. preamble.error = err;
  86. }).on('end', function() {
  87. if (preamble.body)
  88. preamble.body = Buffer.concat(preamble.body, preamble.bodylen);
  89. if (preamble.body || preamble.header)
  90. state.preamble = preamble;
  91. });
  92. });
  93. dicer.on('part', function(p) {
  94. var part = {
  95. body: undefined,
  96. bodylen: 0,
  97. error: undefined,
  98. header: undefined
  99. };
  100. p.on('header', function(h) {
  101. part.header = h;
  102. }).on('data', function(data) {
  103. if (!part.body)
  104. part.body = [ data ];
  105. else
  106. part.body.push(data);
  107. part.bodylen += data.length;
  108. }).on('error', function(err) {
  109. part.error = err;
  110. ++partErrors;
  111. }).on('end', function() {
  112. if (part.body)
  113. part.body = Buffer.concat(part.body, part.bodylen);
  114. state.parts.push(part);
  115. });
  116. }).on('error', function(err) {
  117. error = err;
  118. }).on('finish', function() {
  119. assert(finishes++ === 0, makeMsg(v.what, 'finish emitted multiple times'));
  120. if (v.dicerError)
  121. assert(error !== undefined, makeMsg(v.what, 'Expected error'));
  122. else
  123. assert(error === undefined, makeMsg(v.what, 'Unexpected error: ' + error));
  124. var preamble;
  125. if (fs.existsSync(fixtureBase + '/preamble')) {
  126. var prebody = fs.readFileSync(fixtureBase + '/preamble');
  127. if (prebody.length) {
  128. preamble = {
  129. body: prebody,
  130. bodylen: prebody.length,
  131. error: undefined,
  132. header: undefined
  133. };
  134. }
  135. }
  136. if (fs.existsSync(fixtureBase + '/preamble.header')) {
  137. var prehead = JSON.parse(fs.readFileSync(fixtureBase
  138. + '/preamble.header', 'binary'));
  139. if (!preamble) {
  140. preamble = {
  141. body: undefined,
  142. bodylen: 0,
  143. error: undefined,
  144. header: prehead
  145. };
  146. } else
  147. preamble.header = prehead;
  148. }
  149. if (fs.existsSync(fixtureBase + '/preamble.error')) {
  150. var err = new Error(fs.readFileSync(fixtureBase
  151. + '/preamble.error', 'binary'));
  152. if (!preamble) {
  153. preamble = {
  154. body: undefined,
  155. bodylen: 0,
  156. error: err,
  157. header: undefined
  158. };
  159. } else
  160. preamble.error = err;
  161. }
  162. assert.deepEqual(state.preamble,
  163. preamble,
  164. makeMsg(v.what,
  165. 'Preamble mismatch:\nActual:'
  166. + inspect(state.preamble)
  167. + '\nExpected: '
  168. + inspect(preamble)));
  169. assert.equal(state.parts.length,
  170. v.nparts,
  171. makeMsg(v.what,
  172. 'Part count mismatch:\nActual: '
  173. + state.parts.length
  174. + '\nExpected: '
  175. + v.nparts));
  176. if (!v.npartErrors)
  177. v.npartErrors = 0;
  178. assert.equal(partErrors,
  179. v.npartErrors,
  180. makeMsg(v.what,
  181. 'Part errors mismatch:\nActual: '
  182. + partErrors
  183. + '\nExpected: '
  184. + v.npartErrors));
  185. for (var i = 0, header, body; i < v.nparts; ++i) {
  186. if (fs.existsSync(fixtureBase + '/part' + (i+1))) {
  187. body = fs.readFileSync(fixtureBase + '/part' + (i+1));
  188. if (body.length === 0)
  189. body = undefined;
  190. } else
  191. body = undefined;
  192. assert.deepEqual(state.parts[i].body,
  193. body,
  194. makeMsg(v.what,
  195. 'Part #' + (i+1) + ' body mismatch'));
  196. if (fs.existsSync(fixtureBase + '/part' + (i+1) + '.header')) {
  197. header = fs.readFileSync(fixtureBase
  198. + '/part' + (i+1) + '.header', 'binary');
  199. header = JSON.parse(header);
  200. } else
  201. header = undefined;
  202. assert.deepEqual(state.parts[i].header,
  203. header,
  204. makeMsg(v.what,
  205. 'Part #' + (i+1)
  206. + ' parsed header mismatch:\nActual: '
  207. + inspect(state.parts[i].header)
  208. + '\nExpected: '
  209. + inspect(header)));
  210. }
  211. ++t;
  212. next();
  213. });
  214. fs.createReadStream(fixtureBase + '/original').pipe(dicer);
  215. }
  216. next();
  217. function makeMsg(what, msg) {
  218. return '[' + group + what + ']: ' + msg;
  219. }
  220. process.on('exit', function() {
  221. assert(t === tests.length,
  222. makeMsg('_exit', 'Only ran ' + t + '/' + tests.length + ' tests'));
  223. });