Skip to content

Commit

Permalink
Check for default value changes when argument type changes
Browse files Browse the repository at this point in the history
  • Loading branch information
gnawf committed Mar 31, 2023
1 parent 8bb6464 commit 532042e
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -960,8 +960,9 @@ private void typeEdgeInserted(EditOperation editOperation, List<EditOperation> e

}

private void typeEdgeInsertedForInputField(EditOperation
editOperation, List<EditOperation> editOperations, Mapping mapping) {
private void typeEdgeInsertedForInputField(EditOperation editOperation,
List<EditOperation> editOperations,
Mapping mapping) {
Vertex inputField = editOperation.getTargetEdge().getFrom();
Vertex inputObject = newSchemaGraph.getInputObjectForInputField(inputField);
if (isInputObjectAdded(inputObject.getName())) {
Expand All @@ -977,8 +978,9 @@ private void typeEdgeInsertedForInputField(EditOperation
getInputObjectModification(inputObject.getName()).getDetails().add(inputObjectFieldTypeModification);
}

private void typeEdgeInsertedForArgument(EditOperation
editOperation, List<EditOperation> editOperations, Mapping mapping) {
private void typeEdgeInsertedForArgument(EditOperation editOperation,
List<EditOperation> editOperations,
Mapping mapping) {
Vertex argument = editOperation.getTargetEdge().getFrom();
Vertex fieldOrDirective = newSchemaGraph.getFieldOrDirectiveForArgument(argument);
if (fieldOrDirective.isOfType(SchemaGraph.FIELD)) {
Expand All @@ -987,6 +989,7 @@ private void typeEdgeInsertedForArgument(EditOperation

if (objectOrInterface.isOfType(SchemaGraph.OBJECT)) {
Vertex object = objectOrInterface;

// if the whole object is new we are done
if (isObjectAdded(object.getName())) {
return;
Expand All @@ -999,16 +1002,24 @@ private void typeEdgeInsertedForArgument(EditOperation
if (isArgumentNewForExistingObjectField(object.getName(), field.getName(), argument.getName())) {
return;
}

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, this::isTypeEdge);
String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge());
ObjectFieldArgumentTypeModification objectFieldArgumentTypeModification = new ObjectFieldArgumentTypeModification(field.getName(), argument.getName(), oldType, newType);
getObjectModification(object.getName()).getDetails().add(objectFieldArgumentTypeModification);

String oldDefaultValue = getDefaultValueFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge());
String newDefaultValue = getDefaultValueFromEdgeLabel(editOperation.getTargetEdge());
if (!oldDefaultValue.equals(newDefaultValue)) {
getObjectModification(object.getName()).getDetails().add(new ObjectFieldArgumentDefaultValueModification(field.getName(), argument.getName(), oldDefaultValue, newDefaultValue));
}
} else {
assertTrue(objectOrInterface.isOfType(SchemaGraph.INTERFACE));
Vertex interfaze = objectOrInterface;

// if the whole object is new we are done
if (isInterfaceAdded(interfaze.getName())) {
return;
Expand All @@ -1021,34 +1032,49 @@ private void typeEdgeInsertedForArgument(EditOperation
if (isArgumentNewForExistingInterfaceField(interfaze.getName(), field.getName(), argument.getName())) {
return;
}

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, this::isTypeEdge);
String oldType = getTypeFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge());
InterfaceFieldArgumentTypeModification interfaceFieldArgumentTypeModification = new InterfaceFieldArgumentTypeModification(field.getName(), argument.getName(), oldType, newType);
getInterfaceModification(interfaze.getName()).getDetails().add(interfaceFieldArgumentTypeModification);

String oldDefaultValue = getDefaultValueFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge());
String newDefaultValue = getDefaultValueFromEdgeLabel(editOperation.getTargetEdge());
if (!oldDefaultValue.equals(newDefaultValue)) {
getInterfaceModification(interfaze.getName()).getDetails().add(new InterfaceFieldArgumentDefaultValueModification(field.getName(), argument.getName(), oldDefaultValue, newDefaultValue));
}
}
} else {
assertTrue(fieldOrDirective.isOfType(SchemaGraph.DIRECTIVE));
Vertex directive = fieldOrDirective;

if (isDirectiveAdded(directive.getName())) {
return;
}
if (isArgumentNewForExistingDirective(directive.getName(), argument.getName())) {
return;
}

String newType = getTypeFromEdgeLabel(editOperation.getTargetEdge());
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);
}

String oldDefaultValue = getDefaultValueFromEdgeLabel(deletedTypeEdgeOperation.getSourceEdge());
String newDefaultValue = getDefaultValueFromEdgeLabel(editOperation.getTargetEdge());
if (!oldDefaultValue.equals(newDefaultValue)) {
getDirectiveModification(directive.getName()).getDetails().add(new DirectiveArgumentDefaultValueModification(argument.getName(), oldDefaultValue, newDefaultValue));
}
}
}

private void typeEdgeInsertedForField(EditOperation
editOperation, List<EditOperation> editOperations, Mapping mapping) {
private void typeEdgeInsertedForField(EditOperation editOperation,
List<EditOperation> editOperations,
Mapping mapping) {
Vertex field = editOperation.getTargetEdge().getFrom();
Vertex objectOrInterface = newSchemaGraph.getFieldsContainerForField(field);
if (objectOrInterface.isOfType(SchemaGraph.OBJECT)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2442,6 +2442,121 @@ class EditOperationAnalyzerTest extends Specification {
argumentTypeModification[0].newType == "[String]"
}


def "object field argument type and default value changed"() {
given:
def oldSdl = '''
type Query {
echo(message: String! = "Hello World"): String
}
'''
def newSdl = '''
type Query {
echo(message: ID! = "1"): String
}
'''

when:
def changes = calcDiff(oldSdl, newSdl)

then:
changes.objectDifferences["Query"] instanceof ObjectModification
def queryChanges = changes.objectDifferences["Query"] as ObjectModification
queryChanges.details.size() == 2

def argumentTypeModification = queryChanges.getDetails(ObjectFieldArgumentTypeModification)
argumentTypeModification.size() == 1
argumentTypeModification[0].fieldName == "echo"
argumentTypeModification[0].argumentName == "message"
argumentTypeModification[0].oldType == "String!"
argumentTypeModification[0].newType == "ID!"

def defaultValueModification = queryChanges.getDetails(ObjectFieldArgumentDefaultValueModification)
defaultValueModification.size() == 1
defaultValueModification[0].fieldName == "echo"
defaultValueModification[0].argumentName == "message"
defaultValueModification[0].oldValue == '"Hello World"'
defaultValueModification[0].newValue == '"1"'
}

def "interface field argument type and default value changed"() {
given:
def oldSdl = '''
type Query {
echo: EchoProvider
}
interface EchoProvider {
send(message: String! = "Hello World"): String
}
'''
def newSdl = '''
type Query {
echo: EchoProvider
}
interface EchoProvider {
send(message: ID! = "1"): String
}
'''

when:
def changes = calcDiff(oldSdl, newSdl)

then:
changes.interfaceDifferences["EchoProvider"] instanceof InterfaceModification
def echoProviderChanges = changes.interfaceDifferences["EchoProvider"] as InterfaceModification
echoProviderChanges.details.size() == 2

def argumentTypeModification = echoProviderChanges.getDetails(InterfaceFieldArgumentTypeModification)
argumentTypeModification.size() == 1
argumentTypeModification[0].fieldName == "send"
argumentTypeModification[0].argumentName == "message"
argumentTypeModification[0].oldType == "String!"
argumentTypeModification[0].newType == "ID!"

def defaultValueModification = echoProviderChanges.getDetails(InterfaceFieldArgumentDefaultValueModification)
defaultValueModification.size() == 1
defaultValueModification[0].fieldName == "send"
defaultValueModification[0].argumentName == "message"
defaultValueModification[0].oldValue == '"Hello World"'
defaultValueModification[0].newValue == '"1"'
}

def "directive argument type and default value changed"() {
given:
def oldSdl = '''
directive @deleteBy(date: String = "+1 week") on FIELD_DEFINITION
type Query {
echo: String @deleteBy
}
'''
def newSdl = '''
directive @deleteBy(date: Int = 1000) on FIELD_DEFINITION
type Query {
echo: String @deleteBy
}
'''

when:
def changes = calcDiff(oldSdl, newSdl)

then:
changes.directiveDifferences["deleteBy"] instanceof DirectiveModification
def deleteByChanges = changes.directiveDifferences["deleteBy"] as DirectiveModification
deleteByChanges.details.size() == 2

def argumentTypeModification = deleteByChanges.getDetails(DirectiveArgumentTypeModification)
argumentTypeModification.size() == 1
argumentTypeModification[0].argumentName == "date"
argumentTypeModification[0].oldType == "String"
argumentTypeModification[0].newType == "Int"

def defaultValueModification = deleteByChanges.getDetails(DirectiveArgumentDefaultValueModification)
defaultValueModification.size() == 1
defaultValueModification[0].argumentName == "date"
defaultValueModification[0].oldValue == '"+1 week"'
defaultValueModification[0].newValue == '1000'
}

EditOperationAnalysisResult calcDiff(
String oldSdl,
String newSdl
Expand Down

0 comments on commit 532042e

Please sign in to comment.