• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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