package example.helloworld; import org.seamless.xhtml.XHTML; import example.util.DocletTest; import org.testng.annotations.Test; import static org.testng.Assert.assertEquals; /** * Hello World: Creating testable documentation * <p> * Let's assume you want to test <em>and</em> document the following {@code HelloWorld} Java class: * </p> * <a class="citation" href="javacode://example.helloworld.HelloWorld">Citation</a> * <p> * First, write a unit test method that checks the class: * </p> * <a class="citation" href="javacode://example.helloworld.HelloWorldTest#testHelloWorld">Citation</a> * <p> * This unit test not only validates the correct behavior of the class, it also shows how the class is * supposed to be used. Traditionally, you'd now add a section in your software's manual, where you copy and * paste the code of the {@code HelloWorld} class and some lines from the unit test. Your users will * then be able to understand the internals and how they should work with the class. * </p> * <p> * With Lemma you don't copy/paste anything but write documentation as Javadoc on the test method in XHTML syntax: * </p> * <a class="citation" href="javacode://example.helloworld.HelloWorldTest" style="include: TEST_HELLOWORLD; clean-labels: boundary;">Citation</a> * <p> * You probably already know all of the XHTML elements and attributes used in this Javadoc comment, in fact, you can * use any tags you need to write your documentation. * </p> * <p> * Lemma parses your markup and replaces the content of * {@code <a>} elements that have a {@code citation} class. The first anchor in the example above is * referencing the raw Java source code of a class called {@code example.helloworld.HelloWorld}. How this source * code is found by Lemma depends on your configuration, we'll look at that later. Note how the URL scheme * {@code javacode://} is used to indicate what part of the referenced resource you want to cite. This URL is actually * refactoring-safe, your IDE should be able to automatically update the URL string when you rename the package or * {@code HelloWorld} class name. * </p> * <p> * The second anchor is more specific, it's a citation for a fragment of code. The URL references the source of the * test class and the test method (yes, it's referencing "itself"). You'll probably recognize the method reference syntax * from Javadoc, it's the same as for regular Javadoc {@code @link} and {@code @see} tags, hence also safe for * refactoring. Citation options are declared with the {@code style} attribute, they look like CSS options. The * {@code include} option shown here accepts a list of fragment labels which should be cited. A fragment label is * a Java line comment starting with "{@code // DOC: (LABEL)}". Two lines with the same label mark the beginning and end * of a fragment block. So this citation will only include the four lines of the method body. You'll later see more * details about citation options, fragments, and labels. * </p> * <p> * The previous Javadoc represents just one small section of your overall documentation. Lemma's default processing * pipeline expects that you also create a master template file in XHTML that brings together all of your documentation * parts, chapters, and sections. How that template looks like, and how parts, chapters, and sections are organized and * finally rendered is up to you. Here is a simple example of a template: * </p> * <a class="citation" href="example/helloworld/example01_input.xhtml">Citation</a> * <p> * Note that the URL scheme for this citation is {@code javadoc://}. The Lemma processor will follow the URL * to your test class and test method, and then read and process the Javadoc comment of that resource. This is a recursive * procedure, so any citation anchors in the Javadoc comment are followed and processed as well. Finally, the following output * is generated: * </p> * <a class="citation" href="example/helloworld/example01_output.xhtml">Citation</a> * <p> * The formatting and indentation of this XHTML document has been automatically generated by a pretty printer, so it * readability could obvioulsy be improved. All Javadoc code fragments have been properly escaped in CDATA sections. All * cited source fragments have been escaped with XHTML entities instead (future versions of Lemma will likely embed * XHTML markup for callouts into code blocks, hence they are not defined as CDATA sections). * </p> * <p> * This is how it looks rendered in a browser: * </p> * <img src="doc-files/helloworld_rendered_output.png" style="border: 1px solid black;" alt="HelloWorld Output"/> */ public class HelloWorldTest extends DocletTest { // DOC: TEST_HELLOWORLD /** * The {@code HelloWorld} class * <p> * This is the source of the class: * </p> * * <a class="citation" href="javacode://example.helloworld.HelloWorld"/> * * <p> * To use the class, first instantiate it, then call either {@code getMessage()} to retrieve * the message string or {@code sayHello()} to print the message to {@code System.out}: * </p> * * <a class="citation" href="javacode://example.helloworld.HelloWorldTest#testHelloWorld" style="include: HELLOWORLD_USAGE;"/> * * <p> * If you don't want the message printed to {@code System.out}, don't call the * {@code sayHello()} method. * </p> */ @Test public void testHelloWorld() { HelloWorld hw = new HelloWorld(); // DOC: HELLOWORLD_USAGE assert hw.getMessage().equals("Hello World!"); assert hw.getMessage().endsWith("!"); hw.sayHello(); // DOC: HELLOWORLD_USAGE } // DOC: TEST_HELLOWORLD @Test public void processDocumentation() throws Exception { XHTML output = getTemplatePipeline().execute( parseDocument("example/helloworld/example01_input.xhtml") ); assertEquals( getParser().print(output), getContent("example/helloworld/example01_output.xhtml") ); } }