Skip to content

Commit 189d976

Browse files
findBreakingChanges: reduce duplication by merging some functions (#1909)
1 parent b2aafc4 commit 189d976

File tree

1 file changed

+50
-208
lines changed

1 file changed

+50
-208
lines changed

src/utilities/findBreakingChanges.js

Lines changed: 50 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -97,32 +97,21 @@ function findSchemaChanges(
9797
newSchema: GraphQLSchema,
9898
): Array<BreakingChange | DangerousChange> {
9999
return [
100-
...findRemovedTypes(oldSchema, newSchema),
101-
...findTypesThatChangedKind(oldSchema, newSchema),
102-
...findFieldsThatChangedTypeOnObjectOrInterfaceTypes(oldSchema, newSchema),
103-
...findFieldsThatChangedTypeOnInputObjectTypes(oldSchema, newSchema),
104-
...findTypesAddedToUnions(oldSchema, newSchema),
105-
...findTypesRemovedFromUnions(oldSchema, newSchema),
106-
...findValuesAddedToEnums(oldSchema, newSchema),
107-
...findValuesRemovedFromEnums(oldSchema, newSchema),
100+
...findTypeChanges(oldSchema, newSchema),
101+
...findFieldChanges(oldSchema, newSchema),
102+
...findInputObjectTypeChanges(oldSchema, newSchema),
103+
...findUnionTypeChanges(oldSchema, newSchema),
104+
...findEnumTypeChanges(oldSchema, newSchema),
108105
...findArgChanges(oldSchema, newSchema),
109-
...findInterfacesAddedToObjectTypes(oldSchema, newSchema),
110-
...findInterfacesRemovedFromObjectTypes(oldSchema, newSchema),
111-
...findRemovedDirectives(oldSchema, newSchema),
112-
...findRemovedDirectiveArgs(oldSchema, newSchema),
113-
...findAddedNonNullDirectiveArgs(oldSchema, newSchema),
114-
...findRemovedDirectiveLocations(oldSchema, newSchema),
106+
...findObjectTypeChanges(oldSchema, newSchema),
107+
...findDirectiveChanges(oldSchema, newSchema),
115108
];
116109
}
117110

118-
/**
119-
* Given two schemas, returns an Array containing descriptions of any breaking
120-
* changes in the newSchema related to removing an entire type.
121-
*/
122-
function findRemovedTypes(
111+
function findTypeChanges(
123112
oldSchema: GraphQLSchema,
124113
newSchema: GraphQLSchema,
125-
): Array<BreakingChange> {
114+
): Array<BreakingChange | DangerousChange> {
126115
const schemaChanges = [];
127116

128117
const typesDiff = diff(
@@ -136,23 +125,6 @@ function findRemovedTypes(
136125
description: `${oldType.name} was removed.`,
137126
});
138127
}
139-
return schemaChanges;
140-
}
141-
142-
/**
143-
* Given two schemas, returns an Array containing descriptions of any breaking
144-
* changes in the newSchema related to changing the type of a type.
145-
*/
146-
function findTypesThatChangedKind(
147-
oldSchema: GraphQLSchema,
148-
newSchema: GraphQLSchema,
149-
): Array<BreakingChange> {
150-
const schemaChanges = [];
151-
152-
const typesDiff = diff(
153-
objectValues(oldSchema.getTypeMap()),
154-
objectValues(newSchema.getTypeMap()),
155-
);
156128

157129
for (const [oldType, newType] of typesDiff.persisted) {
158130
if (oldType.constructor !== newType.constructor) {
@@ -164,15 +136,10 @@ function findTypesThatChangedKind(
164136
});
165137
}
166138
}
139+
167140
return schemaChanges;
168141
}
169142

170-
/**
171-
* Given two schemas, returns an Array containing descriptions of any
172-
* breaking or dangerous changes in the newSchema related to arguments
173-
* (such as removal or change of type of an argument, or a change in an
174-
* argument's default value).
175-
*/
176143
function findArgChanges(
177144
oldSchema: GraphQLSchema,
178145
newSchema: GraphQLSchema,
@@ -284,10 +251,10 @@ function typeKindName(type: GraphQLNamedType): string {
284251
throw new TypeError(`Unexpected type: ${inspect((type: empty))}.`);
285252
}
286253

287-
function findFieldsThatChangedTypeOnObjectOrInterfaceTypes(
254+
function findFieldChanges(
288255
oldSchema: GraphQLSchema,
289256
newSchema: GraphQLSchema,
290-
): Array<BreakingChange> {
257+
): Array<BreakingChange | DangerousChange> {
291258
const schemaChanges = [];
292259

293260
const typesDiff = diff(
@@ -334,7 +301,7 @@ function findFieldsThatChangedTypeOnObjectOrInterfaceTypes(
334301
return schemaChanges;
335302
}
336303

337-
function findFieldsThatChangedTypeOnInputObjectTypes(
304+
function findInputObjectTypeChanges(
338305
oldSchema: GraphQLSchema,
339306
newSchema: GraphQLSchema,
340307
): Array<BreakingChange | DangerousChange> {
@@ -464,48 +431,10 @@ function isChangeSafeForInputObjectFieldOrFieldArg(
464431
return isNamedType(newType) && oldType.name === newType.name;
465432
}
466433

467-
/**
468-
* Given two schemas, returns an Array containing descriptions of any breaking
469-
* changes in the newSchema related to removing types from a union type.
470-
*/
471-
function findTypesRemovedFromUnions(
472-
oldSchema: GraphQLSchema,
473-
newSchema: GraphQLSchema,
474-
): Array<BreakingChange> {
475-
const schemaChanges = [];
476-
477-
const typesDiff = diff(
478-
objectValues(oldSchema.getTypeMap()),
479-
objectValues(newSchema.getTypeMap()),
480-
);
481-
482-
for (const [oldType, newType] of typesDiff.persisted) {
483-
if (!isUnionType(oldType) || !isUnionType(newType)) {
484-
continue;
485-
}
486-
487-
const possibleTypesDiff = diff(oldType.getTypes(), newType.getTypes());
488-
489-
for (const oldPossibleType of possibleTypesDiff.removed) {
490-
schemaChanges.push({
491-
type: BreakingChangeType.TYPE_REMOVED_FROM_UNION,
492-
description:
493-
`${oldPossibleType.name} was removed from ` +
494-
`union type ${oldType.name}.`,
495-
});
496-
}
497-
}
498-
return schemaChanges;
499-
}
500-
501-
/**
502-
* Given two schemas, returns an Array containing descriptions of any dangerous
503-
* changes in the newSchema related to adding types to a union type.
504-
*/
505-
function findTypesAddedToUnions(
434+
function findUnionTypeChanges(
506435
oldSchema: GraphQLSchema,
507436
newSchema: GraphQLSchema,
508-
): Array<DangerousChange> {
437+
): Array<BreakingChange | DangerousChange> {
509438
const schemaChanges = [];
510439

511440
const typesDiff = diff(
@@ -528,51 +457,24 @@ function findTypesAddedToUnions(
528457
`union type ${oldType.name}.`,
529458
});
530459
}
531-
}
532-
return schemaChanges;
533-
}
534-
/**
535-
* Given two schemas, returns an Array containing descriptions of any breaking
536-
* changes in the newSchema related to removing values from an enum type.
537-
*/
538-
function findValuesRemovedFromEnums(
539-
oldSchema: GraphQLSchema,
540-
newSchema: GraphQLSchema,
541-
): Array<BreakingChange> {
542-
const schemaChanges = [];
543-
544-
const typesDiff = diff(
545-
objectValues(oldSchema.getTypeMap()),
546-
objectValues(newSchema.getTypeMap()),
547-
);
548-
549-
for (const [oldType, newType] of typesDiff.persisted) {
550-
if (!isEnumType(oldType) || !isEnumType(newType)) {
551-
continue;
552-
}
553-
554-
const valuesDiff = diff(oldType.getValues(), newType.getValues());
555460

556-
for (const oldValue of valuesDiff.removed) {
461+
for (const oldPossibleType of possibleTypesDiff.removed) {
557462
schemaChanges.push({
558-
type: BreakingChangeType.VALUE_REMOVED_FROM_ENUM,
559-
description: `${oldValue.name} was removed from enum type ${
560-
oldType.name
561-
}.`,
463+
type: BreakingChangeType.TYPE_REMOVED_FROM_UNION,
464+
description:
465+
`${oldPossibleType.name} was removed from ` +
466+
`union type ${oldType.name}.`,
562467
});
563468
}
564469
}
470+
565471
return schemaChanges;
566472
}
567473

568-
/**
569-
* Given two schemas, returns an Array containing descriptions of any dangerous
570-
* changes in the newSchema related to adding values to an enum type.
571-
*/
572-
function findValuesAddedToEnums(
474+
function findEnumTypeChanges(
573475
oldSchema: GraphQLSchema,
574476
newSchema: GraphQLSchema,
575-
): Array<DangerousChange> {
477+
): Array<BreakingChange | DangerousChange> {
576478
const schemaChanges = [];
577479

578480
const typesDiff = diff(
@@ -593,47 +495,24 @@ function findValuesAddedToEnums(
593495
description: `${newValue.name} was added to enum type ${oldType.name}.`,
594496
});
595497
}
596-
}
597-
return schemaChanges;
598-
}
599-
600-
function findInterfacesRemovedFromObjectTypes(
601-
oldSchema: GraphQLSchema,
602-
newSchema: GraphQLSchema,
603-
): Array<BreakingChange> {
604-
const schemaChanges = [];
605-
606-
const typesDiff = diff(
607-
objectValues(oldSchema.getTypeMap()),
608-
objectValues(newSchema.getTypeMap()),
609-
);
610-
611-
for (const [oldType, newType] of typesDiff.persisted) {
612-
if (!isObjectType(oldType) || !isObjectType(newType)) {
613-
continue;
614-
}
615498

616-
const interfacesDiff = diff(
617-
oldType.getInterfaces(),
618-
newType.getInterfaces(),
619-
);
620-
621-
for (const oldInterface of interfacesDiff.removed) {
499+
for (const oldValue of valuesDiff.removed) {
622500
schemaChanges.push({
623-
type: BreakingChangeType.INTERFACE_REMOVED_FROM_OBJECT,
624-
description:
625-
`${oldType.name} no longer implements interface ` +
626-
`${oldInterface.name}.`,
501+
type: BreakingChangeType.VALUE_REMOVED_FROM_ENUM,
502+
description: `${oldValue.name} was removed from enum type ${
503+
oldType.name
504+
}.`,
627505
});
628506
}
629507
}
508+
630509
return schemaChanges;
631510
}
632511

633-
function findInterfacesAddedToObjectTypes(
512+
function findObjectTypeChanges(
634513
oldSchema: GraphQLSchema,
635514
newSchema: GraphQLSchema,
636-
): Array<DangerousChange> {
515+
): Array<BreakingChange | DangerousChange> {
637516
const schemaChanges = [];
638517

639518
const typesDiff = diff(
@@ -659,14 +538,23 @@ function findInterfacesAddedToObjectTypes(
659538
`by ${oldType.name}.`,
660539
});
661540
}
541+
542+
for (const oldInterface of interfacesDiff.removed) {
543+
schemaChanges.push({
544+
type: BreakingChangeType.INTERFACE_REMOVED_FROM_OBJECT,
545+
description:
546+
`${oldType.name} no longer implements interface ` +
547+
`${oldInterface.name}.`,
548+
});
549+
}
662550
}
663551
return schemaChanges;
664552
}
665553

666-
function findRemovedDirectives(
554+
function findDirectiveChanges(
667555
oldSchema: GraphQLSchema,
668556
newSchema: GraphQLSchema,
669-
): Array<BreakingChange> {
557+
): Array<BreakingChange | DangerousChange> {
670558
const schemaChanges = [];
671559

672560
const directivesDiff = diff(
@@ -681,46 +569,9 @@ function findRemovedDirectives(
681569
});
682570
}
683571

684-
return schemaChanges;
685-
}
686-
687-
function findRemovedDirectiveArgs(
688-
oldSchema: GraphQLSchema,
689-
newSchema: GraphQLSchema,
690-
): Array<BreakingChange> {
691-
const schemaChanges = [];
692-
693-
const directivesDiff = diff(
694-
oldSchema.getDirectives(),
695-
newSchema.getDirectives(),
696-
);
697-
698572
for (const [oldDirective, newDirective] of directivesDiff.persisted) {
699573
const argsDiff = diff(oldDirective.args, newDirective.args);
700-
for (const oldArg of argsDiff.removed) {
701-
schemaChanges.push({
702-
type: BreakingChangeType.DIRECTIVE_ARG_REMOVED,
703-
description: `${oldArg.name} was removed from ${oldDirective.name}.`,
704-
});
705-
}
706-
}
707574

708-
return schemaChanges;
709-
}
710-
711-
function findAddedNonNullDirectiveArgs(
712-
oldSchema: GraphQLSchema,
713-
newSchema: GraphQLSchema,
714-
): Array<BreakingChange> {
715-
const schemaChanges = [];
716-
717-
const directivesDiff = diff(
718-
oldSchema.getDirectives(),
719-
newSchema.getDirectives(),
720-
);
721-
722-
for (const [oldDirective, newDirective] of directivesDiff.persisted) {
723-
const argsDiff = diff(oldDirective.args, newDirective.args);
724575
for (const newArg of argsDiff.added) {
725576
if (isRequiredArgument(newArg)) {
726577
schemaChanges.push({
@@ -731,23 +582,14 @@ function findAddedNonNullDirectiveArgs(
731582
});
732583
}
733584
}
734-
}
735585

736-
return schemaChanges;
737-
}
738-
739-
function findRemovedDirectiveLocations(
740-
oldSchema: GraphQLSchema,
741-
newSchema: GraphQLSchema,
742-
): Array<BreakingChange> {
743-
const schemaChanges = [];
744-
745-
const directivesDiff = diff(
746-
oldSchema.getDirectives(),
747-
newSchema.getDirectives(),
748-
);
586+
for (const oldArg of argsDiff.removed) {
587+
schemaChanges.push({
588+
type: BreakingChangeType.DIRECTIVE_ARG_REMOVED,
589+
description: `${oldArg.name} was removed from ${oldDirective.name}.`,
590+
});
591+
}
749592

750-
for (const [oldDirective, newDirective] of directivesDiff.persisted) {
751593
for (const location of oldDirective.locations) {
752594
if (newDirective.locations.indexOf(location) === -1) {
753595
schemaChanges.push({
@@ -766,12 +608,12 @@ function diff<T: { name: string }>(
766608
newArray: $ReadOnlyArray<T>,
767609
): {
768610
added: Array<T>,
769-
persisted: Array<[T, T]>,
770611
removed: Array<T>,
612+
persisted: Array<[T, T]>,
771613
} {
772614
const added = [];
773-
const persisted = [];
774615
const removed = [];
616+
const persisted = [];
775617

776618
const oldMap = keyMap(oldArray, ({ name }) => name);
777619
const newMap = keyMap(newArray, ({ name }) => name);

0 commit comments

Comments
 (0)