CakupanTestMojo.java
/**
* Copyright 2011-2015 Matthias Nuessler <m.nuessler@web.de>
*
* Licensed 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.nuessler.maven.plugin.cakupan;
import static org.twdata.maven.mojoexecutor.MojoExecutor.artifactId;
import static org.twdata.maven.mojoexecutor.MojoExecutor.configuration;
import static org.twdata.maven.mojoexecutor.MojoExecutor.element;
import static org.twdata.maven.mojoexecutor.MojoExecutor.executeMojo;
import static org.twdata.maven.mojoexecutor.MojoExecutor.executionEnvironment;
import static org.twdata.maven.mojoexecutor.MojoExecutor.goal;
import static org.twdata.maven.mojoexecutor.MojoExecutor.groupId;
import static org.twdata.maven.mojoexecutor.MojoExecutor.name;
import static org.twdata.maven.mojoexecutor.MojoExecutor.plugin;
import static org.twdata.maven.mojoexecutor.MojoExecutor.version;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.BuildPluginManager;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.*;
import org.twdata.maven.mojoexecutor.MojoExecutor.Element;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
/**
* Run transformation tests using Surefire.
*
* @author Matthias Nuessler
*/
@Mojo(name = "test", defaultPhase = LifecyclePhase.TEST, requiresDependencyResolution = ResolutionScope.TEST)
@Execute(phase = LifecyclePhase.TEST, lifecycle = "cakupan")
public class CakupanTestMojo extends AbstractCakupanMojo {
/**
* The Maven Session Object
*/
@Parameter(property = "session", required = true, readonly = true)
private MavenSession session;
/**
* The Maven PluginManager Object
*/
@Component
private BuildPluginManager pluginManager;
/**
* <i>Maven Internal</i>: List of artifacts for the plugin.
*/
@Parameter(defaultValue = "${plugin.artifacts}", required = true, readonly = true)
protected List<Artifact> pluginArtifacts;
/**
* A list of <include> elements specifying the tests (by pattern) that
* should be included in testing. When not specified, the default
* testIncludes will be <code><br/>
* <testIncludes><br/>
* <include>**/*TransformationTest.java</include><br/>
* <include>**/*XsltTest.java</include><br/>
* </testIncludes><br/>
* </code>
*/
@Parameter
private List<String> testIncludes;
/**
* A list of <exclude> elements specifying the tests (by pattern) that
* should be excluded in testing. When not specified and when the
* <code>test</code> parameter is not specified, the default testExcludes
* will be <code><br/>
* <testExcludes><br/>
* <exclude>**/*$*</exclude><br/>
* </testExcludes><br/>
* </code> (which excludes all inner classes).<br>
*/
@Parameter
private List<String> testExcludes;
/**
* Set this to "true" to ignore a failure during testing. Its use is NOT
* RECOMMENDED, but quite convenient on occasion.
*/
@Parameter(property = "maven.test.failure.ignore", defaultValue = "false")
private boolean testFailureIgnore;
/**
* Specify this parameter to run individual tests by file name, overriding
* the <code>includes/excludes</code> parameters. Each pattern you specify
* here will be used to create an include pattern formatted like
* <code>**/${test}.java</code>, so you can just type
* "-Dtest=MyXsltTest" to run a single test called "foo/MyXsltTest.java".<br/>
* This parameter overrides the <code>includes/excludes</code> parameter.
* <p/>
*/
@Parameter(property = "test")
private String test;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
handleDefaults();
getLog().info("testIncludes: " + testIncludes);
executeMojo(
plugin(groupId("org.apache.maven.plugins"), artifactId("maven-surefire-plugin"), //
version("2.9")), //
goal("test"), //
configuration(createConfigurationElements()),
executionEnvironment(getProject(), session, pluginManager));
}
private Element createSystemPropertyVarElement(String destDir) {
return element(
name("systemPropertyVariables"),
element(name("javax.xml.transform.TransformerFactory"),
"com.cakupan.xslt.transform.SaxonCakupanTransformerInstrumentFactoryImpl"),
element(name("cakupan.dir"), destDir));
}
private Element[] createConfigurationElements() throws MojoFailureException {
List<String> classpathElements = Arrays.asList(getAdditionalClasspathElements());
getLog().info("Augmenting test classpath with cakupan and its dependencies: " + classpathElements);
List<Element> config = Lists.newArrayListWithExpectedSize(6);
config.add(createElementWithChildren("includes", "include", testIncludes));
config.add(createElementWithChildren("excludes", "exclude", testExcludes));
config.add(createElementWithChildren("additionalClasspathElements", "additionalClasspathElement",
classpathElements));
String destDir = null;
try {
destDir = getInstrumentDestDir().getCanonicalPath();
} catch (IOException e) {
throw new MojoFailureException("dest dir not found");
}
config.add(createSystemPropertyVarElement(destDir));
config.add(new Element("testFailureIgnore", String.valueOf(testFailureIgnore)));
if (StringUtils.isNotBlank(test)) {
config.add(new Element("test", test));
}
return config.toArray(new Element[config.size()]);
}
private String[] getAdditionalClasspathElements() {
final List<String> cakupanDepArtifactIds = Arrays.asList("cakupan", "xstream", "saxon", "xalan", "xpp3");
Collection<Artifact> cakupanArtifacts = Collections2.filter(pluginArtifacts, new Predicate<Artifact>() {
@Override
public boolean apply(Artifact input) {
return cakupanDepArtifactIds.contains(input.getArtifactId());
}
});
Collection<String> classpathElements = Collections2.transform(cakupanArtifacts,
new Function<Artifact, String>() {
@Override
public String apply(final Artifact input) {
try {
return input.getFile().getCanonicalPath();
} catch (final IOException e) {
getLog().error(e);
return "";
}
}
});
return classpathElements.toArray(new String[classpathElements.size()]);
}
private Element createElementWithChildren(String parentName, final String childName, List<String> children) {
List<Element> includeElements = Lists.newArrayList(Iterables.transform(children,
new Function<String, Element>() {
@Override
public Element apply(String input) {
return new Element(childName, input);
}
}));
return new Element(parentName, includeElements.toArray(new Element[includeElements.size()]));
}
private void handleDefaults() {
if (CollectionUtils.isEmpty(testIncludes)) {
testIncludes = Arrays.asList("**/*TransformationTest.java", "**/*XsltTest.java");
}
if (CollectionUtils.isEmpty(testExcludes)) {
testExcludes = Arrays.asList("**/*$*");
}
}
}