From a92c6d80107a87e9c8de672e07d45cbfc25b7465 Mon Sep 17 00:00:00 2001 From: Manuel Spigolon Date: Sat, 18 Nov 2023 09:56:19 +0100 Subject: [PATCH 1/2] fix: avoid global unlimited config --- index.js | 21 +++++++++++++++------ test/emit-once-only.test.js | 2 +- test/issue-88.test.js | 26 ++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 test/issue-88.test.js diff --git a/index.js b/index.js index 1e7f87f..5919c8c 100644 --- a/index.js +++ b/index.js @@ -43,7 +43,6 @@ const { format } = require('node:util') function processWarning () { const codes = {} const emitted = new Map() - const opts = Object.create(null) /** * Builds a new {@link ProcessWarning} and adds it to the @@ -91,8 +90,12 @@ function processWarning () { } } - Object.assign(opts, { unlimited }) - emitted.set(code, unlimited) + // We need to manage 4 states: + // - START: code 0: unlimited emission + // - END: code -1: unlimited event emitted + // - START: code 1 (default): limited emission to 1 + // - END: code 2: limited event emitted + emitted.set(code, unlimited ? 0 : 1) codes[code] = buildWarnOpts return codes[code] @@ -137,9 +140,10 @@ function processWarning () { * @param {*} [c] Possible message interpolation value. */ function emit (code, a, b, c) { - if (emitted.get(code) === true && opts.unlimited === false) return + const state = emitted.get(code) + if (state === 2) return if (codes[code] === undefined) throw new Error(`The code '${code}' does not exist`) - emitted.set(code, true) + emitted.set(code, state <= 0 ? -1 : (state + 1)) const warning = codes[code](a, b, c) process.emitWarning(warning.message, warning.name, warning.code) @@ -149,7 +153,12 @@ function processWarning () { create, createDeprecation, emit, - emitted + emitted: { + get (code) { + const state = emitted.get(code) + return state === -1 || state === 2 + } + } } } diff --git a/test/emit-once-only.test.js b/test/emit-once-only.test.js index e1d8a30..75d9036 100644 --- a/test/emit-once-only.test.js +++ b/test/emit-once-only.test.js @@ -1,6 +1,6 @@ 'use strict' -const test = require('tap').test +const { test } = require('tap') const build = require('..') test('emit should emit a given code only once', t => { diff --git a/test/issue-88.test.js b/test/issue-88.test.js new file mode 100644 index 0000000..79696c0 --- /dev/null +++ b/test/issue-88.test.js @@ -0,0 +1,26 @@ +'use strict' + +const { test } = require('tap') +const build = require('..') + +test('Must not overwrite the global config', t => { + t.plan(1) + + const { create, emit } = build() + + function onWarning (warning) { + t.equal(warning.code, 'CODE_1') + } + + create('FastifyWarning', 'CODE_1', 'Msg', { unlimited: false }) + create('FastifyWarning', 'CODE_2', 'Msg', { unlimited: true }) + + process.on('warning', onWarning) + emit('CODE_1') + emit('CODE_1') + + setImmediate(() => { + process.removeListener('warning', onWarning) + t.end() + }) +}) From 7fb42e43bde5ebbf69e97d97412c885477f57a71 Mon Sep 17 00:00:00 2001 From: Manuel Spigolon Date: Sat, 18 Nov 2023 10:18:08 +0100 Subject: [PATCH 2/2] chore: add bench script --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 471d34c..f886dd2 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "scripts": { "lint": "standard", "lint:fix": "standard --fix", + "benchmark": "node benchmarks/warn.js", "test": "npm run test:unit && npm run test:jest && npm run test:typescript", "test:jest": "jest jest.test.js", "test:unit": "tap",