fastify 5.0.0 → 5.2.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.
- package/.borp.yaml +3 -0
- package/.vscode/settings.json +22 -0
- package/README.md +12 -7
- package/docs/Guides/Database.md +15 -15
- package/docs/Guides/Detecting-When-Clients-Abort.md +28 -28
- package/docs/Guides/Ecosystem.md +14 -15
- package/docs/Guides/Index.md +1 -1
- package/docs/Guides/Migration-Guide-V4.md +11 -11
- package/docs/Guides/Migration-Guide-V5.md +133 -9
- package/docs/Guides/Plugins-Guide.md +1 -1
- package/docs/Guides/Prototype-Poisoning.md +3 -3
- package/docs/Guides/Recommendations.md +9 -9
- package/docs/Guides/Serverless.md +5 -5
- package/docs/Guides/Testing.md +58 -57
- package/docs/Guides/Write-Plugin.md +2 -2
- package/docs/Guides/Write-Type-Provider.md +3 -3
- package/docs/Reference/ContentTypeParser.md +4 -4
- package/docs/Reference/Decorators.md +2 -2
- package/docs/Reference/Errors.md +3 -3
- package/docs/Reference/Hooks.md +7 -7
- package/docs/Reference/LTS.md +8 -0
- package/docs/Reference/Logging.md +5 -4
- package/docs/Reference/Reply.md +55 -58
- package/docs/Reference/Request.md +49 -42
- package/docs/Reference/Routes.md +16 -13
- package/docs/Reference/Server.md +32 -28
- package/docs/Reference/TypeScript.md +9 -9
- package/docs/Reference/Validation-and-Serialization.md +5 -5
- package/examples/typescript-server.ts +1 -1
- package/fastify.d.ts +14 -5
- package/fastify.js +8 -6
- package/lib/contentTypeParser.js +9 -7
- package/lib/context.js +1 -2
- package/lib/error-handler.js +9 -9
- package/lib/errors.js +1 -1
- package/lib/fourOhFour.js +1 -1
- package/lib/hooks.js +4 -1
- package/lib/{logger.js → logger-factory.js} +70 -122
- package/lib/logger-pino.js +68 -0
- package/lib/pluginOverride.js +1 -1
- package/lib/pluginUtils.js +2 -2
- package/lib/reply.js +4 -5
- package/lib/request.js +16 -9
- package/lib/route.js +23 -22
- package/lib/validation.js +2 -2
- package/package.json +13 -15
- package/test/404s.test.js +675 -629
- package/test/500s.test.js +72 -63
- package/test/{allowUnsafeRegex.test.js → allow-unsafe-regex.test.js} +30 -26
- package/test/als.test.js +48 -45
- package/test/async-await.test.js +148 -134
- package/test/async-dispose.test.js +4 -5
- package/test/async_hooks.test.js +30 -28
- package/test/{bodyLimit.test.js → body-limit.test.js} +61 -58
- package/test/buffer.test.js +9 -10
- package/test/build/error-serializer.test.js +3 -4
- package/test/build/version.test.js +2 -3
- package/test/build-certificate.js +1 -1
- package/test/bundler/README.md +5 -5
- package/test/bundler/esbuild/bundler-test.js +10 -9
- package/test/bundler/webpack/bundler-test.js +10 -9
- package/test/case-insensitive.test.js +31 -28
- package/test/chainable.test.js +4 -5
- package/test/check.test.js +8 -10
- package/test/{childLoggerFactory.test.js → child-logger-factory.test.js} +56 -19
- package/test/client-timeout.test.js +5 -5
- package/test/close-pipelining.test.js +6 -8
- package/test/conditional-pino.test.js +47 -0
- package/test/{connectionTimeout.test.js → connection-timeout.test.js} +10 -11
- package/test/constrained-routes.test.js +243 -236
- package/test/content-length.test.js +53 -68
- package/test/content-parser.test.js +186 -158
- package/test/content-type.test.js +8 -9
- package/test/context-config.test.js +44 -54
- package/test/custom-http-server.test.js +16 -20
- package/test/custom-parser.5.test.js +32 -32
- package/test/diagnostics-channel/404.test.js +15 -15
- package/test/diagnostics-channel/async-delay-request.test.js +25 -25
- package/test/diagnostics-channel/async-request.test.js +24 -24
- package/test/diagnostics-channel/error-before-handler.test.js +4 -5
- package/test/diagnostics-channel/error-request.test.js +19 -19
- package/test/diagnostics-channel/error-status.test.js +8 -8
- package/test/diagnostics-channel/init.test.js +6 -7
- package/test/diagnostics-channel/sync-delay-request.test.js +16 -16
- package/test/diagnostics-channel/sync-request-reply.test.js +16 -16
- package/test/diagnostics-channel/sync-request.test.js +19 -19
- package/test/encapsulated-child-logger-factory.test.js +8 -8
- package/test/encapsulated-error-handler.test.js +20 -20
- package/test/esm/errorCodes.test.mjs +5 -5
- package/test/esm/esm.test.mjs +3 -3
- package/test/esm/named-exports.mjs +3 -3
- package/test/esm/other.mjs +2 -2
- package/test/fastify-instance.test.js +33 -34
- package/test/{findRoute.test.js → find-route.test.js} +11 -10
- package/test/fluent-schema.test.js +33 -36
- package/test/handler-context.test.js +11 -11
- package/test/has-route.test.js +12 -15
- package/test/header-overflow.test.js +13 -12
- package/test/hooks.on-ready.test.js +2 -2
- package/test/hooks.test.js +25 -25
- package/test/http-methods/copy.test.js +22 -24
- package/test/http-methods/custom-http-methods.test.js +24 -21
- package/test/http-methods/get.test.js +97 -84
- package/test/http-methods/head.test.js +63 -57
- package/test/http-methods/lock.test.js +21 -20
- package/test/http-methods/mkcalendar.test.js +31 -27
- package/test/http-methods/mkcol.test.js +10 -10
- package/test/http-methods/move.test.js +11 -11
- package/test/http-methods/propfind.test.js +32 -27
- package/test/http-methods/proppatch.test.js +21 -19
- package/test/http-methods/report.test.js +32 -27
- package/test/http-methods/search.test.js +52 -47
- package/test/http-methods/trace.test.js +3 -4
- package/test/http-methods/unlock.test.js +10 -10
- package/test/http2/closing.test.js +50 -58
- package/test/http2/constraint.test.js +47 -50
- package/test/http2/head.test.js +18 -19
- package/test/http2/missing-http2-module.test.js +4 -5
- package/test/http2/plain.test.js +31 -31
- package/test/http2/secure-with-fallback.test.js +61 -61
- package/test/http2/secure.test.js +28 -31
- package/test/http2/unknown-http-method.test.js +13 -14
- package/test/https/custom-https-server.test.js +6 -7
- package/test/https/https.test.js +78 -78
- package/test/imports.test.js +5 -6
- package/test/internals/all.test.js +8 -11
- package/test/internals/{contentTypeParser.test.js → content-type-parser.test.js} +5 -6
- package/test/internals/context.test.js +9 -11
- package/test/internals/decorator.test.js +20 -21
- package/test/internals/errors.test.js +427 -427
- package/test/internals/{handleRequest.test.js → handle-request.test.js} +53 -42
- package/test/internals/{hookRunner.test.js → hook-runner.test.js} +99 -100
- package/test/internals/hooks.test.js +31 -35
- package/test/internals/{initialConfig.test.js → initial-config.test.js} +92 -80
- package/test/internals/logger.test.js +28 -28
- package/test/internals/plugin.test.js +17 -18
- package/test/internals/reply-serialize.test.js +106 -106
- package/test/internals/reply.test.js +620 -585
- package/test/internals/{reqIdGenFactory.test.js → req-id-gen-factory.test.js} +31 -31
- package/test/internals/request-validate.test.js +218 -221
- package/test/internals/request.test.js +225 -107
- package/test/internals/server.test.js +15 -12
- package/test/internals/validation.test.js +35 -36
- package/test/{keepAliveTimeout.test.js → keep-alive-timeout.test.js} +9 -10
- package/test/listen.5.test.js +9 -9
- package/test/{maxRequestsPerSocket.test.js → max-requests-per-socket.test.js} +30 -30
- package/test/middleware.test.js +4 -5
- package/test/noop-set.test.js +5 -5
- package/test/post-empty-body.test.js +18 -11
- package/test/pretty-print.test.js +59 -49
- package/test/proto-poisoning.test.js +42 -37
- package/test/reply-code.test.js +34 -32
- package/test/{reply-earlyHints.test.js → reply-early-hints.test.js} +21 -19
- package/test/request-error.test.js +122 -0
- package/test/request-header-host.test.js +339 -0
- package/test/request-id.test.js +31 -25
- package/test/{requestTimeout.test.js → request-timeout.test.js} +11 -11
- package/test/route.1.test.js +79 -72
- package/test/route.2.test.js +17 -16
- package/test/route.3.test.js +32 -27
- package/test/route.4.test.js +21 -25
- package/test/route.5.test.js +45 -64
- package/test/route.6.test.js +70 -89
- package/test/route.7.test.js +61 -65
- package/test/route.8.test.js +80 -18
- package/test/router-options.test.js +80 -77
- package/test/same-shape.test.js +5 -5
- package/test/schema-examples.test.js +72 -38
- package/test/serialize-response.test.js +9 -10
- package/test/server.test.js +75 -78
- package/test/set-error-handler.test.js +2 -3
- package/test/stream-serializers.test.js +10 -7
- package/test/sync-routes.test.js +18 -18
- package/test/test-reporter.mjs +68 -0
- package/test/trust-proxy.test.js +51 -45
- package/test/type-provider.test.js +8 -6
- package/test/types/content-type-parser.test-d.ts +1 -1
- package/test/types/fastify.test-d.ts +16 -4
- package/test/types/hooks.test-d.ts +2 -1
- package/test/types/instance.test-d.ts +13 -13
- package/test/types/logger.test-d.ts +2 -2
- package/test/types/plugin.test-d.ts +17 -9
- package/test/types/register.test-d.ts +22 -6
- package/test/types/reply.test-d.ts +1 -1
- package/test/types/route.test-d.ts +34 -4
- package/test/types/serverFactory.test-d.ts +1 -1
- package/test/types/type-provider.test-d.ts +1 -1
- package/test/url-rewriting.test.js +35 -38
- package/test/{useSemicolonDelimiter.test.js → use-semicolon-delimiter.test.js} +30 -30
- package/test/validation-error-handling.test.js +259 -285
- package/test/versioned-routes.test.js +126 -113
- package/test/web-api.test.js +48 -37
- package/test/{wrapThenable.test.js → wrap-thenable.test.js} +10 -9
- package/types/hooks.d.ts +2 -1
- package/types/instance.d.ts +9 -2
- package/types/register.d.ts +12 -3
- package/types/reply.d.ts +1 -1
- package/types/request.d.ts +2 -6
- package/types/serverFactory.d.ts +3 -3
- package/types/utils.d.ts +13 -5
- package/test/types/import.js +0 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { test } = require('
|
|
3
|
+
const { test } = require('node:test')
|
|
4
4
|
const Fastify = require('..')
|
|
5
5
|
|
|
6
6
|
// Because of how error handlers wrap things, following the control flow can be tricky
|
|
@@ -13,7 +13,7 @@ test('encapsulates an asynchronous error handler', async t => {
|
|
|
13
13
|
fastify.register(async function (fastify) {
|
|
14
14
|
fastify.setErrorHandler(async function a (err) {
|
|
15
15
|
// 3. the inner error handler catches the error, and throws a new error
|
|
16
|
-
t.
|
|
16
|
+
t.assert.strictEqual(err.message, 'from_endpoint')
|
|
17
17
|
throw new Error('from_inner')
|
|
18
18
|
})
|
|
19
19
|
fastify.get('/encapsulated', async () => {
|
|
@@ -24,7 +24,7 @@ test('encapsulates an asynchronous error handler', async t => {
|
|
|
24
24
|
|
|
25
25
|
fastify.setErrorHandler(async function b (err) {
|
|
26
26
|
// 4. the outer error handler catches the error thrown by the inner error handler
|
|
27
|
-
t.
|
|
27
|
+
t.assert.strictEqual(err.message, 'from_inner')
|
|
28
28
|
// 5. the outer error handler throws a new error
|
|
29
29
|
throw new Error('from_outer')
|
|
30
30
|
})
|
|
@@ -32,7 +32,7 @@ test('encapsulates an asynchronous error handler', async t => {
|
|
|
32
32
|
// 1. the endpoint is called
|
|
33
33
|
const res = await fastify.inject('/encapsulated')
|
|
34
34
|
// 6. the default error handler returns the error from the outer error handler
|
|
35
|
-
t.
|
|
35
|
+
t.assert.strictEqual(res.json().message, 'from_outer')
|
|
36
36
|
})
|
|
37
37
|
|
|
38
38
|
// See discussion in https://github.com/fastify/fastify/pull/5222#discussion_r1432573655
|
|
@@ -43,7 +43,7 @@ test('encapsulates a synchronous error handler', async t => {
|
|
|
43
43
|
fastify.register(async function (fastify) {
|
|
44
44
|
fastify.setErrorHandler(function a (err) {
|
|
45
45
|
// 3. the inner error handler catches the error, and throws a new error
|
|
46
|
-
t.
|
|
46
|
+
t.assert.strictEqual(err.message, 'from_endpoint')
|
|
47
47
|
throw new Error('from_inner')
|
|
48
48
|
})
|
|
49
49
|
fastify.get('/encapsulated', async () => {
|
|
@@ -54,7 +54,7 @@ test('encapsulates a synchronous error handler', async t => {
|
|
|
54
54
|
|
|
55
55
|
fastify.setErrorHandler(async function b (err) {
|
|
56
56
|
// 4. the outer error handler catches the error thrown by the inner error handler
|
|
57
|
-
t.
|
|
57
|
+
t.assert.strictEqual(err.message, 'from_inner')
|
|
58
58
|
// 5. the outer error handler throws a new error
|
|
59
59
|
throw new Error('from_outer')
|
|
60
60
|
})
|
|
@@ -62,7 +62,7 @@ test('encapsulates a synchronous error handler', async t => {
|
|
|
62
62
|
// 1. the endpoint is called
|
|
63
63
|
const res = await fastify.inject('/encapsulated')
|
|
64
64
|
// 6. the default error handler returns the error from the outer error handler
|
|
65
|
-
t.
|
|
65
|
+
t.assert.strictEqual(res.json().message, 'from_outer')
|
|
66
66
|
})
|
|
67
67
|
|
|
68
68
|
test('onError hook nested', async t => {
|
|
@@ -72,7 +72,7 @@ test('onError hook nested', async t => {
|
|
|
72
72
|
fastify.register(async function (fastify) {
|
|
73
73
|
fastify.setErrorHandler(async function a (err) {
|
|
74
74
|
// 4. the inner error handler catches the error, and throws a new error
|
|
75
|
-
t.
|
|
75
|
+
t.assert.strictEqual(err.message, 'from_endpoint')
|
|
76
76
|
throw new Error('from_inner')
|
|
77
77
|
})
|
|
78
78
|
fastify.get('/encapsulated', async () => {
|
|
@@ -83,20 +83,20 @@ test('onError hook nested', async t => {
|
|
|
83
83
|
|
|
84
84
|
fastify.setErrorHandler(async function b (err) {
|
|
85
85
|
// 5. the outer error handler catches the error thrown by the inner error handler
|
|
86
|
-
t.
|
|
86
|
+
t.assert.strictEqual(err.message, 'from_inner')
|
|
87
87
|
// 6. the outer error handler throws a new error
|
|
88
88
|
throw new Error('from_outer')
|
|
89
89
|
})
|
|
90
90
|
|
|
91
91
|
fastify.addHook('onError', async function (request, reply, err) {
|
|
92
92
|
// 3. the hook receives the error
|
|
93
|
-
t.
|
|
93
|
+
t.assert.strictEqual(err.message, 'from_endpoint')
|
|
94
94
|
})
|
|
95
95
|
|
|
96
96
|
// 1. the endpoint is called
|
|
97
97
|
const res = await fastify.inject('/encapsulated')
|
|
98
98
|
// 7. the default error handler returns the error from the outer error handler
|
|
99
|
-
t.
|
|
99
|
+
t.assert.strictEqual(res.json().message, 'from_outer')
|
|
100
100
|
})
|
|
101
101
|
|
|
102
102
|
// See https://github.com/fastify/fastify/issues/5220
|
|
@@ -107,7 +107,7 @@ test('encapuslates an error handler, for errors thrown in hooks', async t => {
|
|
|
107
107
|
fastify.register(async function (fastify) {
|
|
108
108
|
fastify.setErrorHandler(function a (err) {
|
|
109
109
|
// 3. the inner error handler catches the error, and throws a new error
|
|
110
|
-
t.
|
|
110
|
+
t.assert.strictEqual(err.message, 'from_hook')
|
|
111
111
|
throw new Error('from_inner')
|
|
112
112
|
})
|
|
113
113
|
fastify.addHook('onRequest', async () => {
|
|
@@ -119,7 +119,7 @@ test('encapuslates an error handler, for errors thrown in hooks', async t => {
|
|
|
119
119
|
|
|
120
120
|
fastify.setErrorHandler(function b (err) {
|
|
121
121
|
// 4. the outer error handler catches the error thrown by the inner error handler
|
|
122
|
-
t.
|
|
122
|
+
t.assert.strictEqual(err.message, 'from_inner')
|
|
123
123
|
// 5. the outer error handler throws a new error
|
|
124
124
|
throw new Error('from_outer')
|
|
125
125
|
})
|
|
@@ -127,7 +127,7 @@ test('encapuslates an error handler, for errors thrown in hooks', async t => {
|
|
|
127
127
|
// 1. the endpoint is called
|
|
128
128
|
const res = await fastify.inject('/encapsulated')
|
|
129
129
|
// 6. the default error handler returns the error from the outer error handler
|
|
130
|
-
t.
|
|
130
|
+
t.assert.strictEqual(res.json().message, 'from_outer')
|
|
131
131
|
})
|
|
132
132
|
|
|
133
133
|
// See https://github.com/fastify/fastify/issues/5220
|
|
@@ -153,7 +153,7 @@ test('encapuslates many synchronous error handlers that rethrow errors', async t
|
|
|
153
153
|
} else if (depth === 0) {
|
|
154
154
|
fastify.setErrorHandler(function a (err) {
|
|
155
155
|
// 3. innermost error handler catches the error, and throws a new error
|
|
156
|
-
t.
|
|
156
|
+
t.assert.strictEqual(err.message, 'from_route')
|
|
157
157
|
throw new Error(`from_handler_${depth}`)
|
|
158
158
|
})
|
|
159
159
|
fastify.get('/encapsulated', async () => {
|
|
@@ -163,7 +163,7 @@ test('encapuslates many synchronous error handlers that rethrow errors', async t
|
|
|
163
163
|
} else {
|
|
164
164
|
fastify.setErrorHandler(function d (err) {
|
|
165
165
|
// 4 to {DEPTH+4}. error handlers each catch errors, and then throws a new error
|
|
166
|
-
t.
|
|
166
|
+
t.assert.strictEqual(err.message, `from_handler_${depth - 1}`)
|
|
167
167
|
throw new Error(`from_handler_${depth}`)
|
|
168
168
|
})
|
|
169
169
|
|
|
@@ -179,7 +179,7 @@ test('encapuslates many synchronous error handlers that rethrow errors', async t
|
|
|
179
179
|
// 1. the endpoint is called
|
|
180
180
|
const res = await fastify.inject('/encapsulated')
|
|
181
181
|
// {DEPTH+5}. the default error handler returns the error from the outermost error handler
|
|
182
|
-
t.
|
|
182
|
+
t.assert.strictEqual(res.json().message, `from_handler_${DEPTH}`)
|
|
183
183
|
})
|
|
184
184
|
|
|
185
185
|
// See https://github.com/fastify/fastify/issues/5220
|
|
@@ -207,7 +207,7 @@ test('encapuslates many asynchronous error handlers that rethrow errors', async
|
|
|
207
207
|
} else if (depth === 0) {
|
|
208
208
|
fastify.setErrorHandler(async function a (err) {
|
|
209
209
|
// 3. innermost error handler catches the error, and throws a new error
|
|
210
|
-
t.
|
|
210
|
+
t.assert.strictEqual(err.message, 'from_route')
|
|
211
211
|
throw new Error(`from_handler_${depth}`)
|
|
212
212
|
})
|
|
213
213
|
fastify.get('/encapsulated', async () => {
|
|
@@ -217,7 +217,7 @@ test('encapuslates many asynchronous error handlers that rethrow errors', async
|
|
|
217
217
|
} else {
|
|
218
218
|
fastify.setErrorHandler(async function m (err) {
|
|
219
219
|
// 4 to {DEPTH+4}. error handlers each catch errors, and then throws a new error
|
|
220
|
-
t.
|
|
220
|
+
t.assert.strictEqual(err.message, `from_handler_${depth - 1}`)
|
|
221
221
|
throw new Error(`from_handler_${depth}`)
|
|
222
222
|
})
|
|
223
223
|
|
|
@@ -233,5 +233,5 @@ test('encapuslates many asynchronous error handlers that rethrow errors', async
|
|
|
233
233
|
// 1. the endpoint is called
|
|
234
234
|
const res = await fastify.inject('/encapsulated')
|
|
235
235
|
// {DEPTH+5}. the default error handler returns the error from the outermost error handler
|
|
236
|
-
t.
|
|
236
|
+
t.assert.strictEqual(res.json().message, `from_handler_${DEPTH}`)
|
|
237
237
|
})
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { errorCodes } from '../../fastify.js'
|
|
2
|
-
import
|
|
2
|
+
import { test } from 'node:test'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
test('errorCodes in ESM', async t => {
|
|
5
5
|
// test a custom fastify error using errorCodes with ESM
|
|
6
6
|
const customError = errorCodes.FST_ERR_VALIDATION('custom error message')
|
|
7
|
-
t.ok(typeof customError !== 'undefined')
|
|
8
|
-
t.ok(customError instanceof errorCodes.FST_ERR_VALIDATION)
|
|
9
|
-
t.
|
|
7
|
+
t.assert.ok(typeof customError !== 'undefined')
|
|
8
|
+
t.assert.ok(customError instanceof errorCodes.FST_ERR_VALIDATION)
|
|
9
|
+
t.assert.strictEqual(customError.message, 'custom error message')
|
|
10
10
|
})
|
package/test/esm/esm.test.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { test } from 'node:test'
|
|
2
2
|
import Fastify from '../../fastify.js'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
test('esm support', async t => {
|
|
5
5
|
const fastify = Fastify()
|
|
6
6
|
|
|
7
7
|
fastify.register(import('./plugin.mjs'), { foo: 'bar' })
|
|
@@ -9,5 +9,5 @@ t.test('esm support', async t => {
|
|
|
9
9
|
|
|
10
10
|
await fastify.ready()
|
|
11
11
|
|
|
12
|
-
t.
|
|
12
|
+
t.assert.strictEqual(fastify.foo, 'bar')
|
|
13
13
|
})
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { test } from 'node:test'
|
|
2
2
|
import { fastify } from '../../fastify.js'
|
|
3
3
|
|
|
4
4
|
// This test is executed in index.test.js
|
|
5
|
-
|
|
5
|
+
test('named exports support', async t => {
|
|
6
6
|
const app = fastify()
|
|
7
7
|
|
|
8
8
|
app.register(import('./plugin.mjs'), { foo: 'bar' })
|
|
@@ -10,5 +10,5 @@ t.test('named exports support', async t => {
|
|
|
10
10
|
|
|
11
11
|
await app.ready()
|
|
12
12
|
|
|
13
|
-
t.
|
|
13
|
+
t.assert.strictEqual(app.foo, 'bar')
|
|
14
14
|
})
|
package/test/esm/other.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const test = t.test
|
|
3
|
+
const { test } = require('node:test')
|
|
5
4
|
const Fastify = require('..')
|
|
6
5
|
const os = require('node:os')
|
|
7
6
|
|
|
@@ -13,7 +12,7 @@ const {
|
|
|
13
12
|
|
|
14
13
|
test('root fastify instance is an object', t => {
|
|
15
14
|
t.plan(1)
|
|
16
|
-
t.
|
|
15
|
+
t.assert.strictEqual(typeof Fastify(), 'object')
|
|
17
16
|
})
|
|
18
17
|
|
|
19
18
|
test('fastify instance should contains ajv options', t => {
|
|
@@ -25,7 +24,7 @@ test('fastify instance should contains ajv options', t => {
|
|
|
25
24
|
}
|
|
26
25
|
}
|
|
27
26
|
})
|
|
28
|
-
t.
|
|
27
|
+
t.assert.deepStrictEqual(fastify[kOptions].ajv, {
|
|
29
28
|
customOptions: {
|
|
30
29
|
nullable: false
|
|
31
30
|
},
|
|
@@ -43,7 +42,7 @@ test('fastify instance should contains ajv options.plugins nested arrays', t =>
|
|
|
43
42
|
plugins: [[]]
|
|
44
43
|
}
|
|
45
44
|
})
|
|
46
|
-
t.
|
|
45
|
+
t.assert.deepStrictEqual(fastify[kOptions].ajv, {
|
|
47
46
|
customOptions: {
|
|
48
47
|
nullable: false
|
|
49
48
|
},
|
|
@@ -53,7 +52,7 @@ test('fastify instance should contains ajv options.plugins nested arrays', t =>
|
|
|
53
52
|
|
|
54
53
|
test('fastify instance get invalid ajv options', t => {
|
|
55
54
|
t.plan(1)
|
|
56
|
-
t.throws(() => Fastify({
|
|
55
|
+
t.assert.throws(() => Fastify({
|
|
57
56
|
ajv: {
|
|
58
57
|
customOptions: 8
|
|
59
58
|
}
|
|
@@ -62,7 +61,7 @@ test('fastify instance get invalid ajv options', t => {
|
|
|
62
61
|
|
|
63
62
|
test('fastify instance get invalid ajv options.plugins', t => {
|
|
64
63
|
t.plan(1)
|
|
65
|
-
t.throws(() => Fastify({
|
|
64
|
+
t.assert.throws(() => Fastify({
|
|
66
65
|
ajv: {
|
|
67
66
|
customOptions: {},
|
|
68
67
|
plugins: 8
|
|
@@ -73,9 +72,9 @@ test('fastify instance get invalid ajv options.plugins', t => {
|
|
|
73
72
|
test('fastify instance should contain default errorHandler', t => {
|
|
74
73
|
t.plan(3)
|
|
75
74
|
const fastify = Fastify()
|
|
76
|
-
t.ok(fastify[kErrorHandler].func instanceof Function)
|
|
77
|
-
t.
|
|
78
|
-
t.
|
|
75
|
+
t.assert.ok(fastify[kErrorHandler].func instanceof Function)
|
|
76
|
+
t.assert.deepStrictEqual(fastify.errorHandler, fastify[kErrorHandler].func)
|
|
77
|
+
t.assert.deepStrictEqual(Object.getOwnPropertyDescriptor(fastify, 'errorHandler').set, undefined)
|
|
79
78
|
})
|
|
80
79
|
|
|
81
80
|
test('errorHandler in plugin should be separate from the external one', async t => {
|
|
@@ -89,24 +88,24 @@ test('errorHandler in plugin should be separate from the external one', async t
|
|
|
89
88
|
|
|
90
89
|
instance.setErrorHandler(inPluginErrHandler)
|
|
91
90
|
|
|
92
|
-
t.
|
|
93
|
-
t.
|
|
91
|
+
t.assert.notDeepStrictEqual(instance.errorHandler, fastify.errorHandler)
|
|
92
|
+
t.assert.strictEqual(instance.errorHandler.name, 'bound inPluginErrHandler')
|
|
94
93
|
|
|
95
94
|
done()
|
|
96
95
|
})
|
|
97
96
|
|
|
98
97
|
await fastify.ready()
|
|
99
98
|
|
|
100
|
-
t.ok(fastify[kErrorHandler].func instanceof Function)
|
|
101
|
-
t.
|
|
99
|
+
t.assert.ok(fastify[kErrorHandler].func instanceof Function)
|
|
100
|
+
t.assert.deepStrictEqual(fastify.errorHandler, fastify[kErrorHandler].func)
|
|
102
101
|
})
|
|
103
102
|
|
|
104
103
|
test('fastify instance should contain default childLoggerFactory', t => {
|
|
105
104
|
t.plan(3)
|
|
106
105
|
const fastify = Fastify()
|
|
107
|
-
t.ok(fastify[kChildLoggerFactory] instanceof Function)
|
|
108
|
-
t.
|
|
109
|
-
t.
|
|
106
|
+
t.assert.ok(fastify[kChildLoggerFactory] instanceof Function)
|
|
107
|
+
t.assert.deepStrictEqual(fastify.childLoggerFactory, fastify[kChildLoggerFactory])
|
|
108
|
+
t.assert.deepStrictEqual(Object.getOwnPropertyDescriptor(fastify, 'childLoggerFactory').set, undefined)
|
|
110
109
|
})
|
|
111
110
|
|
|
112
111
|
test('childLoggerFactory in plugin should be separate from the external one', async t => {
|
|
@@ -120,16 +119,16 @@ test('childLoggerFactory in plugin should be separate from the external one', as
|
|
|
120
119
|
|
|
121
120
|
instance.setChildLoggerFactory(inPluginLoggerFactory)
|
|
122
121
|
|
|
123
|
-
t.
|
|
124
|
-
t.
|
|
122
|
+
t.assert.notDeepStrictEqual(instance.childLoggerFactory, fastify.childLoggerFactory)
|
|
123
|
+
t.assert.strictEqual(instance.childLoggerFactory.name, 'inPluginLoggerFactory')
|
|
125
124
|
|
|
126
125
|
done()
|
|
127
126
|
})
|
|
128
127
|
|
|
129
128
|
await fastify.ready()
|
|
130
129
|
|
|
131
|
-
t.ok(fastify[kChildLoggerFactory] instanceof Function)
|
|
132
|
-
t.
|
|
130
|
+
t.assert.ok(fastify[kChildLoggerFactory] instanceof Function)
|
|
131
|
+
t.assert.deepStrictEqual(fastify.childLoggerFactory, fastify[kChildLoggerFactory])
|
|
133
132
|
})
|
|
134
133
|
|
|
135
134
|
test('ready should resolve in order when called multiply times (promises only)', async (t) => {
|
|
@@ -142,7 +141,7 @@ test('ready should resolve in order when called multiply times (promises only)',
|
|
|
142
141
|
|
|
143
142
|
await Promise.all(promises)
|
|
144
143
|
|
|
145
|
-
t.
|
|
144
|
+
t.assert.deepStrictEqual(result, expectedOrder, 'Should resolve in order')
|
|
146
145
|
})
|
|
147
146
|
|
|
148
147
|
test('ready should reject in order when called multiply times (promises only)', async (t) => {
|
|
@@ -159,7 +158,7 @@ test('ready should reject in order when called multiply times (promises only)',
|
|
|
159
158
|
|
|
160
159
|
await Promise.all(promises)
|
|
161
160
|
|
|
162
|
-
t.
|
|
161
|
+
t.assert.deepStrictEqual(result, expectedOrder, 'Should resolve in order')
|
|
163
162
|
})
|
|
164
163
|
|
|
165
164
|
test('ready should reject in order when called multiply times (callbacks only)', async (t) => {
|
|
@@ -174,10 +173,10 @@ test('ready should reject in order when called multiply times (callbacks only)',
|
|
|
174
173
|
expectedOrder.map((id) => app.ready(() => result.push(id)))
|
|
175
174
|
|
|
176
175
|
await app.ready().catch(err => {
|
|
177
|
-
t.
|
|
176
|
+
t.assert.strictEqual(err.message, 'test')
|
|
178
177
|
})
|
|
179
178
|
|
|
180
|
-
t.
|
|
179
|
+
t.assert.deepStrictEqual(result, expectedOrder, 'Should resolve in order')
|
|
181
180
|
})
|
|
182
181
|
|
|
183
182
|
test('ready should resolve in order when called multiply times (callbacks only)', async (t) => {
|
|
@@ -189,7 +188,7 @@ test('ready should resolve in order when called multiply times (callbacks only)'
|
|
|
189
188
|
|
|
190
189
|
await app.ready()
|
|
191
190
|
|
|
192
|
-
t.
|
|
191
|
+
t.assert.deepStrictEqual(result, expectedOrder, 'Should resolve in order')
|
|
193
192
|
})
|
|
194
193
|
|
|
195
194
|
test('ready should resolve in order when called multiply times (mixed)', async (t) => {
|
|
@@ -207,7 +206,7 @@ test('ready should resolve in order when called multiply times (mixed)', async (
|
|
|
207
206
|
|
|
208
207
|
await app.ready()
|
|
209
208
|
|
|
210
|
-
t.
|
|
209
|
+
t.assert.deepStrictEqual(result, expectedOrder, 'Should resolve in order')
|
|
211
210
|
})
|
|
212
211
|
|
|
213
212
|
test('ready should reject in order when called multiply times (mixed)', async (t) => {
|
|
@@ -228,10 +227,10 @@ test('ready should reject in order when called multiply times (mixed)', async (t
|
|
|
228
227
|
}
|
|
229
228
|
|
|
230
229
|
await app.ready().catch(err => {
|
|
231
|
-
t.
|
|
230
|
+
t.assert.strictEqual(err.message, 'test')
|
|
232
231
|
})
|
|
233
232
|
|
|
234
|
-
t.
|
|
233
|
+
t.assert.deepStrictEqual(result, expectedOrder, 'Should resolve in order')
|
|
235
234
|
})
|
|
236
235
|
|
|
237
236
|
test('ready should resolve in order when called multiply times (mixed)', async (t) => {
|
|
@@ -249,7 +248,7 @@ test('ready should resolve in order when called multiply times (mixed)', async (
|
|
|
249
248
|
|
|
250
249
|
await app.ready()
|
|
251
250
|
|
|
252
|
-
t.
|
|
251
|
+
t.assert.deepStrictEqual(result, expectedOrder, 'Should resolve in order')
|
|
253
252
|
})
|
|
254
253
|
|
|
255
254
|
test('fastify instance should contains listeningOrigin property (with port and host)', async t => {
|
|
@@ -258,7 +257,7 @@ test('fastify instance should contains listeningOrigin property (with port and h
|
|
|
258
257
|
const host = '127.0.0.1'
|
|
259
258
|
const fastify = Fastify()
|
|
260
259
|
await fastify.listen({ port, host })
|
|
261
|
-
t.
|
|
260
|
+
t.assert.deepStrictEqual(fastify.listeningOrigin, `http://${host}:${port}`)
|
|
262
261
|
await fastify.close()
|
|
263
262
|
})
|
|
264
263
|
|
|
@@ -268,7 +267,7 @@ test('fastify instance should contains listeningOrigin property (with port and h
|
|
|
268
267
|
const host = '127.0.0.1'
|
|
269
268
|
const fastify = Fastify({ https: {} })
|
|
270
269
|
await fastify.listen({ port, host })
|
|
271
|
-
t.
|
|
270
|
+
t.assert.deepStrictEqual(fastify.listeningOrigin, `https://${host}:${port}`)
|
|
272
271
|
await fastify.close()
|
|
273
272
|
})
|
|
274
273
|
|
|
@@ -276,7 +275,7 @@ test('fastify instance should contains listeningOrigin property (unix socket)',
|
|
|
276
275
|
const fastify = Fastify()
|
|
277
276
|
const path = `fastify.${Date.now()}.sock`
|
|
278
277
|
await fastify.listen({ path })
|
|
279
|
-
t.
|
|
278
|
+
t.assert.deepStrictEqual(fastify.listeningOrigin, path)
|
|
280
279
|
await fastify.close()
|
|
281
280
|
})
|
|
282
281
|
|
|
@@ -286,6 +285,6 @@ test('fastify instance should contains listeningOrigin property (IPv6)', async t
|
|
|
286
285
|
const host = '::1'
|
|
287
286
|
const fastify = Fastify()
|
|
288
287
|
await fastify.listen({ port, host })
|
|
289
|
-
t.
|
|
288
|
+
t.assert.deepStrictEqual(fastify.listeningOrigin, `http://[::1]:${port}`)
|
|
290
289
|
await fastify.close()
|
|
291
290
|
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { test } = require('
|
|
3
|
+
const { test } = require('node:test')
|
|
4
4
|
const Fastify = require('..')
|
|
5
5
|
const fastifyPlugin = require('fastify-plugin')
|
|
6
6
|
|
|
@@ -15,7 +15,7 @@ test('findRoute should return null when route cannot be found due to a different
|
|
|
15
15
|
handler: (req, reply) => reply.send(typeof req.params.artistId)
|
|
16
16
|
})
|
|
17
17
|
|
|
18
|
-
t.
|
|
18
|
+
t.assert.strictEqual(fastify.findRoute({
|
|
19
19
|
method: 'POST',
|
|
20
20
|
url: '/artists/:artistId'
|
|
21
21
|
}), null)
|
|
@@ -46,7 +46,8 @@ test('findRoute should return an immutable route to avoid leaking and runtime ro
|
|
|
46
46
|
method: 'GET',
|
|
47
47
|
url: '/artists/:artistId'
|
|
48
48
|
})
|
|
49
|
-
|
|
49
|
+
|
|
50
|
+
t.assert.strictEqual(route.params.artistId, ':artistId')
|
|
50
51
|
})
|
|
51
52
|
|
|
52
53
|
test('findRoute should return null when when url is not passed', t => {
|
|
@@ -60,7 +61,7 @@ test('findRoute should return null when when url is not passed', t => {
|
|
|
60
61
|
handler: (req, reply) => reply.send(typeof req.params.artistId)
|
|
61
62
|
})
|
|
62
63
|
|
|
63
|
-
t.
|
|
64
|
+
t.assert.strictEqual(fastify.findRoute({
|
|
64
65
|
method: 'POST'
|
|
65
66
|
}), null)
|
|
66
67
|
})
|
|
@@ -76,7 +77,7 @@ test('findRoute should return null when route cannot be found due to a different
|
|
|
76
77
|
handler: (req, reply) => reply.send(typeof req.params.artistId)
|
|
77
78
|
})
|
|
78
79
|
|
|
79
|
-
t.
|
|
80
|
+
t.assert.strictEqual(fastify.findRoute({
|
|
80
81
|
method: 'GET',
|
|
81
82
|
url: '/books/:bookId'
|
|
82
83
|
}), null)
|
|
@@ -99,11 +100,10 @@ test('findRoute should return the route when found', t => {
|
|
|
99
100
|
method: 'GET',
|
|
100
101
|
url: '/artists/:artistId'
|
|
101
102
|
})
|
|
102
|
-
|
|
103
|
-
t.same(route.params, { artistId: ':artistId' })
|
|
103
|
+
t.assert.strictEqual(route.params.artistId, ':artistId')
|
|
104
104
|
})
|
|
105
105
|
|
|
106
|
-
test('findRoute should work correctly when used within plugins', t => {
|
|
106
|
+
test('findRoute should work correctly when used within plugins', (t, done) => {
|
|
107
107
|
t.plan(1)
|
|
108
108
|
const fastify = Fastify()
|
|
109
109
|
const handler = (req, reply) => reply.send(typeof req.params.artistId)
|
|
@@ -128,7 +128,8 @@ test('findRoute should work correctly when used within plugins', t => {
|
|
|
128
128
|
fastify.register(fastifyPlugin(validateRoutePlugin))
|
|
129
129
|
|
|
130
130
|
fastify.ready(() => {
|
|
131
|
-
t.
|
|
131
|
+
t.assert.strictEqual(fastify.validateRoutes.validateParams(), true)
|
|
132
|
+
done()
|
|
132
133
|
})
|
|
133
134
|
})
|
|
134
135
|
|
|
@@ -147,5 +148,5 @@ test('findRoute should not expose store', t => {
|
|
|
147
148
|
method: 'GET',
|
|
148
149
|
url: '/artists/:artistId'
|
|
149
150
|
})
|
|
150
|
-
t.
|
|
151
|
+
t.assert.strictEqual(route.store, undefined)
|
|
151
152
|
})
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const test = t.test
|
|
3
|
+
const { test } = require('node:test')
|
|
5
4
|
const Fastify = require('..')
|
|
6
5
|
const S = require('fluent-json-schema')
|
|
7
6
|
|
|
8
|
-
test('use fluent-json-schema object', t => {
|
|
9
|
-
t.plan(
|
|
7
|
+
test('use fluent-json-schema object', async (t) => {
|
|
8
|
+
t.plan(10)
|
|
10
9
|
const fastify = Fastify()
|
|
11
10
|
|
|
12
11
|
fastify.post('/:id', {
|
|
@@ -24,73 +23,62 @@ test('use fluent-json-schema object', t => {
|
|
|
24
23
|
}
|
|
25
24
|
})
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
fastify.inject({
|
|
26
|
+
const res1 = await fastify.inject({
|
|
29
27
|
method: 'POST',
|
|
30
28
|
url: '/1',
|
|
31
29
|
headers: { 'x-custom': 'me@me.me' },
|
|
32
30
|
query: { surname: 'bar' },
|
|
33
31
|
payload: { name: 'foo' }
|
|
34
|
-
}, (err, res) => {
|
|
35
|
-
t.error(err)
|
|
36
|
-
t.equal(res.statusCode, 400)
|
|
37
|
-
t.same(res.json(), { statusCode: 400, code: 'FST_ERR_VALIDATION', error: 'Bad Request', message: 'params/id must be >= 42' })
|
|
38
32
|
})
|
|
33
|
+
t.assert.strictEqual(res1.statusCode, 400)
|
|
34
|
+
t.assert.deepStrictEqual(res1.json(), { statusCode: 400, code: 'FST_ERR_VALIDATION', error: 'Bad Request', message: 'params/id must be >= 42' })
|
|
39
35
|
|
|
40
36
|
// check header
|
|
41
|
-
fastify.inject({
|
|
37
|
+
const res2 = await fastify.inject({
|
|
42
38
|
method: 'POST',
|
|
43
39
|
url: '/42',
|
|
44
40
|
headers: { 'x-custom': 'invalid' },
|
|
45
41
|
query: { surname: 'bar' },
|
|
46
42
|
payload: { name: 'foo' }
|
|
47
|
-
}, (err, res) => {
|
|
48
|
-
t.error(err)
|
|
49
|
-
t.equal(res.statusCode, 400)
|
|
50
|
-
t.same(res.json(), { statusCode: 400, code: 'FST_ERR_VALIDATION', error: 'Bad Request', message: 'headers/x-custom must match format "email"' })
|
|
51
43
|
})
|
|
44
|
+
t.assert.strictEqual(res2.statusCode, 400)
|
|
45
|
+
t.assert.deepStrictEqual(res2.json(), { statusCode: 400, code: 'FST_ERR_VALIDATION', error: 'Bad Request', message: 'headers/x-custom must match format "email"' })
|
|
52
46
|
|
|
53
47
|
// check query
|
|
54
|
-
fastify.inject({
|
|
48
|
+
const res3 = await fastify.inject({
|
|
55
49
|
method: 'POST',
|
|
56
50
|
url: '/42',
|
|
57
51
|
headers: { 'x-custom': 'me@me.me' },
|
|
58
52
|
query: { },
|
|
59
53
|
payload: { name: 'foo' }
|
|
60
|
-
}, (err, res) => {
|
|
61
|
-
t.error(err)
|
|
62
|
-
t.equal(res.statusCode, 400)
|
|
63
|
-
t.same(res.json(), { statusCode: 400, code: 'FST_ERR_VALIDATION', error: 'Bad Request', message: 'querystring must have required property \'surname\'' })
|
|
64
54
|
})
|
|
55
|
+
t.assert.strictEqual(res3.statusCode, 400)
|
|
56
|
+
t.assert.deepStrictEqual(res3.json(), { statusCode: 400, code: 'FST_ERR_VALIDATION', error: 'Bad Request', message: 'querystring must have required property \'surname\'' })
|
|
65
57
|
|
|
66
58
|
// check body
|
|
67
|
-
fastify.inject({
|
|
59
|
+
const res4 = await fastify.inject({
|
|
68
60
|
method: 'POST',
|
|
69
61
|
url: '/42',
|
|
70
62
|
headers: { 'x-custom': 'me@me.me' },
|
|
71
63
|
query: { surname: 'bar' },
|
|
72
64
|
payload: { name: [1, 2, 3] }
|
|
73
|
-
}, (err, res) => {
|
|
74
|
-
t.error(err)
|
|
75
|
-
t.equal(res.statusCode, 400)
|
|
76
|
-
t.same(res.json(), { statusCode: 400, code: 'FST_ERR_VALIDATION', error: 'Bad Request', message: 'body/name must be string' })
|
|
77
65
|
})
|
|
66
|
+
t.assert.strictEqual(res4.statusCode, 400)
|
|
67
|
+
t.assert.deepStrictEqual(res4.json(), { statusCode: 400, code: 'FST_ERR_VALIDATION', error: 'Bad Request', message: 'body/name must be string' })
|
|
78
68
|
|
|
79
69
|
// check response
|
|
80
|
-
fastify.inject({
|
|
70
|
+
const res5 = await fastify.inject({
|
|
81
71
|
method: 'POST',
|
|
82
72
|
url: '/42',
|
|
83
73
|
headers: { 'x-custom': 'me@me.me' },
|
|
84
74
|
query: { surname: 'bar' },
|
|
85
75
|
payload: { name: 'foo' }
|
|
86
|
-
}, (err, res) => {
|
|
87
|
-
t.error(err)
|
|
88
|
-
t.equal(res.statusCode, 200)
|
|
89
|
-
t.same(res.json(), { name: 'a', surname: 'b' })
|
|
90
76
|
})
|
|
77
|
+
t.assert.strictEqual(res5.statusCode, 200)
|
|
78
|
+
t.assert.deepStrictEqual(res5.json(), { name: 'a', surname: 'b' })
|
|
91
79
|
})
|
|
92
80
|
|
|
93
|
-
test('use complex fluent-json-schema object', t => {
|
|
81
|
+
test('use complex fluent-json-schema object', (t, done) => {
|
|
94
82
|
t.plan(1)
|
|
95
83
|
const fastify = Fastify()
|
|
96
84
|
|
|
@@ -113,10 +101,13 @@ test('use complex fluent-json-schema object', t => {
|
|
|
113
101
|
.prop('office', S.ref('https://fastify/demo#/definitions/addressSchema')).required()
|
|
114
102
|
|
|
115
103
|
fastify.post('/the/url', { schema: { body: bodyJsonSchema } }, () => { })
|
|
116
|
-
fastify.ready(err =>
|
|
104
|
+
fastify.ready(err => {
|
|
105
|
+
t.assert.ifError(err)
|
|
106
|
+
done()
|
|
107
|
+
})
|
|
117
108
|
})
|
|
118
109
|
|
|
119
|
-
test('use fluent schema and plain JSON schema', t => {
|
|
110
|
+
test('use fluent schema and plain JSON schema', (t, done) => {
|
|
120
111
|
t.plan(1)
|
|
121
112
|
|
|
122
113
|
const fastify = Fastify()
|
|
@@ -154,10 +145,13 @@ test('use fluent schema and plain JSON schema', t => {
|
|
|
154
145
|
.prop('office', S.ref('https://fastify/demo#/definitions/addressSchema')).required()
|
|
155
146
|
|
|
156
147
|
fastify.post('/the/url', { schema: { body: bodyJsonSchema } }, () => { })
|
|
157
|
-
fastify.ready(err =>
|
|
148
|
+
fastify.ready(err => {
|
|
149
|
+
t.assert.ifError(err)
|
|
150
|
+
done()
|
|
151
|
+
})
|
|
158
152
|
})
|
|
159
153
|
|
|
160
|
-
test('Should call valueOf internally', t => {
|
|
154
|
+
test('Should call valueOf internally', (t, done) => {
|
|
161
155
|
t.plan(1)
|
|
162
156
|
|
|
163
157
|
const fastify = new Fastify()
|
|
@@ -208,5 +202,8 @@ test('Should call valueOf internally', t => {
|
|
|
208
202
|
}
|
|
209
203
|
})
|
|
210
204
|
|
|
211
|
-
fastify.ready(
|
|
205
|
+
fastify.ready(err => {
|
|
206
|
+
t.assert.ifError(err)
|
|
207
|
+
done()
|
|
208
|
+
})
|
|
212
209
|
})
|