fastify 3.27.4 → 4.0.0-alpha.3

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 (168) hide show
  1. package/.taprc +3 -0
  2. package/README.md +7 -7
  3. package/build/build-error-serializer.js +27 -0
  4. package/build/build-validation.js +47 -35
  5. package/docs/Guides/Database.md +320 -0
  6. package/docs/Guides/Ecosystem.md +9 -0
  7. package/docs/Guides/Getting-Started.md +7 -7
  8. package/docs/Guides/Plugins-Guide.md +1 -1
  9. package/docs/Guides/Serverless.md +3 -3
  10. package/docs/Guides/Testing.md +2 -2
  11. package/docs/Migration-Guide-V4.md +12 -0
  12. package/docs/Reference/ContentTypeParser.md +4 -0
  13. package/docs/Reference/Decorators.md +2 -2
  14. package/docs/Reference/Encapsulation.md +2 -2
  15. package/docs/Reference/Errors.md +51 -6
  16. package/docs/Reference/HTTP2.md +3 -3
  17. package/docs/Reference/Hooks.md +4 -7
  18. package/docs/Reference/LTS.md +5 -4
  19. package/docs/Reference/Plugins.md +3 -3
  20. package/docs/Reference/Reply.md +73 -22
  21. package/docs/Reference/Request.md +1 -3
  22. package/docs/Reference/Routes.md +22 -15
  23. package/docs/Reference/Server.md +69 -119
  24. package/docs/Reference/TypeScript.md +20 -22
  25. package/docs/Reference/Validation-and-Serialization.md +30 -55
  26. package/docs/Type-Providers.md +257 -0
  27. package/examples/asyncawait.js +1 -1
  28. package/examples/benchmark/hooks-benchmark-async-await.js +1 -1
  29. package/examples/benchmark/hooks-benchmark.js +1 -1
  30. package/examples/benchmark/simple.js +1 -1
  31. package/examples/hooks.js +2 -2
  32. package/examples/http2.js +1 -1
  33. package/examples/https.js +1 -1
  34. package/examples/parser.js +13 -3
  35. package/examples/route-prefix.js +1 -1
  36. package/examples/shared-schema.js +1 -1
  37. package/examples/simple-stream.js +18 -0
  38. package/examples/simple.js +1 -1
  39. package/examples/simple.mjs +1 -1
  40. package/examples/typescript-server.ts +1 -1
  41. package/examples/use-plugin.js +1 -1
  42. package/fastify.d.ts +34 -22
  43. package/fastify.js +40 -36
  44. package/lib/configValidator.js +902 -1023
  45. package/lib/contentTypeParser.js +6 -16
  46. package/lib/context.js +36 -10
  47. package/lib/decorate.js +3 -1
  48. package/lib/error-handler.js +158 -0
  49. package/lib/error-serializer.js +257 -0
  50. package/lib/errors.js +51 -9
  51. package/lib/fourOhFour.js +31 -20
  52. package/lib/handleRequest.js +10 -13
  53. package/lib/hooks.js +14 -9
  54. package/lib/pluginOverride.js +0 -3
  55. package/lib/pluginUtils.js +3 -2
  56. package/lib/reply.js +121 -175
  57. package/lib/request.js +13 -10
  58. package/lib/route.js +131 -138
  59. package/lib/schema-controller.js +2 -2
  60. package/lib/schemas.js +27 -1
  61. package/lib/server.js +242 -116
  62. package/lib/symbols.js +5 -3
  63. package/lib/validation.js +11 -9
  64. package/lib/warnings.js +4 -12
  65. package/lib/wrapThenable.js +4 -11
  66. package/package.json +37 -39
  67. package/test/404s.test.js +258 -125
  68. package/test/500s.test.js +3 -3
  69. package/test/als.test.js +1 -1
  70. package/test/async-await.test.js +20 -76
  71. package/test/bodyLimit.test.js +1 -1
  72. package/test/build-certificate.js +6 -7
  73. package/test/case-insensitive.test.js +4 -4
  74. package/test/close-pipelining.test.js +2 -2
  75. package/test/close.test.js +11 -11
  76. package/test/content-parser.test.js +32 -0
  77. package/test/context-config.test.js +52 -0
  78. package/test/custom-http-server.test.js +14 -7
  79. package/test/custom-parser-async.test.js +1 -66
  80. package/test/custom-parser.test.js +92 -159
  81. package/test/custom-querystring-parser.test.js +3 -3
  82. package/test/decorator.test.js +11 -13
  83. package/test/delete.test.js +6 -6
  84. package/test/encapsulated-error-handler.test.js +50 -0
  85. package/test/esm/index.test.js +0 -14
  86. package/test/fastify-instance.test.js +4 -4
  87. package/test/fluent-schema.test.js +4 -4
  88. package/test/genReqId.test.js +1 -1
  89. package/test/get.test.js +4 -4
  90. package/test/handler-context.test.js +2 -2
  91. package/test/head.test.js +1 -1
  92. package/test/helper.js +19 -4
  93. package/test/hooks-async.test.js +15 -48
  94. package/test/hooks.on-ready.test.js +10 -5
  95. package/test/hooks.test.js +78 -119
  96. package/test/http2/closing.test.js +10 -16
  97. package/test/http2/constraint.test.js +1 -1
  98. package/test/http2/head.test.js +1 -1
  99. package/test/http2/plain.test.js +1 -1
  100. package/test/http2/secure-with-fallback.test.js +1 -1
  101. package/test/http2/secure.test.js +1 -1
  102. package/test/http2/unknown-http-method.test.js +4 -10
  103. package/test/https/custom-https-server.test.js +12 -6
  104. package/test/https/https.test.js +1 -1
  105. package/test/input-validation.js +3 -3
  106. package/test/internals/handleRequest.test.js +6 -43
  107. package/test/internals/initialConfig.test.js +41 -12
  108. package/test/internals/logger.test.js +2 -2
  109. package/test/internals/reply.test.js +317 -48
  110. package/test/internals/request.test.js +13 -7
  111. package/test/internals/server.test.js +88 -0
  112. package/test/listen.deprecated.test.js +202 -0
  113. package/test/listen.test.js +140 -145
  114. package/test/logger.test.js +82 -42
  115. package/test/maxRequestsPerSocket.test.js +8 -6
  116. package/test/middleware.test.js +2 -25
  117. package/test/nullable-validation.test.js +53 -16
  118. package/test/output-validation.test.js +1 -1
  119. package/test/plugin.test.js +47 -21
  120. package/test/pretty-print.test.js +22 -10
  121. package/test/promises.test.js +1 -1
  122. package/test/proto-poisoning.test.js +6 -6
  123. package/test/register.test.js +3 -3
  124. package/test/reply-error.test.js +126 -15
  125. package/test/reply-trailers.test.js +270 -0
  126. package/test/request-error.test.js +3 -6
  127. package/test/route-hooks.test.js +18 -18
  128. package/test/route-prefix.test.js +2 -1
  129. package/test/route.test.js +206 -22
  130. package/test/router-options.test.js +2 -2
  131. package/test/schema-examples.test.js +11 -5
  132. package/test/schema-feature.test.js +25 -20
  133. package/test/schema-serialization.test.js +9 -9
  134. package/test/schema-special-usage.test.js +5 -153
  135. package/test/schema-validation.test.js +9 -9
  136. package/test/skip-reply-send.test.js +2 -2
  137. package/test/stream.test.js +82 -23
  138. package/test/throw.test.js +8 -5
  139. package/test/trust-proxy.test.js +6 -6
  140. package/test/type-provider.test.js +20 -0
  141. package/test/types/fastify.test-d.ts +10 -18
  142. package/test/types/hooks.test-d.ts +61 -5
  143. package/test/types/import.js +2 -0
  144. package/test/types/import.ts +1 -0
  145. package/test/types/instance.test-d.ts +68 -17
  146. package/test/types/logger.test-d.ts +44 -15
  147. package/test/types/reply.test-d.ts +2 -1
  148. package/test/types/request.test-d.ts +71 -1
  149. package/test/types/route.test-d.ts +8 -2
  150. package/test/types/schema.test-d.ts +2 -39
  151. package/test/types/type-provider.test-d.ts +424 -0
  152. package/test/url-rewriting.test.js +3 -3
  153. package/test/validation-error-handling.test.js +8 -8
  154. package/test/versioned-routes.test.js +30 -18
  155. package/test/wrapThenable.test.js +7 -6
  156. package/types/content-type-parser.d.ts +17 -8
  157. package/types/hooks.d.ts +182 -85
  158. package/types/instance.d.ts +286 -118
  159. package/types/logger.d.ts +18 -104
  160. package/types/plugin.d.ts +10 -4
  161. package/types/reply.d.ts +18 -12
  162. package/types/request.d.ts +13 -8
  163. package/types/route.d.ts +62 -34
  164. package/types/schema.d.ts +1 -1
  165. package/types/type-provider.d.ts +99 -0
  166. package/types/utils.d.ts +1 -1
  167. package/lib/schema-compilers.js +0 -12
  168. package/test/emit-warning.test.js +0 -166
package/test/500s.test.js CHANGED
@@ -40,7 +40,7 @@ test('custom 500', t => {
40
40
 
41
41
  fastify.setErrorHandler(function (err, request, reply) {
42
42
  t.type(request, 'object')
43
- t.type(request, fastify[symbols.kRequest])
43
+ t.type(request, fastify[symbols.kRequest].parent)
44
44
  reply
45
45
  .code(500)
46
46
  .type('text/plain')
@@ -74,7 +74,7 @@ test('encapsulated 500', t => {
74
74
 
75
75
  f.setErrorHandler(function (err, request, reply) {
76
76
  t.type(request, 'object')
77
- t.type(request, f[symbols.kRequest])
77
+ t.type(request, fastify[symbols.kRequest].parent)
78
78
  reply
79
79
  .code(500)
80
80
  .type('text/plain')
@@ -155,7 +155,7 @@ test('cannot set errorHandler after binding', t => {
155
155
  const fastify = Fastify()
156
156
  t.teardown(fastify.close.bind(fastify))
157
157
 
158
- fastify.listen(0, err => {
158
+ fastify.listen({ port: 0 }, err => {
159
159
  t.error(err)
160
160
 
161
161
  try {
package/test/als.test.js CHANGED
@@ -31,7 +31,7 @@ app.post('/', function (request, reply) {
31
31
  reply.send({ id })
32
32
  })
33
33
 
34
- app.listen(3000, function (err, address) {
34
+ app.listen({ port: 0 }, function (err, address) {
35
35
  t.error(err)
36
36
 
37
37
  sget({
@@ -46,7 +46,7 @@ test('async await', t => {
46
46
  t.fail()
47
47
  }
48
48
 
49
- fastify.listen(0, err => {
49
+ fastify.listen({ port: 0 }, err => {
50
50
  t.error(err)
51
51
  fastify.server.unref()
52
52
 
@@ -79,12 +79,12 @@ test('ignore the result of the promise if reply.send is called beforehand (undef
79
79
  const payload = { hello: 'world' }
80
80
 
81
81
  server.get('/', async function awaitMyFunc (req, reply) {
82
- reply.send(payload)
82
+ await reply.send(payload)
83
83
  })
84
84
 
85
85
  t.teardown(server.close.bind(server))
86
86
 
87
- server.listen(0, (err) => {
87
+ server.listen({ port: 0 }, (err) => {
88
88
  t.error(err)
89
89
  sget({
90
90
  method: 'GET',
@@ -104,13 +104,13 @@ test('ignore the result of the promise if reply.send is called beforehand (objec
104
104
  const payload = { hello: 'world2' }
105
105
 
106
106
  server.get('/', async function awaitMyFunc (req, reply) {
107
- reply.send(payload)
107
+ await reply.send(payload)
108
108
  return { hello: 'world' }
109
109
  })
110
110
 
111
111
  t.teardown(server.close.bind(server))
112
112
 
113
- server.listen(0, (err) => {
113
+ server.listen({ port: 0 }, (err) => {
114
114
  t.error(err)
115
115
  sget({
116
116
  method: 'GET',
@@ -139,7 +139,7 @@ test('server logs an error if reply.send is called and a value is returned via a
139
139
  })
140
140
 
141
141
  fastify.get('/', async (req, reply) => {
142
- reply.send({ hello: 'world' })
142
+ await reply.send({ hello: 'world' })
143
143
  return { hello: 'world2' }
144
144
  })
145
145
 
@@ -160,12 +160,12 @@ test('ignore the result of the promise if reply.send is called beforehand (undef
160
160
  const payload = { hello: 'world' }
161
161
 
162
162
  server.get('/', async function awaitMyFunc (req, reply) {
163
- reply.send(payload)
163
+ await reply.send(payload)
164
164
  })
165
165
 
166
166
  t.teardown(server.close.bind(server))
167
167
 
168
- server.listen(0, (err) => {
168
+ server.listen({ port: 0 }, (err) => {
169
169
  t.error(err)
170
170
  sget({
171
171
  method: 'GET',
@@ -185,13 +185,13 @@ test('ignore the result of the promise if reply.send is called beforehand (objec
185
185
  const payload = { hello: 'world2' }
186
186
 
187
187
  server.get('/', async function awaitMyFunc (req, reply) {
188
- reply.send(payload)
188
+ await reply.send(payload)
189
189
  return { hello: 'world' }
190
190
  })
191
191
 
192
192
  t.teardown(server.close.bind(server))
193
193
 
194
- server.listen(0, (err) => {
194
+ server.listen({ port: 0 }, (err) => {
195
195
  t.error(err)
196
196
  sget({
197
197
  method: 'GET',
@@ -279,11 +279,13 @@ test('support reply decorators with await', t => {
279
279
  setImmediate(() => {
280
280
  this.send({ hello: 'world' })
281
281
  })
282
+
283
+ return this
282
284
  })
283
285
 
284
286
  fastify.get('/', async (req, reply) => {
285
287
  await sleep(1)
286
- reply.wow()
288
+ await reply.wow()
287
289
  })
288
290
 
289
291
  fastify.inject({
@@ -296,24 +298,6 @@ test('support reply decorators with await', t => {
296
298
  })
297
299
  })
298
300
 
299
- test('support 204', t => {
300
- t.plan(2)
301
-
302
- const fastify = Fastify()
303
-
304
- fastify.get('/', async (req, reply) => {
305
- reply.code(204)
306
- })
307
-
308
- fastify.inject({
309
- method: 'GET',
310
- url: '/'
311
- }, (err, res) => {
312
- t.error(err)
313
- t.equal(res.statusCode, 204)
314
- })
315
- })
316
-
317
301
  test('inject async await', async t => {
318
302
  t.plan(1)
319
303
 
@@ -399,48 +383,8 @@ test('does not call reply.send() twice if 204 response equal already sent', t =>
399
383
  })
400
384
  })
401
385
 
402
- test('error is logged because promise was fulfilled with undefined', t => {
403
- t.plan(3)
404
-
405
- let fastify = null
406
- const stream = split(JSON.parse)
407
- try {
408
- fastify = Fastify({
409
- logger: {
410
- stream,
411
- level: 'error'
412
- }
413
- })
414
- } catch (e) {
415
- t.fail()
416
- }
417
-
418
- t.teardown(fastify.close.bind(fastify))
419
-
420
- fastify.get('/', async (req, reply) => {
421
- reply.code(200)
422
- })
423
-
424
- stream.once('data', line => {
425
- t.equal(line.msg, 'Promise may not be fulfilled with \'undefined\' when statusCode is not 204')
426
- })
427
-
428
- fastify.listen(0, (err) => {
429
- t.error(err)
430
- fastify.server.unref()
431
-
432
- sget({
433
- method: 'GET',
434
- url: 'http://localhost:' + fastify.server.address().port + '/',
435
- timeout: 500
436
- }, (err, res, body) => {
437
- t.equal(err.message, 'Request timed out')
438
- })
439
- })
440
- })
441
-
442
- test('error is not logged because promise was fulfilled with undefined but statusCode 204 was set', t => {
443
- t.plan(3)
386
+ test('promise was fulfilled with undefined', t => {
387
+ t.plan(4)
444
388
 
445
389
  let fastify = null
446
390
  const stream = split(JSON.parse)
@@ -458,14 +402,13 @@ test('error is not logged because promise was fulfilled with undefined but statu
458
402
  t.teardown(fastify.close.bind(fastify))
459
403
 
460
404
  fastify.get('/', async (req, reply) => {
461
- reply.code(204)
462
405
  })
463
406
 
464
407
  stream.once('data', line => {
465
408
  t.fail('should not log an error')
466
409
  })
467
410
 
468
- fastify.listen(0, (err) => {
411
+ fastify.listen({ port: 0 }, (err) => {
469
412
  t.error(err)
470
413
  fastify.server.unref()
471
414
 
@@ -474,7 +417,8 @@ test('error is not logged because promise was fulfilled with undefined but statu
474
417
  url: 'http://localhost:' + fastify.server.address().port + '/'
475
418
  }, (err, res, body) => {
476
419
  t.error(err)
477
- t.equal(res.statusCode, 204)
420
+ t.equal(res.body, undefined)
421
+ t.equal(res.statusCode, 200)
478
422
  })
479
423
  })
480
424
  })
@@ -506,7 +450,7 @@ test('error is not logged because promise was fulfilled with undefined but respo
506
450
  t.fail('should not log an error')
507
451
  })
508
452
 
509
- fastify.listen(0, (err) => {
453
+ fastify.listen({ port: 0 }, (err) => {
510
454
  t.error(err)
511
455
  fastify.server.unref()
512
456
 
@@ -601,7 +545,7 @@ test('customErrorHandler support without throwing', t => {
601
545
 
602
546
  fastify.setErrorHandler(async (err, req, reply) => {
603
547
  t.equal(err.message, 'ouch')
604
- reply.code(401).send('kaboom')
548
+ await reply.code(401).send('kaboom')
605
549
  reply.send = t.fail.bind(t, 'should not be called')
606
550
  })
607
551
 
@@ -28,7 +28,7 @@ test('bodyLimit', t => {
28
28
  reply.send({ error: 'handler should not be called' })
29
29
  })
30
30
 
31
- fastify.listen(0, function (err) {
31
+ fastify.listen({ port: 0 }, function (err) {
32
32
  t.error(err)
33
33
  fastify.server.unref()
34
34
 
@@ -1,19 +1,18 @@
1
1
  'use strict'
2
2
 
3
- const util = require('util')
4
- const pem = require('pem')
5
-
6
- const createCertificate = util.promisify(pem.createCertificate)
3
+ const selfCert = require('self-cert')
7
4
 
8
5
  async function buildCertificate () {
9
6
  // "global" is used in here because "t.context" is only supported by "t.beforeEach" and "t.afterEach"
10
7
  // For the test case which execute this code which will be using `t.before` and it can reduce the
11
8
  // number of times executing it.
12
9
  if (!global.context || !global.context.cert || !global.context.key) {
13
- const keys = await createCertificate({ days: 1, selfSigned: true })
10
+ const certs = selfCert({
11
+ expires: new Date(Date.now() + 86400000)
12
+ })
14
13
  global.context = {
15
- cert: keys.certificate,
16
- key: keys.serviceKey
14
+ cert: certs.certificate,
15
+ key: certs.privateKey
17
16
  }
18
17
  }
19
18
  }
@@ -17,7 +17,7 @@ test('case insensitive', t => {
17
17
  reply.send({ hello: 'world' })
18
18
  })
19
19
 
20
- fastify.listen(0, err => {
20
+ fastify.listen({ port: 0 }, err => {
21
21
  t.error(err)
22
22
 
23
23
  sget({
@@ -45,7 +45,7 @@ test('case insensitive inject', t => {
45
45
  reply.send({ hello: 'world' })
46
46
  })
47
47
 
48
- fastify.listen(0, err => {
48
+ fastify.listen({ port: 0 }, err => {
49
49
  t.error(err)
50
50
 
51
51
  fastify.inject({
@@ -74,7 +74,7 @@ test('case insensitive (parametric)', t => {
74
74
  reply.send({ hello: 'world' })
75
75
  })
76
76
 
77
- fastify.listen(0, err => {
77
+ fastify.listen({ port: 0 }, err => {
78
78
  t.error(err)
79
79
 
80
80
  sget({
@@ -103,7 +103,7 @@ test('case insensitive (wildcard)', t => {
103
103
  reply.send({ hello: 'world' })
104
104
  })
105
105
 
106
- fastify.listen(0, err => {
106
+ fastify.listen({ port: 0 }, err => {
107
107
  t.error(err)
108
108
 
109
109
  sget({
@@ -15,7 +15,7 @@ test('Should return 503 while closing - pipelining', t => {
15
15
  reply.send({ hello: 'world' })
16
16
  })
17
17
 
18
- fastify.listen(0, async err => {
18
+ fastify.listen({ port: 0 }, async err => {
19
19
  t.error(err)
20
20
 
21
21
  const instance = new Client('http://localhost:' + fastify.server.address().port, {
@@ -48,7 +48,7 @@ test('Should not return 503 while closing - pipelining - return503OnClosing', t
48
48
  reply.send({ hello: 'world' })
49
49
  })
50
50
 
51
- fastify.listen(0, err => {
51
+ fastify.listen({ port: 0 }, err => {
52
52
  t.error(err)
53
53
 
54
54
  const instance = new Client('http://localhost:' + fastify.server.address().port, {
@@ -15,7 +15,7 @@ test('close callback', t => {
15
15
  done()
16
16
  }
17
17
 
18
- fastify.listen(0, err => {
18
+ fastify.listen({ port: 0 }, err => {
19
19
  t.error(err)
20
20
 
21
21
  fastify.close((err) => {
@@ -39,7 +39,7 @@ test('inside register', t => {
39
39
  done()
40
40
  })
41
41
 
42
- fastify.listen(0, err => {
42
+ fastify.listen({ port: 0 }, err => {
43
43
  t.error(err)
44
44
 
45
45
  fastify.close((err) => {
@@ -68,7 +68,7 @@ test('close order', t => {
68
68
  done()
69
69
  })
70
70
 
71
- fastify.listen(0, err => {
71
+ fastify.listen({ port: 0 }, err => {
72
72
  t.error(err)
73
73
 
74
74
  fastify.close((err) => {
@@ -95,7 +95,7 @@ test('close order - async', async t => {
95
95
  t.equal(order.shift(), 2)
96
96
  })
97
97
 
98
- await fastify.listen(0)
98
+ await fastify.listen({ port: 0 })
99
99
  await fastify.close()
100
100
 
101
101
  t.equal(order.shift(), 3)
@@ -211,7 +211,7 @@ t.test('Current opened connection should continue to work after closing and retu
211
211
  reply.send({ hello: 'world' })
212
212
  })
213
213
 
214
- fastify.listen(0, err => {
214
+ fastify.listen({ port: 0 }, err => {
215
215
  t.error(err)
216
216
 
217
217
  const port = fastify.server.address().port
@@ -248,7 +248,7 @@ t.test('Current opened connection should not accept new incoming connections', t
248
248
  }, 250)
249
249
  })
250
250
 
251
- fastify.listen(0, err => {
251
+ fastify.listen({ port: 0 }, err => {
252
252
  t.error(err)
253
253
  const instance = new Client('http://localhost:' + fastify.server.address().port)
254
254
  instance.request({ path: '/', method: 'GET' }).then(data => {
@@ -264,11 +264,11 @@ test('Cannot be reopened the closed server without listen callback', async t =>
264
264
  t.plan(2)
265
265
  const fastify = Fastify()
266
266
 
267
- await fastify.listen(0)
267
+ await fastify.listen({ port: 0 })
268
268
  await fastify.close()
269
269
 
270
270
  try {
271
- await fastify.listen(0)
271
+ await fastify.listen({ port: 0 })
272
272
  } catch (err) {
273
273
  t.ok(err)
274
274
  t.equal(err.code, 'FST_ERR_REOPENED_CLOSE_SERVER')
@@ -279,11 +279,11 @@ test('Cannot be reopened the closed server has listen callback', async t => {
279
279
  t.plan(2)
280
280
  const fastify = Fastify()
281
281
 
282
- await fastify.listen(0)
282
+ await fastify.listen({ port: 0 })
283
283
  await fastify.close()
284
284
 
285
285
  await new Promise((resolve, reject) => {
286
- fastify.listen(0, err => {
286
+ fastify.listen({ port: 0 }, err => {
287
287
  reject(err)
288
288
  })
289
289
  }).catch(err => {
@@ -305,7 +305,7 @@ test('shutsdown while keep-alive connections are active (non-async)', t => {
305
305
  reply.send({ hello: 'world' })
306
306
  })
307
307
 
308
- fastify.listen(0, (err, address) => {
308
+ fastify.listen({ port: 0 }, (err, address) => {
309
309
  t.error(err)
310
310
 
311
311
  const client = new Client(
@@ -187,6 +187,38 @@ test('add', t => {
187
187
  t.end()
188
188
  })
189
189
 
190
+ test('non-Error thrown from content parser is properly handled', t => {
191
+ t.plan(3)
192
+
193
+ const fastify = Fastify()
194
+
195
+ const throwable = 'test'
196
+ const payload = 'error'
197
+
198
+ fastify.addContentTypeParser('text/test', (request, payload, done) => {
199
+ done(throwable)
200
+ })
201
+
202
+ fastify.post('/', (req, reply) => {
203
+ })
204
+
205
+ fastify.setErrorHandler((err, req, res) => {
206
+ t.equal(err, throwable)
207
+
208
+ res.send(payload)
209
+ })
210
+
211
+ fastify.inject({
212
+ method: 'POST',
213
+ url: '/',
214
+ headers: { 'Content-Type': 'text/test' },
215
+ body: 'some text'
216
+ }, (err, res) => {
217
+ t.error(err)
218
+ t.equal(res.payload, payload)
219
+ })
220
+ })
221
+
190
222
  test('remove', t => {
191
223
  test('should remove default parser', t => {
192
224
  t.plan(2)
@@ -119,3 +119,55 @@ test('config with exposeHeadRoutes', t => {
119
119
  t.same(JSON.parse(response.payload), { url: '/no-config', method: 'GET' })
120
120
  })
121
121
  })
122
+
123
+ test('config without exposeHeadRoutes', t => {
124
+ t.plan(9)
125
+ const fastify = Fastify({ exposeHeadRoutes: false })
126
+
127
+ fastify.get('/get', {
128
+ schema: schema.schema,
129
+ config: Object.assign({}, schema.config)
130
+ }, handler)
131
+
132
+ fastify.route({
133
+ method: 'GET',
134
+ url: '/route',
135
+ schema: schema.schema,
136
+ handler,
137
+ config: Object.assign({}, schema.config)
138
+ })
139
+
140
+ fastify.route({
141
+ method: 'GET',
142
+ url: '/no-config',
143
+ schema: schema.schema,
144
+ handler
145
+ })
146
+
147
+ fastify.inject({
148
+ method: 'GET',
149
+ url: '/get'
150
+ }, (err, response) => {
151
+ t.error(err)
152
+ t.equal(response.statusCode, 200)
153
+ t.same(JSON.parse(response.payload), Object.assign({ url: '/get', method: 'GET' }, schema.config))
154
+ })
155
+
156
+ fastify.inject({
157
+ method: 'GET',
158
+ url: '/route'
159
+ }, (err, response) => {
160
+ t.error(err)
161
+ t.equal(response.statusCode, 200)
162
+ t.same(JSON.parse(response.payload), Object.assign({ url: '/route', method: 'GET' }, schema.config))
163
+ })
164
+
165
+ fastify.inject({
166
+ method: 'GET',
167
+ url: '/no-config'
168
+ }, (err, response) => {
169
+ t.error(err)
170
+ t.equal(response.statusCode, 200)
171
+ t.same(JSON.parse(response.payload), { url: '/no-config', method: 'GET' })
172
+ })
173
+ })
@@ -5,12 +5,15 @@ const test = t.test
5
5
  const Fastify = require('..')
6
6
  const http = require('http')
7
7
  const sget = require('simple-get').concat
8
+ const dns = require('dns').promises
8
9
 
9
- test('Should support a custom http server', t => {
10
- t.plan(6)
10
+ test('Should support a custom http server', async t => {
11
+ const localAddresses = await dns.lookup('localhost', { all: true })
12
+
13
+ t.plan(localAddresses.length + 3)
11
14
 
12
15
  const serverFactory = (handler, opts) => {
13
- t.ok(opts.serverFactory)
16
+ t.ok(opts.serverFactory, 'it is called twice for every HOST interface')
14
17
 
15
18
  const server = http.createServer((req, res) => {
16
19
  req.custom = true
@@ -29,16 +32,20 @@ test('Should support a custom http server', t => {
29
32
  reply.send({ hello: 'world' })
30
33
  })
31
34
 
32
- fastify.listen(0, err => {
33
- t.error(err)
35
+ await fastify.listen({ port: 0 })
34
36
 
37
+ await new Promise((resolve, reject) => {
35
38
  sget({
36
39
  method: 'GET',
37
- url: 'http://localhost:' + fastify.server.address().port
40
+ url: 'http://localhost:' + fastify.server.address().port,
41
+ rejectUnauthorized: false
38
42
  }, (err, response, body) => {
39
- t.error(err)
43
+ if (err) {
44
+ return reject(err)
45
+ }
40
46
  t.equal(response.statusCode, 200)
41
47
  t.same(JSON.parse(body), { hello: 'world' })
48
+ resolve()
42
49
  })
43
50
  })
44
51
  })
@@ -24,7 +24,7 @@ test('contentTypeParser should add a custom async parser', t => {
24
24
  return res
25
25
  })
26
26
 
27
- fastify.listen(0, err => {
27
+ fastify.listen({ port: 0 }, err => {
28
28
  t.error(err)
29
29
 
30
30
  t.teardown(() => fastify.close())
@@ -64,68 +64,3 @@ test('contentTypeParser should add a custom async parser', t => {
64
64
  })
65
65
  })
66
66
  })
67
-
68
- test('contentTypeParser should add a custom async parser - deprecated syntax', t => {
69
- t.plan(5)
70
- const fastify = Fastify()
71
-
72
- process.on('warning', onWarning)
73
- function onWarning (warning) {
74
- t.equal(warning.name, 'FastifyDeprecation')
75
- t.equal(warning.code, 'FSTDEP003')
76
- }
77
-
78
- fastify.post('/', (req, reply) => {
79
- reply.send(req.body)
80
- })
81
-
82
- fastify.options('/', (req, reply) => {
83
- reply.send(req.body)
84
- })
85
-
86
- fastify.addContentTypeParser('application/jsoff', async function (req) {
87
- const res = await new Promise((resolve, reject) => resolve(req))
88
- return res
89
- })
90
-
91
- fastify.listen(0, err => {
92
- t.error(err)
93
-
94
- t.teardown(() => fastify.close())
95
-
96
- t.test('in POST', t => {
97
- t.plan(3)
98
-
99
- sget({
100
- method: 'POST',
101
- url: 'http://localhost:' + fastify.server.address().port,
102
- body: '{"hello":"world"}',
103
- headers: {
104
- 'Content-Type': 'application/jsoff'
105
- }
106
- }, (err, response, body) => {
107
- t.error(err)
108
- t.equal(response.statusCode, 200)
109
- t.same(body.toString(), JSON.stringify({ hello: 'world' }))
110
- })
111
- })
112
-
113
- t.test('in OPTIONS', t => {
114
- t.plan(3)
115
-
116
- sget({
117
- method: 'OPTIONS',
118
- url: 'http://localhost:' + fastify.server.address().port,
119
- body: '{"hello":"world"}',
120
- headers: {
121
- 'Content-Type': 'application/jsoff'
122
- }
123
- }, (err, response, body) => {
124
- t.error(err)
125
- t.equal(response.statusCode, 200)
126
- t.same(body.toString(), JSON.stringify({ hello: 'world' }))
127
- process.removeListener('warning', onWarning)
128
- })
129
- })
130
- })
131
- })