mirror of https://github.com/nodejs/node.git
assert: accept regular expressions to validate
This makes sure regular expressions on validation objects validate against strings when used with `assert.throws` and `assert.rejects`. PR-URL: https://github.com/nodejs/node/pull/20485 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com>
This commit is contained in:
parent
81b99da96e
commit
cf7be86cd9
|
@ -1070,18 +1070,26 @@ changes:
|
|||
Expects the function `block` to throw an error.
|
||||
|
||||
If specified, `error` can be a [`Class`][], [`RegExp`][], a validation function,
|
||||
an object where each property will be tested for, or an instance of error where
|
||||
each property will be tested for including the non-enumerable `message` and
|
||||
`name` properties.
|
||||
a validation object where each property will be tested for strict deep equality,
|
||||
or an instance of error where each property will be tested for strict deep
|
||||
equality including the non-enumerable `message` and `name` properties. When
|
||||
using an object, it is also possible to use a regular expression, when
|
||||
validating against a string property. See below for examples.
|
||||
|
||||
If specified, `message` will be the message provided by the `AssertionError` if
|
||||
the block fails to throw.
|
||||
|
||||
Custom error object / error instance:
|
||||
Custom validation object / error instance:
|
||||
|
||||
```js
|
||||
const err = new TypeError('Wrong value');
|
||||
err.code = 404;
|
||||
err.foo = 'bar';
|
||||
err.info = {
|
||||
nested: true,
|
||||
baz: 'text'
|
||||
};
|
||||
err.reg = /abc/i;
|
||||
|
||||
assert.throws(
|
||||
() => {
|
||||
|
@ -1089,8 +1097,38 @@ assert.throws(
|
|||
},
|
||||
{
|
||||
name: 'TypeError',
|
||||
message: 'Wrong value'
|
||||
// Note that only properties on the error object will be tested!
|
||||
message: 'Wrong value',
|
||||
info: {
|
||||
nested: true,
|
||||
baz: 'text'
|
||||
}
|
||||
// Note that only properties on the validation object will be tested for.
|
||||
// Using nested objects requires all properties to be present. Otherwise
|
||||
// the validation is going to fail.
|
||||
}
|
||||
);
|
||||
|
||||
// Using regular expressions to validate error properties:
|
||||
assert.throws(
|
||||
() => {
|
||||
throw err;
|
||||
},
|
||||
{
|
||||
// The `name` and `message` properties are strings and using regular
|
||||
// expressions on those will match against the string. If they fail, an
|
||||
// error is thrown.
|
||||
name: /^TypeError$/,
|
||||
message: /Wrong/,
|
||||
foo: 'bar',
|
||||
info: {
|
||||
nested: true,
|
||||
// It is not possible to use regular expressions for nested properties!
|
||||
baz: 'text'
|
||||
},
|
||||
// The `reg` property contains a regular expression and only if the
|
||||
// validation object contains an identical regular expression, it is going
|
||||
// to pass.
|
||||
reg: /abc/i
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ const {
|
|||
}
|
||||
} = require('internal/errors');
|
||||
const { openSync, closeSync, readSync } = require('fs');
|
||||
const { inspect, types: { isPromise } } = require('util');
|
||||
const { inspect, types: { isPromise, isRegExp } } = require('util');
|
||||
const { EOL } = require('os');
|
||||
const { NativeModule } = require('internal/bootstrap/loaders');
|
||||
|
||||
|
@ -362,10 +362,18 @@ assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
|
|||
};
|
||||
|
||||
class Comparison {
|
||||
constructor(obj, keys) {
|
||||
constructor(obj, keys, actual) {
|
||||
for (const key of keys) {
|
||||
if (key in obj)
|
||||
this[key] = obj[key];
|
||||
if (key in obj) {
|
||||
if (actual !== undefined &&
|
||||
typeof actual[key] === 'string' &&
|
||||
isRegExp(obj[key]) &&
|
||||
obj[key].test(actual[key])) {
|
||||
this[key] = actual[key];
|
||||
} else {
|
||||
this[key] = obj[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -375,7 +383,7 @@ function compareExceptionKey(actual, expected, key, message, keys) {
|
|||
if (!message) {
|
||||
// Create placeholder objects to create a nice output.
|
||||
const a = new Comparison(actual, keys);
|
||||
const b = new Comparison(expected, keys);
|
||||
const b = new Comparison(expected, keys, actual);
|
||||
|
||||
const tmpLimit = Error.stackTraceLimit;
|
||||
Error.stackTraceLimit = 0;
|
||||
|
@ -415,6 +423,11 @@ function expectedException(actual, expected, msg) {
|
|||
keys.push('name', 'message');
|
||||
}
|
||||
for (const key of keys) {
|
||||
if (typeof actual[key] === 'string' &&
|
||||
isRegExp(expected[key]) &&
|
||||
expected[key].test(actual[key])) {
|
||||
continue;
|
||||
}
|
||||
compareExceptionKey(actual, expected, key, msg, keys);
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -914,3 +914,29 @@ assert.throws(
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
assert.throws(
|
||||
() => { throw new TypeError('foobar'); },
|
||||
{
|
||||
message: /foo/,
|
||||
name: /^TypeError$/
|
||||
}
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
() => assert.throws(
|
||||
() => { throw new TypeError('foobar'); },
|
||||
{
|
||||
message: /fooa/,
|
||||
name: /^TypeError$/
|
||||
}
|
||||
),
|
||||
{
|
||||
message: `${start}\n${actExp}\n\n` +
|
||||
' Comparison {\n' +
|
||||
"- message: 'foobar',\n" +
|
||||
'+ message: /fooa/,\n' +
|
||||
" name: 'TypeError'\n" +
|
||||
' }'
|
||||
}
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue