Skip to content
Merged
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
53 changes: 50 additions & 3 deletions assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ const { isPromise, isRegExp } = require('util/').types;
const objectAssign = Object.assign ? Object.assign : require('es6-object-assign').assign;
const objectIs = Object.is ? Object.is : require('object-is');

const RegExpPrototypeTest = require('call-bind/callBound')('RegExp.prototype.test');

const errorCache = new Map();

let isDeepEqual;
Expand Down Expand Up @@ -308,7 +310,7 @@ class Comparison {
if (actual !== undefined &&
typeof actual[key] === 'string' &&
isRegExp(obj[key]) &&
obj[key].test(actual[key])
RegExpPrototypeTest(obj[key], actual[key])
) {
this[key] = actual[key];
} else {
Expand Down Expand Up @@ -350,7 +352,7 @@ function compareExceptionKey(actual, expected, key, message, keys, fn) {
function expectedException(actual, expected, msg, fn) {
if (typeof expected !== 'function') {
if (isRegExp(expected))
return expected.test(actual);
return RegExpPrototypeTest(expected, actual);
// assert.doesNotThrow does not accept objects.
if (arguments.length === 2) {
throw new ERR_INVALID_ARG_TYPE(
Expand Down Expand Up @@ -385,7 +387,7 @@ function expectedException(actual, expected, msg, fn) {
if (
typeof actual[key] === 'string' &&
isRegExp(expected[key]) &&
expected[key].test(actual[key])
RegExpPrototypeTest(expected[key], actual[key])
) {
return;
}
Expand Down Expand Up @@ -596,6 +598,51 @@ assert.ifError = function ifError(err) {
}
};

// Currently in sync with Node.js lib/assert.js
// https://github.com/nodejs/node/commit/2a871df3dfb8ea663ef5e1f8f62701ec51384ecb
function internalMatch(string, regexp, message, fn, fnName) {
if (!isRegExp(regexp)) {
throw new ERR_INVALID_ARG_TYPE(
'regexp', 'RegExp', regexp
);
}
const match = fnName === 'match';
if (typeof string !== 'string' ||
RegExpPrototypeTest(regexp, string) !== match) {
if (message instanceof Error) {
throw message;
}

const generatedMessage = !message;

// 'The input was expected to not match the regular expression ' +
message = message || (typeof string !== 'string' ?
'The "string" argument must be of type string. Received type ' +
`${typeof string} (${inspect(string)})` :
(match ?
'The input did not match the regular expression ' :
'The input was expected to not match the regular expression ') +
`${inspect(regexp)}. Input:\n\n${inspect(string)}\n`);
const err = new AssertionError({
actual: string,
expected: regexp,
message,
operator: fnName,
stackStartFn: fn
});
err.generatedMessage = generatedMessage;
throw err;
}
}

assert.match = function match(string, regexp, message) {
internalMatch(string, regexp, message, match, 'match');
};

assert.doesNotMatch = function doesNotMatch(string, regexp, message) {
internalMatch(string, regexp, message, doesNotMatch, 'doesNotMatch');
};

// Expose a strict only variant of assert
function strict(...args) {
innerOk(strict, args.length, ...args);
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"tape": "^4.10.1"
},
"dependencies": {
"call-bind": "^1.0.2",
"es6-object-assign": "^1.1.0",
"is-nan": "^1.2.1",
"object-is": "^1.0.1",
Expand Down
1 change: 1 addition & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const testPaths = [
['test-assert-fail-deprecation.js', () => require('./test/parallel/test-assert-fail-deprecation.js')],
['test-assert-fail.js', () => require('./test/parallel/test-assert-fail.js')],
['test-assert-if-error.js', () => require('./test/parallel/test-assert-if-error.js')],
['test-assert-match.js', () => require('./test/parallel/test-assert-match.js')],
['test-assert-typedarray-deepequal.js', () => require('./test/parallel/test-assert-typedarray-deepequal.js')],
['test-assert.js', () => require('./test/parallel/test-assert.js')],
['test-assert-colors.js', () => require('./test/pseudo-tty/test-assert-colors.js')],
Expand Down
105 changes: 105 additions & 0 deletions test/parallel/test-assert-match.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Currently in sync with Node.js test/parallel/test-assert.js
// https://github.com/nodejs/node/commit/2a871df3dfb8ea663ef5e1f8f62701ec51384ecb

'use strict';

require('../common');
const assert = require('../../assert');

// Multiple assert.match() tests.
{
assert.throws(
() => assert.match(/abc/, 'string'),
{
code: 'ERR_INVALID_ARG_TYPE',
message: 'The "regexp" argument must be of type RegExp. Received type string'
}
);
assert.throws(
() => assert.match('string', /abc/),
{
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(
() => assert.match('string', /abc/, 'foobar'),
{
actual: 'string',
expected: /abc/,
operator: 'match',
message: 'foobar',
generatedMessage: false
}
);
const errorMessage = new RangeError('foobar');
assert.throws(
() => assert.match('string', /abc/, errorMessage),
errorMessage
);
assert.throws(
() => assert.match({ abc: 123 }, /abc/),
{
actual: { abc: 123 },
expected: /abc/,
operator: 'match',
message: 'The "string" argument must be of type string. ' +
'Received type object ({ abc: 123 })',
generatedMessage: true
}
);
assert.match('I will pass', /pass$/);
}

// Multiple assert.doesNotMatch() tests.
{
assert.throws(
() => assert.doesNotMatch(/abc/, 'string'),
{
code: 'ERR_INVALID_ARG_TYPE',
message: 'The "regexp" argument must be of type RegExp. Received type string'
}
);
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('string', /string/, 'foobar'),
{
actual: 'string',
expected: /string/,
operator: 'doesNotMatch',
message: 'foobar',
generatedMessage: false
}
);
const errorMessage = new RangeError('foobar');
assert.throws(
() => assert.doesNotMatch('string', /string/, errorMessage),
errorMessage
);
assert.throws(
() => assert.doesNotMatch({ abc: 123 }, /abc/),
{
actual: { abc: 123 },
expected: /abc/,
operator: 'doesNotMatch',
message: 'The "string" argument must be of type string. ' +
'Received type object ({ abc: 123 })',
generatedMessage: true
}
);
assert.doesNotMatch('I will pass', /different$/);
}