Skip to content

Detect changed numeric ranges #469

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ public DeferredChanged<ChangedOperation> diff(
}

ParametersDiffResult parametersDiffResult =
openApiDiff.getParametersDiff().diff(oldOperation.getParameters(), newOperation.getParameters(), context);
openApiDiff
.getParametersDiff()
.diff(oldOperation.getParameters(), newOperation.getParameters(), context);
builder
.with(parametersDiffResult.deferredChanged)
.ifPresent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ class ParametersDiffResult {
protected DeferredChanged<ChangedParameters> deferredChanged;
protected boolean sameOperationsDiffSchema;

public ParametersDiffResult(DeferredChanged<ChangedParameters> deferredChanged, boolean sameOperationsDiffSchema) {
public ParametersDiffResult(
DeferredChanged<ChangedParameters> deferredChanged, boolean sameOperationsDiffSchema) {
this.deferredChanged = deferredChanged;
this.sameOperationsDiffSchema = sameOperationsDiffSchema;
}
Expand Down Expand Up @@ -57,7 +58,8 @@ public static boolean same(Parameter left, Parameter right) {
&& Objects.equals(left.getIn(), right.getIn());
}

public ParametersDiffResult diff(List<Parameter> left, List<Parameter> right, DiffContext context) {
public ParametersDiffResult diff(
List<Parameter> left, List<Parameter> right, DiffContext context) {
DeferredBuilder<Changed> builder = new DeferredBuilder<>();
ChangedParameters changedParameters =
new ChangedParameters(left, right != null ? new ArrayList<>(right) : null, context);
Expand All @@ -80,9 +82,8 @@ public ParametersDiffResult diff(List<Parameter> left, List<Parameter> right, Di
}
changedParameters.getIncreased().addAll(right);
return new ParametersDiffResult(
builder.buildIsChanged(changedParameters),
pathUnchangedParametersChanged(changedParameters, context)
);
builder.buildIsChanged(changedParameters),
pathUnchangedParametersChanged(changedParameters, context));
}

public boolean pathUnchangedParametersChanged(
Expand All @@ -93,7 +94,8 @@ public boolean pathUnchangedParametersChanged(
return false;
// Go through each missing Parameter and compare it to newly added Parameters
for (Parameter parameter : changedParameters.getMissing()) {
// Speedy Check. Use the map already created in changedParameters to check if missing param is linked to newParam
// Speedy Check. Use the map already created in changedParameters to check if missing param is
// linked to newParam
String newParameterName = context.getParameters().get(parameter.getName());
if (newParameterName.isEmpty()) return false;

Expand All @@ -107,7 +109,8 @@ public boolean pathUnchangedParametersChanged(
Parameter newParameterRealized = newParameter.get();
newParameterRealized.setName(parameter.getName()); // Make names similar
boolean samePathDifferentParameter = !newParameterRealized.equals(parameter);
newParameterRealized.setName(newParameterName); // Important:: MUST Reset the name as this is not a copy
newParameterRealized.setName(
newParameterName); // Important:: MUST Reset the name as this is not a copy
return samePathDifferentParameter;
}
return false;
Expand All @@ -119,10 +122,11 @@ public boolean pathUnchanged(ChangedParameters changedParameters, DiffContext co
String newUrl = context.getRightUrl();
ArrayList<String> oldUrlPathParams = matchedItems(oldUrl, REGEX_PATH);
ArrayList<String> newUrlPathParams = matchedItems(newUrl, REGEX_PATH);
// Path Param count doesn't match or param-less path doesn't match or param is changed --> It's a new endpoint
// Path Param count doesn't match or param-less path doesn't match or param is changed --> It's
// a new endpoint
return oldUrlPathParams.size() == newUrlPathParams.size()
&& changedParameters.getChanged().isEmpty()
&& oldUrl.replaceAll(REGEX_PATH, "").equals(newUrl.replaceAll(REGEX_PATH, ""));
&& changedParameters.getChanged().isEmpty()
&& oldUrl.replaceAll(REGEX_PATH, "").equals(newUrl.replaceAll(REGEX_PATH, ""));
}

public ArrayList<String> matchedItems(String string, String regex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ public DeferredChanged<ChangedPath> diff(PathItem left, PathItem right, DiffCont
.with(
openApiDiff
.getOperationDiff()
.diff(oldOperation, newOperation,
context.copyWithMethod(method).copyWithLeftRightUrls(
context.getLeftUrl(),
context.getRightUrl()
)
)
).ifPresent(changedPath.getChanged()::add);
.diff(
oldOperation,
newOperation,
context
.copyWithMethod(method)
.copyWithLeftRightUrls(context.getLeftUrl(), context.getRightUrl())))
.ifPresent(changedPath.getChanged()::add);
}
builder
.with(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,18 @@ public <V extends Schema<X>, X> DeferredChanged<ChangedSchema> diff(
.setChangeFormat(!Objects.equals(left.getFormat(), right.getFormat()))
.setReadOnly(new ChangedReadOnly(left.getReadOnly(), right.getReadOnly(), context))
.setWriteOnly(new ChangedWriteOnly(left.getWriteOnly(), right.getWriteOnly(), context))
.setMaxLength(new ChangedMaxLength(left.getMaxLength(), right.getMaxLength(), context));
.setMaxLength(new ChangedMaxLength(left.getMaxLength(), right.getMaxLength(), context))
.setNumericRange(
new ChangedNumericRange(
left.getMinimum(),
right.getMinimum(),
left.getMaximum(),
right.getMaximum(),
left.getExclusiveMinimum(),
right.getExclusiveMinimum(),
left.getExclusiveMaximum(),
right.getExclusiveMaximum(),
context));
builder
.with(
openApiDiff
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.stream.Stream;
import org.openapitools.openapidiff.core.model.schema.ChangedEnum;
import org.openapitools.openapidiff.core.model.schema.ChangedMaxLength;
import org.openapitools.openapidiff.core.model.schema.ChangedNumericRange;
import org.openapitools.openapidiff.core.model.schema.ChangedReadOnly;
import org.openapitools.openapidiff.core.model.schema.ChangedRequired;
import org.openapitools.openapidiff.core.model.schema.ChangedWriteOnly;
Expand All @@ -30,6 +31,7 @@ public class ChangedSchema implements ComposedChanged {
protected ChangedWriteOnly writeOnly;
protected boolean changedType;
protected ChangedMaxLength maxLength;
protected ChangedNumericRange numericRange;
protected boolean discriminatorPropertyChanged;
protected ChangedSchema items;
protected ChangedOneOfSchema oneOfSchema;
Expand Down Expand Up @@ -109,6 +111,7 @@ public List<Changed> getChangedElements() {
enumeration,
required,
maxLength,
numericRange,
extensions))
.collect(Collectors.toList());
}
Expand Down Expand Up @@ -356,6 +359,12 @@ public ChangedSchema setMaxLength(final ChangedMaxLength maxLength) {
return this;
}

public ChangedSchema setNumericRange(final ChangedNumericRange numericRange) {
clearChangedCache();
this.numericRange = numericRange;
return this;
}

public ChangedSchema setDiscriminatorPropertyChanged(final boolean discriminatorPropertyChanged) {
clearChangedCache();
this.discriminatorPropertyChanged = discriminatorPropertyChanged;
Expand Down Expand Up @@ -410,6 +419,7 @@ public boolean equals(Object o) {
&& Objects.equals(readOnly, that.readOnly)
&& Objects.equals(writeOnly, that.writeOnly)
&& Objects.equals(maxLength, that.maxLength)
&& Objects.equals(numericRange, that.numericRange)
&& Objects.equals(items, that.items)
&& Objects.equals(oneOfSchema, that.oneOfSchema)
&& Objects.equals(addProp, that.addProp)
Expand Down Expand Up @@ -437,6 +447,7 @@ public int hashCode() {
writeOnly,
changedType,
maxLength,
numericRange,
discriminatorPropertyChanged,
items,
oneOfSchema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,13 @@ public DiffContext setLeftAndRightUrls(String leftUrl, String rightUrl) {
return this;
}

public String getLeftUrl() { return this.leftUrl; }
public String getLeftUrl() {
return this.leftUrl;
}

public String getRightUrl() { return this.rightUrl; }
public String getRightUrl() {
return this.rightUrl;
}

@Override
public boolean equals(Object o) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package org.openapitools.openapidiff.core.model.schema;

import java.math.BigDecimal;
import java.util.Objects;
import org.openapitools.openapidiff.core.model.Changed;
import org.openapitools.openapidiff.core.model.DiffContext;
import org.openapitools.openapidiff.core.model.DiffResult;

public final class ChangedNumericRange implements Changed {
private final BigDecimal oldMinimumValue;
private final BigDecimal newMinimumValue;
private final BigDecimal oldMaximumValue;
private final BigDecimal newMaximumValue;
private final Boolean oldMinimumExclusiveValue;
private final Boolean newMinimumExclusiveValue;
private final Boolean oldMaximumExclusiveValue;
private final Boolean newMaximumExclusiveValue;
private final DiffContext context;

@Override
public DiffResult isChanged() {
if (Objects.equals(oldMinimumValue, newMinimumValue)
&& Objects.equals(oldMaximumValue, newMaximumValue)
&& Objects.equals(oldMinimumExclusiveValue, newMinimumExclusiveValue)
&& Objects.equals(oldMaximumExclusiveValue, newMaximumExclusiveValue)) {
return DiffResult.NO_CHANGES;
}
if (context.isRequest()
&& (newMinimumValue == null
|| oldMinimumValue != null
&& oldMinimumValue.unscaledValue().compareTo(newMinimumValue.unscaledValue())
>= 0)
&& (newMaximumValue == null
|| oldMaximumValue != null
&& oldMaximumValue.unscaledValue().compareTo(newMaximumValue.unscaledValue())
<= 0)
&& (newMinimumExclusiveValue == null
|| oldMinimumExclusiveValue != null && newMinimumExclusiveValue == true)
&& (newMaximumExclusiveValue == null
|| oldMaximumExclusiveValue != null && newMaximumExclusiveValue == true)
|| context.isResponse()
&& (newMinimumValue == null
|| oldMinimumValue != null
&& oldMinimumValue.unscaledValue().compareTo(newMinimumValue.unscaledValue())
>= 0)
&& (newMaximumValue == null
|| oldMaximumValue != null
&& oldMaximumValue.unscaledValue().compareTo(newMaximumValue.unscaledValue())
<= 0)
&& (newMinimumExclusiveValue == null
|| oldMinimumExclusiveValue != null && newMinimumExclusiveValue == true)
&& (newMaximumExclusiveValue == null
|| oldMaximumExclusiveValue != null && newMaximumExclusiveValue == true)) {
return DiffResult.COMPATIBLE;
}
return DiffResult.INCOMPATIBLE;
}

public ChangedNumericRange(
final BigDecimal oldMinimumValue,
final BigDecimal newMinimumValue,
final BigDecimal oldMaximumValue,
final BigDecimal newMaximumValue,
final Boolean oldMinimumExclusiveValue,
final Boolean newMinimumExclusiveValue,
final Boolean oldMaximumExclusiveValue,
final Boolean newMaximumExclusiveValue,
final DiffContext context) {
this.oldMinimumValue = oldMinimumValue;
this.newMinimumValue = newMinimumValue;
this.oldMaximumValue = oldMaximumValue;
this.newMaximumValue = newMaximumValue;
this.oldMinimumExclusiveValue = oldMinimumExclusiveValue;
this.newMinimumExclusiveValue = newMinimumExclusiveValue;
this.oldMaximumExclusiveValue = oldMaximumExclusiveValue;
this.newMaximumExclusiveValue = newMaximumExclusiveValue;
this.context = context;
}

public BigDecimal getOldMinimumValue() {
return oldMinimumValue;
}

public BigDecimal getNewMinimumValue() {
return newMinimumValue;
}

public BigDecimal getOldMaximumValue() {
return oldMaximumValue;
}

public BigDecimal getNewMaximumValue() {
return newMaximumValue;
}

public Boolean getOldMinimumExclusiveValue() {
return oldMinimumExclusiveValue;
}

public Boolean getNewMinimumExclusiveValue() {
return newMinimumExclusiveValue;
}

public Boolean getOldMaximumExclusiveValue() {
return oldMaximumExclusiveValue;
}

public Boolean getNewMaximumExclusiveValue() {
return newMaximumExclusiveValue;
}

public DiffContext getContext() {
return this.context;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ChangedNumericRange that = (ChangedNumericRange) o;
return Objects.equals(oldMinimumValue, newMinimumValue)
&& Objects.equals(oldMaximumValue, newMaximumValue)
&& Objects.equals(oldMinimumExclusiveValue, newMinimumExclusiveValue)
&& Objects.equals(oldMaximumExclusiveValue, newMaximumExclusiveValue)
&& Objects.equals(context, that.context);
}

@Override
public int hashCode() {
return Objects.hash(
oldMinimumValue,
newMinimumValue,
oldMaximumValue,
newMaximumValue,
oldMinimumExclusiveValue,
newMinimumExclusiveValue,
oldMaximumExclusiveValue,
newMaximumExclusiveValue,
context);
}

@Override
public String toString() {
return "ChangedNumericRange("
+ "oldMinimumValue="
+ oldMinimumValue
+ ", newMinimumValue="
+ newMinimumValue
+ ", oldMaximumValue="
+ oldMaximumValue
+ ", newMaximumValue="
+ newMaximumValue
+ ", oldMinimumExclusiveValue="
+ oldMinimumExclusiveValue
+ ", newMinimumExclusiveValue="
+ newMinimumExclusiveValue
+ ", oldMaximumExclusiveValue="
+ oldMaximumExclusiveValue
+ ", newMaximumExclusiveValue="
+ newMaximumExclusiveValue
+ ", context="
+ context
+ ')';
}
}
Loading