diff --git a/lib/internal/console/constructor.js b/lib/internal/console/constructor.js index ef688ca96eacfa..8c0d1a887f7ce9 100644 --- a/lib/internal/console/constructor.js +++ b/lib/internal/console/constructor.js @@ -131,6 +131,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); diff --git a/lib/internal/console/global.js b/lib/internal/console/global.js index 6a1dc3806fdb0b..1c615c78451510 100644 --- a/lib/internal/console/global.js +++ b/lib/internal/console/global.js @@ -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); } diff --git a/lib/internal/util/inspector.js b/lib/internal/util/inspector.js index 5a95bcf8ea852a..8d413b116fd0f2 100644 --- a/lib/internal/util/inspector.js +++ b/lib/internal/util/inspector.js @@ -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]; diff --git a/test/parallel/test-console-methods.js b/test/parallel/test-console-methods.js index 00dc144761cb57..d338cc1f807f2c 100644 --- a/test/parallel/test-console-methods.js +++ b/test/parallel/test-console-methods.js @@ -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); diff --git a/test/parallel/test-repl.js b/test/parallel/test-repl.js index 9b8578293d9e52..73a919e5eacb3c 100644 --- a/test/parallel/test-repl.js +++ b/test/parallel/test-repl.js @@ -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 = [