package io.takari.maven.plugins.configurator;
import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Stack;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.junit.Test;
public class MojoConfigurationMergerTest {
private static MojoConfigurationProcessor merger = new MojoConfigurationProcessor();
private static PluginDescriptorBuilder pluginDescriptorBuilder = new PluginDescriptorBuilder();
@Test
public void determineGoalFromMojoImplementation() throws Exception {
InputStream is = getClass().getResourceAsStream("/META-INF/maven/plugin.xml");
assertNotNull(is);
PluginDescriptor pluginDescriptor = pluginDescriptorBuilder.build(new InputStreamReader(is, "UTF-8"));
String goal = merger.determineGoal("io.takari.maven.plugins.jar.Jar", pluginDescriptor);
assertEquals("We expect the goal name to be 'jar'", "jar", goal);
}
@Test
public void extractionOfMojoSpecificConfigurationAndMergingwithDefaultMojoConfiguration() throws Exception {
InputStream is = getClass().getResourceAsStream("/META-INF/maven/plugin.xml");
assertNotNull(is);
PluginDescriptor pluginDescriptor = pluginDescriptorBuilder.build(new InputStreamReader(is, "UTF-8"));
String goal = merger.determineGoal("io.takari.maven.plugins.jar.Jar", pluginDescriptor);
assertEquals("We expect the goal name to be 'jar'", "jar", goal);
MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo(goal);
PlexusConfiguration defaultMojoConfiguration = mojoDescriptor.getMojoConfiguration();
System.out.println(defaultMojoConfiguration);
PlexusConfiguration configurationFromMaven = builder("configuration") //
.es("jar") //
.es("sourceJar").v("true").ee() //
.ee() //
.buildPlexusConfiguration();
PlexusConfiguration mojoConfiguration = merger.extractAndMerge(goal, configurationFromMaven, defaultMojoConfiguration);
String xml = mojoConfiguration.toString();
assertXpathEvaluatesTo("java.io.File", "/configuration/classesDirectory/@implementation", xml);
assertXpathEvaluatesTo("${project.build.outputDirectory}", "/configuration/classesDirectory/@default-value", xml);
assertXpathEvaluatesTo("java.util.List", "/configuration/reactorProjects/@implementation", xml);
assertXpathEvaluatesTo("${reactorProjects}", "/configuration/reactorProjects/@default-value", xml);
assertXpathEvaluatesTo("true", "/configuration/sourceJar", xml);
}
@Test
public void plexusConfigurationMerging() throws Exception {
PlexusConfiguration mojoConfigurationFromPom = builder("configuration") //
.es("sourceJar").v("true").ee() //
.buildPlexusConfiguration();
PlexusConfiguration defaultMojoConfiguration = builder("configuration") //
.entry("classesDirectory", "java.io.File", "${project.build.outputDirectory}") //
.entry("reactorProjects", "java.util.List", "${reactorProjects}") //
.entry("souceJar", "boolean", "${sourceJar") //
.buildPlexusConfiguration();
PlexusConfiguration mojoConfiguration = merger.mergePlexusConfiguration(mojoConfigurationFromPom, defaultMojoConfiguration);
String xml = mojoConfiguration.toString();
assertXpathEvaluatesTo("java.io.File", "/configuration/classesDirectory/@implementation", xml);
assertXpathEvaluatesTo("${project.build.outputDirectory}", "/configuration/classesDirectory/@default-value", xml);
assertXpathEvaluatesTo("java.util.List", "/configuration/reactorProjects/@implementation", xml);
assertXpathEvaluatesTo("${reactorProjects}", "/configuration/reactorProjects/@default-value", xml);
assertXpathEvaluatesTo("true", "/configuration/sourceJar", xml);
}
private Builder builder(String name) {
return new Builder(name);
}
public class Builder {
private Stack<Xpp3Dom> stack;
private Xpp3Dom configuration;
public Builder(String name) {
stack = new Stack<Xpp3Dom>();
configuration = new Xpp3Dom(name);
}
public Builder entry(String name, String implementation, String defaultValue) {
return es(name).i(implementation).dv(defaultValue).ee();
}
public Builder i(String implementation) {
a("implementation", implementation);
return this;
}
public Builder dv(String value) {
a("default-value", value);
return this;
}
public Builder es(String name) {
Xpp3Dom e = new Xpp3Dom(name);
configuration.addChild(e);
stack.push(configuration);
configuration = e;
return this;
}
public Builder ee() {
configuration = stack.pop();
return this;
}
public Builder v(String value) {
configuration.setValue(value);
return this;
}
public Builder a(String name, String value) {
configuration.setAttribute(name, value);
return this;
}
public Xpp3Dom buildXpp3Dom() {
if (!stack.empty()) {
throw new IllegalStateException("You have unclosed elements.");
}
return configuration;
}
public PlexusConfiguration buildPlexusConfiguration() {
if (!stack.empty()) {
throw new IllegalStateException("You have unclosed elements.");
}
return new XmlPlexusConfiguration(configuration);
}
}
}