diff options
author | Matt Mastracci <matthew@mastracci.com> | 2024-02-10 13:22:13 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-10 20:22:13 +0000 |
commit | f5e46c9bf2f50d66a953fa133161fc829cecff06 (patch) | |
tree | 8faf2f5831c1c7b11d842cd9908d141082c869a5 /cli/tests/node_compat/test/parallel/test-util-inspect.js | |
parent | d2477f780630a812bfd65e3987b70c0d309385bb (diff) |
chore: move cli/tests/ -> tests/ (#22369)
This looks like a massive PR, but it's only a move from cli/tests ->
tests, and updates of relative paths for files.
This is the first step towards aggregate all of the integration test
files under tests/, which will lead to a set of integration tests that
can run without the CLI binary being built.
While we could leave these tests under `cli`, it would require us to
keep a more complex directory structure for the various test runners. In
addition, we have a lot of complexity to ignore various test files in
the `cli` project itself (cargo publish exclusion rules, autotests =
false, etc).
And finally, the `tests/` folder will eventually house the `test_ffi`,
`test_napi` and other testing code, reducing the size of the root repo
directory.
For easier review, the extremely large and noisy "move" is in the first
commit (with no changes -- just a move), while the remainder of the
changes to actual files is in the second commit.
Diffstat (limited to 'cli/tests/node_compat/test/parallel/test-util-inspect.js')
-rw-r--r-- | cli/tests/node_compat/test/parallel/test-util-inspect.js | 3201 |
1 files changed, 0 insertions, 3201 deletions
diff --git a/cli/tests/node_compat/test/parallel/test-util-inspect.js b/cli/tests/node_compat/test/parallel/test-util-inspect.js deleted file mode 100644 index 17fafed2e..000000000 --- a/cli/tests/node_compat/test/parallel/test-util-inspect.js +++ /dev/null @@ -1,3201 +0,0 @@ -// deno-fmt-ignore-file -// deno-lint-ignore-file - -// Copyright Joyent and Node contributors. All rights reserved. MIT license. -// Taken from Node 16.13.0 -// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually - -// Flags: --expose-internals -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. -'use strict'; -const common = require('../common'); -const assert = require('assert'); -// TODO(wafuwafu13): Implement 'internal/test/binding' -// const { internalBinding } = require('internal/test/binding'); -// const JSStream = internalBinding('js_stream').JSStream; -const util = require('util'); -const vm = require('vm'); -// TODO(wafuwafu13): Implement 'v8' -// const v8 = require('v8'); -// TODO(wafuwafu13): Implement 'internal/test/binding' -// const { previewEntries } = internalBinding('util'); -const { inspect } = util; -// TODO(wafuwafu13): Implement MessageChannel -// const { MessageChannel } = require('worker_threads'); - -assert.strictEqual(util.inspect(1), '1'); -assert.strictEqual(util.inspect(false), 'false'); -assert.strictEqual(util.inspect(''), "''"); -assert.strictEqual(util.inspect('hello'), "'hello'"); -assert.strictEqual(util.inspect(function abc() {}), '[Function: abc]'); -assert.strictEqual(util.inspect(() => {}), '[Function (anonymous)]'); -assert.strictEqual( - util.inspect(async function() {}), - '[AsyncFunction (anonymous)]' -); -assert.strictEqual(util.inspect(async () => {}), '[AsyncFunction (anonymous)]'); - -// Special function inspection. -{ - const fn = (() => function*() {})(); - assert.strictEqual( - util.inspect(fn), - '[GeneratorFunction (anonymous)]' - ); - // TODO(wafuwafu13): Fix - // assert.strictEqual( - // util.inspect(async function* abc() {}), - // '[AsyncGeneratorFunction: abc]' - // ); - Object.setPrototypeOf(fn, Object.getPrototypeOf(async () => {})); - // TODO(wafuwafu13): Fix - // assert.strictEqual( - // util.inspect(fn), - // '[GeneratorFunction (anonymous)] AsyncFunction' - // ); - Object.defineProperty(fn, 'name', { value: 5, configurable: true }); - // TODO(wafuwafu13): Fix - // assert.strictEqual( - // util.inspect(fn), - // '[GeneratorFunction: 5] AsyncFunction' - // ); - Object.defineProperty(fn, Symbol.toStringTag, { - value: 'Foobar', - configurable: true - }); - // TODO(wafuwafu13): Fix - // assert.strictEqual( - // util.inspect({ ['5']: fn }), - // "{ '5': [GeneratorFunction: 5] AsyncFunction [Foobar] }" - // ); - Object.defineProperty(fn, 'name', { value: '5', configurable: true }); - Object.setPrototypeOf(fn, null); - // TODO(wafuwafu13): Fix - // assert.strictEqual( - // util.inspect(fn), - // '[GeneratorFunction (null prototype): 5] [Foobar]' - // ); - // assert.strictEqual( - // util.inspect({ ['5']: fn }), - // "{ '5': [GeneratorFunction (null prototype): 5] [Foobar] }" - // ); -} - -assert.strictEqual(util.inspect(undefined), 'undefined'); -assert.strictEqual(util.inspect(null), 'null'); -assert.strictEqual(util.inspect(/foo(bar\n)?/gi), '/foo(bar\\n)?/gi'); -assert.strictEqual( - util.inspect(new Date('Sun, 14 Feb 2010 11:48:40 GMT')), - new Date('2010-02-14T12:48:40+01:00').toISOString() -); -assert.strictEqual(util.inspect(new Date('')), (new Date('')).toString()); -assert.strictEqual(util.inspect('\n\x01'), "'\\n\\x01'"); -// TODO(@crowlKats) -//assert.strictEqual( -// util.inspect(`${Array(75).fill(1)}'\n\x1d\n\x03\x85\x7f\x7e\x9f\xa0`), -// // eslint-disable-next-line no-irregular-whitespace -// `"${Array(75).fill(1)}'\\n" +\n '\\x1D\\n' +\n '\\x03\\x85\\x7F~\\x9F '` -//); -assert.strictEqual(util.inspect([]), '[]'); -assert.strictEqual(util.inspect(Object.create([])), 'Array {}'); -assert.strictEqual(util.inspect([1, 2]), '[ 1, 2 ]'); -assert.strictEqual(util.inspect([1, [2, 3]]), '[ 1, [ 2, 3 ] ]'); -assert.strictEqual(util.inspect({}), '{}'); -assert.strictEqual(util.inspect({ a: 1 }), '{ a: 1 }'); -assert.strictEqual(util.inspect({ a: function() {} }), '{ a: [Function: a] }'); -assert.strictEqual(util.inspect({ a: () => {} }), '{ a: [Function: a] }'); -// eslint-disable-next-line func-name-matching -assert.strictEqual(util.inspect({ a: async function abc() {} }), - '{ a: [AsyncFunction: abc] }'); -assert.strictEqual(util.inspect({ a: async () => {} }), - '{ a: [AsyncFunction: a] }'); -assert.strictEqual(util.inspect({ a: function*() {} }), - '{ a: [GeneratorFunction: a] }'); -assert.strictEqual(util.inspect({ a: 1, b: 2 }), '{ a: 1, b: 2 }'); -assert.strictEqual(util.inspect({ 'a': {} }), '{ a: {} }'); -assert.strictEqual(util.inspect({ 'a': { 'b': 2 } }), '{ a: { b: 2 } }'); -assert.strictEqual(util.inspect({ 'a': { 'b': { 'c': { 'd': 2 } } } }), - '{ a: { b: { c: [Object] } } }'); -assert.strictEqual( - util.inspect({ 'a': { 'b': { 'c': { 'd': 2 } } } }, false, null), - '{\n a: { b: { c: { d: 2 } } }\n}'); -// TODO(wafuwafu13): Fix -// assert.strictEqual(util.inspect([1, 2, 3], true), '[ 1, 2, 3, [length]: 3 ]'); -assert.strictEqual(util.inspect({ 'a': { 'b': { 'c': 2 } } }, false, 0), - '{ a: [Object] }'); -assert.strictEqual(util.inspect({ 'a': { 'b': { 'c': 2 } } }, false, 1), - '{ a: { b: [Object] } }'); -assert.strictEqual(util.inspect({ 'a': { 'b': ['c'] } }, false, 1), - '{ a: { b: [Array] } }'); -// TODO(wafuwafu13): Fix -// assert.strictEqual(util.inspect(new Uint8Array(0)), 'Uint8Array(0) []'); -// assert(inspect(new Uint8Array(0), { showHidden: true }).includes('[buffer]')); -assert.strictEqual( - util.inspect( - Object.create( - {}, - { visible: { value: 1, enumerable: true }, hidden: { value: 2 } } - ) - ), - '{ visible: 1 }' -); -// TODO(wafuwafu13): Fix -// assert.strictEqual( -// util.inspect( -// Object.assign(new String('hello'), { [Symbol('foo')]: 123 }), -// { showHidden: true } -// ), -// "[String: 'hello'] { [length]: 5, [Symbol(foo)]: 123 }" -// ); - -// TODO(wafuwafu13): Implement JSStream -// assert.match(util.inspect((new JSStream())._externalStream), -// /^\[External: [0-9a-f]+\]$/); - -{ - const regexp = /regexp/; - regexp.aprop = 42; - assert.strictEqual(util.inspect({ a: regexp }, false, 0), '{ a: /regexp/ }'); -} - -assert.match( - util.inspect({ a: { a: { a: { a: {} } } } }, undefined, undefined, true), - /Object/ -); -assert.doesNotMatch( - util.inspect({ a: { a: { a: { a: {} } } } }, undefined, null, true), - /Object/ -); - -// TODO(wafuwafu13): Fix -// { -// const showHidden = true; -// const ab = new Uint8Array([1, 2, 3, 4]).buffer; -// const dv = new DataView(ab, 1, 2); -// assert.strictEqual( -// util.inspect(ab, showHidden), -// 'ArrayBuffer { [Uint8Contents]: <01 02 03 04>, byteLength: 4 }' -// ); -// assert.strictEqual(util.inspect(new DataView(ab, 1, 2), showHidden), -// 'DataView {\n' + -// ' byteLength: 2,\n' + -// ' byteOffset: 1,\n' + -// ' buffer: ArrayBuffer {' + -// ' [Uint8Contents]: <01 02 03 04>, byteLength: 4 }\n}'); -// assert.strictEqual( -// util.inspect(ab, showHidden), -// 'ArrayBuffer { [Uint8Contents]: <01 02 03 04>, byteLength: 4 }' -// ); -// assert.strictEqual(util.inspect(dv, showHidden), -// 'DataView {\n' + -// ' byteLength: 2,\n' + -// ' byteOffset: 1,\n' + -// ' buffer: ArrayBuffer { [Uint8Contents]: ' + -// '<01 02 03 04>, byteLength: 4 }\n}'); -// ab.x = 42; -// dv.y = 1337; -// assert.strictEqual(util.inspect(ab, showHidden), -// 'ArrayBuffer { [Uint8Contents]: <01 02 03 04>, ' + -// 'byteLength: 4, x: 42 }'); -// assert.strictEqual(util.inspect(dv, showHidden), -// 'DataView {\n' + -// ' byteLength: 2,\n' + -// ' byteOffset: 1,\n' + -// ' buffer: ArrayBuffer { [Uint8Contents]: <01 02 03 04>,' + -// ' byteLength: 4, x: 42 },\n' + -// ' y: 1337\n}'); -// } - -// TODO(wafuwafu13): Implement `MessageChannel` -// { -// const ab = new ArrayBuffer(42); -// assert.strictEqual(ab.byteLength, 42); -// new MessageChannel().port1.postMessage(ab, [ ab ]); -// assert.strictEqual(ab.byteLength, 0); -// assert.strictEqual(util.inspect(ab), -// 'ArrayBuffer { (detached), byteLength: 0 }'); -// } - -// TODO(wafuwafu13): Fix -// // Truncate output for ArrayBuffers using plural or singular bytes -// { -// const ab = new ArrayBuffer(3); -// assert.strictEqual(util.inspect(ab, { showHidden: true, maxArrayLength: 2 }), -// 'ArrayBuffer { [Uint8Contents]' + -// ': <00 00 ... 1 more byte>, byteLength: 3 }'); -// assert.strictEqual(util.inspect(ab, { showHidden: true, maxArrayLength: 1 }), -// 'ArrayBuffer { [Uint8Contents]' + -// ': <00 ... 2 more bytes>, byteLength: 3 }'); -// } - -// TODO(wafuwafu13): Implement 'vm' -// // Now do the same checks but from a different context. -// { -// const showHidden = false; -// const ab = vm.runInNewContext('new ArrayBuffer(4)'); -// const dv = vm.runInNewContext('new DataView(ab, 1, 2)', { ab }); -// assert.strictEqual( -// util.inspect(ab, showHidden), -// 'ArrayBuffer { [Uint8Contents]: <00 00 00 00>, byteLength: 4 }' -// ); -// assert.strictEqual(util.inspect(new DataView(ab, 1, 2), showHidden), -// 'DataView {\n' + -// ' byteLength: 2,\n' + -// ' byteOffset: 1,\n' + -// ' buffer: ArrayBuffer { [Uint8Contents]: <00 00 00 00>,' + -// ' byteLength: 4 }\n}'); -// assert.strictEqual( -// util.inspect(ab, showHidden), -// 'ArrayBuffer { [Uint8Contents]: <00 00 00 00>, byteLength: 4 }' -// ); -// assert.strictEqual(util.inspect(dv, showHidden), -// 'DataView {\n' + -// ' byteLength: 2,\n' + -// ' byteOffset: 1,\n' + -// ' buffer: ArrayBuffer { [Uint8Contents]: <00 00 00 00>,' + -// ' byteLength: 4 }\n}'); -// ab.x = 42; -// dv.y = 1337; -// assert.strictEqual(util.inspect(ab, showHidden), -// 'ArrayBuffer { [Uint8Contents]: <00 00 00 00>, ' + -// 'byteLength: 4, x: 42 }'); -// assert.strictEqual(util.inspect(dv, showHidden), -// 'DataView {\n' + -// ' byteLength: 2,\n' + -// ' byteOffset: 1,\n' + -// ' buffer: ArrayBuffer { [Uint8Contents]: <00 00 00 00>,' + -// ' byteLength: 4, x: 42 },\n' + -// ' y: 1337\n}'); -// } - -// TODO(wafuwafu13): Fix -// [ Float32Array, -// Float64Array, -// Int16Array, -// Int32Array, -// Int8Array, -// Uint16Array, -// Uint32Array, -// Uint8Array, -// Uint8ClampedArray ].forEach((constructor) => { -// const length = 2; -// const byteLength = length * constructor.BYTES_PER_ELEMENT; -// const array = new constructor(new ArrayBuffer(byteLength), 0, length); -// array[0] = 65; -// array[1] = 97; -// assert.strictEqual( -// util.inspect(array, { showHidden: true }), -// `${constructor.name}(${length}) [\n` + -// ' 65,\n' + -// ' 97,\n' + -// ` [BYTES_PER_ELEMENT]: ${constructor.BYTES_PER_ELEMENT},\n` + -// ` [length]: ${length},\n` + -// ` [byteLength]: ${byteLength},\n` + -// ' [byteOffset]: 0,\n' + -// ` [buffer]: ArrayBuffer { byteLength: ${byteLength} }\n]`); -// assert.strictEqual( -// util.inspect(array, false), -// `${constructor.name}(${length}) [ 65, 97 ]` -// ); -// }); - -// TODO(wafuwafu13): Implement 'vm' -// // Now check that declaring a TypedArray in a different context works the same. -// [ Float32Array, -// Float64Array, -// Int16Array, -// Int32Array, -// Int8Array, -// Uint16Array, -// Uint32Array, -// Uint8Array, -// Uint8ClampedArray ].forEach((constructor) => { -// const length = 2; -// const byteLength = length * constructor.BYTES_PER_ELEMENT; -// const array = vm.runInNewContext( -// 'new constructor(new ArrayBuffer(byteLength), 0, length)', -// { constructor, byteLength, length } -// ); -// array[0] = 65; -// array[1] = 97; -// assert.strictEqual( -// util.inspect(array, true), -// `${constructor.name}(${length}) [\n` + -// ' 65,\n' + -// ' 97,\n' + -// ` [BYTES_PER_ELEMENT]: ${constructor.BYTES_PER_ELEMENT},\n` + -// ` [length]: ${length},\n` + -// ` [byteLength]: ${byteLength},\n` + -// ' [byteOffset]: 0,\n' + -// ` [buffer]: ArrayBuffer { byteLength: ${byteLength} }\n]`); -// assert.strictEqual( -// util.inspect(array, false), -// `${constructor.name}(${length}) [ 65, 97 ]` -// ); -// }); - -// TODO(wafuwafu13): Fix -// { -// const brokenLength = new Float32Array(2); -// Object.defineProperty(brokenLength, 'length', { value: -1 }); -// assert.strictEqual(inspect(brokenLength), 'Float32Array(2) [ 0n, 0n ]'); -// } - -assert.strictEqual( - util.inspect(Object.create({}, { - visible: { value: 1, enumerable: true }, - hidden: { value: 2 } - }), { showHidden: true }), - '{ visible: 1, [hidden]: 2 }' -); -// Objects without prototype. -assert.strictEqual( - util.inspect(Object.create(null, { - name: { value: 'Tim', enumerable: true }, - hidden: { value: 'secret' } - }), { showHidden: true }), - "[Object: null prototype] { name: 'Tim', [hidden]: 'secret' }" -); - -assert.strictEqual( - util.inspect(Object.create(null, { - name: { value: 'Tim', enumerable: true }, - hidden: { value: 'secret' } - })), - "[Object: null prototype] { name: 'Tim' }" -); - -// Dynamic properties. -{ - assert.strictEqual( - util.inspect({ get readonly() { return 1; } }), - '{ readonly: [Getter] }'); - - assert.strictEqual( - util.inspect({ get readwrite() { return 1; }, set readwrite(val) {} }), - '{ readwrite: [Getter/Setter] }'); - - assert.strictEqual( - // eslint-disable-next-line accessor-pairs - util.inspect({ set writeonly(val) {} }), - '{ writeonly: [Setter] }'); - - const value = {}; - value.a = value; - assert.strictEqual(util.inspect(value), '<ref *1> { a: [Circular *1] }'); - const getterFn = { - get one() { - return null; - } - }; - assert.strictEqual( - util.inspect(getterFn, { getters: true }), - '{ one: [Getter: null] }' - ); -} - -// TODO(wafuwafu13): Fix -// // Array with dynamic properties. -// { -// const value = [1, 2, 3]; -// Object.defineProperty( -// value, -// 'growingLength', -// { -// enumerable: true, -// get: function() { this.push(true); return this.length; } -// } -// ); -// Object.defineProperty( -// value, -// '-1', -// { -// enumerable: true, -// value: -1 -// } -// ); -// assert.strictEqual(util.inspect(value), -// "[ 1, 2, 3, growingLength: [Getter], '-1': -1 ]"); -// } - -// Array with inherited number properties. -{ - class CustomArray extends Array {} - CustomArray.prototype[5] = 'foo'; - CustomArray.prototype[49] = 'bar'; - CustomArray.prototype.foo = true; - const arr = new CustomArray(50); - arr[49] = 'I win'; - assert.strictEqual( - util.inspect(arr), - "CustomArray(50) [ <49 empty items>, 'I win' ]" - ); - // TODO(wafuwafu13): Fix - // assert.strictEqual( - // util.inspect(arr, { showHidden: true }), - // 'CustomArray(50) [\n' + - // ' <49 empty items>,\n' + - // " 'I win',\n" + - // ' [length]: 50,\n' + - // " '5': 'foo',\n" + - // ' foo: true\n' + - // ']' - // ); -} - -// TODO(wafuwafu13): Fix -// // Array with extra properties. -// { -// const arr = [1, 2, 3, , ]; -// arr.foo = 'bar'; -// assert.strictEqual(util.inspect(arr), -// "[ 1, 2, 3, <1 empty item>, foo: 'bar' ]"); - -// const arr2 = []; -// assert.strictEqual(util.inspect([], { showHidden: true }), '[ [length]: 0 ]'); -// arr2['00'] = 1; -// assert.strictEqual(util.inspect(arr2), "[ '00': 1 ]"); -// assert.strictEqual(util.inspect(arr2, { showHidden: true }), -// "[ [length]: 0, '00': 1 ]"); -// arr2[1] = 0; -// assert.strictEqual(util.inspect(arr2), "[ <1 empty item>, 0, '00': 1 ]"); -// assert.strictEqual(util.inspect(arr2, { showHidden: true }), -// "[ <1 empty item>, 0, [length]: 2, '00': 1 ]"); -// delete arr2[1]; -// assert.strictEqual(util.inspect(arr2), "[ <2 empty items>, '00': 1 ]"); -// assert.strictEqual(util.inspect(arr2, { showHidden: true }), -// "[ <2 empty items>, [length]: 2, '00': 1 ]"); -// arr2['01'] = 2; -// assert.strictEqual(util.inspect(arr2), -// "[ <2 empty items>, '00': 1, '01': 2 ]"); -// assert.strictEqual(util.inspect(arr2, { showHidden: true }), -// "[ <2 empty items>, [length]: 2, '00': 1, '01': 2 ]"); -// delete arr2['00']; -// arr2[0] = 0; -// assert.strictEqual(util.inspect(arr2), -// "[ 0, <1 empty item>, '01': 2 ]"); -// assert.strictEqual(util.inspect(arr2, { showHidden: true }), -// "[ 0, <1 empty item>, [length]: 2, '01': 2 ]"); -// delete arr2['01']; -// arr2[2 ** 32 - 2] = 'max'; -// arr2[2 ** 32 - 1] = 'too far'; -// assert.strictEqual( -// util.inspect(arr2), -// "[ 0, <4294967293 empty items>, 'max', '4294967295': 'too far' ]" -// ); - -// const arr3 = []; -// arr3[-1] = -1; -// assert.strictEqual(util.inspect(arr3), "[ '-1': -1 ]"); -// } - -// TODO(wafuwafu13): Fix -// // Indices out of bounds. -// { -// const arr = []; -// arr[2 ** 32] = true; // Not a valid array index. -// assert.strictEqual(util.inspect(arr), "[ '4294967296': true ]"); -// arr[0] = true; -// arr[10] = true; -// assert.strictEqual(util.inspect(arr), -// "[ true, <9 empty items>, true, '4294967296': true ]"); -// arr[2 ** 32 - 2] = true; -// arr[2 ** 32 - 1] = true; -// arr[2 ** 32 + 1] = true; -// delete arr[0]; -// delete arr[10]; -// assert.strictEqual(util.inspect(arr), -// ['[', -// '<4294967294 empty items>,', -// 'true,', -// "'4294967296': true,", -// "'4294967295': true,", -// "'4294967297': true\n]", -// ].join('\n ')); -// } - -// Function with properties. -{ - const value = () => {}; - value.aprop = 42; - assert.strictEqual(util.inspect(value), '[Function: value] { aprop: 42 }'); -} - -// Anonymous function with properties. -{ - const value = (() => function() {})(); - value.aprop = 42; - assert.strictEqual( - util.inspect(value), - '[Function (anonymous)] { aprop: 42 }' - ); -} - -// Regular expressions with properties. -{ - const value = /123/ig; - value.aprop = 42; - assert.strictEqual(util.inspect(value), '/123/gi { aprop: 42 }'); -} - -// Dates with properties. -{ - const value = new Date('Sun, 14 Feb 2010 11:48:40 GMT'); - value.aprop = 42; - assert.strictEqual(util.inspect(value), - '2010-02-14T11:48:40.000Z { aprop: 42 }'); -} - -// Test the internal isDate implementation. -{ - const Date2 = vm.runInNewContext('Date'); - const d = new Date2(); - const orig = util.inspect(d); - Date2.prototype.foo = 'bar'; - const after = util.inspect(d); - assert.strictEqual(orig, after); -} - -// Test positive/negative zero. -assert.strictEqual(util.inspect(0), '0'); -assert.strictEqual(util.inspect(-0), '-0'); -// Edge case from check. -assert.strictEqual(util.inspect(-5e-324), '-5e-324'); - -// Test for sparse array. -{ - const a = ['foo', 'bar', 'baz']; - assert.strictEqual(util.inspect(a), "[ 'foo', 'bar', 'baz' ]"); - delete a[1]; - assert.strictEqual(util.inspect(a), "[ 'foo', <1 empty item>, 'baz' ]"); - // TODO(wafuwafu13): Fix - // assert.strictEqual( - // util.inspect(a, true), - // "[ 'foo', <1 empty item>, 'baz', [length]: 3 ]" - // ); - assert.strictEqual(util.inspect(new Array(5)), '[ <5 empty items> ]'); - a[3] = 'bar'; - a[100] = 'qux'; - assert.strictEqual( - util.inspect(a, { breakLength: Infinity }), - "[ 'foo', <1 empty item>, 'baz', 'bar', <96 empty items>, 'qux' ]" - ); - delete a[3]; - assert.strictEqual( - util.inspect(a, { maxArrayLength: 4 }), - "[ 'foo', <1 empty item>, 'baz', <97 empty items>, ... 1 more item ]" - ); - // test 4 special case - assert.strictEqual(util.inspect(a, { - maxArrayLength: 2 - }), "[ 'foo', <1 empty item>, ... 99 more items ]"); -} - -// TODO(wafuwafu13): Implement `previewEntries` -// Test for Array constructor in different context. -// { -// const map = new Map(); -// map.set(1, 2); -// // Passing only a single argument to indicate a set iterator. -// const valsSetIterator = previewEntries(map.entries()); -// // Passing through true to indicate a map iterator. -// const valsMapIterEntries = previewEntries(map.entries(), true); -// const valsMapIterKeys = previewEntries(map.keys(), true); - -// assert.strictEqual(util.inspect(valsSetIterator), '[ 1, 2 ]'); -// assert.strictEqual(util.inspect(valsMapIterEntries), '[ [ 1, 2 ], true ]'); -// assert.strictEqual(util.inspect(valsMapIterKeys), '[ [ 1 ], false ]'); -// } - -// TODO(wafuwafu13): Implement 'vm' -// // Test for other constructors in different context. -// { -// let obj = vm.runInNewContext('(function(){return {}})()', {}); -// assert.strictEqual(util.inspect(obj), '{}'); -// obj = vm.runInNewContext('const m=new Map();m.set(1,2);m', {}); -// assert.strictEqual(util.inspect(obj), 'Map(1) { 1 => 2 }'); -// obj = vm.runInNewContext('const s=new Set();s.add(1);s.add(2);s', {}); -// assert.strictEqual(util.inspect(obj), 'Set(2) { 1, 2 }'); -// obj = vm.runInNewContext('fn=function(){};new Promise(fn,fn)', {}); -// assert.strictEqual(util.inspect(obj), 'Promise { <pending> }'); -// } - -// Test for property descriptors. -{ - const getter = Object.create(null, { - a: { - get: function() { return 'aaa'; } - } - }); - const setter = Object.create(null, { - b: { // eslint-disable-line accessor-pairs - set: function() {} - } - }); - const getterAndSetter = Object.create(null, { - c: { - get: function() { return 'ccc'; }, - set: function() {} - } - }); - assert.strictEqual( - util.inspect(getter, true), - '[Object: null prototype] { [a]: [Getter] }' - ); - assert.strictEqual( - util.inspect(setter, true), - '[Object: null prototype] { [b]: [Setter] }' - ); - assert.strictEqual( - util.inspect(getterAndSetter, true), - '[Object: null prototype] { [c]: [Getter/Setter] }' - ); -} - -// Exceptions should print the error message, not '{}'. -{ - [ - new Error(), - new Error('FAIL'), - new TypeError('FAIL'), - new SyntaxError('FAIL'), - ].forEach((err) => { - assert.strictEqual(util.inspect(err), err.stack); - }); - assert.throws( - () => undef(), // eslint-disable-line no-undef - (e) => { - assert.strictEqual(util.inspect(e), e.stack); - return true; - } - ); - - const ex = util.inspect(new Error('FAIL'), true); - assert(ex.includes('Error: FAIL')); - assert(ex.includes('[stack]')); - assert(ex.includes('[message]')); -} - -{ - const tmp = Error.stackTraceLimit; - Error.stackTraceLimit = 0; - const err = new Error('foo'); - const err2 = new Error('foo\nbar'); - assert.strictEqual(util.inspect(err, { compact: true }), '[Error: foo]'); - assert(err.stack); - delete err.stack; - assert(!err.stack); - assert.strictEqual(util.inspect(err, { compact: true }), '[Error: foo]'); - assert.strictEqual( - util.inspect(err2, { compact: true }), - '[Error: foo\nbar]' - ); - - err.bar = true; - err2.bar = true; - - assert.strictEqual( - util.inspect(err, { compact: true }), - '{ [Error: foo] bar: true }' - ); - assert.strictEqual( - util.inspect(err2, { compact: true }), - '{ [Error: foo\nbar]\n bar: true }' - ); - assert.strictEqual( - util.inspect(err, { compact: true, breakLength: 5 }), - '{ [Error: foo]\n bar: true }' - ); - assert.strictEqual( - util.inspect(err, { compact: true, breakLength: 1 }), - '{ [Error: foo]\n bar:\n true }' - ); - assert.strictEqual( - util.inspect(err2, { compact: true, breakLength: 5 }), - '{ [Error: foo\nbar]\n bar: true }' - ); - assert.strictEqual( - util.inspect(err, { compact: false }), - '[Error: foo] {\n bar: true\n}' - ); - assert.strictEqual( - util.inspect(err2, { compact: false }), - '[Error: foo\nbar] {\n bar: true\n}' - ); - - Error.stackTraceLimit = tmp; -} - -// TODO(wafuwafu13): Fix -// // Prevent enumerable error properties from being printed. -// { -// let err = new Error(); -// err.message = 'foobar'; -// let out = util.inspect(err).split('\n'); -// assert.strictEqual(out[0], 'Error: foobar'); -// assert(out[out.length - 1].startsWith(' at ')); -// // Reset the error, the stack is otherwise not recreated. -// err = new Error(); -// err.message = 'foobar'; -// err.name = 'Unique'; -// Object.defineProperty(err, 'stack', { value: err.stack, enumerable: true }); -// out = util.inspect(err).split('\n'); -// assert.strictEqual(out[0], 'Unique: foobar'); -// assert(out[out.length - 1].startsWith(' at ')); -// err.name = 'Baz'; -// out = util.inspect(err).split('\n'); -// assert.strictEqual(out[0], 'Unique: foobar'); -// assert.strictEqual(out[out.length - 2], " name: 'Baz'"); -// assert.strictEqual(out[out.length - 1], '}'); -// } - -// // Doesn't capture stack trace. -{ - function BadCustomError(msg) { - Error.call(this); - Object.defineProperty(this, 'message', - { value: msg, enumerable: false }); - Object.defineProperty(this, 'name', - { value: 'BadCustomError', enumerable: false }); - } - Object.setPrototypeOf(BadCustomError.prototype, Error.prototype); - Object.setPrototypeOf(BadCustomError, Error); - assert.strictEqual( - util.inspect(new BadCustomError('foo')), - '[BadCustomError: foo]' - ); -} - -// TODO(wafuwafu13): Fix -// // Tampered error stack or name property (different type than string). -// // Note: Symbols are not supported by `Error#toString()` which is called by -// // accessing the `stack` property. -// [ -// [404, '404: foo', '[404]'], -// [0, '0: foo', '[RangeError: foo]'], -// [0n, '0: foo', '[RangeError: foo]'], -// [null, 'null: foo', '[RangeError: foo]'], -// [undefined, 'RangeError: foo', '[RangeError: foo]'], -// [false, 'false: foo', '[RangeError: foo]'], -// ['', 'foo', '[RangeError: foo]'], -// [[1, 2, 3], '1,2,3: foo', '[1,2,3]'], -// ].forEach(([value, outputStart, stack]) => { -// let err = new RangeError('foo'); -// err.name = value; -// assert( -// util.inspect(err).startsWith(outputStart), -// util.format( -// 'The name set to %o did not result in the expected output "%s"', -// value, -// outputStart -// ) -// ); - -// err = new RangeError('foo'); -// err.stack = value; -// assert.strictEqual(util.inspect(err), stack); -// }); - -// https://github.com/nodejs/node-v0.x-archive/issues/1941 -// TODO(@crowlKats) -//assert.strictEqual(util.inspect(Object.create(Date.prototype)), 'Date {}'); - -// https://github.com/nodejs/node-v0.x-archive/issues/1944 -{ - const d = new Date(); - d.toUTCString = null; - util.inspect(d); -} - -// TODO(wafuwafu13): Fix -// // Should not throw. -// { -// const d = new Date(); -// d.toISOString = null; -// util.inspect(d); -// } - -// TODO(wafuwafu13): Fix -// // Should not throw. -// { -// const r = /regexp/; -// r.toString = null; -// util.inspect(r); -// } - -// TODO(wafuwafu13): Fix -// // See https://github.com/nodejs/node-v0.x-archive/issues/2225 -// { -// const x = { [util.inspect.custom]: util.inspect }; -// assert(util.inspect(x).includes( -// '[Symbol(nodejs.util.inspect.custom)]: [Function: inspect] {\n')); -// } - -// TODO(wafuwafu13): Fix -// // `util.inspect` should display the escaped value of a key. -// { -// const w = { -// '\\': 1, -// '\\\\': 2, -// '\\\\\\': 3, -// '\\\\\\\\': 4, -// '\n': 5, -// '\r': 6 -// }; - -// const y = ['a', 'b', 'c']; -// y['\\\\'] = 'd'; -// y['\n'] = 'e'; -// y['\r'] = 'f'; - -// assert.strictEqual( -// util.inspect(w), -// "{ '\\\\': 1, '\\\\\\\\': 2, '\\\\\\\\\\\\': 3, " + -// "'\\\\\\\\\\\\\\\\': 4, '\\n': 5, '\\r': 6 }" -// ); -// assert.strictEqual( -// util.inspect(y), -// "[ 'a', 'b', 'c', '\\\\\\\\': 'd', " + -// "'\\n': 'e', '\\r': 'f' ]" -// ); -// } - -// Test util.inspect.styles and util.inspect.colors. -{ - function testColorStyle(style, input, implicit) { - const colorName = util.inspect.styles[style]; - let color = ['', '']; - if (util.inspect.colors[colorName]) - color = util.inspect.colors[colorName]; - - const withoutColor = util.inspect(input, false, 0, false); - const withColor = util.inspect(input, false, 0, true); - const expect = `\u001b[${color[0]}m${withoutColor}\u001b[${color[1]}m`; - assert.strictEqual( - withColor, - expect, - `util.inspect color for style ${style}`); - } - - testColorStyle('special', function() {}); - testColorStyle('number', 123.456); - testColorStyle('boolean', true); - testColorStyle('undefined', undefined); - testColorStyle('null', null); - testColorStyle('string', 'test string'); - testColorStyle('date', new Date()); - testColorStyle('regexp', /regexp/); -} - -// An object with "hasOwnProperty" overwritten should not throw. -util.inspect({ hasOwnProperty: null }); - -// New API, accepts an "options" object. -{ - const subject = { foo: 'bar', hello: 31, a: { b: { c: { d: 0 } } } }; - Object.defineProperty(subject, 'hidden', { enumerable: false, value: null }); - - assert.strictEqual( - util.inspect(subject, { showHidden: false }).includes('hidden'), - false - ); - assert.strictEqual( - util.inspect(subject, { showHidden: true }).includes('hidden'), - true - ); - assert.strictEqual( - util.inspect(subject, { colors: false }).includes('\u001b[32m'), - false - ); - assert.strictEqual( - util.inspect(subject, { colors: true }).includes('\u001b[32m'), - true - ); - assert.strictEqual( - util.inspect(subject, { depth: 2 }).includes('c: [Object]'), - true - ); - assert.strictEqual( - util.inspect(subject, { depth: 0 }).includes('a: [Object]'), - true - ); - assert.strictEqual( - util.inspect(subject, { depth: null }).includes('{ d: 0 }'), - true - ); - assert.strictEqual( - util.inspect(subject, { depth: undefined }).includes('{ d: 0 }'), - true - ); -} - -{ - // "customInspect" option can enable/disable calling [util.inspect.custom](). - const subject = { [util.inspect.custom]: () => 123 }; - - assert.strictEqual( - util.inspect(subject, { customInspect: true }).includes('123'), - true - ); - assert.strictEqual( - util.inspect(subject, { customInspect: true }).includes('inspect'), - false - ); - assert.strictEqual( - util.inspect(subject, { customInspect: false }).includes('123'), - false - ); - // TODO(wafuwafu13): Fix - // assert.strictEqual( - // util.inspect(subject, { customInspect: false }).includes('inspect'), - // true - // ); - - // A custom [util.inspect.custom]() should be able to return other Objects. - subject[util.inspect.custom] = () => ({ foo: 'bar' }); - - assert.strictEqual(util.inspect(subject), "{ foo: 'bar' }"); - - subject[util.inspect.custom] = common.mustCall((depth, opts) => { - const clone = { ...opts }; - // This might change at some point but for now we keep the stylize function. - // The function should either be documented or an alternative should be - // implemented. - assert.strictEqual(typeof opts.stylize, 'function'); - assert.strictEqual(opts.seen, undefined); - assert.strictEqual(opts.budget, undefined); - assert.strictEqual(opts.indentationLvl, undefined); - assert.strictEqual(opts.showHidden, false); - // TODO(@crowlKats) - //assert.deepStrictEqual( - // new Set(Object.keys(util.inspect.defaultOptions).concat(['stylize'])), - // new Set(Object.keys(opts)) - //); - opts.showHidden = true; - return { [util.inspect.custom]: common.mustCall((depth, opts2) => { - assert.deepStrictEqual(clone, opts2); - }) }; - }); - - util.inspect(subject); - - // util.inspect.custom is a shared symbol which can be accessed as - // Symbol.for("nodejs.util.inspect.custom"). - const inspect = Symbol.for('nodejs.util.inspect.custom'); - - subject[inspect] = () => ({ baz: 'quux' }); - - assert.strictEqual(util.inspect(subject), '{ baz: \'quux\' }'); - - subject[inspect] = (depth, opts) => { - assert.strictEqual(opts.customInspectOptions, true); - assert.strictEqual(opts.seen, null); - return {}; - }; - - util.inspect(subject, { customInspectOptions: true, seen: null }); -} - -{ - const subject = { [util.inspect.custom]: common.mustCall((depth, opts) => { - assert.strictEqual(depth, null); - assert.strictEqual(opts.compact, true); - }) }; - util.inspect(subject, { depth: null, compact: true }); -} - -// TODO(wafuwafu13): Fix -// { -// // Returning `this` from a custom inspection function works. -// const subject = { a: 123, [util.inspect.custom]() { return this; } }; -// const UIC = 'nodejs.util.inspect.custom'; -// assert.strictEqual( -// util.inspect(subject), -// `{\n a: 123,\n [Symbol(${UIC})]: [Function: [${UIC}]]\n}` -// ); -// } - -// Verify that it's possible to use the stylize function to manipulate input. -assert.strictEqual( - util.inspect([1, 2, 3], { stylize() { return 'x'; } }), - '[ x, x, x ]' -); - -// Using `util.inspect` with "colors" option should produce as many lines as -// without it. -{ - function testLines(input) { - const countLines = (str) => (str.match(/\n/g) || []).length; - const withoutColor = util.inspect(input); - const withColor = util.inspect(input, { colors: true }); - assert.strictEqual(countLines(withoutColor), countLines(withColor)); - } - - const bigArray = new Array(100).fill().map((value, index) => index); - - testLines([1, 2, 3, 4, 5, 6, 7]); - testLines(bigArray); - testLines({ foo: 'bar', baz: 35, b: { a: 35 } }); - testLines({ a: { a: 3, b: 1, c: 1, d: 1, e: 1, f: 1, g: 1, h: 1 }, b: 1 }); - testLines({ - foo: 'bar', - baz: 35, - b: { a: 35 }, - veryLongKey: 'very long value', - evenLongerKey: ['with even longer value in array'] - }); -} - -// Test boxed primitives output the correct values. -assert.strictEqual(util.inspect(new String('test')), "[String: 'test']"); -assert.strictEqual( - util.inspect(new String('test'), { colors: true }), - "\u001b[32m[String: 'test']\u001b[39m" -); -assert.strictEqual( - util.inspect(Object(Symbol('test'))), - '[Symbol: Symbol(test)]' -); -assert.strictEqual(util.inspect(new Boolean(false)), '[Boolean: false]'); -// TODO(wafuwafu13): Fix -// assert.strictEqual( -// util.inspect(Object.setPrototypeOf(new Boolean(true), null)), -// '[Boolean (null prototype): true]' -// ); -// assert.strictEqual(util.inspect(new Number(0)), '[Number: 0]'); -// assert.strictEqual( -// util.inspect( -// Object.defineProperty( -// Object.setPrototypeOf(new Number(-0), Array.prototype), -// Symbol.toStringTag, -// { value: 'Foobar' } -// ) -// ), -// '[Number (Array): -0] [Foobar]' -// ); -assert.strictEqual(util.inspect(new Number(-1.1)), '[Number: -1.1]'); -assert.strictEqual(util.inspect(new Number(13.37)), '[Number: 13.37]'); - -// Test boxed primitives with own properties. -{ - const str = new String('baz'); - str.foo = 'bar'; - assert.strictEqual(util.inspect(str), "[String: 'baz'] { foo: 'bar' }"); - - const bool = new Boolean(true); - bool.foo = 'bar'; - assert.strictEqual(util.inspect(bool), "[Boolean: true] { foo: 'bar' }"); - - const num = new Number(13.37); - num.foo = 'bar'; - assert.strictEqual(util.inspect(num), "[Number: 13.37] { foo: 'bar' }"); - - const sym = Object(Symbol('foo')); - sym.foo = 'bar'; - assert.strictEqual(util.inspect(sym), "[Symbol: Symbol(foo)] { foo: 'bar' }"); - - const big = Object(BigInt(55)); - big.foo = 'bar'; - assert.strictEqual(util.inspect(big), "[BigInt: 55n] { foo: 'bar' }"); -} - -// Test es6 Symbol. -if (typeof Symbol !== 'undefined') { - assert.strictEqual(util.inspect(Symbol()), 'Symbol()'); - //assert.strictEqual(util.inspect(Symbol(123)), 'Symbol(123)'); - //assert.strictEqual(util.inspect(Symbol('hi')), 'Symbol(hi)'); - assert.strictEqual(util.inspect([Symbol()]), '[ Symbol() ]'); - assert.strictEqual(util.inspect({ foo: Symbol() }), '{ foo: Symbol() }'); - - const options = { showHidden: true }; - let subject = {}; - - subject[Symbol('sym\nbol')] = 42; - - // TODO(wafuwafu13): Fix - // assert.strictEqual(util.inspect(subject), '{ [Symbol(sym\\nbol)]: 42 }'); - // assert.strictEqual( - // util.inspect(subject, options), - // '{ [Symbol(sym\\nbol)]: 42 }' - // ); - - // Object.defineProperty( - // subject, - // Symbol(), - // { enumerable: false, value: 'non-enum' }); - // assert.strictEqual(util.inspect(subject), '{ [Symbol(sym\\nbol)]: 42 }'); - // assert.strictEqual( - // util.inspect(subject, options), - // "{ [Symbol(sym\\nbol)]: 42, [Symbol()]: 'non-enum' }" - // ); - - // subject = [1, 2, 3]; - // subject[Symbol('symbol')] = 42; - - // assert.strictEqual(util.inspect(subject), - // '[ 1, 2, 3, [Symbol(symbol)]: 42 ]'); -} - -// Test Set. -{ - assert.strictEqual(util.inspect(new Set()), 'Set(0) {}'); - // TODO(wafuwafu13): Fix - // assert.strictEqual(util.inspect(new Set([1, 2, 3])), 'Set(3) { 1, 2, 3 }'); - // const set = new Set(['foo']); - // set.bar = 42; - // assert.strictEqual( - // util.inspect(set, { showHidden: true }), - // "Set(1) { 'foo', bar: 42 }" - // ); -} - -// TODO(wafuwafu13): Fix -// // Test circular Set. -// { -// const set = new Set(); -// set.add(set); -// assert.strictEqual(util.inspect(set), '<ref *1> Set(1) { [Circular *1] }'); -// } - -// Test Map. -{ - assert.strictEqual(util.inspect(new Map()), 'Map(0) {}'); - assert.strictEqual(util.inspect(new Map([[1, 'a'], [2, 'b'], [3, 'c']])), - "Map(3) { 1 => 'a', 2 => 'b', 3 => 'c' }"); - const map = new Map([['foo', null]]); - map.bar = 42; - assert.strictEqual(util.inspect(map, true), - "Map(1) { 'foo' => null, bar: 42 }"); -} - -// Test circular Map. -{ - const map = new Map(); - map.set(map, 'map'); - assert.strictEqual( - inspect(map), - "<ref *1> Map(1) { [Circular *1] => 'map' }" - ); - map.set(map, map); - assert.strictEqual( - inspect(map), - '<ref *1> Map(1) { [Circular *1] => [Circular *1] }' - ); - map.delete(map); - map.set('map', map); - assert.strictEqual( - inspect(map), - "<ref *1> Map(1) { 'map' => [Circular *1] }" - ); -} - -// Test multiple circular references. -{ - const obj = {}; - obj.a = [obj]; - obj.b = {}; - obj.b.inner = obj.b; - obj.b.obj = obj; - - assert.strictEqual( - inspect(obj), - '<ref *1> {\n' + - ' a: [ [Circular *1] ],\n' + - ' b: <ref *2> { inner: [Circular *2], obj: [Circular *1] }\n' + - '}' - ); -} - -// TODO(wafuwafu13): Fix -// // Test Promise. -// { -// const resolved = Promise.resolve(3); -// assert.strictEqual(util.inspect(resolved), 'Promise { 3 }'); - -// const rejected = Promise.reject(3); -// assert.strictEqual(util.inspect(rejected), 'Promise { <rejected> 3 }'); -// // Squelch UnhandledPromiseRejection. -// rejected.catch(() => {}); - -// const pending = new Promise(() => {}); -// assert.strictEqual(util.inspect(pending), 'Promise { <pending> }'); - -// const promiseWithProperty = Promise.resolve('foo'); -// promiseWithProperty.bar = 42; -// assert.strictEqual(util.inspect(promiseWithProperty), -// "Promise { 'foo', bar: 42 }"); -// } - -// Make sure it doesn't choke on polyfills. Unlike Set/Map, there is no standard -// interface to synchronously inspect a Promise, so our techniques only work on -// a bonafide native Promise. -{ - const oldPromise = Promise; - global.Promise = function() { this.bar = 42; }; - assert.strictEqual(util.inspect(new Promise()), '{ bar: 42 }'); - global.Promise = oldPromise; -} - -// TODO(wafuwafu13): Fix -// // Test Map iterators. -// { -// const map = new Map([['foo', 'bar']]); -// assert.strictEqual(util.inspect(map.keys()), '[Map Iterator] { \'foo\' }'); -// const mapValues = map.values(); -// Object.defineProperty(mapValues, Symbol.toStringTag, { value: 'Foo' }); -// assert.strictEqual( -// util.inspect(mapValues), -// '[Foo] [Map Iterator] { \'bar\' }' -// ); -// map.set('A', 'B!'); -// assert.strictEqual(util.inspect(map.entries(), { maxArrayLength: 1 }), -// "[Map Entries] { [ 'foo', 'bar' ], ... 1 more item }"); -// // Make sure the iterator doesn't get consumed. -// const keys = map.keys(); -// assert.strictEqual(util.inspect(keys), "[Map Iterator] { 'foo', 'A' }"); -// assert.strictEqual(util.inspect(keys), "[Map Iterator] { 'foo', 'A' }"); -// keys.extra = true; -// assert.strictEqual( -// util.inspect(keys, { maxArrayLength: 0 }), -// '[Map Iterator] { ... 2 more items, extra: true }'); -// } - -// TODO(wafuwafu13): Fix -// // Test Set iterators. -// { -// const aSet = new Set([1]); -// assert.strictEqual(util.inspect(aSet.entries(), { compact: false }), -// '[Set Entries] {\n [\n 1,\n 1\n ]\n}'); -// aSet.add(3); -// assert.strictEqual(util.inspect(aSet.keys()), '[Set Iterator] { 1, 3 }'); -// assert.strictEqual(util.inspect(aSet.values()), '[Set Iterator] { 1, 3 }'); -// const setEntries = aSet.entries(); -// Object.defineProperty(setEntries, Symbol.toStringTag, { value: 'Foo' }); -// assert.strictEqual(util.inspect(setEntries), -// '[Foo] [Set Entries] { [ 1, 1 ], [ 3, 3 ] }'); -// // Make sure the iterator doesn't get consumed. -// const keys = aSet.keys(); -// Object.defineProperty(keys, Symbol.toStringTag, { value: null }); -// assert.strictEqual(util.inspect(keys), '[Set Iterator] { 1, 3 }'); -// assert.strictEqual(util.inspect(keys), '[Set Iterator] { 1, 3 }'); -// keys.extra = true; -// assert.strictEqual( -// util.inspect(keys, { maxArrayLength: 1 }), -// '[Set Iterator] { 1, ... 1 more item, extra: true }'); -// } - -// Minimal inspection should still return as much information as possible about -// the constructor and Symbol.toStringTag. -{ - class Foo { - get [Symbol.toStringTag]() { - return 'ABC'; - } - } - const a = new Foo(); - assert.strictEqual(inspect(a, { depth: -1 }), 'Foo [ABC] {}'); - a.foo = true; - assert.strictEqual(inspect(a, { depth: -1 }), '[Foo [ABC]]'); - Object.defineProperty(a, Symbol.toStringTag, { - value: 'Foo', - configurable: true, - writable: true - }); - assert.strictEqual(inspect(a, { depth: -1 }), '[Foo]'); - delete a[Symbol.toStringTag]; - Object.setPrototypeOf(a, null); - // TODO(wafuwafu13): Fix - // assert.strictEqual(inspect(a, { depth: -1 }), '[Foo: null prototype]'); - // delete a.foo; - // assert.strictEqual(inspect(a, { depth: -1 }), '[Foo: null prototype] {}'); - // Object.defineProperty(a, Symbol.toStringTag, { - // value: 'ABC', - // configurable: true - // }); - // assert.strictEqual( - // inspect(a, { depth: -1 }), - // '[Foo: null prototype] [ABC] {}' - // ); - // Object.defineProperty(a, Symbol.toStringTag, { - // value: 'Foo', - // configurable: true - // }); - // assert.strictEqual( - // inspect(a, { depth: -1 }), - // '[Object: null prototype] [Foo] {}' - // ); -} - -// Test alignment of items in container. -// Assumes that the first numeric character is the start of an item. -{ - function checkAlignment(container, start, lineX, end) { - const lines = util.inspect(container).split('\n'); - lines.forEach((line, i) => { - if (i === 0) { - assert.strictEqual(line, start); - } else if (i === lines.length - 1) { - assert.strictEqual(line, end); - } else { - let expected = lineX.replace('X', i - 1); - if (i !== lines.length - 2) - expected += ','; - assert.strictEqual(line, expected); - } - }); - } - - const bigArray = []; - for (let i = 0; i < 100; i++) { - bigArray.push(i); - } - - const obj = {}; - bigArray.forEach((prop) => { - obj[prop] = null; - }); - - checkAlignment(obj, '{', " 'X': null", '}'); - // TODO(wafuwafu13): Fix - // checkAlignment(new Set(bigArray), 'Set(100) {', ' X', '}'); - checkAlignment( - new Map(bigArray.map((number) => [number, null])), - 'Map(100) {', ' X => null', '}' - ); -} - - -// Test display of constructors. -{ - class ObjectSubclass {} - class ArraySubclass extends Array {} - class SetSubclass extends Set {} - class MapSubclass extends Map {} - class PromiseSubclass extends Promise {} - - const x = new ObjectSubclass(); - x.foo = 42; - assert.strictEqual(util.inspect(x), - 'ObjectSubclass { foo: 42 }'); - assert.strictEqual(util.inspect(new ArraySubclass(1, 2, 3)), - 'ArraySubclass(3) [ 1, 2, 3 ]'); - // TODO(wafuwafu13): Fix - // assert.strictEqual(util.inspect(new SetSubclass([1, 2, 3])), - // 'SetSubclass(3) [Set] { 1, 2, 3 }'); - assert.strictEqual(util.inspect(new MapSubclass([['foo', 42]])), - "MapSubclass(1) [Map] { 'foo' => 42 }"); - // TODO(wafuwafu13): Fix - // assert.strictEqual(util.inspect(new PromiseSubclass(() => {})), - // 'PromiseSubclass [Promise] { <pending> }'); - assert.strictEqual( - util.inspect({ a: { b: new ArraySubclass([1, [2], 3]) } }, { depth: 1 }), - '{ a: { b: [ArraySubclass] } }' - ); - // TODO(wafuwafu13): Fix - // assert.strictEqual( - // util.inspect(Object.setPrototypeOf(x, null)), - // '[ObjectSubclass: null prototype] { foo: 42 }' - // ); -} - -// Empty and circular before depth. -{ - const arr = [[[[]]]]; - assert.strictEqual(util.inspect(arr), '[ [ [ [] ] ] ]'); - arr[0][0][0][0] = []; - assert.strictEqual(util.inspect(arr), '[ [ [ [Array] ] ] ]'); - arr[0][0][0] = {}; - assert.strictEqual(util.inspect(arr), '[ [ [ {} ] ] ]'); - arr[0][0][0] = { a: 2 }; - assert.strictEqual(util.inspect(arr), '[ [ [ [Object] ] ] ]'); - arr[0][0][0] = arr; - assert.strictEqual(util.inspect(arr), '<ref *1> [ [ [ [Circular *1] ] ] ]'); - arr[0][0][0] = arr[0][0]; - assert.strictEqual(util.inspect(arr), '[ [ <ref *1> [ [Circular *1] ] ] ]'); -} - -// Corner cases. -{ - const x = { constructor: 42 }; - assert.strictEqual(util.inspect(x), '{ constructor: 42 }'); -} - -{ - const x = {}; - Object.defineProperty(x, 'constructor', { - get: function() { - throw new Error('should not access constructor'); - }, - enumerable: true - }); - assert.strictEqual(util.inspect(x), '{ constructor: [Getter] }'); -} - -{ - const x = new function() {}; // eslint-disable-line new-parens - assert.strictEqual(util.inspect(x), '{}'); -} - -{ - const x = Object.create(null); - assert.strictEqual(util.inspect(x), '[Object: null prototype] {}'); -} - -// TODO(wafuwafu13): Fix -// { -// const x = []; -// x[''] = 1; -// assert.strictEqual(util.inspect(x), "[ '': 1 ]"); -// } - -// TODO(wafuwafu13): Fix -// // The following maxArrayLength tests were introduced after v6.0.0 was released. -// // Do not backport to v5/v4 unless all of -// // https://github.com/nodejs/node/pull/6334 is backported. -// { -// const x = new Array(101).fill(); -// assert(util.inspect(x).endsWith('1 more item\n]')); -// assert(!util.inspect(x, { maxArrayLength: 101 }).endsWith('1 more item\n]')); -// assert.strictEqual( -// util.inspect(x, { maxArrayLength: -1 }), -// '[ ... 101 more items ]' -// ); -// assert.strictEqual(util.inspect(x, { maxArrayLength: 0 }), -// '[ ... 101 more items ]'); -// } - -{ - const x = Array(101); - assert.strictEqual(util.inspect(x, { maxArrayLength: 0 }), - '[ ... 101 more items ]'); - assert(!util.inspect(x, { maxArrayLength: null }).endsWith('1 more item\n]')); - assert(!util.inspect( - x, { maxArrayLength: Infinity } - ).endsWith('1 more item ]')); -} - -{ - const x = new Uint8Array(101); - // TODO(wafuwafu13): Fix - // assert(util.inspect(x).endsWith('1 more item\n]')); - assert(!util.inspect(x, { maxArrayLength: 101 }).includes('1 more item')); - // TODO(wafuwafu13): Fix - // assert.strictEqual(util.inspect(x, { maxArrayLength: 0 }), - // 'Uint8Array(101) [ ... 101 more items ]'); - assert(!util.inspect(x, { maxArrayLength: null }).includes('1 more item')); - // TODO(wafuwafu13): Fix - // assert(util.inspect(x, { maxArrayLength: Infinity }).endsWith(' 0, 0\n]')); -} - -{ - const obj = { foo: 'abc', bar: 'xyz' }; - const oneLine = util.inspect(obj, { breakLength: Infinity }); - // Subtract four for the object's two curly braces and two spaces of padding. - // Add one more to satisfy the strictly greater than condition in the code. - const breakpoint = oneLine.length - 5; - const twoLines = util.inspect(obj, { breakLength: breakpoint }); - - assert.strictEqual(oneLine, "{ foo: 'abc', bar: 'xyz' }"); - assert.strictEqual( - util.inspect(obj, { breakLength: breakpoint + 1 }), - twoLines - ); - assert.strictEqual(twoLines, "{\n foo: 'abc',\n bar: 'xyz'\n}"); -} - -// util.inspect.defaultOptions tests. -{ - const arr = new Array(101).fill(); - const obj = { a: { a: { a: { a: 1 } } } }; - - const oldOptions = { ...util.inspect.defaultOptions }; - - // Set single option through property assignment. - util.inspect.defaultOptions.maxArrayLength = null; - assert.doesNotMatch(util.inspect(arr), /1 more item/); - util.inspect.defaultOptions.maxArrayLength = oldOptions.maxArrayLength; - // TODO(wafuwafu13): Fix - // assert.match(util.inspect(arr), /1 more item/); - util.inspect.defaultOptions.depth = null; - assert.doesNotMatch(util.inspect(obj), /Object/); - util.inspect.defaultOptions.depth = oldOptions.depth; - assert.match(util.inspect(obj), /Object/); - assert.strictEqual( - JSON.stringify(util.inspect.defaultOptions), - JSON.stringify(oldOptions) - ); - - // Set multiple options through object assignment. - util.inspect.defaultOptions = { maxArrayLength: null, depth: 2 }; - assert.doesNotMatch(util.inspect(arr), /1 more item/); - assert.match(util.inspect(obj), /Object/); - util.inspect.defaultOptions = oldOptions; - // assert.match(util.inspect(arr), /1 more item/); - assert.match(util.inspect(obj), /Object/); - assert.strictEqual( - JSON.stringify(util.inspect.defaultOptions), - JSON.stringify(oldOptions) - ); - - assert.throws(() => { - util.inspect.defaultOptions = null; - }, { - code: 'ERR_INVALID_ARG_TYPE', - name: 'TypeError', - message: 'The "options" argument must be of type object. ' + - 'Received null' - } - ); - - assert.throws(() => { - util.inspect.defaultOptions = 'bad'; - }, { - code: 'ERR_INVALID_ARG_TYPE', - name: 'TypeError', - message: 'The "options" argument must be of type object. ' + - "Received type string ('bad')" - } - ); -} - -util.inspect(process); - -// TODO(wafuwafu13): Fix -// // Setting custom inspect property to a non-function should do nothing. -// { -// const obj = { [util.inspect.custom]: 'fhqwhgads' }; -// assert.strictEqual( -// util.inspect(obj), -// "{ [Symbol(nodejs.util.inspect.custom)]: 'fhqwhgads' }" -// ); -// } - -{ - // @@toStringTag - const obj = { [Symbol.toStringTag]: 'a' }; - // TODO(wafuwafu13): Fix - // assert.strictEqual( - // util.inspect(obj), - // "{ [Symbol(Symbol.toStringTag)]: 'a' }" - // ); - Object.defineProperty(obj, Symbol.toStringTag, { - value: 'a', - enumerable: false - }); - assert.strictEqual(util.inspect(obj), 'Object [a] {}'); - // TODO(wafuwafu13): Fix - // assert.strictEqual( - // util.inspect(obj, { showHidden: true }), - // "{ [Symbol(Symbol.toStringTag)]: 'a' }" - // ); - - class Foo { - constructor() { - this.foo = 'bar'; - } - - get [Symbol.toStringTag]() { - return this.foo; - } - } - - // TODO(wafuwafu13): Fix - // assert.strictEqual(util.inspect( - // Object.create(null, { [Symbol.toStringTag]: { value: 'foo' } })), - // '[Object: null prototype] [foo] {}'); - - assert.strictEqual(util.inspect(new Foo()), "Foo [bar] { foo: 'bar' }"); - - assert.strictEqual( - util.inspect(new (class extends Foo {})()), - "Foo [bar] { foo: 'bar' }"); - - assert.strictEqual( - util.inspect(Object.create(Object.create(Foo.prototype), { - foo: { value: 'bar', enumerable: true } - })), - "Foo [bar] { foo: 'bar' }"); - - class ThrowingClass { - get [Symbol.toStringTag]() { - throw new Error('toStringTag error'); - } - } - - assert.throws(() => util.inspect(new ThrowingClass()), /toStringTag error/); - - class NotStringClass { - get [Symbol.toStringTag]() { - return null; - } - } - - assert.strictEqual(util.inspect(new NotStringClass()), - 'NotStringClass {}'); -} - -{ - const o = { - a: [1, 2, [[ - 'Lorem ipsum dolor\nsit amet,\tconsectetur adipiscing elit, sed do ' + - 'eiusmod tempor incididunt ut labore et dolore magna aliqua.', - 'test', - 'foo']], 4], - b: new Map([['za', 1], ['zb', 'test']]) - }; - - let out = util.inspect(o, { compact: true, depth: 5, breakLength: 80 }); - let expect = [ - '{ a:', - ' [ 1,', - ' 2,', - " [ [ 'Lorem ipsum dolor\\nsit amet,\\tconsectetur adipiscing elit, " + - "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',", - " 'test',", - " 'foo' ] ],", - ' 4 ],', - " b: Map(2) { 'za' => 1, 'zb' => 'test' } }", - ].join('\n'); - assert.strictEqual(out, expect); - - out = util.inspect(o, { compact: false, depth: 5, breakLength: 60 }); - expect = [ - '{', - ' a: [', - ' 1,', - ' 2,', - ' [', - ' [', - " 'Lorem ipsum dolor\\n' +", - " 'sit amet,\\tconsectetur adipiscing elit, sed do eiusmod " + - "tempor incididunt ut labore et dolore magna aliqua.',", - " 'test',", - " 'foo'", - ' ]', - ' ],', - ' 4', - ' ],', - ' b: Map(2) {', - " 'za' => 1,", - " 'zb' => 'test'", - ' }', - '}', - ].join('\n'); - assert.strictEqual(out, expect); - - out = util.inspect(o.a[2][0][0], { compact: false, breakLength: 30 }); - expect = [ - "'Lorem ipsum dolor\\n' +", - " 'sit amet,\\tconsectetur adipiscing elit, sed do eiusmod tempor " + - "incididunt ut labore et dolore magna aliqua.'", - ].join('\n'); - assert.strictEqual(out, expect); - - out = util.inspect( - '12345678901234567890123456789012345678901234567890', - { compact: false, breakLength: 3 }); - expect = "'12345678901234567890123456789012345678901234567890'"; - assert.strictEqual(out, expect); - - out = util.inspect( - '12 45 78 01 34 67 90 23 56 89 123456789012345678901234567890', - { compact: false, breakLength: 3 }); - expect = [ - "'12 45 78 01 34 67 90 23 56 89 123456789012345678901234567890'", - ].join('\n'); - assert.strictEqual(out, expect); - - // TODO(wafuwafu13): Fix - o.a = () => {}; - o.b = new Number(3); - out = util.inspect(o, { compact: false, breakLength: 3 }); - expect = [ - '{', - ' a: [Function (anonymous)],', - ' b: [Number: 3]', - '}', - ].join('\n'); - assert.strictEqual(out, expect); - - out = util.inspect(o, { compact: false, breakLength: 3, showHidden: true }); - expect = [ - '{', - ' a: [Function (anonymous)] {', - ' [length]: 0,', - " [name]: ''", - ' },', - ' b: [Number: 3]', - '}', - ].join('\n'); - assert.strictEqual(out, expect); - - o[util.inspect.custom] = () => 42; - out = util.inspect(o, { compact: false, breakLength: 3 }); - expect = '42'; - assert.strictEqual(out, expect); - - o[util.inspect.custom] = () => '12 45 78 01 34 67 90 23'; - out = util.inspect(o, { compact: false, breakLength: 3 }); - expect = '12 45 78 01 34 67 90 23'; - assert.strictEqual(out, expect); - - o[util.inspect.custom] = () => ({ a: '12 45 78 01 34 67 90 23' }); - out = util.inspect(o, { compact: false, breakLength: 3 }); - expect = "{\n a: '12 45 78 01 34 67 90 23'\n}"; - assert.strictEqual(out, expect); -} - -// TODO(wafuwafu13): Fix -// // Check compact indentation. -// { -// const typed = new Uint8Array(); -// typed.buffer.foo = true; -// const set = new Set([[1, 2]]); -// const promise = Promise.resolve([[1, set]]); -// const map = new Map([[promise, typed]]); -// map.set(set.values(), map.values()); - -// let out = util.inspect(map, { compact: false, showHidden: true, depth: 9 }); -// let expected = [ -// 'Map(2) {', -// ' Promise {', -// ' [', -// ' [', -// ' 1,', -// ' Set(1) {', -// ' [', -// ' 1,', -// ' 2,', -// ' [length]: 2', -// ' ]', -// ' },', -// ' [length]: 2', -// ' ],', -// ' [length]: 1', -// ' ]', -// ' } => Uint8Array(0) [', -// ' [BYTES_PER_ELEMENT]: 1,', -// ' [length]: 0,', -// ' [byteLength]: 0,', -// ' [byteOffset]: 0,', -// ' [buffer]: ArrayBuffer {', -// ' byteLength: 0,', -// ' foo: true', -// ' }', -// ' ],', -// ' [Set Iterator] {', -// ' [', -// ' 1,', -// ' 2,', -// ' [length]: 2', -// ' ],', -// " [Symbol(Symbol.toStringTag)]: 'Set Iterator'", -// ' } => <ref *1> [Map Iterator] {', -// ' Uint8Array(0) [', -// ' [BYTES_PER_ELEMENT]: 1,', -// ' [length]: 0,', -// ' [byteLength]: 0,', -// ' [byteOffset]: 0,', -// ' [buffer]: ArrayBuffer {', -// ' byteLength: 0,', -// ' foo: true', -// ' }', -// ' ],', -// ' [Circular *1],', -// " [Symbol(Symbol.toStringTag)]: 'Map Iterator'", -// ' }', -// '}', -// ].join('\n'); - -// assert.strict.equal(out, expected); - -// out = util.inspect(map, { compact: 2, showHidden: true, depth: 9 }); - -// expected = [ -// 'Map(2) {', -// ' Promise {', -// ' [', -// ' [', -// ' 1,', -// ' Set(1) { [ 1, 2, [length]: 2 ] },', -// ' [length]: 2', -// ' ],', -// ' [length]: 1', -// ' ]', -// ' } => Uint8Array(0) [', -// ' [BYTES_PER_ELEMENT]: 1,', -// ' [length]: 0,', -// ' [byteLength]: 0,', -// ' [byteOffset]: 0,', -// ' [buffer]: ArrayBuffer { byteLength: 0, foo: true }', -// ' ],', -// ' [Set Iterator] {', -// ' [ 1, 2, [length]: 2 ],', -// " [Symbol(Symbol.toStringTag)]: 'Set Iterator'", -// ' } => <ref *1> [Map Iterator] {', -// ' Uint8Array(0) [', -// ' [BYTES_PER_ELEMENT]: 1,', -// ' [length]: 0,', -// ' [byteLength]: 0,', -// ' [byteOffset]: 0,', -// ' [buffer]: ArrayBuffer { byteLength: 0, foo: true }', -// ' ],', -// ' [Circular *1],', -// " [Symbol(Symbol.toStringTag)]: 'Map Iterator'", -// ' }', -// '}', -// ].join('\n'); - -// assert.strict.equal(out, expected); - -// out = util.inspect(map, { -// showHidden: true, depth: 9, breakLength: 4, compact: true -// }); -// expected = [ -// 'Map(2) {', -// ' Promise {', -// ' [ [ 1,', -// ' Set(1) {', -// ' [ 1,', -// ' 2,', -// ' [length]: 2 ] },', -// ' [length]: 2 ],', -// ' [length]: 1 ] } => Uint8Array(0) [', -// ' [BYTES_PER_ELEMENT]: 1,', -// ' [length]: 0,', -// ' [byteLength]: 0,', -// ' [byteOffset]: 0,', -// ' [buffer]: ArrayBuffer {', -// ' byteLength: 0,', -// ' foo: true } ],', -// ' [Set Iterator] {', -// ' [ 1,', -// ' 2,', -// ' [length]: 2 ],', -// ' [Symbol(Symbol.toStringTag)]:', -// " 'Set Iterator' } => <ref *1> [Map Iterator] {", -// ' Uint8Array(0) [', -// ' [BYTES_PER_ELEMENT]: 1,', -// ' [length]: 0,', -// ' [byteLength]: 0,', -// ' [byteOffset]: 0,', -// ' [buffer]: ArrayBuffer {', -// ' byteLength: 0,', -// ' foo: true } ],', -// ' [Circular *1],', -// ' [Symbol(Symbol.toStringTag)]:', -// " 'Map Iterator' } }", -// ].join('\n'); - -// assert.strict.equal(out, expected); -// } - -// TODO(wafuwafu13): Fix -// { // Test WeakMap && WeakSet -// const obj = {}; -// const arr = []; -// const weakMap = new WeakMap([[obj, arr], [arr, obj]]); -// let out = util.inspect(weakMap, { showHidden: true }); -// let expect = 'WeakMap { [ [length]: 0 ] => {}, {} => [ [length]: 0 ] }'; -// assert.strictEqual(out, expect); - -// out = util.inspect(weakMap); -// expect = 'WeakMap { <items unknown> }'; -// assert.strictEqual(out, expect); - -// out = util.inspect(weakMap, { maxArrayLength: 0, showHidden: true }); -// expect = 'WeakMap { ... 2 more items }'; -// assert.strictEqual(out, expect); - -// weakMap.extra = true; -// out = util.inspect(weakMap, { maxArrayLength: 1, showHidden: true }); -// // It is not possible to determine the output reliable. -// expect = 'WeakMap { [ [length]: 0 ] => {}, ... 1 more item, extra: true }'; -// let expectAlt = 'WeakMap { {} => [ [length]: 0 ], ... 1 more item, ' + -// 'extra: true }'; -// assert(out === expect || out === expectAlt, -// `Found: "${out}"\nrather than: "${expect}"\nor: "${expectAlt}"`); - -// // Test WeakSet -// arr.push(1); -// const weakSet = new WeakSet([obj, arr]); -// out = util.inspect(weakSet, { showHidden: true }); -// expect = 'WeakSet { [ 1, [length]: 1 ], {} }'; -// assert.strictEqual(out, expect); - -// out = util.inspect(weakSet); -// expect = 'WeakSet { <items unknown> }'; -// assert.strictEqual(out, expect); - -// out = util.inspect(weakSet, { maxArrayLength: -2, showHidden: true }); -// expect = 'WeakSet { ... 2 more items }'; -// assert.strictEqual(out, expect); - -// weakSet.extra = true; -// out = util.inspect(weakSet, { maxArrayLength: 1, showHidden: true }); -// // It is not possible to determine the output reliable. -// expect = 'WeakSet { {}, ... 1 more item, extra: true }'; -// expectAlt = 'WeakSet { [ 1, [length]: 1 ], ... 1 more item, extra: true }'; -// assert(out === expect || out === expectAlt, -// `Found: "${out}"\nrather than: "${expect}"\nor: "${expectAlt}"`); -// // Keep references to the WeakMap entries, otherwise they could be GCed too -// // early. -// assert(obj && arr); -// } - -{ // Test argument objects. - const args = (function() { return arguments; })('a'); - assert.strictEqual(util.inspect(args), "[Arguments] { '0': 'a' }"); -} - -{ - // Test that a long linked list can be inspected without throwing an error. - const list = {}; - let head = list; - // A linked list of length 100k should be inspectable in some way, even though - // the real cutoff value is much lower than 100k. - for (let i = 0; i < 100000; i++) - head = head.next = {}; - assert.strictEqual( - util.inspect(list), - '{ next: { next: { next: [Object] } } }' - ); - const longList = util.inspect(list, { depth: Infinity }); - const match = longList.match(/next/g); - assert(match.length > 500 && match.length < 10000); - // TODO(wafuwafu13): Fix - // assert(longList.includes('[Object: Inspection interrupted ' + - // 'prematurely. Maximum call stack size exceeded.]')); -} - -// Do not escape single quotes if no double quote or backtick is present. -assert.strictEqual(util.inspect("'"), '"\'"'); -assert.strictEqual(util.inspect('"\''), '`"\'`'); -// eslint-disable-next-line no-template-curly-in-string -// TODO(@crowlKats) -//assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'"); - -// TODO(wafuwafu13): Fix -// // Errors should visualize as much information as possible. -// // If the name is not included in the stack, visualize it as well. -// [ -// [class Foo extends TypeError {}, 'test'], -// [class Foo extends TypeError {}, undefined], -// [class BarError extends Error {}, 'test'], -// [class BazError extends Error { -// get name() { -// return 'BazError'; -// } -// }, undefined], -// ].forEach(([Class, message], i) => { -// console.log('Test %i', i); -// const foo = new Class(message); -// const name = foo.name; -// const extra = Class.name.includes('Error') ? '' : ` [${foo.name}]`; -// assert( -// util.inspect(foo).startsWith( -// `${Class.name}${extra}${message ? `: ${message}` : '\n'}`), -// util.inspect(foo) -// ); -// Object.defineProperty(foo, Symbol.toStringTag, { -// value: 'WOW', -// writable: true, -// configurable: true -// }); -// const stack = foo.stack; -// foo.stack = 'This is a stack'; -// assert.strictEqual( -// util.inspect(foo), -// '[This is a stack]' -// ); -// foo.stack = stack; -// assert( -// util.inspect(foo).startsWith( -// `${Class.name} [WOW]${extra}${message ? `: ${message}` : '\n'}`), -// util.inspect(foo) -// ); -// Object.setPrototypeOf(foo, null); -// assert( -// util.inspect(foo).startsWith( -// `[${name}: null prototype] [WOW]${message ? `: ${message}` : '\n'}` -// ), -// util.inspect(foo) -// ); -// foo.bar = true; -// delete foo[Symbol.toStringTag]; -// assert( -// util.inspect(foo).startsWith( -// `[${name}: null prototype]${message ? `: ${message}` : '\n'}`), -// util.inspect(foo) -// ); -// foo.stack = 'This is a stack'; -// assert.strictEqual( -// util.inspect(foo), -// '[[Error: null prototype]: This is a stack] { bar: true }' -// ); -// foo.stack = stack.split('\n')[0]; -// assert.strictEqual( -// util.inspect(foo), -// `[[${name}: null prototype]${message ? `: ${message}` : ''}] { bar: true }` -// ); -// }); - -// TODO(wafuwafu13): Fix -// // Verify that classes are properly inspected. -// [ -// /* eslint-disable spaced-comment, no-multi-spaces, brace-style */ -// // The whitespace is intentional. -// [class { }, '[class (anonymous)]'], -// [class extends Error { log() {} }, '[class (anonymous) extends Error]'], -// [class A { constructor(a) { this.a = a; } log() { return this.a; } }, -// '[class A]'], -// [class -// // Random { // comments /* */ are part of the toString() result -// /* eslint-disable-next-line space-before-blocks */ -// äß/**/extends/*{*/TypeError{}, '[class äß extends TypeError]'], -// /* The whitespace and new line is intended! */ -// // Foobar !!! -// [class X extends /****/ Error -// // More comments -// {}, '[class X extends Error]'], -// /* eslint-enable spaced-comment, no-multi-spaces, brace-style */ -// ].forEach(([clazz, string]) => { -// const inspected = util.inspect(clazz); -// assert.strictEqual(inspected, string); -// Object.defineProperty(clazz, Symbol.toStringTag, { -// value: 'Woohoo' -// }); -// const parts = inspected.slice(0, -1).split(' '); -// const [, name, ...rest] = parts; -// rest.unshift('[Woohoo]'); -// if (rest.length) { -// rest[rest.length - 1] += ']'; -// } -// assert.strictEqual( -// util.inspect(clazz), -// ['[class', name, ...rest].join(' ') -// ); -// if (rest.length) { -// rest[rest.length - 1] = rest[rest.length - 1].slice(0, -1); -// rest.length = 1; -// } -// Object.setPrototypeOf(clazz, Map.prototype); -// assert.strictEqual( -// util.inspect(clazz), -// ['[class', name, '[Map]', ...rest].join(' ') + ']' -// ); -// Object.setPrototypeOf(clazz, null); -// assert.strictEqual( -// util.inspect(clazz), -// ['[class', name, ...rest, 'extends [null prototype]]'].join(' ') -// ); -// Object.defineProperty(clazz, 'name', { value: 'Foo' }); -// const res = ['[class', 'Foo', ...rest, 'extends [null prototype]]'].join(' '); -// assert.strictEqual(util.inspect(clazz), res); -// clazz.foo = true; -// assert.strictEqual(util.inspect(clazz), `${res} { foo: true }`); -// }); - -// "class" properties should not be detected as "class". -{ - // eslint-disable-next-line space-before-function-paren - let obj = { class () {} }; - assert.strictEqual( - util.inspect(obj), - '{ class: [Function: class] }' - ); - obj = { class: () => {} }; - assert.strictEqual( - util.inspect(obj), - '{ class: [Function: class] }' - ); - obj = { ['class Foo {}']() {} }; - assert.strictEqual( - util.inspect(obj), - "{ 'class Foo {}': [Function: class Foo {}] }" - ); - function Foo() {} - Object.defineProperty(Foo, 'toString', { value: () => 'class Foo {}' }); - assert.strictEqual( - util.inspect(Foo), - '[Function: Foo]' - ); - function fn() {} - Object.defineProperty(fn, 'name', { value: 'class Foo {}' }); - assert.strictEqual( - util.inspect(fn), - '[Function: class Foo {}]' - ); -} - -// TODO(wafuwafu13): Fix -// // Verify that throwing in valueOf and toString still produces nice results. -// [ -// [new String(55), "[String: '55']"], -// [new Boolean(true), '[Boolean: true]'], -// [new Number(55), '[Number: 55]'], -// [Object(BigInt(55)), '[BigInt: 55n]'], -// [Object(Symbol('foo')), '[Symbol: Symbol(foo)]'], -// [function() {}, '[Function (anonymous)]'], -// [() => {}, '[Function (anonymous)]'], -// [[1, 2], '[ 1, 2 ]'], -// [[, , 5, , , , ], '[ <2 empty items>, 5, <3 empty items> ]'], -// [{ a: 5 }, '{ a: 5 }'], -// [new Set([1, 2]), 'Set(2) { 1, 2 }'], -// [new Map([[1, 2]]), 'Map(1) { 1 => 2 }'], -// [new Set([1, 2]).entries(), '[Set Entries] { [ 1, 1 ], [ 2, 2 ] }'], -// [new Map([[1, 2]]).keys(), '[Map Iterator] { 1 }'], -// [new Date(2000), '1970-01-01T00:00:02.000Z'], -// [new Uint8Array(2), 'Uint8Array(2) [ 0, 0 ]'], -// [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() { -// throw new Error('valueOf'); -// } -// }); -// Object.defineProperty(value, 'toString', { -// get() { -// throw new Error('toString'); -// } -// }); -// assert.strictEqual(util.inspect(value), expected); -// value.foo = 'bar'; -// assert.notStrictEqual(util.inspect(value), expected); -// delete value.foo; -// value[Symbol('foo')] = 'yeah'; -// assert.notStrictEqual(util.inspect(value), expected); -// }); - -// TODO(wafuwafu13): Fix -// // Verify that having no prototype still produces nice results. -// [ -// [[1, 3, 4], '[Array(3): null prototype] [ 1, 3, 4 ]'], -// [new Set([1, 2]), '[Set(2): null prototype] { 1, 2 }'], -// [new Map([[1, 2]]), '[Map(1): null prototype] { 1 => 2 }'], -// [new Promise((resolve) => setTimeout(resolve, 10)), -// '[Promise: null prototype] { <pending> }'], -// [new WeakSet(), '[WeakSet: null prototype] { <items unknown> }'], -// [new WeakMap(), '[WeakMap: null prototype] { <items unknown> }'], -// [new Uint8Array(2), '[Uint8Array(2): null prototype] [ 0, 0 ]'], -// [new Uint16Array(2), '[Uint16Array(2): null prototype] [ 0, 0 ]'], -// [new Uint32Array(2), '[Uint32Array(2): null prototype] [ 0, 0 ]'], -// [new Int8Array(2), '[Int8Array(2): null prototype] [ 0, 0 ]'], -// [new Int16Array(2), '[Int16Array(2): null prototype] [ 0, 0 ]'], -// [new Int32Array(2), '[Int32Array(2): null prototype] [ 0, 0 ]'], -// [new Float32Array(2), '[Float32Array(2): null prototype] [ 0, 0 ]'], -// [new Float64Array(2), '[Float64Array(2): null prototype] [ 0, 0 ]'], -// [new BigInt64Array(2), '[BigInt64Array(2): null prototype] [ 0n, 0n ]'], -// [new BigUint64Array(2), '[BigUint64Array(2): null prototype] [ 0n, 0n ]'], -// [new ArrayBuffer(16), '[ArrayBuffer: null prototype] {\n' + -// ' [Uint8Contents]: <00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00>,\n' + -// ' byteLength: undefined\n}'], -// [new DataView(new ArrayBuffer(16)), -// '[DataView: null prototype] {\n byteLength: undefined,\n ' + -// 'byteOffset: undefined,\n buffer: undefined\n}'], -// [new SharedArrayBuffer(2), '[SharedArrayBuffer: null prototype] ' + -// '{\n [Uint8Contents]: <00 00>,\n byteLength: undefined\n}'], -// [/foobar/, '[RegExp: null prototype] /foobar/'], -// [new Date('Sun, 14 Feb 2010 11:48:40 GMT'), -// '[Date: null prototype] 2010-02-14T11:48:40.000Z'], -// ].forEach(([value, expected]) => { -// assert.strictEqual( -// util.inspect(Object.setPrototypeOf(value, null)), -// expected -// ); -// value.foo = 'bar'; -// assert.notStrictEqual(util.inspect(value), expected); -// delete value.foo; -// value[Symbol('foo')] = 'yeah'; -// assert.notStrictEqual(util.inspect(value), expected); -// }); - -// TODO(wafuwafu13): Fix -// // Verify that subclasses with and without prototype produce nice results. -// [ -// [RegExp, ['foobar', 'g'], '/foobar/g'], -// [WeakSet, [[{}]], '{ <items unknown> }'], -// [WeakMap, [[[{}, {}]]], '{ <items unknown> }'], -// [BigInt64Array, -// [10], -// '[\n 0n, 0n, 0n, 0n, 0n,\n 0n, 0n, 0n, 0n, 0n\n]'], -// [Date, ['Sun, 14 Feb 2010 11:48:40 GMT'], '2010-02-14T11:48:40.000Z'], -// [Date, ['invalid_date'], 'Invalid Date'], -// ].forEach(([base, input, rawExpected]) => { -// class Foo extends base {} -// const value = new Foo(...input); -// const symbol = value[Symbol.toStringTag]; -// const size = base.name.includes('Array') ? `(${input[0]})` : ''; -// const expected = `Foo${size} ${symbol ? `[${symbol}] ` : ''}${rawExpected}`; -// const expectedWithoutProto = -// `[${base.name}${size}: 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.match(res, /foo: 'bar'/); -// delete value.foo; -// value[Symbol('foo')] = 'yeah'; -// res = util.inspect(value); -// assert.notStrictEqual(res, expectedWithoutProto); -// assert.match(res, /\[Symbol\(foo\)]: 'yeah'/); -// }); - -assert.strictEqual(inspect(1n), '1n'); -assert.strictEqual(inspect(Object(-1n)), '[BigInt: -1n]'); -assert.strictEqual(inspect(Object(13n)), '[BigInt: 13n]'); -// TODO(wafuwafu13): Fix -// assert.strictEqual(inspect(new BigInt64Array([0n])), 'BigInt64Array(1) [ 0n ]'); -// assert.strictEqual( -// inspect(new BigUint64Array([0n])), 'BigUint64Array(1) [ 0n ]'); - -// Verify non-enumerable keys get escaped. -{ - const obj = {}; - Object.defineProperty(obj, 'Non\nenumerable\tkey', { value: true }); - assert.strictEqual( - util.inspect(obj, { showHidden: true }), - '{ [Non\\nenumerable\\tkey]: true }' - ); -} - -// Check for special colors. -{ - const special = inspect.colors[inspect.styles.special]; - const string = inspect.colors[inspect.styles.string]; - - assert.strictEqual( - inspect(new WeakSet(), { colors: true }), - `WeakSet { \u001b[${special[0]}m<items unknown>\u001b[${special[1]}m }` - ); - assert.strictEqual( - inspect(new WeakMap(), { colors: true }), - `WeakMap { \u001b[${special[0]}m<items unknown>\u001b[${special[1]}m }` - ); - // TODO(wafuwafu13): Fix - // assert.strictEqual( - // inspect(new Promise(() => {}), { colors: true }), - // `Promise { \u001b[${special[0]}m<pending>\u001b[${special[1]}m }` - // ); - - // const rejection = Promise.reject('Oh no!'); - // assert.strictEqual( - // inspect(rejection, { colors: true }), - // `Promise { \u001b[${special[0]}m<rejected>\u001b[${special[1]}m ` + - // `\u001b[${string[0]}m'Oh no!'\u001b[${string[1]}m }` - // ); - // rejection.catch(() => {}); - - // Verify that aliases do not show up as key while checking `inspect.colors`. - const colors = Object.keys(inspect.colors); - const aliases = Object.getOwnPropertyNames(inspect.colors) - .filter((c) => !colors.includes(c)); - assert(!colors.includes('grey')); - assert(colors.includes('gray')); - // Verify that all aliases are correctly mapped. - for (const alias of aliases) { - assert(Array.isArray(inspect.colors[alias])); - } - // Check consistent naming. - [ - 'black', - 'red', - 'green', - 'yellow', - 'blue', - 'magenta', - 'cyan', - 'white', - ].forEach((color, i) => { - assert.deepStrictEqual(inspect.colors[color], [30 + i, 39]); - assert.deepStrictEqual(inspect.colors[`${color}Bright`], [90 + i, 39]); - const bgColor = `bg${color[0].toUpperCase()}${color.slice(1)}`; - assert.deepStrictEqual(inspect.colors[bgColor], [40 + i, 49]); - assert.deepStrictEqual(inspect.colors[`${bgColor}Bright`], [100 + i, 49]); - }); - - // Unknown colors are handled gracefully: - const stringStyle = inspect.styles.string; - inspect.styles.string = 'UNKNOWN'; - assert.strictEqual(inspect('foobar', { colors: true }), "'foobar'"); - inspect.styles.string = stringStyle; -} - -assert.strictEqual( - inspect([1, 3, 2], { sorted: true }), - inspect([1, 3, 2]) -); -assert.strictEqual( - inspect({ c: 3, a: 1, b: 2 }, { sorted: true }), - '{ a: 1, b: 2, c: 3 }' -); -assert.strictEqual( - inspect( - { a200: 4, a100: 1, a102: 3, a101: 2 }, - { sorted(a, b) { return b.localeCompare(a); } } - ), - '{ a200: 4, a102: 3, a101: 2, a100: 1 }' -); - -// TODO(wafuwafu13): Fix -// // Non-indices array properties are sorted as well. -// { -// const arr = [3, 2, 1]; -// arr.b = 2; -// arr.c = 3; -// arr.a = 1; -// arr[Symbol('b')] = true; -// arr[Symbol('a')] = false; -// assert.strictEqual( -// inspect(arr, { sorted: true }), -// '[ 3, 2, 1, [Symbol(a)]: false, [Symbol(b)]: true, a: 1, b: 2, c: 3 ]' -// ); -// } - -// TODO(wafuwafu13): Fix -// // Manipulate the prototype in weird ways. -// { -// let obj = { a: true }; -// let value = (function() { return function() {}; })(); -// Object.setPrototypeOf(value, null); -// Object.setPrototypeOf(obj, value); -// assert.strictEqual( -// util.inspect(obj), -// 'Object <[Function (null prototype) (anonymous)]> { a: true }' -// ); -// assert.strictEqual( -// util.inspect(obj, { colors: true }), -// 'Object <\u001b[36m[Function (null prototype) (anonymous)]\u001b[39m> ' + -// '{ a: \u001b[33mtrue\u001b[39m }' -// ); - -// obj = { a: true }; -// value = []; -// Object.setPrototypeOf(value, null); -// Object.setPrototypeOf(obj, value); -// assert.strictEqual( -// util.inspect(obj), -// 'Object <[Array(0): null prototype] []> { a: true }' -// ); - -// function StorageObject() {} -// StorageObject.prototype = Object.create(null); -// assert.strictEqual( -// util.inspect(new StorageObject()), -// 'StorageObject <[Object: null prototype] {}> {}' -// ); - -// obj = [1, 2, 3]; -// Object.setPrototypeOf(obj, Number.prototype); -// assert.strictEqual(inspect(obj), "Number { '0': 1, '1': 2, '2': 3 }"); - -// Object.setPrototypeOf(obj, Object.create(null)); -// assert.strictEqual( -// inspect(obj), -// "Array <[Object: null prototype] {}> { '0': 1, '1': 2, '2': 3 }" -// ); - -// StorageObject.prototype = Object.create(null); -// Object.setPrototypeOf(StorageObject.prototype, Object.create(null)); -// Object.setPrototypeOf( -// Object.getPrototypeOf(StorageObject.prototype), -// Object.create(null) -// ); -// assert.strictEqual( -// util.inspect(new StorageObject()), -// 'StorageObject <Object <Object <[Object: null prototype] {}>>> {}' -// ); -// assert.strictEqual( -// util.inspect(new StorageObject(), { depth: 1 }), -// 'StorageObject <Object <Object <Complex prototype>>> {}' -// ); -// } - -// TODO(wafuwafu13): Fix -// // Check that the fallback always works. -// { -// const obj = new Set([1, 2]); -// const iterator = obj[Symbol.iterator]; -// Object.setPrototypeOf(obj, null); -// Object.defineProperty(obj, Symbol.iterator, { -// value: iterator, -// configurable: true -// }); -// assert.strictEqual(util.inspect(obj), '[Set(2): null prototype] { 1, 2 }'); -// Object.defineProperty(obj, Symbol.iterator, { -// value: true, -// configurable: true -// }); -// Object.defineProperty(obj, 'size', { -// value: NaN, -// configurable: true, -// enumerable: true -// }); -// assert.strictEqual( -// util.inspect(obj), -// '[Set(2): null prototype] { 1, 2, size: NaN }' -// ); -// } - -// TODO(wafuwafu13): Fix -// Check the getter option. -{ - let foo = 1; - const get = { get foo() { return foo; } }; - const getset = { - get foo() { return foo; }, - set foo(val) { foo = val; }, - get inc() { return ++foo; } - }; - const thrower = { get foo() { throw new Error('Oops'); } }; - assert.strictEqual( - inspect(get, { getters: true, colors: true }), - '{ foo: \u001b[36m[Getter:\u001b[39m ' + - '\u001b[33m1\u001b[39m\u001b[36m]\u001b[39m }'); - assert.strictEqual( - inspect(thrower, { getters: true }), - '{ foo: [Getter: <Inspection threw (Oops)>] }'); - assert.strictEqual( - inspect(getset, { getters: true }), - '{ foo: [Getter/Setter: 1], inc: [Getter: 2] }'); - assert.strictEqual( - inspect(getset, { getters: 'get' }), - '{ foo: [Getter/Setter], inc: [Getter: 3] }'); - assert.strictEqual( - inspect(getset, { getters: 'set' }), - '{ foo: [Getter/Setter: 3], inc: [Getter] }'); - getset.foo = new Set([[{ a: true }, 2, {}], 'foobar', { x: 1 }]); - // assert.strictEqual( - // inspect(getset, { getters: true }), - // '{\n foo: [Getter/Setter] Set(3) { [ [Object], 2, {} ], ' + - // "'foobar', { x: 1 } },\n inc: [Getter: NaN]\n}"); -} - -// Check compact number mode. -{ - let obj = { - a: { - b: { - x: 5, - c: { - x: '10000000000000000 00000000000000000 '.repeat(1e1), - d: 2, - e: 3 - } - } - }, - b: [ - 1, - 2, - [ 1, 2, { a: 1, b: 2, c: 3 } ], - ], - c: ['foo', 4, 444444], - d: Array.from({ length: 101 }).map((e, i) => { - return i % 2 === 0 ? i * i : i; - }), - e: Array(6).fill('foobar'), - f: Array(9).fill('foobar'), - g: Array(21).fill('foobar baz'), - h: [100].concat(Array.from({ length: 9 }).map((e, n) => (n))), - long: Array(9).fill('This text is too long for grouping!') - }; - - let out = util.inspect(obj, { compact: 3, depth: 10, breakLength: 60 }); - let expected = [ - '{', - ' a: {', - ' b: {', - ' x: 5,', - ' c: {', - " x: '10000000000000000 00000000000000000 10000000000000000 " + - '00000000000000000 10000000000000000 00000000000000000 ' + - '10000000000000000 00000000000000000 10000000000000000 ' + - '00000000000000000 10000000000000000 00000000000000000 ' + - '10000000000000000 00000000000000000 10000000000000000 ' + - '00000000000000000 10000000000000000 00000000000000000 ' + - "10000000000000000 00000000000000000 ',", - ' d: 2,', - ' e: 3', - ' }', - ' }', - ' },', - ' b: [ 1, 2, [ 1, 2, { a: 1, b: 2, c: 3 } ] ],', - " c: [ 'foo', 4, 444444 ],", - ' d: [', - ' 0, 1, 4, 3, 16, 5, 36, 7, 64,', - ' 9, 100, 11, 144, 13, 196, 15, 256, 17,', - ' 324, 19, 400, 21, 484, 23, 576, 25, 676,', - ' 27, 784, 29, 900, 31, 1024, 33, 1156, 35,', - ' 1296, 37, 1444, 39, 1600, 41, 1764, 43, 1936,', - ' 45, 2116, 47, 2304, 49, 2500, 51, 2704, 53,', - ' 2916, 55, 3136, 57, 3364, 59, 3600, 61, 3844,', - ' 63, 4096, 65, 4356, 67, 4624, 69, 4900, 71,', - ' 5184, 73, 5476, 75, 5776, 77, 6084, 79, 6400,', - ' 81, 6724, 83, 7056, 85, 7396, 87, 7744, 89,', - ' 8100, 91, 8464, 93, 8836, 95, 9216, 97, 9604,', - ' 99,', - ' ... 1 more item', - ' ],', - ' e: [', - " 'foobar',", - " 'foobar',", - " 'foobar',", - " 'foobar',", - " 'foobar',", - " 'foobar'", - ' ],', - ' f: [', - " 'foobar', 'foobar',", - " 'foobar', 'foobar',", - " 'foobar', 'foobar',", - " 'foobar', 'foobar',", - " 'foobar'", - ' ],', - ' g: [', - " 'foobar baz', 'foobar baz',", - " 'foobar baz', 'foobar baz',", - " 'foobar baz', 'foobar baz',", - " 'foobar baz', 'foobar baz',", - " 'foobar baz', 'foobar baz',", - " 'foobar baz', 'foobar baz',", - " 'foobar baz', 'foobar baz',", - " 'foobar baz', 'foobar baz',", - " 'foobar baz', 'foobar baz',", - " 'foobar baz', 'foobar baz',", - " 'foobar baz'", - ' ],', - ' h: [', - ' 100, 0, 1, 2, 3,', - ' 4, 5, 6, 7, 8', - ' ],', - ' long: [', - " 'This text is too long for grouping!',", - " 'This text is too long for grouping!',", - " 'This text is too long for grouping!',", - " 'This text is too long for grouping!',", - " 'This text is too long for grouping!',", - " 'This text is too long for grouping!',", - " 'This text is too long for grouping!',", - " 'This text is too long for grouping!',", - " 'This text is too long for grouping!'", - ' ]', - '}', - ].join('\n'); - - // TODO(wafuwafu13): Fix - // assert.strictEqual(out, expected); - - obj = [ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 123456789, - ]; - - out = util.inspect(obj, { compact: 3 }); - - expected = [ - '[', - ' 1, 1, 1, 1,', - ' 1, 1, 1, 1,', - ' 1, 1, 1, 1,', - ' 1, 1, 1, 1,', - ' 1, 1, 1, 1,', - ' 1, 1, 1, 1,', - ' 1, 1, 123456789', - ']', - ].join('\n'); - - // TODO(wafuwafu13): Fix - // assert.strictEqual(out, expected); - - // Unicode support. あ has a length of one and a width of two. - obj = [ - '123', '123', '123', '123', 'あああ', - '123', '123', '123', '123', 'あああ', - ]; - - out = util.inspect(obj, { compact: 3 }); - - expected = [ - '[', - " '123', '123',", - " '123', '123',", - " 'あああ', '123',", - " '123', '123',", - " '123', 'あああ'", - ']', - ].join('\n'); - - // TODO(wafuwafu13): Fix - // assert.strictEqual(out, expected); - - // Verify that array grouping and line consolidation does not happen together. - obj = { - a: { - b: { - x: 5, - c: { - d: 2, - e: 3 - } - } - }, - b: Array.from({ length: 9 }).map((e, n) => { - return n % 2 === 0 ? 'foobar' : 'baz'; - }) - }; - - out = util.inspect(obj, { compact: 1, breakLength: Infinity, colors: true }); - - expected = [ - '{', - ' a: {', - ' b: { x: \u001b[33m5\u001b[39m, c: \u001b[36m[Object]\u001b[39m }', - ' },', - ' b: [', - " \u001b[32m'foobar'\u001b[39m, \u001b[32m'baz'\u001b[39m,", - " \u001b[32m'foobar'\u001b[39m, \u001b[32m'baz'\u001b[39m,", - " \u001b[32m'foobar'\u001b[39m, \u001b[32m'baz'\u001b[39m,", - " \u001b[32m'foobar'\u001b[39m, \u001b[32m'baz'\u001b[39m,", - " \u001b[32m'foobar'\u001b[39m", - ' ]', - '}', - ].join('\n'); - - // TODO(wafuwafu13): Fix - // assert.strictEqual(out, expected); - - obj = Array.from({ length: 60 }).map((e, i) => i); - out = util.inspect(obj, { compact: 1, breakLength: Infinity, colors: true }); - - expected = [ - '[', - /* eslint-disable max-len */ - ' \u001b[33m0\u001b[39m, \u001b[33m1\u001b[39m, \u001b[33m2\u001b[39m, \u001b[33m3\u001b[39m,', - ' \u001b[33m4\u001b[39m, \u001b[33m5\u001b[39m, \u001b[33m6\u001b[39m, \u001b[33m7\u001b[39m,', - ' \u001b[33m8\u001b[39m, \u001b[33m9\u001b[39m, \u001b[33m10\u001b[39m, \u001b[33m11\u001b[39m,', - ' \u001b[33m12\u001b[39m, \u001b[33m13\u001b[39m, \u001b[33m14\u001b[39m, \u001b[33m15\u001b[39m,', - ' \u001b[33m16\u001b[39m, \u001b[33m17\u001b[39m, \u001b[33m18\u001b[39m, \u001b[33m19\u001b[39m,', - ' \u001b[33m20\u001b[39m, \u001b[33m21\u001b[39m, \u001b[33m22\u001b[39m, \u001b[33m23\u001b[39m,', - ' \u001b[33m24\u001b[39m, \u001b[33m25\u001b[39m, \u001b[33m26\u001b[39m, \u001b[33m27\u001b[39m,', - ' \u001b[33m28\u001b[39m, \u001b[33m29\u001b[39m, \u001b[33m30\u001b[39m, \u001b[33m31\u001b[39m,', - ' \u001b[33m32\u001b[39m, \u001b[33m33\u001b[39m, \u001b[33m34\u001b[39m, \u001b[33m35\u001b[39m,', - ' \u001b[33m36\u001b[39m, \u001b[33m37\u001b[39m, \u001b[33m38\u001b[39m, \u001b[33m39\u001b[39m,', - ' \u001b[33m40\u001b[39m, \u001b[33m41\u001b[39m, \u001b[33m42\u001b[39m, \u001b[33m43\u001b[39m,', - ' \u001b[33m44\u001b[39m, \u001b[33m45\u001b[39m, \u001b[33m46\u001b[39m, \u001b[33m47\u001b[39m,', - ' \u001b[33m48\u001b[39m, \u001b[33m49\u001b[39m, \u001b[33m50\u001b[39m, \u001b[33m51\u001b[39m,', - ' \u001b[33m52\u001b[39m, \u001b[33m53\u001b[39m, \u001b[33m54\u001b[39m, \u001b[33m55\u001b[39m,', - ' \u001b[33m56\u001b[39m, \u001b[33m57\u001b[39m, \u001b[33m58\u001b[39m, \u001b[33m59\u001b[39m', - /* eslint-enable max-len */ - ']', - ].join('\n'); - - // TODO(wafuwafu13): Fix - // assert.strictEqual(out, expected); - - out = util.inspect([1, 2, 3, 4], { compact: 1, colors: true }); - expected = '[ \u001b[33m1\u001b[39m, \u001b[33m2\u001b[39m, ' + - '\u001b[33m3\u001b[39m, \u001b[33m4\u001b[39m ]'; - - assert.strictEqual(out, expected); - - obj = [ - 'Object', 'Function', 'Array', - 'Number', 'parseFloat', 'parseInt', - 'Infinity', 'NaN', 'undefined', - 'Boolean', 'String', 'Symbol', - 'Date', 'Promise', 'RegExp', - 'Error', 'EvalError', 'RangeError', - 'ReferenceError', 'SyntaxError', 'TypeError', - 'URIError', 'JSON', 'Math', - 'console', 'Intl', 'ArrayBuffer', - 'Uint8Array', 'Int8Array', 'Uint16Array', - 'Int16Array', 'Uint32Array', 'Int32Array', - 'Float32Array', 'Float64Array', 'Uint8ClampedArray', - 'BigUint64Array', 'BigInt64Array', 'DataView', - 'Map', 'BigInt', 'Set', - 'WeakMap', 'WeakSet', 'Proxy', - 'Reflect', 'decodeURI', 'decodeURIComponent', - 'encodeURI', 'encodeURIComponent', 'escape', - 'unescape', 'eval', 'isFinite', - 'isNaN', 'SharedArrayBuffer', 'Atomics', - 'globalThis', 'WebAssembly', 'global', - 'process', 'Buffer', 'URL', - 'URLSearchParams', 'TextEncoder', 'TextDecoder', - 'clearInterval', 'clearTimeout', 'setInterval', - 'setTimeout', 'queueMicrotask', 'clearImmediate', - 'setImmediate', 'module', 'require', - 'assert', 'async_hooks', 'buffer', - 'child_process', 'cluster', 'crypto', - 'dgram', 'dns', 'domain', - 'events', 'fs', 'http', - 'http2', 'https', 'inspector', - 'net', 'os', 'path', - 'perf_hooks', 'punycode', 'querystring', - 'readline', 'repl', 'stream', - 'string_decoder', 'tls', 'trace_events', - 'tty', 'url', 'v8', - 'vm', 'worker_threads', 'zlib', - '_', '_error', 'util', - ]; - - out = util.inspect( - obj, - { compact: 3, breakLength: 80, maxArrayLength: 250 } - ); - expected = [ - '[', - " 'Object', 'Function', 'Array',", - " 'Number', 'parseFloat', 'parseInt',", - " 'Infinity', 'NaN', 'undefined',", - " 'Boolean', 'String', 'Symbol',", - " 'Date', 'Promise', 'RegExp',", - " 'Error', 'EvalError', 'RangeError',", - " 'ReferenceError', 'SyntaxError', 'TypeError',", - " 'URIError', 'JSON', 'Math',", - " 'console', 'Intl', 'ArrayBuffer',", - " 'Uint8Array', 'Int8Array', 'Uint16Array',", - " 'Int16Array', 'Uint32Array', 'Int32Array',", - " 'Float32Array', 'Float64Array', 'Uint8ClampedArray',", - " 'BigUint64Array', 'BigInt64Array', 'DataView',", - " 'Map', 'BigInt', 'Set',", - " 'WeakMap', 'WeakSet', 'Proxy',", - " 'Reflect', 'decodeURI', 'decodeURIComponent',", - " 'encodeURI', 'encodeURIComponent', 'escape',", - " 'unescape', 'eval', 'isFinite',", - " 'isNaN', 'SharedArrayBuffer', 'Atomics',", - " 'globalThis', 'WebAssembly', 'global',", - " 'process', 'Buffer', 'URL',", - " 'URLSearchParams', 'TextEncoder', 'TextDecoder',", - " 'clearInterval', 'clearTimeout', 'setInterval',", - " 'setTimeout', 'queueMicrotask', 'clearImmediate',", - " 'setImmediate', 'module', 'require',", - " 'assert', 'async_hooks', 'buffer',", - " 'child_process', 'cluster', 'crypto',", - " 'dgram', 'dns', 'domain',", - " 'events', 'fs', 'http',", - " 'http2', 'https', 'inspector',", - " 'net', 'os', 'path',", - " 'perf_hooks', 'punycode', 'querystring',", - " 'readline', 'repl', 'stream',", - " 'string_decoder', 'tls', 'trace_events',", - " 'tty', 'url', 'v8',", - " 'vm', 'worker_threads', 'zlib',", - " '_', '_error', 'util'", - ']', - ].join('\n'); - - // TODO(wafuwafu13): Fix - // assert.strictEqual(out, expected); -} - -// TODO(wafuwafu13): Fix -// { -// // Use a fake stack to verify the expected colored outcome. -// const stack = [ -// 'TypedError: Wonderful message!', -// ' at A.<anonymous> (/test/node_modules/foo/node_modules/bar/baz.js:2:7)', -// ' at Module._compile (node:internal/modules/cjs/loader:827:30)', -// ' at Fancy (node:vm:697:32)', -// // This file is not an actual Node.js core file. -// ' at tryModuleLoad (node:internal/modules/cjs/foo:629:12)', -// ' at Function.Module._load (node:internal/modules/cjs/loader:621:3)', -// // This file is not an actual Node.js core file. -// ' at Module.require [as weird/name] (node:internal/aaaaa/loader:735:19)', -// ' at require (node:internal/modules/cjs/helpers:14:16)', -// ' at /test/test-util-inspect.js:2239:9', -// ' at getActual (node:assert:592:5)', -// ]; -// const isNodeCoreFile = [ -// false, false, true, true, false, true, false, true, false, true, -// ]; -// const err = new TypeError('Wonderful message!'); -// err.stack = stack.join('\n'); -// util.inspect(err, { colors: true }).split('\n').forEach((line, i) => { -// let actual = stack[i].replace(/node_modules\/([a-z]+)/g, (a, m) => { -// return `node_modules/\u001b[4m${m}\u001b[24m`; -// }); -// if (isNodeCoreFile[i]) { -// actual = `\u001b[90m${actual}\u001b[39m`; -// } -// assert.strictEqual(actual, line); -// }); -// } - -// { -// // Cross platform checks. -// const err = new Error('foo'); -// util.inspect(err, { colors: true }).split('\n').forEach((line, i) => { -// assert(i < 2 || line.startsWith('\u001b[90m')); -// }); -// } - -// TODO(wafuwafu13): Implement "trace_events" -// { -// // Tracing class respects inspect depth. -// try { -// const trace = require('trace_events').createTracing({ categories: ['fo'] }); -// const actualDepth0 = util.inspect({ trace }, { depth: 0 }); -// assert.strictEqual(actualDepth0, '{ trace: [Tracing] }'); -// const actualDepth1 = util.inspect({ trace }, { depth: 1 }); -// assert.strictEqual( -// actualDepth1, -// "{ trace: Tracing { enabled: false, categories: 'fo' } }" -// ); -// } catch (err) { -// if (err.code !== 'ERR_TRACE_EVENTS_UNAVAILABLE') -// throw err; -// } -// } - -// Inspect prototype properties. -{ - class Foo extends Map { - prop = false; - prop2 = true; - get abc() { - return true; - } - get def() { - return false; - } - set def(v) {} - get xyz() { - return 'Should be ignored'; - } - func(a) {} - [util.inspect.custom]() { - return this; - } - } - - class Bar extends Foo { - abc = true; - prop = true; - get xyz() { - return 'YES!'; - } - [util.inspect.custom]() { - return this; - } - } - - const bar = new Bar(); - - assert.strictEqual( - inspect(bar), - 'Bar(0) [Map] { prop: true, prop2: true, abc: true }' - ); - // TODO(wafuwafu13): Fix - // assert.strictEqual( - // inspect(bar, { showHidden: true, getters: true, colors: false }), - // 'Bar(0) [Map] {\n' + - // ' prop: true,\n' + - // ' prop2: true,\n' + - // ' abc: true,\n' + - // " [xyz]: [Getter: 'YES!'],\n" + - // ' [def]: [Getter/Setter: false]\n' + - // '}' - // ); - // assert.strictEqual( - // inspect(bar, { showHidden: true, getters: false, colors: true }), - // 'Bar(0) [Map] {\n' + - // ' prop: \x1B[33mtrue\x1B[39m,\n' + - // ' prop2: \x1B[33mtrue\x1B[39m,\n' + - // ' abc: \x1B[33mtrue\x1B[39m,\n' + - // ' \x1B[2m[xyz]: \x1B[36m[Getter]\x1B[39m\x1B[22m,\n' + - // ' \x1B[2m[def]: \x1B[36m[Getter/Setter]\x1B[39m\x1B[22m\n' + - // '}' - // ); - - // const obj = Object.create({ abc: true, def: 5, toString() {} }); - // assert.strictEqual( - // inspect(obj, { showHidden: true, colors: true }), - // '{ \x1B[2mabc: \x1B[33mtrue\x1B[39m\x1B[22m, ' + - // '\x1B[2mdef: \x1B[33m5\x1B[39m\x1B[22m }' - // ); - - // assert.strictEqual( - // inspect(Object.getPrototypeOf(bar), { showHidden: true, getters: true }), - // '<ref *1> Foo [Map] {\n' + - // ' [constructor]: [class Bar extends Foo] {\n' + - // ' [length]: 0,\n' + - // " [name]: 'Bar',\n" + - // ' [prototype]: [Circular *1],\n' + - // ' [Symbol(Symbol.species)]: [Getter: <Inspection threw ' + - // "(Symbol.prototype.toString requires that 'this' be a Symbol)>]\n" + - // ' },\n' + - // " [xyz]: [Getter: 'YES!'],\n" + - // ' [Symbol(nodejs.util.inspect.custom)]: ' + - // '[Function: [nodejs.util.inspect.custom]] {\n' + - // ' [length]: 0,\n' + - // " [name]: '[nodejs.util.inspect.custom]'\n" + - // ' },\n' + - // ' [abc]: [Getter: true],\n' + - // ' [def]: [Getter/Setter: false]\n' + - // ' }' - // ); - - // assert.strictEqual( - // inspect(Object.getPrototypeOf(bar)), - // 'Foo [Map] {}' - // ); - - // assert.strictEqual( - // inspect(Object.getPrototypeOf(new Foo())), - // 'Map {}' - // ); -} - -// Check that prototypes with a null prototype are inspectable. -// Regression test for https://github.com/nodejs/node/issues/35730 -{ - function Func() {} - Func.prototype = null; - const object = {}; - object.constructor = Func; - - assert.strictEqual(util.inspect(object), '{ constructor: [Function: Func] }'); -} - -// Test changing util.inspect.colors colors and aliases. -{ - const colors = util.inspect.colors; - - const originalValue = colors.gray; - - // "grey" is reference-equal alias of "gray". - assert.strictEqual(colors.grey, colors.gray); - - // Assigninging one should assign the other. This tests that the alias setter - // function keeps things reference-equal. - colors.gray = [0, 0]; - assert.deepStrictEqual(colors.gray, [0, 0]); - assert.strictEqual(colors.grey, colors.gray); - - colors.grey = [1, 1]; - assert.deepStrictEqual(colors.grey, [1, 1]); - assert.strictEqual(colors.grey, colors.gray); - - // Restore original value to avoid side effects in other tests. - colors.gray = originalValue; - assert.deepStrictEqual(colors.gray, originalValue); - assert.strictEqual(colors.grey, colors.gray); -} - -// TODO(wafuwafu13): Implement 'vm' -// // https://github.com/nodejs/node/issues/31889 -// { -// v8.setFlagsFromString('--allow-natives-syntax'); -// const undetectable = vm.runInThisContext('%GetUndetectable()'); -// v8.setFlagsFromString('--no-allow-natives-syntax'); -// assert.strictEqual(inspect(undetectable), '{}'); -// } - -// Truncate output for Primitives with 1 character left -{ - assert.strictEqual(util.inspect('bl', { maxStringLength: 1 }), - "'b'... 1 more character"); -} - -{ - const x = 'a'.repeat(1e6); - assert(util.inspect(x).endsWith('... 990000 more characters')); - assert.strictEqual( - util.inspect(x, { maxStringLength: 4 }), - "'aaaa'... 999996 more characters" - ); - assert.match(util.inspect(x, { maxStringLength: null }), /a'$/); -} - -// TODO(wafuwafu13): Implement 'vm' -// { -// // Verify that util.inspect() invokes custom inspect functions on objects -// // from other vm.Contexts but does not pass data from its own Context to that -// // function. -// const target = vm.runInNewContext(` -// ({ -// [Symbol.for('nodejs.util.inspect.custom')](depth, ctx) { -// this.depth = depth; -// this.ctx = ctx; -// try { -// this.stylized = ctx.stylize('🐈'); -// } catch (e) { -// this.stylizeException = e; -// } -// return this.stylized; -// } -// }) -// `, Object.create(null)); -// assert.strictEqual(target.ctx, undefined); - -// { -// // Subtest 1: Just try to inspect the object with default options. -// assert.strictEqual(util.inspect(target), '🐈'); -// assert.strictEqual(typeof target.ctx, 'object'); -// const objectGraph = fullObjectGraph(target); -// assert(!objectGraph.has(Object)); -// assert(!objectGraph.has(Function)); -// } - -// { -// // Subtest 2: Use a stylize function that returns a non-primitive. -// const output = util.inspect(target, { -// stylize: common.mustCall((str) => { -// return {}; -// }) -// }); -// assert.strictEqual(output, '[object Object]'); -// assert.strictEqual(typeof target.ctx, 'object'); -// const objectGraph = fullObjectGraph(target); -// assert(!objectGraph.has(Object)); -// assert(!objectGraph.has(Function)); -// } - -// { -// // Subtest 3: Use a stylize function that throws an exception. -// const output = util.inspect(target, { -// stylize: common.mustCall((str) => { -// throw new Error('oops'); -// }) -// }); -// assert.strictEqual(output, '🐈'); -// assert.strictEqual(typeof target.ctx, 'object'); -// const objectGraph = fullObjectGraph(target); -// assert(!objectGraph.has(Object)); -// assert(!objectGraph.has(Function)); -// } - -// function fullObjectGraph(value) { -// const graph = new Set([value]); - -// for (const entry of graph) { -// if ((typeof entry !== 'object' && typeof entry !== 'function') || -// entry === null) { -// continue; -// } - -// graph.add(Object.getPrototypeOf(entry)); -// const descriptors = Object.values( -// Object.getOwnPropertyDescriptors(entry)); -// for (const descriptor of descriptors) { -// graph.add(descriptor.value); -// graph.add(descriptor.set); -// graph.add(descriptor.get); -// } -// } - -// return graph; -// } - -// // Consistency check. -// assert(fullObjectGraph(global).has(Function.prototype)); -// } - -{ - // Confirm that own constructor value displays correctly. - - function Fhqwhgads() {} - - const sterrance = new Fhqwhgads(); - sterrance.constructor = Fhqwhgads; - - assert.strictEqual( - util.inspect(sterrance, { showHidden: true }), - 'Fhqwhgads {\n' + - ' constructor: <ref *1> [Function: Fhqwhgads] {\n' + - ' [length]: 0,\n' + - " [name]: 'Fhqwhgads',\n" + - ' [prototype]: { [constructor]: [Circular *1] }\n' + - ' }\n' + - '}' - ); -} - -// TODO(wafuwafu13): Fix TypeError: main.hasOwnProperty is not a function -// { -// // Confirm null prototype of generator prototype displays as expected. - -// function getProtoOfProto() { -// return Object.getPrototypeOf(Object.getPrototypeOf(function* () {})); -// } - -// function* generator() {} - -// const generatorPrototype = Object.getPrototypeOf(generator); -// const originalProtoOfProto = Object.getPrototypeOf(generatorPrototype); -// assert.strictEqual(getProtoOfProto(), originalProtoOfProto); -// Object.setPrototypeOf(generatorPrototype, null); -// assert.notStrictEqual(getProtoOfProto, originalProtoOfProto); - -// // This is the actual test. The other assertions in this block are about -// // making sure the test is set up correctly and isn't polluting other tests. -// assert.strictEqual( -// util.inspect(generator, { showHidden: true }), -// '[GeneratorFunction: generator] {\n' + -// ' [length]: 0,\n' + -// " [name]: 'generator',\n" + -// " [prototype]: Object [Generator] { [Symbol(Symbol.toStringTag)]: 'Generator' },\n" + // eslint-disable-line max-len -// " [Symbol(Symbol.toStringTag)]: 'GeneratorFunction'\n" + -// '}' -// ); - -// // Reset so we don't pollute other tests -// Object.setPrototypeOf(generatorPrototype, originalProtoOfProto); -// assert.strictEqual(getProtoOfProto(), originalProtoOfProto); -// } - -{ - // Test for when breakLength results in a single column. - const obj = Array(9).fill('fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf'); - assert.strictEqual( - util.inspect(obj, { breakLength: 256 }), - '[\n' + - " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf',\n" + - " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf',\n" + - " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf',\n" + - " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf',\n" + - " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf',\n" + - " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf',\n" + - " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf',\n" + - " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf',\n" + - " 'fhqwhgadshgnsdhjsdbkhsdabkfabkveybvf'\n" + - ']' - ); -} - -{ - assert.strictEqual( - util.inspect({ ['__proto__']: { a: 1 } }), - "{ ['__proto__']: { a: 1 } }" - ); -} |