Reuse document's attributes when loading snippet content

Previously, when adding blocks for the snippets' content, the
operation macro would call Asciidoctor to load the content with
attributes that only included the projectdir. This resulted in a
failure in environments that did not set the projectdir and instead
relied on another attribute, such as gradle-projectdir as used by
the latest versions of the Asciidoctor Gradle plugin.

This commit updates the macro to reuse all of the main document's
attributes when loading the snippets' content, thereby ensuring that
any attributes available in the main document are also available
during snipppet processing.

Closes gh-624
This commit is contained in:
Andy Wilkinson
2019-06-20 10:15:03 +01:00
parent 3dabf8e53f
commit 619847582a
4 changed files with 170 additions and 20 deletions

View File

@@ -47,8 +47,7 @@ class OperationBlockMacro < Asciidoctor::Extensions::BlockMacroProcessor
end
def add_blocks(content, doc, parent)
options = { safe: doc.options[:safe],
attributes: { 'projectdir' => doc.attr(:projectdir) } }
options = { safe: doc.options[:safe], attributes: doc.attributes }
fragment = Asciidoctor.load content, options
fragment.blocks.each do |b|
b.parent = parent

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,39 +33,48 @@ import org.apache.pdfbox.pdmodel.PDDocument;
import org.asciidoctor.Asciidoctor;
import org.asciidoctor.Attributes;
import org.asciidoctor.Options;
import org.asciidoctor.OptionsBuilder;
import org.asciidoctor.SafeMode;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for Ruby operation block macro.
* Base class for tests for the Ruby operation block macro.
*
* @author Gerrit Meier
* @author Andy Wilkinson
*/
public class OperationBlockMacroTests {
public abstract class AbstractOperationBlockMacroTests {
private final Options options = new Options();
@Rule
public TemporaryFolder temp = new TemporaryFolder();
private Options options;
private final Asciidoctor asciidoctor = Asciidoctor.Factory.create();
@BeforeClass
public static void prepareOperationSnippets() throws IOException {
File destination = new File("build/generated-snippets/some-operation");
@Before
public void setUp() throws IOException {
prepareOperationSnippets(getBuildOutputLocation());
this.options = OptionsBuilder.options().safe(SafeMode.UNSAFE)
.baseDir(getSourceLocation()).get();
this.options.setAttributes(getAttributes());
}
public void prepareOperationSnippets(File buildOutputLocation) throws IOException {
File destination = new File(buildOutputLocation,
"generated-snippets/some-operation");
destination.mkdirs();
FileSystemUtils.copyRecursively(new File("src/test/resources/some-operation"),
destination);
}
@Before
public void setUp() {
this.options.setAttributes(getAttributes());
}
@Test
public void codeBlockSnippetInclude() throws Exception {
String result = this.asciidoctor.convert(
@@ -208,11 +217,11 @@ public class OperationBlockMacroTests {
return File.separatorChar == '\\';
}
private Attributes getAttributes() {
Attributes attributes = new Attributes();
attributes.setAttribute("projectdir", new File(".").getAbsolutePath());
return attributes;
}
protected abstract Attributes getAttributes();
protected abstract File getBuildOutputLocation();
protected abstract File getSourceLocation();
private File configurePdfOutput() {
this.options.setBackend("pdf");

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.restdocs.asciidoctor;
import java.io.File;
import org.asciidoctor.Attributes;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
/**
* Tests for Ruby operation block macro when used in a Gradle build.
*
* @author Andy Wilkinson
*/
@RunWith(Parameterized.class)
public class GradleOperationBlockMacroTests extends AbstractOperationBlockMacroTests {
private final String attributeName;
public GradleOperationBlockMacroTests(String attributeName) {
this.attributeName = attributeName;
}
@Parameters(name = "{0}")
public static Object[] parameters() {
return new Object[] { "projectdir", "gradle-projectdir" };
}
protected Attributes getAttributes() {
Attributes attributes = new Attributes();
attributes.setAttribute(this.attributeName,
new File(temp.getRoot(), "gradle-project").getAbsolutePath());
return attributes;
}
@Override
protected File getBuildOutputLocation() {
File outputLocation = new File(temp.getRoot(), "gradle-project/build");
outputLocation.mkdirs();
return outputLocation;
}
@Override
protected File getSourceLocation() {
File sourceLocation = new File(temp.getRoot(),
"gradle-project/src/docs/asciidoc");
if (!sourceLocation.exists()) {
sourceLocation.mkdirs();
}
return sourceLocation;
}
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.restdocs.asciidoctor;
import java.io.File;
import java.io.IOException;
import org.asciidoctor.Attributes;
import org.junit.After;
import org.junit.Before;
/**
* Tests for Ruby operation block macro when used in a Maven build.
*
* @author Andy Wilkinson
*/
public class MavenOperationBlockMacroTests extends AbstractOperationBlockMacroTests {
@Before
public void setMavenHome() {
System.setProperty("maven.home", "maven-home");
}
@After
public void clearMavenHome() {
System.clearProperty("maven.home");
}
protected Attributes getAttributes() {
try {
File sourceLocation = getSourceLocation();
new File(sourceLocation.getParentFile().getParentFile().getParentFile(),
"pom.xml").createNewFile();
Attributes attributes = new Attributes();
attributes.setAttribute("docdir", sourceLocation.getAbsolutePath());
return attributes;
}
catch (IOException ex) {
throw new RuntimeException(ex);
}
}
@Override
protected File getBuildOutputLocation() {
File outputLocation = new File(temp.getRoot(), "maven-project/target");
outputLocation.mkdirs();
return outputLocation;
}
@Override
protected File getSourceLocation() {
File sourceLocation = new File(temp.getRoot(), "maven-project/src/main/asciidoc");
if (!sourceLocation.exists()) {
sourceLocation.mkdirs();
}
return sourceLocation;
}
}