fastify 4.23.2 → 4.24.1

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 (91) hide show
  1. package/README.md +1 -1
  2. package/docs/Guides/Ecosystem.md +6 -0
  3. package/docs/Reference/Hooks.md +1 -0
  4. package/docs/Reference/Plugins.md +1 -1
  5. package/docs/Reference/Reply.md +4 -3
  6. package/docs/Reference/Request.md +3 -2
  7. package/docs/Reference/Server.md +31 -3
  8. package/docs/Reference/Type-Providers.md +2 -2
  9. package/docs/Reference/TypeScript.md +21 -7
  10. package/fastify.d.ts +2 -2
  11. package/fastify.js +8 -1
  12. package/lib/contentTypeParser.js +1 -1
  13. package/lib/reply.js +20 -3
  14. package/lib/reqIdGenFactory.js +15 -9
  15. package/lib/request.js +1 -1
  16. package/lib/route.js +28 -7
  17. package/lib/schemas.js +3 -3
  18. package/lib/warnings.js +3 -1
  19. package/package.json +33 -33
  20. package/test/404s.test.js +31 -39
  21. package/test/async-await.test.js +1 -1
  22. package/test/async-dispose.test.js +21 -0
  23. package/test/build-certificate.js +90 -1
  24. package/test/close-pipelining.test.js +5 -5
  25. package/test/close.test.js +1 -5
  26. package/test/constrained-routes.test.js +127 -3
  27. package/test/custom-http-server.test.js +94 -91
  28. package/test/custom-parser.0.test.js +21 -47
  29. package/test/custom-parser.1.test.js +10 -732
  30. package/test/custom-parser.2.test.js +102 -0
  31. package/test/custom-parser.3.test.js +245 -0
  32. package/test/custom-parser.4.test.js +239 -0
  33. package/test/custom-parser.5.test.js +149 -0
  34. package/test/head.test.js +204 -0
  35. package/test/helper.js +30 -8
  36. package/test/hooks-async.test.js +163 -13
  37. package/test/hooks.on-listen.test.js +7 -6
  38. package/test/hooks.test.js +4 -15
  39. package/test/http2/closing.test.js +7 -15
  40. package/test/https/custom-https-server.test.js +43 -40
  41. package/test/input-validation.js +3 -3
  42. package/test/internals/reply.test.js +33 -4
  43. package/test/listen.1.test.js +101 -0
  44. package/test/listen.2.test.js +103 -0
  45. package/test/listen.3.test.js +87 -0
  46. package/test/listen.4.test.js +164 -0
  47. package/test/listen.deprecated.test.js +3 -9
  48. package/test/logger/instantiation.test.js +347 -0
  49. package/test/logger/logger-test-utils.js +47 -0
  50. package/test/logger/logging.test.js +406 -0
  51. package/test/logger/options.test.js +500 -0
  52. package/test/logger/request.test.js +292 -0
  53. package/test/logger/response.test.js +184 -0
  54. package/test/plugin.1.test.js +249 -0
  55. package/test/plugin.2.test.js +328 -0
  56. package/test/plugin.3.test.js +311 -0
  57. package/test/plugin.4.test.js +416 -0
  58. package/test/reply-code.test.js +64 -0
  59. package/test/reply-trailers.test.js +1 -2
  60. package/test/route.1.test.js +309 -0
  61. package/test/route.2.test.js +99 -0
  62. package/test/route.3.test.js +205 -0
  63. package/test/route.4.test.js +131 -0
  64. package/test/route.5.test.js +230 -0
  65. package/test/route.6.test.js +306 -0
  66. package/test/route.7.test.js +370 -0
  67. package/test/route.8.test.js +142 -0
  68. package/test/stream.1.test.js +108 -0
  69. package/test/stream.2.test.js +119 -0
  70. package/test/stream.3.test.js +192 -0
  71. package/test/stream.4.test.js +223 -0
  72. package/test/stream.5.test.js +194 -0
  73. package/test/trust-proxy.test.js +2 -4
  74. package/test/types/reply.test-d.ts +3 -3
  75. package/test/types/request.test-d.ts +9 -9
  76. package/test/types/type-provider.test-d.ts +89 -0
  77. package/test/types/using.test-d.ts +14 -0
  78. package/test/upgrade.test.js +3 -3
  79. package/types/context.d.ts +9 -2
  80. package/types/instance.d.ts +4 -1
  81. package/types/plugin.d.ts +2 -1
  82. package/types/reply.d.ts +2 -2
  83. package/types/request.d.ts +3 -3
  84. package/types/route.d.ts +5 -5
  85. package/test/listen.test.js +0 -427
  86. package/test/plugin.test.js +0 -1275
  87. package/test/route.test.js +0 -1762
  88. package/test/serial/logger.0.test.js +0 -866
  89. package/test/serial/logger.1.test.js +0 -862
  90. package/test/stream.test.js +0 -816
  91. /package/test/{serial → logger}/tap-parallel-not-ok +0 -0
@@ -0,0 +1,311 @@
1
+ 'use strict'
2
+
3
+ /* eslint no-prototype-builtins: 0 */
4
+
5
+ const t = require('tap')
6
+ const test = t.test
7
+ const Fastify = require('../fastify')
8
+ const sget = require('simple-get').concat
9
+ const fp = require('fastify-plugin')
10
+
11
+ test('if a plugin raises an error and there is not a callback to handle it, the server must not start', t => {
12
+ t.plan(2)
13
+ const fastify = Fastify()
14
+
15
+ fastify.register((instance, opts, done) => {
16
+ done(new Error('err'))
17
+ })
18
+
19
+ fastify.listen({ port: 0 }, err => {
20
+ t.ok(err instanceof Error)
21
+ t.equal(err.message, 'err')
22
+ })
23
+ })
24
+
25
+ test('add hooks after route declaration', t => {
26
+ t.plan(3)
27
+ const fastify = Fastify()
28
+
29
+ function plugin (instance, opts, done) {
30
+ instance.decorateRequest('check', null)
31
+ instance.addHook('onRequest', (req, reply, done) => {
32
+ req.check = {}
33
+ done()
34
+ })
35
+ setImmediate(done)
36
+ }
37
+ fastify.register(fp(plugin))
38
+
39
+ fastify.register((instance, options, done) => {
40
+ instance.addHook('preHandler', function b (req, res, done) {
41
+ req.check.hook2 = true
42
+ done()
43
+ })
44
+
45
+ instance.get('/', (req, reply) => {
46
+ reply.send(req.check)
47
+ })
48
+
49
+ instance.addHook('preHandler', function c (req, res, done) {
50
+ req.check.hook3 = true
51
+ done()
52
+ })
53
+
54
+ done()
55
+ })
56
+
57
+ fastify.addHook('preHandler', function a (req, res, done) {
58
+ req.check.hook1 = true
59
+ done()
60
+ })
61
+
62
+ fastify.listen({ port: 0 }, err => {
63
+ t.error(err)
64
+
65
+ sget({
66
+ method: 'GET',
67
+ url: 'http://localhost:' + fastify.server.address().port
68
+ }, (err, response, body) => {
69
+ t.error(err)
70
+ t.same(JSON.parse(body), { hook1: true, hook2: true, hook3: true })
71
+ fastify.close()
72
+ })
73
+ })
74
+ })
75
+
76
+ test('nested plugins', t => {
77
+ t.plan(5)
78
+
79
+ const fastify = Fastify()
80
+
81
+ t.teardown(fastify.close.bind(fastify))
82
+
83
+ fastify.register(function (fastify, opts, done) {
84
+ fastify.register((fastify, opts, done) => {
85
+ fastify.get('/', function (req, reply) {
86
+ reply.send('I am child 1')
87
+ })
88
+ done()
89
+ }, { prefix: '/child1' })
90
+
91
+ fastify.register((fastify, opts, done) => {
92
+ fastify.get('/', function (req, reply) {
93
+ reply.send('I am child 2')
94
+ })
95
+ done()
96
+ }, { prefix: '/child2' })
97
+
98
+ done()
99
+ }, { prefix: '/parent' })
100
+
101
+ fastify.listen({ port: 0 }, err => {
102
+ t.error(err)
103
+
104
+ sget({
105
+ method: 'GET',
106
+ url: 'http://localhost:' + fastify.server.address().port + '/parent/child1'
107
+ }, (err, response, body) => {
108
+ t.error(err)
109
+ t.same(body.toString(), 'I am child 1')
110
+ })
111
+
112
+ sget({
113
+ method: 'GET',
114
+ url: 'http://localhost:' + fastify.server.address().port + '/parent/child2'
115
+ }, (err, response, body) => {
116
+ t.error(err)
117
+ t.same(body.toString(), 'I am child 2')
118
+ })
119
+ })
120
+ })
121
+
122
+ test('nested plugins awaited', t => {
123
+ t.plan(5)
124
+
125
+ const fastify = Fastify()
126
+
127
+ t.teardown(fastify.close.bind(fastify))
128
+
129
+ fastify.register(async function wrap (fastify, opts) {
130
+ await fastify.register(async function child1 (fastify, opts) {
131
+ fastify.get('/', function (req, reply) {
132
+ reply.send('I am child 1')
133
+ })
134
+ }, { prefix: '/child1' })
135
+
136
+ await fastify.register(async function child2 (fastify, opts) {
137
+ fastify.get('/', function (req, reply) {
138
+ reply.send('I am child 2')
139
+ })
140
+ }, { prefix: '/child2' })
141
+ }, { prefix: '/parent' })
142
+
143
+ fastify.listen({ port: 0 }, err => {
144
+ t.error(err)
145
+
146
+ sget({
147
+ method: 'GET',
148
+ url: 'http://localhost:' + fastify.server.address().port + '/parent/child1'
149
+ }, (err, response, body) => {
150
+ t.error(err)
151
+ t.same(body.toString(), 'I am child 1')
152
+ })
153
+
154
+ sget({
155
+ method: 'GET',
156
+ url: 'http://localhost:' + fastify.server.address().port + '/parent/child2'
157
+ }, (err, response, body) => {
158
+ t.error(err)
159
+ t.same(body.toString(), 'I am child 2')
160
+ })
161
+ })
162
+ })
163
+
164
+ test('plugin metadata - decorators', t => {
165
+ t.plan(1)
166
+ const fastify = Fastify()
167
+
168
+ fastify.decorate('plugin1', true)
169
+ fastify.decorateReply('plugin1', true)
170
+ fastify.decorateRequest('plugin1', true)
171
+
172
+ plugin[Symbol.for('skip-override')] = true
173
+ plugin[Symbol.for('plugin-meta')] = {
174
+ decorators: {
175
+ fastify: ['plugin1'],
176
+ reply: ['plugin1'],
177
+ request: ['plugin1']
178
+ }
179
+ }
180
+
181
+ fastify.register(plugin)
182
+
183
+ fastify.ready(() => {
184
+ t.ok(fastify.plugin)
185
+ })
186
+
187
+ function plugin (instance, opts, done) {
188
+ instance.decorate('plugin', true)
189
+ done()
190
+ }
191
+ })
192
+
193
+ test('plugin metadata - decorators - should throw', t => {
194
+ t.plan(1)
195
+ const fastify = Fastify()
196
+
197
+ fastify.decorate('plugin1', true)
198
+ fastify.decorateReply('plugin1', true)
199
+
200
+ plugin[Symbol.for('skip-override')] = true
201
+ plugin[Symbol.for('plugin-meta')] = {
202
+ decorators: {
203
+ fastify: ['plugin1'],
204
+ reply: ['plugin1'],
205
+ request: ['plugin1']
206
+ }
207
+ }
208
+
209
+ fastify.register(plugin)
210
+ fastify.ready((err) => {
211
+ t.equal(err.message, "The decorator 'plugin1' is not present in Request")
212
+ })
213
+
214
+ function plugin (instance, opts, done) {
215
+ instance.decorate('plugin', true)
216
+ done()
217
+ }
218
+ })
219
+
220
+ test('plugin metadata - decorators - should throw with plugin name', t => {
221
+ t.plan(1)
222
+ const fastify = Fastify()
223
+
224
+ fastify.decorate('plugin1', true)
225
+ fastify.decorateReply('plugin1', true)
226
+
227
+ plugin[Symbol.for('skip-override')] = true
228
+ plugin[Symbol.for('plugin-meta')] = {
229
+ name: 'the-plugin',
230
+ decorators: {
231
+ fastify: ['plugin1'],
232
+ reply: ['plugin1'],
233
+ request: ['plugin1']
234
+ }
235
+ }
236
+
237
+ fastify.register(plugin)
238
+ fastify.ready((err) => {
239
+ t.equal(err.message, "The decorator 'plugin1' required by 'the-plugin' is not present in Request")
240
+ })
241
+
242
+ function plugin (instance, opts, done) {
243
+ instance.decorate('plugin', true)
244
+ done()
245
+ }
246
+ })
247
+
248
+ test('plugin metadata - dependencies', t => {
249
+ t.plan(1)
250
+ const fastify = Fastify()
251
+
252
+ dependency[Symbol.for('skip-override')] = true
253
+ dependency[Symbol.for('plugin-meta')] = {
254
+ name: 'plugin'
255
+ }
256
+
257
+ plugin[Symbol.for('skip-override')] = true
258
+ plugin[Symbol.for('plugin-meta')] = {
259
+ dependencies: ['plugin']
260
+ }
261
+
262
+ fastify.register(dependency)
263
+ fastify.register(plugin)
264
+
265
+ fastify.ready(() => {
266
+ t.pass('everything right')
267
+ })
268
+
269
+ function dependency (instance, opts, done) {
270
+ done()
271
+ }
272
+
273
+ function plugin (instance, opts, done) {
274
+ done()
275
+ }
276
+ })
277
+
278
+ test('plugin metadata - dependencies (nested)', t => {
279
+ t.plan(1)
280
+ const fastify = Fastify()
281
+
282
+ dependency[Symbol.for('skip-override')] = true
283
+ dependency[Symbol.for('plugin-meta')] = {
284
+ name: 'plugin'
285
+ }
286
+
287
+ nested[Symbol.for('skip-override')] = true
288
+ nested[Symbol.for('plugin-meta')] = {
289
+ dependencies: ['plugin']
290
+ }
291
+
292
+ fastify.register(dependency)
293
+ fastify.register(plugin)
294
+
295
+ fastify.ready(() => {
296
+ t.pass('everything right')
297
+ })
298
+
299
+ function dependency (instance, opts, done) {
300
+ done()
301
+ }
302
+
303
+ function plugin (instance, opts, done) {
304
+ instance.register(nested)
305
+ done()
306
+ }
307
+
308
+ function nested (instance, opts, done) {
309
+ done()
310
+ }
311
+ })
@@ -0,0 +1,416 @@
1
+ 'use strict'
2
+
3
+ /* eslint no-prototype-builtins: 0 */
4
+
5
+ const t = require('tap')
6
+ const test = t.test
7
+ const Fastify = require('../fastify')
8
+ const fp = require('fastify-plugin')
9
+ const fakeTimer = require('@sinonjs/fake-timers')
10
+
11
+ test('pluginTimeout', t => {
12
+ t.plan(5)
13
+ const fastify = Fastify({
14
+ pluginTimeout: 10
15
+ })
16
+ fastify.register(function (app, opts, done) {
17
+ // to no call done on purpose
18
+ })
19
+ fastify.ready((err) => {
20
+ t.ok(err)
21
+ t.equal(err.message,
22
+ "fastify-plugin: Plugin did not start in time: 'function (app, opts, done) { -- // to no call done on purpose'. You may have forgotten to call 'done' function or to resolve a Promise")
23
+ t.equal(err.code, 'FST_ERR_PLUGIN_TIMEOUT')
24
+ t.ok(err.cause)
25
+ t.equal(err.cause.code, 'AVV_ERR_READY_TIMEOUT')
26
+ })
27
+ })
28
+
29
+ test('pluginTimeout - named function', t => {
30
+ t.plan(5)
31
+ const fastify = Fastify({
32
+ pluginTimeout: 10
33
+ })
34
+ fastify.register(function nameFunction (app, opts, done) {
35
+ // to no call done on purpose
36
+ })
37
+ fastify.ready((err) => {
38
+ t.ok(err)
39
+ t.equal(err.message,
40
+ "fastify-plugin: Plugin did not start in time: 'nameFunction'. You may have forgotten to call 'done' function or to resolve a Promise")
41
+ t.equal(err.code, 'FST_ERR_PLUGIN_TIMEOUT')
42
+ t.ok(err.cause)
43
+ t.equal(err.cause.code, 'AVV_ERR_READY_TIMEOUT')
44
+ })
45
+ })
46
+
47
+ test('pluginTimeout default', t => {
48
+ t.plan(5)
49
+ const clock = fakeTimer.install({ shouldClearNativeTimers: true })
50
+
51
+ const fastify = Fastify()
52
+ fastify.register(function (app, opts, done) {
53
+ // default time elapsed without calling done
54
+ clock.tick(10000)
55
+ })
56
+
57
+ fastify.ready((err) => {
58
+ t.ok(err)
59
+ t.equal(err.message,
60
+ "fastify-plugin: Plugin did not start in time: 'function (app, opts, done) { -- // default time elapsed without calling done'. You may have forgotten to call 'done' function or to resolve a Promise")
61
+ t.equal(err.code, 'FST_ERR_PLUGIN_TIMEOUT')
62
+ t.ok(err.cause)
63
+ t.equal(err.cause.code, 'AVV_ERR_READY_TIMEOUT')
64
+ })
65
+
66
+ t.teardown(clock.uninstall)
67
+ })
68
+
69
+ test('plugin metadata - version', t => {
70
+ t.plan(1)
71
+ const fastify = Fastify()
72
+
73
+ plugin[Symbol.for('skip-override')] = true
74
+ plugin[Symbol.for('plugin-meta')] = {
75
+ name: 'plugin',
76
+ fastify: '2.0.0'
77
+ }
78
+
79
+ fastify.register(plugin)
80
+
81
+ fastify.ready(() => {
82
+ t.pass('everything right')
83
+ })
84
+
85
+ function plugin (instance, opts, done) {
86
+ done()
87
+ }
88
+ })
89
+
90
+ test('plugin metadata - version range', t => {
91
+ t.plan(1)
92
+ const fastify = Fastify()
93
+
94
+ plugin[Symbol.for('skip-override')] = true
95
+ plugin[Symbol.for('plugin-meta')] = {
96
+ name: 'plugin',
97
+ fastify: '>=2.0.0'
98
+ }
99
+
100
+ fastify.register(plugin)
101
+
102
+ fastify.ready(() => {
103
+ t.pass('everything right')
104
+ })
105
+
106
+ function plugin (instance, opts, done) {
107
+ done()
108
+ }
109
+ })
110
+
111
+ test('plugin metadata - version not matching requirement', t => {
112
+ t.plan(2)
113
+ const fastify = Fastify()
114
+
115
+ plugin[Symbol.for('skip-override')] = true
116
+ plugin[Symbol.for('plugin-meta')] = {
117
+ name: 'plugin',
118
+ fastify: '99.0.0'
119
+ }
120
+
121
+ fastify.register(plugin)
122
+
123
+ fastify.ready((err) => {
124
+ t.ok(err)
125
+ t.equal(err.code, 'FST_ERR_PLUGIN_VERSION_MISMATCH')
126
+ })
127
+
128
+ function plugin (instance, opts, done) {
129
+ done()
130
+ }
131
+ })
132
+
133
+ test('plugin metadata - version not matching requirement 2', t => {
134
+ t.plan(2)
135
+ const fastify = Fastify()
136
+
137
+ plugin[Symbol.for('skip-override')] = true
138
+ plugin[Symbol.for('plugin-meta')] = {
139
+ name: 'plugin',
140
+ fastify: '<=3.0.0'
141
+ }
142
+
143
+ fastify.register(plugin)
144
+
145
+ fastify.ready((err) => {
146
+ t.ok(err)
147
+ t.equal(err.code, 'FST_ERR_PLUGIN_VERSION_MISMATCH')
148
+ })
149
+
150
+ function plugin (instance, opts, done) {
151
+ done()
152
+ }
153
+ })
154
+
155
+ test('plugin metadata - version not matching requirement 3', t => {
156
+ t.plan(2)
157
+ const fastify = Fastify()
158
+
159
+ plugin[Symbol.for('skip-override')] = true
160
+ plugin[Symbol.for('plugin-meta')] = {
161
+ name: 'plugin',
162
+ fastify: '>=99.0.0'
163
+ }
164
+
165
+ fastify.register(plugin)
166
+
167
+ fastify.ready((err) => {
168
+ t.ok(err)
169
+ t.equal(err.code, 'FST_ERR_PLUGIN_VERSION_MISMATCH')
170
+ })
171
+
172
+ function plugin (instance, opts, done) {
173
+ done()
174
+ }
175
+ })
176
+
177
+ test('plugin metadata - release candidate', t => {
178
+ t.plan(2)
179
+ const fastify = Fastify()
180
+ Object.defineProperty(fastify, 'version', {
181
+ value: '99.0.0-rc.1'
182
+ })
183
+
184
+ plugin[Symbol.for('plugin-meta')] = {
185
+ name: 'plugin',
186
+ fastify: '99.x'
187
+ }
188
+
189
+ fastify.register(plugin)
190
+
191
+ fastify.ready((err) => {
192
+ t.error(err)
193
+ t.pass('everything right')
194
+ })
195
+
196
+ function plugin (instance, opts, done) {
197
+ done()
198
+ }
199
+ })
200
+
201
+ test('fastify-rc loads prior version plugins', t => {
202
+ t.plan(2)
203
+ const fastify = Fastify()
204
+ Object.defineProperty(fastify, 'version', {
205
+ value: '99.0.0-rc.1'
206
+ })
207
+
208
+ plugin[Symbol.for('plugin-meta')] = {
209
+ name: 'plugin',
210
+ fastify: '^98.1.0'
211
+ }
212
+ plugin2[Symbol.for('plugin-meta')] = {
213
+ name: 'plugin2',
214
+ fastify: '98.x'
215
+ }
216
+
217
+ fastify.register(plugin)
218
+
219
+ fastify.ready((err) => {
220
+ t.error(err)
221
+ t.pass('everything right')
222
+ })
223
+
224
+ function plugin (instance, opts, done) {
225
+ done()
226
+ }
227
+
228
+ function plugin2 (instance, opts, done) {
229
+ done()
230
+ }
231
+ })
232
+
233
+ test('hasPlugin method exists as a function', t => {
234
+ t.plan(1)
235
+
236
+ const fastify = Fastify()
237
+ t.equal(typeof fastify.hasPlugin, 'function')
238
+ })
239
+
240
+ test('hasPlugin returns true if the specified plugin has been registered', async t => {
241
+ t.plan(4)
242
+
243
+ const fastify = Fastify()
244
+
245
+ function pluginA (fastify, opts, done) {
246
+ t.ok(fastify.hasPlugin('plugin-A'))
247
+ done()
248
+ }
249
+ pluginA[Symbol.for('fastify.display-name')] = 'plugin-A'
250
+ fastify.register(pluginA)
251
+
252
+ fastify.register(function pluginB (fastify, opts, done) {
253
+ t.ok(fastify.hasPlugin('pluginB'))
254
+ done()
255
+ })
256
+
257
+ fastify.register(function (fastify, opts, done) {
258
+ // one line
259
+ t.ok(fastify.hasPlugin('function (fastify, opts, done) { -- // one line'))
260
+ done()
261
+ })
262
+
263
+ await fastify.ready()
264
+
265
+ t.ok(fastify.hasPlugin('fastify'))
266
+ })
267
+
268
+ test('hasPlugin returns false if the specified plugin has not been registered', t => {
269
+ t.plan(1)
270
+
271
+ const fastify = Fastify()
272
+ t.notOk(fastify.hasPlugin('pluginFoo'))
273
+ })
274
+
275
+ test('hasPlugin returns false when using encapsulation', async t => {
276
+ t.plan(25)
277
+
278
+ const fastify = Fastify()
279
+
280
+ fastify.register(function pluginA (fastify, opts, done) {
281
+ t.ok(fastify.hasPlugin('pluginA'))
282
+ t.notOk(fastify.hasPlugin('pluginAA'))
283
+ t.notOk(fastify.hasPlugin('pluginAAA'))
284
+ t.notOk(fastify.hasPlugin('pluginAB'))
285
+ t.notOk(fastify.hasPlugin('pluginB'))
286
+
287
+ fastify.register(function pluginAA (fastify, opts, done) {
288
+ t.notOk(fastify.hasPlugin('pluginA'))
289
+ t.ok(fastify.hasPlugin('pluginAA'))
290
+ t.notOk(fastify.hasPlugin('pluginAAA'))
291
+ t.notOk(fastify.hasPlugin('pluginAB'))
292
+ t.notOk(fastify.hasPlugin('pluginB'))
293
+
294
+ fastify.register(function pluginAAA (fastify, opts, done) {
295
+ t.notOk(fastify.hasPlugin('pluginA'))
296
+ t.notOk(fastify.hasPlugin('pluginAA'))
297
+ t.ok(fastify.hasPlugin('pluginAAA'))
298
+ t.notOk(fastify.hasPlugin('pluginAB'))
299
+ t.notOk(fastify.hasPlugin('pluginB'))
300
+
301
+ done()
302
+ })
303
+
304
+ done()
305
+ })
306
+
307
+ fastify.register(function pluginAB (fastify, opts, done) {
308
+ t.notOk(fastify.hasPlugin('pluginA'))
309
+ t.notOk(fastify.hasPlugin('pluginAA'))
310
+ t.notOk(fastify.hasPlugin('pluginAAA'))
311
+ t.ok(fastify.hasPlugin('pluginAB'))
312
+ t.notOk(fastify.hasPlugin('pluginB'))
313
+
314
+ done()
315
+ })
316
+
317
+ done()
318
+ })
319
+
320
+ fastify.register(function pluginB (fastify, opts, done) {
321
+ t.notOk(fastify.hasPlugin('pluginA'))
322
+ t.notOk(fastify.hasPlugin('pluginAA'))
323
+ t.notOk(fastify.hasPlugin('pluginAAA'))
324
+ t.notOk(fastify.hasPlugin('pluginAB'))
325
+ t.ok(fastify.hasPlugin('pluginB'))
326
+
327
+ done()
328
+ })
329
+
330
+ await fastify.ready()
331
+ })
332
+
333
+ test('hasPlugin returns true when using no encapsulation', async t => {
334
+ t.plan(26)
335
+
336
+ const fastify = Fastify()
337
+
338
+ fastify.register(fp((fastify, opts, done) => {
339
+ t.equal(fastify.pluginName, 'fastify -> plugin-AA')
340
+ t.ok(fastify.hasPlugin('plugin-AA'))
341
+ t.notOk(fastify.hasPlugin('plugin-A'))
342
+ t.notOk(fastify.hasPlugin('plugin-AAA'))
343
+ t.notOk(fastify.hasPlugin('plugin-AB'))
344
+ t.notOk(fastify.hasPlugin('plugin-B'))
345
+
346
+ fastify.register(fp((fastify, opts, done) => {
347
+ t.ok(fastify.hasPlugin('plugin-AA'))
348
+ t.ok(fastify.hasPlugin('plugin-A'))
349
+ t.notOk(fastify.hasPlugin('plugin-AAA'))
350
+ t.notOk(fastify.hasPlugin('plugin-AB'))
351
+ t.notOk(fastify.hasPlugin('plugin-B'))
352
+
353
+ fastify.register(fp((fastify, opts, done) => {
354
+ t.ok(fastify.hasPlugin('plugin-AA'))
355
+ t.ok(fastify.hasPlugin('plugin-A'))
356
+ t.ok(fastify.hasPlugin('plugin-AAA'))
357
+ t.notOk(fastify.hasPlugin('plugin-AB'))
358
+ t.notOk(fastify.hasPlugin('plugin-B'))
359
+
360
+ done()
361
+ }, { name: 'plugin-AAA' }))
362
+
363
+ done()
364
+ }, { name: 'plugin-A' }))
365
+
366
+ fastify.register(fp((fastify, opts, done) => {
367
+ t.ok(fastify.hasPlugin('plugin-AA'))
368
+ t.ok(fastify.hasPlugin('plugin-A'))
369
+ t.ok(fastify.hasPlugin('plugin-AAA'))
370
+ t.ok(fastify.hasPlugin('plugin-AB'))
371
+ t.notOk(fastify.hasPlugin('plugin-B'))
372
+
373
+ done()
374
+ }, { name: 'plugin-AB' }))
375
+
376
+ done()
377
+ }, { name: 'plugin-AA' }))
378
+
379
+ fastify.register(fp((fastify, opts, done) => {
380
+ t.ok(fastify.hasPlugin('plugin-AA'))
381
+ t.ok(fastify.hasPlugin('plugin-A'))
382
+ t.ok(fastify.hasPlugin('plugin-AAA'))
383
+ t.ok(fastify.hasPlugin('plugin-AB'))
384
+ t.ok(fastify.hasPlugin('plugin-B'))
385
+
386
+ done()
387
+ }, { name: 'plugin-B' }))
388
+
389
+ await fastify.ready()
390
+ })
391
+
392
+ test('hasPlugin returns true when using encapsulation', async t => {
393
+ t.plan(2)
394
+
395
+ const fastify = Fastify()
396
+
397
+ const pluginCallback = function (server, options, done) {
398
+ done()
399
+ }
400
+ const pluginName = 'awesome-plugin'
401
+ const plugin = fp(pluginCallback, { name: pluginName })
402
+
403
+ fastify.register(plugin)
404
+
405
+ fastify.register(async (server) => {
406
+ t.ok(server.hasPlugin(pluginName))
407
+ })
408
+
409
+ fastify.register(async function foo (server) {
410
+ server.register(async function bar (server) {
411
+ t.ok(server.hasPlugin(pluginName))
412
+ })
413
+ })
414
+
415
+ await fastify.ready()
416
+ })