Skip to content

Commit 95d4c0b

Browse files
authored
Add support for 'uniqueItems' schema diff detection (#758)
1 parent 1701963 commit 95d4c0b

File tree

6 files changed

+177
-1
lines changed

6 files changed

+177
-1
lines changed

core/src/main/java/org/openapitools/openapidiff/core/compare/schemadiffresult/SchemaDiffResult.java

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public <V extends Schema<X>, X> DeferredChanged<ChangedSchema> diff(
7575
context))
7676
.setMultipleOf(new ChangedMultipleOf(left.getMultipleOf(), right.getMultipleOf()))
7777
.setNullable(new ChangedNullable(left.getNullable(), right.getNullable()))
78+
.setUniqueItems(new ChangedUniqueItems(left.getUniqueItems(), right.getUniqueItems()))
7879
.setExamples(new ChangedExamples(left.getExamples(), right.getExamples()))
7980
.setExample(new ChangedExample(left.getExample(), right.getExample()))
8081
.setMaxItems(new ChangedMaxItems(left.getMaxItems(), right.getMaxItems(), context))

core/src/main/java/org/openapitools/openapidiff/core/model/ChangedSchema.java

+17
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.openapitools.openapidiff.core.model.schema.ChangedOneOfSchema;
2121
import org.openapitools.openapidiff.core.model.schema.ChangedReadOnly;
2222
import org.openapitools.openapidiff.core.model.schema.ChangedRequired;
23+
import org.openapitools.openapidiff.core.model.schema.ChangedUniqueItems;
2324
import org.openapitools.openapidiff.core.model.schema.ChangedWriteOnly;
2425

2526
public class ChangedSchema implements ComposedChanged {
@@ -50,6 +51,7 @@ public class ChangedSchema implements ComposedChanged {
5051
protected ChangedMaxProperties maxProperties;
5152
protected ChangedMinProperties minProperties;
5253
protected ChangedNullable nullable;
54+
protected ChangedUniqueItems uniqueItems;
5355
protected boolean discriminatorPropertyChanged;
5456
protected ChangedSchema items;
5557
protected ChangedOneOfSchema oneOfSchema;
@@ -138,6 +140,7 @@ public List<Changed> getChangedElements() {
138140
maxProperties,
139141
minProperties,
140142
nullable,
143+
uniqueItems,
141144
extensions))
142145
.collect(Collectors.toList());
143146
}
@@ -313,6 +316,10 @@ public ChangedNullable getNullable() {
313316
return this.nullable;
314317
}
315318

319+
public ChangedUniqueItems getUniqueItems() {
320+
return uniqueItems;
321+
}
322+
316323
public boolean isDiscriminatorPropertyChanged() {
317324
return this.discriminatorPropertyChanged;
318325
}
@@ -487,6 +494,12 @@ public ChangedSchema setNullable(final ChangedNullable nullable) {
487494
return this;
488495
}
489496

497+
public ChangedSchema setUniqueItems(ChangedUniqueItems uniqueItems) {
498+
clearChangedCache();
499+
this.uniqueItems = uniqueItems;
500+
return this;
501+
}
502+
490503
public ChangedSchema setDiscriminatorPropertyChanged(final boolean discriminatorPropertyChanged) {
491504
clearChangedCache();
492505
this.discriminatorPropertyChanged = discriminatorPropertyChanged;
@@ -560,6 +573,7 @@ public boolean equals(Object o) {
560573
&& Objects.equals(maxItems, that.maxItems)
561574
&& Objects.equals(minItems, that.minItems)
562575
&& Objects.equals(nullable, that.nullable)
576+
&& Objects.equals(uniqueItems, that.uniqueItems)
563577
&& Objects.equals(items, that.items)
564578
&& Objects.equals(oneOfSchema, that.oneOfSchema)
565579
&& Objects.equals(addProp, that.addProp)
@@ -596,6 +610,7 @@ public int hashCode() {
596610
maxItems,
597611
minItems,
598612
nullable,
613+
uniqueItems,
599614
discriminatorPropertyChanged,
600615
items,
601616
oneOfSchema,
@@ -657,6 +672,8 @@ public java.lang.String toString() {
657672
+ this.getMinItems()
658673
+ ", nullable="
659674
+ this.getNullable()
675+
+ ", uniqueItems="
676+
+ this.getUniqueItems()
660677
+ ", discriminatorPropertyChanged="
661678
+ this.isDiscriminatorPropertyChanged()
662679
+ ", items="
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package org.openapitools.openapidiff.core.model.schema;
2+
3+
import java.util.Objects;
4+
import org.openapitools.openapidiff.core.model.Changed;
5+
import org.openapitools.openapidiff.core.model.DiffResult;
6+
7+
public class ChangedUniqueItems implements Changed {
8+
9+
private final Boolean left;
10+
private final Boolean right;
11+
12+
public ChangedUniqueItems(Boolean leftNullable, Boolean rightNullable) {
13+
this.left = leftNullable;
14+
this.right = rightNullable;
15+
}
16+
17+
@Override
18+
public DiffResult isChanged() {
19+
boolean leftValue = left != null && left;
20+
boolean rightValue = right != null && right;
21+
22+
if (leftValue == false && rightValue == true) {
23+
return DiffResult.INCOMPATIBLE;
24+
}
25+
26+
if (leftValue == true && rightValue == false) {
27+
return DiffResult.COMPATIBLE;
28+
}
29+
30+
return DiffResult.NO_CHANGES;
31+
}
32+
33+
public Boolean getLeft() {
34+
return left;
35+
}
36+
37+
public Boolean getRight() {
38+
return right;
39+
}
40+
41+
@Override
42+
public String toString() {
43+
return "ChangedUniqueItems [left=" + left + ", right=" + right + "]";
44+
}
45+
46+
@Override
47+
public boolean equals(Object o) {
48+
if (this == o) return true;
49+
if (o == null || getClass() != o.getClass()) return false;
50+
ChangedNullable that = (ChangedNullable) o;
51+
return Objects.equals(left, that.getLeft()) && Objects.equals(right, that.getRight());
52+
}
53+
54+
@Override
55+
public int hashCode() {
56+
return Objects.hash(left, right);
57+
}
58+
}

core/src/test/java/org/openapitools/openapidiff/core/SchemaDiffTest.java

+39-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ public void changeMinMaxItemsHandling() {
171171
}
172172

173173
@Test // issue #482
174-
public void changeNullabeHandling() {
174+
public void changeNullableHandling() {
175175
ChangedOpenApi changedOpenApi =
176176
OpenApiCompare.fromLocations(
177177
"schemaDiff/schema-nullable-diff-1.yaml", "schemaDiff/schema-nullable-diff-2.yaml");
@@ -201,6 +201,44 @@ public void changeNullabeHandling() {
201201
assertThat(props.get("field3").getNullable().getRight()).isTrue();
202202
}
203203

204+
@Test // issue #478
205+
public void changeUniqueItemsHandling() {
206+
ChangedOpenApi changedOpenApi =
207+
OpenApiCompare.fromLocations(
208+
"schemaDiff/schema-uniqueItems-diff-1.yaml",
209+
"schemaDiff/schema-uniqueItems-diff-2.yaml");
210+
ChangedSchema changedSchema =
211+
getRequestBodyChangedSchema(
212+
changedOpenApi, POST, "/schema/uniqueItems", "application/json");
213+
214+
assertThat(changedSchema).isNotNull();
215+
Map<String, ChangedSchema> props = changedSchema.getChangedProperties();
216+
assertThat(props).isNotEmpty();
217+
218+
// Check no changes in uniqueItems
219+
assertThat(props.get("field0")).isNull();
220+
221+
// Check changes true -> false
222+
assertThat(props.get("field1").getUniqueItems().isCompatible()).isTrue();
223+
assertThat(props.get("field1").getUniqueItems().getLeft()).isTrue();
224+
assertThat(props.get("field1").getUniqueItems().getRight()).isFalse();
225+
226+
// Check changes false -> true
227+
assertThat(props.get("field2").getUniqueItems().isIncompatible()).isTrue();
228+
assertThat(props.get("field2").getUniqueItems().getLeft()).isFalse();
229+
assertThat(props.get("field2").getUniqueItems().getRight()).isTrue();
230+
231+
// Check deletion of uniqueItems
232+
assertThat(props.get("field3").getUniqueItems().isCompatible()).isTrue();
233+
assertThat(props.get("field3").getUniqueItems().getLeft()).isTrue();
234+
assertThat(props.get("field3").getUniqueItems().getRight()).isNull();
235+
236+
// Check addition of uniqueItems
237+
assertThat(props.get("field4").getUniqueItems().isIncompatible()).isTrue();
238+
assertThat(props.get("field4").getUniqueItems().getLeft()).isNull();
239+
assertThat(props.get("field4").getUniqueItems().getRight()).isTrue();
240+
}
241+
204242
@Test // issue #479
205243
public void changeMinMaxPropertiesHandling() {
206244
ChangedOpenApi changedOpenApi =
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
openapi: 3.0.1
2+
info:
3+
description: Schema diff uniqueItems
4+
title: schema diff uniqueItems
5+
version: 1.0.0
6+
paths:
7+
/schema/uniqueItems:
8+
post:
9+
requestBody:
10+
content:
11+
application/json:
12+
schema:
13+
$ref: '#/components/schemas/TestDTO'
14+
components:
15+
schemas:
16+
TestDTO:
17+
type: object
18+
properties:
19+
field0:
20+
type: integer
21+
field1:
22+
type: integer
23+
uniqueItems: true
24+
field2:
25+
type: integer
26+
uniqueItems: false
27+
field3:
28+
type: integer
29+
uniqueItems: true
30+
field4:
31+
type: integer
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
openapi: 3.0.1
2+
info:
3+
description: Schema diff uniqueItems
4+
title: schema diff uniqueItems
5+
version: 1.0.0
6+
paths:
7+
/schema/uniqueItems:
8+
post:
9+
requestBody:
10+
content:
11+
application/json:
12+
schema:
13+
$ref: '#/components/schemas/TestDTO'
14+
components:
15+
schemas:
16+
TestDTO:
17+
type: object
18+
properties:
19+
field0:
20+
type: integer
21+
field1:
22+
type: integer
23+
uniqueItems: false
24+
field2:
25+
type: integer
26+
uniqueItems: true
27+
field3:
28+
type: integer
29+
field4:
30+
type: integer
31+
uniqueItems: true

0 commit comments

Comments
 (0)