Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion maven-plugin-testing-harness/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ under the License.
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-testing</artifactId>
<version>1.7.0</version>
<version>2.0.0</version>
<exclusions>
<exclusion>
<!-- we need as optional dependencies -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@
import org.mockito.Mockito;
import org.slf4j.LoggerFactory;

import static org.mockito.Mockito.lenient;

/**
* JUnit's extension to help testing Mojos. The extension should be automatically registered
* by adding the {@link MojoTest} annotation on the test class.
Expand All @@ -96,6 +98,9 @@
*/
public class MojoExtension extends PlexusExtension implements ParameterResolver {

// Namespace for storing/retrieving data related to MojoExtension
private static final ExtensionContext.Namespace MOJO_EXTENSION = ExtensionContext.Namespace.create("MojoExtension");

@Override
public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext)
throws ParameterResolutionException {
Expand Down Expand Up @@ -123,10 +128,9 @@ public Object resolveParameter(ParameterContext parameterContext, ExtensionConte
.ifPresent(mojoParameters::addAll);

Class<?> holder = parameterContext.getTarget().get().getClass();
PluginDescriptor descriptor = extensionContext
.getStore(ExtensionContext.Namespace.GLOBAL)
.get(PluginDescriptor.class, PluginDescriptor.class);
return lookupMojo(holder, injectMojo, mojoParameters, descriptor);
PluginDescriptor descriptor =
extensionContext.getStore(MOJO_EXTENSION).get(PluginDescriptor.class, PluginDescriptor.class);
return lookupMojo(extensionContext, holder, injectMojo, mojoParameters, descriptor);
} catch (Exception e) {
throw new ParameterResolutionException("Unable to resolve parameter", e);
}
Expand All @@ -136,15 +140,13 @@ public Object resolveParameter(ParameterContext parameterContext, ExtensionConte
public void beforeEach(ExtensionContext context) throws Exception {
String basedir = AnnotationSupport.findAnnotation(context.getElement().get(), Basedir.class)
.map(Basedir::value)
.orElse(null);

setTestBasedir(basedir);
.orElseGet(PlexusExtension::getBasedir);

setContext(context);
setTestBasedir(basedir, context);

getContainer().addComponent(getContainer(), PlexusContainer.class.getName());
PlexusContainer plexusContainer = getContainer(context);

((DefaultPlexusContainer) getContainer()).addPlexusInjector(Collections.emptyList(), binder -> {
((DefaultPlexusContainer) plexusContainer).addPlexusInjector(Collections.emptyList(), binder -> {
binder.install(ProviderMethodsModule.forObject(context.getRequiredTestInstance()));
binder.install(new MavenProvidesModule(context.getRequiredTestInstance()));
binder.requestInjection(context.getRequiredTestInstance());
Expand All @@ -153,7 +155,7 @@ public void beforeEach(ExtensionContext context) throws Exception {
binder.bind(MojoExecution.class).toInstance(mockMojoExecution());
});

Map<Object, Object> map = getContainer().getContext().getContextData();
Map<Object, Object> map = plexusContainer.getContext().getContextData();

ClassLoader classLoader = context.getRequiredTestClass().getClassLoader();
try (InputStream is = Objects.requireNonNull(
Expand All @@ -164,10 +166,10 @@ public void beforeEach(ExtensionContext context) throws Exception {

PluginDescriptor pluginDescriptor = new PluginDescriptorBuilder().build(interpolationReader);

context.getStore(ExtensionContext.Namespace.GLOBAL).put(PluginDescriptor.class, pluginDescriptor);
context.getStore(MOJO_EXTENSION).put(PluginDescriptor.class, pluginDescriptor);

for (ComponentDescriptor<?> desc : pluginDescriptor.getComponents()) {
getContainer().addComponentDescriptor(desc);
plexusContainer.addComponentDescriptor(desc);
}
}
}
Expand All @@ -178,7 +180,9 @@ public void beforeEach(ExtensionContext context) throws Exception {
* @return a MojoExecution mock
*/
private MojoExecution mockMojoExecution() {
return Mockito.mock(MojoExecution.class);
MojoExecution mockExecution = Mockito.mock(MojoExecution.class);
lenient().when(mockExecution.getMojoDescriptor()).thenReturn(new MojoDescriptor());
return mockExecution;
}

/**
Expand All @@ -188,8 +192,8 @@ private MojoExecution mockMojoExecution() {
*/
private MavenSession mockMavenSession() {
MavenSession session = Mockito.mock(MavenSession.class);
Mockito.lenient().when(session.getUserProperties()).thenReturn(new Properties());
Mockito.lenient().when(session.getSystemProperties()).thenReturn(new Properties());
lenient().when(session.getUserProperties()).thenReturn(new Properties());
lenient().when(session.getSystemProperties()).thenReturn(new Properties());
return session;
}

Expand All @@ -198,17 +202,19 @@ protected String getPluginDescriptorLocation() {
}

private Mojo lookupMojo(
ExtensionContext extensionContext,
Class<?> holder,
InjectMojo injectMojo,
Collection<MojoParameter> mojoParameters,
PluginDescriptor descriptor)
throws Exception {
String goal = injectMojo.goal();
String pom = injectMojo.pom();
String[] coord = mojoCoordinates(goal);
Path basedir = Paths.get(getTestBasedir(extensionContext));
String[] coord = mojoCoordinates(goal, descriptor);
Xpp3Dom pomDom;
if (pom.startsWith("file:")) {
Path path = Paths.get(getTestBasedir()).resolve(pom.substring("file:".length()));
Path path = basedir.resolve(pom.substring("file:".length()));
pomDom = Xpp3DomBuilder.build(new XmlStreamReader(path.toFile()));
} else if (pom.startsWith("classpath:")) {
URL url = holder.getResource(pom.substring("classpath:".length()));
Expand All @@ -218,9 +224,11 @@ private Mojo lookupMojo(
pomDom = Xpp3DomBuilder.build(new XmlStreamReader(url.openStream()));
} else if (pom.contains("<project>")) {
pomDom = Xpp3DomBuilder.build(new StringReader(pom));
} else {
Path path = Paths.get(getTestBasedir()).resolve(pom);
} else if (!pom.isEmpty()) {
Path path = basedir.resolve(pom);
pomDom = Xpp3DomBuilder.build(new XmlStreamReader(path.toFile()));
} else {
pomDom = new Xpp3Dom("");
}
Xpp3Dom pluginConfiguration = extractPluginConfiguration(coord[1], pomDom);
if (!mojoParameters.isEmpty()) {
Expand All @@ -235,30 +243,29 @@ private Mojo lookupMojo(
children.forEach(config::addChild);
pluginConfiguration = Xpp3Dom.mergeXpp3Dom(config, pluginConfiguration);
}
Mojo mojo = lookupMojo(coord, pluginConfiguration, descriptor);
return mojo;
return lookupMojo(extensionContext, coord, pluginConfiguration, descriptor);
}

protected String[] mojoCoordinates(String goal) throws Exception {
protected String[] mojoCoordinates(String goal, PluginDescriptor pluginDescriptor) throws Exception {
if (goal.matches(".*:.*:.*:.*")) {
return goal.split(":");
} else {
Path pluginPom = Paths.get(getTestBasedir(), "pom.xml");
Xpp3Dom pluginPomDom = Xpp3DomBuilder.build(new XmlStreamReader(pluginPom.toFile()));
String artifactId = pluginPomDom.getChild("artifactId").getValue();
String groupId = resolveFromRootThenParent(pluginPomDom, "groupId");
String version = resolveFromRootThenParent(pluginPomDom, "version");
String artifactId = pluginDescriptor.getArtifactId();
String groupId = pluginDescriptor.getGroupId();
String version = pluginDescriptor.getVersion();
return new String[] {groupId, artifactId, version, goal};
}
}

/**
* lookup the mojo while we have all the relevent information
*/
protected Mojo lookupMojo(String[] coord, Xpp3Dom pluginConfiguration, PluginDescriptor descriptor)
protected Mojo lookupMojo(
ExtensionContext extensionContext, String[] coord, Xpp3Dom pluginConfiguration, PluginDescriptor descriptor)
throws Exception {
PlexusContainer plexusContainer = getContainer(extensionContext);
// pluginkey = groupId : artifactId : version : goal
Mojo mojo = lookup(Mojo.class, coord[0] + ":" + coord[1] + ":" + coord[2] + ":" + coord[3]);
Mojo mojo = plexusContainer.lookup(Mojo.class, coord[0] + ":" + coord[1] + ":" + coord[2] + ":" + coord[3]);
for (MojoDescriptor mojoDescriptor : descriptor.getMojos()) {
if (Objects.equals(
mojoDescriptor.getImplementation(), mojo.getClass().getName())) {
Expand All @@ -268,29 +275,29 @@ protected Mojo lookupMojo(String[] coord, Xpp3Dom pluginConfiguration, PluginDes
}
}
if (pluginConfiguration != null) {
MavenSession session = getContainer().lookup(MavenSession.class);
MavenSession session = plexusContainer.lookup(MavenSession.class);
try {
getContainer().lookup(MavenProject.class);
plexusContainer.lookup(MavenProject.class);
} catch (ComponentLookupException ignore) {
// nothing
}
MojoExecution mojoExecution;
try {
mojoExecution = getContainer().lookup(MojoExecution.class);
mojoExecution = plexusContainer.lookup(MojoExecution.class);
} catch (ComponentLookupException e) {
mojoExecution = null;
}
ExpressionEvaluator evaluator =
new WrapEvaluator(getContainer(), new PluginParameterExpressionEvaluator(session, mojoExecution));
new WrapEvaluator(plexusContainer, new PluginParameterExpressionEvaluator(session, mojoExecution));
ComponentConfigurator configurator = new BasicComponentConfigurator();
configurator.configureComponent(
mojo,
new XmlPlexusConfiguration(pluginConfiguration),
evaluator,
getContainer().getContainerRealm());
plexusContainer.getContainerRealm());
}

mojo.setLog(getContainer().lookup(Log.class));
mojo.setLog(plexusContainer.lookup(Log.class));

return mojo;
}
Expand Down Expand Up @@ -399,6 +406,14 @@ public static Map<String, Object> getVariablesAndValuesFromObject(Class<?> clazz
return map;
}

/**
* Gets the base directory for test resources.
* If not explicitly set via {@link Basedir}, returns the plugin base directory.
*/
public static String getBasedir() {
return PlexusExtension.getBasedir();
}

/**
* Convenience method to set values to variables in objects that don't have setters
*/
Expand All @@ -413,6 +428,7 @@ public static void setVariableValueToObject(Object object, String variable, Obje
static class WrapEvaluator implements TypeAwareExpressionEvaluator {

private final PlexusContainer container;

private final TypeAwareExpressionEvaluator evaluator;

WrapEvaluator(PlexusContainer container, TypeAwareExpressionEvaluator evaluator) {
Expand Down