diff --git a/test/common/README.md b/test/common/README.md index 121bb20bb19710..0542c38bbcb419 100644 --- a/test/common/README.md +++ b/test/common/README.md @@ -109,14 +109,51 @@ Indicates if there is more than 1gb of total memory. returned function has not been called exactly `exact` number of times when the test is complete, then the test will fail. -### expectWarning(name, expected, code) -* `name` [<string>] -* `expected` [<string>] | [<Array>] +### expectWarning(name[, expected[, code]]) +* `name` [<string>] | [<Object>] +* `expected` [<string>] | [<Array>] | [<Object>] * `code` [<string>] -Tests whether `name`, `expected`, and `code` are part of a raised warning. If -an expected warning does not have a code then `common.noWarnCode` can be used -to indicate this. +Tests whether `name`, `expected`, and `code` are part of a raised warning. + +The code is required in case the name is set to `'DeprecationWarning'`. + +Examples: + +```js +const { expectWarning } = require('../common'); + +expectWarning('Warning', 'Foobar is really bad'); + +expectWarning('DeprecationWarning', 'Foobar is deprecated', 'DEP0XXX'); + +expectWarning('DeprecationWarning', [ + 'Foobar is deprecated', 'DEP0XXX' +]); + +expectWarning('DeprecationWarning', [ + ['Foobar is deprecated', 'DEP0XXX'], + ['Baz is also deprecated', 'DEP0XX2'] +]); + +expectWarning('DeprecationWarning', { + DEP0XXX: 'Foobar is deprecated', + DEP0XX2: 'Baz is also deprecated' +}); + +expectWarning({ + DeprecationWarning: { + DEP0XXX: 'Foobar is deprecated', + DEP0XX1: 'Baz is also deprecated' + }, + Warning: [ + ['Multiple array entries are fine', 'SpecialWarningCode'], + ['No code is also fine'] + ], + SingleEntry: ['This will also work', 'WarningCode'], + SingleString: 'Single string entries without code will also work' +}); +``` ### getArrayBufferViews(buf) * `buf` [<Buffer>] @@ -262,9 +299,6 @@ Returns `true` if the exit code `exitCode` and/or signal name `signal` represent the exit code and/or signal name of a node process that aborted, `false` otherwise. -### noWarnCode -See `common.expectWarning()` for usage. - ### opensslCli * [<boolean>] diff --git a/test/common/index.js b/test/common/index.js index 5ac79f4998acc8..49cb50d7e63488 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -498,54 +498,43 @@ function isAlive(pid) { } } -function _expectWarning(name, expected) { - const map = new Map(expected); +function _expectWarning(name, expected, code) { + if (typeof expected === 'string') { + expected = [[expected, code]]; + } else if (!Array.isArray(expected)) { + expected = Object.entries(expected).map(([a, b]) => [b, a]); + } else if (!(Array.isArray(expected[0]))) { + expected = [[expected[0], expected[1]]]; + } + // Deprecation codes are mandatory, everything else is not. + if (name === 'DeprecationWarning') { + expected.forEach(([_, code]) => assert(code, expected)); + } return mustCall((warning) => { + const [ message, code ] = expected.shift(); assert.strictEqual(warning.name, name); - assert.ok(map.has(warning.message), - `unexpected error message: "${warning.message}"`); - const code = map.get(warning.message); + assert.strictEqual(warning.message, message); assert.strictEqual(warning.code, code); - // Remove a warning message after it is seen so that we guarantee that we - // get each message only once. - map.delete(expected); }, expected.length); } -function expectWarningByName(name, expected, code) { - if (typeof expected === 'string') { - expected = [[expected, code]]; - } - process.on('warning', _expectWarning(name, expected)); -} +let catchWarning; -function expectWarningByMap(warningMap) { - const catchWarning = {}; - Object.keys(warningMap).forEach((name) => { - let expected = warningMap[name]; - if (!Array.isArray(expected)) { - throw new Error('warningMap entries must be arrays consisting of two ' + - 'entries: [message, warningCode]'); - } - if (!(Array.isArray(expected[0]))) { - if (expected.length === 0) { - return; - } - expected = [[expected[0], expected[1]]]; - } - catchWarning[name] = _expectWarning(name, expected); - }); - process.on('warning', (warning) => catchWarning[warning.name](warning)); -} - -// Accepts a warning name and description or array of descriptions or a map -// of warning names to description(s) -// ensures a warning is generated for each name/description pair +// Accepts a warning name and description or array of descriptions or a map of +// warning names to description(s) ensures a warning is generated for each +// name/description pair. +// The expected messages have to be unique per `expectWarning()` call. function expectWarning(nameOrMap, expected, code) { + if (catchWarning === undefined) { + catchWarning = {}; + process.on('warning', (warning) => catchWarning[warning.name](warning)); + } if (typeof nameOrMap === 'string') { - expectWarningByName(nameOrMap, expected, code); + catchWarning[nameOrMap] = _expectWarning(nameOrMap, expected, code); } else { - expectWarningByMap(nameOrMap); + Object.keys(nameOrMap).forEach((name) => { + catchWarning[name] = _expectWarning(name, nameOrMap[name]); + }); } } @@ -759,7 +748,6 @@ module.exports = { mustCallAtLeast, mustNotCall, nodeProcessAborted, - noWarnCode: undefined, PIPE, platformTimeout, printSkipMessage, diff --git a/test/common/index.mjs b/test/common/index.mjs index 068dd35049c301..de9119f37e2f3d 100644 --- a/test/common/index.mjs +++ b/test/common/index.mjs @@ -37,7 +37,6 @@ const { nodeProcessAborted, busyLoop, isAlive, - noWarnCode, expectWarning, expectsError, skipIfInspectorDisabled, @@ -84,7 +83,6 @@ export { nodeProcessAborted, busyLoop, isAlive, - noWarnCode, expectWarning, expectsError, skipIfInspectorDisabled, diff --git a/test/parallel/test-atomics-notify.js b/test/parallel/test-atomics-notify.js index fc59d5aa331084..16dd1bb0c7dac1 100644 --- a/test/parallel/test-atomics-notify.js +++ b/test/parallel/test-atomics-notify.js @@ -1,6 +1,6 @@ 'use strict'; -const { expectWarning, noWarnCode } = require('../common'); +const { expectWarning } = require('../common'); const assert = require('assert'); const { runInNewContext } = require('vm'); @@ -14,6 +14,6 @@ assert.strictEqual(runInNewContext('typeof Atomics.notify'), 'function'); expectWarning( 'Atomics', 'Atomics.wake will be removed in a future version, ' + - 'use Atomics.notify instead.', noWarnCode); + 'use Atomics.notify instead.'); Atomics.wake(new Int32Array(new SharedArrayBuffer(4)), 0, 0); diff --git a/test/parallel/test-console.js b/test/parallel/test-console.js index 7448d62208e65f..e94b6020652463 100644 --- a/test/parallel/test-console.js +++ b/test/parallel/test-console.js @@ -42,14 +42,14 @@ if (common.isMainThread) { common.expectWarning( 'Warning', [ - ['Count for \'noLabel\' does not exist', common.noWarnCode], - ['No such label \'noLabel\' for console.timeLog()', common.noWarnCode], - ['No such label \'noLabel\' for console.timeEnd()', common.noWarnCode], - ['Count for \'default\' does not exist', common.noWarnCode], - ['No such label \'default\' for console.timeLog()', common.noWarnCode], - ['No such label \'default\' for console.timeEnd()', common.noWarnCode], - ['Label \'default\' already exists for console.time()', common.noWarnCode], - ['Label \'test\' already exists for console.time()', common.noWarnCode] + ['Count for \'noLabel\' does not exist'], + ['No such label \'noLabel\' for console.timeLog()'], + ['No such label \'noLabel\' for console.timeEnd()'], + ['Count for \'default\' does not exist'], + ['No such label \'default\' for console.timeLog()'], + ['No such label \'default\' for console.timeEnd()'], + ['Label \'default\' already exists for console.time()'], + ['Label \'test\' already exists for console.time()'] ] ); diff --git a/test/parallel/test-crypto-authenticated.js b/test/parallel/test-crypto-authenticated.js index 4f382eae6e849e..414404511f9064 100644 --- a/test/parallel/test-crypto-authenticated.js +++ b/test/parallel/test-crypto-authenticated.js @@ -50,25 +50,25 @@ const ciphers = crypto.getCiphers(); const expectedWarnings = common.hasFipsCrypto ? [] : [ - ['Use Cipheriv for counter mode of aes-192-gcm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-192-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-192-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-128-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-128-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-128-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-256-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-256-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-256-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-256-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-256-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-256-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-256-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-256-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-256-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-256-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-256-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-256-ccm', common.noWarnCode], - ['Use Cipheriv for counter mode of aes-256-ccm', common.noWarnCode] + ['Use Cipheriv for counter mode of aes-192-gcm'], + ['Use Cipheriv for counter mode of aes-192-ccm'], + ['Use Cipheriv for counter mode of aes-192-ccm'], + ['Use Cipheriv for counter mode of aes-128-ccm'], + ['Use Cipheriv for counter mode of aes-128-ccm'], + ['Use Cipheriv for counter mode of aes-128-ccm'], + ['Use Cipheriv for counter mode of aes-256-ccm'], + ['Use Cipheriv for counter mode of aes-256-ccm'], + ['Use Cipheriv for counter mode of aes-256-ccm'], + ['Use Cipheriv for counter mode of aes-256-ccm'], + ['Use Cipheriv for counter mode of aes-256-ccm'], + ['Use Cipheriv for counter mode of aes-256-ccm'], + ['Use Cipheriv for counter mode of aes-256-ccm'], + ['Use Cipheriv for counter mode of aes-256-ccm'], + ['Use Cipheriv for counter mode of aes-256-ccm'], + ['Use Cipheriv for counter mode of aes-256-ccm'], + ['Use Cipheriv for counter mode of aes-256-ccm'], + ['Use Cipheriv for counter mode of aes-256-ccm'], + ['Use Cipheriv for counter mode of aes-256-ccm'] ]; const expectedDeprecationWarnings = [ diff --git a/test/parallel/test-crypto-cipher-decipher.js b/test/parallel/test-crypto-cipher-decipher.js index 12fa98f3b27228..dfa01e2422c23b 100644 --- a/test/parallel/test-crypto-cipher-decipher.js +++ b/test/parallel/test-crypto-cipher-decipher.js @@ -12,7 +12,7 @@ const assert = require('assert'); common.expectWarning({ Warning: [ - ['Use Cipheriv for counter mode of aes-256-gcm', common.noWarnCode] + ['Use Cipheriv for counter mode of aes-256-gcm'] ], DeprecationWarning: [ ['crypto.createCipher is deprecated.', 'DEP0106'] diff --git a/test/parallel/test-dns-lookup.js b/test/parallel/test-dns-lookup.js index 3da4e9f58db95c..951e7e17a98b82 100644 --- a/test/parallel/test-dns-lookup.js +++ b/test/parallel/test-dns-lookup.js @@ -21,21 +21,19 @@ cares.getaddrinfo = () => internalBinding('uv').UV_ENOENT; common.expectsError(() => dnsPromises.lookup(1, {}), err); } +// This also verifies different expectWarning notations. common.expectWarning({ // For 'internal/test/binding' module. 'internal/test/binding': [ 'These APIs are for internal testing only. Do not use them.' ], // For dns.promises. - 'ExperimentalWarning': [ - 'The dns.promises API is experimental' - ], + 'ExperimentalWarning': 'The dns.promises API is experimental', // For calling `dns.lookup` with falsy `hostname`. - 'DeprecationWarning': [ - 'The provided hostname "false" is not a valid ' + - 'hostname, and is supported in the dns module solely for compatibility.', - 'DEP0118', - ], + 'DeprecationWarning': { + DEP0118: 'The provided hostname "false" is not a valid ' + + 'hostname, and is supported in the dns module solely for compatibility.' + } }); common.expectsError(() => { diff --git a/test/parallel/test-fs-filehandle.js b/test/parallel/test-fs-filehandle.js index a56b39f7c92526..30f42a60f044b3 100644 --- a/test/parallel/test-fs-filehandle.js +++ b/test/parallel/test-fs-filehandle.js @@ -21,12 +21,10 @@ let fdnum; common.expectWarning({ 'internal/test/binding': [ - 'These APIs are for internal testing only. Do not use them.', - common.noWarnCode + 'These APIs are for internal testing only. Do not use them.' ], 'Warning': [ - `Closing file descriptor ${fdnum} on garbage collection`, - common.noWarnCode + `Closing file descriptor ${fdnum} on garbage collection` ] }); diff --git a/test/parallel/test-https-strict.js b/test/parallel/test-https-strict.js index 6c1d6325eac176..a7f4b80716c917 100644 --- a/test/parallel/test-https-strict.js +++ b/test/parallel/test-https-strict.js @@ -32,8 +32,7 @@ common.expectWarning( 'Warning', 'Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to \'0\' ' + 'makes TLS connections and HTTPS requests insecure by disabling ' + - 'certificate verification.', - common.noWarnCode + 'certificate verification.' ); const assert = require('assert'); diff --git a/test/parallel/test-process-emit-warning-from-native.js b/test/parallel/test-process-emit-warning-from-native.js index 530b7a24047b92..ee7e731935dc9d 100644 --- a/test/parallel/test-process-emit-warning-from-native.js +++ b/test/parallel/test-process-emit-warning-from-native.js @@ -16,7 +16,7 @@ const key = '0123456789'; ['crypto.createCipher is deprecated.', 'DEP0106'] ], Warning: [ - ['Use Cipheriv for counter mode of aes-256-gcm', common.noWarnCode] + ['Use Cipheriv for counter mode of aes-256-gcm'] ] }); diff --git a/test/parallel/test-promises-unhandled-proxy-rejections.js b/test/parallel/test-promises-unhandled-proxy-rejections.js index 83062e9520165b..b3cf5719cb9ab0 100644 --- a/test/parallel/test-promises-unhandled-proxy-rejections.js +++ b/test/parallel/test-promises-unhandled-proxy-rejections.js @@ -12,7 +12,7 @@ const expectedPromiseWarning = ['Unhandled promise rejection. ' + 'This error originated either by throwing ' + 'inside of an async function without a catch ' + 'block, or by rejecting a promise which was ' + - 'not handled with .catch(). (rejection id: 1)', common.noWarnCode]; + 'not handled with .catch(). (rejection id: 1)']; function throwErr() { throw new Error('Error from proxy'); diff --git a/test/parallel/test-promises-unhandled-symbol-rejections.js b/test/parallel/test-promises-unhandled-symbol-rejections.js index 2102de81918bd7..d777a13e62e984 100644 --- a/test/parallel/test-promises-unhandled-symbol-rejections.js +++ b/test/parallel/test-promises-unhandled-symbol-rejections.js @@ -3,7 +3,7 @@ const common = require('../common'); common.disableCrashOnUnhandledRejection(); -const expectedValueWarning = ['Symbol()', common.noWarnCode]; +const expectedValueWarning = ['Symbol()']; const expectedDeprecationWarning = ['Unhandled promise rejections are ' + 'deprecated. In the future, promise ' + 'rejections that are not handled will ' + @@ -13,13 +13,13 @@ const expectedPromiseWarning = ['Unhandled promise rejection. ' + 'This error originated either by throwing ' + 'inside of an async function without a catch ' + 'block, or by rejecting a promise which was ' + - 'not handled with .catch(). (rejection id: 1)', common.noWarnCode]; + 'not handled with .catch(). (rejection id: 1)']; common.expectWarning({ DeprecationWarning: expectedDeprecationWarning, UnhandledPromiseRejectionWarning: [ - expectedPromiseWarning, - expectedValueWarning + expectedValueWarning, + expectedPromiseWarning ], }); diff --git a/test/parallel/test-tls-dhe.js b/test/parallel/test-tls-dhe.js index 86130aff262ab5..868686335077a5 100644 --- a/test/parallel/test-tls-dhe.js +++ b/test/parallel/test-tls-dhe.js @@ -41,8 +41,7 @@ const ciphers = 'DHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; // Test will emit a warning because the DH parameter size is < 2048 bits common.expectWarning('SecurityWarning', - 'DH parameter is less than 2048 bits', - common.noWarnCode); + 'DH parameter is less than 2048 bits'); function loadDHParam(n) { const params = [`dh${n}.pem`]; diff --git a/test/parallel/test-trace-events-api.js b/test/parallel/test-trace-events-api.js index 2810ac0dd0f6d7..346f943b9c36c5 100644 --- a/test/parallel/test-trace-events-api.js +++ b/test/parallel/test-trace-events-api.js @@ -99,8 +99,7 @@ if (isChild) { common.expectWarning( 'Warning', 'Possible trace_events memory leak detected. There are more than ' + - '10 enabled Tracing objects.', - common.noWarnCode); + '10 enabled Tracing objects.'); for (let n = 0; n < 10; n++) { const tracing = createTracing({ categories: [ `a${n}` ] }); tracing.enable(); diff --git a/test/parallel/test-warn-sigprof.js b/test/parallel/test-warn-sigprof.js index c3986a27be1703..36b0db78d82687 100644 --- a/test/parallel/test-warn-sigprof.js +++ b/test/parallel/test-warn-sigprof.js @@ -13,7 +13,6 @@ if (common.isWindows) common.skipIfWorker(); // Worker inspector never has a server running common.expectWarning('Warning', - 'process.on(SIGPROF) is reserved while debugging', - common.noWarnCode); + 'process.on(SIGPROF) is reserved while debugging'); process.on('SIGPROF', () => {}); diff --git a/test/parallel/test-worker-message-port-transfer-target.js b/test/parallel/test-worker-message-port-transfer-target.js index 8e6354d8269771..e2e4a066221805 100644 --- a/test/parallel/test-worker-message-port-transfer-target.js +++ b/test/parallel/test-worker-message-port-transfer-target.js @@ -11,8 +11,7 @@ const arrayBuf = new ArrayBuffer(10); common.expectWarning('Warning', 'The target port was posted to itself, and the ' + - 'communication channel was lost', - common.noWarnCode); + 'communication channel was lost'); port2.onmessage = common.mustNotCall(); port2.postMessage(null, [port1, arrayBuf]);