fastify 3.23.0 → 3.25.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 (73) hide show
  1. package/README.md +5 -4
  2. package/build/sync-version.js +11 -0
  3. package/docs/{Benchmarking.md → Guides/Benchmarking.md} +14 -5
  4. package/docs/Guides/Ecosystem.md +508 -0
  5. package/docs/{Fluent-Schema.md → Guides/Fluent-Schema.md} +16 -7
  6. package/docs/{Getting-Started.md → Guides/Getting-Started.md} +191 -57
  7. package/docs/Guides/Index.md +30 -4
  8. package/docs/{Migration-Guide-V3.md → Guides/Migration-Guide-V3.md} +43 -37
  9. package/docs/{Plugins-Guide.md → Guides/Plugins-Guide.md} +196 -82
  10. package/docs/{Recommendations.md → Guides/Recommendations.md} +17 -10
  11. package/docs/{Serverless.md → Guides/Serverless.md} +200 -42
  12. package/docs/Guides/Style-Guide.md +246 -0
  13. package/docs/{Testing.md → Guides/Testing.md} +25 -11
  14. package/docs/Guides/Write-Plugin.md +102 -0
  15. package/docs/{ContentTypeParser.md → Reference/ContentTypeParser.md} +68 -30
  16. package/docs/{Decorators.md → Reference/Decorators.md} +52 -47
  17. package/docs/{Encapsulation.md → Reference/Encapsulation.md} +3 -3
  18. package/docs/{Errors.md → Reference/Errors.md} +77 -47
  19. package/docs/{HTTP2.md → Reference/HTTP2.md} +13 -13
  20. package/docs/{Hooks.md → Reference/Hooks.md} +148 -69
  21. package/docs/Reference/Index.md +71 -0
  22. package/docs/{LTS.md → Reference/LTS.md} +31 -32
  23. package/docs/{Lifecycle.md → Reference/Lifecycle.md} +15 -7
  24. package/docs/{Logging.md → Reference/Logging.md} +68 -28
  25. package/docs/Reference/Middleware.md +78 -0
  26. package/docs/{Plugins.md → Reference/Plugins.md} +91 -34
  27. package/docs/{Reply.md → Reference/Reply.md} +205 -94
  28. package/docs/{Request.md → Reference/Request.md} +32 -16
  29. package/docs/{Routes.md → Reference/Routes.md} +243 -111
  30. package/docs/{Server.md → Reference/Server.md} +516 -267
  31. package/docs/{TypeScript.md → Reference/TypeScript.md} +447 -187
  32. package/docs/{Validation-and-Serialization.md → Reference/Validation-and-Serialization.md} +178 -86
  33. package/docs/index.md +24 -0
  34. package/examples/typescript-server.ts +1 -1
  35. package/fastify.js +4 -23
  36. package/lib/decorate.js +6 -3
  37. package/lib/logger.js +2 -2
  38. package/lib/pluginUtils.js +1 -3
  39. package/lib/reply.js +4 -1
  40. package/lib/route.js +1 -1
  41. package/lib/schema-controller.js +11 -2
  42. package/lib/server.js +9 -8
  43. package/lib/symbols.js +1 -0
  44. package/package.json +10 -4
  45. package/test/bundler/webpack/bundler-test.js +2 -6
  46. package/test/constrained-routes.test.js +220 -0
  47. package/test/custom-parser.test.js +11 -2
  48. package/test/decorator.test.js +24 -0
  49. package/test/handler-context.test.js +11 -4
  50. package/test/http2/closing.test.js +14 -5
  51. package/test/internals/logger.test.js +20 -0
  52. package/test/internals/reply.test.js +42 -0
  53. package/test/internals/version.test.js +6 -34
  54. package/test/listen.test.js +36 -22
  55. package/test/logger.test.js +16 -0
  56. package/test/maxRequestsPerSocket.test.js +10 -0
  57. package/test/request-error.test.js +2 -8
  58. package/test/requestTimeout.test.js +4 -1
  59. package/test/route-hooks.test.js +55 -0
  60. package/test/router-options.test.js +10 -1
  61. package/test/schema-feature.test.js +461 -0
  62. package/test/stream.test.js +14 -3
  63. package/test/trust-proxy.test.js +15 -7
  64. package/test/types/instance.test-d.ts +52 -1
  65. package/test/types/request.test-d.ts +7 -1
  66. package/test/types/route.test-d.ts +21 -0
  67. package/types/instance.d.ts +11 -6
  68. package/types/request.d.ts +4 -1
  69. package/types/route.d.ts +1 -1
  70. package/docs/Ecosystem.md +0 -211
  71. package/docs/Middleware.md +0 -53
  72. package/docs/Style-Guide.md +0 -185
  73. package/docs/Write-Plugin.md +0 -58
@@ -79,6 +79,14 @@ class SchemaController {
79
79
  return this.serializerCompiler || (this.parent && this.parent.getSerializerCompiler())
80
80
  }
81
81
 
82
+ getSerializerBuilder () {
83
+ return this.compilersFactory.buildSerializer || (this.parent && this.parent.getSerializerBuilder())
84
+ }
85
+
86
+ getValidatorBuilder () {
87
+ return this.compilersFactory.buildValidator || (this.parent && this.parent.getValidatorBuilder())
88
+ }
89
+
82
90
  /**
83
91
  * This method will be called when a validator must be setup.
84
92
  * Do not setup the compiler more than once
@@ -89,7 +97,7 @@ class SchemaController {
89
97
  if (isReady) {
90
98
  return
91
99
  }
92
- this.validatorCompiler = this.compilersFactory.buildValidator(this.schemaBucket.getSchemas(), serverOption.ajv)
100
+ this.validatorCompiler = this.getValidatorBuilder()(this.schemaBucket.getSchemas(), serverOption.ajv)
93
101
  }
94
102
 
95
103
  /**
@@ -102,7 +110,8 @@ class SchemaController {
102
110
  if (isReady) {
103
111
  return
104
112
  }
105
- this.serializerCompiler = this.compilersFactory.buildSerializer(this.schemaBucket.getSchemas(), serverOption.serializerOpts)
113
+
114
+ this.serializerCompiler = this.getSerializerBuilder()(this.schemaBucket.getSchemas(), serverOption.serializerOpts)
106
115
  }
107
116
  }
108
117
 
package/lib/server.js CHANGED
@@ -14,19 +14,20 @@ function createServer (options, httpHandler) {
14
14
  let server = null
15
15
  if (options.serverFactory) {
16
16
  server = options.serverFactory(httpHandler, options)
17
- } else if (options.https) {
18
- if (options.http2) {
17
+ } else if (options.http2) {
18
+ if (options.https) {
19
19
  server = http2().createSecureServer(options.https, httpHandler)
20
- server.on('session', sessionTimeout(options.http2SessionTimeout))
21
20
  } else {
22
- server = https.createServer(options.https, httpHandler)
23
- server.keepAliveTimeout = options.keepAliveTimeout
21
+ server = http2().createServer(httpHandler)
24
22
  }
25
- } else if (options.http2) {
26
- server = http2().createServer(httpHandler)
27
23
  server.on('session', sessionTimeout(options.http2SessionTimeout))
28
24
  } else {
29
- server = http.createServer(httpHandler)
25
+ // this is http1
26
+ if (options.https) {
27
+ server = https.createServer(options.https, httpHandler)
28
+ } else {
29
+ server = http.createServer(httpHandler)
30
+ }
30
31
  server.keepAliveTimeout = options.keepAliveTimeout
31
32
  server.requestTimeout = options.requestTimeout
32
33
  // we treat zero as null
package/lib/symbols.js CHANGED
@@ -33,6 +33,7 @@ const keys = {
33
33
  kReplySent: Symbol('fastify.reply.sent'),
34
34
  kReplySentOverwritten: Symbol('fastify.reply.sentOverwritten'),
35
35
  kReplyStartTime: Symbol('fastify.reply.startTime'),
36
+ kReplyEndTime: Symbol('fastify.reply.endTime'),
36
37
  kReplyErrorHandlerCalled: Symbol('fastify.reply.errorHandlerCalled'),
37
38
  kReplyIsRunningOnErrorHook: Symbol('fastify.reply.isRunningOnErrorHook'),
38
39
  kSchemaVisited: Symbol('fastify.schemas.visited'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fastify",
3
- "version": "3.23.0",
3
+ "version": "3.25.0",
4
4
  "description": "Fast and low overhead web framework, for Node.js",
5
5
  "main": "fastify.js",
6
6
  "type": "commonjs",
@@ -14,6 +14,7 @@
14
14
  "lint:fix": "standard --fix",
15
15
  "lint:standard": "standard --verbose | snazzy",
16
16
  "lint:typescript": "eslint -c types/.eslintrc.json types/**/*.d.ts test/types/**/*.test-d.ts",
17
+ "prepublishOnly": "tap --no-check-coverage test/internals/version.test.js",
17
18
  "test": "npm run lint && npm run unit && npm run test:typescript",
18
19
  "test:ci": "npm run lint && npm run unit -- --cov --coverage-report=lcovonly && npm run test:typescript",
19
20
  "test:report": "npm run lint && npm run unit:report && npm run test:typescript",
@@ -107,6 +108,11 @@
107
108
  "name": "Vincent Le Goff",
108
109
  "email": "vince.legoff@gmail.com",
109
110
  "url": "https://github.com/zekth"
111
+ },
112
+ {
113
+ "name": "Luis Orbaiceta",
114
+ "email": "luisorbaiceta@gmail.com",
115
+ "url": "https://luisorbaiceta.com"
110
116
  }
111
117
  ],
112
118
  "license": "MIT",
@@ -118,7 +124,7 @@
118
124
  "@fastify/ajv-compiler-8": "npm:@fastify/ajv-compiler@^2.0.0",
119
125
  "@fastify/pre-commit": "^2.0.1",
120
126
  "@hapi/joi": "^17.1.1",
121
- "@sinonjs/fake-timers": "^7.0.0",
127
+ "@sinonjs/fake-timers": "^8.1.0",
122
128
  "@types/node": "^16.0.0",
123
129
  "@types/pino": "^6.0.1",
124
130
  "@typescript-eslint/eslint-plugin": "^4.5.0",
@@ -162,10 +168,10 @@
162
168
  "snazzy": "^9.0.0",
163
169
  "split2": "^4.1.0",
164
170
  "standard": "^16.0.1",
165
- "tap": "^15.0.5",
171
+ "tap": "^15.1.1",
166
172
  "tap-mocha-reporter": "^5.0.1",
167
173
  "then-sleep": "^1.0.1",
168
- "tsd": "^0.18.0",
174
+ "tsd": "^0.19.0",
169
175
  "typescript": "^4.0.2",
170
176
  "undici": "^3.3.5",
171
177
  "x-xss-protection": "^2.0.0",
@@ -12,13 +12,9 @@ test('Bundled package should work', t => {
12
12
  })
13
13
  })
14
14
 
15
- // In the webpack bundle context the fastify package.json is not read
16
- // Because of this the version is set to `undefined`, this makes the plugin
17
- // version check not able to work properly. By then this test shouldn't work
18
- // in non-bundled environment but works in bundled environment
19
- test('Bundled package should work with bad plugin version, undefined version fallback', t => {
15
+ test('Bundled package should not work with bad plugin version', t => {
20
16
  t.plan(1)
21
17
  fastifyFailPlugin.ready((err) => {
22
- t.error(err)
18
+ t.ok(err)
23
19
  })
24
20
  })
@@ -182,3 +182,223 @@ test('Should allow registering custom constrained routes', t => {
182
182
  t.equal(res.statusCode, 404)
183
183
  })
184
184
  })
185
+
186
+ test('Should allow registering an unconstrained route after a constrained route', t => {
187
+ t.plan(6)
188
+ const fastify = Fastify()
189
+
190
+ fastify.route({
191
+ method: 'GET',
192
+ url: '/',
193
+ constraints: { host: 'fastify.io' },
194
+ handler: (req, reply) => {
195
+ reply.send({ hello: 'from fastify.io' })
196
+ }
197
+ })
198
+
199
+ fastify.route({
200
+ method: 'GET',
201
+ url: '/',
202
+ handler: (req, reply) => {
203
+ reply.send({ hello: 'from any other domain' })
204
+ }
205
+ })
206
+
207
+ fastify.inject({
208
+ method: 'GET',
209
+ url: '/',
210
+ headers: {
211
+ host: 'fastify.io'
212
+ }
213
+ }, (err, res) => {
214
+ t.error(err)
215
+ t.same(JSON.parse(res.payload), { hello: 'from fastify.io' })
216
+ t.equal(res.statusCode, 200)
217
+ })
218
+
219
+ fastify.inject({
220
+ method: 'GET',
221
+ url: '/',
222
+ headers: {
223
+ host: 'example.com'
224
+ }
225
+ }, (err, res) => {
226
+ t.error(err)
227
+ t.same(JSON.parse(res.payload), { hello: 'from any other domain' })
228
+ t.equal(res.statusCode, 200)
229
+ })
230
+ })
231
+
232
+ test('Should allow registering constrained routes in a prefixed plugin', t => {
233
+ t.plan(3)
234
+
235
+ const fastify = Fastify()
236
+
237
+ fastify.register(async (scope, opts) => {
238
+ scope.route({
239
+ method: 'GET',
240
+ constraints: { host: 'fastify.io' },
241
+ path: '/route',
242
+ handler: (req, reply) => {
243
+ reply.send({ ok: true })
244
+ }
245
+ })
246
+ }, { prefix: '/prefix' })
247
+
248
+ fastify.inject({
249
+ method: 'GET',
250
+ url: '/prefix/route',
251
+ headers: {
252
+ host: 'fastify.io'
253
+ }
254
+ }, (err, res) => {
255
+ t.error(err)
256
+ t.same(JSON.parse(res.payload), { ok: true })
257
+ t.equal(res.statusCode, 200)
258
+ })
259
+ })
260
+
261
+ test('Should allow registering a constrained GET route after a constrained HEAD route', t => {
262
+ t.plan(3)
263
+ const fastify = Fastify()
264
+
265
+ fastify.route({
266
+ method: 'HEAD',
267
+ url: '/',
268
+ constraints: { host: 'fastify.io' },
269
+ handler: (req, reply) => {
270
+ reply.header('content-type', 'text/plain')
271
+ reply.send('custom HEAD response')
272
+ }
273
+ })
274
+
275
+ fastify.route({
276
+ method: 'GET',
277
+ url: '/',
278
+ constraints: { host: 'fastify.io' },
279
+ handler: (req, reply) => {
280
+ reply.send({ hello: 'from any other domain' })
281
+ }
282
+ })
283
+
284
+ fastify.inject({
285
+ method: 'HEAD',
286
+ url: '/',
287
+ headers: {
288
+ host: 'fastify.io'
289
+ }
290
+ }, (err, res) => {
291
+ t.error(err)
292
+ t.same(res.payload, 'custom HEAD response')
293
+ t.equal(res.statusCode, 200)
294
+ })
295
+ })
296
+
297
+ test('Should allow registering a constrained GET route after an unconstrained HEAD route', t => {
298
+ t.plan(3)
299
+ const fastify = Fastify()
300
+
301
+ fastify.route({
302
+ method: 'HEAD',
303
+ url: '/',
304
+ handler: (req, reply) => {
305
+ reply.header('content-type', 'text/plain')
306
+ reply.send('custom HEAD response')
307
+ }
308
+ })
309
+
310
+ fastify.route({
311
+ method: 'GET',
312
+ url: '/',
313
+ constraints: { host: 'fastify.io' },
314
+ handler: (req, reply) => {
315
+ reply.send({ hello: 'from any other domain' })
316
+ }
317
+ })
318
+
319
+ fastify.inject({
320
+ method: 'HEAD',
321
+ url: '/',
322
+ headers: {
323
+ host: 'fastify.io'
324
+ }
325
+ }, (err, res) => {
326
+ t.error(err)
327
+ t.same(res.payload, 'custom HEAD response')
328
+ t.equal(res.statusCode, 200)
329
+ })
330
+ })
331
+
332
+ test('Will not try to re-createprefixed HEAD route if it already exists and exposeHeadRoutes is true for constrained routes', async (t) => {
333
+ t.plan(1)
334
+
335
+ const fastify = Fastify({ exposeHeadRoutes: true })
336
+
337
+ fastify.register((scope, opts, next) => {
338
+ scope.route({
339
+ method: 'HEAD',
340
+ path: '/route',
341
+ constraints: { host: 'fastify.io' },
342
+ handler: (req, reply) => {
343
+ reply.header('content-type', 'text/plain')
344
+ reply.send('custom HEAD response')
345
+ }
346
+ })
347
+ scope.route({
348
+ method: 'GET',
349
+ path: '/route',
350
+ constraints: { host: 'fastify.io' },
351
+ handler: (req, reply) => {
352
+ reply.send({ ok: true })
353
+ }
354
+ })
355
+
356
+ next()
357
+ }, { prefix: '/prefix' })
358
+
359
+ await fastify.ready()
360
+
361
+ t.ok(true)
362
+ })
363
+
364
+ test('allows separate constrained and unconstrained HEAD routes', async (t) => {
365
+ t.plan(1)
366
+
367
+ const fastify = Fastify({ exposeHeadRoutes: true })
368
+
369
+ fastify.register((scope, opts, next) => {
370
+ scope.route({
371
+ method: 'HEAD',
372
+ path: '/route',
373
+ handler: (req, reply) => {
374
+ reply.header('content-type', 'text/plain')
375
+ reply.send('unconstrained HEAD response')
376
+ }
377
+ })
378
+
379
+ scope.route({
380
+ method: 'HEAD',
381
+ path: '/route',
382
+ constraints: { host: 'fastify.io' },
383
+ handler: (req, reply) => {
384
+ reply.header('content-type', 'text/plain')
385
+ reply.send('constrained HEAD response')
386
+ }
387
+ })
388
+
389
+ scope.route({
390
+ method: 'GET',
391
+ path: '/route',
392
+ constraints: { host: 'fastify.io' },
393
+ handler: (req, reply) => {
394
+ reply.send({ ok: true })
395
+ }
396
+ })
397
+
398
+ next()
399
+ }, { prefix: '/prefix' })
400
+
401
+ await fastify.ready()
402
+
403
+ t.ok(true)
404
+ })
@@ -25,6 +25,15 @@ function plainTextParser (request, callback) {
25
25
  }
26
26
  }
27
27
 
28
+ function getUrl (app) {
29
+ const { address, port } = app.server.address()
30
+ if (address === '::1') {
31
+ return `http://[${address}]:${port}`
32
+ } else {
33
+ return `http://${address}:${port}`
34
+ }
35
+ }
36
+
28
37
  process.removeAllListeners('warning')
29
38
 
30
39
  test('contentTypeParser method should exist', t => {
@@ -61,7 +70,7 @@ test('contentTypeParser should add a custom parser', t => {
61
70
 
62
71
  sget({
63
72
  method: 'POST',
64
- url: 'http://localhost:' + fastify.server.address().port,
73
+ url: getUrl(fastify),
65
74
  body: '{"hello":"world"}',
66
75
  headers: {
67
76
  'Content-Type': 'application/jsoff'
@@ -78,7 +87,7 @@ test('contentTypeParser should add a custom parser', t => {
78
87
 
79
88
  sget({
80
89
  method: 'OPTIONS',
81
- url: 'http://localhost:' + fastify.server.address().port,
90
+ url: getUrl(fastify),
82
91
  body: '{"hello":"world"}',
83
92
  headers: {
84
93
  'Content-Type': 'application/jsoff'
@@ -1024,3 +1024,27 @@ test('decorateRequest/decorateReply is not set to a value', t => {
1024
1024
  })
1025
1025
  })
1026
1026
  })
1027
+
1028
+ test('decorateRequest with dependencies', (t) => {
1029
+ t.plan(2)
1030
+ const app = Fastify()
1031
+
1032
+ const decorator1 = {
1033
+ config: {},
1034
+ app: {}
1035
+ }
1036
+ const decorator2 = {
1037
+ stuff: {}
1038
+ }
1039
+
1040
+ app.decorate('decorator1', decorator1)
1041
+ app.decorateRequest('decorator1', decorator1)
1042
+
1043
+ if (
1044
+ app.hasDecorator('decorator1') &&
1045
+ app.hasRequestDecorator('decorator1')
1046
+ ) {
1047
+ t.doesNotThrow(() => app.decorateRequest('decorator2', decorator2, ['decorator1']))
1048
+ t.ok(app.hasRequestDecorator('decorator2'))
1049
+ }
1050
+ })
@@ -4,6 +4,15 @@ const http = require('http')
4
4
  const test = require('tap').test
5
5
  const fastify = require('../')
6
6
 
7
+ function getUrl (app) {
8
+ const { address, port } = app.server.address()
9
+ if (address === '::1') {
10
+ return `http://[${address}]:${port}`
11
+ } else {
12
+ return `http://${address}:${port}`
13
+ }
14
+ }
15
+
7
16
  test('handlers receive correct `this` context', (t) => {
8
17
  t.plan(4)
9
18
 
@@ -29,8 +38,7 @@ test('handlers receive correct `this` context', (t) => {
29
38
  t.ok(instance.foo)
30
39
  t.equal(instance.foo, 'foo')
31
40
 
32
- const address = `http://127.0.0.1:${instance.server.address().port}/`
33
- http.get(address, () => {}).on('error', t.threw)
41
+ http.get(getUrl(instance), () => {}).on('error', t.threw)
34
42
  })
35
43
  })
36
44
 
@@ -50,7 +58,6 @@ test('handlers have access to the internal context', (t) => {
50
58
  instance.listen(0, (err) => {
51
59
  instance.server.unref()
52
60
  if (err) t.threw(err)
53
- const address = `http://127.0.0.1:${instance.server.address().port}/`
54
- http.get(address, () => {}).on('error', t.threw)
61
+ http.get(getUrl(instance), () => {}).on('error', t.threw)
55
62
  })
56
63
  })
@@ -11,6 +11,15 @@ const { once } = require('events')
11
11
  const { buildCertificate } = require('../build-certificate')
12
12
  t.before(buildCertificate)
13
13
 
14
+ function getUrl (app) {
15
+ const { address, port } = app.server.address()
16
+ if (address === '::1') {
17
+ return `http://[${address}]:${port}`
18
+ } else {
19
+ return `http://${address}:${port}`
20
+ }
21
+ }
22
+
14
23
  t.test('http/2 request while fastify closing', t => {
15
24
  let fastify
16
25
  try {
@@ -30,7 +39,7 @@ t.test('http/2 request while fastify closing', t => {
30
39
 
31
40
  // Skipped because there is likely a bug on Node 8.
32
41
  t.test('return 200', { skip: semver.lt(process.versions.node, '10.15.0') }, t => {
33
- const url = `http://127.0.0.1:${fastify.server.address().port}`
42
+ const url = getUrl(fastify)
34
43
  const session = http2.connect(url, function () {
35
44
  this.request({
36
45
  ':method': 'GET',
@@ -78,7 +87,7 @@ t.test('http/2 request while fastify closing - return503OnClosing: false', t =>
78
87
 
79
88
  // Skipped because there is likely a bug on Node 8.
80
89
  t.test('return 200', { skip: semver.lt(process.versions.node, '10.15.0') }, t => {
81
- const url = `http://127.0.0.1:${fastify.server.address().port}`
90
+ const url = getUrl(fastify)
82
91
  const session = http2.connect(url, function () {
83
92
  this.request({
84
93
  ':method': 'GET',
@@ -115,7 +124,7 @@ t.test('http/2 closes successfully with async await', { skip: semver.lt(process.
115
124
 
116
125
  await fastify.listen(0)
117
126
 
118
- const url = `http://127.0.0.1:${fastify.server.address().port}`
127
+ const url = getUrl(fastify)
119
128
  const session = await connect(url)
120
129
  // An error might or might not happen, as it's OS dependent.
121
130
  session.on('error', () => {})
@@ -135,7 +144,7 @@ t.test('https/2 closes successfully with async await', { skip: semver.lt(process
135
144
 
136
145
  await fastify.listen(0)
137
146
 
138
- const url = `http://127.0.0.1:${fastify.server.address().port}`
147
+ const url = getUrl(fastify)
139
148
  const session = await connect(url)
140
149
  // An error might or might not happen, as it's OS dependent.
141
150
  session.on('error', () => {})
@@ -159,7 +168,7 @@ t.test('http/2 server side session emits a timeout event', { skip: semver.lt(pro
159
168
 
160
169
  await fastify.listen(0)
161
170
 
162
- const url = `http://127.0.0.1:${fastify.server.address().port}`
171
+ const url = getUrl(fastify)
163
172
  const session = await connect(url)
164
173
  const req = session.request({
165
174
  ':method': 'GET',
@@ -112,3 +112,23 @@ test('The logger should error if both stream and file destination are given', t
112
112
  t.equal(err.message, 'Cannot specify both logger.stream and logger.file options')
113
113
  }
114
114
  })
115
+
116
+ test('The serializer prevent fails if the request socket is undefined', t => {
117
+ t.plan(1)
118
+
119
+ const serialized = loggerUtils.serializers.req({
120
+ method: 'GET',
121
+ url: '/',
122
+ socket: undefined,
123
+ headers: {}
124
+ })
125
+
126
+ t.same(serialized, {
127
+ method: 'GET',
128
+ url: '/',
129
+ version: undefined,
130
+ hostname: undefined,
131
+ remoteAddress: undefined,
132
+ remotePort: undefined
133
+ })
134
+ })
@@ -1368,6 +1368,48 @@ test('reply.getResponseTime() should return a number greater than 0 after the ti
1368
1368
  fastify.inject({ method: 'GET', url: '/' })
1369
1369
  })
1370
1370
 
1371
+ test('reply.getResponseTime() should return the time since a request started while inflight', t => {
1372
+ t.plan(1)
1373
+ const fastify = require('../..')()
1374
+ fastify.route({
1375
+ method: 'GET',
1376
+ url: '/',
1377
+ handler: (req, reply) => {
1378
+ reply.send('hello world')
1379
+ }
1380
+ })
1381
+
1382
+ fastify.addHook('preValidation', (req, reply, done) => {
1383
+ t.not(reply.getResponseTime(), reply.getResponseTime())
1384
+ done()
1385
+ })
1386
+
1387
+ fastify.addHook('onResponse', (req, reply) => {
1388
+ t.end()
1389
+ })
1390
+
1391
+ fastify.inject({ method: 'GET', url: '/' })
1392
+ })
1393
+
1394
+ test('reply.getResponseTime() should return the same value after a request is finished', t => {
1395
+ t.plan(1)
1396
+ const fastify = require('../..')()
1397
+ fastify.route({
1398
+ method: 'GET',
1399
+ url: '/',
1400
+ handler: (req, reply) => {
1401
+ reply.send('hello world')
1402
+ }
1403
+ })
1404
+
1405
+ fastify.addHook('onResponse', (req, reply) => {
1406
+ t.equal(reply.getResponseTime(), reply.getResponseTime())
1407
+ t.end()
1408
+ })
1409
+
1410
+ fastify.inject({ method: 'GET', url: '/' })
1411
+ })
1412
+
1371
1413
  test('reply should use the custom serializer', t => {
1372
1414
  t.plan(4)
1373
1415
  const fastify = require('../..')()
@@ -1,43 +1,15 @@
1
1
  'use strict'
2
2
 
3
+ const fs = require('fs')
4
+ const path = require('path')
3
5
  const t = require('tap')
4
6
  const test = t.test
5
- const proxyquire = require('proxyquire')
7
+ const fastify = require('../..')()
6
8
 
7
- test('should output an undefined version in case of package.json not available', t => {
8
- const Fastify = proxyquire('../..', { fs: { accessSync: () => { throw Error('error') } } })
9
+ test('should be the same as package.json', t => {
9
10
  t.plan(1)
10
- const srv = Fastify()
11
- t.equal(srv.version, undefined)
12
- })
13
-
14
- test('should output an undefined version in case of package.json is not the fastify one', t => {
15
- const Fastify = proxyquire('../..', { fs: { accessSync: () => { }, readFileSync: () => JSON.stringify({ name: 'foo', version: '6.6.6' }) } })
16
- t.plan(1)
17
- const srv = Fastify()
18
- t.equal(srv.version, undefined)
19
- })
20
-
21
- test('should skip the version check if the version is undefined', t => {
22
- const Fastify = proxyquire('../..', { fs: { accessSync: () => { }, readFileSync: () => JSON.stringify({ name: 'foo', version: '6.6.6' }) } })
23
- t.plan(3)
24
- const srv = Fastify()
25
- t.equal(srv.version, undefined)
26
-
27
- plugin[Symbol.for('skip-override')] = false
28
- plugin[Symbol.for('plugin-meta')] = {
29
- name: 'plugin',
30
- fastify: '>=99.0.0'
31
- }
32
-
33
- srv.register(plugin)
34
11
 
35
- srv.ready((err) => {
36
- t.error(err)
37
- t.pass('everything right')
38
- })
12
+ const json = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '..', 'package.json')).toString('utf8'))
39
13
 
40
- function plugin (instance, opts, done) {
41
- done()
42
- }
14
+ t.equal(fastify.version, json.version)
43
15
  })