From f649e1a17037c8cd8383acba463424d363567001 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 16 Mar 2015 13:52:00 +0000 Subject: [PATCH] Add support to DocumentationWriter for producing tables This commit adds an API to DocumentationWriter for producing documentation snippets containing tables. The API is intended to be fairly simple such that it can be implemented for a variety of different output formats, and not just for Asciidoctor (the only currently supported format). Closes gh-34 --- .../restdocs/snippet/AsciidoctorWriter.java | 43 ++++++++++++++- .../restdocs/snippet/DocumentationWriter.java | 54 ++++++++++++++++++- .../snippet/AsciidoctorWriterTests.java | 20 +++++++ 3 files changed, 113 insertions(+), 4 deletions(-) diff --git a/spring-restdocs/src/main/java/org/springframework/restdocs/snippet/AsciidoctorWriter.java b/spring-restdocs/src/main/java/org/springframework/restdocs/snippet/AsciidoctorWriter.java index bd64c055..fe35ef42 100644 --- a/spring-restdocs/src/main/java/org/springframework/restdocs/snippet/AsciidoctorWriter.java +++ b/spring-restdocs/src/main/java/org/springframework/restdocs/snippet/AsciidoctorWriter.java @@ -27,6 +27,12 @@ import java.io.Writer; */ public class AsciidoctorWriter extends DocumentationWriter { + private static final String DELIMITER_CODE_BLOCK = "----"; + + private static final String DELIMITER_TABLE = "|==="; + + private final TableWriter tableWriter = new AsciidoctorTableWriter(); + /** * Creates a new {@code AsciidoctorWriter} that will write to the given {@code writer} * @param writer The writer to which output will be written @@ -53,10 +59,43 @@ public class AsciidoctorWriter extends DocumentationWriter { if (language != null) { println("[source," + language + "]"); } - println("----"); + println(DELIMITER_CODE_BLOCK); action.perform(); - println("----"); + println(DELIMITER_CODE_BLOCK); println(); } + @Override + public void table(TableAction action) throws IOException { + println(); + println(DELIMITER_TABLE); + action.perform(this.tableWriter); + println(DELIMITER_TABLE); + println(); + } + + private final class AsciidoctorTableWriter implements TableWriter { + + @Override + public void headers(String... headers) { + StringBuilder builder = new StringBuilder(); + for (String header : headers) { + builder.append("|"); + builder.append(header); + } + println(builder.toString()); + println(); + } + + @Override + public void row(String... entries) { + for (String entry : entries) { + print("|"); + println(entry); + } + println(); + } + + } + } diff --git a/spring-restdocs/src/main/java/org/springframework/restdocs/snippet/DocumentationWriter.java b/spring-restdocs/src/main/java/org/springframework/restdocs/snippet/DocumentationWriter.java index 05480998..b5634401 100644 --- a/spring-restdocs/src/main/java/org/springframework/restdocs/snippet/DocumentationWriter.java +++ b/spring-restdocs/src/main/java/org/springframework/restdocs/snippet/DocumentationWriter.java @@ -46,7 +46,8 @@ public abstract class DocumentationWriter extends PrintWriter { * Calls the given {@code action} to document a code block. The code block will be * annotated as containing code written in the given {@code language}. Any prefix * necessary for the documentation format is written prior to calling the - * {@code action}. Having called the action, any necessary suffix is the written. + * {@code action}. Having called the {@code action}, any necessary suffix is then + * written. * * @param language the language in which the code is written * @param action the action that will produce the code @@ -55,11 +56,20 @@ public abstract class DocumentationWriter extends PrintWriter { public abstract void codeBlock(String language, DocumentationAction action) throws IOException; + /** + * Calls the given {@code action} to document a table. Any prefix necessary for + * documenting a table is written prior to calling the {@code action}. Having called + * the {@code action}, any necessary suffix is then written. + * + * @param action the action that will produce the table + * @throws IOException if the documentation fails + */ + public abstract void table(TableAction action) throws IOException; + /** * Encapsulates an action that outputs some documentation. Typically implemented as a * lamda or, pre-Java 8, as an anonymous inner class. * - * @author Andy Wilkinson * @see DocumentationWriter#shellCommand * @see DocumentationWriter#codeBlock */ @@ -71,5 +81,45 @@ public abstract class DocumentationWriter extends PrintWriter { * @throws IOException if the action fails */ void perform() throws IOException; + } + + /** + * Encapsulates an action that outputs a table. + * + * @see DocumentationWriter#table(TableAction) + */ + public interface TableAction { + + /** + * Perform the encapsulated action + * + * @param tableWriter the writer to be used to write the table + * @throws IOException if the action fails + */ + void perform(TableWriter tableWriter) throws IOException; + + } + + /** + * A writer for producing a table + */ + public interface TableWriter { + + /** + * Writes the table's headers + * + * @param headers the headers + */ + void headers(String... headers); + + /** + * Writes a row in the table + * + * @param entries the entries in the row + */ + void row(String... entries); + + } + } diff --git a/spring-restdocs/src/test/java/org/springframework/restdocs/snippet/AsciidoctorWriterTests.java b/spring-restdocs/src/test/java/org/springframework/restdocs/snippet/AsciidoctorWriterTests.java index 9e56f347..15eb2728 100644 --- a/spring-restdocs/src/test/java/org/springframework/restdocs/snippet/AsciidoctorWriterTests.java +++ b/spring-restdocs/src/test/java/org/springframework/restdocs/snippet/AsciidoctorWriterTests.java @@ -24,6 +24,8 @@ import java.io.Writer; import org.junit.Test; import org.springframework.restdocs.snippet.DocumentationWriter.DocumentationAction; +import org.springframework.restdocs.snippet.DocumentationWriter.TableAction; +import org.springframework.restdocs.snippet.DocumentationWriter.TableWriter; /** * Tests for {@link AsciidoctorWriter} @@ -63,4 +65,22 @@ public class AsciidoctorWriterTests { String expectedOutput = String.format("%n[source,bash]%n----%n$ foo%n----%n%n"); assertEquals(expectedOutput, this.output.toString()); } + + @Test + public void table() throws Exception { + this.documentationWriter.table(new TableAction() { + + @Override + public void perform(TableWriter tableWriter) throws IOException { + tableWriter.headers("One", "Two", "Three"); + tableWriter.row("alpha", "bravo", "charlie"); + tableWriter.row("foo", "bar", "baz"); + } + + }); + String expectedOutput = String + .format("%n|===%n|One|Two|Three%n%n|alpha%n|bravo%n|charlie%n%n|foo%n|bar%n|baz%n%n|===%n%n"); + assertEquals(expectedOutput, this.output.toString()); + System.out.println(this.output.toString()); + } }