diff --git a/cli/src/main/java/org/openapitools/openapidiff/cli/Main.java b/cli/src/main/java/org/openapitools/openapidiff/cli/Main.java index 21503e08a..f19826a93 100644 --- a/cli/src/main/java/org/openapitools/openapidiff/cli/Main.java +++ b/cli/src/main/java/org/openapitools/openapidiff/cli/Main.java @@ -2,9 +2,9 @@ import ch.qos.logback.classic.Level; import io.swagger.v3.parser.core.models.AuthorizationValue; -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; +import java.io.ByteArrayOutputStream; +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; import java.util.Collections; import java.util.List; import org.apache.commons.cli.CommandLine; @@ -14,7 +14,6 @@ import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; -import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.openapitools.openapidiff.core.OpenApiCompare; import org.openapitools.openapidiff.core.model.ChangedOpenApi; @@ -175,29 +174,33 @@ public static void main(String... args) { ChangedOpenApi result = OpenApiCompare.fromLocations(oldPath, newPath, auths); ConsoleRender consoleRender = new ConsoleRender(); if (!logLevel.equals("OFF")) { - System.out.println(consoleRender.render(result)); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); + consoleRender.render(result, outputStreamWriter); + System.out.println(outputStream); } if (line.hasOption("html")) { HtmlRender htmlRender = new HtmlRender(); - String output = htmlRender.render(result); - String outputFile = line.getOptionValue("html"); - writeOutput(output, outputFile); + FileOutputStream outputStream = new FileOutputStream(line.getOptionValue("html")); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); + htmlRender.render(result, outputStreamWriter); } if (line.hasOption("markdown")) { MarkdownRender mdRender = new MarkdownRender(); - String output = mdRender.render(result); - String outputFile = line.getOptionValue("markdown"); - writeOutput(output, outputFile); + FileOutputStream outputStream = new FileOutputStream(line.getOptionValue("markdown")); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); + mdRender.render(result, outputStreamWriter); } if (line.hasOption("text")) { - String output = consoleRender.render(result); - String outputFile = line.getOptionValue("text"); - writeOutput(output, outputFile); + FileOutputStream outputStream = new FileOutputStream(line.getOptionValue("text")); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); + consoleRender.render(result, outputStreamWriter); } if (line.hasOption("json")) { JsonRender jsonRender = new JsonRender(); - String outputFile = line.getOptionValue("json"); - jsonRender.renderToFile(result, outputFile); + FileOutputStream outputStream = new FileOutputStream(line.getOptionValue("json")); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); + jsonRender.render(result, outputStreamWriter); } if (line.hasOption("state")) { System.out.println(result.isChanged().getValue()); @@ -222,17 +225,6 @@ public static void main(String... args) { } } - private static void writeOutput(String output, String outputFile) { - File file = new File(outputFile); - logger.debug("Output file: {}", file.getAbsolutePath()); - try { - FileUtils.writeStringToFile(file, output, StandardCharsets.UTF_8); - } catch (IOException e) { - logger.error("Impossible to write output to file {}", outputFile, e); - System.exit(2); - } - } - public static void printHelp(Options options) { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp("openapi-diff ", options); diff --git a/core/src/main/java/org/openapitools/openapidiff/core/exception/RendererException.java b/core/src/main/java/org/openapitools/openapidiff/core/exception/RendererException.java new file mode 100644 index 000000000..d7dc24447 --- /dev/null +++ b/core/src/main/java/org/openapitools/openapidiff/core/exception/RendererException.java @@ -0,0 +1,12 @@ +package org.openapitools.openapidiff.core.exception; + +public class RendererException extends RuntimeException { + + public RendererException(Throwable cause) { + super(cause); + } + + public RendererException(String message, Throwable cause) { + super(message, cause); + } +} 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 72597ad91..a3e3a31ee 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 @@ -6,11 +6,14 @@ import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.responses.ApiResponse; +import java.io.IOException; +import java.io.OutputStreamWriter; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Optional; import org.apache.commons.lang3.StringUtils; +import org.openapitools.openapidiff.core.exception.RendererException; import org.openapitools.openapidiff.core.model.*; import org.openapitools.openapidiff.core.utils.RefPointer; import org.openapitools.openapidiff.core.utils.RefType; @@ -21,81 +24,78 @@ public class ConsoleRender implements Render { protected ChangedOpenApi diff; @Override - public String render(ChangedOpenApi diff) { + public void render(ChangedOpenApi diff, OutputStreamWriter outputStreamWriter) { this.diff = diff; - StringBuilder output = new StringBuilder(); if (diff.isUnchanged()) { - output.append("No differences. Specifications are equivalents"); + safelyAppend(outputStreamWriter, "No differences. Specifications are equivalents"); } else { - output - .append(bigTitle("Api Change Log")) - .append(StringUtils.center(diff.getNewSpecOpenApi().getInfo().getTitle(), LINE_LENGTH)) - .append(System.lineSeparator()); + safelyAppend(outputStreamWriter, bigTitle("Api Change Log")); + safelyAppend( + outputStreamWriter, + StringUtils.center(diff.getNewSpecOpenApi().getInfo().getTitle(), LINE_LENGTH)); + safelyAppend(outputStreamWriter, System.lineSeparator()); List newEndpoints = diff.getNewEndpoints(); - String ol_newEndpoint = listEndpoints(newEndpoints, "What's New"); + listEndpoints(newEndpoints, "What's New", outputStreamWriter); List missingEndpoints = diff.getMissingEndpoints(); - String ol_missingEndpoint = listEndpoints(missingEndpoints, "What's Deleted"); + listEndpoints(missingEndpoints, "What's Deleted", outputStreamWriter); List deprecatedEndpoints = diff.getDeprecatedEndpoints(); - String ol_deprecatedEndpoint = listEndpoints(deprecatedEndpoints, "What's Deprecated"); + listEndpoints(deprecatedEndpoints, "What's Deprecated", outputStreamWriter); List changedOperations = diff.getChangedOperations(); - String ol_changed = ol_changed(changedOperations); - - output - .append(renderBody(ol_newEndpoint, ol_missingEndpoint, ol_deprecatedEndpoint, ol_changed)) - .append(title("Result")) - .append( - StringUtils.center( - diff.isCompatible() - ? "API changes are backward compatible" - : "API changes broke backward compatibility", - LINE_LENGTH)) - .append(System.lineSeparator()) - .append(separator('-')); + ol_changed(changedOperations, outputStreamWriter); + + safelyAppend( + outputStreamWriter, + StringUtils.center( + diff.isCompatible() + ? "API changes are backward compatible" + : "API changes broke backward compatibility", + LINE_LENGTH)); + safelyAppend(outputStreamWriter, System.lineSeparator()); + safelyAppend(outputStreamWriter, separator('-')); + } + try { + outputStreamWriter.close(); + } catch (IOException e) { + throw new RendererException(e); } - return output.toString(); } - private String ol_changed(List operations) { + private void ol_changed( + List operations, OutputStreamWriter outputStreamWriter) { if (null == operations || operations.isEmpty()) { - return ""; + return; } - StringBuilder sb = new StringBuilder(); - sb.append(title("What's Changed")); + safelyAppend(outputStreamWriter, title("What's Changed")); for (ChangedOperation operation : operations) { String pathUrl = operation.getPathUrl(); String method = operation.getHttpMethod().toString(); String desc = Optional.ofNullable(operation.getSummary()).map(ChangedMetadata::getRight).orElse(""); - StringBuilder ul_detail = new StringBuilder(); if (result(operation.getParameters()).isDifferent()) { - ul_detail - .append(StringUtils.repeat(' ', 2)) - .append("Parameter:") - .append(System.lineSeparator()) - .append(ul_param(operation.getParameters())); + safelyAppend(outputStreamWriter, StringUtils.repeat(' ', 2)); + safelyAppend(outputStreamWriter, "Parameter:"); + safelyAppend(outputStreamWriter, System.lineSeparator()); + safelyAppend(outputStreamWriter, ul_param(operation.getParameters())); } if (operation.resultRequestBody().isDifferent()) { - ul_detail - .append(StringUtils.repeat(' ', 2)) - .append("Request:") - .append(System.lineSeparator()) - .append(ul_content(operation.getRequestBody().getContent(), true)); + safelyAppend(outputStreamWriter, StringUtils.repeat(' ', 2)); + safelyAppend(outputStreamWriter, "Request:"); + safelyAppend(outputStreamWriter, System.lineSeparator()); + safelyAppend(outputStreamWriter, ul_content(operation.getRequestBody().getContent(), true)); } if (operation.resultApiResponses().isDifferent()) { - ul_detail - .append(StringUtils.repeat(' ', 2)) - .append("Return Type:") - .append(System.lineSeparator()) - .append(ul_response(operation.getApiResponses())); + safelyAppend(outputStreamWriter, StringUtils.repeat(' ', 2)); + safelyAppend(outputStreamWriter, "Return Type:"); + safelyAppend(outputStreamWriter, System.lineSeparator()); + safelyAppend(outputStreamWriter, ul_response(operation.getApiResponses())); } - sb.append(itemEndpoint(method, pathUrl, desc)).append(ul_detail); + safelyAppend(outputStreamWriter, itemEndpoint(method, pathUrl, desc)); } - return sb.toString(); } private String ul_response(ChangedApiResponse changedApiResponse) { @@ -279,7 +279,8 @@ private String li_changedParam(ChangedParameter changeParam) { } } - private String listEndpoints(List endpoints, String title) { + private String listEndpoints( + List endpoints, String title, OutputStreamWriter outputStreamWriter) { if (null == endpoints || endpoints.isEmpty()) { return ""; } @@ -317,8 +318,7 @@ public String title(String title, char ch) { separator(ch), little, StringUtils.center(title, LINE_LENGTH - 4), little, separator(ch)); } - public StringBuilder separator(char ch) { - StringBuilder sb = new StringBuilder(); - return sb.append(StringUtils.repeat(ch, LINE_LENGTH)).append(System.lineSeparator()); + public String separator(char ch) { + return StringUtils.repeat(ch, LINE_LENGTH) + System.lineSeparator(); } } diff --git a/core/src/main/java/org/openapitools/openapidiff/core/output/HtmlRender.java b/core/src/main/java/org/openapitools/openapidiff/core/output/HtmlRender.java index 0513424cd..43bb0404b 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/output/HtmlRender.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/output/HtmlRender.java @@ -26,16 +26,20 @@ import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.responses.ApiResponse; +import j2html.rendering.FlatHtml; import j2html.tags.ContainerTag; import j2html.tags.specialized.DivTag; import j2html.tags.specialized.HtmlTag; import j2html.tags.specialized.LiTag; import j2html.tags.specialized.OlTag; import j2html.tags.specialized.UlTag; +import java.io.IOException; +import java.io.OutputStreamWriter; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Optional; +import org.openapitools.openapidiff.core.exception.RendererException; import org.openapitools.openapidiff.core.model.ChangedApiResponse; import org.openapitools.openapidiff.core.model.ChangedContent; import org.openapitools.openapidiff.core.model.ChangedMediaType; @@ -71,7 +75,7 @@ public HtmlRender(String title, String linkCss) { this.linkCss = linkCss; } - public String render(ChangedOpenApi diff) { + public void render(ChangedOpenApi diff, OutputStreamWriter outputStreamWriter) { this.diff = diff; List newEndpoints = diff.getNewEndpoints(); @@ -86,10 +90,16 @@ public String render(ChangedOpenApi diff) { List changedOperations = diff.getChangedOperations(); OlTag ol_changed = ol_changed(changedOperations); - return renderHtml(ol_newEndpoint, ol_missingEndpoint, ol_deprecatedEndpoint, ol_changed); + renderHtml( + ol_newEndpoint, ol_missingEndpoint, ol_deprecatedEndpoint, ol_changed, outputStreamWriter); } - public String renderHtml(OlTag ol_new, OlTag ol_miss, OlTag ol_deprec, OlTag ol_changed) { + public void renderHtml( + OlTag ol_new, + OlTag ol_miss, + OlTag ol_deprec, + OlTag ol_changed, + OutputStreamWriter outputStreamWriter) { HtmlTag html = html() .attr("lang", "en") @@ -110,7 +120,14 @@ public String renderHtml(OlTag ol_new, OlTag ol_miss, OlTag ol_deprec, OlTag ol_ div().with(h2("What's Deprecated"), hr(), ol_deprec), div().with(h2("What's Changed"), hr(), ol_changed)))); - return document().render() + html.render(); + try { + FlatHtml flatHtml = FlatHtml.into(outputStreamWriter); + document().render(flatHtml); + html.render(flatHtml); + outputStreamWriter.close(); + } catch (IOException e) { + throw new RendererException("Problem rendering html document.", e); + } } private OlTag ol_newEndpoint(List endpoints) { diff --git a/core/src/main/java/org/openapitools/openapidiff/core/output/JsonRender.java b/core/src/main/java/org/openapitools/openapidiff/core/output/JsonRender.java index a0dfa09fb..b6629d5f9 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/output/JsonRender.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/output/JsonRender.java @@ -4,7 +4,8 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; -import java.nio.file.Paths; +import java.io.OutputStreamWriter; +import org.openapitools.openapidiff.core.exception.RendererException; import org.openapitools.openapidiff.core.model.ChangedOpenApi; public class JsonRender implements Render { @@ -17,21 +18,14 @@ public JsonRender() { } @Override - public String render(ChangedOpenApi diff) { + public void render(ChangedOpenApi diff, OutputStreamWriter outputStreamWriter) { try { - return objectMapper.writeValueAsString(diff); + objectMapper.writeValue(outputStreamWriter, diff); + outputStreamWriter.close(); } catch (JsonProcessingException e) { - throw new RuntimeException("Could not serialize diff as JSON", e); - } - } - - public void renderToFile(ChangedOpenApi diff, String file) { - try { - objectMapper.writeValue(Paths.get(file).toFile(), diff); - } catch (JsonProcessingException e) { - throw new RuntimeException("Could not serialize diff as JSON", e); + throw new RendererException("Could not serialize diff as JSON", e); } catch (IOException e) { - throw new RuntimeException("Could not write to JSON file", e); + throw new RendererException(e); } } } diff --git a/core/src/main/java/org/openapitools/openapidiff/core/output/MarkdownRender.java b/core/src/main/java/org/openapitools/openapidiff/core/output/MarkdownRender.java index 595b97cf5..5e0d0dd76 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/output/MarkdownRender.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/output/MarkdownRender.java @@ -11,11 +11,14 @@ import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.responses.ApiResponse; +import java.io.IOException; +import java.io.OutputStreamWriter; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang3.StringUtils; +import org.openapitools.openapidiff.core.exception.RendererException; import org.openapitools.openapidiff.core.model.*; import org.openapitools.openapidiff.core.utils.RefPointer; import org.openapitools.openapidiff.core.utils.RefType; @@ -44,28 +47,33 @@ public class MarkdownRender implements Render { */ protected boolean showChangedMetadata; - public String render(ChangedOpenApi diff) { + public void render(ChangedOpenApi diff, OutputStreamWriter outputStreamWriter) { this.diff = diff; this.handledSchemas.clear(); - return listEndpoints("What's New", diff.getNewEndpoints()) - + listEndpoints("What's Deleted", diff.getMissingEndpoints()) - + listEndpoints("What's Deprecated", diff.getDeprecatedEndpoints()) - + listEndpoints(diff.getChangedOperations()); + listEndpoints("What's New", diff.getNewEndpoints(), outputStreamWriter); + listEndpoints("What's Deleted", diff.getMissingEndpoints(), outputStreamWriter); + listEndpoints("What's Deprecated", diff.getDeprecatedEndpoints(), outputStreamWriter); + listEndpoints(diff.getChangedOperations(), outputStreamWriter); + try { + outputStreamWriter.close(); + } catch (IOException e) { + throw new RendererException(e); + } } protected String sectionTitle(String title) { return H4 + title + '\n' + HR + '\n'; } - protected String listEndpoints(String title, List endpoints) { + protected void listEndpoints( + String title, List endpoints, OutputStreamWriter outputStreamWriter) { if (null == endpoints || endpoints.isEmpty()) { - return ""; + return; } - StringBuilder sb = new StringBuilder(sectionTitle(title)); + safelyAppend(outputStreamWriter, sectionTitle(title)); endpoints.stream() .map(e -> itemEndpoint(e.getMethod().toString(), e.getPathUrl(), e.getSummary())) - .forEach(sb::append); - return sb.toString(); + .forEach(csq -> safelyAppend(outputStreamWriter, csq)); } protected String itemEndpoint(String method, String path, String summary) { @@ -80,41 +88,36 @@ protected String titleH5(String title) { return H6 + title + '\n'; } - protected String listEndpoints(List changedOperations) { + protected void listEndpoints( + List changedOperations, OutputStreamWriter outputStreamWriter) { if (null == changedOperations || changedOperations.isEmpty()) { - return ""; + return; } - StringBuilder sb = new StringBuilder(sectionTitle("What's Changed")); - changedOperations.stream() - .map( - operation -> { - StringBuilder details = - new StringBuilder() - .append( - itemEndpoint( - operation.getHttpMethod().toString(), - operation.getPathUrl(), - operation.getSummary())); - if (result(operation.getParameters()).isDifferent()) { - details - .append(titleH5("Parameters:")) - .append(parameters(operation.getParameters())); - } - if (operation.resultRequestBody().isDifferent()) { - details - .append(titleH5("Request:")) - .append(metadata("Description", operation.getRequestBody().getDescription())) - .append(bodyContent(operation.getRequestBody().getContent())); - } - if (operation.resultApiResponses().isDifferent()) { - details - .append(titleH5("Return Type:")) - .append(responses(operation.getApiResponses())); - } - return details.toString(); - }) - .forEach(sb::append); - return sb.toString(); + safelyAppend(outputStreamWriter, sectionTitle("What's Changed")); + changedOperations.forEach( + operation -> { + safelyAppend( + outputStreamWriter, + itemEndpoint( + operation.getHttpMethod().toString(), + operation.getPathUrl(), + operation.getSummary())); + if (result(operation.getParameters()).isDifferent()) { + safelyAppend(outputStreamWriter, titleH5("Parameters:")); + safelyAppend(outputStreamWriter, parameters(operation.getParameters())); + } + if (operation.resultRequestBody().isDifferent()) { + safelyAppend(outputStreamWriter, titleH5("Request:")); + safelyAppend( + outputStreamWriter, + metadata("Description", operation.getRequestBody().getDescription())); + safelyAppend(outputStreamWriter, bodyContent(operation.getRequestBody().getContent())); + } + if (operation.resultApiResponses().isDifferent()) { + safelyAppend(outputStreamWriter, titleH5("Return Type:")); + safelyAppend(outputStreamWriter, responses(operation.getApiResponses())); + } + }); } protected String responses(ChangedApiResponse changedApiResponse) { diff --git a/core/src/main/java/org/openapitools/openapidiff/core/output/Render.java b/core/src/main/java/org/openapitools/openapidiff/core/output/Render.java index 4a48ebcfa..8169f31cd 100644 --- a/core/src/main/java/org/openapitools/openapidiff/core/output/Render.java +++ b/core/src/main/java/org/openapitools/openapidiff/core/output/Render.java @@ -1,8 +1,19 @@ package org.openapitools.openapidiff.core.output; +import java.io.IOException; +import java.io.OutputStreamWriter; +import org.openapitools.openapidiff.core.exception.RendererException; import org.openapitools.openapidiff.core.model.ChangedOpenApi; public interface Render { - String render(ChangedOpenApi diff); + void render(ChangedOpenApi diff, OutputStreamWriter outputStreamWriter); + + default void safelyAppend(OutputStreamWriter outputStreamWriter, String csq) { + try { + outputStreamWriter.append(csq); + } catch (IOException ex) { + throw new RendererException(ex); + } + } } diff --git a/core/src/test/java/org/openapitools/openapidiff/core/AdditionalPropertiesTest.java b/core/src/test/java/org/openapitools/openapidiff/core/AdditionalPropertiesTest.java index df7885e08..7fabd712c 100644 --- a/core/src/test/java/org/openapitools/openapidiff/core/AdditionalPropertiesTest.java +++ b/core/src/test/java/org/openapitools/openapidiff/core/AdditionalPropertiesTest.java @@ -2,6 +2,8 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.io.ByteArrayOutputStream; +import java.io.OutputStreamWriter; import org.junit.jupiter.api.Test; import org.openapitools.openapidiff.core.model.ChangedOpenApi; import org.openapitools.openapidiff.core.output.ConsoleRender; @@ -9,8 +11,11 @@ class AdditionalPropertiesTest { @Test void booleanAdditionalPropertiesAreSupported() { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); ChangedOpenApi diff = OpenApiCompare.fromLocations("issue-256_1.json", "issue-256_2.json"); ConsoleRender render = new ConsoleRender(); - assertThat(render.render(diff)).isNotBlank(); + render.render(diff, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); } } 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 455631700..f56b4cb95 100644 --- a/core/src/test/java/org/openapitools/openapidiff/core/ConsoleRenderTest.java +++ b/core/src/test/java/org/openapitools/openapidiff/core/ConsoleRenderTest.java @@ -2,6 +2,8 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.io.ByteArrayOutputStream; +import java.io.OutputStreamWriter; import org.junit.jupiter.api.Test; import org.openapitools.openapidiff.core.model.ChangedOpenApi; import org.openapitools.openapidiff.core.output.ConsoleRender; @@ -10,16 +12,22 @@ public class ConsoleRenderTest { @Test 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"); - assertThat(render.render(diff)).isNotBlank(); + render.render(diff, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); } @Test public void renderDoesNotFailWhenHTTPStatusCodeIsRange() { ConsoleRender render = new ConsoleRender(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); ChangedOpenApi diff = OpenApiCompare.fromLocations("range_statuscode_1.yaml", "range_statuscode_2.yaml"); - assertThat(render.render(diff)).isNotBlank(); + render.render(diff, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); } } diff --git a/core/src/test/java/org/openapitools/openapidiff/core/HtmlRenderTest.java b/core/src/test/java/org/openapitools/openapidiff/core/HtmlRenderTest.java index 6273ef243..aa44725c4 100644 --- a/core/src/test/java/org/openapitools/openapidiff/core/HtmlRenderTest.java +++ b/core/src/test/java/org/openapitools/openapidiff/core/HtmlRenderTest.java @@ -2,6 +2,8 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.io.ByteArrayOutputStream; +import java.io.OutputStreamWriter; import org.junit.jupiter.api.Test; import org.openapitools.openapidiff.core.model.ChangedOpenApi; import org.openapitools.openapidiff.core.output.HtmlRender; @@ -10,8 +12,11 @@ public class HtmlRenderTest { @Test public void renderDoesNotFailWhenPropertyHasBeenRemoved() { HtmlRender render = new HtmlRender(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); ChangedOpenApi diff = OpenApiCompare.fromLocations("missing_property_1.yaml", "missing_property_2.yaml"); - assertThat(render.render(diff)).isNotBlank(); + render.render(diff, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); } } diff --git a/core/src/test/java/org/openapitools/openapidiff/core/JsonRenderTest.java b/core/src/test/java/org/openapitools/openapidiff/core/JsonRenderTest.java index aba54ea41..280dce9d0 100644 --- a/core/src/test/java/org/openapitools/openapidiff/core/JsonRenderTest.java +++ b/core/src/test/java/org/openapitools/openapidiff/core/JsonRenderTest.java @@ -2,6 +2,8 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.io.ByteArrayOutputStream; +import java.io.OutputStreamWriter; import org.junit.jupiter.api.Test; import org.openapitools.openapidiff.core.model.ChangedOpenApi; import org.openapitools.openapidiff.core.output.JsonRender; @@ -10,16 +12,22 @@ public class JsonRenderTest { @Test public void renderDoesNotFailWhenPropertyHasBeenRemoved() { JsonRender render = new JsonRender(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); ChangedOpenApi diff = OpenApiCompare.fromLocations("missing_property_1.yaml", "missing_property_2.yaml"); - assertThat(render.render(diff)).isNotBlank(); + render.render(diff, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); } @Test public void renderDoesNotFailForJsr310Types() { JsonRender render = new JsonRender(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); ChangedOpenApi diff = OpenApiCompare.fromLocations("jsr310_property_1.yaml", "jsr310_property_2.yaml"); - assertThat(render.render(diff)).isNotBlank(); + render.render(diff, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); } } diff --git a/core/src/test/java/org/openapitools/openapidiff/core/MarkdownRenderTest.java b/core/src/test/java/org/openapitools/openapidiff/core/MarkdownRenderTest.java index 36e007a8c..d30c6e0b1 100644 --- a/core/src/test/java/org/openapitools/openapidiff/core/MarkdownRenderTest.java +++ b/core/src/test/java/org/openapitools/openapidiff/core/MarkdownRenderTest.java @@ -2,6 +2,8 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.io.ByteArrayOutputStream; +import java.io.OutputStreamWriter; import org.junit.jupiter.api.Test; import org.openapitools.openapidiff.core.model.ChangedOpenApi; import org.openapitools.openapidiff.core.output.MarkdownRender; @@ -10,23 +12,32 @@ public class MarkdownRenderTest { @Test public void renderDoesNotFailWhenPropertyHasBeenRemoved() { MarkdownRender render = new MarkdownRender(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); ChangedOpenApi diff = OpenApiCompare.fromLocations("missing_property_1.yaml", "missing_property_2.yaml"); - assertThat(render.render(diff)).isNotBlank(); + render.render(diff, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); } @Test public void renderDoesNotCauseStackOverflowWithRecursiveDefinitions() { MarkdownRender render = new MarkdownRender(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); ChangedOpenApi diff = OpenApiCompare.fromLocations("recursive_old.yaml", "recursive_new.yaml"); - assertThat(render.render(diff)).isNotBlank(); + render.render(diff, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); } @Test public void renderDoesNotFailWhenHTTPStatusCodeIsRange() { MarkdownRender render = new MarkdownRender(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); ChangedOpenApi diff = OpenApiCompare.fromLocations("range_statuscode_1.yaml", "range_statuscode_2.yaml"); - assertThat(render.render(diff)).isNotBlank(); + render.render(diff, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); } } diff --git a/core/src/test/java/org/openapitools/openapidiff/core/OpenApiDiffTest.java b/core/src/test/java/org/openapitools/openapidiff/core/OpenApiDiffTest.java index 2d52392fe..ea21bd282 100644 --- a/core/src/test/java/org/openapitools/openapidiff/core/OpenApiDiffTest.java +++ b/core/src/test/java/org/openapitools/openapidiff/core/OpenApiDiffTest.java @@ -6,12 +6,10 @@ import io.swagger.parser.OpenAPIParser; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.parser.core.models.ParseOptions; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.file.Path; +import java.io.ByteArrayOutputStream; +import java.io.OutputStreamWriter; import java.util.List; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; import org.openapitools.openapidiff.core.model.ChangedOpenApi; import org.openapitools.openapidiff.core.model.ChangedOperation; import org.openapitools.openapidiff.core.model.DiffResult; @@ -19,6 +17,7 @@ import org.openapitools.openapidiff.core.output.HtmlRender; import org.openapitools.openapidiff.core.output.JsonRender; import org.openapitools.openapidiff.core.output.MarkdownRender; +import org.openapitools.openapidiff.core.output.Render; public class OpenApiDiffTest { @@ -35,7 +34,7 @@ public void testEqual() { } @Test - public void testNewApi(@TempDir Path tempDir) throws IOException { + public void testNewApi() { ChangedOpenApi changedOpenApi = OpenApiCompare.fromLocations(OPENAPI_EMPTY_DOC, OPENAPI_DOC2); List newEndpoints = changedOpenApi.getNewEndpoints(); List missingEndpoints = changedOpenApi.getMissingEndpoints(); @@ -44,18 +43,16 @@ public void testNewApi(@TempDir Path tempDir) throws IOException { assertThat(missingEndpoints).isEmpty(); assertThat(changedEndPoints).isEmpty(); - String html = - new HtmlRender("Changelog", "http://deepoove.com/swagger-diff/stylesheets/demo.css") - .render(changedOpenApi); - final Path path = tempDir.resolve("testNewApi.html"); - try (FileWriter fw = new FileWriter(path.toFile())) { - fw.write(html); - } - assertThat(path).isNotEmptyFile(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); + Render render = + new HtmlRender("Changelog", "http://deepoove.com/swagger-diff/stylesheets/demo.css"); + render.render(changedOpenApi, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); } @Test - public void testDeprecatedApi(@TempDir Path tempDir) throws IOException { + public void testDeprecatedApi() { ChangedOpenApi changedOpenApi = OpenApiCompare.fromLocations(OPENAPI_DOC1, OPENAPI_EMPTY_DOC); List newEndpoints = changedOpenApi.getNewEndpoints(); List missingEndpoints = changedOpenApi.getMissingEndpoints(); @@ -64,52 +61,46 @@ public void testDeprecatedApi(@TempDir Path tempDir) throws IOException { assertThat(missingEndpoints).isNotEmpty(); assertThat(changedEndPoints).isEmpty(); - String html = - new HtmlRender("Changelog", "http://deepoove.com/swagger-diff/stylesheets/demo.css") - .render(changedOpenApi); - final Path path = tempDir.resolve("testDeprecatedApi.html"); - try (FileWriter fw = new FileWriter(path.toFile())) { - fw.write(html); - } - assertThat(path).isNotEmptyFile(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); + Render render = + new HtmlRender("Changelog", "http://deepoove.com/swagger-diff/stylesheets/demo.css"); + render.render(changedOpenApi, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); } @Test - public void testDiff(@TempDir Path tempDir) throws IOException { + public void testDiff() { ChangedOpenApi changedOpenApi = OpenApiCompare.fromLocations(OPENAPI_DOC1, OPENAPI_DOC2); List changedEndPoints = changedOpenApi.getChangedOperations(); assertThat(changedEndPoints).isNotEmpty(); - String html = - new HtmlRender("Changelog", "http://deepoove.com/swagger-diff/stylesheets/demo.css") - .render(changedOpenApi); - final Path path = tempDir.resolve("testDiff.html"); - try (FileWriter fw = new FileWriter(path.toFile())) { - fw.write(html); - } - assertThat(path).isNotEmptyFile(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); + Render render = + new HtmlRender("Changelog", "http://deepoove.com/swagger-diff/stylesheets/demo.css"); + render.render(changedOpenApi, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); } @Test - public void testDiffAndMarkdown(@TempDir Path tempDir) throws IOException { + public void testDiffAndMarkdown() { ChangedOpenApi diff = OpenApiCompare.fromLocations(OPENAPI_DOC1, OPENAPI_DOC2); - String render = new MarkdownRender().render(diff); - final Path path = tempDir.resolve("testDiff.md"); - try (FileWriter fw = new FileWriter(path.toFile())) { - fw.write(render); - } - assertThat(path).isNotEmptyFile(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); + Render render = new MarkdownRender(); + render.render(diff, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); } @Test - public void testDiffAndJson(@TempDir Path tempDir) throws IOException { + public void testDiffAndJson() { ChangedOpenApi diff = OpenApiCompare.fromLocations(OPENAPI_DOC1, OPENAPI_DOC2); - String render = new JsonRender().render(diff); - final Path path = tempDir.resolve("testDiff.json"); - try (FileWriter fw = new FileWriter(path.toFile())) { - fw.write(render); - } - assertThat(path).isNotEmptyFile(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); + Render render = new JsonRender(); + render.render(diff, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); } /** Testing that repetitive specs comparisons has to produce consistent result. */ diff --git a/core/src/test/java/org/openapitools/openapidiff/core/ResponseAddedContentSchemaTest.java b/core/src/test/java/org/openapitools/openapidiff/core/ResponseAddedContentSchemaTest.java index a4f0cabb0..725c7e0e9 100644 --- a/core/src/test/java/org/openapitools/openapidiff/core/ResponseAddedContentSchemaTest.java +++ b/core/src/test/java/org/openapitools/openapidiff/core/ResponseAddedContentSchemaTest.java @@ -3,6 +3,8 @@ import static org.assertj.core.api.Assertions.assertThat; import io.swagger.v3.oas.models.media.Content; +import java.io.ByteArrayOutputStream; +import java.io.OutputStreamWriter; import java.util.Map; import org.junit.jupiter.api.Test; import org.openapitools.openapidiff.core.model.ChangedOpenApi; @@ -10,6 +12,7 @@ import org.openapitools.openapidiff.core.output.ConsoleRender; import org.openapitools.openapidiff.core.output.HtmlRender; import org.openapitools.openapidiff.core.output.MarkdownRender; +import org.openapitools.openapidiff.core.output.Render; public class ResponseAddedContentSchemaTest { @@ -39,8 +42,22 @@ public void testDiffDifferent() { public void testDiffCanBeRendered() { ChangedOpenApi changedOpenApi = OpenApiCompare.fromLocations(OPENAPI_DOC1, OPENAPI_DOC2); - assertThat(new ConsoleRender().render(changedOpenApi)).isNotBlank(); - assertThat(new HtmlRender().render(changedOpenApi)).isNotBlank(); - assertThat(new MarkdownRender().render(changedOpenApi)).isNotBlank(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); + Render render = new ConsoleRender(); + render.render(changedOpenApi, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); + + outputStream = new ByteArrayOutputStream(); + outputStreamWriter = new OutputStreamWriter(outputStream); + render = new HtmlRender(); + render.render(changedOpenApi, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); + + outputStream = new ByteArrayOutputStream(); + outputStreamWriter = new OutputStreamWriter(outputStream); + render = new MarkdownRender(); + render.render(changedOpenApi, outputStreamWriter); + assertThat(outputStream.toString()).isNotBlank(); } } diff --git a/maven/src/main/java/org/openapitools/openapidiff/maven/OpenApiDiffMojo.java b/maven/src/main/java/org/openapitools/openapidiff/maven/OpenApiDiffMojo.java index 7b1e679d4..af402c9f2 100644 --- a/maven/src/main/java/org/openapitools/openapidiff/maven/OpenApiDiffMojo.java +++ b/maven/src/main/java/org/openapitools/openapidiff/maven/OpenApiDiffMojo.java @@ -1,5 +1,7 @@ package org.openapitools.openapidiff.maven; +import java.io.ByteArrayOutputStream; +import java.io.OutputStreamWriter; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -37,7 +39,10 @@ public void execute() throws MojoExecutionException, MojoFailureException { try { final ChangedOpenApi diff = OpenApiCompare.fromLocations(oldSpec, newSpec); - getLog().info(new ConsoleRender().render(diff)); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); + new ConsoleRender().render(diff, outputStreamWriter); + getLog().info(outputStream.toString()); if (failOnIncompatible && diff.isIncompatible()) { throw new BackwardIncompatibilityException("The API changes broke backward compatibility");