diff --git a/core/src/main/java/org/openapitools/openapidiff/core/output/ConsoleRender.java b/core/src/main/java/org/openapitools/openapidiff/core/output/ConsoleRender.java index a3e3a31ee..4f8e10fc9 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/output/ConsoleRender.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/output/ConsoleRender.java @@ -47,6 +47,7 @@ public void render(ChangedOpenApi diff, OutputStreamWriter outputStreamWriter) { List changedOperations = diff.getChangedOperations(); ol_changed(changedOperations, outputStreamWriter); + safelyAppend(outputStreamWriter, title("Result")); safelyAppend( outputStreamWriter, StringUtils.center( @@ -76,6 +77,8 @@ private void ol_changed( String desc = Optional.ofNullable(operation.getSummary()).map(ChangedMetadata::getRight).orElse(""); + safelyAppend(outputStreamWriter, itemEndpoint(method, pathUrl, desc)); + if (result(operation.getParameters()).isDifferent()) { safelyAppend(outputStreamWriter, StringUtils.repeat(' ', 2)); safelyAppend(outputStreamWriter, "Parameter:"); @@ -94,7 +97,6 @@ private void ol_changed( safelyAppend(outputStreamWriter, System.lineSeparator()); safelyAppend(outputStreamWriter, ul_response(operation.getApiResponses())); } - safelyAppend(outputStreamWriter, itemEndpoint(method, pathUrl, desc)); } } @@ -279,10 +281,10 @@ private String li_changedParam(ChangedParameter changeParam) { } } - private String listEndpoints( + private void listEndpoints( List endpoints, String title, OutputStreamWriter outputStreamWriter) { if (null == endpoints || endpoints.isEmpty()) { - return ""; + return; } StringBuilder sb = new StringBuilder(); sb.append(title(title)); @@ -291,7 +293,8 @@ private String listEndpoints( itemEndpoint( endpoint.getMethod().toString(), endpoint.getPathUrl(), endpoint.getSummary())); } - return sb.append(System.lineSeparator()).toString(); + + safelyAppend(outputStreamWriter, sb.append(System.lineSeparator()).toString()); } private String itemEndpoint(String method, String path, String desc) { diff --git a/core/src/test/java/org/openapitools/openapidiff/core/ConsoleRenderTest.java b/core/src/test/java/org/openapitools/openapidiff/core/ConsoleRenderTest.java index f56b4cb95..6d9bdd33e 100644 --- a/core/src/test/java/org/openapitools/openapidiff/core/ConsoleRenderTest.java +++ b/core/src/test/java/org/openapitools/openapidiff/core/ConsoleRenderTest.java @@ -14,8 +14,7 @@ public void renderDoesNotFailWhenPropertyHasBeenRemoved() { ConsoleRender render = new ConsoleRender(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); - ChangedOpenApi diff = - OpenApiCompare.fromLocations("missing_property_1.yaml", "missing_property_2.yaml"); + ChangedOpenApi diff = OpenApiCompare.fromLocations("missing_property_1.yaml", "missing_property_2.yaml"); render.render(diff, outputStreamWriter); assertThat(outputStream.toString()).isNotBlank(); } @@ -30,4 +29,50 @@ public void renderDoesNotFailWhenHTTPStatusCodeIsRange() { render.render(diff, outputStreamWriter); assertThat(outputStream.toString()).isNotBlank(); } + + @Test + public void renderShowsWhatsDeletedSectionWhenEndpointIsDeleted() { + ConsoleRender render = new ConsoleRender(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); + ChangedOpenApi diff = + OpenApiCompare.fromLocations("delete_endpoint_1.yaml", "delete_endpoint_2.yaml"); + render.render(diff, outputStreamWriter); + assertThat(outputStream.toString()).contains("What's Deleted"); + } + + @Test + public void renderShowsWhatsNewSectionWhenEndpointIsAdded() { + ConsoleRender render = new ConsoleRender(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); + ChangedOpenApi diff = + OpenApiCompare.fromLocations("add_endpoint_1.yaml", "add_endpoint_2.yaml"); + render.render(diff, outputStreamWriter); + assertThat(outputStream.toString()).contains("What's New"); + } + + @Test + public void renderShowsWhatsDeprecatedSectionWhenEndpointIsDeprecated() { + ConsoleRender render = new ConsoleRender(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); + ChangedOpenApi diff = + OpenApiCompare.fromLocations("deprecate_endpoint_1.yaml", "deprecate_endpoint_2.yaml"); + render.render(diff, outputStreamWriter); + assertThat(outputStream.toString()).contains("What's Deprecated"); + } + + @Test + public void renderShowsWhatsChangedSectionWithCorrectFormattingWhenEndpointIsChanged() { + ConsoleRender render = new ConsoleRender(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); + ChangedOpenApi diff = + OpenApiCompare.fromLocations("change_endpoint_1.yaml", "change_endpoint_2.yaml"); + render.render(diff, outputStreamWriter); + assertThat(outputStream.toString()) + .contains("What's Changed") + .containsSubsequence("- GET /widgets", "Parameter:", "- Changed query-param-1 in query"); + } } diff --git a/core/src/test/resources/add_endpoint_1.yaml b/core/src/test/resources/add_endpoint_1.yaml new file mode 100644 index 000000000..0c544c7b4 --- /dev/null +++ b/core/src/test/resources/add_endpoint_1.yaml @@ -0,0 +1,35 @@ +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' +paths: + /pet/{petId}: + get: + tags: + - pet + summary: gets a pet by id + description: '' + operationId: updatePetWithForm + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + schema: + type: integer + responses: + '405': + description: Invalid input diff --git a/core/src/test/resources/add_endpoint_2.yaml b/core/src/test/resources/add_endpoint_2.yaml new file mode 100644 index 000000000..95906047e --- /dev/null +++ b/core/src/test/resources/add_endpoint_2.yaml @@ -0,0 +1,53 @@ +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' +paths: + /pet/{petId}: + get: + tags: + - pet + summary: gets a pet by id + description: '' + operationId: updatePetWithForm + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + schema: + type: integer + responses: + '405': + description: Invalid input + /pet/{petId2}: + post: + tags: + - pet + summary: deletes a pet + description: '' + operationId: deletePet + deprecated: true + parameters: + - name: petId2 + in: path + description: Pet ID to delete + required: true + schema: + type: integer + responses: + '405': + description: Invalid input diff --git a/core/src/test/resources/change_endpoint_1.yaml b/core/src/test/resources/change_endpoint_1.yaml new file mode 100644 index 000000000..555015991 --- /dev/null +++ b/core/src/test/resources/change_endpoint_1.yaml @@ -0,0 +1,29 @@ +openapi: 3.0.0 +info: + description: myDesc + title: myTitle + version: 1.0.0 +paths: + /widgets: + get: + operationId: listWidgets + parameters: + - name: query-param-1 + in: query + required: true + schema: + type: string + - name: query-param-2 + in: query + style: form + explode: true + allowEmptyValue: true + schema: + type: string + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: string diff --git a/core/src/test/resources/change_endpoint_2.yaml b/core/src/test/resources/change_endpoint_2.yaml new file mode 100644 index 000000000..281fd0514 --- /dev/null +++ b/core/src/test/resources/change_endpoint_2.yaml @@ -0,0 +1,30 @@ +openapi: 3.0.0 +info: + description: myDesc + title: myTitle + version: 1.0.0 +paths: + /widgets: + get: + operationId: listWidgets + parameters: + - name: query-param-1 + in: query + allowEmptyValue: true + required: false + schema: + type: string + - name: query-param-2 + in: query + style: form + explode: true + allowEmptyValue: true + schema: + type: string + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: string diff --git a/core/src/test/resources/delete_endpoint_1.yaml b/core/src/test/resources/delete_endpoint_1.yaml new file mode 100644 index 000000000..59a315cd0 --- /dev/null +++ b/core/src/test/resources/delete_endpoint_1.yaml @@ -0,0 +1,52 @@ +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' +paths: + /pet/{petId}: + get: + tags: + - pet + summary: gets a pet by id + description: '' + operationId: updatePetWithForm + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + schema: + type: integer + responses: + '405': + description: Invalid input + /pet/{petId2}: + get: + tags: + - pet + summary: gets a pet by id + description: '' + operationId: updatePetWithForm + parameters: + - name: petId2 + in: path + description: ID of pet that needs to be updated + required: true + schema: + type: integer + responses: + '405': + description: Invalid input diff --git a/core/src/test/resources/delete_endpoint_2.yaml b/core/src/test/resources/delete_endpoint_2.yaml new file mode 100644 index 000000000..0c544c7b4 --- /dev/null +++ b/core/src/test/resources/delete_endpoint_2.yaml @@ -0,0 +1,35 @@ +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' +paths: + /pet/{petId}: + get: + tags: + - pet + summary: gets a pet by id + description: '' + operationId: updatePetWithForm + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + schema: + type: integer + responses: + '405': + description: Invalid input diff --git a/core/src/test/resources/deprecate_endpoint_1.yaml b/core/src/test/resources/deprecate_endpoint_1.yaml new file mode 100644 index 000000000..6d08cb721 --- /dev/null +++ b/core/src/test/resources/deprecate_endpoint_1.yaml @@ -0,0 +1,52 @@ +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' +paths: + /pet/{petId}: + get: + tags: + - pet + summary: gets a pet by id + description: '' + operationId: updatePetWithForm + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + schema: + type: integer + responses: + '405': + description: Invalid input + /pet/{petId2}: + post: + tags: + - pet + summary: deletes a pet + description: '' + operationId: deletePet + parameters: + - name: petId2 + in: path + description: Pet ID to delete + required: true + schema: + type: integer + responses: + '405': + description: Invalid input diff --git a/core/src/test/resources/deprecate_endpoint_2.yaml b/core/src/test/resources/deprecate_endpoint_2.yaml new file mode 100644 index 000000000..95906047e --- /dev/null +++ b/core/src/test/resources/deprecate_endpoint_2.yaml @@ -0,0 +1,53 @@ +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' +paths: + /pet/{petId}: + get: + tags: + - pet + summary: gets a pet by id + description: '' + operationId: updatePetWithForm + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + schema: + type: integer + responses: + '405': + description: Invalid input + /pet/{petId2}: + post: + tags: + - pet + summary: deletes a pet + description: '' + operationId: deletePet + deprecated: true + parameters: + - name: petId2 + in: path + description: Pet ID to delete + required: true + schema: + type: integer + responses: + '405': + description: Invalid input