blob: 55d89f0ae6396fbd33b619e652eec3e84045afce [file] [log] [blame]
package org.apache.maven.plugin.compiler;
/*
* 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.
*/
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;
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 org.codehaus.plexus.languages.java.version.JavaVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CompilerMojoTestCase
extends AbstractMojoTestCase
{
private String source = AbstractCompilerMojo.DEFAULT_SOURCE;
private String target = AbstractCompilerMojo.DEFAULT_TARGET;
@Override
protected void setUp()
throws Exception
{
super.setUp();
String javaSpec = System.getProperty( "java.specification.version" );
// It is needed to set target/source to JDK 7 for JDK12+
// because this is the lowest version which is supported by those JDK's.
// The default source/target "6" is not supported anymore.
if ( JavaVersion.parse( javaSpec ).isAtLeast( "12" ) )
{
source = "7";
target = "7";
}
}
/**
* 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" );
Logger log = LoggerFactory.getLogger( compileMojo.getClass() );
compileMojo.execute();
File testClass = new File( compileMojo.getOutputDirectory(), "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(), "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" );
Logger log = LoggerFactory.getLogger( compileMojo.getClass() );
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(), "TestCompile2.class" );
assertFalse( testClass.exists() );
testClass = new File( compileMojo.getOutputDirectory(), "TestCompile3.class" );
assertFalse( testClass.exists() );
testClass = new File( compileMojo.getOutputDirectory(), "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(), "TestCompile2TestCase.class" );
assertFalse( testClass.exists() );
testClass = new File( testCompileMojo.getOutputDirectory(), "TestCompile3TestCase.class" );
assertFalse( testClass.exists() );
testClass = new File( testCompileMojo.getOutputDirectory(), "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(), "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(), "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 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(), "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(), "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(), "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(), "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", source );
setVariableValueToObject( mojo, "target", 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", source );
setVariableValueToObject( mojo, "target", 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;
}
}