When we define a list in Asciidoctor we usually have a list item that is a paragraph.
But if we want to have a block as list item we need to add an extra element to make sure the block is parsed correctly as list item.
Because a list item starts with a . or a * at the beginning of a line and a block also is defined on the beginning of the line, we must add the extra element.
Together with the list item continuation (+) we can have a list with blocks.
In the following example we define a numbered list with three listing blocks:
Continue reading →
PlantUML has some features that come from the underlying software to create diagrams.
Graphviz is used by PlantUML and we can use Graphviz features in our PlantUML diagrams.
For example we can align multi-line text of labels to be either center (default), left or right aligned using a Graphviz feature.
When we want to text to be center aligned we simply use the new-line character \n.
If we want to have our text left aligned we use \l instead of \n.
And to right align the text we use \r.
In the following example we have three labels that are center, left and right aligned:
Continue reading →
Normally if we type an URL in Asciidoctor that starts with a scheme Asciidoctor knows about, the URL is turned into a hyperlink.
The following schemes are recognized by Asciidoctor:
Continue reading →
With Asciidoctor markup we can position images in our document.
We can even float images, so text can next to an image, inside only below or about the image.
We can also define multiple images to float, so the images are displayed on the same line next to each other.
Any text that follows these images is also displayed next to the images.
If we want only to have floating images, but the text starting under the images we can place the images inside an open block and assign the block the role float-group.
In the next example we first define three images that all have roles to float left.
In the second part we group these images using the role float-group, so the text will not be displayed next to the images, but under the images:
Continue reading →
In a previous post we learned how to use data in CSV and DSV format.
Recently we can also include tab separated values (TSV) in a Asciidoctor table.
We must set the table attribute format to the value tsv.
The data can be inside the document, but also defined in an external file which we add with the include macro.
In the following example markup we have a table with inline tab separated values.
A second table includes an external file with tab delimited values:
Continue reading →
When we write a list in Asciidoctor we can simply create a list item by starting the line with a dot (.).
To create a another list item we simply start a new line with a dot (.).
But what if we want to add a list item with multiple paragraphs, or text and a source code block element.
We can use the list item continuation (+) to indicate to Asciidoctor we want to keep these together for a single list item.
In the following example we have a list in Asciidoctor markup.
The second list item has multiple paragraphs , the third item has an extra admonition block and the fourth item contains a source code block:
Continue reading →
Writing a parameterized specification in Spock is easy.
We need to add the where: block and use data providers to specify different values.
For each set of values from the data providers our specifications is run, so we can test for example very effectively multiple input arguments for a method and the expected outcome.
A data provider can be anything that implements the Iterable interface.
Spock also adds support for a data table.
In the data table we define columns for each variable and in the rows values for each variable.
Since Spock 1.1 we can reuse the value of the variables inside the data provider or data table.
The value of the variable can only be reused in variables that are defined after the variable we want to reuse is defined.
In the following example we have two feature methods, one uses a data provider and one a data table.
The variable sentence is defined after the variable search, so we can use the search variable value in the definition of the sentence variable.
Continue reading →
We all know writing tests or specifications with Spock is fun.
We can run our specifications and when one of our assertions in a feature method invalid, the feature method is marked as failed.
If we have more than one assertion in our feature method, only the first assertion that fails is returned as an error.
Any other assertion after a failing assertion are not checked.
To let Spock execute all assertions and return all failing assertions at once we must use the verifyAll method.
We pass a closure with all our assertions to the method.
All assertions will be checked when use the verifyAll and if one or more of the assertions is invalid the feature method will fail.
In the following example specification we have 3 assertions in the feature method check all properties are valid.
We don’t use the verifyAll method in our first example.
Continue reading →
Writing unit tests for our handlers in Ratpack is easy with RequestFixture.
We invoke the handle method and use a Handler or Chain we want to test as argument.
We can provide extra details on the fixture instance with a second argument, for example adding objects to the registry or setting the request method.
The handle method returns a HandlingResult object.
This object has the method exception that we can use to see if an exception occurred in our code under test.
The method throws a HandlerExceptionNotThrownException if the expected exception doesn’t occur.
In the following example we have two feature methods to check if an exception occurred or not:
Continue reading →
Sometimes we are working on a new feature in our code and we want to write a specification for it without yet really implementing the feature.
To indicate we know the specification will fail while we are implementing the feature we can add the @PendingFeature annotation to our specification method.
With this annotation Spock will still execute the test, but will set the status to ignored if the test fails.
But if the test passes the status is set to failed.
So when we have finished the feature we need to remove the annotation and Spock will kindly remind us to do so this way.
In the following example specification we use the @PendingFeature annotation:
Continue reading →
Defining tables in Asciidoctor is very easy. The start and end of the table are defined by |===.
But if we want to add a new table to a table cell we cannot use the same syntax.
To define a nested table we must replace the | separator with !.
So instead of |=== to indicate the table boundaries we use !===.
Also the cell separators are now ! instead of |.
Finally we must make sure the table cell or column supports Asciidoc markup, so the table is properly created.
We must configure the cell or column with a so the nested table is created.
In the following example Asciidoctor markup we have a simple table with a nested table in the second column and row.
Notice we can still apply all table configuration to the nested table as well:
Continue reading →
Gradle has incremental build support to speed up our builds.
This means Gradle checks input and output for a task and if something changed the task is executed, otherwise the task is skipped.
In previous posts we learned how to add incremental build support to our tasks with annotations and inputs and outputs property of a task.
When we have a task that has an output file for an input file, like with transformations, we can have a more efficient task using an incremental task action.
With an incremental task action we have extra information on the files that are handled by the task.
We can have different actions based on if an input file is out of date or removed.
This way we can handle only the input files that have changed or removed with incremental builds, instead of all the input files.
To create an incremental task action we must have a task action method (annotated with @TaskAction) that has a single argument of type IncrementalTaskInputs.
The IncrementalTaskInputs class has the method outOfDate and removed.
These methods take an action, that can be implemented with a closure, with an instance of InputFileDetails as argument.
We can get to the input file via this instance and use that for our task logic.
When an input file is out of date, because the file contents has changed or the output file has been removed, the action we defined for the outOfDate method is invoked.
If the input file is removed the action for the method removed is invoked.
Continue reading →