From 14ad59d434dd0be4a1202847f51c7f966559de10 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Sun, 13 Sep 2015 11:58:22 -0400 Subject: [PATCH] Make descriptions more flexible Previously, the description of a link, parameter, or field had to be a String. Given the use of Mustache templates, this was unnecessarily restrictive. It prevented the use of a richer object, the components of which could then be accessed in a template. This commit changes the description of links, parameters, and fields to be an Object, thereby allowing richer objects to be used. The default template will call toString on the description during rendering. Custom templates can be used to make more sophisticated use of the description. To ensure that the description is consistent across all descriptor types, it has been moved up onto the AbstractDescriptor superclass. Closes gh-123 --- .../restdocs/hypermedia/LinkDescriptor.java | 22 ---------------- .../restdocs/hypermedia/LinksSnippet.java | 2 +- .../payload/AbstractFieldsSnippet.java | 2 +- .../restdocs/payload/FieldDescriptor.java | 22 ---------------- .../request/AbstractParametersSnippet.java | 2 +- .../restdocs/request/ParameterDescriptor.java | 22 ---------------- .../restdocs/snippet/AbstractDescriptor.java | 25 ++++++++++++++++++- .../payload/RequestFieldsSnippetTests.java | 20 +++++++++++++++ .../restdocs/test/SnippetMatchers.java | 5 ++++ ...quest-fields-with-list-description.snippet | 12 +++++++++ 10 files changed, 64 insertions(+), 70 deletions(-) create mode 100644 spring-restdocs-core/src/test/resources/custom-snippet-templates/request-fields-with-list-description.snippet diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinkDescriptor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinkDescriptor.java index 9d11f915..cb7e9909 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinkDescriptor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinkDescriptor.java @@ -29,8 +29,6 @@ public class LinkDescriptor extends AbstractDescriptor { private final String rel; - private String description; - private boolean optional; /** @@ -42,17 +40,6 @@ public class LinkDescriptor extends AbstractDescriptor { this.rel = rel; } - /** - * Specifies the description of the link - * - * @param description The link's description - * @return {@code this} - */ - public final LinkDescriptor description(String description) { - this.description = description; - return this; - } - /** * Marks the link as optional * @@ -72,15 +59,6 @@ public class LinkDescriptor extends AbstractDescriptor { return this.rel; } - /** - * Returns the description for the link - * - * @return the link description - */ - public final String getDescription() { - return this.description; - } - /** * Returns {@code true} if the described link is optional, otherwise {@code false} * diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java index 006327bb..d6b225e0 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/LinksSnippet.java @@ -75,7 +75,7 @@ public class LinksSnippet extends TemplatedSnippet { this.linkExtractor = linkExtractor; for (LinkDescriptor descriptor : descriptors) { Assert.hasText(descriptor.getRel()); - Assert.hasText(descriptor.getDescription()); + Assert.notNull(descriptor.getDescription()); this.descriptorsByRel.put(descriptor.getRel(), descriptor); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java index 970cd7ec..1aea09df 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/AbstractFieldsSnippet.java @@ -56,7 +56,7 @@ public abstract class AbstractFieldsSnippet extends TemplatedSnippet { super(type + "-fields", attributes); for (FieldDescriptor descriptor : descriptors) { Assert.notNull(descriptor.getPath()); - Assert.hasText(descriptor.getDescription()); + Assert.notNull(descriptor.getDescription()); } this.fieldDescriptors = descriptors; } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldDescriptor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldDescriptor.java index b9cac2df..1edd352a 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldDescriptor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/payload/FieldDescriptor.java @@ -34,8 +34,6 @@ public class FieldDescriptor extends AbstractDescriptor { private boolean optional; - private String description; - /** * Creates a new {@code FieldDescriptor} describing the field with the given * {@code path}. @@ -68,17 +66,6 @@ public class FieldDescriptor extends AbstractDescriptor { return this; } - /** - * Specifies the description of the field - * - * @param description The field's description - * @return {@code this} - */ - public final FieldDescriptor description(String description) { - this.description = description; - return this; - } - /** * Returns the path of the field described by this descriptor * @@ -106,13 +93,4 @@ public class FieldDescriptor extends AbstractDescriptor { return this.optional; } - /** - * Returns the description for the field - * - * @return the field description - */ - public final String getDescription() { - return this.description; - } - } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java index fcb8ae2b..f0597fef 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/AbstractParametersSnippet.java @@ -55,7 +55,7 @@ public abstract class AbstractParametersSnippet extends TemplatedSnippet { super(snippetName, attributes); for (ParameterDescriptor descriptor : descriptors) { Assert.hasText(descriptor.getName()); - Assert.hasText(descriptor.getDescription()); + Assert.notNull(descriptor.getDescription()); this.descriptorsByName.put(descriptor.getName(), descriptor); } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/ParameterDescriptor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/ParameterDescriptor.java index 549500da..a1a2840f 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/ParameterDescriptor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/request/ParameterDescriptor.java @@ -29,8 +29,6 @@ public class ParameterDescriptor extends AbstractDescriptor private final String name; - private String description; - /** * Creates a new {@code ParameterDescriptor} describing the parameter with the given * {@code name}. @@ -41,17 +39,6 @@ public class ParameterDescriptor extends AbstractDescriptor this.name = name; } - /** - * Specifies the description of the parameter - * - * @param description The parameter's description - * @return {@code this} - */ - public final ParameterDescriptor description(String description) { - this.description = description; - return this; - } - /** * Returns the name of the parameter being described by this descriptor * @@ -61,13 +48,4 @@ public class ParameterDescriptor extends AbstractDescriptor return this.name; } - /** - * Returns the description of the parameter - * - * @return the description - */ - public final String getDescription() { - return this.description; - } - } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/AbstractDescriptor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/AbstractDescriptor.java index 931cd79e..34efc728 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/AbstractDescriptor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/snippet/AbstractDescriptor.java @@ -33,6 +33,8 @@ public abstract class AbstractDescriptor> { private Map attributes = new HashMap<>(); + private Object description; + /** * Adds the given {@code attributes} to the descriptor * @@ -40,13 +42,34 @@ public abstract class AbstractDescriptor> { * @return the descriptor */ @SuppressWarnings("unchecked") - public T attributes(Attribute... attributes) { + public final T attributes(Attribute... attributes) { for (Attribute attribute : attributes) { this.attributes.put(attribute.getKey(), attribute.getValue()); } return (T) this; } + /** + * Specifies the description + * + * @param description the description + * @return the descriptor + */ + @SuppressWarnings("unchecked") + public final T description(Object description) { + this.description = description; + return (T) this; + } + + /** + * Returns the description + * + * @return the description + */ + public final Object getDescription() { + return this.description; + } + /** * Returns the descriptor's attributes * diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetTests.java index 819dd592..7e603a5b 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/payload/RequestFieldsSnippetTests.java @@ -179,6 +179,26 @@ public class RequestFieldsSnippetTests { .request("http://localhost").content("{\"a\": \"foo\"}").build()); } + @Test + public void requestFieldsWithListDescription() throws IOException { + this.snippet.expectRequestFields("request-fields-with-list-description") + .withContents( + tableWithHeader("Path", "Type", "Description") + // + .row("a", "String", String.format(" - one%n - two")) + .configuration("[cols=\"1,1,1a\"]")); + TemplateResourceResolver resolver = mock(TemplateResourceResolver.class); + when(resolver.resolveTemplateResource("request-fields")).thenReturn( + snippetResource("request-fields-with-list-description")); + new RequestFieldsSnippet(Arrays.asList(fieldWithPath("a").description( + Arrays.asList("one", "two")))) + .document(new OperationBuilder("request-fields-with-list-description", + this.snippet.getOutputDirectory()) + .attribute(TemplateEngine.class.getName(), + new MustacheTemplateEngine(resolver)) + .request("http://localhost").content("{\"a\": \"foo\"}").build()); + } + @Test public void xmlRequestFields() throws IOException { this.snippet.expectRequestFields("xml-request").withContents( // diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetMatchers.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetMatchers.java index b174cf40..444b2b53 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetMatchers.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/test/SnippetMatchers.java @@ -191,6 +191,11 @@ public class SnippetMatchers { this.addLine(-1, ""); return this; } + + public AsciidoctorTableMatcher configuration(String configuration) { + this.addLine(0, configuration); + return this; + } } public static class SnippetMatcher extends BaseMatcher { diff --git a/spring-restdocs-core/src/test/resources/custom-snippet-templates/request-fields-with-list-description.snippet b/spring-restdocs-core/src/test/resources/custom-snippet-templates/request-fields-with-list-description.snippet new file mode 100644 index 00000000..e4820496 --- /dev/null +++ b/spring-restdocs-core/src/test/resources/custom-snippet-templates/request-fields-with-list-description.snippet @@ -0,0 +1,12 @@ +[cols="1,1,1a"] +|=== +|Path|Type|Description + +{{#fields}} +|{{path}} +|{{type}} +|{{#description}} - {{.}} +{{/description}} + +{{/fields}} +|=== \ No newline at end of file