Skip to content

Commit 532042e

Browse files
committed
Check for default value changes when argument type changes
1 parent 8bb6464 commit 532042e

2 files changed

Lines changed: 148 additions & 7 deletions

File tree

src/main/java/graphql/schema/diffing/ana/EditOperationAnalyzer.java

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -960,8 +960,9 @@ private void typeEdgeInserted(EditOperation editOperation, List<EditOperation> e
960960

961961
}
962962

963-
private void typeEdgeInsertedForInputField(EditOperation
964-
editOperation, List<EditOperation> editOperations, Mapping mapping) {
963+
private void typeEdgeInsertedForInputField(EditOperation editOperation,
964+
List<EditOperation> editOperations,
965+
Mapping mapping) {
965966
Vertex inputField = editOperation.getTargetEdge().getFrom();
966967
Vertex inputObject = newSchemaGraph.getInputObjectForInputField(inputField);
967968
if (isInputObjectAdded(inputObject.getName())) {
@@ -977,8 +978,9 @@ private void typeEdgeInsertedForInputField(EditOperation
977978
getInputObjectModification(inputObject.getName()).getDetails().add(inputObjectFieldTypeModification);
978979
}
979980

980-
private void typeEdgeInsertedForArgument(EditOperation
981-
editOperation, List<EditOperation> editOperations, Mapping mapping) {
981+
private void typeEdgeInsertedForArgument(EditOperation editOperation,
982+
List<EditOperation> editOperations,
983+
Mapping mapping) {
982984
Vertex argument = editOperation.getTargetEdge().getFrom();
983985
Vertex fieldOrDirective = newSchemaGraph.getFieldOrDirectiveForArgument(argument);
984986
if (fieldOrDirective.isOfType(SchemaGraph.FIELD)) {
@@ -987,6 +989,7 @@ private void typeEdgeInsertedForArgument(EditOperation
987989

988990
if (objectOrInterface.isOfType(SchemaGraph.OBJECT)) {
989991
Vertex object = objectOrInterface;
992+
990993
// if the whole object is new we are done
991994
if (isObjectAdded(object.getName())) {
992995
return;
@@ -999,16 +1002,24 @@ private void typeEdgeInsertedForArgument(EditOperation
9991002
if (isArgumentNewForExistingObjectField(object.getName(), field.getName(), argument.getName())) {
10001003
return;
10011004
}
1005+
10021006
String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge());
10031007
// this means we have an existing object changed its type
10041008
// and there must be a deleted edge with the old type information
10051009
EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping, this::isTypeEdge);
10061010
String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge());
10071011
ObjectFieldArgumentTypeModification objectFieldArgumentTypeModification = new ObjectFieldArgumentTypeModification(field.getName(), argument.getName(), oldType, newType);
10081012
getObjectModification(object.getName()).getDetails().add(objectFieldArgumentTypeModification);
1013+
1014+
String oldDefaultValue = getDefaultValueFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge());
1015+
String newDefaultValue = getDefaultValueFromEdgeLabel(editOperation.getTargetEdge());
1016+
if (!oldDefaultValue.equals(newDefaultValue)) {
1017+
getObjectModification(object.getName()).getDetails().add(new ObjectFieldArgumentDefaultValueModification(field.getName(), argument.getName(), oldDefaultValue, newDefaultValue));
1018+
}
10091019
} else {
10101020
assertTrue(objectOrInterface.isOfType(SchemaGraph.INTERFACE));
10111021
Vertex interfaze = objectOrInterface;
1022+
10121023
// if the whole object is new we are done
10131024
if (isInterfaceAdded(interfaze.getName())) {
10141025
return;
@@ -1021,34 +1032,49 @@ private void typeEdgeInsertedForArgument(EditOperation
10211032
if (isArgumentNewForExistingInterfaceField(interfaze.getName(), field.getName(), argument.getName())) {
10221033
return;
10231034
}
1035+
10241036
String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge());
10251037
// this means we have an existing object changed its type
10261038
// and there must be a deleted edge with the old type information
10271039
EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping, this::isTypeEdge);
10281040
String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge());
10291041
InterfaceFieldArgumentTypeModification interfaceFieldArgumentTypeModification = new InterfaceFieldArgumentTypeModification(field.getName(), argument.getName(), oldType, newType);
10301042
getInterfaceModification(interfaze.getName()).getDetails().add(interfaceFieldArgumentTypeModification);
1043+
1044+
String oldDefaultValue = getDefaultValueFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge());
1045+
String newDefaultValue = getDefaultValueFromEdgeLabel(editOperation.getTargetEdge());
1046+
if (!oldDefaultValue.equals(newDefaultValue)) {
1047+
getInterfaceModification(interfaze.getName()).getDetails().add(new InterfaceFieldArgumentDefaultValueModification(field.getName(), argument.getName(), oldDefaultValue, newDefaultValue));
1048+
}
10311049
}
10321050
} else {
10331051
assertTrue(fieldOrDirective.isOfType(SchemaGraph.DIRECTIVE));
10341052
Vertex directive = fieldOrDirective;
1053+
10351054
if (isDirectiveAdded(directive.getName())) {
10361055
return;
10371056
}
10381057
if (isArgumentNewForExistingDirective(directive.getName(), argument.getName())) {
10391058
return;
10401059
}
1060+
10411061
String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge());
10421062
EditOperation deletedTypeEdgeOperation = findDeletedEdge(argument, editOperations, mapping, this::isTypeEdge);
10431063
String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge());
10441064
DirectiveArgumentTypeModification directiveArgumentTypeModification = new DirectiveArgumentTypeModification(argument.getName(), oldType, newType);
10451065
getDirectiveModification(directive.getName()).getDetails().add(directiveArgumentTypeModification);
1046-
}
10471066

1067+
String oldDefaultValue = getDefaultValueFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge());
1068+
String newDefaultValue = getDefaultValueFromEdgeLabel(editOperation.getTargetEdge());
1069+
if (!oldDefaultValue.equals(newDefaultValue)) {
1070+
getDirectiveModification(directive.getName()).getDetails().add(new DirectiveArgumentDefaultValueModification(argument.getName(), oldDefaultValue, newDefaultValue));
1071+
}
1072+
}
10481073
}
10491074

1050-
private void typeEdgeInsertedForField(EditOperation
1051-
editOperation, List<EditOperation> editOperations, Mapping mapping) {
1075+
private void typeEdgeInsertedForField(EditOperation editOperation,
1076+
List<EditOperation> editOperations,
1077+
Mapping mapping) {
10521078
Vertex field = editOperation.getTargetEdge().getFrom();
10531079
Vertex objectOrInterface = newSchemaGraph.getFieldsContainerForField(field);
10541080
if (objectOrInterface.isOfType(SchemaGraph.OBJECT)) {

src/test/groovy/graphql/schema/diffing/ana/EditOperationAnalyzerTest.groovy

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2442,6 +2442,121 @@ class EditOperationAnalyzerTest extends Specification {
24422442
argumentTypeModification[0].newType == "[String]"
24432443
}
24442444

2445+
2446+
def "object field argument type and default value changed"() {
2447+
given:
2448+
def oldSdl = '''
2449+
type Query {
2450+
echo(message: String! = "Hello World"): String
2451+
}
2452+
'''
2453+
def newSdl = '''
2454+
type Query {
2455+
echo(message: ID! = "1"): String
2456+
}
2457+
'''
2458+
2459+
when:
2460+
def changes = calcDiff(oldSdl, newSdl)
2461+
2462+
then:
2463+
changes.objectDifferences["Query"] instanceof ObjectModification
2464+
def queryChanges = changes.objectDifferences["Query"] as ObjectModification
2465+
queryChanges.details.size() == 2
2466+
2467+
def argumentTypeModification = queryChanges.getDetails(ObjectFieldArgumentTypeModification)
2468+
argumentTypeModification.size() == 1
2469+
argumentTypeModification[0].fieldName == "echo"
2470+
argumentTypeModification[0].argumentName == "message"
2471+
argumentTypeModification[0].oldType == "String!"
2472+
argumentTypeModification[0].newType == "ID!"
2473+
2474+
def defaultValueModification = queryChanges.getDetails(ObjectFieldArgumentDefaultValueModification)
2475+
defaultValueModification.size() == 1
2476+
defaultValueModification[0].fieldName == "echo"
2477+
defaultValueModification[0].argumentName == "message"
2478+
defaultValueModification[0].oldValue == '"Hello World"'
2479+
defaultValueModification[0].newValue == '"1"'
2480+
}
2481+
2482+
def "interface field argument type and default value changed"() {
2483+
given:
2484+
def oldSdl = '''
2485+
type Query {
2486+
echo: EchoProvider
2487+
}
2488+
interface EchoProvider {
2489+
send(message: String! = "Hello World"): String
2490+
}
2491+
'''
2492+
def newSdl = '''
2493+
type Query {
2494+
echo: EchoProvider
2495+
}
2496+
interface EchoProvider {
2497+
send(message: ID! = "1"): String
2498+
}
2499+
'''
2500+
2501+
when:
2502+
def changes = calcDiff(oldSdl, newSdl)
2503+
2504+
then:
2505+
changes.interfaceDifferences["EchoProvider"] instanceof InterfaceModification
2506+
def echoProviderChanges = changes.interfaceDifferences["EchoProvider"] as InterfaceModification
2507+
echoProviderChanges.details.size() == 2
2508+
2509+
def argumentTypeModification = echoProviderChanges.getDetails(InterfaceFieldArgumentTypeModification)
2510+
argumentTypeModification.size() == 1
2511+
argumentTypeModification[0].fieldName == "send"
2512+
argumentTypeModification[0].argumentName == "message"
2513+
argumentTypeModification[0].oldType == "String!"
2514+
argumentTypeModification[0].newType == "ID!"
2515+
2516+
def defaultValueModification = echoProviderChanges.getDetails(InterfaceFieldArgumentDefaultValueModification)
2517+
defaultValueModification.size() == 1
2518+
defaultValueModification[0].fieldName == "send"
2519+
defaultValueModification[0].argumentName == "message"
2520+
defaultValueModification[0].oldValue == '"Hello World"'
2521+
defaultValueModification[0].newValue == '"1"'
2522+
}
2523+
2524+
def "directive argument type and default value changed"() {
2525+
given:
2526+
def oldSdl = '''
2527+
directive @deleteBy(date: String = "+1 week") on FIELD_DEFINITION
2528+
type Query {
2529+
echo: String @deleteBy
2530+
}
2531+
'''
2532+
def newSdl = '''
2533+
directive @deleteBy(date: Int = 1000) on FIELD_DEFINITION
2534+
type Query {
2535+
echo: String @deleteBy
2536+
}
2537+
'''
2538+
2539+
when:
2540+
def changes = calcDiff(oldSdl, newSdl)
2541+
2542+
then:
2543+
changes.directiveDifferences["deleteBy"] instanceof DirectiveModification
2544+
def deleteByChanges = changes.directiveDifferences["deleteBy"] as DirectiveModification
2545+
deleteByChanges.details.size() == 2
2546+
2547+
def argumentTypeModification = deleteByChanges.getDetails(DirectiveArgumentTypeModification)
2548+
argumentTypeModification.size() == 1
2549+
argumentTypeModification[0].argumentName == "date"
2550+
argumentTypeModification[0].oldType == "String"
2551+
argumentTypeModification[0].newType == "Int"
2552+
2553+
def defaultValueModification = deleteByChanges.getDetails(DirectiveArgumentDefaultValueModification)
2554+
defaultValueModification.size() == 1
2555+
defaultValueModification[0].argumentName == "date"
2556+
defaultValueModification[0].oldValue == '"+1 week"'
2557+
defaultValueModification[0].newValue == '1000'
2558+
}
2559+
24452560
EditOperationAnalysisResult calcDiff(
24462561
String oldSdl,
24472562
String newSdl

0 commit comments

Comments
 (0)