From 6b21dbd5ab9ba521d814e44c0096aeb6ee91455e Mon Sep 17 00:00:00 2001 From: Abel Salgado Romero Date: Mon, 22 Mar 2021 23:33:46 +0100 Subject: [PATCH] Migrate AsciidoctorZipMojoTest from Groovy to Java --- CHANGELOG.adoc | 1 + .../maven/test/AsciidoctorZipMojoTest.groovy | 151 ---------------- .../test/plexus/MockPlexusContainer.groovy | 70 -------- .../maven/AsciidoctorZipMojoTest.java | 169 ++++++++++++++++++ .../java/org/asciidoctor/maven/TestUtils.java | 5 + 5 files changed, 175 insertions(+), 221 deletions(-) delete mode 100644 src/test/groovy/org/asciidoctor/maven/test/AsciidoctorZipMojoTest.groovy delete mode 100644 src/test/groovy/org/asciidoctor/maven/test/plexus/MockPlexusContainer.groovy create mode 100644 src/test/java/org/asciidoctor/maven/AsciidoctorZipMojoTest.java diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 1e586623..25ca2f08 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -26,6 +26,7 @@ Maintenance:: * Rewrite `AsciidoctorMojoLogHandlerTest` to Java to make it more approachable (#514) * Rewrite `AsciidoctorMojoExtensionsTest` to Java to make it more approachable (#515) * Rewrite `AsciidoctorHttpMojoTest` to Java to make it more approachable (#516) + * Rewrite `AsciidoctorZipMojoTest` to Java to make it more approachable (#518) == v2.1.0 (2020-09-15) diff --git a/src/test/groovy/org/asciidoctor/maven/test/AsciidoctorZipMojoTest.groovy b/src/test/groovy/org/asciidoctor/maven/test/AsciidoctorZipMojoTest.groovy deleted file mode 100644 index bbda10cc..00000000 --- a/src/test/groovy/org/asciidoctor/maven/test/AsciidoctorZipMojoTest.groovy +++ /dev/null @@ -1,151 +0,0 @@ -package org.asciidoctor.maven.test - -import org.apache.commons.io.FileUtils -import org.asciidoctor.maven.AsciidoctorZipMojo -import org.asciidoctor.maven.test.plexus.MockPlexusContainer -import spock.lang.Specification - -import java.util.zip.ZipFile - -/** - * - */ -class AsciidoctorZipMojoTest extends Specification { - - def setupSpec() { - MockPlexusContainer.initializeMockContext(AsciidoctorZipMojo) - } - - def "zip it"() { - given: 'an empty output directory' - def outputDir = new File('target/asciidoctor-zip-output') - outputDir.deleteDir() - outputDir.mkdirs() - - def zip = new File('target/asciidoctor-zip.zip') - zip.delete() - - when: 'zip mojo is called' - def srcDir = new File('target/test-classes/src/asciidoctor-zip') - srcDir.mkdirs() - - new File(srcDir, "sample.asciidoc").withWriter { - it << ''' - Title - ===== - test - '''.stripIndent() - } - - def mojo = new AsciidoctorZipMojo() - mojo.backend = 'html' - mojo.sourceDirectory = srcDir - mojo.outputDirectory = outputDir - mojo.zipDestination = zip - mojo.zip = true - mojo.execute() - - then: 'a zip is created' - mojo.zipDestination.exists() - - def entries = new ZipFile(mojo.zipDestination).entries() - entries.hasMoreElements() - def entryName = entries.nextElement().name - entryName == 'asciidoctor-zip/target/asciidoctor-zip-output/sample.html' || entryName == 'asciidoctor-zip/target\\asciidoctor-zip-output\\sample.html' - } - - def 'should replicate source structure in zip-standard paths'() { - setup: - File srcDir = new File('src/test/resources/src/asciidoctor/relative-path-treatment') - // Create random folder to avoid mix files when something goes wrong - String outputPath = "target/asciidoctor-output-relative-${UUID.randomUUID().toString().split('-') [0]}/" - File outputDir = new File(outputPath) - - File zip = new File("$outputPath/asciidoctor-zip.zip") - - when: - AsciidoctorZipMojo mojo = new AsciidoctorZipMojo() - mojo.backend = 'html5' - mojo.sourceDirectory = srcDir - mojo.outputDirectory = outputDir - mojo.preserveDirectories = true - mojo.relativeBaseDir = true - mojo.zipDestination = zip - mojo.zip = true - mojo.execute() - - then: - ZipFile zipfile = new ZipFile(zip) - def entries = (zipfile).entries()*.getName().collect() { - // Protection to avoid errors on diferent OS - it.replaceAll('\\\\', '/') - outputPath - } - zipfile.close() - // Paths are adapted for the test are do not match the real paths inside the zip - def expected = [ - 'asciidoctor-zip/HelloWorld.groovy', - 'asciidoctor-zip/HelloWorld.html', - 'asciidoctor-zip/level-1-1/asciidoctor-icon.jpg', - 'asciidoctor-zip/level-1-1/HelloWorld2.groovy', - 'asciidoctor-zip/level-1-1/HelloWorld2.html', - 'asciidoctor-zip/level-1-1/HelloWorld22.html', - 'asciidoctor-zip/level-1-1/level-2-1/HelloWorld3.groovy', - 'asciidoctor-zip/level-1-1/level-2-1/HelloWorld3.html', - 'asciidoctor-zip/level-1-1/level-2-2/HelloWorld3.groovy', - 'asciidoctor-zip/level-1-1/level-2-2/HelloWorld3.html', - 'asciidoctor-zip/level-1-1/level-2-2/level-3-1/HelloWorld4.groovy', - 'asciidoctor-zip/level-1-1/level-2-2/level-3-1/HelloWorld4.html' - ] - expected.containsAll(entries) - entries.containsAll(expected) - - cleanup: - FileUtils.deleteDirectory(outputDir) - } - - def 'should not replicate source structure in zip-standard paths'() { - setup: - File srcDir = new File('src/test/resources/src/asciidoctor/relative-path-treatment') - String outputPath = "target/asciidoctor-output-relative-${UUID.randomUUID().toString().split('-') [0]}/" - File outputDir = new File(outputPath) - - File zip = new File("$outputPath/asciidoctor-zip.zip") - - when: - AsciidoctorZipMojo mojo = new AsciidoctorZipMojo() - mojo.backend = 'html5' - mojo.sourceDirectory = srcDir - mojo.outputDirectory = outputDir - mojo.zipDestination = zip - mojo.zip = true - mojo.execute() - - then: - ZipFile zipfile = new ZipFile(zip) - def entries = (zipfile).entries()*.getName().collect() { - // Protection to avoid errors on diferent OS - it.replaceAll('\\\\', '/') - outputPath - } - zipfile.close() - // Paths are adapted for the test are do not match the real paths inside the zip - def expected = [ - 'asciidoctor-zip/HelloWorld.groovy', - 'asciidoctor-zip/HelloWorld.html', - 'asciidoctor-zip/HelloWorld2.html', - 'asciidoctor-zip/HelloWorld22.html', - 'asciidoctor-zip/HelloWorld3.html', - 'asciidoctor-zip/HelloWorld4.html', - 'asciidoctor-zip/level-1-1/asciidoctor-icon.jpg', - 'asciidoctor-zip/level-1-1/HelloWorld2.groovy', - 'asciidoctor-zip/level-1-1/level-2-1/HelloWorld3.groovy', - 'asciidoctor-zip/level-1-1/level-2-2/HelloWorld3.groovy', - 'asciidoctor-zip/level-1-1/level-2-2/level-3-1/HelloWorld4.groovy' - ] - expected.containsAll(entries) - entries.containsAll(expected) - - cleanup: - FileUtils.deleteDirectory(outputDir) - } - -} diff --git a/src/test/groovy/org/asciidoctor/maven/test/plexus/MockPlexusContainer.groovy b/src/test/groovy/org/asciidoctor/maven/test/plexus/MockPlexusContainer.groovy deleted file mode 100644 index 9fe91aa5..00000000 --- a/src/test/groovy/org/asciidoctor/maven/test/plexus/MockPlexusContainer.groovy +++ /dev/null @@ -1,70 +0,0 @@ -package org.asciidoctor.maven.test.plexus - -import org.apache.maven.plugin.logging.Log -import org.apache.maven.plugin.logging.SystemStreamLog -import org.apache.maven.project.MavenProject -import org.apache.maven.shared.filtering.DefaultMavenFileFilter -import org.apache.maven.shared.filtering.DefaultMavenResourcesFiltering -import org.asciidoctor.maven.AsciidoctorMojo -import org.sonatype.plexus.build.incremental.DefaultBuildContext - -/** - * Initializes a mocks components required to simulate a Plexus container for the tests. - * - * Note: This is a temporal solution. At some point 'proper' testing should be introduced, see: - * - https://vzurczak.wordpress.com/2014/07/23/write-unit-tests-for-a-maven-plug-in/ - * - * @author abelsromero - */ -class MockPlexusContainer { - - class FakeMavenLogger { - @Delegate - Log logger = new SystemStreamLog() - } - - private void initializeMojoContext(AsciidoctorMojo mojo, Map properties) { - - mojo.@project = [ - getBasedir : { - return new File('.') - }, - getProperties: properties as Properties - ] as MavenProject - - def buildContext = new DefaultBuildContext() - def logger = new FakeMavenLogger() as org.codehaus.plexus.logging.Logger - - DefaultMavenFileFilter mavenFileFilter = new DefaultMavenFileFilter() - mavenFileFilter.@buildContext = buildContext - mavenFileFilter.enableLogging(logger) - - DefaultMavenResourcesFiltering resourceFilter = new DefaultMavenResourcesFiltering() - resourceFilter.@mavenFileFilter = mavenFileFilter - resourceFilter.@buildContext = buildContext - resourceFilter.initialize() - resourceFilter.enableLogging(logger) - mojo.encoding = "UTF-8" - mojo.@outputResourcesFiltering = resourceFilter - } - - /** - * Intercept Asciidoctor mojo constructor to mock and inject required plexus objects. - */ - static MockPlexusContainer initializeMockContext(Class clazz) { - initializeMockContext(clazz, Collections.emptyMap()) - } - - static MockPlexusContainer initializeMockContext(Class clazz, Map mavenProperties) { - final MockPlexusContainer mockPlexusContainer = new MockPlexusContainer() - def oldConstructor = clazz.constructors[0] - - clazz.metaClass.constructor = { - def mojo = oldConstructor.newInstance() - mockPlexusContainer.initializeMojoContext(mojo, mavenProperties) - return mojo - } - mockPlexusContainer - } - -} diff --git a/src/test/java/org/asciidoctor/maven/AsciidoctorZipMojoTest.java b/src/test/java/org/asciidoctor/maven/AsciidoctorZipMojoTest.java new file mode 100644 index 00000000..eb3facee --- /dev/null +++ b/src/test/java/org/asciidoctor/maven/AsciidoctorZipMojoTest.java @@ -0,0 +1,169 @@ +package org.asciidoctor.maven; + +import org.apache.commons.io.FileUtils; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.asciidoctor.maven.io.TestFilesHelper; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.List; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.asciidoctor.maven.TestUtils.mockAsciidoctorZipMojo; +import static org.assertj.core.api.Assertions.assertThat; + + +public class AsciidoctorZipMojoTest { + + + @Test + public void should_create_simple_zip() throws IOException, MojoFailureException, MojoExecutionException { + // given: an empty output directory + File outputDir = TestFilesHelper.newOutputTestDirectory("asciidoctor-zip-output"); + + File zip = new File("target/asciidoctor-zip.zip"); + zip.delete(); + + // when: zip mojo is called + File srcDir = new File("target/test-classes/src/asciidoctor-zip"); + srcDir.mkdirs(); + + + FileUtils.write(new File(srcDir, "sample.adoc"), + "= Title\n\ntest", UTF_8); + + AsciidoctorZipMojo mojo = mockAsciidoctorZipMojo(); + mojo.backend = "html"; + mojo.sourceDirectory = srcDir; + mojo.outputDirectory = outputDir; + mojo.zipDestination = zip; + mojo.zip = true; + mojo.execute(); + + // then: a zip is created + mojo.zipDestination.exists(); + + ZipFile zipfile = new ZipFile(zip); + List names = getNames(zipfile.entries()) + .stream() + .map(value -> value.replaceAll("\\\\", "/")) + .map(value -> value.replaceAll("/" + outputDir.toString(), "")) + .collect(Collectors.toList()); + assertThat(names).hasSize(1); + assertThat(names.get(0).replaceAll("\\\\", "/")) + .isEqualTo("asciidoctor-zip/sample.html"); + } + + @Test + public void should_replicate_source_structure_in_zip_standard_paths() throws MojoFailureException, MojoExecutionException, IOException { + // given + File srcDir = new File("src/test/resources/src/asciidoctor/relative-path-treatment"); + File outputDir = TestFilesHelper.newOutputTestDirectory("asciidoctor-zip-output"); + + File zip = new File(outputDir, "asciidoctor-zip.zip"); + + // when + AsciidoctorZipMojo mojo = mockAsciidoctorZipMojo(); + mojo.backend = "html5"; + mojo.sourceDirectory = srcDir; + mojo.outputDirectory = outputDir; + mojo.preserveDirectories = true; + mojo.relativeBaseDir = true; + mojo.zipDestination = zip; + mojo.zip = true; + mojo.execute(); + + // then + ZipFile zipfile = new ZipFile(zip); + List names = getNames(zipfile.entries()) + .stream() + .map(value -> value.replaceAll("\\\\", "/")) + .map(value -> value.replaceAll("/" + outputDir.toString(), "")) + .collect(Collectors.toList()); + zipfile.close(); + // Paths are adapted for the test are do not match the real paths inside the zip + List expected = Arrays.asList( + "asciidoctor-zip/HelloWorld.groovy", + "asciidoctor-zip/HelloWorld.html", + "asciidoctor-zip/level-1-1/asciidoctor-icon.jpg", + "asciidoctor-zip/level-1-1/HelloWorld2.groovy", + "asciidoctor-zip/level-1-1/HelloWorld2.html", + "asciidoctor-zip/level-1-1/HelloWorld22.html", + "asciidoctor-zip/level-1-1/level-2-1/HelloWorld3.groovy", + "asciidoctor-zip/level-1-1/level-2-1/HelloWorld3.html", + "asciidoctor-zip/level-1-1/level-2-2/HelloWorld3.groovy", + "asciidoctor-zip/level-1-1/level-2-2/HelloWorld3.html", + "asciidoctor-zip/level-1-1/level-2-2/level-3-1/HelloWorld4.groovy", + "asciidoctor-zip/level-1-1/level-2-2/level-3-1/HelloWorld4.html" + ); + assertThat(names) + .containsAll(expected); + } + + @Test + public void should_not_replicate_source_structure_in_zip_standard_paths() throws IOException, MojoFailureException, MojoExecutionException { + // setup + File srcDir = new File("src/test/resources/src/asciidoctor/relative-path-treatment"); + File outputDir = TestFilesHelper.newOutputTestDirectory("asciidoctor-zip-output"); + + File zip = new File(outputDir, "asciidoctor-zip.zip"); + + // when + AsciidoctorZipMojo mojo = mockAsciidoctorZipMojo(); + mojo.backend = "html5"; + mojo.sourceDirectory = srcDir; + mojo.outputDirectory = outputDir; + mojo.zipDestination = zip; + mojo.zip = true; + mojo.execute(); + + // then + ZipFile zipfile = new ZipFile(zip); + List names = getNames(zipfile.entries()) + .stream() + .map(value -> value.replaceAll("\\\\", "/")) + .map(value -> value.replaceAll("/" + outputDir.toString(), "")) + .collect(Collectors.toList()); + zipfile.close(); + // Paths are adapted for the test are do not match the real paths inside the zip + List expected = Arrays.asList( + "asciidoctor-zip/HelloWorld.groovy", + "asciidoctor-zip/HelloWorld.html", + "asciidoctor-zip/HelloWorld2.html", + "asciidoctor-zip/HelloWorld22.html", + "asciidoctor-zip/HelloWorld3.html", + "asciidoctor-zip/HelloWorld4.html", + "asciidoctor-zip/level-1-1/asciidoctor-icon.jpg", + "asciidoctor-zip/level-1-1/HelloWorld2.groovy", + "asciidoctor-zip/level-1-1/level-2-1/HelloWorld3.groovy", + "asciidoctor-zip/level-1-1/level-2-2/HelloWorld3.groovy", + "asciidoctor-zip/level-1-1/level-2-2/level-3-1/HelloWorld4.groovy" + ); + assertThat(names) + .containsAll(expected); + } + + private List getNames(Enumeration entries) { + final List names = new ArrayList<>(); + while (entries.hasMoreElements()) { + names.add(entries.nextElement().getName()); + } + return names; + } + + private String fixOsSeparator(String text) { + return isUnix() ? text : text.replaceAll("/", "\\\\"); + } + + private boolean isUnix() { + return File.separatorChar == '/'; + } +} diff --git a/src/test/java/org/asciidoctor/maven/TestUtils.java b/src/test/java/org/asciidoctor/maven/TestUtils.java index 9db8d0dd..9216e5cc 100644 --- a/src/test/java/org/asciidoctor/maven/TestUtils.java +++ b/src/test/java/org/asciidoctor/maven/TestUtils.java @@ -40,6 +40,11 @@ public static AsciidoctorHttpMojo mockAsciidoctorHttpMojo() { return mockAsciidoctorMojo(AsciidoctorHttpMojo.class, null, null); } + @SneakyThrows + public static AsciidoctorZipMojo mockAsciidoctorZipMojo() { + return mockAsciidoctorMojo(AsciidoctorZipMojo.class, null, null); + } + @SneakyThrows public static AsciidoctorMojo mockAsciidoctorMojo(Map mavenProperties) { return mockAsciidoctorMojo(AsciidoctorMojo.class, mavenProperties, null);