From 37e16bc308b08d465b0a3aee3adbeeaa70877b86 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 9 Mar 2016 17:23:04 +0000 Subject: [PATCH] Polish contribution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit polishes the HTTPie request snippet contribution made in b26d8c0. It makes the following significant changes: - Applies project’s coding conventions for formatting and the like - Moves to a composition-based approach for sharing functionality between the curl and HTTPie snippets by replacing AbstractCliSnippet with CliOperationRequest. - Introduces a single package for CLI command snippets, thereby allowing more code to be package-private. See gh-207 --- config/checkstyle/checkstyle.xml | 2 +- docs/src/docs/asciidoc/configuration.adoc | 3 +- docs/src/docs/asciidoc/getting-started.adoc | 2 +- .../mockmvc/CustomDefaultSnippets.java | 10 +- .../restassured/CustomDefaultSnippets.java | 17 +- ...cumentation.java => CliDocumentation.java} | 39 +++- ...iSnippet.java => CliOperationRequest.java} | 124 ++++++------ .../cli/{curl => }/CurlRequestSnippet.java | 48 +++-- .../restdocs/cli/HttpieRequestSnippet.java | 175 +++++++++++++++++ .../cli/httpie/HttpieDocumentation.java | 59 ------ .../cli/httpie/HttpieRequestSnippet.java | 183 ------------------ .../cli/{httpie => }/package-info.java | 6 +- .../restdocs/config/SnippetConfigurer.java | 12 +- .../restdocs/curl/CurlDocumentation.java | 12 +- .../restdocs/curl/CurlRequestSnippet.java | 17 +- .../restdocs/{cli => }/curl/package-info.java | 5 +- .../default-httpie-request.snippet | 2 +- .../markdown/default-httpie-request.snippet | 2 +- .../{curl => }/CurlRequestSnippetTests.java | 2 +- .../HttpieRequestSnippetTests.java | 16 +- .../RestDocumentationConfigurerTests.java | 8 +- .../httpie-request-with-title.snippet | 2 +- .../httpie-request-with-title.snippet | 2 +- ...kMvcRestDocumentationIntegrationTests.java | 34 +++- 24 files changed, 395 insertions(+), 387 deletions(-) rename spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/{curl/CurlDocumentation.java => CliDocumentation.java} (59%) rename spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/{AbstractCliSnippet.java => CliOperationRequest.java} (59%) rename spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/{curl => }/CurlRequestSnippet.java (74%) create mode 100644 spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/HttpieRequestSnippet.java delete mode 100644 spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/httpie/HttpieDocumentation.java delete mode 100644 spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/httpie/HttpieRequestSnippet.java rename spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/{httpie => }/package-info.java (75%) rename spring-restdocs-core/src/main/java/org/springframework/restdocs/{cli => }/curl/package-info.java (83%) rename spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/{curl => }/CurlRequestSnippetTests.java (99%) rename spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/{httpie => }/HttpieRequestSnippetTests.java (96%) diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index 86947f99..061bb501 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -73,7 +73,7 @@ + value="com.jayway.restassured.RestAssured.*, org.junit.Assert.*, org.junit.Assume.*, org.hamcrest.CoreMatchers.*, org.hamcrest.Matchers.*, org.mockito.Mockito.*, org.mockito.BDDMockito.*, org.mockito.Matchers.*, org.springframework.restdocs.cli.CliDocumentation.*, org.springframework.restdocs.headers.HeaderDocumentation.*, org.springframework.restdocs.hypermedia.HypermediaDocumentation.*, org.springframework.restdocs.mockmvc.IterableEnumeration.*, org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*, org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*, org.springframework.restdocs.payload.PayloadDocumentation.*, org.springframework.restdocs.operation.preprocess.Preprocessors.*, org.springframework.restdocs.request.RequestDocumentation.*, org.springframework.restdocs.restassured.RestAssuredRestDocumentation.*, org.springframework.restdocs.restassured.operation.preprocess.RestAssuredPreprocessors.*, org.springframework.restdocs.snippet.Attributes.*, org.springframework.restdocs.templates.TemplateFormats.*, org.springframework.restdocs.test.SnippetMatchers.*, org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*, org.springframework.test.web.servlet.result.MockMvcResultMatchers.*" /> diff --git a/docs/src/docs/asciidoc/configuration.adoc b/docs/src/docs/asciidoc/configuration.adoc index a290c72c..00c31ac6 100644 --- a/docs/src/docs/asciidoc/configuration.adoc +++ b/docs/src/docs/asciidoc/configuration.adoc @@ -87,11 +87,12 @@ include::{examples-dir}/com/example/restassured/CustomFormat.java[tags=custom-fo [[configuration-default-snippets]] === Default snippets -Three snippets are produced by default: +Four snippets are produced by default: - `curl-request` - `http-request` - `http-response` +- `httpie-request` You can change the default snippet configuration during setup using the `RestDocumentationConfigurer` API. For example, to only produce the `curl-request` diff --git a/docs/src/docs/asciidoc/getting-started.adoc b/docs/src/docs/asciidoc/getting-started.adoc index 2e2cc2e3..daed3a4f 100644 --- a/docs/src/docs/asciidoc/getting-started.adoc +++ b/docs/src/docs/asciidoc/getting-started.adoc @@ -374,9 +374,9 @@ static `document` method on By default, four snippets are written: * `/index/curl-request.adoc` - * `/index/httpie-request.adoc` * `/index/http-request.adoc` * `/index/http-response.adoc` + * `/index/httpie-request.adoc` Refer to <> for more information about these and other snippets that can be produced by Spring REST Docs. diff --git a/docs/src/test/java/com/example/mockmvc/CustomDefaultSnippets.java b/docs/src/test/java/com/example/mockmvc/CustomDefaultSnippets.java index 7164e058..4fb2990f 100644 --- a/docs/src/test/java/com/example/mockmvc/CustomDefaultSnippets.java +++ b/docs/src/test/java/com/example/mockmvc/CustomDefaultSnippets.java @@ -18,19 +18,21 @@ package com.example.mockmvc; import org.junit.Before; import org.junit.Rule; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.restdocs.JUnitRestDocumentation; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import static org.springframework.restdocs.cli.curl.CurlDocumentation.curlRequest; +import static org.springframework.restdocs.cli.CliDocumentation.curlRequest; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; public class CustomDefaultSnippets { @Rule - public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("build"); + public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation( + "build"); @Autowired private WebApplicationContext context; @@ -41,8 +43,8 @@ public class CustomDefaultSnippets { public void setUp() { // tag::custom-default-snippets[] this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context) - .apply(documentationConfiguration(this.restDocumentation) - .snippets().withDefaults(curlRequest())) + .apply(documentationConfiguration(this.restDocumentation).snippets() + .withDefaults(curlRequest())) .build(); // end::custom-default-snippets[] } diff --git a/docs/src/test/java/com/example/restassured/CustomDefaultSnippets.java b/docs/src/test/java/com/example/restassured/CustomDefaultSnippets.java index 632507c6..57c65d36 100644 --- a/docs/src/test/java/com/example/restassured/CustomDefaultSnippets.java +++ b/docs/src/test/java/com/example/restassured/CustomDefaultSnippets.java @@ -16,20 +16,21 @@ package com.example.restassured; -import org.junit.Before; -import org.junit.Rule; -import org.springframework.restdocs.JUnitRestDocumentation; - import com.jayway.restassured.builder.RequestSpecBuilder; import com.jayway.restassured.specification.RequestSpecification; +import org.junit.Before; +import org.junit.Rule; -import static org.springframework.restdocs.cli.curl.CurlDocumentation.curlRequest; +import org.springframework.restdocs.JUnitRestDocumentation; + +import static org.springframework.restdocs.cli.CliDocumentation.curlRequest; import static org.springframework.restdocs.restassured.RestAssuredRestDocumentation.documentationConfiguration; public class CustomDefaultSnippets { @Rule - public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("build"); + public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation( + "build"); private RequestSpecification spec; @@ -37,8 +38,8 @@ public class CustomDefaultSnippets { public void setUp() { // tag::custom-default-snippets[] this.spec = new RequestSpecBuilder() - .addFilter(documentationConfiguration(this.restDocumentation) - .snippets().withDefaults(curlRequest())) + .addFilter(documentationConfiguration(this.restDocumentation).snippets() + .withDefaults(curlRequest())) .build(); // end::custom-default-snippets[] } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/curl/CurlDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliDocumentation.java similarity index 59% rename from spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/curl/CurlDocumentation.java rename to spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliDocumentation.java index 73ef5fe4..9b6b7675 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/curl/CurlDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2012-2016 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. @@ -14,24 +14,23 @@ * limitations under the License. */ -package org.springframework.restdocs.cli.curl; +package org.springframework.restdocs.cli; import java.util.Map; import org.springframework.restdocs.snippet.Snippet; /** - * Static factory methods for documenting a RESTful API as if it were being driven using - * the cURL command-line utility. + * Static factory methods for documenting a RESTful API as if it were being driven using a + * command-line utility such as curl or HTTPie. * * @author Andy Wilkinson - * @author Yann Le Guern - * @author Dmitriy Mayboroda - * @author Jonathan Pearlin + * @author Paul-Christian Volkmer + * @author Raman Gupta */ -public abstract class CurlDocumentation { +public abstract class CliDocumentation { - private CurlDocumentation() { + private CliDocumentation() { } @@ -57,4 +56,26 @@ public abstract class CurlDocumentation { return new CurlRequestSnippet(attributes); } + /** + * Returns a new {@code Snippet} that will document the HTTPie request for the API + * operation. + * + * @return the snippet that will document the HTTPie request + */ + public static Snippet httpieRequest() { + return new HttpieRequestSnippet(); + } + + /** + * 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. + * + * @param attributes the attributes + * @return the snippet that will document the HTTPie request + */ + public static Snippet httpieRequest(Map attributes) { + return new HttpieRequestSnippet(attributes); + } + } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/AbstractCliSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliOperationRequest.java similarity index 59% rename from spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/AbstractCliSnippet.java rename to spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliOperationRequest.java index ef00f0ba..99ce6aeb 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/AbstractCliSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliOperationRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2012-2016 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. @@ -16,29 +16,30 @@ package org.springframework.restdocs.cli; +import java.net.URI; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; -import org.springframework.restdocs.operation.Operation; import org.springframework.restdocs.operation.OperationRequest; +import org.springframework.restdocs.operation.OperationRequestPart; import org.springframework.restdocs.operation.Parameters; -import org.springframework.restdocs.snippet.Snippet; -import org.springframework.restdocs.snippet.TemplatedSnippet; import org.springframework.util.Base64Utils; /** - * An abstract {@link Snippet} that for CLI requests. + * An {@link OperationRequest} wrapper with methods that are useful when producing a + * snippet containing a CLI command for a request. * * @author Andy Wilkinson - * @author Paul-Christian Volkmer * @author Raman Gupta */ -public abstract class AbstractCliSnippet extends TemplatedSnippet { +final class CliOperationRequest implements OperationRequest { private static final Set HEADER_FILTERS; @@ -50,33 +51,19 @@ public abstract class AbstractCliSnippet extends TemplatedSnippet { HEADER_FILTERS = Collections.unmodifiableSet(headerFilters); } - /** - * Create a new abstract cli snippet with the given name and attributes. - * @param snippetName The snippet name. - * @param attributes The snippet attributes. - */ - protected AbstractCliSnippet(String snippetName, Map attributes) { - super(snippetName, attributes); + private final OperationRequest delegate; + + CliOperationRequest(OperationRequest delegate) { + this.delegate = delegate; } - /** - * Create the model which will be passed to the template for rendering. - * @param operation The operation - * @return The model. - */ - protected abstract Map createModel(Operation operation); - - /** - * Gets the unique parameters given a request. - * @param request The operation request. - * @return The unique parameters. - */ - protected Parameters getUniqueParameters(OperationRequest request) { + Parameters getUniqueParameters() { Parameters queryStringParameters = new QueryStringParser() - .parse(request.getUri()); + .parse(this.delegate.getUri()); Parameters uniqueParameters = new Parameters(); - for (Map.Entry> parameter : request.getParameters().entrySet()) { + for (Map.Entry> parameter : this.delegate.getParameters() + .entrySet()) { addIfUnique(parameter, queryStringParameters, uniqueParameters); } return uniqueParameters; @@ -98,23 +85,42 @@ public abstract class AbstractCliSnippet extends TemplatedSnippet { } } - /** - * Whether the request operation is a PUT or a POST. - * @param request The request. - * @return boolean - */ - protected boolean isPutOrPost(OperationRequest request) { - return HttpMethod.PUT.equals(request.getMethod()) - || HttpMethod.POST.equals(request.getMethod()); + boolean isPutOrPost() { + return HttpMethod.PUT.equals(this.delegate.getMethod()) + || HttpMethod.POST.equals(this.delegate.getMethod()); } - /** - * Whether the passed header is allowed according to the configured - * header filters. - * @param header The header to test. - * @return boolean - */ - protected boolean allowedHeader(Map.Entry> header) { + String getBasicAuthCredentials() { + List headerValue = this.delegate.getHeaders() + .get(HttpHeaders.AUTHORIZATION); + if (BasicAuthHeaderFilter.isBasicAuthHeader(headerValue)) { + return BasicAuthHeaderFilter.decodeBasicAuthHeader(headerValue); + } + return null; + } + + @Override + public byte[] getContent() { + return this.delegate.getContent(); + } + + @Override + public String getContentAsString() { + return this.delegate.getContentAsString(); + } + + @Override + public HttpHeaders getHeaders() { + HttpHeaders filteredHeaders = new HttpHeaders(); + for (Entry> header : this.delegate.getHeaders().entrySet()) { + if (allowedHeader(header)) { + filteredHeaders.put(header.getKey(), header.getValue()); + } + } + return HttpHeaders.readOnlyHttpHeaders(filteredHeaders); + } + + private boolean allowedHeader(Map.Entry> header) { for (HeaderFilter headerFilter : HEADER_FILTERS) { if (!headerFilter.allow(header.getKey(), header.getValue())) { return false; @@ -123,22 +129,24 @@ public abstract class AbstractCliSnippet extends TemplatedSnippet { return true; } - /** - * Determine if the header passed is a basic auth header. - * @param headerValue The header to test. - * @return boolean - */ - protected boolean isBasicAuthHeader(List headerValue) { - return BasicAuthHeaderFilter.isBasicAuthHeader(headerValue); + @Override + public HttpMethod getMethod() { + return this.delegate.getMethod(); } - /** - * Decodes a basic auth header into name:password credentials. - * @param headerValue The encoded header value. - * @return name:password credentials. - */ - protected String decodeBasicAuthHeader(List headerValue) { - return BasicAuthHeaderFilter.decodeBasicAuthHeader(headerValue); + @Override + public Parameters getParameters() { + return this.delegate.getParameters(); + } + + @Override + public Collection getParts() { + return this.delegate.getParts(); + } + + @Override + public URI getUri() { + return this.delegate.getUri(); } private interface HeaderFilter { diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/curl/CurlRequestSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CurlRequestSnippet.java similarity index 74% rename from spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/curl/CurlRequestSnippet.java rename to spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CurlRequestSnippet.java index af4c253c..5112b6dc 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/curl/CurlRequestSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CurlRequestSnippet.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.restdocs.cli.curl; +package org.springframework.restdocs.cli; import java.io.PrintWriter; import java.io.StringWriter; @@ -23,14 +23,13 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; -import org.springframework.restdocs.cli.AbstractCliSnippet; import org.springframework.restdocs.operation.Operation; import org.springframework.restdocs.operation.OperationRequest; import org.springframework.restdocs.operation.OperationRequestPart; import org.springframework.restdocs.operation.Parameters; import org.springframework.restdocs.snippet.Snippet; +import org.springframework.restdocs.snippet.TemplatedSnippet; import org.springframework.util.StringUtils; /** @@ -38,10 +37,10 @@ import org.springframework.util.StringUtils; * * @author Andy Wilkinson * @author Paul-Christian Volkmer - * @see CurlDocumentation#curlRequest() - * @see CurlDocumentation#curlRequest(Map) + * @see CliDocumentation#curlRequest() + * @see CliDocumentation#curlRequest(Map) */ -public class CurlRequestSnippet extends AbstractCliSnippet { +public class CurlRequestSnippet extends TemplatedSnippet { /** * Creates a new {@code CurlRequestSnippet} with no additional attributes. @@ -76,11 +75,12 @@ public class CurlRequestSnippet extends AbstractCliSnippet { StringWriter command = new StringWriter(); PrintWriter printer = new PrintWriter(command); writeIncludeHeadersInOutputOption(printer); - writeUserOptionIfNecessary(operation.getRequest(), printer); - writeHttpMethodIfNecessary(operation.getRequest(), printer); - writeHeaders(operation.getRequest().getHeaders(), printer); - writePartsIfNecessary(operation.getRequest(), printer); - writeContent(operation.getRequest(), printer); + CliOperationRequest request = new CliOperationRequest(operation.getRequest()); + writeUserOptionIfNecessary(request, printer); + writeHttpMethodIfNecessary(request, printer); + writeHeaders(request, printer); + writePartsIfNecessary(request, printer); + writeContent(request, printer); return command.toString(); } @@ -89,11 +89,10 @@ public class CurlRequestSnippet extends AbstractCliSnippet { writer.print("-i"); } - private void writeUserOptionIfNecessary(OperationRequest request, + private void writeUserOptionIfNecessary(CliOperationRequest request, PrintWriter writer) { - List headerValue = request.getHeaders().get(HttpHeaders.AUTHORIZATION); - if (isBasicAuthHeader(headerValue)) { - String credentials = decodeBasicAuthHeader(headerValue); + String credentials = request.getBasicAuthCredentials(); + if (credentials != null) { writer.print(String.format(" -u '%s'", credentials)); } } @@ -105,12 +104,10 @@ public class CurlRequestSnippet extends AbstractCliSnippet { } } - private void writeHeaders(HttpHeaders headers, PrintWriter writer) { - for (Entry> entry : headers.entrySet()) { - if (allowedHeader(entry)) { - for (String header : entry.getValue()) { - writer.print(String.format(" -H '%s: %s'", entry.getKey(), header)); - } + private void writeHeaders(CliOperationRequest request, PrintWriter writer) { + for (Entry> entry : request.getHeaders().entrySet()) { + for (String header : entry.getValue()) { + writer.print(String.format(" -H '%s: %s'", entry.getKey(), header)); } } } @@ -133,7 +130,7 @@ public class CurlRequestSnippet extends AbstractCliSnippet { } } - private void writeContent(OperationRequest request, PrintWriter writer) { + private void writeContent(CliOperationRequest request, PrintWriter writer) { String content = request.getContentAsString(); if (StringUtils.hasText(content)) { writer.print(String.format(" -d '%s'", content)); @@ -145,17 +142,18 @@ public class CurlRequestSnippet extends AbstractCliSnippet { } } } - else if (isPutOrPost(request)) { + else if (request.isPutOrPost()) { writeContentUsingParameters(request, writer); } } - private void writeContentUsingParameters(OperationRequest request, + private void writeContentUsingParameters(CliOperationRequest request, PrintWriter writer) { - Parameters uniqueParameters = getUniqueParameters(request); + Parameters uniqueParameters = request.getUniqueParameters(); String queryString = uniqueParameters.toQueryString(); if (StringUtils.hasText(queryString)) { writer.print(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 new file mode 100644 index 00000000..0d132e41 --- /dev/null +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/HttpieRequestSnippet.java @@ -0,0 +1,175 @@ +/* + * Copyright 2014-2016 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.io.PrintWriter; +import java.io.StringWriter; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.restdocs.operation.Operation; +import org.springframework.restdocs.operation.OperationRequest; +import org.springframework.restdocs.operation.OperationRequestPart; +import org.springframework.restdocs.operation.Parameters; +import org.springframework.restdocs.snippet.Snippet; +import org.springframework.restdocs.snippet.TemplatedSnippet; +import org.springframework.util.StringUtils; + +/** + * A {@link Snippet} that documents the HTTPie command for a request. + * + * @author Raman Gupta + * @author Andy Wilkinson + * @see CliDocumentation#httpieRequest() + * @see CliDocumentation#httpieRequest(Map) + */ +public class HttpieRequestSnippet extends TemplatedSnippet { + + /** + * Creates a new {@code HttpieRequestSnippet} with no additional attributes. + */ + protected HttpieRequestSnippet() { + this(null); + } + + /** + * Creates a new {@code HttpieRequestSnippet} with the given additional + * {@code attributes} that will be included in the model during template rendering. + * + * @param attributes The additional attributes + */ + protected HttpieRequestSnippet(Map attributes) { + super("httpie-request", attributes); + } + + @Override + protected Map createModel(Operation operation) { + Map model = new HashMap<>(); + CliOperationRequest request = new CliOperationRequest(operation.getRequest()); + model.put("echoContent", getContentStandardIn(request)); + model.put("options", getOptions(request)); + model.put("url", getUrl(request)); + model.put("requestItems", getRequestItems(request)); + return model; + } + + private Object getContentStandardIn(CliOperationRequest request) { + String content = request.getContentAsString(); + if (StringUtils.hasText(content)) { + return String.format("echo '%s' | ", content); + } + return ""; + } + + private String getOptions(CliOperationRequest request) { + StringWriter options = new StringWriter(); + PrintWriter printer = new PrintWriter(options); + writeOptions(request, printer); + writeUserOptionIfNecessary(request, printer); + writeMethodIfNecessary(request, printer); + return options.toString(); + } + + private String getUrl(OperationRequest request) { + return String.format("'%s'", request.getUri()); + } + + private String getRequestItems(CliOperationRequest request) { + StringWriter requestItems = new StringWriter(); + PrintWriter printer = new PrintWriter(requestItems); + writeFormDataIfNecessary(request, printer); + writeHeaders(request, printer); + writeParametersIfNecessary(request, printer); + return requestItems.toString(); + } + + private void writeOptions(CliOperationRequest request, PrintWriter writer) { + if (!request.getParts().isEmpty() || !request.getUniqueParameters().isEmpty()) { + writer.print("--form "); + } + } + + private void writeUserOptionIfNecessary(CliOperationRequest request, + PrintWriter writer) { + String credentials = request.getBasicAuthCredentials(); + if (credentials != null) { + writer.print(String.format("--auth '%s' ", credentials)); + } + } + + private void writeMethodIfNecessary(OperationRequest request, PrintWriter writer) { + writer.print(String.format("%s", request.getMethod().name())); + } + + private void writeFormDataIfNecessary(OperationRequest request, PrintWriter writer) { + for (OperationRequestPart part : request.getParts()) { + writer.printf(" \\%n '%s'", part.getName()); + if (!StringUtils.hasText(part.getSubmittedFileName())) { + // https://github.com/jkbrzt/httpie/issues/342 + writer.printf("@<(echo '%s')", part.getContentAsString()); + } + else { + writer.printf("@'%s'", part.getSubmittedFileName()); + } + } + } + + private void writeHeaders(OperationRequest request, PrintWriter writer) { + HttpHeaders headers = request.getHeaders(); + for (Entry> entry : headers.entrySet()) { + for (String header : entry.getValue()) { + // HTTPie adds Content-Type automatically with --form + if (!request.getParts().isEmpty() + && entry.getKey().equals(HttpHeaders.CONTENT_TYPE) + && header.startsWith(MediaType.MULTIPART_FORM_DATA_VALUE)) { + continue; + } + writer.print(String.format(" '%s:%s'", entry.getKey(), header)); + } + } + } + + private void writeParametersIfNecessary(CliOperationRequest request, + PrintWriter writer) { + if (StringUtils.hasText(request.getContentAsString())) { + return; + } + if (!request.getParts().isEmpty()) { + writeContentUsingParameters(request.getParameters(), writer); + } + else if (request.isPutOrPost()) { + writeContentUsingParameters(request.getUniqueParameters(), writer); + } + } + + private void writeContentUsingParameters(Parameters parameters, PrintWriter writer) { + for (Map.Entry> entry : parameters.entrySet()) { + if (entry.getValue().isEmpty()) { + writer.append(String.format(" '%s='", entry.getKey())); + } + else { + for (String value : entry.getValue()) { + writer.append(String.format(" '%s=%s'", entry.getKey(), value)); + } + } + } + } +} diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/httpie/HttpieDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/httpie/HttpieDocumentation.java deleted file mode 100644 index 0313ae02..00000000 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/httpie/HttpieDocumentation.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2014-2015 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.httpie; - -import java.util.Map; - -import org.springframework.restdocs.snippet.Snippet; - -/** - * Static factory methods for documenting a RESTful API as if it were being driven using - * the httpie command-line utility. - * - * @author Andy Wilkinson - * @author Paul-Christian Volkmer - * @author Raman Gupta - */ -public abstract class HttpieDocumentation { - - private HttpieDocumentation() { - - } - - /** - * Returns a new {@code Snippet} that will document the httpie request for the API - * operation. - * - * @return the snippet that will document the httpie request - */ - public static Snippet httpieRequest() { - return new HttpieRequestSnippet(); - } - - /** - * 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. - * - * @param attributes the attributes - * @return the snippet that will document the httpie request - */ - public static Snippet httpieRequest(Map attributes) { - return new HttpieRequestSnippet(attributes); - } - -} diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/httpie/HttpieRequestSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/httpie/HttpieRequestSnippet.java deleted file mode 100644 index 7e251a90..00000000 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/httpie/HttpieRequestSnippet.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2014-2016 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.httpie; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.springframework.http.HttpHeaders; -import org.springframework.restdocs.cli.AbstractCliSnippet; -import org.springframework.restdocs.operation.Operation; -import org.springframework.restdocs.operation.OperationRequest; -import org.springframework.restdocs.operation.OperationRequestPart; -import org.springframework.restdocs.operation.Parameters; -import org.springframework.restdocs.snippet.Snippet; -import org.springframework.util.StringUtils; - -/** - * A {@link Snippet} that documents the httpie command for a request. - * - * @author Raman Gupta - * @see HttpieDocumentation#httpieRequest() - * @see HttpieDocumentation#httpieRequest(Map) - */ -public class HttpieRequestSnippet extends AbstractCliSnippet { - - /** - * Creates a new {@code CurlRequestSnippet} with no additional attributes. - */ - protected HttpieRequestSnippet() { - this(null); - } - - /** - * Creates a new {@code CurlRequestSnippet} with the given additional - * {@code attributes} that will be included in the model during template rendering. - * - * @param attributes The additional attributes - */ - protected HttpieRequestSnippet(Map attributes) { - super("httpie-request", attributes); - } - - @Override - protected Map createModel(final Operation operation) { - Map model = new HashMap<>(); - model.put("echo_content", getContentStdIn(operation)); - model.put("options", getOptions(operation)); - model.put("url", getUrl(operation)); - model.put("request_items", getRequestItems(operation)); - return model; - } - private Object getContentStdIn(final Operation operation) { - OperationRequest request = operation.getRequest(); - String content = request.getContentAsString(); - if (StringUtils.hasText(content)) { - return String.format("echo '%s' | ", content); - } - else { - return ""; - } - } - - private String getOptions(Operation operation) { - StringWriter options = new StringWriter(); - PrintWriter printer = new PrintWriter(options); - writeOptions(operation.getRequest(), printer); - writeUserOptionIfNecessary(operation.getRequest(), printer); - writeMethodIfNecessary(operation.getRequest(), printer); - return options.toString(); - } - - private String getUrl(Operation operation) { - return String.format("'%s'", operation.getRequest().getUri()); - } - - private String getRequestItems(final Operation operation) { - StringWriter requestItems = new StringWriter(); - PrintWriter printer = new PrintWriter(requestItems); - writeFormDataIfNecessary(operation.getRequest(), printer); - writeHeaders(operation.getRequest(), printer); - writeContent(operation.getRequest(), printer); - return requestItems.toString(); - } - private void writeOptions(OperationRequest request, PrintWriter writer) { - Parameters uniqueParameters = getUniqueParameters(request); - if (request.getParts().size() > 0 || uniqueParameters.size() > 0) { - writer.print("--form "); - } - } - - private void writeUserOptionIfNecessary(OperationRequest request, - PrintWriter writer) { - List headerValue = request.getHeaders().get(HttpHeaders.AUTHORIZATION); - if (isBasicAuthHeader(headerValue)) { - String credentials = decodeBasicAuthHeader(headerValue); - writer.print(String.format("--auth '%s' ", credentials)); - } - } - - private void writeMethodIfNecessary(OperationRequest request, PrintWriter writer) { - writer.print(String.format("%s", request.getMethod().name())); - } - - private void writeFormDataIfNecessary(OperationRequest request, PrintWriter writer) { - for (OperationRequestPart part : request.getParts()) { - writer.printf(" \\\n '%s'", part.getName()); - if (!StringUtils.hasText(part.getSubmittedFileName())) { - // httpie https://github.com/jkbrzt/httpie/issues/342 - writer.printf("@<(echo '%s')", part.getContentAsString()); - } - else { - writer.printf("@'%s'", part.getSubmittedFileName()); - } - // httpie does not currently support manually set content type by part - } - } - - private void writeHeaders(OperationRequest request, PrintWriter writer) { - HttpHeaders headers = request.getHeaders(); - for (Entry> entry : headers.entrySet()) { - if (allowedHeader(entry)) { - for (String header : entry.getValue()) { - // form Content-Type not required, added automatically by httpie with --form - if (request.getParts().size() > 0 - && entry.getKey().equals(HttpHeaders.CONTENT_TYPE) - && header.startsWith("multipart/form-data")) { - continue; - } - writer.print(String.format(" '%s:%s'", entry.getKey(), header)); - } - } - } - } - - private void writeContent(OperationRequest request, PrintWriter writer) { - String content = request.getContentAsString(); - if (!StringUtils.hasText(content)) { - if (!request.getParts().isEmpty()) { - for (Entry> entry : request.getParameters().entrySet()) { - for (String value : entry.getValue()) { - writer.print(String.format(" '%s=%s'", entry.getKey(), value)); - } - } - } - else if (isPutOrPost(request)) { - writeContentUsingParameters(request, writer); - } - } - } - - private void writeContentUsingParameters(OperationRequest request, - PrintWriter writer) { - Parameters uniqueParameters = getUniqueParameters(request); - for (Map.Entry> entry : uniqueParameters.entrySet()) { - if (entry.getValue().isEmpty()) { - writer.append(String.format(" '%s='", entry.getKey())); - } - else { - for (String value : entry.getValue()) { - writer.append(String.format(" '%s=%s'", entry.getKey(), value)); - } - } - } - } -} diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/httpie/package-info.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/package-info.java similarity index 75% rename from spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/httpie/package-info.java rename to spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/package-info.java index 2bdf5df6..f06c9670 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/httpie/package-info.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2015 the original author or authors. + * Copyright 2014-2016 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. @@ -15,6 +15,6 @@ */ /** - * Documenting the httpie command required to make a request to a RESTful API. + * Documenting CLI commands required to make a request to a RESTful API. */ -package org.springframework.restdocs.cli.httpie; +package org.springframework.restdocs.cli; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/SnippetConfigurer.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/SnippetConfigurer.java index 7c2b459c..cb72f152 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/SnippetConfigurer.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/config/SnippetConfigurer.java @@ -21,8 +21,7 @@ import java.util.List; import java.util.Map; import org.springframework.restdocs.RestDocumentationContext; -import org.springframework.restdocs.cli.curl.CurlDocumentation; -import org.springframework.restdocs.cli.httpie.HttpieDocumentation; +import org.springframework.restdocs.cli.CliDocumentation; import org.springframework.restdocs.generate.RestDocumentationGenerator; import org.springframework.restdocs.http.HttpDocumentation; import org.springframework.restdocs.snippet.Snippet; @@ -39,12 +38,9 @@ import org.springframework.restdocs.templates.TemplateFormats; public abstract class SnippetConfigurer extends AbstractNestedConfigurer { - private List defaultSnippets = Arrays.asList( - CurlDocumentation.curlRequest(), - HttpieDocumentation.httpieRequest(), - HttpDocumentation.httpRequest(), - HttpDocumentation.httpResponse() - ); + private List defaultSnippets = Arrays.asList(CliDocumentation.curlRequest(), + CliDocumentation.httpieRequest(), HttpDocumentation.httpRequest(), + HttpDocumentation.httpResponse()); /** * The default encoding for documentation snippets. diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlDocumentation.java index a9b094f6..123c7a66 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlDocumentation.java @@ -24,8 +24,8 @@ import org.springframework.restdocs.snippet.Snippet; * Static factory methods for documenting a RESTful API as if it were being driven using * the cURL command-line utility. * - * @deprecated Since 1.1 in favor of {@link org.springframework.restdocs.cli.curl.CurlDocumentation}. - * + * @deprecated Since 1.1 in favor of + * {@link org.springframework.restdocs.cli.CliDocumentation}. * @author Andy Wilkinson * @author Yann Le Guern * @author Dmitriy Mayboroda @@ -44,8 +44,10 @@ public abstract class CurlDocumentation { * * @return the snippet that will document the curl request * - * @deprecated Since 1.1 in favor of {@link org.springframework.restdocs.cli.curl.CurlDocumentation}. + * @deprecated Since 1.1 in favor of + * {@link org.springframework.restdocs.cli.CliDocumentation#curlRequest()}. */ + @Deprecated public static Snippet curlRequest() { return new CurlRequestSnippet(); } @@ -58,8 +60,10 @@ public abstract class CurlDocumentation { * @param attributes the attributes * @return the snippet that will document the curl request * - * @deprecated Since 1.1 in favor of {@link org.springframework.restdocs.cli.curl.CurlDocumentation}. + * @deprecated Since 1.1 in favor of + * {@link org.springframework.restdocs.cli.CliDocumentation#curlRequest(Map)}. */ + @Deprecated public static Snippet curlRequest(Map attributes) { return new CurlRequestSnippet(attributes); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlRequestSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlRequestSnippet.java index 29396bac..18148392 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlRequestSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/CurlRequestSnippet.java @@ -23,16 +23,23 @@ import org.springframework.restdocs.snippet.Snippet; /** * A {@link Snippet} that documents the curl command for a request. * + * @author Andy Wilkinson + * @author Paul-Christian Volkmer * @author Raman Gupta - * @deprecated Since 1.1 in favor of {@link org.springframework.restdocs.cli.curl.CurlRequestSnippet}. + * @deprecated Since 1.1 in favor of + * {@link org.springframework.restdocs.cli.CurlRequestSnippet}. */ -public class CurlRequestSnippet extends org.springframework.restdocs.cli.curl.CurlRequestSnippet { +@Deprecated +public class CurlRequestSnippet + extends org.springframework.restdocs.cli.CurlRequestSnippet { /** * Creates a new {@code CurlRequestSnippet} with no additional attributes. * - * @deprecated Since 1.1 in favor of {@link org.springframework.restdocs.cli.curl.CurlRequestSnippet}. + * @deprecated Since 1.1 in favor of + * {@link org.springframework.restdocs.cli.CurlRequestSnippet}. */ + @Deprecated protected CurlRequestSnippet() { super(); } @@ -41,8 +48,10 @@ public class CurlRequestSnippet extends org.springframework.restdocs.cli.curl.Cu * Creates a new {@code CurlRequestSnippet} with additional attributes. * @param attributes The additional attributes. * - * @deprecated Since 1.1 in favor of {@link org.springframework.restdocs.cli.curl.CurlRequestSnippet}. + * @deprecated Since 1.1 in favor of + * {@link org.springframework.restdocs.cli.CurlRequestSnippet}. */ + @Deprecated protected CurlRequestSnippet(final Map attributes) { super(attributes); } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/curl/package-info.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/package-info.java similarity index 83% rename from spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/curl/package-info.java rename to spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/package-info.java index 02ebe62c..e614e2b8 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/curl/package-info.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/curl/package-info.java @@ -16,5 +16,8 @@ /** * Documenting the curl command required to make a request to a RESTful API. + * + * @deprecated Since 1.1 in favor of functionality in + * {@code org.springframework.restdocs.cli} */ -package org.springframework.restdocs.cli.curl; +package org.springframework.restdocs.curl; diff --git a/spring-restdocs-core/src/main/resources/org/springframework/restdocs/templates/asciidoctor/default-httpie-request.snippet b/spring-restdocs-core/src/main/resources/org/springframework/restdocs/templates/asciidoctor/default-httpie-request.snippet index 05771238..1b690a5f 100644 --- a/spring-restdocs-core/src/main/resources/org/springframework/restdocs/templates/asciidoctor/default-httpie-request.snippet +++ b/spring-restdocs-core/src/main/resources/org/springframework/restdocs/templates/asciidoctor/default-httpie-request.snippet @@ -1,4 +1,4 @@ [source,bash] ---- -$ {{echo_content}}http {{options}} {{url}}{{request_items}} +$ {{echoContent}}http {{options}} {{url}}{{requestItems}} ---- \ No newline at end of file diff --git a/spring-restdocs-core/src/main/resources/org/springframework/restdocs/templates/markdown/default-httpie-request.snippet b/spring-restdocs-core/src/main/resources/org/springframework/restdocs/templates/markdown/default-httpie-request.snippet index acddb53f..65d78f74 100644 --- a/spring-restdocs-core/src/main/resources/org/springframework/restdocs/templates/markdown/default-httpie-request.snippet +++ b/spring-restdocs-core/src/main/resources/org/springframework/restdocs/templates/markdown/default-httpie-request.snippet @@ -1,3 +1,3 @@ ```bash -$ {{echo_content}}http {{options}} {{url}}{{request_items}} +$ {{echoContent}}http {{options}} {{url}}{{requestItems}} ``` \ No newline at end of file diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/curl/CurlRequestSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java similarity index 99% rename from spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/curl/CurlRequestSnippetTests.java rename to spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java index 0d8bb632..bb7cff80 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/curl/CurlRequestSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.restdocs.cli.curl; +package org.springframework.restdocs.cli; import java.io.IOException; diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/httpie/HttpieRequestSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java similarity index 96% rename from spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/httpie/HttpieRequestSnippetTests.java rename to spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java index 1fb2abd7..6194fef9 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/httpie/HttpieRequestSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.restdocs.cli.httpie; +package org.springframework.restdocs.cli; import java.io.IOException; @@ -156,8 +156,8 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { @Test public void postRequestWithUrlEncodedParameter() throws IOException { this.snippet.expectHttpieRequest("post-request-with-url-encoded-parameter") - .withContents(codeBlock("bash").content( - "$ http --form POST 'http://localhost/foo' 'k1=a&b'")); + .withContents(codeBlock("bash") + .content("$ http --form POST 'http://localhost/foo' 'k1=a&b'")); new HttpieRequestSnippet() .document(operationBuilder("post-request-with-url-encoded-parameter") .request("http://localhost/foo").method("POST").param("k1", "a&b") @@ -214,8 +214,8 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { @Test public void putRequestWithUrlEncodedParameter() throws IOException { this.snippet.expectHttpieRequest("put-request-with-url-encoded-parameter") - .withContents(codeBlock("bash").content( - "$ http --form PUT 'http://localhost/foo' 'k1=a&b'")); + .withContents(codeBlock("bash") + .content("$ http --form PUT 'http://localhost/foo' 'k1=a&b'")); new HttpieRequestSnippet() .document(operationBuilder("put-request-with-url-encoded-parameter") .request("http://localhost/foo").method("PUT").param("k1", "a&b") @@ -224,8 +224,8 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { @Test public void requestWithHeaders() throws IOException { - this.snippet.expectHttpieRequest("request-with-headers") - .withContents(codeBlock("bash").content("$ http GET 'http://localhost/foo'" + this.snippet.expectHttpieRequest("request-with-headers").withContents( + codeBlock("bash").content("$ http GET 'http://localhost/foo'" + " 'Content-Type:application/json' 'a:alpha'")); new HttpieRequestSnippet().document( operationBuilder("request-with-headers").request("http://localhost/foo") @@ -298,7 +298,7 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { } @Test - public void basicAuthCredentialsAreSuppliedUsingUserOption() throws IOException { + public void basicAuthCredentialsAreSuppliedUsingAuthOption() throws IOException { this.snippet.expectHttpieRequest("basic-auth").withContents(codeBlock("bash") .content("$ http --auth 'user:secret' GET 'http://localhost/foo'")); new HttpieRequestSnippet() diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/config/RestDocumentationConfigurerTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/config/RestDocumentationConfigurerTests.java index 7a36e320..7198ffc8 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/config/RestDocumentationConfigurerTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/config/RestDocumentationConfigurerTests.java @@ -24,9 +24,9 @@ import org.hamcrest.Matchers; import org.junit.Test; import org.springframework.restdocs.RestDocumentationContext; -import org.springframework.restdocs.cli.curl.CurlDocumentation; -import org.springframework.restdocs.cli.curl.CurlRequestSnippet; -import org.springframework.restdocs.cli.httpie.HttpieRequestSnippet; +import org.springframework.restdocs.cli.CliDocumentation; +import org.springframework.restdocs.cli.CurlRequestSnippet; +import org.springframework.restdocs.cli.HttpieRequestSnippet; import org.springframework.restdocs.generate.RestDocumentationGenerator; import org.springframework.restdocs.http.HttpRequestSnippet; import org.springframework.restdocs.http.HttpResponseSnippet; @@ -108,7 +108,7 @@ public class RestDocumentationConfigurerTests { public void customDefaultSnippets() { RestDocumentationContext context = new RestDocumentationContext(null, null, null); Map configuration = new HashMap<>(); - this.configurer.snippets().withDefaults(CurlDocumentation.curlRequest()) + this.configurer.snippets().withDefaults(CliDocumentation.curlRequest()) .apply(configuration, context); assertThat(configuration, hasEntry( diff --git a/spring-restdocs-core/src/test/resources/custom-snippet-templates/asciidoctor/httpie-request-with-title.snippet b/spring-restdocs-core/src/test/resources/custom-snippet-templates/asciidoctor/httpie-request-with-title.snippet index 0bff58b1..7c4eb048 100644 --- a/spring-restdocs-core/src/test/resources/custom-snippet-templates/asciidoctor/httpie-request-with-title.snippet +++ b/spring-restdocs-core/src/test/resources/custom-snippet-templates/asciidoctor/httpie-request-with-title.snippet @@ -1,5 +1,5 @@ [source,bash] .{{title}} ---- -$ {{echo_content}}http {{options}} {{url}}{{request_items}} +$ {{echoContent}}http {{options}} {{url}}{{requestItems}} ---- \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/custom-snippet-templates/markdown/httpie-request-with-title.snippet b/spring-restdocs-core/src/test/resources/custom-snippet-templates/markdown/httpie-request-with-title.snippet index 29beade1..67dff455 100644 --- a/spring-restdocs-core/src/test/resources/custom-snippet-templates/markdown/httpie-request-with-title.snippet +++ b/spring-restdocs-core/src/test/resources/custom-snippet-templates/markdown/httpie-request-with-title.snippet @@ -1,4 +1,4 @@ {{title}} ```bash -$ {{echo_content}}http {{options}} {{url}}{{request_items}} +$ {{echoContent}}http {{options}} {{url}}{{requestItems}} ``` \ No newline at end of file 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 ad06b187..51c35ee4 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 @@ -56,7 +56,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; -import static org.springframework.restdocs.cli.curl.CurlDocumentation.curlRequest; +import static org.springframework.restdocs.cli.CliDocumentation.curlRequest; import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel; import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; @@ -171,6 +171,38 @@ public class MockMvcRestDocumentationIntegrationTests { + "-H 'Accept: application/json' -d 'a=alpha'")))); } + @Test + public void httpieSnippetWithContent() throws Exception { + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) + .apply(documentationConfiguration(this.restDocumentation)).build(); + + mockMvc.perform(post("/").accept(MediaType.APPLICATION_JSON).content("content")) + .andExpect(status().isOk()) + .andDo(document("httpie-snippet-with-content")); + assertThat( + 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'")))); + } + + @Test + public void httpieSnippetWithQueryStringOnPost() throws Exception { + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) + .apply(documentationConfiguration(this.restDocumentation)).build(); + mockMvc.perform(post("/?foo=bar").param("foo", "bar").param("a", "alpha") + .accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .andDo(document("httpie-snippet-with-query-string")); + 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'")))); + } + @Test public void linksSnippet() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context)