Skip to content
Permalink
Browse files

util: make inspect aware of RegExp subclasses and null prototype

This adds support for inspect to distinguish regular expression
subclasses and ones with null prototype from "normal" regular
expressions.

PR-URL: #25192
Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information...
BridgeAR authored and targos committed Dec 23, 2018
1 parent 58af085 commit 73f3a1c4e632ec4a2eb5915b924094e538316d33
Showing with 39 additions and 13 deletions.
  1. +5 −2 lib/internal/util/inspect.js
  2. +1 −1 test/parallel/test-assert-deep.js
  3. +33 −10 test/parallel/test-util-inspect.js
@@ -634,9 +634,12 @@ function formatRaw(ctx, value, recurseTimes) {
base = `[${name}]`;
} else if (isRegExp(value)) {
// Make RegExps say that they are RegExps
base = regExpToString(constructor !== null ? value : new RegExp(value));
const prefix = getPrefix(constructor, tag, 'RegExp');
if (prefix !== 'RegExp ')
base = `${prefix}${base}`;
if (keys.length === 0 || recurseTimes < 0)
return ctx.stylize(regExpToString(value), 'regexp');
base = `${regExpToString(value)}`;
return ctx.stylize(base, 'regexp');
} else if (isDate(value)) {
// Make dates with properties first say the date
if (keys.length === 0) {
@@ -149,7 +149,7 @@ assert.throws(
{
code: 'ERR_ASSERTION',
message: `${defaultMsgStartFull}\n\n` +
"+ /test/\n- /test/ {\n- '0': '1'\n- }"
"+ /test/\n- MyRegExp /test/ {\n- '0': '1'\n- }"
}
);

@@ -1580,15 +1580,7 @@ assert.strictEqual(util.inspect('"\''), '`"\'`');
// eslint-disable-next-line no-template-curly-in-string
assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
{
assert.strictEqual(
util.inspect(Object.setPrototypeOf(/a/, null)),
'/undefined/undefined'
);
}
// Verify that throwing in valueOf and having no prototype still produces nice
// results.
// Verify that throwing in valueOf and toString still produces nice results.
[
[new String(55), "[String: '55']"],
[new Boolean(true), '[Boolean: true]'],
@@ -1609,6 +1601,7 @@ assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
[new Promise((resolve) => setTimeout(resolve, 10)), 'Promise { <pending> }'],
[new WeakSet(), 'WeakSet { <items unknown> }'],
[new WeakMap(), 'WeakMap { <items unknown> }'],
[/foobar/g, '/foobar/g']
].forEach(([value, expected]) => {
Object.defineProperty(value, 'valueOf', {
get() {
@@ -1628,6 +1621,7 @@ assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
assert.notStrictEqual(util.inspect(value), expected);
});
// Verify that having no prototype still produces nice results.
[
[[1, 3, 4], '[Array: null prototype] [ 1, 3, 4 ]'],
[new Set([1, 2]), '[Set: null prototype] { 1, 2 }'],
@@ -1652,7 +1646,8 @@ assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
'[DataView: null prototype] {\n byteLength: undefined,\n ' +
'byteOffset: undefined,\n buffer: undefined }'],
[new SharedArrayBuffer(2), '[SharedArrayBuffer: null prototype] ' +
'{ byteLength: undefined }']
'{ byteLength: undefined }'],
[/foobar/, '[RegExp: null prototype] /foobar/']
].forEach(([value, expected]) => {
assert.strictEqual(
util.inspect(Object.setPrototypeOf(value, null)),
@@ -1665,6 +1660,34 @@ assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
assert.notStrictEqual(util.inspect(value), expected);
});
// Verify that subclasses with and without prototype produce nice results.
[
[RegExp, ['foobar', 'g'], '/foobar/g']
].forEach(([base, input, rawExpected]) => {
class Foo extends base {}
const value = new Foo(...input);
const symbol = value[Symbol.toStringTag];
const expected = `Foo ${symbol ? `[${symbol}] ` : ''}${rawExpected}`;
const expectedWithoutProto = `[${base.name}: null prototype] ${rawExpected}`;
assert.strictEqual(util.inspect(value), expected);
value.foo = 'bar';
assert.notStrictEqual(util.inspect(value), expected);
delete value.foo;
assert.strictEqual(
util.inspect(Object.setPrototypeOf(value, null)),
expectedWithoutProto
);
value.foo = 'bar';
let res = util.inspect(value);
assert.notStrictEqual(res, expectedWithoutProto);
assert(/foo: 'bar'/.test(res), res);
delete value.foo;
value[Symbol('foo')] = 'yeah';
res = util.inspect(value);
assert.notStrictEqual(res, expectedWithoutProto);
assert(/\[Symbol\(foo\)]: 'yeah'/.test(res), res);
});
assert.strictEqual(inspect(1n), '1n');
assert.strictEqual(inspect(Object(-1n)), '[BigInt: -1n]');
assert.strictEqual(inspect(Object(13n)), '[BigInt: 13n]');

0 comments on commit 73f3a1c

Please sign in to comment.
You can’t perform that action at this time.