Skip to content

Commit 25ed21b

Browse files
committed
added tests and functionality for unions with object and enum types
1 parent 18b9fd7 commit 25ed21b

File tree

2 files changed

+139
-8
lines changed

2 files changed

+139
-8
lines changed

src/analysis/buildTypeWeights.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ function compareTypes(a: GraphQLOutputType, b: GraphQLOutputType): boolean {
181181
return (
182182
(isObjectType(b) && isObjectType(a) && a.name === b.name) ||
183183
(isUnionType(b) && isUnionType(a) && a.name === b.name) ||
184+
(isEnumType(b) && isEnumType(a) && a.name === b.name) ||
184185
(isInterfaceType(b) && isInterfaceType(a) && a.name === b.name) ||
185186
(isScalarType(b) && isScalarType(a) && a.name === b.name) ||
186187
(isListType(b) && isListType(a) && compareTypes(b.ofType, a.ofType)) ||
@@ -287,24 +288,26 @@ function parseUnionTypes(
287288
* c. objects have a resolveTo type.
288289
* */
289290

290-
const current = commonFields[field].type;
291+
let current = commonFields[field].type;
292+
if (isNonNullType(current)) current = current.ofType;
291293
if (isScalarType(current)) {
292294
fieldTypes[field] = {
293295
weight: commonFields[field].weight,
294296
};
295-
} else if (isObjectType(current) || isInterfaceType(current) || isUnionType(current)) {
297+
} else if (
298+
isObjectType(current) ||
299+
isInterfaceType(current) ||
300+
isUnionType(current) ||
301+
isEnumType(current)
302+
) {
296303
fieldTypes[field] = {
297304
resolveTo: commonFields[field].resolveTo,
298-
weight: typeWeights.object,
299305
};
300306
} else if (isListType(current)) {
301307
fieldTypes[field] = {
302308
resolveTo: commonFields[field].resolveTo,
303309
weight: commonFields[field].weight,
304310
};
305-
} else if (isNonNullType(current)) {
306-
throw new Error('non null types not supported on unions');
307-
// TODO: also a recursive data structure
308311
} else {
309312
throw new Error('Unhandled union type. Should never get here');
310313
}

test/analysis/buildTypeWeights.test.ts

Lines changed: 130 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,8 @@ describe('Test buildTypeWeightsFromSchema function', () => {
460460
});
461461
});
462462

463-
describe('union types', () => {
464-
test('union types', () => {
463+
describe('union types with ...', () => {
464+
test('lists of union types and scalars', () => {
465465
schema = buildSchema(`
466466
union SearchResult = Human | Droid
467467
type Human{
@@ -509,6 +509,134 @@ describe('Test buildTypeWeightsFromSchema function', () => {
509509
},
510510
});
511511
});
512+
513+
test('object types', () => {
514+
schema = buildSchema(`
515+
union SearchResult = Human | Droid
516+
type Human{
517+
name: String
518+
homePlanet: String
519+
info: Info
520+
search(first: Int!): [SearchResult]
521+
}
522+
type Droid {
523+
name: String
524+
primaryFunction: String
525+
info: Info
526+
search(first: Int!): [SearchResult]
527+
}
528+
type Info {
529+
height: Int
530+
}
531+
`);
532+
expect(buildTypeWeightsFromSchema(schema)).toEqual({
533+
searchresult: {
534+
weight: 1,
535+
fields: {
536+
name: { weight: 0 },
537+
search: {
538+
resolveTo: 'searchresult',
539+
weight: expect.any(Function),
540+
},
541+
info: { resolveTo: 'info' },
542+
},
543+
},
544+
human: {
545+
weight: 1,
546+
fields: {
547+
name: { weight: 0 },
548+
homePlanet: { weight: 0 },
549+
search: {
550+
resolveTo: 'searchresult',
551+
weight: expect.any(Function),
552+
},
553+
info: { resolveTo: 'info' },
554+
},
555+
},
556+
droid: {
557+
weight: 1,
558+
fields: {
559+
name: { weight: 0 },
560+
primaryFunction: { weight: 0 },
561+
search: {
562+
resolveTo: 'searchresult',
563+
weight: expect.any(Function),
564+
},
565+
info: { resolveTo: 'info' },
566+
},
567+
},
568+
info: {
569+
weight: 1,
570+
fields: {
571+
height: { weight: 0 },
572+
},
573+
},
574+
});
575+
});
576+
577+
test('enum types', () => {
578+
schema = buildSchema(`
579+
union SearchResult = Human | Droid
580+
type Human{
581+
name: String
582+
homePlanet: String
583+
episode: Episode
584+
search(first: Int!): [SearchResult]
585+
}
586+
type Droid {
587+
name: String
588+
primaryFunction: String
589+
episode: Episode
590+
search(first: Int!): [SearchResult]
591+
}
592+
enum Episode {
593+
NEWHOPE
594+
EMPIRE
595+
JEDI
596+
}
597+
`);
598+
expect(buildTypeWeightsFromSchema(schema)).toEqual({
599+
searchresult: {
600+
weight: 1,
601+
fields: {
602+
episode: { resolveTo: 'episode' },
603+
name: { weight: 0 },
604+
search: {
605+
resolveTo: 'searchresult',
606+
weight: expect.any(Function),
607+
},
608+
},
609+
},
610+
human: {
611+
weight: 1,
612+
fields: {
613+
name: { weight: 0 },
614+
homePlanet: { weight: 0 },
615+
search: {
616+
resolveTo: 'searchresult',
617+
weight: expect.any(Function),
618+
},
619+
episode: { resolveTo: 'episode' },
620+
},
621+
},
622+
droid: {
623+
weight: 1,
624+
fields: {
625+
name: { weight: 0 },
626+
primaryFunction: { weight: 0 },
627+
search: {
628+
resolveTo: 'searchresult',
629+
weight: expect.any(Function),
630+
},
631+
episode: { resolveTo: 'episode' },
632+
},
633+
},
634+
episode: {
635+
weight: 0,
636+
fields: {},
637+
},
638+
});
639+
});
512640
});
513641

514642
describe('Not null operator (!) is used', () => {

0 commit comments

Comments
 (0)