fastify 4.19.1 → 4.20.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 (56) hide show
  1. package/.c8rc.json +8 -0
  2. package/.taprc +3 -2
  3. package/SECURITY.md +9 -0
  4. package/docs/Guides/Prototype-Poisoning.md +2 -2
  5. package/docs/Reference/Errors.md +39 -17
  6. package/docs/Reference/Logging.md +1 -1
  7. package/docs/Reference/Plugins.md +4 -0
  8. package/docs/Reference/Routes.md +8 -0
  9. package/docs/Reference/Server.md +38 -0
  10. package/fastify.d.ts +3 -2
  11. package/fastify.js +51 -24
  12. package/lib/context.js +6 -0
  13. package/lib/errors.js +50 -19
  14. package/lib/fourOhFour.js +5 -9
  15. package/lib/handleRequest.js +3 -5
  16. package/lib/hooks.js +91 -25
  17. package/lib/logger.js +40 -3
  18. package/lib/reply.js +3 -9
  19. package/lib/reqIdGenFactory.js +18 -3
  20. package/lib/route.js +14 -61
  21. package/lib/schema-controller.js +2 -0
  22. package/lib/server.js +23 -8
  23. package/lib/symbols.js +1 -0
  24. package/package.json +8 -7
  25. package/test/500s.test.js +22 -0
  26. package/test/childLoggerFactory.test.js +91 -0
  27. package/test/custom-http-server.test.js +42 -0
  28. package/test/encapsulated-child-logger-factory.test.js +69 -0
  29. package/test/fastify-instance.test.js +43 -10
  30. package/test/inject.test.js +1 -2
  31. package/test/internals/errors.test.js +843 -0
  32. package/test/internals/hookRunner.test.js +22 -8
  33. package/test/internals/initialConfig.test.js +9 -2
  34. package/test/internals/reply.test.js +49 -43
  35. package/test/internals/reqIdGenFactory.test.js +129 -0
  36. package/test/internals/request-validate.test.js +40 -1
  37. package/test/internals/request.test.js +14 -4
  38. package/test/reply-error.test.js +25 -0
  39. package/test/request-id.test.js +131 -0
  40. package/test/route.test.js +135 -0
  41. package/test/server.test.js +64 -2
  42. package/test/types/errors.test-d.ts +82 -0
  43. package/test/types/fastify.test-d.ts +4 -0
  44. package/test/types/hooks.test-d.ts +65 -64
  45. package/test/types/instance.test-d.ts +139 -0
  46. package/test/types/reply.test-d.ts +9 -8
  47. package/test/types/request.test-d.ts +17 -18
  48. package/test/types/route.test-d.ts +10 -7
  49. package/test/types/type-provider.test-d.ts +4 -0
  50. package/types/context.d.ts +3 -3
  51. package/types/errors.d.ts +29 -23
  52. package/types/instance.d.ts +39 -7
  53. package/types/logger.d.ts +25 -0
  54. package/types/reply.d.ts +10 -5
  55. package/types/request.d.ts +5 -5
  56. package/types/route.d.ts +8 -7
@@ -2,12 +2,14 @@
2
2
 
3
3
  const t = require('tap')
4
4
  const test = t.test
5
- const { hookRunner, onSendHookRunner } = require('../../lib/hooks')
5
+ const { hookRunnerGenerator, onSendHookRunner } = require('../../lib/hooks')
6
6
 
7
7
  test('hookRunner - Basic', t => {
8
8
  t.plan(9)
9
9
 
10
- hookRunner([fn1, fn2, fn3], iterator, 'a', 'b', done)
10
+ const hookRunner = hookRunnerGenerator(iterator)
11
+
12
+ hookRunner([fn1, fn2, fn3], 'a', 'b', done)
11
13
 
12
14
  function iterator (fn, a, b, done) {
13
15
  return fn(a, b, done)
@@ -41,7 +43,9 @@ test('hookRunner - Basic', t => {
41
43
  test('hookRunner - In case of error should skip to done', t => {
42
44
  t.plan(7)
43
45
 
44
- hookRunner([fn1, fn2, fn3], iterator, 'a', 'b', done)
46
+ const hookRunner = hookRunnerGenerator(iterator)
47
+
48
+ hookRunner([fn1, fn2, fn3], 'a', 'b', done)
45
49
 
46
50
  function iterator (fn, a, b, done) {
47
51
  return fn(a, b, done)
@@ -73,7 +77,9 @@ test('hookRunner - In case of error should skip to done', t => {
73
77
  test('hookRunner - Should handle throw', t => {
74
78
  t.plan(7)
75
79
 
76
- hookRunner([fn1, fn2, fn3], iterator, 'a', 'b', done)
80
+ const hookRunner = hookRunnerGenerator(iterator)
81
+
82
+ hookRunner([fn1, fn2, fn3], 'a', 'b', done)
77
83
 
78
84
  function iterator (fn, a, b, done) {
79
85
  return fn(a, b, done)
@@ -105,7 +111,9 @@ test('hookRunner - Should handle throw', t => {
105
111
  test('hookRunner - Should handle promises', t => {
106
112
  t.plan(9)
107
113
 
108
- hookRunner([fn1, fn2, fn3], iterator, 'a', 'b', done)
114
+ const hookRunner = hookRunnerGenerator(iterator)
115
+
116
+ hookRunner([fn1, fn2, fn3], 'a', 'b', done)
109
117
 
110
118
  function iterator (fn, a, b, done) {
111
119
  return fn(a, b, done)
@@ -139,7 +147,9 @@ test('hookRunner - Should handle promises', t => {
139
147
  test('hookRunner - In case of error should skip to done (with promises)', t => {
140
148
  t.plan(7)
141
149
 
142
- hookRunner([fn1, fn2, fn3], iterator, 'a', 'b', done)
150
+ const hookRunner = hookRunnerGenerator(iterator)
151
+
152
+ hookRunner([fn1, fn2, fn3], 'a', 'b', done)
143
153
 
144
154
  function iterator (fn, a, b, done) {
145
155
  return fn(a, b, done)
@@ -171,8 +181,10 @@ test('hookRunner - In case of error should skip to done (with promises)', t => {
171
181
  test('hookRunner - Be able to exit before its natural end', t => {
172
182
  t.plan(4)
173
183
 
184
+ const hookRunner = hookRunnerGenerator(iterator)
185
+
174
186
  let shouldStop = false
175
- hookRunner([fn1, fn2, fn3], iterator, 'a', 'b', done)
187
+ hookRunner([fn1, fn2, fn3], 'a', 'b', done)
176
188
 
177
189
  function iterator (fn, a, b, done) {
178
190
  if (shouldStop) {
@@ -208,7 +220,9 @@ test('hookRunner - Promises that resolve to a value do not change the state', t
208
220
 
209
221
  const originalState = { a: 'a', b: 'b' }
210
222
 
211
- hookRunner([fn1, fn2, fn3], iterator, originalState, 'b', done)
223
+ const hookRunner = hookRunnerGenerator(iterator)
224
+
225
+ hookRunner([fn1, fn2, fn3], originalState, 'b', done)
212
226
 
213
227
  function iterator (fn, state, b, done) {
214
228
  return fn(state, b, done)
@@ -55,7 +55,7 @@ test('without options passed to Fastify, initialConfig should expose default val
55
55
  })
56
56
 
57
57
  test('Fastify.initialConfig should expose all options', t => {
58
- t.plan(20)
58
+ t.plan(21)
59
59
 
60
60
  const serverFactory = (handler, opts) => {
61
61
  const server = http.createServer((req, res) => {
@@ -132,6 +132,7 @@ test('Fastify.initialConfig should expose all options', t => {
132
132
  t.equal(fastify.initialConfig.serverFactory, undefined)
133
133
  t.equal(fastify.initialConfig.trustProxy, undefined)
134
134
  t.equal(fastify.initialConfig.genReqId, undefined)
135
+ t.equal(fastify.initialConfig.childLoggerFactory, undefined)
135
136
  t.equal(fastify.initialConfig.querystringParser, undefined)
136
137
  t.equal(fastify.initialConfig.logger, undefined)
137
138
  t.equal(fastify.initialConfig.trustProxy, undefined)
@@ -243,7 +244,7 @@ test('Original options must not be altered (test deep cloning)', t => {
243
244
  })
244
245
 
245
246
  test('Should not have issues when passing stream options to Pino.js', t => {
246
- t.plan(15)
247
+ t.plan(17)
247
248
 
248
249
  const stream = split(JSON.parse)
249
250
 
@@ -259,6 +260,10 @@ test('Should not have issues when passing stream options to Pino.js', t => {
259
260
 
260
261
  try {
261
262
  fastify = Fastify(originalOptions)
263
+ fastify.setChildLoggerFactory(function (logger, bindings, opts) {
264
+ bindings.someBinding = 'value'
265
+ return logger.child(bindings, opts)
266
+ })
262
267
 
263
268
  t.type(fastify, 'object')
264
269
  t.same(fastify.initialConfig, {
@@ -297,6 +302,7 @@ test('Should not have issues when passing stream options to Pino.js', t => {
297
302
  stream.once('data', line => {
298
303
  const id = line.reqId
299
304
  t.ok(line.reqId, 'reqId is defined')
305
+ t.equal(line.someBinding, 'value', 'child logger binding is set')
300
306
  t.ok(line.req, 'req is defined')
301
307
  t.equal(line.msg, 'incoming request', 'message is set')
302
308
  t.equal(line.req.method, 'GET', 'method is get')
@@ -304,6 +310,7 @@ test('Should not have issues when passing stream options to Pino.js', t => {
304
310
  stream.once('data', line => {
305
311
  t.equal(line.reqId, id)
306
312
  t.ok(line.reqId, 'reqId is defined')
313
+ t.equal(line.someBinding, 'value', 'child logger binding is set')
307
314
  t.ok(line.res, 'res is defined')
308
315
  t.equal(line.msg, 'request completed', 'message is set')
309
316
  t.equal(line.res.statusCode, 200, 'statusCode is 200')
@@ -6,6 +6,7 @@ const sget = require('simple-get').concat
6
6
  const http = require('http')
7
7
  const NotFound = require('http-errors').NotFound
8
8
  const Reply = require('../../lib/reply')
9
+ const Fastify = require('../..')
9
10
  const { Readable, Writable } = require('stream')
10
11
  const {
11
12
  kReplyErrorHandlerCalled,
@@ -19,9 +20,11 @@ const fs = require('fs')
19
20
  const path = require('path')
20
21
  const warning = require('../../lib/warnings')
21
22
 
23
+ const agent = new http.Agent({ keepAlive: false })
24
+
22
25
  const doGet = function (url) {
23
26
  return new Promise((resolve, reject) => {
24
- sget({ method: 'GET', url, followRedirects: false }, (err, response, body) => {
27
+ sget({ method: 'GET', url, followRedirects: false, agent }, (err, response, body) => {
25
28
  if (err) {
26
29
  reject(err)
27
30
  } else {
@@ -128,7 +131,8 @@ test('reply.serializer should set a custom serializer', t => {
128
131
 
129
132
  test('reply.serializer should support running preSerialization hooks', t => {
130
133
  t.plan(3)
131
- const fastify = require('../..')()
134
+ const fastify = Fastify()
135
+ t.teardown(fastify.close.bind(fastify))
132
136
 
133
137
  fastify.addHook('preSerialization', async (request, reply, payload) => { t.ok('called', 'preSerialization') })
134
138
  fastify.route({
@@ -182,7 +186,8 @@ test('reply.serialize should serialize payload with a context default serializer
182
186
 
183
187
  test('reply.serialize should serialize payload with Fastify instance', t => {
184
188
  t.plan(2)
185
- const fastify = require('../..')()
189
+ const fastify = Fastify()
190
+ t.teardown(fastify.close.bind(fastify))
186
191
  fastify.route({
187
192
  method: 'GET',
188
193
  url: '/',
@@ -213,7 +218,8 @@ test('reply.serialize should serialize payload with Fastify instance', t => {
213
218
  })
214
219
 
215
220
  test('within an instance', t => {
216
- const fastify = require('../..')()
221
+ const fastify = Fastify()
222
+ t.teardown(fastify.close.bind(fastify))
217
223
  const test = t.test
218
224
 
219
225
  fastify.get('/', function (req, reply) {
@@ -434,7 +440,7 @@ test('within an instance', t => {
434
440
  test('buffer without content type should send a application/octet-stream and raw buffer', t => {
435
441
  t.plan(4)
436
442
 
437
- const fastify = require('../..')()
443
+ const fastify = Fastify()
438
444
 
439
445
  fastify.get('/', function (req, reply) {
440
446
  reply.send(Buffer.alloc(1024))
@@ -457,7 +463,7 @@ test('buffer without content type should send a application/octet-stream and raw
457
463
  test('Uint8Array without content type should send a application/octet-stream and raw buffer', t => {
458
464
  t.plan(4)
459
465
 
460
- const fastify = require('../..')()
466
+ const fastify = Fastify()
461
467
 
462
468
  fastify.get('/', function (req, reply) {
463
469
  reply.send(new Uint8Array(1024).fill(0xff))
@@ -480,7 +486,7 @@ test('Uint8Array without content type should send a application/octet-stream and
480
486
  test('Uint16Array without content type should send a application/octet-stream and raw buffer', t => {
481
487
  t.plan(4)
482
488
 
483
- const fastify = require('../..')()
489
+ const fastify = Fastify()
484
490
 
485
491
  fastify.get('/', function (req, reply) {
486
492
  reply.send(new Uint16Array(50).fill(0xffffffff))
@@ -503,7 +509,7 @@ test('Uint16Array without content type should send a application/octet-stream an
503
509
  test('TypedArray with content type should not send application/octet-stream', t => {
504
510
  t.plan(4)
505
511
 
506
- const fastify = require('../..')()
512
+ const fastify = Fastify()
507
513
 
508
514
  fastify.get('/', function (req, reply) {
509
515
  reply.header('Content-Type', 'text/plain')
@@ -527,7 +533,7 @@ test('TypedArray with content type should not send application/octet-stream', t
527
533
  test('buffer with content type should not send application/octet-stream', t => {
528
534
  t.plan(4)
529
535
 
530
- const fastify = require('../..')()
536
+ const fastify = Fastify()
531
537
 
532
538
  fastify.get('/', function (req, reply) {
533
539
  reply.header('Content-Type', 'text/plain')
@@ -552,7 +558,7 @@ test('buffer with content type should not send application/octet-stream', t => {
552
558
  test('stream with content type should not send application/octet-stream', t => {
553
559
  t.plan(4)
554
560
 
555
- const fastify = require('../..')()
561
+ const fastify = Fastify()
556
562
 
557
563
  const streamPath = path.join(__dirname, '..', '..', 'package.json')
558
564
  const stream = fs.createReadStream(streamPath)
@@ -579,7 +585,7 @@ test('stream with content type should not send application/octet-stream', t => {
579
585
  test('stream without content type should not send application/octet-stream', t => {
580
586
  t.plan(4)
581
587
 
582
- const fastify = require('../..')()
588
+ const fastify = Fastify()
583
589
 
584
590
  const stream = fs.createReadStream(__filename)
585
591
  const buf = fs.readFileSync(__filename)
@@ -605,7 +611,7 @@ test('stream without content type should not send application/octet-stream', t =
605
611
  test('stream using reply.raw.writeHead should return customize headers', t => {
606
612
  t.plan(6)
607
613
 
608
- const fastify = require('../..')()
614
+ const fastify = Fastify()
609
615
  const fs = require('fs')
610
616
  const path = require('path')
611
617
 
@@ -641,7 +647,7 @@ test('stream using reply.raw.writeHead should return customize headers', t => {
641
647
  test('plain string without content type should send a text/plain', t => {
642
648
  t.plan(4)
643
649
 
644
- const fastify = require('../..')()
650
+ const fastify = Fastify()
645
651
 
646
652
  fastify.get('/', function (req, reply) {
647
653
  reply.send('hello world!')
@@ -665,7 +671,7 @@ test('plain string without content type should send a text/plain', t => {
665
671
  test('plain string with content type should be sent unmodified', t => {
666
672
  t.plan(4)
667
673
 
668
- const fastify = require('../..')()
674
+ const fastify = Fastify()
669
675
 
670
676
  fastify.get('/', function (req, reply) {
671
677
  reply.type('text/css').send('hello world!')
@@ -689,7 +695,7 @@ test('plain string with content type should be sent unmodified', t => {
689
695
  test('plain string with content type and custom serializer should be serialized', t => {
690
696
  t.plan(4)
691
697
 
692
- const fastify = require('../..')()
698
+ const fastify = Fastify()
693
699
 
694
700
  fastify.get('/', function (req, reply) {
695
701
  reply
@@ -716,7 +722,7 @@ test('plain string with content type and custom serializer should be serialized'
716
722
  test('plain string with content type application/json should NOT be serialized as json', t => {
717
723
  t.plan(4)
718
724
 
719
- const fastify = require('../..')()
725
+ const fastify = Fastify()
720
726
 
721
727
  fastify.get('/', function (req, reply) {
722
728
  reply.type('application/json').send('{"key": "hello world!"}')
@@ -740,7 +746,7 @@ test('plain string with content type application/json should NOT be serialized a
740
746
  test('plain string with custom json content type should NOT be serialized as json', t => {
741
747
  t.plan(19)
742
748
 
743
- const fastify = require('../..')()
749
+ const fastify = Fastify()
744
750
 
745
751
  const customSamples = {
746
752
  collectionjson: {
@@ -795,7 +801,7 @@ test('plain string with custom json content type should NOT be serialized as jso
795
801
  test('non-string with content type application/json SHOULD be serialized as json', t => {
796
802
  t.plan(4)
797
803
 
798
- const fastify = require('../..')()
804
+ const fastify = Fastify()
799
805
 
800
806
  fastify.get('/', function (req, reply) {
801
807
  reply.type('application/json').send({ key: 'hello world!' })
@@ -819,7 +825,7 @@ test('non-string with content type application/json SHOULD be serialized as json
819
825
  test('non-string with custom json\'s content-type SHOULD be serialized as json', t => {
820
826
  t.plan(4)
821
827
 
822
- const fastify = require('../..')()
828
+ const fastify = Fastify()
823
829
 
824
830
  fastify.get('/', function (req, reply) {
825
831
  reply.type('application/json; version=2; ').send({ key: 'hello world!' })
@@ -843,7 +849,7 @@ test('non-string with custom json\'s content-type SHOULD be serialized as json',
843
849
  test('non-string with custom json content type SHOULD be serialized as json', t => {
844
850
  t.plan(16)
845
851
 
846
- const fastify = require('../..')()
852
+ const fastify = Fastify()
847
853
 
848
854
  const customSamples = {
849
855
  collectionjson: {
@@ -894,7 +900,7 @@ test('non-string with custom json content type SHOULD be serialized as json', t
894
900
  test('error object with a content type that is not application/json should work', t => {
895
901
  t.plan(6)
896
902
 
897
- const fastify = require('../..')()
903
+ const fastify = Fastify()
898
904
 
899
905
  fastify.get('/text', function (req, reply) {
900
906
  reply.type('text/plain')
@@ -928,7 +934,7 @@ test('error object with a content type that is not application/json should work'
928
934
  test('undefined payload should be sent as-is', t => {
929
935
  t.plan(6)
930
936
 
931
- const fastify = require('../..')()
937
+ const fastify = Fastify()
932
938
 
933
939
  fastify.addHook('onSend', function (request, reply, payload, done) {
934
940
  t.equal(payload, undefined)
@@ -958,7 +964,7 @@ test('undefined payload should be sent as-is', t => {
958
964
  test('for HEAD method, no body should be sent but content-length should be', t => {
959
965
  t.plan(11)
960
966
 
961
- const fastify = require('../..')()
967
+ const fastify = Fastify()
962
968
  const contentType = 'application/json; charset=utf-8'
963
969
  const bodySize = JSON.stringify({ foo: 'bar' }).length
964
970
 
@@ -1013,7 +1019,7 @@ test('for HEAD method, no body should be sent but content-length should be', t =
1013
1019
  test('reply.send(new NotFound()) should not invoke the 404 handler', t => {
1014
1020
  t.plan(9)
1015
1021
 
1016
- const fastify = require('../..')()
1022
+ const fastify = Fastify()
1017
1023
 
1018
1024
  fastify.setNotFoundHandler((req, reply) => {
1019
1025
  t.fail('Should not be called')
@@ -1389,7 +1395,7 @@ test('Content type and charset set previously', t => {
1389
1395
 
1390
1396
  test('.status() is an alias for .code()', t => {
1391
1397
  t.plan(2)
1392
- const fastify = require('../..')()
1398
+ const fastify = Fastify()
1393
1399
 
1394
1400
  fastify.get('/', function (req, reply) {
1395
1401
  reply.status(418).send()
@@ -1403,7 +1409,7 @@ test('.status() is an alias for .code()', t => {
1403
1409
 
1404
1410
  test('.statusCode is getter and setter', t => {
1405
1411
  t.plan(4)
1406
- const fastify = require('../..')()
1412
+ const fastify = Fastify()
1407
1413
 
1408
1414
  fastify.get('/', function (req, reply) {
1409
1415
  t.ok(reply.statusCode, 200, 'default status value')
@@ -1455,7 +1461,7 @@ test('reply.header setting multiple cookies as multiple Set-Cookie headers', t =
1455
1461
 
1456
1462
  test('should emit deprecation warning when trying to modify the reply.sent property', t => {
1457
1463
  t.plan(4)
1458
- const fastify = require('../..')()
1464
+ const fastify = Fastify()
1459
1465
 
1460
1466
  const deprecationCode = 'FSTDEP010'
1461
1467
  warning.emitted.delete(deprecationCode)
@@ -1483,7 +1489,7 @@ test('should emit deprecation warning when trying to modify the reply.sent prope
1483
1489
 
1484
1490
  test('should throw error when passing falsy value to reply.sent', t => {
1485
1491
  t.plan(4)
1486
- const fastify = require('../..')()
1492
+ const fastify = Fastify()
1487
1493
 
1488
1494
  fastify.get('/', function (req, reply) {
1489
1495
  try {
@@ -1503,7 +1509,7 @@ test('should throw error when passing falsy value to reply.sent', t => {
1503
1509
 
1504
1510
  test('should throw error when attempting to set reply.sent more than once', t => {
1505
1511
  t.plan(4)
1506
- const fastify = require('../..')()
1512
+ const fastify = Fastify()
1507
1513
 
1508
1514
  fastify.get('/', function (req, reply) {
1509
1515
  reply.sent = true
@@ -1525,7 +1531,7 @@ test('should throw error when attempting to set reply.sent more than once', t =>
1525
1531
 
1526
1532
  test('should not throw error when attempting to set reply.sent if the underlining request was sent', t => {
1527
1533
  t.plan(3)
1528
- const fastify = require('../..')()
1534
+ const fastify = Fastify()
1529
1535
 
1530
1536
  fastify.get('/', function (req, reply) {
1531
1537
  reply.raw.end()
@@ -1549,7 +1555,7 @@ test('reply.getResponseTime() should return 0 before the timer is initialised on
1549
1555
 
1550
1556
  test('reply.getResponseTime() should return a number greater than 0 after the timer is initialised on the reply by setting up response listeners', t => {
1551
1557
  t.plan(1)
1552
- const fastify = require('../..')()
1558
+ const fastify = Fastify()
1553
1559
  fastify.route({
1554
1560
  method: 'GET',
1555
1561
  url: '/',
@@ -1568,7 +1574,7 @@ test('reply.getResponseTime() should return a number greater than 0 after the ti
1568
1574
 
1569
1575
  test('reply.getResponseTime() should return the time since a request started while inflight', t => {
1570
1576
  t.plan(1)
1571
- const fastify = require('../..')()
1577
+ const fastify = Fastify()
1572
1578
  fastify.route({
1573
1579
  method: 'GET',
1574
1580
  url: '/',
@@ -1591,7 +1597,7 @@ test('reply.getResponseTime() should return the time since a request started whi
1591
1597
 
1592
1598
  test('reply.getResponseTime() should return the same value after a request is finished', t => {
1593
1599
  t.plan(1)
1594
- const fastify = require('../..')()
1600
+ const fastify = Fastify()
1595
1601
  fastify.route({
1596
1602
  method: 'GET',
1597
1603
  url: '/',
@@ -1610,7 +1616,7 @@ test('reply.getResponseTime() should return the same value after a request is fi
1610
1616
 
1611
1617
  test('reply should use the custom serializer', t => {
1612
1618
  t.plan(4)
1613
- const fastify = require('../..')()
1619
+ const fastify = Fastify()
1614
1620
  fastify.setReplySerializer((payload, statusCode) => {
1615
1621
  t.same(payload, { foo: 'bar' })
1616
1622
  t.equal(statusCode, 200)
@@ -1638,7 +1644,7 @@ test('reply should use the custom serializer', t => {
1638
1644
  test('reply should use the right serializer in encapsulated context', t => {
1639
1645
  t.plan(9)
1640
1646
 
1641
- const fastify = require('../..')()
1647
+ const fastify = Fastify()
1642
1648
  fastify.setReplySerializer((payload) => {
1643
1649
  t.same(payload, { foo: 'bar' })
1644
1650
  payload.foo = 'bar bar'
@@ -1707,7 +1713,7 @@ test('reply should use the right serializer in encapsulated context', t => {
1707
1713
  test('reply should use the right serializer in deep encapsulated context', t => {
1708
1714
  t.plan(8)
1709
1715
 
1710
- const fastify = require('../..')()
1716
+ const fastify = Fastify()
1711
1717
 
1712
1718
  fastify.route({
1713
1719
  method: 'GET',
@@ -1771,7 +1777,7 @@ test('reply should use the right serializer in deep encapsulated context', t =>
1771
1777
  test('reply should use the route serializer', t => {
1772
1778
  t.plan(3)
1773
1779
 
1774
- const fastify = require('../..')()
1780
+ const fastify = Fastify()
1775
1781
  fastify.setReplySerializer(() => {
1776
1782
  t.fail('this serializer should not be executed')
1777
1783
  })
@@ -1802,7 +1808,7 @@ test('reply should use the route serializer', t => {
1802
1808
  test('cannot set the replySerializer when the server is running', t => {
1803
1809
  t.plan(2)
1804
1810
 
1805
- const fastify = require('../..')()
1811
+ const fastify = Fastify()
1806
1812
  t.teardown(fastify.close.bind(fastify))
1807
1813
 
1808
1814
  fastify.listen({ port: 0 }, err => {
@@ -1819,7 +1825,7 @@ test('cannot set the replySerializer when the server is running', t => {
1819
1825
  test('reply should not call the custom serializer for errors and not found', t => {
1820
1826
  t.plan(9)
1821
1827
 
1822
- const fastify = require('../..')()
1828
+ const fastify = Fastify()
1823
1829
  fastify.setReplySerializer((payload, statusCode) => {
1824
1830
  t.same(payload, { foo: 'bar' })
1825
1831
  t.equal(statusCode, 200)
@@ -1935,7 +1941,7 @@ test('reply.sent should read from response.writableEnded if it is defined', t =>
1935
1941
  })
1936
1942
 
1937
1943
  test('redirect to an invalid URL should not crash the server', async t => {
1938
- const fastify = require('../..')()
1944
+ const fastify = Fastify()
1939
1945
  fastify.route({
1940
1946
  method: 'GET',
1941
1947
  url: '/redirect',
@@ -1988,7 +1994,7 @@ test('redirect to an invalid URL should not crash the server', async t => {
1988
1994
  })
1989
1995
 
1990
1996
  test('invalid response headers should not crash the server', async t => {
1991
- const fastify = require('../..')()
1997
+ const fastify = Fastify()
1992
1998
  fastify.route({
1993
1999
  method: 'GET',
1994
2000
  url: '/bad-headers',
@@ -2021,7 +2027,7 @@ test('invalid response headers should not crash the server', async t => {
2021
2027
  })
2022
2028
 
2023
2029
  test('invalid response headers when sending back an error', async t => {
2024
- const fastify = require('../..')()
2030
+ const fastify = Fastify()
2025
2031
  fastify.route({
2026
2032
  method: 'GET',
2027
2033
  url: '/bad-headers',
@@ -2050,7 +2056,7 @@ test('invalid response headers when sending back an error', async t => {
2050
2056
  })
2051
2057
 
2052
2058
  test('invalid response headers and custom error handler', async t => {
2053
- const fastify = require('../..')()
2059
+ const fastify = Fastify()
2054
2060
  fastify.route({
2055
2061
  method: 'GET',
2056
2062
  url: '/bad-headers',
@@ -0,0 +1,129 @@
1
+ 'use strict'
2
+
3
+ const { test } = require('tap')
4
+ const { reqIdGenFactory } = require('../../lib/reqIdGenFactory')
5
+
6
+ test('should create incremental ids deterministically', t => {
7
+ t.plan(9999)
8
+ const reqIdGen = reqIdGenFactory()
9
+
10
+ for (let i = 1; i < 1e4; ++i) {
11
+ t.equal(reqIdGen(), 'req-' + i.toString(36))
12
+ }
13
+ })
14
+
15
+ test('should have prefix "req-"', t => {
16
+ t.plan(1)
17
+ const reqIdGen = reqIdGenFactory()
18
+
19
+ t.ok(reqIdGen().startsWith('req-'))
20
+ })
21
+
22
+ test('different id generator functions should have separate internal counters', t => {
23
+ t.plan(5)
24
+ const reqIdGenA = reqIdGenFactory()
25
+ const reqIdGenB = reqIdGenFactory()
26
+
27
+ t.equal(reqIdGenA(), 'req-1')
28
+ t.equal(reqIdGenA(), 'req-2')
29
+ t.equal(reqIdGenB(), 'req-1')
30
+ t.equal(reqIdGenA(), 'req-3')
31
+ t.equal(reqIdGenB(), 'req-2')
32
+ })
33
+
34
+ test('should start counting with 1', t => {
35
+ t.plan(1)
36
+ const reqIdGen = reqIdGenFactory()
37
+
38
+ t.equal(reqIdGen(), 'req-1')
39
+ })
40
+
41
+ test('should handle requestIdHeader and return provided id in header', t => {
42
+ t.plan(1)
43
+
44
+ const reqIdGen = reqIdGenFactory('id')
45
+
46
+ t.equal(reqIdGen({ headers: { id: '1337' } }), '1337')
47
+ })
48
+
49
+ test('should handle requestIdHeader and fallback if id is not provided in header', t => {
50
+ t.plan(1)
51
+
52
+ const reqIdGen = reqIdGenFactory('id')
53
+
54
+ t.equal(reqIdGen({ headers: { notId: '1337' } }), 'req-1')
55
+ })
56
+
57
+ test('should handle requestIdHeader and increment internal counter if no header was provided', t => {
58
+ t.plan(4)
59
+
60
+ const reqIdGen = reqIdGenFactory('id')
61
+
62
+ t.equal(reqIdGen({ headers: {} }), 'req-1')
63
+ t.equal(reqIdGen({ headers: {} }), 'req-2')
64
+ t.equal(reqIdGen({ headers: { id: '1337' } }), '1337')
65
+ t.equal(reqIdGen({ headers: {} }), 'req-3')
66
+ })
67
+
68
+ test('should use optGenReqId to generate ids', t => {
69
+ t.plan(4)
70
+
71
+ let i = 1
72
+ let gotCalled = false
73
+ function optGenReqId () {
74
+ gotCalled = true
75
+ return (i++).toString(16)
76
+ }
77
+ const reqIdGen = reqIdGenFactory(undefined, optGenReqId)
78
+
79
+ t.equal(gotCalled, false)
80
+ t.equal(reqIdGen(), '1')
81
+ t.equal(gotCalled, true)
82
+ t.equal(reqIdGen(), '2')
83
+ })
84
+
85
+ test('should use optGenReqId to generate ids if requestIdHeader is used but not provided', t => {
86
+ t.plan(4)
87
+
88
+ let i = 1
89
+ let gotCalled = false
90
+ function optGenReqId () {
91
+ gotCalled = true
92
+ return (i++).toString(16)
93
+ }
94
+ const reqIdGen = reqIdGenFactory('reqId', optGenReqId)
95
+
96
+ t.equal(gotCalled, false)
97
+ t.equal(reqIdGen({ headers: {} }), '1')
98
+ t.equal(gotCalled, true)
99
+ t.equal(reqIdGen({ headers: {} }), '2')
100
+ })
101
+
102
+ test('should not use optGenReqId to generate ids if requestIdHeader is used and provided', t => {
103
+ t.plan(2)
104
+
105
+ function optGenReqId () {
106
+ t.fail()
107
+ }
108
+ const reqIdGen = reqIdGenFactory('reqId', optGenReqId)
109
+
110
+ t.equal(reqIdGen({ headers: { reqId: 'r1' } }), 'r1')
111
+ t.equal(reqIdGen({ headers: { reqId: 'r2' } }), 'r2')
112
+ })
113
+
114
+ test('should fallback to use optGenReqId to generate ids if requestIdHeader is sometimes provided', t => {
115
+ t.plan(4)
116
+
117
+ let i = 1
118
+ let gotCalled = false
119
+ function optGenReqId () {
120
+ gotCalled = true
121
+ return (i++).toString(16)
122
+ }
123
+ const reqIdGen = reqIdGenFactory('reqId', optGenReqId)
124
+
125
+ t.equal(reqIdGen({ headers: { reqId: 'r1' } }), 'r1')
126
+ t.equal(gotCalled, false)
127
+ t.equal(reqIdGen({ headers: {} }), '1')
128
+ t.equal(gotCalled, true)
129
+ })