fastify 5.3.2 → 5.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/README.md +2 -0
  2. package/build/build-validation.js +2 -1
  3. package/docs/Guides/Delay-Accepting-Requests.md +3 -3
  4. package/docs/Guides/Ecosystem.md +16 -7
  5. package/docs/Guides/Serverless.md +28 -69
  6. package/docs/Reference/ContentTypeParser.md +1 -1
  7. package/docs/Reference/Errors.md +2 -4
  8. package/docs/Reference/Hooks.md +14 -14
  9. package/docs/Reference/Logging.md +3 -3
  10. package/docs/Reference/Middleware.md +1 -1
  11. package/docs/Reference/Reply.md +8 -8
  12. package/docs/Reference/Request.md +1 -1
  13. package/docs/Reference/Routes.md +3 -3
  14. package/docs/Reference/Server.md +40 -10
  15. package/docs/Reference/Validation-and-Serialization.md +1 -1
  16. package/eslint.config.js +17 -9
  17. package/fastify.d.ts +2 -1
  18. package/fastify.js +20 -4
  19. package/lib/configValidator.js +1 -1
  20. package/lib/decorate.js +2 -2
  21. package/lib/errors.js +6 -8
  22. package/lib/logger-factory.js +1 -1
  23. package/lib/logger-pino.js +2 -2
  24. package/lib/pluginOverride.js +3 -1
  25. package/lib/reply.js +9 -13
  26. package/lib/request.js +4 -11
  27. package/lib/server.js +30 -51
  28. package/lib/symbols.js +1 -0
  29. package/lib/warnings.js +8 -0
  30. package/package.json +11 -7
  31. package/test/404s.test.js +226 -325
  32. package/test/allow-unsafe-regex.test.js +19 -48
  33. package/test/als.test.js +28 -40
  34. package/test/async-await.test.js +11 -2
  35. package/test/body-limit.test.js +41 -65
  36. package/test/build-certificate.js +1 -1
  37. package/test/close-pipelining.test.js +5 -4
  38. package/test/custom-parser-async.test.js +17 -22
  39. package/test/decorator-namespace.test._js_ +3 -4
  40. package/test/decorator.test.js +422 -341
  41. package/test/diagnostics-channel/async-delay-request.test.js +7 -16
  42. package/test/diagnostics-channel/sync-delay-request.test.js +7 -16
  43. package/test/helper.js +108 -70
  44. package/test/hooks-async.test.js +248 -218
  45. package/test/hooks.on-listen.test.js +255 -239
  46. package/test/hooks.on-ready.test.js +110 -92
  47. package/test/hooks.test.js +910 -769
  48. package/test/http-methods/lock.test.js +31 -31
  49. package/test/http-methods/mkcol.test.js +5 -9
  50. package/test/http-methods/proppatch.test.js +23 -29
  51. package/test/http-methods/report.test.js +44 -69
  52. package/test/http-methods/search.test.js +67 -82
  53. package/test/http2/closing.test.js +38 -20
  54. package/test/http2/secure-with-fallback.test.js +28 -27
  55. package/test/https/https.test.js +56 -53
  56. package/test/inject.test.js +114 -97
  57. package/test/input-validation.js +63 -53
  58. package/test/internals/errors.test.js +0 -10
  59. package/test/internals/handle-request.test.js +49 -66
  60. package/test/internals/hooks.test.js +17 -0
  61. package/test/issue-4959.test.js +14 -5
  62. package/test/listen.4.test.js +31 -43
  63. package/test/logger/response.test.js +19 -20
  64. package/test/nullable-validation.test.js +33 -46
  65. package/test/options.error-handler.test.js +1 -1
  66. package/test/options.test.js +1 -1
  67. package/test/output-validation.test.js +49 -72
  68. package/test/patch.error-handler.test.js +1 -1
  69. package/test/patch.test.js +1 -1
  70. package/test/plugin.1.test.js +71 -60
  71. package/test/plugin.2.test.js +104 -86
  72. package/test/plugin.3.test.js +56 -35
  73. package/test/plugin.4.test.js +124 -119
  74. package/test/promises.test.js +36 -30
  75. package/test/proto-poisoning.test.js +78 -97
  76. package/test/put.error-handler.test.js +1 -1
  77. package/test/put.test.js +1 -1
  78. package/test/reply-error.test.js +169 -148
  79. package/test/reply-trailers.test.js +119 -108
  80. package/test/request-error.test.js +0 -46
  81. package/test/route-hooks.test.js +112 -92
  82. package/test/route-prefix.test.js +194 -133
  83. package/test/schema-feature.test.js +309 -238
  84. package/test/schema-serialization.test.js +177 -154
  85. package/test/schema-special-usage.test.js +165 -132
  86. package/test/schema-validation.test.js +278 -199
  87. package/test/set-error-handler.test.js +58 -1
  88. package/test/skip-reply-send.test.js +64 -69
  89. package/test/stream.1.test.js +30 -27
  90. package/test/stream.2.test.js +20 -10
  91. package/test/stream.3.test.js +37 -31
  92. package/test/trust-proxy.test.js +32 -58
  93. package/test/types/errors.test-d.ts +0 -1
  94. package/test/types/fastify.test-d.ts +3 -0
  95. package/test/types/plugin.test-d.ts +1 -1
  96. package/test/types/register.test-d.ts +1 -1
  97. package/test/types/request.test-d.ts +1 -0
  98. package/test/url-rewriting.test.js +45 -62
  99. package/test/use-semicolon-delimiter.test.js +1 -1
  100. package/types/errors.d.ts +0 -1
  101. package/types/request.d.ts +1 -0
  102. package/.taprc +0 -7
  103. package/test/http2/missing-http2-module.test.js +0 -17
@@ -2,7 +2,7 @@
2
2
 
3
3
  const { test } = require('node:test')
4
4
  const Fastify = require('..')
5
- const { FST_ERR_ERROR_HANDLER_NOT_FN } = require('../lib/errors')
5
+ const { FST_ERR_ERROR_HANDLER_NOT_FN, FST_ERR_ERROR_HANDLER_ALREADY_SET } = require('../lib/errors')
6
6
 
7
7
  test('setErrorHandler should throw an error if the handler is not a function', t => {
8
8
  t.plan(1)
@@ -10,3 +10,60 @@ test('setErrorHandler should throw an error if the handler is not a function', t
10
10
 
11
11
  t.assert.throws(() => fastify.setErrorHandler('not a function'), new FST_ERR_ERROR_HANDLER_NOT_FN())
12
12
  })
13
+
14
+ test('setErrorHandler can be set independently in parent and child scopes', async t => {
15
+ t.plan(1)
16
+
17
+ const fastify = Fastify()
18
+
19
+ t.assert.doesNotThrow(() => {
20
+ fastify.setErrorHandler(() => {})
21
+ fastify.register(async (child) => {
22
+ child.setErrorHandler(() => {})
23
+ })
24
+ })
25
+ })
26
+
27
+ test('setErrorHandler can be overriden if allowErrorHandlerOverride is set to true', async t => {
28
+ t.plan(2)
29
+
30
+ const fastify = Fastify()
31
+ t.after(() => fastify.close())
32
+
33
+ fastify.register(async (child) => {
34
+ child.setErrorHandler(() => {})
35
+ t.assert.doesNotThrow(() => child.setErrorHandler(() => {}))
36
+ })
37
+
38
+ fastify.setErrorHandler(() => {})
39
+ t.assert.doesNotThrow(() => fastify.setErrorHandler(() => {}))
40
+
41
+ await fastify.ready()
42
+ })
43
+
44
+ test('if `allowErrorHandlerOverride` is disabled, setErrorHandler should throw if called more than once in the same scope', t => {
45
+ t.plan(1)
46
+
47
+ const fastify = Fastify({
48
+ allowErrorHandlerOverride: false
49
+ })
50
+
51
+ fastify.setErrorHandler(() => {})
52
+ t.assert.throws(() => fastify.setErrorHandler(() => {}), new FST_ERR_ERROR_HANDLER_ALREADY_SET())
53
+ })
54
+
55
+ test('if `allowErrorHandlerOverride` is disabled, setErrorHandler should throw if called more than once in the same scope 2', async t => {
56
+ t.plan(1)
57
+
58
+ const fastify = Fastify({
59
+ allowErrorHandlerOverride: false
60
+ })
61
+ t.after(() => fastify.close())
62
+
63
+ fastify.register(async (child) => {
64
+ child.setErrorHandler(() => {})
65
+ t.assert.throws(() => child.setErrorHandler(() => {}), new FST_ERR_ERROR_HANDLER_ALREADY_SET())
66
+ })
67
+
68
+ await fastify.ready()
69
+ })
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const { test } = require('tap')
3
+ const { test, describe } = require('node:test')
4
4
  const split = require('split2')
5
5
  const net = require('node:net')
6
6
  const Fastify = require('../fastify')
@@ -19,7 +19,7 @@ const lifecycleHooks = [
19
19
  'onError'
20
20
  ]
21
21
 
22
- test('skip automatic reply.send() with reply.hijack and a body', (t) => {
22
+ test('skip automatic reply.send() with reply.hijack and a body', async (t) => {
23
23
  const stream = split(JSON.parse)
24
24
  const app = Fastify({
25
25
  logger: {
@@ -28,8 +28,8 @@ test('skip automatic reply.send() with reply.hijack and a body', (t) => {
28
28
  })
29
29
 
30
30
  stream.on('data', (line) => {
31
- t.not(line.level, 40) // there are no errors
32
- t.not(line.level, 50) // there are no errors
31
+ t.assert.notStrictEqual(line.level, 40) // there are no errors
32
+ t.assert.notStrictEqual(line.level, 50) // there are no errors
33
33
  })
34
34
 
35
35
  app.get('/', (req, reply) => {
@@ -39,16 +39,16 @@ test('skip automatic reply.send() with reply.hijack and a body', (t) => {
39
39
  return Promise.resolve('this will be skipped')
40
40
  })
41
41
 
42
- return app.inject({
42
+ await app.inject({
43
43
  method: 'GET',
44
44
  url: '/'
45
45
  }).then((res) => {
46
- t.equal(res.statusCode, 200)
47
- t.equal(res.body, 'hello world')
46
+ t.assert.strictEqual(res.statusCode, 200)
47
+ t.assert.strictEqual(res.body, 'hello world')
48
48
  })
49
49
  })
50
50
 
51
- test('skip automatic reply.send() with reply.hijack and no body', (t) => {
51
+ test('skip automatic reply.send() with reply.hijack and no body', async (t) => {
52
52
  const stream = split(JSON.parse)
53
53
  const app = Fastify({
54
54
  logger: {
@@ -57,8 +57,8 @@ test('skip automatic reply.send() with reply.hijack and no body', (t) => {
57
57
  })
58
58
 
59
59
  stream.on('data', (line) => {
60
- t.not(line.level, 40) // there are no error
61
- t.not(line.level, 50) // there are no error
60
+ t.assert.notStrictEqual(line.level, 40) // there are no error
61
+ t.assert.notStrictEqual(line.level, 50) // there are no error
62
62
  })
63
63
 
64
64
  app.get('/', (req, reply) => {
@@ -68,16 +68,16 @@ test('skip automatic reply.send() with reply.hijack and no body', (t) => {
68
68
  return Promise.resolve()
69
69
  })
70
70
 
71
- return app.inject({
71
+ await app.inject({
72
72
  method: 'GET',
73
73
  url: '/'
74
74
  }).then((res) => {
75
- t.equal(res.statusCode, 200)
76
- t.equal(res.body, 'hello world')
75
+ t.assert.strictEqual(res.statusCode, 200)
76
+ t.assert.strictEqual(res.body, 'hello world')
77
77
  })
78
78
  })
79
79
 
80
- test('skip automatic reply.send() with reply.hijack and an error', (t) => {
80
+ test('skip automatic reply.send() with reply.hijack and an error', async (t) => {
81
81
  const stream = split(JSON.parse)
82
82
  const app = Fastify({
83
83
  logger: {
@@ -90,8 +90,8 @@ test('skip automatic reply.send() with reply.hijack and an error', (t) => {
90
90
  stream.on('data', (line) => {
91
91
  if (line.level === 50) {
92
92
  errorSeen = true
93
- t.equal(line.err.message, 'kaboom')
94
- t.equal(line.msg, 'Promise errored, but reply.sent = true was set')
93
+ t.assert.strictEqual(line.err.message, 'kaboom')
94
+ t.assert.strictEqual(line.msg, 'Promise errored, but reply.sent = true was set')
95
95
  }
96
96
  })
97
97
 
@@ -102,13 +102,13 @@ test('skip automatic reply.send() with reply.hijack and an error', (t) => {
102
102
  return Promise.reject(new Error('kaboom'))
103
103
  })
104
104
 
105
- return app.inject({
105
+ await app.inject({
106
106
  method: 'GET',
107
107
  url: '/'
108
108
  }).then((res) => {
109
- t.equal(errorSeen, true)
110
- t.equal(res.statusCode, 200)
111
- t.equal(res.body, 'hello world')
109
+ t.assert.strictEqual(errorSeen, true)
110
+ t.assert.strictEqual(res.statusCode, 200)
111
+ t.assert.strictEqual(res.body, 'hello world')
112
112
  })
113
113
  })
114
114
 
@@ -117,11 +117,8 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
117
117
  const previousHooks = lifecycleHooks.slice(0, idx)
118
118
  const nextHooks = lifecycleHooks.slice(idx + 1)
119
119
 
120
- test(`Hijacking inside ${hookOrHandler} skips all the following hooks and handler execution`, t => {
121
- t.plan(4)
122
- const test = t.test
123
-
124
- test('Sending a response using reply.raw => onResponse hook is called', t => {
120
+ describe(`Hijacking inside ${hookOrHandler} skips all the following hooks and handler execution`, () => {
121
+ test('Sending a response using reply.raw => onResponse hook is called', async (t) => {
125
122
  const stream = split(JSON.parse)
126
123
  const app = Fastify({
127
124
  logger: {
@@ -130,11 +127,11 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
130
127
  })
131
128
 
132
129
  stream.on('data', (line) => {
133
- t.not(line.level, 40) // there are no errors
134
- t.not(line.level, 50) // there are no errors
130
+ t.assert.notStrictEqual(line.level, 40) // there are no errors
131
+ t.assert.notStrictEqual(line.level, 50) // there are no errors
135
132
  })
136
133
 
137
- previousHooks.forEach(h => app.addHook(h, async (req, reply) => t.pass(`${h} should be called`)))
134
+ previousHooks.forEach(h => app.addHook(h, async (req, reply) => t.assert.ok(`${h} should be called`)))
138
135
 
139
136
  if (hookOrHandler === 'handler') {
140
137
  app.get('/', (req, reply) => {
@@ -146,41 +143,41 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
146
143
  reply.hijack()
147
144
  reply.raw.end(`hello from ${hookOrHandler}`)
148
145
  })
149
- app.get('/', (req, reply) => t.fail('Handler should not be called'))
146
+ app.get('/', (req, reply) => t.assert.fail('Handler should not be called'))
150
147
  }
151
148
 
152
149
  nextHooks.forEach(h => {
153
150
  if (h === 'onResponse') {
154
- app.addHook(h, async (req, reply) => t.pass(`${h} should be called`))
151
+ app.addHook(h, async (req, reply) => t.assert.ok(`${h} should be called`))
155
152
  } else {
156
- app.addHook(h, async (req, reply) => t.fail(`${h} should not be called`))
153
+ app.addHook(h, async (req, reply) => t.assert.fail(`${h} should not be called`))
157
154
  }
158
155
  })
159
156
 
160
- return app.inject({
157
+ await app.inject({
161
158
  method: 'GET',
162
159
  url: '/'
163
160
  }).then((res) => {
164
- t.equal(res.statusCode, 200)
165
- t.equal(res.body, `hello from ${hookOrHandler}`)
161
+ t.assert.strictEqual(res.statusCode, 200)
162
+ t.assert.strictEqual(res.body, `hello from ${hookOrHandler}`)
166
163
  })
167
164
  })
168
165
 
169
- test('Sending a response using req.socket => onResponse not called', t => {
166
+ test('Sending a response using req.socket => onResponse not called', (t, testDone) => {
170
167
  const stream = split(JSON.parse)
171
168
  const app = Fastify({
172
169
  logger: {
173
170
  stream
174
171
  }
175
172
  })
176
- t.teardown(() => app.close())
173
+ t.after(() => app.close())
177
174
 
178
175
  stream.on('data', (line) => {
179
- t.not(line.level, 40) // there are no errors
180
- t.not(line.level, 50) // there are no errors
176
+ t.assert.notStrictEqual(line.level, 40) // there are no errors
177
+ t.assert.notStrictEqual(line.level, 50) // there are no errors
181
178
  })
182
179
 
183
- previousHooks.forEach(h => app.addHook(h, async (req, reply) => t.pass(`${h} should be called`)))
180
+ previousHooks.forEach(h => app.addHook(h, async (req, reply) => t.assert.ok(`${h} should be called`)))
184
181
 
185
182
  if (hookOrHandler === 'handler') {
186
183
  app.get('/', (req, reply) => {
@@ -196,13 +193,13 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
196
193
  req.socket.write(`hello from ${hookOrHandler}`)
197
194
  req.socket.end()
198
195
  })
199
- app.get('/', (req, reply) => t.fail('Handler should not be called'))
196
+ app.get('/', (req, reply) => t.assert.fail('Handler should not be called'))
200
197
  }
201
198
 
202
- nextHooks.forEach(h => app.addHook(h, async (req, reply) => t.fail(`${h} should not be called`)))
199
+ nextHooks.forEach(h => app.addHook(h, async (req, reply) => t.assert.fail(`${h} should not be called`)))
203
200
 
204
201
  app.listen({ port: 0 }, err => {
205
- t.error(err)
202
+ t.assert.ifError(err)
206
203
  const client = net.createConnection({ port: (app.server.address()).port }, () => {
207
204
  client.write('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n')
208
205
 
@@ -213,36 +210,36 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
213
210
  })
214
211
 
215
212
  client.on('end', function () {
216
- t.match(chunks, new RegExp(`hello from ${hookOrHandler}`, 'i'))
217
- t.end()
213
+ t.assert.match(chunks, new RegExp(`hello from ${hookOrHandler}`, 'i'))
214
+ testDone()
218
215
  })
219
216
  })
220
217
  })
221
218
  })
222
219
 
223
- test('Throwing an error does not trigger any hooks', t => {
220
+ test('Throwing an error does not trigger any hooks', async (t) => {
224
221
  const stream = split(JSON.parse)
225
222
  const app = Fastify({
226
223
  logger: {
227
224
  stream
228
225
  }
229
226
  })
230
- t.teardown(() => app.close())
227
+ t.after(() => app.close())
231
228
 
232
229
  let errorSeen = false
233
230
  stream.on('data', (line) => {
234
231
  if (hookOrHandler === 'handler') {
235
232
  if (line.level === 40) {
236
233
  errorSeen = true
237
- t.equal(line.err.code, 'FST_ERR_REP_ALREADY_SENT')
234
+ t.assert.strictEqual(line.err.code, 'FST_ERR_REP_ALREADY_SENT')
238
235
  }
239
236
  } else {
240
- t.not(line.level, 40) // there are no errors
241
- t.not(line.level, 50) // there are no errors
237
+ t.assert.notStrictEqual(line.level, 40) // there are no errors
238
+ t.assert.notStrictEqual(line.level, 50) // there are no errors
242
239
  }
243
240
  })
244
241
 
245
- previousHooks.forEach(h => app.addHook(h, async (req, reply) => t.pass(`${h} should be called`)))
242
+ previousHooks.forEach(h => app.addHook(h, async (req, reply) => t.assert.ok(`${h} should be called`)))
246
243
 
247
244
  if (hookOrHandler === 'handler') {
248
245
  app.get('/', (req, reply) => {
@@ -254,23 +251,22 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
254
251
  reply.hijack()
255
252
  throw new Error('This wil be skipped')
256
253
  })
257
- app.get('/', (req, reply) => t.fail('Handler should not be called'))
254
+ app.get('/', (req, reply) => t.assert.fail('Handler should not be called'))
258
255
  }
259
256
 
260
- nextHooks.forEach(h => app.addHook(h, async (req, reply) => t.fail(`${h} should not be called`)))
257
+ nextHooks.forEach(h => app.addHook(h, async (req, reply) => t.assert.fail(`${h} should not be called`)))
261
258
 
262
- return Promise.race([
259
+ await Promise.race([
263
260
  app.inject({ method: 'GET', url: '/' }),
264
261
  new Promise((resolve, reject) => setTimeout(resolve, 1000))
265
- ]).then((err, res) => {
266
- t.error(err)
267
- if (hookOrHandler === 'handler') {
268
- t.equal(errorSeen, true)
269
- }
270
- })
262
+ ])
263
+
264
+ if (hookOrHandler === 'handler') {
265
+ t.assert.strictEqual(errorSeen, true)
266
+ }
271
267
  })
272
268
 
273
- test('Calling reply.send() after hijacking logs a warning', t => {
269
+ test('Calling reply.send() after hijacking logs a warning', async (t) => {
274
270
  const stream = split(JSON.parse)
275
271
  const app = Fastify({
276
272
  logger: {
@@ -283,11 +279,11 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
283
279
  stream.on('data', (line) => {
284
280
  if (line.level === 40) {
285
281
  errorSeen = true
286
- t.equal(line.err.code, 'FST_ERR_REP_ALREADY_SENT')
282
+ t.assert.strictEqual(line.err.code, 'FST_ERR_REP_ALREADY_SENT')
287
283
  }
288
284
  })
289
285
 
290
- previousHooks.forEach(h => app.addHook(h, async (req, reply) => t.pass(`${h} should be called`)))
286
+ previousHooks.forEach(h => app.addHook(h, async (req, reply) => t.assert.ok(`${h} should be called`)))
291
287
 
292
288
  if (hookOrHandler === 'handler') {
293
289
  app.get('/', (req, reply) => {
@@ -299,18 +295,17 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
299
295
  reply.hijack()
300
296
  return reply.send('hello from reply.send()')
301
297
  })
302
- app.get('/', (req, reply) => t.fail('Handler should not be called'))
298
+ app.get('/', (req, reply) => t.assert.fail('Handler should not be called'))
303
299
  }
304
300
 
305
- nextHooks.forEach(h => app.addHook(h, async (req, reply) => t.fail(`${h} should not be called`)))
301
+ nextHooks.forEach(h => app.addHook(h, async (req, reply) => t.assert.fail(`${h} should not be called`)))
306
302
 
307
- return Promise.race([
303
+ await Promise.race([
308
304
  app.inject({ method: 'GET', url: '/' }),
309
305
  new Promise((resolve, reject) => setTimeout(resolve, 1000))
310
- ]).then((err, res) => {
311
- t.error(err)
312
- t.equal(errorSeen, true)
313
- })
306
+ ])
307
+
308
+ t.assert.strictEqual(errorSeen, true)
314
309
  })
315
310
  })
316
311
  }
@@ -1,12 +1,11 @@
1
1
  'use strict'
2
2
 
3
- const t = require('tap')
4
- const test = t.test
3
+ const { test } = require('node:test')
5
4
  const sget = require('simple-get').concat
6
5
  const fs = require('node:fs')
7
6
  const Fastify = require('../fastify')
8
7
 
9
- test('should respond with a stream', t => {
8
+ test('should respond with a stream', (t, testDone) => {
10
9
  t.plan(6)
11
10
  const fastify = Fastify()
12
11
 
@@ -16,23 +15,24 @@ test('should respond with a stream', t => {
16
15
  })
17
16
 
18
17
  fastify.listen({ port: 0 }, err => {
19
- t.error(err)
20
- t.teardown(() => { fastify.close() })
18
+ t.assert.ifError(err)
19
+ t.after(() => { fastify.close() })
21
20
 
22
21
  sget(`http://localhost:${fastify.server.address().port}`, function (err, response, data) {
23
- t.error(err)
24
- t.equal(response.headers['content-type'], undefined)
25
- t.equal(response.statusCode, 200)
22
+ t.assert.ifError(err)
23
+ t.assert.strictEqual(response.headers['content-type'], undefined)
24
+ t.assert.strictEqual(response.statusCode, 200)
26
25
 
27
26
  fs.readFile(__filename, (err, expected) => {
28
- t.error(err)
29
- t.equal(expected.toString(), data.toString())
27
+ t.assert.ifError(err)
28
+ t.assert.strictEqual(expected.toString(), data.toString())
29
+ testDone()
30
30
  })
31
31
  })
32
32
  })
33
33
  })
34
34
 
35
- test('should respond with a stream (error)', t => {
35
+ test('should respond with a stream (error)', (t, testDone) => {
36
36
  t.plan(3)
37
37
  const fastify = Fastify()
38
38
 
@@ -42,17 +42,18 @@ test('should respond with a stream (error)', t => {
42
42
  })
43
43
 
44
44
  fastify.listen({ port: 0 }, err => {
45
- t.error(err)
46
- t.teardown(() => { fastify.close() })
45
+ t.assert.ifError(err)
46
+ t.after(() => { fastify.close() })
47
47
 
48
48
  sget(`http://localhost:${fastify.server.address().port}/error`, function (err, response) {
49
- t.error(err)
50
- t.equal(response.statusCode, 500)
49
+ t.assert.ifError(err)
50
+ t.assert.strictEqual(response.statusCode, 500)
51
+ testDone()
51
52
  })
52
53
  })
53
54
  })
54
55
 
55
- test('should trigger the onSend hook', t => {
56
+ test('should trigger the onSend hook', (t, testDone) => {
56
57
  t.plan(4)
57
58
  const fastify = Fastify()
58
59
 
@@ -61,7 +62,7 @@ test('should trigger the onSend hook', t => {
61
62
  })
62
63
 
63
64
  fastify.addHook('onSend', (req, reply, payload, done) => {
64
- t.ok(payload._readableState)
65
+ t.assert.ok(payload._readableState)
65
66
  reply.header('Content-Type', 'application/javascript')
66
67
  done()
67
68
  })
@@ -69,14 +70,15 @@ test('should trigger the onSend hook', t => {
69
70
  fastify.inject({
70
71
  url: '/'
71
72
  }, (err, res) => {
72
- t.error(err)
73
- t.equal(res.headers['content-type'], 'application/javascript')
74
- t.equal(res.payload, fs.readFileSync(__filename, 'utf8'))
73
+ t.assert.ifError(err)
74
+ t.assert.strictEqual(res.headers['content-type'], 'application/javascript')
75
+ t.assert.strictEqual(res.payload, fs.readFileSync(__filename, 'utf8'))
75
76
  fastify.close()
77
+ testDone()
76
78
  })
77
79
  })
78
80
 
79
- test('should trigger the onSend hook only twice if pumping the stream fails, first with the stream, second with the serialized error', t => {
81
+ test('should trigger the onSend hook only twice if pumping the stream fails, first with the stream, second with the serialized error', (t, testDone) => {
80
82
  t.plan(5)
81
83
  const fastify = Fastify()
82
84
 
@@ -87,22 +89,23 @@ test('should trigger the onSend hook only twice if pumping the stream fails, fir
87
89
  let counter = 0
88
90
  fastify.addHook('onSend', (req, reply, payload, done) => {
89
91
  if (counter === 0) {
90
- t.ok(payload._readableState)
92
+ t.assert.ok(payload._readableState)
91
93
  } else if (counter === 1) {
92
94
  const error = JSON.parse(payload)
93
- t.equal(error.statusCode, 500)
95
+ t.assert.strictEqual(error.statusCode, 500)
94
96
  }
95
97
  counter++
96
98
  done()
97
99
  })
98
100
 
99
101
  fastify.listen({ port: 0 }, err => {
100
- t.error(err)
101
- t.teardown(() => { fastify.close() })
102
+ t.assert.ifError(err)
103
+ t.after(() => { fastify.close() })
102
104
 
103
105
  sget(`http://localhost:${fastify.server.address().port}`, function (err, response) {
104
- t.error(err)
105
- t.equal(response.statusCode, 500)
106
+ t.assert.ifError(err)
107
+ t.assert.strictEqual(response.statusCode, 500)
108
+ testDone()
106
109
  })
107
110
  })
108
111
  })
@@ -1,13 +1,13 @@
1
1
  'use strict'
2
2
 
3
- const t = require('tap')
4
- const test = t.test
3
+ const { test } = require('node:test')
5
4
  const proxyquire = require('proxyquire')
6
5
  const fs = require('node:fs')
7
6
  const resolve = require('node:path').resolve
8
7
  const zlib = require('node:zlib')
9
8
  const pipeline = require('node:stream').pipeline
10
9
  const Fastify = require('..')
10
+ const { waitForCb } = require('./toolkit')
11
11
 
12
12
  test('onSend hook stream', t => {
13
13
  t.plan(4)
@@ -17,6 +17,8 @@ test('onSend hook stream', t => {
17
17
  reply.send({ hello: 'world' })
18
18
  })
19
19
 
20
+ const { stepIn, patience } = waitForCb({ steps: 2 })
21
+
20
22
  fastify.addHook('onSend', (req, reply, payload, done) => {
21
23
  const gzStream = zlib.createGzip()
22
24
 
@@ -24,7 +26,10 @@ test('onSend hook stream', t => {
24
26
  pipeline(
25
27
  fs.createReadStream(resolve(__filename), 'utf8'),
26
28
  gzStream,
27
- t.error
29
+ (err) => {
30
+ t.assert.ifError(err)
31
+ stepIn()
32
+ }
28
33
  )
29
34
  done(null, gzStream)
30
35
  })
@@ -33,16 +38,19 @@ test('onSend hook stream', t => {
33
38
  url: '/',
34
39
  method: 'GET'
35
40
  }, (err, res) => {
36
- t.error(err)
37
- t.equal(res.headers['content-encoding'], 'gzip')
41
+ t.assert.ifError(err)
42
+ t.assert.strictEqual(res.headers['content-encoding'], 'gzip')
38
43
  const file = fs.readFileSync(resolve(__filename), 'utf8')
39
44
  const payload = zlib.gunzipSync(res.rawPayload)
40
- t.equal(payload.toString('utf-8'), file)
45
+ t.assert.strictEqual(payload.toString('utf-8'), file)
41
46
  fastify.close()
47
+ stepIn()
42
48
  })
49
+
50
+ return patience
43
51
  })
44
52
 
45
- test('onSend hook stream should work even if payload is not a proper stream', t => {
53
+ test('onSend hook stream should work even if payload is not a proper stream', (t, testDone) => {
46
54
  t.plan(1)
47
55
 
48
56
  const reply = proxyquire('../lib/reply', {
@@ -59,8 +67,9 @@ test('onSend hook stream should work even if payload is not a proper stream', t
59
67
  fatal: () => { },
60
68
  error: () => { },
61
69
  warn: (message) => {
62
- t.equal(message, 'stream payload does not end properly')
70
+ t.assert.strictEqual(message, 'stream payload does not end properly')
63
71
  fastify.close()
72
+ testDone()
64
73
  },
65
74
  info: () => { },
66
75
  debug: () => { },
@@ -83,7 +92,7 @@ test('onSend hook stream should work even if payload is not a proper stream', t
83
92
  })
84
93
  })
85
94
 
86
- test('onSend hook stream should work on payload with "close" ending function', t => {
95
+ test('onSend hook stream should work on payload with "close" ending function', (t, testDone) => {
87
96
  t.plan(1)
88
97
 
89
98
  const reply = proxyquire('../lib/reply', {
@@ -106,7 +115,8 @@ test('onSend hook stream should work on payload with "close" ending function', t
106
115
  pipe: () => { },
107
116
  close: (cb) => {
108
117
  cb()
109
- t.pass()
118
+ t.assert.ok('close callback called')
119
+ testDone()
110
120
  }
111
121
  }
112
122
  done(null, fakeStream)