diff --git a/.eslintrc.js b/.eslintrc.js index 4b904cd..e45ad66 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -21,7 +21,6 @@ module.exports = { }, env: { node: true, - mocha: true, es6: true } } diff --git a/.taprc b/.taprc deleted file mode 100644 index 4e0cdc0..0000000 --- a/.taprc +++ /dev/null @@ -1,3 +0,0 @@ -disable-coverage: true -files: - - test/**/*.test.js \ No newline at end of file diff --git a/package.json b/package.json index 2fc3c56..2bb13fa 100644 --- a/package.json +++ b/package.json @@ -27,18 +27,18 @@ "lint:everything": "npm run lint && npm run test:types", "lint:fix": "standard --fix", "lint:standard": "standard --verbose | snazzy", - "test:mocha": "tap", + "test:unit": "c8 --statements 98 --branches 97 --functions 96 --lines 98 node --test", "test:types": "tsd", "test:coverage": "nyc npm run test", - "test": "npm run test:mocha" + "test": "npm run test:unit" }, "devDependencies": { "@types/node": "^22.0.0", "busboy": "^1.6.0", + "c8": "^10.1.2", "photofinish": "^1.8.0", "snazzy": "^9.0.0", "standard": "^17.1.0", - "tap": "^21.0.0", "tinybench": "^3.0.0", "tsd": "^0.31.0", "typescript": "~5.6.3" diff --git a/test/basename.test.js b/test/basename.test.js index 0fb4a69..2dda2c7 100644 --- a/test/basename.test.js +++ b/test/basename.test.js @@ -1,9 +1,9 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') const basename = require('../lib/utils/basename') -test('basename', (t) => { +test('basename', async (t) => { const testCases = [ { description: 'returns an empty string if the path is not a string', path: {}, expected: '' }, { description: 'returns an empty string if the path includes a \' and the char after is a .', path: 'path\\.', expected: '' }, @@ -19,10 +19,11 @@ test('basename', (t) => { t.plan(testCases.length) - testCases.forEach((testCase, index) => { - t.test(testCase.description, t => { + const index = 0 + for (const testCase of testCases) { + await t.test(testCase.description, t => { t.plan(1) - t.equal(basename(testCase.path), testCase.expected, `Test case ${index + 1}`) + t.assert.strictEqual(basename(testCase.path), testCase.expected, `Test case ${index + 1}`) }) - }) + } }) diff --git a/test/busboy-constructor.test.js b/test/busboy-constructor.test.js index 8607789..fb4e5dc 100644 --- a/test/busboy-constructor.test.js +++ b/test/busboy-constructor.test.js @@ -1,75 +1,78 @@ 'use strict' const Busboy = require('../lib/main') -const { test } = require('tap') +const { test } = require('node:test') test('busboy-constructor - should throw an Error if no options are provided', t => { t.plan(1) - t.throws(() => new Busboy(), new Error('Busboy expected an options-Object.')) + t.assert.throws(() => new Busboy(), { message: 'Busboy expected an options-Object.' }) }) test('busboy-constructor - should throw an Error if options does not contain headers', t => { t.plan(1) - t.throws(() => new Busboy({}), new Error('Busboy expected an options-Object with headers-attribute.')) + t.assert.throws(() => new Busboy({}), { message: 'Busboy expected an options-Object with headers-attribute.' }) }) test('busboy-constructor - if busboy is called without new-operator, still creates a busboy instance', t => { t.plan(1) const busboyInstance = Busboy({ headers: { 'content-type': 'application/x-www-form-urlencoded' } }) - t.type(busboyInstance, Busboy) + t.assert.strictEqual(busboyInstance instanceof Busboy, true) }) test('busboy-constructor - should throw an Error if content-type is not set', t => { t.plan(1) - t.throws(() => new Busboy({ headers: {} }), new Error('Missing Content-Type-header.')) + t.assert.throws(() => new Busboy({ headers: {} }), { message: 'Missing Content-Type-header.' }) }) test('busboy-constructor - should throw an Error if content-type is unsupported', t => { t.plan(1) - t.throws(() => new Busboy({ headers: { 'content-type': 'unsupported' } }), new Error('Unsupported Content-Type.')) + t.assert.throws(() => new Busboy({ headers: { 'content-type': 'unsupported' } }), { message: 'Unsupported Content-Type.' }) }) test('busboy-constructor - should not throw an Error if content-type is urlencoded', t => { t.plan(1) - t.doesNotThrow(() => new Busboy({ headers: { 'content-type': 'application/x-www-form-urlencoded' } })) + t.assert.doesNotThrow(() => new Busboy({ headers: { 'content-type': 'application/x-www-form-urlencoded' } })) }) test('busboy-constructor - if busboy is called without stream options autoDestroy is set to false', t => { t.plan(1) const busboyInstance = Busboy({ headers: { 'content-type': 'application/x-www-form-urlencoded' } }) - t.equal(busboyInstance._writableState.autoDestroy, false) + t.assert.strictEqual(busboyInstance._writableState.autoDestroy, false) }) test('busboy-constructor - if busboy is called with invalid value for stream option highWaterMark we should throw', t => { t.plan(1) - t.throws(() => Busboy({ highWaterMark: 'not_allowed_value_for_highWaterMark', headers: { 'content-type': 'application/x-www-form-urlencoded' } }), new Error('not_allowed_value_for_highWaterMark')) + t.assert.throws(() => Busboy({ highWaterMark: 'not_allowed_value_for_highWaterMark', headers: { 'content-type': 'application/x-www-form-urlencoded' } }), { + // nmae: 'Error', + message: 'The property \'options.highWaterMark\' is invalid. Received \'not_allowed_value_for_highWaterMark\'' + }) }) test('busboy-constructor - if busboy is called with stream options and autoDestroy:true, autoDestroy should be set to true', t => { t.plan(1) const busboyInstance = Busboy({ autoDestroy: true, headers: { 'content-type': 'application/x-www-form-urlencoded' } }) - t.equal(busboyInstance._writableState.autoDestroy, true) + t.assert.strictEqual(busboyInstance._writableState.autoDestroy, true) }) test('busboy-constructor - busboy should be initialized with private attribute _done set as false', t => { t.plan(1) const busboyInstance = Busboy({ headers: { 'content-type': 'application/x-www-form-urlencoded' } }) - t.equal(busboyInstance._done, false) + t.assert.strictEqual(busboyInstance._done, false) }) test('busboy-constructor - busboy should be initialized with private attribute _finished set as false', t => { t.plan(1) const busboyInstance = Busboy({ headers: { 'content-type': 'application/x-www-form-urlencoded' } }) - t.equal(busboyInstance._finished, false) + t.assert.strictEqual(busboyInstance._finished, false) }) diff --git a/test/busboy-emit.test.js b/test/busboy-emit.test.js index 1e539ab..bfa1736 100644 --- a/test/busboy-emit.test.js +++ b/test/busboy-emit.test.js @@ -1,7 +1,7 @@ 'use strict' const Busboy = require('../lib/main') -const { test } = require('tap') +const { test } = require('node:test') test('busboy, emit', t => { t.plan(1) @@ -11,7 +11,6 @@ test('busboy, emit', t => { busboy._finished = true busboy.emit('finish') - t.equal(busboy.emit('finish'), undefined) - t.end() + t.assert.strictEqual(busboy.emit('finish'), undefined) }) }) diff --git a/test/decode-text.test.js b/test/decode-text.test.js index 5723fe9..5f35752 100644 --- a/test/decode-text.test.js +++ b/test/decode-text.test.js @@ -1,9 +1,9 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') const decodeText = require('../lib/utils/decodeText') -test('decodeText', t => { +test('decodeText', async t => { const testCases = [ { description: 'UTF-8 encoding', text: Buffer.from('Hello, World!', 'utf8'), initialCharset: 'utf8', outputCharset: 'utf8', expected: 'Hello, World!' }, { description: 'UTF-8 encoding empty', text: Buffer.from('', 'utf8'), initialCharset: 'utf8', outputCharset: 'utf8', expected: '' }, @@ -24,10 +24,11 @@ test('decodeText', t => { t.plan(testCases.length) - testCases.forEach((c, index) => { - t.test(c.description, t => { + const index = 0 + for (const c of testCases) { + await t.test(c.description, t => { t.plan(1) - t.equal(decodeText(c.text, c.initialCharset, c.outputCharset), c.expected, `Test case ${index + 1}`) + t.assert.strictEqual(decodeText(c.text, c.initialCharset, c.outputCharset), c.expected, `Test case ${index + 1}`) }) - }) + } }) diff --git a/test/decoder.test.js b/test/decoder.test.js index bc8795d..b8b289a 100644 --- a/test/decoder.test.js +++ b/test/decoder.test.js @@ -1,9 +1,9 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') const Decoder = require('../lib/utils/Decoder') -test('Decoder', t => { +test('Decoder', async t => { const tests = [ { @@ -74,8 +74,8 @@ test('Decoder', t => { ] t.plan(tests.length + 1) - tests.forEach((v) => { - t.test(v.what, t => { + for (const v of tests) { + await t.test(v.what, async t => { t.plan(1) const dec = new Decoder() @@ -86,9 +86,9 @@ test('Decoder', t => { const msg = 'Decoded string mismatch.\n' + 'Saw: ' + result + '\n' + 'Expected: ' + v.expected - t.strictSame(result, v.expected, msg) + t.assert.deepStrictEqual(result, v.expected, msg) }) - }) + } t.test('reset sets internal buffer to undefined', t => { t.plan(2) @@ -96,8 +96,8 @@ test('Decoder', t => { const dec = new Decoder() dec.write('Hello+world%2') - t.notSame(dec.buffer, undefined) + t.assert.notStrictEqual(dec.buffer, undefined) dec.reset() - t.equal(dec.buffer, undefined) + t.assert.strictEqual(dec.buffer, undefined) }) }) diff --git a/test/dicer-constructor.test.js b/test/dicer-constructor.test.js index e0e6a6c..9fb8dca 100644 --- a/test/dicer-constructor.test.js +++ b/test/dicer-constructor.test.js @@ -1,22 +1,22 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') const Dicer = require('../deps/dicer/lib/Dicer') -test('dicer-constructor', t => { +test('dicer-constructor', async t => { t.plan(2) - t.test('should throw an Error when no options parameter is supplied to Dicer', t => { + await t.test('should throw an Error when no options parameter is supplied to Dicer', t => { t.plan(1) - t.throws(() => new Dicer(), new Error('Boundary required')) + t.assert.throws(() => new Dicer(), { message: 'Boundary required' }) }) - t.test('without new operator a new dicer instance will be initialized', t => { + await t.test('without new operator a new dicer instance will be initialized', t => { t.plan(1) - t.type(Dicer({ + t.assert.strictEqual(Dicer({ boundary: '----boundary' - }), Dicer) + }) instanceof Dicer, true) }) }) diff --git a/test/dicer-endfinish.test.js b/test/dicer-endfinish.test.js index 4718076..78fc37f 100644 --- a/test/dicer-endfinish.test.js +++ b/test/dicer-endfinish.test.js @@ -1,96 +1,99 @@ 'use strict' const Dicer = require('../deps/dicer/lib/Dicer') -const { test } = require('tap') +const { test } = require('node:test') -test('dicer-endfinish', t => { +test('dicer-endfinish', async t => { t.plan(1) - t.test('should properly handle finish', t => { + await t.test('should properly handle finish', async t => { t.plan(4) - const CRLF = '\r\n' - const boundary = 'boundary' + await new Promise(resolve => { + const CRLF = '\r\n' + const boundary = 'boundary' - const writeSep = '--' + boundary + const writeSep = '--' + boundary - const writePart = [ - writeSep, - 'Content-Type: text/plain', - 'Content-Length: 0' - ].join(CRLF) + + const writePart = [ + writeSep, + 'Content-Type: text/plain', + 'Content-Length: 0' + ].join(CRLF) + CRLF + CRLF + 'some data' + CRLF - const writeEnd = '--' + CRLF + const writeEnd = '--' + CRLF - let firedEnd = false - let firedFinish = false + let firedEnd = false + let firedFinish = false - const dicer = new Dicer({ boundary }) - dicer.on('part', partListener) - dicer.on('finish', finishListener) - dicer.write(writePart + writeSep) + const dicer = new Dicer({ boundary }) + dicer.on('part', partListener) + dicer.on('finish', finishListener) + dicer.write(writePart + writeSep) - function partListener (partReadStream) { - partReadStream.on('data', function () { }) - partReadStream.on('end', partEndListener) - } - function partEndListener () { - firedEnd = true - setImmediate(afterEnd) - } - function afterEnd () { - dicer.end(writeEnd) - setImmediate(afterWrite) - } - function finishListener () { - t.ok(firedEnd, 'end before finishing') - firedFinish = true - test2() - } - function afterWrite () { - t.ok(firedFinish, 'Failed to finish') - } + function partListener (partReadStream) { + partReadStream.on('data', function () { }) + partReadStream.on('end', partEndListener) + } + function partEndListener () { + firedEnd = true + setImmediate(afterEnd) + } + function afterEnd () { + dicer.end(writeEnd) + setImmediate(afterWrite) + } + function finishListener () { + t.assert.ok(firedEnd, 'end before finishing') + firedFinish = true + test2() + } + function afterWrite () { + t.assert.ok(firedFinish, 'Failed to finish') + } - let isPausePush = true + let isPausePush = true - let firedPauseCallback = false - let firedPauseFinish = false + let firedPauseCallback = false + let firedPauseFinish = false - let dicer2 = null + let dicer2 = null - function test2 () { - dicer2 = new Dicer({ boundary }) - dicer2.on('part', pausePartListener) - dicer2.on('finish', pauseFinish) - dicer2.write(writePart + writeSep, 'utf8', pausePartCallback) - setImmediate(pauseAfterWrite) - } - function pausePartListener (partReadStream) { - partReadStream.on('data', function () { }) - partReadStream.on('end', function () { }) - const realPush = partReadStream.push - partReadStream.push = function fakePush () { - realPush.apply(partReadStream, arguments) - if (!isPausePush) { return true } - isPausePush = false - return false + function test2 () { + dicer2 = new Dicer({ boundary }) + dicer2.on('part', pausePartListener) + dicer2.on('finish', pauseFinish) + dicer2.write(writePart + writeSep, 'utf8', pausePartCallback) + setImmediate(pauseAfterWrite) + } + function pausePartListener (partReadStream) { + partReadStream.on('data', function () { }) + partReadStream.on('end', function () { }) + const realPush = partReadStream.push + partReadStream.push = function fakePush () { + realPush.apply(partReadStream, arguments) + if (!isPausePush) { return true } + isPausePush = false + return false + } + } + function pauseAfterWrite () { + dicer2.end(writeEnd) + setImmediate(pauseAfterEnd) + } + function pauseAfterEnd () { + t.assert.ok(firedPauseCallback, 'Called callback after pause') + t.assert.ok(firedPauseFinish, 'Finish after pause') + resolve() + } + function pauseFinish () { + firedPauseFinish = true + } + function pausePartCallback () { + firedPauseCallback = true } - } - function pauseAfterWrite () { - dicer2.end(writeEnd) - setImmediate(pauseAfterEnd) - } - function pauseAfterEnd () { - t.ok(firedPauseCallback, 'Called callback after pause') - t.ok(firedPauseFinish, 'Finish after pause') - } - function pauseFinish () { - firedPauseFinish = true - } - function pausePartCallback () { - firedPauseCallback = true - } + }) }) }) diff --git a/test/dicer-export.test.js b/test/dicer-export.test.js index 05df4e6..a1a8bd2 100644 --- a/test/dicer-export.test.js +++ b/test/dicer-export.test.js @@ -1,24 +1,24 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') const { Dicer } = require('../lib/main') -test('dicer-export', t => { +test('dicer-export', async t => { t.plan(2) - t.test('without new operator a new dicer instance will be initialized', t => { + await t.test('without new operator a new dicer instance will be initialized', t => { t.plan(1) - t.type(Dicer({ + t.assert.strictEqual(Dicer({ boundary: '----boundary' - }), Dicer) + }) instanceof Dicer, true) }) - t.test('with new operator a new dicer instance will be initialized', t => { + await t.test('with new operator a new dicer instance will be initialized', t => { t.plan(1) - t.type(new Dicer({ + t.assert.strictEqual(new Dicer({ boundary: '----boundary' - }), Dicer) + }) instanceof Dicer, true) }) }) diff --git a/test/dicer-headerparser.test.js b/test/dicer-headerparser.test.js index 73da283..0535579 100644 --- a/test/dicer-headerparser.test.js +++ b/test/dicer-headerparser.test.js @@ -1,9 +1,9 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') const HeaderParser = require('../deps/dicer/lib/HeaderParser') -test('dicer-headerparser', t => { +test('dicer-headerparser', async t => { const DCRLF = '\r\n\r\n' const MAXED_BUFFER = Buffer.allocUnsafe(128 * 1024) MAXED_BUFFER.fill(0x41) // 'A' @@ -163,8 +163,8 @@ test('dicer-headerparser', t => { t.plan(tests.length) - tests.forEach(function (v) { - t.test(v.what, t => { + for (const v of tests) { + await t.test(v.what, t => { t.plan(4) const cfg = { @@ -175,9 +175,9 @@ test('dicer-headerparser', t => { let fired = false parser.on('header', function (header) { - t.ok(!fired, `${v.what}: Header event fired more than once`) + t.assert.ok(!fired, `${v.what}: Header event fired more than once`) fired = true - t.strictSame(header, + t.assert.deepStrictEqual(header, v.expected, `${v.what}: Parsed result mismatch`) }) @@ -185,8 +185,8 @@ test('dicer-headerparser', t => { v.source.forEach(function (s) { parser.push(s) }) - t.ok(fired, `${v.what}: Did not receive header from parser`) - t.pass() + t.assert.ok(fired, `${v.what}: Did not receive header from parser`) + t.assert.ok('passed') }) - }) + } }) diff --git a/test/dicer-malformed-header.test.js b/test/dicer-malformed-header.test.js index c25ccdd..4c81de0 100644 --- a/test/dicer-malformed-header.test.js +++ b/test/dicer-malformed-header.test.js @@ -1,29 +1,32 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') const Dicer = require('../deps/dicer/lib/Dicer') -test('dicer-malformed-header', t => { +test('dicer-malformed-header', async t => { t.plan(1) - t.test('should gracefully handle headers with leading whitespace', t => { + await t.test('should gracefully handle headers with leading whitespace', async t => { t.plan(3) const d = new Dicer({ boundary: '----WebKitFormBoundaryoo6vortfDzBsDiro' }) - d.on('part', function (p) { - p.on('header', function (header) { - t.hasProp(header, ' content-disposition') - t.strictSame(header[' content-disposition'], ['form-data; name="bildbeschreibung"']) + await new Promise((resolve) => { + d.on('part', function (p) { + p.on('header', function (header) { + t.assert.ok(header[' content-disposition']) + t.assert.deepStrictEqual(header[' content-disposition'], ['form-data; name="bildbeschreibung"']) + }) + p.on('data', function (data) { + }) + p.on('end', function () { + }) }) - p.on('data', function (data) { + d.on('finish', function () { + t.assert.ok('finish') + resolve() }) - p.on('end', function () { - }) - }) - d.on('finish', function () { - t.pass() - }) - d.write(Buffer.from('------WebKitFormBoundaryoo6vortfDzBsDiro\r\n Content-Disposition: form-data; name="bildbeschreibung"\r\n\r\n\r\n------WebKitFormBoundaryoo6vortfDzBsDiro--')) + d.write(Buffer.from('------WebKitFormBoundaryoo6vortfDzBsDiro\r\n Content-Disposition: form-data; name="bildbeschreibung"\r\n\r\n\r\n------WebKitFormBoundaryoo6vortfDzBsDiro--')) + }) }) }) diff --git a/test/dicer-multipart-extra-trailer.test.js b/test/dicer-multipart-extra-trailer.test.js index 335605a..3801ea1 100644 --- a/test/dicer-multipart-extra-trailer.test.js +++ b/test/dicer-multipart-extra-trailer.test.js @@ -1,16 +1,16 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') const Dicer = require('../deps/dicer/lib/Dicer') const fs = require('fs') const path = require('path') const FIXTURES_ROOT = path.join(__dirname, 'fixtures/') -test('dicer-multipart-extra-trailer', t => { +test('dicer-multipart-extra-trailer', async t => { t.plan(1) - t.test('Extra trailer data pushed after finished', t => { + await t.test('Extra trailer data pushed after finished', t => { t.plan(5) const fixtureBase = FIXTURES_ROOT + 'many' let n = 0 @@ -52,14 +52,14 @@ test('dicer-multipart-extra-trailer', t => { error = err }).on('trailer', function (data) { trailerEmitted = true - t.equal(data.toString(), 'Extra', 'trailer should contain the extra data') + t.assert.strictEqual(data.toString(), 'Extra', 'trailer should contain the extra data') }).on('finish', function () { - t.ok(finishes++ === 0, makeMsg('Extra trailer data pushed after finished', 'finish emitted multiple times')) - t.ok(trailerEmitted, makeMsg('Extra trailer data pushed after finished', 'should have emitted trailer')) + t.assert.ok(finishes++ === 0, makeMsg('Extra trailer data pushed after finished', 'finish emitted multiple times')) + t.assert.ok(trailerEmitted, makeMsg('Extra trailer data pushed after finished', 'should have emitted trailer')) - t.ok(error === undefined, makeMsg('Extra trailer data pushed after finished', 'Unexpected error')) + t.assert.ok(error === undefined, makeMsg('Extra trailer data pushed after finished', 'Unexpected error')) - t.pass() + t.assert.ok('pass') }) while (true) { diff --git a/test/dicer-multipart-nolisteners.test.js b/test/dicer-multipart-nolisteners.test.js index 1e311ba..ccf1a47 100644 --- a/test/dicer-multipart-nolisteners.test.js +++ b/test/dicer-multipart-nolisteners.test.js @@ -1,44 +1,47 @@ 'use strict' const Dicer = require('../deps/dicer/lib/Dicer') -const { test } = require('tap') +const { test } = require('node:test') const fs = require('fs') const path = require('path') const FIXTURES_ROOT = path.join(__dirname, 'fixtures/') -test('dicer-multipart-nolisteners', t => { +test('dicer-multipart-nolisteners', async t => { t.plan(1) - t.test('No preamble or part listeners', t => { + await t.test('No preamble or part listeners', async t => { t.plan(3) - const fixtureBase = path.resolve(FIXTURES_ROOT, 'many') - let n = 0 - const buffer = Buffer.allocUnsafe(16) - - const fd = fs.openSync(fixtureBase + '/original', 'r') - - const dicer = new Dicer({ boundary: '----WebKitFormBoundaryWLHCs9qmcJJoyjKR' }) - let error - let finishes = 0 - - dicer.on('error', function (err) { - error = err - }).on('finish', function () { - t.ok(finishes++ === 0, 'finish emitted multiple times') - - t.ok(error === undefined, `Unexpected error: ${error}`) - t.pass() - }) - - while (true) { - n = fs.readSync(fd, buffer, 0, buffer.length, null) - if (n === 0) { - dicer.end() - break + await new Promise((resolve) => { + const fixtureBase = path.resolve(FIXTURES_ROOT, 'many') + let n = 0 + const buffer = Buffer.allocUnsafe(16) + + const fd = fs.openSync(fixtureBase + '/original', 'r') + + const dicer = new Dicer({ boundary: '----WebKitFormBoundaryWLHCs9qmcJJoyjKR' }) + let error + let finishes = 0 + + dicer.on('error', function (err) { + error = err + }).on('finish', function () { + t.assert.ok(finishes++ === 0, 'finish emitted multiple times') + + t.assert.ok(error === undefined, `Unexpected error: ${error}`) + t.assert.ok('pass') + resolve() + }) + + while (true) { + n = fs.readSync(fd, buffer, 0, buffer.length, null) + if (n === 0) { + dicer.end() + break + } + dicer.write(n === buffer.length ? buffer : buffer.slice(0, n)) } - dicer.write(n === buffer.length ? buffer : buffer.slice(0, n)) - } - fs.closeSync(fd) + fs.closeSync(fd) + }) }) }) diff --git a/test/dicer-multipart.test.js b/test/dicer-multipart.test.js index c35c4d0..08aae86 100644 --- a/test/dicer-multipart.test.js +++ b/test/dicer-multipart.test.js @@ -1,15 +1,14 @@ 'use strict' const Dicer = require('../deps/dicer/lib/Dicer') -const assert = require('node:assert') const fs = require('node:fs') const path = require('node:path') const inspect = require('node:util').inspect -const { test } = require('tap') +const { test } = require('node:test') const FIXTURES_ROOT = path.join(__dirname, 'fixtures/') -test('dicer-multipart', t => { +test('dicer-multipart', async t => { const tests = [ { @@ -17,14 +16,16 @@ test('dicer-multipart', t => { opts: { boundary: 'AaB03x' }, chsize: 32, nparts: 2, - what: 'One nested multipart' + what: 'One nested multipart', + plan: 10 }, { source: 'many', opts: { boundary: '----WebKitFormBoundaryWLHCs9qmcJJoyjKR' }, chsize: 16, nparts: 7, - what: 'Many parts' + what: 'Many parts', + plan: 20 }, { source: 'many-wrongboundary', @@ -32,7 +33,8 @@ test('dicer-multipart', t => { chsize: 8, nparts: 0, dicerError: true, - what: 'Many parts, wrong boundary' + what: 'Many parts, wrong boundary', + plan: 6 }, { source: 'many-noend', @@ -41,14 +43,16 @@ test('dicer-multipart', t => { nparts: 7, npartErrors: 1, dicerError: true, - what: 'Many parts, end boundary missing, 1 file open' + what: 'Many parts, end boundary missing, 1 file open', + plan: 20 }, { source: 'nested-full', opts: { boundary: 'AaB03x', headerFirst: true }, chsize: 32, nparts: 2, - what: 'One nested multipart with preceding header' + what: 'One nested multipart with preceding header', + plan: 10 }, { source: 'nested-full', @@ -56,166 +60,170 @@ test('dicer-multipart', t => { chsize: 32, nparts: 2, setBoundary: 'AaB03x', - what: 'One nested multipart with preceding header, using setBoundary' + what: 'One nested multipart with preceding header, using setBoundary', + plan: 10 } ] t.plan(tests.length) - tests.forEach(function (v) { - t.test(v.what, t => { - t.plan(1) - const fixtureBase = FIXTURES_ROOT + v.source - const state = { parts: [], preamble: undefined } - - const dicer = new Dicer(v.opts) - let error - let partErrors = 0 - let finishes = 0 - - dicer.on('preamble', function (p) { - const preamble = { - body: undefined, - bodylen: 0, - error: undefined, - header: undefined - } - - p.on('header', function (h) { - preamble.header = h - if (v.setBoundary) { dicer.setBoundary(v.setBoundary) } - }).on('data', function (data) { + for (const v of tests) { + await t.test(v.what, async t => { + t.plan(v.plan) + await new Promise((resolve) => { + const fixtureBase = FIXTURES_ROOT + v.source + const state = { parts: [], preamble: undefined } + + const dicer = new Dicer(v.opts) + let error + let partErrors = 0 + let finishes = 0 + + dicer.on('preamble', function (p) { + const preamble = { + body: undefined, + bodylen: 0, + error: undefined, + header: undefined + } + + p.on('header', function (h) { + preamble.header = h + if (v.setBoundary) { dicer.setBoundary(v.setBoundary) } + }).on('data', function (data) { // make a copy because we are using readSync which re-uses a buffer ... - const copy = Buffer.allocUnsafe(data.length) - data.copy(copy) - data = copy - if (!preamble.body) { preamble.body = [data] } else { preamble.body.push(data) } - preamble.bodylen += data.length - }).on('error', function (err) { - preamble.error = err - }).on('end', function () { - if (preamble.body) { preamble.body = Buffer.concat(preamble.body, preamble.bodylen) } - if (preamble.body || preamble.header) { state.preamble = preamble } + const copy = Buffer.allocUnsafe(data.length) + data.copy(copy) + data = copy + if (!preamble.body) { preamble.body = [data] } else { preamble.body.push(data) } + preamble.bodylen += data.length + }).on('error', function (err) { + preamble.error = err + }).on('end', function () { + if (preamble.body) { preamble.body = Buffer.concat(preamble.body, preamble.bodylen) } + if (preamble.body || preamble.header) { state.preamble = preamble } + }) }) - }) - dicer.on('part', function (p) { - const part = { - body: undefined, - bodylen: 0, - error: undefined, - header: undefined - } - - p.on('header', function (h) { - part.header = h - }).on('data', function (data) { - if (!part.body) { part.body = [data] } else { part.body.push(data) } - part.bodylen += data.length + dicer.on('part', function (p) { + const part = { + body: undefined, + bodylen: 0, + error: undefined, + header: undefined + } + + p.on('header', function (h) { + part.header = h + }).on('data', function (data) { + if (!part.body) { part.body = [data] } else { part.body.push(data) } + part.bodylen += data.length + }).on('error', function (err) { + part.error = err + ++partErrors + }).on('end', function () { + if (part.body) { part.body = Buffer.concat(part.body, part.bodylen) } + state.parts.push(part) + }) }).on('error', function (err) { - part.error = err - ++partErrors - }).on('end', function () { - if (part.body) { part.body = Buffer.concat(part.body, part.bodylen) } - state.parts.push(part) - }) - }).on('error', function (err) { - error = err - }).on('finish', function () { - assert(finishes++ === 0, makeMsg(v.what, 'finish emitted multiple times')) - - if (v.dicerError) { assert(error !== undefined, makeMsg(v.what, 'Expected error')) } else { assert(error === undefined, makeMsg(v.what, 'Unexpected error: ' + error)) } - - let preamble - if (fs.existsSync(fixtureBase + '/preamble')) { - const prebody = fs.readFileSync(fixtureBase + '/preamble') - if (prebody.length) { - preamble = { - body: prebody, - bodylen: prebody.length, - error: undefined, - header: undefined + error = err + }).on('finish', function () { + t.assert.strictEqual(finishes++ === 0, true, makeMsg(v.what, 'finish emitted multiple times')) + + if (v.dicerError) { t.assert.strictEqual(error !== undefined, true, makeMsg(v.what, 'Expected error')) } else { t.assert.strictEqual(error === undefined, true, makeMsg(v.what, 'Unexpected error: ' + error)) } + + let preamble + if (fs.existsSync(fixtureBase + '/preamble')) { + const prebody = fs.readFileSync(fixtureBase + '/preamble') + if (prebody.length) { + preamble = { + body: prebody, + bodylen: prebody.length, + error: undefined, + header: undefined + } } } - } - if (fs.existsSync(fixtureBase + '/preamble.header')) { - const prehead = JSON.parse(fs.readFileSync(fixtureBase + + if (fs.existsSync(fixtureBase + '/preamble.header')) { + const prehead = JSON.parse(fs.readFileSync(fixtureBase + '/preamble.header', 'binary')) - if (!preamble) { - preamble = { - body: undefined, - bodylen: 0, - error: undefined, - header: prehead - } - } else { preamble.header = prehead } - } - if (fs.existsSync(fixtureBase + '/preamble.error')) { - const err = new Error(fs.readFileSync(fixtureBase + + if (!preamble) { + preamble = { + body: undefined, + bodylen: 0, + error: undefined, + header: prehead + } + } else { preamble.header = prehead } + } + if (fs.existsSync(fixtureBase + '/preamble.error')) { + const err = new Error(fs.readFileSync(fixtureBase + '/preamble.error', 'binary')) - if (!preamble) { - preamble = { - body: undefined, - bodylen: 0, - error: err, - header: undefined - } - } else { preamble.error = err } - } + if (!preamble) { + preamble = { + body: undefined, + bodylen: 0, + error: err, + header: undefined + } + } else { preamble.error = err } + } - assert.deepEqual(state.preamble, - preamble, - makeMsg(v.what, - 'Preamble mismatch:\nActual:' + + t.assert.deepEqual(state.preamble, + preamble, + makeMsg(v.what, + 'Preamble mismatch:\nActual:' + inspect(state.preamble) + '\nExpected: ' + inspect(preamble))) - assert.equal(state.parts.length, - v.nparts, - makeMsg(v.what, - 'Part count mismatch:\nActual: ' + + t.assert.equal(state.parts.length, + v.nparts, + makeMsg(v.what, + 'Part count mismatch:\nActual: ' + state.parts.length + '\nExpected: ' + v.nparts)) - if (!v.npartErrors) { v.npartErrors = 0 } - assert.equal(partErrors, - v.npartErrors, - makeMsg(v.what, - 'Part errors mismatch:\nActual: ' + + if (!v.npartErrors) { v.npartErrors = 0 } + t.assert.equal(partErrors, + v.npartErrors, + makeMsg(v.what, + 'Part errors mismatch:\nActual: ' + partErrors + '\nExpected: ' + v.npartErrors)) - for (let i = 0, header, body; i < v.nparts; ++i) { - if (fs.existsSync(fixtureBase + '/part' + (i + 1))) { - body = fs.readFileSync(fixtureBase + '/part' + (i + 1)) - if (body.length === 0) { body = undefined } - } else { body = undefined } - assert.deepEqual(state.parts[i].body, - body, - makeMsg(v.what, - 'Part #' + (i + 1) + ' body mismatch')) - if (fs.existsSync(fixtureBase + '/part' + (i + 1) + '.header')) { - header = fs.readFileSync(fixtureBase + + for (let i = 0, header, body; i < v.nparts; ++i) { + if (fs.existsSync(fixtureBase + '/part' + (i + 1))) { + body = fs.readFileSync(fixtureBase + '/part' + (i + 1)) + if (body.length === 0) { body = undefined } + } else { body = undefined } + t.assert.deepEqual(state.parts[i].body, + body, + makeMsg(v.what, + 'Part #' + (i + 1) + ' body mismatch')) + if (fs.existsSync(fixtureBase + '/part' + (i + 1) + '.header')) { + header = fs.readFileSync(fixtureBase + '/part' + (i + 1) + '.header', 'binary') - header = JSON.parse(header) - } else { header = undefined } - assert.deepEqual(state.parts[i].header, - header, - makeMsg(v.what, - 'Part #' + (i + 1) + + header = JSON.parse(header) + } else { header = undefined } + t.assert.deepEqual(state.parts[i].header, + header, + makeMsg(v.what, + 'Part #' + (i + 1) + ' parsed header mismatch:\nActual: ' + inspect(state.parts[i].header) + '\nExpected: ' + inspect(header))) - } - t.pass() - }) + } + t.assert.ok('pass') + resolve() + }) - fs.createReadStream(fixtureBase + '/original').pipe(dicer) + fs.createReadStream(fixtureBase + '/original').pipe(dicer) + }) }) - }) + } }) function makeMsg (what, msg) { diff --git a/test/dicer-write.test.js b/test/dicer-write.test.js index f270fa3..dd74493 100644 --- a/test/dicer-write.test.js +++ b/test/dicer-write.test.js @@ -1,6 +1,6 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') const { Dicer } = require('../lib/main') test('dicer _write method', t => { @@ -12,7 +12,7 @@ test('dicer _write method', t => { dicer._write(Buffer.from('Content-Type: text/plain'), null, () => { dicer._write(Buffer.from('Content-Type: text/plain'), null, () => { - t.pass('write method called') + t.assert.ok('write method called') }) }) }) diff --git a/test/get-limit.test.js b/test/get-limit.test.js index 76a2997..6da1d95 100644 --- a/test/get-limit.test.js +++ b/test/get-limit.test.js @@ -1,34 +1,34 @@ 'use strict' const getLimit = require('../lib/utils/getLimit') -const { test } = require('tap') +const { test } = require('node:test') -test('Get limit', t => { +test('Get limit', async t => { t.plan(2) - t.test('Correctly resolves limits', t => { + await t.test('Correctly resolves limits', t => { t.plan(8) - t.strictSame(getLimit(undefined, 'fieldSize', 1), 1) - t.strictSame(getLimit(undefined, 'fileSize', Infinity), Infinity) + t.assert.deepStrictEqual(getLimit(undefined, 'fieldSize', 1), 1) + t.assert.deepStrictEqual(getLimit(undefined, 'fileSize', Infinity), Infinity) - t.strictSame(getLimit({}, 'fieldSize', 1), 1) - t.strictSame(getLimit({}, 'fileSize', Infinity), Infinity) - t.strictSame(getLimit({ fieldSize: null }, 'fieldSize', 1), 1) - t.strictSame(getLimit({ fileSize: null }, 'fileSize', Infinity), Infinity) + t.assert.deepStrictEqual(getLimit({}, 'fieldSize', 1), 1) + t.assert.deepStrictEqual(getLimit({}, 'fileSize', Infinity), Infinity) + t.assert.deepStrictEqual(getLimit({ fieldSize: null }, 'fieldSize', 1), 1) + t.assert.deepStrictEqual(getLimit({ fileSize: null }, 'fileSize', Infinity), Infinity) - t.strictSame(getLimit({ fieldSize: 0 }, 'fieldSize', 1), 0) - t.strictSame(getLimit({ fileSize: 2 }, 'fileSize', 1), 2) + t.assert.deepStrictEqual(getLimit({ fieldSize: 0 }, 'fieldSize', 1), 0) + t.assert.deepStrictEqual(getLimit({ fileSize: 2 }, 'fileSize', 1), 2) }) - t.test('Throws an error on incorrect limits', t => { + await t.test('Throws an error on incorrect limits', t => { t.plan(2) - t.throws(function () { + t.assert.throws(function () { getLimit({ fieldSize: '1' }, 'fieldSize', 1) - }, new Error('Limit fieldSize is not a valid number')) + }, { message: 'Limit fieldSize is not a valid number' }) - t.throws(function () { + t.assert.throws(function () { getLimit({ fieldSize: NaN }, 'fieldSize', 1) - }, new Error('Limit fieldSize is not a valid number')) + }, { message: 'Limit fieldSize is not a valid number' }) }) }) diff --git a/test/multipart-constructor.test.js b/test/multipart-constructor.test.js index 87aaad1..671ebf5 100644 --- a/test/multipart-constructor.test.js +++ b/test/multipart-constructor.test.js @@ -2,7 +2,7 @@ const Multipart = require('../lib/types/multipart') const Busboy = require('../lib/main') -const { test } = require('tap') +const { test } = require('node:test') test('multipart constructor', t => { t.plan(1) @@ -10,7 +10,7 @@ test('multipart constructor', t => { t.test('throws if the boundary is not a string', t => { const busboy = new Busboy({ headers: { 'content-type': 'application/x-www-form-urlencoded' } }) - t.throws(() => new Multipart(busboy, { boundary: 123 }), new Error('Multipart: Boundary not found')) - t.end() + t.assert.throws(() => new Multipart(busboy, { boundary: 123 }), { message: 'Multipart: Boundary not found' }) + t.assert.ok('end') }) }) diff --git a/test/multipart-stream-pause.test.js b/test/multipart-stream-pause.test.js index 856cf71..4b17411 100644 --- a/test/multipart-stream-pause.test.js +++ b/test/multipart-stream-pause.test.js @@ -1,7 +1,7 @@ 'use strict' const { inspect } = require('util') -const { test } = require('tap') +const { test } = require('node:test') const Busboy = require('..') @@ -22,7 +22,7 @@ function formDataFile (key, filename, contentType) { ]) } -test('multipart-stream-pause - processes stream correctly', t => { +test('multipart-stream-pause - processes stream correctly', async t => { t.plan(6) const reqChunks = [ Buffer.concat([ @@ -32,51 +32,54 @@ test('multipart-stream-pause - processes stream correctly', t => { formDataSection('bar', 'bar value'), Buffer.from('\r\n--' + BOUNDARY + '--\r\n') ] - const busboy = new Busboy({ - headers: { - 'content-type': 'multipart/form-data; boundary=' + BOUNDARY - } - }) - let finishes = 0 - const results = [] - const expected = [ - ['file', 'file', 'file.bin', '7bit', 'application/octet-stream'], - ['field', 'foo', 'foo value', false, false, '7bit', 'text/plain'], - ['field', 'bar', 'bar value', false, false, '7bit', 'text/plain'] - ] + await new Promise((resolve) => { + const busboy = new Busboy({ + headers: { + 'content-type': 'multipart/form-data; boundary=' + BOUNDARY + } + }) + let finishes = 0 + const results = [] + const expected = [ + ['file', 'file', 'file.bin', '7bit', 'application/octet-stream'], + ['field', 'foo', 'foo value', false, false, '7bit', 'text/plain'], + ['field', 'bar', 'bar value', false, false, '7bit', 'text/plain'] + ] - busboy.on('field', function (key, val, keyTrunc, valTrunc, encoding, contype) { - results.push(['field', key, val, keyTrunc, valTrunc, encoding, contype]) - }) - busboy.on('file', function (fieldname, stream, filename, encoding, mimeType) { - results.push(['file', fieldname, filename, encoding, mimeType]) - // Simulate a pipe where the destination is pausing (perhaps due to waiting - // for file system write to finish) - setTimeout(function () { - stream.resume() - }, 10) - }) - busboy.on('finish', function () { - t.ok(finishes++ === 0, 'finish emitted multiple times') - t.strictSame(results.length, - expected.length, - 'Parsed result count mismatch. Saw ' + + busboy.on('field', function (key, val, keyTrunc, valTrunc, encoding, contype) { + results.push(['field', key, val, keyTrunc, valTrunc, encoding, contype]) + }) + busboy.on('file', function (fieldname, stream, filename, encoding, mimeType) { + results.push(['file', fieldname, filename, encoding, mimeType]) + // Simulate a pipe where the destination is pausing (perhaps due to waiting + // for file system write to finish) + setTimeout(function () { + stream.resume() + }, 10) + }) + busboy.on('finish', function () { + t.assert.ok(finishes++ === 0, 'finish emitted multiple times') + t.assert.deepStrictEqual(results.length, + expected.length, + 'Parsed result count mismatch. Saw ' + results.length + '. Expected: ' + expected.length) - results.forEach(function (result, i) { - t.strictSame(result, - expected[i], - 'Result mismatch:\nParsed: ' + inspect(result) + + results.forEach(function (result, i) { + t.assert.deepStrictEqual(result, + expected[i], + 'Result mismatch:\nParsed: ' + inspect(result) + '\nExpected: ' + inspect(expected[i])) + }) + t.assert.ok('pass') + resolve() + }).on('error', function (err) { + t.assert.ifError(err) }) - t.pass() - }).on('error', function (err) { - t.error(err) - }) - reqChunks.forEach(function (buf) { - busboy.write(buf) + reqChunks.forEach(function (buf) { + busboy.write(buf) + }) + busboy.end() }) - busboy.end() }) diff --git a/test/parse-params.test.js b/test/parse-params.test.js index 3b6bc98..b744bdb 100644 --- a/test/parse-params.test.js +++ b/test/parse-params.test.js @@ -1,10 +1,10 @@ 'use strict' const { inspect } = require('node:util') -const { test } = require('tap') +const { test } = require('node:test') const parseParams = require('../lib/utils/parseParams') -test('parse-params', t => { +test('parse-params', async t => { const tests = [ { source: 'video/ogg', @@ -120,15 +120,15 @@ test('parse-params', t => { t.plan(tests.length) - tests.forEach((v) => { - t.test(v.what, t => { + for (const v of tests) { + await t.test(v.what, t => { t.plan(1) const result = parseParams(v.source) - t.strictSame( + t.assert.deepStrictEqual( result, v.expected, `parsed parameters match.\nSaw: ${inspect(result)}\nExpected: ${inspect(v.expected)}`) }) - }) + } }) diff --git a/test/streamsearch.test.js b/test/streamsearch.test.js index bc9f01c..7327fa9 100644 --- a/test/streamsearch.test.js +++ b/test/streamsearch.test.js @@ -1,33 +1,33 @@ 'use strict' -const { test } = require('tap') +const { test } = require('node:test') const Streamsearch = require('../deps/streamsearch/sbmh') -test('streamsearch', t => { +test('streamsearch', async t => { t.plan(18) - t.test('should throw an error if the needle is not a String or Buffer', t => { + await t.test('should throw an error if the needle is not a String or Buffer', t => { t.plan(1) - t.throws(() => new Streamsearch(2), new Error('The needle has to be a String or a Buffer.')) + t.assert.throws(() => new Streamsearch(2), { message: 'The needle has to be a String or a Buffer.' }) }) - t.test('should throw an error if the needle is an empty String', t => { + await t.test('should throw an error if the needle is an empty String', t => { t.plan(1) - t.throws(() => new Streamsearch(''), new Error('The needle cannot be an empty String/Buffer.')) + t.assert.throws(() => new Streamsearch(''), { message: 'The needle cannot be an empty String/Buffer.' }) }) - t.test('should throw an error if the needle is an empty Buffer', t => { + await t.test('should throw an error if the needle is an empty Buffer', t => { t.plan(1) - t.throws(() => new Streamsearch(Buffer.from('')), new Error('The needle cannot be an empty String/Buffer.')) + t.assert.throws(() => new Streamsearch(Buffer.from('')), { message: 'The needle cannot be an empty String/Buffer.' }) }) - t.test('should throw an error if the needle is bigger than 256 characters', t => { + await t.test('should throw an error if the needle is bigger than 256 characters', t => { t.plan(1) - t.throws(() => new Streamsearch(Buffer.from(Array(257).fill('a').join(''))), new Error('The needle cannot have a length bigger than 256.')) + t.assert.throws(() => new Streamsearch(Buffer.from(Array(257).fill('a').join(''))), { message: 'The needle cannot have a length bigger than 256.' }) }) - t.test('should process a Buffer without a needle', t => { + await t.test('should process a Buffer without a needle', t => { t.plan(5) const expected = [ [false, Buffer.from('bar hello'), 0, 9] @@ -39,20 +39,20 @@ test('streamsearch', t => { ] let i = 0 s.on('info', (isMatched, data, start, end) => { - t.strictSame(isMatched, expected[i][0]) - t.strictSame(data, expected[i][1]) - t.strictSame(start, expected[i][2]) - t.strictSame(end, expected[i][3]) + t.assert.deepStrictEqual(isMatched, expected[i][0]) + t.assert.deepStrictEqual(data, expected[i][1]) + t.assert.deepStrictEqual(start, expected[i][2]) + t.assert.deepStrictEqual(end, expected[i][3]) i++ if (i >= 1) { - t.pass() + t.assert.ok('pass') } }) s.push(chunks[0]) }) - t.test('should cast a string without a needle', t => { + await t.test('should cast a string without a needle', t => { t.plan(5) const expected = [ @@ -65,20 +65,20 @@ test('streamsearch', t => { ] let i = 0 s.on('info', (isMatched, data, start, end) => { - t.strictSame(isMatched, expected[i][0]) - t.strictSame(data, expected[i][1]) - t.strictSame(start, expected[i][2]) - t.strictSame(end, expected[i][3]) + t.assert.deepStrictEqual(isMatched, expected[i][0]) + t.assert.deepStrictEqual(data, expected[i][1]) + t.assert.deepStrictEqual(start, expected[i][2]) + t.assert.deepStrictEqual(end, expected[i][3]) i++ if (i >= 1) { - t.pass() + t.assert.ok('pass') } }) s.push(chunks[0]) }) - t.test('should process a chunk with a needle at the beginning', t => { + await t.test('should process a chunk with a needle at the beginning', t => { t.plan(9) const expected = [ @@ -92,20 +92,20 @@ test('streamsearch', t => { ] let i = 0 s.on('info', (isMatched, data, start, end) => { - t.strictSame(isMatched, expected[i][0]) - t.strictSame(data, expected[i][1]) - t.strictSame(start, expected[i][2]) - t.strictSame(end, expected[i][3]) + t.assert.deepStrictEqual(isMatched, expected[i][0]) + t.assert.deepStrictEqual(data, expected[i][1]) + t.assert.deepStrictEqual(start, expected[i][2]) + t.assert.deepStrictEqual(end, expected[i][3]) i++ if (i >= 2) { - t.pass() + t.assert.ok('pass') } }) s.push(chunks[0]) }) - t.test('should process a chunk with a needle in the middle', t => { + await t.test('should process a chunk with a needle in the middle', t => { t.plan(9) const expected = [ [true, Buffer.from('bar\r\n hello'), 0, 3], @@ -118,20 +118,20 @@ test('streamsearch', t => { ] let i = 0 s.on('info', (isMatched, data, start, end) => { - t.strictSame(isMatched, expected[i][0]) - t.strictSame(data, expected[i][1]) - t.strictSame(start, expected[i][2]) - t.strictSame(end, expected[i][3]) + t.assert.deepStrictEqual(isMatched, expected[i][0]) + t.assert.deepStrictEqual(data, expected[i][1]) + t.assert.deepStrictEqual(start, expected[i][2]) + t.assert.deepStrictEqual(end, expected[i][3]) i++ if (i >= 2) { - t.pass() + t.assert.ok('pass') } }) s.push(chunks[0]) }) - t.test('should process a chunk with a needle at the end', t => { + await t.test('should process a chunk with a needle at the end', t => { t.plan(5) const expected = [ [true, Buffer.from('bar hello\r\n'), 0, 9] @@ -143,20 +143,20 @@ test('streamsearch', t => { ] let i = 0 s.on('info', (isMatched, data, start, end) => { - t.strictSame(isMatched, expected[i][0]) - t.strictSame(data, expected[i][1]) - t.strictSame(start, expected[i][2]) - t.strictSame(end, expected[i][3]) + t.assert.deepStrictEqual(isMatched, expected[i][0]) + t.assert.deepStrictEqual(data, expected[i][1]) + t.assert.deepStrictEqual(start, expected[i][2]) + t.assert.deepStrictEqual(end, expected[i][3]) i++ if (i >= 1) { - t.pass() + t.assert.ok('pass') } }) s.push(chunks[0]) }) - t.test('should process a chunk with multiple needle at the end', t => { + await t.test('should process a chunk with multiple needle at the end', t => { t.plan(9) const expected = [ [true, Buffer.from('bar hello\r\n\r\n'), 0, 9], @@ -169,20 +169,20 @@ test('streamsearch', t => { ] let i = 0 s.on('info', (isMatched, data, start, end) => { - t.strictSame(isMatched, expected[i][0]) - t.strictSame(data, expected[i][1]) - t.strictSame(start, expected[i][2]) - t.strictSame(end, expected[i][3]) + t.assert.deepStrictEqual(isMatched, expected[i][0]) + t.assert.deepStrictEqual(data, expected[i][1]) + t.assert.deepStrictEqual(start, expected[i][2]) + t.assert.deepStrictEqual(end, expected[i][3]) i++ if (i >= 2) { - t.pass() + t.assert.ok('pass') } }) s.push(chunks[0]) }) - t.test('should process two chunks without a needle', t => { + await t.test('should process two chunks without a needle', t => { t.plan(9) const expected = [ [false, Buffer.from('bar'), 0, 3], @@ -196,13 +196,13 @@ test('streamsearch', t => { ] let i = 0 s.on('info', (isMatched, data, start, end) => { - t.strictSame(isMatched, expected[i][0]) - t.strictSame(data, expected[i][1]) - t.strictSame(start, expected[i][2]) - t.strictSame(end, expected[i][3]) + t.assert.deepStrictEqual(isMatched, expected[i][0]) + t.assert.deepStrictEqual(data, expected[i][1]) + t.assert.deepStrictEqual(start, expected[i][2]) + t.assert.deepStrictEqual(end, expected[i][3]) i++ if (i >= 2) { - t.pass() + t.assert.ok('pass') } }) @@ -210,7 +210,7 @@ test('streamsearch', t => { s.push(chunks[1]) }) - t.test('should process two chunks with an overflowing needle', t => { + await t.test('should process two chunks with an overflowing needle', t => { t.plan(13) const expected = [ [false, Buffer.from('bar\r'), 0, 3], @@ -225,13 +225,13 @@ test('streamsearch', t => { ] let i = 0 s.on('info', (isMatched, data, start, end) => { - t.strictSame(isMatched, expected[i][0]) - t.strictSame(data, expected[i][1]) - t.strictSame(start, expected[i][2]) - t.strictSame(end, expected[i][3]) + t.assert.deepStrictEqual(isMatched, expected[i][0]) + t.assert.deepStrictEqual(data, expected[i][1]) + t.assert.deepStrictEqual(start, expected[i][2]) + t.assert.deepStrictEqual(end, expected[i][3]) i++ if (i >= 3) { - t.pass() + t.assert.ok('pass') } }) @@ -239,7 +239,7 @@ test('streamsearch', t => { s.push(chunks[1]) }) - t.test('should process two chunks with a potentially overflowing needle', t => { + await t.test('should process two chunks with a potentially overflowing needle', t => { t.plan(13) const expected = [ @@ -255,13 +255,13 @@ test('streamsearch', t => { ] let i = 0 s.on('info', (isMatched, data, start, end) => { - t.strictSame(isMatched, expected[i][0]) - t.strictSame(data, expected[i][1]) - t.strictSame(start, expected[i][2]) - t.strictSame(end, expected[i][3]) + t.assert.deepStrictEqual(isMatched, expected[i][0]) + t.assert.deepStrictEqual(data, expected[i][1]) + t.assert.deepStrictEqual(start, expected[i][2]) + t.assert.deepStrictEqual(end, expected[i][3]) i++ if (i >= 3) { - t.pass() + t.assert.ok('pass') } }) @@ -269,7 +269,7 @@ test('streamsearch', t => { s.push(chunks[1]) }) - t.test('should process three chunks with a overflowing needle', t => { + await t.test('should process three chunks with a overflowing needle', t => { t.plan(13) const expected = [ @@ -286,13 +286,13 @@ test('streamsearch', t => { ] let i = 0 s.on('info', (isMatched, data, start, end) => { - t.strictSame(isMatched, expected[i][0]) - t.strictSame(data, expected[i][1]) - t.strictSame(start, expected[i][2]) - t.strictSame(end, expected[i][3]) + t.assert.deepStrictEqual(isMatched, expected[i][0]) + t.assert.deepStrictEqual(data, expected[i][1]) + t.assert.deepStrictEqual(start, expected[i][2]) + t.assert.deepStrictEqual(end, expected[i][3]) i++ if (i >= 3) { - t.pass() + t.assert.ok('pass') } }) @@ -301,7 +301,7 @@ test('streamsearch', t => { s.push(chunks[2]) }) - t.test('should process four chunks with a overflowing needle', t => { + await t.test('should process four chunks with a overflowing needle', t => { t.plan(13) const expected = [ @@ -319,13 +319,13 @@ test('streamsearch', t => { ] let i = 0 s.on('info', (isMatched, data, start, end) => { - t.strictSame(isMatched, expected[i][0]) - t.strictSame(data, expected[i][1]) - t.strictSame(start, expected[i][2]) - t.strictSame(end, expected[i][3]) + t.assert.deepStrictEqual(isMatched, expected[i][0]) + t.assert.deepStrictEqual(data, expected[i][1]) + t.assert.deepStrictEqual(start, expected[i][2]) + t.assert.deepStrictEqual(end, expected[i][3]) i++ if (i >= 3) { - t.pass() + t.assert.ok('pass') } }) @@ -335,7 +335,7 @@ test('streamsearch', t => { s.push(chunks[3]) }) - t.test('should process four chunks with repeted starting overflowing needle', t => { + await t.test('should process four chunks with repeted starting overflowing needle', t => { t.plan(13) const expected = [ @@ -353,13 +353,13 @@ test('streamsearch', t => { ] let i = 0 s.on('info', (isMatched, data, start, end) => { - t.strictSame(isMatched, expected[i][0]) - t.strictSame(data, expected[i][1]) - t.strictSame(start, expected[i][2]) - t.strictSame(end, expected[i][3]) + t.assert.deepStrictEqual(isMatched, expected[i][0]) + t.assert.deepStrictEqual(data, expected[i][1]) + t.assert.deepStrictEqual(start, expected[i][2]) + t.assert.deepStrictEqual(end, expected[i][3]) i++ if (i >= 3) { - t.pass() + t.assert.ok('pass') } }) @@ -369,7 +369,7 @@ test('streamsearch', t => { s.push(chunks[3]) }) - t.test('should process four chunks with a potentially overflowing needle', t => { + await t.test('should process four chunks with a potentially overflowing needle', t => { t.plan(17) const expected = [ @@ -388,13 +388,13 @@ test('streamsearch', t => { ] let i = 0 s.on('info', (isMatched, data, start, end) => { - t.strictSame(isMatched, expected[i][0]) - t.strictSame(data, expected[i][1]) - t.strictSame(start, expected[i][2]) - t.strictSame(end, expected[i][3]) + t.assert.deepStrictEqual(isMatched, expected[i][0]) + t.assert.deepStrictEqual(data, expected[i][1]) + t.assert.deepStrictEqual(start, expected[i][2]) + t.assert.deepStrictEqual(end, expected[i][3]) i++ if (i >= 4) { - t.pass() + t.assert.ok('pass') } }) @@ -404,27 +404,27 @@ test('streamsearch', t => { s.push(chunks[3]) }) - t.test('should reset the internal values if .reset() is called', t => { + await t.test('should reset the internal values if .reset() is called', t => { t.plan(9) const s = new Streamsearch('test') - t.strictSame(s._lookbehind_size, 0) - t.strictSame(s.matches, 0) - t.strictSame(s._bufpos, 0) + t.assert.deepStrictEqual(s._lookbehind_size, 0) + t.assert.deepStrictEqual(s.matches, 0) + t.assert.deepStrictEqual(s._bufpos, 0) s._lookbehind_size = 1 s._bufpos = 1 s.matches = 1 - t.strictSame(s._lookbehind_size, 1) - t.strictSame(s.matches, 1) - t.strictSame(s._bufpos, 1) + t.assert.deepStrictEqual(s._lookbehind_size, 1) + t.assert.deepStrictEqual(s.matches, 1) + t.assert.deepStrictEqual(s._bufpos, 1) s.reset() - t.strictSame(s._lookbehind_size, 0) - t.strictSame(s.matches, 0) - t.strictSame(s._bufpos, 0) + t.assert.deepStrictEqual(s._lookbehind_size, 0) + t.assert.deepStrictEqual(s.matches, 0) + t.assert.deepStrictEqual(s._bufpos, 0) }) }) diff --git a/test/types-multipart.test.js b/test/types-multipart.test.js index dc7ae88..9e47459 100644 --- a/test/types-multipart.test.js +++ b/test/types-multipart.test.js @@ -2,7 +2,7 @@ const Busboy = require('..') -const { test } = require('tap') +const { test } = require('node:test') const { inspect } = require('util') const EMPTY_FN = function () { @@ -608,71 +608,76 @@ const tests = [ } ] -tests.forEach((v) => { - test(v.what, t => { - t.plan(v.plan) - const busboy = new Busboy({ - ...v.config, - limits: v.limits, - preservePath: v.preservePath, - headers: { - 'content-type': 'multipart/form-data; boundary=' + v.boundary - } - }) - let finishes = 0 - const results = [] - - if (v.events === undefined || v.events.indexOf('field') > -1) { - busboy.on('field', function (key, val, keyTrunc, valTrunc, encoding, contype) { - results.push(['field', key, val, keyTrunc, valTrunc, encoding, contype]) - }) - } - if (v.events === undefined || v.events.indexOf('file') > -1) { - busboy.on('file', function (fieldname, stream, filename, encoding, mimeType) { - let nb = 0 - const info = ['file', - fieldname, - nb, - 0, - filename, - encoding, - mimeType] - results.push(info) - stream.on('data', function (d) { - nb += d.length - }).on('limit', function () { - ++info[3] - }).on('end', function () { - info[2] = nb - t.ok(typeof (stream.bytesRead) === 'number', 'file.bytesRead is missing') - t.ok(stream.bytesRead === nb, 'file.bytesRead is not equal to filesize') - if (stream.truncated) { ++info[3] } +test('types-multipart.test', async t => { + for (const v of tests) { + await t.test(v.what, async t => { + t.plan(v.plan) + await new Promise((resolve) => { + const busboy = new Busboy({ + ...v.config, + limits: v.limits, + preservePath: v.preservePath, + headers: { + 'content-type': 'multipart/form-data; boundary=' + v.boundary + } }) - }) - } - busboy.on('finish', function () { - t.ok(finishes++ === 0, 'finish emitted multiple times') - t.equal(results.length, - v.expected.length, - 'Parsed result count mismatch. Saw ' + + let finishes = 0 + const results = [] + + if (v.events === undefined || v.events.indexOf('field') > -1) { + busboy.on('field', function (key, val, keyTrunc, valTrunc, encoding, contype) { + results.push(['field', key, val, keyTrunc, valTrunc, encoding, contype]) + }) + } + if (v.events === undefined || v.events.indexOf('file') > -1) { + busboy.on('file', function (fieldname, stream, filename, encoding, mimeType) { + let nb = 0 + const info = ['file', + fieldname, + nb, + 0, + filename, + encoding, + mimeType] + results.push(info) + stream.on('data', function (d) { + nb += d.length + }).on('limit', function () { + ++info[3] + }).on('end', function () { + info[2] = nb + t.assert.ok(typeof (stream.bytesRead) === 'number', 'file.bytesRead is missing') + t.assert.ok(stream.bytesRead === nb, 'file.bytesRead is not.assert.strictEqual to filesize') + if (stream.truncated) { ++info[3] } + }) + }) + } + busboy.on('finish', function () { + t.assert.ok(finishes++ === 0, 'finish emitted multiple times') + t.assert.strictEqual(results.length, + v.expected.length, + 'Parsed result count mismatch. Saw ' + results.length + '. Expected: ' + v.expected.length) - results.forEach(function (result, i) { - t.strictSame(result, - v.expected[i], - 'Result mismatch:\nParsed: ' + inspect(result) + + results.forEach(function (result, i) { + t.assert.deepStrictEqual(result, + v.expected[i], + 'Result mismatch:\nParsed: ' + inspect(result) + '\nExpected: ' + inspect(v.expected[i]) - ) - }) - t.pass() - }).on('error', function (err) { - if (!v.shouldError || v.shouldError !== err.message) { t.error(err) } - }) + ) + }) + t.assert.ok('pass') + resolve() + }).on('error', function (err) { + if (!v.shouldError || v.shouldError !== err.message) { t.assert.ifError(err) } + }) - v.source.forEach(function (s) { - busboy.write(Buffer.from(s, 'utf8'), EMPTY_FN) + v.source.forEach(function (s) { + busboy.write(Buffer.from(s, 'utf8'), EMPTY_FN) + }) + busboy.end() + }) }) - busboy.end() - }) + } }) diff --git a/test/types-urlencoded.test.js b/test/types-urlencoded.test.js index 7673aef..6600f0b 100644 --- a/test/types-urlencoded.test.js +++ b/test/types-urlencoded.test.js @@ -2,7 +2,7 @@ const { inspect } = require('util') const Busboy = require('..') -const { test } = require('tap') +const { test } = require('node:test') const EMPTY_FN = function () { } @@ -198,88 +198,93 @@ const tests = [ } ] -tests.forEach((v) => { - test(v.what, t => { - t.plan(v.plan || 20) - const busboy = new Busboy({ - limits: v.limits, - headers: { - 'content-type': 'application/x-www-form-urlencoded; charset=utf-8' - } - }) - let finishes = 0 - const results = [] +test('types-urlencoded', async t => { + for (const v of tests) { + await t.test(v.what, async t => { + t.plan(v.plan || 20) + const busboy = new Busboy({ + limits: v.limits, + headers: { + 'content-type': 'application/x-www-form-urlencoded; charset=utf-8' + } + }) + await new Promise((resolve) => { + let finishes = 0 + const results = [] - busboy.on('field', function (key, val, keyTrunc, valTrunc) { - results.push([key, val, keyTrunc, valTrunc]) - }) - busboy.on('file', function () { - throw new Error('Unexpected file') - }) - busboy.on('finish', function () { - t.ok(finishes++ === 0, 'finish emitted multiple times') - t.equal(results.length, v.expected.length) + busboy.on('field', function (key, val, keyTrunc, valTrunc) { + results.push([key, val, keyTrunc, valTrunc]) + }) + busboy.on('file', function () { + throw new Error('Unexpected file') + }) + busboy.on('finish', function () { + t.assert.ok(finishes++ === 0, 'finish emitted multiple times') + t.assert.strictEqual(results.length, v.expected.length) - let i = 0 - results.forEach(function (result) { - t.strictSame(result, - v.expected[i], - 'Result mismatch:\nParsed: ' + inspect(result) + + let i = 0 + results.forEach(function (result) { + t.assert.deepStrictEqual(result, + v.expected[i], + 'Result mismatch:\nParsed: ' + inspect(result) + '\nExpected: ' + inspect(v.expected[i]) - ) - ++i + ) + ++i + }) + t.assert.ok('pass') + resolve() + }) + + v.source.forEach(function (s) { + busboy.write(Buffer.from(s, 'utf8'), EMPTY_FN) + }) + busboy.end() }) - t.pass() }) + } + + await t.test('Call parser end twice', t => { + t.plan(1) - v.source.forEach(function (s) { - busboy.write(Buffer.from(s, 'utf8'), EMPTY_FN) + let finishes = 0 + const busboy = new Busboy({ + headers: { + 'content-type': 'application/x-www-form-urlencoded; charset=utf-8' + } }) - busboy.end() - }) -}) -test('Call parser end twice', t => { - t.plan(1) + busboy.on('finish', function () { + t.assert.ok(++finishes === 1, 'finish emitted') + }) - let finishes = 0 - const busboy = new Busboy({ - headers: { - 'content-type': 'application/x-www-form-urlencoded; charset=utf-8' - } - }) + busboy.write(Buffer.from('Hello world', 'utf8'), EMPTY_FN) - busboy.on('finish', function () { - t.ok(++finishes === 1, 'finish emitted') + busboy._parser.end() + busboy._parser.end() }) - busboy.write(Buffer.from('Hello world', 'utf8'), EMPTY_FN) + await t.test('Call emit finish twice', t => { + t.plan(2) - busboy._parser.end() - busboy._parser.end() -}) + let fields = 0 + let finishes = 0 -test('Call emit finish twice', t => { - t.plan(2) + const busboy = new Busboy({ + headers: { + 'content-type': 'application/x-www-form-urlencoded; charset=utf-8' + } + }) + busboy.on('field', function () { + t.assert.ok(++fields === 1, 'field emitted') + }) - let fields = 0 - let finishes = 0 + busboy.on('finish', function () { + t.assert.ok(++finishes === 1, 'finish emitted') + }) - const busboy = new Busboy({ - headers: { - 'content-type': 'application/x-www-form-urlencoded; charset=utf-8' - } - }) - busboy.on('field', function () { - t.ok(++fields === 1, 'field emitted') - }) + busboy.write(Buffer.from('Hello world', 'utf8'), EMPTY_FN) - busboy.on('finish', function () { - t.ok(++finishes === 1, 'finish emitted') + busboy.emit('finish') + busboy.emit('finish') }) - - busboy.write(Buffer.from('Hello world', 'utf8'), EMPTY_FN) - - busboy.emit('finish') - busboy.emit('finish') })