You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

343 lines
16 KiB

  1. var Busboy = require('..');
  2. var path = require('path'),
  3. inspect = require('util').inspect,
  4. assert = require('assert');
  5. var EMPTY_FN = function() {};
  6. var t = 0,
  7. group = path.basename(__filename, '.js') + '/';
  8. var tests = [
  9. { source: [
  10. ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  11. 'Content-Disposition: form-data; name="file_name_0"',
  12. '',
  13. 'super alpha file',
  14. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  15. 'Content-Disposition: form-data; name="file_name_1"',
  16. '',
  17. 'super beta file',
  18. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  19. 'Content-Disposition: form-data; name="upload_file_0"; filename="1k_a.dat"',
  20. 'Content-Type: application/octet-stream',
  21. '',
  22. 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
  23. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  24. 'Content-Disposition: form-data; name="upload_file_1"; filename="1k_b.dat"',
  25. 'Content-Type: application/octet-stream',
  26. '',
  27. 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB',
  28. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
  29. ].join('\r\n')
  30. ],
  31. boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  32. expected: [
  33. ['field', 'file_name_0', 'super alpha file', false, false, '7bit', 'text/plain'],
  34. ['field', 'file_name_1', 'super beta file', false, false, '7bit', 'text/plain'],
  35. ['file', 'upload_file_0', 1023, 0, '1k_a.dat', '7bit', 'application/octet-stream'],
  36. ['file', 'upload_file_1', 1023, 0, '1k_b.dat', '7bit', 'application/octet-stream']
  37. ],
  38. what: 'Fields and files'
  39. },
  40. { source: [
  41. ['------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
  42. 'Content-Disposition: form-data; name="cont"',
  43. '',
  44. 'some random content',
  45. '------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
  46. 'Content-Disposition: form-data; name="pass"',
  47. '',
  48. 'some random pass',
  49. '------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
  50. 'Content-Disposition: form-data; name="bit"',
  51. '',
  52. '2',
  53. '------WebKitFormBoundaryTB2MiQ36fnSJlrhY--'
  54. ].join('\r\n')
  55. ],
  56. boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
  57. expected: [
  58. ['field', 'cont', 'some random content', false, false, '7bit', 'text/plain'],
  59. ['field', 'pass', 'some random pass', false, false, '7bit', 'text/plain'],
  60. ['field', 'bit', '2', false, false, '7bit', 'text/plain']
  61. ],
  62. what: 'Fields only'
  63. },
  64. { source: [
  65. ''
  66. ],
  67. boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
  68. expected: [],
  69. what: 'No fields and no files'
  70. },
  71. { source: [
  72. ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  73. 'Content-Disposition: form-data; name="file_name_0"',
  74. '',
  75. 'super alpha file',
  76. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  77. 'Content-Disposition: form-data; name="upload_file_0"; filename="1k_a.dat"',
  78. 'Content-Type: application/octet-stream',
  79. '',
  80. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  81. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
  82. ].join('\r\n')
  83. ],
  84. boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  85. limits: {
  86. fileSize: 13,
  87. fieldSize: 5
  88. },
  89. expected: [
  90. ['field', 'file_name_0', 'super', false, true, '7bit', 'text/plain'],
  91. ['file', 'upload_file_0', 13, 2, '1k_a.dat', '7bit', 'application/octet-stream']
  92. ],
  93. what: 'Fields and files (limits)'
  94. },
  95. { source: [
  96. ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  97. 'Content-Disposition: form-data; name="file_name_0"',
  98. '',
  99. 'super alpha file',
  100. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  101. 'Content-Disposition: form-data; name="upload_file_0"; filename="1k_a.dat"',
  102. 'Content-Type: application/octet-stream',
  103. '',
  104. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  105. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
  106. ].join('\r\n')
  107. ],
  108. boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  109. limits: {
  110. files: 0
  111. },
  112. expected: [
  113. ['field', 'file_name_0', 'super alpha file', false, false, '7bit', 'text/plain']
  114. ],
  115. what: 'Fields and files (limits: 0 files)'
  116. },
  117. { source: [
  118. ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  119. 'Content-Disposition: form-data; name="file_name_0"',
  120. '',
  121. 'super alpha file',
  122. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  123. 'Content-Disposition: form-data; name="file_name_1"',
  124. '',
  125. 'super beta file',
  126. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  127. 'Content-Disposition: form-data; name="upload_file_0"; filename="1k_a.dat"',
  128. 'Content-Type: application/octet-stream',
  129. '',
  130. 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
  131. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  132. 'Content-Disposition: form-data; name="upload_file_1"; filename="1k_b.dat"',
  133. 'Content-Type: application/octet-stream',
  134. '',
  135. 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB',
  136. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
  137. ].join('\r\n')
  138. ],
  139. boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  140. expected: [
  141. ['field', 'file_name_0', 'super alpha file', false, false, '7bit', 'text/plain'],
  142. ['field', 'file_name_1', 'super beta file', false, false, '7bit', 'text/plain'],
  143. ],
  144. events: ['field'],
  145. what: 'Fields and (ignored) files'
  146. },
  147. { source: [
  148. ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  149. 'Content-Disposition: form-data; name="upload_file_0"; filename="/tmp/1k_a.dat"',
  150. 'Content-Type: application/octet-stream',
  151. '',
  152. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  153. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  154. 'Content-Disposition: form-data; name="upload_file_1"; filename="C:\\files\\1k_b.dat"',
  155. 'Content-Type: application/octet-stream',
  156. '',
  157. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  158. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  159. 'Content-Disposition: form-data; name="upload_file_2"; filename="relative/1k_c.dat"',
  160. 'Content-Type: application/octet-stream',
  161. '',
  162. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  163. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
  164. ].join('\r\n')
  165. ],
  166. boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  167. expected: [
  168. ['file', 'upload_file_0', 26, 0, '1k_a.dat', '7bit', 'application/octet-stream'],
  169. ['file', 'upload_file_1', 26, 0, '1k_b.dat', '7bit', 'application/octet-stream'],
  170. ['file', 'upload_file_2', 26, 0, '1k_c.dat', '7bit', 'application/octet-stream']
  171. ],
  172. what: 'Files with filenames containing paths'
  173. },
  174. { source: [
  175. ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  176. 'Content-Disposition: form-data; name="upload_file_0"; filename="/absolute/1k_a.dat"',
  177. 'Content-Type: application/octet-stream',
  178. '',
  179. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  180. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  181. 'Content-Disposition: form-data; name="upload_file_1"; filename="C:\\absolute\\1k_b.dat"',
  182. 'Content-Type: application/octet-stream',
  183. '',
  184. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  185. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  186. 'Content-Disposition: form-data; name="upload_file_2"; filename="relative/1k_c.dat"',
  187. 'Content-Type: application/octet-stream',
  188. '',
  189. 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  190. '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
  191. ].join('\r\n')
  192. ],
  193. boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
  194. preservePath: true,
  195. expected: [
  196. ['file', 'upload_file_0', 26, 0, '/absolute/1k_a.dat', '7bit', 'application/octet-stream'],
  197. ['file', 'upload_file_1', 26, 0, 'C:\\absolute\\1k_b.dat', '7bit', 'application/octet-stream'],
  198. ['file', 'upload_file_2', 26, 0, 'relative/1k_c.dat', '7bit', 'application/octet-stream']
  199. ],
  200. what: 'Paths to be preserved through the preservePath option'
  201. },
  202. { source: [
  203. ['------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
  204. 'Content-Disposition: form-data; name="cont"',
  205. 'Content-Type: ',
  206. '',
  207. 'some random content',
  208. '------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
  209. 'Content-Disposition: ',
  210. '',
  211. 'some random pass',
  212. '------WebKitFormBoundaryTB2MiQ36fnSJlrhY--'
  213. ].join('\r\n')
  214. ],
  215. boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
  216. expected: [
  217. ['field', 'cont', 'some random content', false, false, '7bit', 'text/plain']
  218. ],
  219. what: 'Empty content-type and empty content-disposition'
  220. },
  221. { source: [
  222. ['--asdasdasdasd\r\n',
  223. 'Content-Type: text/plain\r\n',
  224. 'Content-Disposition: form-data; name="foo"\r\n',
  225. '\r\n',
  226. 'asd\r\n',
  227. '--asdasdasdasd--'
  228. ].join(':)')
  229. ],
  230. boundary: 'asdasdasdasd',
  231. expected: [],
  232. shouldError: 'Unexpected end of multipart data',
  233. what: 'Stopped mid-header'
  234. },
  235. { source: [
  236. ['------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
  237. 'Content-Disposition: form-data; name="cont"',
  238. 'Content-Type: application/json',
  239. '',
  240. '{}',
  241. '------WebKitFormBoundaryTB2MiQ36fnSJlrhY--',
  242. ].join('\r\n')
  243. ],
  244. boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
  245. expected: [
  246. ['field', 'cont', '{}', false, false, '7bit', 'application/json']
  247. ],
  248. what: 'content-type for fields'
  249. },
  250. { source: [
  251. '------WebKitFormBoundaryTB2MiQ36fnSJlrhY--\r\n'
  252. ],
  253. boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
  254. expected: [],
  255. what: 'empty form'
  256. }
  257. ];
  258. function next() {
  259. if (t === tests.length)
  260. return;
  261. var v = tests[t];
  262. var busboy = new Busboy({
  263. limits: v.limits,
  264. preservePath: v.preservePath,
  265. headers: {
  266. 'content-type': 'multipart/form-data; boundary=' + v.boundary
  267. }
  268. }),
  269. finishes = 0,
  270. results = [];
  271. if (v.events === undefined || v.events.indexOf('field') > -1) {
  272. busboy.on('field', function(key, val, keyTrunc, valTrunc, encoding, contype) {
  273. results.push(['field', key, val, keyTrunc, valTrunc, encoding, contype]);
  274. });
  275. }
  276. if (v.events === undefined || v.events.indexOf('file') > -1) {
  277. busboy.on('file', function(fieldname, stream, filename, encoding, mimeType) {
  278. var nb = 0,
  279. info = ['file',
  280. fieldname,
  281. nb,
  282. 0,
  283. filename,
  284. encoding,
  285. mimeType];
  286. results.push(info);
  287. stream.on('data', function(d) {
  288. nb += d.length;
  289. }).on('limit', function() {
  290. ++info[3];
  291. }).on('end', function() {
  292. info[2] = nb;
  293. if (stream.truncated)
  294. ++info[3];
  295. });
  296. });
  297. }
  298. busboy.on('finish', function() {
  299. assert(finishes++ === 0, makeMsg(v.what, 'finish emitted multiple times'));
  300. assert.deepEqual(results.length,
  301. v.expected.length,
  302. makeMsg(v.what, 'Parsed result count mismatch. Saw '
  303. + results.length
  304. + '. Expected: ' + v.expected.length));
  305. results.forEach(function(result, i) {
  306. assert.deepEqual(result,
  307. v.expected[i],
  308. makeMsg(v.what,
  309. 'Result mismatch:\nParsed: ' + inspect(result)
  310. + '\nExpected: ' + inspect(v.expected[i]))
  311. );
  312. });
  313. ++t;
  314. next();
  315. }).on('error', function(err) {
  316. if (!v.shouldError || v.shouldError !== err.message)
  317. assert(false, makeMsg(v.what, 'Unexpected error: ' + err));
  318. });
  319. v.source.forEach(function(s) {
  320. busboy.write(Buffer.from(s, 'utf8'), EMPTY_FN);
  321. });
  322. busboy.end();
  323. }
  324. next();
  325. function makeMsg(what, msg) {
  326. return '[' + group + what + ']: ' + msg;
  327. }
  328. process.on('exit', function() {
  329. assert(t === tests.length,
  330. makeMsg('_exit',
  331. 'Only finished ' + t + '/' + tests.length + ' tests'));
  332. });