/amps-maven-plugin/src/test/java/com/atlassian/maven/plugins/amps/wadl/RestDocsGeneratorTest.java
Java | 301 lines | 248 code | 44 blank | 9 comment | 0 complexity | 572b079a3dd9a8f7344482e2556b0ea5 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause
- package com.atlassian.maven.plugins.amps.wadl;
- import com.atlassian.maven.plugins.amps.MavenContext;
- import com.atlassian.maven.plugins.amps.TestMavenGoals;
- import com.atlassian.maven.plugins.amps.util.MojoExecutorWrapper;
- import com.atlassian.maven.plugins.amps.util.PreserveClassLoaderRule;
- import com.google.common.collect.ImmutableList;
- import org.apache.maven.model.Build;
- import org.apache.maven.model.Plugin;
- import org.apache.maven.plugin.MojoExecutionException;
- import org.apache.maven.plugin.logging.Log;
- import org.apache.maven.project.MavenProject;
- import org.codehaus.plexus.util.xml.Xpp3Dom;
- import org.hamcrest.Description;
- import org.hamcrest.Matcher;
- import org.hamcrest.TypeSafeMatcher;
- import org.junit.Before;
- import org.junit.Rule;
- import org.junit.Test;
- import org.junit.rules.TemporaryFolder;
- import org.junit.rules.TestRule;
- import org.mockito.ArgumentCaptor;
- import org.mockito.InjectMocks;
- import org.mockito.Mock;
- import org.mockito.junit.MockitoJUnit;
- import org.mockito.junit.MockitoRule;
- import org.twdata.maven.mojoexecutor.MojoExecutor.ExecutionEnvironment;
- import java.io.File;
- import java.net.URI;
- import java.net.URISyntaxException;
- import java.net.URL;
- import java.net.URLClassLoader;
- import java.nio.file.Files;
- import java.nio.file.Path;
- import java.nio.file.Paths;
- import java.util.Optional;
- import java.util.Set;
- import java.util.function.Function;
- import java.util.stream.Stream;
- import static com.atlassian.maven.plugins.amps.util.Xpp3DomMatchers.childMatching;
- import static com.atlassian.maven.plugins.amps.util.Xpp3DomMatchers.childrenMatching;
- import static com.atlassian.maven.plugins.amps.util.Xpp3DomMatchers.valueMatching;
- import static java.lang.Thread.currentThread;
- import static java.nio.charset.StandardCharsets.UTF_8;
- import static java.util.Arrays.stream;
- import static java.util.stream.Collectors.toSet;
- import static org.apache.commons.io.FileUtils.readFileToString;
- import static org.apache.commons.io.FileUtils.writeStringToFile;
- import static org.hamcrest.MatcherAssert.assertThat;
- import static org.hamcrest.Matchers.contains;
- import static org.hamcrest.Matchers.is;
- import static org.mockito.ArgumentMatchers.any;
- import static org.mockito.ArgumentMatchers.eq;
- import static org.mockito.ArgumentMatchers.same;
- import static org.mockito.Mockito.doAnswer;
- import static org.mockito.Mockito.doThrow;
- import static org.mockito.Mockito.never;
- import static org.mockito.Mockito.verify;
- import static org.mockito.Mockito.when;
- public class RestDocsGeneratorTest {
- @Rule
- public final MockitoRule mockitoRule = MockitoJUnit.rule();
- @Rule
- public final TemporaryFolder temporaryFolder = new TemporaryFolder();
- @Rule
- public final TestRule preserveClassLoaderRule = new PreserveClassLoaderRule();
- @Mock
- private Build build;
- @Mock
- private ExecutionEnvironment executionEnvironment;
- @Mock
- private Log log;
- @Mock
- private MavenContext mavenContext;
- @Mock
- private MavenProject mavenProject;
- @Mock
- private MojoExecutorWrapper mojoExecutorWrapper;
- @Mock
- private Plugin javadocPlugin;
- @InjectMocks
- private RestDocsGenerator restDocsGenerator;
- @Before
- public void setUpMavenContext() {
- when(mavenContext.getProject()).thenReturn(mavenProject);
- when(mavenProject.getBuild()).thenReturn(build);
- }
- private void setUpExecutionEnvironment() {
- when(mavenContext.getExecutionEnvironment()).thenReturn(executionEnvironment);
- }
- private void setUpLog() {
- when(mavenContext.getLog()).thenReturn(log);
- }
- @Test
- public void shouldGracefullyHandleRestDocGenerationFailure() throws Exception {
- setUpContextClassLoader();
- setUpExecutionEnvironment();
- setUpLog();
- createStructureInTempDirectory();
- copyPluginXmlWithRestModules();
- final Path buildOutputDirectory = temporaryFolder.getRoot().toPath().resolve("target");
- when(build.getOutputDirectory()).thenReturn(buildOutputDirectory.toAbsolutePath().toString());
- final Path sourceDirectory = temporaryFolder.getRoot().toPath().resolve("src/main/java");
- when(build.getSourceDirectory()).thenReturn(sourceDirectory.toAbsolutePath().toString());
- doThrow(new MojoExecutionException("fake problem")).when(mojoExecutorWrapper).executeWithMergedConfig(
- any(), eq("javadoc"), any(), eq(executionEnvironment));
- restDocsGenerator.generateRestDocs("");
- assertGeneratedFileEqualsExpectedFile(buildOutputDirectory, "application-doc.xml",
- "expected-application-doc.xml");
- assertGeneratedFileEqualsExpectedFile(buildOutputDirectory, "application-grammars.xml",
- "expected-application-grammars.xml");
- }
- @Test
- public void shouldNotReplaceRestDocFilesIfTheyWereGenerated() throws Exception {
- setUpContextClassLoader();
- setUpExecutionEnvironment();
- createStructureInTempDirectory();
- copyPluginXmlWithRestModules();
- final Path buildOutputDirectory = temporaryFolder.getRoot().toPath().resolve("target");
- when(build.getOutputDirectory()).thenReturn(buildOutputDirectory.toAbsolutePath().toString());
- final Path sourceDirectory = temporaryFolder.getRoot().toPath().resolve("src/main/java");
- when(build.getSourceDirectory()).thenReturn(sourceDirectory.toAbsolutePath().toString());
- doAnswer(a -> {
- writeStringToFile(buildOutputDirectory.resolve("application-doc.xml").toFile(), "appDoc", UTF_8);
- writeStringToFile(buildOutputDirectory.resolve("application-grammars.xml").toFile(), "appGrammars", UTF_8);
- return null;
- }).when(mojoExecutorWrapper).executeWithMergedConfig(any(), eq("javadoc"), any(), eq(executionEnvironment));
- restDocsGenerator.generateRestDocs("");
- assertGeneratedFileEqualsString(buildOutputDirectory, "application-doc.xml", "appDoc");
- assertGeneratedFileEqualsString(buildOutputDirectory, "application-grammars.xml", "appGrammars");
- }
- @Test
- public void shouldCorrectlyBuildPaths() throws Exception {
- // Arrange
- setUpContextClassLoader();
- setUpExecutionEnvironment();
- setUpLog();
- createStructureInTempDirectory();
- copyPluginXmlWithRestModules();
- final Path buildOutputDirectory = temporaryFolder.getRoot().toPath().resolve("target");
- when(build.getOutputDirectory()).thenReturn(buildOutputDirectory.toAbsolutePath().toString());
- final Path sourceDirectory = temporaryFolder.getRoot().toPath().resolve("src/main/java");
- when(build.getSourceDirectory()).thenReturn(sourceDirectory.toAbsolutePath().toString());
- final String jacksonModules = "java.lang.Object";
- final Set<String> expectedClasspathElements = prepareClasspathElements(buildOutputDirectory.toString());
- when(mavenContext.getPlugin("org.apache.maven.plugins", "maven-javadoc-plugin"))
- .thenReturn(javadocPlugin);
- // Act
- restDocsGenerator.generateRestDocs(jacksonModules);
- // Assert
- final ArgumentCaptor<Xpp3Dom> configCaptor = ArgumentCaptor.forClass(Xpp3Dom.class);
- verify(mojoExecutorWrapper).executeWithMergedConfig(
- same(javadocPlugin), eq("javadoc"), configCaptor.capture(), same(executionEnvironment));
- final Xpp3Dom actualConfig = configCaptor.getValue();
- assertThat(actualConfig, childMatching(
- "sourcepath", valueMatching(sourceDirectory.resolve("com/atlassian/labs").toString())));
- assertThat(actualConfig, childMatching(
- "docletPath", valueMatching(new ClasspathElementsMatcher(expectedClasspathElements))));
- assertThat(actualConfig, childMatching(
- "additionalOptions", childrenMatching(
- contains(
- valueMatching(String.format("-output \"%s\"",
- buildOutputDirectory
- .resolve("resourcedoc.xml")
- .toAbsolutePath())
- ),
- valueMatching(String.format(" -modules \"%s\"", jacksonModules))))));
- }
- private void setUpContextClassLoader() {
- // The production code expects the context class loader to be a
- // URLClassLoader, so we set it to a no-op child of the current one.
- final URLClassLoader urlClassLoader = new URLClassLoader(new URL[0], currentThread().getContextClassLoader());
- currentThread().setContextClassLoader(urlClassLoader);
- }
- @Test
- public void shouldNotExecuteJavadocPluginIfNoRestModulesDefined() throws Exception {
- setUpLog();
- createStructureInTempDirectory();
- copyPluginXmlWithoutRestModules();
- final Path buildOutputDirectory = temporaryFolder.getRoot().toPath().resolve("target");
- when(build.getOutputDirectory()).thenReturn(buildOutputDirectory.toAbsolutePath().toString());
- restDocsGenerator.generateRestDocs("");
- verify(mojoExecutorWrapper, never()).executeWithMergedConfig(any(), eq("javadoc"), any(), any());
- }
- private Set<String> prepareClasspathElements(String buildOutputDirectory) throws Exception {
- final ImmutableList<String> compileClasspathElements = ImmutableList.of("classpath1", "classpath2");
- when(mavenProject.getCompileClasspathElements()).thenReturn(compileClasspathElements);
- final ImmutableList<String> runtimeClasspathElements = ImmutableList.of("runtime1", "runtime2");
- when(mavenProject.getRuntimeClasspathElements()).thenReturn(runtimeClasspathElements);
- final ImmutableList<String> systemClasspathElements = ImmutableList.of("system1", "system2");
- //noinspection deprecation - used in production code
- when(mavenProject.getSystemClasspathElements()).thenReturn(systemClasspathElements);
- return Stream.of(
- Stream.of(buildOutputDirectory),
- compileClasspathElements.stream(),
- runtimeClasspathElements.stream(),
- systemClasspathElements.stream(),
- RestDocsGenerator.getPluginClasspathElements().stream()
- )
- .flatMap(Function.identity())
- .collect(toSet());
- }
- @SuppressWarnings("ResultOfMethodCallIgnored")
- private void createStructureInTempDirectory() {
- new File(temporaryFolder.getRoot(), "src/main/java").mkdirs();
- new File(temporaryFolder.getRoot(), "target").mkdirs();
- }
- private void copyPluginXmlWithRestModules() throws Exception {
- Files.copy(Paths.get(loadResource("plugin-xml-with-rest-modules.xml")),
- temporaryFolder.getRoot().toPath().resolve("target/atlassian-plugin.xml"));
- }
- private void copyPluginXmlWithoutRestModules() throws Exception {
- Files.copy(Paths.get(loadResource("plugin-xml-without-rest-modules.xml")),
- temporaryFolder.getRoot().toPath().resolve("target/atlassian-plugin.xml"));
- }
- private static void assertGeneratedFileEqualsExpectedFile(
- final Path buildOutputDirectory, final String fileName, final String expectedContent) throws Exception {
- assertGeneratedFileEqualsString(buildOutputDirectory, fileName,
- readFileToString(new File(loadResource(expectedContent)), UTF_8));
- }
- private static URI loadResource(final String resource) {
- return Optional.ofNullable(TestMavenGoals.class.getResource(resource))
- .map(url -> {
- try {
- return url.toURI();
- } catch (URISyntaxException e) {
- throw new IllegalStateException(e);
- }
- })
- .orElseThrow(() -> new IllegalStateException("Could not find " + resource));
- }
- private static void assertGeneratedFileEqualsString(
- final Path buildOutputDirectory, final String fileName, final String expectedContent)
- throws Exception {
- assertThat(readFileToString(buildOutputDirectory.resolve(fileName).toFile(), UTF_8),
- is(expectedContent));
- }
- /**
- * A matcher that checks whether a given classpath is equal to the specified set of classpath entries.
- */
- private static class ClasspathElementsMatcher extends TypeSafeMatcher<String> {
- private final Matcher<Set<String>> matcher;
- ClasspathElementsMatcher(final Set<String> classpathElements) {
- this.matcher = is(classpathElements);
- }
- @Override
- protected boolean matchesSafely(final String item) {
- final Set<String> classpathElements = stream(item.split(File.pathSeparator))
- .collect(toSet());
- return matcher.matches(classpathElements);
- }
- @Override
- public void describeTo(final Description description) {
- description.appendText("Matcher for doclet path with elements: ")
- .appendDescriptionOf(matcher);
- }
- }
- }