deno.land / std@0.166.0 / node / _tools / test / parallel / test-util-inspect.js
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201// 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');// TODO(wafuwafu13): Implement 'vm'// 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'");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-matchingassert.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 }');}
// TODO(wafuwafu13): Implement 'vm'// // 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); // TODO(wafuwafu13): Fix // 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/1941assert.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); 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-stringassert.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 } }" );}
Version Info