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,41 +1,44 @@
'use strict'
const t = require('tap')
const { test } = require('node:test')
const Fastify = require('../fastify')
const immediate = require('node:util').promisify(setImmediate)
t.test('onReady should be called in order', t => {
test('onReady should be called in order', (t, done) => {
t.plan(7)
const fastify = Fastify()
let order = 0
fastify.addHook('onReady', function (done) {
t.equal(order++, 0, 'called in root')
t.equal(this.pluginName, fastify.pluginName, 'the this binding is the right instance')
t.assert.strictEqual(order++, 0, 'called in root')
t.assert.strictEqual(this.pluginName, fastify.pluginName, 'the this binding is the right instance')
done()
})
fastify.register(async (childOne, o) => {
childOne.addHook('onReady', function (done) {
t.equal(order++, 1, 'called in childOne')
t.equal(this.pluginName, childOne.pluginName, 'the this binding is the right instance')
t.assert.strictEqual(order++, 1, 'called in childOne')
t.assert.strictEqual(this.pluginName, childOne.pluginName, 'the this binding is the right instance')
done()
})
childOne.register(async (childTwo, o) => {
childTwo.addHook('onReady', async function () {
await immediate()
t.equal(order++, 2, 'called in childTwo')
t.equal(this.pluginName, childTwo.pluginName, 'the this binding is the right instance')
t.assert.strictEqual(order++, 2, 'called in childTwo')
t.assert.strictEqual(this.pluginName, childTwo.pluginName, 'the this binding is the right instance')
})
})
})
fastify.ready(err => t.error(err))
fastify.ready(err => {
t.assert.ifError(err)
done()
})
})
t.test('onReady should be called once', async (t) => {
test('onReady should be called once', async (t) => {
const app = Fastify()
let counter = 0
@@ -47,11 +50,11 @@ t.test('onReady should be called once', async (t) => {
const result = await Promise.race(promises)
t.strictSame(result, 1, 'Should resolve in order')
t.equal(counter, 1, 'Should call onReady only once')
t.assert.strictEqual(result, 1, 'Should resolve in order')
t.assert.strictEqual(counter, 1, 'Should call onReady only once')
})
t.test('async onReady should be called in order', async t => {
test('async onReady should be called in order', async t => {
t.plan(7)
const fastify = Fastify()
@@ -59,31 +62,31 @@ t.test('async onReady should be called in order', async t => {
fastify.addHook('onReady', async function () {
await immediate()
t.equal(order++, 0, 'called in root')
t.equal(this.pluginName, fastify.pluginName, 'the this binding is the right instance')
t.assert.strictEqual(order++, 0, 'called in root')
t.assert.strictEqual(this.pluginName, fastify.pluginName, 'the this binding is the right instance')
})
fastify.register(async (childOne, o) => {
childOne.addHook('onReady', async function () {
await immediate()
t.equal(order++, 1, 'called in childOne')
t.equal(this.pluginName, childOne.pluginName, 'the this binding is the right instance')
t.assert.strictEqual(order++, 1, 'called in childOne')
t.assert.strictEqual(this.pluginName, childOne.pluginName, 'the this binding is the right instance')
})
childOne.register(async (childTwo, o) => {
childTwo.addHook('onReady', async function () {
await immediate()
t.equal(order++, 2, 'called in childTwo')
t.equal(this.pluginName, childTwo.pluginName, 'the this binding is the right instance')
t.assert.strictEqual(order++, 2, 'called in childTwo')
t.assert.strictEqual(this.pluginName, childTwo.pluginName, 'the this binding is the right instance')
})
})
})
await fastify.ready()
t.pass('ready')
t.assert.ok('ready')
})
t.test('mix ready and onReady', async t => {
test('mix ready and onReady', async t => {
t.plan(2)
const fastify = Fastify()
let order = 0
@@ -94,13 +97,13 @@ t.test('mix ready and onReady', async t => {
})
await fastify.ready()
t.equal(order, 1)
t.assert.strictEqual(order, 1)
await fastify.ready()
t.equal(order, 1, 'ready hooks execute once')
t.assert.strictEqual(order, 1, 'ready hooks execute once')
})
t.test('listen and onReady order', async t => {
test('listen and onReady order', async t => {
t.plan(9)
const fastify = Fastify()
@@ -127,19 +130,19 @@ t.test('listen and onReady order', async t => {
fastify.addHook('onReady', checkOrder.bind(null, 3))
await fastify.ready()
t.pass('trigger the onReady')
t.assert.ok('trigger the onReady')
await fastify.listen({ port: 0 })
t.pass('do not trigger the onReady')
t.assert.ok('do not trigger the onReady')
await fastify.close()
function checkOrder (shouldbe) {
t.equal(order, shouldbe)
t.assert.strictEqual(order, shouldbe)
order++
}
})
t.test('multiple ready calls', async t => {
test('multiple ready calls', async t => {
t.plan(11)
const fastify = Fastify()
@@ -154,7 +157,7 @@ t.test('multiple ready calls', async t => {
subinstance.addHook('onReady', checkOrder.bind(null, 7))
})
t.equal(order, 0, 'ready and hooks not triggered yet')
t.assert.strictEqual(order, 0, 'ready and hooks not triggered yet')
order++
})
@@ -163,139 +166,145 @@ t.test('multiple ready calls', async t => {
fastify.addHook('onReady', checkOrder.bind(null, 5))
await fastify.ready()
t.pass('trigger the onReady')
t.assert.ok('trigger the onReady')
await fastify.ready()
t.pass('do not trigger the onReady')
t.assert.ok('do not trigger the onReady')
await fastify.ready()
t.pass('do not trigger the onReady')
t.assert.ok('do not trigger the onReady')
function checkOrder (shouldbe) {
t.equal(order, shouldbe)
t.assert.strictEqual(order, shouldbe)
order++
}
})
t.test('onReady should manage error in sync', t => {
test('onReady should manage error in sync', (t, done) => {
t.plan(4)
const fastify = Fastify()
fastify.addHook('onReady', function (done) {
t.pass('called in root')
t.assert.ok('called in root')
done()
})
fastify.register(async (childOne, o) => {
childOne.addHook('onReady', function (done) {
t.pass('called in childOne')
t.assert.ok('called in childOne')
done(new Error('FAIL ON READY'))
})
childOne.register(async (childTwo, o) => {
childTwo.addHook('onReady', async function () {
t.fail('should not be called')
t.assert.fail('should not be called')
})
})
})
fastify.ready(err => {
t.ok(err)
t.equal(err.message, 'FAIL ON READY')
t.assert.ok(err)
t.assert.strictEqual(err.message, 'FAIL ON READY')
done()
})
})
t.test('onReady should manage error in async', t => {
test('onReady should manage error in async', (t, done) => {
t.plan(4)
const fastify = Fastify()
fastify.addHook('onReady', function (done) {
t.pass('called in root')
t.assert.ok('called in root')
done()
})
fastify.register(async (childOne, o) => {
childOne.addHook('onReady', async function () {
t.pass('called in childOne')
t.assert.ok('called in childOne')
throw new Error('FAIL ON READY')
})
childOne.register(async (childTwo, o) => {
childTwo.addHook('onReady', async function () {
t.fail('should not be called')
t.assert.fail('should not be called')
})
})
})
fastify.ready(err => {
t.ok(err)
t.equal(err.message, 'FAIL ON READY')
t.assert.ok(err)
t.assert.strictEqual(err.message, 'FAIL ON READY')
done()
})
})
t.test('onReady should manage sync error', t => {
test('onReady should manage sync error', (t, done) => {
t.plan(4)
const fastify = Fastify()
fastify.addHook('onReady', function (done) {
t.pass('called in root')
t.assert.ok('called in root')
done()
})
fastify.register(async (childOne, o) => {
childOne.addHook('onReady', function (done) {
t.pass('called in childOne')
t.assert.ok('called in childOne')
throw new Error('FAIL UNWANTED SYNC EXCEPTION')
})
childOne.register(async (childTwo, o) => {
childTwo.addHook('onReady', async function () {
t.fail('should not be called')
t.assert.fail('should not be called')
})
})
})
fastify.ready(err => {
t.ok(err)
t.equal(err.message, 'FAIL UNWANTED SYNC EXCEPTION')
t.assert.ok(err)
t.assert.strictEqual(err.message, 'FAIL UNWANTED SYNC EXCEPTION')
done()
})
})
t.test('onReady can not add decorators or application hooks', t => {
test('onReady can not add decorators or application hooks', (t, done) => {
t.plan(3)
const fastify = Fastify()
fastify.addHook('onReady', function (done) {
t.pass('called in root')
t.assert.ok('called in root')
fastify.decorate('test', () => {})
fastify.addHook('onReady', async function () {
t.fail('it will be not called')
t.assert.fail('it will be not called')
})
done()
})
fastify.addHook('onReady', function (done) {
t.ok(this.hasDecorator('test'))
t.assert.ok(this.hasDecorator('test'))
done()
})
fastify.ready(err => { t.error(err) })
fastify.ready(err => {
t.assert.ifError(err)
done()
})
})
t.test('onReady cannot add lifecycle hooks', t => {
test('onReady cannot add lifecycle hooks', (t, done) => {
t.plan(5)
const fastify = Fastify()
fastify.addHook('onReady', function (done) {
t.pass('called in root')
t.assert.ok('called in root')
try {
fastify.addHook('onRequest', (request, reply, done) => {})
} catch (error) {
t.ok(error)
t.equal(error.message, 'Root plugin has already booted')
t.assert.ok(error)
t.assert.strictEqual(error.message, 'Root plugin has already booted')
// TODO: look where the error pops up
t.equal(error.code, 'AVV_ERR_ROOT_PLG_BOOTED')
t.assert.strictEqual(error.code, 'AVV_ERR_ROOT_PLG_BOOTED')
done(error)
}
})
@@ -303,93 +312,102 @@ t.test('onReady cannot add lifecycle hooks', t => {
fastify.addHook('onRequest', (request, reply, done) => {})
fastify.get('/', async () => 'hello')
fastify.ready((err) => { t.ok(err) })
fastify.ready((err) => {
t.assert.ok(err)
done()
})
})
t.test('onReady throw loading error', t => {
test('onReady throw loading error', t => {
t.plan(2)
const fastify = Fastify()
try {
fastify.addHook('onReady', async function (done) {})
} catch (e) {
t.ok(e.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')
t.ok(e.message === 'Async function has too many arguments. Async hooks should not use the \'done\' argument.')
t.assert.strictEqual(e.code, 'FST_ERR_HOOK_INVALID_ASYNC_HANDLER')
t.assert.ok(e.message === 'Async function has too many arguments. Async hooks should not use the \'done\' argument.')
}
})
t.test('onReady does not call done', t => {
test('onReady does not call done', (t, done) => {
t.plan(6)
const fastify = Fastify({ pluginTimeout: 500 })
fastify.addHook('onReady', function (done) {
t.pass('called in root')
fastify.addHook('onReady', function someHookName (done) {
t.assert.ok('called in root')
// done() // don't call done to test timeout
})
fastify.ready(err => {
t.ok(err)
t.equal(err.message, "A callback for 'onReady' hook timed out. You may have forgotten to call 'done' function or to resolve a Promise")
t.equal(err.code, 'FST_ERR_HOOK_TIMEOUT')
t.ok(err.cause)
t.equal(err.cause.code, 'AVV_ERR_READY_TIMEOUT')
t.assert.ok(err)
t.assert.strictEqual(err.message, 'A callback for \'onReady\' hook "someHookName" timed out. You may have forgotten to call \'done\' function or to resolve a Promise')
t.assert.strictEqual(err.code, 'FST_ERR_HOOK_TIMEOUT')
t.assert.ok(err.cause)
t.assert.strictEqual(err.cause.code, 'AVV_ERR_READY_TIMEOUT')
done()
})
})
t.test('onReady execution order', t => {
test('onReady execution order', (t, done) => {
t.plan(3)
const fastify = Fastify({ })
let i = 0
fastify.ready(() => { i++; t.equal(i, 1) })
fastify.ready(() => { i++; t.equal(i, 2) })
fastify.ready(() => { i++; t.equal(i, 3) })
fastify.ready(() => { i++; t.assert.strictEqual(i, 1) })
fastify.ready(() => { i++; t.assert.strictEqual(i, 2) })
fastify.ready(() => {
i++
t.assert.strictEqual(i, 3)
done()
})
})
t.test('ready return the server with callback', t => {
test('ready return the server with callback', (t, done) => {
t.plan(2)
const fastify = Fastify()
fastify.ready((err, instance) => {
t.error(err)
t.same(instance, fastify)
t.assert.ifError(err)
t.assert.deepStrictEqual(instance, fastify)
done()
})
})
t.test('ready return the server with Promise', t => {
test('ready return the server with Promise', async t => {
t.plan(1)
const fastify = Fastify()
fastify.ready()
.then(instance => { t.same(instance, fastify) })
.catch(err => { t.fail(err) })
await fastify.ready()
.then(instance => { t.assert.deepStrictEqual(instance, fastify) })
.catch(err => { t.assert.fail(err) })
})
t.test('ready return registered', t => {
test('ready return registered', async t => {
t.plan(4)
const fastify = Fastify()
fastify.register((one, opts, done) => {
one.ready().then(itself => { t.same(itself, one) })
one.ready().then(itself => { t.assert.deepStrictEqual(itself, one) })
done()
})
fastify.register((two, opts, done) => {
two.ready().then(itself => { t.same(itself, two) })
two.ready().then(itself => { t.assert.deepStrictEqual(itself, two) })
two.register((twoDotOne, opts, done) => {
twoDotOne.ready().then(itself => { t.same(itself, twoDotOne) })
twoDotOne.ready().then(itself => { t.assert.deepStrictEqual(itself, twoDotOne) })
done()
})
done()
})
fastify.ready()
.then(instance => { t.same(instance, fastify) })
.catch(err => { t.fail(err) })
await fastify.ready()
.then(instance => { t.assert.deepStrictEqual(instance, fastify) })
.catch(err => { t.assert.fail(err) })
})
t.test('do not crash with error in follow up onReady hook', async t => {
test('do not crash with error in follow up onReady hook', async t => {
const fastify = Fastify()
fastify.addHook('onReady', async function () {
@@ -399,5 +417,5 @@ t.test('do not crash with error in follow up onReady hook', async t => {
throw new Error('kaboom')
})
await t.rejects(fastify.ready())
await t.assert.rejects(fastify.ready())
})