View Javadoc
1   package org.apache.maven.plugin.compiler;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import static org.mockito.Mockito.mock;
23  import static org.mockito.Mockito.when;
24  
25  import java.io.File;
26  import java.net.URI;
27  import java.util.ArrayList;
28  import java.util.Arrays;
29  import java.util.Collections;
30  import java.util.HashSet;
31  import java.util.List;
32  import java.util.Set;
33  
34  import org.apache.maven.artifact.Artifact;
35  import org.apache.maven.artifact.handler.ArtifactHandler;
36  import org.apache.maven.execution.MavenSession;
37  import org.apache.maven.plugin.MojoExecution;
38  import org.apache.maven.plugin.compiler.stubs.CompilerManagerStub;
39  import org.apache.maven.plugin.compiler.stubs.DebugEnabledLog;
40  import org.apache.maven.plugin.descriptor.MojoDescriptor;
41  import org.apache.maven.plugin.descriptor.PluginDescriptor;
42  import org.apache.maven.plugin.testing.AbstractMojoTestCase;
43  import org.apache.maven.plugin.testing.stubs.ArtifactStub;
44  import org.apache.maven.project.MavenProject;
45  
46  public class CompilerMojoTestCase
47      extends AbstractMojoTestCase
48  {
49      
50      private String source = AbstractCompilerMojo.DEFAULT_SOURCE;
51  
52      private String target = AbstractCompilerMojo.DEFAULT_TARGET;
53      
54      @Override
55      protected void setUp()
56          throws Exception
57      {
58          super.setUp();
59          
60          String javaSpec = System.getProperty( "java.specification.version" );
61          if ( "9".equals( javaSpec ) )
62          {
63              source = "6";
64              target = "6";
65          }
66      }
67      
68      /**
69       * tests the ability of the plugin to compile a basic file
70       *
71       * @throws Exception
72       */
73      public void testCompilerBasic()
74          throws Exception
75      {
76          CompilerMojo compileMojo = getCompilerMojo( "target/test-classes/unit/compiler-basic-test/plugin-config.xml" );
77          
78          compileMojo.execute();
79  
80          File testClass = new File( compileMojo.getOutputDirectory(), "TestCompile0.class" );
81  
82          assertTrue( testClass.exists() );
83  
84          TestCompilerMojo testCompileMojo =
85              getTestCompilerMojo( compileMojo, "target/test-classes/unit/compiler-basic-test/plugin-config.xml" );
86  
87          testCompileMojo.execute();
88  
89          Artifact projectArtifact = (Artifact) getVariableValueFromObject( compileMojo, "projectArtifact" );
90          assertNotNull( "MCOMPILER-94: artifact file should only be null if there is nothing to compile",
91                         projectArtifact.getFile() );
92  
93          testClass = new File( testCompileMojo.getOutputDirectory(), "TestCompile0Test.class" );
94  
95          assertTrue( testClass.exists() );
96      }
97  
98      /**
99       * tests the ability of the plugin to respond to empty source
100      *
101      * @throws Exception
102      */
103     public void testCompilerEmptySource()
104         throws Exception
105     {
106         CompilerMojo compileMojo =
107             getCompilerMojo( "target/test-classes/unit/compiler-empty-source-test/plugin-config.xml" );
108 
109         compileMojo.execute();
110 
111         assertFalse( compileMojo.getOutputDirectory().exists() );
112 
113         Artifact projectArtifact = (Artifact) getVariableValueFromObject( compileMojo, "projectArtifact" );
114         assertNull( "MCOMPILER-94: artifact file should be null if there is nothing to compile",
115                     projectArtifact.getFile() );
116 
117         TestCompilerMojo testCompileMojo =
118             getTestCompilerMojo( compileMojo, "target/test-classes/unit/compiler-empty-source-test/plugin-config.xml" );
119 
120         testCompileMojo.execute();
121 
122         assertFalse( testCompileMojo.getOutputDirectory().exists() );
123     }
124 
125     /**
126      * tests the ability of the plugin to respond to includes and excludes correctly
127      *
128      * @throws Exception
129      */
130     public void testCompilerIncludesExcludes()
131         throws Exception
132     {
133         CompilerMojo compileMojo =
134             getCompilerMojo( "target/test-classes/unit/compiler-includes-excludes-test/plugin-config.xml" );
135 
136         Set<String> includes = new HashSet<String>();
137         includes.add( "**/TestCompile4*.java" );
138         setVariableValueToObject( compileMojo, "includes", includes );
139 
140         Set<String> excludes = new HashSet<String>();
141         excludes.add( "**/TestCompile2*.java" );
142         excludes.add( "**/TestCompile3*.java" );
143         setVariableValueToObject( compileMojo, "excludes", excludes );
144 
145         compileMojo.execute();
146 
147         File testClass = new File( compileMojo.getOutputDirectory(), "TestCompile2.class" );
148         assertFalse( testClass.exists() );
149 
150         testClass = new File( compileMojo.getOutputDirectory(), "TestCompile3.class" );
151         assertFalse( testClass.exists() );
152 
153         testClass = new File( compileMojo.getOutputDirectory(), "TestCompile4.class" );
154         assertTrue( testClass.exists() );
155 
156         TestCompilerMojo testCompileMojo = getTestCompilerMojo( compileMojo,
157                                                                 "target/test-classes/unit/compiler-includes-excludes-test/plugin-config.xml" );
158 
159         setVariableValueToObject( testCompileMojo, "testIncludes", includes );
160         setVariableValueToObject( testCompileMojo, "testExcludes", excludes );
161 
162         testCompileMojo.execute();
163 
164         testClass = new File( testCompileMojo.getOutputDirectory(), "TestCompile2TestCase.class" );
165         assertFalse( testClass.exists() );
166 
167         testClass = new File( testCompileMojo.getOutputDirectory(), "TestCompile3TestCase.class" );
168         assertFalse( testClass.exists() );
169 
170         testClass = new File( testCompileMojo.getOutputDirectory(), "TestCompile4TestCase.class" );
171         assertTrue( testClass.exists() );
172     }
173 
174     /**
175      * tests the ability of the plugin to fork and successfully compile
176      *
177      * @throws Exception
178      */
179     public void testCompilerFork()
180         throws Exception
181     {
182         CompilerMojo compileMojo = getCompilerMojo( "target/test-classes/unit/compiler-fork-test/plugin-config.xml" );
183 
184         // JAVA_HOME doesn't have to be on the PATH.
185         setVariableValueToObject( compileMojo, "executable",  new File( System.getenv( "JAVA_HOME" ), "bin/javac" ).getPath() );
186 
187         compileMojo.execute();
188 
189         File testClass = new File( compileMojo.getOutputDirectory(), "TestCompile1.class" );
190         assertTrue( testClass.exists() );
191 
192         TestCompilerMojo testCompileMojo =
193             getTestCompilerMojo( compileMojo, "target/test-classes/unit/compiler-fork-test/plugin-config.xml" );
194 
195         // JAVA_HOME doesn't have to be on the PATH.
196         setVariableValueToObject( testCompileMojo, "executable",  new File( System.getenv( "JAVA_HOME" ), "bin/javac" ).getPath() );
197 
198         testCompileMojo.execute();
199 
200         testClass = new File( testCompileMojo.getOutputDirectory(), "TestCompile1TestCase.class" );
201         assertTrue( testClass.exists() );
202     }
203 
204     public void testOneOutputFileForAllInput()
205         throws Exception
206     {
207         CompilerMojo compileMojo =
208             getCompilerMojo( "target/test-classes/unit/compiler-one-output-file-test/plugin-config.xml" );
209 
210         setVariableValueToObject( compileMojo, "compilerManager", new CompilerManagerStub() );
211 
212         compileMojo.execute();
213 
214         File testClass = new File( compileMojo.getOutputDirectory(), "compiled.class" );
215         assertTrue( testClass.exists() );
216 
217         TestCompilerMojo testCompileMojo = getTestCompilerMojo( compileMojo,
218                                                                 "target/test-classes/unit/compiler-one-output-file-test/plugin-config.xml" );
219 
220         setVariableValueToObject( testCompileMojo, "compilerManager", new CompilerManagerStub() );
221 
222         testCompileMojo.execute();
223 
224         testClass = new File( testCompileMojo.getOutputDirectory(), "compiled.class" );
225         assertTrue( testClass.exists() );
226     }
227 
228     public void testCompilerArgs()
229         throws Exception
230     {
231         CompilerMojo compileMojo = getCompilerMojo( "target/test-classes/unit/compiler-args-test/plugin-config.xml" );
232 
233         setVariableValueToObject( compileMojo, "compilerManager", new CompilerManagerStub() );
234 
235         compileMojo.execute();
236 
237         File testClass = new File( compileMojo.getOutputDirectory(), "compiled.class" );
238         assertTrue( testClass.exists() );
239         assertEquals( Arrays.asList( "key1=value1","-Xlint","-my&special:param-with+chars/not>allowed_in_XML_element_names" ), compileMojo.compilerArgs );
240     }
241 
242     public void testOneOutputFileForAllInput2()
243         throws Exception
244     {
245         CompilerMojo compileMojo =
246             getCompilerMojo( "target/test-classes/unit/compiler-one-output-file-test2/plugin-config.xml" );
247 
248         setVariableValueToObject( compileMojo, "compilerManager", new CompilerManagerStub() );
249 
250         Set<String> includes = new HashSet<String>();
251         includes.add( "**/TestCompile4*.java" );
252         setVariableValueToObject( compileMojo, "includes", includes );
253 
254         Set<String> excludes = new HashSet<String>();
255         excludes.add( "**/TestCompile2*.java" );
256         excludes.add( "**/TestCompile3*.java" );
257         setVariableValueToObject( compileMojo, "excludes", excludes );
258 
259         compileMojo.execute();
260 
261         File testClass = new File( compileMojo.getOutputDirectory(), "compiled.class" );
262         assertTrue( testClass.exists() );
263 
264         TestCompilerMojo testCompileMojo = getTestCompilerMojo( compileMojo,
265                                                                 "target/test-classes/unit/compiler-one-output-file-test2/plugin-config.xml" );
266 
267         setVariableValueToObject( testCompileMojo, "compilerManager", new CompilerManagerStub() );
268         setVariableValueToObject( testCompileMojo, "testIncludes", includes );
269         setVariableValueToObject( testCompileMojo, "testExcludes", excludes );
270 
271         testCompileMojo.execute();
272 
273         testClass = new File( testCompileMojo.getOutputDirectory(), "compiled.class" );
274         assertTrue( testClass.exists() );
275     }
276 
277     public void testCompileFailure()
278         throws Exception
279     {
280         CompilerMojo compileMojo = getCompilerMojo( "target/test-classes/unit/compiler-fail-test/plugin-config.xml" );
281 
282         setVariableValueToObject( compileMojo, "compilerManager", new CompilerManagerStub( true ) );
283 
284         try
285         {
286             compileMojo.execute();
287 
288             fail( "Should throw an exception" );
289         }
290         catch ( CompilationFailureException e )
291         {
292             //expected
293         }
294     }
295 
296     public void testCompileFailOnError()
297         throws Exception
298     {
299         CompilerMojo compileMojo =
300             getCompilerMojo( "target/test-classes/unit/compiler-failonerror-test/plugin-config.xml" );
301 
302         setVariableValueToObject( compileMojo, "compilerManager", new CompilerManagerStub( true ) );
303 
304         try
305         {
306             compileMojo.execute();
307             assertTrue( true );
308         }
309         catch ( CompilationFailureException e )
310         {
311             fail( "The compilation error should have been consumed because failOnError = false" );
312         }
313     }
314     
315     /**
316      * Tests that setting 'skipMain' to true skips compilation of the main Java source files, but that test Java source
317      * files are still compiled.
318      * @throws Exception
319      */
320     public void testCompileSkipMain()
321         throws Exception
322     {
323         CompilerMojo compileMojo = getCompilerMojo( "target/test-classes/unit/compiler-skip-main/plugin-config.xml" );
324         setVariableValueToObject( compileMojo, "skipMain", true );
325         compileMojo.execute();
326         File testClass = new File( compileMojo.getOutputDirectory(), "TestSkipMainCompile0.class" );
327         assertFalse( testClass.exists() );
328 
329         TestCompilerMojo testCompileMojo =
330             getTestCompilerMojo( compileMojo, "target/test-classes/unit/compiler-skip-main/plugin-config.xml" );
331         testCompileMojo.execute();
332         testClass = new File( testCompileMojo.getOutputDirectory(), "TestSkipMainCompile0Test.class" );
333         assertTrue( testClass.exists() );
334     }
335     
336     /**
337      * Tests that setting 'skip' to true skips compilation of the test Java source files, but that main Java source
338      * files are still compiled.
339      * @throws Exception
340      */
341     public void testCompileSkipTest()
342         throws Exception
343     {
344         CompilerMojo compileMojo = getCompilerMojo( "target/test-classes/unit/compiler-skip-test/plugin-config.xml" );
345         compileMojo.execute();
346         File testClass = new File( compileMojo.getOutputDirectory(), "TestSkipTestCompile0.class" );
347         assertTrue( testClass.exists() );
348 
349         TestCompilerMojo testCompileMojo =
350             getTestCompilerMojo( compileMojo, "target/test-classes/unit/compiler-skip-test/plugin-config.xml" );
351         setVariableValueToObject( testCompileMojo, "skip", true );
352         testCompileMojo.execute();
353         testClass = new File( testCompileMojo.getOutputDirectory(), "TestSkipTestCompile0Test.class" );
354         assertFalse( testClass.exists() );
355     }
356 
357     private CompilerMojo getCompilerMojo( String pomXml )
358         throws Exception
359     {
360         File testPom = new File( getBasedir(), pomXml );
361 
362         CompilerMojo mojo = (CompilerMojo) lookupMojo( "compile", testPom );
363 
364         setVariableValueToObject( mojo, "log", new DebugEnabledLog() );
365         setVariableValueToObject( mojo, "projectArtifact", new ArtifactStub() );
366         setVariableValueToObject( mojo, "compilePath", Collections.EMPTY_LIST );
367         setVariableValueToObject( mojo, "session", getMockMavenSession() );
368         setVariableValueToObject( mojo, "project", getMockMavenProject() );
369         setVariableValueToObject( mojo, "mojoExecution", getMockMojoExecution() );
370         setVariableValueToObject( mojo, "source", source );
371         setVariableValueToObject( mojo, "target", target );
372 
373         return mojo;
374     }
375 
376     private TestCompilerMojo getTestCompilerMojo( CompilerMojo compilerMojo, String pomXml )
377         throws Exception
378     {
379         File testPom = new File( getBasedir(), pomXml );
380 
381         TestCompilerMojo mojo = (TestCompilerMojo) lookupMojo( "testCompile", testPom );
382 
383         setVariableValueToObject( mojo, "log", new DebugEnabledLog() );
384 
385         File buildDir = (File) getVariableValueFromObject( compilerMojo, "buildDirectory" );
386         File testClassesDir = new File( buildDir, "test-classes" );
387         setVariableValueToObject( mojo, "outputDirectory", testClassesDir );
388 
389         List<String> testClasspathList = new ArrayList<String>();
390         
391         Artifact junitArtifact = mock( Artifact.class );
392         ArtifactHandler handler = mock( ArtifactHandler.class );
393         when( handler.isAddedToClasspath() ).thenReturn( true );
394         when( junitArtifact.getArtifactHandler() ).thenReturn( handler );
395 
396         File artifactFile;
397         String localRepository = System.getProperty( "localRepository" );
398         if ( localRepository != null )
399         {
400             artifactFile = new File( localRepository, "junit/junit/3.8.1/junit-3.8.1.jar" );
401         }
402         else
403         {
404             // for IDE
405             String junitURI = org.junit.Test.class.getResource( "Test.class" ).toURI().toString();
406             junitURI = junitURI.substring( "jar:".length(), junitURI.indexOf( '!' ) );
407             artifactFile = new File( URI.create( junitURI ) );
408         }
409         when ( junitArtifact.getFile() ).thenReturn( artifactFile );
410         
411         testClasspathList.add( artifactFile.getAbsolutePath() );
412         testClasspathList.add( compilerMojo.getOutputDirectory().getPath() );
413 
414         String testSourceRoot = testPom.getParent() + "/src/test/java";
415         setVariableValueToObject( mojo, "compileSourceRoots", Collections.singletonList( testSourceRoot ) );
416 
417         MavenProject project = getMockMavenProject();
418         project.setArtifacts( Collections.singleton( junitArtifact )  );
419         project.getBuild().setOutputDirectory( new File( buildDir, "classes" ).getAbsolutePath() );
420         setVariableValueToObject( mojo, "project", project );
421         setVariableValueToObject( mojo, "compilePath", Collections.EMPTY_LIST );
422         setVariableValueToObject( mojo, "testPath", testClasspathList );
423         setVariableValueToObject( mojo, "session", getMockMavenSession() );
424         setVariableValueToObject( mojo, "mojoExecution", getMockMojoExecution() );
425         setVariableValueToObject( mojo, "source", source );
426         setVariableValueToObject( mojo, "target", target );
427 
428         return mojo;
429     }
430     
431     private MavenProject getMockMavenProject()
432     {
433         MavenProject mp = new MavenProject();
434         mp.getBuild().setDirectory( "target" );
435         mp.getBuild().setOutputDirectory( "target/classes" );
436         mp.getBuild().setSourceDirectory( "src/main/java" );
437         mp.getBuild().setTestOutputDirectory( "target/test-classes" );
438         return mp;
439     }
440 
441     private MavenSession getMockMavenSession()
442     {
443         MavenSession session = mock( MavenSession.class );
444         // when( session.getPluginContext( isA(PluginDescriptor.class), isA(MavenProject.class) ) ).thenReturn(
445         // Collections.emptyMap() );
446         when( session.getCurrentProject() ).thenReturn( getMockMavenProject() );
447         return session;
448     }
449 
450     private MojoExecution getMockMojoExecution()
451     {
452         MojoDescriptor md = new MojoDescriptor();
453         md.setGoal( "compile" );
454 
455         MojoExecution me = new MojoExecution( md );
456 
457         PluginDescriptor pd = new PluginDescriptor();
458         pd.setArtifactId( "maven-compiler-plugin" );
459         md.setPluginDescriptor( pd );
460 
461         return me;
462     }
463 }