console: name console functions appropriately

The current name of most of the global console functions is
"bound consoleCall". This is changed to the actual functions name
e.g., "log" or "error".

Signed-off-by: Ruben Bridgewater <ruben@bridgewater.de>

PR-URL: https://github.com/nodejs/node/pull/33524
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com>
This commit is contained in:
Ruben Bridgewater 2020-05-22 14:02:04 +02:00
parent 87629d7e7c
commit 4bdab881b8
5 changed files with 67 additions and 2 deletions

View File

@ -136,6 +136,9 @@ function Console(options /* or: stdout, stderr, ignoreErrors = true */) {
// the prototype so that users extending the Console can override them
// from the prototype chain of the subclass.
this[key] = this[key].bind(this);
ObjectDefineProperty(this[key], 'name', {
value: key
});
}
this[kBindStreamsEager](stdout, stderr);

View File

@ -36,7 +36,9 @@ for (const prop of ReflectOwnKeys(Console.prototype)) {
if (prop === 'constructor') { continue; }
const desc = ReflectGetOwnPropertyDescriptor(Console.prototype, prop);
if (typeof desc.value === 'function') { // fix the receiver
const name = desc.value.name;
desc.value = desc.value.bind(globalConsole);
ReflectDefineProperty(desc.value, 'name', { value: name });
}
ReflectDefineProperty(globalConsole, prop, desc);
}

View File

@ -1,6 +1,7 @@
'use strict';
const {
ObjectDefineProperty,
ObjectKeys,
} = primordials;
@ -42,6 +43,9 @@ function wrapConsole(consoleFromNode, consoleFromVM) {
consoleFromNode[key] = consoleCall.bind(consoleFromNode,
consoleFromVM[key],
consoleFromNode[key]);
ObjectDefineProperty(consoleFromNode[key], 'name', {
value: key
});
} else {
// Add additional console APIs from the inspector
consoleFromNode[key] = consoleFromVM[key];

View File

@ -1,8 +1,8 @@
'use strict';
require('../common');
// This test ensures that console methods
// cannot be invoked as constructors
// This test ensures that console methods cannot be invoked as constructors and
// that their name is always correct.
const assert = require('assert');
@ -32,7 +32,30 @@ const methods = [
'groupCollapsed',
];
const alternateNames = {
debug: 'log',
info: 'log',
dirxml: 'log',
error: 'warn',
groupCollapsed: 'group'
};
function assertEqualName(method) {
try {
assert.strictEqual(console[method].name, method);
} catch {
assert.strictEqual(console[method].name, alternateNames[method]);
}
try {
assert.strictEqual(newInstance[method].name, method);
} catch {
assert.strictEqual(newInstance[method].name, alternateNames[method]);
}
}
for (const method of methods) {
assertEqualName(method);
assert.throws(() => new console[method](), err);
assert.throws(() => new newInstance[method](), err);
assert.throws(() => Reflect.construct({}, [], console[method]), err);

View File

@ -754,6 +754,39 @@ const errorTests = [
/^Uncaught SyntaxError: /
]
},
{
send: 'console',
expect: [
'{',
' log: [Function: log],',
' warn: [Function: warn],',
' dir: [Function: dir],',
' time: [Function: time],',
' timeEnd: [Function: timeEnd],',
' timeLog: [Function: timeLog],',
' trace: [Function: trace],',
' assert: [Function: assert],',
' clear: [Function: clear],',
' count: [Function: count],',
' countReset: [Function: countReset],',
' group: [Function: group],',
' groupEnd: [Function: groupEnd],',
' table: [Function: table],',
/ debug: \[Function: (debug|log)],/,
/ info: \[Function: (info|log)],/,
/ dirxml: \[Function: (dirxml|log)],/,
/ error: \[Function: (error|warn)],/,
/ groupCollapsed: \[Function: (groupCollapsed|group)],/,
/ Console: \[Function: Console],?/,
...process.features.inspector ? [
' profile: [Function: profile],',
' profileEnd: [Function: profileEnd],',
' timeStamp: [Function: timeStamp],',
' context: [Function: context]',
] : [],
'}',
]
},
];
const tcpTests = [