1'use strict'; 2 3require('../common'); 4 5const assert = require('assert'); 6const { Console } = require('console'); 7 8const queue = []; 9 10const console = new Console({ write: (x) => { 11 queue.push(x); 12}, removeListener: () => {} }, process.stderr, false); 13 14function test(data, only, expected) { 15 if (arguments.length === 2) { 16 expected = only; 17 only = undefined; 18 } 19 console.table(data, only); 20 assert.deepStrictEqual( 21 queue.shift().split('\n'), 22 expected.trimLeft().split('\n') 23 ); 24} 25 26assert.throws(() => console.table([], false), { 27 code: 'ERR_INVALID_ARG_TYPE', 28}); 29 30test(null, 'null\n'); 31test(undefined, 'undefined\n'); 32test(false, 'false\n'); 33test('hi', 'hi\n'); 34test(Symbol(), 'Symbol()\n'); 35test(function() {}, '[Function (anonymous)]\n'); 36 37test([1, 2, 3], ` 38┌─────────┬────────┐ 39│ (index) │ Values │ 40├─────────┼────────┤ 41│ 0 │ 1 │ 42│ 1 │ 2 │ 43│ 2 │ 3 │ 44└─────────┴────────┘ 45`); 46 47test([Symbol(), 5, [10]], ` 48┌─────────┬────┬──────────┐ 49│ (index) │ 0 │ Values │ 50├─────────┼────┼──────────┤ 51│ 0 │ │ Symbol() │ 52│ 1 │ │ 5 │ 53│ 2 │ 10 │ │ 54└─────────┴────┴──────────┘ 55`); 56 57test([null, 5], ` 58┌─────────┬────────┐ 59│ (index) │ Values │ 60├─────────┼────────┤ 61│ 0 │ null │ 62│ 1 │ 5 │ 63└─────────┴────────┘ 64`); 65 66test([undefined, 5], ` 67┌─────────┬───────────┐ 68│ (index) │ Values │ 69├─────────┼───────────┤ 70│ 0 │ undefined │ 71│ 1 │ 5 │ 72└─────────┴───────────┘ 73`); 74 75test({ a: 1, b: Symbol(), c: [10] }, ` 76┌─────────┬────┬──────────┐ 77│ (index) │ 0 │ Values │ 78├─────────┼────┼──────────┤ 79│ a │ │ 1 │ 80│ b │ │ Symbol() │ 81│ c │ 10 │ │ 82└─────────┴────┴──────────┘ 83`); 84 85test(new Map([ ['a', 1], [Symbol(), [2]] ]), ` 86┌───────────────────┬──────────┬────────┐ 87│ (iteration index) │ Key │ Values │ 88├───────────────────┼──────────┼────────┤ 89│ 0 │ 'a' │ 1 │ 90│ 1 │ Symbol() │ [ 2 ] │ 91└───────────────────┴──────────┴────────┘ 92`); 93 94test(new Set([1, 2, Symbol()]), ` 95┌───────────────────┬──────────┐ 96│ (iteration index) │ Values │ 97├───────────────────┼──────────┤ 98│ 0 │ 1 │ 99│ 1 │ 2 │ 100│ 2 │ Symbol() │ 101└───────────────────┴──────────┘ 102`); 103 104test({ a: 1, b: 2 }, ['a'], ` 105┌─────────┬───┐ 106│ (index) │ a │ 107├─────────┼───┤ 108│ a │ │ 109│ b │ │ 110└─────────┴───┘ 111`); 112 113test([{ a: 1, b: 2 }, { a: 3, c: 4 }], ['a'], ` 114┌─────────┬───┐ 115│ (index) │ a │ 116├─────────┼───┤ 117│ 0 │ 1 │ 118│ 1 │ 3 │ 119└─────────┴───┘ 120`); 121 122test(new Map([[1, 1], [2, 2], [3, 3]]).entries(), ` 123┌───────────────────┬─────┬────────┐ 124│ (iteration index) │ Key │ Values │ 125├───────────────────┼─────┼────────┤ 126│ 0 │ 1 │ 1 │ 127│ 1 │ 2 │ 2 │ 128│ 2 │ 3 │ 3 │ 129└───────────────────┴─────┴────────┘ 130`); 131 132test(new Map([[1, 1], [2, 2], [3, 3]]).values(), ` 133┌───────────────────┬────────┐ 134│ (iteration index) │ Values │ 135├───────────────────┼────────┤ 136│ 0 │ 1 │ 137│ 1 │ 2 │ 138│ 2 │ 3 │ 139└───────────────────┴────────┘ 140`); 141 142test(new Map([[1, 1], [2, 2], [3, 3]]).keys(), ` 143┌───────────────────┬────────┐ 144│ (iteration index) │ Values │ 145├───────────────────┼────────┤ 146│ 0 │ 1 │ 147│ 1 │ 2 │ 148│ 2 │ 3 │ 149└───────────────────┴────────┘ 150`); 151 152test(new Set([1, 2, 3]).values(), ` 153┌───────────────────┬────────┐ 154│ (iteration index) │ Values │ 155├───────────────────┼────────┤ 156│ 0 │ 1 │ 157│ 1 │ 2 │ 158│ 2 │ 3 │ 159└───────────────────┴────────┘ 160`); 161 162 163test({ a: { a: 1, b: 2, c: 3 } }, ` 164┌─────────┬───┬───┬───┐ 165│ (index) │ a │ b │ c │ 166├─────────┼───┼───┼───┤ 167│ a │ 1 │ 2 │ 3 │ 168└─────────┴───┴───┴───┘ 169`); 170 171test({ a: { a: { a: 1, b: 2, c: 3 } } }, ` 172┌─────────┬──────────┐ 173│ (index) │ a │ 174├─────────┼──────────┤ 175│ a │ [Object] │ 176└─────────┴──────────┘ 177`); 178 179test({ a: [1, 2] }, ` 180┌─────────┬───┬───┐ 181│ (index) │ 0 │ 1 │ 182├─────────┼───┼───┤ 183│ a │ 1 │ 2 │ 184└─────────┴───┴───┘ 185`); 186 187test({ a: [1, 2, 3, 4, 5], b: 5, c: { e: 5 } }, ` 188┌─────────┬───┬───┬───┬───┬───┬───┬────────┐ 189│ (index) │ 0 │ 1 │ 2 │ 3 │ 4 │ e │ Values │ 190├─────────┼───┼───┼───┼───┼───┼───┼────────┤ 191│ a │ 1 │ 2 │ 3 │ 4 │ 5 │ │ │ 192│ b │ │ │ │ │ │ │ 5 │ 193│ c │ │ │ │ │ │ 5 │ │ 194└─────────┴───┴───┴───┴───┴───┴───┴────────┘ 195`); 196 197test(new Uint8Array([1, 2, 3]), ` 198┌─────────┬────────┐ 199│ (index) │ Values │ 200├─────────┼────────┤ 201│ 0 │ 1 │ 202│ 1 │ 2 │ 203│ 2 │ 3 │ 204└─────────┴────────┘ 205`); 206 207test(Buffer.from([1, 2, 3]), ` 208┌─────────┬────────┐ 209│ (index) │ Values │ 210├─────────┼────────┤ 211│ 0 │ 1 │ 212│ 1 │ 2 │ 213│ 2 │ 3 │ 214└─────────┴────────┘ 215`); 216 217test({ a: undefined }, ['x'], ` 218┌─────────┬───┐ 219│ (index) │ x │ 220├─────────┼───┤ 221│ a │ │ 222└─────────┴───┘ 223`); 224 225test([], ` 226┌─────────┐ 227│ (index) │ 228├─────────┤ 229└─────────┘ 230`); 231 232test(new Map(), ` 233┌───────────────────┬─────┬────────┐ 234│ (iteration index) │ Key │ Values │ 235├───────────────────┼─────┼────────┤ 236└───────────────────┴─────┴────────┘ 237`); 238 239test([{ a: 1, b: 'Y' }, { a: 'Z', b: 2 }], ` 240┌─────────┬─────┬─────┐ 241│ (index) │ a │ b │ 242├─────────┼─────┼─────┤ 243│ 0 │ 1 │ 'Y' │ 244│ 1 │ 'Z' │ 2 │ 245└─────────┴─────┴─────┘ 246`); 247 248{ 249 const line = '─'.repeat(79); 250 const header = `${' '.repeat(37)}name${' '.repeat(40)}`; 251 const name = 'very long long long long long long long long long long long ' + 252 'long long long long'; 253 test([{ name }], ` 254┌─────────┬──${line}──┐ 255│ (index) │ ${header}│ 256├─────────┼──${line}──┤ 257│ 0 │ '${name}' │ 258└─────────┴──${line}──┘ 259`); 260} 261 262test({ foo: '¥', bar: '¥' }, ` 263┌─────────┬────────┐ 264│ (index) │ Values │ 265├─────────┼────────┤ 266│ foo │ '¥' │ 267│ bar │ '¥' │ 268└─────────┴────────┘ 269`); 270 271test({ foo: '你好', bar: 'hello' }, ` 272┌─────────┬─────────┐ 273│ (index) │ Values │ 274├─────────┼─────────┤ 275│ foo │ '你好' │ 276│ bar │ 'hello' │ 277└─────────┴─────────┘ 278`); 279 280// Regression test for prototype pollution via console.table. Earlier versions 281// of Node.js created an object with a non-null prototype within console.table 282// and then wrote to object[column][index], which lead to an error as well as 283// modifications to Object.prototype. 284test([{ foo: 10 }, { foo: 20 }], ['__proto__'], ` 285┌─────────┬───────────┐ 286│ (index) │ __proto__ │ 287├─────────┼───────────┤ 288│ 0 │ │ 289│ 1 │ │ 290└─────────┴───────────┘ 291`); 292assert.strictEqual('0' in Object.prototype, false); 293assert.strictEqual('1' in Object.prototype, false); 294