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) │ Values40├─────────┼────────┤
41014212432344└─────────┴────────┘
45`);
46
47test([Symbol(), 5, [10]], `
48┌─────────┬────┬──────────┐
49│ (index) │ 0Values50├─────────┼────┼──────────┤
510    │    │ Symbol() │
521    │    │    553210 │          │
54└─────────┴────┴──────────┘
55`);
56
57test([null, 5], `
58┌─────────┬────────┐
59│ (index) │ Values60├─────────┼────────┤
610null621563└─────────┴────────┘
64`);
65
66test([undefined, 5], `
67┌─────────┬───────────┐
68│ (index) │  Values69├─────────┼───────────┤
700undefined711572└─────────┴───────────┘
73`);
74
75test({ a: 1, b: Symbol(), c: [10] }, `
76┌─────────┬────┬──────────┐
77│ (index) │ 0Values78├─────────┼────┼──────────┤
79│    a    │    │    180│    b    │    │ Symbol() │
81│    c    │ 10 │          │
82└─────────┴────┴──────────┘
83`);
84
85test(new Map([ ['a', 1], [Symbol(), [2]] ]), `
86┌───────────────────┬──────────┬────────┐
87│ (iteration index) │   KeyValues88├───────────────────┼──────────┼────────┤
890'a'1901Symbol() │ [ 2 ]  │
91└───────────────────┴──────────┴────────┘
92`);
93
94test(new Set([1, 2, Symbol()]), `
95┌───────────────────┬──────────┐
96│ (iteration index) │  Values97├───────────────────┼──────────┤
980199121002Symbol() │
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├─────────┼───┤
1170111813119└─────────┴───┘
120`);
121
122test(new Map([[1, 1], [2, 2], [3, 3]]).entries(), `
123┌───────────────────┬─────┬────────┐
124│ (iteration index) │ KeyValues125├───────────────────┼─────┼────────┤
126011127122128233129└───────────────────┴─────┴────────┘
130`);
131
132test(new Map([[1, 1], [2, 2], [3, 3]]).values(), `
133┌───────────────────┬────────┐
134│ (iteration index) │ Values135├───────────────────┼────────┤
136011371213823139└───────────────────┴────────┘
140`);
141
142test(new Map([[1, 1], [2, 2], [3, 3]]).keys(), `
143┌───────────────────┬────────┐
144│ (iteration index) │ Values145├───────────────────┼────────┤
146011471214823149└───────────────────┴────────┘
150`);
151
152test(new Set([1, 2, 3]).values(), `
153┌───────────────────┬────────┐
154│ (iteration index) │ Values155├───────────────────┼────────┤
156011571215823159└───────────────────┴────────┘
160`);
161
162
163test({ a: { a: 1, b: 2, c: 3 } }, `
164┌─────────┬───┬───┬───┐
165│ (index) │ a │ b │ c │
166├─────────┼───┼───┼───┤
167│    a    │ 123168└─────────┴───┴───┴───┘
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) │ 01182├─────────┼───┼───┤
183│    a    │ 12184└─────────┴───┴───┘
185`);
186
187test({ a: [1, 2, 3, 4, 5], b: 5, c: { e: 5 } }, `
188┌─────────┬───┬───┬───┬───┬───┬───┬────────┐
189│ (index) │ 01234 │ e │ Values190├─────────┼───┼───┼───┼───┼───┼───┼────────┤
191│    a    │ 12345 │   │        │
192│    b    │   │   │   │   │   │   │   5193│    c    │   │   │   │   │   │ 5 │        │
194└─────────┴───┴───┴───┴───┴───┴───┴────────┘
195`);
196
197test(new Uint8Array([1, 2, 3]), `
198┌─────────┬────────┐
199│ (index) │ Values200├─────────┼────────┤
201012021220323204└─────────┴────────┘
205`);
206
207test(Buffer.from([1, 2, 3]), `
208┌─────────┬────────┐
209│ (index) │ Values210├─────────┼────────┤
211012121221323214└─────────┴────────┘
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) │ KeyValues235├───────────────────┼─────┼────────┤
236└───────────────────┴─────┴────────┘
237`);
238
239test([{ a: 1, b: 'Y' }, { a: 'Z', b: 2 }], `
240┌─────────┬─────┬─────┐
241│ (index) │  a  │  b  │
242├─────────┼─────┼─────┤
24301'Y'2441'Z'2245└─────────┴─────┴─────┘
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}──┤
2570'${name}'258└─────────┴──${line}──┘
259`);
260}
261
262test({ foo: '¥', bar: '¥' }, `
263┌─────────┬────────┐
264│ (index) │ Values265├─────────┼────────┤
266foo'¥'267bar'¥'268└─────────┴────────┘
269`);
270
271test({ foo: '你好', bar: 'hello' }, `
272┌─────────┬─────────┐
273│ (index) │ Values274├─────────┼─────────┤
275foo'你好'276bar'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├─────────┼───────────┤
2880    │           │
2891    │           │
290└─────────┴───────────┘
291`);
292assert.strictEqual('0' in Object.prototype, false);
293assert.strictEqual('1' in Object.prototype, false);
294