Aktueller Stand

This commit is contained in:
2026-01-22 19:05:45 +01:00
parent 85dee61a4d
commit e280e4eadb
1967 changed files with 397327 additions and 74093 deletions

View File

@@ -1,6 +1,6 @@
'use strict'
const { test } = require('tap')
const { test } = require('node:test')
const { kReplyCacheSerializeFns, kRouteContext } = require('../../lib/symbols')
const Fastify = require('../../fastify')
@@ -50,8 +50,11 @@ function getResponseSchema () {
content: {
'application/json': {
schema: {
fullName: { type: 'string' },
phone: { type: 'number' }
type: 'object',
properties: {
fullName: { type: 'string' },
phone: { type: 'number' }
}
}
}
}
@@ -59,10 +62,10 @@ function getResponseSchema () {
}
}
test('Reply#compileSerializationSchema', t => {
test('Reply#compileSerializationSchema', async t => {
t.plan(4)
t.test('Should return a serialization function', async t => {
await t.test('Should return a serialization function', async t => {
const fastify = Fastify()
t.plan(4)
@@ -70,14 +73,14 @@ test('Reply#compileSerializationSchema', t => {
fastify.get('/', (req, reply) => {
const serialize = reply.compileSerializationSchema(getDefaultSchema())
const input = { hello: 'world' }
t.type(serialize, Function)
t.type(serialize(input), 'string')
t.equal(serialize(input), JSON.stringify(input))
t.assert.ok(serialize instanceof Function)
t.assert.ok(typeof serialize(input) === 'string')
t.assert.strictEqual(serialize(input), JSON.stringify(input))
try {
serialize({ world: 'foo' })
} catch (err) {
t.equal(err.message, '"hello" is required!')
t.assert.strictEqual(err.message, '"hello" is required!')
}
reply.send({ hello: 'world' })
@@ -89,7 +92,7 @@ test('Reply#compileSerializationSchema', t => {
})
})
t.test('Should reuse the serialize fn across multiple invocations - Route without schema',
await t.test('Should reuse the serialize fn across multiple invocations - Route without schema',
async t => {
const fastify = Fastify()
let serialize = null
@@ -104,20 +107,20 @@ test('Reply#compileSerializationSchema', t => {
counter++
if (counter > 1) {
const newSerialize = reply.compileSerializationSchema(schemaObj)
t.equal(serialize, newSerialize, 'Are the same validate function')
t.assert.strictEqual(serialize, newSerialize, 'Are the same validate function')
serialize = newSerialize
} else {
t.pass('build the schema compilation function')
t.assert.ok(true, 'build the schema compilation function')
serialize = reply.compileSerializationSchema(schemaObj)
}
t.type(serialize, Function)
t.equal(serialize(input), JSON.stringify(input))
t.assert.ok(serialize instanceof Function)
t.assert.strictEqual(serialize(input), JSON.stringify(input))
try {
serialize({ world: 'foo' })
} catch (err) {
t.equal(err.message, '"hello" is required!')
t.assert.strictEqual(err.message, '"hello" is required!')
}
reply.send({ hello: 'world' })
@@ -130,36 +133,36 @@ test('Reply#compileSerializationSchema', t => {
fastify.inject('/')
])
t.equal(counter, 4)
t.assert.strictEqual(counter, 4)
}
)
t.test('Should use the custom serializer compiler for the route',
await t.test('Should use the custom serializer compiler for the route',
async t => {
const fastify = Fastify()
let called = 0
const custom = ({ schema, httpStatus, url, method }) => {
t.equal(schema, schemaObj)
t.equal(url, '/')
t.equal(method, 'GET')
t.equal(httpStatus, '201')
t.assert.strictEqual(schema, schemaObj)
t.assert.strictEqual(url, '/')
t.assert.strictEqual(method, 'GET')
t.assert.strictEqual(httpStatus, '201')
return input => {
called++
t.same(input, { hello: 'world' })
t.assert.deepStrictEqual(input, { hello: 'world' })
return JSON.stringify(input)
}
}
const custom2 = ({ schema, httpStatus, url, method, contentType }) => {
t.equal(schema, schemaObj)
t.equal(url, '/user')
t.equal(method, 'GET')
t.equal(httpStatus, '3xx')
t.equal(contentType, 'application/json')
t.assert.strictEqual(schema, schemaObj)
t.assert.strictEqual(url, '/user')
t.assert.strictEqual(method, 'GET')
t.assert.strictEqual(httpStatus, '3xx')
t.assert.strictEqual(contentType, 'application/json')
return input => {
t.same(input, { fullName: 'Jone', phone: 1090243795 })
t.assert.deepStrictEqual(input, { fullName: 'Jone', phone: 1090243795 })
return JSON.stringify(input)
}
}
@@ -172,10 +175,10 @@ test('Reply#compileSerializationSchema', t => {
const first = reply.compileSerializationSchema(schemaObj, '201')
const second = reply.compileSerializationSchema(schemaObj, '201')
t.equal(first, second)
t.ok(first(input), JSON.stringify(input))
t.ok(second(input), JSON.stringify(input))
t.equal(called, 2)
t.assert.strictEqual(first, second)
t.assert.ok(first(input), JSON.stringify(input))
t.assert.ok(second(input), JSON.stringify(input))
t.assert.strictEqual(called, 2)
reply.send({ hello: 'world' })
})
@@ -183,7 +186,7 @@ test('Reply#compileSerializationSchema', t => {
fastify.get('/user', { serializerCompiler: custom2 }, (req, reply) => {
const input = { fullName: 'Jone', phone: 1090243795 }
const first = reply.compileSerializationSchema(schemaObj, '3xx', 'application/json')
t.ok(first(input), JSON.stringify(input))
t.assert.ok(first(input), JSON.stringify(input))
reply.send(input)
})
@@ -199,7 +202,7 @@ test('Reply#compileSerializationSchema', t => {
}
)
t.test('Should build a WeakMap for cache when called', async t => {
await t.test('Should build a WeakMap for cache when called', async t => {
const fastify = Fastify()
t.plan(4)
@@ -207,10 +210,10 @@ test('Reply#compileSerializationSchema', t => {
fastify.get('/', (req, reply) => {
const input = { hello: 'world' }
t.equal(reply[kRouteContext][kReplyCacheSerializeFns], null)
t.equal(reply.compileSerializationSchema(getDefaultSchema())(input), JSON.stringify(input))
t.type(reply[kRouteContext][kReplyCacheSerializeFns], WeakMap)
t.equal(reply.compileSerializationSchema(getDefaultSchema())(input), JSON.stringify(input))
t.assert.strictEqual(reply[kRouteContext][kReplyCacheSerializeFns], null)
t.assert.strictEqual(reply.compileSerializationSchema(getDefaultSchema())(input), JSON.stringify(input))
t.assert.ok(reply[kRouteContext][kReplyCacheSerializeFns] instanceof WeakMap)
t.assert.strictEqual(reply.compileSerializationSchema(getDefaultSchema())(input), JSON.stringify(input))
reply.send({ hello: 'world' })
})
@@ -222,10 +225,10 @@ test('Reply#compileSerializationSchema', t => {
})
})
test('Reply#getSerializationFunction', t => {
test('Reply#getSerializationFunction', async t => {
t.plan(3)
t.test('Should retrieve the serialization function from the Schema definition',
await t.test('Should retrieve the serialization function from the Schema definition',
async t => {
const fastify = Fastify()
const okInput201 = {
@@ -264,8 +267,11 @@ test('Reply#getSerializationFunction', t => {
'/:id',
{
params: {
id: {
type: 'integer'
type: 'object',
properties: {
id: {
type: 'integer'
}
}
},
schema: {
@@ -285,18 +291,18 @@ test('Reply#getSerializationFunction', t => {
cached201 = serialize201
cachedJson3xx = serializeJson3xx
t.type(serialize4xx, Function)
t.type(serialize201, Function)
t.type(serializeJson3xx, Function)
t.equal(serialize4xx(okInput4xx), JSON.stringify(okInput4xx))
t.equal(serialize201(okInput201), JSON.stringify(okInput201))
t.equal(serializeJson3xx(okInput3xx), JSON.stringify(okInput3xx))
t.notOk(serializeUndefined)
t.assert.ok(serialize4xx instanceof Function)
t.assert.ok(serialize201 instanceof Function)
t.assert.ok(serializeJson3xx instanceof Function)
t.assert.strictEqual(serialize4xx(okInput4xx), JSON.stringify(okInput4xx))
t.assert.strictEqual(serialize201(okInput201), JSON.stringify(okInput201))
t.assert.strictEqual(serializeJson3xx(okInput3xx), JSON.stringify(okInput3xx))
t.assert.ok(!serializeUndefined)
try {
serialize4xx(notOkInput4xx)
} catch (err) {
t.equal(
t.assert.strictEqual(
err.message,
'The value "something" cannot be converted to an integer.'
)
@@ -305,13 +311,13 @@ test('Reply#getSerializationFunction', t => {
try {
serialize201(notOkInput201)
} catch (err) {
t.equal(err.message, '"status" is required!')
t.assert.strictEqual(err.message, '"status" is required!')
}
try {
serializeJson3xx(noOkInput3xx)
} catch (err) {
t.equal(err.message, 'The value "phone" cannot be converted to a number.')
t.assert.strictEqual(err.message, 'The value "phone" cannot be converted to a number.')
}
reply.status(201).send(okInput201)
@@ -320,9 +326,9 @@ test('Reply#getSerializationFunction', t => {
const serialize4xx = reply.getSerializationFunction('4xx')
const serializeJson3xx = reply.getSerializationFunction('3xx', 'application/json')
t.equal(serialize4xx, cached4xx)
t.equal(serialize201, cached201)
t.equal(serializeJson3xx, cachedJson3xx)
t.assert.strictEqual(serialize4xx, cached4xx)
t.assert.strictEqual(serialize201, cached201)
t.assert.strictEqual(serializeJson3xx, cachedJson3xx)
reply.status(401).send(okInput4xx)
}
}
@@ -335,7 +341,7 @@ test('Reply#getSerializationFunction', t => {
}
)
t.test('Should retrieve the serialization function from the cached one',
await t.test('Should retrieve the serialization function from the cached one',
async t => {
const fastify = Fastify()
@@ -356,8 +362,11 @@ test('Reply#getSerializationFunction', t => {
'/:id',
{
params: {
id: {
type: 'integer'
type: 'object',
properties: {
id: {
type: 'integer'
}
}
}
},
@@ -367,26 +376,26 @@ test('Reply#getSerializationFunction', t => {
if (Number(id) === 1) {
const serialize = reply.compileSerializationSchema(schemaObj)
t.type(serialize, Function)
t.equal(serialize(okInput), JSON.stringify(okInput))
t.assert.ok(serialize instanceof Function)
t.assert.strictEqual(serialize(okInput), JSON.stringify(okInput))
try {
serialize(notOkInput)
} catch (err) {
t.equal(err.message, '"hello" is required!')
t.assert.strictEqual(err.message, '"hello" is required!')
}
cached = serialize
} else {
const serialize = reply.getSerializationFunction(schemaObj)
t.equal(serialize, cached)
t.equal(serialize(okInput), JSON.stringify(okInput))
t.assert.strictEqual(serialize, cached)
t.assert.strictEqual(serialize(okInput), JSON.stringify(okInput))
try {
serialize(notOkInput)
} catch (err) {
t.equal(err.message, '"hello" is required!')
t.assert.strictEqual(err.message, '"hello" is required!')
}
}
@@ -401,16 +410,16 @@ test('Reply#getSerializationFunction', t => {
}
)
t.test('Should not instantiate a WeakMap if it is not needed', async t => {
await t.test('Should not instantiate a WeakMap if it is not needed', async t => {
const fastify = Fastify()
t.plan(4)
fastify.get('/', (req, reply) => {
t.notOk(reply.getSerializationFunction(getDefaultSchema()))
t.equal(reply[kRouteContext][kReplyCacheSerializeFns], null)
t.notOk(reply.getSerializationFunction('200'))
t.equal(reply[kRouteContext][kReplyCacheSerializeFns], null)
t.assert.ok(!reply.getSerializationFunction(getDefaultSchema()))
t.assert.strictEqual(reply[kRouteContext][kReplyCacheSerializeFns], null)
t.assert.ok(!reply.getSerializationFunction('200'))
t.assert.strictEqual(reply[kRouteContext][kReplyCacheSerializeFns], null)
reply.send({ hello: 'world' })
})
@@ -422,10 +431,10 @@ test('Reply#getSerializationFunction', t => {
})
})
test('Reply#serializeInput', t => {
test('Reply#serializeInput', async t => {
t.plan(6)
t.test(
await t.test(
'Should throw if missed serialization function from HTTP status',
async t => {
const fastify = Fastify()
@@ -441,8 +450,8 @@ test('Reply#serializeInput', t => {
method: 'GET'
})
t.equal(result.statusCode, 500)
t.same(result.json(), {
t.assert.strictEqual(result.statusCode, 500)
t.assert.deepStrictEqual(result.json(), {
statusCode: 500,
code: 'FST_ERR_MISSING_SERIALIZATION_FN',
error: 'Internal Server Error',
@@ -451,7 +460,7 @@ test('Reply#serializeInput', t => {
}
)
t.test(
await t.test(
'Should throw if missed serialization function from HTTP status with specific content type',
async t => {
const fastify = Fastify()
@@ -465,8 +474,11 @@ test('Reply#serializeInput', t => {
content: {
'application/json': {
schema: {
fullName: { type: 'string' },
phone: { type: 'number' }
type: 'object',
properties: {
fullName: { type: 'string' },
phone: { type: 'number' }
}
}
}
}
@@ -482,8 +494,8 @@ test('Reply#serializeInput', t => {
method: 'GET'
})
t.equal(result.statusCode, 500)
t.same(result.json(), {
t.assert.strictEqual(result.statusCode, 500)
t.assert.deepStrictEqual(result.json(), {
statusCode: 500,
code: 'FST_ERR_MISSING_CONTENTTYPE_SERIALIZATION_FN',
error: 'Internal Server Error',
@@ -492,7 +504,7 @@ test('Reply#serializeInput', t => {
}
)
t.test('Should use a serializer fn from HTTP status', async t => {
await t.test('Should use a serializer fn from HTTP status', async t => {
const fastify = Fastify()
const okInput201 = {
status: 'ok',
@@ -525,8 +537,11 @@ test('Reply#serializeInput', t => {
'/',
{
params: {
id: {
type: 'integer'
type: 'object',
properties: {
id: {
type: 'integer'
}
}
},
schema: {
@@ -534,16 +549,16 @@ test('Reply#serializeInput', t => {
}
},
(req, reply) => {
t.equal(
t.assert.strictEqual(
reply.serializeInput(okInput4xx, '4xx'),
JSON.stringify(okInput4xx)
)
t.equal(
t.assert.strictEqual(
reply.serializeInput(okInput201, 201),
JSON.stringify(okInput201)
)
t.equal(
t.assert.strictEqual(
reply.serializeInput(okInput3xx, {}, '3xx', 'application/json'),
JSON.stringify(okInput3xx)
)
@@ -551,13 +566,13 @@ test('Reply#serializeInput', t => {
try {
reply.serializeInput(noOkInput3xx, '3xx', 'application/json')
} catch (err) {
t.equal(err.message, 'The value "phone" cannot be converted to a number.')
t.assert.strictEqual(err.message, 'The value "phone" cannot be converted to a number.')
}
try {
reply.serializeInput(notOkInput4xx, '4xx')
} catch (err) {
t.equal(
t.assert.strictEqual(
err.message,
'The value "something" cannot be converted to an integer.'
)
@@ -566,7 +581,7 @@ test('Reply#serializeInput', t => {
try {
reply.serializeInput(notOkInput201, 201)
} catch (err) {
t.equal(err.message, '"status" is required!')
t.assert.strictEqual(err.message, '"status" is required!')
}
reply.status(204).send('')
@@ -579,7 +594,7 @@ test('Reply#serializeInput', t => {
})
})
t.test(
await t.test(
'Should compile a serializer out of a schema if serializer fn missed',
async t => {
let compilerCalled = 0
@@ -588,14 +603,14 @@ test('Reply#serializeInput', t => {
const schemaObj = getDefaultSchema()
const fastify = Fastify()
const serializerCompiler = ({ schema, httpStatus, method, url }) => {
t.equal(schema, schemaObj)
t.notOk(httpStatus)
t.equal(method, 'GET')
t.equal(url, '/')
t.assert.strictEqual(schema, schemaObj)
t.assert.ok(!httpStatus)
t.assert.strictEqual(method, 'GET')
t.assert.strictEqual(url, '/')
compilerCalled++
return input => {
t.equal(input, testInput)
t.assert.strictEqual(input, testInput)
serializerCalled++
return JSON.stringify(input)
}
@@ -604,12 +619,12 @@ test('Reply#serializeInput', t => {
t.plan(10)
fastify.get('/', { serializerCompiler }, (req, reply) => {
t.equal(
t.assert.strictEqual(
reply.serializeInput(testInput, schemaObj),
JSON.stringify(testInput)
)
t.equal(
t.assert.strictEqual(
reply.serializeInput(testInput, schemaObj),
JSON.stringify(testInput)
)
@@ -622,12 +637,12 @@ test('Reply#serializeInput', t => {
method: 'GET'
})
t.equal(compilerCalled, 1)
t.equal(serializerCalled, 2)
t.assert.strictEqual(compilerCalled, 1)
t.assert.strictEqual(serializerCalled, 2)
}
)
t.test('Should use a cached serializer fn', async t => {
await t.test('Should use a cached serializer fn', async t => {
let compilerCalled = 0
let serializerCalled = 0
let cached
@@ -635,15 +650,15 @@ test('Reply#serializeInput', t => {
const schemaObj = getDefaultSchema()
const fastify = Fastify()
const serializer = input => {
t.equal(input, testInput)
t.assert.strictEqual(input, testInput)
serializerCalled++
return JSON.stringify(input)
}
const serializerCompiler = ({ schema, httpStatus, method, url }) => {
t.equal(schema, schemaObj)
t.notOk(httpStatus)
t.equal(method, 'GET')
t.equal(url, '/')
t.assert.strictEqual(schema, schemaObj)
t.assert.ok(!httpStatus)
t.assert.strictEqual(method, 'GET')
t.assert.strictEqual(url, '/')
compilerCalled++
return serializer
@@ -652,14 +667,14 @@ test('Reply#serializeInput', t => {
t.plan(12)
fastify.get('/', { serializerCompiler }, (req, reply) => {
t.equal(
t.assert.strictEqual(
reply.serializeInput(testInput, schemaObj),
JSON.stringify(testInput)
)
cached = reply.getSerializationFunction(schemaObj)
t.equal(
t.assert.strictEqual(
reply.serializeInput(testInput, schemaObj),
cached(testInput)
)
@@ -672,21 +687,21 @@ test('Reply#serializeInput', t => {
method: 'GET'
})
t.equal(cached, serializer)
t.equal(compilerCalled, 1)
t.equal(serializerCalled, 3)
t.assert.strictEqual(cached, serializer)
t.assert.strictEqual(compilerCalled, 1)
t.assert.strictEqual(serializerCalled, 3)
})
t.test('Should instantiate a WeakMap after first call', async t => {
await t.test('Should instantiate a WeakMap after first call', async t => {
const fastify = Fastify()
t.plan(3)
fastify.get('/', (req, reply) => {
const input = { hello: 'world' }
t.equal(reply[kRouteContext][kReplyCacheSerializeFns], null)
t.equal(reply.serializeInput(input, getDefaultSchema()), JSON.stringify(input))
t.type(reply[kRouteContext][kReplyCacheSerializeFns], WeakMap)
t.assert.strictEqual(reply[kRouteContext][kReplyCacheSerializeFns], null)
t.assert.strictEqual(reply.serializeInput(input, getDefaultSchema()), JSON.stringify(input))
t.assert.ok(reply[kRouteContext][kReplyCacheSerializeFns] instanceof WeakMap)
reply.send({ hello: 'world' })
})