diff --git a/core/src/main/java/org/openapitools/openapidiff/core/compare/schemadiffresult/ComposedSchemaDiffResult.java b/core/src/main/java/org/openapitools/openapidiff/core/compare/schemadiffresult/ComposedSchemaDiffResult.java index 077552e2a..ea681db13 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/compare/schemadiffresult/ComposedSchemaDiffResult.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/compare/schemadiffresult/ComposedSchemaDiffResult.java @@ -6,6 +6,7 @@ import io.swagger.v3.oas.models.media.Schema; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -63,7 +64,8 @@ public , X> Optional diff( MapKeyDiff mappingDiff = MapKeyDiff.diff( - getSchema(leftComponents, leftMapping), getSchema(rightComponents, rightMapping)); + getSchema(leftComponents, leftMapping, leftComposedSchema), + getSchema(rightComponents, rightMapping, rightComposedSchema)); Map changedMapping = new LinkedHashMap<>(); for (String key : mappingDiff.getSharedKey()) { Schema leftSchema = new Schema(); @@ -88,10 +90,14 @@ public , X> Optional diff( } } - private Map getSchema(Components components, Map mapping) { + private Map getSchema(Components components, Map mapping, ComposedSchema composedSchema) { Map result = new LinkedHashMap<>(); mapping.forEach( (key, value) -> result.put(key, refPointer.resolveRef(components, new Schema(), value))); + + result.putAll(getUnnamedSchemas(composedSchema.getAllOf(), "all-of")); + result.putAll(getUnnamedSchemas(composedSchema.getOneOf(), "one-of")); + result.putAll(getUnnamedSchemas(composedSchema.getAnyOf(), "any-of")); return result; } @@ -100,7 +106,7 @@ private Map getMapping(ComposedSchema composedSchema) { for (Schema schema : composedSchema.getOneOf()) { String ref = schema.get$ref(); if (ref == null) { - throw new IllegalArgumentException("invalid oneOf schema"); + continue; } String schemaName = refPointer.getRefName(ref); if (schemaName == null) { @@ -119,4 +125,25 @@ private Map getMapping(ComposedSchema composedSchema) { return reverseMapping.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); } + + private Map getUnnamedSchemas(List schemas, String name) { + Map result = new LinkedHashMap<>(); + + if (schemas == null) { + return result; + } + + for (int i = 0; i < schemas.size(); i++) { + Schema schema = schemas.get(i); + + // If the ref is named, then we ignore it since getMapping will handle it. + if (schema.get$ref() != null) { + continue; + } + + result.put(String.format("%s-%s", name, i), schema); + } + + return result; + } } diff --git a/core/src/test/java/org/openapitools/openapidiff/core/OneOfDiffTest.java b/core/src/test/java/org/openapitools/openapidiff/core/OneOfDiffTest.java index 236faa717..cf893c588 100644 --- a/core/src/test/java/org/openapitools/openapidiff/core/OneOfDiffTest.java +++ b/core/src/test/java/org/openapitools/openapidiff/core/OneOfDiffTest.java @@ -18,6 +18,7 @@ public class OneOfDiffTest { private final String OPENAPI_DOC7 = "oneOf_discriminator-changed_2.yaml"; private final String OPENAPI_DOC8 = "oneOf_discriminator-missing_1.yaml"; private final String OPENAPI_DOC9 = "oneOf_discriminator-missing_2.yaml"; + private final String OPENAPI_DOC10 = "unnamed_oneof_schema_1.yaml"; @Test public void testDiffSame() { @@ -39,6 +40,10 @@ public void testComposedSchema() { assertOpenApiBackwardIncompatible(OPENAPI_DOC4, OPENAPI_DOC5); } + @Test + public void testComposedSchemaDiff() { + assertOpenApiAreEquals(OPENAPI_DOC10, OPENAPI_DOC10); + } @Test public void testOneOfDiscrimitatorChanged() { // The oneOf 'discriminator' changed: 'realtype' -> 'othertype': diff --git a/core/src/test/resources/unnamed_oneof_schema_1.yaml b/core/src/test/resources/unnamed_oneof_schema_1.yaml new file mode 100644 index 000000000..947757ee2 --- /dev/null +++ b/core/src/test/resources/unnamed_oneof_schema_1.yaml @@ -0,0 +1,22 @@ +openapi: 3.0.0 +info: + title: Test Service + version: 1.0.0 +paths: + /test: + get: + responses: + "200": + description: Success + content: + application/json: + schema: + oneOf: + - type: object + properties: + name: + type: string + - type: object + properties: + name: + type: number \ No newline at end of file