Skip to content

Commit ba327f1

Browse files
committed
Ensure that all nodes for a snippet refer to main document
Previously, when the operation block macro rendered the fragment for a snippet, every top-level block in the fragment had its parent set. Setting the parent has the side-effect of also setting the block's document to be that of its parent. This meant that every top-level block's document referred to the main document, but any descendents were left with their document referring to the fragment document. This did not cause a problem with the HTML backend (which does not consider a block's document) but the PDF backend does consider a block's document resulting in the descendents being omitted from the generated PDF. This commit updates the operation block macro to set the parent of every block in the fragment to its correct value. This has the side-effect of causing the block to update its document reference to point to the main document. Closes gh-396
1 parent 56a0495 commit ba327f1

File tree

7 files changed

+180
-5
lines changed

7 files changed

+180
-5
lines changed

build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ subprojects {
7272
dependency 'javax.validation:validation-api:1.1.0.Final'
7373
dependency 'junit:junit:4.12'
7474
dependency 'io.rest-assured:rest-assured:3.0.2'
75-
dependency 'org.asciidoctor:asciidoctorj:1.5.3.1'
75+
dependency 'org.apache.pdfbox:pdfbox:2.0.6'
76+
dependency 'org.asciidoctor:asciidoctorj:1.5.5'
77+
dependency 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.15'
7678
dependency 'org.hamcrest:hamcrest-core:1.3'
7779
dependency 'org.hamcrest:hamcrest-library:1.3'
7880
dependency 'org.hibernate:hibernate-validator:5.2.2.Final'

spring-restdocs-asciidoctor/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ description = 'Asciidoctor extensions for Spring REST Docs'
33
dependencies {
44
provided 'org.asciidoctor:asciidoctorj'
55
testCompile 'junit:junit'
6+
testCompile 'org.apache.pdfbox:pdfbox'
67
testCompile 'org.asciidoctor:asciidoctorj'
78
testCompile 'org.springframework:spring-core'
9+
testRuntime 'org.asciidoctor:asciidoctorj-pdf'
810
}

spring-restdocs-asciidoctor/src/main/resources/extensions/operation_block_macro.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,15 @@ def do_read_snippets(snippets, parent, operation, snippet_titles)
4747

4848
def add_blocks(content, doc, parent)
4949
options = { safe: doc.options[:safe],
50-
attributes: { 'fragment' => '',
51-
'projectdir' => doc.attr(:projectdir) } }
50+
attributes: { 'projectdir' => doc.attr(:projectdir) } }
5251
fragment = Asciidoctor.load content, options
5352
fragment.blocks.each do |b|
5453
b.parent = parent
5554
parent << b
5655
end
56+
parent.find_by.each do |b|
57+
b.parent = b.parent unless b.is_a? Asciidoctor::Document
58+
end
5759
end
5860

5961
def snippets_to_include(snippet_names, snippets_dir, operation)

spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/OperationBlockMacroTests.java

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,14 @@
2222
import java.nio.file.Files;
2323
import java.nio.file.Path;
2424
import java.nio.file.Paths;
25-
25+
import java.util.ArrayList;
26+
import java.util.List;
27+
28+
import org.apache.pdfbox.contentstream.PDFStreamEngine;
29+
import org.apache.pdfbox.contentstream.operator.Operator;
30+
import org.apache.pdfbox.cos.COSBase;
31+
import org.apache.pdfbox.cos.COSString;
32+
import org.apache.pdfbox.pdmodel.PDDocument;
2633
import org.asciidoctor.Asciidoctor;
2734
import org.asciidoctor.Attributes;
2835
import org.asciidoctor.Options;
@@ -33,6 +40,7 @@
3340
import org.springframework.util.FileSystemUtils;
3441

3542
import static org.hamcrest.CoreMatchers.equalTo;
43+
import static org.hamcrest.CoreMatchers.hasItems;
3644
import static org.hamcrest.CoreMatchers.startsWith;
3745
import static org.junit.Assert.assertThat;
3846

@@ -62,12 +70,38 @@ public void setUp() {
6270
}
6371

6472
@Test
65-
public void simpleSnippetInclude() throws Exception {
73+
public void codeBlockSnippetInclude() throws Exception {
6674
String result = this.asciidoctor.convert(
6775
"operation::some-operation[snippets='curl-request']", this.options);
6876
assertThat(result, equalTo(getExpectedContentFromFile("snippet-simple")));
6977
}
7078

79+
@Test
80+
public void codeBlockSnippetIncludeWithPdfBackend() throws Exception {
81+
File output = configurePdfOutput();
82+
this.asciidoctor.convert("operation::some-operation[snippets='curl-request']",
83+
this.options);
84+
assertThat(extractStrings(output),
85+
hasItems("Curl request", "$ curl 'http://localhost:8080/' -i", "1"));
86+
}
87+
88+
@Test
89+
public void tableSnippetInclude() throws Exception {
90+
String result = this.asciidoctor.convert(
91+
"operation::some-operation[snippets='response-fields']", this.options);
92+
assertThat(result, equalTo(getExpectedContentFromFile("snippet-table")));
93+
}
94+
95+
@Test
96+
public void tableSnippetIncludeWithPdfBackend() throws Exception {
97+
File output = configurePdfOutput();
98+
this.asciidoctor.convert("operation::some-operation[snippets='response-fields']",
99+
this.options);
100+
assertThat(extractStrings(output),
101+
hasItems("Response fields", "Path", "Type", "Description", "a", "Object",
102+
"one", "a.b", "Number", "two", "a.c", "String", "three", "1"));
103+
}
104+
71105
@Test
72106
public void includeSnippetInSection() throws Exception {
73107
String result = this.asciidoctor.convert(
@@ -76,6 +110,16 @@ public void includeSnippetInSection() throws Exception {
76110
assertThat(result, equalTo(getExpectedContentFromFile("snippet-in-section")));
77111
}
78112

113+
@Test
114+
public void includeSnippetInSectionWithPdfBackend() throws Exception {
115+
File output = configurePdfOutput();
116+
this.asciidoctor.convert(
117+
"== Section\n" + "operation::some-operation[snippets='curl-request']",
118+
this.options);
119+
assertThat(extractStrings(output), hasItems("Section", "Curl request",
120+
"$ curl 'http://localhost:8080/' -i", "1"));
121+
}
122+
79123
@Test
80124
public void includeMultipleSnippets() throws Exception {
81125
String result = this.asciidoctor.convert(
@@ -163,4 +207,41 @@ private Attributes getAttributes() {
163207
return attributes;
164208
}
165209

210+
private File configurePdfOutput() {
211+
this.options.setBackend("pdf");
212+
File output = new File("build/output.pdf");
213+
this.options.setToFile(output.getAbsolutePath());
214+
return output;
215+
}
216+
217+
private List<String> extractStrings(File pdfFile) throws IOException {
218+
PDDocument pdf = PDDocument.load(pdfFile);
219+
assertThat(pdf.getNumberOfPages(), equalTo(1));
220+
StringExtractor stringExtractor = new StringExtractor();
221+
stringExtractor.processPage(pdf.getPage(0));
222+
return stringExtractor.getStrings();
223+
}
224+
225+
private static final class StringExtractor extends PDFStreamEngine {
226+
227+
private final List<String> strings = new ArrayList<>();
228+
229+
@Override
230+
protected void processOperator(Operator operator, List<COSBase> operands)
231+
throws IOException {
232+
if ("Tj".equals(operator.getName())) {
233+
for (COSBase operand : operands) {
234+
if (operand instanceof COSString) {
235+
this.strings.add((((COSString) operand).getASCII()));
236+
}
237+
}
238+
}
239+
}
240+
241+
public List<String> getStrings() {
242+
return this.strings;
243+
}
244+
245+
}
246+
166247
}

spring-restdocs-asciidoctor/src/test/resources/operations/all-snippets.html

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,40 @@ <h2 id="_http_request">HTTP request</h2>
2828
</div>
2929
</div>
3030
</div>
31+
</div>
32+
<div class="sect1">
33+
<h2 id="_response_fields">Response fields</h2>
34+
<div class="sectionbody">
35+
<table class="tableblock frame-all grid-all spread">
36+
<colgroup>
37+
<col style="width: 33.3333%;">
38+
<col style="width: 33.3333%;">
39+
<col style="width: 33.3334%;">
40+
</colgroup>
41+
<thead>
42+
<tr>
43+
<th class="tableblock halign-left valign-top">Path</th>
44+
<th class="tableblock halign-left valign-top">Type</th>
45+
<th class="tableblock halign-left valign-top">Description</th>
46+
</tr>
47+
</thead>
48+
<tbody>
49+
<tr>
50+
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>a</code></p></td>
51+
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Object</code></p></td>
52+
<td class="tableblock halign-left valign-top"><p class="tableblock">one</p></td>
53+
</tr>
54+
<tr>
55+
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>a.b</code></p></td>
56+
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Number</code></p></td>
57+
<td class="tableblock halign-left valign-top"><p class="tableblock">two</p></td>
58+
</tr>
59+
<tr>
60+
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>a.c</code></p></td>
61+
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
62+
<td class="tableblock halign-left valign-top"><p class="tableblock">three</p></td>
63+
</tr>
64+
</tbody>
65+
</table>
66+
</div>
3167
</div>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<div class="sect1">
2+
<h2 id="_response_fields">Response fields</h2>
3+
<div class="sectionbody">
4+
<table class="tableblock frame-all grid-all spread">
5+
<colgroup>
6+
<col style="width: 33.3333%;">
7+
<col style="width: 33.3333%;">
8+
<col style="width: 33.3334%;">
9+
</colgroup>
10+
<thead>
11+
<tr>
12+
<th class="tableblock halign-left valign-top">Path</th>
13+
<th class="tableblock halign-left valign-top">Type</th>
14+
<th class="tableblock halign-left valign-top">Description</th>
15+
</tr>
16+
</thead>
17+
<tbody>
18+
<tr>
19+
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>a</code></p></td>
20+
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Object</code></p></td>
21+
<td class="tableblock halign-left valign-top"><p class="tableblock">one</p></td>
22+
</tr>
23+
<tr>
24+
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>a.b</code></p></td>
25+
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Number</code></p></td>
26+
<td class="tableblock halign-left valign-top"><p class="tableblock">two</p></td>
27+
</tr>
28+
<tr>
29+
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>a.c</code></p></td>
30+
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
31+
<td class="tableblock halign-left valign-top"><p class="tableblock">three</p></td>
32+
</tr>
33+
</tbody>
34+
</table>
35+
</div>
36+
</div>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
|===
2+
|Path|Type|Description
3+
4+
|`a`
5+
|`Object`
6+
|one
7+
8+
|`a.b`
9+
|`Number`
10+
|two
11+
12+
|`a.c`
13+
|`String`
14+
|three
15+
16+
|===

0 commit comments

Comments
 (0)