From 1ca09b2db00d365754fffbf7de135883e8cd9954 Mon Sep 17 00:00:00 2001 From: Aliaksandr Pinchuk Date: Fri, 18 Apr 2025 11:18:59 +0200 Subject: [PATCH] Doesn't take pattern field into account Fixes #104 --- .../schemadiffresult/SchemaDiffResult.java | 5 ++ .../openapidiff/core/model/ChangedSchema.java | 23 ++++++++- .../core/model/schema/ChangedPattern.java | 47 +++++++++++++++++++ .../openapidiff/core/SchemaDiffTest.java | 36 ++++++++++++++ .../schemaDiff/schema-pattern-diff-1.yaml | 24 ++++++++++ .../schemaDiff/schema-pattern-diff-2.yaml | 24 ++++++++++ 6 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/org/openapitools/openapidiff/core/model/schema/ChangedPattern.java create mode 100644 core/src/test/resources/schemaDiff/schema-pattern-diff-1.yaml create mode 100644 core/src/test/resources/schemaDiff/schema-pattern-diff-2.yaml diff --git a/core/src/main/java/org/openapitools/openapidiff/core/compare/schemadiffresult/SchemaDiffResult.java b/core/src/main/java/org/openapitools/openapidiff/core/compare/schemadiffresult/SchemaDiffResult.java index 32cb5bee..dd3c8ab3 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/compare/schemadiffresult/SchemaDiffResult.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/compare/schemadiffresult/SchemaDiffResult.java @@ -21,6 +21,10 @@ import org.openapitools.openapidiff.core.model.schema.*; import org.openapitools.openapidiff.core.model.schema.ChangedMaxItems; import org.openapitools.openapidiff.core.model.schema.ChangedMinItems; +import org.openapitools.openapidiff.core.model.schema.ChangedPattern; +import org.openapitools.openapidiff.core.model.schema.ChangedReadOnly; +import org.openapitools.openapidiff.core.model.schema.ChangedRequired; +import org.openapitools.openapidiff.core.model.schema.ChangedUniqueItems; public class SchemaDiffResult { protected ChangedSchema changedSchema; @@ -75,6 +79,7 @@ public , X> DeferredChanged diff( context)) .setMultipleOf(new ChangedMultipleOf(left.getMultipleOf(), right.getMultipleOf())) .setNullable(new ChangedNullable(left.getNullable(), right.getNullable())) + .setPattern(new ChangedPattern(left.getPattern(), right.getPattern(), context)) .setUniqueItems(new ChangedUniqueItems(left.getUniqueItems(), right.getUniqueItems())) .setExamples(new ChangedExamples(left.getExamples(), right.getExamples())) .setExample(new ChangedExample(left.getExample(), right.getExample())) diff --git a/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedSchema.java b/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedSchema.java index 3779ee85..1896783a 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedSchema.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedSchema.java @@ -5,7 +5,11 @@ import static org.openapitools.openapidiff.core.model.BackwardIncompatibleProp.SCHEMA_TYPE_CHANGED; import io.swagger.v3.oas.models.media.Schema; -import java.util.*; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; import org.openapitools.openapidiff.core.model.schema.ChangedEnum; @@ -18,6 +22,7 @@ import org.openapitools.openapidiff.core.model.schema.ChangedNullable; import org.openapitools.openapidiff.core.model.schema.ChangedNumericRange; import org.openapitools.openapidiff.core.model.schema.ChangedOneOfSchema; +import org.openapitools.openapidiff.core.model.schema.ChangedPattern; import org.openapitools.openapidiff.core.model.schema.ChangedReadOnly; import org.openapitools.openapidiff.core.model.schema.ChangedRequired; import org.openapitools.openapidiff.core.model.schema.ChangedUniqueItems; @@ -53,6 +58,7 @@ public class ChangedSchema implements ComposedChanged { protected ChangedNullable nullable; protected ChangedUniqueItems uniqueItems; protected boolean discriminatorPropertyChanged; + protected ChangedPattern pattern; protected ChangedSchema items; protected ChangedOneOfSchema oneOfSchema; protected ChangedSchema addProp; @@ -141,6 +147,7 @@ public List getChangedElements() { minProperties, nullable, uniqueItems, + pattern, extensions)) .collect(Collectors.toList()); } @@ -320,6 +327,10 @@ public ChangedUniqueItems getUniqueItems() { return uniqueItems; } + public ChangedPattern getPattern() { + return pattern; + } + public boolean isDiscriminatorPropertyChanged() { return this.discriminatorPropertyChanged; } @@ -500,6 +511,12 @@ public ChangedSchema setUniqueItems(ChangedUniqueItems uniqueItems) { return this; } + public ChangedSchema setPattern(ChangedPattern pattern) { + clearChangedCache(); + this.pattern = pattern; + return this; + } + public ChangedSchema setDiscriminatorPropertyChanged(final boolean discriminatorPropertyChanged) { clearChangedCache(); this.discriminatorPropertyChanged = discriminatorPropertyChanged; @@ -579,6 +596,7 @@ public boolean equals(Object o) { && Objects.equals(addProp, that.addProp) && Objects.equals(extensions, that.extensions) && Objects.equals(maxProperties, that.maxProperties) + && Objects.equals(pattern, that.pattern) && Objects.equals(minProperties, that.minProperties); } @@ -617,6 +635,7 @@ public int hashCode() { addProp, extensions, maxProperties, + pattern, minProperties); } @@ -688,6 +707,8 @@ public java.lang.String toString() { + this.getMaxProperties() + ", minProperties=" + this.getMinProperties() + + ", pattern=" + + this.getPattern() + ")"; } } diff --git a/core/src/main/java/org/openapitools/openapidiff/core/model/schema/ChangedPattern.java b/core/src/main/java/org/openapitools/openapidiff/core/model/schema/ChangedPattern.java new file mode 100644 index 00000000..06907cd2 --- /dev/null +++ b/core/src/main/java/org/openapitools/openapidiff/core/model/schema/ChangedPattern.java @@ -0,0 +1,47 @@ +package org.openapitools.openapidiff.core.model.schema; + +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 class ChangedPattern implements Changed { + private final String oldPattern; + private final String newPattern; + private final DiffContext context; + + public ChangedPattern(String oldPattern, String newPattern, DiffContext context) { + this.oldPattern = oldPattern; + this.newPattern = newPattern; + this.context = context; + } + + @Override + public DiffResult isChanged() { + return Objects.equals(oldPattern, newPattern) ? DiffResult.NO_CHANGES : DiffResult.INCOMPATIBLE; + } + + @Override + public boolean isCompatible() { + return Objects.equals(oldPattern, newPattern); + } + + public DiffResult isDiffBackwardCompatible() { + if (!Objects.equals(oldPattern, newPattern)) { + return DiffResult.INCOMPATIBLE; + } + return DiffResult.COMPATIBLE; + } + + public String getOldPattern() { + return oldPattern; + } + + public String getNewPattern() { + return newPattern; + } + + public DiffContext getContext() { + return context; + } +} diff --git a/core/src/test/java/org/openapitools/openapidiff/core/SchemaDiffTest.java b/core/src/test/java/org/openapitools/openapidiff/core/SchemaDiffTest.java index f57729e3..f034dabe 100644 --- a/core/src/test/java/org/openapitools/openapidiff/core/SchemaDiffTest.java +++ b/core/src/test/java/org/openapitools/openapidiff/core/SchemaDiffTest.java @@ -317,4 +317,40 @@ public void requiredPropertyChangedTest() { // Verify breaking changes in response - removing required properties is breaking assertThat(responseRequired.isItemsChanged()).isEqualTo(DiffResult.INCOMPATIBLE); } + + @Test // issue #104 + public void changePatternHandling() { + ChangedOpenApi changedOpenApi = + OpenApiCompare.fromLocations( + "schemaDiff/schema-pattern-diff-1.yaml", "schemaDiff/schema-pattern-diff-2.yaml"); + ChangedSchema changedSchema = + getRequestBodyChangedSchema(changedOpenApi, POST, "/schema/pattern", "application/json"); + + assertThat(changedSchema).isNotNull(); + Map props = changedSchema.getChangedProperties(); + assertThat(props).isNotEmpty(); + + // Check no changes in pattern + assertThat(props.get("patternUnchanged")).isNull(); + + // Check changes in pattern (modification) + assertThat(props.get("patternModified").getPattern().isChanged()) + .isEqualTo(DiffResult.INCOMPATIBLE); + assertThat(props.get("patternModified").getPattern().getOldPattern()).isEqualTo("^[a-z]+$"); + assertThat(props.get("patternModified").getPattern().getNewPattern()).isEqualTo("^[a-zA-Z]+$"); + + // Check deletion of pattern + assertThat(props.get("patternRemoved").getPattern().isChanged()) + .isEqualTo(DiffResult.INCOMPATIBLE); + assertThat(props.get("patternRemoved").getPattern().getOldPattern()).isEqualTo("^[0-9]+$"); + assertThat(props.get("patternRemoved").getPattern().getNewPattern()).isNull(); + + // Check addition of pattern + assertThat(props.get("patternAdded").getPattern().isChanged()) + .isEqualTo(DiffResult.INCOMPATIBLE); + assertThat(props.get("patternAdded").getPattern().getOldPattern()).isNull(); + // Adjust assertion to expect single backslashes as parsed from YAML + assertThat(props.get("patternAdded").getPattern().getNewPattern()) + .isEqualTo("^\\d{3}-\\d{2}-\\d{4}$?"); + } } diff --git a/core/src/test/resources/schemaDiff/schema-pattern-diff-1.yaml b/core/src/test/resources/schemaDiff/schema-pattern-diff-1.yaml new file mode 100644 index 00000000..909ac8fa --- /dev/null +++ b/core/src/test/resources/schemaDiff/schema-pattern-diff-1.yaml @@ -0,0 +1,24 @@ +openapi: 3.0.0 +info: + title: Schema Pattern Diff Test - Old + version: 1.0.0 +paths: + /schema/pattern: + post: + requestBody: + content: + application/json: + schema: + type: object + properties: + patternUnchanged: + type: string + pattern: "^[a-z]+$" + patternModified: + type: string + pattern: "^[a-z]+$" + patternRemoved: + type: string + pattern: "^[0-9]+$" + patternAdded: + type: string diff --git a/core/src/test/resources/schemaDiff/schema-pattern-diff-2.yaml b/core/src/test/resources/schemaDiff/schema-pattern-diff-2.yaml new file mode 100644 index 00000000..05ee63f3 --- /dev/null +++ b/core/src/test/resources/schemaDiff/schema-pattern-diff-2.yaml @@ -0,0 +1,24 @@ +openapi: 3.0.0 +info: + title: Schema Pattern Diff Test - New + version: 1.0.0 +paths: + /schema/pattern: + post: + requestBody: + content: + application/json: + schema: + type: object + properties: + patternUnchanged: + type: string + pattern: "^[a-z]+$" + patternModified: + type: string + pattern: "^[a-zA-Z]+$" + patternRemoved: + type: string + patternAdded: + type: string + pattern: "^\\d{3}-\\d{2}-\\d{4}$?"