diff --git a/src/utilities/__tests__/findBreakingChanges-test.js b/src/utilities/__tests__/findBreakingChanges-test.js index 56bfc05661..ddb0cf9c1a 100644 --- a/src/utilities/__tests__/findBreakingChanges-test.js +++ b/src/utilities/__tests__/findBreakingChanges-test.js @@ -921,6 +921,38 @@ describe('findDangerousChanges', () => { expect(findDangerousChanges(oldSchema, newSchema)).to.deep.equal([]); }); + it('should ignore changes in field definitions order', () => { + const oldSchema = buildSchema(` + input Input1 { + a: String + b: String + c: String + } + + type Type1 { + field1( + arg1: Input1 = { a: "a", b: "b", c: "c" } + ): String + } + `); + + const newSchema = buildSchema(` + input Input1 { + c: String + b: String + a: String + } + + type Type1 { + field1( + arg1: Input1 = { a: "a", b: "b", c: "c" } + ): String + } + `); + + expect(findDangerousChanges(oldSchema, newSchema)).to.deep.equal([]); + }); + it('should detect if a value was added to an enum type', () => { const oldSchema = buildSchema(` enum EnumType1 { diff --git a/src/utilities/findBreakingChanges.js b/src/utilities/findBreakingChanges.js index 3d48314c50..d53b107dd7 100644 --- a/src/utilities/findBreakingChanges.js +++ b/src/utilities/findBreakingChanges.js @@ -7,6 +7,7 @@ import inspect from '../jsutils/inspect'; import invariant from '../jsutils/invariant'; import { print } from '../language/printer'; +import { visit } from '../language/visitor'; import { type GraphQLSchema } from '../type/schema'; import { @@ -395,6 +396,9 @@ function findArgChanges( description: `${oldType.name}.${oldField.name} arg ${oldArg.name} defaultValue was removed.`, }); } else { + // Since we looking only for client's observable changes we should + // compare default values in the same representation as they are + // represented inside introspection. const oldValueStr = stringifyValue(oldArg.defaultValue, oldArg.type); const newValueStr = stringifyValue(newArg.defaultValue, newArg.type); @@ -518,7 +522,17 @@ function typeKindName(type: GraphQLNamedType): string { function stringifyValue(value: mixed, type: GraphQLInputType): string { const ast = astFromValue(value, type); invariant(ast != null); - return print(ast); + + const sortedAST = visit(ast, { + ObjectValue(objectNode) { + const fields = [...objectNode.fields].sort((fieldA, fieldB) => + fieldA.name.value.localeCompare(fieldB.name.value), + ); + return { ...objectNode, fields }; + }, + }); + + return print(sortedAST); } function diff(