Skip to content

Commit fdb4633

Browse files
Cleanup 'jsutils/inspect' function (#1499)
1 parent 8682f57 commit fdb4633

File tree

12 files changed

+124
-46
lines changed

12 files changed

+124
-46
lines changed

src/execution/__tests__/executor-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,7 @@ describe('Execute: Handles basic execution tasks', () => {
10531053
errors: [
10541054
{
10551055
message:
1056-
'Expected value of type "SpecialType" but got: {value: "bar"}.',
1056+
'Expected value of type "SpecialType" but got: { value: "bar" }.',
10571057
locations: [{ line: 1, column: 3 }],
10581058
path: ['specials', 1],
10591059
},

src/execution/__tests__/variables-test.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ describe('Execute: Handles inputs', () => {
371371
{
372372
message:
373373
'Variable "$input" got invalid value ' +
374-
'{a: "foo", b: "bar", c: null}; ' +
374+
'{ a: "foo", b: "bar", c: null }; ' +
375375
'Expected non-nullable type String! not to be null at value.c.',
376376
locations: [{ line: 2, column: 16 }],
377377
},
@@ -401,7 +401,7 @@ describe('Execute: Handles inputs', () => {
401401
errors: [
402402
{
403403
message:
404-
'Variable "$input" got invalid value {a: "foo", b: "bar"}; ' +
404+
'Variable "$input" got invalid value { a: "foo", b: "bar" }; ' +
405405
'Field value.c of required type String! was not provided.',
406406
locations: [{ line: 2, column: 16 }],
407407
},
@@ -421,13 +421,13 @@ describe('Execute: Handles inputs', () => {
421421
errors: [
422422
{
423423
message:
424-
'Variable "$input" got invalid value {na: {a: "foo"}}; ' +
424+
'Variable "$input" got invalid value { na: { a: "foo" } }; ' +
425425
'Field value.na.c of required type String! was not provided.',
426426
locations: [{ line: 2, column: 18 }],
427427
},
428428
{
429429
message:
430-
'Variable "$input" got invalid value {na: {a: "foo"}}; ' +
430+
'Variable "$input" got invalid value { na: { a: "foo" } }; ' +
431431
'Field value.nb of required type String! was not provided.',
432432
locations: [{ line: 2, column: 18 }],
433433
},
@@ -446,7 +446,7 @@ describe('Execute: Handles inputs', () => {
446446
{
447447
message:
448448
'Variable "$input" got invalid value ' +
449-
'{a: "foo", b: "bar", c: "baz", extra: "dog"}; ' +
449+
'{ a: "foo", b: "bar", c: "baz", extra: "dog" }; ' +
450450
'Field "extra" is not defined by type TestInputObject.',
451451
locations: [{ line: 2, column: 16 }],
452452
},
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/**
2+
* Copyright (c) 2018-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
import { expect } from 'chai';
9+
import { describe, it } from 'mocha';
10+
import inspect from '../inspect';
11+
12+
describe('inspect', () => {
13+
it('undefined', () => {
14+
expect(inspect(undefined)).to.equal('undefined');
15+
});
16+
17+
it('null', () => {
18+
expect(inspect(null)).to.equal('null');
19+
});
20+
21+
it('boolean', () => {
22+
expect(inspect(true)).to.equal('true');
23+
expect(inspect(false)).to.equal('false');
24+
});
25+
26+
it('string', () => {
27+
expect(inspect('')).to.equal('""');
28+
expect(inspect('abc')).to.equal('"abc"');
29+
expect(inspect('"')).to.equal(String.raw`"\""`);
30+
});
31+
32+
it('number', () => {
33+
expect(inspect(0.0)).to.equal('0');
34+
expect(inspect(3.14)).to.equal('3.14');
35+
expect(inspect(NaN)).to.equal('NaN');
36+
expect(inspect(Infinity)).to.equal('Infinity');
37+
expect(inspect(-Infinity)).to.equal('-Infinity');
38+
});
39+
40+
it('function', () => {
41+
expect(inspect(() => 0)).to.equal('[function]');
42+
43+
function testFunc() {}
44+
expect(inspect(testFunc)).to.equal('[function testFunc]');
45+
});
46+
47+
it('array', () => {
48+
expect(inspect([])).to.equal('[]');
49+
expect(inspect([null])).to.equal('[null]');
50+
expect(inspect([1, NaN])).to.equal('[1, NaN]');
51+
expect(inspect([['a', 'b'], 'c'])).to.equal('[["a", "b"], "c"]');
52+
});
53+
54+
it('object', () => {
55+
expect(inspect({})).to.equal('{}');
56+
expect(inspect({ a: 1 })).to.equal('{ a: 1 }');
57+
expect(inspect({ a: 1, b: 2 })).to.equal('{ a: 1, b: 2 }');
58+
expect(inspect({ array: [null, 0] })).to.equal('{ array: [null, 0] }');
59+
60+
const map = Object.create(null);
61+
map['a'] = true;
62+
map['b'] = null;
63+
expect(inspect(map)).to.equal('{ a: true, b: null }');
64+
});
65+
66+
it('custom inspect', () => {
67+
const object = {
68+
inspect() {
69+
return '<custom inspect>';
70+
},
71+
};
72+
73+
expect(inspect(object)).to.equal('<custom inspect>');
74+
});
75+
});

src/jsutils/inspect.js

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,26 @@
1111
* Used to print values in error messages.
1212
*/
1313
export default function inspect(value: mixed): string {
14-
return value && typeof value === 'object'
15-
? typeof value.inspect === 'function'
16-
? value.inspect()
17-
: Array.isArray(value)
18-
? '[' + value.map(inspect).join(', ') + ']'
19-
: '{' +
20-
Object.keys(value)
21-
.map(k => `${k}: ${inspect(value[k])}`)
22-
.join(', ') +
23-
'}'
24-
: typeof value === 'string'
25-
? '"' + value + '"'
26-
: typeof value === 'function'
27-
? `[function ${value.name}]`
28-
: String(value);
14+
switch (typeof value) {
15+
case 'string':
16+
return JSON.stringify(value);
17+
case 'function':
18+
return value.name ? `[function ${value.name}]` : '[function]';
19+
case 'object':
20+
if (value) {
21+
if (typeof value.inspect === 'function') {
22+
return value.inspect();
23+
} else if (Array.isArray(value)) {
24+
return '[' + value.map(inspect).join(', ') + ']';
25+
}
26+
27+
const properties = Object.keys(value)
28+
.map(k => `${k}: ${inspect(value[k])}`)
29+
.join(', ');
30+
return properties ? '{ ' + properties + ' }' : '{}';
31+
}
32+
return String(value);
33+
default:
34+
return String(value);
35+
}
2936
}

src/language/__tests__/lexer-test.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,9 @@ describe('Lexer', () => {
6060
expect(JSON.stringify(token)).to.equal(
6161
'{"kind":"Name","value":"foo","line":1,"column":1}',
6262
);
63-
// NB: util.inspect used to suck
64-
if (parseFloat(process.version.slice(1)) > 0.1) {
65-
expect(require('util').inspect(token)).to.equal(
66-
"{ kind: 'Name', value: 'foo', line: 1, column: 1 }",
67-
);
68-
}
63+
expect(require('util').inspect(token)).to.equal(
64+
"{ kind: 'Name', value: 'foo', line: 1, column: 1 }",
65+
);
6966
});
7067

7168
it('skips whitespace and comments', () => {

src/language/__tests__/printer-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ describe('Printer: Query document', () => {
3333
it('produces helpful error messages', () => {
3434
const badAst1 = { random: 'Data' };
3535
expect(() => print(badAst1)).to.throw(
36-
'Invalid AST Node: {"random":"Data"}',
36+
'Invalid AST Node: { random: "Data" }',
3737
);
3838
});
3939

src/language/__tests__/schema-printer-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe('Printer: SDL document', () => {
2525
it('produces helpful error messages', () => {
2626
const badAst1 = { random: 'Data' };
2727
expect(() => print(badAst1)).to.throw(
28-
'Invalid AST Node: {"random":"Data"}',
28+
'Invalid AST Node: { random: "Data" }',
2929
);
3030
});
3131

src/language/visitor.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* @flow strict
88
*/
99

10+
import inspect from '../jsutils/inspect';
1011
import type { ASTNode, ASTKindToNode } from './ast';
1112
import type { TypeInfo } from '../utilities/TypeInfo';
1213

@@ -296,7 +297,7 @@ export function visit(
296297
let result;
297298
if (!Array.isArray(node)) {
298299
if (!isNode(node)) {
299-
throw new Error('Invalid AST Node: ' + JSON.stringify(node));
300+
throw new Error('Invalid AST Node: ' + inspect(node));
300301
}
301302
const visitFn = getVisitFn(visitor, node.kind, isLeaving);
302303
if (visitFn) {

src/type/__tests__/enumType-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ describe('Type System: Enum Values', () => {
384384
errors: [
385385
{
386386
message:
387-
'Expected a value of type "Complex" but received: {someRandomValue: 123}',
387+
'Expected a value of type "Complex" but received: { someRandomValue: 123 }',
388388
locations: [{ line: 6, column: 9 }],
389389
path: ['bad'],
390390
},

src/type/__tests__/serialization-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ describe('Type System: Scalar coercion', () => {
178178
},
179179
};
180180
expect(() => GraphQLID.serialize(badObjValue)).to.throw(
181-
'ID cannot represent value: {_id: false, valueOf: [function valueOf]}',
181+
'ID cannot represent value: { _id: false, valueOf: [function valueOf] }',
182182
);
183183

184184
expect(() => GraphQLID.serialize(true)).to.throw(

0 commit comments

Comments
 (0)