Skip to content

Changes on 'minItems' and 'maxItems' not detected #753

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 3 commits into from
Feb 27, 2025
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 @@ -19,6 +19,8 @@
import org.openapitools.openapidiff.core.model.deferred.DeferredChanged;
import org.openapitools.openapidiff.core.model.deferred.RecursiveSchemaSet;
import org.openapitools.openapidiff.core.model.schema.*;
import org.openapitools.openapidiff.core.model.schema.ChangedMaxItems;
import org.openapitools.openapidiff.core.model.schema.ChangedMinItems;

public class SchemaDiffResult {
protected ChangedSchema changedSchema;
Expand Down Expand Up @@ -74,7 +76,9 @@ public <V extends Schema<X>, X> DeferredChanged<ChangedSchema> diff(
.setMultipleOf(new ChangedMultipleOf(left.getMultipleOf(), right.getMultipleOf()))
.setNullable(new ChangedNullable(left.getNullable(), right.getNullable()))
.setExamples(new ChangedExamples(left.getExamples(), right.getExamples()))
.setExample(new ChangedExample(left.getExample(), right.getExample()));
.setExample(new ChangedExample(left.getExample(), right.getExample()))
.setMaxItems(new ChangedMaxItems(left.getMaxItems(), right.getMaxItems(), context))
.setMinItems(new ChangedMinItems(left.getMinItems(), right.getMinItems(), context));
builder
.with(
openApiDiff
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.openapitools.openapidiff.core.model.schema.ChangedEnum;
import org.openapitools.openapidiff.core.model.schema.ChangedMaxItems;
import org.openapitools.openapidiff.core.model.schema.ChangedMaxLength;
import org.openapitools.openapidiff.core.model.schema.ChangedMinItems;
import org.openapitools.openapidiff.core.model.schema.ChangedMultipleOf;
import org.openapitools.openapidiff.core.model.schema.ChangedNullable;
import org.openapitools.openapidiff.core.model.schema.ChangedNumericRange;
Expand Down Expand Up @@ -41,6 +43,8 @@ public class ChangedSchema implements ComposedChanged {
protected ChangedMaxLength maxLength;
protected ChangedNumericRange numericRange;
protected ChangedMultipleOf multipleOf;
protected ChangedMaxItems maxItems;
protected ChangedMinItems minItems;
protected ChangedNullable nullable;
protected boolean discriminatorPropertyChanged;
protected ChangedSchema items;
Expand Down Expand Up @@ -125,6 +129,8 @@ public List<Changed> getChangedElements() {
maxLength,
numericRange,
multipleOf,
maxItems,
minItems,
nullable,
extensions))
.collect(Collectors.toList());
Expand Down Expand Up @@ -289,6 +295,14 @@ public ChangedMultipleOf getMultipleOf() {
return this.multipleOf;
}

public ChangedMaxItems getMaxItems() {
return this.maxItems;
}

public ChangedMinItems getMinItems() {
return this.minItems;
}

public ChangedNullable getNullable() {
return this.nullable;
}
Expand Down Expand Up @@ -441,6 +455,18 @@ public ChangedSchema setMultipleOf(final ChangedMultipleOf multipleOf) {
return this;
}

public ChangedSchema setMaxItems(final ChangedMaxItems maxItems) {
clearChangedCache();
this.maxItems = maxItems;
return this;
}

public ChangedSchema setMinItems(final ChangedMinItems minItems) {
clearChangedCache();
this.minItems = minItems;
return this;
}

public ChangedSchema setNullable(final ChangedNullable nullable) {
clearChangedCache();
this.nullable = nullable;
Expand Down Expand Up @@ -505,6 +531,8 @@ public boolean equals(Object o) {
&& Objects.equals(maxLength, that.maxLength)
&& Objects.equals(numericRange, that.numericRange)
&& Objects.equals(multipleOf, that.multipleOf)
&& Objects.equals(maxItems, that.maxItems)
&& Objects.equals(minItems, that.minItems)
&& Objects.equals(nullable, that.nullable)
&& Objects.equals(items, that.items)
&& Objects.equals(oneOfSchema, that.oneOfSchema)
Expand Down Expand Up @@ -537,6 +565,8 @@ public int hashCode() {
maxLength,
numericRange,
multipleOf,
maxItems,
minItems,
nullable,
discriminatorPropertyChanged,
items,
Expand Down Expand Up @@ -591,6 +621,10 @@ public java.lang.String toString() {
+ this.getNumericRange()
+ ", multipleOf="
+ this.getMultipleOf()
+ ", maxItems="
+ this.getMaxItems()
+ ", minItems="
+ this.getMinItems()
+ ", nullable="
+ this.getNullable()
+ ", discriminatorPropertyChanged="
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.openapitools.openapidiff.core.model.schema;

import org.openapitools.openapidiff.core.model.Changed;
import org.openapitools.openapidiff.core.model.DiffContext;
import org.openapitools.openapidiff.core.model.DiffResult;

public class ChangedMaxItems implements Changed {
private final Integer oldValue;
private final Integer newValue;
private final DiffContext context;

public ChangedMaxItems(Integer oldValue, Integer newValue, DiffContext context) {
this.oldValue = oldValue;
this.newValue = newValue;
this.context = context;
}

@Override
public DiffResult isChanged() {
if (oldValue == null && newValue == null) {
return DiffResult.NO_CHANGES;
}
if (oldValue == null || newValue == null) {
return DiffResult.COMPATIBLE;
}
if (newValue < oldValue) {
return DiffResult.INCOMPATIBLE;
}
return DiffResult.COMPATIBLE;
}

public Integer getOldValue() {
return oldValue;
}

public Integer getNewValue() {
return newValue;
}

public DiffContext getContext() {
return context;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.openapitools.openapidiff.core.model.schema;

import org.openapitools.openapidiff.core.model.Changed;
import org.openapitools.openapidiff.core.model.DiffContext;
import org.openapitools.openapidiff.core.model.DiffResult;

public class ChangedMinItems implements Changed {
private final Integer oldValue;
private final Integer newValue;
private final DiffContext context;

public ChangedMinItems(Integer oldValue, Integer newValue, DiffContext context) {
this.oldValue = oldValue;
this.newValue = newValue;
this.context = context;
}

@Override
public DiffResult isChanged() {
if (oldValue == null && newValue == null) {
return DiffResult.NO_CHANGES;
}
if (oldValue == null || newValue == null) {
return DiffResult.COMPATIBLE;
}
if (newValue > oldValue) {
return DiffResult.INCOMPATIBLE;
}
return DiffResult.COMPATIBLE;
}

public Integer getOldValue() {
return oldValue;
}

public Integer getNewValue() {
return newValue;
}

public DiffContext getContext() {
return context;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,41 @@ public void changeMultipleOfHandling() {
assertThat(props.get("field4").getMultipleOf().getRight()).isNull();
}

@Test // issues #480
public void changeMinMaxItemsHandling() {
ChangedOpenApi changedOpenApi =
OpenApiCompare.fromLocations(
"schemaDiff/schema-min-max-items-diff-1.yaml",
"schemaDiff/schema-min-max-items-diff-2.yaml");
ChangedSchema changedSchema =
getRequestBodyChangedSchema(
changedOpenApi, POST, "/schema/array/items", "application/json");

assertThat(changedSchema).isNotNull();
Map<String, ChangedSchema> props = changedSchema.getChangedProperties();
assertThat(props).isNotEmpty();

// Check increasing of minItems
assertThat(props.get("field1").getMinItems().isIncompatible()).isTrue();
assertThat(props.get("field1").getMinItems().getOldValue()).isEqualTo(1);
assertThat(props.get("field1").getMinItems().getNewValue()).isEqualTo(2);

// Check decreasing of minItems
assertThat(props.get("field2").getMinItems().isCompatible()).isTrue();
assertThat(props.get("field2").getMinItems().getOldValue()).isEqualTo(20);
assertThat(props.get("field2").getMinItems().getNewValue()).isEqualTo(10);

// Check increasing of maxItems
assertThat(props.get("field3").getMaxItems().isCompatible()).isTrue();
assertThat(props.get("field3").getMaxItems().getOldValue()).isEqualTo(90);
assertThat(props.get("field3").getMaxItems().getNewValue()).isEqualTo(100);

// Check decreasing of maxItems
assertThat(props.get("field4").getMaxItems().isIncompatible()).isTrue();
assertThat(props.get("field4").getMaxItems().getOldValue()).isEqualTo(100);
assertThat(props.get("field4").getMaxItems().getNewValue()).isEqualTo(90);
}

@Test // issue #482
public void changeNullabeHandling() {
ChangedOpenApi changedOpenApi =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
openapi: 3.1.0
info:
description: Schema diff
title: schema diff
version: 1.0.0
paths:
/schema/array/items:
post:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/TestDTO'
components:
schemas:
TestDTO:
type: object
properties:
field1:
type: array
items:
type: string
minItems: 1
maxItems: 100
field2:
type: array
items:
type: string
minItems: 20
maxItems: 100
field3:
type: array
items:
type: string
minItems: 1
maxItems: 90
field4:
type: array
items:
type: string
minItems: 1
maxItems: 100
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
openapi: 3.1.0
info:
description: Schema diff
title: schema diff
version: 1.0.0
paths:
/schema/array/items:
post:
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/TestDTO'
components:
schemas:
TestDTO:
type: object
properties:
field1:
type: array
items:
type: string
minItems: 2
maxItems: 100
field2:
type: array
items:
type: string
minItems: 10
maxItems: 100
field3:
type: array
items:
type: string
minItems: 1
maxItems: 100
field4:
type: array
items:
type: string
minItems: 1
maxItems: 90