Skip to content

Commit 9e584e3

Browse files
Error.toStringTag change return string from 'Object' to 'GraphQLError' (#3261)
We maintained this hack for a long time to make our Errors compatible with with chai's `to.deep.equal`
1 parent 2df59f1 commit 9e584e3

21 files changed

+347
-311
lines changed

src/__testUtils__/expectJSON.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { expect } from 'chai';
2+
3+
import { mapValue } from '../jsutils/mapValue';
4+
import { isObjectLike } from '../jsutils/isObjectLike';
5+
6+
/**
7+
* Deeply transforms an arbitrary value to a JSON-safe value by calling toJSON
8+
* on any nested value which defines it.
9+
*/
10+
function toJSONDeep(value: unknown): unknown {
11+
if (!isObjectLike(value)) {
12+
return value;
13+
}
14+
15+
if (typeof value.toJSON === 'function') {
16+
return value.toJSON();
17+
}
18+
19+
if (Array.isArray(value)) {
20+
return value.map(toJSONDeep);
21+
}
22+
23+
return mapValue(value, toJSONDeep);
24+
}
25+
26+
export function expectJSON(value: unknown) {
27+
return expect(toJSONDeep(value));
28+
}
29+
30+
export function expectToThrowJSON(fn: () => unknown) {
31+
function mapException(): unknown {
32+
try {
33+
return fn();
34+
} catch (error) {
35+
throw toJSONDeep(error);
36+
}
37+
}
38+
39+
return expect(mapException).to.throw();
40+
}

src/__tests__/starWarsQuery-test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { expect } from 'chai';
22
import { describe, it } from 'mocha';
33

4+
import { expectJSON } from '../__testUtils__/expectJSON';
5+
46
import { graphql } from '../graphql';
57

68
import { StarWarsSchema as schema } from './starWarsSchema';
@@ -393,7 +395,7 @@ describe('Star Wars Query Tests', () => {
393395
`;
394396

395397
const result = await graphql({ schema, source });
396-
expect(result).to.deep.equal({
398+
expectJSON(result).to.deep.equal({
397399
data: {
398400
hero: {
399401
name: 'R2-D2',
@@ -424,7 +426,7 @@ describe('Star Wars Query Tests', () => {
424426
`;
425427

426428
const result = await graphql({ schema, source });
427-
expect(result).to.deep.equal({
429+
expectJSON(result).to.deep.equal({
428430
data: {
429431
hero: {
430432
name: 'R2-D2',
@@ -475,7 +477,7 @@ describe('Star Wars Query Tests', () => {
475477
`;
476478

477479
const result = await graphql({ schema, source });
478-
expect(result).to.deep.equal({
480+
expectJSON(result).to.deep.equal({
479481
data: {
480482
mainHero: {
481483
name: 'R2-D2',

src/error/GraphQLError.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ export class GraphQLError extends Error {
240240
}
241241

242242
get [Symbol.toStringTag](): string {
243-
return 'Object';
243+
return 'GraphQLError';
244244
}
245245
}
246246

src/execution/__tests__/abstract-test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { expect } from 'chai';
22
import { describe, it } from 'mocha';
33

4+
import { expectJSON } from '../../__testUtils__/expectJSON';
5+
46
import { parse } from '../../language/parser';
57

68
import { GraphQLSchema } from '../../type/schema';
@@ -204,7 +206,7 @@ describe('Execute: Handles execution of abstract types', () => {
204206
}
205207
`;
206208

207-
expect(await executeQuery({ schema, query })).to.deep.equal({
209+
expectJSON(await executeQuery({ schema, query })).to.deep.equal({
208210
data: {
209211
pets: [null, null],
210212
},
@@ -358,7 +360,7 @@ describe('Execute: Handles execution of abstract types', () => {
358360
}
359361
`;
360362

361-
expect(await executeQuery({ schema, query })).to.deep.equal({
363+
expectJSON(await executeQuery({ schema, query })).to.deep.equal({
362364
data: {
363365
pets: [null, null],
364366
},
@@ -539,7 +541,7 @@ describe('Execute: Handles execution of abstract types', () => {
539541
const result = executeSync({ schema, document, rootValue });
540542
return {
541543
toEqual(message: string) {
542-
expect(result).to.deep.equal({
544+
expectJSON(result).to.deep.equal({
543545
data: { pet: null },
544546
errors: [
545547
{

src/execution/__tests__/executor-test.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { expect } from 'chai';
22
import { describe, it } from 'mocha';
33

4+
import { expectJSON } from '../../__testUtils__/expectJSON';
5+
46
import { inspect } from '../../jsutils/inspect';
57
import { invariant } from '../../jsutils/invariant';
68

@@ -497,7 +499,7 @@ describe('Execute: Handles basic execution tasks', () => {
497499
};
498500

499501
const result = await execute({ schema, document, rootValue });
500-
expect(result).to.deep.equal({
502+
expectJSON(result).to.deep.equal({
501503
data: {
502504
sync: 'sync',
503505
syncError: null,
@@ -611,7 +613,7 @@ describe('Execute: Handles basic execution tasks', () => {
611613

612614
const result = await execute({ schema, document });
613615

614-
expect(result).to.deep.equal({
616+
expectJSON(result).to.deep.equal({
615617
data: { foods: null },
616618
errors: [
617619
{
@@ -670,7 +672,7 @@ describe('Execute: Handles basic execution tasks', () => {
670672
`);
671673

672674
const result = executeSync({ schema, document });
673-
expect(result).to.deep.equal({
675+
expectJSON(result).to.deep.equal({
674676
data: {
675677
nullableA: {
676678
aliasedA: null,
@@ -752,7 +754,7 @@ describe('Execute: Handles basic execution tasks', () => {
752754
const rootValue = { a: 'b' };
753755

754756
const result = executeSync({ schema, document, rootValue });
755-
expect(result).to.deep.equal({
757+
expectJSON(result).to.deep.equal({
756758
errors: [{ message: 'Must provide an operation.' }],
757759
});
758760
});
@@ -772,7 +774,7 @@ describe('Execute: Handles basic execution tasks', () => {
772774
`);
773775

774776
const result = executeSync({ schema, document });
775-
expect(result).to.deep.equal({
777+
expectJSON(result).to.deep.equal({
776778
errors: [
777779
{
778780
message:
@@ -798,7 +800,7 @@ describe('Execute: Handles basic execution tasks', () => {
798800
const operationName = 'UnknownExample';
799801

800802
const result = executeSync({ schema, document, operationName });
801-
expect(result).to.deep.equal({
803+
expectJSON(result).to.deep.equal({
802804
errors: [{ message: 'Unknown operation named "UnknownExample".' }],
803805
});
804806
});
@@ -816,7 +818,7 @@ describe('Execute: Handles basic execution tasks', () => {
816818
const operationName = '';
817819

818820
const result = executeSync({ schema, document, operationName });
819-
expect(result).to.deep.equal({
821+
expectJSON(result).to.deep.equal({
820822
errors: [{ message: 'Unknown operation named "".' }],
821823
});
822824
});
@@ -1074,7 +1076,7 @@ describe('Execute: Handles basic execution tasks', () => {
10741076
};
10751077

10761078
const result = executeSync({ schema, document, rootValue });
1077-
expect(result).to.deep.equal({
1079+
expectJSON(result).to.deep.equal({
10781080
data: {
10791081
specials: [{ value: 'foo' }, null],
10801082
},
@@ -1118,7 +1120,7 @@ describe('Execute: Handles basic execution tasks', () => {
11181120
});
11191121

11201122
const result = executeSync({ schema, document: parse('{ customScalar }') });
1121-
expect(result).to.deep.equal({
1123+
expectJSON(result).to.deep.equal({
11221124
data: { customScalar: null },
11231125
errors: [
11241126
{

src/execution/__tests__/lists-test.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { expect } from 'chai';
22
import { describe, it } from 'mocha';
33

4+
import { expectJSON } from '../../__testUtils__/expectJSON';
5+
46
import { parse } from '../../language/parser';
57

68
import { buildSchema } from '../../utilities/buildASTSchema';
@@ -50,7 +52,7 @@ describe('Execute: Accepts any iterable as list value', () => {
5052
it('Does not accept (Iterable) String-literal as a List value', () => {
5153
const listField = 'Singular';
5254

53-
expect(complete({ listField })).to.deep.equal({
55+
expectJSON(complete({ listField })).to.deep.equal({
5456
data: { listField: null },
5557
errors: [
5658
{
@@ -129,11 +131,11 @@ describe('Execute: Handles list nullability', () => {
129131
expect(await complete({ listField, as: '[Int]!' })).to.deep.equal({
130132
data: { listField: [1, null, 2] },
131133
});
132-
expect(await complete({ listField, as: '[Int!]' })).to.deep.equal({
134+
expectJSON(await complete({ listField, as: '[Int!]' })).to.deep.equal({
133135
data: { listField: null },
134136
errors,
135137
});
136-
expect(await complete({ listField, as: '[Int!]!' })).to.deep.equal({
138+
expectJSON(await complete({ listField, as: '[Int!]!' })).to.deep.equal({
137139
data: null,
138140
errors,
139141
});
@@ -152,14 +154,14 @@ describe('Execute: Handles list nullability', () => {
152154
expect(await complete({ listField, as: '[Int]' })).to.deep.equal({
153155
data: { listField: null },
154156
});
155-
expect(await complete({ listField, as: '[Int]!' })).to.deep.equal({
157+
expectJSON(await complete({ listField, as: '[Int]!' })).to.deep.equal({
156158
data: null,
157159
errors,
158160
});
159161
expect(await complete({ listField, as: '[Int!]' })).to.deep.equal({
160162
data: { listField: null },
161163
});
162-
expect(await complete({ listField, as: '[Int!]!' })).to.deep.equal({
164+
expectJSON(await complete({ listField, as: '[Int!]!' })).to.deep.equal({
163165
data: null,
164166
errors,
165167
});
@@ -175,19 +177,19 @@ describe('Execute: Handles list nullability', () => {
175177
},
176178
];
177179

178-
expect(await complete({ listField, as: '[Int]' })).to.deep.equal({
180+
expectJSON(await complete({ listField, as: '[Int]' })).to.deep.equal({
179181
data: { listField: [1, null, 2] },
180182
errors,
181183
});
182-
expect(await complete({ listField, as: '[Int]!' })).to.deep.equal({
184+
expectJSON(await complete({ listField, as: '[Int]!' })).to.deep.equal({
183185
data: { listField: [1, null, 2] },
184186
errors,
185187
});
186-
expect(await complete({ listField, as: '[Int!]' })).to.deep.equal({
188+
expectJSON(await complete({ listField, as: '[Int!]' })).to.deep.equal({
187189
data: { listField: null },
188190
errors,
189191
});
190-
expect(await complete({ listField, as: '[Int!]!' })).to.deep.equal({
192+
expectJSON(await complete({ listField, as: '[Int!]!' })).to.deep.equal({
191193
data: null,
192194
errors,
193195
});
@@ -203,19 +205,19 @@ describe('Execute: Handles list nullability', () => {
203205
},
204206
];
205207

206-
expect(await complete({ listField, as: '[Int]' })).to.deep.equal({
208+
expectJSON(await complete({ listField, as: '[Int]' })).to.deep.equal({
207209
data: { listField: null },
208210
errors,
209211
});
210-
expect(await complete({ listField, as: '[Int]!' })).to.deep.equal({
212+
expectJSON(await complete({ listField, as: '[Int]!' })).to.deep.equal({
211213
data: null,
212214
errors,
213215
});
214-
expect(await complete({ listField, as: '[Int!]' })).to.deep.equal({
216+
expectJSON(await complete({ listField, as: '[Int!]' })).to.deep.equal({
215217
data: { listField: null },
216218
errors,
217219
});
218-
expect(await complete({ listField, as: '[Int!]!' })).to.deep.equal({
220+
expectJSON(await complete({ listField, as: '[Int!]!' })).to.deep.equal({
219221
data: null,
220222
errors,
221223
});

src/execution/__tests__/mutations-test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { expect } from 'chai';
22
import { describe, it } from 'mocha';
33

4+
import { expectJSON } from '../../__testUtils__/expectJSON';
5+
46
import { resolveOnNextTick } from '../../__testUtils__/resolveOnNextTick';
57

68
import { parse } from '../../language/parser';
@@ -167,7 +169,7 @@ describe('Execute: Handles mutation execution ordering', () => {
167169
const rootValue = new Root(6);
168170
const result = await execute({ schema, document, rootValue });
169171

170-
expect(result).to.deep.equal({
172+
expectJSON(result).to.deep.equal({
171173
data: {
172174
first: { theNumber: 1 },
173175
second: { theNumber: 2 },

0 commit comments

Comments
 (0)