1 var common = require('../common');
2 var assert = require('assert');
3 var util = require('util');
5 // test the internal isDate implementation
6 var Date2 = require('vm').runInNewContext('Date');
8 var orig = util.inspect(d);
9 Date2.prototype.foo = 'bar';
10 var after = util.inspect(d);
11 assert.equal(orig, after);
13 // test positive/negative zero
14 assert.equal(util.inspect(0), '0');
15 assert.equal(util.inspect(-0), '-0');
17 // test for sparse array
18 var a = ['foo', 'bar', 'baz'];
19 assert.equal(util.inspect(a), '[ \'foo\', \'bar\', \'baz\' ]');
21 assert.equal(util.inspect(a), '[ \'foo\', , \'baz\' ]');
22 assert.equal(util.inspect(a, true), '[ \'foo\', , \'baz\', [length]: 3 ]');
23 assert.equal(util.inspect(new Array(5)), '[ , , , , ]');
25 // test for property descriptors
26 var getter = Object.create(null, {
28 get: function() { return 'aaa'; }
31 var setter = Object.create(null, {
36 var getterAndSetter = Object.create(null, {
38 get: function() { return 'ccc'; },
42 assert.equal(util.inspect(getter, true), '{ [a]: [Getter] }');
43 assert.equal(util.inspect(setter, true), '{ [b]: [Setter] }');
44 assert.equal(util.inspect(getterAndSetter, true), '{ [c]: [Getter/Setter] }');
46 // exceptions should print the error message, not '{}'
47 assert.equal(util.inspect(new Error()), '[Error]');
48 assert.equal(util.inspect(new Error('FAIL')), '[Error: FAIL]');
49 assert.equal(util.inspect(new TypeError('FAIL')), '[TypeError: FAIL]');
50 assert.equal(util.inspect(new SyntaxError('FAIL')), '[SyntaxError: FAIL]');
54 assert.equal(util.inspect(e), '[ReferenceError: undef is not defined]');
56 var ex = util.inspect(new Error('FAIL'), true);
57 assert.ok(ex.indexOf('[Error: FAIL]') != -1);
58 assert.ok(ex.indexOf('[stack]') != -1);
59 assert.ok(ex.indexOf('[message]') != -1);
63 assert.equal(util.inspect(Object.create(Date.prototype)), '{}');
66 assert.doesNotThrow(function() {
72 assert.doesNotThrow(function() {
78 // bug with user-supplied inspect function returns non-string
79 assert.doesNotThrow(function() {
81 inspect: function() { return 123; }
86 var x = { inspect: util.inspect };
87 assert.ok(util.inspect(x).indexOf('inspect') != -1);
89 // util.inspect should not display the escaped value of a key.
97 var y = ['a', 'b', 'c'];
100 assert.ok(util.inspect(w),
101 '{ \'\\\': 1, \'\\\\\': 2, \'\\\\\\\': 3, \'\\\\\\\\\': 4 }');
102 assert.ok(util.inspect(y), '[ \'a\', \'b\', \'c\', \'\\\\\\\': \'d\' ]');
104 // util.inspect.styles and util.inspect.colors
105 function test_color_style(style, input, implicit) {
106 var color_name = util.inspect.styles[style];
107 var color = ['', ''];
108 if(util.inspect.colors[color_name])
109 color = util.inspect.colors[color_name];
111 var without_color = util.inspect(input, false, 0, false);
112 var with_color = util.inspect(input, false, 0, true);
113 var expect = '\u001b[' + color[0] + 'm' + without_color +
114 '\u001b[' + color[1] + 'm';
115 assert.equal(with_color, expect, 'util.inspect color for style '+style);
118 test_color_style('special', function(){});
119 test_color_style('number', 123.456);
120 test_color_style('boolean', true);
121 test_color_style('undefined', undefined);
122 test_color_style('null', null);
123 test_color_style('string', 'test string');
124 test_color_style('date', new Date);
125 test_color_style('regexp', /regexp/);
127 // an object with "hasOwnProperty" overwritten should not throw
128 assert.doesNotThrow(function() {
134 // new API, accepts an "options" object
135 var subject = { foo: 'bar', hello: 31, a: { b: { c: { d: 0 } } } };
136 Object.defineProperty(subject, 'hidden', { enumerable: false, value: null });
138 assert(util.inspect(subject, { showHidden: false }).indexOf('hidden') === -1);
139 assert(util.inspect(subject, { showHidden: true }).indexOf('hidden') !== -1);
140 assert(util.inspect(subject, { colors: false }).indexOf('\u001b[32m') === -1);
141 assert(util.inspect(subject, { colors: true }).indexOf('\u001b[32m') !== -1);
142 assert(util.inspect(subject, { depth: 2 }).indexOf('c: [Object]') !== -1);
143 assert(util.inspect(subject, { depth: 0 }).indexOf('a: [Object]') !== -1);
144 assert(util.inspect(subject, { depth: null }).indexOf('{ d: 0 }') !== -1);
146 // "customInspect" option can enable/disable calling inspect() on objects
147 subject = { inspect: function() { return 123; } };
149 assert(util.inspect(subject, { customInspect: true }).indexOf('123') !== -1);
150 assert(util.inspect(subject, { customInspect: true }).indexOf('inspect') === -1);
151 assert(util.inspect(subject, { customInspect: false }).indexOf('123') === -1);
152 assert(util.inspect(subject, { customInspect: false }).indexOf('inspect') !== -1);
154 // custom inspect() functions should be able to return other Objects
155 subject.inspect = function() { return { foo: 'bar' }; };
157 assert.equal(util.inspect(subject), '{ foo: \'bar\' }');
159 subject.inspect = function(depth, opts) {
160 assert.strictEqual(opts.customInspectOptions, true);
163 util.inspect(subject, { customInspectOptions: true });
165 // util.inspect with "colors" option should produce as many lines as without it
166 function test_lines(input) {
167 var count_lines = function(str) {
168 return (str.match(/\n/g) || []).length;
171 var without_color = util.inspect(input);
172 var with_color = util.inspect(input, {colors: true});
173 assert.equal(count_lines(without_color), count_lines(with_color));
176 test_lines([1, 2, 3, 4, 5, 6, 7]);
177 test_lines(function() {
179 for (var i = 0; i < 100; i++) {
184 test_lines({foo: 'bar', baz: 35, b: {a: 35}});
189 very_long_key: 'very_long_value',
190 even_longer_key: ['with even longer value in array']
193 // test boxed primitives output the correct values
194 assert.equal(util.inspect(new String('test')), '[String: \'test\']');
195 assert.equal(util.inspect(new Boolean(false)), '[Boolean: false]');
196 assert.equal(util.inspect(new Boolean(true)), '[Boolean: true]');
197 assert.equal(util.inspect(new Number(0)), '[Number: 0]');
198 assert.equal(util.inspect(new Number(-0)), '[Number: -0]');
199 assert.equal(util.inspect(new Number(-1.1)), '[Number: -1.1]');
200 assert.equal(util.inspect(new Number(13.37)), '[Number: 13.37]');
202 // test boxed primitives with own properties
203 var str = new String('baz');
205 assert.equal(util.inspect(str), '{ [String: \'baz\'] foo: \'bar\' }');
207 var bool = new Boolean(true);
209 assert.equal(util.inspect(bool), '{ [Boolean: true] foo: \'bar\' }');
211 var num = new Number(13.37);
213 assert.equal(util.inspect(num), '{ [Number: 13.37] foo: \'bar\' }');
216 if (typeof Symbol !== 'undefined') {
217 assert.equal(util.inspect(Symbol()), 'Symbol()');
218 assert.equal(util.inspect(Symbol(123)), 'Symbol(123)');
219 assert.equal(util.inspect(Symbol('hi')), 'Symbol(hi)');
220 assert.equal(util.inspect([Symbol()]), '[ Symbol() ]');
221 assert.equal(util.inspect({ foo: Symbol() }), '{ foo: Symbol() }');
223 var options = { showHidden: true };
226 subject[Symbol('symbol')] = 42;
228 assert.equal(util.inspect(subject), '{}');
229 assert.equal(util.inspect(subject, options), '{ [Symbol(symbol)]: 42 }');
232 subject[Symbol('symbol')] = 42;
234 assert.equal(util.inspect(subject), '[ 1, 2, 3 ]');
235 assert.equal(util.inspect(subject, options), '[ 1, 2, 3, [length]: 3, [Symbol(symbol)]: 42 ]');
240 assert.equal(util.inspect(new Set), 'Set {}');
241 assert.equal(util.inspect(new Set([1, 2, 3])), 'Set { 1, 2, 3 }');
242 var set = new Set(['foo']);
244 assert.equal(util.inspect(set, true), 'Set { \'foo\', [size]: 1, bar: 42 }');
247 assert.equal(util.inspect(new Map), 'Map {}');
248 assert.equal(util.inspect(new Map([[1, 'a'], [2, 'b'], [3, 'c']])),
249 'Map { 1 => \'a\', 2 => \'b\', 3 => \'c\' }');
250 var map = new Map([['foo', null]]);
252 assert.equal(util.inspect(map, true),
253 'Map { \'foo\' => null, [size]: 1, bar: 42 }');
256 assert.equal(util.inspect(Promise.resolve(3)), 'Promise { 3 }');
257 assert.equal(util.inspect(Promise.reject(3)), 'Promise { <rejected> 3 }');
258 assert.equal(util.inspect(new Promise(function() {})), 'Promise { <pending> }');
259 var promise = Promise.resolve('foo');
261 assert.equal(util.inspect(promise), 'Promise { \'foo\', bar: 42 }');
263 // Make sure it doesn't choke on polyfills. Unlike Set/Map, there is no standard
264 // interface to synchronously inspect a Promise, so our techniques only work on
265 // a bonafide native Promise.
266 var oldPromise = Promise;
267 global.Promise = function() { this.bar = 42; };
268 assert.equal(util.inspect(new Promise), '{ bar: 42 }');
269 global.Promise = oldPromise;
272 // Test alignment of items in container
273 // Assumes that the first numeric character is the start of an item.
275 function checkAlignment(container) {
276 var lines = util.inspect(container).split('\n');
278 lines.forEach(function(line) {
279 var npos = line.search(/\d/);
281 if (pos !== undefined)
282 assert.equal(pos, npos, 'container items not aligned');
289 for (var i = 0; i < 100; i++) {
293 checkAlignment(big_array);
294 checkAlignment(function() {
296 big_array.forEach(function(v) {
301 checkAlignment(new Set(big_array));
302 checkAlignment(new Map(big_array.map(function (y) { return [y, null] })));