diff --git a/core/src/main/java/org/openapitools/openapidiff/core/compare/ContentDiff.java b/core/src/main/java/org/openapitools/openapidiff/core/compare/ContentDiff.java index b647172db..7cf27dca7 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/compare/ContentDiff.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/compare/ContentDiff.java @@ -5,7 +5,9 @@ import io.swagger.v3.oas.models.media.Content; import io.swagger.v3.oas.models.media.MediaType; -import java.util.*; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import org.openapitools.openapidiff.core.model.Changed; import org.openapitools.openapidiff.core.model.ChangedContent; import org.openapitools.openapidiff.core.model.ChangedMediaType; @@ -34,22 +36,15 @@ public DeferredChanged diff(Content left, Content right, DiffCon MediaType oldMediaType = left.get(mediaTypeKey); MediaType newMediaType = right.get(mediaTypeKey); - ChangedMediaType changedMediaType = - new ChangedMediaType(oldMediaType.getSchema(), newMediaType.getSchema(), context); - builder .with( openApiDiff - .getSchemaDiff() - .diff( - oldMediaType.getSchema(), - newMediaType.getSchema(), - context.copyWithRequired(true))) + .getMediaTypeDiff() + .diff(oldMediaType, newMediaType, context.copyWithRequired(true))) .ifPresent( value -> { - changedMediaType.setSchema(value); - if (!isUnchanged(changedMediaType)) { - changedMediaTypes.put(mediaTypeKey, changedMediaType); + if (!isUnchanged(value)) { + changedMediaTypes.put(mediaTypeKey, value); } }); }); diff --git a/core/src/main/java/org/openapitools/openapidiff/core/compare/HeaderDiff.java b/core/src/main/java/org/openapitools/openapidiff/core/compare/HeaderDiff.java index ecdfd5878..0f71c4963 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/compare/HeaderDiff.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/compare/HeaderDiff.java @@ -6,6 +6,8 @@ import java.util.Objects; import java.util.Optional; import org.openapitools.openapidiff.core.model.Changed; +import org.openapitools.openapidiff.core.model.ChangedExample; +import org.openapitools.openapidiff.core.model.ChangedExamples; import org.openapitools.openapidiff.core.model.ChangedHeader; import org.openapitools.openapidiff.core.model.DiffContext; import org.openapitools.openapidiff.core.model.deferred.DeferredBuilder; @@ -49,7 +51,9 @@ protected DeferredChanged computeDiff( !Boolean.TRUE.equals(left.getDeprecated()) && Boolean.TRUE.equals(right.getDeprecated())) .setStyle(!Objects.equals(left.getStyle(), right.getStyle())) - .setExplode(getBooleanDiff(left.getExplode(), right.getExplode())); + .setExplode(getBooleanDiff(left.getExplode(), right.getExplode())) + .setExamples(new ChangedExamples(left.getExamples(), right.getExamples())) + .setExample(new ChangedExample(left.getExample(), right.getExample())); builder .with( openApiDiff diff --git a/core/src/main/java/org/openapitools/openapidiff/core/compare/MediaTypeDiff.java b/core/src/main/java/org/openapitools/openapidiff/core/compare/MediaTypeDiff.java new file mode 100644 index 000000000..a80324a92 --- /dev/null +++ b/core/src/main/java/org/openapitools/openapidiff/core/compare/MediaTypeDiff.java @@ -0,0 +1,40 @@ +package org.openapitools.openapidiff.core.compare; + +import static org.openapitools.openapidiff.core.utils.ChangedUtils.isChanged; + +import io.swagger.v3.oas.models.media.MediaType; +import org.openapitools.openapidiff.core.model.Changed; +import org.openapitools.openapidiff.core.model.ChangedExample; +import org.openapitools.openapidiff.core.model.ChangedExamples; +import org.openapitools.openapidiff.core.model.ChangedMediaType; +import org.openapitools.openapidiff.core.model.DiffContext; +import org.openapitools.openapidiff.core.model.deferred.DeferredBuilder; +import org.openapitools.openapidiff.core.model.deferred.DeferredChanged; + +public class MediaTypeDiff { + + private final OpenApiDiff openApiDiff; + + public MediaTypeDiff(OpenApiDiff openApiDiff) { + this.openApiDiff = openApiDiff; + } + + public DeferredChanged diff( + MediaType left, MediaType right, DiffContext context) { + DeferredBuilder builder = new DeferredBuilder<>(); + + ChangedMediaType changedMediaType = + new ChangedMediaType(left.getSchema(), right.getSchema(), context) + .setExample(new ChangedExample(left.getExample(), right.getExample())) + .setExamples(new ChangedExamples(left.getExamples(), right.getExamples())); + + builder + .with( + openApiDiff + .getSchemaDiff() + .diff(left.getSchema(), right.getSchema(), context.copyWithRequired(true))) + .ifPresent(changedMediaType::setSchema); + + return builder.build().mapOptional(value -> isChanged(changedMediaType)); + } +} diff --git a/core/src/main/java/org/openapitools/openapidiff/core/compare/OpenApiDiff.java b/core/src/main/java/org/openapitools/openapidiff/core/compare/OpenApiDiff.java index f56ed04da..c1bb414d8 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/compare/OpenApiDiff.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/compare/OpenApiDiff.java @@ -24,6 +24,7 @@ public class OpenApiDiff { private PathDiff pathDiff; private SchemaDiff schemaDiff; private ContentDiff contentDiff; + private MediaTypeDiff mediaTypeDiff; private ParametersDiff parametersDiff; private ParameterDiff parameterDiff; private RequestBodyDiff requestBodyDiff; @@ -76,6 +77,7 @@ private void initializeFields() { this.pathDiff = new PathDiff(this); this.schemaDiff = new SchemaDiff(this); this.contentDiff = new ContentDiff(this); + this.mediaTypeDiff = new MediaTypeDiff(this); this.parametersDiff = new ParametersDiff(this); this.parameterDiff = new ParameterDiff(this); this.requestBodyDiff = new RequestBodyDiff(this); @@ -204,6 +206,10 @@ public ContentDiff getContentDiff() { return this.contentDiff; } + public MediaTypeDiff getMediaTypeDiff() { + return this.mediaTypeDiff; + } + public ParametersDiff getParametersDiff() { return this.parametersDiff; } diff --git a/core/src/main/java/org/openapitools/openapidiff/core/compare/ParameterDiff.java b/core/src/main/java/org/openapitools/openapidiff/core/compare/ParameterDiff.java index 6652b0bc4..d85ad92a8 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/compare/ParameterDiff.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/compare/ParameterDiff.java @@ -6,6 +6,8 @@ import java.util.Objects; import java.util.Optional; import org.openapitools.openapidiff.core.model.Changed; +import org.openapitools.openapidiff.core.model.ChangedExample; +import org.openapitools.openapidiff.core.model.ChangedExamples; import org.openapitools.openapidiff.core.model.ChangedParameter; import org.openapitools.openapidiff.core.model.DiffContext; import org.openapitools.openapidiff.core.model.deferred.DeferredBuilder; @@ -56,7 +58,9 @@ protected DeferredChanged computeDiff( .setChangeAllowEmptyValue( getBooleanDiff(left.getAllowEmptyValue(), right.getAllowEmptyValue())) .setChangeStyle(!Objects.equals(left.getStyle(), right.getStyle())) - .setChangeExplode(getBooleanDiff(left.getExplode(), right.getExplode())); + .setChangeExplode(getBooleanDiff(left.getExplode(), right.getExplode())) + .setExamples(new ChangedExamples(left.getExamples(), right.getExamples())) + .setExample(new ChangedExample(left.getExample(), right.getExample())); builder .with( openApiDiff diff --git a/core/src/main/java/org/openapitools/openapidiff/core/compare/SchemaDiff.java b/core/src/main/java/org/openapitools/openapidiff/core/compare/SchemaDiff.java index 1d1961bf7..1b410818b 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/compare/SchemaDiff.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/compare/SchemaDiff.java @@ -106,7 +106,7 @@ protected static Schema resolveComposedSchema( return schema; } - protected static Schema addSchema(Schema schema, Schema fromSchema) { + protected static Schema addSchema(Schema schema, Schema fromSchema) { if (fromSchema.getProperties() != null) { if (schema.getProperties() == null) { schema.setProperties(new LinkedHashMap<>()); @@ -206,6 +206,9 @@ protected static Schema addSchema(Schema schema, Schema fromSchema) { if (fromSchema.getExample() != null) { schema.setExample(fromSchema.getExample()); } + if (fromSchema.getExamples() != null) { + schema.setExamples((List) fromSchema.getExamples()); + } if (fromSchema.getExternalDocs() != null) { if (schema.getExternalDocs() == null) { schema.setExternalDocs(new ExternalDocumentation()); 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 6886f8c54..7b59bc3b1 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 @@ -11,6 +11,8 @@ import org.openapitools.openapidiff.core.compare.OpenApiDiff; import org.openapitools.openapidiff.core.model.Change; import org.openapitools.openapidiff.core.model.Changed; +import org.openapitools.openapidiff.core.model.ChangedExample; +import org.openapitools.openapidiff.core.model.ChangedExamples; import org.openapitools.openapidiff.core.model.ChangedSchema; import org.openapitools.openapidiff.core.model.DiffContext; import org.openapitools.openapidiff.core.model.deferred.DeferredBuilder; @@ -70,7 +72,9 @@ public , X> DeferredChanged diff( right.getExclusiveMinimum(), left.getExclusiveMaximum(), right.getExclusiveMaximum(), - context)); + context)) + .setExamples(new ChangedExamples(left.getExamples(), right.getExamples())) + .setExample(new ChangedExample(left.getExample(), right.getExample())); builder .with( openApiDiff diff --git a/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedExample.java b/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedExample.java new file mode 100644 index 000000000..4e540eca3 --- /dev/null +++ b/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedExample.java @@ -0,0 +1,66 @@ +package org.openapitools.openapidiff.core.model; + +import java.util.Objects; + +public class ChangedExample implements Changed { + + private Object leftExample; + private Object rightExample; + + public ChangedExample(Object leftExample, Object rightExample) { + this.leftExample = leftExample; + this.rightExample = rightExample; + } + + public Object getLeftExample() { + return leftExample; + } + + public void setLeftExample(Object leftExample) { + this.leftExample = leftExample; + } + + public Object getRightExample() { + return rightExample; + } + + public void setRightExample(Object rightExample) { + this.rightExample = rightExample; + } + + @Override + public DiffResult isChanged() { + if (!Objects.equals(leftExample, rightExample)) { + return DiffResult.METADATA; + } + return DiffResult.NO_CHANGES; + } + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } + ChangedExample that = (ChangedExample) object; + return Objects.equals(leftExample, that.leftExample) + && Objects.equals(rightExample, that.rightExample); + } + + @Override + public int hashCode() { + return Objects.hash(leftExample, rightExample); + } + + @Override + public String toString() { + return "ChangedExample{" + + "leftExample=" + + leftExample + + ", rightExample=" + + rightExample + + '}'; + } +} diff --git a/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedExamples.java b/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedExamples.java new file mode 100644 index 000000000..c1a00bbbc --- /dev/null +++ b/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedExamples.java @@ -0,0 +1,66 @@ +package org.openapitools.openapidiff.core.model; + +import java.util.Objects; + +public class ChangedExamples implements Changed { + + private Object leftExamples; + private Object rightExamples; + + public ChangedExamples(Object leftExamples, Object rightExamples) { + this.leftExamples = leftExamples; + this.rightExamples = rightExamples; + } + + public Object getLeftExamples() { + return leftExamples; + } + + public void setLeftExamples(Object leftExamples) { + this.leftExamples = leftExamples; + } + + public Object getRightExamples() { + return rightExamples; + } + + public void setRightExamples(Object rightExamples) { + this.rightExamples = rightExamples; + } + + @Override + public DiffResult isChanged() { + if (!Objects.equals(leftExamples, rightExamples)) { + return DiffResult.METADATA; + } + return DiffResult.NO_CHANGES; + } + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } + ChangedExamples that = (ChangedExamples) object; + return Objects.equals(leftExamples, that.leftExamples) + && Objects.equals(rightExamples, that.rightExamples); + } + + @Override + public int hashCode() { + return Objects.hash(leftExamples, rightExamples); + } + + @Override + public String toString() { + return "ChangedExamples{" + + ", leftExamples=" + + leftExamples + + ", rightExamples=" + + rightExamples + + '}'; + } +} diff --git a/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedHeader.java b/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedHeader.java index b7f505a9b..0c9e3384f 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedHeader.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedHeader.java @@ -18,6 +18,8 @@ public class ChangedHeader implements ComposedChanged { private boolean style; private boolean explode; private ChangedMetadata description; + private ChangedExamples examples; + private ChangedExample example; private ChangedSchema schema; private ChangedContent content; private ChangedExtensions extensions; @@ -30,7 +32,7 @@ public ChangedHeader(Header oldHeader, Header newHeader, DiffContext context) { @Override public List getChangedElements() { - return Arrays.asList(description, schema, content, extensions); + return Arrays.asList(description, example, examples, schema, content, extensions); } @Override @@ -96,6 +98,14 @@ public ChangedMetadata getDescription() { return this.description; } + public ChangedExamples getExamples() { + return this.examples; + } + + public ChangedExample getExample() { + return this.example; + } + public ChangedSchema getSchema() { return this.schema; } @@ -133,6 +143,16 @@ public ChangedHeader setDescription(final ChangedMetadata description) { return this; } + public ChangedHeader setExamples(ChangedExamples examples) { + this.examples = examples; + return this; + } + + public ChangedHeader setExample(ChangedExample example) { + this.example = example; + return this; + } + public ChangedHeader setSchema(final ChangedSchema schema) { this.schema = schema; return this; @@ -161,6 +181,8 @@ public boolean equals(Object o) { && Objects.equals(newHeader, that.newHeader) && Objects.equals(context, that.context) && Objects.equals(description, that.description) + && Objects.equals(examples, that.examples) + && Objects.equals(example, that.example) && Objects.equals(schema, that.schema) && Objects.equals(content, that.content) && Objects.equals(extensions, that.extensions); @@ -177,6 +199,8 @@ public int hashCode() { style, explode, description, + examples, + example, schema, content, extensions); @@ -200,6 +224,10 @@ public java.lang.String toString() { + this.isExplode() + ", description=" + this.getDescription() + + ", examples=" + + this.getExamples() + + ", example=" + + this.getExample() + ", schema=" + this.getSchema() + ", content=" diff --git a/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedMediaType.java b/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedMediaType.java index 7136dea04..43f9a443d 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedMediaType.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedMediaType.java @@ -1,7 +1,7 @@ package org.openapitools.openapidiff.core.model; import io.swagger.v3.oas.models.media.Schema; -import java.util.Collections; +import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -10,6 +10,8 @@ public class ChangedMediaType implements ComposedChanged { private final Schema newSchema; private final DiffContext context; private ChangedSchema schema; + private ChangedExamples examples; + private ChangedExample example; public ChangedMediaType(Schema oldSchema, Schema newSchema, DiffContext context) { this.oldSchema = oldSchema; @@ -19,7 +21,7 @@ public ChangedMediaType(Schema oldSchema, Schema newSchema, DiffContext context) @Override public List getChangedElements() { - return Collections.singletonList(schema); + return Arrays.asList(schema, examples, example); } @Override @@ -43,11 +45,29 @@ public ChangedSchema getSchema() { return this.schema; } + public ChangedExamples getExamples() { + return this.examples; + } + + public ChangedExample getExample() { + return this.example; + } + public ChangedMediaType setSchema(final ChangedSchema schema) { this.schema = schema; return this; } + public ChangedMediaType setExamples(final ChangedExamples examples) { + this.examples = examples; + return this; + } + + public ChangedMediaType setExample(final ChangedExample example) { + this.example = example; + return this; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -56,12 +76,14 @@ public boolean equals(Object o) { return Objects.equals(oldSchema, that.oldSchema) && Objects.equals(newSchema, that.newSchema) && Objects.equals(context, that.context) - && Objects.equals(schema, that.schema); + && Objects.equals(schema, that.schema) + && Objects.equals(examples, that.examples) + && Objects.equals(example, that.example); } @Override public int hashCode() { - return Objects.hash(oldSchema, newSchema, context, schema); + return Objects.hash(oldSchema, newSchema, context, schema, examples, example); } @java.lang.Override @@ -74,6 +96,10 @@ public java.lang.String toString() { + this.getContext() + ", schema=" + this.getSchema() + + ", examples=" + + this.getExamples() + + ", example=" + + this.getExample() + ")"; } } diff --git a/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedParameter.java b/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedParameter.java index ff1ccfb48..4b8208e24 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedParameter.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/model/ChangedParameter.java @@ -19,6 +19,8 @@ public class ChangedParameter implements ComposedChanged { private boolean changeExplode; private boolean changeAllowEmptyValue; private ChangedMetadata description; + private ChangedExamples examples; + private ChangedExample example; private ChangedSchema schema; private ChangedContent content; private ChangedExtensions extensions; @@ -31,7 +33,7 @@ public ChangedParameter(String name, String in, DiffContext context) { @Override public List getChangedElements() { - return Arrays.asList(description, schema, content, extensions); + return Arrays.asList(description, examples, example, schema, content, extensions); } @Override @@ -110,6 +112,14 @@ public ChangedMetadata getDescription() { return this.description; } + public ChangedExamples getExamples() { + return this.examples; + } + + public ChangedExample getExample() { + return this.example; + } + public ChangedSchema getSchema() { return this.schema; } @@ -172,6 +182,16 @@ public ChangedParameter setDescription(final ChangedMetadata description) { return this; } + public ChangedParameter setExamples(final ChangedExamples examples) { + this.examples = examples; + return this; + } + + public ChangedParameter setExample(final ChangedExample example) { + this.example = example; + return this; + } + public ChangedParameter setSchema(final ChangedSchema schema) { this.schema = schema; return this; @@ -203,6 +223,8 @@ public boolean equals(Object o) { && Objects.equals(name, that.name) && Objects.equals(in, that.in) && Objects.equals(description, that.description) + && Objects.equals(examples, that.examples) + && Objects.equals(example, that.example) && Objects.equals(schema, that.schema) && Objects.equals(content, that.content) && Objects.equals(extensions, that.extensions); @@ -222,6 +244,8 @@ public int hashCode() { changeExplode, changeAllowEmptyValue, description, + examples, + example, schema, content, extensions); @@ -251,6 +275,10 @@ public java.lang.String toString() { + this.isChangeAllowEmptyValue() + ", description=" + this.getDescription() + + ", examples=" + + this.getExamples() + + ", example=" + + this.getExample() + ", schema=" + this.getSchema() + ", content=" 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 a8200ba40..01d0ca1aa 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 @@ -25,6 +25,8 @@ public class ChangedSchema implements ComposedChanged { protected Map> missingProperties; protected boolean changeDeprecated; protected ChangedMetadata description; + protected ChangedExamples examples; + protected ChangedExample example; protected boolean changeTitle; protected ChangedRequired required; protected boolean changeDefault; @@ -106,6 +108,8 @@ public List getChangedElements() { changedProperties.values().stream(), Stream.of( description, + examples, + example, readOnly, writeOnly, items, @@ -221,6 +225,14 @@ public boolean isChangeDeprecated() { return this.changeDeprecated; } + public ChangedExamples getExamples() { + return this.examples; + } + + public ChangedExample getExample() { + return this.example; + } + public ChangedMetadata getDescription() { return this.description; } @@ -331,6 +343,18 @@ public ChangedSchema setDescription(final ChangedMetadata description) { return this; } + public ChangedSchema setExamples(final ChangedExamples examples) { + clearChangedCache(); + this.examples = examples; + return this; + } + + public ChangedSchema setExample(final ChangedExample example) { + clearChangedCache(); + this.example = example; + return this; + } + public ChangedSchema setChangeTitle(final boolean changeTitle) { clearChangedCache(); this.changeTitle = changeTitle; @@ -440,6 +464,8 @@ public boolean equals(Object o) { && Objects.equals(increasedProperties, that.increasedProperties) && Objects.equals(missingProperties, that.missingProperties) && Objects.equals(description, that.description) + && Objects.equals(examples, that.examples) + && Objects.equals(example, that.example) && Objects.equals(required, that.required) && Objects.equals(enumeration, that.enumeration) && Objects.equals(readOnly, that.readOnly) @@ -464,6 +490,8 @@ public int hashCode() { missingProperties, changeDeprecated, description, + examples, + example, changeTitle, required, changeDefault, @@ -501,6 +529,10 @@ public java.lang.String toString() { + this.isChangeDeprecated() + ", description=" + this.getDescription() + + ", examples=" + + this.getExamples() + + ", example=" + + this.getExample() + ", changeTitle=" + this.isChangeTitle() + ", required=" diff --git a/core/src/test/java/org/openapitools/openapidiff/core/ExamplesDiffTest.java b/core/src/test/java/org/openapitools/openapidiff/core/ExamplesDiffTest.java new file mode 100644 index 000000000..1743de4d1 --- /dev/null +++ b/core/src/test/java/org/openapitools/openapidiff/core/ExamplesDiffTest.java @@ -0,0 +1,167 @@ +package org.openapitools.openapidiff.core; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.openapitools.openapidiff.core.TestUtils.getOpenApiChangedOperations; + +import java.util.List; +import org.junit.jupiter.api.Test; +import org.openapitools.openapidiff.core.model.ChangedOperation; + +public class ExamplesDiffTest { + + @Test + public void issue666OAS30ExampleInMediaType() { + List changedOperations = + getOpenApiChangedOperations( + "issue-666-oas-3-0-examples-handling-1.yaml", + "issue-666-oas-3-0-examples-handling-2.yaml"); + + ChangedOperation requestMediaTypeExampleChanged = + changedOperations.stream() + .filter(o -> "/example/request/media-type".equals(o.getPathUrl())) + .findFirst() + .orElse(null); + ChangedOperation responseMediaTypeExampleChanged = + changedOperations.stream() + .filter(o -> "/example/response/media-type".equals(o.getPathUrl())) + .findFirst() + .orElse(null); + + assertThat(requestMediaTypeExampleChanged).isNotNull(); + assertThat(responseMediaTypeExampleChanged).isNotNull(); + } + + @Test + public void issue666OAS31ExamplesInMediaType() { + List changedOperations = + getOpenApiChangedOperations( + "issue-666-oas-3-1-examples-handling-1.yaml", + "issue-666-oas-3-1-examples-handling-2.yaml"); + + ChangedOperation requestMediaTypeExamplesChanged = + changedOperations.stream() + .filter(o -> "/examples/request/media-type".equals(o.getPathUrl())) + .findFirst() + .orElse(null); + ChangedOperation responseMediaTypeExamplesChanged = + changedOperations.stream() + .filter(o -> "/examples/response/media-type".equals(o.getPathUrl())) + .findFirst() + .orElse(null); + + assertThat(requestMediaTypeExamplesChanged).isNotNull(); + assertThat(responseMediaTypeExamplesChanged).isNotNull(); + } + + @Test + public void issue666OAS30ExampleInParameter() { + List changedOperations = + getOpenApiChangedOperations( + "issue-666-oas-3-0-examples-handling-1.yaml", + "issue-666-oas-3-0-examples-handling-2.yaml"); + + ChangedOperation paramExampleChanged = + changedOperations.stream() + .filter(o -> "/example/parameter/{id}".equals(o.getPathUrl())) + .findFirst() + .orElse(null); + + assertThat(paramExampleChanged).isNotNull(); + } + + @Test + public void issue666OAS31ExamplesInParameter() { + List changedOperations = + getOpenApiChangedOperations( + "issue-666-oas-3-1-examples-handling-1.yaml", + "issue-666-oas-3-1-examples-handling-2.yaml"); + + ChangedOperation paramExamplesChanged = + changedOperations.stream() + .filter(o -> "/examples/parameter/{id}".equals(o.getPathUrl())) + .findFirst() + .orElse(null); + + assertThat(paramExamplesChanged).isNotNull(); + } + + @Test + public void issue666OAS30ExampleInResponseHeader() { + List changedOperations = + getOpenApiChangedOperations( + "issue-666-oas-3-0-examples-handling-1.yaml", + "issue-666-oas-3-0-examples-handling-2.yaml"); + + ChangedOperation operation = + changedOperations.stream() + .filter(o -> "/example/response/header".equals(o.getPathUrl())) + .findFirst() + .orElse(null); + + assertThat(operation).isNotNull(); + } + + @Test + public void issue666OAS31ExamplesInResponseHeader() { + List changedOperations = + getOpenApiChangedOperations( + "issue-666-oas-3-1-examples-handling-1.yaml", + "issue-666-oas-3-1-examples-handling-2.yaml"); + + ChangedOperation operation = + changedOperations.stream() + .filter(o -> "/examples/response/header".equals(o.getPathUrl())) + .findFirst() + .orElse(null); + + assertThat(operation).isNotNull(); + } + + @Test + public void issue666OAS30ExampleInSchema() { + List changedOperations = + getOpenApiChangedOperations( + "issue-666-oas-3-0-examples-handling-1.yaml", + "issue-666-oas-3-0-examples-handling-2.yaml"); + + ChangedOperation operation = + changedOperations.stream() + .filter(o -> "/example/model/property".equals(o.getPathUrl())) + .findFirst() + .orElse(null); + + assertThat(operation).isNotNull(); + } + + @Test + public void issue666OAS31ExamplesInSchema() { + List changedOperations = + getOpenApiChangedOperations( + "issue-666-oas-3-1-examples-handling-1.yaml", + "issue-666-oas-3-1-examples-handling-2.yaml"); + + ChangedOperation operation = + changedOperations.stream() + .filter(o -> "/examples/model/property".equals(o.getPathUrl())) + .findFirst() + .orElse(null); + + assertThat(operation).isNotNull(); + } + + @Test + public void issue666OAS30ExampleInComposedSchema() { + List changedOperations = + getOpenApiChangedOperations( + "issue-666-oas-3-0-examples-handling-1.yaml", + "issue-666-oas-3-0-examples-handling-2.yaml"); + + ChangedOperation operation = + changedOperations.stream() + .filter(o -> "/example/model/property/composed".equals(o.getPathUrl())) + .findFirst() + .orElse(null); + + assertThat(operation).isNotNull(); + } +} diff --git a/core/src/test/java/org/openapitools/openapidiff/core/TestUtils.java b/core/src/test/java/org/openapitools/openapidiff/core/TestUtils.java index 64dac2767..597bf830f 100644 --- a/core/src/test/java/org/openapitools/openapidiff/core/TestUtils.java +++ b/core/src/test/java/org/openapitools/openapidiff/core/TestUtils.java @@ -3,9 +3,11 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.slf4j.LoggerFactory.getLogger; +import java.util.List; import org.openapitools.openapidiff.core.compare.OpenApiDiffOptions; import org.openapitools.openapidiff.core.model.BackwardIncompatibleProp; import org.openapitools.openapidiff.core.model.ChangedOpenApi; +import org.openapitools.openapidiff.core.model.ChangedOperation; import org.openapitools.openapidiff.core.model.DiffResult; import org.slf4j.Logger; @@ -72,4 +74,9 @@ public static void assertOpenApiBackwardIncompatible(String oldSpec, String newS LOG.info("Result: {}", changedOpenApi.isChanged().getValue()); assertThat(changedOpenApi.isIncompatible()).isTrue(); } + + public static List getOpenApiChangedOperations(String oldSpec, String newSpec) { + ChangedOpenApi changedOpenApi = OpenApiCompare.fromLocations(oldSpec, newSpec); + return changedOpenApi.getChangedOperations(); + } } diff --git a/core/src/test/resources/issue-666-oas-3-0-examples-handling-1.yaml b/core/src/test/resources/issue-666-oas-3-0-examples-handling-1.yaml new file mode 100644 index 000000000..041db37f6 --- /dev/null +++ b/core/src/test/resources/issue-666-oas-3-0-examples-handling-1.yaml @@ -0,0 +1,126 @@ +openapi: 3.0.2 +info: + description: Examples handling + title: Examples + version: 1.0.0 +paths: + /example/request/media-type: + post: + requestBody: + content: + application/json: + example: simple example + schema: + type: string + responses: + '200': + description: description + content: + application/json: + schema: + type: string + /example/response/media-type: + post: + requestBody: + content: + application/json: + schema: + type: string + responses: + '200': + description: description + content: + application/json: + example: simple example + schema: + type: string + /example/parameter/{id}: + post: + parameters: + - name: id + in: path + example: example + schema: + type: string + requestBody: + content: + application/json: + schema: + type: string + responses: + '200': + description: description + content: + application/json: + schema: + type: string + /example/response/header: + post: + requestBody: + content: + application/json: + schema: + type: string + responses: + '200': + description: description + headers: + X-Header: + example: example + schema: + type: integer + format: int32 + content: + application/json: + schema: + type: string + /example/model/property: + post: + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/TestDTO" + responses: + '200': + description: description + content: + application/json: + schema: + type: string + /example/model/property/composed: + post: + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/TestComposedDTO" + responses: + '200': + description: description + content: + application/json: + schema: + type: string +components: + schemas: + TestDTO: + type: object + properties: + field1: + example: example + type: string + TestDTO2: + type: object + properties: + field2: + example: example + type: string + TestComposedDTO: + type: object + properties: + field1: + type: object + allOf: + - $ref: "#/components/schemas/TestDTO" + - $ref: "#/components/schemas/TestDTO2" \ No newline at end of file diff --git a/core/src/test/resources/issue-666-oas-3-0-examples-handling-2.yaml b/core/src/test/resources/issue-666-oas-3-0-examples-handling-2.yaml new file mode 100644 index 000000000..e0d5914a5 --- /dev/null +++ b/core/src/test/resources/issue-666-oas-3-0-examples-handling-2.yaml @@ -0,0 +1,126 @@ +openapi: 3.0.2 +info: + description: Examples handling + title: Examples + version: 2.0.0 +paths: + /example/request/media-type: + post: + requestBody: + content: + application/json: + example: simple example updated + schema: + type: string + responses: + '200': + description: description + content: + application/json: + schema: + type: string + /example/response/media-type: + post: + requestBody: + content: + application/json: + schema: + type: string + responses: + '200': + description: description + content: + application/json: + example: simple example updated + schema: + type: string + /example/parameter/{id}: + post: + parameters: + - name: id + in: path + example: example updated + schema: + type: string + requestBody: + content: + application/json: + schema: + type: string + responses: + '200': + description: description + content: + application/json: + schema: + type: string + /example/response/header: + post: + requestBody: + content: + application/json: + schema: + type: string + responses: + '200': + description: description + headers: + X-Header: + example: updated example + schema: + type: integer + format: int32 + content: + application/json: + schema: + type: string + /example/model/property: + post: + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/TestDTO" + responses: + '200': + description: description + content: + application/json: + schema: + type: string + /example/model/property/composed: + post: + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/TestComposedDTO" + responses: + '200': + description: description + content: + application/json: + schema: + type: string +components: + schemas: + TestDTO: + type: object + properties: + field1: + example: example updated + type: string + TestDTO2: + type: object + properties: + field2: + example: example updated + type: string + TestComposedDTO: + type: object + properties: + field1: + type: object + allOf: + - $ref: "#/components/schemas/TestDTO" + - $ref: "#/components/schemas/TestDTO2" \ No newline at end of file diff --git a/core/src/test/resources/issue-666-oas-3-1-examples-handling-1.yaml b/core/src/test/resources/issue-666-oas-3-1-examples-handling-1.yaml new file mode 100644 index 000000000..e03ea0090 --- /dev/null +++ b/core/src/test/resources/issue-666-oas-3-1-examples-handling-1.yaml @@ -0,0 +1,152 @@ +openapi: 3.1.0 +info: + description: Examples handling + title: Examples + version: 1.0.0 +paths: + /example/request/media-type: + post: + requestBody: + content: + application/json: + example: simple example + schema: + type: string + responses: + '200': + content: + application/json: + schema: + type: string + /examples/request/media-type: + post: + requestBody: + content: + application/json: + examples: + first: example + second: example + schema: + type: string + responses: + '200': + content: + application/json: + schema: + type: string + /example/response/media-type: + post: + requestBody: + content: + application/json: + schema: + type: string + responses: + '200': + content: + application/json: + example: simple example + schema: + type: string + /examples/response/media-type: + post: + requestBody: + content: + application/json: + schema: + type: string + responses: + '200': + content: + application/json: + examples: + first: example + second: example + schema: + type: string + /example/parameter/{id}: + post: + parameters: + - name: id + in: path + example: example + schema: + type: string + requestBody: + content: + application/json: + schema: + type: string + responses: + '200': + content: + application/json: + schema: + type: string + /examples/parameter/{id}: + post: + parameters: + - name: id + in: path + examples: + first: example + second: example + schema: + type: string + requestBody: + content: + application/json: + schema: + type: string + responses: + '200': + content: + application/json: + schema: + type: string + /examples/response/header: + post: + requestBody: + content: + application/json: + schema: + type: string + responses: + '200': + description: description + headers: + X-Header: + examples: + first: example + second: example + schema: + type: integer + format: int32 + content: + application/json: + schema: + type: string + /examples/model/property: + post: + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/TestDTO" + responses: + '200': + description: description + content: + application/json: + schema: + type: string +components: + schemas: + TestDTO: + type: object + properties: + field1: + examples: + - first example + - second example + type: string \ No newline at end of file diff --git a/core/src/test/resources/issue-666-oas-3-1-examples-handling-2.yaml b/core/src/test/resources/issue-666-oas-3-1-examples-handling-2.yaml new file mode 100644 index 000000000..26d11d91d --- /dev/null +++ b/core/src/test/resources/issue-666-oas-3-1-examples-handling-2.yaml @@ -0,0 +1,152 @@ +openapi: 3.1.0 +info: + description: Examples handling + title: Examples + version: 2.0.0 +paths: + /example/request/media-type: + post: + requestBody: + content: + application/json: + example: simple example updated + schema: + type: string + responses: + '200': + content: + application/json: + schema: + type: string + /examples/request/media-type: + post: + requestBody: + content: + application/json: + examples: + first: example updated + second: example updated + schema: + type: string + responses: + '200': + content: + application/json: + schema: + type: string + /example/response/media-type: + post: + requestBody: + content: + application/json: + schema: + type: string + responses: + '200': + content: + application/json: + example: simple example updated + schema: + type: string + /examples/response/media-type: + post: + requestBody: + content: + application/json: + schema: + type: string + responses: + '200': + content: + application/json: + examples: + first: example updated + second: example updated + schema: + type: string + /example/parameter/{id}: + post: + parameters: + - name: id + in: path + example: example updated + schema: + type: string + requestBody: + content: + application/json: + schema: + type: string + responses: + '200': + content: + application/json: + schema: + type: string + /examples/parameter/{id}: + post: + parameters: + - name: id + in: path + examples: + first: example updated + second: example updated + schema: + type: string + requestBody: + content: + application/json: + schema: + type: string + responses: + '200': + content: + application/json: + schema: + type: string + /examples/response/header: + post: + requestBody: + content: + application/json: + schema: + type: string + responses: + '200': + description: description + headers: + X-Header: + examples: + first: example updated + second: example updated + schema: + type: integer + format: int32 + content: + application/json: + schema: + type: string + /examples/model/property: + post: + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/TestDTO" + responses: + '200': + description: description + content: + application/json: + schema: + type: string +components: + schemas: + TestDTO: + type: object + properties: + field1: + examples: + - first example updated + - second example updated + type: string \ No newline at end of file