Skip to content

assert: allow arbitrary argument order in match() and doesNotMatch() #41007

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions doc/api/assert.md
Original file line number Diff line number Diff line change
Expand Up @@ -890,11 +890,16 @@ parameter is an instance of an [`Error`][] then it will be thrown instead of the

## `assert.doesNotMatch(string, regexp[, message])`

## `assert.doesNotMatch(regexp, string[, message])`

<!-- YAML
added:
- v13.6.0
- v12.16.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/41007
description: The argument order may now be "regexp, string".
- version: v16.0.0
pr-url: https://github.com/nodejs/node/pull/38111
description: This API is no longer experimental.
Expand Down Expand Up @@ -1415,11 +1420,16 @@ let err;

## `assert.match(string, regexp[, message])`

## `assert.match(regexp, string[, message])`

<!-- YAML
added:
- v13.6.0
- v12.16.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/41007
description: The argument order may now be "regexp, string".
- version: v16.0.0
pr-url: https://github.com/nodejs/node/pull/38111
description: This API is no longer experimental.
Expand Down
30 changes: 25 additions & 5 deletions lib/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -989,10 +989,17 @@ assert.ifError = function ifError(err) {

function internalMatch(string, regexp, message, fn) {
if (!isRegExp(regexp)) {
throw new ERR_INVALID_ARG_TYPE(
'regexp', 'RegExp', regexp
);
if (isRegExp(string)) {
const tmp = string;
string = regexp;
regexp = tmp;
} else {
throw new ERR_INVALID_ARG_TYPE(
'regexp', 'RegExp', regexp
);
}
}

const match = fn.name === 'match';
if (typeof string !== 'string' ||
RegExpPrototypeTest(regexp, string) !== match) {
Expand All @@ -1002,8 +1009,21 @@ function internalMatch(string, regexp, message, fn) {

const generatedMessage = !message;

// 'The input was expected to not match the regular expression ' +
message = message || (typeof string !== 'string' ?
if (!message) {
if (typeof string !== 'string') {
message = 'The "string" argument must be of type string. ' +
`Received type ${typeof string} (${inspect(string)})`;
} else {
if (match) {
message = 'The input did not match the regular expression';
} else {
message = 'The input was expected to not match the regular ' +
'expression';
}
message += ` ${inspect(regexp)}. Input:\n\n${inspect(string)}\n`;
}
}
message ||= (typeof string !== 'string' ?
'The "string" argument must be of type string. Received type ' +
`${typeof string} (${inspect(string)})` :
(match ?
Expand Down
52 changes: 49 additions & 3 deletions test/parallel/test-assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -1372,11 +1372,34 @@ assert.throws(
// Multiple assert.match() tests.
{
assert.throws(
() => assert.match(/abc/, 'string'),
() => assert.match(/abc/, 5),
{
actual: 5,
expected: /abc/,
operator: 'match',
message: 'The "string" argument must be of type string. ' +
'Received type number (5)',
generatedMessage: true
}
);
assert.throws(
() => assert.match(5, 'string'),
{
name: 'TypeError',
code: 'ERR_INVALID_ARG_TYPE',
message: 'The "regexp" argument must be an instance of RegExp. ' +
"Received type string ('string')"
"Received type string ('string')",
}
);
assert.throws(
() => assert.match(/abc/, 'string'),
{
actual: 'string',
expected: /abc/,
operator: 'match',
message: 'The input did not match the regular expression /abc/. ' +
"Input:\n\n'string'\n",
generatedMessage: true
}
);
assert.throws(
Expand Down Expand Up @@ -1422,8 +1445,31 @@ assert.throws(
// Multiple assert.doesNotMatch() tests.
{
assert.throws(
() => assert.doesNotMatch(/abc/, 'string'),
() => assert.doesNotMatch(/string/, 5),
{
actual: 5,
expected: /string/,
operator: 'doesNotMatch',
message: 'The "string" argument must be of type string. ' +
'Received type number (5)',
generatedMessage: true
}
);
assert.throws(
() => assert.doesNotMatch(/string/, 'string'),
{
actual: 'string',
expected: /string/,
operator: 'doesNotMatch',
message: 'The input was expected to not match the regular expression ' +
"/string/. Input:\n\n'string'\n",
generatedMessage: true
}
);
assert.throws(
() => assert.doesNotMatch(5, 'string'),
{
name: 'TypeError',
code: 'ERR_INVALID_ARG_TYPE',
message: 'The "regexp" argument must be an instance of RegExp. ' +
"Received type string ('string')"
Expand Down