Skip to content

Commit

Permalink
Merge pull request #30 from danalms/master
Browse files Browse the repository at this point in the history
Fix model array change detect and detect produces/consumes changes
  • Loading branch information
Sayi authored Jun 29, 2020
2 parents 109c0ea + a03bcac commit 0d15c25
Show file tree
Hide file tree
Showing 11 changed files with 420 additions and 47 deletions.
83 changes: 73 additions & 10 deletions src/main/java/com/deepoove/swagger/diff/compare/ModelDiff.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@

import com.deepoove.swagger.diff.model.ElProperty;

import io.swagger.models.ArrayModel;
import io.swagger.models.Model;
import io.swagger.models.RefModel;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.RefProperty;
import io.swagger.models.properties.StringProperty;

/**
* compare two model
Expand Down Expand Up @@ -51,12 +55,18 @@ public ModelDiff diff(Model leftModel, Model rightModel, String parentEl) {
return this.diff(leftModel, rightModel, parentEl, new HashSet<Model>());
}

private ModelDiff diff(Model leftModel, Model rightModel, String parentEl, Set<Model> visited) {
public ModelDiff diff(Property leftProperty, Property rightProperty) {
return this.diff(findModel(leftProperty, oldDedinitions), findModel(rightProperty, newDedinitions));
}

private ModelDiff diff(Model leftInputModel, Model rightInputModel, String parentEl, Set<Model> visited) {
// Stop recursing if both models are null
// OR either model is already contained in the visiting history
if ((null == leftModel && null == rightModel) || visited.contains(leftModel) || visited.contains(rightModel)) {
if ((null == leftInputModel && null == rightInputModel) || visited.contains(leftInputModel) || visited.contains(rightInputModel)) {
return this;
}
Model leftModel = isModelReference(leftInputModel) ? findReferenceModel(leftInputModel, oldDedinitions) : leftInputModel;
Model rightModel = isModelReference(rightInputModel) ? findReferenceModel(rightInputModel, newDedinitions) : rightInputModel;
Map<String, Property> leftProperties = null == leftModel ? null : leftModel.getProperties();
Map<String, Property> rightProperties = null == rightModel ? null : rightModel.getProperties();

Expand All @@ -71,19 +81,16 @@ private ModelDiff diff(Model leftModel, Model rightModel, String parentEl, Set<M
sharedKey.stream().forEach((key) -> {
Property left = leftProperties.get(key);
Property right = rightProperties.get(key);

if ((left instanceof RefProperty) && (right instanceof RefProperty)) {
String leftRef = ((RefProperty) left).getSimpleRef();
String rightRef = ((RefProperty) right).getSimpleRef();

diff(oldDedinitions.get(leftRef), newDedinitions.get(rightRef),
Model leftSubModel = findModel(left, oldDedinitions);
Model rightSubModel = findModel(left, newDedinitions);
if (leftSubModel != null || rightSubModel != null) {
diff(leftSubModel, rightSubModel,
buildElString(parentEl, key),
copyAndAdd(visited, leftModel, rightModel));

} else if (left != null && right != null && !left.equals(right)) {
// Add a changed ElProperty if not a Reference
// Useless
changed.add(convert2ElProperty(key, parentEl, left));
changed.add(addChangeMetadata(convert2ElProperty(key, parentEl, left), left, right));
}
});
return this;
Expand Down Expand Up @@ -113,13 +120,69 @@ private ElProperty convert2ElProperty(String propName, String parentEl, Property
return pWithPath;
}

private ElProperty addChangeMetadata(ElProperty diffProperty, Property left, Property right) {
diffProperty.setTypeChange(!left.getType().equalsIgnoreCase(right.getType()));
List<String> leftEnums = enumValues(left);
List<String> rightEnums = enumValues(right);
if (!leftEnums.isEmpty() && !rightEnums.isEmpty()) {
ListDiff<String> enumDiff = ListDiff.diff(leftEnums, rightEnums, (t, enumVal) -> {
for (String value : t) {
if (enumVal.equalsIgnoreCase(value)) { return value; }
}
return null;
});
diffProperty.setNewEnums(enumDiff.getIncreased() != null && ! enumDiff.getIncreased().isEmpty());
diffProperty.setRemovedEnums(enumDiff.getMissing() != null && ! enumDiff.getMissing().isEmpty());
}
return diffProperty;
}

@SuppressWarnings("unchecked")
private <T> Set<T> copyAndAdd(Set<T> set, T... add) {
Set<T> newSet = new HashSet<T>(set);
newSet.addAll(Arrays.asList(add));
return newSet;
}

private List<String> enumValues(Property prop) {
if (prop instanceof StringProperty && ((StringProperty) prop).getEnum() != null) {
return ((StringProperty) prop).getEnum();
} else {
return new ArrayList<>();
}
}

private Model findModel(Property property, Map<String, Model> modelMap) {
String modelName = null;
if (property instanceof RefProperty){
modelName = ((RefProperty) property).getSimpleRef();
} else if (property instanceof ArrayProperty) {
Property arrayType = ((ArrayProperty) property).getItems();
if (arrayType instanceof RefProperty) {
modelName = ((RefProperty) arrayType).getSimpleRef();
}
}
return modelName == null ? null : modelMap.get(modelName);
}

private boolean isModelReference(Model model) {
return model instanceof RefModel || model instanceof ArrayModel;
}

private Model findReferenceModel(Model model, Map<String, Model> modelMap) {
String modelName = null;
if (model instanceof RefModel){
modelName = ((RefModel) model).getSimpleRef();
} else if (model instanceof ArrayModel) {
Property arrayType = ((ArrayModel) model).getItems();
if (arrayType instanceof RefProperty) {
modelName = ((RefProperty) arrayType).getSimpleRef();
}
}
return modelName == null ? null : modelMap.get(modelName);
}


public List<ElProperty> getIncreased() {
return increased;
}
Expand Down
20 changes: 6 additions & 14 deletions src/main/java/com/deepoove/swagger/diff/compare/ParameterDiff.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.deepoove.swagger.diff.model.ChangedParameter;

import io.swagger.models.Model;
import io.swagger.models.RefModel;
import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.Parameter;

Expand Down Expand Up @@ -65,19 +64,12 @@ public ParameterDiff diff(List<Parameter> left, List<Parameter> right) {
BodyParameter leftBodyPara = (BodyParameter) leftPara;
Model leftSchema = leftBodyPara.getSchema();
BodyParameter rightBodyPara = (BodyParameter) rightPara;
Model rightSchema = rightBodyPara.getSchema();
if (leftSchema instanceof RefModel && rightSchema instanceof RefModel) {
String leftRef = ((RefModel) leftSchema).getSimpleRef();
String rightRef = ((RefModel) rightSchema).getSimpleRef();
Model leftModel = oldDedinitions.get(leftRef);
Model rightModel = newDedinitions.get(rightRef);

ModelDiff diff = ModelDiff.buildWithDefinition(oldDedinitions, newDedinitions)
.diff(leftModel, rightModel, leftPara.getName());
changedParameter.setIncreased(diff.getIncreased());
changedParameter.setMissing(diff.getMissing());
changedParameter.setChanged(diff.getChanged());
}
Model rightSchema = rightBodyPara.getSchema();
ModelDiff diff = ModelDiff.buildWithDefinition(oldDedinitions, newDedinitions)
.diff(leftSchema, rightSchema, leftPara.getName());
changedParameter.setIncreased(diff.getIncreased());
changedParameter.setMissing(diff.getMissing());
changedParameter.setChanged(diff.getChanged());
}

// is requried
Expand Down
17 changes: 6 additions & 11 deletions src/main/java/com/deepoove/swagger/diff/compare/PropertyDiff.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import io.swagger.models.Model;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.RefProperty;

public class PropertyDiff {

Expand All @@ -34,16 +33,12 @@ public static PropertyDiff buildWithDefinition(Map<String, Model> left,
}

public PropertyDiff diff(Property left, Property right) {
if ((null == left || left instanceof RefProperty) && (null == right || right instanceof RefProperty)) {
Model leftModel = null == left ? null : oldDedinitions.get(((RefProperty) left).getSimpleRef());
Model rightModel = null == right ? null : newDedinitions.get(((RefProperty) right).getSimpleRef());
ModelDiff diff = ModelDiff
.buildWithDefinition(oldDedinitions, newDedinitions)
.diff(leftModel, rightModel);
increased.addAll(diff.getIncreased());
missing.addAll(diff.getMissing());
changed.addAll(diff.getChanged());
}
ModelDiff diff = ModelDiff
.buildWithDefinition(oldDedinitions, newDedinitions)
.diff(left, right);
increased.addAll(diff.getIncreased());
missing.addAll(diff.getMissing());
changed.addAll(diff.getChanged());
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ public static SpecificationDiff diff(Swagger oldSpec, Swagger newSpec) {
changedOperation.setMissingProps(propertyDiff.getMissing());
changedOperation.setChangedProps(propertyDiff.getChanged());

// Diff Consumes
ListDiff<String> consumeDiff = getMediaTypeDiff(oldOperation.getConsumes(), newOperation.getConsumes());
changedOperation.setAddConsumes(consumeDiff.getIncreased());
changedOperation.setMissingConsumes(consumeDiff.getMissing());

// Diff Produces
ListDiff<String> producesDiff = getMediaTypeDiff(oldOperation.getProduces(), newOperation.getProduces());
changedOperation.setAddProduces(producesDiff.getIncreased());
changedOperation.setMissingProduces(producesDiff.getMissing());

if (changedOperation.isDiff()) {
operas.put(method, changedOperation);
}
Expand Down Expand Up @@ -151,6 +161,15 @@ private static Collection<? extends Endpoint> convert2EndpointList(String pathUr
return endpoints;
}

private static ListDiff<String> getMediaTypeDiff(List<String> oldTypes, List<String> newTypes) {
return ListDiff.diff(oldTypes, newTypes, (t, sample) -> {
for (String mediaType : t) {
if (sample.equalsIgnoreCase(mediaType)) { return mediaType; }
}
return null;
});
}

public List<Endpoint> getNewEndpoints() {
return newEndpoints;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ public class ChangedOperation implements Changed {
private List<ElProperty> addProps = new ArrayList<ElProperty>();
private List<ElProperty> missingProps = new ArrayList<ElProperty>();
private List<ElProperty> changedProps = new ArrayList<ElProperty>();
private List<String> addConsumes = new ArrayList<>();
private List<String> missingConsumes = new ArrayList<>();
private List<String> addProduces = new ArrayList<>();
private List<String> missingProduces = new ArrayList<>();

public List<Parameter> getAddParameters() {
return addParameters;
Expand Down Expand Up @@ -76,7 +80,7 @@ public void setSummary(String summary) {

public boolean isDiff() {
return !addParameters.isEmpty() || !missingParameters.isEmpty()
|| !changedParameter.isEmpty() || isDiffProp();
|| !changedParameter.isEmpty() || isDiffProp() || isDiffConsumes() || isDiffProduces();
}
public boolean isDiffProp(){
return !addProps.isEmpty()
Expand All @@ -87,4 +91,44 @@ public boolean isDiffParam(){
return !addParameters.isEmpty() || !missingParameters.isEmpty()
|| !changedParameter.isEmpty();
}

public boolean isDiffConsumes(){
return !addConsumes.isEmpty() || !missingConsumes.isEmpty();
}

public boolean isDiffProduces(){
return !addProduces.isEmpty() || !missingProduces.isEmpty();
}

public List<String> getAddConsumes() {
return this.addConsumes;
}

public void setAddConsumes(List<String> increased) {
this.addConsumes = increased == null ? new ArrayList<>() : increased;
}

public List<String> getMissingConsumes() {
return this.missingConsumes;
}

public void setMissingConsumes(List<String> missing) {
this.missingConsumes = missing == null ? new ArrayList<>() : missing;
}

public List<String> getAddProduces() {
return this.addProduces;
}

public void setAddProduces(List<String> increased) {
this.addProduces = increased == null ? new ArrayList<>() : increased;
}

public List<String> getMissingProduces() {
return this.missingProduces;
}

public void setMissingProduces(List<String> missing) {
this.missingProduces = missing == null ? new ArrayList<>() : missing;
}
}
28 changes: 28 additions & 0 deletions src/main/java/com/deepoove/swagger/diff/model/ElProperty.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ public class ElProperty {

private Property property;

// optional change metadata
private boolean isTypeChange;
private boolean newEnums;
private boolean removedEnums;

public Property getProperty() {
return property;
}
Expand All @@ -29,4 +34,27 @@ public void setEl(String el) {
this.el = el;
}

public boolean isTypeChange() {
return isTypeChange;
}

public void setTypeChange(boolean typeChange) {
isTypeChange = typeChange;
}

public boolean isNewEnums() {
return newEnums;
}

public void setNewEnums(boolean newEnums) {
this.newEnums = newEnums;
}

public boolean isRemovedEnums() {
return removedEnums;
}

public void setRemovedEnums(boolean removedEnums) {
this.removedEnums = removedEnums;
}
}
Loading

0 comments on commit 0d15c25

Please sign in to comment.