Skip to content

Commit 68a0818

Browse files
Schema: keep order of user provided types (#2410)
Motivation: #2362
1 parent 6652178 commit 68a0818

File tree

6 files changed

+185
-136
lines changed

6 files changed

+185
-136
lines changed

src/__tests__/starWarsIntrospection-test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,16 @@ describe('Star Wars Introspection Tests', () => {
3232
expect(data).to.deep.equal({
3333
__schema: {
3434
types: [
35-
{ name: 'Query' },
36-
{ name: 'Episode' },
35+
{ name: 'Human' },
3736
{ name: 'Character' },
3837
{ name: 'String' },
39-
{ name: 'Human' },
38+
{ name: 'Episode' },
4039
{ name: 'Droid' },
40+
{ name: 'Query' },
41+
{ name: 'Boolean' },
4142
{ name: '__Schema' },
4243
{ name: '__Type' },
4344
{ name: '__TypeKind' },
44-
{ name: 'Boolean' },
4545
{ name: '__Field' },
4646
{ name: '__InputValue' },
4747
{ name: '__EnumValue' },

src/execution/__tests__/union-interface-test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ describe('Execute: Union and intersection types', () => {
199199
name: 'Named',
200200
fields: [{ name: 'name' }],
201201
interfaces: [],
202-
possibleTypes: [{ name: 'Person' }, { name: 'Dog' }, { name: 'Cat' }],
202+
possibleTypes: [{ name: 'Dog' }, { name: 'Cat' }, { name: 'Person' }],
203203
enumValues: null,
204204
inputFields: null,
205205
},
@@ -208,7 +208,7 @@ describe('Execute: Union and intersection types', () => {
208208
name: 'Mammal',
209209
fields: [{ name: 'progeny' }, { name: 'mother' }, { name: 'father' }],
210210
interfaces: [{ name: 'Life' }],
211-
possibleTypes: [{ name: 'Person' }, { name: 'Dog' }, { name: 'Cat' }],
211+
possibleTypes: [{ name: 'Dog' }, { name: 'Cat' }, { name: 'Person' }],
212212
enumValues: null,
213213
inputFields: null,
214214
},

src/type/__tests__/introspection-test.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,15 @@ describe('Introspection', () => {
6969
enumValues: null,
7070
possibleTypes: null,
7171
},
72+
{
73+
kind: 'SCALAR',
74+
name: 'Boolean',
75+
fields: null,
76+
inputFields: null,
77+
interfaces: null,
78+
enumValues: null,
79+
possibleTypes: null,
80+
},
7281
{
7382
kind: 'OBJECT',
7483
name: '__Schema',
@@ -385,15 +394,6 @@ describe('Introspection', () => {
385394
],
386395
possibleTypes: null,
387396
},
388-
{
389-
kind: 'SCALAR',
390-
name: 'Boolean',
391-
fields: null,
392-
inputFields: null,
393-
interfaces: null,
394-
enumValues: null,
395-
possibleTypes: null,
396-
},
397397
{
398398
kind: 'OBJECT',
399399
name: '__Field',

src/type/__tests__/schema-test.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,57 @@ describe('Type System: Schema', () => {
253253
});
254254
});
255255

256+
it('preserve order of use provided types', () => {
257+
const aType = new GraphQLObjectType({
258+
name: 'A',
259+
fields: {
260+
sub: { type: new GraphQLScalarType({ name: 'ASub' }) },
261+
},
262+
});
263+
const zType = new GraphQLObjectType({
264+
name: 'Z',
265+
fields: {
266+
sub: { type: new GraphQLScalarType({ name: 'ZSub' }) },
267+
},
268+
});
269+
const queryType = new GraphQLObjectType({
270+
name: 'Query',
271+
fields: {
272+
a: { type: aType },
273+
z: { type: zType },
274+
sub: { type: new GraphQLScalarType({ name: 'QuerySub' }) },
275+
},
276+
});
277+
const schema = new GraphQLSchema({
278+
types: [zType, queryType, aType],
279+
query: queryType,
280+
});
281+
282+
const typeNames = Object.keys(schema.getTypeMap());
283+
expect(typeNames).to.deep.equal([
284+
'Z',
285+
'ZSub',
286+
'Query',
287+
'QuerySub',
288+
'A',
289+
'ASub',
290+
'Boolean',
291+
'String',
292+
'__Schema',
293+
'__Type',
294+
'__TypeKind',
295+
'__Field',
296+
'__InputValue',
297+
'__EnumValue',
298+
'__Directive',
299+
'__DirectiveLocation',
300+
]);
301+
302+
// Also check that this order is stable
303+
const copySchema = new GraphQLSchema(schema.toConfig());
304+
expect(Object.keys(copySchema.getTypeMap())).to.deep.equal(typeNames);
305+
});
306+
256307
it('can be Object.toStringified', () => {
257308
const schema = new GraphQLSchema({});
258309

src/type/__tests__/validation-test.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,11 +1330,11 @@ describe('Type System: Interface fields must have output types', () => {
13301330
expect(validateSchema(schema)).to.deep.equal([
13311331
{
13321332
message:
1333-
'The type of BadInterface.badField must be Output Type but got: undefined.',
1333+
'The type of BadImplementing.badField must be Output Type but got: undefined.',
13341334
},
13351335
{
13361336
message:
1337-
'The type of BadImplementing.badField must be Output Type but got: undefined.',
1337+
'The type of BadInterface.badField must be Output Type but got: undefined.',
13381338
},
13391339
]);
13401340
});
@@ -1346,10 +1346,10 @@ describe('Type System: Interface fields must have output types', () => {
13461346
const schema = schemaWithInterfaceFieldOfType(type);
13471347
expect(validateSchema(schema)).to.deep.equal([
13481348
{
1349-
message: `The type of BadInterface.badField must be Output Type but got: ${typeStr}.`,
1349+
message: `The type of BadImplementing.badField must be Output Type but got: ${typeStr}.`,
13501350
},
13511351
{
1352-
message: `The type of BadImplementing.badField must be Output Type but got: ${typeStr}.`,
1352+
message: `The type of BadInterface.badField must be Output Type but got: ${typeStr}.`,
13531353
},
13541354
]);
13551355
});
@@ -1361,14 +1361,14 @@ describe('Type System: Interface fields must have output types', () => {
13611361
expect(validateSchema(schema)).to.deep.equal([
13621362
{
13631363
message:
1364-
'The type of BadInterface.badField must be Output Type but got: [function Number].',
1364+
'The type of BadImplementing.badField must be Output Type but got: [function Number].',
13651365
},
13661366
{
1367-
message: 'Expected GraphQL named type but got: [function Number].',
1367+
message:
1368+
'The type of BadInterface.badField must be Output Type but got: [function Number].',
13681369
},
13691370
{
1370-
message:
1371-
'The type of BadImplementing.badField must be Output Type but got: [function Number].',
1371+
message: 'Expected GraphQL named type but got: [function Number].',
13721372
},
13731373
]);
13741374
});

0 commit comments

Comments
 (0)