From a7f082414e63989e754415d1dea156f43b124daf Mon Sep 17 00:00:00 2001 From: Aras Abbasi Date: Mon, 12 Feb 2024 16:01:02 +0100 Subject: [PATCH] chore: migrate a batch of tests to node test runner (#2744) --- test/client-pipeline.js | 380 ++++++++++++++++++++-------------- test/client-pipelining.js | 226 +++++++++++--------- test/client-timeout.js | 57 ++--- test/client-upgrade.js | 163 ++++++++------- test/get-head-body.js | 65 +++--- test/http2-alpn.js | 19 +- test/http2.js | 423 ++++++++++++++++++++------------------ test/readable.test.js | 2 +- test/request.js | 181 ++++++++-------- 9 files changed, 838 insertions(+), 678 deletions(-) diff --git a/test/client-pipeline.js b/test/client-pipeline.js index cbc78b9270d..bc2cd1d3a95 100644 --- a/test/client-pipeline.js +++ b/test/client-pipeline.js @@ -1,6 +1,7 @@ 'use strict' -const { test } = require('tap') +const { tspl } = require('@matteo.collina/tspl') +const { test, after } = require('node:test') const { Client, errors } = require('..') const EE = require('node:events') const { createServer } = require('node:http') @@ -12,30 +13,30 @@ const { PassThrough } = require('node:stream') -test('pipeline get', (t) => { - t.plan(17) +test('pipeline get', async (t) => { + t = tspl(t, { plan: 17 }) const server = createServer((req, res) => { - t.equal('/', req.url) - t.equal('GET', req.method) - t.equal(`localhost:${server.address().port}`, req.headers.host) - t.equal(undefined, req.headers['content-length']) + t.strictEqual('/', req.url) + t.strictEqual('GET', req.method) + t.strictEqual(`localhost:${server.address().port}`, req.headers.host) + t.strictEqual(undefined, req.headers['content-length']) res.setHeader('Content-Type', 'text/plain') res.end('hello') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) { const bufs = [] const signal = new EE() client.pipeline({ signal, path: '/', method: 'GET' }, ({ statusCode, headers, body }) => { - t.equal(statusCode, 200) - t.equal(headers['content-type'], 'text/plain') - t.equal(signal.listenerCount('abort'), 1) + t.strictEqual(statusCode, 200) + t.strictEqual(headers['content-type'], 'text/plain') + t.strictEqual(signal.listenerCount('abort'), 1) return body }) .end() @@ -43,19 +44,19 @@ test('pipeline get', (t) => { bufs.push(buf) }) .on('end', () => { - t.equal('hello', Buffer.concat(bufs).toString('utf8')) + t.strictEqual('hello', Buffer.concat(bufs).toString('utf8')) }) .on('close', () => { - t.equal(signal.listenerCount('abort'), 0) + t.strictEqual(signal.listenerCount('abort'), 0) }) - t.equal(signal.listenerCount('abort'), 1) + t.strictEqual(signal.listenerCount('abort'), 1) } { const bufs = [] client.pipeline({ path: '/', method: 'GET' }, ({ statusCode, headers, body }) => { - t.equal(statusCode, 200) - t.equal(headers['content-type'], 'text/plain') + t.strictEqual(statusCode, 200) + t.strictEqual(headers['content-type'], 'text/plain') return body }) .end() @@ -63,23 +64,25 @@ test('pipeline get', (t) => { bufs.push(buf) }) .on('end', () => { - t.equal('hello', Buffer.concat(bufs).toString('utf8')) + t.strictEqual('hello', Buffer.concat(bufs).toString('utf8')) }) } }) + + await t.completed }) -test('pipeline echo', (t) => { - t.plan(2) +test('pipeline echo', async (t) => { + t = tspl(t, { plan: 2 }) const server = createServer((req, res) => { req.pipe(res) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) let res = '' const buf1 = Buffer.alloc(1e3).toString() @@ -104,19 +107,21 @@ test('pipeline echo', (t) => { callback() }, final (callback) { - t.equal(res, buf1 + buf2) + t.strictEqual(res, buf1 + buf2) callback() } }), (err) => { - t.error(err) + t.ifError(err) } ) }) + + await t.completed }) -test('pipeline ignore request body', (t) => { - t.plan(2) +test('pipeline ignore request body', async (t) => { + t = tspl(t, { plan: 2 }) let done const server = createServer((req, res) => { @@ -124,11 +129,11 @@ test('pipeline ignore request body', (t) => { res.end() done() }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) let res = '' const buf1 = Buffer.alloc(1e3).toString() @@ -153,71 +158,77 @@ test('pipeline ignore request body', (t) => { callback() }, final (callback) { - t.equal(res, 'asd') + t.strictEqual(res, 'asd') callback() } }), (err) => { - t.error(err) + t.ifError(err) } ) }) + + await t.completed }) -test('pipeline invalid handler', (t) => { - t.plan(1) +test('pipeline invalid handler', async (t) => { + t = tspl(t, { plan: 1 }) const client = new Client('http://localhost:5000') client.pipeline({}, null).on('error', (err) => { t.ok(/handler/.test(err)) }) + + await t.completed }) -test('pipeline invalid handler return after destroy should not error', (t) => { - t.plan(3) +test('pipeline invalid handler return after destroy should not error', async (t) => { + t = tspl(t, { plan: 3 }) const server = createServer((req, res) => { req.pipe(res) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 3 }) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) const dup = client.pipeline({ path: '/', method: 'GET' }, ({ body }) => { body.on('error', (err) => { - t.equal(err.message, 'asd') + t.strictEqual(err.message, 'asd') }) dup.destroy(new Error('asd')) return {} }) .on('error', (err) => { - t.equal(err.message, 'asd') + t.strictEqual(err.message, 'asd') }) .on('close', () => { t.ok(true, 'pass') }) .end() }) + + await t.completed }) -test('pipeline error body', (t) => { - t.plan(2) +test('pipeline error body', async (t) => { + t = tspl(t, { plan: 2 }) const server = createServer((req, res) => { req.pipe(res) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) const buf = Buffer.alloc(1e6).toString() pipeline( @@ -245,19 +256,21 @@ test('pipeline error body', (t) => { } ) }) + + await t.completed }) -test('pipeline destroy body', (t) => { - t.plan(2) +test('pipeline destroy body', async (t) => { + t = tspl(t, { plan: 2 }) const server = createServer((req, res) => { req.pipe(res) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) const buf = Buffer.alloc(1e6).toString() pipeline( @@ -285,19 +298,21 @@ test('pipeline destroy body', (t) => { } ) }) + + await t.completed }) -test('pipeline backpressure', (t) => { - t.plan(1) +test('pipeline backpressure', async (t) => { + t = tspl(t, { plan: 1 }) const server = createServer((req, res) => { req.pipe(res) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) const buf = Buffer.alloc(1e6).toString() const duplex = client.pipeline({ @@ -318,19 +333,21 @@ test('pipeline backpressure', (t) => { t.ok(true, 'pass') }) }) + + await t.completed }) -test('pipeline invalid handler return', (t) => { - t.plan(2) +test('pipeline invalid handler return', async (t) => { + t = tspl(t, { plan: 2 }) const server = createServer((req, res) => { req.pipe(res) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.pipeline({ path: '/', @@ -357,19 +374,21 @@ test('pipeline invalid handler return', (t) => { }) .end() }) + + await t.completed }) -test('pipeline throw handler', (t) => { - t.plan(1) +test('pipeline throw handler', async (t) => { + t = tspl(t, { plan: 1 }) const server = createServer((req, res) => { req.pipe(res) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.pipeline({ path: '/', @@ -380,23 +399,25 @@ test('pipeline throw handler', (t) => { throw new Error('asd') }) .on('error', (err) => { - t.equal(err.message, 'asd') + t.strictEqual(err.message, 'asd') }) .end() }) + + await t.completed }) -test('pipeline destroy and throw handler', (t) => { - t.plan(2) +test('pipeline destroy and throw handler', async (t) => { + t = tspl(t, { plan: 2 }) const server = createServer((req, res) => { req.pipe(res) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) const dup = client.pipeline({ path: '/', @@ -415,21 +436,23 @@ test('pipeline destroy and throw handler', (t) => { t.ok(true, 'pass') }) }) + + await t.completed }) -test('pipeline abort res', (t) => { - t.plan(2) +test('pipeline abort res', async (t) => { + t = tspl(t, { plan: 2 }) let _res const server = createServer((req, res) => { res.write('asd') _res = res }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.pipeline({ path: '/', @@ -453,19 +476,21 @@ test('pipeline abort res', (t) => { }) .end() }) + + await t.completed }) -test('pipeline abort server res', (t) => { - t.plan(1) +test('pipeline abort server res', async (t) => { + t = tspl(t, { plan: 1 }) const server = createServer((req, res) => { res.destroy() }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.pipeline({ path: '/', @@ -478,25 +503,27 @@ test('pipeline abort server res', (t) => { }) .end() }) + + await t.completed }) -test('pipeline abort duplex', (t) => { - t.plan(2) +test('pipeline abort duplex', async (t) => { + t = tspl(t, { plan: 2 }) const server = createServer((req, res) => { res.end() }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.request({ path: '/', method: 'PUT' }, (err, data) => { - t.error(err) + t.ifError(err) data.body.resume() client.pipeline({ @@ -509,19 +536,21 @@ test('pipeline abort duplex', (t) => { }) }) }) + + await t.completed }) -test('pipeline abort piped res', (t) => { - t.plan(1) +test('pipeline abort piped res', async (t) => { + t = tspl(t, { plan: 1 }) const server = createServer((req, res) => { res.write('asd') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.pipeline({ path: '/', @@ -534,23 +563,25 @@ test('pipeline abort piped res', (t) => { return pipeline(body, pt, () => {}) }) .on('error', (err) => { - t.equal(err.code, 'UND_ERR_ABORTED') + t.strictEqual(err.code, 'UND_ERR_ABORTED') }) .end() }) + + await t.completed }) -test('pipeline abort piped res 2', (t) => { - t.plan(2) +test('pipeline abort piped res 2', async (t) => { + t = tspl(t, { plan: 2 }) const server = createServer((req, res) => { res.write('asd') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.pipeline({ path: '/', @@ -571,19 +602,21 @@ test('pipeline abort piped res 2', (t) => { }) .end() }) + + await t.completed }) -test('pipeline abort piped res 3', (t) => { - t.plan(2) +test('pipeline abort piped res 3', async (t) => { + t = tspl(t, { plan: 2 }) const server = createServer((req, res) => { res.write('asd') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.pipeline({ path: '/', @@ -591,7 +624,7 @@ test('pipeline abort piped res 3', (t) => { }, ({ body }) => { const pt = new PassThrough() body.on('error', (err) => { - t.equal(err.message, 'asd') + t.strictEqual(err.message, 'asd') }) setImmediate(() => { pt.destroy(new Error('asd')) @@ -600,25 +633,27 @@ test('pipeline abort piped res 3', (t) => { return pt }) .on('error', (err) => { - t.equal(err.message, 'asd') + t.strictEqual(err.message, 'asd') }) .end() }) + + await t.completed }) -test('pipeline abort server res after headers', (t) => { - t.plan(1) +test('pipeline abort server res after headers', async (t) => { + t = tspl(t, { plan: 1 }) let _res const server = createServer((req, res) => { res.write('asd') _res = res }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.pipeline({ path: '/', @@ -632,21 +667,23 @@ test('pipeline abort server res after headers', (t) => { }) .end() }) + + await t.completed }) -test('pipeline w/ write abort server res after headers', (t) => { - t.plan(1) +test('pipeline w/ write abort server res after headers', async (t) => { + t = tspl(t, { plan: 1 }) let _res const server = createServer((req, res) => { req.pipe(res) _res = res }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.pipeline({ path: '/', @@ -661,21 +698,23 @@ test('pipeline w/ write abort server res after headers', (t) => { .resume() .write('asd') }) + + await t.completed }) -test('destroy in push', (t) => { - t.plan(3) +test('destroy in push', async (t) => { + t = tspl(t, { plan: 3 }) let _res const server = createServer((req, res) => { res.write('asd') _res = res }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) client.pipeline({ path: '/', method: 'GET' }, ({ body }) => { body.once('data', () => { @@ -698,15 +737,17 @@ test('destroy in push', (t) => { buf = chunk.toString() _res.end() }).on('end', () => { - t.equal('asd', buf) + t.strictEqual('asd', buf) }) return body }).resume().end() }) + + await t.completed }) -test('pipeline args validation', (t) => { - t.plan(2) +test('pipeline args validation', async (t) => { + t = tspl(t, { plan: 2 }) const client = new Client('http://localhost:5000') @@ -715,19 +756,21 @@ test('pipeline args validation', (t) => { t.ok(/opts/.test(err.message)) t.ok(err instanceof errors.InvalidArgumentError) }) + + await t.completed }) -test('pipeline factory throw not unhandled', (t) => { - t.plan(1) +test('pipeline factory throw not unhandled', async (t) => { + t = tspl(t, { plan: 1 }) const server = createServer((req, res) => { res.write('asd') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.pipeline({ path: '/', @@ -740,19 +783,21 @@ test('pipeline factory throw not unhandled', (t) => { }) .end() }) + + await t.completed }) -test('pipeline destroy before dispatch', (t) => { - t.plan(1) +test('pipeline destroy before dispatch', async (t) => { + t = tspl(t, { plan: 1 }) const server = createServer((req, res) => { res.end('hello') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client .pipeline({ path: '/', method: 'GET' }, ({ body }) => { @@ -764,10 +809,12 @@ test('pipeline destroy before dispatch', (t) => { .end() .destroy() }) + + await t.completed }) -test('pipeline legacy stream', (t) => { - t.plan(1) +test('pipeline legacy stream', async (t) => { + t = tspl(t, { plan: 1 }) const server = createServer((req, res) => { res.write(Buffer.alloc(16e3)) @@ -775,11 +822,11 @@ test('pipeline legacy stream', (t) => { res.end(Buffer.alloc(16e3)) }) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) client .pipeline({ path: '/', method: 'GET' }, ({ body }) => { @@ -793,19 +840,21 @@ test('pipeline legacy stream', (t) => { }) .end() }) + + await t.completed }) -test('pipeline objectMode', (t) => { - t.plan(1) +test('pipeline objectMode', async (t) => { + t = tspl(t, { plan: 1 }) const server = createServer((req, res) => { res.end(JSON.stringify({ asd: 1 })) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) client .pipeline({ path: '/', method: 'GET', objectMode: true }, ({ body }) => { @@ -817,26 +866,28 @@ test('pipeline objectMode', (t) => { }), () => {}) }) .on('data', data => { - t.strictSame(data, { asd: 1 }) + t.deepStrictEqual(data, { asd: 1 }) }) .end() }) + + await t.completed }) -test('pipeline invalid opts', (t) => { - t.plan(2) +test('pipeline invalid opts', async (t) => { + t = tspl(t, { plan: 2 }) const server = createServer((req, res) => { res.end(JSON.stringify({ asd: 1 })) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.close((err) => { - t.error(err) + t.ifError(err) }) client .pipeline({ path: '/', method: 'GET', objectMode: true }, ({ body }) => { @@ -846,19 +897,21 @@ test('pipeline invalid opts', (t) => { t.ok(err) }) }) + + await t.completed }) -test('pipeline CONNECT throw', (t) => { - t.plan(1) +test('pipeline CONNECT throw', async (t) => { + t = tspl(t, { plan: 1 }) const server = createServer((req, res) => { res.end('asd') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.pipeline({ path: '/', @@ -872,19 +925,21 @@ test('pipeline CONNECT throw', (t) => { t.fail() }) }) + + await t.completed }) -test('pipeline body without destroy', (t) => { - t.plan(1) +test('pipeline body without destroy', async (t) => { + t = tspl(t, { plan: 1 }) const server = createServer((req, res) => { res.end('asd') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.pipeline({ path: '/', @@ -900,20 +955,22 @@ test('pipeline body without destroy', (t) => { }) .resume() }) + + await t.completed }) -test('pipeline ignore 1xx', (t) => { - t.plan(1) +test('pipeline ignore 1xx', async (t) => { + t = tspl(t, { plan: 1 }) const server = createServer((req, res) => { res.writeProcessing() res.end('hello') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) let buf = '' client.pipeline({ @@ -924,24 +981,27 @@ test('pipeline ignore 1xx', (t) => { buf += chunk }) .on('end', () => { - t.equal(buf, 'hello') + t.strictEqual(buf, 'hello') }) .end() }) + + await t.completed }) -test('pipeline ignore 1xx and use onInfo', (t) => { - t.plan(3) + +test('pipeline ignore 1xx and use onInfo', async (t) => { + t = tspl(t, { plan: 3 }) const infos = [] const server = createServer((req, res) => { res.writeProcessing() res.end('hello') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) let buf = '' client.pipeline({ @@ -955,16 +1015,18 @@ test('pipeline ignore 1xx and use onInfo', (t) => { buf += chunk }) .on('end', () => { - t.equal(buf, 'hello') - t.equal(infos.length, 1) - t.equal(infos[0].statusCode, 102) + t.strictEqual(buf, 'hello') + t.strictEqual(infos.length, 1) + t.strictEqual(infos[0].statusCode, 102) }) .end() }) + + await t.completed }) -test('pipeline backpressure', (t) => { - t.plan(1) +test('pipeline backpressure', async (t) => { + t = tspl(t, { plan: 1 }) const expected = Buffer.alloc(1e6).toString() @@ -972,11 +1034,11 @@ test('pipeline backpressure', (t) => { res.writeProcessing() res.end(expected) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) let buf = '' client.pipeline({ @@ -996,13 +1058,15 @@ test('pipeline backpressure', (t) => { buf += chunk }) .on('end', () => { - t.equal(buf, expected) + t.strictEqual(buf, expected) }) }) + + await t.completed }) -test('pipeline abort after headers', (t) => { - t.plan(1) +test('pipeline abort after headers', async (t) => { + t = tspl(t, { plan: 1 }) const server = createServer((req, res) => { res.writeProcessing() @@ -1011,11 +1075,11 @@ test('pipeline abort after headers', (t) => { res.write('asd') }) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) const signal = new EE() client.pipeline({ @@ -1033,4 +1097,6 @@ test('pipeline abort after headers', (t) => { t.ok(err instanceof errors.RequestAbortedError) }) }) + + await t.completed }) diff --git a/test/client-pipelining.js b/test/client-pipelining.js index 25441407f43..475b826c62d 100644 --- a/test/client-pipelining.js +++ b/test/client-pipelining.js @@ -1,6 +1,7 @@ 'use strict' -const { test } = require('tap') +const { tspl } = require('@matteo.collina/tspl') +const { test, after } = require('node:test') const { Client } = require('..') const { createServer } = require('node:http') const { finished, Readable } = require('node:stream') @@ -9,9 +10,9 @@ const EE = require('node:events') const { kBusy, kRunning, kSize } = require('../lib/core/symbols') const { maybeWrapStream, consts } = require('./utils/async-iterators') -test('20 times GET with pipelining 10', (t) => { +test('20 times GET with pipelining 10', async (t) => { const num = 20 - t.plan(3 * num + 1) + t = tspl(t, { plan: 3 * num + 1 }) let count = 0 let countGreaterThanOne = false @@ -22,7 +23,7 @@ test('20 times GET with pipelining 10', (t) => { res.end(req.url) }, 10) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) // needed to check for a warning on the maxListeners on the socket function onWarning (warning) { @@ -31,7 +32,7 @@ test('20 times GET with pipelining 10', (t) => { } } process.on('warning', onWarning) - t.teardown(() => { + after(() => { process.removeListener('warning', onWarning) }) @@ -39,7 +40,7 @@ test('20 times GET with pipelining 10', (t) => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 10 }) - t.teardown(client.close.bind(client)) + after(() => client.close()) for (let i = 0; i < num; i++) { makeRequest(i) @@ -55,28 +56,30 @@ test('20 times GET with pipelining 10', (t) => { }) } }) + + await t.completed }) function makeRequestAndExpectUrl (client, i, t, cb) { return client.request({ path: '/' + i, method: 'GET' }, (err, { statusCode, headers, body }) => { cb() - t.error(err) - t.equal(statusCode, 200) + t.ifError(err) + t.strictEqual(statusCode, 200) const bufs = [] body.on('data', (buf) => { bufs.push(buf) }) body.on('end', () => { - t.equal('/' + i, Buffer.concat(bufs).toString('utf8')) + t.strictEqual('/' + i, Buffer.concat(bufs).toString('utf8')) }) }) } -test('A client should enqueue as much as twice its pipelining factor', (t) => { +test('A client should enqueue as much as twice its pipelining factor', async (t) => { const num = 10 let sent = 0 // x * 6 + 1 t.ok + 5 drain - t.plan(num * 6 + 1 + 5 + 2) + t = tspl(t, { plan: num * 6 + 1 + 5 + 2 }) let count = 0 let countGreaterThanOne = false @@ -88,22 +91,22 @@ test('A client should enqueue as much as twice its pipelining factor', (t) => { res.end(req.url) }, 10) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 2 }) - t.teardown(client.close.bind(client)) + after(() => client.close()) for (; sent < 2;) { - t.notOk(client[kSize] > client.pipelining, 'client is not full') + t.ok(client[kSize] <= client.pipelining, 'client is not full') makeRequest() t.ok(client[kSize] <= client.pipelining, 'we can send more requests') } t.ok(client[kBusy], 'client is busy') - t.notOk(client[kSize] > client.pipelining, 'client is full') + t.ok(client[kSize] <= client.pipelining, 'client is full') makeRequest() t.ok(client[kBusy], 'we must stop now') t.ok(client[kBusy], 'client is busy') @@ -117,7 +120,7 @@ test('A client should enqueue as much as twice its pipelining factor', (t) => { t.ok(countGreaterThanOne, 'seen more than one parallel request') const start = sent for (; sent < start + 2 && sent < num;) { - t.notOk(client[kSize] > client.pipelining, 'client is not full') + t.ok(client[kSize] <= client.pipelining, 'client is not full') t.ok(makeRequest()) } } @@ -126,54 +129,58 @@ test('A client should enqueue as much as twice its pipelining factor', (t) => { return client[kSize] <= client.pipelining } }) + + await t.completed }) -test('pipeline 1 is 1 active request', (t) => { - t.plan(9) +test('pipeline 1 is 1 active request', async (t) => { + t = tspl(t, { plan: 9 }) let res2 const server = createServer((req, res) => { res.write('asd') res2 = res }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 1 }) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.request({ path: '/', method: 'GET' }, (err, data) => { - t.equal(client[kSize], 1) - t.error(err) - t.notOk(client.request({ + t.strictEqual(client[kSize], 1) + t.ifError(err) + t.strictEqual(client.request({ path: '/', method: 'GET' }, (err, data) => { - t.error(err) + t.ifError(err) finished(data.body, (err) => { t.ok(err) client.close((err) => { - t.error(err) + t.ifError(err) }) }) data.body.destroy() res2.end() - })) + }), undefined) data.body.resume() res2.end() }) t.ok(client[kSize] <= client.pipelining) t.ok(client[kBusy]) - t.equal(client[kSize], 1) + t.strictEqual(client[kSize], 1) }) + + await t.completed }) -test('pipelined chunked POST stream', (t) => { - t.plan(4 + 8 + 8) +test('pipelined chunked POST stream', async (t) => { + t = tspl(t, { plan: 4 + 8 + 8 }) let a = 0 let b = 0 @@ -187,20 +194,20 @@ test('pipelined chunked POST stream', (t) => { res.end() }) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 2 }) - t.teardown(client.close.bind(client)) + after(() => client.close()) client.request({ path: '/', method: 'GET' }, (err, { body }) => { body.resume() - t.error(err) + t.ifError(err) }) client.request({ @@ -213,7 +220,7 @@ test('pipelined chunked POST stream', (t) => { }) }, (err, { body }) => { body.resume() - t.error(err) + t.ifError(err) }) client.request({ @@ -221,7 +228,7 @@ test('pipelined chunked POST stream', (t) => { method: 'GET' }, (err, { body }) => { body.resume() - t.error(err) + t.ifError(err) }) client.request({ @@ -234,13 +241,15 @@ test('pipelined chunked POST stream', (t) => { }) }, (err, { body }) => { body.resume() - t.error(err) + t.ifError(err) }) }) + + await t.completed }) -test('pipelined chunked POST iterator', (t) => { - t.plan(4 + 8 + 8) +test('pipelined chunked POST iterator', async (t) => { + t = tspl(t, { plan: 4 + 8 + 8 }) let a = 0 let b = 0 @@ -254,20 +263,20 @@ test('pipelined chunked POST iterator', (t) => { res.end() }) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 2 }) - t.teardown(client.close.bind(client)) + after(() => client.close()) client.request({ path: '/', method: 'GET' }, (err, { body }) => { body.resume() - t.error(err) + t.ifError(err) }) client.request({ @@ -280,7 +289,7 @@ test('pipelined chunked POST iterator', (t) => { })() }, (err, { body }) => { body.resume() - t.error(err) + t.ifError(err) }) client.request({ @@ -288,7 +297,7 @@ test('pipelined chunked POST iterator', (t) => { method: 'GET' }, (err, { body }) => { body.resume() - t.error(err) + t.ifError(err) }) client.request({ @@ -301,14 +310,16 @@ test('pipelined chunked POST iterator', (t) => { })() }, (err, { body }) => { body.resume() - t.error(err) + t.ifError(err) }) }) + + await t.completed }) function errordInflightPost (bodyType) { - test(`errored POST body lets inflight complete ${bodyType}`, (t) => { - t.plan(6) + test(`errored POST body lets inflight complete ${bodyType}`, async (t) => { + t = tspl(t, { plan: 6 }) let serverRes const server = createServer() @@ -316,19 +327,19 @@ function errordInflightPost (bodyType) { serverRes = res res.write('asd') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 2 }) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.request({ path: '/', method: 'GET' }, (err, data) => { - t.error(err) + t.ifError(err) data.body .resume() .once('data', () => { @@ -347,10 +358,10 @@ function errordInflightPost (bodyType) { }), bodyType) }, (err, data) => { t.ok(err) - t.equal(data.opaque, 'asd') + t.strictEqual(data.opaque, 'asd') }) client.close((err) => { - t.error(err) + t.ifError(err) }) serverRes.end() }) @@ -359,14 +370,15 @@ function errordInflightPost (bodyType) { }) }) }) + await t.completed }) } errordInflightPost(consts.STREAM) errordInflightPost(consts.ASYNC_ITERATOR) -test('pipelining non-idempotent', (t) => { - t.plan(4) +test('pipelining non-idempotent', async (t) => { + t = tspl(t, { plan: 4 }) const server = createServer() server.on('request', (req, res) => { @@ -374,20 +386,20 @@ test('pipelining non-idempotent', (t) => { res.end('asd') }, 10) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 2 }) - t.teardown(client.close.bind(client)) + after(() => client.close()) let ended = false client.request({ path: '/', method: 'GET' }, (err, data) => { - t.error(err) + t.ifError(err) data.body .resume() .on('end', () => { @@ -401,16 +413,18 @@ test('pipelining non-idempotent', (t) => { method: 'GET', idempotent: false }, (err, data) => { - t.error(err) - t.equal(ended, true) + t.ifError(err) + t.strictEqual(ended, true) data.body.resume() }) }) + + await t.completed }) function pipeliningNonIdempotentWithBody (bodyType) { - test(`pipelining non-idempotent w body ${bodyType}`, (t) => { - t.plan(4) + test(`pipelining non-idempotent w body ${bodyType}`, async (t) => { + t = tspl(t, { plan: 4 }) const server = createServer() server.on('request', (req, res) => { @@ -418,13 +432,13 @@ function pipeliningNonIdempotentWithBody (bodyType) { res.end('asd') }) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 2 }) - t.teardown(client.close.bind(client)) + after(() => client.close()) let ended = false let reading = false @@ -445,7 +459,7 @@ function pipeliningNonIdempotentWithBody (bodyType) { } }), bodyType) }, (err, data) => { - t.error(err) + t.ifError(err) data.body .resume() .on('end', () => { @@ -458,11 +472,13 @@ function pipeliningNonIdempotentWithBody (bodyType) { method: 'GET', idempotent: false }, (err, data) => { - t.error(err) - t.equal(ended, true) + t.ifError(err) + t.strictEqual(ended, true) data.body.resume() }) }) + + await t.completed }) } @@ -470,25 +486,25 @@ pipeliningNonIdempotentWithBody(consts.STREAM) pipeliningNonIdempotentWithBody(consts.ASYNC_ITERATOR) function pipeliningHeadBusy (bodyType) { - test(`pipelining HEAD busy ${bodyType}`, (t) => { - t.plan(7) + test(`pipelining HEAD busy ${bodyType}`, async (t) => { + t = tspl(t, { plan: 7 }) const server = createServer() server.on('request', (req, res) => { res.end('asd') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 10 }) - t.teardown(client.close.bind(client)) + after(() => client.close()) client[kConnect](() => { let ended = false client.once('disconnect', () => { - t.equal(ended, true) + t.strictEqual(ended, true) }) { @@ -500,7 +516,7 @@ function pipeliningHeadBusy (bodyType) { method: 'GET', body: maybeWrapStream(body, bodyType) }, (err, data) => { - t.error(err) + t.ifError(err) data.body .resume() .on('end', () => { @@ -508,7 +524,7 @@ function pipeliningHeadBusy (bodyType) { }) }) body.push(null) - t.equal(client[kBusy], true) + t.strictEqual(client[kBusy], true) } { @@ -520,7 +536,7 @@ function pipeliningHeadBusy (bodyType) { method: 'HEAD', body: maybeWrapStream(body, bodyType) }, (err, data) => { - t.error(err) + t.ifError(err) data.body .resume() .on('end', () => { @@ -529,18 +545,20 @@ function pipeliningHeadBusy (bodyType) { }) }) body.push(null) - t.equal(client[kBusy], true) + t.strictEqual(client[kBusy], true) } }) }) + + await t.completed }) } pipeliningHeadBusy(consts.STREAM) pipeliningHeadBusy(consts.ASYNC_ITERATOR) -test('pipelining empty pipeline before reset', (t) => { - t.plan(8) +test('pipelining empty pipeline before reset', async (t) => { + t = tspl(t, { plan: 8 }) let c = 0 const server = createServer() @@ -553,39 +571,39 @@ test('pipelining empty pipeline before reset', (t) => { }, 100) } }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 10 }) - t.teardown(client.close.bind(client)) + after(() => client.close()) client[kConnect](() => { let ended = false client.once('disconnect', () => { - t.equal(ended, true) + t.strictEqual(ended, true) }) client.request({ path: '/', method: 'GET' }, (err, data) => { - t.error(err) + t.ifError(err) data.body .resume() .on('end', () => { t.ok(true, 'pass') }) }) - t.equal(client[kBusy], false) + t.strictEqual(client[kBusy], false) client.request({ path: '/', method: 'HEAD', body: 'asd' }, (err, data) => { - t.error(err) + t.ifError(err) data.body .resume() .on('end', () => { @@ -593,27 +611,29 @@ test('pipelining empty pipeline before reset', (t) => { t.ok(true, 'pass') }) }) - t.equal(client[kBusy], true) - t.equal(client[kRunning], 2) + t.strictEqual(client[kBusy], true) + t.strictEqual(client[kRunning], 2) }) }) + + await t.completed }) function pipeliningIdempotentBusy (bodyType) { - test(`pipelining idempotent busy ${bodyType}`, (t) => { - t.plan(12) + test(`pipelining idempotent busy ${bodyType}`, async (t) => { + t = tspl(t, { plan: 12 }) const server = createServer() server.on('request', (req, res) => { res.end('asd') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 10 }) - t.teardown(client.close.bind(client)) + after(() => client.close()) { const body = new Readable({ @@ -624,7 +644,7 @@ function pipeliningIdempotentBusy (bodyType) { method: 'GET', body: maybeWrapStream(body, bodyType) }, (err, data) => { - t.error(err) + t.ifError(err) data.body .resume() .on('end', () => { @@ -632,7 +652,7 @@ function pipeliningIdempotentBusy (bodyType) { }) }) body.push(null) - t.equal(client[kBusy], true) + t.strictEqual(client[kBusy], true) } client[kConnect](() => { @@ -645,7 +665,7 @@ function pipeliningIdempotentBusy (bodyType) { method: 'GET', body: maybeWrapStream(body, bodyType) }, (err, data) => { - t.error(err) + t.ifError(err) data.body .resume() .on('end', () => { @@ -653,7 +673,7 @@ function pipeliningIdempotentBusy (bodyType) { }) }) body.push(null) - t.equal(client[kBusy], true) + t.strictEqual(client[kBusy], true) } { @@ -669,9 +689,9 @@ function pipeliningIdempotentBusy (bodyType) { }, (err, data) => { t.ok(err) }) - t.equal(client[kBusy], true) + t.strictEqual(client[kBusy], true) signal.emit('abort') - t.equal(client[kBusy], true) + t.strictEqual(client[kBusy], true) } { @@ -684,7 +704,7 @@ function pipeliningIdempotentBusy (bodyType) { idempotent: false, body: maybeWrapStream(body, bodyType) }, (err, data) => { - t.error(err) + t.ifError(err) data.body .resume() .on('end', () => { @@ -692,18 +712,20 @@ function pipeliningIdempotentBusy (bodyType) { }) }) body.push(null) - t.equal(client[kBusy], true) + t.strictEqual(client[kBusy], true) } }) }) + + await t.completed }) } pipeliningIdempotentBusy(consts.STREAM) pipeliningIdempotentBusy(consts.ASYNC_ITERATOR) -test('pipelining blocked', (t) => { - t.plan(6) +test('pipelining blocked', async (t) => { + t = tspl(t, { plan: 6 }) const server = createServer() @@ -717,19 +739,19 @@ test('pipelining blocked', (t) => { res.end('asd') }) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 10 }) - t.teardown(client.close.bind(client)) + after(() => client.close()) client.request({ path: '/', method: 'GET', blocking: true }, (err, data) => { - t.error(err) + t.ifError(err) blocking = false data.body .resume() @@ -741,7 +763,7 @@ test('pipelining blocked', (t) => { path: '/', method: 'GET' }, (err, data) => { - t.error(err) + t.ifError(err) data.body .resume() .on('end', () => { @@ -749,4 +771,6 @@ test('pipelining blocked', (t) => { }) }) }) + + await t.completed }) diff --git a/test/client-timeout.js b/test/client-timeout.js index dd5b1da6505..4964774d0bc 100644 --- a/test/client-timeout.js +++ b/test/client-timeout.js @@ -1,25 +1,26 @@ 'use strict' -const { test } = require('tap') +const { tspl } = require('@matteo.collina/tspl') +const { test, after } = require('node:test') const { Client, errors } = require('..') const { createServer } = require('node:http') const { Readable } = require('node:stream') const FakeTimers = require('@sinonjs/fake-timers') const timers = require('../lib/timers') -test('refresh timeout on pause', (t) => { - t.plan(1) +test('refresh timeout on pause', async (t) => { + t = tspl(t, { plan: 1 }) const server = createServer((req, res) => { res.flushHeaders() }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { bodyTimeout: 500 }) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.dispatch({ path: '/', @@ -44,30 +45,32 @@ test('refresh timeout on pause', (t) => { } }) }) + + await t.completed }) -test('start headers timeout after request body', (t) => { - t.plan(2) +test('start headers timeout after request body', async (t) => { + t = tspl(t, { plan: 2 }) - const clock = FakeTimers.install() - t.teardown(clock.uninstall.bind(clock)) + const clock = FakeTimers.install({ shouldClearNativeTimers: true }) + after(() => clock.uninstall()) const orgTimers = { ...timers } Object.assign(timers, { setTimeout, clearTimeout }) - t.teardown(() => { + after(() => { Object.assign(timers, orgTimers) }) const server = createServer((req, res) => { }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { bodyTimeout: 0, headersTimeout: 100 }) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) const body = new Readable({ read () {} }) client.dispatch({ @@ -100,30 +103,32 @@ test('start headers timeout after request body', (t) => { } }) }) + + await t.completed }) -test('start headers timeout after async iterator request body', (t) => { - t.plan(1) +test('start headers timeout after async iterator request body', async (t) => { + t = tspl(t, { plan: 1 }) - const clock = FakeTimers.install() - t.teardown(clock.uninstall.bind(clock)) + const clock = FakeTimers.install({ shouldClearNativeTimers: true }) + after(() => clock.uninstall()) const orgTimers = { ...timers } Object.assign(timers, { setTimeout, clearTimeout }) - t.teardown(() => { + after(() => { Object.assign(timers, orgTimers) }) const server = createServer((req, res) => { }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { bodyTimeout: 0, headersTimeout: 100 }) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) let res const body = (async function * () { await new Promise((resolve) => { res = resolve }) @@ -157,21 +162,23 @@ test('start headers timeout after async iterator request body', (t) => { } }) }) + + await t.completed }) -test('parser resume with no body timeout', (t) => { - t.plan(1) +test('parser resume with no body timeout', async (t) => { + t = tspl(t, { plan: 1 }) const server = createServer((req, res) => { res.end('asd') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`, { bodyTimeout: 0 }) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.dispatch({ path: '/', @@ -190,8 +197,10 @@ test('parser resume with no body timeout', (t) => { t.ok(true, 'pass') }, onError (err) { - t.error(err) + t.ifError(err) } }) }) + + await t.completed }) diff --git a/test/client-upgrade.js b/test/client-upgrade.js index c33ab183363..5cf5e553ba7 100644 --- a/test/client-upgrade.js +++ b/test/client-upgrade.js @@ -1,14 +1,15 @@ 'use strict' -const { test } = require('tap') +const { tspl } = require('@matteo.collina/tspl') +const { test, after } = require('node:test') const { Client, errors } = require('..') const net = require('node:net') const http = require('node:http') const EE = require('node:events') const { kBusy } = require('../lib/core/symbols') -test('basic upgrade', (t) => { - t.plan(6) +test('basic upgrade', async (t) => { + t = tspl(t, { plan: 6 }) const server = net.createServer((c) => { c.on('data', (d) => { @@ -25,11 +26,11 @@ test('basic upgrade', (t) => { c.end() }) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) const signal = new EE() client.upgrade({ @@ -38,9 +39,9 @@ test('basic upgrade', (t) => { method: 'GET', protocol: 'Websocket' }, (err, data) => { - t.error(err) + t.ifError(err) - t.equal(signal.listenerCount('abort'), 0) + t.strictEqual(signal.listenerCount('abort'), 0) const { headers, socket } = data @@ -50,22 +51,24 @@ test('basic upgrade', (t) => { }) socket.on('close', () => { - t.equal(recvData.toString(), 'Body') + t.strictEqual(recvData.toString(), 'Body') }) - t.same(headers, { + t.deepStrictEqual(headers, { hello: 'world', connection: 'upgrade', upgrade: 'websocket' }) socket.end() }) - t.equal(signal.listenerCount('abort'), 1) + t.strictEqual(signal.listenerCount('abort'), 1) }) + + await t.completed }) -test('basic upgrade promise', (t) => { - t.plan(2) +test('basic upgrade promise', async (t) => { + t = tspl(t, { plan: 2 }) const server = net.createServer((c) => { c.on('data', (d) => { @@ -81,11 +84,11 @@ test('basic upgrade promise', (t) => { c.end() }) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) const { headers, socket } = await client.upgrade({ path: '/', @@ -99,20 +102,22 @@ test('basic upgrade promise', (t) => { }) socket.on('close', () => { - t.equal(recvData.toString(), 'Body') + t.strictEqual(recvData.toString(), 'Body') }) - t.same(headers, { + t.deepStrictEqual(headers, { hello: 'world', connection: 'upgrade', upgrade: 'websocket' }) socket.end() }) + + await t.completed }) -test('upgrade error', (t) => { - t.plan(1) +test('upgrade error', async (t) => { + t = tspl(t, { plan: 1 }) const server = net.createServer((c) => { c.on('data', (d) => { @@ -127,11 +132,11 @@ test('upgrade error', (t) => { // Ignore error. }) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) try { await client.upgrade({ @@ -143,16 +148,18 @@ test('upgrade error', (t) => { t.ok(err) } }) + + await t.completed }) -test('upgrade invalid opts', (t) => { - t.plan(6) +test('upgrade invalid opts', async (t) => { + t = tspl(t, { plan: 6 }) const client = new Client('http://localhost:5432') client.upgrade(null, err => { t.ok(err instanceof errors.InvalidArgumentError) - t.equal(err.message, 'invalid opts') + t.strictEqual(err.message, 'invalid opts') }) try { @@ -160,7 +167,7 @@ test('upgrade invalid opts', (t) => { t.fail() } catch (err) { t.ok(err instanceof errors.InvalidArgumentError) - t.equal(err.message, 'invalid opts') + t.strictEqual(err.message, 'invalid opts') } try { @@ -168,12 +175,12 @@ test('upgrade invalid opts', (t) => { t.fail() } catch (err) { t.ok(err instanceof errors.InvalidArgumentError) - t.equal(err.message, 'invalid callback') + t.strictEqual(err.message, 'invalid callback') } }) -test('basic upgrade2', (t) => { - t.plan(3) +test('basic upgrade2', async (t) => { + t = tspl(t, { plan: 3 }) const server = http.createServer() server.on('upgrade', (req, c, head) => { @@ -185,18 +192,18 @@ test('basic upgrade2', (t) => { c.write('Body') c.end() }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) client.upgrade({ path: '/', method: 'GET', protocol: 'Websocket' }, (err, data) => { - t.error(err) + t.ifError(err) const { headers, socket } = data @@ -206,10 +213,10 @@ test('basic upgrade2', (t) => { }) socket.on('close', () => { - t.equal(recvData.toString(), 'Body') + t.strictEqual(recvData.toString(), 'Body') }) - t.same(headers, { + t.deepStrictEqual(headers, { hello: 'world', connection: 'upgrade', upgrade: 'websocket' @@ -217,10 +224,12 @@ test('basic upgrade2', (t) => { socket.end() }) }) + + await t.completed }) -test('upgrade wait for empty pipeline', (t) => { - t.plan(7) +test('upgrade wait for empty pipeline', async (t) => { + t = tspl(t, { plan: 7 }) let canConnect = false const server = http.createServer((req, res) => { @@ -228,7 +237,7 @@ test('upgrade wait for empty pipeline', (t) => { canConnect = true }) server.on('upgrade', (req, c, firstBodyChunk) => { - t.equal(canConnect, true) + t.strictEqual(canConnect, true) c.write('HTTP/1.1 101\r\n') c.write('hello: world\r\n') c.write('connection: upgrade\r\n') @@ -237,55 +246,57 @@ test('upgrade wait for empty pipeline', (t) => { c.write('Body') c.end() }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 3 }) - t.teardown(client.close.bind(client)) + after(() => client.close()) client.request({ path: '/', method: 'GET' }, (err) => { - t.error(err) + t.ifError(err) }) client.once('connect', () => { process.nextTick(() => { - t.equal(client[kBusy], false) + t.strictEqual(client[kBusy], false) client.upgrade({ path: '/' }, (err, { socket }) => { - t.error(err) + t.ifError(err) let recvData = '' socket.on('data', (d) => { recvData += d }) socket.on('end', () => { - t.equal(recvData.toString(), 'Body') + t.strictEqual(recvData.toString(), 'Body') }) socket.write('Body') socket.end() }) - t.equal(client[kBusy], true) + t.strictEqual(client[kBusy], true) client.request({ path: '/', method: 'GET' }, (err) => { - t.error(err) + t.ifError(err) }) }) }) }) + + await t.completed }) -test('upgrade aborted', (t) => { - t.plan(6) +test('upgrade aborted', async (t) => { + t = tspl(t, { plan: 6 }) const server = http.createServer((req, res) => { t.fail() @@ -293,13 +304,13 @@ test('upgrade aborted', (t) => { server.on('upgrade', (req, c, firstBodyChunk) => { t.fail() }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, async () => { const client = new Client(`http://localhost:${server.address().port}`, { pipelining: 3 }) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) const signal = new EE() client.upgrade({ @@ -307,22 +318,24 @@ test('upgrade aborted', (t) => { signal, opaque: 'asd' }, (err, { opaque }) => { - t.equal(opaque, 'asd') + t.strictEqual(opaque, 'asd') t.ok(err instanceof errors.RequestAbortedError) - t.equal(signal.listenerCount('abort'), 0) + t.strictEqual(signal.listenerCount('abort'), 0) }) - t.equal(client[kBusy], true) - t.equal(signal.listenerCount('abort'), 1) + t.strictEqual(client[kBusy], true) + t.strictEqual(signal.listenerCount('abort'), 1) signal.emit('abort') client.close(() => { t.ok(true, 'pass') }) }) + + await t.completed }) -test('basic aborted after res', (t) => { - t.plan(1) +test('basic aborted after res', async (t) => { + t = tspl(t, { plan: 1 }) const signal = new EE() const server = http.createServer() @@ -339,11 +352,11 @@ test('basic aborted after res', (t) => { }) signal.emit('abort') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) client.upgrade({ path: '/', @@ -354,10 +367,12 @@ test('basic aborted after res', (t) => { t.ok(err instanceof errors.RequestAbortedError) }) }) + + await t.completed }) -test('basic upgrade error', (t) => { - t.plan(2) +test('basic upgrade error', async (t) => { + t = tspl(t, { plan: 2 }) const server = net.createServer((c) => { c.on('data', (d) => { @@ -372,11 +387,11 @@ test('basic upgrade error', (t) => { }) }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) const _err = new Error() client.upgrade({ @@ -384,30 +399,32 @@ test('basic upgrade error', (t) => { method: 'GET', protocol: 'Websocket' }, (err, data) => { - t.error(err) + t.ifError(err) data.socket.on('error', (err) => { - t.equal(err, _err) + t.strictEqual(err, _err) }) throw _err }) }) + + await t.completed }) -test('upgrade disconnect', (t) => { - t.plan(3) +test('upgrade disconnect', async (t) => { + t = tspl(t, { plan: 3 }) const server = net.createServer(connection => { connection.destroy() }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.close.bind(client)) + after(() => client.close()) client.on('disconnect', (origin, [self], error) => { - t.equal(client, self) + t.strictEqual(client, self) t.ok(error instanceof Error) }) @@ -420,19 +437,21 @@ test('upgrade disconnect', (t) => { t.ok(error instanceof Error) }) }) + + await t.completed }) -test('upgrade invalid signal', (t) => { - t.plan(2) +test('upgrade invalid signal', async (t) => { + t = tspl(t, { plan: 2 }) const server = net.createServer(() => { t.fail() }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.on('disconnect', () => { t.fail() @@ -445,8 +464,10 @@ test('upgrade invalid signal', (t) => { signal: 'error', opaque: 'asd' }, (err, { opaque }) => { - t.equal(opaque, 'asd') + t.strictEqual(opaque, 'asd') t.ok(err instanceof errors.InvalidArgumentError) }) }) + + await t.completed }) diff --git a/test/get-head-body.js b/test/get-head-body.js index 74420a174cd..4e58bc0f5a5 100644 --- a/test/get-head-body.js +++ b/test/get-head-body.js @@ -1,6 +1,7 @@ 'use strict' -const { test } = require('tap') +const { tspl } = require('@matteo.collina/tspl') +const { test, after } = require('node:test') const { Client } = require('..') const { createServer } = require('node:http') const { Readable } = require('node:stream') @@ -8,17 +9,17 @@ const { kConnect } = require('../lib/core/symbols') const { kBusy } = require('../lib/core/symbols') const { wrapWithAsyncIterable } = require('./utils/async-iterators') -test('GET and HEAD with body should reset connection', (t) => { - t.plan(8 + 2) +test('GET and HEAD with body should reset connection', async (t) => { + t = tspl(t, { plan: 8 + 2 }) const server = createServer((req, res) => { res.end('asd') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.on('disconnect', () => { t.ok(true, 'pass') @@ -29,7 +30,7 @@ test('GET and HEAD with body should reset connection', (t) => { body: 'asd', method: 'GET' }, (err, data) => { - t.error(err) + t.ifError(err) data.body.resume() }) @@ -42,7 +43,7 @@ test('GET and HEAD with body should reset connection', (t) => { body: emptyBody, method: 'GET' }, (err, data) => { - t.error(err) + t.ifError(err) data.body.resume() }) @@ -55,7 +56,7 @@ test('GET and HEAD with body should reset connection', (t) => { }), method: 'GET' }, (err, data) => { - t.error(err) + t.ifError(err) data.body.resume() }) @@ -69,7 +70,7 @@ test('GET and HEAD with body should reset connection', (t) => { }), method: 'GET' }, (err, data) => { - t.error(err) + t.ifError(err) data.body.resume() }) @@ -78,7 +79,7 @@ test('GET and HEAD with body should reset connection', (t) => { body: [], method: 'GET' }, (err, data) => { - t.error(err) + t.ifError(err) data.body.resume() }) @@ -91,7 +92,7 @@ test('GET and HEAD with body should reset connection', (t) => { })), method: 'GET' }, (err, data) => { - t.error(err) + t.ifError(err) data.body.resume() }) @@ -105,44 +106,48 @@ test('GET and HEAD with body should reset connection', (t) => { })), method: 'GET' }, (err, data) => { - t.error(err) + t.ifError(err) data.body.resume() }) }) + + await t.completed }) // TODO: Avoid external dependency. -// test('GET with body should work when target parses body as request', (t) => { -// t.plan(4) +// test('GET with body should work when target parses body as request', async (t) => { +// t = tspl(t, { plan: 4 }) // // This URL will send double responses when receiving a // // GET request with body. // const client = new Client('http://feeds.bbci.co.uk') -// t.teardown(client.close.bind(client)) +// after(() => client.close()) // client.request({ method: 'GET', path: '/news/rss.xml', body: 'asd' }, (err, data) => { -// t.error(err) -// t.equal(data.statusCode, 200) +// t.ifError(err) +// t.strictEqual(data.statusCode, 200) // data.body.resume() // }) // client.request({ method: 'GET', path: '/news/rss.xml', body: 'asd' }, (err, data) => { -// t.error(err) -// t.equal(data.statusCode, 200) +// t.ifError(err) +// t.strictEqual(data.statusCode, 200) // data.body.resume() // }) + +// await t.completed // }) -test('HEAD should reset connection', (t) => { - t.plan(8) +test('HEAD should reset connection', async (t) => { + t = tspl(t, { plan: 8 }) const server = createServer((req, res) => { res.end('asd') }) - t.teardown(server.close.bind(server)) + after(() => server.close()) server.listen(0, () => { const client = new Client(`http://localhost:${server.address().port}`) - t.teardown(client.destroy.bind(client)) + after(() => client.destroy()) client.once('disconnect', () => { t.ok(true, 'pass') @@ -152,16 +157,16 @@ test('HEAD should reset connection', (t) => { path: '/', method: 'HEAD' }, (err, data) => { - t.error(err) + t.ifError(err) data.body.resume() }) - t.equal(client[kBusy], true) + t.strictEqual(client[kBusy], true) client.request({ path: '/', method: 'HEAD' }, (err, data) => { - t.error(err) + t.ifError(err) data.body.resume() client.once('disconnect', () => { client[kConnect](() => { @@ -169,16 +174,18 @@ test('HEAD should reset connection', (t) => { path: '/', method: 'HEAD' }, (err, data) => { - t.error(err) + t.ifError(err) data.body.resume() data.body.on('end', () => { t.ok(true, 'pass') }) }) - t.equal(client[kBusy], true) + t.strictEqual(client[kBusy], true) }) }) }) - t.equal(client[kBusy], true) + t.strictEqual(client[kBusy], true) }) + + await t.completed }) diff --git a/test/http2-alpn.js b/test/http2-alpn.js index 04b8cb6abd8..590f65e128e 100644 --- a/test/http2-alpn.js +++ b/test/http2-alpn.js @@ -1,11 +1,12 @@ 'use strict' +const { tspl } = require('@matteo.collina/tspl') +const { test, after } = require('node:test') const https = require('node:https') const { once } = require('node:events') const { createSecureServer } = require('node:http2') const { readFileSync } = require('node:fs') const { join } = require('node:path') -const { test } = require('tap') const { Client } = require('..') @@ -15,7 +16,7 @@ const cert = readFileSync(join(__dirname, 'fixtures', 'cert.pem'), 'utf8') const ca = readFileSync(join(__dirname, 'fixtures', 'ca.pem'), 'utf8') test('Should upgrade to HTTP/2 when HTTPS/1 is available for GET', async (t) => { - t.plan(10) + t = tspl(t, { plan: 10 }) const body = [] const httpsBody = [] @@ -47,7 +48,7 @@ test('Should upgrade to HTTP/2 when HTTPS/1 is available for GET', async (t) => await once(server, 'listening') // close the server on teardown - t.teardown(server.close.bind(server)) + after(() => server.close()) // set the port const port = server.address().port @@ -62,7 +63,7 @@ test('Should upgrade to HTTP/2 when HTTPS/1 is available for GET', async (t) => }) // close the client on teardown - t.teardown(client.close.bind(client)) + after(() => client.close()) // make an undici request using where it wants http/2 const response = await client.request({ @@ -110,7 +111,7 @@ test('Should upgrade to HTTP/2 when HTTPS/1 is available for GET', async (t) => reject(err) }) - t.teardown(httpsRequest.destroy.bind(httpsRequest)) + after(() => httpsRequest.destroy()) }) t.equal(httpsResponse.statusCode, 200) @@ -124,7 +125,7 @@ test('Should upgrade to HTTP/2 when HTTPS/1 is available for GET', async (t) => }) test('Should upgrade to HTTP/2 when HTTPS/1 is available for POST', async (t) => { - t.plan(15) + t = tspl(t, { plan: 15 }) const requestChunks = [] const responseBody = [] @@ -194,7 +195,7 @@ test('Should upgrade to HTTP/2 when HTTPS/1 is available for POST', async (t) => await once(server, 'listening') // close the server on teardown - t.teardown(server.close.bind(server)) + after(() => server.close()) // set the port const port = server.address().port @@ -209,7 +210,7 @@ test('Should upgrade to HTTP/2 when HTTPS/1 is available for POST', async (t) => }) // close the client on teardown - t.teardown(client.close.bind(client)) + after(() => client.close()) // make an undici request using where it wants http/2 const response = await client.request({ @@ -265,7 +266,7 @@ test('Should upgrade to HTTP/2 when HTTPS/1 is available for POST', async (t) => httpsRequest.write(Buffer.from(body)) - t.teardown(httpsRequest.destroy.bind(httpsRequest)) + after(() => httpsRequest.destroy()) }) t.equal(httpsResponse.statusCode, 201) diff --git a/test/http2.js b/test/http2.js index 538c6677788..3319ffddb1e 100644 --- a/test/http2.js +++ b/test/http2.js @@ -1,27 +1,26 @@ 'use strict' +const { tspl } = require('@matteo.collina/tspl') +const { test, after } = require('node:test') const { createSecureServer } = require('node:http2') const { createReadStream, readFileSync } = require('node:fs') const { once } = require('node:events') const { Blob } = require('node:buffer') const { Writable, pipeline, PassThrough, Readable } = require('node:stream') -const { test, plan } = require('tap') const pem = require('https-pem') const { Client, Agent } = require('..') const isGreaterThanv20 = process.versions.node.split('.').map(Number)[0] >= 20 -plan(25) - test('Should support H2 connection', async t => { const body = [] const server = createSecureServer(pem) server.on('stream', (stream, headers, _flags, rawHeaders) => { - t.equal(headers['x-my-header'], 'foo') - t.equal(headers[':method'], 'GET') + t.strictEqual(headers['x-my-header'], 'foo') + t.strictEqual(headers[':method'], 'GET') stream.respond({ 'content-type': 'text/plain; charset=utf-8', 'x-custom-h2': 'hello', @@ -40,9 +39,9 @@ test('Should support H2 connection', async t => { allowH2: true }) - t.plan(6) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + t = tspl(t, { plan: 6 }) + after(() => server.close()) + after(() => client.close()) const response = await client.request({ path: '/', @@ -57,23 +56,23 @@ test('Should support H2 connection', async t => { }) await once(response.body, 'end') - t.equal(response.statusCode, 200) - t.equal(response.headers['content-type'], 'text/plain; charset=utf-8') - t.equal(response.headers['x-custom-h2'], 'hello') - t.equal(Buffer.concat(body).toString('utf8'), 'hello h2!') + t.strictEqual(response.statusCode, 200) + t.strictEqual(response.headers['content-type'], 'text/plain; charset=utf-8') + t.strictEqual(response.headers['x-custom-h2'], 'hello') + t.strictEqual(Buffer.concat(body).toString('utf8'), 'hello h2!') }) test('Should support H2 connection(multiple requests)', async t => { const server = createSecureServer(pem) server.on('stream', async (stream, headers, _flags, rawHeaders) => { - t.equal(headers['x-my-header'], 'foo') - t.equal(headers[':method'], 'POST') + t.strictEqual(headers['x-my-header'], 'foo') + t.strictEqual(headers[':method'], 'POST') const reqData = [] stream.on('data', chunk => reqData.push(chunk.toString())) await once(stream, 'end') const reqBody = reqData.join('') - t.equal(reqBody.length > 0, true) + t.strictEqual(reqBody.length > 0, true) stream.respond({ 'content-type': 'text/plain; charset=utf-8', 'x-custom-h2': 'hello', @@ -92,9 +91,9 @@ test('Should support H2 connection(multiple requests)', async t => { allowH2: true }) - t.plan(21) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + t = tspl(t, { plan: 21 }) + after(() => server.close()) + after(() => client.close()) for (let i = 0; i < 3; i++) { const sendBody = `seq ${i}` @@ -114,10 +113,10 @@ test('Should support H2 connection(multiple requests)', async t => { }) await once(response.body, 'end') - t.equal(response.statusCode, 200) - t.equal(response.headers['content-type'], 'text/plain; charset=utf-8') - t.equal(response.headers['x-custom-h2'], 'hello') - t.equal(Buffer.concat(body).toString('utf8'), `hello h2! ${sendBody}`) + t.strictEqual(response.statusCode, 200) + t.strictEqual(response.headers['content-type'], 'text/plain; charset=utf-8') + t.strictEqual(response.headers['x-custom-h2'], 'hello') + t.strictEqual(Buffer.concat(body).toString('utf8'), `hello h2! ${sendBody}`) } }) @@ -126,9 +125,9 @@ test('Should support H2 connection (headers as array)', async t => { const server = createSecureServer(pem) server.on('stream', (stream, headers) => { - t.equal(headers['x-my-header'], 'foo') - t.equal(headers['x-my-drink'], 'coffee,tea') - t.equal(headers[':method'], 'GET') + t.strictEqual(headers['x-my-header'], 'foo') + t.strictEqual(headers['x-my-drink'], 'coffee,tea') + t.strictEqual(headers[':method'], 'GET') stream.respond({ 'content-type': 'text/plain; charset=utf-8', 'x-custom-h2': 'hello', @@ -147,9 +146,9 @@ test('Should support H2 connection (headers as array)', async t => { allowH2: true }) - t.plan(7) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + t = tspl(t, { plan: 7 }) + after(() => server.close()) + after(() => client.close()) const response = await client.request({ path: '/', @@ -162,21 +161,21 @@ test('Should support H2 connection (headers as array)', async t => { }) await once(response.body, 'end') - t.equal(response.statusCode, 200) - t.equal(response.headers['content-type'], 'text/plain; charset=utf-8') - t.equal(response.headers['x-custom-h2'], 'hello') - t.equal(Buffer.concat(body).toString('utf8'), 'hello h2!') + t.strictEqual(response.statusCode, 200) + t.strictEqual(response.headers['content-type'], 'text/plain; charset=utf-8') + t.strictEqual(response.headers['x-custom-h2'], 'hello') + t.strictEqual(Buffer.concat(body).toString('utf8'), 'hello h2!') }) test('Should support H2 connection(POST Buffer)', async t => { const server = createSecureServer({ ...pem, allowHTTP1: false }) server.on('stream', async (stream, headers, _flags, rawHeaders) => { - t.equal(headers[':method'], 'POST') + t.strictEqual(headers[':method'], 'POST') const reqData = [] stream.on('data', chunk => reqData.push(chunk.toString())) await once(stream, 'end') - t.equal(reqData.join(''), 'hello!') + t.strictEqual(reqData.join(''), 'hello!') stream.respond({ 'content-type': 'text/plain; charset=utf-8', 'x-custom-h2': 'hello', @@ -195,9 +194,9 @@ test('Should support H2 connection(POST Buffer)', async t => { allowH2: true }) - t.plan(6) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + t = tspl(t, { plan: 6 }) + after(() => server.close()) + after(() => client.close()) const sendBody = 'hello!' const body = [] @@ -212,10 +211,10 @@ test('Should support H2 connection(POST Buffer)', async t => { }) await once(response.body, 'end') - t.equal(response.statusCode, 200) - t.equal(response.headers['content-type'], 'text/plain; charset=utf-8') - t.equal(response.headers['x-custom-h2'], 'hello') - t.equal(Buffer.concat(body).toString('utf8'), 'hello h2!') + t.strictEqual(response.statusCode, 200) + t.strictEqual(response.headers['content-type'], 'text/plain; charset=utf-8') + t.strictEqual(response.headers['x-custom-h2'], 'hello') + t.strictEqual(Buffer.concat(body).toString('utf8'), 'hello h2!') }) test('Should support H2 GOAWAY (server-side)', async t => { @@ -223,8 +222,8 @@ test('Should support H2 GOAWAY (server-side)', async t => { const server = createSecureServer(pem) server.on('stream', (stream, headers) => { - t.equal(headers['x-my-header'], 'foo') - t.equal(headers[':method'], 'GET') + t.strictEqual(headers['x-my-header'], 'foo') + t.strictEqual(headers[':method'], 'GET') stream.respond({ 'content-type': 'text/plain; charset=utf-8', 'x-custom-h2': 'hello', @@ -249,9 +248,9 @@ test('Should support H2 GOAWAY (server-side)', async t => { allowH2: true }) - t.plan(9) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + t = tspl(t, { plan: 9 }) + after(() => server.close()) + after(() => client.close()) const response = await client.request({ path: '/', @@ -266,19 +265,21 @@ test('Should support H2 GOAWAY (server-side)', async t => { }) await once(response.body, 'end') - t.equal(response.statusCode, 200) - t.equal(response.headers['content-type'], 'text/plain; charset=utf-8') - t.equal(response.headers['x-custom-h2'], 'hello') - t.equal(Buffer.concat(body).toString('utf8'), 'hello h2!') + t.strictEqual(response.statusCode, 200) + t.strictEqual(response.headers['content-type'], 'text/plain; charset=utf-8') + t.strictEqual(response.headers['x-custom-h2'], 'hello') + t.strictEqual(Buffer.concat(body).toString('utf8'), 'hello h2!') const [url, disconnectClient, err] = await once(client, 'disconnect') t.ok(url instanceof URL) - t.same(disconnectClient, [client]) - t.equal(err.message, 'HTTP/2: "GOAWAY" frame received with code 204') + t.deepStrictEqual(disconnectClient, [client]) + t.strictEqual(err.message, 'HTTP/2: "GOAWAY" frame received with code 204') }) test('Should throw if bad allowH2 has been passed', async t => { + t = tspl(t, { plan: 1 }) + try { // eslint-disable-next-line new Client('https://localhost:1000', { @@ -286,11 +287,13 @@ test('Should throw if bad allowH2 has been passed', async t => { }) t.fail() } catch (error) { - t.equal(error.message, 'allowH2 must be a valid boolean value') + t.strictEqual(error.message, 'allowH2 must be a valid boolean value') } }) test('Should throw if bad maxConcurrentStreams has been passed', async t => { + t = tspl(t, { plan: 2 }) + try { // eslint-disable-next-line new Client('https://localhost:1000', { @@ -299,7 +302,7 @@ test('Should throw if bad maxConcurrentStreams has been passed', async t => { }) t.fail() } catch (error) { - t.equal( + t.strictEqual( error.message, 'maxConcurrentStreams must be a positive integer, greater than 0' ) @@ -313,17 +316,21 @@ test('Should throw if bad maxConcurrentStreams has been passed', async t => { }) t.fail() } catch (error) { - t.equal( + t.strictEqual( error.message, 'maxConcurrentStreams must be a positive integer, greater than 0' ) } + + await t.completed }) test( 'Request should fail if allowH2 is false and server advertises h1 only', { skip: isGreaterThanv20 }, async t => { + t = tspl(t, { plan: 1 }) + const server = createSecureServer( { ...pem, @@ -345,8 +352,8 @@ test( } }) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + after(() => server.close()) + after(() => client.close()) const response = await client.request({ path: '/', @@ -356,7 +363,7 @@ test( } }) - t.equal(response.statusCode, 403) + t.strictEqual(response.statusCode, 403) } ) @@ -385,9 +392,9 @@ test( } }) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) - t.plan(2) + after(() => server.close()) + after(() => client.close()) + t = tspl(t, { plan: 2 }) try { await client.request({ @@ -398,11 +405,11 @@ test( } }) } catch (error) { - t.equal( + t.strictEqual( error.message, 'Client network socket disconnected before secure TLS connection was established' ) - t.equal(error.code, 'ECONNRESET') + t.strictEqual(error.code, 'ECONNRESET') } } ) @@ -413,9 +420,9 @@ test('Should handle h2 continue', async t => { const responseBody = [] server.on('checkContinue', (request, response) => { - t.equal(request.headers.expect, '100-continue') - t.equal(request.headers['x-my-header'], 'foo') - t.equal(request.headers[':method'], 'POST') + t.strictEqual(request.headers.expect, '100-continue') + t.strictEqual(request.headers['x-my-header'], 'foo') + t.strictEqual(request.headers[':method'], 'POST') response.writeContinue() request.on('data', chunk => requestBody.push(chunk)) @@ -427,7 +434,7 @@ test('Should handle h2 continue', async t => { response.end('hello h2!') }) - t.plan(7) + t = tspl(t, { plan: 7 }) server.listen(0) await once(server, 'listening') @@ -440,8 +447,8 @@ test('Should handle h2 continue', async t => { allowH2: true }) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + after(() => server.close()) + after(() => client.close()) const response = await client.request({ path: '/', @@ -458,13 +465,13 @@ test('Should handle h2 continue', async t => { await once(response.body, 'end') - t.equal(response.statusCode, 200) - t.equal(response.headers['content-type'], 'text/plain; charset=utf-8') - t.equal(response.headers['x-custom-h2'], 'foo') - t.equal(Buffer.concat(responseBody).toString('utf-8'), 'hello h2!') + t.strictEqual(response.statusCode, 200) + t.strictEqual(response.headers['content-type'], 'text/plain; charset=utf-8') + t.strictEqual(response.headers['x-custom-h2'], 'foo') + t.strictEqual(Buffer.concat(responseBody).toString('utf-8'), 'hello h2!') }) -test('Dispatcher#Stream', t => { +test('Dispatcher#Stream', async t => { const server = createSecureServer(pem) const expectedBody = 'hello from client!' const bufs = [] @@ -480,7 +487,7 @@ test('Dispatcher#Stream', t => { stream.end('hello h2!') }) - t.plan(4) + t = tspl(t, { plan: 4 }) server.listen(0, async () => { const client = new Client(`https://localhost:${server.address().port}`, { @@ -490,14 +497,14 @@ test('Dispatcher#Stream', t => { allowH2: true }) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + after(() => server.close()) + after(() => client.close()) await client.stream( { path: '/', opaque: { bufs }, method: 'POST', body: expectedBody }, ({ statusCode, headers, opaque: { bufs } }) => { - t.equal(statusCode, 200) - t.equal(headers['x-custom'], 'custom-header') + t.strictEqual(statusCode, 200) + t.strictEqual(headers['x-custom'], 'custom-header') return new Writable({ write (chunk, _encoding, cb) { @@ -508,12 +515,14 @@ test('Dispatcher#Stream', t => { } ) - t.equal(Buffer.concat(bufs).toString('utf-8'), 'hello h2!') - t.equal(requestBody, expectedBody) + t.strictEqual(Buffer.concat(bufs).toString('utf-8'), 'hello h2!') + t.strictEqual(requestBody, expectedBody) }) + + await t.completed }) -test('Dispatcher#Pipeline', t => { +test('Dispatcher#Pipeline', async t => { const server = createSecureServer(pem) const expectedBody = 'hello from client!' const bufs = [] @@ -529,7 +538,7 @@ test('Dispatcher#Pipeline', t => { stream.end('hello h2!') }) - t.plan(5) + t = tspl(t, { plan: 5 }) server.listen(0, () => { const client = new Client(`https://localhost:${server.address().port}`, { @@ -539,8 +548,8 @@ test('Dispatcher#Pipeline', t => { allowH2: true }) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + after(() => server.close()) + after(() => client.close()) pipeline( new Readable({ @@ -552,8 +561,8 @@ test('Dispatcher#Pipeline', t => { client.pipeline( { path: '/', method: 'POST', body: expectedBody }, ({ statusCode, headers, body }) => { - t.equal(statusCode, 200) - t.equal(headers['x-custom'], 'custom-header') + t.strictEqual(statusCode, 200) + t.strictEqual(headers['x-custom'], 'custom-header') return pipeline(body, new PassThrough(), () => {}) } @@ -565,15 +574,17 @@ test('Dispatcher#Pipeline', t => { } }), err => { - t.error(err) - t.equal(Buffer.concat(bufs).toString('utf-8'), 'hello h2!') - t.equal(requestBody, expectedBody) + t.ifError(err) + t.strictEqual(Buffer.concat(bufs).toString('utf-8'), 'hello h2!') + t.strictEqual(requestBody, expectedBody) } ) }) + + await t.completed }) -test('Dispatcher#Connect', t => { +test('Dispatcher#Connect', async t => { const server = createSecureServer(pem) const expectedBody = 'hello from client!' let requestBody = '' @@ -588,7 +599,7 @@ test('Dispatcher#Connect', t => { stream.end('hello h2!') }) - t.plan(6) + t = tspl(t, { plan: 6 }) server.listen(0, () => { const client = new Client(`https://localhost:${server.address().port}`, { @@ -598,19 +609,19 @@ test('Dispatcher#Connect', t => { allowH2: true }) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + after(() => server.close()) + after(() => client.close()) let result = '' client.connect({ path: '/' }, (err, { socket }) => { - t.error(err) + t.ifError(err) socket.on('data', chunk => { result += chunk }) socket.on('response', headers => { - t.equal(headers[':status'], 200) - t.equal(headers['x-custom'], 'custom-header') - t.notOk(socket.closed) + t.strictEqual(headers[':status'], 200) + t.strictEqual(headers['x-custom'], 'custom-header') + t.strictEqual(socket.closed, false) }) // We need to handle the error event although @@ -620,22 +631,24 @@ test('Dispatcher#Connect', t => { socket.on('error', () => {}) socket.once('end', () => { - t.equal(requestBody, expectedBody) - t.equal(result, 'hello h2!') + t.strictEqual(requestBody, expectedBody) + t.strictEqual(result, 'hello h2!') }) socket.end(expectedBody) }) }) + + await t.completed }) -test('Dispatcher#Upgrade', t => { +test('Dispatcher#Upgrade', async t => { const server = createSecureServer(pem) server.on('stream', async (stream, headers) => { stream.end() }) - t.plan(1) + t = tspl(t, { plan: 1 }) server.listen(0, async () => { const client = new Client(`https://localhost:${server.address().port}`, { @@ -645,15 +658,17 @@ test('Dispatcher#Upgrade', t => { allowH2: true }) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + after(() => server.close()) + after(() => client.close()) try { await client.upgrade({ path: '/' }) } catch (error) { - t.equal(error.message, 'Upgrade not supported for H2') + t.strictEqual(error.message, 'Upgrade not supported for H2') } }) + + await t.completed }) test('Dispatcher#destroy', async t => { @@ -674,8 +689,8 @@ test('Dispatcher#destroy', async t => { allowH2: true }) - t.plan(4) - t.teardown(server.close.bind(server)) + t = tspl(t, { plan: 4 }) + after(() => server.close()) promises.push( client.request({ @@ -721,10 +736,10 @@ test('Dispatcher#destroy', async t => { const results = await Promise.allSettled(promises) - t.equal(results[0].status, 'rejected') - t.equal(results[1].status, 'rejected') - t.equal(results[2].status, 'rejected') - t.equal(results[3].status, 'rejected') + t.strictEqual(results[0].status, 'rejected') + t.strictEqual(results[1].status, 'rejected') + t.strictEqual(results[2].status, 'rejected') + t.strictEqual(results[3].status, 'rejected') }) test('Should handle h2 request without body', async t => { @@ -734,9 +749,9 @@ test('Should handle h2 request without body', async t => { const responseBody = [] server.on('stream', async (stream, headers) => { - t.equal(headers[':method'], 'POST') - t.equal(headers[':path'], '/') - t.equal(headers[':scheme'], 'https') + t.strictEqual(headers[':method'], 'POST') + t.strictEqual(headers[':path'], '/') + t.strictEqual(headers[':scheme'], 'https') stream.respond({ 'content-type': 'text/plain; charset=utf-8', @@ -751,7 +766,7 @@ test('Should handle h2 request without body', async t => { stream.end('hello h2!') }) - t.plan(9) + t = tspl(t, { plan: 9 }) server.listen(0) await once(server, 'listening') @@ -763,8 +778,8 @@ test('Should handle h2 request without body', async t => { allowH2: true }) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + after(() => server.close()) + after(() => client.close()) const response = await client.request({ path: '/', @@ -778,15 +793,15 @@ test('Should handle h2 request without body', async t => { responseBody.push(chunk) } - t.equal(response.statusCode, 200) - t.equal(response.headers['content-type'], 'text/plain; charset=utf-8') - t.equal(response.headers['x-custom-h2'], 'foo') - t.equal(Buffer.concat(responseBody).toString('utf-8'), 'hello h2!') - t.equal(requestChunks.length, 0) - t.equal(Buffer.concat(requestChunks).toString('utf-8'), expectedBody) + t.strictEqual(response.statusCode, 200) + t.strictEqual(response.headers['content-type'], 'text/plain; charset=utf-8') + t.strictEqual(response.headers['x-custom-h2'], 'foo') + t.strictEqual(Buffer.concat(responseBody).toString('utf-8'), 'hello h2!') + t.strictEqual(requestChunks.length, 0) + t.strictEqual(Buffer.concat(requestChunks).toString('utf-8'), expectedBody) }) -test('Should handle h2 request with body (string or buffer) - dispatch', t => { +test('Should handle h2 request with body (string or buffer) - dispatch', async t => { const server = createSecureServer(pem) const expectedBody = 'hello from client!' const response = [] @@ -804,7 +819,7 @@ test('Should handle h2 request with body (string or buffer) - dispatch', t => { stream.end('hello h2!') }) - t.plan(7) + t = tspl(t, { plan: 7 }) server.listen(0, () => { const client = new Client(`https://localhost:${server.address().port}`, { @@ -814,8 +829,8 @@ test('Should handle h2 request with body (string or buffer) - dispatch', t => { allowH2: true }) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + after(() => server.close()) + after(() => client.close()) client.dispatch( { @@ -832,22 +847,22 @@ test('Should handle h2 request with body (string or buffer) - dispatch', t => { t.ok(true, 'pass') }, onError (err) { - t.error(err) + t.ifError(err) }, onHeaders (statusCode, headers) { - t.equal(statusCode, 200) - t.equal(headers['content-type'], 'text/plain; charset=utf-8') - t.equal(headers['x-custom-h2'], 'foo') + t.strictEqual(statusCode, 200) + t.strictEqual(headers['content-type'], 'text/plain; charset=utf-8') + t.strictEqual(headers['x-custom-h2'], 'foo') }, onData (chunk) { response.push(chunk) }, onBodySent (body) { - t.equal(body.toString('utf-8'), expectedBody) + t.strictEqual(body.toString('utf-8'), expectedBody) }, onComplete () { - t.equal(Buffer.concat(response).toString('utf-8'), 'hello h2!') - t.equal( + t.strictEqual(Buffer.concat(response).toString('utf-8'), 'hello h2!') + t.strictEqual( Buffer.concat(requestBody).toString('utf-8'), 'hello from client!' ) @@ -855,6 +870,8 @@ test('Should handle h2 request with body (string or buffer) - dispatch', t => { } ) }) + + await t.completed }) test('Should handle h2 request with body (stream)', async t => { @@ -865,9 +882,9 @@ test('Should handle h2 request with body (stream)', async t => { const responseBody = [] server.on('stream', async (stream, headers) => { - t.equal(headers[':method'], 'PUT') - t.equal(headers[':path'], '/') - t.equal(headers[':scheme'], 'https') + t.strictEqual(headers[':method'], 'PUT') + t.strictEqual(headers[':path'], '/') + t.strictEqual(headers[':scheme'], 'https') stream.respond({ 'content-type': 'text/plain; charset=utf-8', @@ -882,7 +899,7 @@ test('Should handle h2 request with body (stream)', async t => { stream.end('hello h2!') }) - t.plan(8) + t = tspl(t, { plan: 8 }) server.listen(0) await once(server, 'listening') @@ -894,8 +911,8 @@ test('Should handle h2 request with body (stream)', async t => { allowH2: true }) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + after(() => server.close()) + after(() => client.close()) const response = await client.request({ path: '/', @@ -910,11 +927,11 @@ test('Should handle h2 request with body (stream)', async t => { responseBody.push(chunk) } - t.equal(response.statusCode, 200) - t.equal(response.headers['content-type'], 'text/plain; charset=utf-8') - t.equal(response.headers['x-custom-h2'], 'foo') - t.equal(Buffer.concat(responseBody).toString('utf-8'), 'hello h2!') - t.equal(Buffer.concat(requestChunks).toString('utf-8'), expectedBody) + t.strictEqual(response.statusCode, 200) + t.strictEqual(response.headers['content-type'], 'text/plain; charset=utf-8') + t.strictEqual(response.headers['x-custom-h2'], 'foo') + t.strictEqual(Buffer.concat(responseBody).toString('utf-8'), 'hello h2!') + t.strictEqual(Buffer.concat(requestChunks).toString('utf-8'), expectedBody) }) test('Should handle h2 request with body (iterable)', async t => { @@ -934,9 +951,9 @@ test('Should handle h2 request with body (iterable)', async t => { } server.on('stream', async (stream, headers) => { - t.equal(headers[':method'], 'POST') - t.equal(headers[':path'], '/') - t.equal(headers[':scheme'], 'https') + t.strictEqual(headers[':method'], 'POST') + t.strictEqual(headers[':path'], '/') + t.strictEqual(headers[':scheme'], 'https') stream.on('data', chunk => requestChunks.push(chunk)) @@ -949,7 +966,7 @@ test('Should handle h2 request with body (iterable)', async t => { stream.end('hello h2!') }) - t.plan(8) + t = tspl(t, { plan: 8 }) server.listen(0) await once(server, 'listening') @@ -961,8 +978,8 @@ test('Should handle h2 request with body (iterable)', async t => { allowH2: true }) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + after(() => server.close()) + after(() => client.close()) const response = await client.request({ path: '/', @@ -979,11 +996,11 @@ test('Should handle h2 request with body (iterable)', async t => { await once(response.body, 'end') - t.equal(response.statusCode, 200) - t.equal(response.headers['content-type'], 'text/plain; charset=utf-8') - t.equal(response.headers['x-custom-h2'], 'foo') - t.equal(Buffer.concat(responseBody).toString('utf-8'), 'hello h2!') - t.equal(Buffer.concat(requestChunks).toString('utf-8'), expectedBody) + t.strictEqual(response.statusCode, 200) + t.strictEqual(response.headers['content-type'], 'text/plain; charset=utf-8') + t.strictEqual(response.headers['x-custom-h2'], 'foo') + t.strictEqual(Buffer.concat(responseBody).toString('utf-8'), 'hello h2!') + t.strictEqual(Buffer.concat(requestChunks).toString('utf-8'), expectedBody) }) test('Should handle h2 request with body (Blob)', { skip: !Blob }, async t => { @@ -996,9 +1013,9 @@ test('Should handle h2 request with body (Blob)', { skip: !Blob }, async t => { }) server.on('stream', async (stream, headers) => { - t.equal(headers[':method'], 'POST') - t.equal(headers[':path'], '/') - t.equal(headers[':scheme'], 'https') + t.strictEqual(headers[':method'], 'POST') + t.strictEqual(headers[':path'], '/') + t.strictEqual(headers[':scheme'], 'https') stream.on('data', chunk => requestChunks.push(chunk)) @@ -1011,7 +1028,7 @@ test('Should handle h2 request with body (Blob)', { skip: !Blob }, async t => { stream.end('hello h2!') }) - t.plan(8) + t = tspl(t, { plan: 8 }) server.listen(0) await once(server, 'listening') @@ -1023,8 +1040,8 @@ test('Should handle h2 request with body (Blob)', { skip: !Blob }, async t => { allowH2: true }) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + after(() => server.close()) + after(() => client.close()) const response = await client.request({ path: '/', @@ -1041,11 +1058,11 @@ test('Should handle h2 request with body (Blob)', { skip: !Blob }, async t => { await once(response.body, 'end') - t.equal(response.statusCode, 200) - t.equal(response.headers['content-type'], 'text/plain; charset=utf-8') - t.equal(response.headers['x-custom-h2'], 'foo') - t.equal(Buffer.concat(responseBody).toString('utf-8'), 'hello h2!') - t.equal(Buffer.concat(requestChunks).toString('utf-8'), expectedBody) + t.strictEqual(response.statusCode, 200) + t.strictEqual(response.headers['content-type'], 'text/plain; charset=utf-8') + t.strictEqual(response.headers['x-custom-h2'], 'foo') + t.strictEqual(Buffer.concat(responseBody).toString('utf-8'), 'hello h2!') + t.strictEqual(Buffer.concat(requestChunks).toString('utf-8'), expectedBody) }) test( @@ -1062,9 +1079,9 @@ test( buf.copy(new Uint8Array(body)) server.on('stream', async (stream, headers) => { - t.equal(headers[':method'], 'POST') - t.equal(headers[':path'], '/') - t.equal(headers[':scheme'], 'https') + t.strictEqual(headers[':method'], 'POST') + t.strictEqual(headers[':path'], '/') + t.strictEqual(headers[':scheme'], 'https') stream.on('data', chunk => requestChunks.push(chunk)) @@ -1077,7 +1094,7 @@ test( stream.end('hello h2!') }) - t.plan(8) + t = tspl(t, { plan: 8 }) server.listen(0) await once(server, 'listening') @@ -1089,8 +1106,8 @@ test( allowH2: true }) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + after(() => server.close()) + after(() => client.close()) const response = await client.request({ path: '/', @@ -1107,11 +1124,11 @@ test( await once(response.body, 'end') - t.equal(response.statusCode, 200) - t.equal(response.headers['content-type'], 'text/plain; charset=utf-8') - t.equal(response.headers['x-custom-h2'], 'foo') - t.equal(Buffer.concat(responseBody).toString('utf-8'), 'hello h2!') - t.equal(Buffer.concat(requestChunks).toString('utf-8'), expectedBody) + t.strictEqual(response.statusCode, 200) + t.strictEqual(response.headers['content-type'], 'text/plain; charset=utf-8') + t.strictEqual(response.headers['x-custom-h2'], 'foo') + t.strictEqual(Buffer.concat(responseBody).toString('utf-8'), 'hello h2!') + t.strictEqual(Buffer.concat(requestChunks).toString('utf-8'), expectedBody) } ) @@ -1120,8 +1137,8 @@ test('Agent should support H2 connection', async t => { const server = createSecureServer(pem) server.on('stream', (stream, headers) => { - t.equal(headers['x-my-header'], 'foo') - t.equal(headers[':method'], 'GET') + t.strictEqual(headers['x-my-header'], 'foo') + t.strictEqual(headers[':method'], 'GET') stream.respond({ 'content-type': 'text/plain; charset=utf-8', 'x-custom-h2': 'hello', @@ -1140,9 +1157,9 @@ test('Agent should support H2 connection', async t => { allowH2: true }) - t.plan(6) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + t = tspl(t, { plan: 6 }) + after(() => server.close()) + after(() => client.close()) const response = await client.request({ origin: `https://localhost:${server.address().port}`, @@ -1158,18 +1175,20 @@ test('Agent should support H2 connection', async t => { }) await once(response.body, 'end') - t.equal(response.statusCode, 200) - t.equal(response.headers['content-type'], 'text/plain; charset=utf-8') - t.equal(response.headers['x-custom-h2'], 'hello') - t.equal(Buffer.concat(body).toString('utf8'), 'hello h2!') + t.strictEqual(response.statusCode, 200) + t.strictEqual(response.headers['content-type'], 'text/plain; charset=utf-8') + t.strictEqual(response.headers['x-custom-h2'], 'hello') + t.strictEqual(Buffer.concat(body).toString('utf8'), 'hello h2!') }) test( 'Should provide pseudo-headers in proper order', async t => { + t = tspl(t, { plan: 2 }) + const server = createSecureServer(pem) server.on('stream', (stream, _headers, _flags, rawHeaders) => { - t.same(rawHeaders, [ + t.deepStrictEqual(rawHeaders, [ ':authority', `localhost:${server.address().port}`, ':method', @@ -1197,15 +1216,17 @@ test( allowH2: true }) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + after(() => server.close()) + after(() => client.close()) const response = await client.request({ path: '/', method: 'GET' }) - t.equal(response.statusCode, 200) + t.strictEqual(response.statusCode, 200) + + await t.complete } ) @@ -1229,9 +1250,9 @@ test('The h2 pseudo-headers is not included in the headers', async t => { allowH2: true }) - t.plan(2) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + t = tspl(t, { plan: 2 }) + after(() => server.close()) + after(() => client.close()) const response = await client.request({ path: '/', @@ -1240,8 +1261,8 @@ test('The h2 pseudo-headers is not included in the headers', async t => { await response.body.text() - t.equal(response.statusCode, 200) - t.equal(response.headers[':status'], undefined) + t.strictEqual(response.statusCode, 200) + t.strictEqual(response.headers[':status'], undefined) }) test('Should throw informational error on half-closed streams (remote)', async t => { @@ -1261,15 +1282,15 @@ test('Should throw informational error on half-closed streams (remote)', async t allowH2: true }) - t.plan(2) - t.teardown(server.close.bind(server)) - t.teardown(client.close.bind(client)) + t = tspl(t, { plan: 2 }) + after(() => server.close()) + after(() => client.close()) await client.request({ path: '/', method: 'GET' }).catch(err => { - t.equal(err.message, 'HTTP/2: stream half-closed (remote)') - t.equal(err.code, 'UND_ERR_INFO') + t.strictEqual(err.message, 'HTTP/2: stream half-closed (remote)') + t.strictEqual(err.code, 'UND_ERR_INFO') }) }) diff --git a/test/readable.test.js b/test/readable.test.js index 3d6b5b1cea1..8e73301ea57 100644 --- a/test/readable.test.js +++ b/test/readable.test.js @@ -36,7 +36,7 @@ test('destroy timing text', async function (t) { const r = new Readable({ resume, abort }) r.destroy(new Error('kaboom')) - t.rejects(r.text(), new Error('kaboom')) + await t.rejects(r.text(), new Error('kaboom')) }) test('destroy timing promise', async function (t) { diff --git a/test/request.js b/test/request.js index bbfab5b3f5c..628bed0d415 100644 --- a/test/request.js +++ b/test/request.js @@ -1,10 +1,13 @@ 'use strict' +const { tspl } = require('@matteo.collina/tspl') const { createServer } = require('node:http') -const { test } = require('tap') +const { test, after, describe } = require('node:test') const { request, errors } = require('..') test('no-slash/one-slash pathname should be included in req.path', async (t) => { + t = tspl(t, { plan: 24 }) + const pathServer = createServer((req, res) => { t.fail('it shouldn\'t be called') res.statusCode = 200 @@ -12,15 +15,17 @@ test('no-slash/one-slash pathname should be included in req.path', async (t) => }) const requestedServer = createServer((req, res) => { - t.equal(`/localhost:${pathServer.address().port}`, req.url) - t.equal('GET', req.method) - t.equal(`localhost:${requestedServer.address().port}`, req.headers.host) + t.strictEqual(`/localhost:${pathServer.address().port}`, req.url) + t.strictEqual('GET', req.method) + t.strictEqual(`localhost:${requestedServer.address().port}`, req.headers.host) res.statusCode = 200 res.end('hello') }) - t.teardown(requestedServer.close.bind(requestedServer)) - t.teardown(pathServer.close.bind(pathServer)) + after(() => { + requestedServer.close() + pathServer.close() + }) await Promise.all([ requestedServer.listen(0), @@ -32,39 +37,41 @@ test('no-slash/one-slash pathname should be included in req.path', async (t) => origin: `http://localhost:${requestedServer.address().port}`, pathname: `localhost:${pathServer.address().port}` }) - t.equal(noSlashPathname.statusCode, 200) + t.strictEqual(noSlashPathname.statusCode, 200) const noSlashPath = await request({ method: 'GET', origin: `http://localhost:${requestedServer.address().port}`, path: `localhost:${pathServer.address().port}` }) - t.equal(noSlashPath.statusCode, 200) + t.strictEqual(noSlashPath.statusCode, 200) const noSlashPath2Arg = await request( `http://localhost:${requestedServer.address().port}`, { path: `localhost:${pathServer.address().port}` } ) - t.equal(noSlashPath2Arg.statusCode, 200) + t.strictEqual(noSlashPath2Arg.statusCode, 200) const oneSlashPathname = await request({ method: 'GET', origin: `http://localhost:${requestedServer.address().port}`, pathname: `/localhost:${pathServer.address().port}` }) - t.equal(oneSlashPathname.statusCode, 200) + t.strictEqual(oneSlashPathname.statusCode, 200) const oneSlashPath = await request({ method: 'GET', origin: `http://localhost:${requestedServer.address().port}`, path: `/localhost:${pathServer.address().port}` }) - t.equal(oneSlashPath.statusCode, 200) + t.strictEqual(oneSlashPath.statusCode, 200) const oneSlashPath2Arg = await request( `http://localhost:${requestedServer.address().port}`, { path: `/localhost:${pathServer.address().port}` } ) - t.equal(oneSlashPath2Arg.statusCode, 200) + t.strictEqual(oneSlashPath2Arg.statusCode, 200) t.end() }) test('protocol-relative URL as pathname should be included in req.path', async (t) => { + t = tspl(t, { plan: 12 }) + const pathServer = createServer((req, res) => { t.fail('it shouldn\'t be called') res.statusCode = 200 @@ -72,15 +79,17 @@ test('protocol-relative URL as pathname should be included in req.path', async ( }) const requestedServer = createServer((req, res) => { - t.equal(`//localhost:${pathServer.address().port}`, req.url) - t.equal('GET', req.method) - t.equal(`localhost:${requestedServer.address().port}`, req.headers.host) + t.strictEqual(`//localhost:${pathServer.address().port}`, req.url) + t.strictEqual('GET', req.method) + t.strictEqual(`localhost:${requestedServer.address().port}`, req.headers.host) res.statusCode = 200 res.end('hello') }) - t.teardown(requestedServer.close.bind(requestedServer)) - t.teardown(pathServer.close.bind(pathServer)) + after(() => { + requestedServer.close() + pathServer.close() + }) await Promise.all([ requestedServer.listen(0), @@ -92,22 +101,24 @@ test('protocol-relative URL as pathname should be included in req.path', async ( origin: `http://localhost:${requestedServer.address().port}`, pathname: `//localhost:${pathServer.address().port}` }) - t.equal(noSlashPathname.statusCode, 200) + t.strictEqual(noSlashPathname.statusCode, 200) const noSlashPath = await request({ method: 'GET', origin: `http://localhost:${requestedServer.address().port}`, path: `//localhost:${pathServer.address().port}` }) - t.equal(noSlashPath.statusCode, 200) + t.strictEqual(noSlashPath.statusCode, 200) const noSlashPath2Arg = await request( `http://localhost:${requestedServer.address().port}`, { path: `//localhost:${pathServer.address().port}` } ) - t.equal(noSlashPath2Arg.statusCode, 200) + t.strictEqual(noSlashPath2Arg.statusCode, 200) t.end() }) test('Absolute URL as pathname should be included in req.path', async (t) => { + t = tspl(t, { plan: 12 }) + const pathServer = createServer((req, res) => { t.fail('it shouldn\'t be called') res.statusCode = 200 @@ -115,15 +126,17 @@ test('Absolute URL as pathname should be included in req.path', async (t) => { }) const requestedServer = createServer((req, res) => { - t.equal(`/http://localhost:${pathServer.address().port}`, req.url) - t.equal('GET', req.method) - t.equal(`localhost:${requestedServer.address().port}`, req.headers.host) + t.strictEqual(`/http://localhost:${pathServer.address().port}`, req.url) + t.strictEqual('GET', req.method) + t.strictEqual(`localhost:${requestedServer.address().port}`, req.headers.host) res.statusCode = 200 res.end('hello') }) - t.teardown(requestedServer.close.bind(requestedServer)) - t.teardown(pathServer.close.bind(pathServer)) + after(() => { + requestedServer.close() + pathServer.close() + }) await Promise.all([ requestedServer.listen(0), @@ -135,46 +148,46 @@ test('Absolute URL as pathname should be included in req.path', async (t) => { origin: `http://localhost:${requestedServer.address().port}`, pathname: `http://localhost:${pathServer.address().port}` }) - t.equal(noSlashPathname.statusCode, 200) + t.strictEqual(noSlashPathname.statusCode, 200) const noSlashPath = await request({ method: 'GET', origin: `http://localhost:${requestedServer.address().port}`, path: `http://localhost:${pathServer.address().port}` }) - t.equal(noSlashPath.statusCode, 200) + t.strictEqual(noSlashPath.statusCode, 200) const noSlashPath2Arg = await request( `http://localhost:${requestedServer.address().port}`, { path: `http://localhost:${pathServer.address().port}` } ) - t.equal(noSlashPath2Arg.statusCode, 200) + t.strictEqual(noSlashPath2Arg.statusCode, 200) t.end() }) -test('DispatchOptions#reset', scope => { - scope.plan(4) +describe('DispatchOptions#reset', () => { + test('Should throw if invalid reset option', async t => { + t = tspl(t, { plan: 1 }) - scope.test('Should throw if invalid reset option', t => { - t.plan(1) - - t.rejects(request({ + await t.rejects(request({ method: 'GET', origin: 'http://somehost.xyz', reset: 0 - }), 'invalid reset') + }), /invalid reset/) + + await t.completed }) - scope.test('Should include "connection:close" if reset true', async t => { + test('Should include "connection:close" if reset true', async t => { + t = tspl(t, { plan: 3 }) + const server = createServer((req, res) => { - t.equal('GET', req.method) - t.equal(`localhost:${server.address().port}`, req.headers.host) - t.equal(req.headers.connection, 'close') + t.strictEqual('GET', req.method) + t.strictEqual(`localhost:${server.address().port}`, req.headers.host) + t.strictEqual(req.headers.connection, 'close') res.statusCode = 200 res.end('hello') }) - t.plan(3) - - t.teardown(server.close.bind(server)) + after(() => server.close()) await new Promise((resolve, reject) => { server.listen(0, (err) => { @@ -190,18 +203,18 @@ test('DispatchOptions#reset', scope => { }) }) - scope.test('Should include "connection:keep-alive" if reset false', async t => { + test('Should include "connection:keep-alive" if reset false', async t => { + t = tspl(t, { plan: 3 }) + const server = createServer((req, res) => { - t.equal('GET', req.method) - t.equal(`localhost:${server.address().port}`, req.headers.host) - t.equal(req.headers.connection, 'keep-alive') + t.strictEqual('GET', req.method) + t.strictEqual(`localhost:${server.address().port}`, req.headers.host) + t.strictEqual(req.headers.connection, 'keep-alive') res.statusCode = 200 res.end('hello') }) - t.plan(3) - - t.teardown(server.close.bind(server)) + after(() => server.close()) await new Promise((resolve, reject) => { server.listen(0, (err) => { @@ -217,18 +230,18 @@ test('DispatchOptions#reset', scope => { }) }) - scope.test('Should react to manual set of "connection:close" header', async t => { + test('Should react to manual set of "connection:close" header', async t => { + t = tspl(t, { plan: 3 }) + const server = createServer((req, res) => { - t.equal('GET', req.method) - t.equal(`localhost:${server.address().port}`, req.headers.host) - t.equal(req.headers.connection, 'close') + t.strictEqual('GET', req.method) + t.strictEqual(`localhost:${server.address().port}`, req.headers.host) + t.strictEqual(req.headers.connection, 'close') res.statusCode = 200 res.end('hello') }) - t.plan(3) - - t.teardown(server.close.bind(server)) + after(() => server.close()) await new Promise((resolve, reject) => { server.listen(0, (err) => { @@ -247,14 +260,14 @@ test('DispatchOptions#reset', scope => { }) }) -test('Should include headers from iterable objects', scope => { - scope.plan(4) +describe('Should include headers from iterable objects', scope => { + test('Should include headers built with Headers global object', async t => { + t = tspl(t, { plan: 3 }) - scope.test('Should include headers built with Headers global object', async t => { const server = createServer((req, res) => { - t.equal('GET', req.method) - t.equal(`localhost:${server.address().port}`, req.headers.host) - t.equal(req.headers.hello, 'world') + t.strictEqual('GET', req.method) + t.strictEqual(`localhost:${server.address().port}`, req.headers.host) + t.strictEqual(req.headers.hello, 'world') res.statusCode = 200 res.end('hello') }) @@ -262,9 +275,7 @@ test('Should include headers from iterable objects', scope => { const headers = new Headers() headers.set('hello', 'world') - t.plan(3) - - t.teardown(server.close.bind(server)) + after(() => server.close()) await new Promise((resolve, reject) => { server.listen(0, (err) => { @@ -281,11 +292,13 @@ test('Should include headers from iterable objects', scope => { }) }) - scope.test('Should include headers built with Map', async t => { + test('Should include headers built with Map', async t => { + t = tspl(t, { plan: 3 }) + const server = createServer((req, res) => { - t.equal('GET', req.method) - t.equal(`localhost:${server.address().port}`, req.headers.host) - t.equal(req.headers.hello, 'world') + t.strictEqual('GET', req.method) + t.strictEqual(`localhost:${server.address().port}`, req.headers.host) + t.strictEqual(req.headers.hello, 'world') res.statusCode = 200 res.end('hello') }) @@ -293,9 +306,7 @@ test('Should include headers from iterable objects', scope => { const headers = new Map() headers.set('hello', 'world') - t.plan(3) - - t.teardown(server.close.bind(server)) + after(() => server.close()) await new Promise((resolve, reject) => { server.listen(0, (err) => { @@ -312,11 +323,13 @@ test('Should include headers from iterable objects', scope => { }) }) - scope.test('Should include headers built with custom iterable object', async t => { + test('Should include headers built with custom iterable object', async t => { + t = tspl(t, { plan: 3 }) + const server = createServer((req, res) => { - t.equal('GET', req.method) - t.equal(`localhost:${server.address().port}`, req.headers.host) - t.equal(req.headers.hello, 'world') + t.strictEqual('GET', req.method) + t.strictEqual(`localhost:${server.address().port}`, req.headers.host) + t.strictEqual(req.headers.hello, 'world') res.statusCode = 200 res.end('hello') }) @@ -327,9 +340,7 @@ test('Should include headers from iterable objects', scope => { } } - t.plan(3) - - t.teardown(server.close.bind(server)) + after(() => server.close()) await new Promise((resolve, reject) => { server.listen(0, (err) => { @@ -346,7 +357,9 @@ test('Should include headers from iterable objects', scope => { }) }) - scope.test('Should throw error if headers iterable object does not yield key-value pairs', async t => { + test('Should throw error if headers iterable object does not yield key-value pairs', async t => { + t = tspl(t, { plan: 2 }) + const server = createServer((req, res) => { res.end('hello') }) @@ -357,9 +370,7 @@ test('Should include headers from iterable objects', scope => { } } - t.plan(2) - - t.teardown(server.close.bind(server)) + after(() => server.close()) await new Promise((resolve, reject) => { server.listen(0, (err) => { @@ -374,8 +385,8 @@ test('Should include headers from iterable objects', scope => { reset: true, headers }).catch((err) => { - t.type(err, errors.InvalidArgumentError) - t.equal(err.message, 'headers must be in key-value pair format') + t.ok(err instanceof errors.InvalidArgumentError) + t.strictEqual(err.message, 'headers must be in key-value pair format') }) }) })