diff --git a/core/src/main/java/org/openapitools/openapidiff/core/utils/RefPointer.java b/core/src/main/java/org/openapitools/openapidiff/core/utils/RefPointer.java index ab5a5643a..7da55e06f 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/utils/RefPointer.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/utils/RefPointer.java @@ -57,7 +57,10 @@ public String getRefName(String ref) { final String baseRef = getBaseRefForType(refType.getName()); if (!ref.startsWith(baseRef)) { - throw new IllegalArgumentException("Invalid ref: " + ref); + // If the ref doesn't point to something in #/components, + // we return it as-is. This avoids making an assumption + // that we can simplify refs without collisions. + return ref; } return ref.substring(baseRef.length()); } diff --git a/core/src/test/java/org/openapitools/openapidiff/core/RemoteRefsDiffTest.java b/core/src/test/java/org/openapitools/openapidiff/core/RemoteRefsDiffTest.java new file mode 100644 index 000000000..b06de3d56 --- /dev/null +++ b/core/src/test/java/org/openapitools/openapidiff/core/RemoteRefsDiffTest.java @@ -0,0 +1,21 @@ +package org.openapitools.openapidiff.core; + +import static org.openapitools.openapidiff.core.TestUtils.assertOpenApiAreEquals; + +import org.junit.jupiter.api.Test; + +public class RemoteRefsDiffTest { + + private final String OPENAPI_DOC1 = "remoteRefs/diff_1.yaml"; + private final String OPENAPI_DOC2 = "remoteRefs/diff_2.yaml"; + + @Test + public void testDiffSame() { + assertOpenApiAreEquals(OPENAPI_DOC1, OPENAPI_DOC1); + } + + @Test + public void testDiffSameWithAllOf() { + assertOpenApiAreEquals(OPENAPI_DOC1, OPENAPI_DOC2); + } +} diff --git a/core/src/test/resources/remoteRefs/components/BasePet.yaml b/core/src/test/resources/remoteRefs/components/BasePet.yaml new file mode 100644 index 000000000..503195ed8 --- /dev/null +++ b/core/src/test/resources/remoteRefs/components/BasePet.yaml @@ -0,0 +1,4 @@ +type: object +properties: + pet_color: + type: string \ No newline at end of file diff --git a/core/src/test/resources/remoteRefs/components/Pet.yaml b/core/src/test/resources/remoteRefs/components/Pet.yaml new file mode 100644 index 000000000..d79e286cf --- /dev/null +++ b/core/src/test/resources/remoteRefs/components/Pet.yaml @@ -0,0 +1,8 @@ +allOf: + - $ref: './BasePet.yaml' + - type: object + required: + - pet_type + properties: + pet_type: + type: string \ No newline at end of file diff --git a/core/src/test/resources/remoteRefs/diff_1.yaml b/core/src/test/resources/remoteRefs/diff_1.yaml new file mode 100644 index 000000000..250895d78 --- /dev/null +++ b/core/src/test/resources/remoteRefs/diff_1.yaml @@ -0,0 +1,113 @@ +openapi: 3.0.0 +servers: + - url: 'http://petstore.swagger.io/v2' +info: + description: >- + This is a sample server Petstore server. You can find out more about + Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, + #swagger](http://swagger.io/irc/). For this sample, you can use the api key + `special-key` to test the authorization filters. + version: 1.0.0 + title: Swagger Petstore + termsOfService: 'http://swagger.io/terms/' + contact: + email: apiteam@swagger.io + license: + name: Apache 2.0 + url: 'http://www.apache.org/licenses/LICENSE-2.0.html' +tags: + - name: pet + description: Everything about your Pets + externalDocs: + description: Find out more + url: 'http://swagger.io' + - name: store + description: Access to Petstore orders + - name: user + description: Operations about user + externalDocs: + description: Find out more about our store + url: 'http://swagger.io' +paths: + /pet/findByStatus: + get: + tags: + - pet + summary: Finds Pets by status + description: Multiple status values can be provided with comma separated strings + operationId: findPetsByStatus + parameters: + - name: status + in: query + description: Status values that need to be considered for filter + required: true + explode: true + schema: + type: array + items: + type: string + enum: + - available + - pending + - sold + default: available + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + properties: + pets: + type: array + items: + $ref: '#/components/schemas/Cat' + '400': + description: Invalid status value + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' +externalDocs: + description: Find out more about Swagger + url: 'http://swagger.io' +components: + requestBodies: + Pet: + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + description: Pet object that needs to be added to the store + required: true + securitySchemes: + petstore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: 'http://petstore.swagger.io/oauth/dialog' + scopes: + 'write:pets': modify pets in your account + 'read:pets': read your pets + api_key: + type: apiKey + name: api_key + in: header + schemas: + Cat: + description: Cat class + allOf: + - $ref: './components/Pet.yaml' + type: object + properties: + name: + type: string + Dog: + description: Dog class + allOf: + - $ref: './components/Pet.yaml' + type: object + properties: + bark: + type: string diff --git a/core/src/test/resources/remoteRefs/diff_2.yaml b/core/src/test/resources/remoteRefs/diff_2.yaml new file mode 100644 index 000000000..1178036a6 --- /dev/null +++ b/core/src/test/resources/remoteRefs/diff_2.yaml @@ -0,0 +1,125 @@ +openapi: 3.0.0 +servers: + - url: 'http://petstore.swagger.io/v2' +info: + description: >- + This is a sample server Petstore server. You can find out more about + Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, + #swagger](http://swagger.io/irc/). For this sample, you can use the api key + `special-key` to test the authorization filters. + version: 1.0.0 + title: Swagger Petstore + termsOfService: 'http://swagger.io/terms/' + contact: + email: apiteam@swagger.io + license: + name: Apache 2.0 + url: 'http://www.apache.org/licenses/LICENSE-2.0.html' +tags: + - name: pet + description: Everything about your Pets + externalDocs: + description: Find out more + url: 'http://swagger.io' + - name: store + description: Access to Petstore orders + - name: user + description: Operations about user + externalDocs: + description: Find out more about our store + url: 'http://swagger.io' +paths: + /pet/findByStatus: + get: + tags: + - pet + summary: Finds Pets by status + description: Multiple status values can be provided with comma separated strings + operationId: findPetsByStatus + parameters: + - name: status + in: query + description: Status values that need to be considered for filter + required: true + explode: true + schema: + type: array + items: + type: string + enum: + - available + - pending + - sold + default: available + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + properties: + pets: + type: array + items: + $ref: '#/components/schemas/Cat' + '400': + description: Invalid status value + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' +externalDocs: + description: Find out more about Swagger + url: 'http://swagger.io' +components: + requestBodies: + Pet: + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + description: Pet object that needs to be added to the store + required: true + securitySchemes: + petstore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: 'http://petstore.swagger.io/oauth/dialog' + scopes: + 'write:pets': modify pets in your account + 'read:pets': read your pets + api_key: + type: apiKey + name: api_key + in: header + schemas: + Pet: + type: object + required: + - pet_type + properties: + pet_type: + nullable: false + type: string + Cat: + description: Cat class + type: object + required: + - pet_type + properties: + pet_type: + type: string + name: + type: string + pet_color: + type: string + Dog: + description: Dog class + allOf: + - $ref: './components/Pet.yaml' + type: object + properties: + bark: + type: string