diff --git a/maven-plugin-testing-harness/pom.xml b/maven-plugin-testing-harness/pom.xml index 3d7419b..e439c76 100644 --- a/maven-plugin-testing-harness/pom.xml +++ b/maven-plugin-testing-harness/pom.xml @@ -30,6 +30,18 @@ under the License. Maven Plugin Testing Mechanism The Maven Plugin Testing Harness provides mechanisms to manage tests on Mojo. + + + + org.junit + junit-bom + 5.10.0 + pom + import + + + + @@ -70,14 +82,11 @@ under the License. 4.0.0 + org.codehaus.plexus plexus-xml 4.0.0 - - - commons-io - commons-io - 2.11.0 + true org.codehaus.plexus @@ -89,16 +98,41 @@ under the License. org.codehaus.plexus plexus-testing 1.1.0 + + + + org.junit.jupiter + junit-jupiter-api + + + + + + com.google.guava + guava + 32.0.1-jre junit junit 4.13.2 + true + + + org.junit.jupiter + junit-jupiter-api + true org.mockito mockito-core 4.6.1 + + org.slf4j + slf4j-simple + 1.7.36 + test + diff --git a/maven-plugin-testing-harness/src/main/java/org/apache/maven/api/plugin/testing/MojoExtension.java b/maven-plugin-testing-harness/src/main/java/org/apache/maven/api/plugin/testing/MojoExtension.java index f0a4f09..b217fab 100644 --- a/maven-plugin-testing-harness/src/main/java/org/apache/maven/api/plugin/testing/MojoExtension.java +++ b/maven-plugin-testing-harness/src/main/java/org/apache/maven/api/plugin/testing/MojoExtension.java @@ -29,12 +29,16 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -100,7 +104,18 @@ public Object resolveParameter(ParameterContext parameterContext, ExtensionConte InjectMojo injectMojo = parameterContext .findAnnotation(InjectMojo.class) .orElseGet(() -> parameterContext.getDeclaringExecutable().getAnnotation(InjectMojo.class)); - List mojoParameters = parameterContext.findRepeatableAnnotations(MojoParameter.class); + + Set mojoParameters = + new HashSet<>(parameterContext.findRepeatableAnnotations(MojoParameter.class)); + + Optional.ofNullable(parameterContext.getDeclaringExecutable().getAnnotation(MojoParameter.class)) + .ifPresent(mojoParameters::add); + + Optional.ofNullable(parameterContext.getDeclaringExecutable().getAnnotation(MojoParameters.class)) + .map(MojoParameters::value) + .map(Arrays::asList) + .ifPresent(mojoParameters::addAll); + Class holder = parameterContext.getTarget().get().getClass(); PluginDescriptor descriptor = extensionContext .getStore(ExtensionContext.Namespace.GLOBAL) @@ -113,6 +128,7 @@ public Object resolveParameter(ParameterContext parameterContext, ExtensionConte @Override public void beforeEach(ExtensionContext context) throws Exception { + // TODO provide protected setters in PlexusExtension Field field = PlexusExtension.class.getDeclaredField("basedir"); field.setAccessible(true); field.set(null, getBasedir()); @@ -152,7 +168,10 @@ protected String getPluginDescriptorLocation() { } private Mojo lookupMojo( - Class holder, InjectMojo injectMojo, List mojoParameters, PluginDescriptor descriptor) + Class holder, + InjectMojo injectMojo, + Collection mojoParameters, + PluginDescriptor descriptor) throws Exception { String goal = injectMojo.goal(); String pom = injectMojo.pom(); diff --git a/maven-plugin-testing-harness/src/main/java/org/apache/maven/plugin/testing/junit5/MojoExtension.java b/maven-plugin-testing-harness/src/main/java/org/apache/maven/plugin/testing/junit5/MojoExtension.java index f5d2d21..c7746c2 100644 --- a/maven-plugin-testing-harness/src/main/java/org/apache/maven/plugin/testing/junit5/MojoExtension.java +++ b/maven-plugin-testing-harness/src/main/java/org/apache/maven/plugin/testing/junit5/MojoExtension.java @@ -29,12 +29,17 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Properties; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -74,6 +79,7 @@ import org.junit.jupiter.api.extension.ParameterContext; import org.junit.jupiter.api.extension.ParameterResolutionException; import org.junit.jupiter.api.extension.ParameterResolver; +import org.mockito.Mockito; import org.slf4j.LoggerFactory; /** @@ -100,7 +106,18 @@ public Object resolveParameter(ParameterContext parameterContext, ExtensionConte InjectMojo injectMojo = parameterContext .findAnnotation(InjectMojo.class) .orElseGet(() -> parameterContext.getDeclaringExecutable().getAnnotation(InjectMojo.class)); - List mojoParameters = parameterContext.findRepeatableAnnotations(MojoParameter.class); + + Set mojoParameters = + new HashSet<>(parameterContext.findRepeatableAnnotations(MojoParameter.class)); + + Optional.ofNullable(parameterContext.getDeclaringExecutable().getAnnotation(MojoParameter.class)) + .ifPresent(mojoParameters::add); + + Optional.ofNullable(parameterContext.getDeclaringExecutable().getAnnotation(MojoParameters.class)) + .map(MojoParameters::value) + .map(Arrays::asList) + .ifPresent(mojoParameters::addAll); + Class holder = parameterContext.getTarget().get().getClass(); PluginDescriptor descriptor = extensionContext .getStore(ExtensionContext.Namespace.GLOBAL) @@ -113,6 +130,7 @@ public Object resolveParameter(ParameterContext parameterContext, ExtensionConte @Override public void beforeEach(ExtensionContext context) throws Exception { + // TODO provide protected setters in PlexusExtension Field field = PlexusExtension.class.getDeclaredField("basedir"); field.setAccessible(true); field.set(null, getBasedir()); @@ -126,6 +144,8 @@ public void beforeEach(ExtensionContext context) throws Exception { binder.install(ProviderMethodsModule.forObject(context.getRequiredTestInstance())); binder.requestInjection(context.getRequiredTestInstance()); binder.bind(Log.class).toInstance(new MojoLogWrapper(LoggerFactory.getLogger("anonymous"))); + binder.bind(MavenSession.class).toInstance(mockMavenSession()); + binder.bind(MojoExecution.class).toInstance(mockMojoExecution()); }); Map map = getContainer().getContext().getContextData(); @@ -147,12 +167,36 @@ public void beforeEach(ExtensionContext context) throws Exception { } } + /** + * Default MojoExecution mock + * + * @return a MojoExecution mock + */ + private MojoExecution mockMojoExecution() { + return Mockito.mock(MojoExecution.class); + } + + /** + * Default MavenSession mock + * + * @return a MavenSession mock + */ + private MavenSession mockMavenSession() { + MavenSession session = Mockito.mock(MavenSession.class); + Mockito.when(session.getUserProperties()).thenReturn(new Properties()); + Mockito.when(session.getSystemProperties()).thenReturn(new Properties()); + return session; + } + protected String getPluginDescriptorLocation() { return "META-INF/maven/plugin.xml"; } private Mojo lookupMojo( - Class holder, InjectMojo injectMojo, List mojoParameters, PluginDescriptor descriptor) + Class holder, + InjectMojo injectMojo, + Collection mojoParameters, + PluginDescriptor descriptor) throws Exception { String goal = injectMojo.goal(); String pom = injectMojo.pom(); @@ -242,6 +286,8 @@ protected Mojo lookupMojo(String[] coord, Xpp3Dom pluginConfiguration, PluginDes getContainer().getContainerRealm()); } + mojo.setLog(getContainer().lookup(Log.class)); + return mojo; } diff --git a/maven-plugin-testing-harness/src/test/java/org/apache/maven/api/plugin/testing/ExpressionEvaluatorTest.java b/maven-plugin-testing-harness/src/test/java/org/apache/maven/api/plugin/testing/ExpressionEvaluatorTest.java index 9869aeb..b287bbf 100644 --- a/maven-plugin-testing-harness/src/test/java/org/apache/maven/api/plugin/testing/ExpressionEvaluatorTest.java +++ b/maven-plugin-testing-harness/src/test/java/org/apache/maven/api/plugin/testing/ExpressionEvaluatorTest.java @@ -30,6 +30,8 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; @@ -59,6 +61,30 @@ public class ExpressionEvaluatorTest { @Test @InjectMojo(goal = COORDINATES, pom = CONFIG) public void testInjection(ExpressionEvaluatorMojo mojo) { + assertNotNull(mojo.basedir); + assertNotNull(mojo.workdir); + assertDoesNotThrow(mojo::execute); + } + + @Test + @InjectMojo(goal = COORDINATES, pom = CONFIG) + @MojoParameter(name = "param", value = "paramValue") + public void testParam(ExpressionEvaluatorMojo mojo) { + assertNotNull(mojo.basedir); + assertNotNull(mojo.workdir); + assertEquals("paramValue", mojo.param); + assertDoesNotThrow(mojo::execute); + } + + @Test + @InjectMojo(goal = COORDINATES, pom = CONFIG) + @MojoParameter(name = "param", value = "paramValue") + @MojoParameter(name = "param2", value = "param2Value") + public void testParams(ExpressionEvaluatorMojo mojo) { + assertNotNull(mojo.basedir); + assertNotNull(mojo.workdir); + assertEquals("paramValue", mojo.param); + assertEquals("param2Value", mojo.param2); assertDoesNotThrow(mojo::execute); } @@ -68,6 +94,10 @@ public static class ExpressionEvaluatorMojo implements org.apache.maven.api.plug private String workdir; + private String param; + + private String param2; + /** {@inheritDoc} */ @Override public void execute() throws MojoException { diff --git a/maven-plugin-testing-harness/src/test/java/org/apache/maven/plugin/testing/ParametersMojo.java b/maven-plugin-testing-harness/src/test/java/org/apache/maven/plugin/testing/ParametersMojo.java index 255f3e3..77e52d9 100644 --- a/maven-plugin-testing-harness/src/test/java/org/apache/maven/plugin/testing/ParametersMojo.java +++ b/maven-plugin-testing-harness/src/test/java/org/apache/maven/plugin/testing/ParametersMojo.java @@ -32,5 +32,7 @@ public class ParametersMojo extends AbstractMojo { public String withPropertyAndDefault; @Override - public void execute() throws MojoExecutionException, MojoFailureException {} + public void execute() throws MojoExecutionException, MojoFailureException { + getLog().info("Plain value = " + plain); + } } diff --git a/maven-plugin-testing-harness/src/test/java/org/apache/maven/plugin/testing/junit5/Junit5Test.java b/maven-plugin-testing-harness/src/test/java/org/apache/maven/plugin/testing/junit5/Junit5Test.java new file mode 100644 index 0000000..9da0036 --- /dev/null +++ b/maven-plugin-testing-harness/src/test/java/org/apache/maven/plugin/testing/junit5/Junit5Test.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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.apache.maven.plugin.testing.junit5; + +import javax.inject.Inject; + +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.plugin.testing.ParametersMojo; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@MojoTest +class Junit5Test { + + private static final String POM = "" + + "" + + " " + + " " + + " test-plugin" + + " " + + " " + + " " + + " " + + "" + ""; + + @Inject + private Log log; + + @Test + @InjectMojo(goal = "test:test-plugin:0.0.1-SNAPSHOT:parameters", pom = POM) + void simpleMojo(ParametersMojo mojo) { + assertEquals(log, mojo.getLog()); + assertDoesNotThrow(mojo::execute); + } + + @Test + @InjectMojo(goal = "test:test-plugin:0.0.1-SNAPSHOT:parameters", pom = POM) + @MojoParameter(name = "plain", value = "plainValue") + @MojoParameter(name = "withDefault", value = "withDefaultValue") + void simpleMojoWithParameters(ParametersMojo mojo) { + assertEquals("plainValue", mojo.plain); + assertEquals("withDefaultValue", mojo.withDefault); + assertDoesNotThrow(mojo::execute); + } + + @Test + @InjectMojo(goal = "test:test-plugin:0.0.1-SNAPSHOT:parameters", pom = POM) + @MojoParameter(name = "plain", value = "plainValue") + void simpleMojoWithParameter(ParametersMojo mojo) { + assertEquals("plainValue", mojo.plain); + assertDoesNotThrow(mojo::execute); + } +}