blob: a19ce74753bd9072d6d57529608fb49ca916670f [file] [log] [blame]
/*
* 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.compiler;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.compiler.stubs.CompilerManagerStub;
import org.apache.maven.plugin.compiler.stubs.DebugEnabledLog;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugin.testing.AbstractMojoTestCase;
import org.apache.maven.plugin.testing.stubs.ArtifactStub;
import org.apache.maven.project.MavenProject;
import static org.mockito.ArgumentMatchers.startsWith;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class CompilerMojoTestCase extends AbstractMojoTestCase {
/**
* tests the ability of the plugin to compile a basic file
*
* @throws Exception
*/
public void testCompilerBasic() throws Exception {
CompilerMojo compileMojo = getCompilerMojo("target/test-classes/unit/compiler-basic-test/plugin-config.xml");
Log log = mock(Log.class);
compileMojo.setLog(log);
compileMojo.execute();
File testClass = new File(compileMojo.getOutputDirectory(), "foo/TestCompile0.class");
assertTrue(testClass.exists());
TestCompilerMojo testCompileMojo =
getTestCompilerMojo(compileMojo, "target/test-classes/unit/compiler-basic-test/plugin-config.xml");
testCompileMojo.execute();
Artifact projectArtifact = (Artifact) getVariableValueFromObject(compileMojo, "projectArtifact");
assertNotNull(
"MCOMPILER-94: artifact file should only be null if there is nothing to compile",
projectArtifact.getFile());
testClass = new File(testCompileMojo.getOutputDirectory(), "foo/TestCompile0Test.class");
verify(log).warn(startsWith("No explicit value set for target or release!"));
assertTrue(testClass.exists());
}
public void testCompilerBasicSourceTarget() throws Exception {
CompilerMojo compileMojo =
getCompilerMojo("target/test-classes/unit/compiler-basic-sourcetarget/plugin-config.xml");
Log log = mock(Log.class);
compileMojo.setLog(log);
compileMojo.execute();
verify(log, never()).warn(startsWith("No explicit value set for target or release!"));
}
/**
* tests the ability of the plugin to respond to empty source
*
* @throws Exception
*/
public void testCompilerEmptySource() throws Exception {
CompilerMojo compileMojo =
getCompilerMojo("target/test-classes/unit/compiler-empty-source-test/plugin-config.xml");
compileMojo.execute();
assertFalse(compileMojo.getOutputDirectory().exists());
Artifact projectArtifact = (Artifact) getVariableValueFromObject(compileMojo, "projectArtifact");
assertNull(
"MCOMPILER-94: artifact file should be null if there is nothing to compile", projectArtifact.getFile());
TestCompilerMojo testCompileMojo = getTestCompilerMojo(
compileMojo, "target/test-classes/unit/compiler-empty-source-test/plugin-config.xml");
testCompileMojo.execute();
assertFalse(testCompileMojo.getOutputDirectory().exists());
}
/**
* tests the ability of the plugin to respond to includes and excludes correctly
*
* @throws Exception
*/
public void testCompilerIncludesExcludes() throws Exception {
CompilerMojo compileMojo =
getCompilerMojo("target/test-classes/unit/compiler-includes-excludes-test/plugin-config.xml");
Set<String> includes = new HashSet<>();
includes.add("**/TestCompile4*.java");
setVariableValueToObject(compileMojo, "includes", includes);
Set<String> excludes = new HashSet<>();
excludes.add("**/TestCompile2*.java");
excludes.add("**/TestCompile3*.java");
setVariableValueToObject(compileMojo, "excludes", excludes);
compileMojo.execute();
File testClass = new File(compileMojo.getOutputDirectory(), "foo/TestCompile2.class");
assertFalse(testClass.exists());
testClass = new File(compileMojo.getOutputDirectory(), "foo/TestCompile3.class");
assertFalse(testClass.exists());
testClass = new File(compileMojo.getOutputDirectory(), "foo/TestCompile4.class");
assertTrue(testClass.exists());
TestCompilerMojo testCompileMojo = getTestCompilerMojo(
compileMojo, "target/test-classes/unit/compiler-includes-excludes-test/plugin-config.xml");
setVariableValueToObject(testCompileMojo, "testIncludes", includes);
setVariableValueToObject(testCompileMojo, "testExcludes", excludes);
testCompileMojo.execute();
testClass = new File(testCompileMojo.getOutputDirectory(), "foo/TestCompile2TestCase.class");
assertFalse(testClass.exists());
testClass = new File(testCompileMojo.getOutputDirectory(), "foo/TestCompile3TestCase.class");
assertFalse(testClass.exists());
testClass = new File(testCompileMojo.getOutputDirectory(), "foo/TestCompile4TestCase.class");
assertTrue(testClass.exists());
}
/**
* tests the ability of the plugin to fork and successfully compile
*
* @throws Exception
*/
public void testCompilerFork() throws Exception {
CompilerMojo compileMojo = getCompilerMojo("target/test-classes/unit/compiler-fork-test/plugin-config.xml");
// JAVA_HOME doesn't have to be on the PATH.
setVariableValueToObject(
compileMojo, "executable", new File(System.getenv("JAVA_HOME"), "bin/javac").getPath());
compileMojo.execute();
File testClass = new File(compileMojo.getOutputDirectory(), "foo/TestCompile1.class");
assertTrue(testClass.exists());
TestCompilerMojo testCompileMojo =
getTestCompilerMojo(compileMojo, "target/test-classes/unit/compiler-fork-test/plugin-config.xml");
// JAVA_HOME doesn't have to be on the PATH.
setVariableValueToObject(
testCompileMojo, "executable", new File(System.getenv("JAVA_HOME"), "bin/javac").getPath());
testCompileMojo.execute();
testClass = new File(testCompileMojo.getOutputDirectory(), "foo/TestCompile1TestCase.class");
assertTrue(testClass.exists());
}
public void testOneOutputFileForAllInput() throws Exception {
CompilerMojo compileMojo =
getCompilerMojo("target/test-classes/unit/compiler-one-output-file-test/plugin-config.xml");
setVariableValueToObject(compileMojo, "compilerManager", new CompilerManagerStub());
compileMojo.execute();
File testClass = new File(compileMojo.getOutputDirectory(), "compiled.class");
assertTrue(testClass.exists());
TestCompilerMojo testCompileMojo = getTestCompilerMojo(
compileMojo, "target/test-classes/unit/compiler-one-output-file-test/plugin-config.xml");
setVariableValueToObject(testCompileMojo, "compilerManager", new CompilerManagerStub());
testCompileMojo.execute();
testClass = new File(testCompileMojo.getOutputDirectory(), "compiled.class");
assertTrue(testClass.exists());
}
public void testCompilerArgs() throws Exception {
CompilerMojo compileMojo = getCompilerMojo("target/test-classes/unit/compiler-args-test/plugin-config.xml");
setVariableValueToObject(compileMojo, "compilerManager", new CompilerManagerStub());
compileMojo.execute();
File testClass = new File(compileMojo.getOutputDirectory(), "compiled.class");
assertTrue(testClass.exists());
assertEquals(
Arrays.asList("key1=value1", "-Xlint", "-my&special:param-with+chars/not>allowed_in_XML_element_names"),
compileMojo.compilerArgs);
}
public void testImplicitFlagNone() throws Exception {
CompilerMojo compileMojo =
getCompilerMojo("target/test-classes/unit/compiler-implicit-test/plugin-config-none.xml");
assertEquals("none", compileMojo.getImplicit());
}
public void testImplicitFlagNotSet() throws Exception {
CompilerMojo compileMojo =
getCompilerMojo("target/test-classes/unit/compiler-implicit-test/plugin-config-not-set.xml");
assertNull(compileMojo.getImplicit());
}
public void testOneOutputFileForAllInput2() throws Exception {
CompilerMojo compileMojo =
getCompilerMojo("target/test-classes/unit/compiler-one-output-file-test2/plugin-config.xml");
setVariableValueToObject(compileMojo, "compilerManager", new CompilerManagerStub());
Set<String> includes = new HashSet<>();
includes.add("**/TestCompile4*.java");
setVariableValueToObject(compileMojo, "includes", includes);
Set<String> excludes = new HashSet<>();
excludes.add("**/TestCompile2*.java");
excludes.add("**/TestCompile3*.java");
setVariableValueToObject(compileMojo, "excludes", excludes);
compileMojo.execute();
File testClass = new File(compileMojo.getOutputDirectory(), "compiled.class");
assertTrue(testClass.exists());
TestCompilerMojo testCompileMojo = getTestCompilerMojo(
compileMojo, "target/test-classes/unit/compiler-one-output-file-test2/plugin-config.xml");
setVariableValueToObject(testCompileMojo, "compilerManager", new CompilerManagerStub());
setVariableValueToObject(testCompileMojo, "testIncludes", includes);
setVariableValueToObject(testCompileMojo, "testExcludes", excludes);
testCompileMojo.execute();
testClass = new File(testCompileMojo.getOutputDirectory(), "compiled.class");
assertTrue(testClass.exists());
}
public void testCompileFailure() throws Exception {
CompilerMojo compileMojo = getCompilerMojo("target/test-classes/unit/compiler-fail-test/plugin-config.xml");
setVariableValueToObject(compileMojo, "compilerManager", new CompilerManagerStub(true));
try {
compileMojo.execute();
fail("Should throw an exception");
} catch (CompilationFailureException e) {
// expected
}
}
public void testCompileFailOnError() throws Exception {
CompilerMojo compileMojo =
getCompilerMojo("target/test-classes/unit/compiler-failonerror-test/plugin-config.xml");
setVariableValueToObject(compileMojo, "compilerManager", new CompilerManagerStub(true));
try {
compileMojo.execute();
assertTrue(true);
} catch (CompilationFailureException e) {
fail("The compilation error should have been consumed because failOnError = false");
}
}
/**
* Tests that setting 'skipMain' to true skips compilation of the main Java source files, but that test Java source
* files are still compiled.
* @throws Exception
*/
public void testCompileSkipMain() throws Exception {
CompilerMojo compileMojo = getCompilerMojo("target/test-classes/unit/compiler-skip-main/plugin-config.xml");
setVariableValueToObject(compileMojo, "skipMain", true);
compileMojo.execute();
File testClass = new File(compileMojo.getOutputDirectory(), "foo/TestSkipMainCompile0.class");
assertFalse(testClass.exists());
TestCompilerMojo testCompileMojo =
getTestCompilerMojo(compileMojo, "target/test-classes/unit/compiler-skip-main/plugin-config.xml");
testCompileMojo.execute();
testClass = new File(testCompileMojo.getOutputDirectory(), "foo/TestSkipMainCompile0Test.class");
assertTrue(testClass.exists());
}
/**
* Tests that setting 'skip' to true skips compilation of the test Java source files, but that main Java source
* files are still compiled.
* @throws Exception
*/
public void testCompileSkipTest() throws Exception {
CompilerMojo compileMojo = getCompilerMojo("target/test-classes/unit/compiler-skip-test/plugin-config.xml");
compileMojo.execute();
File testClass = new File(compileMojo.getOutputDirectory(), "foo/TestSkipTestCompile0.class");
assertTrue(testClass.exists());
TestCompilerMojo testCompileMojo =
getTestCompilerMojo(compileMojo, "target/test-classes/unit/compiler-skip-test/plugin-config.xml");
setVariableValueToObject(testCompileMojo, "skip", true);
testCompileMojo.execute();
testClass = new File(testCompileMojo.getOutputDirectory(), "foo/TestSkipTestCompile0Test.class");
assertFalse(testClass.exists());
}
private CompilerMojo getCompilerMojo(String pomXml) throws Exception {
File testPom = new File(getBasedir(), pomXml);
CompilerMojo mojo = (CompilerMojo) lookupMojo("compile", testPom);
setVariableValueToObject(mojo, "log", new DebugEnabledLog());
setVariableValueToObject(mojo, "projectArtifact", new ArtifactStub());
setVariableValueToObject(mojo, "compilePath", Collections.EMPTY_LIST);
setVariableValueToObject(mojo, "session", getMockMavenSession());
setVariableValueToObject(mojo, "project", getMockMavenProject());
setVariableValueToObject(mojo, "mojoExecution", getMockMojoExecution());
setVariableValueToObject(mojo, "source", AbstractCompilerMojo.DEFAULT_SOURCE);
setVariableValueToObject(mojo, "target", AbstractCompilerMojo.DEFAULT_TARGET);
return mojo;
}
private TestCompilerMojo getTestCompilerMojo(CompilerMojo compilerMojo, String pomXml) throws Exception {
File testPom = new File(getBasedir(), pomXml);
TestCompilerMojo mojo = (TestCompilerMojo) lookupMojo("testCompile", testPom);
setVariableValueToObject(mojo, "log", new DebugEnabledLog());
File buildDir = (File) getVariableValueFromObject(compilerMojo, "buildDirectory");
File testClassesDir = new File(buildDir, "test-classes");
setVariableValueToObject(mojo, "outputDirectory", testClassesDir);
List<String> testClasspathList = new ArrayList<>();
Artifact junitArtifact = mock(Artifact.class);
ArtifactHandler handler = mock(ArtifactHandler.class);
when(handler.isAddedToClasspath()).thenReturn(true);
when(junitArtifact.getArtifactHandler()).thenReturn(handler);
File artifactFile;
String localRepository = System.getProperty("localRepository");
if (localRepository != null) {
artifactFile = new File(localRepository, "junit/junit/3.8.1/junit-3.8.1.jar");
} else {
// for IDE
String junitURI =
org.junit.Test.class.getResource("Test.class").toURI().toString();
junitURI = junitURI.substring("jar:".length(), junitURI.indexOf('!'));
artifactFile = new File(URI.create(junitURI));
}
when(junitArtifact.getFile()).thenReturn(artifactFile);
testClasspathList.add(artifactFile.getAbsolutePath());
testClasspathList.add(compilerMojo.getOutputDirectory().getPath());
String testSourceRoot = testPom.getParent() + "/src/test/java";
setVariableValueToObject(mojo, "compileSourceRoots", Collections.singletonList(testSourceRoot));
MavenProject project = getMockMavenProject();
project.setFile(testPom);
project.addCompileSourceRoot("/src/main/java");
project.setArtifacts(Collections.singleton(junitArtifact));
project.getBuild().setOutputDirectory(new File(buildDir, "classes").getAbsolutePath());
setVariableValueToObject(mojo, "project", project);
setVariableValueToObject(mojo, "testPath", testClasspathList);
setVariableValueToObject(mojo, "session", getMockMavenSession());
setVariableValueToObject(mojo, "mojoExecution", getMockMojoExecution());
setVariableValueToObject(mojo, "source", AbstractCompilerMojo.DEFAULT_SOURCE);
setVariableValueToObject(mojo, "target", AbstractCompilerMojo.DEFAULT_TARGET);
return mojo;
}
private MavenProject getMockMavenProject() {
MavenProject mp = new MavenProject();
mp.getBuild().setDirectory("target");
mp.getBuild().setOutputDirectory("target/classes");
mp.getBuild().setSourceDirectory("src/main/java");
mp.getBuild().setTestOutputDirectory("target/test-classes");
return mp;
}
private MavenSession getMockMavenSession() {
MavenSession session = mock(MavenSession.class);
// when( session.getPluginContext( isA(PluginDescriptor.class), isA(MavenProject.class) ) ).thenReturn(
// Collections.emptyMap() );
when(session.getCurrentProject()).thenReturn(getMockMavenProject());
return session;
}
private MojoExecution getMockMojoExecution() {
MojoDescriptor md = new MojoDescriptor();
md.setGoal("compile");
MojoExecution me = new MojoExecution(md);
PluginDescriptor pd = new PluginDescriptor();
pd.setArtifactId("maven-compiler-plugin");
md.setPluginDescriptor(pd);
return me;
}
}