test: add deprecation code to expectWarning

This commit adds a deprecation code to expectWarning and updates the
function to check the passed code against the code property on the
warning object.

Not all warnings have a deprecation code so for those that don't an
explicit code of common.noWarnCode is required. Passing this skips the
assertion of the code.

PR-URL: https://github.com/nodejs/node/pull/19474
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
This commit is contained in:
Daniel Bevenius 2018-03-20 12:39:46 +01:00
parent ebbf393600
commit 8fb4ea9f75
29 changed files with 101 additions and 59 deletions

View File

@ -108,11 +108,17 @@ Indicates if there is more than 1gb of total memory.
returned function has not been called exactly `exact` number of times when the returned function has not been called exactly `exact` number of times when the
test is complete, then the test will fail. test is complete, then the test will fail.
### expectWarning(name, expected) ### expectWarning(name, expected, code)
* `name` [&lt;string>] * `name` [&lt;string>]
* `expected` [&lt;string>] | [&lt;Array>] * `expected` [&lt;string>] | [&lt;Array>]
* `code` [&lt;string>]
Tests whether `name` and `expected` are part of a raised warning. 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.
### noWarnCode
See `common.expectWarning()` for usage.
### fileExists(pathname) ### fileExists(pathname)
* pathname [&lt;string>] * pathname [&lt;string>]

View File

@ -611,20 +611,32 @@ exports.isAlive = function isAlive(pid) {
} }
}; };
function expectWarning(name, expectedMessages) { exports.noWarnCode = 'no_expected_warning_code';
function expectWarning(name, expected) {
const map = new Map(expected);
return exports.mustCall((warning) => { return exports.mustCall((warning) => {
assert.strictEqual(warning.name, name); assert.strictEqual(warning.name, name);
assert.ok(expectedMessages.includes(warning.message), assert.ok(map.has(warning.message),
`unexpected error message: "${warning.message}"`); `unexpected error message: "${warning.message}"`);
const code = map.get(warning.message);
if (code === undefined) {
throw new Error('An error code must be specified or use ' +
'common.noWarnCode if there is no error code. The error ' +
`code for this warning was ${warning.code}`);
}
if (code !== exports.noWarnCode) {
assert.strictEqual(warning.code, code);
}
// Remove a warning message after it is seen so that we guarantee that we // Remove a warning message after it is seen so that we guarantee that we
// get each message only once. // get each message only once.
expectedMessages.splice(expectedMessages.indexOf(warning.message), 1); map.delete(expected);
}, expectedMessages.length); }, map.size);
} }
function expectWarningByName(name, expected) { function expectWarningByName(name, expected, code) {
if (typeof expected === 'string') { if (typeof expected === 'string') {
expected = [expected]; expected = [[expected, code]];
} }
process.on('warning', expectWarning(name, expected)); process.on('warning', expectWarning(name, expected));
} }
@ -633,8 +645,15 @@ function expectWarningByMap(warningMap) {
const catchWarning = {}; const catchWarning = {};
Object.keys(warningMap).forEach((name) => { Object.keys(warningMap).forEach((name) => {
let expected = warningMap[name]; let expected = warningMap[name];
if (typeof expected === 'string') { if (!Array.isArray(expected)) {
expected = [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); catchWarning[name] = expectWarning(name, expected);
}); });
@ -644,9 +663,9 @@ function expectWarningByMap(warningMap) {
// accepts a warning name and description or array of descriptions or a map // accepts a warning name and description or array of descriptions or a map
// of warning names to description(s) // of warning names to description(s)
// ensures a warning is generated for each name/description pair // ensures a warning is generated for each name/description pair
exports.expectWarning = function(nameOrMap, expected) { exports.expectWarning = function(nameOrMap, expected, code) {
if (typeof nameOrMap === 'string') { if (typeof nameOrMap === 'string') {
expectWarningByName(nameOrMap, expected); expectWarningByName(nameOrMap, expected, code);
} else { } else {
expectWarningByMap(nameOrMap); expectWarningByMap(nameOrMap);
} }

View File

@ -6,7 +6,8 @@ const assert = require('assert');
common.expectWarning( common.expectWarning(
'DeprecationWarning', 'DeprecationWarning',
'assert.fail() with more than one argument is deprecated. ' + 'assert.fail() with more than one argument is deprecated. ' +
'Please use assert.strictEqual() instead or only pass a message.' 'Please use assert.strictEqual() instead or only pass a message.',
'DEP0094'
); );
// Two args only, operator defaults to '!=' // Two args only, operator defaults to '!='

View File

@ -9,7 +9,7 @@ const bufferWarning = 'The Buffer() and new Buffer() constructors are not ' +
'Buffer.allocUnsafe(), or Buffer.from() construction ' + 'Buffer.allocUnsafe(), or Buffer.from() construction ' +
'methods instead.'; 'methods instead.';
common.expectWarning('DeprecationWarning', bufferWarning); common.expectWarning('DeprecationWarning', bufferWarning, 'DEP0005');
// This is used to make sure that a warning is only emitted once even though // This is used to make sure that a warning is only emitted once even though
// `new Buffer()` is called twice. // `new Buffer()` is called twice.

View File

@ -9,7 +9,7 @@ const oldSpawnSync = internalCp.spawnSync;
{ {
const msg = 'child_process: options.customFds option is deprecated. ' + const msg = 'child_process: options.customFds option is deprecated. ' +
'Use options.stdio instead.'; 'Use options.stdio instead.';
common.expectWarning('DeprecationWarning', msg); common.expectWarning('DeprecationWarning', msg, 'DEP0006');
const customFds = [-1, process.stdout.fd, process.stderr.fd]; const customFds = [-1, process.stdout.fd, process.stderr.fd];
internalCp.spawnSync = common.mustCall(function(opts) { internalCp.spawnSync = common.mustCall(function(opts) {

View File

@ -336,13 +336,16 @@ const errMessages = {
const ciphers = crypto.getCiphers(); const ciphers = crypto.getCiphers();
const expectedWarnings = common.hasFipsCrypto ? const expectedWarnings = common.hasFipsCrypto ?
[] : ['Use Cipheriv for counter mode of aes-192-gcm']; [] : [['Use Cipheriv for counter mode of aes-192-gcm',
common.noWarnCode]];
const expectedDeprecationWarnings = [0, 1, 2, 6, 9, 10, 11, 17] const expectedDeprecationWarnings = [0, 1, 2, 6, 9, 10, 11, 17]
.map((i) => `Permitting authentication tag lengths of ${i} bytes is ` + .map((i) => [`Permitting authentication tag lengths of ${i} bytes is ` +
'deprecated. Valid GCM tag lengths are 4, 8, 12, 13, 14, 15, 16.'); 'deprecated. Valid GCM tag lengths are 4, 8, 12, 13, 14, 15, 16.',
'DEP0090']);
expectedDeprecationWarnings.push('crypto.DEFAULT_ENCODING is deprecated.'); expectedDeprecationWarnings.push(['crypto.DEFAULT_ENCODING is deprecated.',
'DEP0091']);
common.expectWarning({ common.expectWarning({
Warning: expectedWarnings, Warning: expectedWarnings,

View File

@ -236,7 +236,8 @@ testCipher2(Buffer.from('0123456789abcdef'));
const data = Buffer.from('test-crypto-cipher-decipher'); const data = Buffer.from('test-crypto-cipher-decipher');
common.expectWarning('Warning', common.expectWarning('Warning',
'Use Cipheriv for counter mode of aes-256-gcm'); 'Use Cipheriv for counter mode of aes-256-gcm',
common.noWarnCode);
const cipher = crypto.createCipher('aes-256-gcm', key); const cipher = crypto.createCipher('aes-256-gcm', key);
cipher.setAAD(aadbuf); cipher.setAAD(aadbuf);

View File

@ -8,10 +8,12 @@ const crypto = require('crypto');
const tls = require('tls'); const tls = require('tls');
common.expectWarning('DeprecationWarning', [ common.expectWarning('DeprecationWarning', [
'crypto.Credentials is deprecated. Use tls.SecureContext instead.', ['crypto.Credentials is deprecated. Use tls.SecureContext instead.',
'crypto.createCredentials is deprecated. Use tls.createSecureContext ' + 'DEP0011'],
'instead.', ['crypto.createCredentials is deprecated. Use tls.createSecureContext ' +
'crypto.Decipher.finaltol is deprecated. Use crypto.Decipher.final instead.' 'instead.', 'DEP0010'],
['crypto.Decipher.finaltol is deprecated. Use crypto.Decipher.final instead.',
'DEP0105']
]); ]);
// Accessing the deprecated function is enough to trigger the warning event. // Accessing the deprecated function is enough to trigger the warning event.

View File

@ -20,7 +20,8 @@ let fdnum;
common.expectWarning( common.expectWarning(
'Warning', 'Warning',
`Closing file descriptor ${fdnum} on garbage collection` `Closing file descriptor ${fdnum} on garbage collection`,
common.noWarnCode
); );
gc(); // eslint-disable-line no-undef gc(); // eslint-disable-line no-undef

View File

@ -15,7 +15,7 @@ const msg = 'Using fs.truncate with a file descriptor is deprecated.' +
' Please use fs.ftruncate with a file descriptor instead.'; ' Please use fs.ftruncate with a file descriptor instead.';
common.expectWarning('DeprecationWarning', msg); common.expectWarning('DeprecationWarning', msg, 'DEP0081');
fs.truncate(fd, 5, common.mustCall(function(err) { fs.truncate(fd, 5, common.mustCall(function(err) {
assert.ok(!err); assert.ok(!err);
assert.strictEqual(fs.readFileSync(filename, 'utf8'), 'hello'); assert.strictEqual(fs.readFileSync(filename, 'utf8'), 'hello');

View File

@ -64,8 +64,8 @@ fs.ftruncateSync(fd);
stat = fs.statSync(filename); stat = fs.statSync(filename);
assert.strictEqual(stat.size, 0); assert.strictEqual(stat.size, 0);
// Check truncateSync // truncateSync
common.expectWarning('DeprecationWarning', msg); common.expectWarning('DeprecationWarning', msg, 'DEP0081');
fs.truncateSync(fd); fs.truncateSync(fd);
fs.closeSync(fd); fs.closeSync(fd);

View File

@ -30,7 +30,7 @@ const server = new net.Server();
const expectedWarning = 'Server.connections property is deprecated. ' + const expectedWarning = 'Server.connections property is deprecated. ' +
'Use Server.getConnections method instead.'; 'Use Server.getConnections method instead.';
common.expectWarning('DeprecationWarning', expectedWarning); common.expectWarning('DeprecationWarning', expectedWarning, 'DEP0020');
// test that server.connections property is no longer enumerable now that it // test that server.connections property is no longer enumerable now that it
// has been marked as deprecated // has been marked as deprecated

View File

@ -20,10 +20,10 @@ performance.maxEntries = 1;
); );
}); });
common.expectWarning('Warning', [ common.expectWarning('Warning', 'Possible perf_hooks memory leak detected. ' +
'Possible perf_hooks memory leak detected. There are 2 entries in the ' + 'There are 2 entries in the ' +
'Performance Timeline. Use the clear methods to remove entries that are no ' + 'Performance Timeline. Use the clear methods to remove entries that are no ' +
'longer needed or set performance.maxEntries equal to a higher value ' + 'longer needed or set performance.maxEntries equal to a higher value ' +
'(currently the maxEntries is 1).']); '(currently the maxEntries is 1).', common.noWarnCode);
performance.mark('test'); performance.mark('test');

View File

@ -4,7 +4,8 @@ const assert = require('assert');
common.expectWarning( common.expectWarning(
'DeprecationWarning', 'DeprecationWarning',
'process.assert() is deprecated. Please use the `assert` module instead.' 'process.assert() is deprecated. Please use the `assert` module instead.',
'DEP0100'
); );
assert.strictEqual(process.assert(1, 'error'), undefined); assert.strictEqual(process.assert(1, 'error'), undefined);

View File

@ -12,7 +12,8 @@ const key = '0123456789';
{ {
common.expectWarning('Warning', common.expectWarning('Warning',
'Use Cipheriv for counter mode of aes-256-gcm'); 'Use Cipheriv for counter mode of aes-256-gcm',
common.noWarnCode);
// Emits regular warning expected by expectWarning() // Emits regular warning expected by expectWarning()
crypto.createCipher('aes-256-gcm', key); crypto.createCipher('aes-256-gcm', key);

View File

@ -8,7 +8,8 @@ common.expectWarning(
'DeprecationWarning', 'DeprecationWarning',
'Assigning any value other than a string, number, or boolean to a ' + 'Assigning any value other than a string, number, or boolean to a ' +
'process.env property is deprecated. Please make sure to convert the value ' + 'process.env property is deprecated. Please make sure to convert the value ' +
'to a string before setting process.env with it.' 'to a string before setting process.env with it.',
'DEP0104'
); );
process.env.ABC = undefined; process.env.ABC = undefined;

View File

@ -1,16 +1,16 @@
'use strict'; 'use strict';
const common = require('../common'); const common = require('../common');
const expectedDeprecationWarning = 'Unhandled promise rejections are ' + const expectedDeprecationWarning = ['Unhandled promise rejections are ' +
'deprecated. In the future, promise ' + 'deprecated. In the future, promise ' +
'rejections that are not handled will ' + 'rejections that are not handled will ' +
'terminate the Node.js process with a ' + 'terminate the Node.js process with a ' +
'non-zero exit code.'; 'non-zero exit code.', 'DEP0018'];
const expectedPromiseWarning = 'Unhandled promise rejection. ' + const expectedPromiseWarning = ['Unhandled promise rejection. ' +
'This error originated either by throwing ' + 'This error originated either by throwing ' +
'inside of an async function without a catch ' + 'inside of an async function without a catch ' +
'block, or by rejecting a promise which was ' + 'block, or by rejecting a promise which was ' +
'not handled with .catch(). (rejection id: 1)'; 'not handled with .catch(). (rejection id: 1)', common.noWarnCode];
function throwErr() { function throwErr() {
throw new Error('Error from proxy'); throw new Error('Error from proxy');

View File

@ -1,17 +1,17 @@
'use strict'; 'use strict';
const common = require('../common'); const common = require('../common');
const expectedValueWarning = 'Symbol()'; const expectedValueWarning = ['Symbol()', common.noWarnCode];
const expectedDeprecationWarning = 'Unhandled promise rejections are ' + const expectedDeprecationWarning = ['Unhandled promise rejections are ' +
'deprecated. In the future, promise ' + 'deprecated. In the future, promise ' +
'rejections that are not handled will ' + 'rejections that are not handled will ' +
'terminate the Node.js process with a ' + 'terminate the Node.js process with a ' +
'non-zero exit code.'; 'non-zero exit code.', common.noWarnCode];
const expectedPromiseWarning = 'Unhandled promise rejection. ' + const expectedPromiseWarning = ['Unhandled promise rejection. ' +
'This error originated either by throwing ' + 'This error originated either by throwing ' +
'inside of an async function without a catch ' + 'inside of an async function without a catch ' +
'block, or by rejecting a promise which was ' + 'block, or by rejecting a promise which was ' +
'not handled with .catch(). (rejection id: 1)'; 'not handled with .catch(). (rejection id: 1)', common.noWarnCode];
common.expectWarning({ common.expectWarning({
DeprecationWarning: expectedDeprecationWarning, DeprecationWarning: expectedDeprecationWarning,

View File

@ -9,7 +9,7 @@ function testParseREPLKeyword() {
const server = repl.start({ prompt: '> ' }); const server = repl.start({ prompt: '> ' });
const warn = 'REPLServer.parseREPLKeyword() is deprecated'; const warn = 'REPLServer.parseREPLKeyword() is deprecated';
common.expectWarning('DeprecationWarning', warn); common.expectWarning('DeprecationWarning', warn, 'DEP0075');
assert.ok(server.parseREPLKeyword('clear')); assert.ok(server.parseREPLKeyword('clear'));
assert.ok(!server.parseREPLKeyword('tacos')); assert.ok(!server.parseREPLKeyword('tacos'));
server.close(); server.close();

View File

@ -9,7 +9,7 @@ function testMemory() {
const server = repl.start({ prompt: '> ' }); const server = repl.start({ prompt: '> ' });
const warn = 'REPLServer.memory() is deprecated'; const warn = 'REPLServer.memory() is deprecated';
common.expectWarning('DeprecationWarning', warn); common.expectWarning('DeprecationWarning', warn, 'DEP0082');
assert.strictEqual(server.memory(), undefined); assert.strictEqual(server.memory(), undefined);
server.close(); server.close();
} }

View File

@ -8,7 +8,7 @@ function testTurnOffEditorMode() {
const server = repl.start({ prompt: '> ' }); const server = repl.start({ prompt: '> ' });
const warn = 'REPLServer.turnOffEditorMode() is deprecated'; const warn = 'REPLServer.turnOffEditorMode() is deprecated';
common.expectWarning('DeprecationWarning', warn); common.expectWarning('DeprecationWarning', warn, 'DEP0078');
server.turnOffEditorMode(); server.turnOffEditorMode();
server.close(); server.close();
} }

View File

@ -29,8 +29,8 @@ const deps = [
]; ];
common.expectWarning('DeprecationWarning', deprecatedModules.map((m) => { common.expectWarning('DeprecationWarning', deprecatedModules.map((m) => {
return `Requiring Node.js-bundled '${m}' module is deprecated. ` + return [`Requiring Node.js-bundled '${m}' module is deprecated. ` +
'Please install the necessary module locally.'; 'Please install the necessary module locally.', 'DEP0084'];
})); }));
for (const m of deprecatedModules) { for (const m of deprecatedModules) {

View File

@ -41,7 +41,8 @@ const ciphers = 'DHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
// Test will emit a warning because the DH parameter size is < 2048 bits // Test will emit a warning because the DH parameter size is < 2048 bits
common.expectWarning('SecurityWarning', common.expectWarning('SecurityWarning',
'DH parameter is less than 2048 bits'); 'DH parameter is less than 2048 bits',
common.noWarnCode);
function loadDHParam(n) { function loadDHParam(n) {
const params = [`dh${n}.pem`]; const params = [`dh${n}.pem`];

View File

@ -48,7 +48,8 @@ const options = {
}; };
common.expectWarning('DeprecationWarning', common.expectWarning('DeprecationWarning',
'{ ecdhCurve: false } is deprecated.'); '{ ecdhCurve: false } is deprecated.',
'DEP0083');
const server = tls.createServer(options, common.mustNotCall()); const server = tls.createServer(options, common.mustNotCall());

View File

@ -8,7 +8,8 @@ const tls = require('tls');
common.expectWarning( common.expectWarning(
'DeprecationWarning', 'DeprecationWarning',
'tls.createSecurePair() is deprecated. Please use tls.TLSSocket instead.' 'tls.createSecurePair() is deprecated. Please use tls.TLSSocket instead.',
'DEP0064'
); );
tls.createSecurePair(); tls.createSecurePair();

View File

@ -59,7 +59,8 @@ common.restoreStderr();
{ {
common.expectWarning('DeprecationWarning', common.expectWarning('DeprecationWarning',
'tls.parseCertString() is deprecated. ' + 'tls.parseCertString() is deprecated. ' +
'Please use querystring.parse() instead.'); 'Please use querystring.parse() instead.',
'DEP0076');
const ret = tls.parseCertString('foo=bar'); const ret = tls.parseCertString('foo=bar');
assert.deepStrictEqual(ret, { __proto__: null, foo: 'bar' }); assert.deepStrictEqual(ret, { __proto__: null, foo: 'bar' });

View File

@ -11,7 +11,8 @@ const util = require('util');
// `common.expectWarning` will expect the warning exactly one time only // `common.expectWarning` will expect the warning exactly one time only
common.expectWarning( common.expectWarning(
'DeprecationWarning', 'DeprecationWarning',
'Custom inspection function on Objects via .inspect() is deprecated' 'Custom inspection function on Objects via .inspect() is deprecated',
'DEP0079'
); );
util.inspect(target); // should emit deprecation warning util.inspect(target); // should emit deprecation warning
util.inspect(target); // should not emit deprecation warning util.inspect(target); // should not emit deprecation warning

View File

@ -142,10 +142,10 @@ assert.strictEqual(util.isFunction(), false);
assert.strictEqual(util.isFunction('string'), false); assert.strictEqual(util.isFunction('string'), false);
common.expectWarning('DeprecationWarning', [ common.expectWarning('DeprecationWarning', [
'util.print is deprecated. Use console.log instead.', ['util.print is deprecated. Use console.log instead.', common.noWarnCode],
'util.puts is deprecated. Use console.log instead.', ['util.puts is deprecated. Use console.log instead.', common.noWarnCode],
'util.debug is deprecated. Use console.error instead.', ['util.debug is deprecated. Use console.error instead.', common.noWarnCode],
'util.error is deprecated. Use console.error instead.' ['util.error is deprecated. Use console.error instead.', common.noWarnCode]
]); ]);
util.print('test'); util.print('test');

View File

@ -10,6 +10,7 @@ if (common.isWindows)
common.skip('test does not apply to Windows'); common.skip('test does not apply to Windows');
common.expectWarning('Warning', common.expectWarning('Warning',
'process.on(SIGPROF) is reserved while debugging'); 'process.on(SIGPROF) is reserved while debugging',
common.noWarnCode);
process.on('SIGPROF', () => {}); process.on('SIGPROF', () => {});