From c6d08f96e2fd746864e985048439703342b99834 Mon Sep 17 00:00:00 2001 From: Franklin Wang Date: Wed, 1 Mar 2023 14:21:28 +1300 Subject: [PATCH 1/3] Fix type change and directive deletion problems in schema diffing --- .../diffing/ana/EditOperationAnalyzer.java | 35 ++- ...rationAnalyzerAppliedDirectivesTest.groovy | 13 +- .../ana/EditOperationAnalyzerTest.groovy | 239 ++++++++++++++++++ 3 files changed, 270 insertions(+), 17 deletions(-) diff --git a/src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java b/src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java index 2b1e11868d..86eb7e11f9 100644 --- a/src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java +++ b/src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java @@ -15,6 +15,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.function.Predicate; import static graphql.Assert.assertTrue; import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveAddition; @@ -593,7 +594,7 @@ private void handleUnionMemberChanges(List editOperations, Mappin break; case DELETE_EDGE: Edge oldEdge = editOperation.getSourceEdge(); - if (oldEdge.getFrom().isOfType(SchemaGraph.UNION)) { + if (oldEdge.getFrom().isOfType(SchemaGraph.UNION) && !oldEdge.getTo().isOfType(SchemaGraph.APPLIED_DIRECTIVE)) { handleUnionMemberDeleted(editOperation); } break; @@ -606,13 +607,13 @@ private void handleEnumValuesChanges(List editOperations, Mapping switch (editOperation.getOperation()) { case INSERT_EDGE: Edge newEdge = editOperation.getTargetEdge(); - if (newEdge.getFrom().isOfType(SchemaGraph.ENUM)) { + if (newEdge.getFrom().isOfType(SchemaGraph.ENUM) && newEdge.getTo().isOfType(SchemaGraph.ENUM_VALUE)) { handleEnumValueAdded(editOperation); } break; case DELETE_EDGE: Edge oldEdge = editOperation.getSourceEdge(); - if (oldEdge.getFrom().isOfType(SchemaGraph.ENUM)) { + if (oldEdge.getFrom().isOfType(SchemaGraph.ENUM) && oldEdge.getTo().isOfType(SchemaGraph.ENUM_VALUE)) { handleEnumValueDeleted(editOperation); } break; @@ -709,6 +710,9 @@ private void handleEnumValueAdded(EditOperation editOperation) { return; } Vertex newValue = newEdge.getTo(); + if (!newValue.isOfType(SchemaGraph.ENUM_VALUE)) { + return; + } EnumModification enumModification = getEnumModification(enumVertex.getName()); enumModification.getDetails().add(new EnumValueAddition(newValue.getName())); } @@ -720,6 +724,9 @@ private void handleEnumValueDeleted(EditOperation editOperation) { return; } Vertex value = deletedEdge.getTo(); + if (!value.isOfType(SchemaGraph.ENUM_VALUE)) { + return; + } EnumModification enumModification = getEnumModification(enumVertex.getName()); enumModification.getDetails().add(new EnumValueDeletion(value.getName())); } @@ -932,7 +939,7 @@ private void typeEdgeInsertedForInputField(EditOperation return; } String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); - EditOperation deletedTypeEdgeOperation = findDeletedEdge(inputField, editOperations, mapping); + EditOperation deletedTypeEdgeOperation = findDeletedEdge(inputField, editOperations, mapping, edge -> edge.getLabel().contains("type=")); String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); InputObjectFieldTypeModification inputObjectFieldTypeModification = new InputObjectFieldTypeModification(inputField.getName(), oldType, newType); getInputObjectModification(inputObject.getName()).getDetails().add(inputObjectFieldTypeModification); @@ -963,7 +970,7 @@ private void typeEdgeInsertedForArgument(EditOperation String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); // this means we have an existing object changed its type // and there must be a deleted edge with the old type information - EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping); + EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping, edge -> edge.getLabel().contains("type=")); String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); ObjectFieldArgumentTypeModification objectFieldArgumentTypeModification = new ObjectFieldArgumentTypeModification(field.getName(), argument.getName(), oldType, newType); getObjectModification(object.getName()).getDetails().add(objectFieldArgumentTypeModification); @@ -985,7 +992,7 @@ private void typeEdgeInsertedForArgument(EditOperation String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); // this means we have an existing object changed its type // and there must be a deleted edge with the old type information - EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping); + EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping, edge -> edge.getLabel().contains("type=")); String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); InterfaceFieldArgumentTypeModification interfaceFieldArgumentTypeModification = new InterfaceFieldArgumentTypeModification(field.getName(), argument.getName(), oldType, newType); getInterfaceModification(interfaze.getName()).getDetails().add(interfaceFieldArgumentTypeModification); @@ -1000,7 +1007,7 @@ private void typeEdgeInsertedForArgument(EditOperation return; } String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); - EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping); + EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping, edge -> edge.getLabel().contains("type=")); String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); DirectiveArgumentTypeModification directiveArgumentTypeModification = new DirectiveArgumentTypeModification(argument.getName(), oldType, newType); getDirectiveModification(directive.getName()).getDetails().add(directiveArgumentTypeModification); @@ -1025,11 +1032,10 @@ private void typeEdgeInsertedForField(EditOperation String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); // this means we have an existing object changed its type // and there must be a deleted edge with the old type information - EditOperation deletedTypeEdgeOperation = findDeletedEdge(field, editOperations, mapping); + EditOperation deletedTypeEdgeOperation = findDeletedEdge(field, editOperations, mapping, (edge) -> edge.getLabel().contains("type=")); String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); ObjectFieldTypeModification objectFieldTypeModification = new ObjectFieldTypeModification(field.getName(), oldType, newType); getObjectModification(object.getName()).getDetails().add(objectFieldTypeModification); - } else { assertTrue(objectOrInterface.isOfType(SchemaGraph.INTERFACE)); Vertex interfaze = objectOrInterface; @@ -1042,22 +1048,23 @@ private void typeEdgeInsertedForField(EditOperation String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); // this means we have an existing object changed its type // and there must be a deleted edge with the old type information - EditOperation deletedTypeEdgeOperation = findDeletedEdge(field, editOperations, mapping); + EditOperation deletedTypeEdgeOperation = findDeletedEdge(field, editOperations, mapping, (edge) -> edge.getLabel().contains("type=")); String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); InterfaceFieldTypeModification interfaceFieldTypeModification = new InterfaceFieldTypeModification(field.getName(), oldType, newType); getInterfaceModification(interfaze.getName()).getDetails().add(interfaceFieldTypeModification); - } } - private EditOperation findDeletedEdge(Vertex targetVertexFrom, List editOperations, Mapping - mapping) { + private EditOperation findDeletedEdge(Vertex targetVertexFrom, + List editOperations, + Mapping mapping, + Predicate edgePredicate) { Vertex sourceVertexFrom = mapping.getSource(targetVertexFrom); for (EditOperation editOperation : editOperations) { if (editOperation.getOperation() == EditOperation.Operation.DELETE_EDGE) { Edge deletedEdge = editOperation.getSourceEdge(); - if (deletedEdge.getFrom() == sourceVertexFrom) { + if (deletedEdge.getFrom() == sourceVertexFrom && edgePredicate.test(deletedEdge)) { return editOperation; } } diff --git a/src/test/groovy/graphql/schema/diffing/ana/EditOperationAnalyzerAppliedDirectivesTest.groovy b/src/test/groovy/graphql/schema/diffing/ana/EditOperationAnalyzerAppliedDirectivesTest.groovy index 4e1c30a21d..623c2dfc04 100644 --- a/src/test/groovy/graphql/schema/diffing/ana/EditOperationAnalyzerAppliedDirectivesTest.groovy +++ b/src/test/groovy/graphql/schema/diffing/ana/EditOperationAnalyzerAppliedDirectivesTest.groovy @@ -547,7 +547,11 @@ class EditOperationAnalyzerAppliedDirectivesTest extends Specification { def changes = calcDiff(oldSdl, newSdl) then: changes.enumDifferences["E"] instanceof EnumModification - def appliedDirective = (changes.enumDifferences["E"] as EnumModification).getDetails(AppliedDirectiveDeletion) + def diff = changes.enumDifferences["E"] as EnumModification + + diff.getDetails().size() == 1 + + def appliedDirective = diff.getDetails(AppliedDirectiveDeletion) (appliedDirective[0].locationDetail as AppliedDirectiveEnumLocation).name == "E" appliedDirective[0].name == "d" } @@ -778,7 +782,6 @@ class EditOperationAnalyzerAppliedDirectivesTest extends Specification { appliedDirective[0].name == "d" } - def "applied directive deleted union"() { given: def oldSdl = ''' @@ -802,8 +805,12 @@ class EditOperationAnalyzerAppliedDirectivesTest extends Specification { when: def changes = calcDiff(oldSdl, newSdl) then: + changes.unionDifferences.keySet() == ["U"] as Set changes.unionDifferences["U"] instanceof UnionModification - def appliedDirective = (changes.unionDifferences["U"] as UnionModification).getDetails(AppliedDirectiveDeletion) + def diff = changes.unionDifferences["U"] as UnionModification + diff.details.size() == 1 + + def appliedDirective = diff.getDetails(AppliedDirectiveDeletion) (appliedDirective[0].locationDetail as AppliedDirectiveUnionLocation).name == "U" appliedDirective[0].name == "d" } diff --git a/src/test/groovy/graphql/schema/diffing/ana/EditOperationAnalyzerTest.groovy b/src/test/groovy/graphql/schema/diffing/ana/EditOperationAnalyzerTest.groovy index 2a5b223212..006108d48d 100644 --- a/src/test/groovy/graphql/schema/diffing/ana/EditOperationAnalyzerTest.groovy +++ b/src/test/groovy/graphql/schema/diffing/ana/EditOperationAnalyzerTest.groovy @@ -4,6 +4,11 @@ import graphql.TestUtil import graphql.schema.diffing.SchemaDiffing import spock.lang.Specification +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveDeletion +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveObjectFieldArgumentLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveDirectiveArgumentLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveObjectFieldLocation +import static graphql.schema.diffing.ana.SchemaDifference.AppliedDirectiveInterfaceFieldArgumentLocation import static graphql.schema.diffing.ana.SchemaDifference.DirectiveAddition import static graphql.schema.diffing.ana.SchemaDifference.DirectiveArgumentAddition import static graphql.schema.diffing.ana.SchemaDifference.DirectiveArgumentDefaultValueModification @@ -1663,6 +1668,240 @@ class EditOperationAnalyzerTest extends Specification { argTypeModification[0].newType == '[String]!' } + def "field renamed and output type changed and argument deleted"() { + given: + def oldSdl = ''' + type Query { + ping(pong: String): ID + } + ''' + def newSdl = ''' + type Query { + echo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + true + changes.objectDifferences["Query"] instanceof ObjectModification + def objectDiff = changes.objectDifferences["Query"] as ObjectModification + + def rename = objectDiff.getDetails(ObjectFieldRename) + rename.size() == 1 + rename[0].oldName == "ping" + rename[0].newName == "echo" + + def argumentDeletion = objectDiff.getDetails(ObjectFieldArgumentDeletion) + argumentDeletion.size() == 1 + argumentDeletion[0].fieldName == "ping" + argumentDeletion[0].name == "pong" + + def typeModification = objectDiff.getDetails(ObjectFieldTypeModification) + typeModification.size() == 1 + typeModification[0].fieldName == "echo" + typeModification[0].oldType == "ID" + typeModification[0].newType == "String" + } + + def "object field argument changed and applied directive deleted"() { + given: + def oldSdl = ''' + type Query { + ping(pong: String @d): ID + } + directive @d on ARGUMENT_DEFINITION + ''' + def newSdl = ''' + type Query { + ping(pong: Int): ID + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + true + changes.objectDifferences["Query"] instanceof ObjectModification + def objectDiff = changes.objectDifferences["Query"] as ObjectModification + + def typeModification = objectDiff.getDetails(ObjectFieldArgumentTypeModification) + typeModification.size() == 1 + typeModification[0].oldType == "String" + typeModification[0].newType == "Int" + typeModification[0].fieldName == "ping" + typeModification[0].argumentName == "pong" + + def directiveDeletion = objectDiff.getDetails(AppliedDirectiveDeletion) + directiveDeletion.size() == 1 + directiveDeletion[0].name == "d" + directiveDeletion[0].locationDetail instanceof AppliedDirectiveObjectFieldArgumentLocation + + def location = directiveDeletion[0].locationDetail as AppliedDirectiveObjectFieldArgumentLocation + location.objectName == "Query" + location.fieldName == "ping" + location.argumentName == "pong" + } + + def "interface field argument changed and applied directive deleted"() { + given: + def oldSdl = ''' + type Query { + echo: String + } + interface TableTennis { + ping(pong: String @d): ID + } + directive @d on ARGUMENT_DEFINITION + ''' + def newSdl = ''' + type Query { + echo: String + } + interface TableTennis { + ping(pong: Int): ID + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + true + changes.interfaceDifferences["TableTennis"] instanceof InterfaceModification + def diff = changes.interfaceDifferences["TableTennis"] as InterfaceModification + + def typeModification = diff.getDetails(InterfaceFieldArgumentTypeModification) + typeModification.size() == 1 + typeModification[0].oldType == "String" + typeModification[0].newType == "Int" + typeModification[0].fieldName == "ping" + typeModification[0].argumentName == "pong" + + def directiveDeletion = diff.getDetails(AppliedDirectiveDeletion) + directiveDeletion.size() == 1 + directiveDeletion[0].name == "d" + directiveDeletion[0].locationDetail instanceof AppliedDirectiveInterfaceFieldArgumentLocation + + def location = directiveDeletion[0].locationDetail as AppliedDirectiveInterfaceFieldArgumentLocation + location.interfaceName == "TableTennis" + location.fieldName == "ping" + location.argumentName == "pong" + } + + def "directive argument changed and applied directive deleted"() { + given: + def oldSdl = ''' + type Query { + ping(pong: String): ID @d + } + directive @a on ARGUMENT_DEFINITION + directive @d(message: ID @a) on FIELD_DEFINITION + ''' + def newSdl = ''' + type Query { + ping(pong: String): ID @d + } + directive @a on ARGUMENT_DEFINITION + directive @d(message: String) on FIELD_DEFINITION + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + true + changes.directiveDifferences["d"] instanceof DirectiveModification + def diff = changes.directiveDifferences["d"] as DirectiveModification + + def typeModification = diff.getDetails(DirectiveArgumentTypeModification) + typeModification.size() == 1 + typeModification[0].oldType == "ID" + typeModification[0].newType == "String" + typeModification[0].argumentName == "message" + + def directiveDeletion = diff.getDetails(AppliedDirectiveDeletion) + directiveDeletion.size() == 1 + directiveDeletion[0].name == "a" + directiveDeletion[0].locationDetail instanceof AppliedDirectiveDirectiveArgumentLocation + + def location = directiveDeletion[0].locationDetail as AppliedDirectiveDirectiveArgumentLocation + location.directiveName == "d" + location.argumentName == "message" + } + + def "field output type changed and applied directive removed"() { + given: + def oldSdl = ''' + type Query { + echo: ID @d + } + directive @d on FIELD_DEFINITION + ''' + def newSdl = ''' + type Query { + echo: String + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + true + changes.objectDifferences["Query"] instanceof ObjectModification + def objectDiff = changes.objectDifferences["Query"] as ObjectModification + + def typeModification = objectDiff.getDetails(ObjectFieldTypeModification) + typeModification.size() == 1 + typeModification[0].fieldName == "echo" + typeModification[0].oldType == "ID" + typeModification[0].newType == "String" + + def directiveDeletion = objectDiff.getDetails(AppliedDirectiveDeletion) + directiveDeletion.size() == 1 + directiveDeletion[0].name == "d" + directiveDeletion[0].locationDetail instanceof AppliedDirectiveObjectFieldLocation + + def location = directiveDeletion[0].locationDetail as AppliedDirectiveObjectFieldLocation + location.objectName == "Query" + location.fieldName == "echo" + } + + def "input field renamed and type changed and applied directive removed"() { + given: + def oldSdl = ''' + type Query { + echo(input: Echo): String + } + input Echo { + message: String @d + } + directive @d on INPUT_FIELD_DEFINITION + ''' + def newSdl = ''' + type Query { + echo(input: Echo): String + } + input Echo { + age: Int + } + ''' + when: + def changes = calcDiff(oldSdl, newSdl) + then: + true + changes.inputObjectDifferences["Echo"] instanceof InputObjectModification + def diff = changes.inputObjectDifferences["Echo"] as InputObjectModification + + def rename = diff.getDetails(InputObjectFieldRename) + rename.size() == 1 + rename[0].oldName == "message" + rename[0].newName == "age" + + def typeModification = diff.getDetails(InputObjectFieldTypeModification) + typeModification.size() == 1 + typeModification[0].fieldName == "age" + typeModification[0].oldType == "String" + typeModification[0].newType == "Int" + + def directiveDeletion = diff.getDetails(AppliedDirectiveDeletion) + directiveDeletion.size() == 1 + directiveDeletion[0].name == "d" + } EditOperationAnalysisResult calcDiff( String oldSdl, From c3a54979fedff796aa5979059a1d2dab8fdd8768 Mon Sep 17 00:00:00 2001 From: Franklin Wang Date: Wed, 1 Mar 2023 14:25:54 +1300 Subject: [PATCH 2/3] Remove redundant check --- .../graphql/schema/diffing/ana/EditOperationAnalyzer.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java b/src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java index 86eb7e11f9..1da208cf4f 100644 --- a/src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java +++ b/src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java @@ -710,9 +710,6 @@ private void handleEnumValueAdded(EditOperation editOperation) { return; } Vertex newValue = newEdge.getTo(); - if (!newValue.isOfType(SchemaGraph.ENUM_VALUE)) { - return; - } EnumModification enumModification = getEnumModification(enumVertex.getName()); enumModification.getDetails().add(new EnumValueAddition(newValue.getName())); } @@ -724,9 +721,6 @@ private void handleEnumValueDeleted(EditOperation editOperation) { return; } Vertex value = deletedEdge.getTo(); - if (!value.isOfType(SchemaGraph.ENUM_VALUE)) { - return; - } EnumModification enumModification = getEnumModification(enumVertex.getName()); enumModification.getDetails().add(new EnumValueDeletion(value.getName())); } From fb695efb018dbee37fa78196f9ae789cbeaf30f1 Mon Sep 17 00:00:00 2001 From: Franklin Wang Date: Thu, 2 Mar 2023 12:16:45 +1300 Subject: [PATCH 3/3] Add helper to check whether edge is a type --- .../diffing/ana/EditOperationAnalyzer.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java b/src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java index 1da208cf4f..819fc325ef 100644 --- a/src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java +++ b/src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java @@ -933,7 +933,7 @@ private void typeEdgeInsertedForInputField(EditOperation return; } String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); - EditOperation deletedTypeEdgeOperation = findDeletedEdge(inputField, editOperations, mapping, edge -> edge.getLabel().contains("type=")); + EditOperation deletedTypeEdgeOperation = findDeletedEdge(inputField, editOperations, mapping, this::isTypeEdge); String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); InputObjectFieldTypeModification inputObjectFieldTypeModification = new InputObjectFieldTypeModification(inputField.getName(), oldType, newType); getInputObjectModification(inputObject.getName()).getDetails().add(inputObjectFieldTypeModification); @@ -964,7 +964,7 @@ private void typeEdgeInsertedForArgument(EditOperation String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); // this means we have an existing object changed its type // and there must be a deleted edge with the old type information - EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping, edge -> edge.getLabel().contains("type=")); + EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping, this::isTypeEdge); String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); ObjectFieldArgumentTypeModification objectFieldArgumentTypeModification = new ObjectFieldArgumentTypeModification(field.getName(), argument.getName(), oldType, newType); getObjectModification(object.getName()).getDetails().add(objectFieldArgumentTypeModification); @@ -986,7 +986,7 @@ private void typeEdgeInsertedForArgument(EditOperation String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); // this means we have an existing object changed its type // and there must be a deleted edge with the old type information - EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping, edge -> edge.getLabel().contains("type=")); + EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping, this::isTypeEdge); String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); InterfaceFieldArgumentTypeModification interfaceFieldArgumentTypeModification = new InterfaceFieldArgumentTypeModification(field.getName(), argument.getName(), oldType, newType); getInterfaceModification(interfaze.getName()).getDetails().add(interfaceFieldArgumentTypeModification); @@ -1001,7 +1001,7 @@ private void typeEdgeInsertedForArgument(EditOperation return; } String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); - EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping, edge -> edge.getLabel().contains("type=")); + EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping, this::isTypeEdge); String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); DirectiveArgumentTypeModification directiveArgumentTypeModification = new DirectiveArgumentTypeModification(argument.getName(), oldType, newType); getDirectiveModification(directive.getName()).getDetails().add(directiveArgumentTypeModification); @@ -1026,7 +1026,7 @@ private void typeEdgeInsertedForField(EditOperation String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); // this means we have an existing object changed its type // and there must be a deleted edge with the old type information - EditOperation deletedTypeEdgeOperation = findDeletedEdge(field, editOperations, mapping, (edge) -> edge.getLabel().contains("type=")); + EditOperation deletedTypeEdgeOperation = findDeletedEdge(field, editOperations, mapping, this::isTypeEdge); String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); ObjectFieldTypeModification objectFieldTypeModification = new ObjectFieldTypeModification(field.getName(), oldType, newType); getObjectModification(object.getName()).getDetails().add(objectFieldTypeModification); @@ -1042,7 +1042,7 @@ private void typeEdgeInsertedForField(EditOperation String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge()); // this means we have an existing object changed its type // and there must be a deleted edge with the old type information - EditOperation deletedTypeEdgeOperation = findDeletedEdge(field, editOperations, mapping, (edge) -> edge.getLabel().contains("type=")); + EditOperation deletedTypeEdgeOperation = findDeletedEdge(field, editOperations, mapping, this::isTypeEdge); String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge()); InterfaceFieldTypeModification interfaceFieldTypeModification = new InterfaceFieldTypeModification(field.getName(), oldType, newType); getInterfaceModification(interfaze.getName()).getDetails().add(interfaceFieldTypeModification); @@ -1200,6 +1200,10 @@ private String getDefaultValueFromEdgeLabel(Edge edge) { return defaultValue; } + private boolean isTypeEdge(Edge edge) { + String label = edge.getLabel(); + return label.startsWith("type="); + } private void interfaceImplementationDeleted(Edge deletedEdge) { Vertex from = deletedEdge.getFrom();