Skip to content

Commit

Permalink
Fix calculation of baseDir in site-integration
Browse files Browse the repository at this point in the history
Calculation now takes into consideration locale and siteDirectory
correctly.
  • Loading branch information
abelsromero committed Nov 1, 2024
1 parent 72490d4 commit a134c8b
Show file tree
Hide file tree
Showing 10 changed files with 404 additions and 199 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.asciidoctor.maven.site.SiteBaseDirResolver.resolveBaseDir;

/**
* This class is used by <a href="https://maven.apache.org/doxia/overview.html">the Doxia framework</a>
* to handle the actual parsing of the AsciiDoc input files into HTML to be consumed/wrapped
Expand Down Expand Up @@ -68,7 +70,7 @@ public void parse(Reader reader, Sink sink, String reference) throws ParseExcept

final MavenProject project = mavenProjectProvider.get();
final Xpp3Dom siteConfig = getSiteConfig(project);
final File siteDirectory = resolveSiteDirectory(project, siteConfig);
final File siteDirectory = resolveBaseDir(project.getBasedir(), siteConfig);

// Doxia handles a single instance of this class and invokes it multiple times.
// We need to ensure certain elements are initialized only once to avoid errors.
Expand Down Expand Up @@ -127,17 +129,13 @@ protected Xpp3Dom getSiteConfig(MavenProject project) {
return project.getGoalConfiguration("org.apache.maven.plugins", "maven-site-plugin", "site", "site");
}

protected File resolveSiteDirectory(MavenProject project, Xpp3Dom siteConfig) {
File siteDirectory = new File(project.getBasedir(), "src/site");
if (siteConfig != null) {
Xpp3Dom siteDirectoryNode = siteConfig.getChild("siteDirectory");
if (siteDirectoryNode != null) {
siteDirectory = new File(siteDirectoryNode.getValue());
}
}
return siteDirectory;
}

// The possible baseDir based on configuration are:
//
// with nothing : src/site + /asciidoc
// with locale : src/site + {locale} + /asciidoc
// with siteDirectory : {siteDirectory} + /asciidoc
// with siteDirectory + locale : {siteDirectory} + {locale} + /asciidoc
protected OptionsBuilder defaultOptions(File siteDirectory) {
return Options.builder()
.backend("xhtml")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

Expand All @@ -15,6 +16,7 @@
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import static org.asciidoctor.maven.site.AsciidoctorConverterDoxiaParser.ROLE_HINT;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.codehaus.plexus.util.ReflectionUtils.setVariableValueInObject;
Expand All @@ -24,43 +26,44 @@
class AsciidoctorConverterDoxiaParserTest {

private static final String TEST_DOCS_PATH = "src/test/resources/";
private static final String SAMPLE_ASCIIDOC = "sample.asciidoc";

@Test
void should_convert_html_without_any_configuration() throws FileNotFoundException, ParseException {
final File srcAsciidoc = new File(TEST_DOCS_PATH, "sample.asciidoc");
final File srcAsciidoc = new File(TEST_DOCS_PATH, SAMPLE_ASCIIDOC);
final Sink sink = createSinkMock();

AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser();

parser.parse(new FileReader(srcAsciidoc), sink);

assertThat(((TextProviderSink) sink).text)
.contains("<h1>Document Title</h1>")
.contains("<div class=\"ulist\">")
.contains("<div class=\"listingblock\">")
.contains("require 'asciidoctor'")
.contains("<div class=\"title\">Note</div>");
.contains("<h1>Document Title</h1>")
.contains("<div class=\"ulist\">")
.contains("<div class=\"listingblock\">")
.contains("require 'asciidoctor'")
.contains("<div class=\"title\">Note</div>");
}

@Test
void should_convert_html_with_an_attribute() throws FileNotFoundException, ParseException {
final File srcAsciidoc = new File(TEST_DOCS_PATH, "sample.asciidoc");
final File srcAsciidoc = new File(TEST_DOCS_PATH, SAMPLE_ASCIIDOC);
Reader reader = new FileReader(srcAsciidoc);

Sink sink = createSinkMock();
AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <asciidoc>\n" +
" <attributes>\n" +
" <icons>font</icons>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");
"<configuration>\n" +
" <asciidoc>\n" +
" <attributes>\n" +
" <icons>font</icons>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");

parser.parse(reader, sink);

assertThat(((TextProviderSink) sink).text)
.contains("<i class=\"fa icon-note\" title=\"Note\"></i>");
.contains("<i class=\"fa icon-note\" title=\"Note\"></i>");
}

@Test
Expand All @@ -69,18 +72,18 @@ void should_convert_html_with_baseDir_option() throws FileNotFoundException, Par
final Sink sink = createSinkMock();

AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <asciidoc>\n" +
" <baseDir>" + new File(srcAsciidoc.getParent()).getAbsolutePath() + "</baseDir>\n" +
" </asciidoc>\n" +
"</configuration>");
"<configuration>\n" +
" <asciidoc>\n" +
" <baseDir>" + new File(srcAsciidoc.getParent()).getAbsolutePath() + "</baseDir>\n" +
" </asciidoc>\n" +
"</configuration>");

parser.parse(new FileReader(srcAsciidoc), sink);

// 'include works'
assertThat(((TextProviderSink) sink).text)
.contains("<h1>Include test</h1>")
.contains("println \"HelloWorld from Groovy on ${new Date()}\"");
.contains("<h1>Include test</h1>")
.contains("println \"HelloWorld from Groovy on ${new Date()}\"");
}

@Test
Expand All @@ -89,39 +92,39 @@ void should_convert_html_with_relative_baseDir_option() throws FileNotFoundExcep
final Sink sink = createSinkMock();

AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <asciidoc>\n" +
" <baseDir>" + TEST_DOCS_PATH + "</baseDir>\n" +
" </asciidoc>\n" +
"</configuration>");
"<configuration>\n" +
" <asciidoc>\n" +
" <baseDir>" + TEST_DOCS_PATH + "</baseDir>\n" +
" </asciidoc>\n" +
"</configuration>");

parser.parse(new FileReader(srcAsciidoc), sink);

// 'include works'
assertThat(((TextProviderSink) sink).text)
.contains("<h1>Include test</h1>")
.contains("println \"HelloWorld from Groovy on ${new Date()}\"");
.contains("<h1>Include test</h1>")
.contains("println \"HelloWorld from Groovy on ${new Date()}\"");
}

@Test
void should_convert_html_with_templateDir_option() throws FileNotFoundException, ParseException {
final File srcAsciidoc = new File(TEST_DOCS_PATH, "sample.asciidoc");
final File srcAsciidoc = new File(TEST_DOCS_PATH, SAMPLE_ASCIIDOC);
final Sink sink = createSinkMock();

AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <asciidoc>\n" +
" <templateDirs>\n" +
" <dir>" + TEST_DOCS_PATH + "/templates</dir>\n" +
" </templateDirs>\n" +
" </asciidoc>\n" +
"</configuration>");
"<configuration>\n" +
" <asciidoc>\n" +
" <templateDirs>\n" +
" <dir>" + TEST_DOCS_PATH + "/templates</dir>\n" +
" </templateDirs>\n" +
" </asciidoc>\n" +
"</configuration>");

parser.parse(new FileReader(srcAsciidoc), sink);

assertThat(((TextProviderSink) sink).text)
.contains("<h1>Document Title</h1>")
.contains("<p class=\"custom-template \">");
.contains("<h1>Document Title</h1>")
.contains("<p class=\"custom-template \">");
}

@Test
Expand All @@ -130,68 +133,92 @@ void should_convert_html_with_attributes_and_baseDir_option() throws FileNotFoun
final Sink sink = createSinkMock();

AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <asciidoc>\n" +
" <baseDir>" + new File(srcAsciidoc.getParent()).getAbsolutePath() + "</baseDir>\n" +
" <attributes>\n" +
" <sectnums></sectnums>\n" +
" <icons>font</icons>\n" +
" <my-label>Hello World!!</my-label>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");
"<configuration>\n" +
" <asciidoc>\n" +
" <baseDir>" + new File(srcAsciidoc.getParent()).getAbsolutePath() + "</baseDir>\n" +
" <attributes>\n" +
" <sectnums></sectnums>\n" +
" <icons>font</icons>\n" +
" <my-label>Hello World!!</my-label>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");

parser.parse(new FileReader(srcAsciidoc), sink);

assertThat(((TextProviderSink) sink).text)
.contains("<h1>Include test</h1>")
.contains("<h2 id=\"code\">1. Code</h2>")
.contains("<h2 id=\"optional_section\">2. Optional section</h2>")
.contains("println \"HelloWorld from Groovy on ${new Date()}\"")
.contains("Hello World!!")
.contains("<i class=\"fa icon-tip\" title=\"Tip\"></i>");
.contains("<h1>Include test</h1>")
.contains("<h2 id=\"code\">1. Code</h2>")
.contains("<h2 id=\"optional_section\">2. Optional section</h2>")
.contains("println \"HelloWorld from Groovy on ${new Date()}\"")
.contains("Hello World!!")
.contains("<i class=\"fa icon-tip\" title=\"Tip\"></i>");
}

@Test
void should_convert_html_in_locale_path() throws IOException, ParseException {
final String localeSourceDir = TEST_DOCS_PATH + "with-locale/";
final File srcAsciidoc = new File(localeSourceDir + "en/" + ROLE_HINT, "sample.adoc");
Reader reader = new FileReader(srcAsciidoc);

Sink sink = createSinkMock();
AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <siteDirectory>" + localeSourceDir + "</siteDirectory>\n" +
" <locales>en</locales>\n" +
" <asciidoc>\n" +
" <attributes>\n" +
" <icons>font</icons>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");

parser.parse(reader, sink);

assertThat(((TextProviderSink) sink).text)
.contains("This has been included");
}

@Test
void should_process_empty_selfclosing_XML_attributes() throws FileNotFoundException, ParseException {
final File srcAsciidoc = new File(TEST_DOCS_PATH, "sample.asciidoc");
final File srcAsciidoc = new File(TEST_DOCS_PATH, SAMPLE_ASCIIDOC);
final Sink sink = createSinkMock();

AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <asciidoc>\n" +
" <attributes>\n" +
" <sectnums/>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");
"<configuration>\n" +
" <asciidoc>\n" +
" <attributes>\n" +
" <sectnums/>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");

parser.parse(new FileReader(srcAsciidoc), sink);

assertThat(((TextProviderSink) sink).text)
.contains("<h2 id=\"id_section_a\">1. Section A</h2>")
.contains("<h3 id=\"id_section_a_subsection\">1.1. Section A Subsection</h3>");
.contains("<h2 id=\"id_section_a\">1. Section A</h2>")
.contains("<h3 id=\"id_section_a_subsection\">1.1. Section A Subsection</h3>");
}

@Test
void should_process_empty_value_XML_attributes() throws FileNotFoundException, ParseException {
final File srcAsciidoc = new File(TEST_DOCS_PATH, "sample.asciidoc");
final File srcAsciidoc = new File(TEST_DOCS_PATH, SAMPLE_ASCIIDOC);
final Sink sink = createSinkMock();

AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <asciidoc>\n" +
" <attributes>\n" +
" <sectnums></sectnums>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");
"<configuration>\n" +
" <asciidoc>\n" +
" <attributes>\n" +
" <sectnums></sectnums>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");

parser.parse(new FileReader(srcAsciidoc), sink);

assertThat(((TextProviderSink) sink).text)
.contains("<h2 id=\"id_section_a\">1. Section A</h2>")
.contains("<h3 id=\"id_section_a_subsection\">1.1. Section A Subsection</h3>");
.contains("<h2 id=\"id_section_a\">1. Section A</h2>")
.contains("<h3 id=\"id_section_a_subsection\">1.1. Section A Subsection</h3>");
}

@Test
Expand All @@ -200,32 +227,32 @@ void should_fail_when_logHandler_failIf_is_WARNING() {
final Sink sink = createSinkMock();

AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <asciidoc>\n" +
" <logHandler>\n" +
" <!-- <outputToConsole>false</outputToConsole> -->\n" +
" <failIf>\n" +
" <severity>WARN</severity>\n" +
" </failIf>\n" +
" </logHandler>\n" +
" </asciidoc>\n" +
"</configuration>");
"<configuration>\n" +
" <asciidoc>\n" +
" <logHandler>\n" +
" <!-- <outputToConsole>false</outputToConsole> -->\n" +
" <failIf>\n" +
" <severity>WARN</severity>\n" +
" </failIf>\n" +
" </logHandler>\n" +
" </asciidoc>\n" +
"</configuration>");

Throwable throwable = catchThrowable(() -> parser.parse(new FileReader(srcAsciidoc), sink));

// 'issues with WARN and ERROR are returned'
assertThat(throwable)
.isInstanceOf(org.apache.maven.doxia.parser.ParseException.class)
.hasMessageContaining("Found 4 issue(s) of severity WARN or higher during conversion");
.isInstanceOf(org.apache.maven.doxia.parser.ParseException.class)
.hasMessageContaining("Found 4 issue(s) of severity WARN or higher during conversion");
}

@SneakyThrows
private javax.inject.Provider<MavenProject> createMavenProjectMock(String configuration) {
MavenProject mockProject = Mockito.mock(MavenProject.class);
when(mockProject.getBasedir())
.thenReturn(new File("."));
.thenReturn(new File("."));
when(mockProject.getGoalConfiguration(anyString(), anyString(), anyString(), anyString()))
.thenReturn(configuration != null ? Xpp3DomBuilder.build(new StringReader(configuration)) : null);
.thenReturn(configuration != null ? Xpp3DomBuilder.build(new StringReader(configuration)) : null);

return () -> mockProject;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
== Included section

This has been included.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
= Document Title

== Include

include::included.adoc[]
Loading

0 comments on commit a134c8b

Please sign in to comment.