View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugin.compiler;
20  
21  import java.io.File;
22  import java.util.Arrays;
23  import java.util.Collections;
24  import java.util.HashSet;
25  import java.util.Set;
26  
27  import org.apache.maven.artifact.Artifact;
28  import org.apache.maven.plugin.compiler.stubs.CompilerManagerStub;
29  import org.apache.maven.plugin.logging.Log;
30  import org.apache.maven.plugin.testing.junit5.InjectMojo;
31  import org.apache.maven.plugin.testing.junit5.MojoTest;
32  import org.apache.maven.plugin.testing.stubs.ArtifactStub;
33  import org.junit.jupiter.api.Test;
34  
35  import static org.apache.maven.plugin.compiler.MojoTestUtils.getMockMavenProject;
36  import static org.apache.maven.plugin.compiler.MojoTestUtils.getMockMavenSession;
37  import static org.apache.maven.plugin.compiler.MojoTestUtils.getMockMojoExecution;
38  import static org.apache.maven.plugin.compiler.MojoTestUtils.getVariableValueFromObject;
39  import static org.apache.maven.plugin.compiler.MojoTestUtils.setVariableValueToObject;
40  import static org.junit.jupiter.api.Assertions.assertEquals;
41  import static org.junit.jupiter.api.Assertions.assertFalse;
42  import static org.junit.jupiter.api.Assertions.assertNotNull;
43  import static org.junit.jupiter.api.Assertions.assertNull;
44  import static org.junit.jupiter.api.Assertions.assertTrue;
45  import static org.junit.jupiter.api.Assertions.fail;
46  import static org.mockito.ArgumentMatchers.startsWith;
47  import static org.mockito.Mockito.mock;
48  import static org.mockito.Mockito.never;
49  import static org.mockito.Mockito.verify;
50  
51  @MojoTest
52  class CompilerMojoTest {
53  
54      private static final String COMPILE = "compile";
55  
56      /**
57       * tests the ability of the plugin to compile a basic file
58       *
59       * @throws Exception
60       */
61      @Test
62      @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-basic-test/plugin-config.xml")
63      void testCompilerBasic(CompilerMojo compilerMojo) throws Exception {
64          setUpCompilerMojoTestEnv(compilerMojo);
65  
66          Log log = mock(Log.class);
67  
68          compilerMojo.setLog(log);
69  
70          setVariableValueToObject(compilerMojo, "targetOrReleaseSet", false);
71          compilerMojo.execute();
72  
73          Artifact projectArtifact = getVariableValueFromObject(compilerMojo, "projectArtifact");
74          assertNotNull(
75                  projectArtifact.getFile(),
76                  "MCOMPILER-94: artifact file should only be null if there is nothing to compile");
77  
78          File testClass = new File(compilerMojo.getOutputDirectory(), "foo/TestCompile0.class");
79  
80          verify(log).warn(startsWith("No explicit value set for target or release!"));
81  
82          assertTrue(testClass::exists);
83      }
84  
85      @Test
86      @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-basic-sourcetarget/plugin-config.xml")
87      void testCompilerBasicSourceTarget(CompilerMojo compilerMojo) throws Exception {
88          setUpCompilerMojoTestEnv(compilerMojo);
89  
90          Log log = mock(Log.class);
91  
92          compilerMojo.setLog(log);
93  
94          compilerMojo.execute();
95  
96          verify(log, never()).warn(startsWith("No explicit value set for target or release!"));
97      }
98  
99      /**
100      * tests the ability of the plugin to respond to empty source
101      *
102      * @throws Exception
103      */
104     @Test
105     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-empty-source-test/plugin-config.xml")
106     void testCompilerEmptySource(CompilerMojo compilerMojo) throws Exception {
107         setUpCompilerMojoTestEnv(compilerMojo);
108 
109         compilerMojo.execute();
110 
111         assertFalse(compilerMojo.getOutputDirectory().exists());
112 
113         Artifact projectArtifact = getVariableValueFromObject(compilerMojo, "projectArtifact");
114         assertNull(
115                 projectArtifact.getFile(), "MCOMPILER-94: artifact file should be null if there is nothing to compile");
116     }
117 
118     /**
119      * tests the ability of the plugin to respond to includes and excludes correctly
120      *
121      * @throws Exception
122      */
123     @Test
124     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-includes-excludes-test/plugin-config.xml")
125     void testCompilerIncludesExcludes(CompilerMojo compilerMojo) throws Exception {
126         setUpCompilerMojoTestEnv(compilerMojo);
127 
128         Set<String> includes = new HashSet<>();
129         includes.add("**/TestCompile4*.java");
130         setVariableValueToObject(compilerMojo, "includes", includes);
131 
132         Set<String> excludes = new HashSet<>();
133         excludes.add("**/TestCompile2*.java");
134         excludes.add("**/TestCompile3*.java");
135         setVariableValueToObject(compilerMojo, "excludes", excludes);
136 
137         compilerMojo.execute();
138 
139         File testClass = new File(compilerMojo.getOutputDirectory(), "foo/TestCompile2.class");
140         assertFalse(testClass.exists());
141 
142         testClass = new File(compilerMojo.getOutputDirectory(), "foo/TestCompile3.class");
143         assertFalse(testClass.exists());
144 
145         testClass = new File(compilerMojo.getOutputDirectory(), "foo/TestCompile4.class");
146         assertTrue(testClass.exists());
147     }
148 
149     /**
150      * tests the ability of the plugin to fork and successfully compile
151      *
152      * @throws Exception
153      */
154     @Test
155     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-fork-test/plugin-config.xml")
156     void testCompilerFork(CompilerMojo compilerMojo) throws Exception {
157         setUpCompilerMojoTestEnv(compilerMojo);
158         // JAVA_HOME doesn't have to be on the PATH.
159         setVariableValueToObject(
160                 compilerMojo, "executable", new File(System.getenv("JAVA_HOME"), "bin/javac").getPath());
161 
162         compilerMojo.execute();
163 
164         File testClass = new File(compilerMojo.getOutputDirectory(), "foo/TestCompile1.class");
165         assertTrue(testClass.exists());
166     }
167 
168     @Test
169     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-one-output-file-test/plugin-config.xml")
170     void testOneOutputFileForAllInput(CompilerMojo compilerMojo) throws Exception {
171         setUpCompilerMojoTestEnv(compilerMojo);
172 
173         setVariableValueToObject(compilerMojo, "compilerManager", new CompilerManagerStub());
174 
175         compilerMojo.execute();
176 
177         File testClass = new File(compilerMojo.getOutputDirectory(), "compiled.class");
178         assertTrue(testClass.exists());
179     }
180 
181     @Test
182     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-args-test/plugin-config.xml")
183     void testCompilerArgs(CompilerMojo compilerMojo) throws Exception {
184         setUpCompilerMojoTestEnv(compilerMojo);
185 
186         setVariableValueToObject(compilerMojo, "compilerManager", new CompilerManagerStub());
187 
188         compilerMojo.execute();
189 
190         File testClass = new File(compilerMojo.getOutputDirectory(), "compiled.class");
191         assertTrue(testClass.exists());
192         assertEquals(
193                 Arrays.asList("key1=value1", "-Xlint", "-my&special:param-with+chars/not>allowed_in_XML_element_names"),
194                 compilerMojo.compilerArgs);
195     }
196 
197     @Test
198     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-implicit-test/plugin-config-none.xml")
199     void testImplicitFlagNone(CompilerMojo compilerMojo) throws Exception {
200         setUpCompilerMojoTestEnv(compilerMojo);
201 
202         assertEquals("none", compilerMojo.getImplicit());
203     }
204 
205     @Test
206     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-implicit-test/plugin-config-not-set.xml")
207     void testImplicitFlagNotSet(CompilerMojo compilerMojo) throws Exception {
208         setUpCompilerMojoTestEnv(compilerMojo);
209 
210         assertNull(compilerMojo.getImplicit());
211     }
212 
213     @Test
214     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-one-output-file-test2/plugin-config.xml")
215     void testOneOutputFileForAllInput2(CompilerMojo compilerMojo) throws Exception {
216         setUpCompilerMojoTestEnv(compilerMojo);
217 
218         setVariableValueToObject(compilerMojo, "compilerManager", new CompilerManagerStub());
219 
220         Set<String> includes = new HashSet<>();
221         includes.add("**/TestCompile4*.java");
222         setVariableValueToObject(compilerMojo, "includes", includes);
223 
224         Set<String> excludes = new HashSet<>();
225         excludes.add("**/TestCompile2*.java");
226         excludes.add("**/TestCompile3*.java");
227         setVariableValueToObject(compilerMojo, "excludes", excludes);
228 
229         compilerMojo.execute();
230 
231         File testClass = new File(compilerMojo.getOutputDirectory(), "compiled.class");
232         assertTrue(testClass.exists());
233     }
234 
235     @Test
236     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-fail-test/plugin-config.xml")
237     void testCompileFailure(CompilerMojo compilerMojo) throws Exception {
238         setUpCompilerMojoTestEnv(compilerMojo);
239 
240         setVariableValueToObject(compilerMojo, "compilerManager", new CompilerManagerStub(true));
241 
242         try {
243             compilerMojo.execute();
244 
245             fail("Should throw an exception");
246         } catch (CompilationFailureException e) {
247             // expected
248         }
249     }
250 
251     @Test
252     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-failonerror-test/plugin-config.xml")
253     void testCompileFailOnError(CompilerMojo compilerMojo) throws Exception {
254         setUpCompilerMojoTestEnv(compilerMojo);
255 
256         setVariableValueToObject(compilerMojo, "compilerManager", new CompilerManagerStub(true));
257 
258         try {
259             compilerMojo.execute();
260             assertTrue(true);
261         } catch (CompilationFailureException e) {
262             fail("The compilation error should have been consumed because failOnError = false");
263         }
264     }
265 
266     /**
267      * Tests that setting 'skipMain' to true skips compilation of the main Java source files, but that test Java source
268      * files are still compiled.
269      * @throws Exception
270      */
271     @Test
272     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-skip-main/plugin-config.xml")
273     void testCompileSkipMain(CompilerMojo compilerMojo) throws Exception {
274         setUpCompilerMojoTestEnv(compilerMojo);
275         setVariableValueToObject(compilerMojo, "skipMain", true);
276         compilerMojo.execute();
277         File testClass = new File(compilerMojo.getOutputDirectory(), "foo/TestSkipMainCompile0.class");
278         assertFalse(testClass.exists());
279     }
280 
281     /**
282      * Tests that setting 'skip' to true skips compilation of the test Java source files, but that main Java source
283      * files are still compiled.
284      * @throws Exception
285      */
286     @Test
287     @InjectMojo(goal = COMPILE, pom = "classpath:/unit/compiler-skip-test/plugin-config.xml")
288     void testCompileSkipTest(CompilerMojo compilerMojo) throws Exception {
289         setUpCompilerMojoTestEnv(compilerMojo);
290 
291         compilerMojo.execute();
292 
293         File testClass = new File(compilerMojo.getOutputDirectory(), "foo/TestSkipTestCompile0.class");
294         assertTrue(testClass.exists());
295     }
296 
297     private void setUpCompilerMojoTestEnv(CompilerMojo mojo) throws Exception {
298         setVariableValueToObject(mojo, "projectArtifact", new ArtifactStub());
299         setVariableValueToObject(mojo, "compilePath", Collections.EMPTY_LIST);
300         setVariableValueToObject(mojo, "session", getMockMavenSession());
301         setVariableValueToObject(mojo, "project", getMockMavenProject());
302         setVariableValueToObject(mojo, "mojoExecution", getMockMojoExecution());
303         setVariableValueToObject(mojo, "source", AbstractCompilerMojo.DEFAULT_SOURCE);
304         setVariableValueToObject(mojo, "target", AbstractCompilerMojo.DEFAULT_TARGET);
305     }
306 }