diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliDocumentation.java index b22a2b04..4f44f964 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliDocumentation.java @@ -27,10 +27,13 @@ import org.springframework.restdocs.snippet.Snippet; * @author Andy Wilkinson * @author Paul-Christian Volkmer * @author Raman Gupta + * @author Tomasz Kopczynski * @since 1.1.0 */ public abstract class CliDocumentation { + static final CommandFormatter DEFAULT_COMMAND_FORMATTER = multiLineFormat(); + private CliDocumentation() { } @@ -42,7 +45,7 @@ public abstract class CliDocumentation { * @return the snippet that will document the curl request */ public static Snippet curlRequest() { - return new CurlRequestSnippet(); + return curlRequest(DEFAULT_COMMAND_FORMATTER); } /** @@ -54,7 +57,36 @@ public abstract class CliDocumentation { * @return the snippet that will document the curl request */ public static Snippet curlRequest(Map attributes) { - return new CurlRequestSnippet(attributes); + return curlRequest(attributes, DEFAULT_COMMAND_FORMATTER); + } + + /** + * Returns a new {@code Snippet} that will document the curl request for the API + * operation. The given {@code commandFormatter} will be used to format the curl + * command in the snippet. + * + * @param commandFormatter the command formatter + * @return the snippet that will document the curl request + * @since 1.2.0 + */ + public static Snippet curlRequest(CommandFormatter commandFormatter) { + return curlRequest(null, commandFormatter); + } + + /** + * Returns a new {@code Snippet} that will document the curl request for the API + * operation. The given {@code attributes} will be available during snippet + * generation. The given {@code commandFormatter} will be used to format the curl + * command in the snippet. + * + * @param attributes the attributes + * @param commandFormatter the command formatter + * @return the snippet that will document the curl request + * @since 1.2.0 + */ + public static Snippet curlRequest(Map attributes, + CommandFormatter commandFormatter) { + return new CurlRequestSnippet(attributes, commandFormatter); } /** @@ -64,7 +96,7 @@ public abstract class CliDocumentation { * @return the snippet that will document the HTTPie request */ public static Snippet httpieRequest() { - return new HttpieRequestSnippet(); + return httpieRequest(DEFAULT_COMMAND_FORMATTER); } /** @@ -76,7 +108,54 @@ public abstract class CliDocumentation { * @return the snippet that will document the HTTPie request */ public static Snippet httpieRequest(Map attributes) { - return new HttpieRequestSnippet(attributes); + return httpieRequest(attributes, DEFAULT_COMMAND_FORMATTER); + } + + /** + * Returns a new {@code Snippet} that will document the HTTPie request for the API + * operation. The given {@code commandFormatter} will be used to format the HTTPie + * command in the snippet. + * + * @param commandFormatter the command formatter + * @return the snippet that will document the HTTPie request + * @since 1.2.0 + */ + public static Snippet httpieRequest(CommandFormatter commandFormatter) { + return httpieRequest(null, commandFormatter); + } + + /** + * Returns a new {@code Snippet} that will document the HTTPie request for the API + * operation. The given {@code attributes} will be available during snippet + * generation. The given {@code commandFormatter} will be used to format the HTTPie + * command in the snippet snippet. + * + * @param attributes the attributes + * @param commandFormatter the command formatter + * @return the snippet that will document the HTTPie request + * @since 1.2.0 + */ + public static Snippet httpieRequest(Map attributes, + CommandFormatter commandFormatter) { + return new HttpieRequestSnippet(attributes, commandFormatter); + } + + /** + * Creates a new {@code CommandFormatter} that produces multi-line output. + * + * @return A multi-line {@code CommandFormatter} + */ + public static CommandFormatter multiLineFormat() { + return new ConcatenatingCommandFormatter(" \\%n "); + } + + /** + * Creates a new {@code CommandFormatter} that produces single-line output. + * + * @return A single-line {@code CommandFormatter} + */ + public static CommandFormatter singleLineFormat() { + return new ConcatenatingCommandFormatter(" "); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CommandFormatter.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CommandFormatter.java new file mode 100644 index 00000000..da6d43ce --- /dev/null +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CommandFormatter.java @@ -0,0 +1,38 @@ +/* + * Copyright 2014-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.restdocs.cli; + +import java.util.List; + +/** + * Formatter for CLI commands such as those included in {@link CurlRequestSnippet} and + * {@link HttpieRequestSnippet}. + * + * @author Tomasz Kopczynski + * @since 1.2.0 + */ +public interface CommandFormatter { + + /** + * Formats a list of {@code elements} into a single {@code String}. + * + * @param elements The {@code String} elements to be formatted + * @return A single formatted {@code String} + */ + String format(List elements); + +} diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/ConcatenatingCommandFormatter.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/ConcatenatingCommandFormatter.java new file mode 100644 index 00000000..b95f8df2 --- /dev/null +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/ConcatenatingCommandFormatter.java @@ -0,0 +1,57 @@ +/* + * Copyright 2014-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.restdocs.cli; + +import java.util.List; + +import org.springframework.util.CollectionUtils; + +/** + * {@link CommandFormatter} which concatenates commands with a given {@code separator}. + * + * @author Tomasz Kopczynski + */ +final class ConcatenatingCommandFormatter implements CommandFormatter { + + private String separator; + + ConcatenatingCommandFormatter(String separator) { + this.separator = separator; + } + + /** + * Concatenates a list of {@code String}s with a specified separator. + * + * @param elements A list of {@code String}s to be concatenated + * @return Concatenated list of {@code String}s as one {@code String} + */ + @Override + public String format(List elements) { + if (CollectionUtils.isEmpty(elements)) { + return ""; + } + + StringBuilder result = new StringBuilder(); + + for (String element : elements) { + result.append(String.format(this.separator)); + result.append(element); + } + + return result.toString(); + } +} diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CurlRequestSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CurlRequestSnippet.java index 1fb6140a..23161fcb 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CurlRequestSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CurlRequestSnippet.java @@ -16,8 +16,7 @@ package org.springframework.restdocs.cli; -import java.io.PrintWriter; -import java.io.StringWriter; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -31,6 +30,7 @@ import org.springframework.restdocs.operation.Parameters; import org.springframework.restdocs.operation.RequestCookie; import org.springframework.restdocs.snippet.Snippet; import org.springframework.restdocs.snippet.TemplatedSnippet; +import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; @@ -39,17 +39,35 @@ import org.springframework.util.StringUtils; * * @author Andy Wilkinson * @author Paul-Christian Volkmer + * @author Tomasz Kopczynski * @since 1.1.0 * @see CliDocumentation#curlRequest() + * @see CliDocumentation#curlRequest(CommandFormatter) * @see CliDocumentation#curlRequest(Map) + * @see CliDocumentation#curlRequest(Map, CommandFormatter) */ public class CurlRequestSnippet extends TemplatedSnippet { + private final CommandFormatter commandFormatter; + /** * Creates a new {@code CurlRequestSnippet} with no additional attributes. + * + * @deprecated since 1.2.0 in favor of {@link #CurlRequestSnippet(CommandFormatter)} */ + @Deprecated protected CurlRequestSnippet() { - this(null); + this(null, CliDocumentation.DEFAULT_COMMAND_FORMATTER); + } + + /** + * Creates a new {@code CurlRequestSnippet} that will use the given + * {@code commandFormatter} to format the curl command. + * + * @param commandFormatter The formatter + */ + protected CurlRequestSnippet(CommandFormatter commandFormatter) { + this(null, commandFormatter); } /** @@ -57,9 +75,27 @@ public class CurlRequestSnippet extends TemplatedSnippet { * {@code attributes} that will be included in the model during template rendering. * * @param attributes The additional attributes + * @deprecated since 1.2.0 in favor of + * {@link #CurlRequestSnippet(Map, CommandFormatter)} */ + @Deprecated protected CurlRequestSnippet(Map attributes) { + this(attributes, CliDocumentation.DEFAULT_COMMAND_FORMATTER); + } + + /** + * Creates a new {@code CurlRequestSnippet} with the given additional + * {@code attributes} that will be included in the model during template rendering. + * The given {@code commandFormaatter} will be used to format the curl command. + * + * @param attributes The additional attributes + * @param commandFormatter The formatter for generating the snippet + */ + protected CurlRequestSnippet(Map attributes, + CommandFormatter commandFormatter) { super("curl-request", attributes); + Assert.notNull(commandFormatter, "Command formatter must not be null"); + this.commandFormatter = commandFormatter; } @Override @@ -87,21 +123,25 @@ public class CurlRequestSnippet extends TemplatedSnippet { } private String getOptions(Operation operation) { - StringWriter command = new StringWriter(); - PrintWriter printer = new PrintWriter(command); - writeIncludeHeadersInOutputOption(printer); - CliOperationRequest request = new CliOperationRequest(operation.getRequest()); - writeUserOptionIfNecessary(request, printer); - writeHttpMethodIfNecessary(request, printer); - writeHeaders(request, printer); - writeCookies(request, printer); - writePartsIfNecessary(request, printer); - writeContent(request, printer); + StringBuilder builder = new StringBuilder(); + writeIncludeHeadersInOutputOption(builder); - return command.toString(); + CliOperationRequest request = new CliOperationRequest(operation.getRequest()); + writeUserOptionIfNecessary(request, builder); + writeHttpMethodIfNecessary(request, builder); + + List additionaLines = new ArrayList<>(); + writeHeaders(request, additionaLines); + writeCookies(request, additionaLines); + writePartsIfNecessary(request, additionaLines); + writeContent(request, additionaLines); + + builder.append(this.commandFormatter.format(additionaLines)); + + return builder.toString(); } - private void writeCookies(CliOperationRequest request, PrintWriter printer) { + private void writeCookies(CliOperationRequest request, List lines) { if (!CollectionUtils.isEmpty(request.getCookies())) { StringBuilder cookiesBuilder = new StringBuilder(); for (RequestCookie cookie : request.getCookies()) { @@ -111,79 +151,82 @@ public class CurlRequestSnippet extends TemplatedSnippet { cookiesBuilder.append( String.format("%s=%s", cookie.getName(), cookie.getValue())); } - printer.print(String.format(" --cookie '%s'", cookiesBuilder.toString())); + lines.add(String.format("--cookie '%s'", cookiesBuilder.toString())); } } - private void writeIncludeHeadersInOutputOption(PrintWriter writer) { - writer.print("-i"); + private void writeIncludeHeadersInOutputOption(StringBuilder builder) { + builder.append("-i"); } private void writeUserOptionIfNecessary(CliOperationRequest request, - PrintWriter writer) { + StringBuilder builder) { String credentials = request.getBasicAuthCredentials(); if (credentials != null) { - writer.print(String.format(" -u '%s'", credentials)); + builder.append(String.format(" -u '%s'", credentials)); } } private void writeHttpMethodIfNecessary(OperationRequest request, - PrintWriter writer) { + StringBuilder builder) { if (!HttpMethod.GET.equals(request.getMethod())) { - writer.print(String.format(" -X %s", request.getMethod())); + builder.append(String.format(" -X %s", request.getMethod())); } } - private void writeHeaders(CliOperationRequest request, PrintWriter writer) { + private void writeHeaders(CliOperationRequest request, List lines) { for (Entry> entry : request.getHeaders().entrySet()) { for (String header : entry.getValue()) { - writer.print(String.format(" -H '%s: %s'", entry.getKey(), header)); + lines.add(String.format("-H '%s: %s'", entry.getKey(), header)); } } } - private void writePartsIfNecessary(OperationRequest request, PrintWriter writer) { + private void writePartsIfNecessary(OperationRequest request, List lines) { for (OperationRequestPart part : request.getParts()) { - writer.printf(" -F '%s=", part.getName()); + + StringBuilder oneLine = new StringBuilder(); + oneLine.append(String.format("-F '%s=", part.getName())); if (!StringUtils.hasText(part.getSubmittedFileName())) { - writer.append(part.getContentAsString()); + oneLine.append(part.getContentAsString()); } else { - writer.printf("@%s", part.getSubmittedFileName()); + oneLine.append(String.format("@%s", part.getSubmittedFileName())); } if (part.getHeaders().getContentType() != null) { - writer.append(";type=") - .append(part.getHeaders().getContentType().toString()); + oneLine.append(";type="); + oneLine.append(part.getHeaders().getContentType().toString()); } - writer.append("'"); + oneLine.append("'"); + lines.add(oneLine.toString()); } } - private void writeContent(CliOperationRequest request, PrintWriter writer) { + private void writeContent(CliOperationRequest request, List lines) { String content = request.getContentAsString(); if (StringUtils.hasText(content)) { - writer.print(String.format(" -d '%s'", content)); + lines.add(String.format("-d '%s'", content)); } else if (!request.getParts().isEmpty()) { for (Entry> entry : request.getParameters().entrySet()) { for (String value : entry.getValue()) { - writer.print(String.format(" -F '%s=%s'", entry.getKey(), value)); + lines.add(String.format("-F '%s=%s'", entry.getKey(), value)); } } } else if (request.isPutOrPost()) { - writeContentUsingParameters(request, writer); + writeContentUsingParameters(request, lines); } } private void writeContentUsingParameters(OperationRequest request, - PrintWriter writer) { + List lines) { Parameters uniqueParameters = request.getParameters() .getUniqueParameters(request.getUri()); String queryString = uniqueParameters.toQueryString(); if (StringUtils.hasText(queryString)) { - writer.print(String.format(" -d '%s'", queryString)); + lines.add(String.format("-d '%s'", queryString)); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/HttpieRequestSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/HttpieRequestSnippet.java index 410495fe..529e8230 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/HttpieRequestSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/HttpieRequestSnippet.java @@ -18,6 +18,7 @@ package org.springframework.restdocs.cli; import java.io.PrintWriter; import java.io.StringWriter; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -33,6 +34,7 @@ import org.springframework.restdocs.operation.Parameters; import org.springframework.restdocs.operation.RequestCookie; import org.springframework.restdocs.snippet.Snippet; import org.springframework.restdocs.snippet.TemplatedSnippet; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** @@ -40,17 +42,33 @@ import org.springframework.util.StringUtils; * * @author Raman Gupta * @author Andy Wilkinson + * @author Tomasz Kopczynski * @since 1.1.0 * @see CliDocumentation#httpieRequest() * @see CliDocumentation#httpieRequest(Map) */ public class HttpieRequestSnippet extends TemplatedSnippet { + private final CommandFormatter commandFormatter; + /** * Creates a new {@code HttpieRequestSnippet} with no additional attributes. + * + * @deprecated since 1.2.0 in favor of {@link #HttpieRequestSnippet(CommandFormatter)} */ + @Deprecated protected HttpieRequestSnippet() { - this(null); + this(null, null); + } + + /** + * Creates a new {@code HttpieRequestSnippet} that will use the given + * {@code commandFormatter} to format the HTTPie command. + * + * @param commandFormatter The formatter + */ + protected HttpieRequestSnippet(CommandFormatter commandFormatter) { + this(null, commandFormatter); } /** @@ -58,9 +76,27 @@ public class HttpieRequestSnippet extends TemplatedSnippet { * {@code attributes} that will be included in the model during template rendering. * * @param attributes The additional attributes + * @deprecated since 1.2.0 in favor of + * {@link #HttpieRequestSnippet(Map, CommandFormatter)} */ + @Deprecated protected HttpieRequestSnippet(Map attributes) { + this(attributes, null); + } + + /** + * Creates a new {@code HttpieRequestSnippet} with the given additional + * {@code attributes} that will be included in the model during template rendering. + * The given {@code commandFormaatter} will be used to format the HTTPie command. + * + * @param attributes The additional attributes + * @param commandFormatter The formatter for generating the snippet + */ + protected HttpieRequestSnippet(Map attributes, + CommandFormatter commandFormatter) { super("httpie-request", attributes); + Assert.notNull(commandFormatter, "Command formatter must not be null"); + this.commandFormatter = commandFormatter; } @Override @@ -103,13 +139,14 @@ public class HttpieRequestSnippet extends TemplatedSnippet { } private String getRequestItems(CliOperationRequest request) { - StringWriter requestItems = new StringWriter(); - PrintWriter printer = new PrintWriter(requestItems); - writeFormDataIfNecessary(request, printer); - writeHeaders(request, printer); - writeCookies(request, printer); - writeParametersIfNecessary(request, printer); - return requestItems.toString(); + List lines = new ArrayList<>(); + + writeFormDataIfNecessary(request, lines); + writeHeaders(request, lines); + writeCookies(request, lines); + writeParametersIfNecessary(request, lines); + + return this.commandFormatter.format(lines); } private void writeOptions(OperationRequest request, PrintWriter writer) { @@ -136,20 +173,23 @@ public class HttpieRequestSnippet extends TemplatedSnippet { writer.print(String.format("%s", request.getMethod().name())); } - private void writeFormDataIfNecessary(OperationRequest request, PrintWriter writer) { + private void writeFormDataIfNecessary(OperationRequest request, List lines) { for (OperationRequestPart part : request.getParts()) { - writer.printf(" \\%n '%s'", part.getName()); + StringBuilder oneLine = new StringBuilder(); + oneLine.append(String.format("'%s'", part.getName())); if (!StringUtils.hasText(part.getSubmittedFileName())) { // https://github.com/jkbrzt/httpie/issues/342 - writer.printf("@<(echo '%s')", part.getContentAsString()); + oneLine.append(String.format("@<(echo '%s')", part.getContentAsString())); } else { - writer.printf("@'%s'", part.getSubmittedFileName()); + oneLine.append(String.format("@'%s'", part.getSubmittedFileName())); } + + lines.add(oneLine.toString()); } } - private void writeHeaders(OperationRequest request, PrintWriter writer) { + private void writeHeaders(OperationRequest request, List lines) { HttpHeaders headers = request.getHeaders(); for (Entry> entry : headers.entrySet()) { for (String header : entry.getValue()) { @@ -159,41 +199,40 @@ public class HttpieRequestSnippet extends TemplatedSnippet { && header.startsWith(MediaType.MULTIPART_FORM_DATA_VALUE)) { continue; } - writer.print(String.format(" '%s:%s'", entry.getKey(), header)); + lines.add(String.format("'%s:%s'", entry.getKey(), header)); } } } - private void writeCookies(OperationRequest request, PrintWriter writer) { + private void writeCookies(OperationRequest request, List lines) { for (RequestCookie cookie : request.getCookies()) { - writer.print(String.format(" 'Cookie:%s=%s'", cookie.getName(), - cookie.getValue())); + lines.add( + String.format("'Cookie:%s=%s'", cookie.getName(), cookie.getValue())); } } private void writeParametersIfNecessary(CliOperationRequest request, - PrintWriter writer) { + List lines) { if (StringUtils.hasText(request.getContentAsString())) { return; } if (!request.getParts().isEmpty()) { - writeContentUsingParameters(request.getParameters(), writer); + writeContentUsingParameters(request.getParameters(), lines); } else if (request.isPutOrPost()) { writeContentUsingParameters( - request.getParameters().getUniqueParameters(request.getUri()), - writer); + request.getParameters().getUniqueParameters(request.getUri()), lines); } } - private void writeContentUsingParameters(Parameters parameters, PrintWriter writer) { + private void writeContentUsingParameters(Parameters parameters, List lines) { for (Map.Entry> entry : parameters.entrySet()) { if (entry.getValue().isEmpty()) { - writer.append(String.format(" '%s='", entry.getKey())); + lines.add(String.format("'%s='", entry.getKey())); } else { for (String value : entry.getValue()) { - writer.append(String.format(" '%s=%s'", entry.getKey(), value)); + lines.add(String.format("'%s=%s'", entry.getKey(), value)); } } } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/ConcatenatingCommandFormatterTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/ConcatenatingCommandFormatterTests.java new file mode 100644 index 00000000..fe5fe13a --- /dev/null +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/ConcatenatingCommandFormatterTests.java @@ -0,0 +1,61 @@ +/* + * Copyright 2014-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.restdocs.cli; + +import java.util.Arrays; +import java.util.Collections; + +import org.junit.Test; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +/** + * Tests for {@link CommandFormatter}. + * + * @author Tomasz Kopczynski + * @author Andy Wilkinson + */ +public class ConcatenatingCommandFormatterTests { + + private CommandFormatter singleLineFormat = new ConcatenatingCommandFormatter(" "); + + @Test + public void formattingAnEmptyListProducesAnEmptyString() { + assertThat(this.singleLineFormat.format(Collections.emptyList()), + is(equalTo(""))); + } + + @Test + public void formattingNullProducesAnEmptyString() { + assertThat(this.singleLineFormat.format(null), is(equalTo(""))); + } + + @Test + public void formattingASingleElement() { + assertThat(this.singleLineFormat.format(Collections.singletonList("alpha")), + is(equalTo(" alpha"))); + } + + @Test + public void formattingMultipleElements() { + assertThat(this.singleLineFormat.format(Arrays.asList("alpha", "bravo")), + is(equalTo(String.format(" alpha bravo")))); + } + +} diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java index 33d6aa88..a6ecd8a8 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java @@ -45,10 +45,13 @@ import static org.springframework.restdocs.snippet.Attributes.key; * @author Dmitriy Mayboroda * @author Jonathan Pearlin * @author Paul-Christian Volkmer + * @author Tomasz Kopczynski */ @RunWith(Parameterized.class) public class CurlRequestSnippetTests extends AbstractSnippetTests { + private CommandFormatter commandFormatter = CliDocumentation.singleLineFormat(); + public CurlRequestSnippetTests(String name, TemplateFormat templateFormat) { super(name, templateFormat); } @@ -57,7 +60,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { public void getRequest() throws IOException { this.snippets.expectCurlRequest().withContents( codeBlock("bash").content("$ curl 'http://localhost/foo' -i")); - new CurlRequestSnippet() + new CurlRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo").build()); } @@ -65,7 +68,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { public void getRequestWithParameter() throws IOException { this.snippets.expectCurlRequest().withContents( codeBlock("bash").content("$ curl 'http://localhost/foo?a=alpha' -i")); - new CurlRequestSnippet().document(this.operationBuilder + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo").param("a", "alpha").build()); } @@ -73,7 +76,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { public void nonGetRequest() throws IOException { this.snippets.expectCurlRequest().withContents( codeBlock("bash").content("$ curl 'http://localhost/foo' -i -X POST")); - new CurlRequestSnippet().document(this.operationBuilder + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo").method("POST").build()); } @@ -81,7 +84,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { public void requestWithContent() throws IOException { this.snippets.expectCurlRequest().withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo' -i -d 'content'")); - new CurlRequestSnippet().document(this.operationBuilder + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo").content("content").build()); } @@ -89,7 +92,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { public void getRequestWithQueryString() throws IOException { this.snippets.expectCurlRequest().withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo?param=value' -i")); - new CurlRequestSnippet().document(this.operationBuilder + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo?param=value").build()); } @@ -98,7 +101,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { throws IOException { this.snippets.expectCurlRequest().withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo?param=value' -i")); - new CurlRequestSnippet().document( + new CurlRequestSnippet(this.commandFormatter).document( this.operationBuilder.request("http://localhost/foo?param=value") .param("param", "value").build()); } @@ -108,7 +111,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { throws IOException { this.snippets.expectCurlRequest().withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i")); - new CurlRequestSnippet() + new CurlRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo?a=alpha") .param("a", "alpha").param("b", "bravo").build()); } @@ -117,7 +120,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { public void getRequestWithDisjointQueryStringAndParameters() throws IOException { this.snippets.expectCurlRequest().withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i")); - new CurlRequestSnippet().document(this.operationBuilder + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo?a=alpha").param("b", "bravo").build()); } @@ -125,7 +128,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { public void getRequestWithQueryStringWithNoValue() throws IOException { this.snippets.expectCurlRequest().withContents( codeBlock("bash").content("$ curl 'http://localhost/foo?param' -i")); - new CurlRequestSnippet().document( + new CurlRequestSnippet(this.commandFormatter).document( this.operationBuilder.request("http://localhost/foo?param").build()); } @@ -133,7 +136,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { public void postRequestWithQueryString() throws IOException { this.snippets.expectCurlRequest().withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo?param=value' -i -X POST")); - new CurlRequestSnippet().document(this.operationBuilder + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo?param=value").method("POST").build()); } @@ -141,7 +144,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { public void postRequestWithQueryStringWithNoValue() throws IOException { this.snippets.expectCurlRequest().withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo?param' -i -X POST")); - new CurlRequestSnippet().document(this.operationBuilder + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo?param").method("POST").build()); } @@ -149,7 +152,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { public void postRequestWithOneParameter() throws IOException { this.snippets.expectCurlRequest().withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo' -i -X POST -d 'k1=v1'")); - new CurlRequestSnippet() + new CurlRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo") .method("POST").param("k1", "v1").build()); } @@ -158,7 +161,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { public void postRequestWithOneParameterWithNoValue() throws IOException { this.snippets.expectCurlRequest().withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo' -i -X POST -d 'k1='")); - new CurlRequestSnippet().document(this.operationBuilder + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo").method("POST").param("k1").build()); } @@ -168,7 +171,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { .withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo' -i -X POST" + " -d 'k1=v1&k1=v1-bis&k2=v2'")); - new CurlRequestSnippet().document( + new CurlRequestSnippet(this.commandFormatter).document( this.operationBuilder.request("http://localhost/foo").method("POST") .param("k1", "v1", "v1-bis").param("k2", "v2").build()); } @@ -177,7 +180,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { public void postRequestWithUrlEncodedParameter() throws IOException { this.snippets.expectCurlRequest().withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo' -i -X POST -d 'k1=a%26b'")); - new CurlRequestSnippet() + new CurlRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo") .method("POST").param("k1", "a&b").build()); } @@ -186,7 +189,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { public void postRequestWithDisjointQueryStringAndParameter() throws IOException { this.snippets.expectCurlRequest().withContents(codeBlock("bash").content( "$ curl 'http://localhost/foo?a=alpha' -i -X POST -d 'b=bravo'")); - new CurlRequestSnippet() + new CurlRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo?a=alpha") .method("POST").param("b", "bravo").build()); } @@ -196,7 +199,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { throws IOException { this.snippets.expectCurlRequest().withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i -X POST")); - new CurlRequestSnippet().document( + new CurlRequestSnippet(this.commandFormatter).document( this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo") .method("POST").param("a", "alpha").param("b", "bravo").build()); } @@ -206,7 +209,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { throws IOException { this.snippets.expectCurlRequest().withContents(codeBlock("bash").content( "$ curl 'http://localhost/foo?a=alpha' -i -X POST -d 'b=bravo'")); - new CurlRequestSnippet() + new CurlRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo?a=alpha") .method("POST").param("a", "alpha").param("b", "bravo").build()); } @@ -215,7 +218,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { public void putRequestWithOneParameter() throws IOException { this.snippets.expectCurlRequest().withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo' -i -X PUT -d 'k1=v1'")); - new CurlRequestSnippet().document(this.operationBuilder + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo").method("PUT").param("k1", "v1").build()); } @@ -225,7 +228,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { .withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo' -i -X PUT" + " -d 'k1=v1&k1=v1-bis&k2=v2'")); - new CurlRequestSnippet().document(this.operationBuilder + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo").method("PUT").param("k1", "v1") .param("k1", "v1-bis").param("k2", "v2").build()); } @@ -234,7 +237,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { public void putRequestWithUrlEncodedParameter() throws IOException { this.snippets.expectCurlRequest().withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo' -i -X PUT -d 'k1=a%26b'")); - new CurlRequestSnippet() + new CurlRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo") .method("PUT").param("k1", "a&b").build()); } @@ -244,7 +247,21 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { this.snippets.expectCurlRequest() .withContents(codeBlock("bash").content("$ curl 'http://localhost/foo' -i" + " -H 'Content-Type: application/json' -H 'a: alpha'")); - new CurlRequestSnippet() + new CurlRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo") + .header(HttpHeaders.CONTENT_TYPE, + MediaType.APPLICATION_JSON_VALUE) + .header("a", "alpha").build()); + } + + @Test + public void requestWithHeadersMultiline() throws IOException { + this.snippets.expectCurlRequest() + .withContents(codeBlock("bash") + .content(String.format("$ curl 'http://localhost/foo' -i \\%n" + + " -H 'Content-Type: application/json' \\%n" + + " -H 'a: alpha'"))); + new CurlRequestSnippet(CliDocumentation.multiLineFormat()) .document(this.operationBuilder.request("http://localhost/foo") .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) @@ -256,7 +273,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { this.snippets.expectCurlRequest() .withContents(codeBlock("bash").content("$ curl 'http://localhost/foo' -i" + " --cookie 'name1=value1;name2=value2'")); - new CurlRequestSnippet() + new CurlRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo") .cookie("name1", "value1").cookie("name2", "value2").build()); } @@ -268,11 +285,11 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { + "'metadata={\"description\": \"foo\"}'"; this.snippets.expectCurlRequest() .withContents(codeBlock("bash").content(expectedContent)); - new CurlRequestSnippet().document( + new CurlRequestSnippet(this.commandFormatter).document( this.operationBuilder.request("http://localhost/upload").method("POST") .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("metadata", "{\"description\": \"foo\"}".getBytes()).build()); + .part("metadata", "{\"description\": \"foo\"}".getBytes()).build()); } @Test @@ -282,13 +299,13 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { + "'image=@documents/images/example.png;type=image/png'"; this.snippets.expectCurlRequest() .withContents(codeBlock("bash").content(expectedContent)); - new CurlRequestSnippet().document( + new CurlRequestSnippet(this.commandFormatter).document( this.operationBuilder.request("http://localhost/upload").method("POST") .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("image", new byte[0]) - .header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE) - .submittedFileName("documents/images/example.png").build()); + .part("image", new byte[0]) + .header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE) + .submittedFileName("documents/images/example.png").build()); } @Test @@ -298,12 +315,12 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { + "'image=@documents/images/example.png'"; this.snippets.expectCurlRequest() .withContents(codeBlock("bash").content(expectedContent)); - new CurlRequestSnippet().document( + new CurlRequestSnippet(this.commandFormatter).document( this.operationBuilder.request("http://localhost/upload").method("POST") .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("image", new byte[0]) - .submittedFileName("documents/images/example.png").build()); + .part("image", new byte[0]) + .submittedFileName("documents/images/example.png").build()); } @Test @@ -314,25 +331,25 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { + "-F 'b=banana'"; this.snippets.expectCurlRequest() .withContents(codeBlock("bash").content(expectedContent)); - new CurlRequestSnippet().document( + new CurlRequestSnippet(this.commandFormatter).document( this.operationBuilder.request("http://localhost/upload").method("POST") .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("image", new byte[0]) - .submittedFileName("documents/images/example.png").and() - .param("a", "apple", "avocado").param("b", "banana").build()); + .part("image", new byte[0]) + .submittedFileName("documents/images/example.png").and() + .param("a", "apple", "avocado").param("b", "banana").build()); } @Test public void basicAuthCredentialsAreSuppliedUsingUserOption() throws IOException { this.snippets.expectCurlRequest().withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo' -i -u 'user:secret'")); - new CurlRequestSnippet() + new CurlRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo") .header(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils .encodeToString("user:secret".getBytes())) - .build()); + .build()); } @Test @@ -344,13 +361,12 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { .willReturn(snippetResource("curl-request-with-title")); new CurlRequestSnippet( attributes( - key("title").value("curl request title"))) - .document( - this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine( - resolver)) - .request("http://localhost/foo").build()); + key("title").value("curl request title")), + this.commandFormatter) + .document(this.operationBuilder + .attribute(TemplateEngine.class.getName(), + new MustacheTemplateEngine(resolver)) + .request("http://localhost/foo").build()); } @Test @@ -359,7 +375,7 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { .withContents(codeBlock("bash").content( "$ curl 'http://localhost/foo' -i" + " -H 'Host: api.example.com'" + " -H 'Content-Type: application/json' -H 'a: alpha'")); - new CurlRequestSnippet() + new CurlRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo") .header(HttpHeaders.HOST, "api.example.com") .header(HttpHeaders.CONTENT_TYPE, @@ -373,9 +389,8 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { .withContents(codeBlock("bash") .content("$ curl 'http://localhost/foo?a=alpha&b=bravo' -i " + "-X POST -d 'Some content'")); - new CurlRequestSnippet().document(this.operationBuilder + new CurlRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo").param("a", "alpha").method("POST") .param("b", "bravo").content("Some content").build()); } - } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java index acb12cb9..233d5d96 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java @@ -46,10 +46,14 @@ import static org.springframework.restdocs.snippet.Attributes.key; * @author Jonathan Pearlin * @author Paul-Christian Volkmer * @author Raman Gupta + * @author Tomasz Kopczynski + * */ @RunWith(Parameterized.class) public class HttpieRequestSnippetTests extends AbstractSnippetTests { + private CommandFormatter commandFormatter = CliDocumentation.singleLineFormat(); + public HttpieRequestSnippetTests(String name, TemplateFormat templateFormat) { super(name, templateFormat); } @@ -58,7 +62,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { public void getRequest() throws IOException { this.snippets.expectHttpieRequest().withContents( codeBlock("bash").content("$ http GET 'http://localhost/foo'")); - new HttpieRequestSnippet() + new HttpieRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo").build()); } @@ -66,7 +70,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { public void getRequestWithParameter() throws IOException { this.snippets.expectHttpieRequest().withContents( codeBlock("bash").content("$ http GET 'http://localhost/foo?a=alpha'")); - new HttpieRequestSnippet().document(this.operationBuilder + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo").param("a", "alpha").build()); } @@ -74,7 +78,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { public void nonGetRequest() throws IOException { this.snippets.expectHttpieRequest().withContents( codeBlock("bash").content("$ http POST 'http://localhost/foo'")); - new HttpieRequestSnippet().document(this.operationBuilder + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo").method("POST").build()); } @@ -82,7 +86,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { public void requestWithContent() throws IOException { this.snippets.expectHttpieRequest().withContents(codeBlock("bash") .content("$ echo 'content' | http GET 'http://localhost/foo'")); - new HttpieRequestSnippet().document(this.operationBuilder + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo").content("content").build()); } @@ -90,7 +94,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { public void getRequestWithQueryString() throws IOException { this.snippets.expectHttpieRequest().withContents(codeBlock("bash") .content("$ http GET 'http://localhost/foo?param=value'")); - new HttpieRequestSnippet().document(this.operationBuilder + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo?param=value").build()); } @@ -99,7 +103,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { throws IOException { this.snippets.expectHttpieRequest().withContents(codeBlock("bash") .content("$ http GET 'http://localhost/foo?param=value'")); - new HttpieRequestSnippet().document( + new HttpieRequestSnippet(this.commandFormatter).document( this.operationBuilder.request("http://localhost/foo?param=value") .param("param", "value").build()); } @@ -109,7 +113,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { throws IOException { this.snippets.expectHttpieRequest().withContents(codeBlock("bash") .content("$ http GET 'http://localhost/foo?a=alpha&b=bravo'")); - new HttpieRequestSnippet() + new HttpieRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo?a=alpha") .param("a", "alpha").param("b", "bravo").build()); } @@ -118,7 +122,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { public void getRequestWithDisjointQueryStringAndParameters() throws IOException { this.snippets.expectHttpieRequest().withContents(codeBlock("bash") .content("$ http GET 'http://localhost/foo?a=alpha&b=bravo'")); - new HttpieRequestSnippet().document(this.operationBuilder + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo?a=alpha").param("b", "bravo").build()); } @@ -126,7 +130,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { public void getRequestWithQueryStringWithNoValue() throws IOException { this.snippets.expectHttpieRequest().withContents( codeBlock("bash").content("$ http GET 'http://localhost/foo?param'")); - new HttpieRequestSnippet().document( + new HttpieRequestSnippet(this.commandFormatter).document( this.operationBuilder.request("http://localhost/foo?param").build()); } @@ -134,7 +138,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { public void postRequestWithQueryString() throws IOException { this.snippets.expectHttpieRequest().withContents(codeBlock("bash") .content("$ http POST 'http://localhost/foo?param=value'")); - new HttpieRequestSnippet().document(this.operationBuilder + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo?param=value").method("POST").build()); } @@ -142,7 +146,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { public void postRequestWithQueryStringWithNoValue() throws IOException { this.snippets.expectHttpieRequest().withContents( codeBlock("bash").content("$ http POST 'http://localhost/foo?param'")); - new HttpieRequestSnippet().document(this.operationBuilder + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo?param").method("POST").build()); } @@ -150,7 +154,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { public void postRequestWithOneParameter() throws IOException { this.snippets.expectHttpieRequest().withContents(codeBlock("bash") .content("$ http --form POST 'http://localhost/foo' 'k1=v1'")); - new HttpieRequestSnippet() + new HttpieRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo") .method("POST").param("k1", "v1").build()); } @@ -159,7 +163,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { public void postRequestWithOneParameterWithNoValue() throws IOException { this.snippets.expectHttpieRequest().withContents(codeBlock("bash") .content("$ http --form POST 'http://localhost/foo' 'k1='")); - new HttpieRequestSnippet().document(this.operationBuilder + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo").method("POST").param("k1").build()); } @@ -169,7 +173,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { .withContents(codeBlock("bash") .content("$ http --form POST 'http://localhost/foo'" + " 'k1=v1' 'k1=v1-bis' 'k2=v2'")); - new HttpieRequestSnippet().document( + new HttpieRequestSnippet(this.commandFormatter).document( this.operationBuilder.request("http://localhost/foo").method("POST") .param("k1", "v1", "v1-bis").param("k2", "v2").build()); } @@ -178,7 +182,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { public void postRequestWithUrlEncodedParameter() throws IOException { this.snippets.expectHttpieRequest().withContents(codeBlock("bash") .content("$ http --form POST 'http://localhost/foo' 'k1=a&b'")); - new HttpieRequestSnippet() + new HttpieRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo") .method("POST").param("k1", "a&b").build()); } @@ -187,7 +191,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { public void postRequestWithDisjointQueryStringAndParameter() throws IOException { this.snippets.expectHttpieRequest().withContents(codeBlock("bash") .content("$ http --form POST 'http://localhost/foo?a=alpha' 'b=bravo'")); - new HttpieRequestSnippet() + new HttpieRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo?a=alpha") .method("POST").param("b", "bravo").build()); } @@ -197,7 +201,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { throws IOException { this.snippets.expectHttpieRequest().withContents(codeBlock("bash") .content("$ http POST 'http://localhost/foo?a=alpha&b=bravo'")); - new HttpieRequestSnippet().document( + new HttpieRequestSnippet(this.commandFormatter).document( this.operationBuilder.request("http://localhost/foo?a=alpha&b=bravo") .method("POST").param("a", "alpha").param("b", "bravo").build()); } @@ -207,7 +211,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { throws IOException { this.snippets.expectHttpieRequest().withContents(codeBlock("bash") .content("$ http --form POST 'http://localhost/foo?a=alpha' 'b=bravo'")); - new HttpieRequestSnippet() + new HttpieRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo?a=alpha") .method("POST").param("a", "alpha").param("b", "bravo").build()); } @@ -216,7 +220,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { public void putRequestWithOneParameter() throws IOException { this.snippets.expectHttpieRequest().withContents(codeBlock("bash") .content("$ http --form PUT 'http://localhost/foo' 'k1=v1'")); - new HttpieRequestSnippet().document(this.operationBuilder + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo").method("PUT").param("k1", "v1").build()); } @@ -226,7 +230,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { .withContents(codeBlock("bash") .content("$ http --form PUT 'http://localhost/foo'" + " 'k1=v1' 'k1=v1-bis' 'k2=v2'")); - new HttpieRequestSnippet().document(this.operationBuilder + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo").method("PUT").param("k1", "v1") .param("k1", "v1-bis").param("k2", "v2").build()); } @@ -235,7 +239,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { public void putRequestWithUrlEncodedParameter() throws IOException { this.snippets.expectHttpieRequest().withContents(codeBlock("bash") .content("$ http --form PUT 'http://localhost/foo' 'k1=a&b'")); - new HttpieRequestSnippet() + new HttpieRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo") .method("PUT").param("k1", "a&b").build()); } @@ -245,7 +249,19 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { this.snippets.expectHttpieRequest().withContents( codeBlock("bash").content("$ http GET 'http://localhost/foo'" + " 'Content-Type:application/json' 'a:alpha'")); - new HttpieRequestSnippet() + new HttpieRequestSnippet(this.commandFormatter) + .document(this.operationBuilder.request("http://localhost/foo") + .header(HttpHeaders.CONTENT_TYPE, + MediaType.APPLICATION_JSON_VALUE) + .header("a", "alpha").build()); + } + + @Test + public void requestWithHeadersMultiline() throws IOException { + this.snippets.expectHttpieRequest().withContents(codeBlock("bash") + .content(String.format("$ http GET 'http://localhost/foo' \\%n" + + " 'Content-Type:application/json' \\%n 'a:alpha'"))); + new HttpieRequestSnippet(CliDocumentation.multiLineFormat()) .document(this.operationBuilder.request("http://localhost/foo") .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) @@ -257,84 +273,80 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { this.snippets.expectHttpieRequest().withContents( codeBlock("bash").content("$ http GET 'http://localhost/foo'" + " 'Cookie:name1=value1' 'Cookie:name2=value2'")); - new HttpieRequestSnippet() + new HttpieRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo") .cookie("name1", "value1").cookie("name2", "value2").build()); } @Test public void multipartPostWithNoSubmittedFileName() throws IOException { - String expectedContent = String - .format("$ http --form POST 'http://localhost/upload' \\%n" - + " 'metadata'@<(echo '{\"description\": \"foo\"}')"); + String expectedContent = "$ http --form POST 'http://localhost/upload'" + + " 'metadata'@<(echo '{\"description\": \"foo\"}')"; this.snippets.expectHttpieRequest() .withContents(codeBlock("bash").content(expectedContent)); - new HttpieRequestSnippet().document( + new HttpieRequestSnippet(this.commandFormatter).document( this.operationBuilder.request("http://localhost/upload").method("POST") .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("metadata", "{\"description\": \"foo\"}".getBytes()).build()); + .part("metadata", "{\"description\": \"foo\"}".getBytes()).build()); } @Test public void multipartPostWithContentType() throws IOException { // httpie does not yet support manually set content type by part - String expectedContent = String - .format("$ http --form POST 'http://localhost/upload' \\%n" - + " 'image'@'documents/images/example.png'"); + String expectedContent = "$ http --form POST 'http://localhost/upload'" + + " 'image'@'documents/images/example.png'"; this.snippets.expectHttpieRequest() .withContents(codeBlock("bash").content(expectedContent)); - new HttpieRequestSnippet().document( + new HttpieRequestSnippet(this.commandFormatter).document( this.operationBuilder.request("http://localhost/upload").method("POST") .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("image", new byte[0]) - .header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE) - .submittedFileName("documents/images/example.png").build()); + .part("image", new byte[0]) + .header(HttpHeaders.CONTENT_TYPE, MediaType.IMAGE_PNG_VALUE) + .submittedFileName("documents/images/example.png").build()); } @Test public void multipartPost() throws IOException { - String expectedContent = String - .format("$ http --form POST 'http://localhost/upload' \\%n" - + " 'image'@'documents/images/example.png'"); + String expectedContent = "$ http --form POST 'http://localhost/upload'" + + " 'image'@'documents/images/example.png'"; this.snippets.expectHttpieRequest() .withContents(codeBlock("bash").content(expectedContent)); - new HttpieRequestSnippet().document( + new HttpieRequestSnippet(this.commandFormatter).document( this.operationBuilder.request("http://localhost/upload").method("POST") .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("image", new byte[0]) - .submittedFileName("documents/images/example.png").build()); + .part("image", new byte[0]) + .submittedFileName("documents/images/example.png").build()); } @Test public void multipartPostWithParameters() throws IOException { - String expectedContent = String - .format("$ http --form POST 'http://localhost/upload' \\%n" - + " 'image'@'documents/images/example.png' 'a=apple' 'a=avocado'" - + " 'b=banana'"); + String expectedContent = "$ http --form POST 'http://localhost/upload'" + + " 'image'@'documents/images/example.png' 'a=apple' 'a=avocado'" + + " 'b=banana'"; this.snippets.expectHttpieRequest() .withContents(codeBlock("bash").content(expectedContent)); - new HttpieRequestSnippet().document( + new HttpieRequestSnippet(this.commandFormatter).document( this.operationBuilder.request("http://localhost/upload").method("POST") .header(HttpHeaders.CONTENT_TYPE, MediaType.MULTIPART_FORM_DATA_VALUE) - .part("image", new byte[0]) - .submittedFileName("documents/images/example.png").and() - .param("a", "apple", "avocado").param("b", "banana").build()); + .part("image", new byte[0]) + .submittedFileName("documents/images/example.png").and() + .param("a", "apple", "avocado").param("b", "banana").build()); } @Test public void basicAuthCredentialsAreSuppliedUsingAuthOption() throws IOException { this.snippets.expectHttpieRequest().withContents(codeBlock("bash") .content("$ http --auth 'user:secret' GET 'http://localhost/foo'")); - new HttpieRequestSnippet() + new HttpieRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo") .header(HttpHeaders.AUTHORIZATION, "Basic " + Base64Utils .encodeToString("user:secret".getBytes())) - .build()); + .build()); } @Test @@ -345,14 +357,13 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { given(resolver.resolveTemplateResource("httpie-request")) .willReturn(snippetResource("httpie-request-with-title")); new HttpieRequestSnippet( - attributes( - key("title").value("httpie request title"))) - .document( - this.operationBuilder - .attribute(TemplateEngine.class.getName(), - new MustacheTemplateEngine( - resolver)) - .request("http://localhost/foo").build()); + attributes(key("title") + .value("httpie request title")), + this.commandFormatter) + .document(this.operationBuilder + .attribute(TemplateEngine.class.getName(), + new MustacheTemplateEngine(resolver)) + .request("http://localhost/foo").build()); } @Test @@ -361,7 +372,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { .withContents(codeBlock("bash").content( "$ http GET 'http://localhost/foo' 'Host:api.example.com'" + " 'Content-Type:application/json' 'a:alpha'")); - new HttpieRequestSnippet() + new HttpieRequestSnippet(this.commandFormatter) .document(this.operationBuilder.request("http://localhost/foo") .header(HttpHeaders.HOST, "api.example.com") .header(HttpHeaders.CONTENT_TYPE, @@ -374,7 +385,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { this.snippets.expectHttpieRequest().withContents( codeBlock("bash").content("$ echo 'Some content' | http POST " + "'http://localhost/foo?a=alpha&b=bravo'")); - new HttpieRequestSnippet().document(this.operationBuilder + new HttpieRequestSnippet(this.commandFormatter).document(this.operationBuilder .request("http://localhost/foo").method("POST").param("a", "alpha") .param("b", "bravo").content("Some content").build()); } diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java index fb23bee8..cd516696 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java @@ -102,6 +102,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. * * @author Andy Wilkinson * @author Dewet Diener + * @author Tomasz Kopczynski */ @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @@ -161,9 +162,11 @@ public class MockMvcRestDocumentationIntegrationTests { assertThat( new File( "build/generated-snippets/curl-snippet-with-content/curl-request.adoc"), - is(snippet(asciidoctor()).withContents(codeBlock(asciidoctor(), "bash") - .content("$ curl " + "'http://localhost:8080/' -i -X POST " - + "-H 'Accept: application/json' -d 'content'")))); + is(snippet(asciidoctor()) + .withContents(codeBlock(asciidoctor(), "bash").content(String + .format("$ curl 'http://localhost:8080/' -i -X POST \\%n" + + " -H 'Accept: application/json' \\%n" + + " -d 'content'"))))); } @Test @@ -178,8 +181,9 @@ public class MockMvcRestDocumentationIntegrationTests { new File( "build/generated-snippets/curl-snippet-with-cookies/curl-request.adoc"), is(snippet(asciidoctor()).withContents(codeBlock(asciidoctor(), "bash") - .content("$ curl " + "'http://localhost:8080/' -i " - + "-H 'Accept: application/json' --cookie 'cookieName=cookieVal'")))); + .content(String.format("$ curl 'http://localhost:8080/' -i \\%n" + + " -H 'Accept: application/json' \\%n" + + " --cookie 'cookieName=cookieVal'"))))); } @Test @@ -192,10 +196,11 @@ public class MockMvcRestDocumentationIntegrationTests { assertThat( new File( "build/generated-snippets/curl-snippet-with-query-string/curl-request.adoc"), - is(snippet(asciidoctor()) - .withContents(codeBlock(asciidoctor(), "bash").content("$ curl " - + "'http://localhost:8080/?foo=bar' -i -X POST " - + "-H 'Accept: application/json' -d 'a=alpha'")))); + is(snippet(asciidoctor()).withContents( + codeBlock(asciidoctor(), "bash").content(String.format("$ curl " + + "'http://localhost:8080/?foo=bar' -i -X POST \\%n" + + " -H 'Accept: application/json' \\%n" + + " -d 'a=alpha'"))))); } @Test @@ -209,9 +214,10 @@ public class MockMvcRestDocumentationIntegrationTests { new File( "build/generated-snippets/curl-snippet-with-content-and-parameters/curl-request.adoc"), is(snippet(asciidoctor()) - .withContents(codeBlock(asciidoctor(), "bash").content("$ curl " - + "'http://localhost:8080/?a=alpha' -i -X POST " - + "-H 'Accept: application/json' -d 'some content'")))); + .withContents(codeBlock(asciidoctor(), "bash").content(String + .format("$ curl 'http://localhost:8080/?a=alpha' -i -X POST \\%n" + + " -H 'Accept: application/json' \\%n" + + " -d 'some content'"))))); } @Test @@ -226,8 +232,9 @@ public class MockMvcRestDocumentationIntegrationTests { new File( "build/generated-snippets/httpie-snippet-with-content/httpie-request.adoc"), is(snippet(asciidoctor()).withContents(codeBlock(asciidoctor(), "bash") - .content("$ echo 'content' | http POST 'http://localhost:8080/'" - + " 'Accept:application/json'")))); + .content(String.format("$ echo 'content' | " + + "http POST 'http://localhost:8080/' \\%n" + + " 'Accept:application/json'"))))); } @Test @@ -242,8 +249,9 @@ public class MockMvcRestDocumentationIntegrationTests { new File( "build/generated-snippets/httpie-snippet-with-cookies/httpie-request.adoc"), is(snippet(asciidoctor()).withContents(codeBlock(asciidoctor(), "bash") - .content("$ http GET 'http://localhost:8080/'" - + " 'Accept:application/json' 'Cookie:cookieName=cookieVal'")))); + .content(String.format("$ http GET 'http://localhost:8080/' \\%n" + + " 'Accept:application/json' \\%n" + + " 'Cookie:cookieName=cookieVal'"))))); } @Test @@ -256,10 +264,10 @@ public class MockMvcRestDocumentationIntegrationTests { assertThat( new File( "build/generated-snippets/httpie-snippet-with-query-string/httpie-request.adoc"), - is(snippet(asciidoctor()) - .withContents(codeBlock(asciidoctor(), "bash").content("$ http " - + "--form POST 'http://localhost:8080/?foo=bar' " - + "'Accept:application/json' 'a=alpha'")))); + is(snippet(asciidoctor()).withContents(codeBlock(asciidoctor(), + "bash").content(String.format("$ http " + + "--form POST 'http://localhost:8080/?foo=bar' \\%n" + + " 'Accept:application/json' \\%n 'a=alpha'"))))); } @Test @@ -273,9 +281,9 @@ public class MockMvcRestDocumentationIntegrationTests { new File( "build/generated-snippets/httpie-snippet-post-with-content-and-parameters/httpie-request.adoc"), is(snippet(asciidoctor()).withContents(codeBlock(asciidoctor(), "bash") - .content("$ echo " + "'some content' | http POST " - + "'http://localhost:8080/?a=alpha' " - + "'Accept:application/json'")))); + .content(String.format("$ echo " + "'some content' | http POST " + + "'http://localhost:8080/?a=alpha' \\%n" + + " 'Accept:application/json'"))))); } @Test @@ -560,8 +568,9 @@ public class MockMvcRestDocumentationIntegrationTests { new File( "build/generated-snippets/custom-context-path/curl-request.adoc"), is(snippet(asciidoctor()) - .withContents(codeBlock(asciidoctor(), "bash").content( - "$ curl 'http://localhost:8080/custom/' -i -H 'Accept: application/json'")))); + .withContents(codeBlock(asciidoctor(), "bash").content(String + .format("$ curl 'http://localhost:8080/custom/' -i \\%n" + + " -H 'Accept: application/json'"))))); } @Test diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentationIntegrationTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentationIntegrationTests.java index 77815031..6a4cafbd 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentationIntegrationTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured/RestAssuredRestDocumentationIntegrationTests.java @@ -70,6 +70,7 @@ import static org.springframework.restdocs.test.SnippetMatchers.snippet; * Integration tests for using Spring REST Docs with REST Assured. * * @author Andy Wilkinson + * @author Tomasz Kopczynski */ public class RestAssuredRestDocumentationIntegrationTests { @@ -101,10 +102,11 @@ public class RestAssuredRestDocumentationIntegrationTests { new File( "build/generated-snippets/curl-snippet-with-content/curl-request.adoc"), is(snippet(asciidoctor()).withContents(codeBlock(asciidoctor(), "bash") - .content("$ curl 'http://localhost:" + tomcat.getPort() + "/' -i " - + "-X POST -H 'Accept: application/json' " - + "-H 'Content-Type: " + contentType + "' " - + "-d 'content'")))); + .content(String.format("$ curl 'http://localhost:" + + tomcat.getPort() + "/' -i -X POST \\%n" + + " -H 'Accept: application/json' \\%n" + + " -H 'Content-Type: " + contentType + "' \\%n" + + " -d 'content'"))))); } @Test @@ -118,11 +120,12 @@ public class RestAssuredRestDocumentationIntegrationTests { assertThat( new File( "build/generated-snippets/curl-snippet-with-cookies/curl-request.adoc"), - is(snippet(asciidoctor()).withContents(codeBlock(asciidoctor(), "bash") - .content("$ curl 'http://localhost:" + tomcat.getPort() + "/' -i " - + "-H 'Accept: application/json' " + "-H 'Content-Type: " - + contentType + "' " - + "--cookie 'cookieName=cookieVal'")))); + is(snippet(asciidoctor()).withContents(codeBlock(asciidoctor(), + "bash").content(String.format("$ curl 'http://localhost:" + + tomcat.getPort() + "/' -i \\%n" + + " -H 'Accept: application/json' \\%n" + + " -H 'Content-Type: " + contentType + "' \\%n" + + " --cookie 'cookieName=cookieVal'"))))); } @Test @@ -137,10 +140,11 @@ public class RestAssuredRestDocumentationIntegrationTests { new File( "build/generated-snippets/curl-snippet-with-query-string/curl-request.adoc"), is(snippet(asciidoctor()).withContents(codeBlock(asciidoctor(), "bash") - .content("$ curl " + "'http://localhost:" + tomcat.getPort() - + "/?foo=bar' -i -X POST " - + "-H 'Accept: application/json' " + "-H 'Content-Type: " - + contentType + "' " + "-d 'a=alpha'")))); + .content(String.format("$ curl " + "'http://localhost:" + + tomcat.getPort() + "/?foo=bar' -i -X POST \\%n" + + " -H 'Accept: application/json' \\%n" + + " -H 'Content-Type: " + contentType + "' \\%n" + + " -d 'a=alpha'"))))); } @Test