Skip to content

Commit

Permalink
Merge pull request #984 from excitement-engineer/enum-dangerous-change
Browse files Browse the repository at this point in the history
Adding a value to an enum is now a dangerous change.
  • Loading branch information
wincent authored Aug 7, 2017
2 parents 0e7d460 + bb98768 commit b6a46a0
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
63 changes: 63 additions & 0 deletions src/utilities/__tests__/findBreakingChanges-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
findTypesRemovedFromUnions,
findTypesThatChangedKind,
findValuesRemovedFromEnums,
findValuesAddedToEnums,
findArgChanges,
findInterfacesRemovedFromObjectTypes,
} from '../findBreakingChanges';
Expand Down Expand Up @@ -1349,7 +1350,63 @@ describe('findDangerousChanges', () => {
});
});

it('should detect if a value was added to an enum type', () => {
const oldEnumType = new GraphQLEnumType({
name: 'EnumType1',
values: {
VALUE0: { value: 0 },
VALUE1: { value: 1 },
}
});
const newEnumType = new GraphQLEnumType({
name: 'EnumType1',
values: {
VALUE0: { value: 0 },
VALUE1: { value: 1 },
VALUE2: { value: 2 },
}
});

const oldSchema = new GraphQLSchema({
query: queryType,
types: [
oldEnumType,
]
});
const newSchema = new GraphQLSchema({
query: queryType,
types: [
newEnumType,
]
});

expect(findValuesAddedToEnums(oldSchema, newSchema)).to.eql(
[
{
type: DangerousChangeType.VALUE_ADDED_TO_ENUM,
description: 'VALUE2 was added to enum type EnumType1.',
}
]
);
});

it('should find all dangerous changes', () => {
const enumThatGainsAValueOld = new GraphQLEnumType({
name: 'EnumType1',
values: {
VALUE0: { value: 0 },
VALUE1: { value: 1 },
}
});
const enumThatGainsAValueNew = new GraphQLEnumType({
name: 'EnumType1',
values: {
VALUE0: { value: 0 },
VALUE1: { value: 1 },
VALUE2: { value: 2 },
}
});

const oldType = new GraphQLObjectType({
name: 'Type1',
fields: {
Expand Down Expand Up @@ -1384,20 +1441,26 @@ describe('findDangerousChanges', () => {
query: queryType,
types: [
oldType,
enumThatGainsAValueOld
]
});

const newSchema = new GraphQLSchema({
query: queryType,
types: [
newType,
enumThatGainsAValueNew
]
});

const expectedDangerousChanges = [
{
description: 'Type1.field1 arg name has changed defaultValue',
type: 'ARG_DEFAULT_VALUE_CHANGE'
},
{
description: 'VALUE2 was added to enum type EnumType1.',
type: 'VALUE_ADDED_TO_ENUM',
}
];

Expand Down
38 changes: 38 additions & 0 deletions src/utilities/findBreakingChanges.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const BreakingChangeType = {

export const DangerousChangeType = {
ARG_DEFAULT_VALUE_CHANGE: 'ARG_DEFAULT_VALUE_CHANGE',
VALUE_ADDED_TO_ENUM: 'VALUE_ADDED_TO_ENUM'
};

export type BreakingChange = {
Expand Down Expand Up @@ -85,6 +86,7 @@ export function findDangerousChanges(
): Array<DangerousChange> {
return [
...findArgChanges(oldSchema, newSchema).dangerousChanges,
...findValuesAddedToEnums(oldSchema, newSchema)
];
}

Expand Down Expand Up @@ -542,6 +544,42 @@ export function findValuesRemovedFromEnums(
return valuesRemovedFromEnums;
}

/**
* Given two schemas, returns an Array containing descriptions of any dangerous
* changes in the newSchema related to adding values to an enum type.
*/
export function findValuesAddedToEnums(
oldSchema: GraphQLSchema,
newSchema: GraphQLSchema
): Array<DangerousChange> {
const oldTypeMap = oldSchema.getTypeMap();
const newTypeMap = newSchema.getTypeMap();

const valuesAddedToEnums = [];
Object.keys(oldTypeMap).forEach(typeName => {
const oldType = oldTypeMap[typeName];
const newType = newTypeMap[typeName];
if (!(oldType instanceof GraphQLEnumType) ||
!(newType instanceof GraphQLEnumType)) {
return;
}

const valuesInOldEnum = Object.create(null);
oldType.getValues().forEach(value => {
valuesInOldEnum[value.name] = true;
});
newType.getValues().forEach(value => {
if (!valuesInOldEnum[value.name]) {
valuesAddedToEnums.push({
type: DangerousChangeType.VALUE_ADDED_TO_ENUM,
description: `${value.name} was added to enum type ${typeName}.`
});
}
});
});
return valuesAddedToEnums;
}

export function findInterfacesRemovedFromObjectTypes(
oldSchema: GraphQLSchema,
newSchema: GraphQLSchema
Expand Down

0 comments on commit b6a46a0

Please sign in to comment.